From: "Jesús Gabriel y Galán" Date: 2010-04-09T17:03:33+09:00 Subject: Re: read and write stock prices to file using arrays On Fri, Apr 9, 2010 at 2:34 AM, Peter Miller wrote: > I'm trying to write a script that will take stock ticker symbols from a > file, pull the company name and current price and write it back to the > file while ignoring comments and blank lines so as to leave the rest of > the file intact. > > I can get the stock prices etc. i'm after using the yahoofinance module > http://www.transparentech.com/opensource/yahoofinance > like so > > require 'rubygems' > require 'yahoofinance' > > quote_type = YahooFinance::StandardQuote > > # Set the symbols for which we want to retrieve quotes. > quote_symbols = ['yhoo','goog'] > > # Get the quotes from Yahoo! Finance.  The get_quotes method call > # returns a Hash containing one quote object of type "quote_type" for > # each symbol in "quote_symbols".  If a block is given, it will be > # called with the quote object (as in the example below). > YahooFinance.get_quotes( quote_type, quote_symbols ) do |qt| >  puts "QUOTING: #{qt.symbol}" >  puts "#{qt.name}" >  puts "#{qt.lastTrade}" > end > > I want to create an array of ticker symbols like quote_symbols above, > but from a file. > > here's a test data file i'm using > # this is the comment line > > # that was a blank, below is a stock > YHOO > GOOG # this comment can be deleted > > i would like the output to look like > # this is the comment line > > # that was a blank, below is a stock > YHOO:Yahoo! Inc.:17.35 > GOOG:Google Inc.:567.49 > > this is the code i'm having trouble with. > filename = ARGV[0] > > File.open(filename, 'r+') do |f| >  lines = f.readlines            # load array of lines >  lines.each do |line| >    next if line =~ /^#/         # skip comments >    next if line.chomp.empty?    # skip empty lines >    $ticker[lines] = line        #***the problem >    puts lines.index(line) >  end > end If you are just reading the lines you can do: lines = File.readlines(filename) Then: ticker = [] lines.each do |line| next if line =~ /^#/ # skip comments next if line.chomp.empty? # skip empty lines ticker << line end p ticker From your specs I think you are missing also the functionality of removing everything after a #. If a line can contain only a ticker symbol and optional things (after all a ticker symbol is just a word), you can do: ticker = [] lines.each do |line| next if line =~ /^#/ # skip comments next if line.chomp.empty? # skip empty lines ticker << line.split(" ")[0] # or maybe line[/\w+/] end > The other stumbling block for me is how to keep the results of YHOO -> > Yahoo! Inc. and the price 17.35 matched up with YHOO so i can put it > back on the same line. An idea would be to fill a hash with the data retrieved for each symbol: ticker_data = {} YahooFinance.get_quotes( quote_type, quote_symbols ) do |qt| puts "QUOTING: #{qt.symbol}" puts "#{qt.name}" puts "#{qt.lastTrade}" ticker_data[qt.symbol] = [qt.name, qt.lastTrade] end and then write to the file the data in ticker_data. I can see additional complexity if you want to keep the file exactly as it is (with the comments) but inserting the retrieved data in place. The easiest would be to just write ticker_data: File.open(filename, "w") do |file| ticker_data.each {|ticker, data| file.puts "#{ticker} #{data.join(" ")}"} end If you want to keep the same order of the symbols: File.open(filename, "w") do |file| ticker.each do |ticker| file.puts "#{ticker} #{ticker_data[ticker].join(" ")}"} end end Although this would remove the comments from the file. Jesus.