2—
Python Language Review

This book isn't a Python tutorial. We feel that Python is a straightforward language, and if you have any programming experience, you should be able to follow the examples in the book and understand them. For readers new to Python, this chapter provides a brief introduction; others can safely skip it.

A Crash Course

Python offers an interactive mode that lets you evaluate an expression at a time. This is an excellent way to learn the language. We will step rapidly through the main features of the language in interactive mode. We won't provide detailed explanations, since most features are remarkably clear and obvious anyway.

Either go to an MS-DOS prompt, or (if you've already installed it) start PythonWin. You should see something like this:

Pythonwin 1.5.2b2 (#0, Feb 16 1999, 17:09:09) [MSC 32 bit (Intel)] on win32
Copyright 1991�1995 Stichting Mathematisch Centrum, Amsterdam
Portions Copyright 1994�1998 Mark Hammond ([email protected])
>>>

You can type in simple expressions, which are evaluated for you:

>>> 2+2
4

Numbers, Strings, and Variables

You can assign to variables with =. There is no separate declaration required before you assign a variable:

>>> x=3
>>> x

3
>>> y=x*2
>>> y
6
>>>

Python supports all standard arithmetic operators. Note that the division operator ( /) yields different results on integer and floating-point types:

>>> 22 / 7
3
>>> 22.0 / 7.0
3.14285714286
>>>

Scientists and mathematicians will be pleased to hear that complex numbers are fully supported using the letter j:

>>> (3 + 1j) * (3 - 1j)
(10+0j)
>>>

Strings can be wrapped in either double or single quotes. They can be concatenated with the + operator and repeated with the * operator. You can also access individual characters by their position:

>>> greeting = 'hello'
>>> epithet = 'stranger'
>>> greeting + ", " + epithet
'hello, stranger'
>>> "spam" * 10
'spamspamspamspamspamspamspamspamspamspam'
>>>

Lists and Tuples

Much of Python's power comes from its support for lists and its compact syntax for manipulating them. Lists are wrapped in square brackets and can contain any Python objects. You can also insert and delete items in a list and even use negative positions to access the end of the list without knowing its length:

>>> mylunch = ['spam', 'eggs', 'guinness', 'raspberries', 'wafer-thin mint']
>>> mylunch[0]
'spam'
>>> mylunch[1:3], mylunch[-1]
(['eggs', 'guinness'], 'wafer-thin mint')
>>>

When you enter two results separated by a comma on the same line, you get two expressions, but enclosed in parentheses. Parentheses indicate a tuple, which is similar to a list but can't be modified once created:

>>> mylunch[2] = 'tea'
>>> mylunch

['spam', 'eggs', 'tea', 'raspberries', 'wafer-thin mint']
>>> meal_deal = ('burger', 'fries', 'coke')   # a tuple
>>> meal_deal[1] = 'onion rings'
Traceback (innermost last):
  File "<interactive input>", line 1, in ?
TypeError: object doesn't support item assignment
>>>

The last example also shows our first error message. When errors occur, you see a traceback stating which functions were active and the line of the source file that caused the error, as well as the error type and message on the last line. In this case, you type commands interactively rather than running a source file, so you don't see a helpful filename or line number.

Control Structures

The for loop actually operates over lists, not numbers:

>>> for item in mylunch:
�     print item

spam
eggs
tea
raspberries
wafer-thin mint
>>>

There are several things to note at this point. First, after typing the colon and pressing the Return key, Python indents the next line, and you don't have to type anything to end the for loop. Python actually uses indentation for syntax, saving typing and making the language highly readable: the layout of code on the page indicates its structure. A second point is that the >>> prompt changes to � for subsequent lines. This indicates that Python knows you are entering a multiline statement at the command prompt.

Another common structure is the while loop:

>>> x = 2
>>> while x < 50:
�     x = x * 2
�     print x

4
8
16
32
64
>>>

The if structure is also present; the else clause is optional:

>>> if 'chocolate' in mylunch:
�     print "that's not allowed"
� else:
�     print "enjoy your meal"

enjoy your meal
>>>

You can also have a number of intermediate elif clauses, short for else-if. These allow something like the switch or case statements in other languages:

>>> salary = 20000
>>> if salary < 4000:
�     tax_rate = 0
� elif salary < 29000:
�     tax_rate = 0.25
� elif salary < 100000:
�     tax_rate = 0.4
� else:
�     emigrate()     # that's a function call

>>>

Functions

Functions are defined by the def statement and use return to exit immediately from the function and return a value. You can return more than one value by using a tuple or return no value at all:

>>> def double(x):
�     return x * 2

>>> double(2
4
>>> def first_and_last(aList):
�     return (aList[0], aList[-1])

>>> first_and_last(range(5))
(0, 4)
>>> def sayHello():
�     print 'hello'

>>> sayHello(0
hello
>>>

Functions may have default arguments that allow them to be called in certain ways or allow you to initialize variables:

>>> def makeCoffee(size, milk=None, sugar=None):
�     order = 'one ' + Size + ' Coffee'
�     if milk and sugar:

�         order = order + ' with milk and sugar'
�     elif milk:
�         order = order + ' with milk'
�     elif sugar:
�         order = order + ' with sugar'
�     else:
�         pass  # pass means 'do nothing'
�     return order

>>> makeCoffee('large')
'one large coffee'
>>> makeCoffee('large', 1)
'one large coffee with milk'
>>> makeCoffee('large', milk=0, sugar=1)
'one large coffee with sugar'
>>>

Note that you can name the arguments and that both 0 and the special variable None are treated as false.

Dictionaries

Python also offers a dictionary type. This is based on a hash table, and the lookup time is almost constant, irrespective of size. Dictionaries are enclosed in braces ({}), and the keys and values are displayed separated by a colon. You can access and set their elements with a notation similar to list indexes:

>>> fur_colors = {}
>>> fur_colors['Tinky-Winky'] = 'purple'
>>> fur_colors['Dipsy'] = 'green'
>>> fur_colors['LaLa'] = 'yellow'
>>> fur_colors
{'Tinky-Winky': 'purple', 'Dipsy': 'green', 'LaLa': 'yellow'}
>>> fur_colors['LaLa']
'yellow'
>>>

Dictionaries have no natural order. They support some useful methods of searching, e.g., by keys, values, and whether or not a certain key is present:

>>> fur_colors.keys()
['Tinky-Winky', 'Dipsy', 'LaLa']
>>> fur_colors.values()
['purple', 'green', 'yellow']
>>> fur_colors.items()    # converts to a list of tuples
[('Tinky-Winky', 'purple'), ('Dipsy', 'green'), ('LaLa', 'yellow')]
>>> len(fur_colors)
3
>>> fur_colors.has_key('Po')
0
>>>

Lists and dictionaries together allow you to build more powerful data structures, such as sets or even database indexes, in few lines of code. The values in a dictionary can be anything, while the keys can be strings, numbers, or tuples of other values. In Chapter 6, A Financial Modeling Toolkit in Python, we show how to construct some extremely useful utilities from dictionaries.

Modules

Python code is organized into modules. A module must be loaded into memory using the import statement. Some modules are built into Python and always available; others are stored in external files. Modules can also be written either in C (in which case they are compiled as a special kind of DLL) or in Python (in which case they are saved in text files ending in .py). As far as the user is concerned, they are all used the same way:

>>> import math
>>> math.sin(math.pi/2)
1.0
>>>

We used both a function and a constant from the math module. Note that the module's name must be prefixed. This prevents namespace collisions: imagine how many different programs might wish to define a function called read() or save(). It's also possible to import a function explicitly into the present namespace:

>>> from string import split, join
>>> split ('We are the knights who say Ni')
['We', 'are', 'the', 'knights', 'who', 'say', 'Ni']
>>>

This procedure can be used for brevity but increases the risk of a collision, and, more important, of losing track of what your code means a few months later. It should be used sparingly.

Classes

Python makes object-oriented programming easy. The class statement begins the definition of a class. Classes can use a special constructor called __init__() to initialize their data. Because Python doesn't declare variables, this constructor is a common place to initialize any variables the class may require:

>>> class Car:
�    def __init__(self) :
�         self.milespergallon = 25.0
�         self.travelled = 0
�         self.color = 'blue'
�         self.gas = 20

�     def drive(self, miles):
�         self.travelled = self.travelled + miles
�         self.gas = self.gas - (miles / self.milespergallon)

>>> C = Car()
>>> C.drive(100)
>>> C.travelled
100
>>> C.gas
16.0
>>>

Note that you have to use the keyword self each time you access an attribute.

As with other languages, classes may inherit from a base class and be initialized with arguments supplied by the constructor. We won't give any further examples at this point; you can see many classes throughout this book, and the syntax is self-evident if you are used to object-oriented programming.

Exception Handling

When errors occur, Python throws an exception and prints an informative traceback to standard output. If the error occurred in a source file and not a console session, you get the filename and line number. Here's a simple error, nested three functions deep, and its traceback:

>>> def func1(arg) :
�     func2(arg)

>>> def func2(arg) :
�     func3(arg)

>>> def func3(arg) :
�     # this should cause an error
�     return arg / 0

>>> func1(17)
Traceback (innermost last):
  File "<interactive input>", line 0, in ?
  File "<interactive input>", line 2, in func1
  File "<interactive input>", line 2, in func2
  File "<interactive input>", line 3, in func3
ZeroDivisionError: integer division or modulo
>>>

The traceback tells us where the error happened and the enclosing functions that called the functions that caused the error.

Exceptions can be handled using the try�except and try�finally structure. If you aren't used to exception handling, these offer two benefits over Visual Basic-style error-handling. First, you can write a decent-sized chunk of code and put the error handlers at the end; the intent of the programmer is clearer than with a lot of on error goto and on error resume next statements. Second, exception handlers don't work on just the present chunk of code, but also on any subroutines within it, however deeply nested.

The except clause can optionally specify particular error types to look for or handle all errors:

>>> try:
�    y_scale_factor = plotHeight / (dataMax - dataMin)
� except ZeroDivisionError:
�    y_scale_factor = 0

>>>

The try�finally clause always executes the finally section whether an error occurs or not. This ensures that resources such as files are freed up:

>>> f = open('somefile.dat', 'wb')
>>> try:
�     #fetch some data
�     #store it in the file
� finally:
�     f.close()  # make sure the file is closed,
�                # even if errors occurred

>>>

Conclusion

This concludes our brief introduction. We have left out many features, but hopefully have given you a feel for how straightforward Python is.

We urge you to look at the Python tutorial or one of the books noted in the next section, but if you want to survey what Python can do, you should now be able to follow the code examples in the next few chapters.

References

Python comes with a comprehensive tutorial in HTML format written by Guido van Rossum. This can be completed in two to three hours and is worth reading at this point. If you've installed Python, the master documentation index can be found on your hard disk at C:\Program Files\Python\Doc\index.html. We also recommend O'Reilly's books Learning Python by Mark Lutz and David Ascher and Programming Python by Mark Lutz.


Back