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;
end

Wow, 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

RubyExamples (last edited 2008-07-09 05:48:02 by localhost)