RE: Help with a Python Program

  • From: "Ken Perry" <whistler@xxxxxxxxxxxxx>
  • To: <programmingblind@xxxxxxxxxxxxx>
  • Date: Thu, 9 Oct 2008 21:13:53 -0500

 
I am re writing your example for another device so I wills end you the code
when I am done.  It will be partial code because I have to create it for
another kind of frame work but it will run on a PC when I send it.  
 
As to your import question.  The answer is it depends how often you run the
function and this page has an example of it and many other things just
search for import on this page its a few down.
 
 
http://www.szgti.bmf.hu/harp/python/fastpython.html
 
Ken


  _____  

From: programmingblind-bounce@xxxxxxxxxxxxx
[mailto:programmingblind-bounce@xxxxxxxxxxxxx] On Behalf Of BlueScale
Sent: Thursday, October 09, 2008 4:36 PM
To: programmingblind@xxxxxxxxxxxxx
Subject: RE: Help with a Python Program



        
Hi,
I haven't been able to get much info about sax.  I haven't searched very
much for it though.  I am in the midst of a project at the moment.  This
script is only part of the whole thing.  IF your offer still stands, would
you be willing to rewrite it for me with the sax info.  Please document for
a Python newbie.  This script is going to be redistributed, so include
whatever author info you want in it as well.  I always like to make code run
as fast as possible no matter what system it is running on, and it sounds
like sax would speed it up quite a bit.  Oh yeah, a quick question.  When
importing a library, if it is imported inside a function, is the import
forgotten outside the function?  Does this help with speed and/or freeing up
memory that isn't necessary in the rest of the script?
Thanks
On Thu, 2008-10-09 at 06:56 -0500, Ken Perry wrote: 

Yes but are they light weight enough for a small device that already ahs to
many libraries installed.  I am using the sax because it is on all devices
yes I have to do a bit of code writing but its worth it for the speed.  I
will have a look at the two libraries but I don't know about adding more
libraries for the device I am working on. 

Ken 


  _____  


From: programmingblind-bounce@xxxxxxxxxxxxx
[mailto:programmingblind-bounce@xxxxxxxxxxxxx] On Behalf Of Jim Dunleavy
Sent: Wednesday, October 08, 2008 11:17 AM
To: programmingblind@xxxxxxxxxxxxx
Subject: Re: Help with a Python Program





Hi, 

I use the BeautifulSoup library from www.crummy.com. 

The API is much more concise than calling those long-winded DOM 

functions. 

e.g. 

cond = tree.find('yweather:condition') 

result = '%s, %s' % (cond['temp'], cond['text']) 

Or if you want speed, check out the lxml package and xpath. 

--Jim 

----- Original Message ----- 

From: Ken Perry <mailto:whistler@xxxxxxxxxxxxx>  

To: programmingblind@xxxxxxxxxxxxx 

Sent: Wednesday, October 08, 2008 5:11 AM 

Subject: RE: Help with a Python Program 



Just a hint on this code you can speed it up  a heck of a lot if you get
away from dom and use sax or the simple template parser in python.  Its not
that important to speed up on a PC but I am currently coding on a PDA and
this runs a bit slow do to the interpreter and the dom. 

Ken 


  _____  


From: programmingblind-bounce@xxxxxxxxxxxxx
[mailto:programmingblind-bounce@xxxxxxxxxxxxx] On Behalf Of BlueScale
Sent: Monday, October 06, 2008 10:39 PM
To: programmingblind@xxxxxxxxxxxxx
Subject: RE: Help with a Python Program





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: