python习题

Exercises? 1.11. Exercises?
1. Write an English sentence with understandable semantics but incorrect syntax. Write another English sentence which has correct syntax but has semantic errors.

2.

Start a Python shell. Type 1 + 2 and then hit return. Python evaluates this expression, prints the result, and then prints another prompt. * is the multiplication operator, and ** is the exponentiation operator. Experiment by entering different expressions and recording what is printed by the Python interpreter. What happens if you use the / operator? Are the results what you expect? Explain.

3.

Type 1 2 and then hit return. Python tries to evaluate the expression, but it can’t because the expression is not syntactically legal. Instead, it prints the error message:

4. 5. 6.

File "<stdin>", line 1 1 2 ^

SyntaxError: invalid syntax

In many cases, Python indicates where the syntax error occurred, but it is not always right, and it doesn’t give you much information about what is wrong.

So, for the most part, the burden is on you to learn the syntax rules.

In this case, Python is complaining because there is no operator between the numbers.

See if you can find a few more examples of things that will produce error messages when you enter them at the Python prompt. Write down what you enter at the prompt and the last line of the error message that Python reports back to you.

7.

Type print ‘hello’. Python executes this statement, which has the effect of printing the letters h-e-l-l-o. Notice that the quotation marks that you used to enclose the string are not part of the output. Now type "hello" and describe your result. Make note of when you see the quotation marks and when you don’t.

8.

Type print cheese without the quotation marks. The output will look something like this:

9. 10.

Traceback (most recent call last): File "<stdin>", line 1, in ?

NameError: name 'cheese' is not defined

This is a run-time error; specifically, it is a NameError, and even more specifically, it is an error because the name cheese is not defined. If you don’t know what that means yet, you will soon.

11.

Type 'This is a test...' at the Python prompt and hit enter. Record what happens.

Now create a python script named test1.py with the following contents (be sure to save it before you try to run it):

'This is a test...'

What happens when you run this script? Now change the contents to:

print 'This is a test...'

and run it again.

What happened this time?

Whenever an expression is typed at the Python prompt, it is evaluated and the result is printed on the line below. 'This is a test...' is an expression, which evaluates to 'This is a test...' (just like the expression 42 evaluates to 42). In a script, however, evaluations of expressions are not sent to the program output, so it is necessary to explicitly print them.

Exercises? 2.13. Exercises?
1. Record what happens when you print an assignment statement:

2.

>>> print n = 7

How about this?

>>> print 7 + 5

Or this?

>>> print 5.2, "this", 4 - 2, "that", 5/2.0

Can you think a general rule for what can follow the print statement? What does the print statement return?

3.

Take the sentence: All work and no play makes Jack a dull boy. Store each word in a separate variable, then print out the sentence on one line using print.

4.

Add parenthesis to the expression 6 * 1 - 2 to change its value from 4 to -6.

5.

Place a comment before a line of code that previously worked, and record what happens when you rerun the program.

6.

The difference between input and raw_input is that input evaluates the input string and raw_input does not. Try the following in the interpreter and record what happens:

7. 8. 9. 10. 11. 12. 13. 14. 15.

>>> x = input() 3.14 >>> type(x) >>> x = raw_input() 3.14 >>> type(x) >>> x = input() 'The knights who say "ni!"' >>> x

What happens if you try the example above without the quotation marks?

>>> x = input() The knights who say "ni!" >>> x >>> x = raw_input() 'The knights who say "ni!"' >>> x

Describe and explain each result.

16.

Start the Python interpreter and enter bruce + 4 at the prompt. This will give you an error:

NameError: name 'bruce' is not defined

Assign a value to bruce so that bruce + 4 evaluates to 10.

17.

Write a program (Python script) named madlib.py, which asks the user to enter a series of nouns, verbs, adjectives, adverbs, plural nouns, past tense verbs, etc., and then generates a paragraph which is syntactically correct but semantically ridiculous (see http://madlibs.org for examples).

3.8. Exercises? Exercises?
1. Using a text editor, create a Python script named tryme3.py . Write a function in this file called nine_lines that uses
three_lines to print nine blank lines. Now add a function named clear_screen that prints out twenty-five blank

lines. The last line of your program should be a call to clear_screen.

2.

Move the last line of tryme3.py to the top of the program, so the function call to clear_screen appears before the

function definition. Run the program and record what error message you get. Can you state a rule about function definitions and function calls which describes where they can appear relative to each other in a program?

3.

Starting with a working version of tryme3.py , move the definition of new_line after the definition of three_lines. Record what happens when you run this program. Now move the definition of new_line below a call to
three_lines(). Explain how this is an example of the rule you stated in the previous exercise.

4.

Fill in the body of the function definition for cat_n_times so that it will print the string, s, n times:

5.

def cat_n_times(s, n):

<fill in your code here>

Save this function in a script named import_test.py. Now at a unix prompt, make sure you are in the same directory where the import_test.py is located ( ls should show import_test.py). Start a Python shell and try the following:

>>> from import_test import * >>> cat_n_times('Spam', 7) SpamSpamSpamSpamSpamSpamSpam

If all is well, your session should work the same as this one. Experiment with other calls to cat_n_times until you feel comfortable with how it works.

Exercises? 4.13. Exercises?
1. Try to evaluate the following numerical expressions in your head, then use the Python interpreter to check your results:

1. 2. 3. 4. 5. 6. 7.

>>> 5 % 2

>>> 9 % 5

>>> 15 % 12

>>> 12 % 15

>>> 6 % 6

>>> 0 % 7

>>> 7 % 0

What happened with the last example? Why? If you were able to correctly anticipate the computer’s response in all but the last one, it is time to move on. If not, take time now to make up examples of your own. Explore the modulus operator until you are confident you understand how it works.

2. 3. 4. 5. 6. 7.

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"

8.

Wrap this code in a function called compare(x, y). Call compare three times: one each where the first
argument is less than, greater than, and equal to the second argument.

9.

To better understand boolean expressions, it is helpful to construct truth tables. Two boolean expressions are logically equivalent if and only if they have the same truth table.

The following Python script prints out the truth table for any boolean expression in two variables: p and q:

expression = raw_input("Enter a boolean expression in two variables, p and q: ")

print " p

q

%s"

% expression

length = len( " p print length*"="

q

%s"

% expression)

for p in True, False: for q in True, False: print "%-7s %-7s %-7s" % (p, q, eval(expression))

You will learn how this script works in later chapters. For now, you will use it to learn about boolean expressions. Copy this program to a file named p_and_q.py, then run it from the command line and give it: p or q, when prompted for a boolean expression. You should get the following output:

p

q

p or q

===================== True True False False True False True False True True True False

Now that we see how it works, let’s wrap it in a function to make it easier to use:

def truth_table(expression): print " p q %s" q % expression %s" % expression)

length = len( " p print length*"="

for p in True, False: for q in True, False: print "%-7s %-7s %-7s" % (p, q, eval(expression))

We can import it into a Python shell and call truth_table with a string containing our boolean expression in p and q as an argument:

>>> from p_and_q import * >>> truth_table("p or q") p q p or q

===================== True True True

True False False >>>

False True False

True True False

Use the truth_table functions with the following boolean expressions, recording the truth table produced each time:

1. 2. 3. 4. 5.

not(p or q) p and q not(p and q) not(p) or not(q) not(p) and not(q)

Which of these are logically equivalent?

10.

Enter the following expressions into the Python shell:

11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.

True or False True and False not(False) and True True or 7 False or 7 True and 0 False or 8 "happy" and "sad" "happy" or "sad" "" and "sad" "happy" and ""

Analyze these results. What observations can you make about values of different types and logical operators? Can you write these observations in the form of simple rules about and and or expressions?

22. 23. 24.

if choice == 'a': function_a() elif choice == 'b':

25. 26. 27. 28. 29.

function_b() elif choice == 'c': function_c() else: print "Invalid choice."

30.

Wrap this code in a function called dispatch(choice). Then define function_a, function_b, and
function_c so that they print out a message saying they were called. For example:

31. 32.

def function_a(): print "function_a was called..."

Put the four functions ( dispatch, function_a, function_b, and function_c into a script named
ch04e05.py. At the bottom of this script add a call to dispatch('b'). Your output should be:

function_b was called...

Finally, modify the script so that user can enter ‘a’, ‘b’, or ‘c’. Test it by importing your script into the Python shell.

33.

Write a function named is_divisible_by_3 that takes a single integer as an argument and prints “This number is divisible by three.” if the argument is evenly divisible by 3 and “This number is not divisible by three.” otherwise.

Now write a similar function named is_divisible_by_5.

34.

Generalize the functions you wrote in the previous exercise into a function named is_divisible_by_n(x,
n) that takes two integer arguments and prints out whether the first is divisible by the second. Save this

in a file named ch04e07.py. Import it into a shell and try it out. A sample session might look like this:

35. 36. 37. 38. 39.

>>> from ch04e07 import * >>> is_divisible_by_n(20, 4) Yes, 20 is divisible by 4 >>> is_divisible_by_n(21, 8) No, 21 is not divisible by 8

40.

What will be the output of the following?

41. 42. 43. 44. 45. 46. 47. 48. 49.

if "Ni!": print 'We are the Knights who say, "Ni!"' else: print "Stop it! No more of this!"

if 0: print "And now for something completely different..." else: print "What's all this, then?"

Explain what happened and why it happened.

50.

The following gasp script, in a file named house.py, draws a simple house on a gasp canvas:

51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65.

from gasp import *

# import everything from the gasp library

begin_graphics()

# open the graphics canvas

Box((20, 20), 100, 100) Box((55, 20), 30, 50) Box((40, 80), 20, 20) Box((80, 80), 20, 20) Line((20, 120), (70, 160))

# the house # the door # the left window # the right window # the left roof

Line((70, 160), (120, 120)) # the right roof

update_when('key_pressed') end_graphics()

# keep the canvas open until a key is pressed # close the canvas (which would happen # anyway, since the script ends here, but it # is better to be explicit).

Run this script and confirm that you get a window that looks like this:

1. 2. 3. 4.

Wrap the house code in a function named draw_house(). Run the script now. Do you see a house? Why not? Add a call to draw_house() at the botton of the script so that the house returns to the screen.

Parameterize the function with x and y parameters – the header should then become def
draw_house(x, y):, so that you can pass in the location of the house on the canvas.

5. 66.

Use draw_house to place five houses on the canvas in different locations. o

Exploration: Read over Appendix B and write a script named houses.py that produces the following
when run:

hint: You will need to use a Polygon for the roof instead of two Lines to get filled=True to work with it.

Exercises? 5.10. Exercises?

All of the exercises below should be added to a file named ch05.py that contains the following at the bottom:

if __name__ == '__main__': import doctest doctest.testmod()

After completing each exercise in turn, run the program to confirm that the doctests for your new function pass.

1.

Write a compare function that returns 1 if a > b, 0 if a == b, and -1 if a < b.

2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.

def compare(a, b): """ >>> compare(5, 4) 1 >>> compare(7, 7) 0 >>> compare(2, 3) -1 >>> compare(42, 1) 1 """ # Your function body should begin here.

Fill in the body of the function so the doctests pass.

14.

Use incremental development to write a function called hypotenuse that returns the length of the hypotenuse of a right triangle given the lengths of the two legs as parameters. Record each stage of the incremental development process as you go.

15. 16. 17. 18. 19. 20. 21. 22. 23.

def hypotenuse(a, b): """ >>> hypotenuse(3, 4) 5.0 >>> hypotenuse(12, 5) 13.0 >>> hypotenuse(7, 24) 25.0 >>> hypotenuse(9, 12)

24. 25.

15.0 """

When you are finished add your completed function with the doctests to ch05.py and confirm that the doctests pass.

26.

Write a function slope(x1, y1, x2, y2) that returns the slope of the line through the points (x1, y1) and (x2, y2). Be sure your implementation of slope can pass the following doctests:

27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37.

def slope(x1, y1, x2, y2): """ >>> slope(5, 3, 4, 2) 1.0 >>> slope(1, 2, 3, 2) 0.0 >>> slope(1, 2, 3, 3) 0.5 >>> slope(2, 4, 1, 2) 2.0 """

Then a call to slope in a new function named intercept(x1, y1, x2, y2) that returns the y-intercept of the line through the points (x1, y1) and (x2, y2).

def intercept(x1, y1, x2, y2): """ >>> intercept(1, 6, 3, 12) 3.0 >>> intercept(6, 1, 1, 6) 7.0 >>> intercept(4, 6, 12, 8) 5.0 """

intercept should pass the doctests above.

38.

Write a function called is_even(n) that takes an integer as an argument and returns True if the argument is an even odd. number and False if it is odd

Add your own doctests to this function.

39.

Now write the function is_odd(n) that returns True when n is odd and False otherwise. Include doctests for this function as you write it.

Finally, modify it so that it uses a call to is_even to determine if its argument is an odd integer.

40.

Add the following function definition header and doctests to ch05.py:

41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53.

def is_factor(f, n): """ >>> is_factor(3, 12) True >>> is_factor(5, 12) False >>> is_factor(7, 14) True >>> is_factor(2, 14) True >>> is_factor(7, 15) False """

Add a body to is_factor to make the doctests pass.

54.

Add the following function definition header and doctests to ch05.py:

55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66.

def is_multiple(m, n): """ >>> is_multiple(12, 3) True >>> is_multiple(12, 4) True >>> is_multiple(12, 5) False >>> is_multiple(12, 6) True >>> is_multiple(12, 7) False

67.

"""

Add a body to is_multiple to make the doctests pass. Can you find a way to use is_factor in your definition of
is_multiple?

68.

Add the following function definition header and doctests to ch05.py:

69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85.

def f2c(t): """ >>> f2c(212) 100 >>> f2c(32) 0 >>> f2c(-40) -40 >>> f2c(36) 2 >>> f2c(37) 3 >>> f2c(38) 3 >>> f2c(39) 4 """

Write a body for the function definition of f2c designed to return the integer value of the nearest degree Celsius for given tempurature in Fahrenheit. (hint: you may want to make use of the built-in function, round. Try printing
round.__doc__ in a Python shell and experimenting with round until you are comfortable with how it works.)

86.

Add the following function definition header and doctests to ch05.py:

87. 88. 89. 90. 91. 92.

def c2f(t): """ >>> c2f(0) 32 >>> c2f(100) 212

93. 94. 95. 96. 97. 98. 99. 100. 101.

>>> c2f(-40) -40 >>> c2f(12) 54 >>> c2f(18) 64 >>> c2f(-48) -54 """

Add a function body for c2f to convert from Celsius to Fahrenheit.

Exercises? 6.17. Exercises?
1. Write a single string that:

2. 3.

produces this

output.

4.

Add a print statement to the sqrt function defined in section 6.14 that prints out better each time it is calculated. Call your modified function with 25 as an argument and record the results.

5.

Trace the execution of the last version of print_mult_table and figure out how it works.

6.

Write a function print_triangular_numbers(n) that prints out the first n triangular numbers. A call to
print_triangular_numbers(5) would produce the following output:

7. 8. 9. 10.

1 2 3 4

1 3 6 10

5

15

(hint: use a web search to find out what a triangular number is.)

11.

Open a file named ch06.py and add the following:

12. 13. 14.

if __name__ == '__main__': import doctest doctest.testmod()

Write a function, is_prime, which takes a single integral argument and returns True when the argument is a prime number and False otherwise. Add doctests to your function as you develop it.

15.

What will num_digits(0) return? Modify it to return 1 for this case. Why does a call to num_digits(-24) result in an infinite loop (hint: -1/10 evaluates to -1)? Modify num_digits so that it works correctly with any integer value. Add the following to the ch06.py file you created in the previous exercise:

16. 17. 18. 19. 20. 21. 22. 23. 24.

def num_digits(n): """ >>> num_digits(12345) 5 >>> num_digits(0) 1 >>> num_digits(-12345) 5 """

Add your function body to num_digits and confirm that it passes the doctests.

25.

Add the following to the ch06.py:

26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37.

def num_even_digits(n): """ >>> num_even_digits(123456) 3 >>> num_even_digits(2468) 4 >>> num_even_digits(1357) 0 >>> num_even_digits(2) 1 >>> num_even_digits(20) 2

38.

"""

Write a body for num_even_digits so that it works as expected.

39.

Add the following to ch06.py:

40. 41. 42. 43. 44. 45. 46. 47. 48.

def print_digits(n): """ >>> print_digits(13789) 9 8 7 3 1 >>> print_digits(39874613) 3 1 6 4 7 8 9 3 >>> print_digits(213141) 1 4 1 3 1 2 """

Write a body for print_digits so that it passes the given doctests.

49.

Write a function sum_of_squares_of_digits that computes the sum of the squares of the digits of an integer passed to it. For example, sum_of_squares_of_digits(987) should return 194, since 9**2 + 8**2 + 7**2 == 81 + 64 + 49
== 194.

50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62.

def sum_of_squares_of_digits(n): """ >>> sum_of_squares_of_digits(1) 1 >>> sum_of_squares_of_digits(9) 81 >>> sum_of_squares_of_digits(11) 2 >>> sum_of_squares_of_digits(121) 6 >>> sum_of_squares_of_digits(987) 194 """

Check your solution against the doctests above.

Exercises? 7.14.1. First Exercises?

1.

Write the Python interpreter’s evaluation to each of the following expressions:

2. 3. 4. 5. 6. 7. 8. 9. 10.

>>> 'Python'[1] >>> "Strings are sequences of characters."[5] >>> len("wonderful") >>> 'Mystery'[:4] >>> 'p' in 'Pinapple' >>> 'apple' in 'Pinapple' >>> 'pear' in 'Pinapple' >>> 'apple' > 'pinapple' >>> 'pinapple' < 'Peach'

11.

Write Python code to make each of the following doctests pass:

12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33.

""" >>> type(fruit) <type 'str'> >>> len(fruit) 8 >>> fruit[:3] 'ram' """ """ >>> group = "John, Paul, George, and Ringo" >>> group[12:x] 'George' >>> group[n:m] 'Paul' >>> group[:r] 'John' >>> group[s:] 'Ringo' """ """ >>> len(s) 8

34. 35. 36.

>>> s[4:6] == 'on' True """

Exercises? 7.16. Exercises?
1. Modify:

2. 3. 4. 5. 6.

prefixes = "JKLMNOPQ" suffix = "ack"

for letter in prefixes: print letter + suffix

so that Ouack and Quack are spelled correctly.

7.

Encapsulate

8. 9. 10. 11. 12. 13.

fruit = "banana" count = 0 for char in fruit: if char == 'a': count += 1 print count

in a function named count_letters, and generalize it so that it accepts the string and the letter as arguments.

14.

Now rewrite the count_letters function so that instead of traversing the string, it repeatedly calls find (the version from Optional parameters), with the optional third parameter to locate new occurences of the letter being counted.

15.

Which version of is_lower do you think will be fastest? Can you think of other reasons besides speed to prefer one version or the other?

16.

Create a file named stringtools.py and put the following in it:

17.

def reverse(s):

18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31.

""" >>> reverse('happy') 'yppah' >>> reverse('Python') 'nohtyP' >>> reverse("") '' >>> reverse("P") 'P' """

if __name__ == '__main__': import doctest doctest.testmod()

Add a function body to reverse to make the doctests pass.

32.

Add mirror to stringtools.py .

33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45.

def mirror(s): """ >>> mirror("good") 'gooddoog' >>> mirror("yes") 'yessey' >>> mirror('Python') 'PythonnohtyP' >>> mirror("") '' >>> mirror("a") 'aa' """

Write a function body for it that will make it work as indicated by the doctests.

46.

Include remove_letter in stringtools.py .

47.

def remove_letter(letter, strng):

48. 49. 50. 51. 52. 53. 54. 55. 56. 57.

""" >>> remove_letter('a', 'apple') 'pple' >>> remove_letter('a', 'banana') 'bnn' >>> remove_letter('z', 'banana') 'banana' >>> remove_letter('i', 'Mississippi') 'Msssspp' """

Write a function body for it that will make it work as indicated by the doctests.

58.

Finally, add bodies to each of the following functions, one at a time

59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80.

def is_palindrome(s): """ >>> is_palindrome('abba') True >>> is_palindrome('abab') False >>> is_palindrome('tenet') True >>> is_palindrome('banana') False >>> is_palindrome('straw warts') True """ def count(sub, s): """ >>> count('is', 'Mississippi') 2 >>> count('an', 'banana') 2 >>> count('ana', 'banana') 2 >>> count('nana', 'banana')

81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106.

1 >>> count('nanan', 'banana') 0 """ def remove(sub, s): """ >>> remove('an', 'banana') 'bana' >>> remove('cyc', 'bicycle') 'bile' >>> remove('iss', 'Mississippi') 'Missippi' >>> remove('egg', 'bicycle') 'bicycle' """ def remove_all(sub, s): """ >>> remove_all('an', 'banana') 'ba' >>> remove_all('cyc', 'bicycle') 'bile' >>> remove_all('iss', 'Mississippi') 'Mippi' >>> remove_all('eggs', 'bicycle') 'bicycle' """

until all the doctests pass.

107. Try each of the following formatted string operations in a Python shell and record the results:

1. 2. 3. 4.

“%s %d %f” % (5, 5, 5) “%-.2f” % 3 “%-10.2f%-10.2f” % (7, 1.0/2) print ” $%5.2fn $%5.2fn $%5.2f” % (3, 4.5, 11.2)

108. The following formatted strings have errors. Fix them:

1. 2. 3.

“%s %s %s %s” % (‘this’, ‘that’, ‘something’) “%s %s %s” % (‘yes’, ‘no’, ‘up’, ‘down’) “%d %f %f” % (3, 3, ‘three’)

Exercises? 8.12. Exercises?
1. What happens when you press the key while running mitt.py? List the two lines from the program that produce this behavior and explain how they work.

2.

What is the name of the counter variable in guess.py? With a proper strategy, the maximum number of guesses required to arrive at the correct number should be 11. What is this strategy?

3.

What happens when the mitt in mitt.py gets to the top or bottom of the graphics window? List the lines from the program that control this behavior and explain in detail how they work.

4.

Change the value of ball1_dx in collide.py to 2. How does the program behave differently? Now change ball1_dx back to 4 and set ball2_dx to -2. Explain in detail how these changes effect the behavior of the program.

5.

Comment out (put a # in front of the statement) the break statement in collide.py. Do you notice any change in the behavior of the program? Now also comment out the remove_from_screen(ball1) statement. What happens now? Experiment with commenting and uncommenting the two remove_from_screen statements and the break statement until you can describe specifically how these statements work together to produce the desired behavior in the program.

6.

Where can you add the lines

7. 8.

Text("Player Wins!", (340, 290), size=32) sleep(2)

to the version of catch.py in section 8.8 so that the program displays this message when the ball is caught?

9.

Trace the flow of execution in the final version of catch.py when you press the escape key during the execution of
play_round. What happens when you press this key? Why?

10.

List the main body of the final version of catch.py. Describe in detail what each line of code does. Which statement calls the function that starts the game?

11.

Identify the function responsible for displaying the ball and the mitt. What other operations are provided by this function?

12.

Which function keeps track of the score? Is this also the function that displays the score? Justify your answer by discussing specific parts of the code which implement these operations.

8.13. Project: pong.py?

Pong was one of the first commercial video games. With a capital P it is a registered trademark, but pong is used to refer any of the table tennis like paddle and ball video games.

catch.py already contains all the programming tools we need to develop our own version of pong. Incrementally changing

catch.py into pong.py is the goal of this project, which you will accomplish by completing the following series of exercises:

1.

Copy catch.py to pong1.py and change the ball into a paddle by using Box instead of the Circle. You can look at Appendix A for more information on Box. Make the adjustments needed to keep the paddle on the screen.

2.

Copy pong1.py to pong2.py. Replace the distance function with a boolean function hit(bx, by, r, px, py, h) that returns True when the vertical coordinate of the ball (by) is between the bottom and top of the paddle, and the horizontal location of the ball (bx) is less than or equal to the radius (r) away from the front of the paddle. Use hit to determine when the ball hits the paddle, and make the ball bounce back in the opposite horizontal direction when
hit returns True. Your completed function should pass these doctests:

3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.

def hit(bx, by, r, px, py, h): """ >>> hit(760, 100, 10, 780, 100, 100) False >>> hit(770, 100, 10, 780, 100, 100) True >>> hit(770, 200, 10, 780, 100, 100) True >>> hit(770, 210, 10, 780, 100, 100) False """

Finally, change the scoring logic to give the player a point when the ball goes off the screen on the left.

14.

Copy pong2.py to pong3.py. Add a new paddle on the left side of the screen which moves up when 'a' is pressed and down when 's' is pressed. Change the starting point for the ball to the center of the screen, (400, 300), and make it randomly move to the left or right at the start of each round.

Exercises? 9.22. Exercises?
1. Write a loop that traverses:

2.

['spam!', 1, ['Brie', 'Roquefort', 'Pol le Veq'], [1, 2, 3]]

and prints the length of each element. What happens if you send an integer to len? Change 1 to 'one' and run your solution again.

3.

Open a file named ch09e02.py and with the following content:

4. 5. 6. 7. 8. 9. 10. 11. 12. 13.

# """ """

Add your doctests here:

# Write your Python code here:

if __name__ == '__main__': import doctest doctest.testmod()

Add each of the following sets of doctests to the docstring at the top of the file and write Python code to make the doctests pass.

""" >>> a_list[3] 42 >>> a_list[6] 'Ni!' >>> len(a_list) 8 """ """

>>> b_list[1:] ['Stills', 'Nash'] >>> group = b_list + c_list >>> group[-1] 'Young' """ """ >>> 'war' in mystery_list False >>> 'peace' in mystery_list True >>> 'justice' in mystery_list True >>> 'oppression' in mystery_list False >>> 'equality' in mystery_list True """ """ >>> range(a, b, c) [5, 9, 13, 17] """

Only add one set of doctests at a time. The next set of doctests should not be added until the previous set pass.

14.

What is the Python interpreter’s response to the following?

15.

>>> range(10, 0, -2)

The three arguments to the range function are start, stop, and step, respectively. In this example, start is greater than stop. What happens if start < stop and step < 0? Write a rule for the relationships among start, stop, and step.

16.

Draw a state diagram for a and b before and after the third line of the following python code is executed:

17. 18. 19.

a = [1, 2, 3] b = a[:] b[0] = 5

20.

What will be the output of the following program?

21. 22. 23. 24. 25.

this = ['I', 'am', 'not', 'a', 'crook'] that = ['I', 'am', 'not', 'a', 'crook'] print "Test 1: %s" % (this is that) that = this print "Test 2: %s" % (this is that)

Provide a detailed explaination of the results.

26.

Open a file named ch09e06.py and use the same procedure as in exercise 2 to make the following doctests pass:

27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49.

""" >>> 13 in junk True >>> del junk[4] >>> junk [3, 7, 9, 10, 17, 21, 24, 27] >>> del junk[a:b] >>> junk [3, 7, 27] """ """ >>> nlist[2][1] 0 >>> nlist[0][2] 17 >>> nlist[1][1] 5 """ """ >>> import string >>> string.split(message, '??') ['this', 'and', 'that'] """

50.

Lists can be used to represent mathematical vectors. In this exercise and several that follow you will write functions to perform standard operations on vectors. Create a file named vectors.py and write Python code to make the doctests for each function pass.

Write a function add_vectors(u, v) that takes two lists of numbers of the same length, and returns a new list containing the sums of the corresponding elements of each.

def add_vectors(u, v): """ >>> add_vectors([1, 0], [1, 1]) [2, 1] >>> add_vectors([1, 2], [1, 4]) [2, 6] >>> add_vectors([1, 2, 1], [1, 4, 3]) [2, 6, 4] >>> add_vectors([11, 0, -4, 5], [2, -4, 17, 0]) [13, -4, 13, 5] """

add_vectors should pass the doctests above.

51.

Write a function scalar_mult(s, v) that takes a number, s , and a list, v and returns the scalar multiple of v by s.

52. 53. 54. 55. 56. 57. 58. 59. 60.

def scalar_mult(s, v): """ >>> scalar_mult(5, [1, 2]) [5, 10] >>> scalar_mult(3, [1, 0, -1]) [3, 0, -3] >>> scalar_mult(7, [3, 0, 5, 11, 2]) [21, 0, 35, 77, 14] """

61.

Write a function dot_product(u, v) that takes two lists of numbers of the same length, and returns the sum of the products of the corresponding elements of each (the dot_product).

62. 63.

def dot_product(u, v): """

64. 65. 66. 67. 68. 69. 70. 71. 72.

>>> dot_product([1, 1], [1, 1]) 2 >>> dot_product([1, 2], [1, 4]) 9 >>> dot_product([1, 2, 1], [1, 4, 3]) 12 >>> dot_product([2, 0, -1, 1], [1, 5, 2, 0]) 0 """

Verify that dot_product passes the doctests above.

73.

Extra challenge for the mathematically inclined: Write a function cross_product(u, v) that takes two lists of
numbers of length 3 and returns their cross product. You should write your own doctests and use the test driven development process described in the chapter.

74.

Create a new module named matrices.py and add the following two functions introduced in the section on test-driven development:

75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92.

def add_row(matrix): """ >>> m = [[0, 0], [0, 0]] >>> add_row(m) [[0, 0], [0, 0], [0, 0]] >>> n = [[3, 2, 5], [1, 4, 7]] >>> add_row(n) [[3, 2, 5], [1, 4, 7], [0, 0, 0]] >>> n [[3, 2, 5], [1, 4, 7]] """ def add_column(matrix): """ >>> m = [[0, 0], [0, 0]] >>> add_column(m) [[0, 0, 0], [0, 0, 0]] >>> n = [[3, 2], [5, 1], [4, 7]] >>> add_column(n)

93. 94. 95. 96.

[[3, 2, 0], [5, 1, 0], [4, 7, 0]] >>> n [[3, 2], [5, 1], [4, 7]] """

Your new functions should pass the doctests. Note that the last doctest in each function assures that add_row and
add_column are pure functions. ( hint: Python has a copy module with a function named deepcopy that could make

your task easier here. We will talk more about deepcopy in chapter 13, but google python copy module if you would like to try it now.)

97.

Write a function add_matrices(m1, m2) that adds m1 and m2 and returns a new matrix containing their sum. You can assume that m1 and m2 are the same size. You add two matrices by adding their corresponding values.

98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112.

def add_matrices(m1, m2): """ >>> a = [[1, 2], [3, 4]] >>> b = [[2, 2], [2, 2]] >>> add_matrices(a, b) [[3, 4], [5, 6]] >>> c = [[8, 2], [3, 4], [5, 7]] >>> d = [[3, 2], [9, 2], [10, 12]] >>> add_matrices(c, d) [[11, 4], [12, 6], [15, 19]] >>> c [[8, 2], [3, 4], [5, 7]] >>> d [[3, 2], [9, 2], [10, 12]] """

Add your new function to matrices.py and be sure it passes the doctests above. The last two doctests confirm that
add_matrices is a pure function.

113. Write a function scalar_mult(s, m) that multiplies a matrix, m, by a scalar, s.

114. def scalar_mult(n, m): 115. 116. """ >>> a = [[1, 2], [3, 4]]

117. 118. 119. 120. 121. 122. 123. 124.

>>> scalar_mult(3, a) [[3, 6], [9, 12]] >>> b = [[3, 5, 7], [1, 1, 1], [0, 2, 0], [2, 2, 3]] >>> scalar_mult(10, b) [[30, 50, 70], [10, 10, 10], [0, 20, 0], [20, 20, 30]] >>> b [[3, 5, 7], [1, 1, 1], [0, 2, 0], [2, 2, 3]] """

Add your new function to matrices.py and be sure it passes the doctests above.

125. Write functions row_times_column and matrix_mult:

126. def row_times_column(m1, row, m2, column): 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. """ >>> row_times_column([[1, 2], [3, 4]], 0, [[5, 6], [7, 8]], 0) 19 >>> row_times_column([[1, 2], [3, 4]], 0, [[5, 6], [7, 8]], 1) 22 >>> row_times_column([[1, 2], [3, 4]], 1, [[5, 6], [7, 8]], 0) 43 >>> row_times_column([[1, 2], [3, 4]], 1, [[5, 6], [7, 8]], 1) 50 """

137. def matrix_mult(m1, m2): 138. 139. 140. 141. 142. 143. 144. 145. """ >>> matrix_mult([[1, 2], [3, [[19, 22], [43, 50]] >>> matrix_mult([[1, 2, 3], [4, [[31, 19], [85, 55]] >>> matrix_mult([[7, 8], [9, 1], [2, 3]], [[1, 2, 3], [4, 5, 6]]) [[39, 54, 69], [13, 23, 33], [14, 19, 24]] """ 5, 6]], [[7, 8], [9, 1], [2, 3]]) 4]], [[5, 6], [7, 8]])

Add your new functions to matrices.py and be sure it passes the doctests above.

146. Create a new module named numberlists.py and add the following functions to the module:

147. def only_evens(numbers): 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. """ >>> only_evens([1, 3, 4, 6, 7, 8]) [4, 6, 8] >>> only_evens([2, 4, 6, 8, 10, 11, 0]) [2, 4, 6, 8, 10, 0] >>> only_evens([1, 3, 5, 7, 9, 11]) [] >>> only_evens([4, 0, -1, 2, 6, 7, -4]) [4, 0, 2, 6, -4] >>> nums = [1, 2, 3, 4] >>> only_evens(nums) [2, 4] >>> nums [1, 2, 3, 4] """

163. def only_odds(numbers): 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. """ >>> only_odds([1, 3, 4, 6, 7, 8]) [1, 3, 7] >>> only_odds([2, 4, 6, 8, 10, 11, 0]) [11] >>> only_odds([1, 3, 5, 7, 9, 11]) [1, 3, 5, 7, 9, 11] >>> only_odds([4, 0, -1, 2, 6, 7, -4]) [-1, 7] >>> nums = [1, 2, 3, 4] >>> only_odds(nums) [1, 3] >>> nums [1, 2, 3, 4] """

Be sure these new functions pass the doctests.

179. Add a function multiples_of(num, numlist) to numberlists.py that takes an integer (num), and a list of integers (numlist) as arguments and returns a list of those integers in numlist that are multiples of num. Add your own doctests and use TDD to develope this function.

180. Given:

181. import string 182. 183. song = "The rain in Spain..."

Describe the relationship between string.join(string.split(song)) and song. Are they the same for all strings? When would they be different?

184. Write a function replace(s, old, new) that replaces all occurences of old with new in a string s.

185. def replace(s, old, new): 186. 187. 188. 189. 190. 191. 192. 193. 194. """ >>> replace('Mississippi', 'i', 'I') 'MIssIssIppI' >>> s = 'I love spom! Spom is my favorite food. Spom, spom, spom, yum!'

>>> replace(s, 'om', 'am') 'I love spam! Spam is my favorite food. Spam, spam, spam, yum!'

>>> replace(s, 'o', 'a') 'I lave spam! """ Spam is my favarite faad. Spam, spam, spam, yum!'

Your solution should pass the doctests above. Hint: use string.split and string.join.

Exercises? 10.13. Exercises?
1. Complete the following:

o o o o

Start the pydoc server with the command pydoc -g at the command prompt.

Click on the open browser button in the pydoc tk window.

Find the calendar module and click on it.

While looking at the Functions section, try out the following in a Python shell:

o o o o

>>> import calendar >>> year = calendar.calendar(2008) >>> print year # What happens here?

Experiment with calendar.isleap. What does it expect as an argument? What does it return as a result? What kind of a function is this?

Make detailed notes about what you learned from this exercise.

2.

If you don’t have Tkinter installed on your computer, then pydoc -g will return an error, since the graphics window that it opens requires Tkinter. An alternative is to start the web server directly:

$ pydoc -p 7464

This starts the pydoc web server on port 7464. Now point your web browser at:

http://localhost:7464

and you will be able to browse the Python libraries installed on your system. Use this approach to start
pydoc and take a look at the math module.

a. b.

How many functions are there in the math module? What does math.ceil do? What about math.floor? ( hint: both floor and ceil expect floating point arguments.)

c.

Describe how we have been computing the same value as math.sqrt without using the math module.

d.

What are the two data constants in the math module?

Record detailed notes of your investigation in this exercise.

Use pydoc to investigate the copy module. What does deepcopy do? In which exercises from last chapter would deepcopy have come in handy?

Create a module named mymodule1.py. Add attributes myage set to your current age, and year set to the current year. Create another module named mymodule2.py. Add attributes myage set to 0, and year

set to the year you were born. Now create a file named namespace_test.py. Import both of the modules above and write the following statement:

print (mymodule2.myage - mymodule1.myage) == (mymodule2.year - mymodule1.year)

When you will run namespace_test.py you will see either True or False as output depending on whether or not you’ve already had your birthday this year.

Add the following statement to mymodule1.py, mymodule2.py, and namespace_test.py from the previous exercise:

print "My name is %s" % __name__

Run namespace_test.py. What happens? Why? Now add the following to the bottom of mymodule1.py:

if __name__ == '__main__': print "This won't run if I'm imported."

Run mymodule1.py and namespace_test.py again. In which case do you see the new print statement?

In a Python shell try the following:

>>> import this

What does Tim Peters have to say about namespaces?

Use pydoc to find and test three other functions from the string module. Record your findings.

Rewrite matrix_mult from the last chapter using what you have learned about list methods.

The dir function, which we first saw in Chapter 7, prints out a list of the attributes of an object passed to it as an argument. In other words, dir returns the contents of the namespace of its argument. Use
dir(str) and dir(list) to find at least three string and list methods which have not been introduced in

the examples in the chapter. You should ignore anything that begins with double underscore (__) for the time being. Be sure to make detailed notes of your findings, including names of the new methods and examples of their use. ( hint: Print the docstring of a function you want to explore. For example, to find out how str.join works, print str.join.__doc__)

Give the Python interpreter’s response to each of the following from a continuous interpreter session:

>>> s = "If we took the bones out, it wouldn't be crunchy, would it?" >>> s.split() >>> type(s.split()) >>> s.split('o') >>> s.split('i') >>> '0'.join(s.split('o'))

Be sure you understand why you get each result. Then apply what you have learned to fill in the body of the function below using the split and join methods of str objects:

def myreplace(old, new, s): """ Replace all occurences of old with new in the string s.

>>> myreplace(',', ';', 'this, that, and, some, other, thing') 'this; that; and; some; other; thing' >>> myreplace(' ', '**', 'Words will now be separated by stars.') 'Words**will**now**be**separated**by**stars.' """

Your solution should pass all doctests.

Create a module named wordtools.py with the following at the bottom:

if __name__ == '__main__': import doctest doctest.testmod()

Explain how this statement makes both using and testing this module convenient. What will be the value of __name__ when wordtools.py is imported from another module? What will it be when it is run as a main program? In which case will the doctests run? Now add bodies to each of the following functions to make the doctests pass:

def cleanword(word): """

>>> cleanword('what?') 'what' >>> cleanword('"now!"') 'now' >>> cleanword('?+="word!,@$()"') 'word' """ def has_dashdash(s): """ >>> has_dashdash('distance--but') True >>> has_dashdash('several') False >>> has_dashdash('critters') False >>> has_dashdash('spoke--fancy') True >>> has_dashdash('yo-yo') False """ def extract_words(s): """ >>> extract_words('Now is the time! "Now", is the time? Yes, now.')

['now', 'is', 'the', 'time', 'now', 'is', 'the', 'time', 'yes', 'now'] >>> extract_words('she tried to curtsey as she spoke--fancy') ['she', 'tried', 'to', 'curtsey', 'as', 'she', 'spoke', 'fancy'] """ def wordcount(word, wordlist): """ >>> wordcount('now', ['now', 'is', 'time', 'is', 'now', 'is', 'is']) ['now', 2] >>> wordcount('is', ['now', 'is', 'time', 'is', 'now', 'is', 'the', 'is']) ['is', 4] >>> wordcount('time', ['now', 'is', 'time', 'is', 'now', 'is', 'is']) ['time', 1] >>> wordcount('frog', ['now', 'is', 'time', 'is', 'now', 'is', 'is']) ['frog', 0]

""" def wordset(wordlist): """ >>> wordset(['now', 'is', 'time', 'is', 'now', 'is', 'is']) ['is', 'now', 'time'] >>> wordset(['I', 'a', 'a', 'is', 'a', 'is', 'I', 'am']) ['I', 'a', 'am', 'is'] >>> wordset(['or', 'a', 'am', 'is', 'are', 'be', 'but', 'am']) ['a', 'am', 'are', 'be', 'but', 'is', 'or'] """ def longestword(wordset): """ >>> longestword(['a', 'apple', 'pear', 'grape']) 5 >>> longestword(['a', 'am', 'I', 'be']) 2 >>> longestword(['this', 'that', 'supercalifragilisticexpialidocious']) 34 """

Save this module so you can use the tools it contains in your programs.

unsorted_fruits.txt contains a list of 26 fruits, each one with a name that begins with a different letter of the alphabet. Write a program named sort_fruits.py that reads in the fruits from
unsorted_fruits.txt and writes them out in alphabetical order to a file named sorted_fruits.txt.

Answer the following questions about countletters.py:

o

Explain in detail what the three lines do:

o o o

infile = open('alice_in_wonderland.txt', 'r') text = infile.read() infile.close()

What would type(text) return after these lines have been executed?

o

What does the expression 128 * [0] evaluate to? Read about ASCII in Wikipedia and explain why you think the variable, counts is assigned to 128 * [0] in light of what you read.

o

What does

o o

for letter in text: counts[ord(letter)] += 1

do to counts?

o

Explain the purpose of the display function. Why does it check for values 10, 13, and 32? What is special about those values?

o

Describe in detail what the lines

o o o

outfile = open('alice_counts.dat', 'w') outfile.write("%-12s%s\n" % ("Character", "Count")) outfile.write("=================\n")

do. What will be in alice_counts.dat when they finish executing?

o

Finally, explain in detail what

o o o

for i in range(len(counts)): if counts[i]: outfile.write("%-12s%d\n" % (display(i), counts[i]))

does. What is the purpose of if counts[i]?

Write a program named mean.py that takes a sequence of numbers on the command line and returns the mean of their values.

$ python mean.py 3 4 3.5 $ python mean.py 3 4 5 4.0 $ python mean.py 11 15 94.5 22 35.625

A session of your program running on the same input should produce the same output as the sample session above.

Write a program named median.py that takes a sequence of numbers on the command line and returns the median of their values.

$ python median.py 3 7 11 7 $ python median.py 19 85 121 85 $ python median.py 11 15 16 22 15.5

A session of your program running on the same input should produce the same output as the sample session above.

Modify the countletters.py program so that it takes the file to open as a command line argument. How will you handle the naming of the output file?

Exercises? 11.13. Exercises?
1. 2. 3. 4. 5. 6. 7. 8. 9. a, b = 0, 1 print "before swap function call: id(a):", id(a), "id(b):", id(b) def swap(x, y): print # incorrect version

"before swap statement: id(x):", id(x), "id(y):", id(y)

x, y = y, x print "after swap statement: id(x):", id(x), "id(y):", id(y)

swap(a, b) print "after swap function call: id(a):", id(a), "id(b):", id(b)

10.

Run this program and describe the results. Use the results to explain why this version of swap does not work as intended. What will be the values of a and b after the call to swap?

11.

Create a module named seqtools.py. Add the functions encapsulate and insert_in_middle from the chapter. Add doctests which test that these two functions work as intended with all three sequence types.

12.

Add each of the following functions to seqtools.py:

13.

def make_empty(seq):

14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50.

""" >>> make_empty([1, 2, 3, 4]) [] >>> make_empty(('a', 'b', 'c')) () >>> make_empty("No, not me!") '' """

def insert_at_end(val, seq): """ >>> insert_at_end(5, [1, 3, 4, 6]) [1, 3, 4, 6, 5] >>> insert_at_end('x', 'abc') 'abcx' >>> insert_at_end(5, (1, 3, 4, 6)) (1, 3, 4, 6, 5) """

def insert_in_front(val, seq): """ >>> insert_in_front(5, [1, 3, 4, 6]) [5, 1, 3, 4, 6] >>> insert_in_front(5, (1, 3, 4, 6)) (5, 1, 3, 4, 6) >>> insert_in_front('x', 'abc') 'xabc' """

def index_of(val, seq, start=0): """ >>> index_of(9, [1, 7, 11, 9, 10]) 3 >>> index_of(5, (1, 2, 4, 5, 6, 10, 5, 5)) 3 >>> index_of(5, (1, 2, 4, 5, 6, 10, 5, 5), 4) 6

51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87.

>>> index_of('y', 'happy birthday') 4 >>> index_of('banana', ['apple', 'banana', 'cherry', 'date']) 1 >>> index_of(5, [2, 3, 4]) -1 >>> index_of('b', ['apple', 'banana', 'cherry', 'date']) -1 """

def remove_at(index, seq): """ >>> remove_at(3, [1, 7, 11, 9, 10]) [1, 7, 11, 10] >>> remove_at(5, (1, 4, 6, 7, 0, 9, 3, 5)) (1, 4, 6, 7, 0, 3, 5) >>> remove_at(2, "Yomrktown") 'Yorktown' """

def remove_val(val, seq): """ >>> remove_val(11, [1, 7, 11, 9, 10]) [1, 7, 9, 10] >>> remove_val(15, (1, 15, 11, 4, 9)) (1, 11, 4, 9) >>> remove_val('what', ('who', 'what', 'when', 'where', 'why', 'how')) ('who', 'when', 'where', 'why', 'how') """

def remove_all(val, seq): """ >>> remove_all(11, [1, 7, 11, 9, 11, 10, 2, 11]) [1, 7, 9, 10, 2] >>> remove_all('i', 'Mississippi') 'Msssspp' """

88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. def sort_sequence(seq): 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. if __name__ == "__main__": 120. 121. import doctest doctest.testmod() """ >>> sort_sequence([3, 4, 6, 7, 8, 2]) [2, 3, 4, 6, 7, 8] >>> sort_sequence((3, 4, 6, 7, 8, 2)) (2, 3, 4, 6, 7, 8) >>> sort_sequence("nothappy") 'ahnoppty' """ def reverse(seq): """ >>> reverse([1, 2, 3, 4, 5]) [5, 4, 3, 2, 1] >>> reverse(('shoe', 'my', 'buckle', 2, 1)) (1, 2, 'buckle', 'my', 'shoe') >>> reverse('Python') 'nohtyP' """ def count(val, seq): """ >>> count(5, (1, 5, 3, 7, 5, 8, 5)) 3 >>> count('s', 'Mississippi') 4 >>> count((1, 2), [1, 5, (1, 2), 7, (1, 2), 8, 5]) 2 """

As usual, work on each of these one at a time until they pass all of the doctests.

122. Write a function, recursive_min, that returns the smallest value in a nested number list:

123. def recursive_min(nested_num_list): 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. """ >>> recursive_min([2, 9, [1, 13], 8, 6]) 1 >>> recursive_min([2, [[100, 1], 90], [10, 13], 8, 6]) 1 >>> recursive_min([2, [[13, -7], 90], [1, 100], 8, 6]) -7 >>> recursive_min([[[-13, 7], 90], 2, [1, 100], 8, 6]) -13 """

Your function should pass the doctests.

134. Write a function recursive_count that returns the number of occurances of target in
nested_number_list:

135. def recursive_count(target, nested_num_list): 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. """ >>> recursive_count(2, [2, 9, [2, 1, 13, 2], 8, [2, 6]]) 4 >>> recursive_count(7, [[9, [7, 1, 13, 2], 8], [7, 6]]) 2 >>> recursive_count(15, [[9, [7, 1, 13, 2], 8], [2, 6]]) 0 >>> recursive_count(5, [[5, [5, [1, 5], 5], 5], [5, 6]]) 6 """

As usual, your function should pass the doctests.

146. Write a function flatten that returns a simple list of numbers containing all the values in a
nested_number_list:

147. def flatten(nested_num_list): 148. """

149. 150. 151. 152. 153. 154. 155. 156. 157.

>>> flatten([2, 9, [2, 1, 13, 2], 8, [2, 6]]) [2, 9, 2, 1, 13, 2, 8, 2, 6] >>> flatten([[9, [7, 1, 13, 2], 8], [7, 6]]) [9, 7, 1, 13, 2, 8, 7, 6] >>> flatten([[9, [7, 1, 13, 2], 8], [2, 6]]) [9, 7, 1, 13, 2, 8, 2, 6] >>> flatten([[5, [5, [1, 5], 5], 5], [5, 6]]) [5, 5, 1, 5, 5, 5, 5, 6] """

Run your function to confirm that the doctests pass.

158. Write a function named readposint that prompts the user for a positive integer and then checks the input to confirm that it meets the requirements. A sample session might look like this:

159. >>> num = readposint() 160. Please enter a positive integer: yes 161. yes is not a positive integer. Try again.

162. Please enter a positive integer: 3.14 163. 3.14 is not a positive integer. Try again.

164. Please enter a positive integer: -6 165. -6 is not a positive integer. Try again.

166. Please enter a positive integer: 42 167. >>> num 168. 42 169. >>> num2 = readposint("Now enter another one: ") 170. Now enter another one: 31 171. >>> num2 172. 31 173. >>>

Use Python’s exception handling mechanisms in confirming that the user’s input is valid.

174. Give the Python interpreter’s response to each of the following:

1. 2.

>>> nums = [1, 2, 3, 4] >>> [x**3 for x in nums]

3.

4. 5.

>>> nums = [1, 2, 3, 4] >>> [x**2 for x in nums if x**2 != 4]

6.

7. 8.

>>> nums = [1, 2, 3, 4] >>> [(x, y) for x in nums for y in nums]

9.

10. 11.

>>> nums = [1, 2, 3, 4] >>> [(x, y) for x in nums for y in nums if x != y]

12.

You should anticipate the results before you try them in the interpreter.

175. Use either pydoc or the on-line documentation at http://pydoc.org to find out what
sys.getrecursionlimit() and sys.setrecursionlimit(n) do. Create several experiments like what was

done in infinite_recursion.py to test your understanding of how these module functions work.

176. Rewrite the factorial function using iteration instead of recursion. Call your new function with 1000 as an argument and make note of how fast it returns a value.

177. Write a program named litter.py that creates an empty file named trash.txt in each subdirectory of a directory tree given the root of the tree as an argument (or the current directory as a default). Now write a program named cleanup.py that removes all these files. Hint: Use the tree program from the mini case study as a basis for these two recursive programs.

Exercises? 12.10. Exercises?
1. Write a program that reads in a string on the command line and returns a table of the letters of the alphabet in alphabetical order which occur in the string together with the number of times each letter occurs. Case should be ignored. A sample run of the program would look this this:

2. 3. 4.

$ python letter_counts.py "ThiS is String with Upper and lower case Letters." a c 2 1

5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.

d e g h i l n o p r s t u w

1 5 1 2 4 2 2 1 2 4 5 5 1 2

$

19.

Give the Python interpreter’s response to each of the following from a continuous interpreter session:

1. 2.

>>> d = {'apples': 15, 'bananas': 35, 'grapes': 12} >>> d['banana']

3.

4. 5.

>>> d['oranges'] = 20 >>> len(d)

6.

7.

>>> d.has_key('grapes')

8.

9.

>>> d['pears']

10.

11.

>>> d.get('pears', 0)

12.

13. 14.

>>> fruits = d.keys() >>> fruits.sort()

15.

>>> print fruits

16.

17. 18.

>>> del d['apples'] >>> d.has_key('apples')

19.

Be sure you understand why you get each result. Then apply what you have learned to fill in the body of the function below:

def add_fruit(inventory, fruit, quantity=0): """ Adds quantity of fruit to inventory.

>>> new_inventory = {} >>> add_fruit(new_inventory, 'strawberries', 10) >>> new_inventory.has_key('strawberries') True >>> new_inventory['strawberries'] 10 >>> add_fruit(new_inventory, 'strawberries', 25) >>> new_inventory['strawberries'] """

Your solution should pass the doctests.

20.

Write a program called alice_words.py that creates a text file named alice_words.txt containing an alphabetical listing of all the words found in alice_in_wonderland.txt together with the number of times each word occurs. The first 10 lines of your output file should look something like this:

21. 22. 23. 24. 25. 26.

Word

Count

======================= a a-piece abide able 631 1 1 1

27. 28. 29.

about above absence

94 3 1

absurd

2

How many times does the word, alice, occur in the book?

30.

What is the longest word in Alice in Wonderland ? How many charactes does it have?

31.

Copy the code from the Setting up the world, the player, and the main loop section into a file named
robots.py and run it. You should be able to move the player around the screen using the numeric

keypad and to quit the program by pressing the escape key.

32.

Laptops usually have smaller keyboards than desktop computers that do not include a seperate numeric keypad. Modify the robots program so that it uses ‘a’, ‘q’, ‘w’, ‘e’, ‘d’, ‘c’, ‘x’, and ‘z’ instead of ‘4’, ‘7’, ‘8’, ‘9’, ‘6’, ‘3’, ‘2’, and ‘1’ so that it will work on a typical laptop keyboard.

33.

Add all the code from the Adding a robot section in the places indicated. Make sure the program works and that you now have a robot following around your player.

34.

Add all the code from the Checking for Collisions section in the places indicated. Verify that the program ends when the robot catches the player after displaying a They got you! message for 3 seconds.

35.

Modify the move_player function to add the ability for the player to jump to a random location whenever the 0 key is pressed. (hint: place_player already has the logic needed to place the player in a random location. Just add another conditional branch to move_player that uses this logic when key_pressed('0') is true.) Test the program to verify that your player can now teleport to a random place on the screen to get out of trouble.

36.

Make all the changes to your program indicated in Adding more robots. Be sure to loop over the robots list, removing each robot in turn, after defeated becomes true. Test your program to verify that there are now two robots chasing your player. Let a robot catch you to test whether you have correctly handled removing all the robots. Change the argument from 2 to 4 in robots = place_robots(2) and confirm that you have 4 robots.

37.

Make the changes to your program indicated in Adding ``junk``. Fix place_robots by moving the random generation of values for x and y to the appropriate location and passing these values as arguments in the call to place_robot. Now we are ready to make temporary modifications to our program to remove the randomness so we can control it for testing. We can start by placing a pile of junk in the center of our game board. Change:

38.

junk = []

to:

junk = [place_robot(GRID_WIDTH/2, GRID_HEIGHT/2, junk=True)]

Run the program and confirm that there is a black box in the center of the board.Now change
place_player so that it looks like this:

def place_player(): # x = random.randint(0, GRID_WIDTH) # y = random.randint(0, GRID_HEIGHT) x, y = GRID_WIDTH/2 + 3, GRID_HEIGHT/2 return {'shape': Circle((10*x+5, 10*y+5), 5, filled=True), 'x': x, 'y': y}

Finally, temporarily comment out the random generation of x and y values in place_robots and the creation of numbots robots. Replace this logic with code to create two robots in fixed locations:

def place_robots(numbots): robots = [] # for i in range(numbots): # # # x = random.randint(0, GRID_WIDTH) y = random.randint(0, GRID_HEIGHT) robots.append(place_robot(x, y))

robots.append(place_robot(GRID_WIDTH/2 - 4, GRID_HEIGHT/2 + 2)) robots.append(place_robot(GRID_WIDTH/2 - 4, GRID_HEIGHT/2 - 2)) return robots

When you start your program now, it should look like this:

When you run this program and either stay still (by pressing the 5 repeatedly) or move away from the pile of junk, you can confirm that the robots move through it unharmed. When you move into the junk pile, on the other hand, you die.

39.

Make the following mo modifications to play_game to integrate with the changes made in Turning robots

into junk and enabling the player to win:

1.

Rename defeated to winner and initialize it to the empty string instead of False.

Exercises? 13.7. Exercises?

1.

Create and print a Point object, and then use id to print the object’s unique identifier. Translate the hexadecimal form into decimal and confirm that they match.

2.

Rewrite the distance function from chapter 5 so that it takes two Points as parameters instead of four numbers.


相关文档

Python 习题
可爱的python习题答案
Python题库
PYTHON习题选编
python编程练习题1
python练习题
Python 核心编程 第十三章习题答案
Python核心第二版习题答案
Python例题
python习题整理
电脑版