Browse by

How to Think Like a Computer Scientist

Learning with Python

ii

How to Think Like a Computer Scientist
Learning with Python

Allen Downey Jeﬀrey Elkner Chris Meyers

Green Tea Press
Wellesley, Massachusetts

Copyright c 2002 Allen Downey, Jeﬀrey Elkner, and Chris Meyers. Edited by Shannon Turlington and Lisa Cutler. Cover design by Rebecca Gimenez. Printing history: April 2002: First edition. Green Tea Press 1 Grove St. P.O. Box 812901 Wellesley, MA 02482 Permission is granted to copy, distribute, and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being “Foreword,” “Preface,” and “Contributor List,” with no Front-Cover Texts, and with no BackCover Texts. A copy of the license is included in the appendix entitled “GNU Free Documentation License.” The GNU Free Documentation License is available from www.gnu.org or by writing to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 021111307, USA.
A A The original form of this book is L TEX source code. Compiling this L TEX source has the eﬀect of generating a device-independent representation of a textbook, which can be converted to other formats and printed. A The L TEX source for this book is available from http://www.thinkpython.com

Foreword
By David Beazley As an educator, researcher, and book author, I am delighted to see the completion of this book. Python is a fun and extremely easy-to-use programming language that has steadily gained in popularity over the last few years. Developed over ten years ago by Guido van Rossum, Python’s simple syntax and overall feel is largely derived from ABC, a teaching language that was developed in the 1980’s. However, Python was also created to solve real problems and it borrows a wide variety of features from programming languages such as C++, Java, Modula-3, and Scheme. Because of this, one of Python’s most remarkable features is its broad appeal to professional software developers, scientists, researchers, artists, and educators. Despite Python’s appeal to many diﬀerent communities, you may still wonder “why Python?” or “why teach programming with Python?” Answering these questions is no simple task—especially when popular opinion is on the side of more masochistic alternatives such as C++ and Java. However, I think the most direct answer is that programming in Python is simply a lot of fun and more productive. When I teach computer science courses, I want to cover important concepts in addition to making the material interesting and engaging to students. Unfortunately, there is a tendency for introductory programming courses to focus far too much attention on mathematical abstraction and for students to become frustrated with annoying problems related to low-level details of syntax, compilation, and the enforcement of seemingly arcane rules. Although such abstraction and formalism is important to professional software engineers and students who plan to continue their study of computer science, taking such an approach in an introductory course mostly succeeds in making computer science boring. When I teach a course, I don’t want to have a room of uninspired students. I would much rather see them trying to solve interesting problems by exploring diﬀerent ideas, taking unconventional approaches, breaking the rules,

Although Python is still a young and evolving language. data structures. I don’t want to waste half of the semester trying to sort out obscure syntax problems. I am constantly faced with the daunting task of covering a lot of diﬃcult course material in a blistering nine week quarter.” I ﬁnd that using Python allows me to better focus on the actual topic at hand while allowing students to complete substantial class projects. Since Python is interpreted. students can be gradually introduced to topics such as procedural abstraction. I sometimes use Python for these exact same reasons in advanced graduate level computer science courses at the University of Chicago. Furthermore. David Beazley University of Chicago Author of the Python Essential Reference
. This book is an important step in that direction. In reading Jeﬀrey’s preface. Since Python fully supports procedures and classes.vi
Foreword
and learning from their mistakes.” Although these comments refer to his introductory course. In doing so. I have often found this approach to be counterproductive— especially when the course is about a topic unrelated to just “programming. and object-oriented programming—all of which are applicable to later courses on Java or C++. Python even borrows a number of features from functional programming languages and can be used to introduce concepts that would be covered in more detail in courses on Scheme and Lisp. Python comes with a large library of modules that can be used to do all sorts of tasks ranging from web-programming to graphics. However. or the several hundred ways that a program might generate a general protection fault. unintelligible compiler error messages. In these courses. beginners can pick up the language and start doing neat things almost immediately without getting lost in the problems of compilation and linking. Python can also serve as an excellent foundation for introducing important computer science concepts. I am struck by his comments that Python allowed him to see a “higher level of success and a lower level of frustration” and that he was able to “move faster with better results. One of the reasons why I like Python is that it provides a really nice balance between the practical and the conceptual. I believe that it has a bright future in education. Although it is certainly possible for me to inﬂict a lot of pain and suﬀering by using a language like C++. Having such a practical focus is a great way to engage students and it allows them to complete significant projects.

Up to this point. Pascal was the language of instruction in both our ﬁrst-year and AP courses. Its three authors—a college professor. a high school teacher.Preface
By Jeﬀ Elkner This book owes its existence to the collaboration made possible by the Internet and the free software movement. it is also an extremely diﬃcult language to learn and teach. the College Board’s Advanced Placement (AP) Computer Science exam was given in C++ for the ﬁrst time. In keeping with past practice of giving students two years of exposure to the same language. Two years later. we made the decision to switch to C++ in the ﬁrst-year course for the 1997-98 school year so that we would be in step with the College Board’s change for the AP course the following year. We think this book is a testament to the beneﬁts and future possibilities of this kind of collaboration. but we have been able to work closely together and have been aided by many wonderful folks who have donated their time and energy to helping make this book better. the framework for which has been put in place by Richard Stallman and the Free Software Foundation. As in many high schools throughout the country. Virginia. the decision to change languages had a direct impact on the computer science curriculum at Yorktown High School in Arlington. I found myself constantly ﬁghting with C++’s diﬃcult syntax and multiple ways of doing things.
How and why I came to use Python
In 1999. and I was losing many students unnecessarily as a
. and a professional programmer—have yet to meet face to face. While it is certainly a very powerful programming language. where I teach. I was convinced that C++ was a poor choice to use for introducing students to computer science.

which meant it could be used freely and modiﬁed to meet the needs of its user. Once I decided to use Python.
Finding a textbook
Having decided to use Python in both of my introductory computer science classes the following year. Python stood out as the best candidate for the job. Matt Ahrens. In two months he not only learned the language but wrote an application called pyTicket that enabled our staﬀ to report technology problems via the Web. It had to support both procedural and object-oriented programming. suggested that Python was the solution I was looking for. to give Python a try. Allen had already written a ﬁrst-year computer science textbook. I knew that Matt could not have ﬁnished an application of that scale in so short a time in C++. It emphasized the processes of thought involved in programming rather than the features of a particular language. the most pressing problem was the lack of an available textbook. but it had been released under a GNU public license. How to Think Like a Computer Scientist was not just an excellent book. so that students could use it at home regardless of their income. and one that had an active developer community around it. Convinced there had to be a better language choice for our ﬁrst-year class. Reading it immediately made me a better teacher. I wanted it to be free and available electronically. While I would not have been able to write a textbook on my own. When I investigated the choices with these goals in mind. it had to be easy to learn and teach. I knew immediately that I wanted to use it in my class. And most importantly. it occurred to me that I could translate Allen’s original Java version of the book into the new language. I asked one of Yorktown’s talented students. It was the clearest and most helpful computer science text I had seen. having Allen’s book to work from made it possible for me to do so. Earlier in the year.viii
Preface
result. I went looking for an alternative to C++. and this accomplishment. How to Think Like a Computer Scientist. I needed a language that would run on the machines in our Linux lab as well as on the Windows and Macintosh platforms most students have at home. combined with Matt’s positive assessment of Python. Free content came to the rescue.
. When I read this book. Richard Stallman had introduced me to Allen Downey. I wanted a language that was used by professional programmers. Both of us had written to Richard expressing an interest in developing free educational content.

" << endl. which in the C++ version of the book looks like this: #include <iostream. It is the traditional “hello. By the end of the school year he had created a companion project on our Website at http://www. The prospect of teaching the course had led Chris to the book. Oregon. This had the double beneﬁt of encouraging them to read the text more carefully and of getting the text thoroughly reviewed by its most important critics. world” program. guiding them beyond where I could take them. students using it to learn computer science. and my students played a big part in the process.org/obp called Python for Fun and was working with some of my most advanced students as a master teacher.ix at the same time demonstrating that the cooperative development model used so well in software could also work for educational content. I knew that someone with more real programming experience than I had would be needed to do it right. Since I could make instant changes whenever someone found a spelling error or diﬃcult passage. } in the Python version it becomes:
.
Introducing programming with Python
The process of translating and using How to Think Like a Computer Scientist for the past two years has conﬁrmed Python’s suitability for teaching beginning students. For the second half of the book on object-oriented programming.ibiblio. The book sat in an unﬁnished state for the better part of a year until the free software community once again provided the needed means for its completion.h> void main() { cout << "Hello. Working on this book for the last two years has been rewarding for both my students and me. I encouraged them to look for mistakes in the book by giving them a bonus point each time they made a suggestion that resulted in a change in the text. The ﬁrst example from the text illustrates this point. world. and he started helping out with it immediately. Chris is a professional programmer who started teaching a programming course last year using Python at Lane Community College in Eugene. Python greatly simpliﬁes programming examples and makes important programming ideas easier to teach. I received an email from Chris Meyers expressing interest in the book.

thereby introducing them to the programming environment. and I spent less time helping students with problems using them. The educational objectives at this point in the course are to introduce students to the idea of a programming statement and to get them to write their ﬁrst program. In Python a variable is a name that refers to a thing. The powerful and fundamental concept of a variable is already diﬃcult enough for beginning students (in both computer science and algebra). The C++ version has always forced me to choose between two unsatisfying options: either to explain the #include. world!” in the C++ version.x print "Hello. void main(). World!"
Preface
Even though this is a trivial example. There are thirteen paragraphs of explanation of “Hello.” and risk the same thing. Comparing the explanatory text of the program in each version of the book further illustrates what this means to the beginning student. or to tell them. More importantly. we will talk about it later. there are only two. Variables have to be declared with types at least in part because the size of the place to which they refer needs to be predetermined. This is a far more intuitive concept for beginning students and is much closer to the meaning of “variable” that they learned in their math courses. the missing eleven paragraphs do not deal with the “big ideas” in computer programming but with the minutia of C++ syntax. It thus creates the ability to put “ﬁrst things ﬁrst” pedagogically. having heard that computer programming is diﬃcult to learn. so many of the students seeing this example are looking at their ﬁrst program. Another example of how Python aids in the teaching and learning of programming is in its syntax for functions. I had much less diﬃculty teaching variables this year than I did in the past. One of the best examples of this is the way in which Python handles variables. Yorktown’s Computer Science I course has no prerequisites. My students have always had a great deal of diﬃculty understanding functions. Using a very high-level language like Python allows a teacher to postpone talking about low-level details of the machine until students have the background that they need to better make sense of the details. and nothing more. Whole paragraphs simply disappear from the Python version of the text because Python’s much clearer syntax renders them unnecessary. the idea of a variable is bound up with the hardware of the machine. In C++ a variable is a name for a place that holds a thing. Some of them are undoubtedly a little nervous. The Python program has exactly what is needed to do these things. the advantages of Python stand out. Thus. “Just don’t worry about all of that stuﬀ now. {. Bytes and addresses do not help the matter. I found this same thing happening throughout the book. in the Python version. and } statements and risk confusing or intimidating some of the students right at the start. The main problem centers around the
.

I expect the growth in the user community to continue and accelerate. Function deﬁnitions begin with the keyword def. we can increase the quality of materials available for our use and save valuable time. followed by the name of the function that you are deﬁning. I see a higher general level of success and a lower level of frustration than I experienced during the two years I taught C++. Please write to the authors at feedback@thinkpython. so I am now able to teach functions in less than half the time that it previously took me. parameter types.thinkpython. and many people have been contributing to the project by sending in materials for the companion Website at http://www.
Building a community
I have received email from all over the globe from people using this book to learn or to teach programming. arguments go with calls. I invite you to join our community and look forward to hearing from you. I move faster with better results. simply call (type) out its name. and the related distinction between a parameter and an argument. By working together.com.xi diﬀerence between a function deﬁnition and a function call. The emergence of this user community and the possibility it suggests for similar collaboration among educators have been the most exciting parts of working on this project for me. Python comes to the rescue with syntax that is nothing short of beautiful. begin with def. so I simply tell my students. Using Python has improved the eﬀectiveness of our computer science program for all students.com. A user community has begun to emerge. or reference and value parameters to get in the way. More students leave the course with the ability to create meaningful programs and with the positive attitude toward the experience of programming that this engenders. with better comprehension. There are no return types. Virginia
. With the publication of the book in print form.” Parameters go with deﬁnitions. “When you deﬁne a function. Jeﬀrey Elkner Yorktown High School Arlington. when you call a function.

xii
Preface
.

making it available to us. just by sending us a note. If we make a change due to your suggestion.
. Thank you! • Lloyd Hugh Allen sent in a correction to Section 8. we decided to express our gratitude in the form of a contributor list. • Yvon Boulianne sent in a correction of a semantic error in Chapter 5. and he initiated discussion on the technical aspects of interpreters.com.4. In the spirit of free software. So we would like to thank the Free Software Foundation for developing this license and.1. • Michael Conlon sent in a grammar correction in Chapter 2 and an improvement in style in Chapter 1. of course. but not necessarily free like free pizza. you will appear in the next version of the contributor list (unless you ask to be omitted). but we are doing our best to keep it up to date. If you should stumble across one. It came about because of a collaboration that would not have been possible without the GNU Free Documentation License. Impossible as it may seem after so many corrections. The email address is feedback@thinkpython. Unfortunately. • Jonah Cohen wrote the Perl scripts to convert the LaTeX source for this book into beautiful HTML. you should realize that each person here has spared you and all subsequent readers from the confusion of a technical error or a less-than-transparent explanation. there may still be errors in this book. We would also like to thank the more than 100 sharp-eyed and thoughtful readers who have sent us suggestions and corrections over the past few years. • Fred Bremmer submitted a correction in Section 2. we hope you will take a minute to contact us. If you have a chance to look through the list. this book is free like free speech.Contributor List
To paraphrase the philosophy of the Free Software Foundation. this list is not complete.

as well as kind words of encouragement.9 and 3.xiv
Contributor List
• Benoit Girard sent in a correction to a humorous mistake in Section 5. and indeed he should be listed as one of the principal editors of the text.10. • Simon Dicon Montford reported a missing function deﬁnition and several typos in Chapter 3. He has submitted numerous corrections.4. • Lee Harr submitted more corrections than we have room to list here. • Eddie Lam has sent in numerous corrections to Chapters 1.10. and 3. He also found errors in the increment function in Chapter 13. • Robin Shaw pointed out an error in Section 13. • David Pool sent in a typo in the glossary of Chapter 1. • Matthew J. 2. He also ﬁxed the Makeﬁle so that it creates an index the ﬁrst time it is run and helped us set up a versioning scheme. • Courtney Gleason and Katherine Smith wrote horsebet.
. • David Mayo pointed out that the word “unconsciously” in Chapter 1 needed to be changed to “subconsciously”. which was used as a case study in an earlier version of the book. • Michael Schmitt sent in a correction to the chapter on ﬁles and exceptions. • Man-Yong Lee sent in a correction to the example code in Section 2. • John Ouzts corrected the deﬁnition of “return value” in Chapter 3. Their program can now be found on the website.6. • Kevin Parks sent in valuable comments and suggestions as to how to improve the distribution of the book. where the printTime function was used in an example without being deﬁned.1. Moelter has been a long-time contributor who sent in numerous corrections and suggestions to the book. • Chris McAloon sent in several corrections to Sections 3. • David Kershaw ﬁxed the broken catTwice function in Section 3.py. • Paul Sleigh found an error in Chapter 7 and a bug in Jonah Cohen’s Perl script that generates HTML from LaTeX. • James Kaylin is a student using the text.

• Hayden McAfee caught a potentially confusing inconsistency between two examples.
. Smith caught several typos and is helping us prepare to update the book for Python 2. • Keith Verheyden sent in a correction in Chapter 3.2. • David Hutchins caught a typo in the Foreword. • Dr. he provided continual guidance in the early stages of the book. • Kalin Harvey suggested a clariﬁcation in Chapter 7 and caught some typos. • Ian Thomas and his students are using the text in a programming course. including two in the contributor list. • Peter Winstanley let us know about a longstanding error in our Latin in Chapter 3. • Chris Wrobel made corrections to the code in the chapter on ﬁle I/O and exceptions. • James Mayer sent us a whole slew of spelling and typographical errors. • Moshe Zadka has made invaluable contributions to this project. Michele Alzetta caught an error in Chapter 8 and sent some interesting pedagogic comments and suggestions about Fibonacci and Old Maid. • Christopher P. Snydal is testing the text in a course at Drew University. • Andy Mitchell caught a typo in Chapter 1 and a broken example in Chapter 2. He has contributed several valuable suggestions and corrections. and they have made numerous corrections and suggestions. • Tauhidul Hoque and Lex Berezhny created the illustrations in Chapter 1 and improved many of the other illustrations. They are the ﬁrst ones to test the chapters in the latter half of the book. • Angel Arnal is part of an international team of translators working on the Spanish version of the text. • Christoph Zwerschke sent several corrections and pedagogic suggestions. In addition to writing the ﬁrst draft of the chapter on Dictionaries. and explained the diﬀerence between gleich and selbe.xv • Craig T. He has also found several errors in the English version.

• Ben Logan sent in a number of typos and problems with translating the book into HTML. and he caught a couple of bad errors in Chapter 5. • D. • Julie Peters caught a typo in the Preface. Austria. a correction in printTime. • Brian Cain suggested several clariﬁcations in Chapters 2 and 3. • Ken found a ﬁstful of errors in Chapters 8. and a nice typo. J.xvi
Contributor List
• Gregor Lingl is teaching Python at a high school in Vienna. • Florin Oprina sent in an improvement in makeTime. • Ivo Wever caught a typo in Chapter 5 and suggested a clariﬁcation in Chapter 3. Webre suggested a clariﬁcation in Chapter 3. • Jason Armstrong saw the missing word in Chapter 2.
. He is working on a German translation of the book. 9 and 11. • Curtis Yanko suggested a clariﬁcation in Chapter 2. • Louis Cordier noticed a spot in Chapter 16 where the code didn’t match the text.

“The way of the program. the process of learning to program is an excellent opportunity to practice problemsolving skills. The single most important skill for a computer scientist is problem solving. That’s why this chapter is called.1
The Python programming language
The programming language you will be learning is Python. you will use programming as a means to an end. Python is an example of a high-level language. and test predictions. they design things. As you might infer from the name “high-level language. and Java. think creatively about solutions. Like mathematicians. C++. assembling components into systems and evaluating tradeoﬀs among alternatives. sometimes referred to as “machine languages” or “assembly
. This way of thinking combines some of the best features of mathematics. engineering. and express a solution clearly and accurately. computer scientists use formal languages to denote ideas (speciﬁcally computations).Chapter 1
The way of the program
The goal of this book is to teach you to think like a computer scientist.
1. As it turns out. Like scientists. a useful skill by itself. they observe the behavior of complex systems. that end will become clearer. Problem solving means the ability to formulate problems. form hypotheses.” On one level. Like engineers. and natural science. you will be learning to program. As we go along. Perl. On another level.” there are also lowlevel languages. other high-level languages you might have heard of are C.

There are two ways to use the interpreter: commandline mode and script mode. you can execute it repeatedly without further translation. it is much easier to program in a high-level language. which is a small disadvantage of high-level languages. computers can only execute programs written in low-level languages. meaning that they can run on diﬀerent kinds of computers with few or no modiﬁcations.” Loosely speaking. An interpreter reads a high-level program and executes it. Low-level languages are used only for a few specialized applications. almost all programs are written in high-level languages.
SOURCE CODE
INTERPRETER
OUTPUT
A compiler reads the program and translates it completely before the program starts running. Second. In command-line mode.2
The way of the program
languages. In this case. Low-level programs can run on only one kind of computer and have to be rewritten to run on another. Programs written in a high-level language take less time to write. alternately reading lines and performing computations. and the translated program is called the object code or the executable. It processes the program a little at a time. meaning that it does what the program says. This extra processing takes some time. they are shorter and easier to read. Due to these advantages. But the advantages are enormous. First. you type Python programs and the interpreter prints the result:
. Once a program is compiled. high-level languages are portable. Thus. and they are more likely to be correct. Two kinds of programs process high-level languages into low-level languages: interpreters and compilers.
SOURCE CODE
COMPILER
OBJECT CODE
EXECUTOR
OUTPUT
Python is considered an interpreted language because Python programs are executed by an interpreter. the high-level program is called the source code. programs written in a high-level language have to be processed before they can run.

Once you have a working program. Working on the command line is convenient for program development and testing. The details look diﬀerent in diﬀerent languages.
1.1. The next two lines are messages from the interpreter. such as solving a system of equations or ﬁnding the roots of a polynomial. Such a ﬁle is called a script.2 What is a program? $ python Python 1. For example. and the interpreter replied 2.py 2 In other development environments. Also. you can write a program in a ﬁle and use the interpreter to execute the contents of the ﬁle. you should store it in a script so you can execute or modify it in the future. The third line starts with >>>. To execute the program. but a few basic instructions appear in just about every language:
. The computation might be something mathematical.2
What is a program?
A program is a sequence of instructions that speciﬁes how to perform a computation. we used a text editor to create a ﬁle named latoya. which is the prompt the interpreter uses to indicate that it is ready.py. Amsterdam >>> print 1 + 1 2
3
The ﬁrst line of this example is the command that starts the Python interpreter. ﬁles that contain Python programs have names that end with . 16:32:16) Copyright 1991-1995 Stichting Mathematish Centrum. the details of executing programs may differ. Feb 1 2000. such as searching and replacing text in a document or (strangely enough) compiling a program. we have to tell the interpreter the name of the script: $ python latoya. most programs are more interesting than this one.5.py with the following contents: print 1 + 1 By convention. because you can type programs and execute them immediately. but it can also be a symbolic computation. Alternatively. We typed print 1 + 1. Most of the examples in this book are executed on the command line.2 (#1.

3. As you gain experience. a few syntax errors are not a signiﬁcant problem. no matter how complicated. cummings without spewing error messages. or some other device.1
Syntax errors
Python can only execute a program if the program is syntactically correct. Three kinds of errors can occur in a program: syntax errors. usually with some variation. otherwise. we can describe programming as the process of breaking a large. you will make fewer errors and ﬁnd them faster. For whimsical reasons. repetition: Perform some action repeatedly. Every program you’ve ever used. Syntax refers to the structure of a program and the rules about that structure. Thus. it often leads to errors.3
What is debugging?
Programming is a complex process. and semantic errors. e. So does this one For most readers. and you will not be able to run your program. During the ﬁrst few weeks of your programming career. though. Believe it or not. a sentence must begin with a capital letter and end with a period.4
The way of the program
input: Get data from the keyboard.
1. the process fails and returns an error message. That may be a little vague. you will probably spend a lot of time tracking down syntax errors.
. programming errors are called bugs and the process of tracking them down and correcting them is called debugging. Python is not so forgiving. in English. and because it is done by human beings. math: Perform basic mathematical operations like addition and multiplication. which is why we can read the poetry of e. Python will print an error message and quit. output: Display data on the screen or send data to a ﬁle or other device. runtime errors. that’s pretty much all there is to it. If there is a single syntax error anywhere in your program. For example. conditional execution: Check for certain conditions and execute the appropriate sequence of statements. a ﬁle. but we will come back to this topic later when we talk about algorithms. this sentence contains a syntax error. is made up of instructions that look more or less like these. complex task into smaller and smaller subtasks until the subtasks are simple enough to be performed with one of these basic instructions.
1. It is useful to distinguish between them in order to track them down more quickly.

Once you have an idea what is going wrong. it will run successfully. The meaning of the program (its semantics) is wrong. It will do something else. Conan Doyle. “When you have eliminated the impossible. As Sherlock Holmes pointed out. Debugging is also like an experimental science. so it might be a while before you encounter one. Although it can be frustrating. so called because the error does not appear until you run the program. so that you always have a working program.4
Experimental debugging
One of the most important skills you will acquire is debugging.2
Runtime errors
The second type of error is a runtime error.3. it will do what you told it to do.
1. and you have to infer the processes and events that led to the results you see. debugging them as you go.3. If your hypothesis was wrong. You are confronted with clues. programming and debugging are the same thing. That is. The problem is that the program you wrote is not the program you wanted to write. The Sign of Four) For some people. you modify your program and try again. but it will not do the right thing. and interesting parts of programming. then you can predict the result of the modiﬁcation. must be the truth. however improbable. you have to come up with a new one. and you take a step closer to a working program.3 What is debugging?
5
1. Identifying semantic errors can be tricky because it requires you to work backward by looking at the output of the program and trying to ﬁgure out what it is doing.1.3. whatever remains. debugging is like detective work. If there is a semantic error in your program. Runtime errors are rare in the simple programs you will see in the ﬁrst few chapters. programming is the process of gradually debugging a program until it does what you want. Speciﬁcally. These errors are also called exceptions because they usually indicate that something exceptional (and bad) has happened.
. debugging is one of the most intellectually rich.” (A. In some ways.
1. challenging. The idea is that you should start with a program that does something and make small modiﬁcations.3
Semantic errors
The third type of error is the semantic error. If your hypothesis was correct. in the sense that the computer will not generate any error messages.

4
Formal and natural languages
Natural languages are the languages that people speak. Formal languages tend to have strict rules about syntax. such as English.6
The way of the program
For example. the way the tokens are arranged. but 3=+6$ is not. “One of Linus’s earlier projects was a program that would switch between printing AAAA and BBBB.
. And most importantly: Programming languages are formal languages that have been designed to express computations. According to Larry Greenﬁeld. Tokens are the basic elements of the language. The statement 3=+6$ is structurally illegal because you can’t place a plus sign immediately after an equal sign. they evolved naturally. such as words. numbers. and French. but 2 Zz is not. pertaining to tokens and structure. molecular formulas have to have subscripts after the element name. This later evolved to Linux. 3 + 3 = 6 is a syntactically correct mathematical statement.
1. but it started out as a simple program Linus Torvalds used to explore the Intel 80386 chip. H 2 O is a syntactically correct chemical name. Similarly. For example. Chemists use a formal language to represent the chemical structure of molecules. For example. create what appears to be a well-structured English sentence with unrecognizable tokens in it. 2 Zz is not legal because there is no element with the abbreviation Zz. the notation that mathematicians use is a formal language that is particularly good at denoting relationships among numbers and symbols. As an exercise. and chemical elements. Similarly. They were not designed by people (although people try to impose some order on them). One of the problems with 3=+6$ is that $ is not a legal token in mathematics (at least as far as we know). The second type of syntax error pertains to the structure of a statement—that is. Linux is an operating system that contains thousands of lines of code. not before. Formal languages are languages that are designed by people for speciﬁc applications.” (The Linux Users’ Guide Beta Version 1) Later chapters will make more suggestions about debugging and other programming practices. Spanish. Syntax rules come in two ﬂavors. Then write another sentence with all valid tokens but with invalid structure.

Formal languages are less redundant and more concise. and the whole poem together creates an eﬀect or emotional response. structure. Here are some suggestions for reading programs (and other formal languages). Formal languages are designed to be nearly or completely unambiguous. you will understand the general implication of this sentence. and can be understood entirely by analysis of the tokens and structure. you can ﬁgure out what it means.” there is probably no shoe and nothing falling. so
. Assuming that you know what a shoe is and what it means to fall. remember that formal languages are much more dense than natural languages. and semantics—there are many diﬀerences: ambiguity: Natural languages are full of ambiguity. For example. and the structure contributes more meaning. so it takes longer to read them. the structure is very important. This process is called parsing. First. “The other shoe fell. which people deal with by using contextual clues and other information. or the semantics of the sentence.” you understand that “the other shoe” is the subject and “fell” is the verb. Also. People who grow up speaking a natural language—everyone—often have a hard time adjusting to formal languages. which means that any statement has exactly one meaning. Prose: The literal meaning of words is more important.1. they are often verbose. If I say. literalness: Natural languages are full of idiom and metaphor. Once you have parsed a sentence. Prose is more amenable to analysis than poetry but still often ambiguous. Ambiguity is not only common but often deliberate. As a result. redundancy: In order to make up for ambiguity and reduce misunderstandings. natural languages employ lots of redundancy. In some ways. when you hear the sentence. Although formal and natural languages have many features in common—tokens. syntax. you have to ﬁgure out what the structure of the sentence is (although in a natural language you do this subconsciously). Formal languages mean exactly what they say. “The other shoe fell. regardless of context. Programs: The meaning of a computer program is unambiguous and literal. the diﬀerence between formal and natural language is like the diﬀerence between poetry and prose.4 Formal and natural languages
7
When you read a sentence in English or a statement in a formal language. but more so: Poetry: Words are used for their sounds as well as for their meaning.

Some people judge the quality of a programming language by the simplicity of the “Hello.8
The way of the program
it is usually not a good idea to read from top to bottom. World!” program. can make a big diﬀerence in a formal language. they don’t appear in the result. It displays a value on the screen.
.5
The ﬁrst program
Traditionally. and expressing the solution. Python does about as well as possible. the ﬁrst program written in a new language is called “Hello. By this standard. learn to parse the program in your head. which you can get away with in natural languages. the details matter. Instead. ﬁnding a solution.
1. World!” In Python. left to right. Finally.
1.6
Glossary
problem solving: The process of formulating a problem. it looks like this: print "Hello. World!" This is an example of a print statement. In this case. Little things like spelling errors and bad punctuation. “Hello.” portability: A property of a program that can run on more than one kind of computer. also called “machine language” or “assembly language. high-level language: A programming language like Python that is designed to be easy for humans to read and write. World! The quotation marks in the program mark the beginning and end of the value. the result is the words Hello. low-level language: A programming language that is designed to be easy for a computer to execute. World!” because all it does is display the words. which doesn’t actually print anything on paper. interpret: To execute a program in a high-level language by translating it one line at a time. identifying the tokens and interpreting the structure.

runtime error: An error that does not occur until the program has started to execute but that prevents the program from continuing. parse: To examine a program and analyze the syntactic structure. script: A program stored in a ﬁle (usually one that will be interpreted). syntax error: An error in a program that makes it impossible to parse (and therefore impossible to interpret). bug: An error in a program. syntax: The structure of a program. all programming languages are formal languages. executable: Another name for object code that is ready to be executed. debugging: The process of ﬁnding and removing any of the three kinds of programming errors.6 Glossary
9
compile: To translate a program written in a high-level language into a lowlevel language all at once. in preparation for later execution. exception: Another name for a runtime error. semantic error: An error in a program that makes it do something other than what the programmer intended.1. natural language: Any one of the languages that people speak that evolved naturally. algorithm: A general process for solving a category of problems. formal language: Any one of the languages that people have designed for speciﬁc purposes. token: One of the basic elements of the syntactic structure of a program. program: A set of instructions that speciﬁes a computation. print statement: An instruction that causes the Python interpreter to display a value on the screen. source code: A program in a high-level language before being compiled. semantics: The meaning of a program. analogous to a word in a natural language.
. such as representing mathematical ideas or computer programs. object code: The output of the compiler after it translates the program.

10
The way of the program
.

strings belong to the type string and integers belong to the type int. and "Hello. The values we have seen so far are 2 (the result when we added 1 + 1). You (and the interpreter) can identify strings because they are enclosed in quotation marks. because these numbers are represented in a format called ﬂoatingpoint. World!". so-called because it contains a “string” of letters. Less obviously. The print statement also works for integers. >>> type("Hello. These values belong to diﬀerent types: 2 is an integer. >>> print 4 4 If you are not sure what type a value has. and "Hello. the interpreter can tell you. expressions and statements
2. World!" is a string. numbers with a decimal point belong to a type called float.Chapter 2
Variables.1 Values and types
A value is one of the fundamental things—like a letter or a number—that a program manipulates.
. World!") <type ’string’> >>> type(17) <type ’int’> Not surprisingly.

2. This kind of ﬁgure is called a state diagram because it shows what state each of the variables is in (think of it as the variable’s state of mind). which it prints consecutively.14159 to pi. The assignment statement creates new variables and gives them values: >>> message = "What’s up. This diagram shows the result of the assignment statements:
.2"? They look like numbers. but they are in quotation marks like strings.000 as a comma-separated list of three integers. The second gives the integer 17 to n. This is not a legal integer in Python. When you type a large integer. A variable is a name that refers to a value. but it is a legal expression: >>> print 1.000. and the third gives the ﬂoating-point number 3. Doc?" to a new variable named message.2") <type ’string’> They’re strings. expressions and statements
What about values like "17" and "3.2
Variables
One of the most powerful features of a programming language is the ability to manipulate variables.14159 This example makes three assignments. >>> type("17") <type ’string’> >>> type("3. that’s not what we expected at all! Python interprets 1. you might be tempted to use commas between groups of three digits. This is the ﬁrst example we have seen of a semantic error: the code runs without producing an error message. A common way to represent variables on paper is to write the name with an arrow pointing to the variable’s value. Doc?" >>> n = 17 >>> pi = 3.000.000.2) <type ’float’>
Variables.000 1 0 0 Well.12 >>> type(3. The ﬁrst assigns the string "What’s up.000. but it doesn’t do the “right” thing. as in 1.

remember that case matters.2. They can contain both letters and numbers. Variable names can be arbitrarily long. Although it is legal to use uppercase letters.3 Variable names and keywords
message n pi "What’s up. If you do. If you give a variable an illegal name. The underscore character ( ) can appear in a name. such as my name or price of tea in china. Doc? >>> print n 17 >>> print pi 3. you get a syntax error:
. >>> print message What’s up. Variables also have types. >>> type(message) <type ’string’> >>> type(n) <type ’int’> >>> type(pi) <type ’float’> The type of a variable is the type of the value it refers to.14159 In each case the result is the value of the variable. we can ask the interpreter what they are. by convention we don’t. It is often used in names with multiple words.14159
13
The print statement also works with variables. again. but they have to begin with a letter.
2. Doc?" 17 3. Bruce and bruce are diﬀerent variables.3
Variable names and keywords
Programmers generally choose names for their variables that are meaningful— they document what the variable is used for.

Python has twenty-eight keywords: and assert break class continue def del elif else except exec finally for from global if import in is lambda not or pass print raise return try while
You might want to keep this list handy. expressions and statements
>>> 76trombones = "big parade" SyntaxError: invalid syntax >>> more$ = 1000000 SyntaxError: invalid syntax >>> class = "Computer Science 101" SyntaxError: invalid syntax 76trombones is illegal because it does not begin with a letter. For example. if there is one. the results appear one at a time as the statements execute. We have seen two kinds of statements: print and assignment.14
Variables. Python executes it and displays the result. the script print 1 x = 2 print x produces the output 1 2 Again.4
Statements
A statement is an instruction that the Python interpreter can execute. When you type a statement on the command line. A script usually contains a sequence of statements. see if it is on this list. Assignment statements don’t produce a result. If there is more than one statement. Keywords deﬁne the language’s rules and structure. If the interpreter complains about one of your variable names and you don’t know why. the assignment statement produces no output.
2. and they cannot be used as variable names. the dollar sign. The result of a print statement is a value.
. But what’s wrong with class? It turns out that class is one of the Python keywords. more$ is illegal because it contains an illegal character.

2. but it doesn’t do anything. If you type an expression on the command line. A value all by itself is considered an expression. an expression all by itself is a legal statement. variables.5 Evaluating expressions
15
2. and operators. World!" 1 + 1 produces no output at all. In a script. >>> message = "What’s up. How would you change the script to display the values of these four expressions?
. which in this case is the contents of the string. it uses the same format you would use to enter a value. Doc?" >>> print message What’s up. Doc? When Python displays the value of an expression. variables. the interpreter evaluates it and displays the result: >>> 1 + 1 2 Although expressions contain values. Doc?" >>> message "What’s up. evaluating an expression is not quite the same thing as printing a value. In the case of strings. and operators.5
Evaluating expressions
An expression is a combination of values. that means that it includes the quotation marks. But the print statement prints the value of the expression. not every expression contains all of these elements. >>> 17 17 >>> x 2 Confusingly. and so is a variable. The script 17 3.2 "Hello.

multiplication. The acronym PEMDAS is a useful way to remember the order of operations:
. and ** is the symbol for exponentiation. but at least now the answer is approximately correct. Addition. Another alternative is to use ﬂoating-point division. expressions and statements
2.
2. it is replaced with its value before the operation is performed. A possible solution to this problem is to calculate a percentage rather than a fraction: >>> minute*100/60 98 Again the result is rounded down.98333. mean in Python what they mean in mathematics. which we get to in Chapter 3. the result must also be an integer. and exponentiation all do what you expect. even in cases like this where the next integer is very close. -. the order of evaluation depends on the rules of precedence. The asterisk (*) is the symbol for multiplication. subtraction. not 0. The reason for the discrepancy is that Python is performing integer division. integer division always rounds down. When a variable name appears in the place of an operand. The following operation has an unexpected result: >>> minute = 59 >>> minute/60 0 The value of minute is 59. and the use of parenthesis for grouping.7
Order of operations
When more than one operator appears in an expression. When both of the operands are integers. and in conventional arithmetic 59 divided by 60 is 0. but you might be surprised by division. The values the operator uses are called operands. Python follows the same precedence rules for its mathematical operators that mathematics does. The following are all legal Python expressions whose meaning is more or less clear: 20+32 hour-1 hour*60+minute minute/60 5**2 (5+9)*(15-7)
The symbols +.6
Operators and operands
Operators are special symbols that represent computations like addition and multiplication. and by convention.16
Variables. and /.

which also have the same precedence. and 2/3-1 is -1. Since expressions in parentheses are evaluated ﬁrst. which is wrong. which is 59. For example: fruit = "banana" bakedGood = " nut bread" print fruit + bakedGood The output of this program is banana nut bread. even if the strings look like numbers.8 Operations on strings
17
• Parentheses have the highest precedence and can be used to force an expression to evaluate in the order you want. you cannot perform mathematical operations on strings. So 2*3-1 yields 5 rather than 4. and (1+1)**(5-2) is 8. the + operator represents concatenation. • Exponentiation has the next highest precedence. • Operators with the same precedence are evaluated from left to right.2. For strings. the multiplication happens ﬁrst. and 3*1**3 is 3 and not 27. although it does not do exactly what you might expect. which means joining the two operands by linking them end-to-end.
2. and is necessary to produce the space between the concatenated strings. • Multiplication and Division have the same precedence. One of the operands has to be a string. For example. If the operations had been evaluated from right to left. the result would have been 59*1. not 1 (remember that in integer division. 2/3=0). You can also use parentheses to make an expression easier to read.8
Operations on strings
In general. yielding 5900/60. which is higher than Addition and Subtraction. The * operator also works on strings. "Fun"*3 is "FunFunFun". as in (minute * 100) / 60. The space before the word nut is part of the string. the other has to be an integer. The following are illegal (assuming that message has type string): message-1 "Hello"/123 message*"Hello" "15"+2
Interestingly. 2 * (3-1) is 4. even though it doesn’t change the result. the + operator does work with strings. so 2**1+1 is 3 and not 4. So in the expression minute*100/60. which in turn yields 98. it performs repetition.
.

expressions.9
Composition
So far. this interpretation of + and * makes sense by analogy with addition and multiplication. or why. the following is illegal: minute+1 = hour. The point is that any expression involving numbers. Formal languages are dense. For example. they get more diﬃcult to read. Can you think of a property that addition and multiplication have that string concatenation and repetition do not?
2. the addition has to happen before the printing. we have looked at the elements of a program—variables. but you will see other examples where composition makes it possible to express complex computations neatly and concisely. it turns out we can do both at the same time: >>> 20 print 17 + 3
In reality. not an expression. and variables can be used inside a print statement. One of the most useful features of programming languages is their ability to take small building blocks and compose them. so the actions aren’t actually happening at the same time. Just as 4*3 is equivalent to 4+4+4. and statements—in isolation. You’ve already seen an example of this: print "Number of minutes since midnight: ".18
Variables. and it is often diﬃcult to look at a piece of code and ﬁgure out what it is doing. the left-hand side of an assignment statement has to be a variable name. and it is.
. expressions and statements
On one hand. we know how to add numbers and we know how to print. without talking about how to combine them.
2. So. Warning: There are limits on where you can use certain expressions.10
Comments
As programs get bigger and more complicated. On the other hand. we expect "Fun"*3 to be the same as "Fun"+"Fun"+"Fun". hour*60+minute You can also put arbitrary expressions on the right-hand side of an assignment statement: percentage = (minute * 100) / 60 This ability may not seem impressive now. strings. For example. there is a signiﬁcant way in which string concatenation and repetition are diﬀerent from integer addition and multiplication.

2. statement: A section of code that represents a command or action. and while as variable names. the comment appears on a line by itself. type: A set of values.
. and strings (type string). ﬂoating-point: A format for representing numbers with fractional parts. the types you have seen are integers (type int). operand: One of the values on which an operator operates. ﬂoating-point numbers (type float). operator: A special symbol that represents a simple computation like addition. You can also put comments at the end of a line: percentage = (minute * 100) / 60 # caution: integer division
Everything from the # to the end of the line is ignored—it has no eﬀect on the program. def. variable: A name that refers to a value. keyword: A reserved word that is used by the compiler to parse a program. it is a good idea to add notes to your programs to explain in natural language what the program is doing. state diagram: A graphical representation of a set of variables and the values to which they refer. The type of a value determines how it can be used in expressions. So far. and they are marked with the # symbol: # compute the percentage of the hour that has elapsed percentage = (minute * 100) / 60 In this case.11
Glossary
value: A number or string (or other thing to be named later) that can be stored in a variable or computed in an expression. So far. the statements you have seen are assignments and print statements. you cannot use keywords like if. or string concatenation.2. it reminds the reader about the ever-surprising behavior of integer division. These notes are called comments. In this case. The message is intended for the programmer or for future programmers who might use this code. assignment: A statement that assigns a value to a variable. multiplication.11 Glossary
19
For this reason.

20

Variables, expressions and statements

expression: A combination of variables, operators, and values that represents a single result value. evaluate: To simplify an expression by performing the operations in order to yield a single value. integer division: An operation that divides one integer by another and yields an integer. Integer division yields only the whole number of times that the numerator is divisible by the denominator and discards any remainder. rules of precedence: The set of rules governing the order in which expressions involving multiple operators and operands are evaluated. concatenate: To join two operands end-to-end. composition: The ability to combine simple expressions and statements into compound statements and expressions in order to represent complex computations concisely. comment: Information in a program that is meant for other programmers (or anyone reading the source code) and has no eﬀect on the execution of the program.

Chapter 3

Functions
3.1 Function calls

You have already seen one example of a function call: >>> type("32") <type ’string’> The name of the function is type, and it displays the type of a value or variable. The value or variable, which is called the argument of the function, has to be enclosed in parentheses. It is common to say that a function “takes” an argument and “returns” a result. The result is called the return value. Instead of printing the return value, we could assign it to a variable: >>> betty = type("32") >>> print betty <type ’string’> As another example, the id function takes a value or a variable and returns an integer that acts as a unique identiﬁer for the value: >>> id(3) 134882108 >>> betty = 3 >>> id(betty) 134882108 Every value has an id, which is a unique number related to where it is stored in the memory of the computer. The id of a variable is the id of the value to which it refers.

22

Functions

3.2

Type conversion

Python provides a collection of built-in functions that convert values from one type to another. The int function takes any value and converts it to an integer, if possible, or complains otherwise: >>> int("32") 32 >>> int("Hello") ValueError: invalid literal for int(): Hello int can also convert ﬂoating-point values to integers, but remember that it truncates the fractional part: >>> int(3.99999) 3 >>> int(-2.3) -2 The float function converts integers and strings to ﬂoating-point numbers: >>> float(32) 32.0 >>> float("3.14159") 3.14159 Finally, the str function converts to type string: >>> str(32) ’32’ >>> str(3.14149) ’3.14149’ It may seem odd that Python distinguishes the integer value 1 from the ﬂoatingpoint value 1.0. They may represent the same number, but they belong to diﬀerent types. The reason is that they are represented diﬀerently inside the computer.

3.3

Type coercion

Now that we can convert between types, we have another way to deal with integer division. Returning to the example from the previous chapter, suppose we want to calculate the fraction of an hour that has elapsed. The most obvious expression, minute / 60, does integer arithmetic, so the result is always 0, even at 59 minutes past the hour.

3.4 Math functions

23

One solution is to convert minute to ﬂoating-point and do ﬂoating-point division: >>> minute = 59 >>> float(minute) / 60 0.983333333333 Alternatively, we can take advantage of the rules for automatic type conversion, which is called type coercion. For the mathematical operators, if either operand is a float, the other is automatically converted to a float: >>> minute = 59 >>> minute / 60.0 0.983333333333 By making the denominator a float, we force Python to do ﬂoating-point division.

3.4

Math functions

In mathematics, you have probably seen functions like sin and log, and you have learned to evaluate expressions like sin(pi/2) and log(1/x). First, you evaluate the expression in parentheses (the argument). For example, pi/2 is approximately 1.571, and 1/x is 0.1 (if x happens to be 10.0). Then, you evaluate the function itself, either by looking it up in a table or by performing various computations. The sin of 1.571 is 1, and the log of 0.1 is -1 (assuming that log indicates the logarithm base 10). This process can be applied repeatedly to evaluate more complicated expressions like log(1/sin(pi/2)). First, you evaluate the argument of the innermost function, then evaluate the function, and so on. Python has a math module that provides most of the familiar mathematical functions. A module is a ﬁle that contains a collection of related functions grouped together. Before we can use the functions from a module, we have to import them: >>> import math To call one of the functions, we have to specify the name of the module and the name of the function, separated by a dot, also known as a period. This format is called dot notation.

The ﬁrst statement sets decibel to the logarithm of 17, base 10. There is also a function called log that takes logarithm base e. The third statement ﬁnds the sine of the value of the variable angle. sin and the other trigonometric functions (cos, tan, etc.) take arguments in radians. To convert from degrees to radians, divide by 360 and multiply by 2*pi. For example, to ﬁnd the sine of 45 degrees, ﬁrst calculate the angle in radians and then take the sine: >>> degrees = 45 >>> angle = degrees * 2 * math.pi / 360.0 >>> math.sin(angle) 0.707106781187 The constant pi is also part of the math module. If you know your geometry, you can check the previous result by comparing it to the square root of two divided by two: >>> math.sqrt(2) / 2.0 0.707106781187

3.5

Composition

Just as with mathematical functions, Python functions can be composed, meaning that you use one expression as part of another. For example, you can use any expression as an argument to a function: >>> x = math.cos(angle + pi/2) This statement takes the value of pi, divides it by 2, and adds the result to the value of angle. The sum is then passed as an argument to the cos function. You can also take the result of one function and pass it as an argument to another: >>> x = math.exp(math.log(10.0)) This statement ﬁnds the log base e of 10 and then raises e to that power. The result gets assigned to x.

In the examples in this book. This operation is speciﬁed in a function deﬁnition. The ﬁrst couple of functions we are going to write have no parameters. because it allows us to use the functions without worrying about the details of their deﬁnitions. we have only been using the functions that come with Python. The empty parentheses indicate that it has no parameters.3. we will use an indentation of two spaces. In the context of programming.) The syntax for calling the new function is the same as the syntax for built-in functions: print "First Line. a function is a named sequence of statements that performs a desired operation." newLine() print "Second Line. if any.6
Adding new functions
So far. The list of parameters speciﬁes what information. This is a good thing. Creating new functions to solve your particular problems is one of the most useful things about a general-purpose programming language. The functions we have been using so far have been deﬁned for us. except that you can’t use a name that is a Python keyword. but it is also possible to add new functions. There can be any number of statements inside the function. you have to provide in order to use the new function. The syntax for a function deﬁnition is: def NAME( LIST OF PARAMETERS ): STATEMENTS You can make up any names you want for the functions you create. (That’s what happens when you use a print command without any arguments. but they have to be indented from the left margin. It contains only a single statement. so the syntax looks like this: def newLine(): print This function is named newLine. and these deﬁnitions have been hidden.6 Adding new functions
25
3. which outputs a newline character." The output of this program is:
.

it may not be clear why it is worth the trouble to create all of these new functions.26 First line. What if we wanted more space between the lines? We could call the same function repeatedly: print "First Line. Python knows that it is not part of the function." threeLines() print "Second Line. Since the next statement is not indented. You should notice a few things about this program: 1. You can call the same procedure repeatedly.
." Or we could write a new function named threeLines that prints three new lines: def threeLines(): newLine() newLine() newLine() print "First Line. but this example demonstrates two: • Creating a new function gives you an opportunity to name a group of statements." This function contains three statements. in this case threeLines calls newLine. Second line. You can have one function call another function. 2. Functions can simplify a program by hiding a complex computation behind a single command and by using English words in place of arcane code. So far. all of which are indented by two spaces. it is quite common and useful to do so." newLine() newLine() newLine() print "Second Line.
Functions
Notice the extra space between the two lines. Actually. there are a lot of reasons. In fact.

the function deﬁnition has to be executed before the ﬁrst time it is called. What happens when you run this program?
. Run the program and see what error message you get.6. As an exercise. As an exercise. In other words. How would you print twentyseven new lines?
3.7
Deﬁnitions and use
Pulling together the code fragments from Section 3. move the last three lines of this program to the top. and the function deﬁnition generates no output.3. As you might expect.7 Deﬁnitions and use
27
• Creating a new function can make a program smaller by eliminating repetitive code. a short way to print nine consecutive new lines is to call threeLines three times. As another exercise." threeLines() print "Second Line. but the eﬀect is to create the new function. so the function calls appear before the deﬁnitions. write a function called nineLines that uses threeLines to print nine blank lines. Function deﬁnitions get executed just like other statements. start with the working version of the program and move the deﬁnition of newLine after the deﬁnition of threeLines. For example. you have to create a function before you can execute it." This program contains two function deﬁnitions: newLine and threeLines. the whole program looks like this: def newLine(): print def threeLines(): newLine() newLine() newLine() print "First Line. The statements inside the function do not get executed until the function is called.

Python is adept at keeping track of where it is. Thus. the values that control how the function does its job. which is called the ﬂow of execution. and then comes back to pick up where it left oﬀ. the ﬂow jumps to the ﬁrst line of the called function. But while executing that new function. sin takes a numeric value as an argument. Inside the function.28
Functions
3. until you remember that one function can call another.8
Flow of execution
In order to ensure that a function is deﬁned before its ﬁrst use. Some functions take more than one argument. the base and the exponent. you can deﬁne one function inside another. Function calls are like a detour in the ﬂow of execution. you have to indicate what the number is. the program picks up where it left oﬀ in the function that called it.9
Parameters and arguments
Some of the built-in functions you have used require arguments. so each time a function completes. if you want to ﬁnd the sine of a number. the program might have to execute yet another function! Fortunately. Although it is not common. For example. Instead of going to the next statement. For example. In this case. When it gets to the end of the program. pow takes two arguments. Statements are executed one at a time. the program might have to execute the statements in another function. Execution always begins at the ﬁrst statement of the program.
3. the inner deﬁnition isn’t executed until the outer function is called. follow the ﬂow of execution. Here is an example of a user-deﬁned function that takes a parameter: def printTwice(bruce): print bruce. Instead. but remember that statements inside the function are not executed until the function is called. it terminates. the values that are passed get assigned to variables called parameters. you have to know the order in which statements are executed. While in the middle of one function. in order from top to bottom. executes all the statements there. What’s the moral of this sordid tale? When you read a program. That sounds simple enough. bruce
. Function deﬁnitions do not alter the ﬂow of execution of the program. don’t read from top to bottom.

it’s a float. the half a bee. In the third. It doesn’t matter what the value was called back home (in the caller). but in general.0 -1. so we can use any kind of expression as an argument for printTwice: >>> printTwice(’Spam’*4) SpamSpamSpamSpam SpamSpamSpamSpam >>> printTwice(math.’ >>> printTwice(michael) Eric. The same rules of composition that apply to built-in functions also apply to user-deﬁned functions. We can also use a variable as an argument: >>> michael = ’Eric. here in printTwice. The name of the variable we pass as an argument (michael) has nothing to do with the name of the parameter (bruce). followed by a newline. the half a bee.14159 3. the half a bee.0 As usual.cos(math.
. As an exercise. Eric. The name bruce was chosen to suggest that the name you give a parameter is up to you.14159 In the ﬁrst function call. we call everybody bruce.14159) 3. the argument is a string. and the type of quote not used to enclose the string can be used inside it as part of the string. you want to choose something more illustrative than bruce. so printTwice prints SpamSpamSpamSpam SpamSpamSpamSpam instead of ’Spam’*4 ’Spam’*4. The function printTwice works for any type that can be printed: >>> printTwice(’Spam’) Spam Spam >>> printTwice(5) 5 5 >>> printTwice(3.9 Parameters and arguments
29
This function takes a single argument and assigns it to a parameter named bruce.pi)) -1. Hint: strings can be enclosed in either single or double quotes. write a call to printTwice that does print ’Spam’*4 ’Spam’*4. In the second. it’s an integer.3. Notice something very important here. The value of the parameter (at this point we have no idea what it will be) is printed twice. the expression is evaluated before the function is run.

30
Functions
3. it is sometimes useful to draw a stack diagram.11
Stack diagrams
To keep track of which variables can be used where. outside the function printTwice. it only exists inside the function. A frame is a box with the name of a function beside it and the parameters and variables of the function inside it. but they also show the function to which each variable belongs. and you cannot use it outside. Like state diagrams. concatenates them. For example. The stack diagram for the previous example looks like this:
. and then prints the result twice. we get an error: >>> print cat NameError: cat Parameters are also local.
3. stack diagrams show the value of each variable. If we try to print it." catTwice(chant1. Each function is represented by a frame. For example: def catTwice(part1. " chant2 = "Dona eis requiem. Python will complain. the variable cat is destroyed. Dona eis requiem.10
Variables and parameters are local
When you create a local variable inside a function. Pie Jesu domine. Dona eis requiem.
When catTwice terminates. part2): cat = part1 + part2 printTwice(cat) This function takes two arguments. We can call the function with two strings: >>> >>> >>> Pie chant1 = "Pie Jesu domine. chant2) Jesu domine. If you try to use it. there is no such thing as bruce.

. and the name of the function that called that. all the way back to main .11 Stack diagrams
__main__ chant1 chant2 catTwice part1 part2 cat printTwice bruce "Pie Jesu domine. part1 has the same value as chant1." "Pie Jesu domine. part2 has the same value as chant2. which is a special name for the topmost function.py".3. line 13." "Dona eis requiem. Dona eis requiem. Python prints the name of the function. and the name of the function that called it. Each parameter refers to the same value as its corresponding argument. It tells you what program ﬁle the error occurred in. It’s not a coincidence. line 9. For example." "Dona eis requiem. printTwice was called by catTwice. and what line. chant2) File "test. Notice the similarity between the traceback and the stack diagram. and bruce has the same value as cat. So. and catTwice was called by main . If an error occurs during a function call. in printTwice print cat NameError: cat This list of functions is called a traceback.py". in catTwice printTwice(cat) File "test."
31
The order of the stack shows the ﬂow of execution. we get a NameError: Traceback (innermost last): File "test. When you create a variable outside of any function. It also shows the line of code that caused the error." "Pie Jesu domine. and what functions were executing at the time. Dona eis requiem." "Pie Jesu domine.py". line 5. it belongs to main . in __main__ catTwice(chant1. if we try to access cat from within printTwice.

the return value is the value of the expression. type conversion: An explicit statement that takes a value of one type and computes a corresponding value of another type. perform an action but don’t return a value. As an exercise. specifying the module name followed by a dot (period) and the function name. dot notation: The syntax for calling a function in another module. type coercion: A type conversion that happens automatically according to Python’s coercion rules. What happens if you use a function without a result as part of an expression. and we’ll do it in Chapter 5. Can you write functions that yield results. such as newLine() + 7? 3. or are you stuck with simple function like newLine and printTwice? The answer to the third question is yes.13
Glossary
function call: A statement that executes a function. If a function call is used as an expression.
3.32
Functions
3. module: A ﬁle that contains a collection of related functions and classes. answer the other two questions by trying them out. a good way to ﬁnd out is to ask the interpreter. It consists of the name of the function followed by a list of arguments enclosed in parentheses. argument: A value provided to a function when the function is called. like newLine. you don’t assign it to a variable or use it as part of a larger expression)? 2. return value: The result of a function. That raises some questions: 1.12
Functions with results
You might have noticed by now that some of the functions we are using.
.. yield results. such as the math functions. What happens if you call a function and you don’t do anything with the result (i.e. Other functions. When you have a question about what is legal or illegal in Python. This value is assigned to the corresponding parameter in the function.

frame: A box in a stack diagram that represents a function call. and the values to which they refer. specifying its name. stack diagram: A graphical representation of a stack of functions. parameter: A name used inside a function to refer to the value passed as an argument.13 Glossary
33
function: A named sequence of statements that performs some useful operation.3. Functions may or may not take parameters and may or may not produce a result. function deﬁnition: A statement that creates a new function. printed when a runtime error occurs. their variables. and the statements it executes. A local variable can only be used inside its function. ﬂow of execution: The order in which statements are executed during a program run. It contains the local variables and parameters of the function.
. traceback: A list of the functions that are executing. parameters. local variable: A variable deﬁned inside a function.

34
Functions
.

the modulus operator is a percent sign (%).
. In Python. For example. In Python. x % 10 yields the right-most digit of x (in base 10). an expression that is true has the value 1. For example. and an expression that is false has the value 0.2
Boolean expressions
A boolean expression is an expression that is either true or false. Similarly x % 100 yields the last two digits. Also.
4. The syntax is the same as for other operators: >>> >>> 2 >>> >>> 1 quotient = 7 / 3 print quotient remainder = 7 % 3 print remainder
So 7 divided by 3 is 2 with 1 left over. The modulus operator turns out to be surprisingly useful. then x is divisible by y. you can extract the right-most digit or digits from a number.1 The modulus operator
The modulus operator works on integers (and integer expressions) and yields the remainder when the ﬁrst operand is divided by the second.Chapter 4
Conditionals and recursion
4. you can check whether one number is divisible by another—if x % y is zero.

the others are: x x x x x != y > y < y >= y <= y # # # # # x x x x x is is is is is not equal to greater than less than y greater than less than or y y or equal to y equal to y
Although these operations are probably familiar to you. so not(x > y) is true if (x > y) is false. For example. if x is less than or equal to y. the operands of the logical operators should be boolean expressions.3
Logical operators
There are three logical operators: and. the not operator negates a boolean expression. Strictly speaking.36
Conditionals and recursion
The operator == compares two values and produces a boolean expression: >>> 5 == 5 1 >>> 5 == 6 0 In the ﬁrst statement. and not. The == operator is one of the comparison operators. Any nonzero number is interpreted as “true. in the second statement. Finally. The semantics (meaning) of these operators is similar to their meaning in English. the two operands are equal. so we get 0 (false). if the number is divisible by 2 or 3. A common error is to use a single equal sign (=) instead of a double equal sign (==). or.” >>> >>> 1 >>> >>> 0 x = 5 x and 1 y = 0 y and 1
. that is. but Python is not very strict. so the expression evaluates to 1 (true). Also. n%2 == 0 or n%3 == 0 is true if either of the conditions is true. there is no such thing as =< or =>. 5 is not equal to 6.
4. Remember that = is an assignment operator and == is a comparison operator. x > 0 and x < 10 is true only if x is greater than 0 and less than 10. the Python symbols are diﬀerent from the mathematical symbols. that is.

The indented statements that follow are called a block. then the indented statement gets executed. but there has to be at least one.5
Alternative execution
A second form of the if statement is alternative execution.. "is odd"
. If not. this sort of thing is not considered good style. The simplest form is the if statement: if x > 0: print "x is positive" The boolean expression after the if statement is called the condition. Occasionally. There is no limit on the number of statements that can appear in the body of an if statement. nothing happens.. "is even" else: print x. we almost always need the ability to check conditions and change the behavior of the program accordingly. Conditional statements give us this ability. Like other compound statements. The ﬁrst unindented statement marks the end of the block. In that case.4 Conditional execution
37
In general. you should do it explicitly.4
Conditional execution
In order to write useful programs. in which there are two possibilities and the condition determines which one gets executed. The syntax looks like this: if x%2 == 0: print x. If it is true. which does nothing. A statement block inside a compound statement is called the body of the statement.
4. the if statement is made up of a header and a block of statements: HEADER: FIRST STATEMENT . it is useful to have a body with no statements (usually as a place keeper for code you haven’t written yet). If you want to compare a value to zero.4. you can use the pass statement. LAST STATEMENT The header begins on a new line and ends with a colon (:).
4.

exactly one branch will be executed. If the condition is false. "are equal" elif is an abbreviation of “else if. exactly one of the alternatives will be executed. "is less than". but the last branch has to be an else statement: if choice == ’A’: functionA() elif choice == ’B’: functionB() elif choice == ’C’: functionC() else: print "Invalid choice. "is even" else: print x."
. then we know that x is even. y else: print x. >>> printParity(17) >>> printParity(y+1)
4. "is odd" For any value of x. There is no limit of the number of elif statements. Since the condition must be true or false. y elif x > y: print x.” Again. As an aside. you might “wrap” this code in a function: def printParity(x): if x%2 == 0: print x. "is greater than". y. because they are branches in the ﬂow of execution.6
Chained conditionals
Sometimes there are more than two possibilities and we need more than two branches. "and". and the program displays a message to that eﬀect. The alternatives are called branches. printParity displays an appropriate message. if you need to check the parity (evenness or oddness) of numbers often. One way to express a computation like that is a chained conditional: if x < y: print x.38
Conditionals and recursion
If the remainder when x is divided by 2 is 0. When you call it. you can provide any integer expression as an argument. the second set of statements is executed.

Those two branches are both output statements. so Python provides an alternative syntax that is similar to mathematical notation:
. Even if more than one condition is true. only the ﬁrst true branch executes. For example. The ﬁrst branch contains a simple output statement.7 Nested conditionals
39
Each condition is checked in order. the next is checked. "are equal" else: if x < y: print x. If the ﬁrst is false. and so on. Although the indentation of the statements makes the structure apparent. the corresponding branch executes. In general. and the statement ends. As an exercise.7
Nested conditionals
One conditional can also be nested within another. We could have written the trichotomy example as follows: if x == y: print x.
4.4. y) and dispatch(choice). The second branch contains another if statement. "and". it is a good idea to avoid them when you can. so we can use the and operator: if 0 < x and x < 10: print "x is a positive single digit. y. nested conditionals become diﬃcult to read very quickly. "is greater than". "is less than". which has two branches of its own. we can rewrite the following code using a single conditional: if 0 < x: if x < 10: print "x is a positive single digit. wrap these examples in functions called compare(x. y The outer conditional contains two branches." The print statement is executed only if we make it past both the conditionals. If one of them is true. Logical operators often provide a way to simplify nested conditional statements." These kinds of conditions are common. y else: print x. although they could have been conditional statements as well.

4. The ﬁrst thing it does is check whether x is less than or equal to 0. you have to import it. and you have seen several examples of that." return result = math.8
The return statement
The return statement allows you to terminate the execution of a function before you reach the end. but it turns out to be one of the most magical and interesting things a program can do. please. look at the following function: def countdown(n): if n == 0: print "Blastoff!" else: print n countdown(n-1)
. and the remaining lines of the function are not executed.40 if 0 < x < 10: print "x is a positive single digit.log(x) print "The log of x is". One reason to use it is if you detect an error condition: import math def printLogarithm(x): if x <= 0: print "Positive numbers only. Remember that to use a function from the math module.
4.9
Recursion
We mentioned that it is legal for one function to call another. The ﬂow of execution immediately returns to the caller. For example. result The function printLogarithm takes a parameter named x. We neglected to mention that it is also legal for a function to call itself."
Conditionals and recursion
This condition is semantically the same as the compound boolean expression and the nested conditional. in which case it displays an error message and then uses return to exit the function. It may not be obvious why that is a good thing.

“Blastoﬀ!” and then returns.. The execution of countdown begins with n=1. The countdown that got n=2 returns. “Blastoﬀ!” Otherwise. and then calls itself. The countdown that got n=3 returns. or 106. The execution of countdown begins with n=2. and then calls itself. it outputs the value 3. it outputs n and then calls a function named countdown—itself—passing n-1 as an argument.9 Recursion
41
countdown expects the parameter. The countdown that got n=1 returns. and since n is not 0. and then calls itself. and since n is 0. If n is 0.. it outputs the value 1.. What happens if we call this function like this: >>> countdown(3) The execution of countdown begins with n=3. to be a positive integer. and since n is not 0... n. it outputs the value 2. A better alternative would be this: main (what a trip). And then you’re back in this: 3 2 1 Blastoff! As a second example.4. look again at the functions newLine and threeLines: def newline(): print def threeLines(): newLine() newLine() newLine() Although these work. The execution of countdown begins with n=0. it outputs the word. it outputs the word. So. they would not be much help if we wanted to output 2 newlines.. and since n is not 0. the total output looks like
.

as long as n is greater than 0. there might be more than one frame on the stack at the same time. The same kind of diagram can help interpret a recursive function. which contains the function’s local variables and parameters.
4.
. so there are no more frames. is called the base case. if you do your algebra right. the top of the stack is the frame for main . Every time a function gets called. It is empty because we did not create any variables in main or pass any parameters to it. Python creates a new function frame. The bottom of the stack. The process of a function calling itself is recursion. we used a stack diagram to represent the state of a program during a function call. where n=0. it outputs one newline and then calls itself to output n-1 additional newlines.42 def nLines(n): if n > 0: print nLines(n-1)
Conditionals and recursion
This program is similar to countdown. It does not make a recursive call. This ﬁgure shows a stack diagram for countdown called with n = 3:
__main__ countdown countdown countdown countdown n n n n 3 2 1 0
As usual.11. Thus. As an exercise.10
Stack diagrams for recursive functions
In Section 3. and such functions are said to be recursive.1) which. The four countdown frames have diﬀerent values for the parameter n. the total number of newlines is 1 + (n . draw a stack diagram for nLines called with n=4. For a recursive function. comes out to n.

4.11
Inﬁnite recursion
If a recursion never reaches a base case. and it is generally not considered a good idea. the program resumes and raw input returns what the user typed as a string: >>> input = raw_input () What are you waiting for? >>> print input What are you waiting for? Before calling raw input. and the program never terminates. it goes on making recursive calls forever. We can supply a prompt as an argument to raw input:
. This is known as inﬁnite recursion. When the error occurs. Python reports an error message when the maximum recursion depth is reached: File "<stdin>". line 2. This message is called a prompt. write a function with inﬁnite recursion and run it in the Python interpreter. When this function is called. They just do the same thing every time. it is a good idea to print a message telling the user what to input. there are 100 recurse frames on the stack! As an exercise. the program stops and waits for the user to type something. a program with inﬁnite recursion does not really run forever.12
Keyboard input
The programs we have written so far are a bit rude in the sense that they accept no input from the user.4. Here is a minimal program with an inﬁnite recursion: def recurse(): recurse() In most programming environments. in recurse (98 repetitions omitted) File "<stdin>". The simplest is called raw input. Python provides built-in functions that get input from the keyboard.11 Inﬁnite recursion
43
4. in recurse RuntimeError: Maximum recursion depth exceeded This traceback is a little bigger than the one we saw in the previous chapter. When the user presses Return or the Enter key. line 2.

an African or a European swallow? SyntaxError: invalid syntax To avoid this kind of error.
4. that works on integers and yields the remainder when one number is divided by another. it is converted to an integer and assigned to speed.. >=. the program crashes: >>> speed = input (prompt) What. denoted with a percent sign (%). conditional statement: A statement that controls the ﬂow of execution depending on some condition. logical operator: One of the operators that combines boolean expressions: and.44
Conditionals and recursion
>>> name = raw_input ("What.. it is generally a good idea to use raw input to get a string and then use conversion functions to convert to other types.is your name? ") What. King of the Britons! >>> print name Arthur. and <=. if the user types a character that is not a digit. condition: The boolean expression in a conditional statement that determines which branch is executed. <. boolean expression: An expression that is either true or false. King of the Britons! If we expect the response to be an integer. The body is indented relative to the header.. compound statement: A statement that consists of a header and a body.13
Glossary
modulus operator: An operator.is your name? Arthur..is the airspeed velocity of an unladen swallow?\n" speed = input(prompt) If the user types a string of digits. and not. Unfortunately.
.. we can use the input function: prompt = "What..is the airspeed velocity of an unladen swallow? What do you mean. >.. or. The header ends with a colon (:). comparison operator: One of the operators that compares two values: ==. !=..

13 Glossary block: A group of consecutive statements with the same indentation. body: The block in a compound statement that follows the header.4. prompt: A visual cue that tells the user to input data. recursion: The process of calling the function that is currently executing.
. inﬁnite recursion: A function that calls itself recursively without ever reaching the base case. an inﬁnite recursion causes a runtime error.
45
nesting: One program structure within another. Eventually. such as a conditional statement inside a branch of another conditional statement. base case: A branch of the conditional statement in a recursive function that does not result in a recursive call.

46
Conditionals and recursion
.

so we could have written this function more concisely: def area(radius): return math.0) height = radius * math.pi * radius**2 return temp We have seen the return statement before. In this chapter. but in a fruitful function the return statement includes a return value. which we usually assign to a variable or use as part of an expression. which returns the area of a circle with the given radius: import math def area(radius): temp = math. The ﬁrst example is area. This statement means: “Return immediately from this function and use the following expression as a return value.1 Return values
Some of the built-in functions we have used. Calling the function generates a new value. e = math. for want of a better name.” The expression provided can be arbitrarily complicated.pi * radius**2
. such as the math functions.exp(1.sin(angle) But so far. none of the functions we have written has returned a value. have produced results. we are going to write functions that return values.Chapter 5
Fruitful functions
5. which we will call fruitful functions.

As you write larger functions. you have written some small functions. neither condition is true. As soon as one is executed. 0 if x == y. Also.2
Program development
At this point.
5. and -1 if x < y. one in each branch of a conditional: def absoluteValue(x): if x < 0: return -x else: return x Since these return statements are in an alternative conditional. only one will be executed.48
Fruitful functions
On the other hand. temporary variables like temp often make debugging easier. the function terminates without executing any subsequent statements. the return value is a special value called None: >>> print absoluteValue(0) None As an exercise. is called dead code. or any other place the ﬂow of execution can never reach. In a fruitful function. write a compare function that returns 1 if x > y.
. Code that appears after a return statement. and the function ends without hitting a return statement. it is a good idea to ensure that every possible path through the program hits a return statement. especially with runtime and semantic errors. you might start to have more diﬃculty. you should be able to look at complete functions and tell what they do. For example: def absoluteValue(x): if x < 0: return -x elif x > 0: return x This program is not correct because if x happens to be 0. In this case. if you have been doing the exercises. Sometimes it is useful to have multiple return statements.

After each incremental change. we call it with sample values: >>> distance(1.1)
The ﬁrst step is to consider what a distance function should look like in Python. suppose you want to ﬁnd the distance between two points. which we can represent using four parameters. But it is syntactically correct. the two points are the inputs. it always returns zero. We will store those values in temporary variables named dx and dy and print them. At this point we have conﬁrmed that the function is syntactically correct. If an error occurs at any point.2 Program development
49
To deal with increasingly complex programs. y1. Already we can write an outline of the function: def distance(x1. When testing a function. The return value is the distance. By the Pythagorean theorem.0 Obviously. x2.0 We chose these values so that the horizontal distance equals 3 and the vertical distance equals 4. y1 ) and (x2 . y2): return 0. this version of the function doesn’t compute distances. we know where it must be—in the last line we added. which is a ﬂoating-point value. what are the inputs (parameters) and what is the output (return value)? In this case. the result is 5 (the hypotenuse of a 3-4-5 triangle). A logical ﬁrst step in the computation is to ﬁnd the diﬀerences x2 − x1 and y2 − y1 . we are going to suggest a technique called incremental development. The goal of incremental development is to avoid long debugging sessions by adding and testing only a small amount of code at a time.5. 2. As an example. it is useful to know the right answer. 4. which means that we can test it before we make it more complicated. given by the coordinates (x1 .
. and it will run. In other words. To test the new function. we test the function again. and we can start adding lines of code. that way. the distance is:
distance =
(x2 − x1 )2 + (y2 − y1 )2
(5. 6) 0. y2 ).

If not. y1. y2): dx = x2 . y2): dx = x2 . dsquared return 0.y1 dsquared = dx**2 + dy**2 result = math. y1.x1 dy = y2 . x2. Otherwise. you might want to print the value of result before the return statement. y1.sqrt(dsquared) return result If that works correctly.x1 dy = y2 . Next we compute the sum of squares of dx and dy: def distance(x1.y1 print "dx is". y2): dx = x2 . you should add only a line or two of code at a time. x2. If so.0
Fruitful functions
If the function is working. we would run the program at this stage and check the output (which should be 25). there are only a few lines to check. dx print "dy is".0 Notice that we removed the print statements we wrote in the previous step. Either way. x2. we know that the function is getting the right parameters and performing the ﬁrst computation correctly. you might ﬁnd yourself writing and debugging bigger chunks. the incremental development process can save you a lot of debugging time. Finally. As you gain more experience.y1 dsquared = dx**2 + dy**2 print "dsquared is: ". if we have imported the math module. Code like that is called scaﬀolding because it is helpful for building the program but is not part of the ﬁnal product. Again. When you start out. The key aspects of the process are:
. dy return 0. the outputs should be 3 and 4. we can use the sqrt function to compute and return the result: def distance(x1. you are done.50 def distance(x1.x1 dy = y2 .

we’ll write a function that takes two points. yc. Assume that the center point is stored in the variables xc and yc. 2. yc. we get: def area2(xc. the center of the circle and a point on the perimeter. and computes the area of the circle.
. and the perimeter point is in xp and yp. 3. that does that: radius = distance(xc. At any point. Use temporary variables to hold intermediate values so you can output and check them. yp) result = area(radius) return result We called this function area2 to distinguish it from the area function deﬁned earlier. which is the distance between the two points. As an exercise. yp) The second step is to ﬁnd the area of a circle with that radius and return it: result = area(radius) return result Wrapping that up in a function. you can call one function from within another. There can only be one function with a given name within a given module. you might want to remove some of the scaﬀolding or consolidate multiple statements into compound expressions.5. yp): radius = distance(xc. xp. Once the program is working. but only if it does not make the program diﬃcult to read. The ﬁrst step is to ﬁnd the radius of the circle. yc. distance. there is a function. Fortunately. Start with a working program and make small incremental changes. This ability is called composition. use incremental development to write a function called hypotenuse that returns the length of the hypotenuse of a right triangle given the lengths of the two legs as parameters.
5. xp. Record each stage of the incremental development process as you go. you will know exactly where it is. xp. As an example. if there is an error.3 Composition
51
1.3
Composition
As you should expect by now.

but once the program is working. 4) isDivisible(6.52
Fruitful functions
The temporary variables radius and result are useful for development and debugging. we can make it more concise by composing the function calls: def area2(xc. y2) that returns the y-intercept of the line through the points (x1. isDivisible returns either 1 or 0 to indicate whether the x is or is not divisible by y. yp)) As an exercise. y1) and (x2. We can return it directly. xp. yp): return area(distance(xc. We can make the function more concise by taking advantage of the fact that the condition of the if statement is itself a boolean expression. avoiding the if statement altogether: def isDivisible(x. Then use this function in a function called intercept(x1. y1) and (x2. yc.
5. write a function slope(x1. y1. y2). x2. x2. y2) that returns the slope of the line through the points (x1. It is common to give boolean functions names that sound like yes/no questions. y1. which is often convenient for hiding complicated tests inside functions. For example: def isDivisible(x. xp. y): if x % y == 0: return 1 # it’s true else: return 0 # it’s false The name of this function is isDivisible. y): return x % y == 0 This session shows the new function in action: >>> 0 >>> 1 isDivisible(6. y2).4
Boolean functions
Functions can return boolean values. yc. 3)
Boolean functions are often used in conditional statements:
.

we’ll evaluate a few recursively deﬁned mathematical functions. As an exercise. you might get something like this: 0! = 1 n! = n(n − 1)! This deﬁnition says that the factorial of 0 is 1.. A recursive deﬁnition is similar to a circular deﬁnition. is n multiplied by the factorial of n − 1. if you looked up the deﬁnition of the mathematical function factorial. you might be annoyed. Accordingly.
. A truly circular deﬁnition is not very useful: frabjuous: An adjective used to describe something that is frabjuous.5
More recursion
So far. but a lot of early computer scientists started as mathematicians). write a function isBetween(x.5. it is known as the Turing Thesis. Proving that claim is a nontrivial exercise ﬁrst accomplished by Alan Turing. y): print "x is divisible by y" else: print "x is not divisible by y" It might be tempting to write something like: if isDivisible(x. mouse. If you saw that deﬁnition in the dictionary. If you take a course on the Theory of Computation. y. you have only learned a small subset of Python. etc. but you might be interested to know that this subset is a complete programming language. y) == 1: But the extra comparison is unnecessary. Any program ever written could be rewritten using only the language features you have learned so far (actually. which means that anything that can be computed can be expressed in this language.
53
5. z) that returns 1 if y ≤ x ≤ z or 0 otherwise. in the sense that the deﬁnition contains a reference to the thing being deﬁned. but that’s all). one of the ﬁrst computer scientists (some would argue that he was a mathematician. On the other hand. n. you would need a few commands to control devices like the keyboard. and the factorial of any other value. To give you an idea of what you can do with the tools you have learned so far. disks. you will have a chance to see the proof.5 More recursion if isDivisible(x.

becomes the return value of the function call that started the whole process.. If you can write a recursive deﬁnition of something. we take the second branch and calculate the factorial of n-1. we have to make a recursive call to ﬁnd the factorial of n − 1 and then multiply it by n: def factorial(n): if n == 0: return 1 else: recurse = factorial(n-1) result = n * recurse return result The ﬂow of execution for this program is similar to the ﬂow of countdown in Section 4. which is 3. Putting it all together.. which is 6. The ﬁrst step is to decide what the parameters are for this function.. which is 1 times 0!. we take the ﬁrst branch and return 1 without making any more recursive calls. we take the second branch and calculate the factorial of n-1. 3! equals 3 times 2 times 1 times 1. and the result is returned. With little eﬀort.. The return value (2) is multiplied by n. and the result is returned. which is 1. all we have to do is return 1: def factorial(n): if n == 0: return 1 Otherwise. and this is the interesting part. and the result.9.54
Fruitful functions
So 3! is 3 times 2!. you should conclude that factorial takes a single parameter: def factorial(n): If the argument happens to be 0.. which is 2. Since 1 is not 0.. we take the second branch and calculate the factorial of n-1. The return value (1) is multiplied by n. The return value (1) is multiplied by n. If we call factorial with the value 3: Since 3 is not 0. Since 0 is 0. you can usually write a Python program to evaluate it. 6. Since 2 is not 0.
. which is 2 times 1!.

which is the product of n and recurse.4. the local variables recurse and result do not exist. you don’t examine the implementations of those functions. you should assume that the recursive
. When you get to the recursive call.6 Leap of faith Here is what the stack diagram looks like for this sequence of function calls:
__main__ 6 factorial factorial factorial factorial n n n n 3 2 1 0 recurse recurse recurse 2 1 1 return return return 6 2 2 1 1 1
55
The return values are shown being passed back up the stack.6
Leap of faith
Following the ﬂow of execution is one way to read programs. The same is true when you call one of your own functions. you assume that the function works correctly and returns the appropriate value. In each frame. instead of following the ﬂow of execution.exp. You just assume that they work because the people who wrote the built-in libraries were good programmers. An alternative is what we call the “leap of faith. instead of following the ﬂow of execution.
5. In fact. you are already practicing this leap of faith when you use built-in functions. we wrote a function called isDivisible that determines whether one number is divisible by another. because the branch that creates them did not execute.cos or math. For example.” When you come to a function call. Once we have convinced ourselves that this function is correct—by testing and examining the code—we can use the function without looking at the code again. When you call math. Notice that in the last frame. but it can quickly become labyrinthine. the return value is the value of result. The same is true of recursive programs. in Section 5.5.

the most common example of a recursively deﬁned mathematical function is fibonacci. even for fairly small values of n. it’s a bit strange to assume that the function works correctly when you haven’t ﬁnished writing it.
. it looks like this: def fibonacci (n): if n == 0 or n == 1: return 1 else: return fibonacci(n-1) + fibonacci(n-2) If you try to follow the ﬂow of execution here.7
One more example
In the previous example.56
Fruitful functions
call works (yields the correct result) and then ask yourself. you can tighten it up if you are feeling inspired. But according to the leap of faith. but we recommend that you use the more explicit version while you are developing code. if you assume that the two recursive calls work correctly. which has the following deﬁnition: f ibonacci(0) = 1 f ibonacci(1) = 1 f ibonacci(n) = f ibonacci(n − 1) + f ibonacci(n − 2). we used temporary variables to spell out the steps and to make the code easier to debug. by multiplying by n. Translated into Python. Of course. but that’s why it’s called a leap of faith!
5. but we could have saved a few lines: def factorial(n): if n == 0: return 1 else: return n * factorial(n-1) From now on. it is clear that you can. then it is clear that you get the right result by adding them together. we will tend to use the more concise form. your head explodes. can I compute the factorial of n?” In this case. “Assuming that I can ﬁnd the factorial of n − 1. After factorial. When you have it working.

-1. the program prints an error message and returns a special value.8
Checking types
What happens if we call factorial and give it 1. and we can prove that the recursion terminates. it gets smaller and smaller. it is -0. We have two choices.5) RuntimeError: Maximum recursion depth exceeded It looks like an inﬁnite recursion. In both cases." return -1 elif n < 0: print "Factorial is only defined for positive integers.
. The second catches negative integers. We can use type to compare the type of the parameter to the type of a known integer value (like 1)." return -1 elif n == 0: return 1 else: return n * factorial(n-1) Now we have three base cases.8 Checking types
57
5.5. but it will never be 0. In the next. or we can make factorial check the type of its parameter.5. The ﬁrst option is called the gamma function and it’s a little beyond the scope of this book. But how can that be? There is a base case— when n == 0. The ﬁrst catches nonintegers. -1 >>> factorial (-2) Factorial is only defined for positive integers. In the ﬁrst recursive call. From there. We can try to generalize the factorial function to work with ﬂoating-point numbers. While we’re at it. we also make sure the parameter is positive: def factorial (n): if type(n) != type(1): print "Factorial is only defined for integers. to indicate that something went wrong: >>> factorial ("fred") Factorial is only defined for integers. So we’ll go for the second.5. -1 If we get past both checks. The problem is that the values of n miss the base case. then we know that n is a positive integer. the value of n is 0.5 as an argument? >>> factorial (1.

return value: The value provided as the result of a function call. or a return statement without an argument.58
Fruitful functions
This program demonstrates a pattern sometimes called a guardian. often because it appears after a return statement. dead code: Part of a program that can never be executed.
5. The guardians make it possible to prove the correctness of the code.
. temporary variable: A variable used to store an intermediate value in a complex calculation. guardian: A condition that checks for and handles circumstances that might cause an error. The ﬁrst two conditionals act as guardians.9
Glossary
fruitful function: A function that yields a return value. incremental development: A program development plan intended to avoid debugging by adding and testing only a small amount of code at a time. scaﬀolding: Code that is used during program development but is not part of the ﬁnal version. protecting the code that follows from values that might cause an error. None: A special Python value returned by functions that have no return statement.

Chapter 6
Iteration
6. and the second time.1 Multiple assignment
As you may have discovered. A new assignment makes an existing variable refer to a new value (and stop referring to the old value). his value is 7. It is not!
. because the ﬁrst time bruce is printed. it is legal to make more than one assignment to the same variable. bruce print bruce print = 5 bruce. = 7 bruce
The output of this program is 5 7. his value is 5. The comma at the end of the ﬁrst print statement suppresses the newline after the output. which is why both outputs appear on the same line. Because Python uses the equal sign (=) for assignment. Here is what multiple assignment looks like in a state diagram:
5 7
bruce
With multiple assignment it is especially important to distinguish between an assignment operation and a statement of equality. it is tempting to interpret a statement like a = b as a statement of equality.

an assignment statement can make two variables equal. We have seen two programs. to avoid confusion. so they are no longer equal. in mathematics. equality is commutative and assignment is not.or :=. a diﬀerent symbol is used for assignment.
6. If the values of variables change frequently. in mathematics. if a = 7 then 7 = a. display the word Blastoff!” More formally. a statement of equality is always true. you should use it with caution. Repeating identical or similar tasks without making errors is something that computers do well and people do poorly. such as <. “While n is greater than 0. then a will always equal b. For example. that use recursion to perform repetition. When you get to 0. it can make the code diﬃcult to read and debug.2
The while statement
Computers are often used to automate repetitive tasks. the statement a = 7 is legal and 7 = a is not. It means. But in Python. Python provides several language features to make it easier. If a = b now. nLines and countdown. but they don’t have to stay that way: a = 5 b = a a = 3 # a and b are now equal # a and b are no longer equal
The third line changes the value of a but does not change the value of b. The ﬁrst feature we are going to look at is the while statement. Here is what countdown looks like with a while statement: def countdown(n): while n > 0: print n n = n-1 print "Blastoff!" Since we removed the recursive call. this function is not recursive. Because iteration is so common. In Python. continue displaying the value of n and then reducing the value of n by 1. which is also called iteration. Furthermore. (In some programming languages. here is the ﬂow of execution for a while statement:
.60
Iteration
First. You can almost read the while statement as if it were English.) Although multiple assignment is frequently helpful.

Each time through the loop. the value of n is divided by 2. which will make the condition false. In the case of countdown. if n%2 == 0: n = n/2 else: n = n*3+1
# n is even # n is odd
The condition for this loop is n != 1. then the value of n will be even each time through the loop until it reaches 1.2 The while statement 1.
61
2. For example. The body of the loop should change the value of one or more variables so that eventually the condition becomes false and the loop terminates. 16. If the condition is false (0). Since n sometimes increases and sometimes decreases. 3. we can prove that the loop terminates because we know that the value of n is ﬁnite. the statements inside the loop are never executed. For example. exit the while statement and continue execution at the next statement. if the starting value is a power of two. which is called an inﬁnite loop. we can prove termination. so the loop will continue until n is 1. if the starting value (the argument passed to sequence) is 3. The body consists of all of the statements below the header with the same indentation. 10. Evaluate the condition.
. starting with 16. and we can see that the value of n gets smaller each time through the loop. If the condition is true (1). so eventually we have to get to 0. there is no obvious proof that n will ever reach 1. rinse. Otherwise the loop will repeat forever.” are an inﬁnite loop. 4. repeat.6. For some particular values of n. If it is odd. or that the program terminates. 8. it is not so easy to tell: def sequence(n): while n != 1: print n. This type of ﬂow is called a loop because the third step loops back around to the top. execute each of the statements in the body and then go back to step 1. the resulting sequence is 3. Notice that if the condition is false the ﬁrst time through the loop. the value is replaced by n*3+1. An endless source of amusement for computer scientists is the observation that the directions on shampoo. the program outputs the value of n and then checks whether it is even or odd. yielding 0 or 1. “Lather. 2. If it is even. In other cases. The previous example ends with such a sequence. 5. 1.

sines and cosines. Before computers were readily available. and they tended to be full of errors. and other mathematical functions by hand. one of the initial reactions was. After a print statement.3
Tables
One of the things loops are good for is generating tabular data. Soon thereafter.” That turned out to be true (mostly) but shortsighted. “This is great! We can use the computers to generate the tables. computers and calculators were so pervasive that the tables became obsolete. so there will be no errors. people had to calculate logarithms. In some cases. no one has been able to prove it or disprove it! As an exercise.0: print x. For some operations.62
Iteration
Particular values aside. Creating the tables was slow and boring. the cursor normally goes to the beginning of the next line. Well.0 while x < 10. The tab character shifts the cursor to the right until it reaches one of the tab stops. The following program outputs a sequence of values in the left column and their logarithms in the right column: x = 1. most famously in the table the Intel Pentium used to perform ﬂoating-point division. As characters and strings are displayed on the screen. there have been errors in the underlying tables. almost. as in the output of the previous program:
.
6. an invisible marker called the cursor keeps track of where the next character will go.log(x) x = x + 1. So far.0 The string ’\t’ represents a tab character. ’\t’. the interesting question is whether we can prove that this program terminates for all values of n. To make that easier. computers use tables of values to get an approximate answer and then perform computations to improve the approximation. math. it still makes a good example of iteration. Although a log table is not as useful as it once was. When computers appeared on the scene. rewrite the function nLines from Section 4.9 using iteration instead of recursion. Tabs are useful for making columns of text line up. mathematics books contained long tables listing the values of these functions.

0 2.0 1.0 5.0 0.80735492206 3.69314718056 1.0 7.0 4. If we wanted to ﬁnd the logarithms of other powers of two.0 9.log(2.0 Now instead of adding something to x each time through the loop. we can use the following formula: log2 x = Changing the output statement to: print x.94591014906 2.32192809489 2. we often want to ﬁnd logarithms with respect to base 2.79175946923 1.0 7.0 8.58496250072 2.0 0. 2. yielding a geometric sequence.60943791243 1.0 9.0) loge x loge 2 (6. ’\t’. remember that the log function uses base e.0 1.16992500144 math. Since powers of two are so important in computer science.0 6.0) x = x * 2.0 2. we could modify the program like this: x = 1.0 8.0 3.0 0. yields: 1.38629436112 1.6.58496250072 2.log(2.0 2.0 4. math.0 6.0 5.0: print x. To do that. ’\t’.1)
We can see that 1.log(x)/math.3 Tables 1.0 while x < 100.0 3. we multiply x by something. The result is:
.09861228867 1.07944154168 2.log(x)/math.19722457734
63
If these values seem odd. and 8 are powers of two because their logarithms base 2 are round numbers. which yields an arithmetic sequence.0 3. 4.

all on one line: i = 1 while i <= 6: print 2*i. Logarithm tables may not be useful any more.0
Iteration
Because of the tab characters between the columns.0 1.0 16. ’ i = i + 1 print
’.
. The backslash character in ’\t’ indicates the beginning of an escape sequence. knowing the powers of two is! As an exercise.536 (that’s 216 ). A good way to start is to write a loop that prints the multiples of 2.0 6.0 0.4
Two-dimensional tables
A two-dimensional table is a table where you read the value at the intersection of a row and a column. the position of the second column does not depend on the number of digits in the ﬁrst column. Escape sequences are used to represent invisible characters like tabs and newlines. the tab escape sequence is the only thing in the string.0 32.0 2.0 5.64 1.
6. A multiplication table is a good example.0 4. Let’s say you want to print a multiplication table for the values from 1 to 6. in the example. but for computer scientists. An escape sequence can appear anywhere in a string. The sequence \n represents a newline.0 3. write a single string that produces this output. Print it out and memorize it.0 64.0 2.0 4. How do you think you represent a backslash in a string? As an exercise.0 8. modify this program so that it outputs the powers of two up to 65.

’\t’. Again. If we call this function with the argument 2. the second print statement starts a new line. so good.6. all we had to do was replace the value 2 with the parameter n. i = i + 1 print To encapsulate. the output is: 4 8 12 16 20 24
. such as printing the multiples of any integer. As the loop executes. which declares the name of the function and the parameter list. the output is: 3 6 9 12 15 18
With the argument 4. Generalization means taking something speciﬁc. the comma in the print statement suppresses the newline. This function encapsulates the previous loop and generalizes it to print multiples of n: def printMultiples(n): i = 1 while i <= 6: print n*i. You have seen two examples of encapsulation: printParity in Section 4. and making it more general. which acts as a counter or loop variable.5 Encapsulation and generalization
65
The ﬁrst line initializes a variable named i. When i is 7. The next step is to encapsulate and generalize. With the argument 3. and isDivisible in Section 5.
6.4. all we had to do was add the ﬁrst line. it displays the value of 2*i. The output of the program is: 2 4 6 8 10 12
So far. Each time through the loop. such as printing the multiples of 2.5. To generalize. we get the same output as before. followed by three spaces. the loop terminates. allowing you to take advantage of all the things functions are good for. the value of i increases from 1 to 6.5
Encapsulation and generalization
Encapsulation is the process of wrapping a piece of code in a function. After the loop completes.

. or typing them in to the interpreter. we extract it and wrap it up in a function. let’s take the code from the end of Section 6. when you start writing. All we did was replace the print statement with a function call. This approach lets you design as you go along. how to divide the program into functions.5 and wrap it up in a function: def printMultTable(): i = 1 while i <= 6: printMultiples(i) i = i + 1 This process is a common development plan. In fact. The output of this program is a multiplication table: 1 2 3 4 5 6 2 4 6 8 10 12 3 6 9 12 15 18 4 8 12 16 20 24 5 10 15 20 25 30 6 12 18 24 30 36
6. we can use another loop: i = 1 while i <= 6: printMultiples(i) i = i + 1 Notice how similar this loop is to the one inside printMultiples.6
More encapsulation
To demonstrate encapsulation again.66
Iteration
By now you can probably guess how to print a multiplication table—by calling printMultiples repeatedly with diﬀerent arguments. We develop code by writing lines of code outside any function. When we get the code working. This development plan is particularly useful if you don’t know.

In the diagram. and changing one does not aﬀect the other. That value gets assigned to the parameter n. because the i in printMultiples and the i in printMultTable are not the same variable. you can’t access a local variable from outside its “home” function. i.
. you will probably make the program harder to read. In the diagram it happens to be 3. If you avoid using them in one function just because you used them somewhere else. Doesn’t it cause problems when one of the functions changes the value of the variable? The answer is no. it happens to be 2. They can refer to diﬀerent values.6. It is common and perfectly legal to have diﬀerent local variables with the same name.
printMultTable i 1 2 3 1 2
printMultiples n 3 i
The value of i in printMultTable goes from 1 to 6.7 Local variables
67
6.7
Local variables
You might be wondering how we can use the same variable. Each time through the loop. names like i and j are used frequently as loop variables. In particular. in both printMultiples and printMultTable. Changing this variable has no eﬀect on the value of i in printMultTable. That means you are free to have multiple variables with the same name as long as they are not in the same function. Variables created inside a function deﬁnition are local. The next time through the loop it will be 4. The stack diagram for this program shows that the two variables named i are not the same variable. the value of i goes from 1 to 6. printMultTable calls printMultiples with the current value of i as an argument. Inside printMultiples.

it displays: 1 2 3 4 5 6 7 2 4 6 8 10 12 14 3 6 9 12 15 18 21 4 8 12 16 20 24 28 5 10 15 20 25 30 35 6 12 18 24 30 36 42
This is ﬁne. To do that. we had to change the ﬁrst line of the function (the function heading). Just to be annoying. You could add a parameter to printMultTable: def printMultTable(high): i = 1 while i <= high: printMultiples(i) i = i + 1 We replaced the value 6 with the parameter high.68
Iteration
6. high) i = i + 1 Notice that when we added a new parameter. we call this parameter high. ’\t’. i = i + 1 print def printMultTable(high): i = 1 while i <= high: printMultiples(i.8
More generalization
As another example of generalization. If we call printMultTable with the argument 7. Here’s the whole program: def printMultiples(n. except that we probably want the table to be square—with the same number of rows and columns. demonstrating that diﬀerent functions can have parameters with the same name (just like local variables). high): i = 1 while i <= high: print n*i. and we also had to change the place where
. we add another parameter to printMultiples to specify how many columns the table should have. not just the six-by-six table. imagine you wanted a program that would print a multiplication table of any size.

you might notice that. you only have to change one line of printMultTable. Change printMultiples(i. we have mentioned “all the things functions are good for. you often get a program with capabilities you didn’t plan. because ab = ba. this program generates a square seven-by-seven table: 1 2 3 4 5 6 7 2 4 6 8 10 12 14 3 6 9 12 15 18 21 4 8 12 16 20 24 28 5 10 15 20 25 30 35 6 12 18 24 30 36 42 7 14 21 28 35 42 49
69
When you generalize a function appropriately.
6.
.” By now. You could save ink by printing only half the table. Here are some of them: • Giving a name to a sequence of statements makes your program easier to read and debug.9
Functions
A few times now. As expected.9 Functions the function is called in printMultTable.6. To do that. high) to printMultiples(i. i) and you get 1 2 3 4 5 6 7 4 6 8 10 12 14
9 12 15 18 21
16 20 24 28
25 30 35
36 42
49 this version of
As an exercise. For example. trace the execution of printMultTable and ﬁgure out how it works. you might be wondering what exactly those things are. all the entries in the table appear twice.

escape sequence: An escape character (\) followed by one or more printable characters used to designate a nonprintable character. you can reuse it. newline: A special character that causes the cursor to move to the beginning of the next line. • Functions facilitate both recursion and iteration.
. development plan: A process for developing a program. body: The statements inside a loop. Once you write and debug one. generalize: To replace something unnecessarily speciﬁc (like a constant value) with something appropriately general (like a variable or parameter). In this chapter. cursor: An invisible marker that keeps track of where the next character will be printed. for example). and sometimes even easier to write. encapsulate: To divide a large complex program into components (like functions) and isolate the components from each other (by using local variables.10
Glossary
multiple assignment: Making more than one assignment to the same variable during the execution of a program. Generalization makes code more versatile. we demonstrated a style of development based on developing code to do simple. tab: A special character that causes the cursor to move to the next tab stop on the current line.
6. and then compose them into a whole. speciﬁc things and then encapsulating and generalizing.70
Iteration • Dividing a long program into functions allows you to separate parts of the program. loop: A statement or group of statements that execute repeatedly until a terminating condition is satisﬁed. debug them in isolation. inﬁnite loop: A loop in which the terminating condition is never satisﬁed. iteration: Repeated execution of a set of statements using either a recursive function call or a loop. more likely to be reused. • Well-designed functions are often useful for many programs. loop variable: A variable used as part of the terminating condition of a loop.

we get a surprise: a The ﬁrst letter of "banana" is not a. and string. Types that comprise smaller pieces are called compound data types. and n is the 2th (“two-eth”) letter. The bracket operator selects a single character from a string.Chapter 7
Strings
7. in the brackets:
. or any expression with the value 0. you just put 0.1 A compound data type
So far we have seen three types: int. In that case you should think of the expression in brackets as an oﬀset from the beginning of the string. we may want to treat a compound data type as a single thing. To get the ﬁrst letter of a string. or we may want to access its parts. Depending on what we are doing. The variable letter refers to the result. Strings are qualitatively diﬀerent from the other two because they are made up of smaller pieces— characters. When we display letter. and the oﬀset of the ﬁrst letter is zero. So b is the 0th letter (“zero-eth”) of "banana". float. Unless you are a computer scientist. a is the 1th letter (“one-eth”). This ambiguity is useful. >>> fruit = "banana" >>> letter = fruit[1] >>> print letter The expression fruit[1] selects character number 1 from fruit.

the six letters are numbered 0 to 5. Since we started counting at zero. It can be any integer expression. which count backward from the end of the string. The expression fruit[-1] yields the last letter. and so on. we can use negative indices. The index indicates which one you want.72 >>> letter = fruit[0] >>> print letter b
Strings
The expression in brackets is called an index. and continue until the end.
7. fruit[-2] yields the second to last. The reason is that there is no 6th letter in "banana". we have to subtract 1 from length: length = len(fruit) last = fruit[length-1] Alternatively. To get the last character.2
Length
The len function returns the number of characters in a string: >>> fruit = "banana" >>> len(fruit) 6 To get the last letter of a string. An index speciﬁes a member of an ordered set. you might be tempted to try something like this: length = len(fruit) last = fruit[length] # ERROR!
That won’t work. One way to encode a traversal is with a while statement: index = 0 while index < len(fruit): letter = fruit[index] print letter index = index + 1
.3
Traversal and the for loop
A lot of computations involve processing a string one character at a time.
7. This pattern of processing is called a traversal. hence the name. in this case the set of characters in the string. select each character in turn. do something to it. Often they start at the beginning. It causes the runtime error IndexError: string index out of range.

modify the program to ﬁx this error. Kack.
. and Quack. which is the last character in the string. The loop condition is index < len(fruit). Pack.3 Traversal and the for loop
73
This loop traverses the string and displays each letter on a line by itself. the condition is false. Nack. As an exercise.7. that’s not quite right because “Ouack” and “Quack” are misspelled. Mack. the next character in the string is assigned to the variable char. As an exercise. write a function that takes a string as an argument and outputs the letters backward. the names of the ducklings are Jack. Using an index to traverse a set of values is so common that Python provides an alternative. For example. The loop continues until no characters are left. Ouack. and the body of the loop is not executed. “Abecedarian” refers to a series or list in which the elements appear in alphabetical order. in Robert McCloskey’s book Make Way for Ducklings. The following example shows how to use concatenation and a for loop to generate an abecedarian series. This loop outputs these names in order: prefixes = "JKLMNOPQ" suffix = "ack" for letter in prefixes: print letter + suffix The output of this program is: Jack Kack Lack Mack Nack Oack Pack Qack Of course. so when index is equal to the length of the string. simpler syntax—the for loop: for char in fruit: print char Each time through the loop. Lack. one per line. The last character accessed is the one with the index len(fruit)-1.

as in the following diagram:
fruit index
"banana"
0 1 2 3 4 5 6
If you omit the ﬁrst index (before the colon). it makes more sense if you imagine the indices pointing between the characters. Selecting a slice is similar to selecting a character: >>> s = "Peter. To see if two strings are equal: if word == "banana": print "Yes. Thus: >>> fruit = "banana" >>> fruit[:3] ’ban’ >>> fruit[3:] ’ana’ What do you think s[:] means?
7. and Mary" >>> print s[0:5] Peter >>> print s[7:11] Paul >>> print s[17:21] Mary The operator [n:m] returns the part of the string from the “n-eth” character to the “m-eth” character. we have no bananas!"
. This behavior is counterintuitive. the slice starts at the beginning of the string. Paul. the slice goes to the end of the string.5
String comparison
The comparison operators work on strings.74
Strings
7.4
String slices
A segment of a string is called a slice. If you omit the second index. including the ﬁrst but excluding the last.

we have no bananas!" You should be aware. such as all lowercase. world!" newGreeting = ’J’ + greeting[1:] print newGreeting The solution here is to concatenate a new ﬁrst letter onto a slice of greeting.6
Strings are immutable
It is tempting to use the [] operator on the left side of an assignment. comes before banana.7. A more diﬃcult problem is making the program realize that zebras are not fruit. though. which means you can’t change an existing string.6 Strings are immutable
75
Other comparison operations are useful for putting words in alphabetical order: if word < "banana": print "Your word. A common way to address this problem is to convert strings to a standard format.and lowercase letters the same way that people do. before performing the comparison. this code produces the runtime error TypeError: object doesn’t support item assignment. that Python does not handle upper. world!" greeting[0] = ’J’ print greeting
# ERROR!
Instead of producing the output Jello. This operation has no eﬀect on the original string. As a result: Your word. The best you can do is create a new string that is a variation on the original: greeting = "Hello. All the uppercase letters come before all the lowercase letters.
. with the intention of changing a character in a string.
7. comes before banana." elif word > "banana": print "Your word. comes after banana." + word + ". Zebra." + word + ". Strings are immutable. world!." else: print "Yes. For example: greeting = "Hello.

If the character is not found.7
A find function
What does the following function do? def find(str. ch): index = 0 while index < len(str): if str[index] == ch: return index index = index + 1 return -1 In a sense. the index in the string where it should start looking. we can cry “Eureka!” and stop looking.76
Strings
7. modify the find function so that it takes a third parameter. the function returns -1. breaking out of the loop prematurely. Instead of taking an index and extracting the corresponding character. find is the opposite of the [] operator. it takes a character and ﬁnds the index where that character appears. If str[index] == ch.8
Looping and counting
The following program counts the number of times the letter a appears in a string: fruit = "banana" count = 0 for char in fruit: if char == ’a’: count = count + 1 print count This program demonstrates another pattern of computation called a counter. If the character doesn’t appear in the string.
7. This is the ﬁrst example we have seen of a return statement inside a loop. then the program exits the loop normally and returns -1. This pattern of computation is sometimes called a “eureka” traversal because as soon as we ﬁnd what we are looking for. The variable count is initialized to 0 and then incremented each time an a is
. the function returns immediately. As an exercise.

Actually. it takes an additional argument that speciﬁes the index it should start at: >>> string.9
The string module
The string module contains useful functions that manipulate strings. it can ﬁnd substrings. not just characters: >>> string.find("banana".
7.find is more general than our version. "na") 2 Also. we have to import the module before we can use it: >>> import string The string module includes a function named find that does the same thing as the function we wrote. >>> fruit = "banana" >>> index = string. (To increment is to increase by one.find("banana".9 The string module
77
found. encapsulate this code in a function named countLetters. string. To call it we have to specify the name of the module and the name of the function using dot notation. As usual. As an exercise. count contains the result—the total number of a’s. it is the opposite of decrement. "a") >>> print index 1 This example demonstrates one of the beneﬁts of modules—they help avoid collisions between the names of built-in functions and user-deﬁned functions. and unrelated to “excrement. "na".” which is a noun.7.find(fruit. it uses the three-parameter version of find from the previous. By using dot notation we can specify which version of find we want. and generalize it so that it accepts the string and the letter as parameters.) When the loop exits. First. 3) 4 Or it can take two additional arguments that specify a range of indices:
. rewrite this function so that instead of traversing the string. As a second exercise.

uppercase contains all of the uppercase letters.find(string.lowercase contains all of the letters that the system considers to be lowercase. "b".10
Character classiﬁcation
It is often helpful to examine a character and test whether it is upper.digits We can use these constants and find to classify characters. Similarly. ch) != -1 Alternatively. if find(lowercase.uppercase >>> print string. we can use the comparison operator: def isLower(ch): return ’a’ <= ch <= ’z’ If ch is between a and z.
7. For example. 1.78 >>> string. The string string.lowercase As yet another alternative. or whether it is a character or a digit.or lowercase. discuss which version of isLower you think will be fastest. Can you think of other reasons besides speed to prefer one or the other? Another constant deﬁned in the string module may surprise you when you print it:
. The string module provides several constants that are useful for these purposes. string.find("bob". the search fails because the letter b does not appear in the index range from 1 to 2 (not including 2). Try the following and see what you get: >>> print string. which determines whether a character appears in a string: def isLower(ch): return ch in string.lowercase. we can take advantage of the in operator. it must be a lowercase letter. then ch must be lowercase: def isLower(ch): return string. 2) -1
Strings
In this example. As an exercise. ch) returns a value other than -1.lowercase >>> print string.

whitespace contains all the whitespace characters.7.
7. including space. but this book isn’t intended to be a reference manual.org. or elements. www.11 Glossary >>> print string. mutable: A compound data types whose elements can be assigned new values. index: A variable or value used to select a member of an ordered set. that are themselves values.
. Along with a wealth of other documentation.whitespace
79
Whitespace characters move the cursor without printing anything.11
Glossary
compound data type: A data type in which the values are made up of components. On the other hand. They create the white space between visible characters (at least on white paper). it’s available from the Python website. whitespace: Any of the characters that move the cursor without printing visible characters. The constant string.whitespace contains all the whitespace characters.python. counter: A variable used to count something. usually initialized to zero and then incremented. the Python Library Reference is. The constant string. increment: To increase the value of a variable by one. tab (\t). and newline (\n). slice: A part of a string speciﬁed by a range of indices. such as a character from a string. There are other useful functions in the string module. performing a similar operation on each. traverse: To iterate through the elements of a set. decrement: To decrease the value of a variable by one.

80
Strings
.

1
List values
There are several ways to create a new list. 2. [10. an integer. Lists that contain consecutive integers are common. a ﬂoat. The values that make up a list are called its elements.5) [1. The second is a list of three strings. 40] ["spam". Lists are similar to strings. where each value is identiﬁed by an index. "bungee". Lists and strings—and other things that behave like ordered sets—are called sequences. so Python provides a simple way to create them: >>> range(1. 5. 20. except that the elements of a list can have any type.0. and (mirabile dictu) another list: ["hello".
8. The elements of a list don’t have to be the same type. 20]] A list within another list is said to be nested. "swallow"] The ﬁrst example is a list of four integers. 3. 2. 4]
. which are ordered sets of characters. The following list contains a string. the simplest is to enclose the elements in square brackets ([ and ]): [10.Chapter 8
Lists
A list is an ordered set of values. 30.

0] TypeError: sequence index must be integer
. empty [’ameliorate’. 7. 6. 2. including the ﬁrst but not including the second! There are two other forms of range. numbers. which is called the step size. 8. 7. it would be disappointing if we couldn’t assign list values to variables or pass lists as parameters to functions. it creates a list that starts at 0: >>> range(10) [0. With a single argument. When it appears on the left side of an assignment. "castigate". there is a special list that contains no elements. 123] []
8. 123] empty = [] print vocabulary. The expression inside the brackets speciﬁes the index. vocabulary = ["ameliorate". 9] If there is a third argument. "defenestrate"] numbers = [17. Any integer expression can be used as an index: >>> numbers[3-2] 5 >>> numbers[1. 5. 9] Finally. ’castigate’. it changes one of the elements in the list.82
Lists
The range function takes two arguments and returns a list that contains all the integers from the ﬁrst to the second. We can. which used to be 123. Remember that the indices start at 0: print numbers[0] numbers[1] = 5 The bracket operator can appear anywhere in an expression. 1. is now 5.2
Accessing elements
The syntax for accessing the elements of a list is the same as the syntax for accessing the characters of a string—the bracket operator ([]). it speciﬁes the space between successive values. With all these ways to create lists. This example counts from 1 to 10 by steps of 2: >>> range(1. 10. 3. and it is denoted []. 5. 2) [1. It is called the empty list. so the one-eth element of numbers. 3. 4. ’defenestrate’] [17.

8. "death"] i = 0 while i < 4: print horsemen[i] i = i + 1 This while loop counts from 0 to 4. horsemen = ["war".3
List length
The function len returns the length of a list. When the loop variable i is 4. "pestilence". Each time through the loop.3 List length
83
If you try to read or write an element that does not exist. they will work correctly for any size list:
.
8. It is a good idea to use this value as the upper bound of a loop instead of a constant. printing the i-eth element. and numbers[-3] doesn’t exist. So the body of the loop is only executed when i is 0. you get a runtime error: >>> numbers[2] = 5 IndexError: list assignment index out of range If an index has a negative value. it counts backward from the end of the list: >>> numbers[-1] 5 >>> numbers[-2] 17 >>> numbers[-3] IndexError: list index out of range numbers[-1] is the last element of the list. the variable i is used as an index into the list. the condition fails and the loop terminates. and 3. 2. 1. That way. you won’t have to go through the program changing all the loops. "famine". numbers[-2] is the second to last. It is common to use a loop variable as a list index. This pattern of computation is called a list traversal. if the size of the list changes.

’pestilence’.5
Lists and for loops
The for loop we saw in Section 7. [1. The length of this list is four: [’spam!’. 2. in returns false. ’Pol le Veq’]. but it also works with lists and other sequences: >>> horsemen = [’war’. write a loop that traverses the previous list and prints the length of each element. Although a list can contain another list. 3]] As an exercise. When i is equal to len(horsemen). "famine". Since “debauchery” is not in the list.10 with strings. which is a good thing. ’Roquefort’. 1.84 horsemen = ["war". which is the index of the last element. because len(horsemen) is not a legal index. [’Brie’. i is len(horsemen) . What happens if you send an integer to len?
8. "death"] i = 0 while i < len(horsemen): print horsemen[i] i = i + 1
Lists
The last time the body of the loop is executed. The generalized syntax of a for loop is:
. ’famine’. We used it in Section 7.4
List membership
in is a boolean operator that tests membership in a sequence. We can use the not in combination with in to test whether an element is not a member of a list: >>> ’debauchery’ not in horsemen 1
8.1. "pestilence". ’death’] >>> ’pestilence’ in horsemen 1 >>> ’debauchery’ in horsemen 0 Since “pestilence” is a member of the horsemen list. the in operator returns true.3 also works with lists. the nested list still counts as a single element. the condition fails and the body is not executed.

i. a = [1. Here is the previous loop written with a for loop. "quince"]: print "I like to eat " + fruit + "s!" The ﬁrst example prints all the even numbers between zero and nineteen.6 List operations for VARIABLE in LIST: BODY This statement is equivalent to: i = 0 while i < len(LIST): VARIABLE = LIST[i] BODY i = i + 1
85
The for loop is more concise because we can eliminate the loop variable.” Any list expression can be used in a for loop: for number in range(20): if number % 2 == 0: print number for fruit in ["banana". 6] c = a + b print c 2. 5. 5. 3. 4. 2.6
List operations
The + operator concatenates lists: >>> >>> >>> >>> [1.
8. for horseman in horsemen: print horseman It almost reads like English: “For (every) horseman in (the list of) horsemen. the * operator repeats a list a given number of times:
.8. 3] b = [4. The second example expresses enthusiasm for various fruits. print (the name of the) horseman. "apple". 6]
Similarly.

2. a and b refer to two diﬀerent things that have the same value. 3] >>> id(a) 135045528 >>> id(b) 135041704 So the state diagram looks like this:
a b [ 1. >>> id(a) 135044008 >>> id(b) 135044008 In fact. 2. we can tell whether they refer to the same object. which we can obtain with the id function. they refer to the same thing. There are two possible states:
a b "banana" "banana" a b
"banana"
In one case. Interestingly. 2. 3 ]
a and b have the same value but do not refer to the same object. But we can’t tell whether they point to the same string.88
Lists
8. 2. and both a and b refer to it. lists behave diﬀerently. These “things” have names—they are called objects. By printing the identiﬁer of a and b. 3] >>> b = [1. In the second case. 3 ] [ 1. a = "banana" b = "banana" we know that a and b will refer to a string with the letters "banana". we get the same identiﬁer twice.
. An object is something a variable can refer to. which means that Python only created one string. When we create two lists.10
Objects and values
If we execute these assignment statements. Every object has a unique identiﬁer. we get two objects: >>> a = [1.

if we assign one variable to another. for immutable objects. 3] >>> b = a In this case. Changes made with one alias aﬀect the other: >>> b[0] = 5 >>> print a [5. This process is sometimes called cloning. 3]
Taking any slice of a creates a new list. it is sometimes unexpected or undesirable. a and b. we need to be able to make a copy of the list itself.8. there’s no problem. 3] b = a[:] print b 2. 3] Although this behavior can be useful.” The easiest way to clone a list is to use the slice operator: >>> >>> >>> [1. 2. the state diagram looks like this:
a b
[ 1. both variables refer to the same object: >>> a = [1. we say that it is aliased. 2.
8.11 Aliasing
89
8. Of course. In this case the slice happens to consist of the whole list. 2.12
Cloning lists
If we want to modify a list and also keep a copy of the original. In general. That’s why Python is free to alias strings when it sees an opportunity to economize. 2. to avoid the ambiguity of the word “copy.11
Aliasing
Since variables refer to objects. not just the reference. 3 ]
Because the same list has two diﬀerent names. a = [1. it is safer to avoid aliasing when you are working with mutable objects. Now we are free to make changes to b without worrying about a:
.

For example. 2. numbers = [1.
Lists
8. The state diagram looks like this:
__main__ numbers [ 1. the caller sees the change. 2. 3] deleteHead(numbers) print numbers 3]
. 2. 3 ] head list
Since the list object is shared by two frames. For example. not a copy of the list. we drew it between them. draw a state diagram for a and b before and after this change.90 >>> b[0] = 5 >>> print a [1. If a function modiﬁes a list parameter. 3] As an exercise. 2. deleteHead removes the ﬁrst element from a list: def deleteHead(list): del list[0] Here’s how deleteHead is used: >>> >>> >>> [2.13
List parameters
Passing a list as an argument actually passes a reference to the list. the function head takes a list as a parameter and returns the ﬁrst element: def head(list): return list[0] Here’s how it is used: >>> numbers = [1. 3] >>> head(numbers) 1 The parameter list and the variable numbers are aliases for the same object.

2. Creating rest. the matrix:
. To extract an element from the nested list. 20].8. 3] rest = tail(numbers) print rest 3]
Because the return value was created with the slice operator. For example.
8. it returns a reference to the list.0. In this list. 5. For example. 2.14 Nested lists
91
If a function returns a list. tail returns a list that contains all but the ﬁrst element of the given list: def tail(list): return list[1:] Here’s how tail is used: >>> >>> >>> [2. numbers = [1.15
Matrixes
1 2 3 4 5 6 7 8 9
Nested lists are often used to represent matrices. 20]] If we print list[3].
8. have no eﬀect on numbers. so this expression gets the threeeth element of list and extracts the one-eth element from it. [10. and any subsequent changes to rest. we can proceed in two steps: >>> elt = list[3] >>> elt[0] 10 Or we can combine them: >>> list[3][1] 20 Bracket operators evaluate from left to right. the three-eth element is a nested list: >>> list = ["hello".14
Nested lists
A nested list is a list that appears as an element in another list. it is a new list. we get [10.

split(song. A small variation is to use a list of columns instead of a list of rows.. The split function breaks a string into a list of words. 8. We can select an entire row from the matrix in the usual way: >>> matrix[1] [4. ’in’..
8. 6] Or we can extract a single element from the matrix using the double-index form: >>> matrix[1][1] 5 The ﬁrst index selects the row. 6]. ’n. [4. ’Spain.’
. any number of whitespace characters is considered a word boundary: >>> import string >>> song = "The rain in Spain. The join function is the inverse of split. Later we will see a more radical alternative using a dictionary.’] >>> string. 5. 9]]
Lists
matrix is a list with three elements. Although this way of representing matrices is common..’] Notice that the delimiter doesn’t appear in the list. ’Spain. [7.join(list) ’The rain in Spain.. ’in’. It takes a list of strings and concatenates the elements with a space between each pair: >>> list = [’The’. ’n in Sp’.. it is not the only possibility. 5.16
Strings and lists
Two of the most useful functions in the string module involve lists of strings. and the second index selects the column. ’rain’.. ’rain’...split(song) [’The’. 3]. The following example uses the string ai as the delimiter: >>> string. ’ai’) [’The r’. 2. By default." >>> string.’] An optional argument called a delimiter can be used to specify which characters to use as word boundaries.92 might be represented as: >>> matrix = [[1.. where each element is a row of the matrix..

Copying a reference to an object creates an alias but doesn’t clone the object. with each element identiﬁed by an index. aliases: Multiple variables that contain references to the same object. list traversal: The sequential accessing of each element in a list. index: An integer variable or value that indicates an element of a list.split(song)) and song.17 Glossary
93
Like split.17
Glossary
list: A named collection of objects. sequence: Any of the data types that consist of an ordered set of elements..join(string..
. The bracket operator selects elements of a list.8. ’_’) ’The_rain_in_Spain. element: One of the values in a list (or other sequence). describe the relationship between string. clone: To create a new object that has the same value as an existing object. where each object is identiﬁed by an index. delimiter: A character or string used to indicate where a string should be split.join(list. nested list: A list that is an element of another list. join takes an optional delimiter that is inserted between elements: >>> string. Are they the same for all strings? When would they be diﬀerent?
8. object: A thing to which a variable can refer.’ As an exercise.

94
Lists
.

strings are immutable and lists are mutable. and lists. Syntactically. but the characters in a string cannot. ’b’. ’c’. One of the diﬀerences we noted is that the elements of a list can be modiﬁed. ’e’ Although it is not necessary. we have to include the ﬁnal comma: >>> t1 = (’a’. ’c’. In other words.) >>> type(t1) <type ’tuple’> Without the comma. ’e’) To create a tuple with a single element.1 Mutability and tuples
So far. which are made up of elements of any type. There is another type in Python called a tuple that is similar to a list except that it is immutable. which are made up of characters. ’d’. ’d’. Python treats (’a’) as a string in parentheses: >>> t2 = (’a’) >>> type(t2) <type ’string’>
. ’b’.Chapter 9
Tuples
9. it is conventional to enclose tuples in parentheses: >>> tuple = (’a’. you have seen two compound types: strings. a tuple is a comma-separated list of values: >>> tuple = ’a’.

even if we can’t modify the elements of a tuple. For example. b = b. we can replace it with a diﬀerent tuple: >>> tuple = (’A’.96
Tuples
Syntax issues aside. we have to use a temporary variable. The index operator selects an element from a tuple. >>> tuple[1:3] (’b’. ’d’. ’e’)
9. a The left side is a tuple of variables. All the expressions on the right side are evaluated before any of the assignments. the right side is a tuple of values. we get a error: >>> tuple[0] = ’A’ TypeError: object doesn’t support item assignment Of course. to swap a and b: >>> temp = a >>> a = b >>> b = temp If we have to do this often. >>> tuple = (’a’. ’c’. it is useful to swap the values of two variables. ’c’. ’d’. Naturally. the operations on tuples are the same as the operations on lists. Python provides a form of tuple assignment that solves this problem neatly: >>> a. the number of variables on the left and the number of values on the right have to be the same:
. ’b’.2
Tuple assignment
Once in a while. Each value is assigned to its respective variable.) + tuple[1:] >>> tuple (’A’. ’b’. With conventional assignment statements. ’c’) But if we try to modify one of the elements of the tuple. This feature makes tuple assignment quite versatile. this approach becomes cumbersome. ’e’) >>> tuple[0] ’a’ And the slice operator selects a range of elements.

but there are more. For example. x # incorrect version
If we call this function like this: swap(a. since we expect the same calculation to yield the same result. we could write a function that swaps two parameters: def swap(x. c. though. y): x. In fact.9. b) In this case. For some applications. which is the following tempting mistake: def swap(x. b = swap(a. y = y. This is an example of a semantic error. This function runs without producing an error message. we want the computer to be unpredictable. As an exercise. y): return y. x Then we can assign the return value to a tuple with two variables: a. 3 ValueError: unpack tuple of wrong size
97
9. 2. Similarly. Changing x inside swap makes x refer to a diﬀerent value. there is no great advantage in making swap a function. d = 1.3
Tuples as return values
Functions can return tuples as return values. there is a danger in trying to encapsulate swap.
9. but it doesn’t do what we intended. Determinism is usually a good thing. but it has no eﬀect on a in main . changing y has no eﬀect on b.3 Tuples as return values >>> a. b.4
Random numbers
Most computer programs do the same thing every time they execute. b) then a and x are aliases for the same value. so they are said to be deterministic.
. draw a state diagram for this function so that you can see why it doesn’t work. Games are an obvious example.

random() return s We’ll test this function with a list of eight elements.5
List of random numbers
The ﬁrst step is to generate a list of random values. The random module contains a function called random that returns a ﬂoatingpoint number between 0. but there are ways to make it at least seem nondeterministic.0 and 1.random() print x To generate a random number between 0. but for our purposes they will do. it is a good idea to start small. Python provides a built-in function that generates pseudorandom numbers.0 and an upper bound like high. run this loop: import random for i in range(10): x = random. you get the next number in a long series. It starts with a list of n zeros. One of them is to generate random numbers and use them to determine the outcome of the program.98
Tuples
Making a program truly nondeterministic turns out to be not so easy. The return value is a reference to the complete list: def randomList(n): s = [0] * n for i in range(n): s[i] = random.0.
9. For purposes of debugging. To see a sample. including both end points. Each time through the loop. generate a random number between low and high. which are not truly random in the mathematical sense. multiply x by high. As an additional exercise. randomList takes an integer parameter and returns a list of random numbers with the given length. it replaces one of the elements with a random number.
. Each time you call random. generate a random integer between low and high. As an exercise.

6
Counting
A good approach to problems like this is to divide the problem into subproblems and look for subproblems that ﬁt a computational pattern you have seen before.275119183077 0. That doesn’t change the program.
.810894847068 0. The second step is to change the test.9. If we divide the range of possible values into equal-sized “buckets.360371157682 0. we can proceed by copying the old program and adapting it for the current problem.328578797631 0. it just makes it more readable.
9. We want to see if num is between the given values low and high. we should get roughly the same number in each. So. We aren’t interested in ﬁnding letters.498048560109 0.759199803101 0.” and count the number of times a random value falls in each bucket. The original program was: count = 0 for char in fruit: if char == ’a’: count = count + 1 print count The ﬁrst step is to replace fruit with list and char with num. We can test this theory by writing a program to divide the range into buckets and count the number of values in each.6 Counting >>> randomList(8) 0. In this case. which means that every value is equally likely. In Section 7.8.15156642489 0. we wrote a program that traversed a string and counted the number of times a given letter appeared. we want to traverse a list of numbers and count the number of times a value falls in a given range. That sounds familiar.800367163582
99
The numbers generated by random are supposed to be distributed uniformly.

0. def inBucket(list.25.0. 0.5. then the width of each bucket is 1.5. low. high): count = 0 for num in list: if low < num < high: count = count + 1 return count By copying and modifying an existing program. we were able to write this function quickly and save a lot of debugging time.100 count = 0 for num in list if low < num < high: count = count + 1 print count
Tuples
The last step is to encapsulate this code in a function called inBucket. The other is that we have to compute the range for each bucket. it’s not bad: low = inBucket(a. inBucket gets a little unwieldy. i.75. 0. inBucket(a. inBucket(a.
9. 1. One is that we have to make up new variable names for each result. We’ll use a loop to compute the range of each bucket. If you ﬁnd yourself working on a problem you have solved before. counts from 0 to numBuckets-1:
. 0. 0.7
Many buckets
As the number of buckets increases. 0.5) 0. We’ll solve the second problem ﬁrst. reuse the solution. The parameters are the list and the values low and high.5) high = inBucket(a.0. If the number of buckets is numBuckets.25) 0.75) 0. The loop variable.0)
There are two problems.0 / numBuckets. With two buckets. bucket1 bucket2 bucket3 bucket4 = = = = inBucket(a. 1) But with four buckets it is getting cumbersome. This development plan is called pattern matching. 0. inBucket(a.

that they don’t overlap.7 Many buckets bucketWidth = 1.9.125 0.875 0.625 0. we multiply the loop variable by the bucket width. By now you should be thinking.75 to 0. using the loop variable to indicate one at a time. 130.
. “List!” We have to create the bucket list outside the loop. we’ll call inBucket repeatedly and update the i-eth element of the list: numBuckets = 8 buckets = [0] * numBuckets bucketWidth = 1.0 to 1. 117. because we only want to do it once.0 / numBuckets for i in range(numBuckets): low = i * bucketWidth high = low + bucketWidth print low. As an exercise. At least. test this function with some longer lists. 128. We need a way to store eight integers. high) print buckets With a list of 1000 values.0 / numBuckets for i in range(numBuckets): low = i * bucketWidth high = low + bucketWidth buckets[i] = inBucket(list.5 0.125 to 0. and see if the number of values in each bucket tends to level oﬀ.375 0.625 to 0. 131] These numbers are fairly close to 125. low. The high end is just a bucketWidth away. 124. which is what we expected. 114. With numBuckets = 8. they are close enough that we can believe the random number generator is working. "to".25 to 0. Inside the loop. this code produces this bucket list: [138.5 to 0.25 0.0 You can conﬁrm that each bucket is the same width.875 to 1. the output is: 0. 118. and that they cover the entire range from 0.0 to 0. Now back to the ﬁrst problem.75 0.375 to 0. high
101
To compute the low end of each bucket.0.

As an exercise. If we round that number to the next lower integer. i. If we multiply a number in the range 0. that gets to be a lot of traversals.0 / numBuckets.0 and ﬁnd the index of the bucket where it falls. That guess is correct. Now we want to take a value in the range 0.0 to 1. As the number of buckets increases.102
Tuples
9. It would be better to make a single pass through the list and compute for each value the index of the bucket in which it falls. it is not as eﬃcient as it could be.0 by numBuckets. Every time it calls inBucket. it traverses the entire list. Then we can increment the appropriate counter. dividing by bucketWidth is the same as multiplying by numBuckets. we get exactly what we are looking for—a bucket index: numBuckets = 8 buckets = [0] * numBuckets for i in list: index = int(i * numBuckets) buckets[index] = buckets[index] + 1 We used the int function to convert a ﬂoating-point number to an integer. Since bucketWidth = 1. write a function called histogram that takes a list and a number of buckets as parameters and returns a histogram with the given number of buckets. In the previous section we took an index.0 to 1.8
A single-pass solution
Although this program works.
. and multiplied it by the bucketWidth to ﬁnd the lower bound of a given bucket. Is it possible for this calculation to produce an index that is out of range (either negative or greater than len(buckets)-1)? A list like buckets that contains counts of the number of values in each range is called a histogram. Since this problem is the inverse of the previous problem.0 to numBuckets. we get a number in the range from 0. we might guess that we should divide by bucketWidth instead of multiplying.

pattern matching: A program development plan that involves identifying a familiar computational pattern and copying the solution to a similar problem. tuple assignment: An assignment to all of the elements in a tuple using a single assignment statement. strings and tuples are not. pseudorandom: A sequence of numbers that appear to be random but that are actually the result of a deterministic computation.9.9 Glossary
103
9.9
Glossary
immutable type: A type in which the elements cannot be modiﬁed. tuple: A sequence type that is similar to a list except that it is immutable. mutable type: A data type in which the elements can be modiﬁed. deterministic: A program that does the same thing each time it is called. Tuples can be used wherever an immutable type is required. All mutable types are compound types. Tuple assignment occurs in parallel rather than in sequence.
. Lists and dictionaries are mutable data types. Assignments to elements or slices of immutable types cause an error. such as a key in a dictionary. making it useful for swapping values. histogram: A list of integers in which each element counts the number of times something happens.

104
Tuples
.

One way to create a dictionary is to start with the empty dictionary and add elements. the indices are called keys. For this dictionary. the other assignments add new elements to the dictionary. The empty dictionary is denoted {}: >>> eng2sp = {} >>> eng2sp[’one’] = ’uno’ >>> eng2sp[’two’] = ’dos’ The ﬁrst assignment creates a dictionary named eng2sp. we will create a dictionary to translate English words into Spanish. and tuples—use integers as indices. so the elements are called key-value pairs. Another way to create a dictionary is to provide a list of key-value pairs using the same syntax as the previous output:
. As an example. Dictionaries are similar to other compound types except that they can use any immutable type as an index. Each entry contains an index and a value separated by a colon. ’two’: ’dos’} The elements of a dictionary appear in a comma-separated list.Chapter 10
Dictionaries
The compound types you have learned about—strings. lists. We can print the current value of the dictionary in the usual way: >>> print eng2sp {’one’: ’uno’. you get an error. If you try to use any other type as an index. the indices are strings. In a dictionary.

’bananas’: 312} If someone buys all of the pears. ’three’: ’tres’} If we print the value of eng2sp again. For example.1
Dictionary operations
The del statement removes a key-value pair from a dictionary. there is no reason to care about the order. ’two’: ’dos’} The key-value pairs are not in order! Fortunately. ’two’: ’dos’. ’pears’: 0. we might just change the value associated with pears: >>> inventory[’pears’] = 0 >>> print inventory {’oranges’: 525. the following dictionary contains the names of various fruits and the number of each fruit in stock: >>> inventory = {’apples’: 430. ’pears’: 217.106
Dictionaries
>>> eng2sp = {’one’: ’uno’. ’pears’: 217} >>> print inventory {’oranges’: 525. we can remove the entry from the dictionary: >>> del inventory[’pears’] >>> print inventory {’oranges’: 525. since the elements of a dictionary are never indexed with integer indices. ’bananas’: 312} The len function also works on dictionaries. it returns the number of key-value pairs: >>> len(inventory) 4
. ’bananas’: 312} Or if we’re expecting more pears soon. ’oranges’: 525. ’apples’: 430. ’three’: ’tres’. ’apples’: 430. ’bananas’: 312. ’apples’: 430. we get a surprise: >>> print eng2sp {’one’: ’uno’. Instead. we use the keys to look up the corresponding values: >>> print eng2sp[’two’] ’dos’ The key ’two’ yields the value ’dos’ even though it appears in the third keyvalue pair.
10.

For example.has_key(’deux’) 0 If you try to call a method without specifying an object. ’dos’)] The syntax provides useful type information.keys(). ’two’] This form of dot notation speciﬁes the name of the function. The parentheses indicate that this method takes no parameters. in the form of a list of tuples—one for each key-value pair: >>> eng2sp. (’three’.values() [’uno’. eng2sp. you get an error. and the name of the object to apply the function to. ’three’. we would say that we are invoking keys on the object eng2sp. ’tres’.2
Dictionary methods
A method is similar to a function—it takes parameters and returns a value— but the syntax is diﬀerent. the keys method takes a dictionary and returns a list of the keys that appear.has_key(’one’) 1 >>> eng2sp.2 Dictionary methods
107
10. we use the method syntax eng2sp. in this case. The values method is similar.’uno’). The parentheses indicate that the elements of the list are tuples. keys. The square brackets indicate that this is a list. ’tres’). ’dos’] The items method returns both. it uses the same syntax as a function call. (’two’.10.items() [(’one’.keys() [’one’. but instead of the function syntax keys(eng2sp). it returns a list of the values in the dictionary: >>> eng2sp. In this case. For example. A method call is called an invocation. the method has key takes a key and returns true (1) if the key appears in the dictionary: >>> eng2sp. If a method takes an argument. >>> eng2sp. the error message is not very helpful: >>> has_key(’one’) NameError: has_key
.

If we modify alias.0]. copy refers to a fresh copy of the same dictionary. opposites is a dictionary that contains pairs of opposites: >>> opposites = {’up’: ’down’. [0.0].0.1. For example.0].0] ]
.108
Dictionaries
10. changes to one aﬀect the other.0.2.0.0.0.0]. use the copy method. [0. Whenever two variables refer to the same object.0. but consider a sparse matrix like this one:
0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 1 0 0 0 3 0 0 0 0 0
The list representation contains a lot of zeroes: matrix = [ [0.4
Sparse matrices
In Section 8.copy() alias and opposites refer to the same object. you need to be aware of aliasing.14.0. ’true’: ’false’} >>> alias = opposites >>> copy = opposites.3. opposites is unchanged: >>> copy[’right’] = ’privilege’ >>> opposites[’right’] ’left’
10.0. If you want to modify a dictionary and keep a copy of the original. opposites is also changed: >>> alias[’right’] = ’left’ >>> opposites[’right’] ’left’ If we modify copy.0.0. we used a list of lists to represent a matrix. [0. That is a good choice for a matrix with mostly nonzero values.3
Aliasing and copying
Because dictionaries are mutable. ’right’: ’wrong’. [0.0.0.

the longer the function takes to run. we use one index. Each key is a tuple. (2.3): 1. 0) 0 get deﬁnitely improves the semantics of accessing a sparse matrix.get((0. you might have noticed that the bigger the argument you provide. If we specify an element that is zero.3). On one of our machines. the second argument is the value get should return if the key is not in the dictionary: >>> matrix. fibonacci(30) takes about a second. the run time increases very quickly. because there is no entry in the dictionary with that key: >>> matrix[1. one for each nonzero element of the matrix. To access an element of the matrix. 1): 2. Here is the dictionary representation of the same matrix: matrix = {(0.3). There is one problem. which is a tuple of integers. 3): 3} We only need three key-value pairs.7.
10.get((1. 3) The get method solves this problem: >>> matrix. we get an error. Instead of two integer indices. 0) 1 The ﬁrst argument is the key.
. Furthermore.5 Hints
109
An alternative is to use a dictionary. and each value is an integer. and fibonacci(40) takes roughly forever. fibonacci(20) ﬁnishes instantly. Shame about the syntax. (4. we could use the [] operator: matrix[0. For the keys.5
Hints
If you played around with the fibonacci function from Section 5.3] KeyError: (1.10.3] 1 Notice that the syntax for the dictionary representation is not the same as the syntax for the nested list representation. we can use tuples that contain the row and column numbers.

The new value is added to the dictionary before the function returns. We start with only two pairs: 0 maps to 1. A good solution is to keep track of values that have already been computed by storing them in a dictionary. Count how many times fibonacci(0) and fibonacci(1) are called.
. fibonacci with n=3 calls fibonacci with n=2 and n=1. In turn. If not.has_key(n): return previous[n] else: newValue = fibonacci(n-1) + fibonacci(n-2) previous[n] = newValue return newValue The dictionary named previous keeps track of the Fibonacci numbers we already know. Whenever fibonacci is called. A previously computed value that is stored for later use is called a hint. Here is an implementation of fibonacci using hints: previous = {0:1. and 1 maps to 1. the function can return immediately without making any more recursive calls.110
Dictionaries
To understand why. consider this call graph for fibonacci with n=4:
fibonacci n 4
fibonacci n 3
fibonacci n 2
fibonacci n 2
fibonacci n 1
fibonacci n 1
fibonacci n 0
fibonacci n 1
fibonacci n 0
A call graph shows a set function frames. it checks the dictionary to determine if it contains the result. and it gets far worse as the argument gets bigger. This is an ineﬃcient solution to the problem. 1:1} def fibonacci(n): if previous. If it’s there. And so on. At the top of the graph. fibonacci with n=4 calls fibonacci with n=3 and n=2. with lines connecting each frame to the frames of the functions it calls. it has to compute the new value.

Fortunately. is 20. The ﬁrst two numbers in the sequence are long ints. so we don’t have to do much to adapt fibonacci: >>> previous = {0:1L. so all of the subsequent numbers in the sequence are. The problem is that this number is too big to ﬁt into a Python integer. long can accept any numerical type and even strings of digits: >>> long(1) 1L >>> long(3.
.9) 3L >>> long(’57’) 57L All of the math operations work on long ints. we get a diﬀerent problem: >>> fibonacci(50) OverflowError: integer addition The answer.6
Long integers
Python provides a type called long int that can handle any size integer. we change the behavior of fibonacci.6 Long integers
111
Using this version of fibonacci. It overﬂows. this problem has an easy solution. 1:1L} >>> fibonacci(50) 20365011074L Just by changing the initial contents of previous.
10. as you will see in a minute. One is to write an integer with a capital L at the end: >>> type(1L) <type ’long int’> The other is to use the long function to convert a value to a long int.365. There are two ways to create a long int value. As an exercise.10. convert factorial so that it produces a long int as a result.011. too.074. But when we try to compute fibonacci(50). our machines can compute fibonacci(40) in an eyeblink.

There are several other list methods. including append. how many times each letter appears.
10.. 2). Dictionaries provide an elegant way to generate a histogram: >>> letterCounts = {} >>> for letter in "Mississippi": . At the end. key-value pair: One of the items in a dictionary. method: A kind of function that is called with a diﬀerent syntax and invoked “on” an object. (’p’.8
Glossary
dictionary: A collection of key-value pairs that maps from keys to values. Consult the Python documentation for details. we wrote a function that counted the number of occurrences of a letter in a string. and reverse. but sort is the ﬁrst method you have encountered that applies to lists.7
Counting letters
In Chapter 7. 4). we ﬁnd the current count (possibly zero) and increment it. It might be more appealing to display the histogram in alphabetical order.. and the values can be any type. A more general version of this problem is to form a histogram of the letters in the string. 0) + 1 ..get (letter. ’p’: 2.
. We can do that with the items and sort methods: >>> letterItems = letterCounts.. letterCounts[letter] = letterCounts. ’i’: 4} We start with an empty dictionary.sort() >>> print letterItems [(’M’. 1). (’s’.112
Dictionaries
10.items() >>> letterItems. that is. For each letter in the string. Because diﬀerent letters appear with diﬀerent frequencies. extend. the dictionary contains pairs of letters and their frequencies. Such a histogram might be useful for compressing a text ﬁle. (’i’. key: A value that is used to look up an entry in a dictionary. we can compress a ﬁle by using shorter codes for common letters and longer codes for letters that appear less frequently. ’s’: 4. 4)] You have seen the items method before. >>> letterCounts {’M’: 1. The keys can be any immutable type.

10.
113
hint: Temporary storage of a precomputed value to avoid redundant computation.8 Glossary invoke: To call a method. overﬂow: A numerical result that is too large to be represented in a numerical format.
.

114
Dictionaries
.

or CD-ROM. or a combination of a ﬁle name and a directory name.
. or the computer shuts down. Files are usually stored on a hard drive.dat".dat’. mode ’w’ at fe820> The open function takes two arguments. Each ﬁle is identiﬁed by a unique name. Most of the time."w") >>> print f <open file ’test. you can either write in it or read from it. While the book is open. you have to put it in a ﬁle. When there are a large number of ﬁles. The ﬁrst is the name of the ﬁle. ﬂoppy drive. you know where you are in the book. and the second is the mode. they are often organized into directories (also called “folders”). data in memory disappears. its data is in memory. you specify its name and indicate whether you want to read or write. When you’re done. In this example. Mode "w" means that we are opening the ﬁle for writing. By reading and writing ﬁles. Opening a ﬁle creates a ﬁle object. programs can exchange information with each other and generate printable formats like PDF. you have to close it. >>> f = open("test. you read the whole book in its natural order. but you can also skip around. When the program ends. To open a ﬁle. To use a book. you have to open it. To store data permanently. In either case. Working with ﬁles is a lot like working with books.Chapter 11
Files and exceptions
While a program is running. the variable f refers to the new ﬁle object. All of this applies to ﬁles as well.

read() >>>
."r") >>> print f.write("Now is the time") >>> f. With no arguments."r") IOError: [Errno 2] No such file or directory: ’test. When we get to the end of the ﬁle. read can also take an argument that indicates how many characters to read: >>> f = open("test. it will be created.write("to close the file") Closing the ﬁle tells the system that we are done writing and makes the ﬁle available for reading: >>> f.close() Now we can open the ﬁle again. we get an error: >>> f = open("test. the mode. This time."r") If we try to open a ﬁle that doesn’t exist. and read the contents into a string. When we print the ﬁle object. If there already is one. read returns the empty string: >>> print f. the mode argument is "r" for reading: >>> f = open("test.cat’ Not surprisingly. it will be replaced by the ﬁle we are writing. To put data in the ﬁle we invoke the write method on the ﬁle object: >>> f.read() >>> print text Now is the timeto close the file There is no space between “time” and “to” because we did not write a space between the strings.dat". the read method reads data from the ﬁle.cat". and the location of the object.dat. read returns the remaining characters.dat".read(5) Now i If not enough characters are left in the ﬁle.116
Files and exceptions
If there is no ﬁle named test. we see the name of the ﬁle. it reads the entire contents of the ﬁle: >>> text = f.read(1000006) s the timeto close the file >>> print f. this time for reading.

dat". The only way to get out of the loop is to execute break.close() f2.close() return The break statement is new.
11.write(text) f1. "w") while 1: text = f1. "r") f2 = open(newFile. reading and writing up to ﬁfty characters at a time.read(50) if text == "": break f2. the second is the name of the new ﬁle: def copyFile(oldFile."w") >>> f. organized into lines separated by newline characters.close() The readline method reads all the characters up to and including the next newline character: >>> f = open("test.1
Text ﬁles
A text ﬁle is a ﬁle that contains printable characters and whitespace. Since Python is speciﬁcally designed to process text ﬁles."r") >>> print f. which happens when text is the empty string. it provides methods that make the job easy.1 Text ﬁles
117
The following function copies a ﬁle.dat".11. To demonstrate. The ﬁrst argument is the name of the original ﬁle. the while loop is inﬁnite because the value 1 is always true. the ﬂow of execution moves to the ﬁrst statement after the loop.write("line one\nline two\nline three\n") >>> f. we’ll create a text ﬁle with three lines of text separated by newlines: >>> f = open("test. newFile): f1 = open(oldFile.readline() line one >>>
. In this example. which happens when we get to the end of the ﬁle. Executing it breaks out of the loop.

’line three\012’] In this case. "r") f2 = open(newFile.
11.close() return The continue statement ends the current iteration of the loop. which means that the strings appear with quotation marks and the newline character appears as the escape sequence 012.readline() if text == "": break if text[0] == ’#’: continue f2. The ﬂow of execution moves to the top of the loop. the output is in list format. but continues looping. Only if both conditions fail do we copy text into the new ﬁle. if text is the empty string. and proceeds accordingly. we have to convert them to strings ﬁrst. If the ﬁrst character of text is a hash mark. so if we want to put other values in a ﬁle.readlines() [] The following is an example of a line-processing program.118
Files and exceptions
readlines returns all of the remaining lines as a list of strings: >>> print f. readline returns the empty string and readlines returns the empty list: >>> print f. "w") while 1: text = f1.readline() >>> print f. At the end of the ﬁle.close() f2. the loop exits. newFile): f1 = open(oldFile.write(text) f1. filterFile makes a copy of oldFile. The easiest way to do that is
. checks the condition.readlines() [’line two\012’. Thus. the ﬂow of execution goes to the top of the loop.2
Writing variables
The argument of write has to be a string. omitting any lines that begin with #: def filterFile(oldFile.

’dollars’) ’In 34 days we made 6. But when the ﬁrst operand is a string.2) not enough arguments for format string ’dollars’ illegal argument type for built-in operation
. When applied to integers. The number of expressions in the tuple has to match the number of format sequences in the string. Also. The result is a string that contains the values of the expressions.’ The format sequence "%f" formats the next item in the tuple as a ﬂoating-point number.’ By default.2 Writing variables with the str function: >>> x = 52 >>> f. % is the format operator. the format sequence "%d" means that the ﬁrst expression in the tuple should be formatted as an integer. A format sequence can appear anywhere in the format string. Here the letter d stands for “decimal”: >>> cars = 52 >>> "%d" % cars ’52’ The result is the string ’52’. formatted according to the format string.6. the ﬂoating-point format prints six decimal places.1. and the second operand is a tuple of expressions. % is the modulus operator. and "%s" formats the next item as a string: >>> "In %d days we made %f million %s.100000 million dollars. As a simple example. the types of the expressions have to match the format sequences: >>> "%d %d TypeError: >>> "%d" % TypeError: %d" % (1.11." % (34.write (str(x))
119
An alternative is to use the format operator %." % cars ’In July we sold 52 cars. The ﬁrst operand is the format string. which is not to be confused with the integer value 52. so we can embed a value in a sentence: >>> cars = 52 >>> "In July we sold %d cars.

For more control over the format of numbers.100000’ The number after the percent sign is the minimum number of spaces the number will take up. as long as the names contain fewer than twenty-one characters and the wages are less than one billion dollars an hour. Here is a function that prints the contents of the dictionary as a formatted report: def report (wages) : students = wages. there aren’t enough expressions.sort() for student in students : print "%-20s %12. the expression is the wrong type.23 By controlling the width of each value.keys() students.25 mary 6. ’joe’: 5. imagine a dictionary that contains student names as keys and hourly wages as values. we’ll create a small dictionary and print the contents: >>> wages = {’mary’: 6. in the second. we guarantee that the columns will line up.2f" % 6. leading spaces are added. we can also specify the number of digits after the decimal point: >>> "%12. If the value provided takes fewer digits.02f" % (student.45 joshua 4. If the number of spaces is negative. This format is useful for printing dollar amounts with the decimal points aligned.45.
. wages[student]) To test this the function. trailing spaces are added: >>> "%-6d" % 62 ’62 ’ For ﬂoating-point numbers. we can specify the number of digits as part of the format sequence: >>> "%6d" % 62 ’ 62’ >>> "%12f" % 6.10’ In this example.25} >>> report (wages) joe 5. the result takes up twelve spaces and includes two digits after the decimal.1 ’ 6. For example. ’joshua’: 4.120
Files and exceptions
In the ﬁrst example.1 ’ 6.23.

so called because it “preserves” data structures. import pickle and then open the ﬁle in the usual way: >>> import pickle >>> f = open("test. In fact. If you want to open a ﬁle somewhere else. You cannot use / as part of a ﬁlename.3[1.readline() Aarhus This example opens a ﬁle named words that resides in a directory named dict. you get a string.write (str(12. it is reserved as a delimiter between directory and ﬁlenames."w")
. 2.4
Pickling
In order to put values into a ﬁle.3
Directories
When you create a new ﬁle by opening it and writing. of which the ﬁrst is the name of a Danish university. called /. which resides in usr.readline() ’12.3)) >>> f. The pickle module contains the necessary commands.
11. which is the name of the directory (or folder) where the ﬁle is located: >>> f = open("/usr/share/dict/words". The original type information has been lost.11. which resides in the top-level directory of the system. you can’t even tell where one value ends and the next begins: >>> f. Python looks for it in the current directory. You have already seen how to do that with str: >>> f.write (str([1. you have to convert them to strings. which resides in share.3 Directories
121
11. The ﬁle /usr/share/dict/words contains a list of words in alphabetical order. To use it. 3]’ The solution is pickling. when you open a ﬁle for reading. you have to specify the path to the ﬁle. the new ﬁle goes in the current directory (wherever you were when you ran the program)."r") >>> print f. Similarly.2.3])) The problem is that when you read the value back.pck".

dump(12. For example.2.load(f) >>> x 12. use the dump method and then close the ﬁle in the usual way: >>> pickle.5
Exceptions
Whenever a runtime error occurs.
11.pck".3 >>> type(x) <type ’float’> >>> y = pickle. f) >>> f.load(f) >>> y [1.close() Then we can open the ﬁle for reading and load the data structures we dumped: >>> f = open("test. it creates an exception. dividing by zero creates an exception: >>> print 55/0 ZeroDivisionError: integer division or modulo So does accessing a nonexistent list item: >>> a = [] >>> print a[5] IndexError: list index out of range Or accessing a key that isn’t in the dictionary: >>> b = {} >>> print b[’what’] KeyError: what
.dump([1.122
Files and exceptions
To store a data structure.3. Usually. 2. we get a single value from the ﬁle."r") >>> x = pickle. 3] >>> type(y) <type ’list’> Each time we invoke load. f) >>> pickle. complete with its original type.3]. the program stops and Python prints an error message.

11.5 Exceptions

123

In each case, the error message has two parts: the type of error before the colon, and speciﬁcs about the error after the colon. Normally Python also prints a traceback of where the program was, but we have omitted that from the examples. Sometimes we want to execute an operation that could cause an exception, but we don’t want the program to stop. We can handle the exception using the try and except statements. For example, we might prompt the user for the name of a ﬁle and then try to open it. If the ﬁle doesn’t exist, we don’t want the program to crash; we want to handle the exception: filename = raw_input(’Enter a file name: ’) try: f = open (filename, "r") except: print ’There is no file named’, filename The try statement executes the statements in the ﬁrst block. If no exceptions occur, it ignores the except statement. If any exception occurs, it executes the statements in the except branch and then continues. We can encapsulate this capability in a function: exists takes a ﬁlename and returns true if the ﬁle exists, false if it doesn’t: def exists(filename): try: f = open(filename) f.close() return 1 except: return 0 You can use multiple except blocks to handle diﬀerent kinds of exceptions. The Python Reference Manual has the details. If your program detects an error condition, you can make it raise an exception. Here is an example that gets input from the user and checks for the value 17. Assuming that 17 is not valid input for some reason, we raise an exception. def inputNumber () : x = input (’Pick a number: ’) if x == 17 : raise ’BadNumberError’, ’17 is a bad number’ return x

124

Files and exceptions

The raise statement takes two arguments: the exception type and speciﬁc information about the error. BadNumberError is a new kind of exception we invented for this application. If the function that called inputNumber handles the error, then the program can continue; otherwise, Python prints the error message and exits: >>> inputNumber () Pick a number: 17 BadNumberError: 17 is a bad number The error message includes the exception type and the additional information you provided. As an exercise, write a function that uses inputNumber to input a number from the keyboard and that handles the BadNumberError exception.

11.6

Glossary

ﬁle: A named entity, usually stored on a hard drive, ﬂoppy disk, or CD-ROM, that contains a stream of characters. directory: A named collection of ﬁles, also called a folder. path: A sequence of directory names that speciﬁes the exact location of a ﬁle. text ﬁle: A ﬁle that contains printable characters organized into lines separated by newline characters. break statement: A statement that causes the ﬂow of execution to exit a loop. continue statement: A statement that causes the current iteration of a loop to end. The ﬂow of execution goes to the top of the loop, evaluates the condition, and proceeds accordingly. format operator: The % operator takes a format string and a tuple of expressions and yields a string that includes the expressions, formatted according to the format string. format string: A string that contains printable characters and format sequences that indicate how to format values. format sequence: A sequence of characters beginning with % that indicates how to format a value.

11.6 Glossary

125

pickle: To write a data value in a ﬁle along with its type information so that it can be reconstituted later. exception: An error that occurs at runtime. handle: To prevent an exception from terminating a program using the try and except statements. raise: To signal an exception using the raise statement.

126

Files and exceptions

Chapter 12

Classes and objects
12.1 User-deﬁned compound types

Having used some of Python’s built-in types, we are ready to create a userdeﬁned type: the Point. Consider the concept of a mathematical point. In two dimensions, a point is two numbers (coordinates) that are treated collectively as a single object. In mathematical notation, points are often written in parentheses with a comma separating the coordinates. For example, (0, 0) represents the origin, and (x, y) represents the point x units to the right and y units up from the origin. A natural way to represent a point in Python is with two ﬂoating-point values. The question, then, is how to group these two values into a compound object. The quick and dirty solution is to use a list or tuple, and for some applications that might be the best choice. An alternative is to deﬁne a new user-deﬁned compound type, also called a class. This approach involves a bit more eﬀort, but it has advantages that will be apparent soon. A class deﬁnition looks like this: class Point: pass Class deﬁnitions can appear anywhere in a program, but they are usually near the beginning (after the import statements). The syntax rules for a class deﬁnition are the same as for other compound statements (see Section 4.4).

There
.0 The expression blank.x = 3.0
The variable blank refers to a Point object.y = 4.x >>> print x 3. we call a function named (you guessed it) Point: blank = Point() The variable blank is assigned a reference to a new Point object. The following state diagram shows the result of these assignments:
blank x y 3. These named items are called attributes.128
Classes and objects
This deﬁnition creates a new class called Point. we are selecting a data item from an instance. also called Point.y 4. Creating a new instance is called instantiation. By creating the Point class. though. In this case. A function like Point that creates new objects is called a constructor.0 4.x means. which contains two attributes. such as math.0 >>> blank.2
Attributes
We can add new data to an instance using dot notation: >>> blank.0 >>> x = blank.” In this case. we assign that value to a variable named x. The pass statement has no eﬀect.pi or string. We can read the value of an attribute using the same syntax: >>> print blank. The members of this type are called instances of the type or objects. “Go to the object blank refers to and get the value of x. Each attribute refers to a ﬂoating-point number. it is only necessary because a compound statement must have something in its body. we created a new type.uppercase. To instantiate a Point object.0 This syntax is similar to the syntax for selecting a variable from a module.
12.

“Chris and I have the same car. For example. but that they are two diﬀerent cars. As an exercise.y) + ’)’ distanceSquared = blank. 80f8e70 is the unique identiﬁer for this object. the output is (3. so the following statements are legal: print ’(’ + str(blank.12. As an exercise. and then you realize there is more to it than you expected. For example: def printPoint(p): print ’(’ + str(p. You might be tempted to print the value of blank itself: >>> print blank <__main__.y) + ’)’ printPoint takes a point as an argument and displays it in the standard format. the second line calculates the value 25.2 so that it takes two Points as parameters instead of four numbers. and then use id to print the object’s unique identiﬁer. ’ + str(blank.y * blank. rewrite the distance function from Section 5.x + blank. create and print a Point object.
12.0.Point instance at 80f8e70> The result indicates that blank is an instance of the Point class and it was deﬁned in main . 4. This is probably not the most informative way to display a Point object. The purpose of dot notation is to identify which variable you are referring to unambiguously.x * blank.0).x) + ’.” you mean that his car and yours are the same make and model. 4. written in hexadecimal (base 16).
. You will see how to change it shortly.3 Instances as parameters
129
is no conﬂict between the variable x and the attribute x.x) + ’.0).4
Sameness
The meaning of the word “same” seems perfectly clear until you give it some thought. if you say.3
Instances as parameters
You can pass an instance as a parameter in the usual way. You can use dot notation as part of any expression.0. Translate the hexadecimal form into decimal and conﬁrm that they match.
12. If you call printPoint(blank).0.y The ﬁrst line outputs (3. ’ + str(p.

x == p2.” and “same mother” would be “selbe Mutter.x) and (p1. there is a similar ambiguity. For example. For example: >>> >>> >>> >>> >>> >>> >>> 0 p1 = Point() p1. p2) : return (p1. When you talk about objects.x = 3 p1. If we assign p1 to p2. does that mean they contain the same data (coordinates) or that they are actually the same object? To ﬁnd out if two references refer to the same object.
1 Not all languages have the same problem.” you mean that his mother and yours are the same person. if two Points are the same. “Chris and I have the same mother.x = 3 p2. not the contents of the objects.1 So the idea of “sameness” is diﬀerent depending on the context.y == p2. use the == operator. then the two variables are aliases of the same object: >>> p2 = p1 >>> p1 == p2 1 This type of equality is called shallow equality because it compares only the references.”
.130
Classes and objects
If you say. German has diﬀerent words for diﬀerent kinds of sameness. we can use samePoint to ﬁnd out if they represent the same point. “Same car” in this context would be “gleiche Auto. they are not the same object. To compare the contents of the objects—deep equality—we can write a function called samePoint: def samePoint(p1. For example.y = 4 p1 == p2
Even though p1 and p2 contain the same coordinates.y) Now if we create two diﬀerent objects that contain the same data.y = 4 p2 = Point() p2.

0 This code creates a new Rectangle object with two ﬂoating-point attributes. There are a few possibilities: we could specify the center of the rectangle (two coordinates) and its size (width and height).0. we’ll deﬁne a new class: class Rectangle: pass And instantiate it: box = Rectangle() box.5 Rectangles >>> >>> >>> >>> >>> >>> >>> 1 p1 = Point() p1.corner = Point() box.y = 4 samePoint(p1.height = 200.y = 4 p2 = Point() p2. assume that the rectangle is oriented either vertically or horizontally.y = 0. or we could specify one of the corners and the size. The dot operator composes.corner.width = 100. The question is. A conventional choice is to specify the upper-left corner of the rectangle and the size.0.0 box. “Go to the object box refers to and select the attribute named corner.12. p2)
131
Of course.corner.x = 3 p1. we can embed an object within an object! box. what information do we have to provide in order to specify a rectangle? To keep things simple.”
.x = 0. To specify the upper-left corner. never at an angle.x means.x = 3 p2. box.5
Rectangles
Let’s say that we want a class to represent a rectangle. if the two variables refer to the same object. Again. The expression box. or we could specify two opposing corners.corner. then go to that object and select the attribute named x. they have both shallow and deep equality.
12.

height + dheight
.0
12.0 return p To call this function. findCenter takes a Rectangle as an argument and returns a Point that contains the coordinates of the center of the Rectangle: def findCenter(box): p = Point() p.0)
12. dwidth.height/2. 100.x = box.y + box. pass box as an argument and assign the result to a variable: >>> center = findCenter(box) >>> printPoint(center) (50.corner.0 p.132 The ﬁgure shows the state of this object:
box width height corner 100. For example. dheight) : box.0 0. we could modify the values of width and height: box.6
Instances as return values
Functions can return instances.0.height = box.0 200.width/2.0 x y
Classes and objects
0.x + box.width = box.width = box.height + 100 We could encapsulate this code in a method and generalize it to grow the rectangle by any amount: def growRect(box.y = box. For example.height = box.width + dwidth box. to change the size of a rectangle without changing its position.7
Objects are mutable
We can change the state of an object by making an assignment to one of its attributes.width + 50 box.corner.

x = 0. but they contain the same data. we could create a new Rectangle named bob and pass it to growRect: >>> >>> >>> >>> >>> >>> >>> bob = Rectangle() bob. It is hard to keep track of all the variables that might refer to a given object.copy(p1) p1 == p2 samePoint(p1. write a function named moveRect that takes a Rectangle and two parameters named dx and dy.
12. As an exercise.12.8
Copying
Aliasing can make a program diﬃcult to read because changes made in one place might have unexpected eﬀects in another place.0.x = 3 p1.
. bob.corner = Point() bob.height = 200.corner.width = 100. Invoking this method has the eﬀect of modifying the Rectangle that is passed as an argument.0 bob.0. 100)
While growRect is running. growRect(bob. Copying an object is often an alternative to aliasing. the parameter box is an alias for bob.corner. p1 and p2 are not the same point. For example. The copy module contains a function called copy that can duplicate any object: >>> >>> >>> >>> >>> >>> 0 >>> 1 import copy p1 = Point() p1. p2)
Once we import the copy module.0 bob. Any changes made to box also aﬀect bob. 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.y = 4 p2 = copy.8 Copying
133
The variables dwidth and dheight indicate how much the rectangle should grow in each direction. 50.y = 0. we can use the copy method to make a new Point.

height + dheight return newBox An an exercise.height = newBox. dheight) : import copy newBox = copy.0 200. Fortunately. You will not be surprised to learn that this operation is called a deep copy.
.0
100. This is called shallow copying. the resulting state diagram looks like this:
b1
width height corner
100. For something like a Rectangle.width + dwidth newBox.width = newBox.deepcopy(box) newBox. in the usual way and then make a copy. It copies the reference to the Point object. In this case.0 200. copy doesn’t do quite the right thing.0 x y 0. rewrite moveRect so that it creates and returns a new Rectangle instead of modifying the old one. b2. so both the old Rectangle and the new one refer to a single Point.134
Classes and objects
To copy a simple object like a Point. invoking growRect on one of the Rectangles would not aﬀect the other.0 0. dwidth. >>> b2 = copy.deepcopy(b1) Now b1 and b2 are completely separate objects. but invoking moveRect on either would aﬀect both! This behavior is confusing and error-prone. which doesn’t contain any embedded objects. If we create a box. copy is suﬃcient.0
width height corner
b2
This is almost certainly not what we want. b1. which contains a reference to a Point. using copy. We can use deepcopy to rewrite growRect so that instead of modifying an existing Rectangle. it creates a new Rectangle that has the same location as the old one but new dimensions: def growRect(box. the copy module contains a method named deepcopy that copies not only the object but also any embedded objects.

A class can also be thought of as a template for the objects that are instances of it.9
Glossary
class: A user-deﬁned compound type. or two references that point to the same object. instantiate: To create an instance of a class. and any objects embedded in them.9 Glossary
135
12. instance: An object that belongs to a class. including any references to embedded objects. implemented by the copy function in the copy module. constructor: A method used to create new objects.
. shallow copy: To copy the contents of an object. or two references that point to objects that have the same value. attribute: One of the named data items that makes up an instance. object: A compound data type that is often used to model a thing or concept in the real world. implemented by the deepcopy function in the copy module. deep equality: Equality of values.12. deep copy: To copy the contents of an object as well as any embedded objects. shallow equality: Equality of references. and so on.

136
Classes and objects
.

.1 Time
As another example of a user-deﬁned type. write a function printTime that takes a Time object as an argument and prints it in the form hours:minutes:seconds. minutes.Chapter 13
Classes and functions
13. The class deﬁnition looks like this: class Time: pass We can create a new Time object and assign attributes for hours. and seconds: time = Time() time.hours = 11 time.minutes = 59 time. we’ll deﬁne a class called Time that records the time of day.seconds = 30 The state diagram for the Time object looks like this:
time hour minute second 11 59 30
As an exercise.

The following is a rough version of addTime: def addTime(t1. write a boolean function after that takes two Time objects. take a look ahead to Section 14. Here is an example of how to use this function.seconds return sum The function creates a new Time object.seconds = 0
>>> doneTime = addTime(currentTime.hours sum.minutes = t1. breadTime) >>> printTime(doneTime)
.hours = 3 breadTime.138
Classes and functions As a second exercise.seconds = 30 breadTime = Time() breadTime. Then we’ll use addTime to ﬁgure out when the bread will be done.minutes = 14 currentTime.minutes + t2.hours + t2. we’ll write two versions of a function called addTime. which contains the current time. which calculates the sum of two Times. such as displaying a value or getting user input. This is called a pure function because it does not modify any of the objects passed to it as parameters and it has no side eﬀects. t2): sum = Time() sum. and breadTime. which contains the amount of time it takes for a breadmaker to make bread. t1 and t2. initializes its attributes. They will demonstrate two kinds of functions: pure functions and modiﬁers. and returns true (1) if t1 follows t2 chronologically and false (0) otherwise.seconds + t2.minutes sum. and returns a reference to the new object.hours = 9 currentTime.2 before you try this: >>> >>> >>> >>> >>> >>> >>> >>> currentTime = Time() currentTime. If you haven’t ﬁnished writing printTime yet. We’ll create two Time objects: currentTime.minutes = 35 breadTime. as arguments.hours = t1.
13.2
Pure functions
In the next few sections.seconds = t1.

3
Modiﬁers
There are times when it is useful for a function to modify one or more of the objects it gets as parameters.seconds = sum.60 sum.minutes sum. A rough draft of the function looks like this:
. it is starting to get big. Can you think of one? The problem is that this function does not deal with cases where the number of seconds or minutes adds up to more than sixty.seconds . which adds a given number of seconds to a Time object.hours + t2. When that happens. t2): sum = Time() sum. increment.seconds = t1.hours sum.seconds + t2.60 sum.seconds if sum.seconds >= 60: sum. On the other hand.3 Modiﬁers
139
The output of this program is 12:49:30.minutes + t2.
13. would be written most naturally as a modiﬁer.hours + 1 return sum Although this function is correct. Here’s a second corrected version of the function: def addTime(t1.minutes = t1.minutes = sum. the caller keeps a reference to the objects it passes. there are cases where the result is not correct.13. so any changes the function makes are visible to the caller. Functions that work this way are called modiﬁers.minutes >= 60: sum.minutes = sum. Later we will suggest an alternative approach that yields shorter code.hours = sum. which is correct.minutes .hours = t1.minutes + 1 if sum. we have to “carry” the extra seconds into the minutes column or the extra minutes into the hours column. Usually.

minutes = time.minutes . some programming languages only allow pure functions.seconds = time.140 def increment(time.minutes = time.minutes . Is this function correct? What happens if the parameter seconds is much greater than sixty? In that case.seconds = time.hours = time.60 time.hours + 1
Classes and functions
The ﬁrst line performs the basic operation. There is some evidence that programs that use pure functions are faster to develop and less error-prone than programs that use modiﬁers. As an exercise.hours = time. One solution is to replace the if statements with while statements: def increment(time.seconds .seconds = time. seconds): time.minutes + 1 while time.seconds = time.minutes + 1 if time.seconds .minutes = time.60 time.
13. but it is not the most eﬃcient solution.minutes >= 60: time.minutes >= 60: time. modiﬁers are convenient at times. we have to keep doing it until seconds is less than sixty. Nevertheless. functional programs are less eﬃcient.minutes = time. and in some cases.seconds >= 60: time.60 time.seconds >= 60: time. rewrite increment as a pure function. it is not enough to carry once. the remainder deals with the special cases we saw before. In fact.hours + 1 This function is now correct.4
Which is better?
Anything that can be done with modiﬁers can also be done with pure functions. and write function calls to both versions. rewrite this function so that it doesn’t contain any loops.seconds + seconds if time. As a second exercise.seconds + seconds while time. seconds): time.60 time.
.

13.minutes = (seconds%3600)/60 time.” and the hour component is the “thirty-six hundreds column. it can lead to 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. we demonstrated an approach to program development that we call prototype development.5 Prototype development versus planning
141
In general.seconds return seconds Now. we wrote a rough draft (or prototype) that performed the basic calculation and then tested it on a few cases.5
Prototype development versus planning
In this chapter.” the minute component is the “sixties column.hours = seconds/3600 time.
13. This observation suggests another approach to the whole problem—we can convert a Time object into a single number and take advantage of the fact that the computer knows how to do arithmetic with numbers. In this case. The following function converts a Time object into an integer: def convertToSeconds(t): minutes = t. In each case.” When we wrote addTime and increment.seconds = seconds%60 return time You might have to think a bit to convince yourself that this function is correct. Assuming you are convinced. correcting ﬂaws as we found them. the insight is that a Time object is really a three-digit number in base 60! The second component is the “ones column. This approach might be called a functional programming style. we were eﬀectively doing addition in base 60. An alternative is planned development. you can use it and convertToSeconds to rewrite addTime:
. in which high-level insight into the problem can make the programming much easier. which is why we had to carry from one column to the next. we recommend that you write pure functions whenever it is reasonable to do so and resort to modiﬁers only if there is a compelling advantage. all we need is a way to convert from an integer to a Time object: def makeTime(seconds): time = Time() time.hours * 60 + t. Although this approach can be eﬀective.minutes seconds = minutes * 60 + t.

142

Classes and functions

def addTime(t1, t2): seconds = convertToSeconds(t1) + convertToSeconds(t2) return makeTime(seconds) This version is much shorter than the original, and it is much easier to demonstrate that it is correct. As an exercise, rewrite increment the same way.

13.6

Generalization

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 times is better. But if we have the insight to treat times as base 60 numbers and make the investment of writing the conversion functions (convertToSeconds and makeTime), 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 ﬁnd the duration between them. The na¨ approach would be to ıve 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).

13.7

Algorithms

When you write a general solution for a class of problems, as opposed to a speciﬁc solution to a single problem, you have written an algorithm. We mentioned this word before but did not deﬁne it carefully. It is not easy to deﬁne, so we will try a couple of approaches. First, consider something that is not an algorithm. When you learned to multiply single-digit numbers, you probably memorized the multiplication table. In eﬀect, you memorized 100 speciﬁc solutions. That kind of knowledge is not algorithmic. But if you were “lazy,” you probably cheated by learning a few tricks. For example, to ﬁnd the product of n and 9, you can write n − 1 as the ﬁrst digit and 10 − n as the second digit. This trick is a general solution for multiplying any single-digit number by 9. That’s an algorithm!

13.8 Glossary

143

Similarly, the techniques you learned for addition with carrying, subtraction with borrowing, and long division are all algorithms. One of the characteristics of algorithms is that they do not require any intelligence to carry out. They are mechanical processes in which each step follows from the last according to a simple set of rules. In our opinion, it is embarrassing that humans spend so much time in school learning to execute algorithms that, quite literally, require no intelligence. On the other hand, the process of designing algorithms is interesting, intellectually challenging, and a central part of what we call programming. Some of the things that people do naturally, without diﬃculty or conscious thought, are the hardest to express algorithmically. Understanding natural language is a good example. We all do it, but so far no one has been able to explain how we do it, at least not in the form of an algorithm.

13.8

Glossary

pure function: A function that does not modify any of the objects it receives as parameters. Most pure functions are fruitful. modiﬁer: A function that changes one or more of the objects it receives as parameters. Most modiﬁers are void. functional programming style: A style of program design in which the majority of functions are pure. prototype development: A way of developing programs starting with a prototype and gradually testing and improving it. planned development: A way of developing programs that involves high-level insight into the problem and more planning than incremental development or prototype development. algorithm: A set of instructions for solving a class of problems by a mechanical, unintelligent process.

144

Classes and functions

Chapter 14

Classes and methods
14.1 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 deﬁne object-oriented programming, but we have already seen some of its characteristics: • Programs are made up of object deﬁnitions and function deﬁnitions, and most of the computation is expressed in terms of operations on objects. • Each object deﬁnition 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 deﬁned in Chapter 13 corresponds to the way people record the time of day, and the functions we deﬁned 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. Strictly speaking, these features are not necessary. For the most part, they provide an 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 deﬁnition and the function deﬁnitions that follow. With some examination, it is apparent that every function takes at least one Time object as a parameter.

146

Classes and methods

This observation is the motivation for methods. We have already seen some methods, such as keys and values, which were invoked on dictionaries. Each method is associated with a class and is intended to be invoked on instances of that class. Methods are just like functions, with two diﬀerences: • Methods are deﬁned inside a class deﬁnition in order to make the relationship between the class and the method explicit. • The syntax for invoking a method is diﬀerent 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.

14.2

printTime

In Chapter 13, we deﬁned a class named Time and you wrote a function named printTime, which should have looked something like this: class Time: pass def printTime(time): print str(time.hours) + ":" + \ str(time.minutes) + ":" + \ str(time.seconds) To call this function, we passed a Time object as a parameter: >>> >>> >>> >>> >>> currentTime = Time() currentTime.hours = 9 currentTime.minutes = 14 currentTime.seconds = 30 printTime(currentTime)

To make printTime a method, all we have to do is move the function deﬁnition inside the class deﬁnition. Notice the change in indentation.

” In object-oriented programming. the objects are the active agents. it may not be. By convention. but it is not obvious that it is useful. suggests that the function is the active agent.. but it is based on a useful metaphor. but you should keep them in your version: class Time: #previous method definitions here. It says something like. the object on which the method is invoked appears before the dot and the name of the method appears after the dot. >>> currentTime.seconds) Now we can invoke printTime using dot notation.printTime() says “Hey currentTime! Please print yourself!” This change in perspective might be more polite. To save space. def increment(self. The reason for this is a little convoluted. The syntax for a function call.seconds
.3) to a method.minutes) + ":" + \ str(time. An invocation like currentTime.3
Another example
Let’s convert increment (from Section 13. printTime(currentTime).14.3 Another example class Time: def printTime(time): print str(time. seconds): self. “Hey printTime! Here’s an object for you to print. In the examples we have seen so far. we will leave out previously deﬁned methods.hours) + ":" + \ str(time. But sometimes shifting responsibility from the functions onto the objects makes it possible to write more versatile functions. the ﬁrst parameter of a method is called self..seconds = seconds + self. The object on which the method is invoked is assigned to the ﬁrst parameter. so in this case currentTime is assigned to the parameter time.
14.printTime()
147
As usual. and makes it easier to maintain and reuse code.

increment(500) Again.hour: return 0 if self. currentTime. the object on which the method is invoked gets assigned to the ﬁrst parameter.4
A more complicated example
The after function is slightly more complicated because it operates on two Time objects. seconds gets the value 500. We can only convert one of the parameters to self.hour > time2.minutes = self.. not just one.minute > time2.seconds >= 60: self. As an exercise. time2): if self.
14. Now we can invoke increment as a method. def after(self.seconds = self. self.minute: return 1 if self.hours = self.seconds .second: return 1 return 0
.hour: return 1 if self.60 self.minutes + 1 while self.5) to a method in the Time class.hour < time2.minutes .minutes >= 60: self. The second parameter.minute: return 0 if self.minutes = self.hours + 1
Classes and methods
The transformation is purely mechanical—we move the method deﬁnition into the class deﬁnition and change the name of the ﬁrst parameter.second > time2. the other stays the same: class Time: #previous method definitions here.minute < time2.60 self.148 while self. convert convertToSeconds (from Section 13..

14.5 Optional arguments We invoke this method on one object and pass the other as an argument: if doneTime.after(currentTime): print "The bread is not done yet."

149

You can almost read the invocation like English: “If the done-time is after the current-time, then...”

14.5

Optional arguments

We have seen built-in functions that take a variable number of arguments. For example, string.find can take two, three, or four arguments. It is possible to write user-deﬁned functions with optional argument lists. For example, we can upgrade our own version of find to do the same thing as string.find. This is the original version from Section 7.7: def find(str, ch): index = 0 while index < len(str): if str[index] == ch: return index index = index + 1 return -1 This is the new and improved version: def find(str, ch, start=0): index = start while index < len(str): if str[index] == ch: return index index = index + 1 return -1 The third parameter, start, is optional because a default value, 0, is provided. If we invoke find with only two arguments, it uses the default value and starts from the beginning of the string: >>> find("apple", "p") 1 If we provide a third parameter, it overrides the default:

150 >>> find("apple", "p", 2) 2 >>> find("apple", "p", 3) -1

Classes and methods

As an exercise, add a fourth parameter, end, that speciﬁes where to stop looking. Warning: This exercise is a bit tricky. The default value of end should be len(str), but that doesn’t work. The default values are evaluated when the function is deﬁned, not when it is called. When find is deﬁned, str doesn’t exist yet, so you can’t ﬁnd its length.

14.6

The initialization method

The initialization method is a special method that is invoked when an object is created. The name of this method is init (two underscore characters, followed by init, and then two more underscores). An initialization method for the Time class looks like this: class Time: def __init__(self, hours=0, minutes=0, seconds=0): self.hours = hours self.minutes = minutes self.seconds = seconds There is no conﬂict between the attribute self.hours and the parameter hours. Dot notation speciﬁes which variable we are referring to. When we invoke the Time constructor, the arguments we provide are passed along to init: >>> currentTime = Time(9, 14, 30) >>> currentTime.printTime() >>> 9:14:30 Because the parameters are optional, we can omit them: >>> currentTime = Time() >>> currentTime.printTime() >>> 0:0:0 Or provide only the ﬁrst parameter:

When we write a new class, we almost always start by writing init , which makes it easier to instantiate objects, and str , which is almost always useful for debugging.

14.8

Operator overloading

Some languages make it possible to change the deﬁnition of the built-in operators when they are applied to user-deﬁned types. This feature is called operator overloading. It is especially useful when deﬁning new mathematical types. For example, to override the addition operator +, we provide a method named add : class Point: # previously defined methods here... def __add__(self, other): return Point(self.x + other.x, self.y + other.y) As usual, the ﬁrst parameter is the object on which the method is invoked. The second parameter is conveniently named other to distinguish it from self. To add two Points, we create and return a new Point that contains the sum of the x coordinates and the sum of the y coordinates. Now, when we apply the + operator to Point objects, Python invokes >>> p1 = Point(3, 4) >>> p2 = Point(5, 7) >>> p3 = p1 + p2 >>> print p3 (8, 11) The expression p1 + p2 is equivalent to p1. add (p2), but obviously more elegant. As an exercise, add a method sub (self, other) that overloads the subtraction operator, and try it out. There are several ways to override the behavior of the multiplication operator: by deﬁning a method named mul , or rmul , or both. If the left operand of * is a Point, Python invokes mul , which assumes that the other operand is also a Point. It computes the dot product of the two points, deﬁned according to the rules of linear algebra: add :

If the left operand of * is a primitive type and the right operand is a Point, Python invokes rmul , which performs scalar multiplication: def __rmul__(self, other): return Point(other * self.x, other * self.y)

The result is a new Point whose coordinates are a multiple of the original coordinates. If other is a type that cannot be multiplied by a ﬂoating-point number, then rmul will yield an error. This example demonstrates both kinds of multiplication: >>> p1 = Point(3, 4) >>> p2 = Point(5, 7) >>> print p1 * p2 43 >>> print 2 * p2 (10, 14) What happens if we try to evaluate p2 * 2? Since the ﬁrst parameter is a Point, Python invokes mul with 2 as the second argument. Inside mul , the program tries to access the x coordinate of other, which fails because an integer has no attributes: >>> print p2 * 2 AttributeError: ’int’ object has no attribute ’x’ Unfortunately, the error message is a bit opaque. This example demonstrates some of the diﬃculties of object-oriented programming. Sometimes it is hard enough just to ﬁgure out what code is running. For a more complete example of operator overloading, see Appendix B.

14.9

Polymorphism

Most of the methods we have written only work for a speciﬁc type. When you create a new object, you write methods that operate on that type. But there are certain operations that you will want to apply to many types, such as the arithmetic operations in the previous sections. If many types support the same set of operations, you can write functions that work on any of those types.

1) 7 Or with Points: >>> p1 = Point(3. 4] >>> frontAndBack(myList) [1. 3. consider the method frontAndBack. 15) >>> print multadd 44 4) 7) (2. forward and backward: def frontAndBack(front): import copy back = copy. p2) (p1. 2. so the third parameter also has to be a numeric value. Here’s an example that applies frontAndBack to a list: >>> myList = [1. >>> print multadd (11. As another example. That way. the multadd operation (which is common in linear algebra) takes three parameters. it multiplies the ﬁrst two and then adds the third. 3. y. 1)
In the ﬁrst case.copy(front) back. we make a copy of the list before reversing it. p1. the Point is multiplied by a scalar and then added to another Point.154
Classes and methods
For example. this method doesn’t modify the list it gets as a parameter. We can write it in Python like this: def multadd (x. We can invoke it with numeric values: >>> multadd (3. 4][4. In the second case. 2.reverse() print str(front) + str(back) Because the reverse method is a modiﬁer. >>> p2 = Point(5. 2. 3. which prints a list twice. z): return x * y + z This method will work for any values of x and y that can be multiplied and for any value of z that can be added to the product. p2. 1]
. 2. the dot product yields a numeric value. A function like this that can take parameters with diﬀerent types is called polymorphic.

copy works on any object. The operations in the method include copy. 4)(4. override: To replace a default.y = self.14.x Then we can pass Points to frontAndBack: >>> p = Point(3.
. we intended to apply this function to lists. What would be surprising is if we could apply it to a Point. self. method for
14. reverse.10 Glossary
155
Of course. method: A function that is deﬁned inside a class deﬁnition and is invoked on instances of that class. we apply the fundamental rule of polymorphism: If all of the operations inside the function can be applied to the type. self. Examples include replacing a default parameter with a particular argument and replacing a default method by providing a new method with the same name. so it is not surprising that it works. so all we need is a reverse method in the Point class: def reverse(self): self. initialization method: A special method that is invoked automatically when a new object is created and that initializes the object’s attributes. that facilitate object-oriented programming. To determine whether a function can be applied to a new type. such as userdeﬁned classes and inheritance. 4) >>> frontAndBack(p) (3.y.10
Glossary
object-oriented language: A language that provides features. where you discover that a function you have already written can be applied to a type for which you never planned. 3) The best kind of polymorphism is the unintentional kind. and we have already written a str Points. the function can be applied to the type. object-oriented programming: A style of programming in which data and the operations that manipulate it are organized into classes and methods.x . and print.

dot product: An operation deﬁned in linear algebra that multiplies two Points and yields a numeric value. -. *. scalar multiplication: An operation deﬁned in linear algebra that multiplies each of the coordinates of a Point by a numeric value. <.156
Classes and methods
operator overloading: Extending built-in operators (+. etc.) so that they work with user-deﬁned types. If all the operations in a function can be applied to a type. >.
. then the function can be applied to a type. polymorphic: A function that can operate on more than one type.

or else this chapter might not make much sense. Having seen this pattern. you should not be surprised to learn that you can create lists of objects. and so on. Hearts. 9.Chapter 15
Sets of objects
15. 7. There are ﬁfty-two cards in a deck. One of the ﬁrst examples was using a method invocation as part of an expression. 5.1 Composition
By now. within another if statement. you can put an if statement within a while loop. In this chapter and the next. and Clubs (in descending order in bridge). now would be a good time to get a deck. Another example is the nested structure of statements. 10. If we want to deﬁne a new object to represent a playing card. The ranks are Ace. using Card objects as an example.
15. 8. it is obvious what the attributes should be: rank and suit. the rank of Ace may be higher than King or lower than 2. you have seen several examples of composition. Depending on the game that you are playing. we will look at some examples of these combinations. 2. each of which belongs to one of four suits and one of thirteen ranks. and so on. 4. 6. and having learned about lists and objects. It is not as obvious what type
. 3. The suits are Spades. Jack. Queen. and King. Diamonds.2
Card objects
If you are not familiar with common playing cards. You can also create objects that contain lists (as attributes). you can create lists that contain lists. you can create objects that contain objects.

By “encode. An alternative is to use integers to encode the ranks and suits. 0.rank = rank As usual. What a computer scientist means by “encode” is “to deﬁne a mapping between a sequence of numbers and the items I want to represent.suit = suit self. One possibility is to use strings containing words like "Spade" for suits and "Queen" for ranks. suit=0. The class deﬁnition for the Card type looks like this: class Card: def __init__(self. One problem with this implementation is that it would not be easy to compare cards to see which had a higher rank or suit. To create an object that represents the 3 of Clubs. use this command: threeOfClubs = Card(0.” we do not mean what some people think. rank=0): self. which is to encrypt or translate into a secret code. so we can compare suits by comparing integers.
.158
Sets of objects
the attributes should be. we provide an initialization method that takes an optional parameter for each attribute.” For example: Spades Hearts Diamonds Clubs → → → → 3 2 1 0
An obvious feature of this mapping is that the suits map to integers in order. represents the suit Clubs. each of the numerical ranks maps to the corresponding integer. The mapping for ranks is fairly obvious. They are part of the program design. but they never appear explicitly in the code. and for face cards: Jack Queen King → → → 11 12 13
The reason we are using mathematical notation for these mappings is that they are not part of the Python program. 3) The ﬁrst argument.

and select the appropriate string. This wasted item is not entirely necessary. A natural way to do that is with lists of strings.suitList[self.rankList[self. "2". we want to map the integer codes onto words. and so on.suitList[self. we can use suitList and rankList to map the numerical values of suit and rank to strings. "6".rank] + " of " + self. "5". the expression self.3
Class attributes and the
str
method
In order to print Card objects in a way that people can easily read. as usual. which will never be used. With the methods we have so far.3 Class attributes and the
str
method
159
15. "8".suit]) A class attribute is deﬁned outside of any method. 11) >>> print card1 Jack of Diamonds Class attributes like suitList are shared by all Card objects. "Queen".suitList[1] Diamonds
. "Ace". "9". 3) >>> print card2 3 of Diamonds >>> print card2. "3". "4". "Jack".” The reason for the "narf" in the ﬁrst element in rankList is to act as a place keeper for the zero-eth element of the list. we can create and print cards: >>> card1 = Card(1. "Spades"] rankList = ["narf". The advantage of this is that we can use any Card object to access the class attributes: >>> card2 = Card(1.15. and it can be accessed from any of the methods in the class. We assign these lists to class attributes at the top of the class deﬁnition: class Card: suitList = ["Clubs". "King"] #init method omitted def __str__(self): return (self. Inside str . "7". but it is less confusing to encode 2 as 2. "Diamonds".suit] means “use the attribute suit from the object self as an index into the class attribute named suitList. We could have started at 0. For example. "Hearts". "10". 3 as 3. The only valid ranks are 1 to 13.

if we decide that “Jack of Diamonds” should really be called “Jack of Swirly Whales. self and other. which means that sometimes you can compare cards and sometimes not. and the 3 of Diamonds is higher than the 3 of Clubs. it aﬀects every instance of the class.
15. ==.4
Comparing cards
For primitive types. we will say that suit is more important. and returns 1 if the ﬁrst object is greater. For example. followed by all the Diamonds. the integers and the ﬂoatingpoint numbers are completely ordered. -1 if the second object is greater. The set of playing cards is partially ordered. With that decided.suitList[1] = "Swirly Whales" >>> print card1 Jack of Swirly Whales The problem is that all of the Diamonds just became Swirly Whales: >>> print card2 3 of Swirly Whales It is usually not a good idea to modify class attributes. the fruits are unordered. you know that the 3 of Clubs is higher than the 2 of Clubs. Some types are completely ordered. you have to decide which is more important.160
Sets of objects
The disadvantage is that if we modify a class attribute. To be honest. In order to make cards comparable. which means that you can compare any two elements and tell which is bigger. For example. cmp takes two parameters. By convention. and so on. >.) that compare values and determine when one is greater than. For example. the 3 of Clubs or the 2 of Diamonds? One has a higher rank. Some sets are unordered. less than. and 0 if they are equal to each other. because a new deck of cards comes sorted with all the Clubs together. which means that there is no meaningful way to say that one element is bigger than another. For example. we can write cmp :
. which is why you cannot compare apples and oranges. but the other has a higher suit. For user-deﬁned types. etc. the choice is arbitrary. rank or suit. we can override the behavior of the built-in operators by providing a method named cmp . there are conditional operators (<.” we could do this: >>> card1. For the sake of choosing. or equal to another. But which is better.

cards = [] for suit in range(4): for rank in range(1. it’s a tie return 0 In this ordering. of course. check ranks if self. tuples. Of course. the next logical step is to deﬁne a class to represent a Deck. The following is a class deﬁnition for the Deck class. so each Deck object will contain a list of cards as an attribute. The initialization method creates the attribute cards and generates the standard set of ﬁfty-two cards: class Deck: def __init__(self): self..6
Printing the deck
As usual. other): # check the suits if self.suit: return 1 if self. To print a Deck.rank: return -1 # ranks are the same... modify Kings.
15. The inner loop enumerates the ranks from 1 to 13. 14): self.cards.suit < other.5
Decks
Now that we have objects to represent Cards.rank > other. and the inner loop iterates thirteen times. the total number of times the body is executed is ﬁfty-two (thirteen times four). The append method works on lists but not. Aces appear lower than Deuces (2s). As an exercise. a deck is made up of cards. Since the outer loop iterates four times.. we traverse the list and print each Card:
.15. cmp so that Aces are ranked higher than
161
15. and appends that card to the cards list.5 Decks def __cmp__(self.suit > other. The outer loop enumerates the suits from 0 to 3. Each iteration creates a new instance of Card with the current suit and rank.rank < other.append(Card(suit.rank: return 1 if self. when we deﬁne a new type of object we want a method that prints the contents of an object.suit: return -1 # suits are the same. rank)) The easiest way to populate the deck is with a nested loop.

s contains the complete string representation of the Deck. which looks like this:
. Third. and from now on. As an alternative to printDeck. def printDeck(self): for card in self. Finally. To add a bit of pizzazz.) indicates that we have omitted the other methods in the class. When the loop ends. s is the empty string. Passing an object as an argument to str is equivalent to invoking the str method on the object..cards: print card
Sets of objects
Here. def __str__(self): s = "" for i in range(len(self. Here is a version of str that returns a string representation of a Deck. we are using the string multiplication operator to indent each card by one more space than the last. we could write a str method for the Deck class. it arranges the cards in a cascade where each card is indented one space more than the previous card: class Deck: . we are using i as a loop variable and an index into the list of cards... Each time through the loop. instead of traversing self. Initially.. Second.cards)): s = s + " "*i + str(self. a new string is generated and concatenated with the old value of s to get the new value.cards[i]) + "\n" return s This example demonstrates several features. it generates a string representation that other parts of the program can manipulate before printing..162 class Deck: . we are using the variable s as an accumulator. we use the str function. The advantage of str is that it is more ﬂexible. the ellipsis (. The expression " "*i yields a number of spaces equal to the current value of i. First. instead of using the print command to print the cards. or store for later use.cards and assigning each card to a variable. Rather than just printing the contents of the object..

a and b.
15. then any card is equally likely to appear anywhere in the deck. For example. To shuﬄe the deck. but that is ﬁne.7
Shuﬄing the deck
If a deck is perfectly shuﬄed. Even though the result appears on 52 lines.randrange(0. It is possible that the card will be swapped with itself. it is one long string that contains newlines. and we are guaranteed to get a legal index. Since the upper bound is strictly less than b. In fact.cards)) An easy way to shuﬄe the deck is by traversing the cards and swapping each card with a randomly chosen one. With two integer arguments. we can use the length of a list as the second parameter.15. len(self. the order of the cards would be less than entirely random:
. if we precluded that possibility. this expression chooses the index of a random card in a deck: random. we will use the randrange function from the random module. and any location in the deck is equally likely to contain any card.7 Shuﬄing the deck >>> deck = Deck() >>> print deck Ace of Clubs 2 of Clubs 3 of Clubs 4 of Clubs 5 of Clubs 6 of Clubs 7 of Clubs 8 of Clubs 9 of Clubs 10 of Clubs Jack of Clubs Queen of Clubs King of Clubs Ace of Diamonds
163
And so on. randrange chooses a random integer in the range a <= x < b.

the removeCard method checks for deep equality. If the ﬁrst operand is an object. which must be a list or a tuple.cards[j] = self.cards[i].. as in Section 9.. we choose a random card from among the cards that haven’t been shuﬄed yet.cards[j] = self. Since the cmp in the Card class checks for deep equality. def removeCard(self.
15.2: self. self.cards[i].cards[i] As an exercise.164
Sets of objects
class Deck: . To swap the cards we use a tuple assignment.. To deal cards.cards[j]. which takes a card as a parameter.cards[i] Rather than assume that there are ﬁfty-two cards in the deck. self.randrange(i. we want to remove and return the top card. and returns true (1) if the card was in the deck and false (0) otherwise: class Deck: .cards: self. The list method pop provides a convenient way to do that:
.cards) for i in range(nCards): j = random. Then we swap the current card (i) with the selected card (j).8
Removing and dealing cards
Another method that would be useful for the Deck class is removeCard. Python uses the object’s cmp method to determine equality with items in the list. rewrite this line of code without using a sequence assignment. card): if card in self. For each card in the deck. self.remove(card) return 1 else: return 0 The in operator returns true if the ﬁrst operand is in the second. self. nCards) self. removes it.cards.cards[j]. we get the actual length of the list and store it in nCards.. def shuffle(self): import random nCards = len(self.

.cards) == 0)
15. such as by concatenating them onto a string or adding them to a running sum. which returns true if the deck contains no cards: class Deck: . class attribute: A variable that is deﬁned inside a class deﬁnition but outside any method.pop()
165
Actually. def isEmpty(self): return (len(self..15.9 Glossary class Deck: .
.cards. accumulator: A variable used in a loop to accumulate a series of values. def popCard(self): return self.9
Glossary
encode: To represent one set of values using another set of values by constructing a mapping between them.. Class attributes are accessible from any method in the class and are shared by all instances of the class.. pop removes the last card in the list. so we are in eﬀect dealing from the bottom of the deck. One more operation that we are likely to want is the boolean function isEmpty.

166
Sets of objects
.

the inheritance structure reﬂects the natural structure of the problem. One of our goals is to write code that could be reused to implement other card games. many of the things that can be done using inheritance can be done as elegantly (or more so) without it. The relevant code may be scattered among several modules.” Inheritance is a powerful feature. Extending this metaphor.
. When a method is invoked. If the natural structure of the problem does not lend itself to inheritance. it is sometimes not clear where to ﬁnd its deﬁnition. The new class may be called the child class or sometimes “subclass. since you can customize the behavior of parent classes without having to modify them. Also. It is called “inheritance” because the new class inherits all of the methods of the existing class. On the other hand. Some programs that would be complicated without inheritance can be written concisely and simply with it.1 Inheritance
The language feature most often associated with object-oriented programming is inheritance. which makes the program easier to understand. In some cases.Chapter 16
Inheritance
16. In this chapter we will demonstrate the use of inheritance as part of a program that plays the card game Old Maid. Inheritance is the ability to deﬁne a new class that is a modiﬁed version of an existing class. The primary advantage of this feature is that you can add new methods to a class without modifying the existing class. inheritance can facilitate code reuse. this style of programming can do more harm than good. Also. the existing class is sometimes called the parent class. inheritance can make programs diﬃcult to read.

But we have to write addCard: class Hand(Deck): .name = name For just about any card game. probably by the name of the player that holds it.) or compare it with another hand. def addCard(self. The string name identiﬁes this hand. and new methods can be added. Also. ﬂush. it will have all the methods of Deck. in poker we might classify a hand (straight. Removing cards is already taken care of. cards is the list of cards in the hand.card) : self. For example. the ellipsis indicates that we have omitted other methods. Depending on the game being played. etc. it is necessary to add and remove cards from the deck. since Hand inherits removeCard from Deck. we might want to perform some operations on hands that don’t make sense for a deck. of course. The name is an optional parameter with the empty string as a default value. and both require operations like adding and removing cards. we need to represent a hand of cards. In the class deﬁnition. A hand is similar to a deck.cards = [] self. The Hand constructor initializes the attributes for the hand. The list append method adds the new card to the end of the list of cards.. If Hand is a subclass of Deck. Both are made up of a set of cards.2
A hand of cards
For almost any card game.168
Inheritance
16.append(card) Again. name=""): self. In bridge. we might like the ability to shuﬄe both decks and hands.cards. we might want to compute a score for a hand in order to make a bid. A hand is also diﬀerent from a deck. the name of the parent class appears in parentheses: class Hand(Deck): pass This statement indicates that the new Hand class inherits from the existing Deck class.
. initialized to the empty list: class Hand(Deck): def __init__(self. which are name and cards. This situation suggests the use of inheritance..

def deal(self.16. For example:
. The modulus operator (%) allows us to deal cards in a round robin (one card at a time to each hand). a card is removed from the deck using the list method pop.addCard(card) # add the card to the hand The second parameter.isEmpty(): break # break if out of cards card = self.. Each time through the loop. is optional. which removes and returns the last item in the list.
16. When i is equal to the number of hands in the list.3
Dealing cards
Now that we have a Hand class. nCards. hands. we want to deal cards from the Deck into hands. nCards=999): nHands = len(hands) for i in range(nCards): if self. the method deals out all of the cards and stops: class Deck : .popCard() # take the top card hand = hands[i % nHands] # whose turn is next? hand. If there are not enough cards in the deck. deal takes two parameters. The loop variable i goes from 0 to nCards-1. it is more natural to put it in Deck.. It is not immediately obvious whether this method should go in the Hand class or in the Deck class.3 Dealing cards
169
16. a list (or tuple) of hands and the total number of cards to deal.4
Printing a Hand
To print the contents of a hand. since diﬀerent games will have diﬀerent requirements. We may want to deal out the entire deck at once or add one card to each hand. but since it operates on a single deck and (possibly) several hands. the expression i % nHands wraps around to the beginning of the list (index 0). the default is a large number. which eﬀectively means that all of the cards in the deck will get dealt. deal should be fairly general. we can take advantage of the printDeck and str methods inherited from Deck.

so it is legal to send a Hand to a Deck method. the program appends the words is empty and returns the result. In general.170 >>> deck = Deck() >>> deck.name if self. it is always legal to use an instance of a subclass in place of an instance of a parent class. Hand objects can do everything Deck objects can.. there is additional information in a Hand object we might want to include when we print one. s is a string that identiﬁes the hand.isEmpty(): return s + " is empty\n" else: return s + " contains\n" + Deck. we can provide a str method in the Hand class that overrides the one in the Deck class: class Hand(Deck) .shuffle() >>> hand = Hand("frank") >>> deck. 5) >>> print hand Hand frank contains 2 of Spades 3 of Spades 4 of Spades Ace of Hearts 9 of Clubs It’s not a great hand. which refers to the current Hand.deal([hand]. computed by invoking the str method in the Deck class on self. To do that. It may seem odd to send self.
. the program appends the word contains and the string representation of the Deck.__str__(self) Initially. def __str__(self): s = "Hand " + self. If the hand is empty.
Inheritance
Although it is convenient to inherit the existing methods. but it has the makings of a straight ﬂush. until you remember that a Hand is a kind of Deck. Otherwise.. to a Deck method.

5
The CardGame class
The CardGame class takes care of some basic chores common to all games. some nuances of the real game are lost. The computer simply picks a neighbor’s card at random. For example. we’ll write a simulation of Old Maid. the computer plays all hands. The ﬁfty-one remaining cards are dealt to the players in a round robin. To begin the game. Otherwise. As an example. OldMaidHand.16. The Jack of Hearts matches the Jack of Diamonds since both are red.shuffle() This is the ﬁrst case we have seen where the initialization method performs a signiﬁcant computation. or perhaps failing to display it more prominently. by displaying it a little more prominently. If the chosen card matches a card in the player’s hand. In our computer simulation of the game. leaving only the Queen of Spades in the loser’s hand. To implement speciﬁc games. The object of Old Maid is to get rid of cards in your hand. each player picks a card (without looking) from the closest neighbor to the left who still has cards. we can inherit from CardGame and add features for the new game. or even failing to fail to display that card more prominently.5 The CardGame class
171
16. You do this by matching cards by rank and color. play begins. We will deﬁne a new class.deck. the Queen of Clubs is removed from the deck so that the Queen of Spades has no match. Eventually all possible matches are made.
16.6
OldMaidHand class
A hand for playing Old Maid requires some abilities beyond the general abilities of a Hand. such as creating the deck and shuﬄing it: class CardGame: def __init__(self): self. When no more matches can be made. After the deal. the pair is removed. In turn. beyond initializing attributes. Unfortunately.deck = Deck() self. In a real game. that inherits from Hand and provides an additional method called removeMatches:
. the player with the Old Maid goes to some eﬀort to get their neighbor to pick that card. all players match and discard as many cards as possible. the 4 of Clubs matches the 4 of Spades since both suits are black. the card is added to the player’s hand.

deck.card.rank) if match in self. 13) >>> print hand Hand frank contains Ace of Spades 2 of Diamonds 7 of Spades 8 of Clubs 6 of Hearts 8 of Spades 7 of Clubs Queen of Clubs 7 of Diamonds 5 of Clubs Jack of Diamonds 10 of Diamonds 10 of Hearts
. The match card has the same rank and the other suit of the same color.remove(card) self.name.card.cards: self. Since self.cards is modiﬁed in the loop.remove(match) print "Hand %s: %s matches %s" % (self.deal([hand].cards[:] for card in originalCards: match = Card(3 .suit.suit turns a Club (suit 0) into a Spade (suit 3) and a Diamond (suit 1) into a Heart (suit 2). The following example demonstrates how to use removeMatches: >>> game = CardGame() >>> hand = OldMaidHand("frank") >>> game. both cards are removed.cards.card. The expression 3 . we ﬁgure out what the matching card is and go looking for it. Python can get quite confused if it is traversing a list that is changing! For each card in the hand. card.cards.172
Inheritance
class OldMaidHand(Hand): def removeMatches(self): count = 0 originalCards = self. we don’t want to use it to control the traversal. so that we can traverse the copy while removing cards from the original. You should satisfy yourself that the opposite operations also work.match) count = count + 1 return count We start by making a copy of the list of cards. If the match card is also in the hand.

Since init is inherited from CardGame.hands = [] for name in names : self. names): # remove Queen of Clubs self.deck. OldMaidGame is a subclass of CardGame with a new method called play that takes a list of players as a parameter.hands.hands) print "---------. init method for the OldMaidHand class.Cards have been dealt" self.12)) # make a hand for each player self.16.deal(self.append(OldMaidHand(name)) # deal the cards self. We inherit
16.removeMatches() Hand frank: 7 of Spades matches 7 of Clubs Hand frank: 8 of Spades matches 8 of Clubs Hand frank: 10 of Diamonds matches 10 of Hearts >>> print hand Hand frank contains Ace of Spades 2 of Diamonds 6 of Hearts Queen of Clubs 7 of Diamonds 5 of Clubs Jack of Diamonds Notice that there is no it from Hand.7 OldMaidGame class
173
>>> hand.7
OldMaidGame class
Now we can turn our attention to the game itself.printHands()
.removeCard(Card(0.deck. a new OldMaidGame object contains a new shuﬄed deck: class OldMaidGame(CardGame): def play(self.

174 # remove initial matches matches = self.removeMatches() return count As an exercise. which means that only one card is left and the game is over. The method playOneTurn takes a parameter that indicates whose turn it is. The variable turn keeps track of which player’s turn it is.hands) while matches < 25: matches = matches + self..hands and prints each hand. write printHands which traverses self.printHands() # play until all 50 cards are matched turn = 0 numHands = len(self. When the total number of matches reaches twenty-ﬁve.Game is Over" self.playOneTurn(turn) turn = (turn + 1) % numHands print "---------. count is an accumulator that adds up the number of matches in each hand and returns the total. play begins" self.printHands()
Inheritance
Some of the steps of the game have been separated into methods. The return value is the number of matches made during this turn:
. when it reaches numHands. the modulus operator wraps it back around to 0.. ﬁfty cards have been removed from the hands.removeAllMatches() print "---------.hands: count = count + hand. It starts at 0 and increases by one each time. def removeAllMatches(self): count = 0 for hand in self. removeAllMatches traverses the list of hands and invokes removeMatches on each: class OldMaidGame(CardGame): .Matches discarded.

OldMaidGame() >>> game.name.16. the cards in the hand are shuﬄed so that the next player’s choice is random."Jeff". a turn consists of ﬁnding the ﬁrst player on the left that has cards.hands[neighbor]. i): numHands = len(self...removeMatches() self.numHands): neighbor = (i + next) % numHands if not self. You can write that one yourself. We have omitted the printHands method. def playOneTurn(self.hands) for next in range(1. pickedCard count = self. we can prove that that will never happen (as long as the end of the game is detected correctly).popCard() self. i): if self. >>> import cards >>> game = cards. it would return None and cause an error elsewhere in the program. "picked".hands[i]. Otherwise.addCard(pickedCard) print "Hand". Before returning.shuffle() return count
175
If a player’s hand is empty..hands[i].hands[i].hands[i].findNeighbor(i) pickedCard = self. Fortunately.7 OldMaidGame class class OldMaidGame(CardGame): .isEmpty(): return neighbor If findNeighbor ever went all the way around the circle without ﬁnding cards. and checking for matches.hands[neighbor]. def findNeighbor(self.. so he or she does nothing and returns 0. taking one card from the neighbor. The following output is from a truncated form of the game where only the top ﬁfteen cards (tens and higher) were dealt to three players."Chris"])
.isEmpty(): return 0 neighbor = self.play(["Allen". self. that player is out of the game. The method findNeighbor starts with the player to the immediate left and continues around the circle until it ﬁnds a player that still has cards: class OldMaidGame(CardGame): . With this small deck.hands[i]. play stops after seven matches instead of twenty-ﬁve.

176 ---------.Cards have been dealt Hand Allen contains King of Hearts Jack of Clubs Queen of Spades King of Spades 10 of Diamonds Hand Jeff contains Queen of Hearts Jack of Spades Jack of Hearts King of Diamonds Queen of Diamonds Hand Chris contains Jack of Diamonds King of Clubs 10 of Spades 10 of Hearts 10 of Clubs Hand Jeff: Queen of Hearts matches Queen of Diamonds Hand Chris: 10 of Spades matches 10 of Clubs ---------. play begins Hand Allen contains King of Hearts Jack of Clubs Queen of Spades King of Spades 10 of Diamonds Hand Jeff contains Jack of Spades Jack of Hearts King of Diamonds Hand Chris contains Jack of Diamonds King of Clubs 10 of Hearts
Inheritance
.Matches discarded.

parent class: The class from which a child class inherits.16.8 Glossary Hand Allen picked King of Diamonds Hand Allen: King of Hearts matches King of Diamonds Hand Jeff picked 10 of Hearts Hand Chris picked Jack of Clubs Hand Allen picked Jack of Hearts Hand Jeff picked Jack of Diamonds Hand Chris picked Queen of Spades Hand Allen picked Jack of Diamonds Hand Allen: Jack of Hearts matches Jack of Diamonds Hand Jeff picked King of Clubs Hand Chris picked King of Spades Hand Allen picked 10 of Hearts Hand Allen: 10 of Diamonds matches 10 of Hearts Hand Jeff picked Queen of Spades Hand Chris picked Jack of Spades Hand Chris: Jack of Clubs matches Jack of Spades Hand Jeff picked King of Spades Hand Jeff: King of Clubs matches King of Spades ---------.Game is Over Hand Allen is empty Hand Jeff contains Queen of Spades Hand Chris is empty So Jeﬀ loses.”
. also called a “subclass.
177
16.8
Glossary
inheritance: The ability to deﬁne a new class that is a modiﬁed version of a previously deﬁned class. child class: A new class created by inheriting from an existing class.

178
Inheritance
.

In addition. A linked list is considered a recursive data structure because it has a recursive deﬁnition. which we called embedded references (see Section 12. each node contains a unit of data called the cargo.1 Embedded references
We have seen examples of attributes that refer to other objects. where each node contains a reference to the next node in the list. we’ll start with the initialization and str methods so that we can test the basic mechanism of creating and displaying the new type:
.
17. A common data structure. takes advantage of this feature.2
The Node class
As usual when writing a new class.Chapter 17
Linked lists
17. Recursive data structures lend themselves to recursive methods. the linked list. A linked list is either: • the empty list. or • a node that contains a cargo object and a reference to a linked list. Linked lists are made up of nodes.8). represented by None.

cargo)
Linked lists
As usual. To test the implementation so far. we have to make the ﬁrst node refer to the second and the second node refer to the third: >>> node1. the parameters for the initialization method are optional. By default.cargo = cargo self. Since any value can be passed to the str function. cargo=None. The state diagram looks like this:
node1 node2 node3
cargo next
1 None
cargo next
2 None
cargo next
3 None
To link the nodes. but we don’t have a list yet because the nodes are not linked. next. we need a list with more than one node: >>> node1 = Node(1) >>> node2 = Node(2) >>> node3 = Node(3) This code creates three nodes. we can store any value in a list. are set to None.180 class Node: def __init__(self. we can create a Node and print it: >>> node = Node("test") >>> print node test To make it interesting.next = next def __str__(self): return str(self. The string representation of a node is just the string representation of the cargo.next = node2 >>> node2.next = node3 The reference of the third node is None. which indicates that it is the end of the list. Now the state diagram looks like this:
. both the cargo and the link. next=None): self.

What might be less clear at this point is why. To pass the list as a parameter. but there is no variable that refers to the other nodes.3 Lists as collections
node1 node2 node3
181
cargo next
1
cargo next
2
cargo next
3 None
Now you know how to create nodes and link them into lists. it is common to use a loop variable like node to refer to each of the nodes in succession. In the example. For example. the ﬁrst node of the list serves as a reference to the entire list. we pass a reference to the ﬁrst node: >>> printList(node1) 1 2 3 Inside printList we have a reference to the ﬁrst node of the list. This diagram shows the value of list and the values that node takes on:
. To traverse a linked list. the function printList takes a single node as an argument. Starting with the head of the list.3
Lists as collections
Lists are useful because they provide a way to assemble multiple objects into a single entity.next print To invoke this method. node = node. we only have to pass a reference to the ﬁrst node. We have to use the next value from each node to get to the next node. it prints each node until it gets to the end: def printList(node): while node: print node.17. sometimes called a collection.
17.

3. The ﬁrst line handles the base case by doing nothing. a natural base case is the empty list. lists are often printed in brackets with commas between the elements. the following is a recursive algorithm for printing a list backwards: 1. As an exercise.182
node1 node2 node3
Linked lists
cargo y
1
cargo y
2
cargo y
3 None
node
By convention. the recursive call. represented by None: def printBackward(list): if list == None: return head = list tail = list. Given the recursive deﬁnition of a list. Separate the list into two pieces: the ﬁrst node (called the head). as in [1. The last two lines print the list. 3]. Of course. 2.4
Lists and recursion
It is natural to express many list operations using recursive methods. Print the tail backward. assumes that we have a way of printing a list backward. But if we assume that the recursive call works—the leap of faith—then we can convince ourselves that this algorithm works. 2. and the rest (called the tail). Print the head. For example.
17. we will eventually get to the base case. Step 2. The next two lines split the list into head and tail. The comma at the end of the last line keeps Python from printing a newline after each node. modify printList so that it generates output in this format.next printBackward(tail) print head. All we need are a base case and a way of proving that for any list.
.

You will see more examples soon. it will loop forever. For example. Regardless. it is problematic that we cannot prove that printList and printBackward terminate. will it always reach the base case? In fact. one of which refers to itself:
list
cargo next
1
cargo next
2
If we invoke printList on this list. it will recurse inﬁnitely. This sort of behavior makes inﬁnite lists diﬃcult to work with. Can we prove that printBackward will always terminate? In other words. including itself. the answer is no. this ﬁgure shows a list with two nodes. The reason is that we want to use None to represent the empty list and it is not legal to invoke a method on None.” This sort of claim is called a precondition. “If the list contains no loops.
. Nevertheless.5 Inﬁnite lists We invoke this method as we invoked printList: >>> printBackward(node1) 3 2 1 The result is a backward list. If we invoke printBackward. Some lists will make this method crash. For example. they are occasionally useful. The best we can do is the hypothetical statement. we might represent a number as a list of digits and use an inﬁnite list to represent a repeating fraction.
183
You might wonder why printList and printBackward are functions and not methods in the Node class. This limitation makes it awkward to write list-manipulating code in a clean object-oriented style.5
Inﬁnite lists
There is nothing to prevent a node from referring back to an earlier node in the list. then these methods will terminate. It imposes a constraint on one of the parameters and describes the behavior of the method if the constraint is satisﬁed.17.
17.

This ambiguity can be useful. We could have written printBackward without head and tail.184
Linked lists
17. we can change the cargo of one of the nodes.
17. they are in the mind of the programmer.7
Modifying lists
There are two ways to modify a linked list. but it can also make programs diﬃcult to read. These “roles” are not part of the program.next) print list. let’s write a method that removes the second node in the list and returns a reference to the removed node:
. head and list have the same type and the same value. We often use variable names like node and list to document how we intend to use a variable and sometimes create additional variables to disambiguate. but the more interesting operations are the ones that add. and we think of list as a reference to the ﬁrst node of a list. which makes it more concise but possibly less clear: def printBackward(list) : if list == None : return printBackward(list. As an example.next After the ﬁrst assignment. Obviously. remove.6
The fundamental ambiguity theorem
One part of printBackward might have raised an eyebrow: head = list tail = list. The fundamental ambiguity theorem describes the ambiguity that is inherent in a reference to a node: A variable that refers to a node might treat the node as a single object or as the ﬁrst in a list of nodes. we have to remember that printBackward treats its argument as a collection and print treats its argument as a single object. Looking at the two function calls. In general we can’t tell by looking at a program what role a variable plays. So why did we create a new variable? The reason is that the two variables play diﬀerent roles. or reorder the nodes. We think of head as a reference to a single node.

Here is how to use this method: >>> 1 2 >>> >>> 2 >>> 1 3 printList(node1) 3 removed = removeSecond(node1) printList(removed) printList(node1)
This state diagram shows the eﬀect of the operation:
first second
cargo next
1
cargo next
2
cargo next
3 None
What happens if you invoke this method and pass a list with only one element (a singleton)? What happens if you pass the empty list as an argument? Is there a precondition for this method? If so. but we need a separate method to print the brackets and the ﬁrst node.next = None return second
185
Again.
17.17. 2.8 Wrappers and helpers def removeSecond(list): if list == None: return first = list second = list.8
Wrappers and helpers
It is often useful to divide a list operation into two methods. For example. we are using temporary variables to make the code more readable. ﬁx the method to handle a violation of the precondition in a reasonable way. Let’s call it printBackwardNicely:
. 2.next # separate the second node from the rest of the list second.next = second.next # make the first node refer to the third first. 1] we can use the printBackward method to print 3. to print a list backward in the conventional list format [3.

186 def printBackwardNicely(list) : print "[".head = None One nice thing about the LinkedList class is that it provides a natural place to put wrapper functions like printBackwardNicely.next printBackward(tail) print head. if self. if list != None : head = list tail = list. First.
Linked lists
Again.. When we use this method elsewhere in the program.9
The LinkedList class
There are some subtle problems with the way we have been implementing lists. we’ll propose an alternative implementation ﬁrst and then explain what problems it solves. print "]". and it invokes printBackward on our behalf. LinkedList objects serve as handles for manipulating lists of Node objects: class LinkedList : def __init__(self) : self. Its attributes are an integer that contains the length of the list and a reference to the ﬁrst node. we’ll create a new class called LinkedList. which we can make a method of the LinkedList class: class LinkedList: . In that sense. In a reversal of cause and eﬀect. it is a good idea to check methods like this to see if they work with special cases like an empty list or a singleton. we invoke printBackwardNicely directly.. def printBackward(self): print "[".printBackward() print "]". printBackwardNicely acts as a wrapper.head.length = 0 self.head != None: self.
17.
. and it uses printBackward as a helper.

17.head = node self. For example.next != None: tail = self. Specifying invariants for objects is a useful programming practice because it makes it easier to prove the correctness of code. Now there are two methods named printBackward: one in the Node class (the helper).
187
Just to make things confusing.length + 1 As usual.printBackward() print self.10
Invariants
Some lists are “well formed”. When the wrapper invokes self. check the integrity of data structures.10 Invariants class Node: . For example. if a list contains a loop. it is invoking the helper.head self. they should be true of every object all the time.. so we might want to require that lists contain no loops.head.length = self. others are not. def addFirst(self.next tail. addFirst is a method for LinkedLists. it takes an item of cargo as an argument and puts it at the beginning of the list: class LinkedList: .. what happens if the list is initially empty?
17.. it will cause many of our methods to crash. you should check code like this to see if it handles the special cases. One thing that is sometimes confusing about invariants is that there are times when they are violated. and one in the LinkedList class (the wrapper). cargo): node = Node(cargo) node. Another requirement is that the length value in the LinkedList object should be equal to the actual number of nodes in the list. Another beneﬁt of the LinkedList class is that it makes it easier to add or remove the ﬁrst element of a list. we renamed printBackwardNicely. in the middle of addFirst. ideally. because self.head is a Node object. after we
.. For example.next = self. def printBackward(self): if self. and detect errors.cargo.printBackward. Requirements like these are called invariants because. For example.

11
Glossary
embedded reference: A reference stored in an attribute of an object. in fact. we require that every method that violates an invariant must restore the invariant. fundamental ambiguity theorem: A reference to a list node can be treated as a single object or as the ﬁrst in a list of nodes. the invariant is violated. This kind of violation is acceptable. precondition: An assertion that must be true in order for a method to work correctly. node: An element of a list. linked list: A data structure that implements a collection using a sequence of linked nodes. wrapper: A method that acts as a middleman between a caller and a helper method. link: An embedded reference used to link one object to another. helper: A method that is not invoked directly by a caller but is used by another method to perform part of an operation. invariant: An assertion that should be true of an object at all times (except perhaps while the object is being modiﬁed).
17. If there is any signiﬁcant stretch of code in which the invariant is violated. usually implemented as an object that contains a reference to another object of the same type.188
Linked lists
have added the node but before we have incremented length. it is often impossible to modify an object without violating an invariant for at least a little while. Normally. singleton: A linked list with a single node. cargo: An item of data contained in a node. it is important for the comments to make that clear. so that no operations are performed that depend on the invariant. often making the method easier or less error-prone to invoke.
.

An abstract data type.Chapter 18
Stacks
18.
. but it does not specify the implementation of the operations. For example. As we discussed at the time. the Card class represents a card using two integers. • Since there are usually many ways to implement an ADT. or ADT. it might be useful to write an algorithm that can be used with any of the possible implementations. in the sense that we have completely speciﬁed how they are implemented. • Well-known ADTs. • The operations on ADTs provide a common high-level language for specifying and talking about algorithms. there are many alternative implementations. that is not the only way to represent a card. such as the Stack ADT in this chapter. Why is that useful? • It simpliﬁes the task of specifying an algorithm if you can denote the operations you need without having to think at the same time about how the operations are performed. speciﬁes a set of operations (or methods) and the semantics of the operations (what they do). are often implemented in standard libraries so they can be written once and used by many programmers. That’s what makes it abstract.1 Abstract data types
The data types you have seen so far are all concrete.

The interface isn’t exactly what it is supposed to be. The item that is returned is always the last one that was added. A stack is sometimes called a “last in.
18.
18. Here is an implementation of the Stack ADT that uses a Python list: class Stack : def __init__(self) : self. meaning that it is a data structure that contains multiple elements.items = [] def push(self. push: Add a new item to the stack. an implementation is a set of methods that satisfy the syntactic and semantic requirements of an interface. A stack is a collection. ﬁrst out” or LIFO data structure. called the provider code. This code is called an implementation of the Stack ADT. called the client code. In general. the stack. we will look at one common ADT. but we can write code to translate from the Stack ADT to the built-in operations. Other collections we have seen include dictionaries and lists. because the last item added is the ﬁrst to be removed. pop: Remove and return an item from the stack. An ADT is deﬁned by the operations that can be performed on it.2
The Stack ADT
In this chapter. we often distinguish the code that uses the ADT.190
Stacks
When we talk about ADTs.items. from the code that implements the ADT. item) : self. which is called an interface. isEmpty: Check whether the stack is empty. The interface for a stack consists of these operations: init : Initialize a new empty stack.3
Implementing stacks with Python lists
The list operations that Python provides are similar to the operations that deﬁne a stack.append(item)
.

in which the methods consist of simple invocations of existing methods.items. The following example pushes two integers and a string onto the stack: >>> >>> >>> >>> s = Stack() s.18.push("+")
We can use isEmpty and pop to remove and print all of the items on the stack: while not s.pop() def isEmpty(self) : return (self.pop(). In real life. isEmpty compares items to the empty list. veneer is a thin coating of good quality wood used in furniture-making to hide lower quality wood underneath. The initialization method sets items to the empty list. To push a new item onto the stack.push(54) s.
18.4 Pushing and popping
191
def pop(self) : return self. push appends it onto items. which means that we can add any type of item to it. The output is + 45 54. Computer scientists use this metaphor to describe a small piece of code that hides the details of an implementation and provides a simpler. we just used a stack to print the items backward! Granted. it was remarkably easy to do. to check if the stack is empty. An implementation like this.items == []) A Stack object contains an attribute named items that is a list of items in the stack. it’s not the standard format for printing a list. In other words. pop uses the homonymous1 list method to remove and return the last item on the list. is called a veneer. Finally. or more standard.isEmpty() : print s.
1 same-named
. To pop an item oﬀ the stack.push(45) s. but by using a stack.4
Pushing and popping
A stack is a generic data structure. interface.

In postﬁx. except that it uses a Stack object instead of the runtime stack. mathematical expressions are written with the operator between the two operands. and push the result back on the stack. The stack algorithm does the same thing. pop two operands oﬀ the stack.
18. write a postﬁx expression that is equivalent to 1 + 2 * 3. As an exercise.4. This example demonstrates one of the advantages of postﬁx—there is no need to use parentheses to control the order of operations. As an exercise. This format is called inﬁx. there should be exactly one operand left on the stack.5
Using a stack to evaluate postﬁx
In most programming languages. – If the term is an operand. apply this algorithm to the expression 1 2 + 3 *. perform the operation on them. we need to be able to traverse a string and break it into operands and operators. There is a natural parallel between the recursive version of printBackward and the stack algorithm here. – If the term is an operator. get one term (operator or operand) at a time.6
Parsing
To implement the previous algorithm. as in 1+2. • When you get to the end of the expression. as in 1 2 +. we would have to write (1 + 2) * 3. This process is an example of parsing. push it on the stack. That operand is the result. An alternative used by some calculators is called postﬁx.
18.
.192
Stacks
You should compare this bit of code to the implementation of printBackward in Section 17. The reason postﬁx is sometimes useful is that there is a natural way to evaluate a postﬁx expression using a stack: • Starting at the beginning of the expression. and then prints them on the way back from the recursion. The diﬀerence is that printBackward uses the runtime stack to keep track of the nodes while it traverses the list. the operator follows the operands. To get the same result in inﬁx.

18. ’time’] In this case. ’/’. For example: >>> import string >>> string. ’’] Notice that the order of the arguments is diﬀerent from string. allowing us to provide a regular expression instead of a delimiter. the delimiter comes before the string.split is more powerful.split("([^0-9])". ’the’. A regular expression is a way of specifying a set of strings.7 Evaluating postﬁx
193
and the results—the individual chunks of the string—are called tokens. ’+’. Python provides a split method in both the string and re (regular expression) modules. we’ll start with an evaluator that only implements the operators + and *:
. The function string. the delimiter is the space character. so [^0-9] is the set of everything that is not a number.
18. "123+456*/") [’123’. For example. You might remember these words from Chapter 1.split("Now is the time". To keep things simple. ’is’. The resulting list includes the operands 123 and 456 and the operators * and /." ") [’Now’. we will use the parser from the previous section and the algorithm from the section before that.7
Evaluating postﬁx
To evaluate a postﬁx expression.split splits a string into a list using a single character as a delimiter. [A-z] is the set of all letters and [0-9] is the set of all numbers. ’456’. which is exactly the set we want to use to split up postﬁx expressions: >>> import re >>> re. ’*’.split. It also includes two empty strings that are inserted after the operands. The ^ operator negates a set. ’’. so the string is split at each space. The function re.

pop()
Stacks
The ﬁrst condition takes care of spaces and empty strings.
18. when you implement an ADT.pop() stack.pop() stack.pop() + stack.push(int(token)) return stack.194 def evalPostfix(expr): import re tokenList = re.pop() * stack.8
Clients and providers
One of the fundamental goals of an ADT is to separate the interests of the provider. you have the luxury of thinking exclusively as a client. the client assumes that the implementation of the ADT is correct and doesn’t worry about the details. Of course. We assume. and the client. In that case. The next two conditions handle operators. Let’s test it by evaluating the postﬁx form of (56+47)*2: >>> print evalPostfix ("56 47 + 2 *") 206 That’s close enough. who uses the ADT.split("([^0-9])". you also have to write client code to test it. You should make some eﬀort to keep track of which role you are playing at any moment.
. who writes the code that implements the ADT. which can be confusing. you play both roles.push(sum) elif token == ’*’: product = stack.push(product) else: stack. When you are using one of Python’s built-in types. for now. it would be better to check for erroneous input and report an error message. expr) stack = Stack() for token in tokenList: if token == ’’ or token == ’ ’: continue if token == ’+’: sum = stack. that anything else must be an operand. but we’ll get to that later. The provider only has to worry about whether the implementation is correct—in accord with the speciﬁcation of the ADT—and not how it will be used. Of course. Conversely.

client: A program (or the person who wrote it) that uses an ADT. such as the words in a natural language.9 Glossary
195
18. provider: The code (or the person who wrote it) that implements an ADT. veneer: A class deﬁnition that implements an ADT with method deﬁnitions that are invocations of other methods.9
Glossary
abstract data type (ADT): A data type (usually a collection of objects) that is deﬁned by a set of operations but that can be implemented in a variety of ways. implementation: Code that satisﬁes the syntactic and semantic requirements of an interface. parse: To read a string of characters or tokens and analyze its grammatical structure. generic data structure: A kind of data structure that can contain data of any type. but it improves or standardizes the interface seen by the client.18. sometimes with simple transformations. delimiter: A character that is used to separate tokens. The veneer does no signiﬁcant work. inﬁx: A way of writing mathematical expressions with the operators between the operands. token: A set of characters that are treated as a unit for purposes of parsing. postﬁx: A way of writing mathematical expressions with the operators after the operands.
. interface: The set of operations that deﬁne an ADT. such as punctuation in a natural language.

196
Stacks
.

how many groceries the customer has. a polite customer might let someone with only a few items go ﬁrst.1
The Queue ADT
The Queue ADT is deﬁned by the following operations: init : Initialize a new empty queue.” but fairness is in the eye of the beholder. At supermarkets. The diﬀerence is in the semantics of the operations: a queue uses the FIFO policy. In real life.
.
19. the ﬁrst customer in line is the next customer to be served.” The most general queueing policy is priority queueing. We say this is the most general policy because the priority can be based on anything: what time a ﬂight leaves. The rule that determines who goes next is called the queueing policy. for “ﬁrst-in-ﬁrst-out. customers whose ﬂights are leaving soon are sometimes taken from the middle of the queue. At airports. insert: Add a new item to the queue. and a priority queue (as the name suggests) uses the priority queueing policy. There are exceptions. though.Chapter 19
Queues
This chapter presents two ADTs: the Queue and the Priority Queue. The Queue ADT and the Priority Queue ADT have the same set of operations. a queue is a line of customers waiting for service of some kind. The simplest queueing policy is called FIFO. regardless of the order of arrival. or how important the customer is. In most cases. not all queueing policies are “fair. Of course. in which each customer is assigned a priority and the customer with the highest priority goes ﬁrst.

We want to insert new items at the end of the list.length == 0) def insert(self.2
Linked Queue
The ﬁrst implementation of the Queue ADT we will look at is called a linked queue because it is made up of linked Node objects.1 return cargo The methods isEmpty and remove are identical to the LinkedList methods isEmpty and removeFirst. isEmpty: Check whether the queue is empty.length = self.cargo self.head = node else: # find the last node in the list last = self.
.next self.198
Queues
remove: Remove and return an item from the queue. The insert method is new and a bit more complicated.
19. If the queue is empty.head = None def isEmpty(self): return (self.head while last.next: last = last. Here is the class deﬁnition: class Queue: def __init__(self): self. cargo): node = Node(cargo) node.next = node self.length + 1 def remove(self): cargo = self.head. The item that is returned is the ﬁrst one that was added. we just set head to refer to the new node.length = self.length .head == None: # if list is empty the new node goes first self.length = 0 self.head = self.head.next = None if self.next # append the new node last.

that’s very bad. we traverse the list to the last node and tack the new node on the end. the method might be slightly faster when the list is empty since it skips the body of the conditional.4
Improved Linked Queue
We would like an implementation of the Queue ADT that can perform all operations in constant time. In the general case. How long does it take. In reality. Convince yourself that this method preserves both invariants. The value of length should be the number of nodes in the queue. There are two invariants for a properly formed Queue object.
19. we have to traverse the list to ﬁnd the last element. Compared to constant time. we are not concerned with the details of its implementation. But there is one “detail” we might want to know—the performance characteristics of the method. There are no loops or function calls here. and the last node should have next equal to None. Since the runtime is a linear function of the length. The performance of insert is very diﬀerent.19.3
Performance characteristics
Normally when we invoke a method. One way to do that is to modify the Queue class so that it maintains a reference to both the ﬁrst and the last node. This traversal takes time proportional to the length of the list. Such a method is called a constant-time operation. this method is called linear time. We can identify the last node because its next attribute is None. and how does the run time change as the number of items in the collection increases? First look at remove.
19.3 Performance characteristics
199
Otherwise. as shown in the ﬁgure:
head length 3 last
cargo next
1
cargo next
2
cargo next
3
. but that diﬀerence is not signiﬁcant. suggesting that the runtime of this method is the same every time.

There is a price to pay for that speed.. def remove(self): cargo = self.last = None return cargo
. We have to add a special case to remove to set last to None when the last node is removed: class ImprovedQueue: .1 if self.length = 0 self.next = None if self.length = self.head. def insert(self. It is used in insert and remove methods: class ImprovedQueue: .200 The ImprovedQueue implementation looks like this: class ImprovedQueue: def __init__(self): self.length == 0: self.. As a result.head.next self. the only change is the attribute last.next = node self.length = self. the new node is head and last self.head = None self.head = self.last # append the new node last.last = None def isEmpty(self): return (self. we don’t have to search for it.length .length + 1 Since last keeps track of the last node. cargo): node = Node(cargo) node..last = node self.cargo self. this method is constant time.head = self.length == 0)
Queues
So far.last = node else: # find the last node last = self..length == 0: # if list is empty.

if the items in the queue have names. As long as we can compare the items in the queue.5 Priority queue
201
This implementation is more complicated than the Linked Queue implementation. we might choose them in alphabetical order.5
Priority queue
The Priority Queue ADT has the same interface as the Queue ADT. but if they are golf scores. Again. and it is more diﬃcult to demonstrate that it is correct. For example.items = [] def isEmpty(self): return self. but diﬀerent semantics. Rather. remove: Remove and return an item from the queue. insert: Add a new item to the queue. write an implementation of the Queue ADT using a Python list.19. It depends on which items are in the queue. Compare the performance of this implementation to the ImprovedQueue for a range of queue lengths.
19. If they are bowling scores. The semantic diﬀerence is that the item that is removed from the queue is not necessarily the ﬁrst one that was added. we might go from highest to lowest. This implementation of Priority Queue has as an attribute a Python list that contains the items in the queue. As an exercise. we can ﬁnd and remove the one with the highest priority. it is the item in the queue that has the highest priority. we would go from lowest to highest. class PriorityQueue: def __init__(self): self. The item that is returned is the one with the highest priority. What the priorities are and how they compare to each other are not speciﬁed by the Priority Queue implementation. The advantage is that we have achieved the goal—both insert and remove are constant-time operations.items == []
. the interface is: init : Initialize a new empty queue. isEmpty: Check whether the queue is empty.

.. Each time through the loop.remove()
If the queue contains simple numbers or strings. from highest to lowest. maxi holds the index of the biggest item (highest priority) we have seen so far.isEmpty(): print q. the value of maxi if set to i. If the queue contains an object type. If the new item is bigger. maxi is the index of the biggest item.items[maxi:maxi+1] = [] return item At the beginning of each iteration.insert(12) q. This item is removed from the list and returned. Python can ﬁnd the biggest integer or string because it can compare them using the built-in comparison operators.insert(13) while not q. they are removed in numerical or alphabetical order. When the for statement completes. As long as the cmp method works correctly. and insert are all veneers on list operations. When remove uses the > operator to compare items.items. The only interesting method is remove: class PriorityQueue: .insert(11) q.append(item) The initialization method.items[maxi]: maxi = i item = self. it invokes the cmp for one of the items and passes the other as a parameter.items[maxi] self.202
Queues
def insert(self. it has to provide a cmp method. Let’s test the implementation: >>> >>> >>> >>> >>> >>> 14 13 12 11 q = PriorityQueue() q.insert(14) q.items[i] > self. the program compares the i-eth item to the champion.len(self. item): self.items)): if self. isEmpty. def remove(self): maxi = 0 for i in range(1.
. the Priority Queue will work.

score: return -1 return 0
# less is more
Now we are ready to test the priority queue with the Golfer class: >>> tiger = Golfer("Tiger Woods". As always.. and 0 if they are equal. You should keep the list sorted so that removal is a constant time operation.isEmpty(): print pq.name = name self.6 The Golfer class
203
19..score= score def __str__(self): return "%-16s: %d" % (self.score) str uses the format operator to put the names and scores in neat columns.insert(phil) >>> pq. 69) >>> >>> pq = PriorityQueue() >>> pq.
.6
The Golfer class
As an example of an object with an unusual deﬁnition of priority. self. cmp returns 1 if self is “greater than” other.insert(tiger) >>> pq. other): if self. score): self. def __cmp__(self. let’s implement a class called Golfer that keeps track of the names and scores of golfers.
Next we deﬁne a version of cmp where the lowest score gets highest priority. -1 if self is “less than” other. class Golfer: .score < other.insert(hal) >>> while not pq.name. As usual.score: return 1 if self. Compare the performance of this implementation with the Python list implementation.19.score > other. 61) >>> phil = Golfer("Phil Mickelson". name. write an implementation of the Priority Queue ADT using a linked list. we start by deﬁning init and str : class Golfer: def __init__(self.remove() Tiger Woods : 61 Hal Sutton : 69 Phil Mickelson : 72 As an exercise. 72) >>> hal = Golfer("Hal Sutton".

Priority Queue: An ADT that deﬁnes the operations one might perform on a priority queue. Queue: An ADT that performs the operations one might perform on a queue. The member with the highest priority is the ﬁrst to be removed. priority queue: A queueing policy in which each member has a priority determined by external factors. linked queue: An implementation of a queue using a linked list.
.” a queueing policy in which the ﬁrst member to arrive is the ﬁrst to be removed. linear time: An operation whose runtime is a linear function of the size of the data structure.7
Glossary
queue: An ordered set of objects waiting for a service of some kind. First Out. constant time: An operation whose runtime does not depend on the size of the data structure. queueing policy: The rules that determine which member of a queue is removed next.204
Queues
19. FIFO: “First In.

trees are made up of nodes. but that is not the strangest thing. A state diagram for a tree looks like this:
tree
cargo left
1 right
cargo left
2 right
cargo left
3 right
None
None
None
None
To avoid cluttering up the picture.
. computer scientists mix in another metaphor—the family tree. Nodes with the same parent are called siblings. in which each node contains a reference to two other nodes (possibly null). tree nodes also contain cargo. we often omit the Nones. It may seem odd that we draw the picture with the root at the top and the leaves at the bottom. In keeping with the tree metaphor. The top node is sometimes called a parent and the nodes it refers to are its children. the other nodes are called branches and the nodes at the tips with null references are called leaves.Chapter 20
Trees
Like linked lists. These references are referred to as the left and right subtrees. A common kind of tree is a binary tree. Like list nodes. The top of the tree (the node tree refers to) is called the root. To make things worse.

but the left and right parameters should be tree nodes. the result is the tree at the beginning of the chapter.right = right def __str__(self): return str(self. right). class Tree: def __init__(self. We probably don’t need three metaphors for talking about trees. Allocate the child nodes ﬁrst: left = Tree(2) right = Tree(3) Then create the parent node and link it to the children: tree = Tree(1. To print a node. left.206
Trees
Finally.cargo) The cargo can be any type. all of the nodes that are the same distance from the root comprise a level of the tree. left=None. We already mentioned left and right. Tree(2). trees are recursive data structures because they are deﬁned recursively. but there is also “up” (toward the parent/root) and “down” (toward the children/leaves).
. represented by None.cargo = cargo self.1
Building trees
The process of assembling a tree is similar to the process of assembling a linked list. or • a node that contains an object reference and two tree references. cargo.left = left self.
20. We can write this code more concisely by nesting constructor invocations: >>> tree = Tree(1. Tree(3)) Either way. Also. Each constructor invocation builds a single node. the default value is None. we just print the cargo. there is a geometric vocabulary for talking about trees. Like linked lists. left and right are optional. One way to build a tree is from the bottom up. right=None): self. but there they are. A tree is either: • the empty tree.

left) + total(tree. For example. Tree(1). The recursive step makes two recursive calls to ﬁnd the sum of the child trees. This expression tree represents the same computation:
tree
cargo left
+
right
cargo left
1 right
cargo left
right
*
cargo left 3 right
cargo left
2 right
The nodes of an expression tree can be operands like 1 and 2 or operators like + and *. “How do I traverse it?” The most natural way to traverse a tree is recursively. if the tree contains integers as cargo. For example.right) + tree.
20. Unlike other notations. operator nodes contain references to their operands.2
Traversing trees
Any time you see a new data structure.3
Expression trees
A tree is a natural way to represent the structure of an expression. When the recursive calls complete. it can represent the computation unambiguously. we add the cargo of the parent and return the total.) We can build this tree like this: >>> tree = Tree(’+’. so the sum is 0. which contains no cargo.20. your ﬁrst question should be. meaning they have exactly two operands. Tree(’*’. Tree(2). the inﬁx expression 1 + 2 * 3 is ambiguous unless we know that the multiplication happens before the addition. (All of these operators are binary. Operands are leaf nodes. this function returns their sum: def total(tree): if tree == None: return 0 return total(tree.cargo The base case is the empty tree.2 Traversing trees
207
20. Tree(3)))
.

and translate programs. This way of traversing a tree is called a preorder. Similar trees are used inside compilers to parse.left) printTree(tree. Tree(’*’. then the root. preﬁx. to print a tree. 1 2 3 * +.
20.cargo. you get: def printTreePostorder(tree): if tree == None: return printTreePostorder(tree.right) In other words. because the contents of the root appear before the contents of the children.cargo. For example. if you print the subtrees ﬁrst and then the root node. it is another notation called preﬁx. Finally. and then the right tree:
. the multiplication happens ﬁrst in order to compute the second operand of the addition. The result. For the previous example. and then print the entire right subtree.right) print tree. Tree(1). You might suspect that if you traverse the tree in a diﬀerent order. and inﬁx. The example in this chapter uses trees to translate expressions to postﬁx.4
Tree traversal
We can traverse an expression tree and print the contents like this: def printTree(tree): if tree == None: return print tree. Expression trees have many uses.208
Trees
Looking at the ﬁgure. is in postﬁx! This order of traversal is called postorder. there is no question what the order of operations is. optimize. in which the operators appear before their operands. to traverse a tree inorder. ﬁrst print the contents of the root.left) printTreePostorder(tree. you print the left tree. you will get the expression in a diﬀerent notation. Tree(3))) >>> printTree(tree) + 1 * 2 3 This format is diﬀerent from both postﬁx and inﬁx. printTree(tree. Tree(2). then print the entire left subtree. the output is: >>> tree = Tree(’+’.

By default. The result for the example tree is: >>> printTreeIndented(tree) 3 * 2 + 1 If you look at the output sideways. Is the output correct and unambiguous? Are the parentheses always necessary? If we do an inorder traversal and keep track of what level in the tree we are on. the expression tree and the three recursive traversals provide a general way to translate expressions from one format to another. level+1) The parameter level keeps track of where we are in the tree. we should point out that we have omitted an important complication. Sometimes when we write an expression in inﬁx. level+1) print ’ ’*level + str(tree.20.right. it is initially 0.4 Tree traversal def printTreeInorder(tree): if tree == None: return printTreeInorder(tree. which is the expression in inﬁx. you see a simpliﬁed version of the original ﬁgure. As an exercise. we have to use parentheses to preserve the order of operations. Each time we make a recursive call. Each item is indented by two spaces per level.cargo) printTreeIndented(tree. we can generate a graphical representation of a tree: def printTreeIndented(tree.
209
To be fair. Nevertheless. level=0): if tree == None: return printTreeIndented(tree.right) The result is 1 + 2 * 3.cargo. with a few improvements. printTreeInorder(tree.left) print tree.
. modify printTreeInorder so that it puts parentheses around every operator and pair of operands. we pass level+1 because the child’s level is always one greater than the parent’s.left. So an inorder traversal is not quite suﬃcient to generate an inﬁx expression.

3. ’*’. The parser we will write handles expressions that include numbers. and the operators + and *. the changes made here are visible to any other variable that refers to the same object. ’+’.5
Building an expression tree
In this section. otherwise. parentheses. ’end’] The end token is useful for preventing the parser from reading past the end of the list. write a function that takes an expression string and returns a token list. ’)’. For example. it returns false: def getToken(tokenList. The ﬁrst function we’ll write is getToken. we parse inﬁx expressions and build the corresponding expression trees. the expression (3+7)*9 yields the following tree:
*
+ 3 7 9
Notice that we have simpliﬁed the diagram by leaving out the names of the attributes. As an exercise. We assume that the input string has already been tokenized into a Python list.210
Trees
20.
. 7. It compares the expected token to the ﬁrst token on the list: if they match. which takes a token list and an expected token as parameters. expected): if tokenList[0] == expected: del tokenList[0] return 1 else: return 0 Since tokenList refers to a mutable object. The token list for (3+7)*9 is: [’(’. it removes the token from the list and returns true. 9.

If the next token in tokenList is a number. and print what remains of the token list: >>> tokenList = [9. If the next character is anything else. otherwise. extract the ﬁrst. def getProduct(tokenList): a = getNumber(tokenList) if getToken(tokenList. None. 11. then we just return the leaf node with a. handles operands. Here are two examples: >>> tokenList = [9. like 3 * 7. getNumber removes it and returns a leaf node containing the number. ’*’. we should test getNumber in isolation. b) else: return a Assuming that getNumber succeeds and returns a singleton tree. If the next character is *. A simple product has two numbers as operands. ’end’] >>> x = getNumber(tokenList) >>> printTreePostorder(x) 9 >>> print tokenList [11. ’end’] >>> tree = getProduct(tokenList) >>> printTreePostorder(tree) 9 11 *
. b. ’end’] The next method we need is getProduct. getNumber. Here is a version of getProduct that handles simple products. which builds an expression tree for products.20. it returns None. print the result. We assign a list of numbers to tokenList. ’*’): b = getNumber(tokenList) return Tree (’*’.5 Building an expression tree
211
The next function. we assign the ﬁrst operand to a. def getNumber(tokenList): x = tokenList[0] if type(x) != type(0): return None del tokenList[0] return Tree (x. and the operator. we get the second number and build an expression tree with a. a. 11. None) Before continuing.

’end’] tree = getProduct(tokenList) printTreePostorder(tree) 5 7 * * *
Next we will add the ability to parse sums. 5 . and a sum on the right. namely 3 * (5 * 13).” For us. Now we have to deal with compound products. a. a sum can be a tree with + at the root. a product on the left. 7. This kind of recursive deﬁnition should be starting to feel familiar. ’*’. we use a slightly counterintuitive deﬁnition of “sum. like like 3 * 5 * 13. The resulting tree is:
*
3 5
*
13
With a small change in getProduct. 11. Or. Again. ’+’. We treat this expression as a product of products. a product can be either a singleton or a tree with * at the root. a number on the left.212 >>> tokenList = [9. ’*’): b = getProduct(tokenList) return Tree (’*’. ’*’. 3.
. This deﬁnition of “product” is counterintuitive. but it turns out to be useful. ’*’. b) else: return a
# this line changed
In other words. Let’s test the new version with a compound product: >>> >>> >>> 2 3 tokenList = [2. ’end’] >>> tree = getProduct(tokenList) >>> printTreePostorder(tree) 9
Trees
The second example implies that we consider a single operand to be a kind of product. a sum can be just a product. and a product on the right. we can handle an arbitrarily long product: def getProduct(tokenList): a = getNumber(tokenList) if getToken(tokenList.

it has a nice property: we can represent any expression (without parentheses) as a sum of products. ’+’. def getSum(tokenList): a = getProduct(tokenList) if getToken(tokenList. ’*’. 5. ’*’. a. ’)’. ’*’.5 Building an expression tree
213
If you are willing to play along with this deﬁnition. Anywhere in an expression where there can be a number. None) Let’s test this code with 9 * (11 + 5) * 7: >>> tokenList = [9. 7. None. ’+’. 5. getSum tries to build a tree with a product on the left and a sum on the right. ’(’): x = getSum(tokenList) # get the subexpression getToken(tokenList. there can also be an entire sum enclosed in parentheses. but we still have to handle parentheses. ’end’] >>> tree = getSum(tokenList) >>> printTreePostorder(tree) 9 11 5 + 7 * *
. ’(’. b) else: return a Let’s test it with 9 * 11 + 5 * 7: >>> tokenList = [9. This property is the basis of our parsing algorithm. ’end’] >>> tree = getSum(tokenList) >>> printTreePostorder(tree) 9 11 * 5 7 * + We are almost done. 11. We just need to modify getNumber to handle subexpressions: def getNumber(tokenList): if getToken(tokenList. But if it doesn’t ﬁnd a +. 7. ’)’) # remove the closing parenthesis return x else: x = tokenList[0] if type(x) != type(0): return None tokenList[0:1] = [] return Tree (x.20. 11. it just builds a product. ’*’. ’+’): b = getSum(tokenList) return Tree (’+’.

6
Handling errors
Throughout the parser.7
The animal tree
In this section. For example. the addition happens before the multiplication. then the program can continue. Test your code with improperly formed expressions. or one of the other functions in the traceback. it would be a good idea to give getNumber a name more descriptive of its new role. when we reach the end of a subexpression. In the ﬁnal version of the program. handles the exception. ﬁnd other places in these functions where errors can occur and add appropriate raise statements. Here is a sample run:
. called a BadExpressionError. ’missing parenthesis’ return x else: # the rest of the function omitted The raise statement creates an exception. Otherwise. If the function that called getNumber. The program interacts with the user to create a tree of questions and animal names.
20. in this case we create a new kind of exception. we assume that the next character is a close parenthesis. def getNumber(tokenList): if getToken(tokenList. we’ve been assuming that expressions are well-formed. ’(’): x = getSum(tokenList) if not getToken(tokenList. If there is an error and the next character is something else. As an exercise. we should deal with it. Python will print an error message and quit. ’)’): raise ’BadExpressionError’.
20. we develop a small program that uses a tree to represent a knowledge base.214
Trees
The parser handled the parentheses correctly.

If the guess is not correct. it makes a guess. At that point. Then it adds a node to the tree with the new question and the new animal. Depending on the answer. it moves to the left or right child and continues until it gets to a leaf node. Here is the code:
.7 The animal tree Are you thinking of an animal? y Is it a bird? n What is the animals name? dog What question would distinguish a dog from a bird? Can it fly If the animal were dog the answer would be? n Are you thinking of an animal? y Can it fly? n Is it a dog? n What is the animals name? cat What question would distinguish a cat from a dog? Does it bark If the animal were cat the answer would be? n Are you thinking of an animal? y Can it fly? n Does it bark? y Is it a dog? y I rule! Are you thinking of an animal? n Here is the tree this dialog builds:
215
Can it fly? n Does it bark? n cat y dog y bird
At the beginning of each round. the program starts at the top of the tree and asks the ﬁrst question. it asks the user for the name of the new animal and a question that distinguishes the (bad) guess from the new animal.20.

8 Glossary def yes(ques): from string import lower ans = lower(raw_input(ques)) return (ans[0] == ’y’)
217
The condition of the outer loop is 1. When a new node is added to the tree. it forgets everything you carefully taught it! As an exercise. leaf: A bottom-most node in a tree. or two dependent nodes. subexpression: An expression in parentheses that acts as a single operand in a larger expression. Implement the one you think is easiest. One shortcoming of the program is that when it exits. siblings: Nodes that share a common parent. the new question replaces the cargo. guided by the user’s responses. with no parent.8
Glossary
binary tree: A tree in which each node refers to zero.
20. think of various ways you might save the knowledge tree in a ﬁle. binary operator: An operator that takes two operands. which means it will continue until the break statement executes. root: The topmost node in a tree. one.
. preﬁx notation: A way of writing a mathematical expression with each operator appearing before its operands. if the user is not thinking of an animal. level: The set of nodes equidistant from the root. preorder: A way to traverse a tree. child: One of the nodes referred to by a node. visiting each node before its children. and the two children are the new animal and the original cargo. The inner while loop walks the tree from top to bottom.20. parent: The node that refers to a given node. with no children.

. visiting the children of each node before the node itself. inorder: A way to traverse a tree. then the root. and then the right subtree.218
Trees
postorder: A way to traverse a tree. visiting the left subtree.

some techniques are applicable in more than one situation.” • Semantic errors are problems with a program that compiles and runs but doesn’t do the right thing. They usually indicate that there is something wrong with the syntax of the program.Appendix A
Debugging
Diﬀerent kinds of errors can occur in a program. Example: An expression may not be evaluated in the order you expect. the error messages are often not helpful. Although the following sections are organized by error type. Example: Omitting the colon at the end of a def statement yields the somewhat redundant message SyntaxError: invalid syntax. • Runtime errors are produced by the runtime system if something goes wrong while the program is running. Most runtime error messages include information about where the error occurred and what functions were executing. Example: An inﬁnite recursion eventually causes a runtime error of “maximum recursion depth exceeded. Unfortunately.1
Syntax errors
Syntax errors are usually easy to ﬁx once you ﬁgure out what they are. The ﬁrst step in debugging is to ﬁgure out which kind of error you are dealing with. yielding an unexpected result.
A. The most common
. and it is useful to distinguish among them in order to track them down more quickly: • Syntax errors are produced by Python when it is translating the source code into byte code.

On the other hand. Each level should be nested the same amount. Sometimes the error is prior to the location of the error message. If nothing works. You may indent with either spaces or tabs but it’s best not to mix them. it might be. If you are building the program incrementally. 5. Actually.. Check that indentation is consistent. If you have multiline strings with triple quotes (single or double). Check that you have a colon at the end of the header of every compound statement. including for. Make sure that any strings in the code have matching quotation marks.220
Debugging invalid
messages are SyntaxError: invalid syntax and SyntaxError: token. start by comparing your code to the book’s code very carefully. or it may treat the following part of the program as a string until it comes to the next string. it tells you where Python noticed a problem. the message does tell you where in the program the problem occurred. while. 2. At the same time. Generally. In the second case. or [—makes Python continue with the next line as part of the current statement. Check every character. make sure you have terminated the string properly. you should have a good idea about where the error is. neither of which is very informative. An unclosed bracket—(. {. it might not produce an error message at all! 6.. an error occurs almost immediately in the next line. Here are some ways to avoid the most common syntax errors: 1. often on the preceding line. It will be in the last line you added. Check for the classic = instead of == inside a conditional. move on to the next section. and def statements. If you are copying code from a book. if. 7.
. 3. so if you see something that looks like a syntax error. An unterminated string may cause an invalid token error at the end of your program. 4. remember that the book might be wrong. Make sure you are not using a Python keyword for a variable name. which is not necessarily where the error is.

If you are not sure.2
My program hangs. Now run (or import) it again. there is probably something wrong with the way your environment is set up. make sure that you are invoking a function to start execution. one approach is to start again with a new program like “Hello. Also see the “Flow of Execution” section below. we say it is “hanging.1
My program does absolutely nothing. Check your programming environment to make sure that the program you are editing is the one Python is trying to run. If this happens. Python can import it and at least start running it. World!. Then gradually add the pieces of the new program to the working one.” Run the program.
A.” and make sure you can get a known program to run.2. This may be intentional if you only plan to import this module to supply classes and functions.
This problem is most common when your ﬁle consists of functions and classes but does not actually invoke anything to start execution. What could possibly go wrong?
A. or execute one from the interactive prompt.2.
If a program stops and seems to be doing nothing.
.1. If you get the ﬁrst message and not the second. that might be because you and the compiler are not looking at the same code. add a print statement immediately before the loop that says “entering the loop” and another immediately after that says “exiting the loop. you’ve got an inﬁnite loop.
If the compiler says there is an error and you don’t see it. try putting an obvious and deliberate syntax error at the beginning of the program.
A.2 Runtime errors
221
A. • If there is a particular loop that you suspect is the problem. If it is not intentional. Go to the “Inﬁnite Loop” section below.1
I can’t get my program to run no matter what I do.2
Runtime errors
Once your program is syntactically correct. If the compiler doesn’t ﬁnd the new error.” Often that means that it is caught in an inﬁnite loop or an inﬁnite recursion.A.

start testing other loops and other recursive functions and methods. then it is possible that you don’t understand the ﬂow of execution in your program. y "condition: ". the condition should be false. • If neither of those steps works. • If that doesn’t work. an inﬁnite recursion will cause the program to run for a while and then produce a “RuntimeError: Maximum recursion depth exceeded” error. Inﬁnite Recursion Most of the time. you will be able to see the values of x and y. If you suspect that a function or method is causing an inﬁnite recursion. x "y: ". there should be some condition that will cause the function or method to return without
.222
Debugging
• Most of the time. start by checking to make sure that there is a base case. (x > 0 and y < 0)
Now when you run the program. you will see three lines of output for each time through the loop. In other words. If that happens. you can still use the techniques in the “Inﬁnite Recursion” section. add a print statement at the end of the loop that prints the values of the variables in the condition and the value of the condition. For example: while x > 0 and y < 0 : # do something to x # do something to y print print print "x: ". and you might ﬁgure out why they are not being updated correctly. If you are not getting this error but you suspect there is a problem with a recursive method or function. Inﬁnite Loop If you think you have an inﬁnite loop and you think you know what loop is causing the problem. If the loop keeps going. go to the “Inﬁnite Recursion” section below. The last time through the loop. Go to the “Flow of Execution” section below. an inﬁnite recursion will cause the program to run for a while and then produce a Maximum recursion depth exceeded error.

Flow of Execution If you are not sure how the ﬂow of execution is moving through your program. The traceback identiﬁes the function that is currently running. If not. the line of the program where the problem occurred. and you will see the parameters. You cannot refer to them from outside the function where they are deﬁned. Now when you run the program. it traces the path of function invocations that got you to where you are. TypeError: There are several possible causes: • You are trying to use a value improperly.
. These are some of the most common runtime errors: NameError: You are trying to use a variable that doesn’t exist in the current environment.2. you will see a few lines of output every time the function or method is invoked. The ﬁrst step is to examine the place in the program where the error occurred and see if you can ﬁgure out what happened. and a traceback. Python prints a message that includes the name of the exception.3
When I run the program I get an exception. add print statements to the beginning of each function with a message like “entering function foo. and then the function that invoked that. Now when you run the program. If the parameters are not moving toward the base case. It also includes the line number in your ﬁle where each of these calls occurs. or tuple with something other than an integer. and then the function that invoked it. you will get some ideas about why not. it will print a trace of each function as it is invoked.
If something goes wrong during runtime.
A. add a print statement at the beginning of the function or method that prints the parameters.2 Runtime errors
223
making a recursive invocation. list. then you need to rethink the algorithm and identify a base case.” where foo is the name of the function. and so on. Remember that local variables are local.A. If there is a base case but the program doesn’t seem to be reaching it. Example: indexing a string. In other words.

Often the process of ﬁnding the minimal test case leads you to the bug. try rewriting that part with simpler structure. Second.4
I added so many print statements I get inundated with output. that gives you a clue about what is going on. make sure you are invoking the method on an object with the right type and providing the other arguments correctly. There are two ways to proceed: simplify the output or simplify the program. For example. Remove dead code and reorganize the program to make it as easy to read as possible.2.
KeyError: You are trying to access an element of a dictionary using a key value that the dictionary does not contain. if you are sorting an array. or tuple is greater than its length minus one. If you ﬁnd that a program works in one situation but not in another. To simplify the output. or format the output so it is easier to understand. If you suspect a large function.
. IndexError: The index you are using to access a list.
One of the problems with using print statements for debugging is that you can end up buried in output. To simplify the program. if you suspect that the problem is in a deeply nested part of the program. For example. Is the array the right size? Is the index the right value?
A. give it the simplest input that causes the problem. or combine them. For methods. clean up the program. • You are passing the wrong number of arguments to a function or method. This can happen if either the number of items does not match or an invalid conversion is called for. AttributeError: You are trying to access an attribute or method that does not exist. If the program takes input from the user. look at the method deﬁnition and check that the ﬁrst parameter is self. First. Immediately before the site of the error. sort a small array. there are several things you can do. add a print statement to display the value of the index and the length of the array. scale down the problem the program is working on. you can remove or comment out print statements that aren’t helping. string. try splitting it into smaller functions and testing them separately.224
Debugging • There is a mismatch between the items in a format string and the items passed for conversion. Then look at the method invocation.

that can tip you oﬀ. very often the problem is not in the program.1
My program doesn’t work.A.
A.
You should ask yourself these questions: • Is there something the program was supposed to do but which doesn’t seem to be happening? Find the section of the code that performs that function and make sure it is executing when you think it should. rewriting a piece of code can help you ﬁnd subtle bugs. The ﬁrst step is to make a connection between the program text and the behavior you are seeing.3
Semantic errors
In some ways. One of the things that makes that hard is that computers run so fast. If you make a change that you think doesn’t aﬀect the program. semantic errors are the hardest to debug. You will often wish that you could slow the program down to human speed. If you write a program that doesn’t do what you expect.3. especially if it involves invocations to functions or methods in other Python modules. and “walking” the program to where the error is occurring. • Is a section of code producing an eﬀect that is not what you expected? Make sure that you understand the code in question. Try them out by writing simple test cases and checking the results. you need to have a mental model of how programs work. In order to program. because the compiler and the runtime system provide no information about what is wrong. Read the documentation for the functions you invoke. • Is something happening that shouldn’t? Find code in your program that performs that function and see if it is executing when it shouldn’t.
A. it’s in your mental model. But the time it takes to insert a few well-placed print statements is often short compared to setting up the debugger. and it does. You need a hypothesis about what the program is actually doing. and only you know that it isn’t doing it. Only you know what the program is supposed to do. and with some debuggers you can.
. inserting and removing breakpoints.3 Semantic errors
225
Similarly.

hands[neighbor].hands[i].findNeighbor(i)].addCard (pickedCard) The explicit version is easier to read because the variable names provide additional documentation.
Writing complex expressions is ﬁne as long as they are readable. Once you ﬁnd the discrepancy between your model and reality. Another problem that can occur with big expressions is that the order of evaluation may not be what you expect. Whenever you are not sure of the order of evaluation. That is not correct because multiplication and division have the same precedence and are evaluated from left to right. you might write: y = x / 2 * math.addCard (self. and it is easier to debug because you can check the types of the intermediate variables and display their values.popCard()) This can be rewritten as: neighbor = self.pi. you can solve the problem. use parentheses. So this expression computes xπ/2.hands[self.pi).226
Debugging
The best way to correct your mental model is to break the program into its components (usually the functions and methods) and test each component independently.3. Of course.
A. A good way to debug expressions is to add parentheses to make the order of evaluation explicit: y = x / (2 * math. if you are translating the x expression 2π into Python.
. Not only will the program be correct (in the sense of doing what you intended).hands[i].popCard() self. it will also be more readable for other people who haven’t memorized the rules of precedence. but they can be hard to debug. For example: self.findNeighbor (i) pickedCard = self. there should be only a small amount of new code that is not known to be correct.2
I’ve got a big hairy expression and it doesn’t do what I expect. you should be building and testing components as you develop the program. It is often a good idea to break a complex expression into a series of assignments to temporary variables. For example. If you encounter a problem.

5
No. you don’t have a chance to print the return value before returning.removeMatches() you could write: count = self.
It happens. just before you fall asleep. Some of the best places to ﬁnd bugs are trains. try getting away from the computer for a few minutes. get up and go for a walk. When you are calm. Even the best programmers occasionally get stuck. instead of: return self.
A. you can use a temporary variable.A.hands[i]. For example.
A. causing these eﬀects: • Frustration and/or rage. and in bed. showers. We often ﬁnd bugs when we are away from the computer and let our minds wander.
If you have a return statement with a complex expression.3.3
I’ve got a function or method that doesn’t return what I expect. • Random-walk programming (the attempt to program by writing every possible program and choosing the one that does the right thing).
. think about the program.4
I’m really.removeMatches() return count Now you have the opportunity to display the value of count before returning.3. really stuck and I need help.3. Computers emit waves that aﬀect the brain. What is it doing? What are some possible causes of that behavior? When was the last time you had a working program. and what did you do next? Sometimes it just takes time to ﬁnd a bug. Again.3 Semantic errors
227
A. Sometimes you work on a program so long that you can’t see the error. If you ﬁnd yourself suﬀering from any of these symptoms.
First. A fresh pair of eyes is just the thing. I really need help.hands[i]. • Superstitious beliefs (“the computer hates me”) and magical thinking (“the program only works when I wear my hat backward”).

be sure to give them the information they need: • If there is an error message. You should understand the problem well enough to describe it concisely. what is it and what part of the program does it indicate? • What was the last thing you did before this error occurred? What were the last lines of code that you wrote.228
Debugging
Before you bring someone else in. or what is the new test case that fails? • What have you tried so far.
. and what have you learned? When you ﬁnd the bug. Your program should be as simple as possible. When you bring someone in to help. Next time you see something similar. you will be able to ﬁnd the bug more quickly. make sure you have exhausted the techniques described here. the goal is not just to make the program work. and you should be working on the smallest input that causes the error. You should have print statements in the appropriate places (and the output they produce should be comprehensible). The goal is to learn how to make the program work. take a second to think about what you could have done to ﬁnd it faster. Remember.

and ﬂoats.Appendix B
Creating a new data type
Object-oriented programming languages allow programmers to create new data types that behave much like built-in data types. We will explore this capability by building a Fraction class that works very much like the built-in numeric types. The top number is called the numerator and the bottom number is called the denominator.
We start by deﬁning a Fraction class with an initialization method that provides the numerator and denominator as integers:
. longs. integers. are values that can be expressed as a ratio of whole numbers.
Fractions. also known as rational numbers. such as 5/6.

def __mul__(self.1
Fraction multiplication
We would like to be able to apply the normal addition. self.numerator = numerator self. To multiply fractions.denominator = denominator The denominator is optional.
As usual. The next step is to write a str method that displays fractions in a way that makes sense.6) print "The fraction is". If the numerator is n. numerator. To do this.numerator. multiplication.numerator. we build the Fraction n/1. >>> >>> >>> The from Fraction import Fraction spam = Fraction(5.denominator) To test what we have so far. A Fraction with just one just one parameter represents a whole number. the print command invokes the
B.. self.230
Creating a new data type
class Fraction: def __init__(self. Then we create a fraction object and print it..numerator*object. object): return Fraction(self. and division operations to fractions. subtraction. def __str__(self): return "%d/%d" % (self. We’ll start with multiplication because it is the easiest to implement. mul is the name Python uses for a method that overloads the * operator: class Fraction: . The form “numerator/denominator” is natural here: class Fraction: . we can overload the mathematical operators for Fraction objects. we put it in a ﬁle named Fraction.denominator*object.denominator) We can test this method by computing the product of two fractions:
.. we create a new fraction with a numerator that is the product of the original numerators and a denominator that is a product of the original denominators. denominator=1): self.. spam fraction is 5/6 str method implicitly.py and import it into the Python interpreter.

self.numerator. and mul can handle an integer paramrmul :
. Python checks the right operand to see if it provides an rmul method that supports the ﬁrst type. Python invokes rmul on the Fraction object and passes 4 as a parameter: >>> print 4 * Fraction(5.numerator * other.denominator * other. In this case.. there is a simple way to provide class Fraction: . def __mul__(self.6) 20/6 Since rmul is the same as eter.6).6) * 4 20/6 >>> print 4 * Fraction(5.. Next. class Fraction: .B. mul ..6) TypeError: __mul__ nor __rmul__ defined for these operands To evaluate a binary operator like multiplication. we haven’t provided rmul . __rmul__ = __mul__ This assignment says that the rmul is the same as mul . but we can do better! We can extend the method to handle multiplication by an integer. In this case.4) 15/24
231
It works. we’re all set.denominator) Multiplying fractions and integers now works.. but only if the fraction is the left operand: >>> print Fraction(5. On the other hand. so it fails.1 Fraction multiplication >>> print Fraction(5. Now if we evaluate 4 * Fraction(5. the built-in integer operator doesn’t support fractions.6) * Fraction(3. other): if type(other) == type(5): other = Fraction(other) return Fraction(self. We use the type function to test if other is an integer and convert it to a fraction if it is. Python checks the left operand ﬁrst to see if it provides a mul that supports the type of the second operand.

>>> print Fraction(5. the last invokes radd . Using the multiplication code as a model.. we have to divide the numerator and denominator by their greatest common divisor (GCD). we should reduce it by dividing the numerator and denominator by their GCD.3
Euclid’s algorithm
In the previous example. To reduce the fraction to its simplest terms.
B. but still not too bad. 325–265 BCE) presented an algorithm to ﬁnd the GCD for two integers m and n: If n divides m evenly.6) + Fraction(5.denominator) __radd__ = __add__ We can test these methods with Fractions and integers.numerator * other. which is 12.denominator + self. we can write add and radd :
class Fraction: .denominator * other.6) + 3 23/6 >>> print 2 + Fraction(5. self. If the fraction is already reduced.6) 17/6 The ﬁrst two examples invoke add . def __add__(self.6) 60/36 >>> print Fraction(5. we computed the sum 5/6 + 5/6 and got 60/36. Otherwise the GCD is the GCD of n and the remainder of m divided by n.2
Fraction addition
Addition is more complicated than multiplication.denominator * other. Euclid of Alexandria (approx. other): if type(other) == type(5): other = Fraction(other) return Fraction(self. The result is 5/3.. whenever we create a new Fraction object. In general.
.232
Creating a new data type
B. then n is the GCD. That is correct. The sum of a/b and c/d is the fraction (a*d+c*b)/b*d. the GCD is 1. but it’s not the best way to represent the answer.numerator.

numerator. denominator=1): g = gcd (numerator.
B. m%n)
233
In the ﬁrst line of the body.B. the minus sign is always moved to the numerator. The default implementation of == tests for shallow equality.4. The simplest way to compare fractions is to cross-multiply. As we saw in Section 15. denominator) self. With that in mind.-36) -25/9 A nice feature of gcd is that if the fraction is negative. and we evaluate a == b. we use it to compute the remainder after division. zero if they are the same. More likely. class Fraction: def __init__(self. we want to return true if a and b have the same value—that is. By convention. and a positive number if self is greater than other. deep equality. We have to teach fractions how to compare themselves. so it only returns true if a and b are the same object.4
Comparing fractions
Suppose we have two Fraction objects.4 Comparing fractions This recursive deﬁnition can be expressed concisely as a function: def gcd (m. a and b. On the last line. n): if m % n == 0: return n else: return gcd(n. it is reduced to its simplest form: >>> Fraction(100. here is the code for cmp :
. the cmp method returns a negative number if self is less than other. we can overload all the comparison operators at once by supplying a cmp method. then ad > bc. Since all the operations we’ve written create new Fractions for the result.numerator = numerator / g self. we can reduce all results by modifying the initialization method. If a/b > c/d.denominator = denominator / g Now whenever we create a Fraction. we use the modulus operator to check divisibility.

and long integers as numerators and denominators.234
Creating a new data type
class Fraction: . we have assumed that the numerator and denominator are integers. which is the use of the minus sign with a single operand. then diff will be negative. We can’t just set rsub and rdiv equal to sub and div . So far. the order of the operands makes a diﬀerence. In these operations. def __cmp__(self. Next.
B. If they are the same. As an exercise.. There is one other extension to the Fraction class that you might want to think about.2) is the square root of 2.5
Taking it further
Of course. We can compute powers by overriding pow . So it’s not easy to write the most general version of pow . We still have to implement subtraction by overriding sub and division by overriding div . For example.numerator * self. we can’t use the same trick we used for addition and multiplication. then it may not be possible to represent the result as a Fraction. we override neg . because subtraction and division are not commutative. then diff will be positive.
. Then we can subtract by negating the second operand and adding. To handle unary negation. diff is zero. exponentiation. but the implementation is a little tricky. we are not done..numerator * other. we have to provide rsub and rdiv .denominator) return diff If self is greater than other.denominator other. which is an irrational number (it can’t be represented as a fraction). One way to handle those operations is to implement negation by overriding neg and inversion by overriding invert . If the exponent isn’t an integer. If other is greater. We might also want to allow them to be long integers. ﬁnish the implementation of the Fraction class so that it handles subtraction. Unfortunately. other): diff = (self. and we can divide by inverting the second operand and multiplying. division. Fraction(2) ** Fraction(1.

reduce: To change a fraction into an equivalent form with a GCD of 1. Called “unary” by contrast with the binary minus operation.
.6 Glossary
235
B. usually denoted with a leading minus sign. unary negation: The operation that computes an additive inverse.6
Glossary
greatest common divisor (GCD): The largest positive integer that divides without a remainder into both the numerator and denominator of a fraction.B. which is subtraction.

236
Creating a new data type
.

For example. sometimes forcing you to rethink the whole structure of a program. extending your knowledge of Python speciﬁcally and computer science in general. • GUI (graphical user interface) programming lets your program use a windowing environment to interact with the user and display graphics. Any type of GUI programming will lead you into event-driven programming. where the user and not the programmer determines the ﬂow of execution. Another popular platform is wxPython. Tkinter comes bundled with the Python distribution. which is based on Jon Ousterhout’s Tcl and Tk scripting languages. The examples in this book have been deliberately simple. This style of programming takes some getting used to. Here is a sampling of extensions to Python and suggestions for projects that use them.Appendix C
Recommendations for further reading
So where do you go from here? There are many directions to pursue. The oldest graphics package for Python is Tkinter. but they may not have shown oﬀ Python’s most exciting capabilities. which is essentially a Python veneer over wxWindows. • Web programming integrates the Python with the Internet. you can build web client programs that open and read a remote web page
. The windows and controls under wxPython tend to have a more native look and feel than those of Tkinter and are somewhat simpler to program. a C++ package which in turn implements windows using native interfaces on Windows and Unix (including Linux) platforms.

.238
Recommendations for further reading (almost) as easily as you can open a ﬁle on disk. • Thread programming lets you run several threads of execution within a single program. Python for Fun.org is the place to start your search for any Python related material. then you have a feel for what threads can do. a set of case studies in Python by Chris Meyers.. links to other sites and SIG (Special Interest Group) mailing lists that you can join. Python is also widely used for web server programs to handle input forms.
. and The Linux Cookbook by Michael Stultz. Kuphaldt. and relationships between data items let you access the data in various ways. and modules to let you send and receive email. Such extensions form the base of many of the modules in the Python library. a set of tutorials on a range of computer science topics..
C. Python has several modules to enable users to connect to various database engines. • The Open Book Project www.com/obp contains not only this book online but also similar books for Java and C++ by Allen Downey.1
Python-related web sites and books
Here are the authors’ recommendations for Python resources on the web: • The Python home page at www. SWIG (Simpliﬁed Wrapper and Interface Generator) is a tool to make the process much simpler.000 hits. written and edited by high school students.python. documentation. • Finally if you go to Google and use the search string “python -snake monty” you will get about 750. both Open Source and commercial. The mechanics of linking functions and data is somewhat complex. Getting down with .ibiblio. If you have had the experience of using a web browser to scroll the beginning of a page while the browser continues to load the rest of it. You will ﬁnd help.
• Databases are a bit like super ﬁles where data is stored in predeﬁned schemas. • When speed is paramount Python extensions may be written in a compiled language like C or C++. with 300 pages of tips and techniques. In addition there are Lessons in Electric Circuits by Tony R. There are also Python modules that let you access remote ﬁles via ftp.

The ﬁrst part of the book covers the basic Python language features.
. They deal with good programming practices and computer science in general. builds a small application with wxPython. • The Elements of Java Style edited by Al Vermeulen is another small book that discusses some of the ﬁner points of good programming. and even whitespace and indentation (somewhat of a nonissue in Python).2
Recommended general computer science books
The following suggestions for further reading include many of the authors’ favorite books. such as good use of naming conventions. Beazley is a small book. and proper programming with threads and their synchronization. and even uses Python to script windows applications such as Word and Excel.2 Recommended general computer science books
239
And here are some books that contain more material on the Python language: • Core Python Programming by Wesley Chun is a large book at about 750 pages.
C. • Python Pocket Reference by Mark Lutz really does ﬁt in your pocket. but it is packed with information both on the language itself and the modules in the standard library. The examples are mostly C++ and Java. • Python Essential Reference by David M. comments. • Python Programming on Win32 by Mark Hammond and Andy Robinson is a “must have” for anyone seriously using Python to develop Windows applications. Although not as extensive as Python Essential Reference it is a handy reference for the most commonly used functions and modules. with none in Python. Mark Lutz is also the author of Programming Python. but also debugging. It is also very well indexed. • The Practice of Programming by Kernighan and Pike covers not only the design and coding of algorithms and data structures.C. testing and improving the performance of programs. Among other things it covers the integration of Python and COM. His later book Learning Python is smaller and more accessible. using assertions to catch errors by testing preconditions and postconditions. The second part provides an easy-paced introduction to more advanced topics including many of those mentioned above. one of the earliest (and largest) books on Python and not aimed at the beginning programmer. The book also covers programming by contract.

Escher and Bach by Douglas Hofstadter.K Dewdney provides a gentle introduction to 66 topics of computer science ranging from parallel computing to computer viruses. He demonstrates such patterns in the music of Bach. It is Hofstadter’s contention that such “strange loops” are an essential part of what separates the animate from the inanimate. • The New Turing Omnibus by A. This book was very popular and was followed by a second volume. The studies deal with tradeoﬀs in programming and why it is often an especially bad idea to run with your ﬁrst idea for a program. An earlier book by Dewdney The Armchair Universe is a collection from his column Computer Recreations in Scientiﬁc American. • Turtles. from cat scans to genetic algorithms. so the examples are in older languages. the pictures of Escher and G¨del’s incompleteness theorem. Many of the programs in the book were developed by students in middle school and high school. The book is a bit older than those above (1986). which is often counterintuitive. Termites and Traﬃc Jams by Mitchel Resnick is about the power of decentralization and how complex behavior can arise from coordinated simple activity of a multitude of agents. • G¨del. One of Hofstadter’s themes involves “strange loops” where patterns evolve and ascend until they meet themselves again. Put simply.240
Recommendations for further reading
• Programming Pearls by Jon Bentley is a classic book. It introduces the language StarLogo. It consists of case studies that originally appeared in the author’s column in the Communications of the ACM. Similar programs could be written in Python using simple graphics and threads. There are lots of problems to solve. which allows the user to write programs for the agents. some with solutions and others with hints. All of the topics are short and entertaining. if you found o magic in recursion you will also ﬁnd it in this bestselling book. Running the program demonstrates complex aggregate behavior. o
. Both books are rich source of ideas for projects.

Inc. MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document. textbook.
Preamble
The purpose of this License is to make a manual. Secondarily. 59 Temple Place. while not being considered responsible for modiﬁcations made by others.” which means that derivative works of the document must themselves be free in the same sense. either commercially or noncommercially. But this
. Suite 330.1. This License is a kind of “copyleft.Appendix D
GNU Free Documentation License
Version 1. which is a copyleft license designed for free software. Boston. or other written document “free” in the sense of freedom: to assure everyone the eﬀective freedom to copy and redistribute it. this License preserves for the author and publisher a way to get credit for their work. with or without modifying it. We have designed this License in order to use it for manuals for free software. because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. It complements the GNU General Public License. March 2000 Copyright c 2000 Free Software Foundation. but changing it is not allowed.

ethical. We recommend this License principally for works whose purpose is instruction or reference.” A “Modiﬁed Version” of the Document means any work containing the Document or a portion of it. A copy that is not “Transparent” is called “Opaque.” below. The “Document.242
GNU Free Documentation License
License is not limited to software manuals. A copy made in an otherwise Transparent ﬁle format whose markup has been designed to thwart or discourage subsequent modiﬁcation by readers is not Transparent. (For example. and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. regardless of subject matter or whether it is published as a printed book.) The relationship could be a matter of historical connection with the subject or with related matters. or of legal. or political position regarding them. as being those of Invariant Sections. whose contents can be viewed and edited directly and straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor. in the notice that says that the Document is released under this License. represented in a format whose speciﬁcation is available to the general public. philosophical.1
Applicability and Deﬁnitions
This License applies to any manual or other work that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. if the Document is in part a textbook of mathematics. The “Invariant Sections” are certain Secondary Sections whose titles are designated. The “Cover Texts” are certain short passages of text that are listed. either copied verbatim. refers to any such manual or work. as FrontCover Texts or Back-Cover Texts.”
. or with modiﬁcations and/or translated into another language. and is addressed as “you. A “Transparent” copy of the Document means a machine-readable copy. it can be used for any textual work.
D. A “Secondary Section” is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document’s overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. a Secondary Section may not explain any mathematics. in the notice that says that the Document is released under this License. commercial. Any member of the public is a licensee.

clearly and legibly. For works in formats which do not have any title page as such. proprietary formats that can be read and edited only by proprietary word processors. SGML or XML for which the DTD and/or processing tools are not generally available. for a printed book. and you may publicly display copies.D. either commercially or noncommercially. Texinfo input format. and standard-conforming simple HTML designed for human modiﬁcation. PDF. SGML or XML using a publicly available DTD.
D. preceding the beginning of the body of the text. under the same conditions stated above. Opaque formats include PostScript. and the machine-generated HTML produced by some word processors for output purposes only. and the license notice saying this License applies to the Document are reproduced in all copies.
. the material this License requires to appear in the title page. If you distribute a large enough number of copies you must also follow the conditions in Section 3. The front cover must present the full title with all words of the title equally prominent and visible. and the Document’s license notice requires Cover Texts. You may also lend copies. you may accept compensation in exchange for copies.3
Copying in Quantity
If you publish printed copies of the Document numbering more than 100. The “Title Page” means. all these Cover Texts: Front-Cover Texts on the front cover. Copying with changes limited to the covers. as long as they preserve the title of the Document and satisfy these conditions.
D. L TEX input format.2 Verbatim Copying
243
Examples of suitable formats for Transparent copies include plain ASCII without A markup. However. can be treated as verbatim copying in other respects. provided that this License. plus such following pages as are needed to hold. Both covers must also clearly and legibly identify you as the publisher of these copies. You may add other material on the covers in addition. you must enclose the copies in covers that carry. “Title Page” means the text near the most prominent appearance of the work’s title. and Back-Cover Texts on the back cover. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. legibly. the copyright notices.2
Verbatim Copying
You may copy and distribute the Document in any medium. the title page itself. and that you add no other conditions whatsoever to those of this License.

but not required.4
Modiﬁcations
You may copy and distribute a Modiﬁed Version of the Document under the conditions of Sections 2 and 3 above. If you use the latter option. you must either include a machine-readable Transparent copy along with each Opaque copy. or state in or with each Opaque copy a publicly accessible computer-network location containing a complete Transparent copy of the Document. as authors. with the Modiﬁed Version ﬁlling the role of the Document. thus licensing distribution and modiﬁcation of the Modiﬁed Version to whoever possesses a copy of it. provided that you release the Modiﬁed Version under precisely this License. together with at least ﬁve of the principal authors of the Document (all of its principal authors. and from those of previous versions (which should.244
GNU Free Documentation License
If the required texts for either cover are too voluminous to ﬁt legibly.
D. You may use the same title as a previous version if the original publisher of that version gives permission. In addition. and continue the rest onto adjacent pages. be listed in the History section of the Document). when you begin distribution of Opaque copies in quantity. • State on the Title page the name of the publisher of the Modiﬁed Version. It is requested. which the general network-using public has access to download anonymously at no charge using public-standard network protocols. if any) a title distinct from that of the Document. free of added material. if there were any. to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public. to give them a chance to provide you with an updated version of the Document. you must take reasonably prudent steps. • List on the Title Page. you must do these things in the Modiﬁed Version: • Use in the Title Page (and on the covers. • Preserve all the copyright notices of the Document. as the publisher.
. one or more persons or entities responsible for authorship of the modiﬁcations in the Modiﬁed Version. if it has less than ﬁve). you should put the ﬁrst ones listed (as many as ﬁt reasonably) on the actual cover. If you publish or distribute Opaque copies of the Document numbering more than 100. that you contact the authors of the Document well before redistributing any large number of copies.

Section numbers or the equivalent are not considered part of the section titles. a license notice giving the public permission to use the Modiﬁed Version under the terms of this License. unaltered in their text and in their titles. • Include an unaltered copy of this License. then add an item describing the Modiﬁed Version as stated in the previous sentence. You may omit a network location for a work that was published at least four years before the Document itself.” Such a section may not be included in the Modiﬁed Version. • Preserve the network location. or if the original publisher of the version it refers to gives permission. authors.D. • Preserve the section entitled “History.” preserve the section’s title. immediately after the copyright notices. These may be placed in the “History” section.
. and publisher of the Modiﬁed Version as given on the Title Page. • Include. you may at your option designate some or all of these sections as invariant. new authors. • In any section entitled “Acknowledgements” or “Dedications. and add to it an item stating at least the title. and publisher of the Document as given on its Title Page. • Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document’s license notice. given in the Document for public access to a Transparent copy of the Document. create one stating the title. • Preserve all the Invariant Sections of the Document. • Delete any section entitled “Endorsements. If there is no section entitled “History” in the Document. if any. in the form shown in the Addendum below.4 Modiﬁcations
245
• Add an appropriate copyright notice for your modiﬁcations adjacent to the other copyright notices.” and its title. and likewise the network locations given in the Document for previous versions it was based on. and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein. If the Modiﬁed Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document. year. • Do not retitle any existing section as “Endorsements” or to conﬂict in title with any Invariant Section. year.

246
GNU Free Documentation License
To do this. unmodiﬁed. likewise combine any sections entitled “Acknowledgements.” provided it contains nothing but endorsements of your Modiﬁed Version by various parties—for example. You may add a passage of up to ﬁve words as a Front-Cover Text. previously added by you or by arrangement made by the same entity you are acting on behalf of. make the title of each such section unique by adding at the end of it. statements of peer review or that the text has been approved by an organization as the authoritative deﬁnition of a standard.” and any sections entitled “Dedications. These titles must be distinct from any other section titles. but you may replace the old one.5
Combining Documents
You may combine the Document with other documents released under this License. the name of the original author or publisher of that section if known.”
. you must combine any sections entitled “History” in the various original documents. or else a unique number.
D. You may add a section entitled “Endorsements. Only one passage of Front-Cover Text and one of BackCover Text may be added by (or through arrangements made by) any one entity. and a passage of up to 25 words as a Back-Cover Text. and list them all as Invariant Sections of your combined work in its license notice. If the Document already includes a cover text for the same cover.” You must delete all sections entitled “Endorsements. The combined work need only contain one copy of this License. in parentheses. you may not add another. forming one section entitled “History”. on explicit permission from the previous publisher that added the old one. and multiple identical Invariant Sections may be replaced with a single copy. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modiﬁed Version. provided that you include in the combination all of the Invariant Sections of all of the original documents. add their titles to the list of Invariant Sections in the Modiﬁed Version’s license notice. In the combination. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. to the end of the list of Cover Texts in the Modiﬁed Version. under the terms deﬁned in Section 4 above for modiﬁed versions. If there are multiple Invariant Sections with the same name but diﬀerent contents.

if they are not themselves derivative works of the Document.6 Collections of Documents
247
D.
. provided you insert a copy of this License into the extracted document.D. then if the Document is less than one quarter of the entire aggregate. You may extract a single document from such a collection. the original English version will prevail. You may include a translation of this License provided that you also include the original English version of this License. so you may distribute translations of the Document under the terms of Section 4.8
Translation
Translation is considered a kind of modiﬁcation. in or on a volume of a storage or distribution medium. provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. and replace the individual copies of this License in the various documents with a single copy that is included in the collection.6
Collections of Documents
You may make a collection consisting of the Document and other documents released under this License.
D. Otherwise they must appear on covers around the whole aggregate. on account of their being thus compiled. If the Cover Text requirement of Section 3 is applicable to these copies of the Document. Replacing Invariant Sections with translations requires special permission from their copyright holders. and follow this License in all other respects regarding verbatim copying of that document.” and this License does not apply to the other self-contained works thus compiled with the Document.
D. but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections.7
Aggregation with Independent Works
A compilation of the Document or its derivatives with other separate and independent documents or works. and distribute it individually under this License. the Document’s Cover Texts may be placed on covers that surround only the Document within the aggregate. In case of a disagreement between the translation and the original English version of this License. provided no compilation copyright is claimed for the compilation. Such a compilation is called an “aggregate. does not as a whole count as a Modiﬁed Version of the Document.

and will automatically terminate your rights under this License. revised versions of the GNU Free Documentation License from time to time. If the Document speciﬁes that a particular numbered version of this License ”or any later version” applies to it.org/copyleft/. with the Invariant Sections being LIST THEIR TITLES. Permission is granted to copy. from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
D. or rights.gnu. include a copy of the License in the document and put the following copyright and license notices just after the title page: Copyright c YEAR YOUR NAME. distribute and/or modify this document under the terms of the GNU Free Documentation License. A copy of the license is included in the section entitled “GNU Free Documentation License. parties who have received copies.”
. and with the Back-Cover Texts being LIST.11
Addendum: How to Use This License for Your Documents
To use this License in a document you have written. modify. you may choose any version ever published (not as a draft) by the Free Software Foundation.9
Termination
You may not copy. with the Front-Cover Texts being LIST. or distribute the Document except as expressly provided for under this License.
D.10
Future Revisions of This License
The Free Software Foundation may publish new. you have the option of following the terms and conditions either of that speciﬁed version or of any later version that has been published (not as a draft) by the Free Software Foundation. or distribute the Document is void. Version 1. Each version of the License is given a distinguishing version number. but may diﬀer in detail to address new problems or concerns. Such new versions will be similar in spirit to the present version.1 or any later version published by the Free Software Foundation. See http:///www. Any other attempt to copy. sublicense.248
GNU Free Documentation License
D. sublicense. modify. However. If the Document does not specify a version number of this License.

likewise for Back-Cover Texts.D. write “no Front-Cover Texts” instead of “Front-Cover Texts being LIST”. write “with no Invariant Sections” instead of saying which ones are invariant. If you have no Front-Cover Texts.
. such as the GNU General Public License. If your document contains nontrivial examples of program code. we recommend releasing these examples in parallel under your choice of free software license. to permit their use in free software.11 Addendum: How to Use This License for Your Documents 249 If you have no Invariant Sections.