diff --git a/book/book.tex b/book/book.tex index 9e0368e..74e9278 100644 --- a/book/book.tex +++ b/book/book.tex @@ -28,7 +28,8 @@ \usepackage{upquote} \usepackage{appendix} \usepackage[bookmarks]{hyperref} - +\usepackage{listings} +\usepackage{color} \title{Think Python} \author{Allen B. Downey} \newcommand{\thetitle}{Think Python: How to Think Like a Computer Scientist} @@ -880,7 +881,7 @@ \section{Running Python} Now you're ready to get started. From here on, I assume that you know how to start the Python interpreter and run code. - +\input{codecolor} \section{The first program} \label{hello} @@ -890,17 +891,17 @@ \section{The first program} is called ``Hello, World!'' because all it does is display the words ``Hello, World!''. In Python, it looks like this: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> print('Hello, World!') -\end{verbatim} +\end{lstlisting} % This is an example of a {\bf print statement}, although it doesn't actually print anything on paper. It displays a result on the screen. In this case, the result is the words -\begin{verbatim} +\begin{lstlisting}[language=python] Hello, World! -\end{verbatim} +\end{lstlisting} % The quotation marks in the program mark the beginning and end of the text to be displayed; they don't appear in the result. @@ -916,9 +917,9 @@ \section{The first program} a function, so it doesn't use parentheses. \index{Python 2} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> print 'Hello, World!' -\end{verbatim} +\end{lstlisting} % This distinction will make more sense soon, but that's enough to get started. @@ -935,21 +936,21 @@ \section{Arithmetic operators} The operators {\tt +}, {\tt -}, and {\tt *} perform addition, subtraction, and multiplication, as in the following examples: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> 40 + 2 42 >>> 43 - 1 42 >>> 6 * 7 42 -\end{verbatim} +\end{lstlisting} % The operator {\tt /} performs division: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> 84 / 2 42.0 -\end{verbatim} +\end{lstlisting} % You might wonder why the result is {\tt 42.0} instead of {\tt 42}. I'll explain in the next section. @@ -957,19 +958,19 @@ \section{Arithmetic operators} Finally, the operator {\tt **} performs exponentiation; that is, it raises a number to a power: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> 6**2 + 6 42 -\end{verbatim} +\end{lstlisting} % In some other languages, \verb"^" is used for exponentiation, but in Python it is a bitwise operator called XOR. If you are not familiar with bitwise operators, the result will surprise you: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> 6 ^ 2 4 -\end{verbatim} +\end{lstlisting} % I won't cover bitwise operators in this book, but you can read about @@ -997,14 +998,14 @@ \section{Values and types} If you are not sure what type a value has, the interpreter can tell you: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> type(2) >>> type(42.0) >>> type('Hello, World!') -\end{verbatim} +\end{lstlisting} % In these results, the word ``class'' is used in the sense of a category; a type is a category of values. @@ -1026,12 +1027,12 @@ \section{Values and types} strings. \index{quotation mark} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> type('2') >>> type('42.0') -\end{verbatim} +\end{lstlisting} % They're strings. @@ -1039,10 +1040,10 @@ \section{Values and types} between groups of digits, as in {\tt 1,000,000}. This is not a legal {\em integer} in Python, but it is legal: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> 1,000,000 (1, 0, 0) -\end{verbatim} +\end{lstlisting} % That's not what we expected at all! Python interprets {\tt 1,000,000} as a comma-separated sequence of integers. We'll learn @@ -1388,11 +1389,11 @@ \section{Assignment statements} An {\bf assignment statement} creates a new variable and gives it a value: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> message = 'And now for something completely different' >>> n = 17 >>> pi = 3.1415926535897932 -\end{verbatim} +\end{lstlisting} % This example makes three assignments. The first assigns a string to a new variable named {\tt message}; @@ -1434,14 +1435,14 @@ \section{Variable names} If you give a variable an illegal name, you get a syntax error: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> 76trombones = 'big parade' SyntaxError: invalid syntax >>> more@ = 1000000 SyntaxError: invalid syntax >>> class = 'Advanced Theoretical Zymurgy' SyntaxError: invalid syntax -\end{verbatim} +\end{lstlisting} % {\tt 76trombones} is illegal because it begins with a number. {\tt more@} is illegal because it contains an illegal character, {\tt @@ -1454,6 +1455,7 @@ \section{Variable names} Python 3 has these keywords: +\color{pybrown}{ \begin{verbatim} False class finally is return None continue for lambda try @@ -1462,7 +1464,7 @@ \section{Variable names} as elif if or yield assert else import pass break except in raise -\end{verbatim} +\end{verbatim}}\color{black}{} % You don't have to memorize this list. In most development environments, keywords are displayed in a different color; if you try to use one @@ -1476,14 +1478,14 @@ \section{Expressions and statements} a variable, so the following are all legal expressions: \index{expression} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> 42 42 >>> n 17 >>> n + 25 42 -\end{verbatim} +\end{lstlisting} % When you type an expression at the prompt, the interpreter {\bf evaluates} it, which means that it finds the value of @@ -1496,10 +1498,10 @@ \section{Expressions and statements} creating a variable or displaying a value. \index{statement} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> n = 17 >>> print(n) -\end{verbatim} +\end{lstlisting} % The first line is an assignment statement that gives a value to {\tt n}. The second line is a print statement that displays the @@ -1540,11 +1542,11 @@ \section{Script mode} For example, if you are using Python as a calculator, you might type -\begin{verbatim} +\begin{lstlisting}[language=python] >>> miles = 26.2 >>> miles * 1.61 42.182 -\end{verbatim} +\end{lstlisting} The first line assigns a value to {\tt miles}, but it has no visible effect. The second line is an expression, so the @@ -1558,20 +1560,20 @@ \section{Script mode} display the result. To display the result, you need a {\tt print} statement like this: -\begin{verbatim} +\begin{lstlisting}[language=python] miles = 26.2 print(miles * 1.61) -\end{verbatim} +\end{lstlisting} This behavior can be confusing at first. To check your understanding, type the following statements in the Python interpreter and see what they do: -\begin{verbatim} +\begin{lstlisting}[language=python] 5 x = 5 x + 1 -\end{verbatim} +\end{lstlisting} Now put the same statements in a script and run it. What is the output? Modify the script by transforming each @@ -1624,9 +1626,9 @@ \section{String operations} In general, you can't perform mathematical operations on strings, even if the strings look like numbers, so the following are illegal: -\begin{verbatim} +\begin{lstlisting}[language=python] 'chinese'-'food' 'eggs'/'easy' 'third'*'a charm' -\end{verbatim} +\end{lstlisting} % But there are two exceptions, {\tt +} and {\tt *}. @@ -1634,12 +1636,12 @@ \section{String operations} it joins the strings by linking them end-to-end. For example: \index{concatenation} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> first = 'throat' >>> second = 'warbler' >>> first + second throatwarbler -\end{verbatim} +\end{lstlisting} % The {\tt *} operator also works on strings; it performs repetition. For example, \verb"'Spam'*3" is \verb"'SpamSpamSpam'". If one of the @@ -1667,17 +1669,17 @@ \section{Comments} in natural language what the program is doing. These notes are called {\bf comments}, and they start with the \verb"#" symbol: -\begin{verbatim} +\begin{lstlisting}[language=python] # compute the percentage of the hour that has elapsed percentage = (minute * 100) / 60 -\end{verbatim} +\end{lstlisting} % In this case, the comment appears on a line by itself. You can also put comments at the end of a line: -\begin{verbatim} +\begin{lstlisting}[language=python] percentage = (minute * 100) / 60 # percentage of an hour -\end{verbatim} +\end{lstlisting} % Everything from the {\tt \#} to the end of the line is ignored---it has no effect on the execution of the program. @@ -1688,15 +1690,15 @@ \section{Comments} This comment is redundant with the code and useless: -\begin{verbatim} +\begin{lstlisting}[language=python] v = 5 # assign 5 to v -\end{verbatim} +\end{lstlisting} % This comment contains useful information that is not in the code: -\begin{verbatim} +\begin{lstlisting}[language=python] v = 5 # velocity in meters/second. -\end{verbatim} +\end{lstlisting} % Good variable names can reduce the need for comments, but long names can make complex expressions hard to read, so there is @@ -1896,7 +1898,7 @@ \section{Function calls} We have already seen one example of a {\bf function call}: \begin{verbatim} ->>> type(42) +>>> type(42) \end{verbatim} % @@ -1918,45 +1920,45 @@ \section{Function calls} \index{int function} \index{function!int} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> int('32') 32 >>> int('Hello') -ValueError: invalid literal for int(): Hello -\end{verbatim} +<@\textcolor{black}{ValueError: invalid literal for int(): Hello}@> +\end{lstlisting} % {\tt int} can convert floating-point values to integers, but it doesn't round off; it chops off the fraction part: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> int(3.99999) 3 >>> int(-2.3) -2 -\end{verbatim} +\end{lstlisting} % {\tt float} converts integers and strings to floating-point numbers: \index{float function} \index{function!float} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> float(32) 32.0 >>> float('3.14159') 3.14159 -\end{verbatim} +\end{lstlisting} % Finally, {\tt str} converts its argument to a string: \index{str function} \index{function!str} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> str(32) '32' >>> str(3.14159) '3.14159' -\end{verbatim} +\end{lstlisting} % \section{Math functions} @@ -1972,9 +1974,9 @@ \section{Math functions} Before we can use the functions in a module, we have to import it with an {\bf import statement}: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> import math -\end{verbatim} +\end{lstlisting} % This statement creates a {\bf module object} named math. If you display the module object, you get some information about it: @@ -1990,13 +1992,13 @@ \section{Math functions} known as a period). This format is called {\bf dot notation}. \index{dot notation} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> ratio = signal_power / noise_power >>> decibels = 10 * math.log10(ratio) >>> radians = 0.7 >>> height = math.sin(radians) -\end{verbatim} +\end{lstlisting} % The first example uses \verb"math.log10" to compute a signal-to-noise ratio in decibels (assuming that \verb"signal_power" and @@ -2014,12 +2016,12 @@ \section{Math functions} convert from degrees to radians, divide by 180 and multiply by $\pi$: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> degrees = 45 >>> radians = degrees / 180.0 * math.pi >>> math.sin(radians) 0.707106781187 -\end{verbatim} +\end{lstlisting} % The expression {\tt math.pi} gets the variable {\tt pi} from the math module. Its value is a floating-point approximation @@ -2032,10 +2034,10 @@ \section{Math functions} \index{sqrt function} \index{function!sqrt} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> math.sqrt(2) / 2.0 0.707106781187 -\end{verbatim} +\end{lstlisting} % \section{Composition} @@ -2050,15 +2052,15 @@ \section{Composition} example, the argument of a function can be any kind of expression, including arithmetic operators: -\begin{verbatim} +\begin{lstlisting}[language=python] x = math.sin(degrees / 360.0 * 2 * math.pi) -\end{verbatim} +\end{lstlisting} % And even function calls: -\begin{verbatim} +\begin{lstlisting}[language=python] x = math.exp(math.log(x+1)) -\end{verbatim} +\end{lstlisting} % Almost anywhere you can put a value, you can put an arbitrary expression, with one exception: the left side of an assignment @@ -2066,11 +2068,11 @@ \section{Composition} side is a syntax error (we will see exceptions to this rule later). -\begin{verbatim} +\begin{lstlisting}[language=python] >>> minutes = hours * 60 # right >>> hours * 60 = minutes # wrong! -SyntaxError: can't assign to operator -\end{verbatim} +<@\textcolor{black}{SyntaxError: can't assign to operator}@> +\end{lstlisting} % \index{SyntaxError} \index{exception!SyntaxError} @@ -2088,11 +2090,11 @@ \section{Adding new functions} Here is an example: -\begin{verbatim} +\begin{lstlisting}[language=python] def print_lyrics(): print("I'm a lumberjack, and I'm okay.") print("I sleep all night and I work all day.") -\end{verbatim} +\end{lstlisting} % {\tt def} is a keyword that indicates that this is a function definition. The name of the function is \verb"print_lyrics". The @@ -2134,12 +2136,12 @@ \section{Adding new functions} isn't complete: \index{ellipses} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> def print_lyrics(): ... print("I'm a lumberjack, and I'm okay.") ... print("I sleep all night and I work all day.") ... -\end{verbatim} +\end{lstlisting} % To end the function, you have to enter an empty line. @@ -2148,12 +2150,12 @@ \section{Adding new functions} \index{function type} \index{type!function} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> print(print_lyrics) >>> type(print_lyrics) - -\end{verbatim} +<@\textcolor{black}{}@> +\end{lstlisting} % The syntax for calling the new function is the same as for built-in functions: @@ -2168,11 +2170,11 @@ \section{Adding new functions} function. For example, to repeat the previous refrain, we could write a function called \verb"repeat_lyrics": -\begin{verbatim} +\begin{lstlisting}[language=python] def repeat_lyrics(): print_lyrics() print_lyrics() -\end{verbatim} +\end{lstlisting} % And then call \verb"repeat_lyrics": @@ -2193,7 +2195,7 @@ \section{Definitions and uses} Pulling together the code fragments from the previous section, the whole program looks like this: -\begin{verbatim} +\begin{lstlisting}[language=python] def print_lyrics(): print("I'm a lumberjack, and I'm okay.") print("I sleep all night and I work all day.") @@ -2203,7 +2205,7 @@ \section{Definitions and uses} print_lyrics() repeat_lyrics() -\end{verbatim} +\end{lstlisting} % This program contains two function definitions: \verb"print_lyrics" and \verb"repeat_lyrics". Function definitions get executed just like other @@ -2278,11 +2280,11 @@ \section{Parameters and arguments} a function that takes an argument: \index{parentheses!parameters in} -\begin{verbatim} +\begin{lstlisting}[language=python] def print_twice(bruce): print(bruce) print(bruce) -\end{verbatim} +\end{lstlisting} % This function assigns the argument to a parameter named {\tt bruce}. When the function is called, it prints the value of @@ -2290,7 +2292,7 @@ \section{Parameters and arguments} This function works with any value that can be printed. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> print_twice('Spam') Spam Spam @@ -2300,7 +2302,7 @@ \section{Parameters and arguments} >>> print_twice(math.pi) 3.14159265359 3.14159265359 -\end{verbatim} +\end{lstlisting} % The same rules of composition that apply to built-in functions also apply to programmer-defined functions, so we can use any kind of expression @@ -2309,14 +2311,14 @@ \section{Parameters and arguments} \index{programmer-defined function} \index{function!programmer defined} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> print_twice('Spam '*4) Spam Spam Spam Spam Spam Spam Spam Spam >>> print_twice(math.cos(math.pi)) -1.0 -1.0 -\end{verbatim} +\end{lstlisting} % The argument is evaluated before the function is called, so in the examples the expressions \verb"'Spam '*4" and @@ -2325,12 +2327,12 @@ \section{Parameters and arguments} You can also use a variable as an argument: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> michael = 'Eric, the half a bee.' >>> print_twice(michael) Eric, the half a bee. Eric, the half a bee. -\end{verbatim} +\end{lstlisting} % The name of the variable we pass as an argument ({\tt michael}) has nothing to do with the name of the parameter ({\tt bruce}). It @@ -2347,33 +2349,33 @@ \section{Variables and parameters are local} exists inside the function. For example: \index{parentheses!parameters in} -\begin{verbatim} +\begin{lstlisting}[language=python] def cat_twice(part1, part2): cat = part1 + part2 print_twice(cat) -\end{verbatim} +\end{lstlisting} % This function takes two arguments, concatenates them, and prints the result twice. Here is an example that uses it: \index{concatenation} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> line1 = 'Bing tiddle ' >>> line2 = 'tiddle bang.' >>> cat_twice(line1, line2) Bing tiddle tiddle bang. Bing tiddle tiddle bang. -\end{verbatim} +\end{lstlisting} % When \verb"cat_twice" terminates, the variable {\tt cat} is destroyed. If we try to print it, we get an exception: \index{NameError} \index{exception!NameError} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> print(cat) -NameError: name 'cat' is not defined -\end{verbatim} +<@\textcolor{black}{}NameError: name 'cat' is not defined}@> +\end{lstlisting} % Parameters are also local. For example, outside \verb"print_twice", there is no @@ -2467,25 +2469,25 @@ \section{Fruitful functions and void functions} want to do something with the result; for example, you might assign it to a variable or use it as part of an expression: -\begin{verbatim} +\begin{lstlisting}[language=python] x = math.cos(radians) golden = (math.sqrt(5) + 1) / 2 -\end{verbatim} +\end{lstlisting} % When you call a function in interactive mode, Python displays the result: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> math.sqrt(5) 2.2360679774997898 -\end{verbatim} +\end{lstlisting} % But in a script, if you call a fruitful function all by itself, the return value is lost forever! -\begin{verbatim} +\begin{lstlisting}[language=python] math.sqrt(5) -\end{verbatim} +\end{lstlisting} % This script computes the square root of 5, but since it doesn't store or display the result, it is not very useful. @@ -2499,21 +2501,21 @@ \section{Fruitful functions and void functions} \index{None special value} \index{special value!None} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> result = print_twice('Bing') Bing Bing >>> print(result) None -\end{verbatim} +\end{lstlisting} % The value {\tt None} is not the same as the string \verb"'None'". It is a special value that has its own type: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> type(None) - -\end{verbatim} +<@\textcolor{black}{}@> +\end{lstlisting} % The functions we have written so far are all void. We will start writing fruitful functions in a few chapters. @@ -2692,11 +2694,11 @@ \section{Exercises} named {\tt s} as a parameter and prints the string with enough leading spaces so that the last letter of the string is in column 70 of the display. - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] >>> right_justify('monty') monty -\end{verbatim} +\end{lstlisting}} Hint: Use string concatenation and repetition. Also, Python provides a built-in function called {\tt len} that @@ -2712,22 +2714,22 @@ \section{Exercises} A function object is a value you can assign to a variable or pass as an argument. For example, \verb"do_twice" is a function that takes a function object as an argument and calls it twice: - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] def do_twice(f): f() f() -\end{verbatim} +\end{lstlisting}} Here's an example that uses \verb"do_twice" to call a function named \verb"print_spam" twice. - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] def print_spam(): print('spam') do_twice(print_spam) -\end{verbatim} +\end{lstlisting}} \begin{enumerate} @@ -2767,8 +2769,8 @@ \section{Exercises} \item Write a function that draws a grid like the following: \index{grid} - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] + - - - - + - - - - + | | | | | | @@ -2780,22 +2782,22 @@ \section{Exercises} | | | | | | + - - - - + - - - - + -\end{verbatim} +\end{lstlisting}} % Hint: to print more than one value on a line, you can print a comma-separated sequence of values: - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] print('+', '-') -\end{verbatim} +\end{lstlisting}} % By default, {\tt print} advances to the next line, but you can override that behavior and put a space at the end, like this: - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] print('+', end=' ') print('-') -\end{verbatim} +\end{lstlisting}} % The output of these statements is \verb"'+ -'" on the same line. The output from the next print statement would begin on the next line. @@ -2842,10 +2844,10 @@ \section{The turtle module} To check whether you have the {\tt turtle} module, open the Python interpreter and type -\begin{verbatim} +\begin{lstlisting}[language=python] >>> import turtle >>> bob = turtle.Turtle() -\end{verbatim} +\end{lstlisting} When you run this code, it should create a new window with small arrow that represents the turtle. Close the window. @@ -2853,21 +2855,21 @@ \section{The turtle module} Create a file named {\tt mypolygon.py} and type in the following code: -\begin{verbatim} +\begin{lstlisting}[language=python] import turtle bob = turtle.Turtle() print(bob) turtle.mainloop() -\end{verbatim} +\end{lstlisting} % The {\tt turtle} module (with a lowercase 't') provides a function called {\tt Turtle} (with an uppercase 'T') that creates a Turtle object, which we assign to a variable named {\tt bob}. Printing {\tt bob} displays something like: -\begin{verbatim} +\begin{lstlisting}[language=python] -\end{verbatim} +\end{lstlisting} % This means that {\tt bob} refers to an object with type {\tt Turtle} @@ -2882,9 +2884,9 @@ \section{The turtle module} uses slightly different syntax. For example, to move the turtle forward: -\begin{verbatim} +\begin{lstlisting}[language=python] bob.fd(100) -\end{verbatim} +\end{lstlisting} % The method, {\tt fd}, is associated with the turtle object we're calling {\tt bob}. @@ -2906,11 +2908,11 @@ \section{The turtle module} To draw a right angle, add these lines to the program (after creating {\tt bob} and before calling \verb"mainloop"): -\begin{verbatim} +\begin{lstlisting}[language=python] bob.fd(100) bob.lt(90) bob.fd(100) -\end{verbatim} +\end{lstlisting} % When you run this program, you should see {\tt bob} move east and then north, leaving two line segments behind. @@ -2926,7 +2928,7 @@ \section{Simple repetition} Chances are you wrote something like this: -\begin{verbatim} +\begin{lstlisting}[language=python] bob.fd(100) bob.lt(90) @@ -2937,7 +2939,7 @@ \section{Simple repetition} bob.lt(90) bob.fd(100) -\end{verbatim} +\end{lstlisting} % We can do the same thing more concisely with a {\tt for} statement. Add this example to {\tt mypolygon.py} and run it again: @@ -2945,19 +2947,19 @@ \section{Simple repetition} \index{loop!for} \index{statement!for} -\begin{verbatim} +\begin{lstlisting}[language=python] for i in range(4): print('Hello!') -\end{verbatim} +\end{lstlisting} % You should see something like this: -\begin{verbatim} +\begin{lstlisting}[language=python] Hello! Hello! Hello! Hello! -\end{verbatim} +\end{lstlisting} % This is the simplest use of the {\tt for} statement; we will see more later. But that should be enough to let you rewrite your @@ -2965,11 +2967,11 @@ \section{Simple repetition} Here is a {\tt for} statement that draws a square: -\begin{verbatim} +\begin{lstlisting}[language=python] for i in range(4): bob.fd(100) bob.lt(90) -\end{verbatim} +\end{lstlisting} % The syntax of a {\tt for} statement is similar to a function definition. It has a header that ends with a colon and an indented @@ -3044,14 +3046,14 @@ \section{Encapsulation} into a function definition and then call the function, passing the turtle as a parameter. Here is a solution: -\begin{verbatim} +\begin{lstlisting}[language=python] def square(t): for i in range(4): t.fd(100) t.lt(90) square(bob) -\end{verbatim} +\end{lstlisting} % The innermost statements, {\tt fd} and {\tt lt} are indented twice to show that they are inside the {\tt for} loop, which is inside the @@ -3066,10 +3068,10 @@ \section{Encapsulation} turtle, not just {\tt bob}, so you could create a second turtle and pass it as an argument to {\tt square}: -\begin{verbatim} +\begin{lstlisting}[language=python] alice = turtle.Turtle() square(alice) -\end{verbatim} +\end{lstlisting} % Wrapping a piece of code up in a function is called {\bf encapsulation}. One of the benefits of encapsulation is that it @@ -3084,14 +3086,14 @@ \section{Generalization} The next step is to add a {\tt length} parameter to {\tt square}. Here is a solution: -\begin{verbatim} +\begin{lstlisting}[language=python] def square(t, length): for i in range(4): t.fd(length) t.lt(90) square(bob, 100) -\end{verbatim} +\end{lstlisting} % Adding a parameter to a function is called {\bf generalization} because it makes the function more general: in the previous @@ -3103,7 +3105,7 @@ \section{Generalization} squares, {\tt polygon} draws regular polygons with any number of sides. Here is a solution: -\begin{verbatim} +\begin{lstlisting}[language=python] def polygon(t, n, length): angle = 360 / n for i in range(n): @@ -3111,7 +3113,7 @@ \section{Generalization} t.lt(angle) polygon(bob, 7, 70) -\end{verbatim} +\end{lstlisting} % This example draws a 7-sided polygon with side length 70. @@ -3126,9 +3128,9 @@ \section{Generalization} it is often a good idea to include the names of the parameters in the argument list: -\begin{verbatim} +\begin{lstlisting}[language=python] polygon(bob, n=7, length=70) -\end{verbatim} +\end{lstlisting} % These are called {\bf keyword arguments} because they include the parameter names as ``keywords'' (not to be confused with @@ -3147,7 +3149,7 @@ \section{Interface design} {\tt r}, as a parameter. Here is a simple solution that uses {\tt polygon} to draw a 50-sided polygon: -\begin{verbatim} +\begin{lstlisting}[language=python] import math def circle(t, r): @@ -3155,7 +3157,7 @@ \section{Interface design} n = 50 length = circumference / n polygon(t, n, length) -\end{verbatim} +\end{lstlisting} % The first line computes the circumference of a circle with radius {\tt r} using the formula $2 \pi r$. Since we use {\tt math.pi}, we @@ -3188,13 +3190,13 @@ \section{Interface design} to choose an appropriate value of {\tt n} depending on {\tt circumference}: -\begin{verbatim} +\begin{lstlisting}[language=python] def circle(t, r): circumference = 2 * math.pi * r n = int(circumference / 3) + 3 length = circumference / n polygon(t, n, length) -\end{verbatim} +\end{lstlisting} % Now the number of segments is an integer near {\tt circumference/3}, so the length of each segment is approximately 3, which is small @@ -3217,7 +3219,7 @@ \section{Refactoring} of {\tt polygon} and transform it into {\tt arc}. The result might look like this: -\begin{verbatim} +\begin{lstlisting}[language=python] def arc(t, r, angle): arc_length = 2 * math.pi * r * angle / 360 n = int(arc_length / 3) + 1 @@ -3227,7 +3229,7 @@ \section{Refactoring} for i in range(n): t.fd(step_length) t.lt(step_angle) -\end{verbatim} +\end{lstlisting} % The second half of this function looks like {\tt polygon}, but we can't re-use {\tt polygon} without changing the interface. We could @@ -3235,16 +3237,16 @@ \section{Refactoring} but then {\tt polygon} would no longer be an appropriate name! Instead, let's call the more general function {\tt polyline}: -\begin{verbatim} +\begin{lstlisting}[language=python] def polyline(t, n, length, angle): for i in range(n): t.fd(length) t.lt(angle) -\end{verbatim} +\end{lstlisting} % Now we can rewrite {\tt polygon} and {\tt arc} to use {\tt polyline}: -\begin{verbatim} +\begin{lstlisting}[language=python] def polygon(t, n, length): angle = 360.0 / n polyline(t, n, length, angle) @@ -3255,14 +3257,14 @@ \section{Refactoring} step_length = arc_length / n step_angle = float(angle) / n polyline(t, n, step_length, step_angle) -\end{verbatim} +\end{lstlisting} % Finally, we can rewrite {\tt circle} to use {\tt arc}: -\begin{verbatim} +\begin{lstlisting}[language=python] def circle(t, r): arc(t, r, 360) -\end{verbatim} +\end{lstlisting} % This process---rearranging a program to improve interfaces and facilitate code re-use---is called {\bf refactoring}. @@ -3316,7 +3318,7 @@ \section{docstring} explains the interface (``doc'' is short for ``documentation''). Here is an example: -\begin{verbatim} +\begin{lstlisting}[language=python] def polyline(t, n, length, angle): """Draws n line segments with the given length and angle (in degrees) between them. t is a turtle. @@ -3324,7 +3326,7 @@ \section{docstring} for i in range(n): t.fd(length) t.lt(angle) -\end{verbatim} +\end{lstlisting} % By convention, all docstrings are triple-quoted strings, also known as multiline strings because the triple quotes allow the string @@ -3541,29 +3543,29 @@ \section{Floor division and modulus} long that is in hours. Conventional division returns a floating-point number: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> minutes = 105 >>> minutes / 60 1.75 -\end{verbatim} +\end{lstlisting} But we don't normally write hours with decimal points. Floor division returns the integer number of hours, rounding down: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> minutes = 105 >>> hours = minutes // 60 >>> hours 1 -\end{verbatim} +\end{lstlisting} To get the remainder, you could subtract off one hour in minutes: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> remainder = minutes - hours * 60 >>> remainder 45 -\end{verbatim} +\end{lstlisting} \index{floor division} \index{floating-point division} @@ -3575,11 +3577,11 @@ \section{Floor division and modulus} An alternative is to use the {\bf modulus operator}, \verb"%", which divides two numbers and returns the remainder. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> remainder = minutes % 60 >>> remainder 45 -\end{verbatim} +\end{lstlisting} % The modulus operator is more useful than it seems. For example, you can check whether one number is divisible by another---if @@ -3609,12 +3611,12 @@ \section{Boolean expressions} operator {\tt ==}, which compares two operands and produces {\tt True} if they are equal and {\tt False} otherwise: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> 5 == 5 True >>> 5 == 6 False -\end{verbatim} +\end{lstlisting} % {\tt True} and {\tt False} are special values that belong to the type {\tt bool}; they are not strings: @@ -3625,23 +3627,23 @@ \section{Boolean expressions} \index{bool type} \index{type!bool} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> type(True) - +<@\textcolor{black}{}@> >>> type(False) - -\end{verbatim} +<@\textcolor{black}{}@> +\end{lstlisting} % The {\tt ==} operator is one of the {\bf relational operators}; the others are: -\begin{verbatim} +\begin{lstlisting}[language=python] x != y # x is not equal to y x > y # x is greater than y x < y # x is less than y x >= y # x is greater than or equal to y x <= y # x is less than or equal to y -\end{verbatim} +\end{lstlisting} % Although these operations are probably familiar to you, the Python symbols are different from the mathematical symbols. A common error @@ -3681,10 +3683,10 @@ \section{Boolean expressions} boolean expressions, but Python is not very strict. Any nonzero number is interpreted as {\tt True}: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> 42 and True True -\end{verbatim} +\end{lstlisting} % This flexibility can be useful, but there are some subtleties to it that might be confusing. You might want to avoid it (unless @@ -3704,10 +3706,10 @@ \section{Conditional execution} accordingly. {\bf Conditional statements} give us this ability. The simplest form is the {\tt if} statement: -\begin{verbatim} +\begin{lstlisting}[language=python] if x > 0: print('x is positive') -\end{verbatim} +\end{lstlisting} % The boolean expression after {\tt if} is called the {\bf condition}. If it is true, the indented @@ -3728,10 +3730,10 @@ \section{Conditional execution} \index{pass statement} \index{statement!pass} -\begin{verbatim} +\begin{lstlisting}[language=python] if x < 0: pass # TODO: need to handle negative values! -\end{verbatim} +\end{lstlisting} % \section{Alternative execution} @@ -3744,12 +3746,12 @@ \section{Alternative execution} in which there are two possibilities and the condition determines which one runs. The syntax looks like this: -\begin{verbatim} +\begin{lstlisting}[language=python] if x % 2 == 0: print('x is even') else: print('x is odd') -\end{verbatim} +\end{lstlisting} % If the remainder when {\tt x} is divided by 2 is 0, then we know that {\tt x} is even, and the program displays an appropriate message. If @@ -3769,14 +3771,14 @@ \section{Chained conditionals} two branches. One way to express a computation like that is a {\bf chained conditional}: -\begin{verbatim} +\begin{lstlisting}[language=python] if x < y: print('x is less than y') elif x > y: print('x is greater than y') else: print('x and y are equal') -\end{verbatim} +\end{lstlisting} % {\tt elif} is an abbreviation of ``else if''. Again, exactly one branch will run. There is no limit on the number of {\tt @@ -3785,14 +3787,14 @@ \section{Chained conditionals} \index{elif keyword} \index{keyword!elif} -\begin{verbatim} +\begin{lstlisting}[language=python] if choice == 'a': draw_a() elif choice == 'b': draw_b() elif choice == 'c': draw_c() -\end{verbatim} +\end{lstlisting} % Each condition is checked in order. If the first is false, the next is checked, and so on. If one of them is @@ -3808,7 +3810,7 @@ \section{Nested conditionals} One conditional can also be nested within another. We could have written the example in the previous section like this: -\begin{verbatim} +\begin{lstlisting}[language=python] if x == y: print('x and y are equal') else: @@ -3816,7 +3818,7 @@ \section{Nested conditionals} print('x is less than y') else: print('x is greater than y') -\end{verbatim} +\end{lstlisting} % The outer conditional contains two branches. The first branch contains a simple statement. The second branch @@ -3832,26 +3834,26 @@ \section{Nested conditionals} statements. For example, we can rewrite the following code using a single conditional: -\begin{verbatim} +\begin{lstlisting}[language=python] if 0 < x: if x < 10: print('x is a positive single-digit number.') -\end{verbatim} +\end{lstlisting} % The {\tt print} statement runs only if we make it past both conditionals, so we can get the same effect with the {\tt and} operator: -\begin{verbatim} +\begin{lstlisting}[language=python] if 0 < x and x < 10: print('x is a positive single-digit number.') -\end{verbatim} +\end{lstlisting} For this kind of condition, Python provides a more concise option: -\begin{verbatim} +\begin{lstlisting}[language=python] if 0 < x < 10: print('x is a positive single-digit number.') -\end{verbatim} +\end{lstlisting} \section{Recursion} @@ -3864,14 +3866,14 @@ \section{Recursion} magical things a program can do. For example, look at the following function: -\begin{verbatim} +\begin{lstlisting}[language=python] def countdown(n): if n <= 0: print('Blastoff!') else: print(n) countdown(n-1) -\end{verbatim} +\end{lstlisting} % If {\tt n} is 0 or negative, it outputs the word, ``Blastoff!'' Otherwise, it outputs {\tt n} and then calls a function named {\tt @@ -3879,9 +3881,9 @@ \section{Recursion} What happens if we call this function like this? -\begin{verbatim} +\begin{lstlisting}[language=python] >>> countdown(3) -\end{verbatim} +\end{lstlisting} % The execution of {\tt countdown} begins with {\tt n=3}, and since {\tt n} is greater than 0, it outputs the value 3, and then calls itself... @@ -3912,12 +3914,12 @@ \section{Recursion} total output looks like this: \index{main} -\begin{verbatim} +\begin{lstlisting}[language=python] 3 2 1 Blastoff! -\end{verbatim} +\end{lstlisting} % A function that calls itself is {\bf recursive}; the process of executing it is called {\bf recursion}. @@ -3927,13 +3929,13 @@ \section{Recursion} As another example, we can write a function that prints a string {\tt n} times. -\begin{verbatim} +\begin{lstlisting}[language=python] def print_n(s, n): if n <= 0: return print(s) print_n(s, n-1) -\end{verbatim} +\end{lstlisting} % If {\tt n <= 0} the {\bf return statement} exits the function. The flow of execution immediately returns to the caller, and the remaining @@ -4010,10 +4012,10 @@ \section{Infinite recursion} known as {\bf infinite recursion}, and it is generally not a good idea. Here is a minimal program with an infinite recursion: -\begin{verbatim} +\begin{lstlisting}[language=python] def recurse(): recurse() -\end{verbatim} +\end{lstlisting} % In most programming environments, a program with infinite recursion does not really run forever. Python reports an error @@ -4021,7 +4023,7 @@ \section{Infinite recursion} \index{exception!RuntimeError} \index{RuntimeError} -\begin{verbatim} +\begin{lstlisting}[language=python] File "", line 2, in recurse File "", line 2, in recurse File "", line 2, in recurse @@ -4030,7 +4032,7 @@ \section{Infinite recursion} . File "", line 2, in recurse RuntimeError: Maximum recursion depth exceeded -\end{verbatim} +\end{lstlisting} % This traceback is a little bigger than the one we saw in the previous chapter. When the error occurs, there are 1000 @@ -4058,25 +4060,25 @@ \section{Keyboard input} \index{input function} \index{function!input} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> text = input() -What are you waiting for? +<@\textcolor{black}{What are you waiting for?}@> >>> text 'What are you waiting for?' -\end{verbatim} +\end{lstlisting} % Before getting input from the user, it is a good idea to print a prompt telling the user what to type. \verb"input" can take a prompt as an argument: \index{prompt} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> name = input('What...is your name?\n') -What...is your name? +<@\textcolor{black}{What...is your name?}@> Arthur, King of the Britons! >>> name 'Arthur, King of the Britons!' -\end{verbatim} +\end{lstlisting} % The sequence \verb"\n" at the end of the prompt represents a {\bf newline}, which is a special character that causes a line break. @@ -4085,25 +4087,25 @@ \section{Keyboard input} If you expect the user to type an integer, you can try to convert the return value to {\tt int}: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> prompt = 'What...is the airspeed velocity of an unladen swallow?\n' >>> speed = input(prompt) -What...is the airspeed velocity of an unladen swallow? +<@\textcolor{black}{What...is the airspeed velocity of an unladen swallow?}@> 42 >>> int(speed) 42 -\end{verbatim} +\end{lstlisting} % But if the user types something other than a string of digits, you get an error: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> speed = input(prompt) -What...is the airspeed velocity of an unladen swallow? -What do you mean, an African or a European swallow? +<@\textcolor{black}{What...is the airspeed velocity of an unladen swallow? +What do you mean, an African or a European swallow?}@> >>> int(speed) -ValueError: invalid literal for int() with base 10 -\end{verbatim} +<@\textcolor{black}{ValueError: invalid literal for int() with base 10}@> +\end{lstlisting} % We will see how to handle this kind of error later. \index{ValueError} @@ -4132,14 +4134,14 @@ \section{Debugging} tabs are invisible and we are used to ignoring them. \index{whitespace} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> x = 5 >>> y = 6 File "", line 1 y = 6 ^ IndentationError: unexpected indent -\end{verbatim} +\end{lstlisting} % In this example, the problem is that the second line is indented by one space. But the error message points to {\tt y}, which is @@ -4154,14 +4156,14 @@ \section{Debugging} is $SNR_{db} = 10 \log_{10} (P_{signal} / P_{noise})$. In Python, you might write something like this: -\begin{verbatim} +\begin{lstlisting}[language=python] import math signal_power = 9 noise_power = 10 ratio = signal_power // noise_power decibels = 10 * math.log10(ratio) print(decibels) -\end{verbatim} +\end{lstlisting} % When you run this program, you get an exception: % @@ -4267,12 +4269,12 @@ \section{Exercises} returns the current Greenwich Mean Time in ``the epoch'', which is an arbitrary time used as a reference point. On UNIX systems, the epoch is 1 January 1970. - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] >>> import time >>> time.time() 1437746094.5735958 -\end{verbatim} +\end{lstlisting}} Write a script that reads the current time and converts it to a time of day in hours, minutes, and seconds, plus the number of @@ -4349,8 +4351,8 @@ \section{Exercises} What is the output of the following program? Draw a stack diagram that shows the state of the program when it prints the result. - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] def recurse(n, s): if n == 0: print(s) @@ -4358,7 +4360,7 @@ \section{Exercises} recurse(n-1, n+s) recurse(3, 0) -\end{verbatim} +\end{lstlisting}} \begin{enumerate} @@ -4382,8 +4384,8 @@ \section{Exercises} Read the following function and see if you can figure out what it does (see the examples in Chapter~\ref{turtlechap}). Then run it and see if you got it right. - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] def draw(t, length, n): if n == 0: return @@ -4395,7 +4397,7 @@ \section{Exercises} draw(t, length, n-1) t.lt(angle) t.bk(length*n) -\end{verbatim} +\end{lstlisting}} \end{exercise} @@ -4471,10 +4473,10 @@ \section{Return values} value, which we usually assign to a variable or use as part of an expression. -\begin{verbatim} +\begin{lstlisting}[language=python] e = math.exp(1.0) height = radius * math.sin(radians) -\end{verbatim} +\end{lstlisting} % The functions we have written so far are void. Speaking casually, they have no return value; more precisely, @@ -4484,11 +4486,11 @@ \section{Return values} The first example is {\tt area}, which returns the area of a circle with the given radius: -\begin{verbatim} +\begin{lstlisting}[language=python] def area(radius): a = math.pi * radius**2 return a -\end{verbatim} +\end{lstlisting} % We have seen the {\tt return} statement before, but in a fruitful function the {\tt return} statement includes @@ -4499,10 +4501,10 @@ \section{Return values} \index{return statement} \index{statement!return} -\begin{verbatim} +\begin{lstlisting}[language=python] def area(radius): return math.pi * radius**2 -\end{verbatim} +\end{lstlisting} % On the other hand, {\bf temporary variables} like {\tt a} can make debugging easier. @@ -4512,13 +4514,13 @@ \section{Return values} Sometimes it is useful to have multiple return statements, one in each branch of a conditional: -\begin{verbatim} +\begin{lstlisting}[language=python] def absolute_value(x): if x < 0: return -x else: return x -\end{verbatim} +\end{lstlisting} % Since these {\tt return} statements are in an alternative conditional, only one runs. @@ -4533,13 +4535,13 @@ \section{Return values} that every possible path through the program hits a {\tt return} statement. For example: -\begin{verbatim} +\begin{lstlisting}[language=python] def absolute_value(x): if x < 0: return -x if x > 0: return x -\end{verbatim} +\end{lstlisting} % This function is incorrect because if {\tt x} happens to be 0, neither condition is true, and the function ends without hitting a @@ -4549,10 +4551,10 @@ \section{Return values} \index{None special value} \index{special value!None} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> print(absolute_value(0)) None -\end{verbatim} +\end{lstlisting} % By the way, Python provides a built-in function called {\tt abs} that computes absolute values. @@ -4599,10 +4601,10 @@ \section{Incremental development} Immediately you can write an outline of the function: -\begin{verbatim} +\begin{lstlisting}[language=python] def distance(x1, y1, x2, y2): return 0.0 -\end{verbatim} +\end{lstlisting} % Obviously, this version doesn't compute distances; it always returns zero. But it is syntactically correct, and it runs, which means that @@ -4610,10 +4612,10 @@ \section{Incremental development} To test the new function, call it with sample arguments: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> distance(1, 2, 4, 6) 0.0 -\end{verbatim} +\end{lstlisting} % I chose these values so that the horizontal distance is 3 and the vertical distance is 4; that way, the result is 5, the hypotenuse @@ -4627,14 +4629,14 @@ \section{Incremental development} $x_2 - x_1$ and $y_2 - y_1$. The next version stores those values in temporary variables and prints them. -\begin{verbatim} +\begin{lstlisting}[language=python] def distance(x1, y1, x2, y2): dx = x2 - x1 dy = y2 - y1 print('dx is', dx) print('dy is', dy) return 0.0 -\end{verbatim} +\end{lstlisting} % If the function is working, it should display \verb"dx is 3" and \verb"dy is 4". If so, we know that the function is getting the right @@ -4643,14 +4645,14 @@ \section{Incremental development} Next we compute the sum of squares of {\tt dx} and {\tt dy}: -\begin{verbatim} +\begin{lstlisting}[language=python] def distance(x1, y1, x2, y2): dx = x2 - x1 dy = y2 - y1 dsquared = dx**2 + dy**2 print('dsquared is: ', dsquared) return 0.0 -\end{verbatim} +\end{lstlisting} % Again, you would run the program at this stage and check the output (which should be 25). @@ -4658,14 +4660,14 @@ \section{Incremental development} \index{sqrt} \index{function!sqrt} -\begin{verbatim} +\begin{lstlisting}[language=python] def distance(x1, y1, x2, y2): dx = x2 - x1 dy = y2 - y1 dsquared = dx**2 + dy**2 result = math.sqrt(dsquared) return result -\end{verbatim} +\end{lstlisting} % If that works correctly, you are done. Otherwise, you might want to print the value of {\tt result} before the return @@ -4725,35 +4727,35 @@ \section{Composition} between the two points. We just wrote a function, {\tt distance}, that does that: -\begin{verbatim} +\begin{lstlisting}[language=python] radius = distance(xc, yc, xp, yp) -\end{verbatim} +\end{lstlisting} % The next step is to find the area of a circle with that radius; we just wrote that, too: -\begin{verbatim} +\begin{lstlisting}[language=python] result = area(radius) -\end{verbatim} +\end{lstlisting} % Encapsulating these steps in a function, we get: \index{encapsulation} -\begin{verbatim} +\begin{lstlisting}[language=python] def circle_area(xc, yc, xp, yp): radius = distance(xc, yc, xp, yp) result = area(radius) return result -\end{verbatim} +\end{lstlisting} % The temporary variables {\tt radius} and {\tt result} are useful for development and debugging, but once the program is working, we can make it more concise by composing the function calls: -\begin{verbatim} +\begin{lstlisting}[language=python] def circle_area(xc, yc, xp, yp): return area(distance(xc, yc, xp, yp)) -\end{verbatim} +\end{lstlisting} % \section{Boolean functions} @@ -4763,13 +4765,13 @@ \section{Boolean functions} complicated tests inside functions. \index{boolean function} For example: -\begin{verbatim} +\begin{lstlisting}[language=python] def is_divisible(x, y): if x % y == 0: return True else: return False -\end{verbatim} +\end{lstlisting} % It is common to give boolean functions names that sound like yes/no questions; \verb"is_divisible" returns either {\tt True} or {\tt False} @@ -4777,36 +4779,36 @@ \section{Boolean functions} Here is an example: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> is_divisible(6, 4) False >>> is_divisible(6, 3) True -\end{verbatim} +\end{lstlisting} % The result of the {\tt ==} operator is a boolean, so we can write the function more concisely by returning it directly: -\begin{verbatim} +\begin{lstlisting}[language=python] def is_divisible(x, y): return x % y == 0 -\end{verbatim} +\end{lstlisting} % Boolean functions are often used in conditional statements: \index{conditional statement} \index{statement!conditional} -\begin{verbatim} +\begin{lstlisting}[language=python] if is_divisible(x, y): print('x is divisible by y') -\end{verbatim} +\end{lstlisting} % It might be tempting to write something like: -\begin{verbatim} +\begin{lstlisting}[language=python] if is_divisible(x, y) == True: print('x is divisible by y') -\end{verbatim} +\end{lstlisting} % But the extra comparison is unnecessary. @@ -4879,23 +4881,23 @@ \section{More recursion} what the parameters should be. In this case it should be clear that {\tt factorial} takes an integer: -\begin{verbatim} +\begin{lstlisting}[language=python] def factorial(n): -\end{verbatim} +\end{lstlisting} % If the argument happens to be 0, all we have to do is return 1: -\begin{verbatim} +\begin{lstlisting}[language=python] def factorial(n): if n == 0: return 1 -\end{verbatim} +\end{lstlisting} % Otherwise, and this is the interesting part, we have to make a recursive call to find the factorial of $n-1$ and then multiply it by $n$: -\begin{verbatim} +\begin{lstlisting}[language=python] def factorial(n): if n == 0: return 1 @@ -4903,7 +4905,7 @@ \section{More recursion} recurse = factorial(n-1) result = n * recurse return result -\end{verbatim} +\end{lstlisting} % The flow of execution for this program is similar to the flow of {\tt countdown} in Section~\ref{recursion}. If we call {\tt factorial} @@ -5019,7 +5021,7 @@ \section{One more example} % Translated into Python, it looks like this: -\begin{verbatim} +\begin{lstlisting}[language=python] def fibonacci(n): if n == 0: return 0 @@ -5027,7 +5029,7 @@ \section{One more example} return 1 else: return fibonacci(n-1) + fibonacci(n-2) -\end{verbatim} +\end{lstlisting} % If you try to follow the flow of execution here, even for fairly small values of $n$, your head explodes. But according to the @@ -5046,10 +5048,10 @@ \section{Checking types} \index{factorial function} \index{RuntimeError} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> factorial(1.5) RuntimeError: Maximum recursion depth exceeded -\end{verbatim} +\end{lstlisting} % It looks like an infinite recursion. How can that be? The function has a base case---when {\tt n == 0}. But if {\tt n} is not an integer, @@ -5074,7 +5076,7 @@ \section{Checking types} \index{isinstance function} \index{function!isinstance} -\begin{verbatim} +\begin{lstlisting}[language=python] def factorial(n): if not isinstance(n, int): print('Factorial is only defined for integers.') @@ -5086,21 +5088,21 @@ \section{Checking types} return 1 else: return n * factorial(n-1) -\end{verbatim} +\end{lstlisting} % The first base case handles nonintegers; the second handles negative integers. In both cases, the program prints an error message and returns {\tt None} to indicate that something went wrong: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> print(factorial('fred')) -Factorial is only defined for integers. +<@\textcolor{black}{Factorial is only defined for integers.}@> None >>> print(factorial(-2)) -Factorial is not defined for negative integers. +<@\textcolor{black}{Factorial is not defined for negative integers.}@> None -\end{verbatim} +\end{lstlisting} % If we get past both checks, we know that $n$ is a non-negative integer, so we can prove that the recursion terminates. \index{guardian pattern} @@ -5159,7 +5161,7 @@ \section{Debugging} For example, here is a version of {\tt factorial} with print statements: -\begin{verbatim} +\begin{lstlisting}[language=python] def factorial(n): space = ' ' * (4 * n) print(space, 'factorial', n) @@ -5171,12 +5173,12 @@ \section{Debugging} result = n * recurse print(space, 'returning', result) return result -\end{verbatim} +\end{lstlisting} % {\tt space} is a string of space characters that controls the indentation of the output. Here is the result of {\tt factorial(4)} : -\begin{verbatim} +\begin{lstlisting}[language=python] factorial 4 factorial 3 factorial 2 @@ -5187,7 +5189,7 @@ \section{Debugging} returning 2 returning 6 returning 24 -\end{verbatim} +\end{lstlisting} % If you are confused about the flow of execution, this kind of output can be helpful. It takes some time to develop effective @@ -5231,8 +5233,8 @@ \section{Exercises} Draw a stack diagram for the following program. What does the program print? \index{stack diagram} - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] def b(z): prod = a(z, z) print(z, prod) @@ -5250,7 +5252,7 @@ \section{Exercises} x = 1 y = x + 1 print(c(x, y+3, x+y)) -\end{verbatim} +\end{lstlisting}} \end{exercise} @@ -5290,8 +5292,8 @@ \section{Exercises} The following are functions that take a string argument and return the first, last, and middle letters: - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] def first(word): return word[0] @@ -5300,7 +5302,7 @@ \section{Exercises} def middle(word): return word[1:-1] -\end{verbatim} +\end{lstlisting}} % We'll see how they work in Chapter~\ref{strings}. @@ -5374,14 +5376,14 @@ \section{Reassignment} assignment to the same variable. A new assignment makes an existing variable refer to a new value (and stop referring to the old value). -\begin{verbatim} +\begin{lstlisting}[language=python] >>> x = 5 >>> x 5 >>> x = 7 >>> x 7 -\end{verbatim} +\end{lstlisting} % The first time we display {\tt x}, its value is 5; the second time, its @@ -5408,13 +5410,13 @@ \section{Reassignment} In Python, an assignment statement can make two variables equal, but they don't have to stay that way: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> a = 5 >>> b = a # a and b are now equal >>> a = 3 # a and b are no longer equal >>> b 5 -\end{verbatim} +\end{lstlisting} % The third line changes the value of {\tt a} but does not change the value of {\tt b}, so they are no longer equal. @@ -5441,9 +5443,9 @@ \section{Updating variables} A common kind of reassignment is an {\bf update}, where the new value of the variable depends on the old. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> x = x + 1 -\end{verbatim} +\end{lstlisting} % This means ``get the current value of {\tt x}, add one, and then update {\tt x} with the new value.'' @@ -5452,19 +5454,19 @@ \section{Updating variables} error, because Python evaluates the right side before it assigns a value to {\tt x}: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> x = x + 1 NameError: name 'x' is not defined -\end{verbatim} +\end{lstlisting} % Before you can update a variable, you have to {\bf initialize} it, usually with a simple assignment: \index{initialization (before update)} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> x = 0 >>> x = x + 1 -\end{verbatim} +\end{lstlisting} % Updating a variable by adding 1 is called an {\bf increment}; subtracting 1 is called a {\bf decrement}. @@ -5494,13 +5496,13 @@ \section{The {\tt while} statement} Another is the {\tt while} statement. Here is a version of {\tt countdown} that uses a {\tt while} statement: -\begin{verbatim} +\begin{lstlisting}[language=python] def countdown(n): while n > 0: print(n) n = n - 1 print('Blastoff!') -\end{verbatim} +\end{lstlisting} % You can almost read the {\tt while} statement as if it were English. It means, ``While {\tt n} is greater than 0, @@ -5544,7 +5546,7 @@ \section{The {\tt while} statement} For some other loops, it is not so easy to tell. For example: -\begin{verbatim} +\begin{lstlisting}[language=python] def sequence(n): while n != 1: print(n) @@ -5552,7 +5554,7 @@ \section{The {\tt while} statement} n = n / 2 else: # n is odd n = n*3 + 1 -\end{verbatim} +\end{lstlisting} % The condition for this loop is {\tt n != 1}, so the loop will continue until {\tt n} is {\tt 1}, which makes the condition false. @@ -5592,7 +5594,7 @@ \section{{\tt break}} For example, suppose you want to take input from the user until they type {\tt done}. You could write: -\begin{verbatim} +\begin{lstlisting}[language=python] while True: line = input('> ') if line == 'done': @@ -5600,7 +5602,7 @@ \section{{\tt break}} print(line) print('Done!') -\end{verbatim} +\end{lstlisting} % The loop condition is {\tt True}, which is always true, so the loop runs until it hits the break statement. @@ -5642,28 +5644,28 @@ \section{Square roots} % For example, if $a$ is 4 and $x$ is 3: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> a = 4 >>> x = 3 >>> y = (x + a/x) / 2 >>> y 2.16666666667 -\end{verbatim} +\end{lstlisting} % The result is closer to the correct answer ($\sqrt{4} = 2$). If we repeat the process with the new estimate, it gets even closer: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> x = y >>> y = (x + a/x) / 2 >>> y 2.00641025641 -\end{verbatim} +\end{lstlisting} % After a few more updates, the estimate is almost exact: \index{update} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> x = y >>> y = (x + a/x) / 2 >>> y @@ -5672,14 +5674,14 @@ \section{Square roots} >>> y = (x + a/x) / 2 >>> y 2.00000000003 -\end{verbatim} +\end{lstlisting} % In general we don't know ahead of time how many steps it takes to get to the right answer, but we know when we get there because the estimate stops changing: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> x = y >>> y = (x + a/x) / 2 >>> y @@ -5688,20 +5690,20 @@ \section{Square roots} >>> y = (x + a/x) / 2 >>> y 2.0 -\end{verbatim} +\end{lstlisting} % When {\tt y == x}, we can stop. Here is a loop that starts with an initial estimate, {\tt x}, and improves it until it stops changing: -\begin{verbatim} +\begin{lstlisting}[language=python] while True: print(x) y = (x + a/x) / 2 if y == x: break x = y -\end{verbatim} +\end{lstlisting} % For most values of {\tt a} this works fine, but in general it is dangerous to test {\tt float} equality. @@ -5715,10 +5717,10 @@ \section{Square roots} is safer to use the built-in function {\tt abs} to compute the absolute value, or magnitude, of the difference between them: -\begin{verbatim} +\begin{lstlisting}[language=python] if abs(y-x) < epsilon: break -\end{verbatim} +\end{lstlisting} % Where \verb"epsilon" has a value like {\tt 0.0000001} that determines how close is close enough. @@ -5852,8 +5854,8 @@ \section{Exercises} To test it, write a function named \verb"test_square_root" that prints a table like this: - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] a mysqrt(a) math.sqrt(a) diff - --------- ------------ ---- 1.0 1.0 1.0 0.0 @@ -5865,7 +5867,7 @@ \section{Exercises} 7.0 2.64575131106 2.64575131106 0.0 8.0 2.82842712475 2.82842712475 4.4408920985e-16 9.0 3.0 3.0 0.0 -\end{verbatim} +\end{lstlisting}} % The first column is a number, $a$; the second column is the square root of $a$ computed with \verb"mysqrt"; the third column is the @@ -5880,16 +5882,16 @@ \section{Exercises} The built-in function {\tt eval} takes a string and evaluates it using the Python interpreter. For example: - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] >>> eval('1 + 2 * 3') 7 >>> import math >>> eval('math.sqrt(5)') 2.2360679774997898 >>> eval('type(math.pi)') - -\end{verbatim} +<@\textcolor{black}{}@> +\end{lstlisting}} % Write a function called \verb"eval_loop" that iteratively prompts the user, takes the resulting input and evaluates @@ -5945,10 +5947,10 @@ \section{A string is a sequence} You can access the characters one at a time with the bracket operator: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> fruit = 'banana' >>> letter = fruit[1] -\end{verbatim} +\end{lstlisting} % The second statement selects character number 1 from {\tt fruit} and assigns it to {\tt letter}. @@ -5960,20 +5962,20 @@ \section{A string is a sequence} But you might not get what you expect: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> letter 'a' -\end{verbatim} +\end{lstlisting} % For most people, the first letter of \verb"'banana'" is {\tt b}, not {\tt a}. But for computer scientists, the index is an offset from the beginning of the string, and the offset of the first letter is zero. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> letter = fruit[0] >>> letter 'b' -\end{verbatim} +\end{lstlisting} % So {\tt b} is the 0th letter (``zero-eth'') of \verb"'banana'", {\tt a} is the 1th letter (``one-eth''), and {\tt n} is the 2th letter @@ -5984,13 +5986,13 @@ \section{A string is a sequence} operators: \index{index} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> i = 1 >>> fruit[i] 'a' >>> fruit[i+1] 'n' -\end{verbatim} +\end{lstlisting} % But the value of the index has to be an integer. Otherwise you @@ -5998,10 +6000,10 @@ \section{A string is a sequence} \index{exception!TypeError} \index{TypeError} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> letter = fruit[1.5] TypeError: string indices must be integers -\end{verbatim} +\end{lstlisting} % \section{{\tt len}} @@ -6011,33 +6013,33 @@ \section{{\tt len}} {\tt len} is a built-in function that returns the number of characters in a string: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> fruit = 'banana' >>> len(fruit) 6 -\end{verbatim} +\end{lstlisting} % To get the last letter of a string, you might be tempted to try something like this: \index{exception!IndexError} \index{IndexError} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> length = len(fruit) >>> last = fruit[length] -IndexError: string index out of range -\end{verbatim} +<@\textcolor{black}{IndexError: string index out of range}@> +\end{lstlisting} % The reason for the {\tt IndexError} is that there is no letter in {\tt 'banana'} with the index 6. Since we started counting at zero, the six letters are numbered 0 to 5. To get the last character, you have to subtract 1 from {\tt length}: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> last = fruit[length-1] >>> last 'a' -\end{verbatim} +\end{lstlisting} % Or you can use negative indices, which count backward from the end of the string. The expression {\tt fruit[-1]} yields the last @@ -6061,13 +6063,13 @@ \section{Traversal with a {\tt for} loop} processing is called a {\bf traversal}. One way to write a traversal is with a {\tt while} loop: -\begin{verbatim} +\begin{lstlisting}[language=python] index = 0 while index < len(fruit): letter = fruit[index] print(letter) index = index + 1 -\end{verbatim} +\end{lstlisting} % This loop traverses the string and displays each letter on a line by itself. The loop condition is {\tt index < len(fruit)}, so @@ -6081,10 +6083,10 @@ \section{Traversal with a {\tt for} loop} Another way to write a traversal is with a {\tt for} loop: -\begin{verbatim} +\begin{lstlisting}[language=python] for letter in fruit: print(letter) -\end{verbatim} +\end{lstlisting} % Each time through the loop, the next character in the string is assigned to the variable {\tt letter}. The loop continues until no characters are @@ -6100,17 +6102,17 @@ \section{Traversal with a {\tt for} loop} Mack, Nack, Ouack, Pack, and Quack. This loop outputs these names in order: -\begin{verbatim} +\begin{lstlisting}[language=python] prefixes = 'JKLMNOPQ' suffix = 'ack' for letter in prefixes: print(letter + suffix) -\end{verbatim} +\end{lstlisting} % The output is: -\begin{verbatim} +\begin{lstlisting}[language=python] Jack Kack Lack @@ -6119,7 +6121,7 @@ \section{Traversal with a {\tt for} loop} Oack Pack Qack -\end{verbatim} +\end{lstlisting} % Of course, that's not quite right because ``Ouack'' and ``Quack'' are misspelled. As an exercise, modify the program to fix this error. @@ -6134,13 +6136,13 @@ \section{String slices} A segment of a string is called a {\bf slice}. Selecting a slice is similar to selecting a character: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> s = 'Monty Python' >>> s[0:5] 'Monty' >>> s[6:12] 'Python' -\end{verbatim} +\end{lstlisting} % The operator {\tt [n:m]} returns the part of the string from the ``n-eth'' character to the ``m-eth'' character, including the first but @@ -6159,23 +6161,23 @@ \section{String slices} the beginning of the string. If you omit the second index, the slice goes to the end of the string: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> fruit = 'banana' >>> fruit[:3] 'ban' >>> fruit[3:] 'ana' -\end{verbatim} +\end{lstlisting} % If the first index is greater than or equal to the second the result is an {\bf empty string}, represented by two quotation marks: \index{quotation mark} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> fruit = 'banana' >>> fruit[3:3] '' -\end{verbatim} +\end{lstlisting} % An empty string contains no characters and has length 0, but other than that, it is the same as any other string. @@ -6198,11 +6200,11 @@ \section{Strings are immutable} \index{TypeError} \index{exception!TypeError} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> greeting = 'Hello, world!' >>> greeting[0] = 'J' -TypeError: 'str' object does not support item assignment -\end{verbatim} +<@\textcolor{black}{TypeError: 'str' object does not support item assignment}@> +\end{lstlisting} % The ``object'' in this case is the string and the ``item'' is the character you tried to assign. For now, an object is @@ -6219,12 +6221,12 @@ \section{Strings are immutable} existing string. The best you can do is create a new string that is a variation on the original: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> greeting = 'Hello, world!' >>> new_greeting = 'J' + greeting[1:] >>> new_greeting 'Jello, world!' -\end{verbatim} +\end{lstlisting} % This example concatenates a new first letter onto a slice of {\tt greeting}. It has no effect on @@ -6239,7 +6241,7 @@ \section{Searching} \index{find function} \index{function!find} -\begin{verbatim} +\begin{lstlisting}[language=python] def find(word, letter): index = 0 while index < len(word): @@ -6247,7 +6249,7 @@ \section{Searching} return index index = index + 1 return -1 -\end{verbatim} +\end{lstlisting} % In a sense, {\tt find} is the inverse of the {\tt []} operator. Instead of taking an index and extracting the corresponding character, @@ -6283,14 +6285,14 @@ \section{Looping and counting} The following program counts the number of times the letter {\tt a} appears in a string: -\begin{verbatim} +\begin{lstlisting}[language=python] word = 'banana' count = 0 for letter in word: if letter == 'a': count = count + 1 print(count) -\end{verbatim} +\end{lstlisting} % This program demonstrates another pattern of computation called a {\bf counter}. The variable {\tt count} is initialized to 0 and then @@ -6322,12 +6324,12 @@ \section{String methods} Instead of the function syntax {\tt upper(word)}, it uses the method syntax {\tt word.upper()}. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> word = 'banana' >>> new_word = word.upper() >>> new_word 'BANANA' -\end{verbatim} +\end{lstlisting} % This form of dot notation specifies the name of the method, {\tt upper}, and the name of the string to apply the method to, {\tt @@ -6343,12 +6345,12 @@ \section{String methods} As it turns out, there is a string method named {\tt find} that is remarkably similar to the function we wrote: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> word = 'banana' >>> index = word.find('a') >>> index 1 -\end{verbatim} +\end{lstlisting} % In this example, we invoke {\tt find} on {\tt word} and pass the letter we are looking for as a parameter. @@ -6356,30 +6358,30 @@ \section{String methods} Actually, the {\tt find} method is more general than our function; it can find substrings, not just characters: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> word.find('na') 2 -\end{verbatim} +\end{lstlisting} % By default, {\tt find} starts at the beginning of the string, but it can take a second argument, the index where it should start: \index{optional argument} \index{argument!optional} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> word.find('na', 3) 4 -\end{verbatim} +\end{lstlisting} % This is an example of an {\bf optional argument}; {\tt find} can also take a third argument, the index where it should stop: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> name = 'bob' >>> name.find('b', 1, 2) -1 -\end{verbatim} +\end{lstlisting} % This search fails because {\tt b} does not appear in the index range from {\tt 1} to {\tt 2}, not including {\tt @@ -6398,22 +6400,22 @@ \section{The {\tt in} operator} The word {\tt in} is a boolean operator that takes two strings and returns {\tt True} if the first appears as a substring in the second: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> 'a' in 'banana' True >>> 'seed' in 'banana' False -\end{verbatim} +\end{lstlisting} % For example, the following function prints all the letters from {\tt word1} that also appear in {\tt word2}: -\begin{verbatim} +\begin{lstlisting}[language=python] def in_both(word1, word2): for letter in word1: if letter in word2: print(letter) -\end{verbatim} +\end{lstlisting} % With well-chosen variable names, Python sometimes reads like English. You could read @@ -6422,12 +6424,12 @@ \section{The {\tt in} operator} Here's what you get if you compare apples and oranges: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> in_both('apples', 'oranges') a e s -\end{verbatim} +\end{lstlisting} % \section{String comparison} @@ -6436,30 +6438,30 @@ \section{String comparison} The relational operators work on strings. To see if two strings are equal: -\begin{verbatim} +\begin{lstlisting}[language=python] if word == 'banana': print('All right, bananas.') -\end{verbatim} +\end{lstlisting} % Other relational operations are useful for putting words in alphabetical order: -\begin{verbatim} +\begin{lstlisting}[language=python] if word < 'banana': print('Your word, ' + word + ', comes before banana.') elif word > 'banana': print('Your word, ' + word + ', comes after banana.') else: print('All right, bananas.') -\end{verbatim} +\end{lstlisting} % Python does not handle uppercase and lowercase letters the same way people do. All the uppercase letters come before all the lowercase letters, so: -\begin{verbatim} +\begin{lstlisting}[language=python] Your word, Pineapple, comes before banana. -\end{verbatim} +\end{lstlisting} % A common way to address this problem is to convert strings to a standard format, such as all lowercase, before performing the @@ -6477,7 +6479,7 @@ \section{Debugging} words and return {\tt True} if one of the words is the reverse of the other, but it contains two errors: -\begin{verbatim} +\begin{lstlisting}[language=python] def is_reverse(word1, word2): if len(word1) != len(word2): return False @@ -6492,7 +6494,7 @@ \section{Debugging} j = j-1 return True -\end{verbatim} +\end{lstlisting} % The first {\tt if} statement checks whether the words are the same length. If not, we can return {\tt False} immediately. @@ -6514,19 +6516,19 @@ \section{Debugging} \index{IndexError} \index{exception!IndexError} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> is_reverse('pots', 'stop') ... File "reverse.py", line 15, in is_reverse if word1[i] != word2[j]: -IndexError: string index out of range -\end{verbatim} +<@\textcolor{black}{IndexError: string index out of range} +\end{lstlisting} % For debugging this kind of error, my first move is to print the values of the indices immediately before the line where the error appears. -\begin{verbatim} +\begin{lstlisting}[language=python] while j > 0: print(i, j) # print here @@ -6534,16 +6536,16 @@ \section{Debugging} return False i = i+1 j = j-1 -\end{verbatim} +\end{lstlisting} % Now when I run the program again, I get more information: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> is_reverse('pots', 'stop') 0 4 ... -IndexError: string index out of range -\end{verbatim} +<@\textcolor{black}{IndexError: string index out of range}@> +\end{lstlisting} % The first time through the loop, the value of {\tt j} is 4, which is out of range for the string \verb"'pots'". @@ -6552,13 +6554,13 @@ \section{Debugging} If I fix that error and run the program again, I get: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> is_reverse('pots', 'stop') 0 3 1 2 2 1 True -\end{verbatim} +\end{lstlisting} % This time we get the right answer, but it looks like the loop only ran three times, which is suspicious. To get a better idea of what is @@ -6682,12 +6684,12 @@ \section{Exercises} size''; that is, the number of spaces between successive characters. A step size of 2 means every other character; 3 means every third, etc. - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] >>> fruit = 'banana' >>> fruit[0:5:2] 'bnn' -\end{verbatim} +\end{lstlisting}} A step size of -1 goes through the word backwards, so the slice \verb"[::-1]" generates a reversed string. @@ -6704,8 +6706,8 @@ \section{Exercises} string contains any lowercase letters, but at least some of them are wrong. For each function, describe what the function actually does (assuming that the parameter is a string). - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] def any_lowercase1(s): for c in s: if c.islower(): @@ -6736,7 +6738,7 @@ \section{Exercises} if not c.islower(): return False return True -\end{verbatim} +\end{lstlisting}} \end{exercise} @@ -6768,11 +6770,11 @@ \section{Exercises} a character to a numeric code, and {\tt chr}, which converts numeric codes to characters. Letters of the alphabet are encoded in alphabetical order, so for example: - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] >>> ord('c') - ord('a') 2 -\end{verbatim} +\end{lstlisting}} Because \verb"'c'" is the two-eth letter of the alphabet. But beware: the numeric codes for upper case letters are different. @@ -6823,9 +6825,9 @@ \section{Reading word lists} \index{object!file} \index{file object} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> fin = open('words.txt') -\end{verbatim} +\end{lstlisting} % {\tt fin} is a common name for a file object used for input. The file object provides several methods for reading, including {\tt readline}, @@ -6833,10 +6835,10 @@ \section{Reading word lists} returns the result as a string: \index{readline method} \index{method!readline} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> fin.readline() 'aa\n' -\end{verbatim} +\end{lstlisting} % The first word in this particular list is ``aa'', which is a kind of lava. The sequence \verb"\n" represents the newline character that @@ -6845,10 +6847,10 @@ \section{Reading word lists} The file object keeps track of where it is in the file, so if you call {\tt readline} again, you get the next word: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> fin.readline() 'aah\n' -\end{verbatim} +\end{lstlisting} % The next word is ``aah'', which is a perfectly legitimate word, so stop looking at me like that. @@ -6857,12 +6859,12 @@ \section{Reading word lists} \index{strip method} \index{method!strip} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> line = fin.readline() >>> word = line.strip() >>> word 'aahed' -\end{verbatim} +\end{lstlisting} % You can also use a file object as part of a {\tt for} loop. This program reads {\tt words.txt} and prints each word, one @@ -6870,12 +6872,12 @@ \section{Reading word lists} \index{open function} \index{function!open} -\begin{verbatim} +\begin{lstlisting}[language=python] fin = open('words.txt') for line in fin: word = line.strip() print(word) -\end{verbatim} +\end{lstlisting} % \section{Exercises} @@ -6972,13 +6974,13 @@ \section{Search} in common; they can be solved with the search pattern we saw in Section~\ref{find}. The simplest example is: -\begin{verbatim} +\begin{lstlisting}[language=python] def has_no_e(word): for letter in word: if letter == 'e': return False return True -\end{verbatim} +\end{lstlisting} % The {\tt for} loop traverses the characters in {\tt word}. If we find the letter ``e'', we can immediately return {\tt False}; otherwise we @@ -6996,13 +6998,13 @@ \section{Search} {\tt avoids} is a more general version of \verb"has_no_e" but it has the same structure: -\begin{verbatim} +\begin{lstlisting}[language=python] def avoids(word, forbidden): for letter in word: if letter in forbidden: return False return True -\end{verbatim} +\end{lstlisting} % We can return {\tt False} as soon as we find a forbidden letter; if we get to the end of the loop, we return {\tt True}. @@ -7010,13 +7012,13 @@ \section{Search} \verb"uses_only" is similar except that the sense of the condition is reversed: -\begin{verbatim} +\begin{lstlisting}[language=python] def uses_only(word, available): for letter in word: if letter not in available: return False return True -\end{verbatim} +\end{lstlisting} % Instead of a list of forbidden letters, we have a list of available letters. If we find a letter in {\tt word} that is not in @@ -7025,13 +7027,13 @@ \section{Search} \verb"uses_all" is similar except that we reverse the role of the word and the string of letters: -\begin{verbatim} +\begin{lstlisting}[language=python] def uses_all(word, required): for letter in required: if letter not in word: return False return True -\end{verbatim} +\end{lstlisting} % Instead of traversing the letters in {\tt word}, the loop traverses the required letters. If any of the required letters @@ -7042,10 +7044,10 @@ \section{Search} have recognized that \verb"uses_all" was an instance of a previously solved problem, and you would have written: -\begin{verbatim} +\begin{lstlisting}[language=python] def uses_all(word, required): return uses_only(required, word) -\end{verbatim} +\end{lstlisting} % This is an example of a program development plan called {\bf reduction to a previously solved problem}, which means that you @@ -7065,7 +7067,7 @@ \section{Looping with indices} For \verb"is_abecedarian" we have to compare adjacent letters, which is a little tricky with a {\tt for} loop: -\begin{verbatim} +\begin{lstlisting}[language=python] def is_abecedarian(word): previous = word[0] for c in word: @@ -7073,22 +7075,22 @@ \section{Looping with indices} return False previous = c return True -\end{verbatim} +\end{lstlisting} An alternative is to use recursion: -\begin{verbatim} +\begin{lstlisting}[language=python] def is_abecedarian(word): if len(word) <= 1: return True if word[0] > word[1]: return False return is_abecedarian(word[1:]) -\end{verbatim} +\end{lstlisting} Another option is to use a {\tt while} loop: -\begin{verbatim} +\begin{lstlisting}[language=python] def is_abecedarian(word): i = 0 while i < len(word)-1: @@ -7096,7 +7098,7 @@ \section{Looping with indices} return False i = i+1 return True -\end{verbatim} +\end{lstlisting} % The loop starts at {\tt i=0} and ends when {\tt i=len(word)-1}. Each time through the loop, it compares the $i$th character (which you can @@ -7121,7 +7123,7 @@ \section{Looping with indices} Exercise~\ref{palindrome}) that uses two indices; one starts at the beginning and goes up; the other starts at the end and goes down. -\begin{verbatim} +\begin{lstlisting}[language=python] def is_palindrome(word): i = 0 j = len(word)-1 @@ -7133,17 +7135,17 @@ \section{Looping with indices} j = j-1 return True -\end{verbatim} +\end{lstlisting} Or we could reduce to a previously solved problem and write: \index{reduction to a previously solved problem} \index{development plan!reduction} -\begin{verbatim} +\begin{lstlisting}[language=python] def is_palindrome(word): return is_reverse(word, word) -\end{verbatim} +\end{lstlisting} % Using \verb"is_reverse" from Section~\ref{isreverse}. @@ -7328,19 +7330,19 @@ \section{A list is a sequence} There are several ways to create a new list; the simplest is to enclose the elements in square brackets (\verb"[" and \verb"]"): -\begin{verbatim} +\begin{lstlisting}[language=python] [10, 20, 30, 40] ['crunchy frog', 'ram bladder', 'lark vomit'] -\end{verbatim} +\end{lstlisting} % The first example is a list of four integers. The second is a list of three strings. The elements of a list don't have to be the same type. The following list contains a string, a float, an integer, and (lo!) another list: -\begin{verbatim} +\begin{lstlisting}[language=python] ['spam', 2.0, 5, [10, 20]] -\end{verbatim} +\end{lstlisting} % A list within another list is {\bf nested}. \index{nested list} @@ -7354,13 +7356,13 @@ \section{A list is a sequence} As you might expect, you can assign list values to variables: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> cheeses = ['Cheddar', 'Edam', 'Gouda'] >>> numbers = [42, 123] >>> empty = [] >>> print(cheeses, numbers, empty) ['Cheddar', 'Edam', 'Gouda'] [42, 123] [] -\end{verbatim} +\end{lstlisting} % \index{assignment} @@ -7378,22 +7380,22 @@ \section{Lists are mutable} expression inside the brackets specifies the index. Remember that the indices start at 0: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> cheeses[0] 'Cheddar' -\end{verbatim} +\end{lstlisting} % Unlike strings, lists are mutable. When the bracket operator appears on the left side of an assignment, it identifies the element of the list that will be assigned. \index{mutability} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> numbers = [42, 123] >>> numbers[1] = 5 >>> numbers [42, 5] -\end{verbatim} +\end{lstlisting} % The one-eth element of {\tt numbers}, which used to be 123, is now 5. @@ -7447,13 +7449,13 @@ \section{Lists are mutable} The {\tt in} operator also works on lists. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> cheeses = ['Cheddar', 'Edam', 'Gouda'] >>> 'Edam' in cheeses True >>> 'Brie' in cheeses False -\end{verbatim} +\end{lstlisting} \section{Traversing a list} @@ -7466,10 +7468,10 @@ \section{Traversing a list} The most common way to traverse the elements of a list is with a {\tt for} loop. The syntax is the same as for strings: -\begin{verbatim} +\begin{lstlisting}[language=python] for cheese in cheeses: print(cheese) -\end{verbatim} +\end{lstlisting} % This works well if you only need to read the elements of the list. But if you want to write or update the elements, you @@ -7478,10 +7480,10 @@ \section{Traversing a list} \index{looping!with indices} \index{index!looping with} -\begin{verbatim} +\begin{lstlisting}[language=python] for i in range(len(numbers)): numbers[i] = numbers[i] * 2 -\end{verbatim} +\end{lstlisting} % This loop traverses the list and updates each element. {\tt len} returns the number of elements in the list. {\tt range} returns @@ -7495,10 +7497,10 @@ \section{Traversing a list} A {\tt for} loop over an empty list never runs the body: -\begin{verbatim} +\begin{lstlisting}[language=python] for x in []: print('This never happens.') -\end{verbatim} +\end{lstlisting} % Although a list can contain another list, the nested list still counts as a single element. The length of this list is @@ -7506,9 +7508,9 @@ \section{Traversing a list} \index{nested list} \index{list!nested} -\begin{verbatim} +\begin{lstlisting}[language=python] ['spam', 1, ['Brie', 'Roquefort', 'Pol le Veq'], [1, 2, 3]] -\end{verbatim} +\end{lstlisting} @@ -7519,24 +7521,24 @@ \section{List operations} \index{concatenation!list} \index{list!concatenation} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> a = [1, 2, 3] >>> b = [4, 5, 6] >>> c = a + b >>> c [1, 2, 3, 4, 5, 6] -\end{verbatim} +\end{lstlisting} % The {\tt *} operator repeats a list a given number of times: \index{repetition!list} \index{list!repetition} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> [0] * 4 [0, 0, 0, 0] >>> [1, 2, 3] * 3 [1, 2, 3, 1, 2, 3, 1, 2, 3] -\end{verbatim} +\end{lstlisting} % The first example repeats {\tt [0]} four times. The second example repeats the list {\tt [1, 2, 3]} three times. @@ -7551,7 +7553,7 @@ \section{List slices} The slice operator also works on lists: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = ['a', 'b', 'c', 'd', 'e', 'f'] >>> t[1:3] ['b', 'c'] @@ -7559,7 +7561,7 @@ \section{List slices} ['a', 'b', 'c', 'd'] >>> t[3:] ['d', 'e', 'f'] -\end{verbatim} +\end{lstlisting} % If you omit the first index, the slice starts at the beginning. If you omit the second, the slice goes to the end. So if you @@ -7568,10 +7570,10 @@ \section{List slices} \index{slice!copy} \index{copy!slice} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t[:] ['a', 'b', 'c', 'd', 'e', 'f'] -\end{verbatim} +\end{lstlisting} % Since lists are mutable, it is often useful to make a copy before performing operations that modify lists. @@ -7582,34 +7584,34 @@ \section{List slices} \index{slice!update} \index{update!slice} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = ['a', 'b', 'c', 'd', 'e', 'f'] >>> t[1:3] = ['x', 'y'] >>> t ['a', 'x', 'y', 'd', 'e', 'f'] -\end{verbatim} +\end{lstlisting} % % You can add elements to a list by squeezing them into an empty % slice: -% % \begin{verbatim} +% % \begin{lstlisting}[language=python] % >>> t = ['a', 'd', 'e', 'f'] % >>> t[1:1] = ['b', 'c'] % >>> print t % ['a', 'b', 'c', 'd', 'e', 'f'] -% \end{verbatim} +% \end{lstlisting} % \afterverb % % And you can remove elements from a list by assigning the empty list to % them: -% % \begin{verbatim} +% % \begin{lstlisting}[language=python] % >>> t = ['a', 'b', 'c', 'd', 'e', 'f'] % >>> t[1:3] = [] % >>> print t % ['a', 'd', 'e', 'f'] -% \end{verbatim} +% \end{lstlisting} % \afterverb % % But both of those operations can be expressed more clearly @@ -7625,25 +7627,25 @@ \section{List methods} \index{append method} \index{method!append} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = ['a', 'b', 'c'] >>> t.append('d') >>> t ['a', 'b', 'c', 'd'] -\end{verbatim} +\end{lstlisting} % {\tt extend} takes a list as an argument and appends all of the elements: \index{extend method} \index{method!extend} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t1 = ['a', 'b', 'c'] >>> t2 = ['d', 'e'] >>> t1.extend(t2) >>> t1 ['a', 'b', 'c', 'd', 'e'] -\end{verbatim} +\end{lstlisting} % This example leaves {\tt t2} unmodified. @@ -7651,12 +7653,12 @@ \section{List methods} \index{sort method} \index{method!sort} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = ['d', 'c', 'e', 'b', 'a'] >>> t.sort() >>> t ['a', 'b', 'c', 'd', 'e'] -\end{verbatim} +\end{lstlisting} % Most list methods are void; they modify the list and return {\tt None}. If you accidentally write {\tt t = t.sort()}, you will be disappointed @@ -7674,13 +7676,13 @@ \section{Map, filter and reduce} % see add.py -\begin{verbatim} +\begin{lstlisting}[language=python] def add_all(t): total = 0 for x in t: total += x return total -\end{verbatim} +\end{lstlisting} % {\tt total} is initialized to 0. Each time through the loop, {\tt x} gets one element from the list. The {\tt +=} operator @@ -7691,15 +7693,15 @@ \section{Map, filter and reduce} \index{assignment!augmented} \index{augmented assignment} -\begin{verbatim} +\begin{lstlisting}[language=python] total += x -\end{verbatim} +\end{lstlisting} % is equivalent to -\begin{verbatim} +\begin{lstlisting}[language=python] total = total + x -\end{verbatim} +\end{lstlisting} % As the loop runs, {\tt total} accumulates the sum of the elements; a variable used this way is sometimes called an @@ -7709,11 +7711,11 @@ \section{Map, filter and reduce} Adding up the elements of a list is such a common operation that Python provides it as a built-in function, {\tt sum}: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = [1, 2, 3] >>> sum(t) 6 -\end{verbatim} +\end{lstlisting} % An operation like this that combines a sequence of elements into a single value is sometimes called {\bf reduce}. @@ -7725,13 +7727,13 @@ \section{Map, filter and reduce} another. For example, the following function takes a list of strings and returns a new list that contains capitalized strings: -\begin{verbatim} +\begin{lstlisting}[language=python] def capitalize_all(t): res = [] for s in t: res.append(s.capitalize()) return res -\end{verbatim} +\end{lstlisting} % {\tt res} is initialized with an empty list; each time through the loop, we append the next element. So {\tt res} is another @@ -7751,14 +7753,14 @@ \section{Map, filter and reduce} function takes a list of strings and returns a list that contains only the uppercase strings: -\begin{verbatim} +\begin{lstlisting}[language=python] def only_upper(t): res = [] for s in t: if s.isupper(): res.append(s) return res -\end{verbatim} +\end{lstlisting} % {\tt isupper} is a string method that returns {\tt True} if the string contains only upper case letters. @@ -7780,14 +7782,14 @@ \section{Deleting elements} \index{pop method} \index{method!pop} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = ['a', 'b', 'c'] >>> x = t.pop(1) >>> t ['a', 'c'] >>> x 'b' -\end{verbatim} +\end{lstlisting} % {\tt pop} modifies the list and returns the element that was removed. If you don't provide an index, it deletes and returns the @@ -7798,24 +7800,24 @@ \section{Deleting elements} \index{del operator} \index{operator!del} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = ['a', 'b', 'c'] >>> del t[1] >>> t ['a', 'c'] -\end{verbatim} +\end{lstlisting} % If you know the element you want to remove (but not the index), you can use {\tt remove}: \index{remove method} \index{method!remove} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = ['a', 'b', 'c'] >>> t.remove('b') >>> t ['a', 'c'] -\end{verbatim} +\end{lstlisting} % The return value from {\tt remove} is {\tt None}. \index{None special value} @@ -7824,12 +7826,12 @@ \section{Deleting elements} To remove more than one element, you can use {\tt del} with a slice index: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = ['a', 'b', 'c', 'd', 'e', 'f'] >>> del t[1:5] >>> t ['a', 'f'] -\end{verbatim} +\end{lstlisting} % As usual, the slice selects all the elements up to but not including the second index. @@ -7848,12 +7850,12 @@ \section{Lists and strings} \index{list!function} \index{function!list} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> s = 'spam' >>> t = list(s) >>> t ['s', 'p', 'a', 'm'] -\end{verbatim} +\end{lstlisting} % Because {\tt list} is the name of a built-in function, you should avoid using it as a variable name. I also avoid {\tt l} because @@ -7865,12 +7867,12 @@ \section{Lists and strings} \index{split method} \index{method!split} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> s = 'pining for the fjords' >>> t = s.split() >>> t ['pining', 'for', 'the', 'fjords'] -\end{verbatim} +\end{lstlisting} % An optional argument called a {\bf delimiter} specifies which characters to use as word boundaries. @@ -7880,13 +7882,13 @@ \section{Lists and strings} \index{argument!optional} \index{delimiter} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> s = 'spam-spam-spam' >>> delimiter = '-' >>> t = s.split(delimiter) >>> t ['spam', 'spam', 'spam'] -\end{verbatim} +\end{lstlisting} % {\tt join} is the inverse of {\tt split}. It takes a list of strings and @@ -7897,13 +7899,13 @@ \section{Lists and strings} \index{method!join} \index{concatenation} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = ['pining', 'for', 'the', 'fjords'] >>> delimiter = ' ' >>> s = delimiter.join(t) >>> s 'pining for the fjords' -\end{verbatim} +\end{lstlisting} % In this case the delimiter is a space character, so {\tt join} puts a space between words. To concatenate @@ -7920,10 +7922,10 @@ \section{Objects and values} If we run these assignment statements: -\begin{verbatim} +\begin{lstlisting}[language=python] a = 'banana' b = 'banana' -\end{verbatim} +\end{lstlisting} % We know that {\tt a} and {\tt b} both refer to a string, but we don't @@ -7947,23 +7949,23 @@ \section{Objects and values} To check whether two variables refer to the same object, you can use the {\tt is} operator. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> a = 'banana' >>> b = 'banana' >>> a is b True -\end{verbatim} +\end{lstlisting} % In this example, Python only created one string object, and both {\tt a} and {\tt b} refer to it. But when you create two lists, you get two objects: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> a = [1, 2, 3] >>> b = [1, 2, 3] >>> a is b False -\end{verbatim} +\end{lstlisting} % So the state diagram looks like Figure~\ref{fig.list2}. \index{state diagram} @@ -8001,12 +8003,12 @@ \section{Aliasing} If {\tt a} refers to an object and you assign {\tt b = a}, then both variables refer to the same object: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> a = [1, 2, 3] >>> b = a >>> b is a True -\end{verbatim} +\end{lstlisting} % The state diagram looks like Figure~\ref{fig.list3}. \index{state diagram} @@ -8031,11 +8033,11 @@ \section{Aliasing} If the aliased object is mutable, changes made with one alias affect the other: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> b[0] = 42 >>> a [42, 2, 3] -\end{verbatim} +\end{lstlisting} % Although this behavior can be useful, it is error-prone. In general, it is safer to avoid aliasing when you are working with mutable @@ -8045,10 +8047,10 @@ \section{Aliasing} For immutable objects like strings, aliasing is not as much of a problem. In this example: -\begin{verbatim} +\begin{lstlisting}[language=python] a = 'banana' b = 'banana' -\end{verbatim} +\end{lstlisting} % It almost never makes a difference whether {\tt a} and {\tt b} refer to the same string or not. @@ -8067,19 +8069,19 @@ \section{List arguments} the change. For example, \verb"delete_head" removes the first element from a list: -\begin{verbatim} +\begin{lstlisting}[language=python] def delete_head(t): del t[0] -\end{verbatim} +\end{lstlisting} % Here's how it is used: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> letters = ['a', 'b', 'c'] >>> delete_head(letters) >>> letters ['b', 'c'] -\end{verbatim} +\end{lstlisting} % The parameter {\tt t} and the variable {\tt letters} are aliases for the same object. The stack diagram looks like @@ -8108,26 +8110,26 @@ \section{List arguments} Here's an example using {\tt append}: % -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t1 = [1, 2] >>> t2 = t1.append(3) >>> t1 [1, 2, 3] >>> t2 None -\end{verbatim} +\end{lstlisting} % The return value from {\tt append} is {\tt None}. Here's an example using the {\tt +} operator: % -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t3 = t1 + [4] >>> t1 [1, 2, 3] >>> t3 [1, 2, 3, 4] -\end{verbatim} +\end{lstlisting} % The result of the operator is a new list, and the original list is unchanged. @@ -8136,22 +8138,22 @@ \section{List arguments} are supposed to modify lists. For example, this function {\em does not} delete the head of a list: % -\begin{verbatim} +\begin{lstlisting}[language=python] def bad_delete_head(t): t = t[1:] # WRONG! -\end{verbatim} +\end{lstlisting} % The slice operator creates a new list and the assignment makes {\tt t} refer to it, but that doesn't affect the caller. \index{slice operator} \index{operator!slice} % -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t4 = [1, 2, 3] >>> bad_delete_head(t4) >>> t4 [1, 2, 3] -\end{verbatim} +\end{lstlisting} % At the beginning of \verb"bad_delete_head", {\tt t} and {\tt t4} refer to the same list. At the end, {\tt t} refers to a new list, @@ -8162,20 +8164,20 @@ \section{List arguments} example, {\tt tail} returns all but the first element of a list: -\begin{verbatim} +\begin{lstlisting}[language=python] def tail(t): return t[1:] -\end{verbatim} +\end{lstlisting} % This function leaves the original list unmodified. Here's how it is used: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> letters = ['a', 'b', 'c'] >>> rest = tail(letters) >>> rest ['b', 'c'] -\end{verbatim} +\end{lstlisting} @@ -8194,15 +8196,15 @@ \section{Debugging} If you are used to writing string code like this: -\begin{verbatim} +\begin{lstlisting}[language=python] word = word.strip() -\end{verbatim} +\end{lstlisting} It is tempting to write list code like this: -\begin{verbatim} +\begin{lstlisting}[language=python] t = t.sort() # WRONG! -\end{verbatim} +\end{lstlisting} \index{sort method} \index{method!sort} @@ -8223,20 +8225,20 @@ \section{Debugging} the {\tt +} operator. Assuming that {\tt t} is a list and {\tt x} is a list element, these are correct: -\begin{verbatim} +\begin{lstlisting}[language=python] t.append(x) t = t + [x] t += [x] -\end{verbatim} +\end{lstlisting} And these are wrong: -\begin{verbatim} +\begin{lstlisting}[language=python] t.append([x]) # WRONG! t = t.append(x) # WRONG! t + [x] # WRONG! t = t + x # WRONG! -\end{verbatim} +\end{lstlisting} Try out each of these examples in interactive mode to make sure you understand what they do. Notice that only the last @@ -8252,7 +8254,7 @@ \section{Debugging} the argument, but you need to keep the original list as well, you can make a copy. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = [3, 1, 2] >>> t2 = t[:] >>> t2.sort() @@ -8260,20 +8262,20 @@ \section{Debugging} [3, 1, 2] >>> t2 [1, 2, 3] -\end{verbatim} +\end{lstlisting} In this example you could also use the built-in function {\tt sorted}, which returns a new, sorted list and leaves the original alone. \index{sorted!function} \index{function!sorted} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t2 = sorted(t) >>> t [3, 1, 2] >>> t2 [1, 2, 3] -\end{verbatim} +\end{lstlisting} \end{enumerate} @@ -8352,12 +8354,13 @@ \section{Exercises} Write a function called \verb"nested_sum" that takes a list of lists of integers and adds up the elements from all of the nested lists. For example: - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] >>> t = [[1, 2], [3], [4, 5, 6]] >>> nested_sum(t) 21 -\end{verbatim} +\end{lstlisting}} + \end{exercise} @@ -8369,12 +8372,12 @@ \section{Exercises} returns the cumulative sum; that is, a new list where the $i$th element is the sum of the first $i+1$ elements from the original list. For example: - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] >>> t = [1, 2, 3] >>> cumsum(t) [1, 3, 6] -\end{verbatim} +\end{lstlisting}} \end{exercise} @@ -8383,12 +8386,12 @@ \section{Exercises} Write a function called \verb"middle" that takes a list and returns a new list that contains all but the first and last elements. For example: - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] >>> t = [1, 2, 3, 4] >>> middle(t) [2, 3] -\end{verbatim} +\end{lstlisting}} \end{exercise} @@ -8397,13 +8400,13 @@ \section{Exercises} Write a function called \verb"chop" that takes a list, modifies it by removing the first and last elements, and returns {\tt None}. For example: - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] >>> t = [1, 2, 3, 4] >>> chop(t) >>> t [2, 3] -\end{verbatim} +\end{lstlisting}} \end{exercise} @@ -8412,13 +8415,13 @@ \section{Exercises} Write a function called \verb"is_sorted" that takes a list as a parameter and returns {\tt True} if the list is sorted in ascending order and {\tt False} otherwise. For example: - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] >>> is_sorted([1, 2, 2]) True >>> is_sorted(['b', 'a']) False -\end{verbatim} +\end{lstlisting}} \end{exercise} @@ -8593,44 +8596,44 @@ \section{A dictionary is a mapping} \index{dict function} \index{function!dict} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> eng2sp = dict() >>> eng2sp {} -\end{verbatim} +\end{lstlisting} The squiggly-brackets, \verb"{}", represent an empty dictionary. To add items to the dictionary, you can use square brackets: \index{squiggly bracket} \index{bracket!squiggly} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> eng2sp['one'] = 'uno' -\end{verbatim} +\end{lstlisting} % This line creates an item that maps from the key \verb"'one'" to the value \verb"'uno'". If we print the dictionary again, we see a key-value pair with a colon between the key and value: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> eng2sp {'one': 'uno'} -\end{verbatim} +\end{lstlisting} % This output format is also an input format. For example, you can create a new dictionary with three items: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> eng2sp = {'one': 'uno', 'two': 'dos', 'three': 'tres'} -\end{verbatim} +\end{lstlisting} % But if you print {\tt eng2sp}, you might be surprised: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> eng2sp {'one': 'uno', 'three': 'tres', 'two': 'dos'} -\end{verbatim} +\end{lstlisting} % The order of the key-value pairs might not be the same. If you type the same example on your computer, you might get a @@ -8641,10 +8644,10 @@ \section{A dictionary is a mapping} the elements of a dictionary are never indexed with integer indices. Instead, you use the keys to look up the corresponding values: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> eng2sp['two'] 'dos' -\end{verbatim} +\end{lstlisting} % The key \verb"'two'" always maps to the value \verb"'dos'" so the order of the items doesn't matter. @@ -8653,20 +8656,20 @@ \section{A dictionary is a mapping} \index{exception!KeyError} \index{KeyError} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> eng2sp['four'] KeyError: 'four' -\end{verbatim} +\end{lstlisting} % The {\tt len} function works on dictionaries; it returns the number of key-value pairs: \index{len function} \index{function!len} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> len(eng2sp) 3 -\end{verbatim} +\end{lstlisting} % The {\tt in} operator works on dictionaries, too; it tells you whether something appears as a {\em key} in the dictionary (appearing @@ -8675,12 +8678,12 @@ \section{A dictionary is a mapping} \index{in operator} \index{operator!in} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> 'one' in eng2sp True >>> 'uno' in eng2sp False -\end{verbatim} +\end{lstlisting} % To see whether something appears as a value in a dictionary, you can use the method {\tt values}, which returns a collection of @@ -8688,11 +8691,11 @@ \section{A dictionary is a mapping} \index{values method} \index{method!values} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> vals = eng2sp.values() >>> 'uno' in vals True -\end{verbatim} +\end{lstlisting} % The {\tt in} operator uses different algorithms for lists and dictionaries. For lists, it searches the elements of the list in @@ -8745,7 +8748,7 @@ \section{Dictionary as a collection of counters} Here is what the code might look like: -\begin{verbatim} +\begin{lstlisting}[language=python] def histogram(s): d = dict() for c in s: @@ -8754,7 +8757,7 @@ \section{Dictionary as a collection of counters} else: d[c] += 1 return d -\end{verbatim} +\end{lstlisting} % The name of the function is {\tt histogram}, which is a statistical term for a collection of counters (or frequencies). @@ -8772,11 +8775,11 @@ \section{Dictionary as a collection of counters} Here's how it works: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> h = histogram('brontosaurus') >>> h {'a': 1, 'b': 1, 'o': 2, 'n': 1, 's': 2, 'r': 2, 'u': 2, 't': 1} -\end{verbatim} +\end{lstlisting} % The histogram indicates that the letters \verb"'a'" and \verb"'b'" appear once; \verb"'o'" appears twice, and so on. @@ -8789,7 +8792,7 @@ \section{Dictionary as a collection of counters} {\tt get} returns the corresponding value; otherwise it returns the default value. For example: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> h = histogram('a') >>> h {'a': 1} @@ -8797,7 +8800,7 @@ \section{Dictionary as a collection of counters} 1 >>> h.get('c', 0) 0 -\end{verbatim} +\end{lstlisting} % As an exercise, use {\tt get} to write {\tt histogram} more concisely. You should be able to eliminate the {\tt if} statement. @@ -8812,15 +8815,15 @@ \section{Looping and dictionaries} the keys of the dictionary. For example, \verb"print_hist" prints each key and the corresponding value: -\begin{verbatim} +\begin{lstlisting}[language=python] def print_hist(h): for c in h: print(c, h[c]) -\end{verbatim} +\end{lstlisting} % Here's what the output looks like: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> h = histogram('parrot') >>> print_hist(h) a 1 @@ -8828,14 +8831,14 @@ \section{Looping and dictionaries} r 2 t 1 o 1 -\end{verbatim} +\end{lstlisting} % Again, the keys are in no particular order. To traverse the keys in sorted order, you can use the built-in function {\tt sorted}: \index{sorted!function} \index{function!sorted} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> for key in sorted(h): ... print(key, h[key]) a 1 @@ -8843,7 +8846,7 @@ \section{Looping and dictionaries} p 1 r 2 t 1 -\end{verbatim} +\end{lstlisting} %TODO: get this on Atlas @@ -8869,13 +8872,13 @@ \section{Reverse lookup} Here is a function that takes a value and returns the first key that maps to that value: -\begin{verbatim} +\begin{lstlisting}[language=python] def reverse_lookup(d, v): for k in d: if d[k] == v: return k raise LookupError() -\end{verbatim} +\end{lstlisting} % This function is yet another example of the search pattern, but it uses a feature we haven't seen before, {\tt raise}. The @@ -8892,12 +8895,12 @@ \section{Reverse lookup} Here is an example of a successful reverse lookup: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> h = histogram('parrot') >>> key = reverse_lookup(h, 2) >>> key 'r' -\end{verbatim} +\end{lstlisting} % And an unsuccessful one: @@ -8905,8 +8908,7 @@ \section{Reverse lookup} >>> key = reverse_lookup(h, 3) Traceback (most recent call last): File "", line 1, in - File "", line 5, in reverse_lookup -LookupError + File "", line 5, in reverse_lookup LookupError \end{verbatim} % The effect when you raise an exception is the same as when @@ -8917,12 +8919,12 @@ \section{Reverse lookup} When you raise an exception, you can provide a detailed error message as an optional argument. For example: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> raise LookupError('value does not appear in the dictionary') Traceback (most recent call last): - File "", line 1, in ? -LookupError: value does not appear in the dictionary -\end{verbatim} + <@\textcolor{black}{File "", line 1, in ? +LookupError: value does not appear in the dictionary}@> +\end{lstlisting} % A reverse lookup is much slower than a forward lookup; if you have to do it often, or if the dictionary gets big, the performance @@ -8943,7 +8945,7 @@ \section{Dictionaries and lists} Here is a function that inverts a dictionary: -\begin{verbatim} +\begin{lstlisting}[language=python] def invert_dict(d): inverse = dict() for key in d: @@ -8953,7 +8955,7 @@ \section{Dictionaries and lists} else: inverse[val].append(key) return inverse -\end{verbatim} +\end{lstlisting} % Each time through the loop, {\tt key} gets a key from {\tt d} and {\tt val} gets the corresponding value. If {\tt val} is not in {\tt @@ -8964,14 +8966,14 @@ \section{Dictionaries and lists} Here is an example: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> hist = histogram('parrot') >>> hist {'a': 1, 'p': 1, 'r': 2, 't': 1, 'o': 1} >>> inverse = invert_dict(hist) >>> inverse {1: ['a', 'p', 't', 'o'], 2: ['r']} -\end{verbatim} +\end{lstlisting} \begin{figure} \centerline @@ -8994,14 +8996,14 @@ \section{Dictionaries and lists} \index{exception!TypeError} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = [1, 2, 3] >>> d = dict() >>> d[t] = 'oops' Traceback (most recent call last): File "", line 1, in ? TypeError: list objects are unhashable -\end{verbatim} +\end{lstlisting} % I mentioned earlier that a dictionary is implemented using a hashtable and that means that the keys have to be {\bf hashable}. @@ -9069,7 +9071,7 @@ \section{Memos} that is stored for later use is called a {\bf memo}. Here is a ``memoized'' version of {\tt fibonacci}: -\begin{verbatim} +\begin{lstlisting}[language=python] known = {0:0, 1:1} def fibonacci(n): @@ -9079,7 +9081,7 @@ \section{Memos} res = fibonacci(n-1) + fibonacci(n-2) known[n] = res return res -\end{verbatim} +\end{lstlisting} % {\tt known} is a dictionary that keeps track of the Fibonacci numbers we already know. It starts with @@ -9114,25 +9116,25 @@ \section{Global variables} a flag named {\tt verbose} to control the level of detail in the output: -\begin{verbatim} +\begin{lstlisting}[language=python] verbose = True def example1(): if verbose: print('Running example1') -\end{verbatim} +\end{lstlisting} % If you try to reassign a global variable, you might be surprised. The following example is supposed to keep track of whether the function has been called: \index{reassignment} -\begin{verbatim} +\begin{lstlisting}[language=python] been_called = False def example2(): been_called = True # WRONG -\end{verbatim} +\end{lstlisting} % But if you run it you will see that the value of \verb"been_called" doesn't change. The problem is that {\tt example2} creates a new local @@ -9145,13 +9147,13 @@ \section{Global variables} To reassign a global variable inside a function you have to {\bf declare} the global variable before you use it: -\begin{verbatim} +\begin{lstlisting}[language=python] been_called = False def example2(): global been_called been_called = True -\end{verbatim} +\end{lstlisting} % The {\bf global statement} tells the interpreter something like, ``In this function, when I say \verb"been_called", I @@ -9161,52 +9163,52 @@ \section{Global variables} Here's an example that tries to update a global variable: -\begin{verbatim} +\begin{lstlisting}[language=python] count = 0 def example3(): count = count + 1 # WRONG -\end{verbatim} +\end{lstlisting} % If you run it you get: \index{UnboundLocalError} \index{exception!UnboundLocalError} -\begin{verbatim} +\begin{lstlisting}[language=python] UnboundLocalError: local variable 'count' referenced before assignment -\end{verbatim} +\end{lstlisting} % Python assumes that {\tt count} is local, and under that assumption you are reading it before writing it. The solution, again, is to declare {\tt count} global. \index{counter} -\begin{verbatim} +\begin{lstlisting}[language=python] def example3(): global count count += 1 -\end{verbatim} +\end{lstlisting} % If a global variable refers to a mutable value, you can modify the value without declaring the variable: \index{mutability} -\begin{verbatim} +\begin{lstlisting}[language=python] known = {0:0, 1:1} def example4(): known[2] = 1 -\end{verbatim} +\end{lstlisting} % So you can add, remove and replace elements of a global list or dictionary, but if you want to reassign the variable, you have to declare it: -\begin{verbatim} +\begin{lstlisting}[language=python] def example5(): global known known = dict() -\end{verbatim} +\end{lstlisting} % Global variables can be useful, but if you have a lot of them, and you modify them frequently, they can make programs @@ -9514,56 +9516,56 @@ \section{Tuples are immutable} Syntactically, a tuple is a comma-separated list of values: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = 'a', 'b', 'c', 'd', 'e' -\end{verbatim} +\end{lstlisting} % Although it is not necessary, it is common to enclose tuples in parentheses: \index{parentheses!tuples in} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = ('a', 'b', 'c', 'd', 'e') -\end{verbatim} +\end{lstlisting} % To create a tuple with a single element, you have to include a final comma: \index{singleton} \index{tuple!singleton} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t1 = 'a', >>> type(t1) - -\end{verbatim} +<@\textcolor{black}{}@> +\end{lstlisting} % A value in parentheses is not a tuple: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t2 = ('a') >>> type(t2) - -\end{verbatim} +<@\textcolor{black}{}@> +\end{lstlisting} % Another way to create a tuple is the built-in function {\tt tuple}. With no argument, it creates an empty tuple: \index{tuple function} \index{function!tuple} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = tuple() >>> t () -\end{verbatim} +\end{lstlisting} % If the argument is a sequence (string, list or tuple), the result is a tuple with the elements of the sequence: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = tuple('lupins') >>> t ('l', 'u', 'p', 'i', 'n', 's') -\end{verbatim} +\end{lstlisting} % Because {\tt tuple} is the name of a built-in function, you should avoid using it as a variable name. @@ -9573,11 +9575,11 @@ \section{Tuples are immutable} \index{bracket operator} \index{operator!bracket} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = ('a', 'b', 'c', 'd', 'e') >>> t[0] 'a' -\end{verbatim} +\end{lstlisting} % And the slice operator selects a range of elements. \index{slice operator} @@ -9585,10 +9587,10 @@ \section{Tuples are immutable} \index{tuple!slice} \index{slice!tuple} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t[1:3] ('b', 'c') -\end{verbatim} +\end{lstlisting} % But if you try to modify one of the elements of the tuple, you get an error: @@ -9597,19 +9599,19 @@ \section{Tuples are immutable} \index{item assignment} \index{assignment!item} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t[0] = 'A' TypeError: object doesn't support item assignment -\end{verbatim} +\end{lstlisting} % Because tuples are immutable, you can't modify the elements. But you can replace one tuple with another: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = ('A',) + t[1:] >>> t ('A', 'b', 'c', 'd', 'e') -\end{verbatim} +\end{lstlisting} % This statement makes a new tuple and then makes {\tt t} refer to it. @@ -9621,12 +9623,12 @@ \section{Tuples are immutable} \index{comparison!tuple} \index{tuple!comparison} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> (0, 1, 2) < (0, 3, 4) True >>> (0, 1, 2000000) < (0, 3, 4) True -\end{verbatim} +\end{lstlisting} @@ -9641,17 +9643,17 @@ \section{Tuple assignment} With conventional assignments, you have to use a temporary variable. For example, to swap {\tt a} and {\tt b}: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> temp = a >>> a = b >>> b = temp -\end{verbatim} +\end{lstlisting} % This solution is cumbersome; {\bf tuple assignment} is more elegant: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> a, b = b, a -\end{verbatim} +\end{lstlisting} % The left side is a tuple of variables; the right side is a tuple of expressions. Each value is assigned to its respective variable. @@ -9663,10 +9665,10 @@ \section{Tuple assignment} \index{exception!ValueError} \index{ValueError} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> a, b = 1, 2, 3 ValueError: too many values to unpack -\end{verbatim} +\end{lstlisting} % More generally, the right side can be any kind of sequence (string, list or tuple). For example, to split an email address @@ -9675,21 +9677,21 @@ \section{Tuple assignment} \index{method!split} \index{email address} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> addr = 'monty@python.org' >>> uname, domain = addr.split('@') -\end{verbatim} +\end{lstlisting} % The return value from {\tt split} is a list with two elements; the first element is assigned to {\tt uname}, the second to {\tt domain}. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> uname 'monty' >>> domain 'python.org' -\end{verbatim} +\end{lstlisting} % \section{Tuples as return values} @@ -9710,30 +9712,30 @@ \section{Tuples as return values} returns a tuple of two values, the quotient and remainder. You can store the result as a tuple: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = divmod(7, 3) >>> t (2, 1) -\end{verbatim} +\end{lstlisting} % Or use tuple assignment to store the elements separately: \index{tuple assignment} \index{assignment!tuple} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> quot, rem = divmod(7, 3) >>> quot 2 >>> rem 1 -\end{verbatim} +\end{lstlisting} % Here is an example of a function that returns a tuple: -\begin{verbatim} +\begin{lstlisting}[language=python] def min_max(t): return min(t), max(t) -\end{verbatim} +\end{lstlisting} % {\tt max} and {\tt min} are built-in functions that find the largest and smallest elements of a sequence. \verb"min_max" @@ -9757,18 +9759,18 @@ \section{Variable-length argument tuples} a tuple. For example, {\tt printall} takes any number of arguments and prints them: -\begin{verbatim} +\begin{lstlisting}[language=python] def printall(*args): print(args) -\end{verbatim} +\end{lstlisting} % The gather parameter can have any name you like, but {\tt args} is conventional. Here's how the function works: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> printall(1, 2.0, '3') (1, 2.0, '3') -\end{verbatim} +\end{lstlisting} % The complement of gather is {\bf scatter}. If you have a sequence of values and you want to pass it to a function @@ -9780,18 +9782,18 @@ \section{Variable-length argument tuples} \index{TypeError} \index{exception!TypeError} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = (7, 3) >>> divmod(t) -TypeError: divmod expected 2 arguments, got 1 -\end{verbatim} +<@\textcolor{black}{TypeError: divmod expected 2 arguments, got 1}@> +\end{lstlisting} % But if you scatter the tuple, it works: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> divmod(*t) (2, 1) -\end{verbatim} +\end{lstlisting} % Many of the built-in functions use variable-length argument tuples. For example, {\tt max} @@ -9801,19 +9803,19 @@ \section{Variable-length argument tuples} \index{min function} \index{function!min} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> max(1, 2, 3) 3 -\end{verbatim} +\end{lstlisting} % But {\tt sum} does not. \index{sum function} \index{function!sum} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> sum(1, 2, 3) -TypeError: sum expected at most 2 arguments, got 3 -\end{verbatim} +<@\textcolor{black}{TypeError: sum expected at most 2 arguments, got 3}@> +\end{lstlisting} % As an exercise, write a function called \verb"sum_all" that takes any number of arguments and returns their sum. @@ -9829,24 +9831,24 @@ \section{Lists and tuples} This example zips a string and a list: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> s = 'abc' >>> t = [0, 1, 2] >>> zip(s, t) - -\end{verbatim} +<@\textcolor{black}{}@> +\end{lstlisting} % The result is a {\bf zip object} that knows how to iterate through the pairs. The most common use of {\tt zip} is in a {\tt for} loop: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> for pair in zip(s, t): ... print(pair) ... ('a', 0) ('b', 1) ('c', 2) -\end{verbatim} +\end{lstlisting} % A zip object is a kind of {\bf iterator}, which is any object that iterates through a sequence. Iterators are similar to lists in some @@ -9857,10 +9859,10 @@ \section{Lists and tuples} If you want to use list operators and methods, you can use a zip object to make a list: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> list(zip(s, t)) [('a', 0), ('b', 1), ('c', 2)] -\end{verbatim} +\end{lstlisting} % The result is a list of tuples; in this example, each tuple contains a character from the string and the corresponding element from @@ -9870,10 +9872,10 @@ \section{Lists and tuples} If the sequences are not the same length, the result has the length of the shorter one. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> list(zip('Anne', 'Elk')) [('A', 'E'), ('n', 'l'), ('n', 'k')] -\end{verbatim} +\end{lstlisting} % You can use tuple assignment in a {\tt for} loop to traverse a list of tuples: @@ -9881,22 +9883,22 @@ \section{Lists and tuples} \index{tuple assignment} \index{assignment!tuple} -\begin{verbatim} +\begin{lstlisting}[language=python] t = [('a', 0), ('b', 1), ('c', 2)] for letter, number in t: print(number, letter) -\end{verbatim} +\end{lstlisting} % Each time through the loop, Python selects the next tuple in the list and assigns the elements to {\tt letter} and {\tt number}. The output of this loop is: \index{loop} -\begin{verbatim} +\begin{lstlisting}[language=python] 0 a 1 b 2 c -\end{verbatim} +\end{lstlisting} % If you combine {\tt zip}, {\tt for} and tuple assignment, you get a useful idiom for traversing two (or more) sequences at the same @@ -9905,13 +9907,13 @@ \section{Lists and tuples} such that {\tt t1[i] == t2[i]}: \index{for loop} -\begin{verbatim} +\begin{lstlisting}[language=python] def has_match(t1, t2): for x, y in zip(t1, t2): if x == y: return True return False -\end{verbatim} +\end{lstlisting} % If you need to traverse the elements of a sequence and their indices, you can use the built-in function {\tt enumerate}: @@ -9919,21 +9921,21 @@ \section{Lists and tuples} \index{enumerate function} \index{function!enumerate} -\begin{verbatim} +\begin{lstlisting}[language=python] for index, element in enumerate('abc'): print(index, element) -\end{verbatim} +\end{lstlisting} % The result from {\tt enumerate} is an enumerate object, which iterates a sequence of pairs; each pair contains an index (starting from 0) and an element from the given sequence. In this example, the output is -\begin{verbatim} +\begin{lstlisting}[language=python] 0 a 1 b 2 c -\end{verbatim} +\end{lstlisting} % Again. \index{iterator} @@ -9951,26 +9953,26 @@ \section{Dictionaries and tuples} Dictionaries have a method called {\tt items} that returns a sequence of tuples, where each tuple is a key-value pair. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> d = {'a':0, 'b':1, 'c':2} >>> t = d.items() >>> t dict_items([('c', 2), ('a', 0), ('b', 1)]) -\end{verbatim} +\end{lstlisting} % The result is a \verb"dict_items" object, which is an iterator that iterates the key-value pairs. You can use it in a {\tt for} loop like this: \index{iterator} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> for key, value in d.items(): ... print(key, value) ... c 2 a 0 b 1 -\end{verbatim} +\end{lstlisting} % As you should expect from a dictionary, the items are in no particular order. @@ -9978,22 +9980,22 @@ \section{Dictionaries and tuples} Going in the other direction, you can use a list of tuples to initialize a new dictionary: \index{dictionary!initialize} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = [('a', 0), ('c', 2), ('b', 1)] >>> d = dict(t) >>> d {'a': 0, 'c': 2, 'b': 1} -\end{verbatim} +\end{lstlisting} Combining {\tt dict} with {\tt zip} yields a concise way to create a dictionary: \index{zip function!use with dict} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> d = dict(zip('abc', range(3))) >>> d {'a': 0, 'c': 2, 'b': 1} -\end{verbatim} +\end{lstlisting} % The dictionary method {\tt update} also takes a list of tuples and adds them, as key-value pairs, to an existing dictionary. @@ -10010,18 +10012,18 @@ \section{Dictionaries and tuples} \index{tuple!as key in dictionary} \index{hashable} -\begin{verbatim} +\begin{lstlisting}[language=python] directory[last, first] = number -\end{verbatim} +\end{lstlisting} % The expression in brackets is a tuple. We could use tuple assignment to traverse this dictionary. \index{tuple!in brackets} -\begin{verbatim} +\begin{lstlisting}[language=python] for last, first in directory: print(first, last, directory[last,first]) -\end{verbatim} +\end{lstlisting} % This loop traverses the keys in {\tt directory}, which are tuples. It assigns the elements of each tuple to {\tt last} and {\tt first}, then @@ -10134,47 +10136,47 @@ \section{Debugging} Here's the result for a simple list: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> from structshape import structshape >>> t = [1, 2, 3] >>> structshape(t) 'list of 3 int' -\end{verbatim} +\end{lstlisting} % A fancier program might write ``list of 3 int{\em s}'', but it was easier not to deal with plurals. Here's a list of lists: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t2 = [[1,2], [3,4], [5,6]] >>> structshape(t2) 'list of 3 list of 2 int' -\end{verbatim} +\end{lstlisting} % If the elements of the list are not the same type, {\tt structshape} groups them, in order, by type: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t3 = [1, 2, 3, 4.0, '5', '6', [7], [8], 9] >>> structshape(t3) 'list of (3 int, float, 2 str, 2 list of int, int)' -\end{verbatim} +\end{lstlisting} % Here's a list of tuples: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> s = 'abc' >>> lt = list(zip(t, s)) >>> structshape(lt) 'list of 3 tuple of (int, str)' -\end{verbatim} +\end{lstlisting} % And here's a dictionary with 3 items that map integers to strings. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> d = dict(lt) >>> structshape(d) 'dict of 3 int->str' -\end{verbatim} +\end{lstlisting} % If you are having trouble keeping track of your data structures, {\tt structshape} can help. @@ -10249,13 +10251,13 @@ \section{Exercises} prints all the sets of words that are anagrams. Here is an example of what the output might look like: - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] ['deltas', 'desalt', 'lasted', 'salted', 'slated', 'staled'] ['retainers', 'ternaries'] ['generating', 'greatening'] ['resmelts', 'smelters', 'termless'] -\end{verbatim} +\end{lstlisting}} % Hint: you might want to build a dictionary that maps from a collection of letters to a list of words that can be spelled with those @@ -10393,12 +10395,12 @@ \section{Word frequency analysis} which contains space, tab, newline, etc., and {\tt punctuation} which contains the punctuation characters. Let's see if we can make Python swear: - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] >>> import string >>> string.punctuation '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' -\end{verbatim} +\end{lstlisting}} % Also, you might consider using the string methods {\tt strip}, {\tt replace} and {\tt translate}. @@ -10487,13 +10489,13 @@ \section{Random numbers} call {\tt random}, you get the next number in a long series. To see a sample, run this loop: -\begin{verbatim} +\begin{lstlisting}[language=python] import random for i in range(10): x = random.random() print(x) -\end{verbatim} +\end{lstlisting} % The function {\tt randint} takes parameters {\tt low} and {\tt high} and returns an integer between {\tt low} and @@ -10501,25 +10503,25 @@ \section{Random numbers} \index{randint function} \index{function!randint} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> random.randint(5, 10) 5 >>> random.randint(5, 10) 9 -\end{verbatim} +\end{lstlisting} % To choose an element from a sequence at random, you can use {\tt choice}: \index{choice function} \index{function!choice} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = [1, 2, 3] >>> random.choice(t) 2 >>> random.choice(t) 3 -\end{verbatim} +\end{lstlisting} % The {\tt random} module also provides functions to generate random values from continuous distributions including @@ -10532,13 +10534,13 @@ \section{Random numbers} a histogram as defined in Section~\ref{histogram} and returns a random value from the histogram, chosen with probability in proportion to frequency. For example, for this histogram: - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] >>> t = ['a', 'a', 'b'] >>> hist = histogram(t) >>> hist {'a': 2, 'b': 1} -\end{verbatim} +\end{lstlisting}} % your function should return \verb"'a'" with probability $2/3$ and \verb"'b'" with probability $1/3$. @@ -10556,7 +10558,7 @@ \section{Word histogram} words in the file: \index{histogram!word frequencies} -\begin{verbatim} +\begin{lstlisting}[language=python] import string def process_file(filename): @@ -10575,7 +10577,7 @@ \section{Word histogram} hist[word] = hist.get(word, 0) + 1 hist = process_file('emma.txt') -\end{verbatim} +\end{lstlisting} % This program reads {\tt emma.txt}, which contains the text of {\em Emma} by Jane Austen. @@ -10602,32 +10604,32 @@ \section{Word histogram} To count the total number of words in the file, we can add up the frequencies in the histogram: -\begin{verbatim} +\begin{lstlisting}[language=python] def total_words(hist): return sum(hist.values()) -\end{verbatim} +\end{lstlisting} % The number of different words is just the number of items in the dictionary: -\begin{verbatim} +\begin{lstlisting}[language=python] def different_words(hist): return len(hist) -\end{verbatim} +\end{lstlisting} % Here is some code to print the results: -\begin{verbatim} +\begin{lstlisting}[language=python] print('Total number of words:', total_words(hist)) print('Number of different words:', different_words(hist)) -\end{verbatim} +\end{lstlisting} % And the results: -\begin{verbatim} +\begin{lstlisting}[language=python] Total number of words: 161080 Number of different words: 7214 -\end{verbatim} +\end{lstlisting} % \section{Most common words} @@ -10639,7 +10641,7 @@ \section{Most common words} The following function takes a histogram and returns a list of word-frequency tuples: -\begin{verbatim} +\begin{lstlisting}[language=python] def most_common(hist): t = [] for key, value in hist.items(): @@ -10647,18 +10649,18 @@ \section{Most common words} t.sort(reverse=True) return t -\end{verbatim} +\end{lstlisting} In each tuple, the frequency appears first, so the resulting list is sorted by frequency. Here is a loop that prints the ten most common words: -\begin{verbatim} +\begin{lstlisting}[language=python] t = most_common(hist) print('The most common words are:') for freq, word in t[:10]: print(word, freq, sep='\t') -\end{verbatim} +\end{lstlisting} % I use the keyword argument {\tt sep} to tell {\tt print} to use a tab character as a ``separator'', rather than a space, so the second @@ -10694,13 +10696,13 @@ \section{Optional parameters} \index{programmer-defined function} \index{function!programmer defined} -\begin{verbatim} +\begin{lstlisting}[language=python] def print_most_common(hist, num=10): t = most_common(hist) print('The most common words are:') for freq, word in t[:num]: print(word, freq, sep='\t') -\end{verbatim} +\end{lstlisting} The first parameter is required; the second is optional. The {\bf default value} of {\tt num} is 10. @@ -10709,15 +10711,15 @@ \section{Optional parameters} If you only provide one argument: -\begin{verbatim} +\begin{lstlisting}[language=python] print_most_common(hist) -\end{verbatim} +\end{lstlisting} {\tt num} gets the default value. If you provide two arguments: -\begin{verbatim} +\begin{lstlisting}[language=python] print_most_common(hist, 20) -\end{verbatim} +\end{lstlisting} {\tt num} gets the value of the argument instead. In other words, the optional argument {\bf overrides} the default value. @@ -10744,27 +10746,27 @@ \section{Dictionary subtraction} in {\tt d2}. Since we don't really care about the values, we set them all to None. -\begin{verbatim} +\begin{lstlisting}[language=python] def subtract(d1, d2): res = dict() for key in d1: if key not in d2: res[key] = None return res -\end{verbatim} +\end{lstlisting} % To find the words in the book that are not in {\tt words.txt}, we can use \verb"process_file" to build a histogram for {\tt words.txt}, and then subtract: -\begin{verbatim} +\begin{lstlisting}[language=python] words = process_file('words.txt') diff = subtract(hist, words) print("Words in the book that aren't in the word list:") for word in diff: print(word, end=' ') -\end{verbatim} +\end{lstlisting} % Here are some of the results from {\em Emma}: @@ -10802,14 +10804,14 @@ \section{Random words} is to build a list with multiple copies of each word, according to the observed frequency, and then choose from the list: -\begin{verbatim} +\begin{lstlisting}[language=python] def random_word(h): t = [] for word, freq in h.items(): t.extend([word] * freq) return random.choice(t) -\end{verbatim} +\end{lstlisting} % The expression {\tt [word] * freq} creates a list with {\tt freq} copies of the string {\tt word}. The {\tt extend} @@ -11005,10 +11007,10 @@ \section{Data structures} With tuples, you can't append or remove, but you can use the addition operator to form a new tuple: -\begin{verbatim} +\begin{lstlisting}[language=python] def shift(prefix, word): return prefix[1:] + (word,) -\end{verbatim} +\end{lstlisting} % {\tt shift} takes a tuple of words, {\tt prefix}, and a string, {\tt word}, and forms a new tuple that has all the words @@ -11267,9 +11269,9 @@ \section{Reading and writing} To write a file, you have to open it with mode \verb"'w'" as a second parameter: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> fout = open('output.txt', 'w') -\end{verbatim} +\end{lstlisting} % If the file already exists, opening it in write mode clears out the old data and starts fresh, so be careful! @@ -11279,28 +11281,28 @@ \section{Reading and writing} with the file. The {\tt write} method puts data into the file. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> line1 = "This here's the wattle,\n" >>> fout.write(line1) 24 -\end{verbatim} +\end{lstlisting} % The return value is the number of characters that were written. The file object keeps track of where it is, so if you call {\tt write} again, it adds the new data to the end of the file. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> line2 = "the emblem of our land.\n" >>> fout.write(line2) 24 -\end{verbatim} +\end{lstlisting} % When you are done writing, you should close the file. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> fout.close() -\end{verbatim} +\end{lstlisting} % \index{close method} \index{method!close} @@ -11317,10 +11319,10 @@ \section{Format operator} to put other values in a file, we have to convert them to strings. The easiest way to do that is with {\tt str}: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> x = 52 >>> fout.write(str(x)) -\end{verbatim} +\end{lstlisting} % An alternative is to use the {\bf format operator}, {\tt \%}. When applied to integers, {\tt \%} is the modulus operator. But @@ -11337,11 +11339,11 @@ \section{Format operator} the second operand should be formatted as a decimal integer: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> camels = 42 >>> '%d' % camels '42' -\end{verbatim} +\end{lstlisting} % The result is the string \verb"'42'", which is not to be confused with the integer value {\tt 42}. @@ -11349,10 +11351,10 @@ \section{Format operator} A format sequence can appear anywhere in the string, so you can embed a value in a sentence: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> 'I have spotted %d camels.' % camels 'I have spotted 42 camels.' -\end{verbatim} +\end{lstlisting} % If there is more than one format sequence in the string, the second argument has to be a tuple. Each format sequence is @@ -11362,10 +11364,10 @@ \section{Format operator} \verb"'%g'" to format a floating-point number, and \verb"'%s'" to format a string: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> 'In %d years I have spotted %g %s.' % (3, 0.1, 'camels') 'In 3 years I have spotted 0.1 camels.' -\end{verbatim} +\end{lstlisting} % The number of elements in the tuple has to match the number of format sequences in the string. Also, the types of the @@ -11373,12 +11375,12 @@ \section{Format operator} \index{exception!TypeError} \index{TypeError} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> '%d %d %d' % (1, 2) TypeError: not enough arguments for format string >>> '%d' % 'dollars' TypeError: %d format: a number is required, not str -\end{verbatim} +\end{lstlisting} % In the first example, there aren't enough elements; in the second, the element is the wrong type. @@ -11393,10 +11395,10 @@ \section{Format operator} % formats a floating-point number to be 8 characters long, with % 2 digits after the decimal point: -% % \begin{verbatim} +% % \begin{lstlisting}[language=python] % >>> '%8.2f' % 3.14159 % ' 3.14' -% \end{verbatim} +% \end{lstlisting} % \afterverb % % % The result takes up eight spaces with two @@ -11424,12 +11426,12 @@ \section{Filenames and paths} \index{getcwd function} \index{function!getcwd} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> import os >>> cwd = os.getcwd() >>> cwd '/home/dinsdale' -\end{verbatim} +\end{lstlisting} % {\tt cwd} stands for ``current working directory''. The result in this example is {\tt /home/dinsdale}, which is the home directory of a @@ -11451,10 +11453,10 @@ \section{Filenames and paths} directory; it is called an {\bf absolute path}. To find the absolute path to a file, you can use {\tt os.path.abspath}: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> os.path.abspath('memo.txt') '/home/dinsdale/memo.txt' -\end{verbatim} +\end{lstlisting} % {\tt os.path} provides other functions for working with filenames and paths. For example, @@ -11463,29 +11465,29 @@ \section{Filenames and paths} \index{exists function} \index{function!exists} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> os.path.exists('memo.txt') True -\end{verbatim} +\end{lstlisting} % If it exists, {\tt os.path.isdir} checks whether it's a directory: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> os.path.isdir('memo.txt') False >>> os.path.isdir('/home/dinsdale') True -\end{verbatim} +\end{lstlisting} % Similarly, {\tt os.path.isfile} checks whether it's a file. {\tt os.listdir} returns a list of the files (and other directories) in the given directory: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> os.listdir(cwd) ['music', 'photos', 'memo.txt'] -\end{verbatim} +\end{lstlisting} % To demonstrate these functions, the following example ``walks'' through a directory, prints @@ -11494,7 +11496,7 @@ \section{Filenames and paths} \index{walk, directory} \index{directory!walk} -\begin{verbatim} +\begin{lstlisting}[language=python] def walk(dirname): for name in os.listdir(dirname): path = os.path.join(dirname, name) @@ -11503,7 +11505,7 @@ \section{Filenames and paths} print(path) else: walk(path) -\end{verbatim} +\end{lstlisting} % {\tt os.path.join} takes a directory and a file name and joins them into a complete path. @@ -11526,26 +11528,28 @@ \section{Catching exceptions} \index{exception!IOError} \index{IOError} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> fin = open('bad_file') -IOError: [Errno 2] No such file or directory: 'bad_file' -\end{verbatim} +<@\textcolor{black}{ +IOError: [Errno 2] No such file or directory: 'bad\_file' +}@> +\end{lstlisting} % If you don't have permission to access a file: \index{file!permission} \index{permission, file} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> fout = open('/etc/passwd', 'w') PermissionError: [Errno 13] Permission denied: '/etc/passwd' -\end{verbatim} +\end{lstlisting} % And if you try to open a directory for reading, you get -\begin{verbatim} +\begin{lstlisting}[language=python] >>> fin = open('/home') IsADirectoryError: [Errno 21] Is a directory: '/home' -\end{verbatim} +\end{lstlisting} % To avoid these errors, you could use functions like {\tt os.path.exists} and {\tt os.path.isfile}, but it would take a lot of time and code @@ -11559,12 +11563,12 @@ \section{Catching exceptions} happen---which is exactly what the {\tt try} statement does. The syntax is similar to an {\tt if...else} statement: -\begin{verbatim} +\begin{lstlisting}[language=python] try: fin = open('bad_file') except: print('Something went wrong.') -\end{verbatim} +\end{lstlisting} % Python starts by executing the {\tt try} clause. If all goes well, it skips the {\tt except} clause and proceeds. If an @@ -11597,10 +11601,10 @@ \section{Databases} Opening a database is similar to opening other files: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> import dbm >>> db = dbm.open('captions', 'c') -\end{verbatim} +\end{lstlisting} % The mode \verb"'c'" means that the database should be created if it doesn't already exist. The result is a database object @@ -11611,16 +11615,16 @@ \section{Databases} When you create a new item, {\tt dbm} updates the database file. \index{update!database} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> db['cleese.png'] = 'Photo of John Cleese.' -\end{verbatim} +\end{lstlisting} % When you access one of the items, {\tt dbm} reads the file: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> db['cleese.png'] b'Photo of John Cleese.' -\end{verbatim} +\end{lstlisting} % The result is a {\bf bytes object}, which is why it begins with {\tt b}. A bytes object is similar to a string in many ways. When you @@ -11632,11 +11636,11 @@ \section{Databases} If you make another assignment to an existing key, {\tt dbm} replaces the old value: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> db['cleese.png'] = 'Photo of John Cleese doing a silly walk.' >>> db['cleese.png'] b'Photo of John Cleese doing a silly walk.' -\end{verbatim} +\end{lstlisting} % Some dictionary methods, like {\tt keys} and {\tt items}, don't @@ -11644,17 +11648,17 @@ \section{Databases} loop works: \index{dictionary methods!dbm module} -\begin{verbatim} +\begin{lstlisting}[language=python] for key in db: print(key, db[key]) -\end{verbatim} +\end{lstlisting} % As with other files, you should close the database when you are done: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> db.close() -\end{verbatim} +\end{lstlisting} % \index{close method} \index{method!close} @@ -11674,34 +11678,34 @@ \section{Pickling} {\tt pickle.dumps} takes an object as a parameter and returns a string representation ({\tt dumps} is short for ``dump string''): -\begin{verbatim} +\begin{lstlisting}[language=python] >>> import pickle >>> t = [1, 2, 3] >>> pickle.dumps(t) b'\x80\x03]q\x00(K\x01K\x02K\x03e.' -\end{verbatim} +\end{lstlisting} % The format isn't obvious to human readers; it is meant to be easy for {\tt pickle} to interpret. {\tt pickle.loads} (``load string'') reconstitutes the object: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t1 = [1, 2, 3] >>> s = pickle.dumps(t1) >>> t2 = pickle.loads(s) >>> t2 [1, 2, 3] -\end{verbatim} +\end{lstlisting} % Although the new object has the same value as the old, it is not (in general) the same object: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t1 == t2 True >>> t1 is t2 False -\end{verbatim} +\end{lstlisting} % In other words, pickling and then unpickling has the same effect as copying the object. @@ -11740,10 +11744,10 @@ \section{Pipes} \index{popen function} \index{function!popen} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> cmd = 'ls -l' >>> fp = os.popen(cmd) -\end{verbatim} +\end{lstlisting} % The argument is a string that contains a shell command. The return value is an object that behaves like an open @@ -11755,19 +11759,19 @@ \section{Pipes} \index{read method} \index{method!read} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> res = fp.read() -\end{verbatim} +\end{lstlisting} % When you are done, you close the pipe like a file: \index{close method} \index{method!close} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> stat = fp.close() >>> print(stat) None -\end{verbatim} +\end{lstlisting} % The return value is the final status of the {\tt ls} process; {\tt None} means that it ended normally (with no errors). @@ -11784,7 +11788,7 @@ \section{Pipes} You can use a pipe to run {\tt md5sum} from Python and get the result: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> filename = 'book.tex' >>> cmd = 'md5sum ' + filename >>> fp = os.popen(cmd) @@ -11794,7 +11798,7 @@ \section{Pipes} 1e0033f0ed0656636de0d75144ba32e0 book.tex >>> print(stat) None -\end{verbatim} +\end{lstlisting} @@ -11807,7 +11811,7 @@ \section{Writing modules} For example, suppose you have a file named {\tt wc.py} with the following code: -\begin{verbatim} +\begin{lstlisting}[language=python] def linecount(filename): count = 0 for line in open(filename): @@ -11815,32 +11819,32 @@ \section{Writing modules} return count print(linecount('wc.py')) -\end{verbatim} +\end{lstlisting} % If you run this program, it reads itself and prints the number of lines in the file, which is 7. You can also import it like this: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> import wc 7 -\end{verbatim} +\end{lstlisting} % Now you have a module object {\tt wc}: \index{module object} \index{object!module} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> wc -\end{verbatim} +\end{lstlisting} % The module object provides \verb"linecount": -\begin{verbatim} +\begin{lstlisting}[language=python] >>> wc.linecount('wc.py') 7 -\end{verbatim} +\end{lstlisting} % So that's how you write modules in Python. @@ -11854,10 +11858,10 @@ \section{Writing modules} Programs that will be imported as modules often use the following idiom: -\begin{verbatim} +\begin{lstlisting}[language=python] if __name__ == '__main__': print(linecount('wc.py')) -\end{verbatim} +\end{lstlisting} % \verb"__name__" is a built-in variable that is set when the program starts. If the program is running as a script, @@ -11893,12 +11897,12 @@ \section{Debugging} with whitespace. These errors can be hard to debug because spaces, tabs and newlines are normally invisible: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> s = '1 2\t 3\n 4' >>> print(s) 1 2 3 4 -\end{verbatim} +\end{lstlisting} \index{repr function} \index{function!repr} \index{string representation} @@ -11908,10 +11912,10 @@ \section{Debugging} strings, it represents whitespace characters with backslash sequences: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> print(repr(s)) '1 2\t 3\n 4' -\end{verbatim} +\end{lstlisting} This can be helpful for debugging. @@ -12127,10 +12131,10 @@ \section{Programmer-defined types} \index{class definition} \index{definition!class} -\begin{verbatim} +\begin{lstlisting}[language=python] class Point: """Represents a point in 2-D space.""" -\end{verbatim} +\end{lstlisting} % The header indicates that the new class is called {\tt Point}. The body is a docstring that explains what the class is for. @@ -12142,10 +12146,10 @@ \section{Programmer-defined types} Defining a class named {\tt Point} creates a {\bf class object}. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> Point - -\end{verbatim} +<@\textcolor{black}{}@> +\end{lstlisting} % Because {\tt Point} is defined at the top level, its ``full name'' is \verb"__main__.Point". @@ -12155,11 +12159,11 @@ \section{Programmer-defined types} The class object is like a factory for creating objects. To create a Point, you call {\tt Point} as if it were a function. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> blank = Point() >>> blank -<__main__.Point object at 0xb7e9d3ac> -\end{verbatim} +<@\textcolor{black}{<\_\_main\_\_.Point object at 0xb7e9d3ac>}@> +\end{lstlisting} % The return value is a reference to a Point object, which we assign to {\tt blank}. @@ -12189,10 +12193,10 @@ \section{Attributes} You can assign values to an instance using dot notation: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> blank.x = 3.0 >>> blank.y = 4.0 -\end{verbatim} +\end{lstlisting} % This syntax is similar to the syntax for selecting a variable from a module, such as {\tt math.pi} or {\tt string.whitespace}. In this case, @@ -12223,13 +12227,13 @@ \section{Attributes} You can read the value of an attribute using the same syntax: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> blank.y 4.0 >>> x = blank.x >>> x 3.0 -\end{verbatim} +\end{lstlisting} % The expression {\tt blank.x} means, ``Go to the object {\tt blank} refers to and get the value of {\tt x}.'' In the example, we assign that @@ -12238,31 +12242,31 @@ \section{Attributes} You can use dot notation as part of any expression. For example: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> '(%g, %g)' % (blank.x, blank.y) '(3.0, 4.0)' >>> distance = math.sqrt(blank.x**2 + blank.y**2) >>> distance 5.0 -\end{verbatim} +\end{lstlisting} % You can pass an instance as an argument in the usual way. For example: \index{instance!as argument} -\begin{verbatim} +\begin{lstlisting}[language=python] def print_point(p): print('(%g, %g)' % (p.x, p.y)) -\end{verbatim} +\end{lstlisting} % \verb"print_point" takes a point as an argument and displays it in mathematical notation. To invoke it, you can pass {\tt blank} as an argument: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> print_point(blank) (3.0, 4.0) -\end{verbatim} +\end{lstlisting} % Inside the function, {\tt p} is an alias for {\tt blank}, so if the function modifies {\tt p}, {\tt blank} changes. @@ -12302,13 +12306,13 @@ \section{Rectangles} Here is the class definition: -\begin{verbatim} +\begin{lstlisting}[language=python] class Rectangle: """Represents a rectangle. attributes: width, height, corner. """ -\end{verbatim} +\end{lstlisting} % The docstring lists the attributes: {\tt width} and {\tt height} are numbers; {\tt corner} is a Point object that @@ -12317,14 +12321,14 @@ \section{Rectangles} To represent a rectangle, you have to instantiate a Rectangle object and assign values to the attributes: -\begin{verbatim} +\begin{lstlisting}[language=python] box = Rectangle() box.width = 100.0 box.height = 200.0 box.corner = Point() box.corner.x = 0.0 box.corner.y = 0.0 -\end{verbatim} +\end{lstlisting} % The expression {\tt box.corner.x} means, ``Go to the object {\tt box} refers to and select the attribute named @@ -12357,22 +12361,22 @@ \section{Instances as return values} takes a {\tt Rectangle} as an argument and returns a {\tt Point} that contains the coordinates of the center of the {\tt Rectangle}: -\begin{verbatim} +\begin{lstlisting}[language=python] def find_center(rect): p = Point() p.x = rect.corner.x + rect.width/2 p.y = rect.corner.y + rect.height/2 return p -\end{verbatim} +\end{lstlisting} % Here is an example that passes {\tt box} as an argument and assigns the resulting Point to {\tt center}: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> center = find_center(box) >>> print_point(center) (50, 100) -\end{verbatim} +\end{lstlisting} % \section{Objects are mutable} @@ -12384,31 +12388,31 @@ \section{Objects are mutable} without changing its position, you can modify the values of {\tt width} and {\tt height}: -\begin{verbatim} +\begin{lstlisting}[language=python] box.width = box.width + 50 box.height = box.height + 100 -\end{verbatim} +\end{lstlisting} % You can also write functions that modify objects. For example, \verb"grow_rectangle" takes a Rectangle object and two numbers, {\tt dwidth} and {\tt dheight}, and adds the numbers to the width and height of the rectangle: -\begin{verbatim} +\begin{lstlisting}[language=python] def grow_rectangle(rect, dwidth, dheight): rect.width += dwidth rect.height += dheight -\end{verbatim} +\end{lstlisting} % Here is an example that demonstrates the effect: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> box.width, box.height (150.0, 300.0) >>> grow_rectangle(box, 50, 100) >>> box.width, box.height (200.0, 400.0) -\end{verbatim} +\end{lstlisting} % Inside the function, {\tt rect} is an alias for {\tt box}, so when the function modifies {\tt rect}, @@ -12438,19 +12442,19 @@ \section{Copying} The {\tt copy} module contains a function called {\tt copy} that can duplicate any object: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> p1 = Point() >>> p1.x = 3.0 >>> p1.y = 4.0 >>> import copy >>> p2 = copy.copy(p1) -\end{verbatim} +\end{lstlisting} % {\tt p1} and {\tt p2} contain the same data, but they are not the same Point. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> print_point(p1) (3, 4) >>> print_point(p2) @@ -12459,7 +12463,7 @@ \section{Copying} False >>> p1 == p2 False -\end{verbatim} +\end{lstlisting} % The {\tt is} operator indicates that {\tt p1} and {\tt p2} are not the same object, which is what we expected. But you might have expected @@ -12478,13 +12482,13 @@ \section{Copying} that it copies the Rectangle object but not the embedded Point. \index{embedded object!copying} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> box2 = copy.copy(box) >>> box2 is box False >>> box2.corner is box.corner True -\end{verbatim} +\end{lstlisting} \begin{figure} \centerline @@ -12519,13 +12523,13 @@ \section{Copying} \index{deepcopy function} \index{function!deepcopy} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> box3 = copy.deepcopy(box) >>> box3 is box False >>> box3.corner is box.corner False -\end{verbatim} +\end{lstlisting} % {\tt box3} and {\tt box} are completely separate objects. @@ -12543,44 +12547,44 @@ \section{Debugging} \index{exception!AttributeError} \index{AttributeError} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> p = Point() >>> p.x = 3 >>> p.y = 4 >>> p.z AttributeError: Point instance has no attribute 'z' -\end{verbatim} +\end{lstlisting} % If you are not sure what type an object is, you can ask: \index{type function} \index{function!type} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> type(p) - -\end{verbatim} +<@\textcolor{black}{}@> +\end{lstlisting} % You can also use {\tt isinstance} to check whether an object is an instance of a class: \index{isinstance function} \index{function!isinstance} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> isinstance(p, Point) True -\end{verbatim} +\end{lstlisting} % If you are not sure whether an object has a particular attribute, you can use the built-in function {\tt hasattr}: \index{hasattr function} \index{function!hasattr} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> hasattr(p, 'x') True >>> hasattr(p, 'z') False -\end{verbatim} +\end{lstlisting} % The first argument can be any object; the second argument is a {\em string} that contains the name of the attribute. @@ -12591,12 +12595,12 @@ \section{Debugging} \index{try statement} \index{statement!try} -\begin{verbatim} +\begin{lstlisting}[language=python] try: x = p.x except AttributeError: x = 0 -\end{verbatim} +\end{lstlisting} This approach can make it easier to write functions that work with different types; more on that topic is @@ -12719,23 +12723,23 @@ \section{Time} looks like this: \index{programmer-defined type} \index{type!programmer-defined} \index{Time class} \index{class!Time} -\begin{verbatim} +\begin{lstlisting}[language=python] class Time: """Represents the time of day. attributes: hour, minute, second """ -\end{verbatim} +\end{lstlisting} % We can create a new {\tt Time} object and assign attributes for hours, minutes, and seconds: -\begin{verbatim} +\begin{lstlisting}[language=python] time = Time() time.hour = 11 time.minute = 59 time.second = 30 -\end{verbatim} +\end{lstlisting} % The state diagram for the {\tt Time} object looks like Figure~\ref{fig.time}. \index{state diagram} @@ -12774,14 +12778,14 @@ \section{Pure functions} Here is a simple prototype of \verb"add_time": -\begin{verbatim} +\begin{lstlisting}[language=python] def add_time(t1, t2): sum = Time() sum.hour = t1.hour + t2.hour sum.minute = t1.minute + t2.minute sum.second = t1.second + t2.second return sum -\end{verbatim} +\end{lstlisting} % The function creates a new {\tt Time} object, initializes its attributes, and returns a reference to the new object. This is called @@ -12800,7 +12804,7 @@ \section{Pure functions} \verb"add_time" figures out when the movie will be done. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> start = Time() >>> start.hour = 9 >>> start.minute = 45 @@ -12814,7 +12818,7 @@ \section{Pure functions} >>> done = add_time(start, duration) >>> print_time(done) 10:80:00 -\end{verbatim} +\end{lstlisting} % The result, {\tt 10:80:00} might not be what you were hoping for. The problem is that this function does not deal with cases where the @@ -12825,7 +12829,7 @@ \section{Pure functions} Here's an improved version: -\begin{verbatim} +\begin{lstlisting}[language=python] def add_time(t1, t2): sum = Time() sum.hour = t1.hour + t2.hour @@ -12841,7 +12845,7 @@ \section{Pure functions} sum.hour += 1 return sum -\end{verbatim} +\end{lstlisting} % Although this function is correct, it is starting to get big. We will see a shorter alternative later. @@ -12861,7 +12865,7 @@ \section{Modifiers} object, can be written naturally as a modifier. Here is a rough draft: -\begin{verbatim} +\begin{lstlisting}[language=python] def increment(time, seconds): time.second += seconds @@ -12872,7 +12876,7 @@ \section{Modifiers} if time.minute >= 60: time.minute -= 60 time.hour += 1 -\end{verbatim} +\end{lstlisting} % The first line performs the basic operation; the remainder deals with the special cases we saw before. @@ -12944,25 +12948,25 @@ \section{Prototyping versus planning} Here is a function that converts Times to integers: -\begin{verbatim} +\begin{lstlisting}[language=python] def time_to_int(time): minutes = time.hour * 60 + time.minute seconds = minutes * 60 + time.second return seconds -\end{verbatim} +\end{lstlisting} % And here is a function that converts an integer to a Time (recall that {\tt divmod} divides the first argument by the second and returns the quotient and remainder as a tuple). \index{divmod} -\begin{verbatim} +\begin{lstlisting}[language=python] def int_to_time(seconds): time = Time() minutes, time.second = divmod(seconds, 60) time.hour, time.minute = divmod(minutes, 60) return time -\end{verbatim} +\end{lstlisting} % You might have to think a bit, and run some tests, to convince yourself that these functions are correct. One way to test them is to @@ -12973,11 +12977,11 @@ \section{Prototyping versus planning} Once you are convinced they are correct, you can use them to rewrite \verb"add_time": -\begin{verbatim} +\begin{lstlisting}[language=python] def add_time(t1, t2): seconds = time_to_int(t1) + time_to_int(t2) return int_to_time(seconds) -\end{verbatim} +\end{lstlisting} % This version is shorter than the original, and easier to verify. As an exercise, rewrite {\tt increment} using \verb"time_to_int" and @@ -13025,39 +13029,39 @@ \section{Debugging} like \verb"valid_time" that takes a Time object and returns {\tt False} if it violates an invariant: -\begin{verbatim} +\begin{lstlisting}[language=python] def valid_time(time): if time.hour < 0 or time.minute < 0 or time.second < 0: return False if time.minute >= 60 or time.second >= 60: return False return True -\end{verbatim} +\end{lstlisting} % At the beginning of each function you could check the arguments to make sure they are valid: \index{raise statement} \index{statement!raise} -\begin{verbatim} +\begin{lstlisting}[language=python] def add_time(t1, t2): if not valid_time(t1) or not valid_time(t2): raise ValueError('invalid Time object in add_time') seconds = time_to_int(t1) + time_to_int(t2) return int_to_time(seconds) -\end{verbatim} +\end{lstlisting} % Or you could use an {\bf assert statement}, which checks a given invariant and raises an exception if it fails: \index{assert statement} \index{statement!assert} -\begin{verbatim} +\begin{lstlisting}[language=python] def add_time(t1, t2): assert valid_time(t1) and valid_time(t2) seconds = time_to_int(t1) + time_to_int(t2) return int_to_time(seconds) -\end{verbatim} +\end{lstlisting} % {\tt assert} statements are useful because they distinguish code that deals with normal conditions from code @@ -13248,46 +13252,46 @@ \section{Printing objects} {\tt Time} and in Section~\ref{isafter}, you wrote a function named \verb"print_time": -\begin{verbatim} +\begin{lstlisting}[language=python] class Time: """Represents the time of day.""" def print_time(time): print('%.2d:%.2d:%.2d' % (time.hour, time.minute, time.second)) -\end{verbatim} +\end{lstlisting} % To call this function, you have to pass a {\tt Time} object as an argument: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> start = Time() >>> start.hour = 9 >>> start.minute = 45 >>> start.second = 00 >>> print_time(start) 09:45:00 -\end{verbatim} +\end{lstlisting} % To make \verb"print_time" a method, all we have to do is move the function definition inside the class definition. Notice the change in indentation. \index{indentation} -\begin{verbatim} +\begin{lstlisting}[language=python] class Time: def print_time(time): print('%.2d:%.2d:%.2d' % (time.hour, time.minute, time.second)) -\end{verbatim} +\end{lstlisting} % Now there are two ways to call \verb"print_time". The first (and less common) way is to use function syntax: \index{function syntax} \index{dot notation} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> Time.print_time(start) 09:45:00 -\end{verbatim} +\end{lstlisting} % In this use of dot notation, {\tt Time} is the name of the class, and \verb"print_time" is the name of the method. {\tt start} is @@ -13296,10 +13300,10 @@ \section{Printing objects} The second (and more concise) way is to use method syntax: \index{method syntax} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> start.print_time() 09:45:00 -\end{verbatim} +\end{lstlisting} % In this use of dot notation, \verb"print_time" is the name of the method (again), and {\tt start} is the object the method is @@ -13318,11 +13322,11 @@ \section{Printing objects} called {\tt self}, so it would be more common to write \verb"print_time" like this: -\begin{verbatim} +\begin{lstlisting}[language=python] class Time: def print_time(self): print('%.2d:%.2d:%.2d' % (self.hour, self.minute, self.second)) -\end{verbatim} +\end{lstlisting} % The reason for this convention is an implicit metaphor: \index{metaphor, method invocation} @@ -13358,13 +13362,13 @@ \section{Another example} Here's a version of {\tt increment} (from Section~\ref{increment}) rewritten as a method: -\begin{verbatim} +\begin{lstlisting}[language=python] # inside class Time: def increment(self, seconds): seconds += self.time_to_int() return int_to_time(seconds) -\end{verbatim} +\end{lstlisting} % This version assumes that \verb"time_to_int" is written as a method. Also, note that @@ -13372,13 +13376,13 @@ \section{Another example} Here's how you would invoke {\tt increment}: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> start.print_time() 09:45:00 >>> end = start.increment(1337) >>> end.print_time() 10:07:17 -\end{verbatim} +\end{lstlisting} % The subject, {\tt start}, gets assigned to the first parameter, {\tt self}. The argument, {\tt 1337}, gets assigned to the @@ -13390,10 +13394,10 @@ \section{Another example} \index{exception!TypeError} \index{TypeError} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> end = start.increment(1337, 460) TypeError: increment() takes 2 positional arguments but 3 were given -\end{verbatim} +\end{lstlisting} % The error message is initially confusing, because there are only two arguments in parentheses. But the subject is also @@ -13405,9 +13409,9 @@ \section{Another example} \index{positional argument} \index{argument!positional} -\begin{verbatim} +\begin{lstlisting}[language=python] sketch(parrot, cage, dead=True) -\end{verbatim} +\end{lstlisting} {\tt parrot} and {\tt cage} are positional, and {\tt dead} is a keyword argument. @@ -13421,20 +13425,20 @@ \section{A more complicated example} and the second parameter {\tt other}: \index{other (parameter name)} \index{parameter!other} -\begin{verbatim} +\begin{lstlisting}[language=python] # inside class Time: def is_after(self, other): return self.time_to_int() > other.time_to_int() -\end{verbatim} +\end{lstlisting} % To use this method, you have to invoke it on one object and pass the other as an argument: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> end.is_after(start) True -\end{verbatim} +\end{lstlisting} % One nice thing about this syntax is that it almost reads like English: ``end is after start?'' @@ -13450,21 +13454,21 @@ \section{The init method} followed by {\tt init}, and then two more underscores). An init method for the {\tt Time} class might look like this: -\begin{verbatim} +\begin{lstlisting}[language=python] # inside class Time: def __init__(self, hour=0, minute=0, second=0): self.hour = hour self.minute = minute self.second = second -\end{verbatim} +\end{lstlisting} % It is common for the parameters of \verb"__init__" to have the same names as the attributes. The statement -\begin{verbatim} +\begin{lstlisting}[language=python] self.hour = hour -\end{verbatim} +\end{lstlisting} % stores the value of the parameter {\tt hour} as an attribute of {\tt self}. @@ -13476,28 +13480,28 @@ \section{The init method} The parameters are optional, so if you call {\tt Time} with no arguments, you get the default values. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> time = Time() >>> time.print_time() 00:00:00 -\end{verbatim} +\end{lstlisting} % If you provide one argument, it overrides {\tt hour}: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> time = Time (9) >>> time.print_time() 09:00:00 -\end{verbatim} +\end{lstlisting} % If you provide two arguments, they override {\tt hour} and {\tt minute}. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> time = Time(9, 45) >>> time.print_time() 09:45:00 -\end{verbatim} +\end{lstlisting} % And if you provide three arguments, they override all three default values. @@ -13519,22 +13523,22 @@ \section{The {\tt \_\_str\_\_} method} For example, here is a {\tt str} method for Time objects: -\begin{verbatim} +\begin{lstlisting}[language=python] # inside class Time: def __str__(self): return '%.2d:%.2d:%.2d' % (self.hour, self.minute, self.second) -\end{verbatim} +\end{lstlisting} % When you {\tt print} an object, Python invokes the {\tt str} method: \index{print statement} \index{statement!print} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> time = Time(9, 45) >>> print(time) 09:45:00 -\end{verbatim} +\end{lstlisting} % When I write a new class, I almost always start by writing \verb"__init__", which makes it easier to instantiate objects, and @@ -13558,22 +13562,22 @@ \section{Operator overloading} \index{add method} \index{method!add} -\begin{verbatim} +\begin{lstlisting}[language=python] # inside class Time: def __add__(self, other): seconds = self.time_to_int() + other.time_to_int() return int_to_time(seconds) -\end{verbatim} +\end{lstlisting} % And here is how you could use it: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> start = Time(9, 45) >>> duration = Time(1, 35) >>> print(start + duration) 11:20:00 -\end{verbatim} +\end{lstlisting} % When you apply the {\tt +} operator to Time objects, Python invokes \verb"__add__". When you print the result, Python invokes @@ -13597,7 +13601,7 @@ \section{Type-based dispatch} that checks the type of {\tt other} and invokes either \verb"add_time" or {\tt increment}: -\begin{verbatim} +\begin{lstlisting}[language=python] # inside class Time: def __add__(self, other): @@ -13613,7 +13617,7 @@ \section{Type-based dispatch} def increment(self, seconds): seconds += self.time_to_int() return int_to_time(seconds) -\end{verbatim} +\end{lstlisting} % The built-in function {\tt isinstance} takes a value and a class object, and returns {\tt True} if the value is an instance @@ -13633,23 +13637,23 @@ \section{Type-based dispatch} Here are examples that use the {\tt +} operator with different types: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> start = Time(9, 45) >>> duration = Time(1, 35) >>> print(start + duration) 11:20:00 >>> print(start + 1337) 10:07:17 -\end{verbatim} +\end{lstlisting} % Unfortunately, this implementation of addition is not commutative. If the integer is the first operand, you get \index{commutativity} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> print(1337 + start) -TypeError: unsupported operand type(s) for +: 'int' and 'instance' -\end{verbatim} +<@\textcolor{black}{TypeError: unsupported operand type(s) for +: 'int' and 'instance'}@> +\end{lstlisting} % The problem is, instead of asking the Time object to add an integer, Python is asking an integer to add a Time object, and it doesn't know @@ -13660,19 +13664,19 @@ \section{Type-based dispatch} \index{radd method} \index{method!radd} -\begin{verbatim} +\begin{lstlisting}[language=python] # inside class Time: def __radd__(self, other): return self.__add__(other) -\end{verbatim} +\end{lstlisting} % And here's how it's used: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> print(1337 + start) 10:07:17 -\end{verbatim} +\end{lstlisting} % As an exercise, write an {\tt add} method for Points that works with @@ -13708,7 +13712,7 @@ \section{Polymorphism} we used {\tt histogram} to count the number of times each letter appears in a word. -\begin{verbatim} +\begin{lstlisting}[language=python] def histogram(s): d = dict() for c in s: @@ -13717,17 +13721,17 @@ \section{Polymorphism} else: d[c] = d[c]+1 return d -\end{verbatim} +\end{lstlisting} % This function also works for lists, tuples, and even dictionaries, as long as the elements of {\tt s} are hashable, so they can be used as keys in {\tt d}. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = ['spam', 'egg', 'spam', 'spam', 'bacon', 'spam'] >>> histogram(t) {'bacon': 1, 'egg': 1, 'spam': 4} -\end{verbatim} +\end{lstlisting} % Functions that work with several types are called {\bf polymorphic}. Polymorphism can facilitate code reuse. For example, the built-in @@ -13738,14 +13742,14 @@ \section{Polymorphism} Since Time objects provide an {\tt add} method, they work with {\tt sum}: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t1 = Time(7, 43) >>> t2 = Time(7, 41) >>> t3 = Time(7, 37) >>> total = sum([t1, t2, t3]) >>> print(total) 23:01:00 -\end{verbatim} +\end{lstlisting} % In general, if all of the operations inside a function work with a given type, the function works with that type. @@ -13777,20 +13781,20 @@ \section{Debugging} which takes an object and returns a dictionary that maps from attribute names (as strings) to their values: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> p = Point(3, 4) >>> vars(p) {'y': 4, 'x': 3} -\end{verbatim} +\end{lstlisting} % For purposes of debugging, you might find it useful to keep this function handy: -\begin{verbatim} +\begin{lstlisting}[language=python] def print_attributes(obj): for attr in vars(obj): print(attr, getattr(obj, attr)) -\end{verbatim} +\end{lstlisting} % \verb"print_attributes" traverses the dictionary and prints each attribute name and its corresponding value. @@ -14032,14 +14036,14 @@ \section{Card objects} The class definition for {\tt Card} looks like this: -\begin{verbatim} +\begin{lstlisting}[language=python] class Card: """Represents a standard playing card.""" def __init__(self, suit=0, rank=2): self.suit = suit self.rank = rank -\end{verbatim} +\end{lstlisting} % As usual, the init method takes an optional parameter for each attribute. The default card is @@ -14050,9 +14054,9 @@ \section{Card objects} To create a Card, you call {\tt Card} with the suit and rank of the card you want. -\begin{verbatim} +\begin{lstlisting}[language=python] queen_of_diamonds = Card(1, 12) -\end{verbatim} +\end{lstlisting} % @@ -14067,7 +14071,7 @@ \section{Class attributes} do that is with lists of strings. We assign these lists to {\bf class attributes}: -\begin{verbatim} +\begin{lstlisting}[language=python] # inside class Card: suit_names = ['Clubs', 'Diamonds', 'Hearts', 'Spades'] @@ -14077,7 +14081,7 @@ \section{Class attributes} def __str__(self): return '%s of %s' % (Card.rank_names[self.rank], Card.suit_names[self.suit]) -\end{verbatim} +\end{lstlisting} % Variables like \verb"suit_names" and \verb"rank_names", which are defined inside a class but outside of any method, are called @@ -14113,11 +14117,11 @@ \section{Class attributes} With the methods we have so far, we can create and print cards: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> card1 = Card(2, 11) >>> print(card1) Jack of Hearts -\end{verbatim} +\end{lstlisting} \begin{figure} \centerline @@ -14169,7 +14173,7 @@ \section{Comparing cards} With that decided, we can write \verb"__lt__": -\begin{verbatim} +\begin{lstlisting}[language=python] # inside class Card: def __lt__(self, other): @@ -14179,20 +14183,20 @@ \section{Comparing cards} # suits are the same... check ranks return self.rank < other.rank -\end{verbatim} +\end{lstlisting} % You can write this more concisely using tuple comparison: \index{tuple!comparison} \index{comparison!tuple} -\begin{verbatim} +\begin{lstlisting}[language=python] # inside class Card: def __lt__(self, other): t1 = self.suit, self.rank t2 = other.suit, other.rank return t1 < t2 -\end{verbatim} +\end{lstlisting} % As an exercise, write an \verb"__lt__" method for Time objects. You can use tuple comparison, but you also might consider @@ -14217,7 +14221,7 @@ \section{Decks} \index{Deck class} \index{class!Deck} -\begin{verbatim} +\begin{lstlisting}[language=python] class Deck: def __init__(self): @@ -14226,7 +14230,7 @@ \section{Decks} for rank in range(1, 14): card = Card(suit, rank) self.cards.append(card) -\end{verbatim} +\end{lstlisting} % The easiest way to populate the deck is with a nested loop. The outer loop enumerates the suits from 0 to 3. The inner loop enumerates the @@ -14244,7 +14248,7 @@ \section{Printing the deck} Here is a \verb"__str__" method for {\tt Deck}: -\begin{verbatim} +\begin{lstlisting}[language=python] #inside class Deck: def __str__(self): @@ -14252,7 +14256,7 @@ \section{Printing the deck} for card in self.cards: res.append(str(card)) return '\n'.join(res) -\end{verbatim} +\end{lstlisting} % This method demonstrates an efficient way to accumulate a large string: building a list of strings and then using the string method @@ -14264,7 +14268,7 @@ \section{Printing the deck} Since we invoke {\tt join} on a newline character, the cards are separated by newlines. Here's what the result looks like: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> deck = Deck() >>> print(deck) Ace of Clubs @@ -14275,7 +14279,7 @@ \section{Printing the deck} Jack of Spades Queen of Spades King of Spades -\end{verbatim} +\end{lstlisting} % Even though the result appears on 52 lines, it is one long string that contains newlines. @@ -14289,12 +14293,12 @@ \section{Add, remove, shuffle and sort} \index{pop method} \index{method!pop} -\begin{verbatim} +\begin{lstlisting}[language=python] #inside class Deck: def pop_card(self): return self.cards.pop() -\end{verbatim} +\end{lstlisting} % Since {\tt pop} removes the {\em last} card in the list, we are dealing from the bottom of the deck. @@ -14303,12 +14307,12 @@ \section{Add, remove, shuffle and sort} To add a card, we can use the list method {\tt append}: -\begin{verbatim} +\begin{lstlisting}[language=python] #inside class Deck: def add_card(self, card): self.cards.append(card) -\end{verbatim} +\end{lstlisting} % A method like this that uses another method without doing much work is sometimes called a {\bf veneer}. The metaphor @@ -14329,12 +14333,12 @@ \section{Add, remove, shuffle and sort} \index{shuffle function} \index{function!shuffle} -\begin{verbatim} +\begin{lstlisting}[language=python] # inside class Deck: def shuffle(self): random.shuffle(self.cards) -\end{verbatim} +\end{lstlisting} % Don't forget to import {\tt random}. @@ -14370,10 +14374,10 @@ \section{Inheritance} \index{Hand class} \index{class!Hand} -\begin{verbatim} +\begin{lstlisting}[language=python] class Hand(Deck): """Represents a hand of playing cards.""" -\end{verbatim} +\end{lstlisting} % This definition indicates that {\tt Hand} inherits from {\tt Deck}; that means we can use methods like \verb"pop_card" and \verb"add_card" @@ -14395,47 +14399,47 @@ \section{Inheritance} If we provide an init method in the {\tt Hand} class, it overrides the one in the {\tt Deck} class: -\begin{verbatim} +\begin{lstlisting}[language=python] # inside class Hand: def __init__(self, label=''): self.cards = [] self.label = label -\end{verbatim} +\end{lstlisting} % When you create a Hand, Python invokes this init method, not the one in {\tt Deck}. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> hand = Hand('new hand') >>> hand.cards [] >>> hand.label 'new hand' -\end{verbatim} +\end{lstlisting} % The other methods are inherited from {\tt Deck}, so we can use \verb"pop_card" and \verb"add_card" to deal a card: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> deck = Deck() >>> card = deck.pop_card() >>> hand.add_card(card) >>> print(hand) King of Spades -\end{verbatim} +\end{lstlisting} % A natural next step is to encapsulate this code in a method called \verb"move_cards": \index{encapsulation} -\begin{verbatim} +\begin{lstlisting}[language=python] #inside class Deck: def move_cards(self, hand, num): for i in range(num): hand.add_card(self.pop_card()) -\end{verbatim} +\end{lstlisting} % \verb"move_cards" takes two arguments, a Hand object and the number of cards to deal. It modifies both {\tt self} and {\tt hand}, and @@ -14561,20 +14565,20 @@ \section{Debugging} object and a method name (as a string) and returns the class that provides the definition of the method: -\begin{verbatim} +\begin{lstlisting}[language=python] def find_defining_class(obj, meth_name): for ty in type(obj).mro(): if meth_name in ty.__dict__: return ty -\end{verbatim} +\end{lstlisting} % Here's an example: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> hand = Hand() >>> find_defining_class(hand, 'shuffle') - -\end{verbatim} +<@\textcolor{black}{}@> +\end{lstlisting} % So the {\tt shuffle} method for this Hand is the one in {\tt Deck}. \index{mro method} @@ -14625,10 +14629,10 @@ \section{Data encapsulation} you'll see that it uses two global variables---\verb"suffix_map" and \verb"prefix"---that are read and written from several functions. -\begin{verbatim} +\begin{lstlisting}[language=python] suffix_map = {} prefix = () -\end{verbatim} +\end{lstlisting} Because these variables are global, we can only run one analysis at a time. If we read two texts, their prefixes and suffixes would be @@ -14639,18 +14643,18 @@ \section{Data encapsulation} the state of each analysis in an object. Here's what that looks like: -\begin{verbatim} +\begin{lstlisting}[language=python] class Markov: def __init__(self): self.suffix_map = {} self.prefix = () -\end{verbatim} +\end{lstlisting} Next, we transform the functions into methods. For example, here's \verb"process_word": -\begin{verbatim} +\begin{lstlisting}[language=python] def process_word(self, word, order=2): if len(self.prefix) < order: self.prefix += (word,) @@ -14663,7 +14667,7 @@ \section{Data encapsulation} self.suffix_map[self.prefix] = [word] self.prefix = shift(self.prefix, word) -\end{verbatim} +\end{lstlisting} Transforming a program like this---changing the design without changing the behavior---is another example of refactoring @@ -14768,8 +14772,8 @@ \section{Exercises} \begin{exercise} For the following program, draw a UML class diagram that shows these classes and the relationships among them. - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] class PingPongParent: pass @@ -14791,7 +14795,7 @@ \section{Exercises} pong = Pong() ping = Ping(pong) pong.add_ping(ping) -\end{verbatim} +\end{lstlisting}} \end{exercise} @@ -14916,12 +14920,12 @@ \section{Conditional expressions} \index{conditional expression} \index{expression!conditional} -\begin{verbatim} +\begin{lstlisting}[language=python] if x > 0: y = math.log(x) else: y = float('nan') -\end{verbatim} +\end{lstlisting} This statement checks whether {\tt x} is positive. If so, it computes {\tt math.log}. If not, {\tt math.log} would raise a ValueError. To @@ -14933,9 +14937,9 @@ \section{Conditional expressions} We can write this statement more concisely using a {\bf conditional expression}: -\begin{verbatim} +\begin{lstlisting}[language=python] y = math.log(x) if x > 0 else float('nan') -\end{verbatim} +\end{lstlisting} You can almost read this line like English: ``{\tt y} gets log-{\tt x} if {\tt x} is greater than 0; otherwise it gets NaN''. @@ -14945,20 +14949,20 @@ \section{Conditional expressions} \index{factorial} \index{function!factorial} -\begin{verbatim} +\begin{lstlisting}[language=python] def factorial(n): if n == 0: return 1 else: return n * factorial(n-1) -\end{verbatim} +\end{lstlisting} We can rewrite it like this: -\begin{verbatim} +\begin{lstlisting}[language=python] def factorial(n): return 1 if n == 0 else n * factorial(n-1) -\end{verbatim} +\end{lstlisting} Another use of conditional expressions is handling optional arguments. For example, here is the init method from @@ -14966,21 +14970,21 @@ \section{Conditional expressions} \index{optional argument} \index{argument!optional} -\begin{verbatim} +\begin{lstlisting}[language=python] def __init__(self, name, contents=None): self.name = name if contents == None: contents = [] self.pouch_contents = contents -\end{verbatim} +\end{lstlisting} We can rewrite this one like this: -\begin{verbatim} +\begin{lstlisting}[language=python] def __init__(self, name, contents=None): self.name = name self.pouch_contents = [] if contents == None else contents -\end{verbatim} +\end{lstlisting} In general, you can replace a conditional statement with a conditional expression if both branches contain simple expressions that are @@ -14996,21 +15000,21 @@ \section{List comprehensions} example, this function takes a list of strings, maps the string method {\tt capitalize} to the elements, and returns a new list of strings: -\begin{verbatim} +\begin{lstlisting}[language=python] def capitalize_all(t): res = [] for s in t: res.append(s.capitalize()) return res -\end{verbatim} +\end{lstlisting} We can write this more concisely using a {\bf list comprehension}: \index{list comprehension} -\begin{verbatim} +\begin{lstlisting}[language=python] def capitalize_all(t): return [s.capitalize() for s in t] -\end{verbatim} +\end{lstlisting} The bracket operators indicate that we are constructing a new list. The expression inside the brackets specifies the elements @@ -15030,21 +15034,21 @@ \section{List comprehensions} \index{filter pattern} \index{pattern!filter} -\begin{verbatim} +\begin{lstlisting}[language=python] def only_upper(t): res = [] for s in t: if s.isupper(): res.append(s) return res -\end{verbatim} +\end{lstlisting} We can rewrite it using a list comprehension -\begin{verbatim} +\begin{lstlisting}[language=python] def only_upper(t): return [s for s in t if s.isupper()] -\end{verbatim} +\end{lstlisting} List comprehensions are concise and easy to read, at least for simple expressions. And they are usually faster than the equivalent for @@ -15066,11 +15070,11 @@ \section{Generator expressions} \index{generator expression} \index{expression!generator} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> g = (x**2 for x in range(5)) >>> g at 0x7f4c45a786c0> -\end{verbatim} +\end{lstlisting} % The result is a generator object that knows how to iterate through a sequence of values. But unlike a list comprehension, it does not @@ -15079,12 +15083,12 @@ \section{Generator expressions} \index{generator object} \index{object!generator} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> next(g) 0 >>> next(g) 1 -\end{verbatim} +\end{lstlisting} % When you get to the end of the sequence, {\tt next} raises a StopIteration exception. You can also use a {\tt for} loop to iterate @@ -15092,32 +15096,32 @@ \section{Generator expressions} \index{StopIteration} \index{exception!StopIteration} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> for val in g: ... print(val) 4 9 16 -\end{verbatim} +\end{lstlisting} % The generator object keeps track of where it is in the sequence, so the {\tt for} loop picks up where {\tt next} left off. Once the generator is exhausted, it continues to raise {\tt StopIteration}: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> next(g) StopIteration -\end{verbatim} +\end{lstlisting} Generator expressions are often used with functions like {\tt sum}, {\tt max}, and {\tt min}: \index{sum} \index{function!sum} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> sum(x**2 for x in range(5)) 30 -\end{verbatim} +\end{lstlisting} \section{{\tt any} and {\tt all}} @@ -15128,19 +15132,19 @@ \section{{\tt any} and {\tt all}} \index{any} \index{built-in function!any} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> any([False, False, True]) True -\end{verbatim} +\end{lstlisting} % But it is often used with generator expressions: \index{generator expression} \index{expression!generator} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> any(letter == 't' for letter in 'monty') True -\end{verbatim} +\end{lstlisting} % That example isn't very useful because it does the same thing as the {\tt in} operator. But we could use {\tt any} to rewrite @@ -15149,10 +15153,10 @@ \section{{\tt any} and {\tt all}} \index{search pattern} \index{pattern!search} -\begin{verbatim} +\begin{lstlisting}[language=python] def avoids(word, forbidden): return not any(letter in forbidden for letter in word) -\end{verbatim} +\end{lstlisting} % The function almost reads like English, ``{\tt word} avoids {\tt forbidden} if there are not any forbidden letters in {\tt word}.'' @@ -15179,14 +15183,14 @@ \section{Sets} returns a dictionary that contains the keys from {\tt d1} that are not in {\tt d2}. -\begin{verbatim} +\begin{lstlisting}[language=python] def subtract(d1, d2): res = dict() for key in d1: if key not in d2: res[key] = None return res -\end{verbatim} +\end{lstlisting} % In all of these dictionaries, the values are {\tt None} because we never use them. As a result, we waste some storage space. @@ -15204,10 +15208,10 @@ \section{Sets} {\tt subtract} like this: \index{set subtraction} -\begin{verbatim} +\begin{lstlisting}[language=python] def subtract(d1, d2): return set(d1) - set(d2) -\end{verbatim} +\end{lstlisting} % The result is a set instead of a dictionary, but for operations like iteration, the behavior is the same. @@ -15217,7 +15221,7 @@ \section{Sets} \verb"has_duplicates", from Exercise~\ref{duplicate}, that uses a dictionary: -\begin{verbatim} +\begin{lstlisting}[language=python] def has_duplicates(t): d = {} for x in t: @@ -15225,7 +15229,7 @@ \section{Sets} return True d[x] = True return False -\end{verbatim} +\end{lstlisting} When an element appears for the first time, it is added to the dictionary. If the same element appears again, the function returns @@ -15233,10 +15237,10 @@ \section{Sets} Using sets, we can write the same function like this: -\begin{verbatim} +\begin{lstlisting}[language=python] def has_duplicates(t): return len(set(t)) < len(t) -\end{verbatim} +\end{lstlisting} % An element can only appear in a set once, so if an element in {\tt t} appears more than once, the set will be smaller than {\tt t}. If there @@ -15247,21 +15251,21 @@ \section{Sets} Chapter~\ref{wordplay}. For example, here's a version of \verb"uses_only" with a loop: -\begin{verbatim} +\begin{lstlisting}[language=python] def uses_only(word, available): for letter in word: if letter not in available: return False return True -\end{verbatim} +\end{lstlisting} % \verb"uses_only" checks whether all letters in {\tt word} are in {\tt available}. We can rewrite it like this: -\begin{verbatim} +\begin{lstlisting}[language=python] def uses_only(word, available): return set(word) <= set(available) -\end{verbatim} +\end{lstlisting} % The \verb"<=" operator checks whether one set is a subset of another, including the possibility that they are equal, which is true if all @@ -15287,12 +15291,12 @@ \section{Counters} \index{collections} \index{module!collections} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> from collections import Counter >>> count = Counter('parrot') >>> count Counter({'r': 2, 't': 1, 'o': 1, 'p': 1, 'a': 1}) -\end{verbatim} +\end{lstlisting} Counters behave like dictionaries in many ways; they map from each key to the number of times it appears. As in dictionaries, @@ -15301,18 +15305,18 @@ \section{Counters} Unlike dictionaries, Counters don't raise an exception if you access an element that doesn't appear. Instead, they return 0: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> count['d'] 0 -\end{verbatim} +\end{lstlisting} We can use Counters to rewrite \verb"is_anagram" from Exercise~\ref{anagram}: -\begin{verbatim} +\begin{lstlisting}[language=python] def is_anagram(word1, word2): return Counter(word1) == Counter(word2) -\end{verbatim} +\end{lstlisting} If two words are anagrams, they contain the same letters with the same counts, so their Counters are equivalent. @@ -15323,14 +15327,14 @@ \section{Counters} returns a list of value-frequency pairs, sorted from most common to least: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> count = Counter('parrot') >>> for val, freq in count.most_common(3): ... print(val, freq) r 2 p 1 a 1 -\end{verbatim} +\end{lstlisting} \section{defaultdict} @@ -15349,29 +15353,29 @@ \section{defaultdict} and other types can be used as factories: \index{factory function} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> from collections import defaultdict >>> d = defaultdict(list) -\end{verbatim} +\end{lstlisting} Notice that the argument is {\tt list}, which is a class object, not {\tt list()}, which is a new list. The function you provide doesn't get called unless you access a key that doesn't exist. -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t = d['new key'] >>> t [] -\end{verbatim} +\end{lstlisting} The new list, which we're calling {\tt t}, is also added to the dictionary. So if we modify {\tt t}, the change appears in {\tt d}: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> t.append('new value') >>> d -defaultdict(, {'new key': ['new value']}) -\end{verbatim} +<@\textcolor{black}{defaultdict(, {'new key': ['new value']})}@> +\end{lstlisting} If you are making a dictionary of lists, you can often write simpler code using {\tt defaultdict}. In my solution to @@ -15384,7 +15388,7 @@ \section{defaultdict} Here's the original code: -\begin{verbatim} +\begin{lstlisting}[language=python] def all_anagrams(filename): d = {} for line in open(filename): @@ -15395,13 +15399,13 @@ \section{defaultdict} else: d[t].append(word) return d -\end{verbatim} +\end{lstlisting} This can be simplified using {\tt setdefault}, which you might have used in Exercise~\ref{setdefault}: \index{setdefault} -\begin{verbatim} +\begin{lstlisting}[language=python] def all_anagrams(filename): d = {} for line in open(filename): @@ -15409,7 +15413,7 @@ \section{defaultdict} t = signature(word) d.setdefault(t, []).append(word) return d -\end{verbatim} +\end{lstlisting} This solution has the drawback that it makes a new list every time, regardless of whether it is needed. For lists, @@ -15420,7 +15424,7 @@ \section{defaultdict} We can avoid this problem and simplify the code using a {\tt defaultdict}: -\begin{verbatim} +\begin{lstlisting}[language=python] def all_anagrams(filename): d = defaultdict(list) for line in open(filename): @@ -15428,7 +15432,7 @@ \section{defaultdict} t = signature(word) d[t].append(word) return d -\end{verbatim} +\end{lstlisting} My solution to Exercise~\ref{poker}, which you can download from \url{http://thinkpython2.com/code/PokerHandSoln.py}, @@ -15446,7 +15450,7 @@ \section{Named tuples} two numbers, {\tt x} and {\tt y}. When you define a class like this, you usually start with an init method and a str method: -\begin{verbatim} +\begin{lstlisting}[language=python] class Point: def __init__(self, x=0, y=0): @@ -15455,15 +15459,15 @@ \section{Named tuples} def __str__(self): return '(%g, %g)' % (self.x, self.y) -\end{verbatim} +\end{lstlisting} This is a lot of code to convey a small amount of information. Python provides a more concise way to say the same thing: -\begin{verbatim} +\begin{lstlisting}[language=python] from collections import namedtuple Point = namedtuple('Point', ['x', 'y']) -\end{verbatim} +\end{lstlisting} The first argument is the name of the class you want to create. The second is a list of the attributes Point objects should have, @@ -15473,10 +15477,10 @@ \section{Named tuples} \index{collections} \index{module!collections} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> Point -\end{verbatim} +\end{lstlisting} {\tt Point} automatically provides methods like \verb"__init__" and \verb"__str__" so you don't have to write them. @@ -15485,11 +15489,11 @@ \section{Named tuples} To create a Point object, you use the Point class as a function: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> p = Point(1, 2) >>> p Point(x=1, y=2) -\end{verbatim} +\end{lstlisting} The init method assigns the arguments to attributes using the names you provided. The str method prints a representation of the Point @@ -15497,21 +15501,21 @@ \section{Named tuples} You can access the elements of the named tuple by name: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> p.x, p.y (1, 2) -\end{verbatim} +\end{lstlisting} But you can also treat a named tuple as a tuple: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> p[0], p[1] (1, 2) >>> x, y = p >>> x, y (1, 2) -\end{verbatim} +\end{lstlisting} Named tuples provide a quick way to define simple classes. The drawback is that simple classes don't always stay simple. @@ -15520,10 +15524,10 @@ \section{Named tuples} the named tuple: \index{inheritance} -\begin{verbatim} +\begin{lstlisting}[language=python] class Pointier(Point): # add more methods here -\end{verbatim} +\end{lstlisting} Or you could switch to a conventional class definition. @@ -15534,67 +15538,67 @@ \section{Gathering keyword args} gathers its arguments into a tuple: \index{gather} -\begin{verbatim} +\begin{lstlisting}[language=python] def printall(*args): print(args) -\end{verbatim} +\end{lstlisting} % You can call this function with any number of positional arguments (that is, arguments that don't have keywords): \index{positional argument} \index{argument!positional} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> printall(1, 2.0, '3') (1, 2.0, '3') -\end{verbatim} +\end{lstlisting} % But the {\tt *} operator doesn't gather keyword arguments: \index{keyword argument} \index{argument!keyword} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> printall(1, 2.0, third='3') TypeError: printall() got an unexpected keyword argument 'third' -\end{verbatim} +\end{lstlisting} % To gather keyword arguments, you can use the {\tt **} operator: -\begin{verbatim} +\begin{lstlisting}[language=python] def printall(*args, **kwargs): print(args, kwargs) -\end{verbatim} +\end{lstlisting} % You can call the keyword gathering parameter anything you want, but {\tt kwargs} is a common choice. The result is a dictionary that maps keywords to values: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> printall(1, 2.0, third='3') (1, 2.0) {'third': '3'} -\end{verbatim} +\end{lstlisting} % If you have a dictionary of keywords and values, you can use the scatter operator, {\tt **} to call a function: \index{scatter} -\begin{verbatim} +\begin{lstlisting}[language=python] >>> d = dict(x=1, y=2) >>> Point(**d) Point(x=1, y=2) -\end{verbatim} +\end{lstlisting} % Without the scatter operator, the function would treat {\tt d} as a single positional argument, so it would assign {\tt d} to {\tt x} and complain because there's nothing to assign to {\tt y}: -\begin{verbatim} +\begin{lstlisting}[language=python] >>> d = dict(x=1, y=2) >>> Point(d) Traceback (most recent call last): File "", line 1, in TypeError: __new__() missing 1 required positional argument: 'y' -\end{verbatim} +\end{lstlisting} % When you are working with functions that have a large number of parameters, it is often useful to create and pass around dictionaries @@ -15637,8 +15641,8 @@ \section{Exercises} The following is a function computes the binomial coefficient recursively. - -\begin{verbatim} +{\tt +\begin{lstlisting}[language=python] def binomial_coeff(n, k): """Compute the binomial coefficient "n choose k". @@ -15654,7 +15658,7 @@ \section{Exercises} res = binomial_coeff(n-1, k) + binomial_coeff(n-1, k-1) return res -\end{verbatim} +\end{lstlisting}} Rewrite the body of the function using nested conditional expressions. @@ -15908,7 +15912,7 @@ \subsubsection{Infinite Loop} For example: -\begin{verbatim} +\begin{lstlisting}[language=python] while x > 0 and y < 0 : # do something to x # do something to y @@ -15916,7 +15920,7 @@ \subsubsection{Infinite Loop} print('x: ', x) print('y: ', y) print("condition: ", (x > 0 and y < 0)) -\end{verbatim} +\end{lstlisting} % Now when you run the program, you will see three lines of output for each time through the loop. The last time through the @@ -16171,17 +16175,17 @@ \subsection{I've got a big hairy expression and it doesn't For example: -\begin{verbatim} +\begin{lstlisting}[language=python] self.hands[i].addCard(self.hands[self.findNeighbor(i)].popCard()) -\end{verbatim} +\end{lstlisting} % This can be rewritten as: -\begin{verbatim} +\begin{lstlisting}[language=python] neighbor = self.findNeighbor(i) pickedCard = self.hands[neighbor].popCard() self.hands[i].addCard(pickedCard) -\end{verbatim} +\end{lstlisting} % The explicit version is easier to read because the variable names provide additional documentation, and it is easier to debug @@ -16195,9 +16199,9 @@ \subsection{I've got a big hairy expression and it doesn't For example, if you are translating the expression $\frac{x}{2 \pi}$ into Python, you might write: -\begin{verbatim} +\begin{lstlisting}[language=python] y = x / 2 * math.pi -\end{verbatim} +\end{lstlisting} % That is not correct because multiplication and division have the same precedence and are evaluated from left to right. @@ -16208,9 +16212,9 @@ \subsection{I've got a big hairy expression and it doesn't A good way to debug expressions is to add parentheses to make the order of evaluation explicit: -\begin{verbatim} +\begin{lstlisting}[language=python] y = x / (2 * math.pi) -\end{verbatim} +\end{lstlisting} % Whenever you are not sure of the order of evaluation, use parentheses. Not only will the program be correct (in the sense @@ -16228,16 +16232,16 @@ \subsection{I've got a function that doesn't return what I returning. Again, you can use a temporary variable. For example, instead of: -\begin{verbatim} +\begin{lstlisting}[language=python] return self.hands[i].removeMatches() -\end{verbatim} +\end{lstlisting} % you could write: -\begin{verbatim} +\begin{lstlisting}[language=python] count = self.hands[i].removeMatches() return count -\end{verbatim} +\end{lstlisting} % Now you have the opportunity to display the value of {\tt count} before returning. @@ -16574,11 +16578,11 @@ \section{Analysis of basic Python operations} of the loop are constant time. For example, adding up the elements of a list is linear: -\begin{verbatim} +\begin{lstlisting}[language=python] total = 0 for x in t: total += x -\end{verbatim} +\end{lstlisting} The built-in function {\tt sum} is also linear because it does the same thing, but it tends to be faster because it is a more @@ -16766,7 +16770,7 @@ \section{Hashtables} tuples, where each tuple is a key-value pair. \index{LinearMap@{\tt LinearMap}} -\begin{verbatim} +\begin{lstlisting}[language=python] class LinearMap: def __init__(self): @@ -16780,7 +16784,7 @@ \section{Hashtables} if key == k: return val raise KeyError -\end{verbatim} +\end{lstlisting} {\tt add} appends a key-value tuple to the list of items, which takes constant time. @@ -16806,7 +16810,7 @@ \section{Hashtables} but {\tt BetterMap} is a step on the path toward hashtables: \index{BetterMap@{\tt BetterMap}} -\begin{verbatim} +\begin{lstlisting}[language=python] class BetterMap: def __init__(self, n=100): @@ -16825,7 +16829,7 @@ \section{Hashtables} def get(self, k): m = self.find_map(k) return m.get(k) -\end{verbatim} +\end{lstlisting} \verb"__init__" makes a list of {\tt n} {\tt LinearMap}s. @@ -16868,7 +16872,7 @@ \section{Hashtables} Here is an implementation of a hashtable: \index{HashMap} -\begin{verbatim} +\begin{lstlisting}[language=python] class HashMap: def __init__(self): @@ -16893,7 +16897,7 @@ \section{Hashtables} new_maps.add(k, v) self.maps = new_maps -\end{verbatim} +\end{lstlisting} \verb"__init__" creates a {\tt BetterMap} and initializes {\tt num}, which keeps track of the number of items. @@ -17037,3 +17041,4 @@ \section{Glossary} \end{document} + diff --git a/book/codecolor.tex b/book/codecolor.tex new file mode 100644 index 0000000..2669bb3 --- /dev/null +++ b/book/codecolor.tex @@ -0,0 +1,17 @@ +\lstset{escapeinside={<@}{@>}} +\definecolor{pyblue}{RGB}{0,0,102} % for comments +\definecolor{pybrown}{RGB}{102,0,0} % for commands +\definecolor{pygreen}{RGB}{0,102,102} % for keywords +\definecolor{pyred}{RGB}{102,0,102} % for strings + +\lstset{language=Python, +otherkeywords={True, False, None, nonlocal, yield}, +morekeywords={0,1,2,3,4,5,6,7,8,9}, +basicstyle=\ttfamily, +keywordstyle=\ttfamily\bfseries\color{pybrown}, +stringstyle=\ttfamily\color{pyred}, +commentstyle=\ttfamily\color{pyblue}, +morecomment=[s][\ttfamily\color{pyred}]{"""}{"""}, +tabsize=4, +showspaces=false, +showstringspaces=false}