Title | Think Python Answers - Wikibooks, open books for an open world |
---|---|
Course | Programming Fundamentals |
Institution | University of the People |
Pages | 53 |
File Size | 1.5 MB |
File Type | |
Total Downloads | 101 |
Total Views | 163 |
From Google , Think Python Answers - Wikibooks, open books for an open world...
Think Python/Answers < Think Python
Chapter 1 See below for Chapter 1 exercises.
Exercise 1.2 3.) If you run a 10 kilometer race in 42 minutes 42 seconds, what is your average time per mile? What is your average speed in miles per hour? (Hint: there are about 1.61 kilometers in a mile.) >>> 10 / 1.61 # convert kilometers to miles 6.211180124223602 >>> (42 * 60) + 42 # convert time to seconds 2562 >>> 2562 / 6.211180124223602 # what is your average time (seconds) per mile 412.482 >>> 412.482 / 60 # what is your average time (minutes) per mile
6.874700000000001 >>> 60 / 6.874700000000001 # miles per hour 8.727653570337614 How about another way >>> 10 / 42.7 # avg kilometers per minute 0.23419203747072598 >>> 0.23419203747072598 * 60 # kilometers per hour 14.05152224824356 >>> 14.05152224824356 / 1.61 # convert to M.P.H 8.727653570337614 or a one-liner >>> (10 / 1.61) / (42.7 / 60) # (distance in miles) / (time in hours) 8.727653570337614 # miles/hour
Chapter 2 Exercise 2.1 If you type an integer with a leading zero, you might get a confusing error:
>>> zipcode = 02492 ^ : invalid token Other number seem to work, but the results are bizarre:
>>> zipcode = 02132 >>> print zipcode
1114 So python is assuming you want to convert an octal number to a decimal number. In the base 8 numbering system where valid numbers are 0, 1, 2, 3, 4, 5, 6 and 7.
Base
8: 00 01 02 03 04 05 06 07 10 11 12 13 14 15 16 17 20 21 22
23 24 Base 10: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 Every 8 numbers we increment the left hand columns. This means that the right most column is the number of 'ones'. The one to the left of that is a tally of the number of 'eights', the one next to that is a tally of a full column of 'eight' times the 'eight column' - 64. The one next to that is 64*8 512 and so on. For more information read Base Eight math (http://www.felderbooks.com/paper s/bases.html) . That is why zipcode = 02492 is invalid as the digit 9 is not a valid octal number. We can do the conversion manually as follows:
>>> print 02132 1114 >>> (2*512)+(1*64)+(3*8)+(2*1) 1114 >>>
Exercise 2.2 The volume of a sphere with radius r is 4/3 π r3. What is the volume of a sphere with radius 5?
>>> pi = 3.1415926535897932 >>> r = 5 >>> 4/3*pi*r**3 # This is the wrong answer 392.69908169872411 >>> r = 5.0 # Radius can be a float here as well, but is not
_necessary_. >>> 4.0/3.0*pi*r**3 # Using floats give the correct answer
523.5987755982989 >>> Suppose the cover price of a book is $24.95, but bookstores get a 40% discount. Shipping costs $3 for the first copy and 75 cents for each additional copy. What is the total wholesale cost for 60 copies?
$24.95 $9.98 $14.97 60 $898.20
Cost Discount per book Cost per book after discount Total number of books Total cost
inc delivery
$3.00
First book delivery
59
Remaining books
$0.75
Delivery cost
extra books
$44.25
Total cost
$47.25
Total Delivery cost
$945.45
extra books
Total Bill
This answer
wrong because 40.0/100.0
0.40000000000000002
wrong value
more info see IEEE 754 (Standard
Floating-Point Arithmetic) >>> (24.95-24.95*40.0/100.0)*60+3+0.75*(60-1) 945.44999999999993 >>> 24.95*0.6*60+0.75*(60-1)+3 945.45 You can use the decimal module to maintain precision. Decimal .. ... wholesale_cost(args): d = 1 - args.get('discount')/100
purchase = Decimal(args.get('cost') * d * 60) purchase + Decimal(args.get('delivery')) args =
{'cost': 24.95, 'discount': 40, 'delivery': 3.00+0.75*59}
Another solution using functions as well as input prompts:
# Total wholesale book cost calculator cover_price = 24.95 number_of_books = int(input("How many books do you want to order at wholesale? ")) ship_cost (number_of_books): number_of_books == 1: (number_of_books * 3) # Cost of shipping one book is
$3 : (3 + (number_of_books - 1) * 0.75) # Each additional
copy of the book is $0.75 to ship discounted_price(number_of_books): (cover_price - (cover_price * .4)) # There is a 40%
discount on wholesale book sales wholesale_cost(number_of_books): ((discounted_price(number_of_books) * number_of_books) + ship_cost(number_of_books)) print("The cost of buying and shipping", number_of_books, "books is $",round(wholesale_cost(number_of_books), 2)) If I leave my house at 6:52 am and run 1 mile at an easy pace (8:15 per mile), then 3 miles at tempo (7:12 per mile) and 1 mile at easy pace again, what time do I get home for breakfast? Answer: 7:30 am
How I did it:
>>> start = (6*60+52)*60 >>> easy = (8*60+15)*2 >>> fast = (7*60+12)*3 >>> finish_hour = (start + easy + fast)/(60*60.0) >>> finish_floored = (start + easy + fast)//(60*60)
#int()
function can also be used to get integer value, but isn't taught yet. >>> finish_minute
= (finish_hour - finish_floored)*60
>>> print ('Finish time was
:
' % (finish_hour,finish_minute))
Finish time was 7:30 *** ANOTHER WAY *** start_time_hr = 6 + 52 / 60.0 easy_pace_hr = (8 + 15 / 60.0 ) / 60.0 tempo_pace_hr = (7 + 12 / 60.0) / 60.0 running_time_hr = 2 * easy_pace_hr + 3 * tempo_pace_hr breakfast_hr = start_time_hr + running_time_hr breakfast_min = (breakfast_hr-int(breakfast_hr))*60 breakfast_sec= (breakfast_min-int(breakfast_min))*60 print ('breakfast_hr', int(breakfast_hr) ) print ('breakfast_min', int (breakfast_min) ) print ('breakfast_sec', int (breakfast_sec) ) >>>
Chapter 3 Exercise 3.1 Python provides a built-in function called len that returns the length of a string, so the value of len('allen') is 5. Write a function named right_justify that takes a string named 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.
>>>
right_justify(s): print (' '*(70-len(s))+s)
>>> right_justify('allen') allen >>>
Alternate Solution Using concatenation and repetition
right_justify(s): total_length = 70 current_length = len(s) current_string = s current_length < total_length: current_string = " " + current_string current_length = len(current_string) print(current_string) OUTPUT >>> right_justify("monty") monty
Exercise 3.3 You can see my solution at http://thinkpython.com/code/grid.py .
""" Solution to Exercise 3.5 on page 27 of Think Python Allen B. Downey, Version 1.1.24+Kart [Python 3.2]
""" # here is a mostly-straightforward solution to the # two-by-two version of the grid. do_twice(f): f() f() do_four(f): do_twice(f) do_twice(f) print_beam(): print('+ - - - -', end='') print_post(): print('|
', end='')
print_beams(): do_twice(print_beam) print('+') print_posts(): do_twice(print_post) print('|') print_row(): print_beams() do_twice(print_posts) print_grid(): do_twice(print_row) print_beams() print_grid()
____________
# another solution do_twice(f): f() f() do_four(f): do_twice(f) do_twice(f) print_column(): print '+----+----+' print_row(): print '|
|
|'
print_rows(): do_four(print_row) do_block(): print_column() print_rows() print_block(): do_twice(do_block) print_column() print_block()
# nathan moses-gonzales _________
# straight-forward solution to 4x4 grid
do_twice(f): f() f() do_four(f): # not needed for 2x2 grid do_twice(f) do_twice(f) print_beam(): print('+----', end='') print_post(): print('|
', end='')
print_beams(): do_twice(print_beam) print('+') print_posts(): do_twice(print_post) print('|') print_row(): print_beams() do_twice(print_posts) print_grid2x2(): do_twice(print_row) print_beams() print_beam4(): do_four(print_beam) print('+') print_post4(): do_four(print_post)
print('|') print_row4(): print_beam4() do_twice(print_post4) print_grid4x4(): do_four(print_row4) print_beam4() print_grid4x4() -----------------------
# here is a less-straightforward solution to the # four-by-four grid one_four_one(f, g, h): f() do_four(g) h() print_plus(): print '+', print_dash(): print '-', print_bar(): print '|', print_space(): print ' ', print_end(): print
nothing(): "do nothing" print1beam(): one_four_one(nothing, print_dash, print_plus) print1post(): one_four_one(nothing, print_space, print_bar) print4beams(): one_four_one(print_plus, print1beam, print_end) print4posts(): one_four_one(print_bar, print1post, print_end) print_row(): one_four_one(nothing, print4posts, print4beams) print_grid(): one_four_one(print4beams, print_row, nothing) print_grid() comment = """ After writing a draft of the 4x4 grid, I noticed that many of the functions had the same structure: they would do something, do something else four times, and then do something else once. So I wrote one_four_one, which takes three functions as arguments; it calls the first one once, then uses do_four to call the second one four times, then calls the third. Then I rewrote print1beam, print1post, print4beams, print4posts, print_row and print_grid using one_four_one.
Programming is an exploratory process.
Writing a draft of a
program often gives you insight into the problem, which might lead you to rewrite the code to reflect the structure of the solution. --- Allen """ print comment
# another solution beam(): plus = "+" minus = "-"*4 print(plus, minus, plus,minus, plus, minus, plus, minus, plus) straight(): straight = "|" space = " "*4 print(straight, space, straight, space, straight, space, straight, space, straight, space) quad_straight(): straight() straight() straight() straight() twice(): beam() quad_straight() beam() quad_straight() quad():
twice() twice() beam() quad() -- :) ------------------
# Without functions. print("+ - - - - " * 2 + "+") print("|
|
|
" * 3 + "|
|
|")
|
|")
print("+ - - - - " * 2 + "+") print("|
|
|
" *3 + "|
print("+ - - - - " * 2 + "+") -----------------Why
using the first solution do_twice(f): f() f() do_four(f): do_twice(f) do_twice(f) print_column(): print '+----+----+----+----+' print_row(): print '|
|
|
print_rows(): do_four(print_row)
|
|'
adapt it to the number of rows
do_block(): print_column() print_rows() print_block(): do_twice(do_block)
# print_column() do_twice(do_block) print_column() print_block()
-----------------------
# mteodor draw_line(bar, middle = ' ', repeat = 2, lenght = 2):
""" Draw a single line like this: [ (B M*repeat)*lenght B] """ k
range(lenght):
print("
" % (bar, middle*repeat), end='')
print(bar) draw_grid(lenght = 2, height = 2, width = 2):
""" Draw a grid like this: + -- + -- + |
|
|
|
|
|
+ -- + -- + |
|
|
|
|
|
+ -- + -- + where: * lenght x heigth are the table size * width is the size of a cell/column
""" i
range(height):
draw_line('+', '-', width, lenght) j
range(lenght):
draw_line('|', ' ', width, lenght) draw_line('+', '-', width, lenght) draw_grid(4, 4, 3)
--------------------------
#kipp # auto adjust size of columns size=4 beam(): print(" + - - - -"*size, "+") post(): print(" |
"*size, "|")
repeat(func): func() func() func()
# manual adjust size for rows # this is 4 beam() repeat(post) beam() repeat(post) beam()
repeat(post) beam() repeat(post) beam()
Chapter 4 4.3 Exercise 1 * world = TurtleWorld() bob = Turtle() square(t): i
range(4):
fd(t, 100) lt(t) square(bob) wait_for_user()
4.3 Exercise 2 * world = TurtleWorld() bob = Turtle() print(bob) square(t, length): t = Turtle() i
range(4):
fd(t, length) lt(t)
square(bob, 200) wait_for_user()
4.3 Exercise 3 * world = TurtleWorld() bob = Turtle() print(bob) polygon(t, length, n): i
range(n):
fd(t, length) lt(t, 360 / n) polygon(bob, 50, 8) wait_for_user()
Chapter 5 Exercise 5.2 countdown(a):
# A typical countdown function
a < 0: print("Blastoff") a > 0: print(a) countdown(a - 1) call_function(n,a):
# The countdown function is called "n"
number of times. Any other function can be used instead of countdown function. i
range(n):
countdown(a)
call_function(3, 10)
Exercise 5.3 Def is_triangle(a, b, c): a >
cumulative(l): cumulative_sum = 0 new_list = [] i
l:
cumulative_sum += i new_list.append(cumulative_sum) new_list
Exercise 10.4 Write a function called middle that takes a list and returns a new list that contains all but the first and last elements.
>>>
middle(x): res = [] i = 1 i >>
middle(x): x[1:-1]
Exercise 10.5 Write a function called chop that takes a list and modifies it, removing the first and last elements, and returns None.
>>>
chop(x): x[:1] x[-1:]
Chapter 11 Exercise 11.1 Write a function that reads the words in words.txt and stores them as keys in a dictionary. It doesn’t matter what the values are. Then you can use the in operator as a fast way to check whether a string is in the dictionary.
fin = open('words.txt') englishdict = dict()
create_diction(): counter = 0 dictionairy = dict() line
fin:
word = line.strip() dictionairy[word] = counter counter += 1 dictionairy
Exercise 11.2 invert_dict(s): i={} key
s:
v=s[key] i.setdefault(v, []).append(key) i Edit: This was not the exercise I found in my edition of 'Think Python', so I've added my answer in case anyone else is curious: Use get to write histogram more concisely. You should be able to eliminate the if statement.
histogram(s): d = dict()
c
s:
d[c] = d.get(c,0)+1 d
Exercise 11.3 Dictionaries have a method called keys that returns the keys of the dictionary, in no particular order, as a list. Modify print_hist to print the keys and their values in alphabetical order.
v = {'p' : 1, 'a' : 1, 'r' : 2, 'o' : 1, 't' : 1} print_hist(h): d = [] d += sorted(h.keys()) c
d:
print(c, h[c]) OR
v = {'p' : 1, 'a' : 1, 'r' : 2, 'o' : 1, 't' : 1} print_hist(h): c
sorted(h.keys()):
print c, h[c]
Exercise 11.4 Modify reverse_lookup so that it builds and returns a list of all keys that map to v, or an empty list if there are none.
reverse_lookup(d,v): l = list() c
d: d[c] == v: l.append(c) l
Chapter 12
Exercise 12.1 numbers = (1,2,3) sumall(numbers): x = 0 i
numbers:
x = x + i print x sumall(numbers) or
sumall(*t): x = 0 i
range(len(t)):
x += t[i] x or
sumall(*args): t = list(args) sum(t) or
sumall(*args): sum(args)
Exercise 12.2
sort_by_length(words): t = []
word
words:
t.append((len(word),word)) t.sort(reverse=
)
res = [] length, word
t:
res.append(word) i=0 final = [] i 1: shuffle(d[key])
r.extend(d[key]) r
):
Exercise 12.3
most_frequent(s): d = dict() inv = dict() char
s:
char
string.ascii_letters:
letter = char.lower() d[letter] = d.get(letter, 0) + 1 letter, freq
d.items():
inv.setdefault(freq, []).append(letter) freq print('
sorted(inv, reverse=
):
:'.format(freq/(sum(list(inv)*len(inv[freq])))), ',
'.join(inv[freq]))
Chapter 13 Exercise 13.7 punctuation, whitespace, digits randint bisect_left process_file(filename): h = dict() fp = open(filename) line
fp:
process_line(line, h) h process_line(line, h):
line = line.replace('-', ' ') word
line.split():
word = word.strip(punctuation + whitespace + digits) word = word.lower() word != '': h[word] = h.get(word, 0) + 1 hist = process_file('emma.txt') cum_sum(list_of_numbers): cum_list = [] i, elem
enumerate(list_of_numbers):
i == 0: cum_list.append(elem) : cum_list.append(cum_list[i-1] + elem) cum_list random_word(h): word_list = list(h.keys()) num_list = [] word
word_list:
num_list.append(h[word]) cum_list = cum_sum(num_list) i = randint(1, cum_list[-1]) pos = bisect_left(cum_list, i) word_list[pos] print(random_word(hist))
Chapter 14 Exercise 14.3
dict_of_signatures_and_words(filename='words.txt'): d = dict() line
open(filename):
word = line.lower().strip() signature = ''.join(sorted(word)) d.setdefault(signature, []).append(word) d db_of_anagrams(filename='anagrams', d=dict_of_signatures_and_words()): db = shelve.open(filename) key, values
d.items():
len(values)>1: index, value
enumerate(values):
db[value]=values[:index]+values[index+1:] db.close() print_contents_of_db(filename='anagrams'): db = shelve.open(filename, flag='r') key
sorted(db):
print(key.rjust(12), '
', ', '.join(db[key]))
db.close() db_of_anagrams() print_contents_of_db()
Exercise 14.5 # Replace urllib.request with urllib if you use Python 2. # I would love to see a more elegant solution for this exercise, possibly by someone who understands html.
check(zip_code): zip_code == 'done':
: len(zip_code) != 5: print('
The zip code must have five digits!')
get_html(zip_code): gibberish = urllib.request.urlopen('http://www.uszip.com/zip/' + zip_code) less_gib = gibberish.read().decode('utf-8') less_gib extract_truth(code, key, delimiter): pos = code.find(key) + len(key) nearly_true = code[pos:pos+40] truth = nearly_true.split(delimiter)[0] truth : zip_code = input('Please type a zip code (5 digits) or "done" if want to stop:
')
check(zip_code):
code = get_html(zip_code) invalid_key = '(0 results)' invalid_key print('
code:
Not a valid zip code.')
name_key = '' name_del = ' zip' name = extract_truth(code, name_key, name_del)
pop_key = 'Total population' pop_del = '...