In exercise you will learn how to use a Python interpreter interactively and to run simple pieces of code. Using this knowledge you will investigate the basic syntax of a Python program, learn what many of the operators and keywords do, and explore the Python type system and its semantics. The exercises were written to target the CPython interpreter and, in particular, the Enthought Python Distribution (EPD) installed on a Mac, but everything here should be portable between different operating systems, interpreters and Python distributions.

Work through the following exercises in order, they should be self-explanatory but do ask if you have a problem. It doesn’t matter too much if you don’t manage to finish this afternoon, but you should try and find time to look at everything before Thursday afternoon. Python code and output is typeset in monotype font, and this can be typed directly into the interpreter.

Exercise 1: Assignment, equality and logic

Start up as terminal and then the python interpreter by typing ./python. You should see the version information and a command prompt:

Enthought Python Distribution -- www.enthought.com
Version: 7.1-2 (32-bit)

Python 2.7.2 |EPD 7.1-2 (32-bit)| (default, Jul 27 2011, 13:29:32)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "packages", "demo" or "enthought" for more information.
>>>

You can run simple python code from the ">>>" command prompt.

  • Let a = 1 (type "a=1" at the command prompt). What is a (type "a")?

  • Let b = 2. What is b?

  • Let c = 2.75. What is c?

  • What is b after you type b=a?

  • What is a?

a, b, and c are variables, 1, 2 and 2.75 are values, = is the assignment operator.

  • What is f?

Note You should see an error as f has not been defined. This is useful as it helps avoid turning simple typo’s into hard to fix bugs.
  • Let e = 2 and f = 3.

  • Is e == b?

  • Is f > e?

  • Is c < f?

  • Is c < a?

  • Is a <= e?

  • Is e >= a?

  • Let t = True. What is t?

==, >, <, <= and >= are the basic logical operators used to test for equality, greater than, less than, less than or equals and greater than or equals. True and False are logical values representing truth and falsehood.

Warning == and = do different things; True and False must be capitalised.
  • What is not True

  • What is not False

  • What is (e == b) and (c < f)?

  • What is (e < 3) and t?

  • What is True and False?

  • What is False and False?

  • What is True and True?

  • What is True or False?

  • What is not (True or False)?

The Boolean operators and, or, and not, can be used to combine logical tests. Brackets (parentheses) can be used to group and order them.

Quit the interpretor (type quit() or Ctrl-D).

Exercise 2: Block statments

The python interpreter can also be used to execute a series of statements in a file. These statements are executed in sequence from the first line to the last. Use your favorite text editor to create a file called count.py containing the following python code:

i = 1
while (i < 10):
    print i
    i = i + 1
print "The end"

Run this code by typing python ./count.py at the shell command prompt. What is printed to the screen? Is this what you expect?

You should see the numbers 1 to 9 and the string "The end" printed before the interpreter exits and you are returned to the command prompt. The while statement begins a block of code that is executed in a loop until some logical condition is false. What is the logical test in your count program? Is this tested before or after the block of code guarded by the while statement is run?

Modify the logic in your program to make it count to 10. Is there another way to change the logic to achieve the same thing? Now change the program to count backwards from 10 to 1. Change it again to only print the even numbers.

Often, one of the most disconcerting features of Python is that blocks of code are delimited by indentation. Most programmers will indent loops and other blocks of code they write but Python is unusual in demanding indentation and using it as part of the syntax of the language. If you’ve not already inadvertently found out, see what happens if you change your counting program so that the indentation is not consistent. For example, indent the print line more than the i = i + 1 line.

Note Although Python allows flexibility when indenting blocks of code, the use of four space characters is strongly recommended by the semi-official style guide (PEP 8). Most code you read will have blocks indented with four spaces. Most code you write should also use four spaces for indentation.

What does the following code snippet do?

def count():
    i = 1
    while (i < 10):
        print i
        i = i + 1
print "The end"

Are you sure? It’s in the file count_func.py, run it to find out.

Although Python programs are executed sequentially, from the start to the end of the file, like many languages, you can specify a piece of code should form a subroutine or function that can be run later. When the interpreter reaches a block of code guarded by the def statement a function is defined. The function is not run until it is called by name. Modify count_func.py to call the count function:

def count():
    i = 1
    while (i < 10):
        print i
        i = i + 1
count()
print "The end"

What does this code do?

What happens if you try and call the function before the function has been defined? Does this work:

count()
def count():
    i = 1
    while (i < 10):
        print i
        i = i + 1
count()
print "The end"

Functions can (optionally) have one or more arguments (in the parentheses). These allow the function to be more general. Modify your code to accept an argument, n, the upper limit of the printed numbers, and m the lower limit. Print three lists of numbers, 1 – 10, 14 – 27, and 88 – 96.

Note Argument lists to Python functions allow considerable flexibility. It’s easy to give functions optional arguments, arguments with default values, and even accept lists of arguments without knowing what they will be when you write the function. Functions don’t need to be given names. Functions can take functions as arguments, can call them (and can call themselves recursively) and functions can return other functions. For example, you can write a general integration routine without knowing the function you will be integrating. We will look at some of these features later in the course. A good introduction can also be found in Chapter 4.6 and 4.7 of the Python tutorial.

The third block statement allows pieces of code to be executed conditionally. What does the following code print?

i = 1
while i <= 10:
    if (i >= 5):
        print i
    i = i + 1

print "The end"

Are you sure? It’s in the file count_if.py, run it to find out.

The block of indented code guarded by an if statement is only executed when the condition is true. Note that we can embed one indented block within another. What does the following print?

i = 1
while i <= 100:
    if (i >= 5):
        if (i < 15):
            print i
    i = i + 1

print "The end"

Can you condese the two nested if statments into one with more complex logic?

Exercise 3: Basic mathematical operators and scalar types

Now look at how python handles mathematics. Beware, there may by one or two surprises. Use the interpreter interactively to decide:

  • What is 2+3?

  • What is 2*6?

  • What is 2-5?

  • What is 6/3?

The arithmetic operators work as you may expect.

  • What is 7/3?

  • What is -7/3?

Is this what you expected?

Note Remember that numbers in python can be integers or floats and that integer division rounds down.
  • What is type(3)?

  • What about type(7)?

  • So what is type(7/3)?

  • Does 7.0/3 give you the right answer?

  • Why?

  • What is type(7.0)

  • So what is type(7.0/3)?

  • What about type(7/3.0)?

You can also do calculations with floating point numbers. * What is 1.0 - 0.5? * What about 1.2 - 1.0? * Is that correct? what’s going on?

Warning Floating point mathematics isn’t quite like the mathematics you learnt at school. On computers numbers are represented internally in binary, as strings of 1s and 0s. The set of real numbers that can be represented exactly in a finite number of binary digits is different to the set of real numbers that can be represented exactly in decimal. This leads to some interesting issues discussed at the end of the standard Python Tutorial and described in much more detail in the paper What Every Computer Scientist Should Know About Floating-Point Arithmetic It’s worth knowing that Python has support in the standard library for fixed point numbers (i.e. decimal calculations which are exact to a given number of decimal places) and for rational numbers (fractions). These may be useful, but will be slower (computer hardware is built for floating point binary mathematics, it’s too expensive to fit hardware decimal units).
  • What is 1+2j?

  • What is type(1+2j)?

  • What is (1+2j)-(1-2j)?

  • If c = 2+4j what is c**2?

  • What about c + 1?

  • What are c.real and c.imag?

  • And what is c.conjugate()?

Complex numbers are built in. The operators work as you may expect.

Exercise 4: Strings

Another data type in Python is the string. Literal strings are embedded in single or double quotes and strings can be assigned to variables just like the other types:

  • If a = "Some text", what is type(a)?

  • What is a[0]?

  • And a[0:4]?

  • What is a[8]?

  • What is a[5:9]?

  • What about a[5:]?

  • What is a[:]? Is this any different from a?

  • What is a[:4]?

  • Is "Some text" the same as 'Some text'? Are the two strings equal?

In Python strings are a sequence of characters numbered from 0. Sub-strings can be accessed using an index notation using brackets (not parentheses) containing integers separated by colons. When only one index is provided a single character is returned. When two indices are provided a series of characters are returned from the first, to one less than the second index. If left out (but with the colon in place) the indices default to the start and end of the string.

  • What is a + " some more text"?

  • What about a * 3?

  • Do the - or / operators work on strings?

When placed between strings, + acts as a concatenation operator and * works as a repetition operator.

  • What is a[0:9:2]?

  • What about a[-4:]?

  • What is a[-2:-1]?

  • What is a[::-1]?

  • What happens if you try and change the "S" into an "s" in a? Does a[0] = "s" work?

The third list index specifies how the sub-string is constructed by stepping through the string. Negative indices count backwards from the end, or reverse along the string. Note that strings are immutable. You cannot use the index notation to change bits of a string. We’ll cover this concept in more detail later.

  • If b = "1.0" what is type(b)?

  • What is float(b)? What is its type?

  • If c = "1" what is its type?

  • What is int(c) and what is its type?

  • Can you turn b into an integer? What about c into a float?

  • If d = 4+7j what is type(d)?

  • Can you print d?

  • Does print d + " is a complex number" work?

  • Why not? How does Python know what + does?

  • What is str(d) and what is it’s type?

  • Can you fix print d + " is a complex number" so that it does work?

  • Does this work with the other numerical types?

Exercise 5: Lists

Strings are the first of Python’s built in sequence types; lists are the second. To a large extent, if you know how to use one sequence type you know them all. In a list instead of each numbered "container" holding a single character, each container can hold any variable. Start up a python intepreter.

  • If a = [1, 2.3, 4.5, 'one', "1"] what is type(a)?

  • What is a[1]?

  • What about a[4]?

  • What is type(a[0])?

  • What is the type of each element of a?

  • What is a[3][1]?

Note that lists can contain variables of different types mixed together. We can access characters within a string within a list by using multiple indices next to each other.

  • What is a*2?

  • What about a+['the end of the list'].

  • Do the - or / operators work on lists?

  • If a[3] = 'two' what is a?

  • We described strings as an immutable type. How could we describe lists?

  • Let b = [0, 1, 2, 3, 4] and c = range(5).

  • Are b and c the same?

  • Does b == c?

  • Does a == c?

  • Make a[1] = b. What is a?

  • Notice that lists can contain other lists.

  • What is a[1][0]?

  • Does a == c now?

  • What about a[1] == c?

  • If d = [] what could you call d? Is d a list?

Python contains several other built in sequence types (there are seven in total). We’ll briefly look at them later. Some work like strings (and can only contain a particular type of data) and some work like lists (and can contain any type of data). Some sequence types are mutable and others are immutable. All sequence types support index notation with brackets and colons, along with several other operations including + and *.

Exercise 6: Sequences and iteration

We’ve seen that Python supports more than one sequence type. When writing a program, sequences (usually lists) are commonly used to store the working data. We often want to do "something" to each item of data in turn: perhaps we want to calculate the average of all the numbers in the list, maybe we want to find the maximum or add a number to each element of the list. What we need is a way to iterate through the list. A block of code using the for x in l: statement allows us to do this. What does the following program print?

groups = ['BEEST', 'Geophysics', 'Geochemistry',
         'Palaeobiology and Biodiversity', 'Volcanology',
         'Climate and Environmental Change']

print "The School of Earth Sciences has six research groups:"

for group in groups:
    print "\t* " + group

The program can be found in the file for_in.py. Run it to confirm your suspicion.

Warning In Python for x in l: is quite different to for in C or do in Fortran. It iterates through a list and it does not denote a loop. However, Python’s for x in l: can be used to build a loop with little effort. (This is the same as the difference between Perl’s for and foreach constructs.)

Modify the program to print the numbers from 0 to 10. Use the range function to generate the list.

With one argument, n, the range function generates a list of n integers starting a zero. range() can also take two integer arguments. What is the meaning of the first and second arguments in this case? Modify the program to print the numbers from 1 to 10.

Range can also take a third argument. Modify the code to print the even numbers between 1 and 10 using the three-argument form.

Does range accept four or more arguments? Does it accept negative arguments? What do they do?

It is sometimes necessary to iterate through two sequences together in lock step. The zip() function can be used for this. What does the following program (zip.py) print? Do you see how it works?

names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
         'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

rain = [10.2, 12.4, 9.4, 8.2, 8.9, 7.2, 3.9, 7.6, 8.0, 11.2, 10.5, 9.9]

for month, inch in zip(names, rain):
    print "In " + month + " there was " + str(inch) + " inches of rain"

Modify the program to calculate the average monthly rainfall in the year using two other variables and the for loop above. Print this after the monthly report. Imperial measurements are outdated. Convert the output into mm.

If rain = [10.2, 12.4, 9.4, 8.2, 8.9, 7.2, 3.9, 7.6, 8.0, 11.2, 10.5, 9.9], what is len(rain)? What is sum rain? Calculate the average monthly rainfall without using for.

What does the following program (caesar.py) do? The variable names may help.

shift = 3
alphabet = 'abcdefghijklmnopqrstuvwxyz'
cipherbet = alphabet[shift:27]+alphabet[0:shift]

plaintext = 'the quick brown fox jumps over the lazy dog'
ciphertext = ''

for p in plaintext:
    if p == ' ':
        ciphertext = ciphertext + ' ' # Keep the spaces
    else:
        for a, c in zip(alphabet, cipherbet):
            if p == a:
                ciphertext = ciphertext + c
                break # No need to finish the inner loop

print plaintext
print ciphertext

Can you write a program to perform the inverse function?

Exercise 7: Dictionaries

Dictionaries are another data type found in Python. A dictionary is equivalent to a hash in Perl, std::map in C++ and "maps" in Java, all are implementations of associative arrays. Like a list a dictionary links a key to a value. A list’s key is the index and this must be an integer. This means that lists have a natural order (for the list l, l[3] comes after l[2] and before l[4]). Many data types can play the role of a key in a dictionary. This means dictionaries have no natural order and you should never assume that keys and values will be returned if you iterate through a dictionary twice. This is OK, there are many things in the world you may want to refer to in a program that don’t have a natural order (but may have an unnatural order). Words and word definitions in one of those books of the language, for example.

  • If d = {"Around the world in 80 days": "Jules Verne", "The Hobbit": "J R R Tolkien", "A Journey to the center of the Earth": "Jules Verne", "A study in scarlet": "Doyle", "The valley of Fear": "Doyle", "The Lord of the Rings": "Tolkien"} what is d? Is the order you put in the same as the order you got out?

  • What is type(d)?

  • What is d["The Lord of the Rings"]? What is its type?

  • Can you change the value of d["The Lord of the Rings"] to "J R R Tolkien"?

  • What is d.keys()? What about d.values()? What type are returned by these functions? What do you notice about the order of the elements in these lists?

  • Can a dictionary contain two elements with the same key?

  • Is it OK for two elements to share the same value?

  • Is "A Journey to the center of the Earth" in d?

  • Is "Tolkien" in d?

  • What does in do?

  • Does it check the keys or the values?

  • How do you think you could iterate through a dictionary?

  • What is i in each iteration of for i in d:?

  • What if you need the key too? Could you use d.keys(), d.values() and zip()? How?

  • Can a dictionary have an integer as a value? What about as a key?

  • What about a floating point number or a complex number?

  • Can make a dictionary have a list as a value?

  • What about using a list as a key?

  • Are strings immutable?

  • Are lists mutable?

  • Do you think dictionary keys have to be immutable?

  • What is d.items()? What is the type of the elements of the list that is returned?

  • Have you seen this type before?

  • Can this type be used as the key to a dictionary?

  • Is it mutable?

Dictionaries and tuples turn out to be quite important if you want to really understand Python, but you can get by without them.