On Aug 5, 2005, at 11:30 AM, Ruby Quiz wrote:
> This week's Ruby Quiz is to build this simple tool.
Here's the code used to create the quiz:
#!/usr/local/bin/ruby
require "yaml"
require "soap/rpc/driver"
server = SOAP::RPC::Driver.new( "http://services.xmethods.com/soap",
"urn:xmethods-delayed-quotes" )
server.add_method( "getQuote", "symbol" )
Struct.new("Shares", :symbol, :shares, :price, :date)
file_name = File.join(ENV["HOME"], ".portfolio.yaml")
portfolio = if File.exist? file_name
File.open(file_name) { |file| YAML.load(file) }
else
Hash.new
end
if portfolio.empty? or not ARGV.empty? and ARGV.first == "-p"
loop do
print "Buy (symbol shares/dollars): "
line = $stdin.gets.strip
break if line.empty?
ticker, amount = line.split
price = server.getQuote(ticker)
if price <= 0
puts "Unable to fetch a price for that ticker symbol."
next
end
if amount =~ /^\$(\d+)$/
dollars = Integer($1)
shares = (dollars / price).to_i
elsif amount =~ /^[1-9]\d*$/
shares = Integer(amount)
else
puts "Unknown amount format."
next
end
if shares.zero?
puts "You can't purchase any shares for that amount."
next
else
date = Time.now.strftime("%m/%d/%y %H:%M")
buy = Struct::Shares.new(ticker, shares, price, date)
portfolio[buy.symbol] = buy
puts "You purchased #{buy.shares} shares of #
{buy.symbol} " +
"for $#{"%.2f" % (buy.shares * price)}."
end
end
File.open(file_name, "w") { |file| YAML.dump(portfolio, file) }
end
output = [%w{Symbol Shares Buy\ Price Buy\ Date Current\ Price Gain/
Loss}]
portfolio.each do |ticker, details|
current = server.getQuote(ticker)
output << [ ticker, details.shares, details.price, details.date,
current,
details.shares * current - details.shares *
details.price ]
end
widths = Array.new(output.first.size, 0)
output.each do |row|
row.each_index do |index|
width = if row[index].is_a? Float
("%.2f" % row[index]).length + 1
else
row[index].to_s.length
end
widths[index] = width if width > widths[index]
end
end
border = "+-" + widths.map { |width| "-" * width }.join("-+-") + "-+"
template = ("| " + output.last.map do |column|
case column
when Float
"$%#{widths.shift - 1}.2f"
when Integer
"%#{widths.shift}d"
else
"%#{widths.shift}s"
end
end.join(" | ") + " |").sub(/\A\| %/, "| %-")
puts border
puts template.gsub(/ \| \$?%(\d+)(?:\.\d+)?[sdf]/, " | %\\1s") %
output.first
output[1..-1].sort.each do |row|
puts border
puts template % row
end
puts border
__END__
James Edward Gray II