Exercise 9.1

Objectives:

  • Using Python’s built-in Template strings to perform $variable substitutions in text.

Files Created: stockreport.py

Files Modified: None

Python is commonly used to write scripts that generate text such as reports, forms, or web pages.

Create a file stockreport.py that contains the following code:

# stockreport.py

import sys
import urllib
import csv

if len(sys.argv) != 2:
    print >>sys.stderr,'Usage: %s symbol' % sys.argv[0]
    raise SystemExit(1)

symbol = sys.argv[1]

u      = urllib.urlopen('http://finance.yahoo.com/d/quotes.csv?f=snl1d1t1c1p2ohgv&s='+symbol)
colnames = ['symbol','name','price','date','time','change','percent','open','high','low','volume']
stocks = csv.DictReader(u,colnames)

for s in stocks:
    print '<p>'
    print '<b>%s (%s)</b>' % (s['symbol'],s['name'])
    print '<font size=+2><b>%s</b></font>' % (s['price'])
    print '%s (%s)' % (s['change'],s['percent'])
    print '%s %s<br>' % (s['date'], s['time'])
    print '<table>'
    print '<tr>'
    print '<td>Open:</td><td>%s</td><td>Volume:</td><td>%s</td>' % (s['open'],s['volume'])
    print '</tr>'
    print '<tr>'
    print '<td>High:</td><td>%s</td><td>Low:</td><td>%s</td>' % (s['high'],s['low'])
    print '</table>'
    print '</p>'

This program is a command line tool that takes the name of a stock, performs a query, and produces a fragment of HTML with information about the stock. To run this, you need to run it at the terminal window, not IDLE. Try it out:

bash % python stockreport.py IBM
<p>
<b>IBM (International Bus)</b><br>
<font size=+2><b>126.02</b></font>
+2.56 (+2.07%)
7/7/2010 2:16pm<br>
<table>
<tr>
<td>Open:</td><td>123.89</td><td>Volume:</td><td>3852924</td>
</tr>
<tr>
<td>High:</td><td>126.38</td><td>Low:</td><td>123.47</td>
</table>
</p>
bash %

Now, observe how this program is already a horrible mess. Look at all of those print statements and the embedded HTML. What if you want to make a change to the output format? What if you wrote a 10000 line program entirely in this style? Would it be maintainable? Probably not.

(a) Using Template Strings

Modify the stockreport.py program above to produce its output using a template string instead of print statements. Specifically, define the output string as a template like this:

# stockreport.py
...
import string

output = string.Template("""
<p>
<b>$symbol ($name)</b><br>
<font size=+2><b>$price</b></font>
$change ($percent)
$date $time<br>
<table>
   <tr>
      <td>Open:</td><td>$open</td><td>Volume:</td><td>$volume</td>
   </tr>
   <tr>
      <td>High:</td><td>$high</td><td>Low:</td><td>$low</td>
   </tr>
</table>
</p>
""")

Have the program call output.substitute() with appropriate variables to produce the output.

(b) Using Template Files

In part (a), the program still has the output hardwired into the program. Modify the program so that the output template is read from a file stockreport_template.html instead.

Discussion:

The use of templates is widespread in web programming applications. For instance, PHP and Microsoft’s Active Server Pages (ASP) are based on a similar concept. Almost all of the web programming frameworks for Python (e.g., Django, Flask, web2py, etc.) also provide their own template engines.

Links