0% found this document useful (0 votes)
2K views

Think Python/Answers

The document provides examples and explanations of base 8 (octal) numbering. It shows how each place value in an octal number corresponds to a power of 8, similar to how place values work in base 10 decimal. It provides the octal equivalents for numbers from 0 to 23 in base 10. It then explains that the digit 9 is invalid in octal numbers since it is not between 0-7. Finally, it demonstrates manually converting the octal number 02132 to its decimal equivalent of 1114.

Uploaded by

peyman
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2K views

Think Python/Answers

The document provides examples and explanations of base 8 (octal) numbering. It shows how each place value in an octal number corresponds to a power of 8, similar to how place values work in base 10 decimal. It provides the octal equivalents for numbers from 0 to 23 in base 10. It then explains that the digit 9 is invalid in octal numbers since it is not between 0-7. Finally, it demonstrates manually converting the octal number 02132 to its decimal equivalent of 1114.

Uploaded by

peyman
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

Think Python/Answers

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

Chapter 1

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.

See below for Chapter 1 exercises.

1.1

Exercise 1.4

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:

If you run a 10 kilometer race in 43 minutes 30 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.)

>>>
print
02132
1114
>>>
(2*512)+(1*64)+(3*8)+(2*1)
1114
>>>
>>> 10 / 1.61 # Convert kilometers to miles
6.2111801242236018 >>> (43 * 60) + 30 # Convert
time to seconds 2610 >>> 2610 / 6.2111801242236018
# what is your average time (seconds) per mile 2.2 Exercise 2.4
420.21000000000004 >>> 420.21000000000004 /
60 # what is your average time (minutes) per mile The volume of a sphere with radius r is 4/3 r3 . What is
7.0035000000000007 >>> 60 / 7.0035000000000007 the volume of a sphere with radius 5?
# Miles per hour 8.5671449989291055 How
about >>> 10 / 43.5 # avg kilometers per minute >>> pi = 3.1415926535897931 >>> r = 5
0.22988505747126436 >>> 0.22988505747126436*60 >>> 4/3*pi*r**3 # This is the wrong answer
# kilometers per hour 13.793103448275861 >>> 392.69908169872411 >>> r = 5.0 # Radius can be
13.793103448275861 / 1.61 # convert to M.P.H a oat here as well, but is not _necessary_. >>>
8.567144998929106 or a one-liner >>> (10 / 1.61) 4.0/3.0*pi*r**3 # Using oats give the correct answer
/ (43.5 / 60) # (distance in miles) / (time in hours) 523.59877559829886 >>>
8.567144998929106 # miles/hour making it 'pretty' & Suppose the cover price of a book is $24.95, but bookexploring how print works.... >>> print round((10 / stores get a 40% discount. Shipping costs $3 for the rst
1.61) / (43.5 / 60), 2), 'mph' # (distance in miles)/(time copy and 75 cents for each additional copy. What is the
in hours) rounded to 2 places 8.57 mph
total wholesale cost for 60 copies?
$24.95 Cost $9.98 Discount per book $14.97 Cost
per book after discount 60 Total number of books
$898.20 Total cost not inc delivery $3.00 First book
2 Chapter 2
delivery 59 Remaining books $0.75 Delivery cost
for extra books $44.25 Total cost for extra books
2.1 Exercise 2.1
$47.25 Total Delivery cost $945.45 Total Bill This
answer is wrong because 40.0/100.0 return wrong
If you type an integer with a leading zero, you might get value 0.40000000000000002 for more info see
a confusing error:
IEEE 754 (Standard for Floating-Point Arithmetic)
>>>
(24.95-24.95*40.0/100.0)*60+3+0.75*(60-1)
>>> zipcode = 02492 ^ SyntaxError: invalid token
945.44999999999993 >>> 24.95*0.6*60+0.75*(60Other number seem to work, but the results are bizarre: 1)+3 945.45
>>> zipcode = 02132 >>> print zipcode 1114
If I leave my house at 6:52 am and run 1 mile at an easy
So python is assuming you want to convert an octal num- pace (8:15 per mile), then 3 miles at tempo (7:12 per
ber to a decimal number. In the base 8 numbering system mile) and 1 mile at easy pace again, what time do I get
where valid numbers are 0, 1, 2, 3, 4, 5, 6 and 7.
home for breakfast?
1

3 CHAPTER 3

Answer: 7:30 am
How I did it:
>>> start = (6*60+52)*60 >>> easy = (8*60+15)*2
>>> fast = (7*60+12)*3 >>> nish_hour = (start + easy
+ fast)/(60*60.0) >>> nish_oored = (start + easy +
fast)//(60*60) #int() function can also be used to get
integer value, but isn't taught yet. >>> nish_minute
= (nish_hour - nish_oored)*60 >>> print 'Finish
time was %d:%d' % (nish_hour,nish_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) ) >>>

3
3.1

Chapter 3
Exercise 3.3

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.
>>> def right_justify(s): print (' '*(70-len(s))+s) >>>
right_justify('allen') allen >>>

3.2

Exercise 3.5

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 # twoby-two version of the grid. def do_twice(f): f() f() def
do_four(f): do_twice(f) do_twice(f) def print_beam():
print('+ - - - -', end='') def print_post(): print('| ', end='')
def print_beams(): do_twice(print_beam) print('+')
def print_posts(): do_twice(print_post) print('|') def
print_row():
print_beams() do_twice(print_posts)
def print_grid(): do_twice(print_row) print_beams()
print_grid() ____________ # another solution def
do_twice(f): f() f() def do_four(f): do_twice(f)
do_twice(f) def print_column():
print '+----+---+' def print_row(): print '| | |' def print_rows():
do_four(print_row) def do_block(): print_column()
print_rows() def print_block(): do_twice(do_block)
print_column() print_block() # nathan moses-gonzales

_________ # straight-forward solution to 4x4 grid def


do_twice(f): f() f() def do_four(f): # not needed for
2x2 grid do_twice(f) do_twice(f) def print_beam():
print('+----', end='') def print_post(): print('| ', end='')
def print_beams(): do_twice(print_beam) print('+')
def print_posts(): do_twice(print_post) print('|') def
print_row(): print_beams() do_twice(print_posts) def
print_grid2x2(): do_twice(print_row) print_beams()
def print_beam4(): do_four(print_beam) print('+')
def print_post4(): do_four(print_post) print('|') def
print_row4(): print_beam4() do_twice(print_post4) def
print_grid4x4(): do_four(print_row4) print_beam4()
print_grid4x4() ----------------------- # here is a lessstraightforward solution to the # four-by-four grid
def one_four_one(f, g, h): f() do_four(g) h() def
print_plus(): print '+', def print_dash(): print '-', def
print_bar(): print '|', def print_space(): print ' ', def
print_end(): print def nothing(): do nothing def
print1beam():
one_four_one(nothing, print_dash,
print_plus) def print1post(): one_four_one(nothing,
print_space,
print_bar)
def
print4beams():
one_four_one(print_plus,
print1beam,
print_end)
def print4posts(): one_four_one(print_bar, print1post,
print_end) def print_row(): one_four_one(nothing,
print4posts,
print4beams)
def
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 rst 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
reect the structure of the solution. --- Allen """ print
comment # another solution def beam(): plus = "+"
minus = "-"*4 print(plus, minus, plus,minus, plus, minus,
plus, minus, plus) def straight(): straight = "|" space = "
"*4 print(straight, space, straight, space, straight, space,
straight, space, straight, space) def quad_straight():
straight() straight() straight() straight() def twice():
beam() quad_straight() beam() quad_straight() def
quad(): twice() twice() beam() quad() -- :) ----------------- # Without functions. print("+ - - - - " * 2 +
"+") print("|\t\t | \t\t|\n * 3 + "|\t\t | \t\t|") print("+ - - - " * 2 + "+") print("|\t\t | \t\t|\n " *3 + "|\t\t | \t\t|")
print("+ - - - - " * 2 + "+") ------------------ Why not
using the rst solution and adapt it to the number of
rows def do_twice(f): f() f() def do_four(f): do_twice(f)
do_twice(f) def print_column(): print '+----+----+---+----+' def print_row(): print '| | | | |' def print_rows():
do_four(print_row) def do_block(): print_column()
print_rows() def print_block(): do_twice(do_block)
# print_column() do_twice(do_block) print_column()

3
print_block() ----------------------- # mteodor def
draw_line(bar, middle = ' ', repeat = 2, lenght = 2):
""" Draw a single line like this: [ (B M*repeat)*lenght
B] """ for k in range(lenght): print("%s %s " % (bar,
middle*repeat), end='') print(bar) def 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 """ for i in range(height): draw_line('+',
'-', width, lenght) for j in range(lenght): draw_line('|',
' ', width, lenght) draw_line('+', '-', width, lenght)
draw_grid(4, 4, 3)

4
4.1

Chapter 4

6 Chapter 9
6.1 Exercise 9.1
n = open('words.txt') for line in n: word = line.strip()
if len(word) > 20: print (word)

6.2 Exercise 9.2


n = open('words.txt') def has_no_e(word): for char in
word: if char in 'Ee': return False return True count =
0 for line in n: word = line.strip() if has_no_e(word):
count += 1 print word percent = (count / 113809.0) *
100 print str(percent) + "% of the words don't have an 'e'.

4.3 Exercise 1
6.3 Exercise 9.3

from TurtleWorld import * world = TurtleWorld() bob


= Turtle() def square(t): for i in range(4): fd(t, 100) lt(t) n = open('words.txt') def avoids(word,letter): for char
square(bob) wait_for_user()
in word: if char in letter: return False return True letter
= raw_input('What letters to exclude? ') count = 0 for
line in n: word = line.strip() if avoids(word, letter):
count += 1 print word percent = (count / 113809.0) *
100 print str(percent) + "% of the words don't have " +
4.2 4.3 Exercise 2
letter + '.'
from TurtleWorld import * world = TurtleWorld() bob
= Turtle() print(bob) def square(t, length): t = Turtle()
for i in range(4): fd(t, length) lt(t) square(bob, 200)
wait_for_user()

7 Chapter 10
7.1 Exercise 10.1

4.3

4.3 Exercise 3

Write a function called nested_sum that takes a nested list


of integers and add up the elements from all of the nested
from TurtleWorld import * world = TurtleWorld() bob = lists.
Turtle() print(bob) def polygon(t, length, n): t = Turtle()
def nested_sum(nestedList, newList = [0]): ''' nestfor i in range(n): fd(t, length) lt(t, 360 / n) polygon(bob,
edList: list composed of nested lists containing int.
50, 8) wait_for_user()
newList: list. The at list composed of all the items
present in the nested lists. Returns the sum of all the
int in the nested list ''' #Helper function to atten the
list def atlist(nestedList): ''' Returns a at list ''' for i
in range(len(nestedList)): if type(nestedList[i]) == int:
5 Chapter 5
newList.append(nestedList[i]) else: atlist(nestedList[i])
return newList atlist(nestedList) print sum(newList)
nested_sum(nestedList)
5.1 Exercise 5.2
def countdown(a): # A typical countdown function if a
< 0: print(Blasto) elif a > 0: print(a) countdown(a 1) def call_function(n,a): # The countdown function is 7.2 Exercise 10.2
called n number of times. Any other function can be
used instead of countdown function. for i in range(n): Write a function named capitalize_nested that takes a
nested list of strings and returns a new nested list with all
countdown(a) call(3, 10)
strings capitalized.

>>> def capitalize_nested(l): def capitalize(s): return


s.capitalize() for n, i in enumerate(l): if type(i) is list:
l[n] = capitalize_nested(l[n]) elif type(i) is str: l[n] =
8.3
capitalize(i) return l

7.3

Exercise 10.3

CHAPTER 12

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.

Write a function that takes a list of numbers and returns


v = {'p' : 1, 'a' : 1, 'r' : 2, 'o' : 1, 't' : 1} def print_hist(h):
the cumulative sum.
d = [] d += sorted(h.keys()) for c in d: print(c, h[c])
>>> def cumulative(l):
cumulative_sum = 0
new_list = [] for i in l: cumulative_sum += i
OR
new_list.append(cumulative_sum) return new_list
v = {'p' : 1, 'a' : 1, 'r' : 2, 'o' : 1, 't' : 1} def print_hist(h):
for c in sorted(h.keys()): print c, h[c]

7.4

Exercise 10.4

Write a function called middle that takes a list and returns 8.4 Exercise 11.4
a new list that contains all but the rst and last elements.
Modify reverse_lookup so that it builds and returns a list
>>> def middle(x): res = [] i = 1 while i <= len(x)2:
of all keys that map to v, or an empty list if there are none.
res.append(x[i]) i += 1 return res
def reverse_lookup(d,v): l = list() for c in d: if d[c] ==
v: l.append(c) return l
This can also be done simply with a slice.
>>> def middle(x): return x[1:1]

9 Chapter 12
7.5

Exercise 10.5
9.1 Exercise 12.1

Write a function called chop that takes a list and modies


it, removing the rst and last elements, and returns None. numbers = (1,2,3) def sumall(numbers): x = 0 for i in
numbers: x = x + i print x sumall(numbers)
>>> def chop(x): del x[:1] del x[1:]
or

8
8.1

Chapter 11
Exercise 11.1

def sumall(*t): x = 0 for i in range(len(t)): x += t[i]


return x
or

def sumall(*args): t = list(args) return sum(t)


Write a function that reads the words in words.txt and
stores them as keys in a dictionary. It doesnt matter what
the values are. Then you can use the in operator as a fast or
way to check whether a string is in the dictionary.
def sumall(*args): return sum(args)
n = open('words.txt') englishdict = dict() def create_diction(): counter = 0 dictionairy = dict() for line
in n: word = line.strip() dictionairy[word] = counter
9.2 Exercise 12.2
counter += 1 return dictionairy
import random def sort_by_length(words): t = []
for word in words:
t.append((len(word),word))
t.sort(reverse=True) res = [] for length, word in t:
8.2 Exercise 11.2
res.append(word) i=0 nal = [] while i <= len(res)2:
def histogram(s): d = dict() for c in s: d[c] = 1 + d.get(c, if len(res[i]) == len(res[i+1]): y_list = [res[i], res[i+1]]
0) return d
random.shue(y_list) nal = nal + y_list i += 2

11.2

Exercise 14.5

else: nal.append(res[i]) i += 1 if i == len(res)1:


nal.append(res[i]) return nal

d=dict_of_signatures_and_words()):
db
=
shelve.open(lename) for key, values in d.items():
if len(values)>1: for index, value in enumerate(values):
db[value]=values[:index]+values[index+1:] db.close()
or
def print_contents_of_db(lename='anagrams): db =
from random import shue def sort_by_length(words): shelve.open(lename, ag='r') for key in sorted(db):
r = [] d = dict() for word in words: d.setdefault(len(word), print(key.rjust(12), '\t<==>\t', ', '.join(db[key]))
[]).append(word) for key in sorted(d, reverse=True): if db.close() db_of_anagrams() print_contents_of_db()
len(d[key]) > 1: shue(d[key]) r.extend(d[key]) return r

9.3

Exercise 12.3

11.2 Exercise 14.5

# Replace urllib.request with urllib if you use Python


import string def most_frequent(s): d = dict() inv 2. # I would love to see a more elegant solution for
= dict() for char in s: if char in string.ascii_letters: this exercise, possibly by someone who understands
letter = char.lower() d[letter] = d.get(letter, 0) + html. import urllib.request def check(zip_code): if
1 for letter, freq in d.items(): inv.setdefault(freq, zip_code == 'done': return False else: if len(zip_code)
[]).append(letter) for freq in sorted(inv, reverse=True): != 5: print('\nThe zip code must have ve digits!')
print('{:.2%}:'.format(freq/(sum(list(inv)*len(inv[freq])))), return True def get_html(zip_code): gibberish =
', '.join(inv[freq]))
urllib.request.urlopen('http://www.uszip.com/zip/'
+
zip_code) less_gib = gibberish.read().decode('utf-8')
return less_gib def extract_truth(code, key, delimiter): pos = code.nd(key) + len(key) nearly_true =
code[pos:pos+40] truth = nearly_true.split(delimiter)[0]
10 Chapter 13
return truth while True: zip_code = input('Please type
a zip code (5 digits) or done if want to stop:\n') if
10.1 Exercise 13.7
not check(zip_code): break code = get_html(zip_code)
invalid_key = '(0 results)' if invalid_key in code:
from string import punctuation, whitespace, digits print('\nNot a valid zip code.') continue name_key =
from random import randint from bisect import bi- '<title>' name_del = ' zip' name = extract_truth(code,
sect_left def process_le(lename): h = dict() fp = name_key, name_del) pop_key = 'Total populaopen(lename) for line in fp: process_line(line, h) return tion</dt><dd>' pop_del = '<' pop = extract_truth(code,
h def process_line(line, h): line = line.replace('-', ' ') pop_key, pop_del) if not 1 < len(pop) < 9: pop = 'not
for word in line.split(): word = word.strip(punctuation available' print('\n' + name) print('Population:', pop, '\n')
+ whitespace + digits) word = word.lower() if word
!= '': h[word] = h.get(word, 0) + 1 hist = process_le('emma.txt') def cum_sum(list_of_numbers):
cum_list = [] for i, elem in enumerate(list_of_numbers):
if i == 0:
cum_list.append(elem) else: 12 Chapter 15
cum_list.append(cum_list[i-1] + elem) return cum_list
def random_word(h): word_list = list(h.keys()) num_list 12.1 Exercise 15.1
= [] for word in word_list: num_list.append(h[word])
cum_list = cum_sum(num_list) i = randint(1, import math class Point(object): """represents a point
cum_list[1]) pos = bisect_left(cum_list, i) return in 2-D space""" def distance(p1, p2): distance =
word_list[pos] print(random_word(hist))
math.sqrt((p2.x - p1.x)**2 + (p2.y - p1.y)**2) return
distance p1 = Point() p2 = Point() p1.x = 3 p1.y = 2 p2.x
= 4 p2.y = 3 print(distance(p1, p2))

11

Chapter 14

11.1

Exercise 14.3

13 Chapter 16

13.1 Exercise 16.1


import shelve def dict_of_signatures_and_words(lename='words.txt'):
d = dict() for line in open(lename): word =
line.lower().strip() signature = ''.join(sorted(word)) def print_time(t): print '%.2d:%.2d:%.2d' % (t.hour,
d.setdefault(signature,
[]).append(word)
return t.minute, t.second)
d
def
db_of_anagrams(lename='anagrams,

13

CHAPTER 16

or

minutes, time.second = divmod(seconds, 60) time.hour,


# Solution for Python3 # More on string formatting: http: time.minute = divmod(minutes, 60) return time def
//docs.python.org/py3k/library/string.html#formatspec increment(time, addtime): seconds = time_to_int(time)
def print_time(t): # 0 is a ll character, 2 denes the return int_to_time(seconds + addtime) def print_time
width print('{}:{:02}:{:02}'.format(t.hour, t.minute, (x): print 'The time is %.2d : %.2d : %.2d' % (x.hour,
x.minute, x.second) print_time (time) newtime = incret.second))
ment (time, 70) print_time (newtime)

13.2

Exercise 16.2

13.6 Exercise 16.6

def is_after(t1, t2): return (t1.hour, t1.minute, t1.second)


def time_to_int(time): minutes = time.hour * 60 +
> (t2.hour, t2.minute, t2.second)
time.minute seconds = minutes * 60 + time.second
return seconds def int_to_time(seconds): time = Time()
minutes, time.second = divmod(seconds, 60) time.hour,
time.minute = divmod(minutes, 60) return time def
13.3 Exercise 16.3
mul_time(time, factor): seconds = time_to_int(time)
# Comment not by the author: This will give a wrong seconds *= factor seconds = int(seconds) return
result, if (time.second + seconds % 60) > 60 def incre- int_to_time(seconds) def average_pace(time, distance):
ment(time, seconds): n = seconds/60 time.second += return mul_time(time, 1/distance)
seconds - 60.0*n time.minute += n m = time.minute/60
time.minute -= m*60 time.hour += m

13.7 Exercise 16.7

or
# Solution for Python3 # Replace '//' by '/' for Python2
def increment(time, seconds): time.second += seconds time.minute += time.second//60 time.hour +=
time.minute//60 time.second %= 60 time.minute %= 60
time.hour %= 24
# A dierent way of going about it def increment(time,
seconds): # Converts total to seconds, then back to
a readable format time.second = time.hour*3600 +
time.minute*60 + time.second + seconds (time.minute,
time.second)
=
divmod(time_in_seconds,
60)
(time.hour, time.minute) = divmod(time.minute,
60)

13.4

Exercise 16.4

# Solution for Python3 # Replace '//' by '/' for Python2


from copy import deepcopy def increment(time, seconds): r = deepcopy(time) r.second += seconds r.minute
+= r.second//60 r.hour += r.minute//60 r.second %= 60
r.minute %= 60 r.hour %= 24 return r

13.5

Exercise 16.5

class Time(object): """represents the time of day.


attributes: hour, minute, second""" time = Time()
time.hour = 11 time.minute = 59 time.second = 30
def time_to_int(time): minutes = time.hour * 60 +
time.minute seconds = minutes * 60 + time.second
return seconds def int_to_time(seconds): time = Time()

Write a class denition for a Date object that has attributes day, month and year. Write a function called
increment_date that takes a Date object, date, and an integer, n, and returns a new Date object that represents the
day n days after date. Hint: Thirty days hath September... Challenge: does your function deal with leap years
correctly? See wikipedia.org/wiki/Leap_year.
class Date(object): """represents a date. attributes:
day, month, year""" def print_date(date): # German date format print('{}.{}.{}'.format(date.day,
date.month, date.year)) def is_leap_year(year): #
http://en.wikipedia.org/wiki/Leap_year#Algorithm if
year % 4 == 0: if year % 100 == 0: if year % 400 ==
0: return True return False return True return False
def month_list(year): if is_leap_year(year): return
[31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] return
[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] def
days_of_year(year): if is_leap_year(year): return 366
return 365 def date_to_int(date): days = 0 for year
in range(1, date.year): days += days_of_year(year)
month_days = month_list(date.year) for month in
range(1, date.month): days += month_days[month - 1]
days += date.day - 1 return days def int_to_date(days):
date = Date() date.year = 1 next_days = 365 while
days >= next_days: date.year += 1 days -= next_days
next_days = days_of_year(date.year) date.month = 1
next_days = 31 month_days = month_list(date.year)
while days >= next_days: date.month += 1 days -=
next_days next_days = month_days[date.month - 1]
date.day = days + 1 return date def increment_date(date,
n): days = date_to_int(date) return int_to_date(days
+ n) d1 = Date() d1.day, d1.month, d1.year = 8,

7
3, 2012 print_date(d1) d2 = increment_date(d1, 7) to get a list of the colors. from color_list import
print_date(d2)
COLORS from visual import scene, sphere def
all_colors(colors_string=COLORS): """Extract a list
of unique RGB-tuples from COLORS. The tuples look
like (r, g, b), where r, g and b are each integers in
[0, 255]. """ # split the string into lines and remove
13.8 Exercise 16.8
irrelevant lines lines = colors_string.split('\n')[2:2]
1. Use the datetime module to write a program that gets # split the individual lines and remove the names
numbers_only = [line.split()[:3] for line in lines] # turn
the current date and prints the day of the week.
strings into ints and rgb-lists into tuples rgb_tuples = [tufrom datetime import date def current_weekday(): i =
ple([int(s) for s in lst]) for lst in numbers_only] # return
date.today() print i.strftime('%A') current_weekday()
a list of unique tuples return list(set(rgb_tuples)) def
make_spheres(color_tuples=all_colors()): scene.range
2. Write a program that takes a birthday as input and = (256, 256, 256) scene.center = (128, 128, 128)
prints the users age and the number of days, hours, min- for (r, g, b) in color_tuples: sphere(pos=(r, g, b),
utes and seconds until their next birthday.
radius=7, color=(r/255., g/255., b/255.)) if __name__
# Python3 solution. Replace input by raw_input == '__main__': make_spheres()
for Python2.
from datetime import datetime def
time_until_birthday(): dob_input = input(('Please enter
the date of your birth in ' 'the format mm/dd/yyyy":
')) dob = datetime.strptime(dob_input, '%m/%d/%Y')
now = datetime.now() if now > datetime(now.year,
dob.month, dob.day): age = now.year - dob.year
next_year = True else: age = now.year - dob.year
- 1 next_year = False time_to_birthday = datetime(now.year + next_year, dob.month, dob.day) now days = time_to_birthday.days hours, remainder
= divmod(time_to_birthday.seconds, 3600) minutes,
seconds = divmod(remainder, 60) print("\nYou are {}
years old..format(age)) print((You have {0} days, {1}
hours, {2} minutes and {3} " seconds left until your
next birthday.).format( days, hours, minutes, seconds))
time_until_birthday()

15 Chapter 3.5
15.1 calculator

#recursion or recursive print "\n INDEX\n""\n C=1


for addition\n""\n C=2 for substraction\n""\n C=3
for multiplication\n""\n C=4 for division\n""\n C=5
for to nd modulus\n""\n C=6 to nd factorial\n
C=input(Enter your choice here: ") def add(x,y):
c=x+y print x,"+",y,"=",c def sub(x,y): c=x-y print
x,"-",y,"=",c def mul(x,y): c=x*y print x,"*",y,"=",c
def div(x,y): c=x/y print x,"/",y,"=",c def mod(x,y):
c=x%y print x,"%",y,"=",c if C==6: def f(n): if n==1:
print n return n else: print n,"*", return n*f(n-1)
n=input(enter your no here: ") print f(n) if C==1:
a=input(Enter your rst no here: ") b=input(Enter your
14 Chapter 17
second no here: ") add(a,b) elif C==2: a=input(Enter
your rst no here: ") b=input(Enter your second no
here: ") sub(a,b) elif C==3: a=input(Enter your rst
14.1 Exercise 17.8
no here: ") b=input(Enter your second no here: ")
mul(a,b) elif C==4: a=input(Enter your rst no here:
2.
") b=input(Enter your second no here: ") div(a,b)
from visual import scene, sphere scene.range = (256,
elif C==5: a=input(Enter your rst no here: ")
256, 256) scene.center = (128, 128, 128) t = range(0,
b=input(Enter your second no here: ") mod(a,b)
256, 51) for x in t: for y in t: for z in t: pos = x, y, z color
= (x/255., y/255., z/255.) sphere(pos=pos, radius=10,
color=color)
3. Download http://thinkpython.com/code/color_list.py
and use the function read_colors to generate a list of the
available colors on your system, their names and RGB
values. For each named color draw a sphere in the position that corresponds to its RGB values.

15.2 palindrome

def rst(word): return word[0] def last(word):return


word[1] def middle(word): return word[1:1] def
palindrome(word): if rst(word)==last(word): word
= middle(word) n=len(word) if n<2: print palin# As there currently (2013-04-12) is no function drome else: return palindrome(word) else: print not
read_colors in color_list.py # I use a workaround and palindrome word=raw_input(Enter the string:") palinsimply import the variable COLORS from color_list.py. drome(word)
# I then use the function all_colors() on COLORS

15.3

16

sum of all digits

def sum_of_n_numbers(number):
if(number==0):
return
0
else:
return
number
+
sum_of_n_numbers(number-1)
num
=
raw_input(Enter
a
number:")
num=int(num)
sum
=
sum_of_n_numbers(num)
print
sum
###another answer in case of while loops def
sum_of_Digits(number):
sum=0 while number>0:
digit=number%10 sum=sum+digit number=number/10
return sum num=raw_input(enter the number)
num=int(num)
sum_of_digits=sum_of_Digits(num)
print sum_of_digits

15.4

Exercise 18.5

class Card(object): suit_names = ['Clubs, 'Diamonds, 'Hearts, 'Spades] rank_names = [None,


'Ace', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack',
'Queen', 'King'] def __init__(self, suit = 0, rank =
2): self.suit = suit self.rank = rank def __str__(self):
return '%s of %s % (Card.rank_names[self.rank],
Card.suit_names[self.suit]) def __cmp__(self, other):
c1 = (self.suit, self.rank) c2 = (other.suit, other.rank)
return cmp(c1, c2) def is_valid(self): return self.rank
> 0 class Deck(object): def __init__(self, label =
'Deck'): self.label = label self.cards = [] for i in
range(4): for k in range(1, 14): card = Card(i, k)
self.cards.append(card) def __str__(self): res = []
for card in self.cards: res.append(str(card)) print
self.label return '\n'.join(res) def deal_card(self):
return self.cards.pop(0) def add_card(self, card):
self.cards.append(card) def shue(self): import random
random.shue(self.cards) def sort(self): self.cards.sort()
def move_cards(self, other, num): for i in range(num):
other.add_card(self.deal_card()) def deal_hands(self,
num_hands, num_cards): if num_hands*num_cards >
52: return 'Not enough cards.' l = [] for i in range(1,
num_hands + 1): hand_i = Hand('Hand %d' % i)
self.move_cards(hand_i, num_cards) l.append(hand_i)
return l class Hand(Deck): def __init__(self, label
= ''): self.cards = [] self.label = label # 18-6, 1-4:
class PokerHand(Hand): def suit_hist(self): self.suits
= {} for card in self.cards: self.suits[card.suit] =
self.suits.get(card.suit, 0) + 1 return self.suits def
rank_hist(self): self.ranks = {} for card in self.cards:
self.ranks[card.rank] = self.ranks.get(card.rank, 0) +
1 return self.ranks def P(self): self.rank_hist() for
val in self.ranks.values(): if val >= 2: return True
return False def TP(self): self.rank_hist() count =
0 for val in self.ranks.values(): if val == 4: return
True elif val >= 2 and val < 4: count += 1 return
count >= 2 def TOAK(self): self.rank_hist() for val in
self.ranks.values(): if val >= 3: return True return False
def STRseq(self): seq = [] l = STRlist() self.rank_hist()
h = self.ranks.keys() h.sort() if len(h) < 5: return [] #

APPENDIX B

Accounts for high Aces: if 1 in h: h.append(1) for i


in range(5, len(h)+1): if h[i-5:i] in l: seq.append(h[i5:i]) return seq def STR(self): seq = self.STRseq()
return seq != [] def FL(self): self.suit_hist() for val in
self.suits.values(): if val >= 5: return True return False
def FH(self): d = self.rank_hist() keys = d.keys() for key
in keys: if d[key] >= 3: keys.remove(key) for key in keys:
if d[key] >= 2: return True return False def FOAK(self):
self.rank_hist() for val in self.ranks.values(): if val
>= 4: return True return False def SFL(self): seq =
self.STRseq() if seq == []: return False for list in seq:
list_suits = [] for index in list: for card in self.cards:
if card.rank == index: list_suits.append(card.suit)
list_hist = histogram(list_suits) for key in list_hist.keys():
if list_hist[key] >= 5: return True return False def
classify(self): self.scores = [] hands = ['Pair', 'TwoPair', 'Three of a Kind', 'Straight', 'Flush', 'Full
House', 'Four of a Kind', 'Straight Flush'] if self.P():
self.scores.append(1) if self.TP(): self.scores.append(2)
if
self.TOAK():
self.scores.append(3)
if
self.STR():
self.scores.append(4) if self.FL():
self.scores.append(5) if self.FH(): self.scores.append(6)
if self.FOAK(): self.scores.append(7) if self.SFL():
self.scores.append(8) if self.scores != []:
return
hands[max(self.scores)1] def STRlist(): s = []
for i in range(0,9):
s.append(range(1,14)[i:i+5])
s.append([10,11,12,13,1]) return s def histogram(l): d
= dict() for k in range(len(l)): d[l[k]] = 1 + d.get(l[k],0)
return d # 18-6, 5: def p(cong = '', trials = 10000, n =
1): """Estimates probability that the nth dealt hand will
be cong. A hand consists of seven cards.""" successes
= 0 for i in range(1, trials + 1): deck = Deck('Deck %d'
% i) deck.shue() box = Hand() deck.move_cards(box,
(n-1)*7) hand = PokerHand('Poker Hand %d' % i)
deck.move_cards(hand, 7) if hand.classify() == cong:
successes += 1 return 1.0*successes/trials #Iterate until
rst desired cong.: if __name__ == '__main__': c = 1
while True: deck = Deck() deck.shue() hand = PokerHand('Poker Hand %d' % c) deck.move_cards(hand,
5) print hand print hand.SFL() if hand.SFL(): print
hand.STRseq() break print '' c += 1 Code by Victor
Alvarez

16 Appendix B
16.1 Exercise B.3
Write a function called bisection that takes a sorted list
and a target value and returns the index of the value in
the list, if its there, or None if its not.
from bisect import bisect_left def bisection(sorted_list,
item):
i = bisect_left(sorted_list, item) if i <
len(sorted_list) and sorted_list[i] == item: return i
else: return None if __name__ == '__main__': a
= [1, 2, 3] print(bisection(a, 2)) # expect 1 b = [1,

16.1

Exercise B.3

3] print(bisection(b, 2)) # expect None c = [1, 2]


print(bisection(c, 3)) # expect None

10

17

17
17.1

TEXT AND IMAGE SOURCES, CONTRIBUTORS, AND LICENSES

Text and image sources, contributors, and licenses


Text

Think Python/Answers Source: https://en.wikibooks.org/wiki/Think_Python/Answers?oldid=3116099 Contributors: Cprompt,


Panic2k4, Recent Runes, JackPotte, QuiteUnusual, Adrignola, Ken fallon, RichardMcMahon, Fishpi, Liberacy, Fdfddfdf, Borgesvive, LlamaAl, Kmwaziri, Leon saudanha, Atcovi, D civera ca, Arunkhattri, Cjaeger, Doby123lindong, Devngc, Timshel07, Hillions,
Catalin.ciubotariu, Zepman864 and Anonymous: 62

17.2

Images

17.3

Content license

Creative Commons Attribution-Share Alike 3.0

You might also like