# Think Python/Files

## Persistence

Most of the programs we have seen so far are transient in the sense that
they run for a short time and produce some output, but when they end,
their data disappears. If you run the program again, it starts with a
clean slate.

Other programs are **persistent**: they run for a long time (or all the
time); they keep at least some of their data in permanent storage (a
hard drive, for example); and if they shut down and restart, they pick
up where they left off.

Examples of persistent programs are operating systems, which run pretty
much whenever a computer is on, and web servers, which run all the time,
waiting for requests to come in on the network.

One of the simplest ways for programs to maintain their data is by
reading and writing text files. We have already seen programs that read
text files; in this chapters we will see programs that write them.

An alternative is to store the state of the program in a database. In
this chapter I will present a simple database and a module, `pickle`,
that makes it easy to store program data.

## Reading and writing

A text file is a sequence of characters stored on a permanent medium
like a hard drive, flash memory, or CD-ROM. We saw how to open and read
a file in Section 9.1.

To write a file, you have to open it with mode `'w'` as a second
parameter:

``` python
>>> fout = open('output.txt', 'w')
>>> print fout
<open file 'output.txt', mode 'w' at 0xb7eb2410>
```

If the file already exists, opening it in write mode clears out the old
data and starts fresh, so be careful! If the file doesn't exist, a new
one is created.

The `write` method puts data into the file.

``` python
>>> line1 = "This here's the wattle,\n"
>>> fout.write(line1)
```

Again, the file object keeps track of where it is, so if you call
`write` again, it adds the new data to the end.

``` python
>>> line2 = "the emblem of our land.\n"
>>> fout.write(line2)
```

When you are done writing, you have to close the file.

``` python
>>> fout.close()
```

## Format operator

The argument of `write` has to be a string, so if we want to put other
values in a file, we have to convert them to strings. The easiest way to
do that is with `str`:

``` python
>>> x = 52
>>> f.write(str(x))
```

An alternative is to use the **format operator**, `%`. When applied to
integers, `%` is the modulus operator. But when the first operand is a
string, `%` is the format operator.

The first operand is the **format string**, and the second operand is a
tuple of expressions. The result is a string that contains the values of
the expressions, formatted according to the format string.

As an example, the **format sequence** `'%d'` means that the first
expression in the tuple should be formatted as an integer (`d` stands
for "decimal"):

``` python
>>> camels = 42
>>> '%d' % camels
'42'
```

The result is the string `'42'`, which is not to be confused with the
integer value `42`.

A format sequence can appear anywhere in the format string, so you can
embed a value in a sentence:

``` python
>>> camels = 42
>>> 'I have spotted %d camels.' % camels
'I have spotted 42 camels.'
```

The format sequence `'%g'` formats the next element in the tuple as a
floating-point number (don't ask why), and `'%s'` formats the next item
as a string:

``` python
>>> 'In %d years I have spotted %g %s.' % (3, 0.1, 'camels')
'In 3 years I have spotted 0.1 camels.'
```

The number of elements in the tuple has to match the number of format
sequences in the string. Also, the types of the elements have to match
the format sequences:

``` python
>>> '%d %d %d' % (1, 2)
TypeError: not enough arguments for format string
>>> '%d' % 'dollars'
TypeError: illegal argument type for built-in operation
```

In the first example, there aren't enough elements; in the second, the
element is the wrong type.

The format operator is powerful but difficult to use. You can read more
about it at `docs.python.org/lib/typesseq-strings.html`.

## Filenames and paths

Files are organized into **directories** (also called "folders"). Every
running program has a "current directory," which is the default
directory for most operations. For example, when you open a file for
reading, Python looks for it in the current directory.

The `os` module provides functions for working with files and
directories ("os" stands for "operating system"). `os.getcwd` returns
the name of the current directory:

``` python
>>> import os
>>> cwd = os.getcwd()
>>> print cwd
/home/dinsdale
```

`cwd` stands for "current working directory." The result in this example
is `/home/dinsdale`, which is the home directory of a user named
`dinsdale`.

A string like `cwd` that identifies a file is called a **path**. A
**relative path** starts from the current directory; an **absolute
path** starts from the topmost directory in the file system.

The paths we have seen so far are simple filenames, so they are relative
to the current directory. To find the absolute path to a file, you can
use `os.path.abspath`:

``` python
>>> os.path.abspath('memo.txt')
'/home/dinsdale/memo.txt'
```

`os.path.exists` checks whether a file or directory exists:

``` python
>>> os.path.exists('memo.txt')
True
```

If it exists, `os.path.isdir` checks whether it's a directory:

``` python
>>> os.path.isdir('memo.txt')
False
>>> os.path.isdir('music')
True
```

Similarly, `os.path.isfile` checks whether it's a file.

`os.listdir` returns a list of the files (and other directories) in the
given directory:

``` python
>>> os.listdir(cwd)
['music', 'photos', 'memo.txt']
```

To demonstrate these functions, the following example "walks" through a
directory, prints the names of all the files, and calls itself
recursively on all the directories.

``` python
def walk(dir):
    for name in os.listdir(dir):
        path = os.path.join(dir, name)

        if os.path.isfile(path):
            print path
        else:
            walk(path)
```

`os.path.join` takes a directory and a file name and joins them into a
complete path.

### Exercise 1

Modify **\'`walk`**\' so that instead of printing the names of the
files, it returns a list of names. \'\'

```{=html}
</DIV>
```
```{=html}
<DIV CLASS="theorem">
```
**Exercise 2**  \'\' The **\'`os`**\' module provides a function called
**\'`walk`**\' that is similar to this one but more versatile. Read the
documentation and use it to print the names of the files in a given
directory and its subdirectories.

## Catching exceptions

A lot of things can go wrong when you try to read and write files. If
you try to open a file that doesn't exist, you get an `IOError`:

``` python
>>> fin = open('bad_file')
IOError: [Errno 2] No such file or directory: 'bad_file'
```

If you don't have permission to access a file:

``` python
>>> fout = open('/etc/passwd', 'w')
IOError: [Errno 13] Permission denied: '/etc/passwd'
```

And if you try to open a directory for reading, you get

``` python
>>> fin = open('/home')
IOError: [Errno 21] Is a directory
```

To avoid these errors, you could use functions like `os.path.exists` and
`os.path.isfile`, but it would take a lot of time and code to check all
the possibilities (if "`Errno 21`" is any indication, there are at least
21 things that can go wrong).

It is better to go ahead and try, and deal with problems if they happen,
which is exactly what the `try` statement does. The syntax is similar to
an `if` statement:

``` python
try:
    fin = open('bad_file')
    for line in fin:
        print line
    fin.close()
except:
    print 'Something went wrong.'
```

Python starts by executing the `try` clause. If all goes well, it skips
the `except` clause and proceeds. If an exception occurs, it jumps out
of the `try` clause and executes the `except` clause.

Handling an exception with a `try` statement is called **catching** an
exception. In this example, the `except` clause prints an error message
that is not very helpful. In general, catching an exception gives you a
chance to fix the problem, or try again, or at least end the program
gracefully.

## Databases

A **database** is a file that is organized for storing data. Most
databases are organized like a dictionary in the sense that they map
from keys to values. The biggest difference is that the database is on
disk (or other permanent storage), so it persists after the program
ends.

The module `anydbm` provides an interface for creating and updating
database files. As an example, I'll create a database that contains
captions for image files.

Opening a database is similar to opening other files:

``` python
>>> import anydbm
>>> db = anydbm.open('captions.db', 'c')
```

The mode `'c'` means that the database should be created if it doesn't
already exist. The result is a database object that can be used (for
most operations) like a dictionary. If you create a new item, `anydbm`
updates the database file.

``` python
>>> db['cleese.png'] = 'Photo of John Cleese.'
```

When you access one of the items, `anydbm` reads the file:

``` python
>>> print db['cleese.png']
Photo of John Cleese.
```

If you make another assignment to an existing key, `anydbm` replaces the
old value:

``` python
>>> db['cleese.png'] = 'Photo of John Cleese doing a silly walk.'
>>> print db['cleese.png']
Photo of John Cleese doing a silly walk.
```

Many dictionary methods, like `keys` and `items`, also work with
database objects. So does iteration with a `for` statement.

``` python
for key in db:
     print key
```

As with other files, you should close the database when you are done:

``` python
>>> db.close()
```

## Pickling

A limitation of `anydbm` is that the keys and values have to be strings.
If you try to use any other type, you get an error.

The `pickle` module can help. It translates almost any type of object
into a string suitable for storage in a database, and then translates
strings back into objects.

`pickle.dumps` takes an object as a parameter and returns a string
representation (`dumps` is short for "dump string"):

``` python
>>> import pickle
>>> t = [1, 2, 3]
>>> pickle.dumps(t)
'(lp0\nI1\naI2\naI3\na.'
```

The format isn't obvious to human readers; it is meant to be easy for
`pickle` to interpret. `pickle.loads` ("load string") reconstitutes the
object:

``` python
>>> t1 = [1, 2, 3]
>>> s = pickle.dumps(t1)
>>> t2 = pickle.loads(s)
>>> print t2
[1, 2, 3]
```

Although the new object has the same value as the old, it is not (in
general) the same object:

``` python
>>> t == t2
True
>>> t is t2
False
```

In other words, pickling and then unpickling has the same effect as
copying the object.

You can use `pickle` to store non-strings in a database. In fact, this
combination is so common that it has been encapsulated in a module
called `shelve`.

```{=html}
<DIV CLASS="theorem">
```
**Exercise 3**

*If you did Exercise **\'12.4**\', modify your solution so that it
creates a database that maps from each word in the list to a list of
words that use the same set of letters.*

*Write a different program that opens the database and prints the
contents in a human-readable format.*

```{=html}
</DIV>
```
## Pipes

Most operating systems provide a command-line interface, also known as a
**shell**. Shells usually provide commands to navigate the file system
and launch applications. For example, in Unix, you can change
directories with `cd`, display the contents of a directory with `ls`,
and launch a web browser by typing (for example) `Firefox`.

Any program that you can launch from the shell can also be launched from
Python using a **pipe**. A pipe is an object that represents a running
process.

For example, the Unix command `ls -l` normally displays the contents of
the current directory (in long format). You can launch `ls` with
`os.popen`:

``` python
>>> cmd = 'ls -l'
>>> fp = os.popen(cmd)
```

The argument is a string that contains a shell command. The return value
is a file pointer that behaves just like an open file. You can read the
output from the `ls` process one line at a time with `readline` or get
the whole thing at once with `read`:

``` python
>>> res = fp.read()
```

When you are done, you close the pipe like a file:

``` python
>>> stat = fp.close()
>>> print stat
None
```

The return value is the final status of the `ls` process; `None` means
that it ended normally (with no errors).

A common use of pipes is to read a compressed file incrementally; that
is, without uncompressing the whole thing at once. The following
function takes the name of a compressed file as a parameter and returns
a pipe that uses `gzip` to decompress the contents:

``` python
def open_gzip(filename):
    cmd = 'gunzip -c ' + filename
    fp = os.popen(cmd)
    return fp
```

If you read lines from `fp` one at a time, you never have to store the
uncompressed file in memory or on disk.

## Writing modules

Any file that contains Python code can be imported as a module. For
example, suppose you have a file named `wc.py` with the following code:

``` python
def linecount(filename):
    count = 0
    for line in open(filename):
        count += 1
    return count

print linecount('wc.py')
```

If you run this program, it reads itself and prints the number of lines
in the file, which is 7. You can also import it like this:

``` python
>>> import wc
7
```

Now you have a module object `wc`:

``` python
>>> print wc
<module 'wc' from 'wc.py'>
```

That provides a function called `linecount`:

``` python
>>> wc.linecount('wc.py')
7
```

So that's how you write modules in Python.

The only problem with this example is that when you import the module it
executes the test code at the bottom. Normally when you import a module,
it defines new functions but it doesn't execute them.

Programs that will be imported as modules often use the following idiom:

``` python
if __name__ == '__main__':
    print linecount('wc.py')
```

`__name__` is a built-in variable that is set when the program starts.
If the program is running as a script, `__name__` has the value
`__main__`; in that case, the test code is executed. Otherwise, if the
module is being imported, the test code is skipped.

```{=html}
<DIV CLASS="theorem">
```
**Exercise 4**  *Type this example into a file named **\'`wc.py`**\' and
run it as a script. Then run the Python interpreter and
**\'`import wc`**\'. What is the value of`__name__`when the module is
being imported?* *Warning: If you import a module that has already been
imported, Python does nothing. It does not re-read the file, even if it
has changed.*

*If you want to reload a module, you can use the built-in function
**\'`reload`**\', but it can be tricky, so the safest thing to do is
restart the interpreter and then import the module again.*

```{=html}
</DIV>
```
## Debugging

When you are reading and writing files, you might run into problems with
whitespace. These errors can be hard to debug because spaces, tabs and
newlines are normally invisible:

``` python
>>> s = '1 2\t 3\n 4'
>>> print s
1 2  3
 4
```

The built-in function `repr` can help. It takes any object as an
argument and returns a string representation of the object. For strings,
it represents whitespace characters with backslash sequences:

``` python
>>> print repr(s)
'1 2\t 3\n 4'
```

This can be helpful for debugging.

One other problem you might run into is that different systems use
different characters to indicate the end of a line. Some systems use a
newline, represented `\n`. Others use a return character, represented
`\r`. Some use both. If you move files between different systems, these
inconsistencies might cause problems.

For most systems, there are applications to convert from one format to
another. You can find them (and read more about this issue) at
`wikipedia.org/wiki/Newline`. Or, of course, you could write one
yourself.

## Glossary

```{=html}
<DL CLASS="description">
```
```{=html}
<DT CLASS="dt-description">
```
**persistent:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
Pertaining to a program that runs indefinitely and keeps at least some
of its data in permanent storage.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**format operator:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
An operator, `%`, that takes a format string and a tuple and generates a
string that includes the elements of the tuple formatted as specified by
the format string.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**format string:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A string, used with the format operator, that contains format sequences.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**format sequence:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A sequence of characters in a format string, like `%d`, that specifies
how a value should be formatted.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**text file:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A sequence of characters stored in permanent storage like a hard drive.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**directory:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A named collection of files, also called a folder.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**path:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A string that identifies a file.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**relative path:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A path that starts from the current directory.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**absolute path:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A path that starts from the topmost directory in the file system.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**catch:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
To prevent an exception from terminating a program using the `try` and
`except` statements.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**database:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A file whose contents are organized like a dictionary with keys that
correspond to values.

```{=html}
</DD>
```
```{=html}
</DL>
```
## Exercises

```{=html}
<DIV CLASS="theorem">
```
**Exercise 5**  The **\'`urllib`**\' module provides methods for
manipulating URLs and downloading information from the web. The
following example downloads and prints a secret message from
**\'`thinkpython.com`**\':\'\'

``` python
import urllib

conn = urllib.urlopen('http://thinkpython.com/secret.html')
for line in conn.fp:
    print line.strip()
```

*Run this code and follow the instructions you see there.*

```{=html}
</DIV>
```
```{=html}
<DIV CLASS="theorem">
```
**Exercise 6**

*In a large collection of MP3 files, there may be more than one copy of
the same song, stored in different directories or with different file
names. The goal of this exercise is to search for these duplicates.*

-   \'\'Write a program that searches a directory and all of its

subdirectories, recursively, and returns a list of complete paths for
all files with a given suffix (like **\'`.mp3`**\'). Hint:
**\'`os.path`**\' provides several useful functions for manipulating
file and path names.\'\'

-   \'\'To recognize duplicates, you can use a hash function that

reads the file and generates a short summary of the contents. For
example, MD5 (Message-Digest algorithm 5) takes an arbitrarily-long
"message" and returns a 128-bit "checksum." The probability is very
small that two files with different contents will return the same
checksum.You can read about MD5 at **\'`wikipedia.org/wiki/Md5`**\'. On
a Unix system you can use the program **\'`md5sum`**\' and a pipe to
compute checksums from Python.\'\'

```{=html}
</DIV>
```
```{=html}
<DIV CLASS="theorem">
```
**Exercise 7**

*The Internet Movie Database (IMDb) is an online collection of
information about movies. Their database is available in plain text
format, so it is reasonably easy to read from Python. For this exercise,
the files you need are **\'`actors.list.gz`**\' and
**\'`actresses.list.gz`**\'; you can download them from
**\'`www.imdb.com/interfaces#plain`**\'.*

*I have written a program that parses these files and splits them into
actor names, movie titles, etc. You can download it from
**\'`thinkpython.com/code/imdb.py`**\'.*

*If you run **\'`imdb.py`**\' as a script, it reads
**\'`actors.list.gz`**\' and prints one actor-movie pair per line. Or,
if you **\'`import imdb`**\' you can use the function`process_file`to,
well, process the file. The arguments are a filename, a function object
and an optional number of lines to process. Here is an example:*

``` python
''import imdb

def print_info(actor, date, title, role):
    print actor, date, title, role

imdb.process_file('actors.list.gz', print_info)
''
```

*When you call`process_file`, it opens **\'`filename`**\', reads the
contents, and calls`print_info`once for each line in the
file.`print_info`takes an actor, date, movie title and role as arguments
and prints them.*

-   \'\'Write a program that reads **\'`actors.list.gz`**\' and
    **\'`actresses.list.gz`**\' and uses **\'`shelve`**\' to build a
    database

that maps from each actor to a list of his or her films. \'\'

-   \'\'Two actors are "costars" if they have been in at least one

movie together. Process the database you built in the previous step and
build a second database that maps from each actor to a list of his or
her costars. \'\'

-   \'\'Write a program that can play the "Six Degrees of Kevin

Bacon," which you can read about at
**\'`wikipedia.org/wiki/Six_Degrees_of_Kevin_Bacon`**\'. This problem is
challenging because it requires you to find the shortest path in a
graph. You can read about shortest path algorithms at
**\'`wikipedia.org/wiki/Shortest_path_problem`**\'.\'\'

```{=html}
</DIV>
```


# Think Python/Classes and objects

## User-defined types

We have used many of Python's built-in types; now we are going to define
a new type. As an example, we will create a type called `Point` that
represents a point in two-dimensional space.

In mathematical notation, points are often written in parentheses with a
comma separating the coordinates. For example, (0, 0) represents the
origin, and (`<I>`{=html}x`</I>`{=html}, `<I>`{=html}y`</I>`{=html})
represents the point `<I>`{=html}x`</I>`{=html} units to the right and
`<I>`{=html}y`</I>`{=html} units up from the origin.

There are several ways we might represent points in Python:

-   We could store the coordinates separately in two variables, `x` and
    `y`.
-   We could store the coordinates as elements in a list or tuple.
-   We could create a new type to represent points as objects.

Creating a new type is (a little) more complicated than the other
options, but it has advantages that will be apparent soon.

A user-defined type is also called a **class**. A class definition looks
like this:

``` python
class Point(object):
    """represents a point in 2-D space"""
```

This header indicates that the new class is a `Point`, which is a kind
of `object`, which is a built-in type.

The body is a docstring that explains what the class is for. You can
define variables and functions inside a class definition, but we will
get back to that later.

Defining a class named `Point` creates a class object.

``` python
>>> print Point
<class '__main__.Point'>
```

Because `Point` is defined at the top level, its "full name" is
`__main__.Point`.

The class object is like a factory for creating objects. To create a
Point, you call `Point` as if it were a function.

``` python
>>> blank = Point()
>>> print blank
<__main__.Point instance at 0xb7e9d3ac>
```

The return value is a reference to a Point object, which we assign to
`blank`. Creating a new object is called **instantiation**, and the
object is an **instance** of the class.

When you print an instance, Python tells you what class it belongs to
and where it is stored in memory (the prefix `0x` means that the
following number is in hexadecimal).

## Attributes

You can assign values to an instance using dot notation:

``` python
>>> blank.x = 3.0
>>> blank.y = 4.0
```

This syntax is similar to the syntax for selecting a variable from a
module, such as `math.pi` or `string.whitespace`. In this case, though,
we are assigning values to named elements of an object. These elements
are called **attributes**.

As a noun, "AT-trib-ute" is pronounced with emphasis on the first
syllable, as opposed to "a-TRIB-ute," which is a verb.

The following diagram shows the result of these assignments. A state
diagram that shows an object and its attributes is called an **object
diagram**:

![](book022.png "book022.png")

The variable `blank` refers to a Point object, which contains two
attributes. Each attribute refers to a floating-point number.

You can read the value of an attribute using the same syntax:

``` python
>>> print blank.y
4.0
>>> x = blank.x
>>> print x
3.0
```

The expression `blank.x` means, "Go to the object `blank` refers to and
get the value of `x`." In this case, we assign that value to a variable
named `x`. There is no conflict between the variable `x` and the
attribute `x`.

You can use dot notation as part of any expression. For example:

``` python
>>> print '(%g, %g)' % (blank.x, blank.y)
(3.0, 4.0)
>>> distance = math.sqrt(blank.x**2 + blank.y**2)
>>> print distance
5.0
```

You can pass an instance as an argument in the usual way. For example:

``` python
def print_point(p):
    print '(%g, %g)' % (p.x, p.y)
```

`print_point` takes a point as an argument and displays it in
mathematical notation. To invoke it, you can pass `blank` as an
argument:

``` python
>>> print_point(blank)
(3.0, 4.0)
```

Inside the function, `p` is an alias for `blank`, so if the function
modifies `p`, `blank` changes.

### Exercise 1

Write a function called **\'`distance`**\' that it takes two Points as
arguments and returns the distance between them.

## Rectangles

Sometimes it is obvious what the attributes of an object should be, but
other times you have to make decisions. For example, imagine you are
designing a class to represent rectangles. What attributes would you use
to specify the location and size of a rectangle? You can ignore angle;
to keep things simple, assume that the rectangle is either vertical or
horizontal.

There are at least two possibilities:

-   You could specify one corner of the rectangle (or the center), the
    width, and the height.
-   You could specify two opposing corners.

At this point it is hard to say whether either is better than the other,
so we'll implement the first one, just as an example.

Here is the class definition:

``` python
class Rectangle(object):
    """represent a rectangle.
       attributes: width, height, corner.
    """
```

The docstring lists the attributes: `width` and `height` are numbers;
`corner` is a Point object that specifies the lower-left corner.

To represent a rectangle, you have to instantiate a Rectangle object and
assign values to the attributes:

``` python
box = Rectangle()
box.width = 100.0
box.height = 200.0
box.corner = Point()
box.corner.x = 0.0
box.corner.y = 0.0
```

The expression `box.corner.x` means, "Go to the object `box` refers to
and select the attribute named `corner`; then go to that object and
select the attribute named `x`."

The figure shows the state of this object:

![](book023.png "book023.png") An object that is an attribute of another
object is **embedded**.

## Instances as return values

Functions can return instances. For example, `find_center` takes a
`Rectangle` as an argument and returns a `Point` that contains the
coordinates of the center of the `Rectangle`:

``` python
def find_center(box):
    p = Point()
    p.x = box.corner.x + box.width/2.0
    p.y = box.corner.y + box.height/2.0
    return p
```

Here is an example that passes `box` as an argument and assigns the
resulting Point to `center`:

``` python
>>> center = find_center(box)
>>> print_point(center)
(50.0, 100.0)
```

## Objects are mutable

You can change the state of an object by making an assignment to one of
its attributes. For example, to change the size of a rectangle without
changing its position, you can modify the values of `width` and
`height`:

``` python
box.width = box.width + 50
box.height = box.height + 100
```

You can also write functions that modify objects. For example,
`grow_rectangle` takes a Rectangle object and two numbers, `dwidth` and
`dheight`, and adds the numbers to the width and height of the
rectangle:

``` python
def grow_rectangle(rect, dwidth, dheight) :
    rect.width += dwidth
    rect.height += dheight
```

Here is an example that demonstrates the effect:

``` python
>>> print box.width
100.0
>>> print box.height
200.0
>>> grow_rectangle(box, 50, 100)
>>> print box.width
150.0
>>> print box.height
300.0
```

Inside the function, `rect` is an alias for `box`, so if the function
modifies `rect`, `box` changes.

### Exercise 2

Write a function named **`move_rectangle`** that takes a Rectangle and
two numbers named **\'`dx`**\' and **\'`dy`**\'. It should change the
location of the rectangle by adding **\'`dx`**\' to the **\'`x`**\'
coordinate of **\'`corner`**\' and adding **\'`dy`**\' to the
**\'`y`**\' coordinate of **\'`corner`**\'.

## Copying

Aliasing can make a program difficult to read because changes in one
place might have unexpected effects in another place. It is hard to keep
track of all the variables that might refer to a given object.

Copying an object is often an alternative to aliasing. The `copy` module
contains a function called `copy` that can duplicate any object:

``` python
>>> p1 = Point()
>>> p1.x = 3.0
>>> p1.y = 4.0

>>> import copy
>>> p2 = copy.copy(p1)
```

`p1` and `p2` contain the same data, but they are not the same Point.

``` python
>>> print_point(p1)
(3.0, 4.0)
>>> print_point(p2)
(3.0, 4.0)
>>> p1 is p2
False
>>> p1 == p2
False
```

The `is` operator indicates that `p1` and `p2` are not the same object,
which is what we expected. But you might have expected `==` to yield
`True` because these points contain the same data. In that case, you
will be disappointed to learn that for instances, the default behavior
of the `==` operator is the same as the `is` operator; it checks object
identity, not object equivalence. This behavior can be changed---we'll
see how later.

If you use `copy.copy` to duplicate a Rectangle, you will find that it
copies the Rectangle object but not the embedded Point.

``` python
>>> box2 = copy.copy(box)
>>> box2 is box
False
>>> box2.corner is box.corner
True
```

Here is what the object diagram looks like:

```{=html}
<DIV CLASS="center">
```
`<IMG SRC="book024.png">`{=html}

```{=html}
</DIV>
```
This operation is called a **shallow copy** because it copies the object
and any references it contains, but not the embedded objects.

For most applications, this is not what you want. In this example,
invoking `grow_rectangle` on one of the Rectangles would not affect the
other, but invoking `move_rectangle` on either would affect both! This
behavior is confusing and error-prone.

Fortunately, the `copy` module contains a method named `deepcopy` that
copies not only the object but also the objects it refers to, and the
objects *they* refer to, and so on. You will not be surprised to learn
that this operation is called a **deep copy**.

``` python
>>> box3 = copy.deepcopy(box)
>>> box3 is box
False
>>> box3.corner is box.corner
False
```

`box3` and `box` are completely separate objects.

### Exercise 3

Write a version of **`move_rectangle`** that creates and returns a new
Rectangle instead of modifying the old one.

## Debugging

When you start working with objects, you are likely to encounter some
new exceptions. If you try to access an attribute that doesn't exist,
you get an `AttributeError`:

``` python
>>> p = Point()
>>> print p.z
AttributeError: Point instance has no attribute 'z'
```

If you are not sure what type an object is, you can ask:

``` python
>>> type(p)
<type '__main__.Point'>
```

If you are not sure whether an object has a particular attribute, you
can use the built-in function `hasattr`:

``` python
>>> hasattr(p, 'x')
True
>>> hasattr(p, 'z')
False
```

The first argument can be any object; the second argument is a *string*
that contains the name of the attribute.

## Glossary

```{=html}
<DL CLASS="description">
```
```{=html}
<DT CLASS="dt-description">
```
**class:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A user-defined type. A class definition creates a new class object.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**class object:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
An object that contains information about a user-defined type. The class
object can be used to create instances of the type.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**instance:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
An object that belongs to a class.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**attribute:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
One of the named values associated with an object.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**embedded (object):**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
An object that is stored as an attribute of another object.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**shallow copy:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
To copy the contents of an object, including any references to embedded
objects; implemented by the `copy` function in the `copy` module.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**deep copy:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
To copy the contents of an object as well as any embedded objects, and
any objects embedded in them, and so on; implemented by the `deepcopy`
function in the `copy` module.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**object diagram:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A diagram that shows objects, their attributes, and the values of the
attributes.

```{=html}
</DD>
```
```{=html}
</DL>
```
## Exercises

### Exercise 4

*`World.py`**\', which is part of Swampy (see Chapter **\'4**\'),
contains a class definition for a user-defined type called**\'`World`.
If you run this code:*

``` python
''from World import *
world = World()
wait_for_user()
''
```

*A window should appear with a title bar and an empty square. In this
exercise we will use this window to draw Points, Rectangles and other
shapes. Add the following lines before`wait_for_user`and run the program
again*

``` python
''canvas = world.ca(width=500, height=500, background='white')
bbox = [[-150,-100], [150, 100]]
canvas.rectangle(bbox, outline='black', width=2, fill='green4')
''
```

*You should see a green rectangle with a black outline. The first line
creates a Canvas, which appears in the window as a white square. The
Canvas object provides methods like **\'`rectangle`**\' for drawing
various shapes.*

*`bbox`is a list of lists that represents the "bounding box" of the
rectangle. The first pair of coordinates is the lower-left corner of the
rectangle; the second pair is the upper-right corner.*

*You can draw a circle like this:*

``` python
''canvas.circle([-25,0], 70, outline=None, fill='red')
''
```

*The first parameter is the coordinate pair for the center of the
circle; the second parameter is the radius.*

*If you add this line to the program, the result should resemble the
national flag of Bangladesh (see
**\'`wikipedia.org/wiki/Gallery_of_sovereign-state_flags`**\').*

-   *Write a function called`draw_rectangle`*\'\' that takes a

Canvas and a Rectangle as arguments and draws a representation of the
Rectangle on the Canvas.\'\'

-   \'\'Add an attribute named **\'`color`**\' to your Rectangle objects
    and

modify **`draw_rectangle`** so that it uses the color attribute as the
fill color.\'\'

-   *Write a function called`draw_point`*\'\' that takes a

Canvas and a Point as arguments and draws a representation of the Point
on the Canvas.\'\'

-   \'\'Define a new class called Circle with appropriate attributes and

instantiate a few Circle objects. Write a function called
**`draw_circle`** that draws circles on the canvas.\'\'

-   *Write a program that draws the national flag of the Czech
    Republic.*

Hint: you can draw a polygon like this:\'\'

``` python
''points = [[-150,-100], [150, 100], [150, -100]]
canvas.polygon(points, fill='blue')
''
```

*I have written a small program that lists the available colors; you can
download it from **\'`thinkpython.com/code/color_list.py`**\'.*


# Think Python/Classes and functions

## Time

As another example of a user-defined type, we\'ll define a class called
`Time` that records the time of day. The class definition looks like
this:

``` python
class Time(object):
  """represents the time of day.
    attributes: hour, minute, second"""
```

We can create a new `Time` object and assign attributes for hours,
minutes, and seconds:

``` python
time = Time()
time.hour = 11
time.minute = 59
time.second = 30
```

The state diagram for the `Time` object looks like this:

```{=html}
<DIV CLASS="center">
```
`<IMG SRC="book025.png">`{=html}

```{=html}
</DIV>
```
### Exercise 1

Write a function called `print_time` that takes a Time object and prints
it in the form `hour:minute:second`.

Hint: the format sequence `%.2d` prints an integer using at least two
digits, including a leading zero if necessary.

### Exercise 2

Write a boolean function called `is_after` that takes two Time objects,
`t1` and `t2`, and returns `True` if `t1` follows `t2` chronologically
and `False` otherwise.

Challenge: don\'t use an `if` statement.

## Pure functions

In the next few sections, we'll write two functions that add time
values. They demonstrate two kinds of functions: pure functions and
modifiers. They also demonstrate a development plan I'll call
**prototype and patch**, which is a way of tackling a complex problem by
starting with a simple prototype and incrementally dealing with the
complications.

Here is a simple prototype of `add_time`:

``` python
def add_time(t1, t2):
  sum = Time()
  sum.hour = t1.hour + t2.hour
  sum.minute = t1.minute + t2.minute
  sum.second = t1.second + t2.second
  return sum
```

The function creates a new `Time` object, initializes its attributes,
and returns a reference to the new object. This is called a **pure
function** because it does not modify any of the objects passed to it as
arguments and it has no effect, like displaying a value or getting user
input, other than returning a value.

To test this function, I'll create two Time objects: `start` contains
the start time of a movie, like *Monty Python and the Holy Grail*, and
`duration` contains the run time of the movie, which is one hour 35
minutes.

`add_time` figures out when the movie will be done.

``` python
>>> start = Time()
>>> start.hour = 9
>>> start.minute = 45
>>> start.second = 0

>>> duration = Time()
>>> duration.hour = 1
>>> duration.minute = 35
>>> duration.second = 0

>>> done = add_time(start, duration)
>>> print_time(done)
10:80:00
```

The result, `10:80:00` might not be what you were hoping for. The
problem is that this function does not deal with cases where the number
of seconds or minutes adds up to more than sixty. When that happens, we
have to "carry" the extra seconds into the minute column or the extra
minutes into the hour column.

Here's an improved version:

``` python
def add_time(t1, t2):
  sum = Time()
  sum.hour = t1.hour + t2.hour
  sum.minute = t1.minute + t2.minute
  sum.second = t1.second + t2.second

  if sum.second >= 60:
    sum.second -= 60
    sum.minute += 1

  if sum.minute >= 60:
    sum.minute -= 60
    sum.hour += 1

  return sum
```

Although this function is correct, it is starting to get big. We will
see a shorter alternative later.

## Modifiers

Sometimes it is useful for a function to modify the objects it gets as
parameters. In that case, the changes are visible to the caller.
Functions that work this way are called **modifiers**.

`increment`, which adds a given number of seconds to a `Time` object,
can be written naturally as a modifier. Here is a rough draft:

``` python
def increment(time, seconds):
  time.second += seconds

  if time.second >= 60:
    time.second -= 60
    time.minute += 1

  if time.minute >= 60:
    time.minute -= 60
    time.hour += 1
```

The first line performs the basic operation; the remainder deals with
the special cases we saw before.

Is this function correct? What happens if the parameter `seconds` is
much greater than sixty?

In that case, it is not enough to carry once; we have to keep doing it
until `time.second` is less than sixty. One solution is to replace the
`if` statements with `while` statements. That would make the function
correct, but not very efficient.

```{=html}
<DIV CLASS="theorem">
```
**Exercise 3**  *Write a correct version of **\'`increment`**\' that
doesn't contain any loops.*

```{=html}
</DIV>
```
Anything that can be done with modifiers can also be done with pure
functions. In fact, some programming languages only allow pure
functions. There is some evidence that programs that use pure functions
are faster to develop and less error-prone than programs that use
modifiers. But modifiers are convenient at times, and functional
programs tend to be less efficient.

In general, I recommend that you write pure functions whenever it is
reasonable and resort to modifiers only if there is a compelling
advantage. This approach might be called a **functional programming
style**.

```{=html}
<DIV CLASS="theorem">
```
**Exercise 4**  \'\' Write a "pure" version of **\'`increment`**\' that
creates and returns a new Time object rather than modifying the
parameter.

## Prototyping versus planning

The development plan I am demonstrating is called "prototype and patch."
For each function, I wrote a prototype that performed the basic
calculation and then tested it, patching errors along the way.

This approach can be effective, especially if you don't yet have a deep
understanding of the problem. But incremental corrections can generate
code that is unnecessarily complicated---since it deals with many
special cases---and unreliable---since it is hard to know if you have
found all the errors.

An alternative is **planned development**, in which high-level insight
into the problem can make the programming much easier. In this case, the
insight is that a Time object is really a three-digit number in base 60
(see `wikipedia.org/wiki/Sexagesimal`)! The `second` attribute is the
"ones column," the `minute` attribute is the "sixties column," and the
`hour` attribute is the "thirty-six hundreds column."

When we wrote `add_time` and `increment`, we were effectively doing
addition in base 60, which is why we had to carry from one column to the
next.

This observation suggests another approach to the whole problem---we can
convert Time objects to integers and take advantage of the fact that the
computer knows how to do integer arithmetic.

Here is a function that converts Times to integers:

``` python
def time_to_int(time):
  minutes = time.hour * 60 + time.minute
  seconds = minutes * 60 + time.second
  return seconds
```

And here is the function that converts integers to Times (recall that
`divmod` divides the first argument by the second and returns the
quotient and remainder as a tuple).

``` python
def int_to_time(seconds):
  time = Time()
  minutes, time.second = divmod(seconds, 60)
  time.hour, time.minute = divmod(minutes, 60)
  return time
```

You might have to think a bit, and run some tests, to convince yourself
that these functions are correct. One way to test them is to check that
`time_to_int(int_to_time(x)) == x` for many values of `x`. This is an
example of a consistency check.

Once you are convinced they are correct, you can use them to rewrite
`add_time`:

``` python
def add_time(t1, t2):
  seconds = time_to_int(t1) + time_to_int(t2)
  return int_to_time(seconds)
```

This version is shorter than the original, and easier to verify.

```{=html}
<DIV CLASS="theorem">
```
**Exercise 5**  *Rewrite **\'`increment`**\'
using`time_to_int`and`int_to_time`.*

```{=html}
</DIV>
```
In some ways, converting from base 60 to base 10 and back is harder than
just dealing with times. Base conversion is more abstract; our intuition
for dealing with time values is better.

But if we have the insight to treat times as base 60 numbers and make
the investment of writing the conversion functions (`time_to_int` and
`int_to_time`), we get a program that is shorter, easier to read and
debug, and more reliable.

It is also easier to add features later. For example, imagine
subtracting two Times to find the duration between them. The naïve
approach would be to implement subtraction with borrowing. Using the
conversion functions would be easier and more likely to be correct.

Ironically, sometimes making a problem harder (or more general) makes it
easier (because there are fewer special cases and fewer opportunities
for error).

## Debugging

A Time object is well-formed if the values of `minutes` and `seconds`
are between 0 and 60 (including 0 but not 60) and if `hours` is
positive. `hours` and `minutes` should be integral values, but we might
allow `seconds` to have a fraction part.

These kind of requirements are called **invariants** because they should
always be true. To put it a different way, if they are not true, then
something has gone wrong.

Writing code to check your invariants can help you detect errors and
find their causes. For example, you might have a function like
`valid_time` that takes a Time object and returns `False` if it violates
an invariant:

``` python
def valid_time(time):
  if time.hours < 0 or time.minutes < 0 or time.seconds < 0:
    return False
  if time.minutes >= 60 or time.seconds >= 60:
    return False
  return True
```

Then at the beginning of each function you could check the arguments to
make sure they are valid:

``` python
def add_time(t1, t2):
  if not valid_time(t1) or not valid_time(t2):
    raise ValueError, 'invalid Time object in add_time'
  seconds = time_to_int(t1) + time_to_int(t2)
  return int_to_time(seconds)
```

Or you could use an `assert` statement, which checks a given invariant
and raises an exception if it fails:

``` python
def add_time(t1, t2):
  assert valid_time(t1) and valid_time(t2)
  seconds = time_to_int(t1) + time_to_int(t2)
  return int_to_time(seconds)
```

`assert` statements are useful because they distinguish code that deals
with normal conditions from code that checks for errors.

## Glossary

```{=html}
<DL CLASS="description">
```
```{=html}
<DT CLASS="dt-description">
```
**prototype and patch:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A development plan that involves writing a rough draft of a program,
testing, and correcting errors as they are found.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**planned development:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A development plan that involves high-level insight into the problem and
more planning than incremental development or prototype development.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**pure function:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A function that does not modify any of the objects it receives as
arguments. Most pure functions are fruitful.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**modifier:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A function that changes one or more of the objects it receives as
arguments. Most modifiers are fruitless.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**functional programming style:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A style of program design in which the majority of functions are pure.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**invariant:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A condition that should always be true during the execution of a
program.

```{=html}
</DD>
```
```{=html}
</DL>
```
## Exercises

### Exercise 6

Write a function called **`mul_time`** that takes a Time object and a
number and returns a new Time object that contains the product of the
original Time and the number.Then use **`mul_time`** to write a function
that takes a Time object that represents the finishing time in a race,
and a number that represents the distance, and returns a Time object
that represents the average pace (time per mile).\'\'

### Exercise 7

*Write a class definition for a Date object that has attributes
**\'`day`**\', **\'`month`**\' and **\'`year`**\'. Write a function
called`increment_date`that takes a Date object, **\'`date`**\' and an
integer, **\'`n`**\', and returns a new Date object that represents the
day **\'`n`**\' days after **\'`date`**\'. Hint: "Thirty days hath
September\..." Challenge: does your function deal with leap years
correctly? See`wikipedia.org/wiki/Leap_year`*

### Exercise 8

*The **\'`datetime`**\' module provides **\'`date`**\' and
**\'`time`**\' objects that are similar to the Date and Time objects in
this chapter, but they provide a rich set of methods and operators. Read
the documentation at **\'`docs.python.org/lib/datetime-date.html`**\'.*

-   *Use the **\'`datetime`**\' module to write a program that gets the
    current date and prints the day of the week.*
-   *Write a program that takes a birthday as input and prints the
    user's age and the number of days, hours, minutes and seconds until
    their next birthday.*


# Think Python/Classes and methods

## Object-oriented features

Python is an **object-oriented programming language**, which means that
it provides features that support object-oriented programming.

It is not easy to define object-oriented programming, but we have
already seen some of its characteristics:

-   Programs are made up of object definitions and function definitions,
    and most of the computation is expressed in terms of operations on
    objects.

```{=html}
<!-- -->
```
-   Each object definition corresponds to some object or concept in the
    real world, and the functions that operate on that object correspond
    to the ways real-world objects interact.

For example, the `Time` class defined in Chapter 16 corresponds to the
way people record the time of day, and the functions we defined
correspond to the kinds of things people do with times. Similarly, the
`Point` and `Rectangle` classes correspond to the mathematical concepts
of a point and a rectangle.

So far, we have not taken advantage of the features Python provides to
support object-oriented programming. These features are not strictly
necessary; most of them provide alternative syntax for things we have
already done. But in many cases, the alternative is more concise and
more accurately conveys the structure of the program.

For example, in the `Time` program, there is no obvious connection
between the class definition and the function definitions that follow.
With some examination, it is apparent that every function takes at least
one `Time` object as an argument.

This observation is the motivation for **methods**; a method is a
function that is associated with a particular class. We have seen
methods for strings, lists, dictionaries and tuples. In this chapter, we
will define methods for user-defined types.

Methods are semantically the same as functions, but there are two
syntactic differences:

-   Methods are defined inside a class definition in order to make the
    relationship between the class and the method explicit.
-   The syntax for invoking a method is different from the syntax for
    calling a function.

In the next few sections, we will take the functions from the previous
two chapters and transform them into methods. This transformation is
purely mechanical; you can do it simply by following a sequence of
steps. If you are comfortable converting from one form to another, you
will be able to choose the best form for whatever you are doing.

## Printing objects

In Chapter 16, we defined a class named `Time` and in Exercise 16.1, you
wrote a function named `print_time`:

``` python
class Time(object):
    """represents the time of day.
       attributes: hour, minute, second"""

def print_time(time):
    print '%.2d:%.2d:%.2d' % (time.hour, time.minute, time.second)
```

To call this function, you have to pass a `Time` object as an argument:

``` python
>>> start = Time()
>>> start.hour = 9
>>> start.minute = 45
>>> start.second = 00
>>> print_time(start)
09:45:00
```

To make `print_time` a method, all we have to do is move the function
definition inside the class definition. Notice the change in
indentation.

``` python
class Time(object):
    def print_time(time):
        print '%.2d:%.2d:%.2d' % (time.hour, time.minute, time.second)
```

Now there are two ways to call `print_time`. The first (and less common)
way is to use function syntax:

``` python
>>> Time.print_time(start)
09:45:00
```

In this use of dot notation, `Time` is the name of the class, and
`print_time` is the name of the method. `start` is passed as a
parameter.

The second (and more concise) way is to use method syntax:

``` python
>>> start.print_time()
09:45:00
```

In this use of dot notation, `print_time` is the name of the method
(again), and `start` is the object the method is invoked on, which is
called the **subject**. Just as the subject of a sentence is what the
sentence is about, the subject of a method invocation is what the method
is about.

Inside the method, the subject is assigned to the first parameter, so in
this case `start` is assigned to `time`.

By convention, the first parameter of a method is called `self`, so it
would be more common to write `print_time` like this:

``` python
class Time(object):
    def print_time(self):
        print '%.2d:%.2d:%.2d' % (self.hour, self.minute, self.second)
```

The reason for this convention is an implicit metaphor:

-   The syntax for a function call, `print_time(start)`,

suggests that the function is the active agent. It says something like,
"Hey `print_time`! Here's an object for you to print."

-   In object-oriented programming, the objects are the active agents.

A method invocation like `start.print_time()` says "Hey `start`! Please
print yourself."

This change in perspective might be more polite, but it is not obvious
that it is useful. In the examples we have seen so far, it may not be.
But sometimes shifting responsibility from the functions onto the
objects makes it possible to write more versatile functions, and makes
it easier to maintain and reuse code.

### Exercise 1

Rewrite **`time_to_int`** (from Section **\'16.4**\') as a method. It is
probably not appropriate to rewrite **`int_to_time`** as a method; it's
not clear what object you would invoke it on!

## Another example

Here's a version of `increment` (from Section 16.3) rewritten as a
method:

``` python
# inside class Time:

    def increment(self, seconds):
        seconds += self.time_to_int()
        return int_to_time(seconds)
```

This version assumes that `time_to_int` is written as a method, as in
Exercise 17.1. Also, note that it is a pure function, not a modifier.

Here's how you would invoke `increment`:

``` python
>>> start.print_time()
09:45:00
>>> end = start.increment(1337)
>>> end.print_time()
10:07:17
```

The subject, `start`, gets assigned to the first parameter, `self`. The
argument, `1337`, gets assigned to the second parameter, `seconds`.

This mechanism can be confusing, especially if you make an error. For
example, if you invoke `increment` with two arguments, you get:

``` python
>>> end = start.increment(1337, 460)
TypeError: increment() takes exactly 2 arguments (3 given)
```

The error message is initially confusing, because there are only two
arguments in parentheses. But the subject is also considered an
argument, so all together that's three.

## A more complicated example

`is_after` (from Exercise 16.2) is slightly more complicated because it
takes two Time objects as parameters. In this case it is conventional to
name the first parameter `self` and the second parameter `other`:

``` python
# inside class Time:

    def is_after(self, other):
        return self.time_to_int() > other.time_to_int()
```

To use this method, you have to invoke it on one object and pass the
other as an argument:

``` python
>>> end.is_after(start)
True
```

One nice thing about this syntax is that it almost reads like English:
"end is after start?"

## The init method

The init method (short for "initialization") is a special method that
gets invoked when an object is instantiated. Its full name is `__init__`
(two underscore characters, followed by `init`, and then two more
underscores). An init method for the `Time` class might look like this:

``` python
# inside class Time:

    def __init__(self, hour=0, minute=0, second=0):
        self.hour = hour
        self.minute = minute
        self.second = second
```

It is common for the parameters of `__init__` to have the same names as
the attributes. The statement

``` python
        self.hour = hour
```

stores the value of the parameter `hour` as an attribute of `self`.

The parameters are optional, so if you call `Time` with no arguments,
you get the default values.

``` python
>>> time = Time()
>>> time.print_time()
00:00:00
```

If you provide one argument, it overrides `hour`:

``` python
>>> time = Time (9)
>>> time.print_time()
09:00:00
```

If you provide two arguments, they override `hour` and `minute`.

``` python
>>> time = Time(9, 45)
>>> time.print_time()
09:45:00
```

And if you provide three arguments, they override all three default
values.

### Exercise 2

*Write an init method for the **\'`Point`**\' class that takes
**\'`x`**\' and **\'`y`**\' as optional parameters and assigns them to
the corresponding attributes.*

## The `__str__` method

`__str__` is a special method, like `__init__`, that is supposed to
return a string representation of an object.

For example, here is a `str` method for Time objects:

``` python
# inside class Time:

    def __str__(self):
        return '%.2d:%.2d:%.2d' % (self.hour, self.minute, self.second)
```

When you `print` an object, Python invokes the `str` method:

``` python
>>> time = Time(9, 45)
>>> print time
09:45:00
```

When I write a new class, I almost always start by writing `__init__`,
which makes it easier to instantiate objects, and `__str__`, which is
useful for debugging.

### Exercise 3

Write a **\'`str`**\' method for the **\'`Point`**\' class. Create a
Point object and print it.

## Operator overloading

By defining other special methods, you can specify the behavior of
operators on user-defined types. For example, if you define a method
named `__add__` for the `Time` class, you can use the `+` operator on
Time objects.

Here is what the definition might look like:

``` python
# inside class Time:

    def __add__(self, other):
        seconds = self.time_to_int() + other.time_to_int()
        return int_to_time(seconds)
```

And here is how you could use it:

``` python
>>> start = Time(9, 45)
>>> duration = Time(1, 35)
>>> print start + duration
11:20:00
```

When you apply the `+` operator to Time objects, Python invokes
`__add__`. When you print the result, Python invokes `__str__`. So there
is quite a lot happening behind the scenes!

Changing the behavior of an operator so that it works with user-defined
types is called **operator overloading**. For every operator in Python
there is a corresponding special method, like `__add__`. For more
details, see `docs.python.org/ref/specialnames.html`.

### Exercise 4

Write an **\'`add`**\' method for the Point class.

## Type-based dispatch

In the previous section we added two Time objects, but you also might
want to add an integer to a Time object. The following is a version of
`__add__` that checks the type of `other` and invokes either `add_time`
or `increment`:

``` python
# inside class Time:

    def __add__(self, other):
        if isinstance(other, Time):
            return self.add_time(other)
        else:
            return self.increment(other)

    def add_time(self, other):
        seconds = self.time_to_int() + other.time_to_int()
        return int_to_time(seconds)

    def increment(self, seconds):
        seconds += self.time_to_int()
        return int_to_time(seconds)
```

The built-in function `isinstance` takes a value and a class object, and
returns `True` if the value is an instance of the class.

If `other` is a Time object, `__add__` invokes `add_time`. Otherwise it
assumes that the parameter is a number and invokes `increment`. This
operation is called a **type-based dispatch** because it dispatches the
computation to different methods based on the type of the arguments.

Here are examples that use the `+` operator with different types:

``` python
>>> start = Time(9, 45)
>>> duration = Time(1, 35)
>>> print start + duration
11:20:00
>>> print start + 1337
10:07:17
```

Unfortunately, this implementation of addition is not commutative. If
the integer is the first operand, you get

``` python
>>> print 1337 + start
TypeError: unsupported operand type(s) for +: 'int' and 'instance'
```

The problem is, instead of asking the Time object to add an integer,
Python is asking an integer to add a Time object, and it doesn't know
how to do that. But there is a clever solution for this problem: the
special method `__radd__`, which stands for "right-side add." This
method is invoked when a Time object appears on the right side of the
`+` operator. Here's the definition:

``` python
# inside class Time:

    def __radd__(self, other):
        return self.__add__(other)
```

And here's how it's used:

``` python
>>> print 1337 + start
10:07:17
```

### Exercise 5

Write an **\'`add`**\' method for Points that works with either a Point
object or a tuple: \'\'

-   *If the second operand is a Point, the method should return a new
    Point whose **\'`<I>`{=html}x`</I>`{=html}**\' coordinate is the sum
    of the **\'`<I>`{=html}x`</I>`{=html}**\' coordinates of the
    operands, and likewise for the **\'`<I>`{=html}y`</I>`{=html}**\'
    coordinates.*
-   *If the second operand is a tuple, the method should add the first
    element of the tuple to the **\'`<I>`{=html}x`</I>`{=html}**\'
    coordinate and the second element to the
    **\'`<I>`{=html}y`</I>`{=html}**\' coordinate, and return a new
    Point with the result.*

## Polymorphism

Type-based dispatch is useful when it is necessary, but (fortunately) it
is not always necessary. Often you can avoid it by writing functions
that work correctly for arguments with different types.

Many of the functions we wrote for strings will actually work for any
kind of sequence. For example, in Section 11.1 we used `histogram` to
count the number of times each letter appears in a word.

``` python
def histogram(s):
    d = dict()
    for c in s:
        if c not in d:
            d[c] = 1
        else:
            d[c] = d[c]+1
    return d
```

This function also works for lists, tuples, and even dictionaries, as
long as the elements of `s` are hashable, so they can be used as keys in
`d`.

``` python
>>> t = ['spam', 'egg', 'spam', 'spam', 'bacon', 'spam']
>>> histogram(t)
{'bacon': 1, 'egg': 1, 'spam': 4}
```

Functions that can work with several types are called **polymorphic**.
Polymorphism can facilitate code reuse. For example, the built-in
function `sum`, which adds the elements of a sequence, works as long as
the elements of the sequence support addition.

Since Time objects provide an `add` method, they work with `sum`:

``` python
>>> t1 = Time(7, 43)
>>> t2 = Time(7, 41)
>>> t3 = Time(7, 37)
>>> total = sum([t1, t2, t3])
>>> print total
23:01:00
```

In general, if all of the operations inside a function work with a given
type, then the function works with that type.

The best kind of polymorphism is the unintentional kind, where you
discover that a function you already wrote can be applied to a type you
never planned for.

## Debugging

It is legal to add attributes to objects at any point in the execution
of a program, but if you are a stickler for type theory, it is a dubious
practice to have objects of the same type with different attribute sets.
It is usually a good idea to initialize all of an objects attributes in
the init method.

If you are not sure whether an object has a particular attribute, you
can use the built-in function `hasattr` (see Section 15.7).

Another way to access the attributes of an object is through the special
attribute `__dict__`, which is a dictionary that maps attribute names
(as strings) and values:

``` python
>>> p = Point(3, 4)
>>> print p.__dict__
{'y': 4, 'x': 3}
```

For purposes of debugging, you might find it useful to keep this
function handy:

``` python
def print_attributes(obj):
    for attr in obj.__dict__:
        print attr, getattr(obj, attr)
```

`print_attributes` traverses the items in the object's dictionary and
prints each attribute name and its corresponding value.

The built-in function `getattr` takes an object and an attribute name
(as a string) and returns the attribute's value.

## Glossary

```{=html}
<DL CLASS="description">
```
```{=html}
<DT CLASS="dt-description">
```
**object-oriented language:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A language that provides features, such as user-defined classes and
method syntax, that facilitate object-oriented programming.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**object-oriented programming:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A style of programming in which data and the operations that manipulate
it are organized into classes and methods.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**method:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A function that is defined inside a class definition and is invoked on
instances of that class.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**subject:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
The object a method is invoked on.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**operator overloading:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
Changing the behavior of an operator like `+` so it works with a
user-defined type.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**type-based dispatch:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A programming pattern that checks the type of an operand and invokes
different functions for different types.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**polymorphic:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
Pertaining to a function that can work with more than one type.

```{=html}
</DD>
```
```{=html}
</DL>
```
## Exercises

### Exercise 6

*This exercise is a cautionary tale about one of the most common, and
difficult to find, errors in Python.*

-   \'\'Write a definition for a class named **\'`Kangaroo`**\' with the
    following

methods:\'\'

-   *An`__init__`method that initializes an attribute
    named`pouch_contents`to an empty list.*

```{=html}
<!-- -->
```
-   *A method named`put_in_pouch`that takes an object of any type and
    adds it to`pouch_contents`.*

```{=html}
<!-- -->
```
-   *A`__str__`method that returns a string representation of the
    Kangaroo object and the contents of the pouch.*

Test your code by creating two \'\'***\'`Kangaroo`*objects, assigning
them to variables named*`kanga`*and*`roo`*, and then adding*`roo`*to the
contents of*`kanga`*****'s pouch.**\'

-   **\'Download*`thinkpython.com/code/BadKangaroo.py`***\'\'\'. It
    contains

a solution to the previous problem with one big, nasty bug. Find and fix
the bug.**\'**\'If you get stuck, you can download
\'\'***\'`thinkpython.com/code/GoodKangaroo.py`*****, which explains the
problem and demonstrates a solution.**\'

### Exercise 7

*Visual is a Python module that provides 3-D graphics. It is not always
included in a Python installation, so you might have to install it from
your software repository or, if it's not there, from
**\'`vpython.org`**\'.*

*The following example creates a 3-D space that is 256 units wide, long
and high, and sets the "center" to be the point **\'(128, 128, 128)**\'.
Then it draws a blue sphere.*

``` python
''from visual import *

scene.range = (256, 256, 256)
scene.center = (128, 128, 128)

color = (0.1, 0.1, 0.9)          # mostly blue
sphere(pos=scene.center, radius=128, color=color)
''
```

*`color`**\' is an RGB tuple; that is, the elements are Red-Green-Blue
levels between 0.0 and 1.0
(see**\'`wikipedia.org/wiki/RGB_color_model`).*

*If you run this code, you should see a window with a black background
and a blue sphere. If you drag the middle button up and down, you can
zoom in and out. You can also rotate the scene by dragging the right
button, but with only one sphere in the world, it is hard to tell the
difference.*

*The following loop creates a cube of spheres:*

``` python
''t = range(0, 256, 51)
for x in t:
    for y in t:
        for z in t:
            pos = x, y, z
            sphere(pos=pos, radius=10, color=color)
''
```

-   \'\'Put this code in a script and make sure it works for

you.\'\'

-   \'\'Modify the program so that each sphere in the cube

has the color that corresponds to its position in RGB space. Notice that
the coordinates are in the range 0--255, but the RGB tuples are in the
range 0.0--1.0. \'\'

-   \'\'Download **\'`thinkpython.com/code/color_list.py`**\'

and use the function **`read_colors`** to generate a list of the
available colors on your system, their names and RGB values. For each
named color draw a sphere in the position that corresponds to its RGB
values.\'\'

*You can see my solution at
**\'`thinkpython.com/code/color_space.py`**\'.*

## Further reading

-   Wikipedia: VPython
-   Wikipedia: RGB color model


# Think Python/Inheritance

In this chapter we will develop classes to represent playing cards,
decks of cards, and poker hands. If you don't play poker, you can read
about it at
`wikipedia.org/wiki/Poker`, but
you don\'t have to; I\'ll tell you what you need to know for the
exercises.

If you are not familiar with Anglo-American playing cards, you can read
about them at
`wikipedia.org/wiki/Playing_cards`.

## Card objects

There are fifty-two cards in a deck, each of which belongs to one of
four suits and one of thirteen ranks. The suits are Spades, Hearts,
Diamonds, and Clubs (in descending order in bridge). The ranks are Ace,
2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, and King. Depending on the game
that you are playing, an Ace may be higher than King or lower than 2.

If we want to define a new object to represent a playing card, it is
obvious what the attributes should be: `rank` and `suit`. It is not as
obvious what type the attributes should be. One possibility is to use
strings containing words like `'Spade'` for suits and `'Queen'` for
ranks. One problem with this implementation is that it would not be easy
to compare cards to see which had a higher rank or suit.

An alternative is to use integers to **encode** the ranks and suits. In
this context, "encode" means that we are going to define a mapping
between numbers and suits, or between numbers and ranks. This kind of
encoding is not meant to be a secret (that would be "encryption").

For example, this table shows the suits and the corresponding integer
codes:

  ---------- --- ---
  Spades     ↦   3
  Hearts     ↦   2
  Diamonds   ↦   1
  Clubs      ↦   0
  ---------- --- ---

This code makes it easy to compare cards; because higher suits map to
higher numbers, we can compare suits by comparing their codes.

The mapping for ranks is fairly obvious; each of the numerical ranks
maps to the corresponding integer, and for face cards:

  ------- --- ----
  Jack    ↦   11
  Queen   ↦   12
  King    ↦   13
  ------- --- ----

I am using the ↦ symbol to make it clear that these mappings are not
part of the Python program. They are part of the program design, but
they don't appear explicitly in the code.

The class definition for `Card` looks like this:

``` python
class Card:
    """represents a standard playing card."""

    def __init__(self, suit=0, rank=2):
        self.suit = suit
        self.rank = rank
```

As usual, the init method takes an optional parameter for each
attribute. The default card is the 2 of Clubs.

To create a Card, you call `Card` with the suit and rank of the card you
want.

``` python
queen_of_diamonds = Card(1, 12)
```

## Class attributes

In order to print Card objects in a way that people can easily read, we
need a mapping from the integer codes to the corresponding ranks and
suits. A natural way to do that is with lists of strings. We assign
these lists to **class attributes**:

``` python
# inside class Card:

    suit_names = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
    rank_names = [None, 'Ace', '2', '3', '4', '5', '6', '7',
              '8', '9', '10', 'Jack', 'Queen', 'King']

    def __str__(self):
        return '%s of %s' % (Card.rank_names[self.rank],
                             Card.suit_names[self.suit])
```

Variables like `suit_names` and `rank_names`, which are defined inside a
class but outside of any method, are called class attributes because
they are associated with the class object `Card`.

This term distinguished them from variables like `suit` and `rank`,
which are called **instance attributes** because they are associated
with a particular instance.

Both kinds of attribute are accessed using dot notation. For example, in
`__str__`, `self` is a Card object, and `self.rank` is its rank.
Similarly, `Card` is a class object, and `Card.rank_names` is a list of
strings associated with the class.

Every card has its own `suit` and `rank`, but there is only one copy of
`suit_names` and `rank_names`.

Putting it all together, the expression `Card.rank_names[self.rank]`
means "use the attribute `rank` from the object `self` as an index into
the list `rank_names` from the class `Card`, and select the appropriate
string."

The first element of `rank_names` is `None` because there is no card
with rank zero. By including `None` as a place-keeper, we get a mapping
with the nice property that the index 2 maps to the string `'2'`, and so
on. To avoid this tweak, we could have used a dictionary instead of a
list.

With the methods we have so far, we can create and print cards:

``` python
>>> card1 = Card(2, 11)
>>> print card1
Jack of Hearts
```

Here is a diagram that shows the `Card` class object and one Card
instance:

```{=html}
<DIV CLASS="center">
```
`<IMG SRC="book026.png">`{=html}

```{=html}
</DIV>
```
`Card` is a class object, so it has type `type`. `card1` has type
`Card`. (To save space, I didn't draw the contents of `suit_names` and
`rank_names`).

## Comparing cards

For built-in types, there are conditional operators (`<`, `>`, `==`,
etc.) that compare values and determine when one is greater than, less
than, or equal to another. For user-defined types, we can override the
behavior of the built-in operators by providing a method named
`__cmp__`.

`__cmp__` takes two parameters, `self` and `other`, and returns a
positive number if the first object is greater, a negative number if the
second object is greater, and 0 if they are equal to each other.

The correct ordering for cards is not obvious. For example, which is
better, the 3 of Clubs or the 2 of Diamonds? One has a higher rank, but
the other has a higher suit. In order to compare cards, you have to
decide whether rank or suit is more important.

The answer might depend on what game you are playing, but to keep things
simple, we'll make the arbitrary choice that suit is more important, so
all of the Spades outrank all of the Diamonds, and so on.

With that decided, we can write `__cmp__`:

``` python
# inside class Card:

    def __cmp__(self, other):
        # check the suits
        if self.suit > other.suit: return 1
        if self.suit < other.suit: return -1

        # suits are the same... check ranks
        if self.rank > other.rank: return 1
        if self.rank < other.rank: return -1

        # ranks are the same... it's a tie
        return 0
```

You can write this more concisely using tuple comparison:

``` python
# inside class Card:

    def __cmp__(self, other):
        t1 = self.suit, self.rank
        t2 = other.suit, other.rank
        return cmp(t1, t2)
```

The built-in function `cmp` has the same interface as the method
`__cmp__`: it takes two values and returns a positive number if the
first is larger, a negative number of the second is larger, and 0 if
they are equal.

### Exercise 1

Write a **`__cmp__`** method for Time objects. Hint: you can use tuple
comparison, but you also might consider using integer subtraction.\'\'

## Decks

Now that we have Cards, the next step is to define Decks. Since a deck
is made up of cards, it is natural for each Deck to contain a list of
cards as an attribute.

The following is a class definition for `Deck`. The init method creates
the attribute `cards` and generates the standard set of fifty-two cards:

``` python
class Deck:

    def __init__(self):
        self.cards = []
        for suit in range(4):
            for rank in range(1, 14):
                card = Card(suit, rank)
                self.cards.append(card)
```

The easiest way to populate the deck is with a nested loop. The outer
loop enumerates the suits from 0 to 3. The inner loop enumerates the
ranks from 1 to 13. Each iteration creates a new Card with the current
suit and rank, and appends it to `self.cards`.

## Printing the deck

Here is a `__str__` method for `Deck`:

``` python
#inside class Deck:

    def __str__(self):
        res = [str(card) for card in self.cards]
        return '\n'.join(res)
```

This method demonstrates an efficient way to accumulate a large string:
building a list of strings and then using `join`. The built-in function
`str` invokes the `__str__` method on each card and returns the string
representation.

Since we invoke `join` on a newline character, the cards are separated
by newlines. Here's what the result looks like:

``` python
>>> deck = Deck()
>>> print deck
Ace of Clubs
2 of Clubs
3 of Clubs
...
10 of Spades
Jack of Spades
Queen of Spades
King of Spades
```

Even though the result appears on 52 lines, it is one long string that
contains newlines.

## Add, remove, shuffle and sort

To deal cards, we would like a method that removes a card from the deck
and returns it. The list method `pop` provides a convenient way to do
that:

``` python
#inside class Deck:

    def pop_card(self):
        return self.cards.pop()
```

Since `pop` removes the *last* card in the list, we are dealing from the
bottom of the deck. In real life bottom dealing is frowned upon^1^, but
in this context it's ok.

To add a card, we can use the list method `append`:

``` python
#inside class Deck:

    def add_card(self, card):
        self.cards.append(card)
```

A method like this that uses another function without doing much real
work is sometimes called a **veneer**. The metaphor comes from
woodworking, where it is common to glue a thin layer of good quality
wood to the surface of a cheaper piece of wood.

In this case we are defining a "thin" method that expresses a list
operation in terms that are appropriate for decks.

As another example, we can write a Deck method named `shuffle` using the
function `shuffle` from the `random` module:

``` python
# inside class Deck:

    def shuffle(self):
        random.shuffle(self.cards)
```

Don't forget to import `random`.

### Exercise 2

*Write a Deck method named **\'`sort`**\' that uses the list method
**\'`sort`**\' to sort the cards in a **\'`Deck`**\'. **\'`sort`**\'
uses the`__cmp__`method we defined to determine sort order.*

## Inheritance

The language feature most often associated with object-oriented
programming is **inheritance**. Inheritance is the ability to define a
new class that is a modified version of an existing class.

It is called "inheritance" because the new class inherits the methods of
the existing class. Extending this metaphor, the existing class is
called the **parent** and the new class is called the **child**.

As an example, let's say we want a class to represent a "hand," that is,
the set of cards held by one player. A hand is similar to a deck: both
are made up of a set of cards, and both require operations like adding
and removing cards.

A hand is also different from a deck; there are operations we want for
hands that don't make sense for a deck. For example, in poker we might
compare two hands to see which one wins. In bridge, we might compute a
score for a hand in order to make a bid.

This relationship between classes---similar, but different---lends
itself to inheritance.

The definition of a child class is like other class definitions, but the
name of the parent class appears in parentheses:

``` python
class Hand(Deck):
    """represents a hand of playing cards"""
```

This definition indicates that `Hand` inherits from `Deck`; that means
we can use methods like `pop_card` and `add_card` for Hands as well as
Decks.

`Hand` also inherits `__init__` from `Deck`, but it doesn't really do
what we want: instead of populating the hand with 52 new cards, the init
method for Hands should initialize `cards` with an empty list.

If we provide an init method in the `Hand` class, it overrides the one
in the `Deck` class:

``` python
# inside class Hand:

    def __init__(self, label=''):
        self.cards = []
        self.label = label
```

So when you create a Hand, Python invokes this init method:

``` python
>>> hand = Hand('new hand')
>>> print hand.cards
[]
>>> print hand.label
new hand
```

But the other methods are inherited from `Deck`, so we can use
`pop_card` and `add_card` to deal a card:

``` python
>>> deck = Deck()
>>> card = deck.pop_card()
>>> hand.add_card(card)
>>> print hand
King of Spades
```

A natural next step is to encapsulate this code in a method called
`move_cards`:

``` python
#inside class Deck:

    def move_cards(self, hand, num):
        for i in range(num):
            hand.add_card(self.pop_card())
```

`move_cards` takes two arguments, a Hand object and the number of cards
to deal. It modifies both `self` and `hand`, and returns `None`.

In some games, cards are moved from one hand to another, or from a hand
back to the deck. You can use `move_cards` for any of these operations:
`self` can be either a Deck or a Hand, and `hand`, despite the name, can
also be a `Deck`.

```{=html}
<DIV CLASS="theorem">
```
**Exercise 3**  *Write a Deck method called`deal_hands`that takes two
parameters, the number of hands and the number of cards per hand, and
that creates new Hand objects, deals the appropriate number of cards per
hand, and returns a list of Hand objects.*

```{=html}
</DIV>
```
Inheritance is a useful feature. Some programs that would be repetitive
without inheritance can be written more elegantly with it. Inheritance
can facilitate code reuse, since you can customize the behavior of
parent classes without having to modify them. In some cases, the
inheritance structure reflects the natural structure of the problem,
which makes the program easier to understand.

On the other hand, inheritance can make programs difficult to read. When
a method is invoked, it is sometimes not clear where to find its
definition. The relevant code may be scattered among several modules.
Also, many of the things that can be done using inheritance can be done
as well or better without it.

## Class diagrams

So far we have seen stack diagrams, which show the state of a program,
and object diagrams, which show the attributes of an object and their
values. These diagrams represent a snapshot in the execution of a
program, so they change as the program runs.

They are also highly detailed; for some purposes, too detailed. A class
diagrams is a more abstract representation of the structure of a
program. Instead of showing individual objects, it shows classes and the
relationships between them.

There are several kinds of relationship between classes:

-   Objects in one class might contain references to objects in another
    class. For example, each Rectangle contains a reference to a Point,
    and each Deck contains references to many Cards. This kind of
    relationship is called **HAS-A**, as in, "a Rectangle has a Point."
-   One class might inherit from another. This relationship is called
    **IS-A**, as in, "a Hand is a kind of a Deck."
-   One class might depend on another in the sense that changes in one
    class would require changes in the other.

A **class diagram** is a graphical representation of these
relationships^2^. For example, this diagram shows the relationships
between `Card`, `Deck` and `Hand`.

```{=html}
<DIV CLASS="center">
```
`<IMG SRC="book027.png">`{=html}

```{=html}
</DIV>
```
The arrow with a hollow triangle head represents an IS-A relationship;
in this case it indicates that Hand inherits from Deck.

The standard arrow head represents a HAS-A relationship; in this case a
Deck has references to Card objects.

The star (`*`) near the arrow head is a **multiplicity**; it indicates
how many Cards a Deck has. A multiplicity can be a simple number, like
`52`, a range, like `5..7` or a star, which indicates that a Deck can
have any number of Cards.

A more detailed diagram might show that a Deck actually contains a
*list* of Cards, but built-in types like list and dict are usually not
included in class diagrams.

### Exercise 4

Read **\'`TurtleWorld.py`**\', **\'`World.py`**\' and **\'`Gui.py`**\'
and draw a class diagram that shows the relationships among the classes
defined there.

## Debugging

Inheritance can make debugging a challenge because when you invoke a
method on an object, you might not know which method will be invoked.

Suppose you are writing a function that works with Hand objects. You
would like it to work with all kinds of Hands, like PokerHands,
BridgeHands, etc. If you invoke a method like `shuffle`, you might get
the one defined in `Deck`, but if any of the subclasses override this
method, you'll get that version instead.

Any time you are unsure about the flow of execution through your
program, the simplest solution is to add print statements at the
beginning of the relevant methods. If `Deck.shuffle` prints a message
that says something like `Running Deck.shuffle`, then as the program
runs it traces the flow of execution.

As an alternative, you could use this function, which takes an object
and a method name (as a string) and returns the class that provides the
definition of the method:

``` python
def find_defining_class(obj, meth_name):
    for ty in type(obj).mro():
        if meth_name in ty.__dict__:
            return ty
```

Here's an example:

``` python
>>> hand = Hand()
>>> print find_defining_class(hand, 'shuffle')
<class 'Card.Deck'>
```

So the `shuffle` method for this Hand is the one in `Deck`.

`find_defining_class` uses the `mro` method to get the list of class
objects (types) that will be searched for methods. "MRO" stands for
"method resolution order."

Here's a program design suggestion: whenever you override a method, the
interface of the new method should be the same as the old. It should
take the same parameters, return the same type, and obey the same
preconditions and postconditions. If you obey this rule, you will find
that any function designed to work with an instance of a superclass,
like a Deck, will also work with instances of subclasses like a Hand or
PokerHand.

If you violate this rule, your code will collapse like (sorry) a house
of cards.

## Glossary

```{=html}
<DL CLASS="description">
```
```{=html}
<DT CLASS="dt-description">
```
**encode:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
To represent one set of values using another set of values by
constructing a mapping between them.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**class attribute:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
An attribute associated with a class object. Class attributes are
defined inside a class definition but outside any method.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**instance attribute:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
An attribute associated with an instance of a class.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**veneer:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A method or function that provides a different interface to another
function without doing much computation.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**inheritance:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
The ability to define a new class that is a modified version of a
previously defined class.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**parent class:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
The class from which a child class inherits.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**child class:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A new class created by inheriting from an existing class; also called a
"subclass."

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**IS-A relationship:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
The relationship between a child class and its parent class.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**HAS-A relationship:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
The relationship between two classes where instances of one class
contain references to instances of the other.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**class diagram:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A diagram that shows the classes in a program and the relationships
between them.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
**multiplicity:**

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
A notation in a class diagram that shows, for a HAS-A relationship, how
many references there are to instances of another class.

```{=html}
</DD>
```
```{=html}
</DL>
```
## Exercises

### Exercise 5

*The following are the possible hands in poker, in increasing order of
value (and decreasing order of probability):*

```{=html}
<DL CLASS="description">
```
```{=html}
<DT CLASS="dt-description">
```
***pair:***

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
*two cards with the same rank*

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
****two pair:****

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
*two pairs of cards with the same rank*

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
****three of a kind:****

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
*three cards with the same rank*

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
****straight:****

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
*five cards with ranks in sequence (aces can be high or low, so
**\'`Ace-2-3-4-5`**\' is a straight and so is
**\'`10-Jack-Queen-King-Ace`**\', but **\'`Queen-King-Ace-2-3`**\' is
not.)*

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
****flush:****

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
*five cards with the same suit*

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
****full house:****

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
*three cards with one rank, two cards with another*

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
****four of a kind:****

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
*four cards with the same rank*

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-description">
```
****straight flush:****

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-description">
```
*five cards in sequence (as defined above) and with the same suit*

```{=html}
</DD>
```
```{=html}
</DL>
```
*The goal of these exercises is to estimate the probability of drawing
these various hands.*

-   *Download the following files from **\'`thinkpython.com/code`**\':*
    ```{=html}
    <DL CLASS="description">
    ```
    ```{=html}
    <DT CLASS="dt-description">
    ```
    ***`Card.py`***

    ```{=html}
    </DT>
    ```
    ```{=html}
    <DD CLASS="dd-description">
    ```
    *: A complete version of the **\'`Card`**\', **\'`Deck`**\' and
    **\'`Hand`**\' classes in this chapter.*

    ```{=html}
    </DD>
    ```
    ```{=html}
    <DT CLASS="dt-description">
    ```
    ****`PokerHand.py`****

    ```{=html}
    </DT>
    ```
    ```{=html}
    <DD CLASS="dd-description">
    ```
    \'\': An incomplete implementation of a class

that represents a poker hand, and some code that tests it.\'\'

```{=html}
</DD>
```
```{=html}
</DL>
```
-   **\'If you run*`PokerHand.py`***\'\'\', it deals six 7-card poker
    hands

and checks to see if any of them contains a flush. Read this code
carefully before you go on.\'\'\'\'

-   **\'Add methods
    to*`PokerHand.py`*named**\'**`'has_pair`**`'`\'\'\'\',

**\'**`'has_twopair`**`'`**\', etc. that return True or False according
to whether or not the hand meets the relevant criteria. Your code should
work correctly for "hands" that contain any number of cards (although 5
and 7 are the most common sizes).\'\'\'\'

-   **\'Write a method named*`classify`***\'\'\' that figures out

the highest-value classification for a hand and sets the
\'\'***\'`label`*****attribute accordingly. For example, a 7-card hand
might contain a flush and a pair; it should be labeled "flush".**\'

-   \'\'\'\'When you are convinced that your classification methods are

working, the next step is to estimate the probabilities of the various
hands. Write a function in \'\'***\'`PokerHand.py`*****that shuffles a
deck of cards, divides it into hands, classifies the hands, and counts
the number of times various classifications appear.**\'

-   \'\'\'\'Print a table of the classifications and their
    probabilities.

Run your program with larger and larger numbers of hands until the
output values converge to a reasonable degree of accuracy. Compare your
results to the values at
\'\'***\'`wikipedia.org/wiki/Hand_rankings`*****.**\'

### Exercise 6

*This exercise uses TurtleWorld from Chapter **\'4**\'. You will write
code that makes Turtles play tag. If you are not familiar with the rules
of tag, see **\'`wikipedia.org/wiki/Tag_(game)`**\'.*

-   \'\'Download **\'`thinkpython.com/code/Wobbler.py`**\' and run it.
    You

should see a TurtleWorld with three Turtles. If you press the
**\'Run**\' button, the Turtles wander at random.\'\'

-   \'\'Read the code and make sure you understand how it works.

The **\'`Wobbler`**\' class inherits from **\'`Turtle`**\', which means
that the **\'`Turtle`**\' methods **\'`lt`**\', **\'`rt`**\',
**\'`fd`**\' and **\'`bk`**\' work on Wobblers.The **\'`step`**\' method
gets invoked by TurtleWorld. It invokes **\'`steer`**\', which turns the
Turtle in the desired direction, **\'`wobble`**\', which makes a random
turn in proportion to the Turtle's clumsiness, and **\'`move`**\', which
moves forward a few pixels, depending on the Turtle's speed.\'\'

-   \'\'Create a file named **\'`Tagger.py`**\'. Import everything from

**\'`Wobbler`**\', then define a class named **\'`Tagger`**\' that
inherits from **\'`Wobbler`**\'. Call **`make_world`** passing the
**\'`Tagger`**\' class object as an argument.\'\'

-   \'\'Add a **\'`steer`**\' method to **\'`Tagger`**\' to override the
    one in

**\'`Wobbler`**\'. As a starting place, write a version that always
points the Turtle toward the origin. Hint: use the math function
**\'`atan2`**\' and the Turtle attributes **\'`x`**\', **\'`y`**\' and
**\'`heading`**\'.\'\'

-   \'\'Modify **\'`steer`**\' so that the Turtles stay in bounds.

For debugging, you might want to use the **\'Step**\' button, which
invokes **\'`step`**\' once on each Turtle.\'\'

-   \'\'Modify **\'`steer`**\' so that each Turtle points toward its
    nearest

neighbor. Hint: Turtles have an attribute, **\'`world`**\', that is a
reference to the TurtleWorld they live in, and the TurtleWorld has an
attribute, **\'`animals`**\', that is a list of all Turtles in the
world.\'\'

-   \'\'Modify **\'`steer`**\' so the Turtles play tag. You can add
    methods

to **\'`Tagger`**\' and you can override **\'`steer`**\' and
**`__init__`**, but you may not modify or override **\'`step`**\',
**\'`wobble`**\' or **\'`move`**\'. Also, **\'`steer`**\' is allowed to
change the heading of the Turtle but not the position.Adjust the rules
and your **\'`steer`**\' method for good quality play; for example, it
should be possible for the slow Turtle to tag the faster Turtles
eventually.\'\'

*You can get my solution from **\'`thinkpython.com/code/Tagger.py`**\'.*

```{=html}
</DIV>
```
```{=html}
<HR CLASS="footnoterule">
```
```{=html}
<DL CLASS="thefootnotes">
```
```{=html}
<DT CLASS="dt-thefootnotes">
```
1

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-thefootnotes">
```
See `wikipedia.org/wiki/Bottom_dealing`.

```{=html}
</DD>
```
```{=html}
<DT CLASS="dt-thefootnotes">
```
2

```{=html}
</DT>
```
```{=html}
<DD CLASS="dd-thefootnotes">
```
The diagrams I am using here are similar to UML (see
`wikipedia.org/wiki/Unified_Modeling_Language`), with a few
simplifications.

```{=html}
</DD>
```
```{=html}
</DL>
```