Example 1: Gathering Stock Quotes
by: JustinBishop
This example may seem a bit obfuscated...
Requirements, and extending Array
First we're going to want to add the library net/http for gathering our stock quotes.
require 'net/http'
Now we're going to take advantage of Ruby's ability to dynamically extend all objects, even standard ones like 'Array'. We're going to add a method to Array classes called insert(index, value);. The concept is pretty self explanatory, the 'value' will be inserted into the array at position 'index'.
class Array
def insert(index, value, start=[], ident=0)
(index > 0) ?
self.insert(index - 1, value, start.concat([self[ident]]), ident + 1) :
start.concat([value]).concat(self[ident..self.length]);
end
end
Actual Slick Library Function
Now to our actual library function call. It may seem superfluous to wrap a class around this one function, but i plan to extend upon this framework in the future. This one function, RubyStock::getStocks(<list of symbols,,,>) will return a hash with a key for each symbol passed. Each hash key will then have a value which is another hash that has 2 keys of it's own, "Name" and "Price". "Name" is the full name of the company with the given symbol, and "Price" is the symbols last trade value.
class RubyStock
def RubyStock::getStocks(*symbols)
Hash[*(symbols.collect{|symbol|[symbol,Hash[\
*(Net::HTTP.get('quote.yahoo.com','/d?f=nl1&s='+symbol).chop\
.split(',').unshift("Name").insert(2,"Price"))]];}.flatten)];
end
end
Library in action...
Finally an example of this function call in use. We'll gather information on a few popular computer related companies...
myHash = RubyStock::getStocks("IBM","YHOO","RHAT","MSFT","AOL");Now we'll print out the information gathered...
myHash = RubyStock::getStocks("IBM","YHOO","RHAT","MSFT","AOL");
myHash.each { |key,value|
print "Symbol is: #{key}...";
print "FullName: #{value['Name']}...";
print "Price: #{value['Price']}\n";
}And my results at this posting are:
Symbol is: YHOO...FullName: "YAHOO INC"...Price: 31.46 Symbol is: AOL...FullName: "AOL TIME WARNER"...Price: 15.30 Symbol is: MSFT...FullName: "MICROSOFT CP"...Price: 26.17 Symbol is: RHAT...FullName: "RED HAT INC"...Price: 6.91 Symbol is: IBM...FullName: "INTL BUS MACHINE"...Price: 81.27
Example 2: Old School Way of Finding Square Root
I talked to my uncle recently about how he and his fellow aerospace engineers managed to compute square-roots in the 1950's when they had no calculators...he showed me a method which he called the "Rule of 20's."...he couldn't remember any other name. It's kind of like a complex version of long division...and it'll work to as many decimal points as you wish.
I find this fascinating. Here's an implementation of that procedure, done with Ruby...if you follow the code closely you can understand how it's done by hand. The function name is SqRoot The first parameter to the function is the number you want to find the square-root of, and the second parameter is the number of decimal points you want to calculate to return in the answer.
$rootTable = Array.new(100);
$rootTable[0] = 0;
1.upto(3) {|i| $rootTable[i] = 1; }
4.upto(8) {|i| $rootTable[i] = 2; }
9.upto(15) {|i| $rootTable[i] = 3; }
16.upto(24) {|i| $rootTable[i] = 4; }
25.upto(35) {|i| $rootTable[i] = 5; }
36.upto(48) {|i| $rootTable[i] = 6; }
49.upto(63) {|i| $rootTable[i] = 7; }
64.upto(80) {|i| $rootTable[i] = 8; }
81.upto(99) {|i| $rootTable[i] = 9; }
def SqRoot(input, clarity)
val = input.to_s;
left, right = val.split('.');
right ||= "";
#get front values and begin answer
front = ((left.length % 2) == 0) ? left.slice!(0,2) : left.slice!(0,1);
ans = $rootTable[front.to_i].to_s;
#values for diving down with
top = front;
subtractor = ans.to_i * ans.to_i;
#go through above-decimal values
while(not left.empty?)
front = left.slice!(0,2);
top = ((top.to_i - subtractor).to_s + front).to_i;
searchon = ans.to_i * 20;
nextans = 9;
nextans -= 1 while(((searchon + nextans) * nextans) > top);
subtractor = ((searchon + nextans) * nextans);
ans += nextans.to_s;
end
#get front decimal values and continue answer
clarity.times {
front = if (right.empty?)
"00";
elsif (right.length == 1)
right.slice!(0,1) + "0";
else
right.slice!(0,2);
end
top = ((top.to_i - subtractor).to_s + front).to_i;
searchon = ans.to_i * 20;
nextans = 9;
nextans -= 1 while(((searchon + nextans) * nextans) > top);
subtractor = ((searchon + nextans) * nextans);
ans += nextans.to_s;
}
#put in decimal point and return
return (ans[0...-clarity] + "." + ans[-clarity,clarity]).to_f;
endWow, that's a cool way to introduce Ruby. Good job.
-- MikeNolan
I agree, this is a neat little hack. I could use something like this to check on used book prices on half.com, etc. -- AndrewKuehn
