Python Excursions

From IPRE Wiki
Jump to: navigation, search

Deepak's Python Excursions

Here, I will document and show off some of the cool (at least to me) features and excursions you can make into Python. Most of them will be examples that can be used in CS1/CS2 level courses. Examples that get lots of endorsements and/or pass the text of time will ultimately make it into our text(s) under development. Feel free to beg, borrow, steal, modify, comments, etc. This is supposed to be pure fun for beginners (keep that in mind, please).

Python built-in enumerate(<sequence>)

You might often find yourself writing the following code:

for i in range(len(someList)):
   # do something on i and someList[i]

Well, enumerate(someList) will come in handy here. enumerate returns an iterator object. To understand it is easy. First, let us see what it does:

>>> someList = ['a', 'b', 'c']
>>> list(enumerate(someList))
[(0, 'a'), (1, 'b'), (2, 'c')]

That is, it pairs each item in the list with its index position in the list. Since it is an iterator, you can use the following:

for i, item in enumerate(someList):
    # do something on i and item

Simple, neat and elegant.

Basic Geocoding in Python

Geocoding refers to finding geographic coordinates (like, latitude and longitude) of a given geographical location. The location could be identified by a name (as in Jim Thorpe, PA), an address (as in 1600 Pennsylvania Ave. NW, Washington, DC 20500), etc. This is normally the first thing you would do to create your own map mashups (as in Google/Yahoo Map Mashups). Given a location on a map, you will need its lat-long data to tag the place on a map (this is also called geotagging). Google Maps API has a simple geocodiong service that you can use in your own Python programs to access lat-long coordinates for almost any location. For this, you will need to install the Python package geopy (see below on how to find and install Python packages). Once installed, here is how you can obtain the coordinates:

First import the geocoders resource:

>>> from geopy import geocoders

Next, create a geocoder client:

g = geocoders.Google(resource='maps')

Next, try a location:

g.geocode("Jim Thorpe, PA")
Fetching http://maps.google.com/maps?q=Jim+Thorpe%2C+PA&output=kml...
(u'Jim Thorpe, PA', (40.887456999999998, -75.743325999999996))

or

>>> place, (latitude, longitude)  = g.geocode("1600 Pennsylvania Ave. NW, Washington, DC 20500")
Fetching http://maps.google.com/maps?q=1600+Pennsylvania+Ave.+NW%2C+Washington%2C+DC+20500&output=kml...
>>> print place, latitude, longitude
1600 Pennsylvania Ave NW, Washington, DC 20006 38.898632 -77.036541

Some documentation on geopy suggests that you may need a key to create your client, as in:

g = geocoders.Google('YOUR API KEY')

However, I have found that you do not need this for simple geocoding (as shown in the example above). geopy has facilities to do much more. For example, you can use the Yahoo Maps API instead of Google using geocoders.Yahoo('...'). I may return to this later.

Finding and Installing Python Packages (Easy Install)

Pyhton's versatility is powered by the proliferation of all kinds of useful packages people have developed (geopy being one example). For example, if you wanted to find and install the geopy package, you can use easy_install as follows:

% easy_install geopy

The script will go out and look for the latest source distribution of geopy, retreive the correct version for your OS and config and then install it in the right place. There are many variations on how you can use easy_install (you can install an already downloaded package or specify location(s) to go find something, etc.

So, how do you install easy_install itself??? :-)

Just a little legwork is needed. The setuptools package is distributed here. Follow the simple instructions to download and install all the scripts and set up the paths and you're all set.

Election 2008 Special: Plotting State Tracking Polls

Yes, this example shows how you can plot real time (i.e. most up to date poll data available) poll data for any given state. The data obtained is from www.electoral-vote.com. This particular version (see code for URL) retrieves state poll data for the year (since January 2008) and plots it for Obama (blue line) and McCain (red line).

import urllib
from myro import *
import calendar as cal

# Access the web data resource
#f = urllib.urlopen("http://www.electoral-vote.com/evp2008/Pres/Excel/today.csv")
f = urllib.urlopen("http://www.electoral-vote.com/evp2008/Pres/pres_polls.raw")
# read the raw data from it
rawdata = f.read()

# have fun with it

# First split each line
data = rawdata.split("\n")

# Enter the state you wish to track
state = ask("Enter the state code...")

# For now assume state entered is legit
# Extract poll data for the state
statedata = [line for line in data if line[0:2] == state]
##statedata = []
##for line in data:
##    if line[0:2] == state:
##        statedata.append(line)
##        print line
print statedata

# Poll data is most recent first...
statedata.reverse()
# Now plot data...
# The graph window...
w = GraphWin(state+"Tracking Poll", 500, 500)
w.setBackground("white")
# The coordinate system (xLL, yLL, xUR, YUR)
w.setCoords(-10, -10, 366, 100)
yaxis = Line(Point(0, 0), Point(0, 100))
yaxis.draw(w)
xaxis = Line(Point(0, 0), Point(500, 0))
xaxis.draw(w)
for m in range(12):
    d = cal.dayOfYear(m+1, 1, 2008)
    dash = Line(Point(d, -2), Point(d, 2))
    dash.draw(w)

# create plot data
plotdata = []
for polldata in statedata:
    state, Obama, McCain, Other, startMonth, startDay, endMonth, endDay = polldata.split()[0:8]
    day = cal.dayOfYear(cal.monthNum(endMonth), int(endDay), 2008)
    plotdata.append((day, int(Obama), int(McCain)))

# Finally plot the two curves
for i in range(1, len(plotdata)):
    print "plotting...", plotdata[i]
    day1, Obama1, McCain1 = plotdata[i-1]
    day2, Obama2, McCain2 = plotdata[i]
    L1 = Line(Point(day1, Obama1), Point(day2, Obama2))
    L1.setOutline("blue")
    L2 = Line(Point(day1, McCain1), Point(day2, McCain2))
    L2.setOutline("red")
    L1.draw(w)
    L2.draw(w)
print "Done"

I am working on a version that uses matplotlib package (use easy_install to find it) to plot th data and create a web loadable image...