RE: Help with a Python Program

  • From: BlueScale <bluescale1976@xxxxxxx>
  • To: programmingblind@xxxxxxxxxxxxx
  • Date: Mon, 06 Oct 2008 23:39:05 -0400

Hi,
Thanks for responding.  I actually just finished writing my own.  I
never did get that code shrunk down to size, so I visited the Yahoo
developer site and read through the documentation and code samples.  It
took a lot of trial and error, but I finally got it working!  I also
learned a little more about Python in the process.
If anyone else would like the code, here it is:
#change zipCode to your zip code
zipCode = 0
def getWeather(zip_code):
  if zip_code != 0:
    import urllib
    from xml.dom import minidom
    WEATHER_URL = 'http://xml.weather.yahoo.com/forecastrss?p=%s'
    WEATHER_NS = 'http://xml.weather.yahoo.com/ns/rss/1.0'
    url = WEATHER_URL % zip_code
    dom = minidom.parse(urllib.urlopen(url))
    ycondition = dom.getElementsByTagNameNS(WEATHER_NS, 'condition')[0]
    weatherReport = ycondition.getAttribute('temp') + ' | ' +
ycondition.getAttribute('text')
  else:
    weatherReport = "No zip code set."
  return weatherReport
print getWeather(zipCode)



On Mon, 2008-10-06 at 22:28 -0500, Ken Perry wrote:
>  
>  
> This is pretty easy to do.  Unfortunately I am extremely busy right
> this minute.  However if no one gets to you till Wednesday I will get
> to it.  
> Ken
>  
> 
> 
> 
> 
> ______________________________________________________________________
> From: programmingblind-bounce@xxxxxxxxxxxxx
> [mailto:programmingblind-bounce@xxxxxxxxxxxxx] On Behalf Of BlueScale
> Sent: Sunday, October 05, 2008 10:39 PM
> To: programmingblind@xxxxxxxxxxxxx
> Subject: Help with a Python Program
> 
> 
> 
> 
> Hi,
> I found this program to get the weather with a commandline program.  I
> want to modify it for use inside another program, but every time I do
> anything to it I end up breaking it.  I am still very new at Python.
> I would like it simplified quite a bit.  All I need is a variable set
> at the top with a 5 digit zipcode, so it is easy to modify.  I would
> like it to only return the current temp followed by the current
> condition.  For example, when ran it should return something like 78F
> | cloudy.  I need to remove the extended forecast and the commandline
> arguments.  Can someone please help with this and send me some info on
> how it was done? I thought it would be easy to do but apparently I was
> wrong. *grin*  It would be even better if the whole program could be
> simplified down to one function, but I am not sure that will be
> possible.
> Thanks for the help, and here is the code:
> #! /usr/bin/python
> 
> """
> Fetches weather reports from Yahoo!
> 
> Written by Thomas Upton (http://thomas.fiveuptons.com/),
> with contributions from Chris Lasher (http://igotgenes.blogspot.com/).
> 
> This code is licensed under a BY-NC-SA Creative Commons license.
> http://creativecommons.org/licenses/by-nc-sa/3.0/us/
> """
> 
> import sys
> import urllib
> from optparse import OptionParser
> from xml.dom.minidom import parse
> 
> # Yahoo!'s limit on the number of days they will forecast for
> DAYS_LIMIT = 2
> WEATHER_URL = 'http://xml.weather.yahoo.com/forecastrss?p=%s'
> WEATHER_NS = 'http://xml.weather.yahoo.com/ns/rss/1.0'
> 
> def get_weather(zip_code, days):
>   """
>   Fetches weather report from Yahoo!
> 
>   :Parameters:
>   -`zip_code`: A five digit US zip code.
>   -`days`: number of days to obtain forecasts for
> 
>   :Returns:
>   -`weather_data`: a dictionary of weather data
> 
>   """
> 
>   # Get the correct weather url.
>   url = WEATHER_URL % zip_code
> 
>   # Parse the XML feed.
>   dom = parse(urllib.urlopen(url))
> 
>   # Get the units of the current feed.
>   yunits = dom.getElementsByTagNameNS(WEATHER_NS, 'units')[0]
> 
>   # Get the location of the specified zip code.
>   ylocation = dom.getElementsByTagNameNS(WEATHER_NS, 'location')[0]
> 
>   # Get the currrent conditions.
>   ycondition = dom.getElementsByTagNameNS(WEATHER_NS, 'condition')[0]
> 
>   # Hold the forecast in a hash.
>   forecasts = []
> 
>   # Walk the DOM in order to find the forecast nodes.
>   for i, node in enumerate(
>           dom.getElementsByTagNameNS(WEATHER_NS,'forecast')):
>       # Stop if the number of obtained forecasts equals the number of
> requested days
>       if i + 1 > days:
>           break
>       else:
>           # Insert the forecast into the forcast dictionary.
>           forecasts.append (
>               {
>                   'date': node.getAttribute('date'),
>                   'low': node.getAttribute('low'),
>                   'high': node.getAttribute('high'),
>                   'condition': node.getAttribute('text')
>               }
>           )
> 
>   # Return a dictionary of the weather that we just parsed.
>   weather_data = {
>       'current_condition': ycondition.getAttribute('text'),
>       'current_temp': ycondition.getAttribute('temp'),
>       'forecasts': forecasts,
>       'units': yunits.getAttribute('temperature'),
>       'city': ylocation.getAttribute('city'),
>       'region': ylocation.getAttribute('region'),
>   }
>   
>   return weather_data
> 
> def create_report(weather_data, options):
>   """
>   Constructs a weather report as a string.
> 
>   :Parameters:
>   -`weather_data`: a dictionary of weather data
>   -`options`: options to determine output selections
> 
>   :Returns:
>   -`report_str`: a formatted string reporting weather
> 
>   """
> 
>   report = []
>   
>   if options.location:
>       if options.verbose:
>           # Add the location header.
>           report.append("Location:")
> 
>       # Add the location.
>       location_string = "%(city)s, %(region)s\n" % weather_data
>       report.append(location_string)
> 
>   if (not options.nocurr):
>       if options.verbose:
>           # Add current conditions header.
>           report.append("Current conditions:")
> 
>       # Add the current weather.
>       currstr = "%(current_temp)s%(units)s | %(current_condition)s \n"
> % weather_data
>       report.append(currstr)
> 
>   if (options.forecast > 0):
>     if options.verbose:
>         # Add the forecast header.
>         report.append("Forecast:")
> 
>     # Add the forecasts.
>     for forecast in weather_data['forecasts']:
>       
>         forecast['units'] = weather_data['units']
>       
>         forecast_str = """\
>   %(date)s
>     Low: %(low)s%(units)s
>     High: %(high)s%(units)s
>     Condition: %(condition)s
>   """ % forecast
> 
>         report.append(forecast_str)
> 
>   report_str = "\n".join(report)
>   
>   return report_str
> 
> def create_cli_parser():
>   """Creates a command line interface parser."""
> 
>   usage = (
>       "%prog [options] zip_code",
>       __doc__,
>       """\
> Arguments:
>   ZIPCODE: The ZIP code for the region of interest.
> """
>   )
>   
>   usage = "\n\n".join(usage)
>   
>   cli_parser = OptionParser(usage)
>   
>   # Add the CLI options
>   cli_parser.add_option('-c', '--nocurr', action='store_true',
>       help="Suppress reporting the current weather conditions"
>   )
>   
>   cli_parser.add_option('-f', '--forecast', action='store',
> type='int',
>       help="Show the forecast for DAYS days", metavar="DAYS")
>   
>   cli_parser.add_option('-l', '--location', action='store_true',
>       help="Give the location of the weather"
>   )
>   
>   cli_parser.add_option('-v', '--verbose', action='store_true',
>       help="Print the weather section headers"
>   )
>   
>   cli_parser.set_defaults(forecast=0)
> 
>   return cli_parser
> 
> def main(argv):
> 
>   # Create the command line parser.
>   cli_parser = create_cli_parser()
>   
>   # Get the options and arguments.
>   opts, args = cli_parser.parse_args(argv)
> 
>   # Check that an argument was passed.
>   if len(args) < 1:
>       cli_parser.error("Not enough arguments supplied.")
> 
>   # Check the zip code
>   zip_code = args[0]
>   
>   if len(zip_code) != 5 or not zip_code.isdigit():
>       cli_parser.error("ZIP code must be 5 digits")
>   
>   if opts.forecast > DAYS_LIMIT or opts.forecast < 0:
>      cli_parser.error("Days to forecast must be between 0 and %d" %
> DAYS_LIMIT)
> 
>   # Get the weather.
>   weather = get_weather(zip_code, opts.forecast)
> 
>   # Create the report.
>   report = create_report(weather, opts)
> 
>   print report
> 
> if __name__ == "__main__":
>   main(sys.argv[1:]) 

Other related posts: