A quick and dirty guide to getting started in python

Posted by David on Jun 4th, 2003

Introduction

Just as Tcl has more uses than getting Pysol to run, so does Python. Python is a high-level, interpreted, object-oriented programming language, and is useful for all manner of tasks, from simple, everyday tasks, to large-scale applications (like Pysol). Python is also commonly used as a glue language to combine assorted unrelated software packages into mighty juggernauts of computation, helped by its large number of available extensions and a simple C language API that can be used to write new modules.

Python began in 1990 at the Centrum voor Wiskunde en Informatica in Amsterdam. Guido van Rossum, the creator, wanted a better means of system administration for the Amoeba distributed operating system, and he decided to write a portable, extensible scripting language. Python can now be run on a multitude of operating systems, including Linux, Windows, MacOS, QNX, and OS/400. There is also Jython, a python interpreter written in Java, in case Sun Microsystems got around to your operating system before the Python people did.

Running Python

The three usual ways to invoke Python are by typing python at the command line, which will start a read-eval-print loop; by giving python a filename to run, as in python runme.py; or by making a script executable. It’s difficult to predict where python will be installed on any particular site, but env is almost always in the same place, so it is common to use env to execute python in scripts.

#!/usr/bin/env python
code goes here
.
.
.

As with many interpreted languages, the octothorp (#) also begins a comment. The comment can begin anywhere in a line and continues to the end of the line. Comments are not held to the indentation rules of blocks, so leading whitespace won’t kill the program.

Variables

Variables in python are created by assigning a value to a name. The variable is then referenced simply by using this name. To demonstrate, the universal program:

Hello = "Hello"
world='world'
print Hello + ", " + world + "!"

This, of course, prints the string “Hello, world!” to standard output. It also reveals a few more details of Python. First of all, I switched between double quotes (”) and single quotes (’) for the string literals. Either form is equivalent, though there are also some other ways to specify strings. More on that later.

Secondly, the strings in the print statement are concatenated with the ‘+’ operator. Each of the arguments is a string, and the end result is a single string that is passed to the print command. Strings in Python are immutable, so each time strings are concatenated, a new string is created. Other variable types, such as numbers, cannot be concatenated to strings without converting them first; Python does not convert them for you. So the following piece of code,

number=12
print "Your number is " + number

would fail. Something like

print "Your number is " + str(number)

would be necessary, instead. The print command itself, however, is somewhat more charitable, and will print out pretty much anything you hand to it. print can also be given more than item, separated by commas, and it will concatenate them in the output, separating each with a space. So, the above example could also be written as

print "Your number is", number

Numbers

Python, like any decent programming language, can do math. Python defines three types of real numbers: int, which is implemented using C’s long (at least 32 bits); long, which is an infinite precision integer; and float, which is a floating point number implemented using C’s double type. long literals can be specified by placing a ‘L’ character at the end of a number, and float literals can be specified by including any decimal portion.

Numbers can be added, subtracted, multiplied, and divided pretty much as one would expect. One possible point of confusion is integer division, which returns the floor of the result (truncate toward negative infinity) instead of C’s truncate toward 0. So 7 / 2 would result in 3, while 7 / -2 is -4. 7.0 / 2 would result in 3.5.

The exponent of a number can be found either C-style (pow(mantissa,exponent)) or FORTRAN-style (mantissa ** exponent).

Python also supports complex numbers. These can be specified either by (real + imaginaryJ), or complex(real,imaginary). The real portion is accessible as variable.real, and the imaginary as variable.imag.

Sequences

Some of Python’s greatest power is contained in the sequence types. The most general sequence type is the list.

A list, syntactically, is a bunch of variables enclosed in square brackets. ['asdf', 12, []] is a three element list, where the first element is a string, the second element is an int, and the third element is another list, which happens to be empty. List indices start from 0.

listdemo=['asdf', 12, []]
listdemo[1] += 4
print listdemo

['asdf', 16, []]

The += operator is the same sort of arithmetic assignment shorthand found in C and other languages.

Useful list operations include ‘+’ to concatenate two lists, len(list) to find the number of elements in a list, list.append(item) to add an item to the end of a list, and list.sort() which reorders the items in the list from lowest to highest. A highest to lowest sort can be achieved by using list.reverse() after sorting. (Note: these need to be two separate statements, since sort() does not return the list, so list.sort().reverse() would create an error)

In addition to single element access, entire sections of a list can be accessed as a sublist, called a slice.

print listdemo[0:2]

['asdf',12]

The slice is a list of all the elements between the two indices, starting with the first and ending at, but not including, the last. Either index may be omitted, meaning to go from the beginning, or until the end, with list[:] being the entire list.

Negative indices may also be given, which are interpreted as a number of elements counted from the opposite end of a list. So list[-2:] would be the last two elements in a list, and list[:-1] would be every element in a list except the last.

Slices may also be used in assignments to add and replace portions of a list.

slicedemo=['one', 'two', 'three', 'four']
print slicedemo[2:]

['three','four']

slicedemo[2:]=['five']  # value replacing slice must be a list
print slicedemo

['one','two','five']

# zero-length slice, inserts at 1
slicedemo[1:1]=['twelve', 'forty-seven']
print slicedemo

['one', 'twelve', 'forty-seven', 'two', 'five']

Strings

Strings are another sequence type, so everything that would work for a list works for a string, except for assignment, since strings are immutable. C-style escape sequences can be included in strings, such as \n or \t. A string can be broken across several lines by placing a \ at the end of the line.

A “raw” string can be specified by using a “r” character before the opening quote. In raw strings, newlines are included in the string itself.

demostring = r"This string is more\
than one line"

is equivalent to

demostring = "This string is more\\\nthan one line"

Multiline strings can also be created with triple quotes (”"” or ”’), in which backslash sequences are allowed, as well as newlines.

Strings only use 7-bit ASCII characters. For 8-bit data, use Unicode strings (u"string").

Tuples

Tuples are another immutable sequence type, but can hold anything. Tuples are specified like lists, but using parenthesis instead of square brackets. An exception is the one-item tuple, which is specified as (item,).

Dictionaries

The dictionary type is an associative array of keys to values. The key may be any immutable value (strings, numbers, or tuples if the tuple contains no mutable items). Dictionaries are specified as lists of key:value pairs enclosed in curly braces.

dictionary={'key1': 'item1', 'key21': 'item2'}
print dictionary['key1']

'item1'

print dictionary.keys()

['key2', 'key1']

print dictionary.values()

['item2', 'item1']

print dictionary.items()

[('key2', 'item2'), ('key1', 'item1')]

As this example demonstrated, dictionaries are unsorted. To get around this, use the sort() method on either the keys or the values. Items can be added to a dictionary simply by assigning to a new key. Items can be removed by using the del command on the value. del can be used on any variable and unbinds that variable from the namespace.

del dictionary['first']
print dictionary.keys()

['second']

Control Structures

Python also allows you to execute code conditionally, or over and over and over again.

if i > 13:
    print 'i is large!'
elif i == 13:
    print 'i is 13'
else:
    print 'i is small'
    i -= 10
    print '...and now is even smaller'

You may notice that the only thing separating the if/else statements from the code they execute is the indentation. In Python, indentation defines blocks. It doesn’t matter whether you use spaces or tabs, or how much whitespace you use, just as long as inner blocks consist of whatever the outer block had plus some more whitespace of its own.

Every value in Python is considered true, except for the number 0 (or 0L, or 0,0), empty sequences (”, (), or []), empty mappings ({}), or the special value None. The keyword False is also defined, and is equal to the number 0.

Python offers the <, <=, >, >=, ==, and != operators to compare numbers and sequences, as well item in list and item not in list to test the presence or absence of a value in a sequence, and item in dictionary and item not in dictionary to test whether a dictionary contains a certain key. Any value can be negated with the not keyword, and other possibilities of boolean combinations are available with and and or. Parenthesis can be used to group values.

Boolean combinations only execute the second expression if truth or falsity cannot be determined from the first expression, similar to C, Java, and many other programming languages.

if ('sixty-three' in dictionary) and not fakefunctionname(dictionary):
    print 'Fake function failed'

This would only execute fakefunctionname if the key ’sixty-three’ exists in dictionary, which is important if fakefunctionname creates any side-effects.

Iteration over a sequence can be done with a for loop. The syntax is similar to that used by the Bourne shell.

newlist=[]
for item in oldlist:
    # each element is oldlist is assigned to the variable "item"
    # make a list out of item and concatenate with newlist
    newlist = [item] + newlist

This would place the items in oldlist into newlist, in reverse order. To execute a block of code some number of times, the builtin function range() can be used. Range takes an optional starting point (default is 0), a stopping point, and an optional step amount, and returns a list of integers. range(3) would return the list [0, 1, 2], and range(1,10,3) would return the list [1, 4, 7].

Python also has while loops, which execute a block of code as long as a condition is true.

Exceptions

When something goes wrong in Python, an exception is thrown. Any unhandled exception will cause Python to halt and print a stack trace. Exceptions can be caught using try blocks.

try:
    print 'Your magic number is', number
catch NameError:
    print 'Oops, number undefined'
catch IOError, arg:
    print 'This won't happen, but shows that exceptions can carry arguments'
catch (RuntimeError, TypeError):
    print "This statement can handle two different exceptions"
    print "but neither will happen unless the computer is on fire"
    raise   # throw the exception again
catch:
    print "and this handles anything else"

The type and contents of an exception’s data vary. More details on specific exceptions are available in the Python Library Reference.

Exceptions are raised as raise ExceptionType, data.

Functions

Functions would be nice, too, I suppose. Here’s how to define them:

def addnums(a,b):
  return a + b

If no return statement is given, the function will return None. An empty return statement also returns None.

Default values can be given to the function parameters. Let’s say you expect to be adding to the number 3 most frequently.

def addnums(a,b=3):
  return a + b

Now addnums(1,2) will return 3, and addnums(1) will return 4. The names of the variables can also be given as part of the function call, so addnums(a=1,b=2) and addnums(b=2,a=1) will both pass in 1 for a and 2 for b. This syntax is sometimes necessary when there is more than default value in a function.

Functions create a new scope for variables, so variables created within a function cannot be used outside of it.

Files and I/O

By now you’re probably wondering how to read input. Python provides a builtin function, raw_input(), to read a line of input, but there are more versatile functions available as part of the stdin file object. stdin is part of the sys module, which must be imported before it can be used.

from sys import stdin
line = stdin.readline()
while line:
    if line[-1:] == '\n':   # readline() includes newlines
      line = line[:-1]      # remove if present
    print line
    line = stdin.readline()

This copies input to output, one line at a time. When the end of input is reached, readline() returns an empty string, which the while loop treats as false. The assignment cannot be made as part of the test, as is common in some other languages, since Python syntax requires assignments to be separate from other statements.

New file objects can be created with the builtin file() method, which uses the same syntax as fopen() in C.

from sys import stdin
f=file("outputfile","w")  # opens a file for writing
line = stdin.readline()
while line:
    f.write(line)
    line = stdin.readline()
f.close()

Objects and Classes

I mentioned at the beginning that Python is object-oriented. Here’s a brief look at classes:

class Animal:
# __init__ is called when the class is created
# the first argument in the methods is always be the object
    def __init__(self,name,species="Monkey"):
        self.species=species
        self.name=name

    def printname(self):
        # no implicit namespace, self is always necessary
        print self.name, 'is a', self.species

# class Dog is a child of Animal
# multiple inheritance is also possible
class Dog(Animal):
    def __init__(self,name="Biff"):
        self.species="Dog"
        self.name=name

    def bark(self,message='Woof! Woof!):
        print message

biff=Dog()
jimbo=Animal(name="Jimbo")
jimbo.printname()
biff.printname()
biff.bark('woof.')

Jimbo is a Monkey
Biff is a Dog
woof.

Some other useful standard methods, like __init__, are __str__, which is called to get a string for print statements, __cmp__, which is used for comparisons, __nonzero__, which is used to determine whether the object is true or false, and __del__, which is called when the object’s reference count becomes 0.

Modules

Many of Python’s capabilities are contained in modules, which must be imported before using. The import command, when given a module name, will make that module’s namespace available. The from…import command can be used to bring all or parts of a module into the default namespace.

# allows items in sys module to be used as sys.stdin, sys.argv, etc
import sys

# allows all items in re (regular expression) module to be used as search(),
# match(), etc.
from re import *

# makes only the atoi function available
from string import atoi

The module search path includes the script’s directory, so you can make your own modules simply by putting a bunch of functions and classes and whatnot into a file and importing. import filename will try to find the file “filename.py” and execute it.

A Dash of Functional Programming

Python also offers a handful of features to make the functional programmer feel a bit more at home. The builtin function filter() can be used to take only certain values from a list.

# true if x is divisible by 4 or larger than 12
def filterfunc(x):
    return (x % 4 == 0) or x > 12

# function names are just like any other symbol, and can be passed around
# as function arguments
print filter(filterfunc,range(5,14))

[8, 12, 13]

The map() function also takes a function and a sequence as its arguments, and returns a new sequence containing the return values from the function. map can take more than sequence at a time, with the second argument becoming the second argument to the function, and so on. If None is given for the function, then a function is substituted that returns its arguments.

xcoords=[1,5,13]
ycoords=[6,30,9]
zcoords=[4,4,-9]

points=map(None,xcoords,ycoords,zcoords)
print points

[(1, 6, 4), (5, 30, 4), (13, 9, -9)]

def scalex(point,x):
    return map((lambda x,y: x*y),point,[x for i in point])

# multiplies first point by 1, second by 5,
# and third by 13
print map(scalex,points,xcoords)

[[1, 6, 4], [25, 150, 20], [169, 117, -117]]

The lambda is a small, anonymous function, and can be treated like any other function. These are commonly used to create factory functions that returns specialized lambdas for some task. The list in the last argument to map is a list comprehension form. It uses the value (in this case, x) as the list element for each iteration through the for loop, so this example creates a list of x’s with the same length as the point. The initial for clause can be followed by more for or if clauses, to create complicated messes of lists.

# combines every x with every y
print [x*y for x in range(1,6) for y in range(5) if y%2 == 0]

[0, 2, 4, 0, 4, 8, 0, 6, 12, 0, 8, 16, 0, 10, 20]

# could also be done with:
a=[]
for x in range(1,6):
    for y in range(5):
        if y%2 == 0:
            a.append(x*y)
print a
[0, 2, 4, 0, 4, 8, 0, 6, 12, 0, 8, 16, 0, 10, 20]

reduce() is another useful list function. It takes a function and a list as its arguments, and returns a single value constructed by calling the function on the first two elements of the list, calling it again on the returned value and the third element of the list, and so on.

def sum(a,b):
  return a+b

print reduce(sum,[1,3,5,7])

16

And lastly, since I don’t have a better place to put it, Python has a little bit of syntactic sugar to allow multiple variables to be assigned in a single statement.

a, b = 1, 2

This would assign 1 to a and 2 to b. This can also be used to swap two variables in a single statement by using a, b = b, a

References and further reading