
Beginning Python (2005)
.pdf
Answers to Exercises
Chapter 19
Exercise 1 solution
def format_bytes(bytes): units = (
(“GB”, 1024 ** 3), (“MB”, 1024 ** 2), (“KB”, 1024 ** 1), (“bytes”, 1),
)
terms = []
for name, scale in units:
if scale > bytes: continue
#Show how many of this unit. count = bytes // scale
terms.append(“%d %s” % (count, name))
#Compute the leftover bytes.
bytes = bytes % scale
# Construct the full output from the terms. return “ + “.join(terms)
Exercise 2 solution
def rgb_to_html(red, green, blue):
#Convert floats between zero and one to ints between 0 and 255. red = int(round(red * 255))
green = int(round(green * 255)) blue = int(round(blue * 255))
#Write out HTML color syntax.
return “#%02x%02x%02x” % (red, green, blue)
Exercise 3 solution
Solution using a list of numbers:
from math import sqrt
def normalize(numbers):
#Compute the sum of squares of the numbers. sum_of_squares = 0
for number in numbers: sum_of_squares += number * number
#Copy the list of numbers.
result = list(numbers)
# Scale each element in the list. scale = 1 / sqrt(sum_of_squares) for i in xrange(len(result)):
result[i] *= scale return result
601
TEAM LinG

Appendix A
This very concise numarray version works only when called with a numarray.array object. You can convert a different array type with numbers = numarray.array(numbers):
from math import sqrt import numarray
def normalize(numbers):
return numbers / sqrt(numarray.sum(numbers * numbers))
Chapter 21
Exercise 1 solution
Put the name of the wiki in the resource identifier, before the page name: Instead of “/PageName”, it would be “/Wikiname/PageName”. This is RESTful because it puts data in the resource identifier, keeping it transparent. Not surprising, this identifier scheme also corresponds to the way the wiki files would be stored on disk.
Exercise 2 solution
#!/usr/bin/python import cgi import cgitb import os
from WishListBargainFinder import BargainFinder, getWishList cgitb.enable()
SUBSCRIPTION_ID = ‘[Insert your subscription ID here.]’
SUBSCRIPTION_ID = ‘D8O1OTR10IMN7’
form = cgi.FieldStorage()
wishListID = form.getfirst(‘wishlist’, ‘’)
args = {‘title’ : ‘Amazon Wish List Bargain Finder’, ‘action’ : os.environ[‘SCRIPT_NAME’], ‘wishListID’ : wishListID}
print ‘Content-type: text/html\n’
print ‘’’<html><head><title>%(title)s</title></head> <form method=”get” action=”%(action)s”> <h1>%(title)s</h1>
Enter an Amazon wish list ID:
<input name=”wishlist” length=”13” maxlength=”13” value=”%(wishListID)s” /> <input type=”submit” value=”Find bargains”/>
</form>’’’ % args
if wishListID: print ‘<pre>’
BargainFinder().printBargains(getWishList(SUBSCRIPTION_ID, wishListID)) print ‘</pre>’
print ‘</body></html>’
602 |
TEAM LinG |

Answers to Exercises
Note that this points to an improvement in BargainFinder: creating a method that returns the bargain information in a data structure, which can be formatted in plaintext, HTML, or any other way, instead of just printing the plaintext of the bargains.
Exercise 3 solution
For REST: The BittyWiki web application already outputs rendered HTML because that’s what web browsers know how to parse. However, a BittyWiki page served by the web application includes navigation links and other elements besides just a rendering of the page text. If web service users aren’t happy scraping away that extraneous HTML to get to the actual page text, or if you want to save bandwidth by not sending that HTML in the first place, there are two other solutions. The first is to have web service clients provide the HTTP Accept header in GET requests to convey whether they want the “text/plain” or “text/html” flavor of the resource. The second is to provide different flavors of the same document through different resources. For instance, /bittywiki-rest.py/PageName.txt could provide the plaintext version of a page, and /bittywiki-rest.py/PageName.html could provide the rendered HTML version of the same page.
For XML-RPC and SOAP, the decision is simpler. Just have clients pass in an argument to getPage specifying which flavor of a page they want.
Exercise 4 solution
This could be fixed by changing the GET resource or getPage API call to return not only the raw text of the page, but a representation of which WikiWords on the page correspond to existing pages. This could be a list of WikiWords that have associated pages, or a dictionary that maps all of the page’s referenced WikiWords to True (if the word has an associated page) or False (if not). The advantage of the second solution is that it could save the robot side from having to keep its own definition of what constitutes a WikiWord.
Exercise 5 solution
Create a new API call specifically for renaming a page. In XML-RPC or SOAP, this would be as simple as creating a rename function and removing the delete function. For a REST API, you might add a capability to the POST request that creates a new wiki page: Instead of providing the data, let it name another page of the wiki to use as the data source, with the understanding that the other page will be deleted afterward.
Chapter 22
Exercise 1 solution
Many organizations have an investment in another programming language. Jython, though, enables you to use Python in a Java environment.
Exercise 2 solution
Jython is written in Java. The python interpreter is written in C.
603
TEAM LinG

Appendix A
Exercise 3 solution
You need to include your Jython scripts, of course, but also the following:
The jython.jar Java library
The Jython Lib directory
The Jython cachedir directory. This directory must be writeable.
Exercise 4 solution
No, unless the DB drivers are written in Python or Java. Most Python DB drivers are written in C and Python, and so cannot run from Jython (without a lot of work with the Java Native Interface, or JNI). Luckily, the Jython zxJDBC module enables you to call on any JDBC driver from your Jython scripts. This opens up your options to allow you to access more databases than those for which you can get Python DB drivers.
Exercise 5 solution
This is probably the simplest way to create such a window:
from javax.swing import JFrame
frame = JFrame(size=(500,100))
# Use a tuple for RGB color values. frame.background = 255,0,0
frame.setVisible(1)
You can get fancy and add widgets such as buttons and labels, if desired.
604 |
TEAM LinG |

B
Online Resources
Python is software available from the Internet, and Python’s best day-to-day resources can all be found there. This appendix describes the software that is used in this book and how to install it.
Most Python-related software can be downloaded for free, and much of it can be downloaded as source code and compiled — for those of you interested in doing that for yourself. For those readers who begin with the second part of the book, this may be the challenge you’re looking for.
However, the broader audience for this book will be glad to know that everything you need to follow along with the book’s examples can be installed as packages for the operating systems on which they are supported.
Software
The examples in this book require that your computer have additional software installed, as well as an appropriate and functioning operating system such as Windows 2000, XP, XP Pro, or 2003; Linux (Red Hat’s Fedora RC3 or newer; Debian testing or unstable; or a similarly current distribution); or Mac OS X 10.2 or newer.
Following is a brief list of the required software, with a description and the URL from which the software can be downloaded:
Python (www.python.org/) is the home page for the Python language. You can find out about all things Python there, including additional online tutorials, introductions to the language, and mailing lists to help you out. The people who write, maintain, change, and use Python are there. You can find a complete, if terse, set of documentation available there as well. The version of software used in this book is Python 2.4, and to download it you can click the Download link at the top of the Python home page, or go directly to www.python.org/download/. If you’re lucky, maybe you’ll find a more recent version of Python there that you can use! At the time of publication, Python 2.4.1 has been released.
For Windows, use the Windows .msi installer of the most recent Python 2.4 installations.
TEAM LinG

Appendix B
For Linux systems, install the package provided for your distribution by the maintainer of the distribution (for example, the .deb packages from debian.org or the .rpm packages from redhat.com, such as the information at www.python.org/2.4/). For other Linux distributions, see the home page for this book for comments from other readers that the authors will be compiling.
It’s important to understand that Apple has incorporated Python 2.3 into Mac OS X 10.3, so only Python 2.3 can be used there. The authors expect that this situation will change in the future. More information can be found at http://homepages.cwi.nl/~jack/macpython/ macpython-osx.html.
PythonCard: PythonCard is a lot more than just an editor, and when you are just beginning to start programming, one of the hardest things to do is get used to the language — how it looks, behaves, and works. Having a programmers’ editor that can take a lot of the fussy work out of your hands makes everything a lot faster and easier, and PythonCard comes with an editor called codeEditor that is very useful for a beginner, in addition to being very useful for more advanced users who can take advantage of how easy it makes the little tasks, such as running a program through a test cycle.
PythonCard can be found at http://pythoncard.sourceforge.net/, and it requires a package called wxWidgets on which it builds. It can be found at www.wxwidgets.org/. The version of PythonCard used when writing this book was version 0.8.1, although the developers are rapidly heading toward version 1.0.
For Windows 2000 and later, the installation instructions for PythonCard are described at http://pythoncard.sourceforge.net/windows_installation.html; however, that installation will work with the 2.4 version of Python (at the time of writing, the version of Python mentioned on the web site is 2.3.4).
For Linux distributions, you should install the PythonCard distribution that is appropriate to your distribution and provided with the distribution by following the instructions at http://pythoncard.sourceforge.net/linux_installation.html. The installation instructions for Mandrake Linux should also work for Red Hat’s Fedora Core distribution.
For Mac OS X, the installation instructions for Mac OS X 10.2 (Jaguar) are at http:// pythoncard.sourceforge.net/macosx_jaguar_installation.html; and for 10.3 (Panther), the slightly different instructions are at http://pythoncard.sourceforge.net/ macosx_installation.html.
The instructions for installing wxWidgets are described on the respective PythonCard installation pages.
Pygtk and pyglade: The GUI programming chapter in this book is written using the pygtk interface, which gives you access to the GTK+ graphical user interface toolkit from within Python, along with pyglade, which offers a simple mechanism to design the visual interface with pygtk.
Pygtk is cross-platform but was originally built for the X Window system, and now is available natively for Windows and Linux as well as being available on Mac OS X if the X Window libraries are installed.
The main web site for pygtk is www.pygtk.org/.
For a FAQ, which is also a rapidly updated wiki, for pygtk, and which also answers questions about pyglade, check out www.async.com.br/faq/pygtk/index.py?req=index.
606 |
TEAM LinG |

Online Resources
PyUnit: The unit testing framework for Python. This module provides a systematic way of writing tests within your own source code so that you can verify that your code works as you expect.
PyUnit’s home page is at http://pyunit.sourceforge.net/.
MySQL: A popular and fast open-source relational database system. Python has robust MySQL support:
www.mysql.com/ — This is the home page for mysql.com, the company that maintains the mysql database.
http://sourceforge.net/projects/mysql-python — This is the home page of the mysqlpython module, but there is a minimum amount of documentation online.
Wftk and PyWFTK: The Workflow toolkit. This toolkit allows for the construction of workflows and the enforcement of those workflows.
www.vivtek.com/wftk/ — The wftk home page. http://sourceforge.net/projects/wftk/ — The wftk download page. www.vivtek.com/wftk/doc/code/python/ — The home page for the PyWFTK module.
Jython: An implementation of the python language in pure Java, Jython provides access to all of the tools available in the commercial Java product space, but it enables you to program using Python as your language. Visit www.jython.org/.
For More Information
You can find a lot of Python-related information on the Internet. In addition, you can find information related to the specific components that appear in this book. As a result of the constantly changing nature of Python and its modules, please look at this book’s web page at www.wrox.com, and follow the instructions in the introduction to find the specific page for this book. That’s the place to go for help with installing software, to download samples and provide feedback to the authors, and to receive help with anything in the book. In addition, more packages and information about the ones that have been mentioned can be found online at the web site for this book.
607
TEAM LinG

TEAM LinG

C
What’s New in Python 2.4
Python is constantly changing in little ways. Python 2.4 has evolved from version 2.3, but it contains important changes. In this appendix, you’ll be introduced to the changes relevant to the topics covered in this book. This means that this is not an exhaustive treatment by any means but only a selection of topics touched on in the book — topics that you may want to know as someone new to Python.
The official list of changes to Python 2.4 can be found at www.python.org/doc/2.4/whatsnew/ whatsnew24.html. If a newer version of Python is available by the time you read this, the list of changes for that version can be found on the Python web site as well.
Negative Numbers
Numbers that are negative in Python prior to 2.4 would be represented differently when used in the wrong context. In the past, when unsigned numbers (numbers that are only supposed to be positive) were manipulated in such a way that they would otherwise have become negative, the language would instead change the number into a very large positive number. This “wrap” around to a high positive number is what many programmers expect to happen; however, as of Python 2.4, the number will silently be transformed into a signed number and be a normal negative number.
Automatic Promotion of Large Numbers
Prior to 2.4, some operations wouldn’t automatically convert an integer to a long when the integer was manipulated to become much larger. In Python 2.4, all operations on an integer that would have resulted in a overflow (a number larger than what the type can hold) will now always turn the integer into a long.
TEAM LinG

Appendix C
A Different String Substitution
As you learned in Chapter 9, there is a new format for creating Templates, which is a method for performing substitutions from elements within a dictionary into a string based on the key and value pairs that exist in the dictionary.
The syntax that was added was that when the string.Template or string.SafeTemplate classes are invoked with a format such as “$first $second $third”, a template object is returned that, when templateObject.substitute({‘first’: ‘Yes’, ‘second’:’No’, ‘third’:’Maybe’}) is invoked, the parts of the template that began with the dollar sign are replaced by the values in the dictionary whose key matches the template of the same name — just that the dollar sign is ignored when looking things up in the dictionary.
Looking at Sequences in Reverse
If you have a long sequence that you want to access in reverse, Python 2.4 has a built-in function called reverse.
In prior versions of Python, a loop or similar mechanism would have to be explicitly written to proceed from the end of a sequence to the beginning. Because it works on a special class of sequences called iterators, reverse works with xrange objects as well as lists and tuples.
reverse is the fastest way of going through something like a large sequence from back to front.
A More Pythonish Subprocess Creation
Chapter 9 looked at working with subprocesses at the same time that threads were first looked at. There are a few other system-specific ways of creating subprocesses. In version 2.4 a new module called subprocess was added that has just one class — Popen. Popen provides an interface that is more useful to experienced programmers because of the flexibility that it offers. In addition, for more experienced programmers, it offers a way to do things that are often difficult to get right, such as sending data to a child process or checking to see whether the process is done.
In addition, a shortcut that is considered “safer” than os.system has been provided. Called subprocess.call, it acts almost the same but eliminates the need to worry about the input you are sending to the subprocess. This is because os.system invokes the command shell, which can read text that you pass to it and be induced into misbehaving. Using subprocess.call, this issue can be avoided.
610 |
TEAM LinG |