<--- On Feb 24, Ruby Quiz wrote --->

> by Caleb Tennis
>
> Write a Ruby program such that given a certain argument to the program it
> will return the current temperature of that location.  People living in
> the United States may be interested in temperature by ZIP code:
>
> 	$ ruby current_temp.rb 47201
> 	The temperature in Columbus, Indiana is 32 degrees F.
>
> Other locales may want to use their own mailing codes, or city names:
>
> 	$ ruby current_temp.rb madrid
> 	The temperature in Madrid, Spain is 12 degrees C.
>
> Which arguments you support is up to you.

This quiz finally got me going to read Ruby's Net API. It turned out 
to be very pleasing. Here is my solution.

I use the wunderground website to get the weather. The program 
supports all kinds of search arguments that are supported by 
wundergroud. I pass on the input arguments to wu website. If a city is 
found, the search results contain a link to rss feed. Instead of 
parsing the html document, I get this rss feed and parse it. This 
method fails sometimes, for small cities outside US.

Here is the code

# Examples:
#   $ current_temp.rb 48105
#   > The temperature in Ann Arbor, MI is 34 degrees F / 1 degrees C
#
#   $ current_temp.rb Ann Arbor, MI
#   > The temperature in Ann Arbor, MI is 34 degrees F / 1 degrees C
#
#   $ current_temp DTW
#   > The temperature in Detroit Metro Wayne County, MI is 36 degrees F / 2 degrees C
#
#   $ current_temp New Delhi, India
#   > The temperature in New Delhi, India is 77 degrees F / 25 degrees C
#
#   $ current_temp DEL
#   > The temperature in New Delhi, India is 77 degrees F / 25 degrees C
#

#--------------------------------------%<--------------------------------------
require 'net/http'
require 'uri'
require 'rexml/document'

if ARGV.length == 0
   puts "Usage: ruby current_temp.rb [city, state | zipcode | city, 
country | airport code]"
   exit
end
urlbase = 
"http://www.wunderground.com/cgi-bin/findweather/getForecast?query="
zipcode = ARGV.join('%20')

# Search for the zipcode on wunderground website
response = Net::HTTP.get_response URI.parse(urlbase << zipcode)

# Parse the result for the link to a rss feed
rss_feed = String.new
# Get the line with rss feed
response.body.each do |line|
   if line.include?("application/rss+xml") then
     stop_pos  = line.rindex('"') - 1
     start_pos = line.rindex('"',stop_pos) + 1
     rss_feed  = line.slice(start_pos..stop_pos)
     break
   end
end
# Get the feed and parse it for city and weather information
# The response is different for US cities and places outside US.
# Use appropritate regular expression to parse both simultaneously
if rss_feed == "" then
   puts ARGV.join(' ') << ": No such city"
else
   feed     = Net::HTTP.get_response(URI.parse(rss_feed))
   document = REXML::Document.new feed.body
   title    = document.elements.to_a("//title")[0].text
   channel  = 
document.elements.to_a("//channel/item/description")[0].text
   city     = title.gsub(/\s*(Weather from)?\s*Weather 
Underground\s*(-)?\s*/,"")
   temp     = channel.gsub(/(^Temperature:|\|.*$|\W)/,"")
   temp     = temp.gsub("F", " degrees F / ").gsub("C", " degrees C")
# For exact format as asked in the quiz, uncomment the following
# temp     = temp.gsub("F.*$", "F")
   puts "The temperature in #{city} is #{temp}"
end
#--------------------------------------%<--------------------------------------


Thanks for the nice quiz.

Aditya



-- 
Aditya Mahajan, EECS Systems, University of Michigan
http://www.eecs.umich.edu/~adityam || Ph: 7342624008