Think Python/答案
請參閱下面的第 1 章練習。
1.) 42 分 42 秒有多少秒?
>>> (42 * 60) + 42
2562 秒
2.) 10 公里有多少英里?提示:1 英里約等於 1.61 公里。
>>> 10/1.61
6.21 英里
3.) 如果你在 42 分 42 秒內跑完 10 公里,你的平均每英里時間是多少?你的平均速度是多少英里每小時?(提示:1 英里約等於 1.61 公里。)
>>> 10 / 1.61 # 將公里轉換為英里
6.211180124223602
>>> (42 * 60) + 42 # 將時間轉換為秒
2562
>>> 2562 / 6.211180124223602 # 你的平均每英里時間(秒)
412.482
>>> 412.482 / 60 # 你的平均每英里時間(分鐘)
6.874700000000001
>>> 60 / 6.874700000000001 # 英里每小時
8.727653570337614
另一種方法
>>> 10 / 42.7 # 平均每分鐘公里
0.23419203747072598
>>> 0.23419203747072598 * 60 # 公里每小時
14.05152224824356
>>> 14.05152224824356 / 1.61 # 轉換為英里每小時
8.727653570337614
或者一個一行程式碼
>>> (10 / 1.61) / (42.7 / 60) # (距離,英里) / (時間,小時)
8.727653570337614 # 英里/小時
如果你輸入一個以 0 開頭的整數,你可能會得到一個令人困惑的錯誤
>>> zipcode = 02492
^
SyntaxError: invalid token
其他數字似乎可以工作,但結果很奇怪
>>> zipcode = 02132
>>> print zipcode
1114
因此,python 假設你想要將八進位制數轉換為十進位制數。在以 8 為底的數字系統中,有效的數字是 0、1、2、3、4、5、6 和 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
每 8 個數字,我們將左側列加 1。這意味著最右側的列是“1”的數量。它左側的是“8”的數量,它旁邊的列是“8”列乘以“8”列的完整列,即 64。它旁邊的列是 64*8 - 512 等等。有關更多資訊,請閱讀 八進位制數學。
這就是為什麼 zipcode = 02492 無效的原因,因為數字 9 不是有效的八進位制數。我們可以手動進行轉換,如下所示
>>> print 02132
1114
>>> (2*512)+(1*64)+(3*8)+(2*1)
1114
>>>
半徑為 的球體的體積是 4/3 π 。半徑為 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
>>>
假設一本書的封面價為 24.95 美元,但書店可以享受 40% 的折扣。第一本的運費為 3 美元,每增加一本運費為 75 美分。60 本書的總批發價是多少?
$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 delivery
59 Remaining books
$0.75 Delivery cost for extra books
$44.25 Total cost for extra books
$47.25 Total Delivery cost
$945.45 Total Bill
This answer is wrong because 40.0/100.0 return wrong value 0.40000000000000002 for more info see IEEE 754 (Standard for 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.
from decimal import Decimal
..
...
def wholesale_cost(args):
d = 1 - args.get('discount')/100
purchase = Decimal(args.get('cost') * d * 60)
return purchase + Decimal(args.get('delivery'))
args = {'cost': 24.95, 'discount': 40, 'delivery': 3.00+0.75*59}
另一個使用函式和輸入提示的解決方案
# Total wholesale book cost calculator
cover_price = 24.95
number_of_books = int(input("How many books do you want to order at wholesale? "))
def ship_cost (number_of_books):
if number_of_books == 1:
return (number_of_books * 3) # Cost of shipping one book is $3
else:
return (3 + (number_of_books - 1) * 0.75) # Each additional copy of the book is $0.75 to ship
def discounted_price(number_of_books):
return(cover_price - (cover_price * .4)) # There is a 40% discount on wholesale book sales
def wholesale_cost(number_of_books):
return ((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))
如果我早上 6:52 離開家,以輕鬆的步伐跑 1 英里(每英里 8:15),然後以快步跑 3 英里(每英里 7:12),最後再以輕鬆的步伐跑 1 英里,我幾點回家吃早餐?
答案:早上 7:30
我的做法
>>> 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 it hasn't taught yet.
>>> finish_minute = (finish_hour - finish_floored)*60
>>> print ('Finish time was %d:%d' % (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) )
>>>
Python 提供了一個名為 len 的內建函式,它返回字串的長度,因此 len('allen') 的值為 5。編寫一個名為 right_justify 的函式,它接受一個名為 s 的字串作為引數,並列印該字串,並在其前面加上足夠的空格,以便字串的最後一個字母出現在顯示的第 70 列。
>>> def right_justify(s):
print (' '*(70-len(s))+s)
>>> right_justify('allen')
allen
>>>
使用串聯和重複的另一種解決方案
def right_justify(s):
total_length = 70
current_length = len(s)
current_string = s
while current_length < total_length:
current_string = " " + current_string
current_length = len(current_string)
print(current_string)
OUTPUT
>>> right_justify("monty")
monty
你可以在 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.
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 less-straightforward 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 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
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 first 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()
print_block()
-----------------------
# mteodor
def draw_line(bar, middle = ' ', repeat = 2, length = 2):
""" Draw a single line like this:
[ (B M*repeat)*length B]
"""
for k in range(length):
print("%s %s " % (bar, middle*repeat), end='')
print(bar)
def draw_grid(length = 2, height = 2, width = 2):
""" Draw a grid like this:
+ -- + -- +
| | |
| | |
+ -- + -- +
| | |
| | |
+ -- + -- +
where:
* length x height are the table size
* width is the size of a cell/column
"""
for i in range(height):
draw_line('+', '-', width, length)
for j in range(length):
draw_line('|', ' ', width, length)
draw_line('+', '-', width, length)
draw_grid(4, 4, 3)
--------------------------
#kipp
# auto adjust size of columns
size=4
def beam():
print(" + - - - -"*size, "+")
def post():
print(" | "*size, "|")
def 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()
from TurtleWorld import *
world = TurtleWorld()
bob = Turtle()
def square(t):
for i in range(4):
fd(t, 100)
lt(t)
square(bob)
wait_for_user()
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()
from swampy.TurtleWorld import *
world = TurtleWorld()
bob = Turtle()
print(bob)
def polygon(t, length, n):
for i in range(n):
fd(t, length)
lt(t, 360 / n)
polygon(bob, 50, 8)
wait_for_user()
def countdown(a): # A typical countdown function
if a < 0:
print("Blastoff")
elif a > 0:
print(a)
countdown(a - 1)
def call_function(n,a): # The countdown function is called "n" number of times. Any other function can be used instead of countdown function.
for i in range(n):
countdown(a)
call_function(3, 10)
def is_triangle(a, b, c):
if a <= b+c:
if b <= a+c:
if c <= a+b:
return 'yes'
else:
return 'no'
else:
return 'no'
else:
return 'no'
is_triangle(1, 12, 1)
'no'
def is_triangle(a, b, c):
if a<=b+c and b<=a+c and c<=a+b:
return 'yes'
else:
return 'no'
is_triangle(1, 12, 3)
'no'
fin = open('words.txt')
for line in fin:
word = line.strip()
if len(word) > 20:
print (word)
fin = 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 fin:
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'."
fin = open('words.txt')
def avoids(word,letter):
for char in word:
if char in letter:
return False
return True
letter = raw_input('What letters to exclude? ')
count = 0
for line in fin:
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 " + letter + '.'
def uses_only(word, letters):
"""returns true if word is made only out of letters else flase"""
for letter in word:
if letter not in letters:
return False
return True
編寫一個名為 nested_sum 的函式,它接收一個巢狀的整數列表,並累加所有巢狀列表中的元素。
def nested_sum(nestedList):
'''
nestedList: list composed of nested lists containing int.
Returns the sum of all the int in the nested list
'''
newList = []
#Helper function to flatten the list
def flatlist(nestedList):
'''
Returns a flat list
'''
for i in range(len(nestedList)):
if type(nestedList[i]) == int:
newList.append(nestedList[i])
else:
flatlist(nestedList[i])
return newList
flatlist(nestedList)
print sum(newList)
nested_sum(nestedList)
編寫一個名為 "capitalize_nested" 的函式,它接收一個巢狀的字串列表,並返回一個新的巢狀列表,其中所有字串都已大寫。
>>> 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] = capitalize(i)
return l
編寫一個函式,它接收一個數字列表,並返回累加和。
>>> def cumulative(l):
cumulative_sum = 0
new_list = []
for i in l:
cumulative_sum += i
new_list.append(cumulative_sum)
return new_list
編寫一個名為 middle 的函式,它接收一個列表,並返回一個包含除第一個和最後一個元素之外的所有元素的新列表。
>>> def middle(x):
res = []
i = 1
while i <= len(x)-2:
res.append(x[i])
i += 1
return res
這也可以透過簡單地使用切片來實現。
>>> def middle(x):
return x[1:-1]
編寫一個名為 chop 的函式,它接收一個列表並修改它,刪除第一個和最後一個元素,並返回 None。
>>> def chop(x):
del x[:1]
del x[-1:]
編寫一個函式,它讀取 words.txt 中的單詞並將它們儲存為字典中的鍵。值並不重要。然後,可以使用 in 運算子作為快速方法來檢查字串是否在字典中。
fin = open('words.txt')
englishdict = dict()
def create_diction():
counter = 0
dictionairy = dict()
for line in fin:
word = line.strip()
dictionairy[word] = counter
counter += 1
return dictionairy
def invert_dict(s):
i={}
for key in s:
v=s[key]
i.setdefault(v, []).append(key)
return i
編輯: 這不是我在 "Think Python" 的版本中找到的練習,所以為了以防萬一其他人好奇,我添加了我的答案: 使用 get 更簡潔地編寫 histogram。你應該能夠消除 if 語句。
def histogram(s):
d = dict()
for c in s:
d[c] = d.get(c,0)+1
return d
字典有一個名為 keys 的方法,它返回字典的鍵,無特定順序,作為列表。修改 print_hist 以按字母順序列印鍵及其值。
v = {'p' : 1, 'a' : 1, 'r' : 2, 'o' : 1, 't' : 1}
def print_hist(h):
d = []
d += sorted(h.keys())
for c in d:
print(c, h[c])
或者
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]
修改 reverse_lookup,使其構建並返回對映到 v 的所有鍵的列表,如果沒有則返回空列表。
def reverse_lookup(d,v):
l = list()
for c in d:
if d[c] == v:
l.append(c)
return l
numbers = (1,2,3)
def sumall(numbers):
x = 0
for i in numbers:
x = x + i
print x
sumall(numbers)
或者
def sumall(*t):
x = 0
for i in range(len(t)):
x += t[i]
return x
或者
def sumall(*args):
t = list(args)
return sum(t)
或者
def sumall(*args):
return sum(args)
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:
res.append(word)
i=0
final = []
while i <= len(res)-2:
if len(res[i]) == len(res[i+1]):
y_list = [res[i], res[i+1]]
random.shuffle(y_list)
final = final + y_list
i += 2
else:
final.append(res[i])
i += 1
if i == len(res)-1:
final.append(res[i])
return final
或者
from random import shuffle
def sort_by_length(words):
r = []
d = dict()
for word in words:
d.setdefault(len(word), []).append(word)
for key in sorted(d, reverse=True):
if len(d[key]) > 1:
shuffle(d[key])
r.extend(d[key])
return r
import string
def most_frequent(s):
d = dict()
inv = dict()
for char in s:
if char in string.ascii_letters:
letter = char.lower()
d[letter] = d.get(letter, 0) + 1
for letter, freq in d.items():
inv.setdefault(freq, []).append(letter)
for freq in sorted(inv, reverse=True):
print('{:.2%}:'.format(freq/(sum(list(inv)*len(inv[freq])))), ', '.join(inv[freq]))
from string import punctuation, whitespace, digits
from random import randint
from bisect import bisect_left
def process_file(filename):
h = dict()
fp = open(filename)
for line in fp:
process_line(line, h)
return h
def process_line(line, h):
line = line.replace('-', ' ')
for word in line.split():
word = word.strip(punctuation + whitespace + digits)
word = word.lower()
if word != '':
h[word] = h.get(word, 0) + 1
hist = process_file('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:
cum_list.append(cum_list[i-1] + elem)
return cum_list
def random_word(h):
word_list = list(h.keys())
num_list = []
for word in 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)
return word_list[pos]
print(random_word(hist))
import shelve
def dict_of_signatures_and_words(filename='words.txt'):
d = dict()
for line in open(filename):
word = line.lower().strip()
signature = ''.join(sorted(word))
d.setdefault(signature, []).append(word)
return d
def db_of_anagrams(filename='anagrams', d=dict_of_signatures_and_words()):
db = shelve.open(filename)
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()
def print_contents_of_db(filename='anagrams'):
db = shelve.open(filename, flag='r')
for key in sorted(db):
print(key.rjust(12), '\t<==>\t', ', '.join(db[key]))
db.close()
db_of_anagrams()
print_contents_of_db()
# 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.
import urllib.request
def check(zip_code):
if zip_code == 'done':
return False
else:
if len(zip_code) != 5:
print('\nThe zip code must have five digits!')
return True
def get_html(zip_code):
gibberish = 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.find(key) + len(key)
nearly_true = code[pos:pos+40]
truth = nearly_true.split(delimiter)[0]
return truth
while True:
zip_code = input('Please type a zip code (5 digits) or "done" if want to stop:\n')
if not check(zip_code):
break
code = get_html(zip_code)
invalid_key = '(0 results)'
if invalid_key in code:
print('\nNot a valid zip code.')
continue
name_key = '<title>'
name_del = ' zip'
name = extract_truth(code, name_key, name_del)
pop_key = 'Total population</dt><dd>'
pop_del = '<'
pop = extract_truth(code, pop_key, pop_del)
if not 1 < len(pop) < 9:
pop = 'not available'
print('\n' + name)
print('Population:', pop, '\n')
import math
class Point(object):
"""represents a point in 2-D space"""
def distance(p1, p2):
distance = 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))
import copy
def move_rectangle(rec, dx, dy):
""" does a deep copy and return the newRec with changes applied """
newRec = copy.deepcopy(rec)
newRec.corner.x += dx
newRec.corner.y += dy
return newRec
def print_time(t):
print '%.2d:%.2d:%.2d' % (t.hour, t.minute, t.second)
或者
# Solution for Python3
# More on string formatting: https://docs.python.club.tw/py3k/library/string.html#formatspec
def print_time(t):
# 0 is a fill character, 2 defines the width
print('{}:{:02}:{:02}'.format(t.hour, t.minute, t.second))
def is_after(t1, t2):
return (t1.hour, t1.minute, t1.second) > (t2.hour, t2.minute, t2.second)
# Comment not by the author: This will give a wrong result, if (time.second + seconds % 60) > 60
def increment(time, seconds):
n = seconds/60
time.second += seconds - 60.0*n
time.minute += n
m = time.minute/60
time.minute -= m*60
time.hour += m
或者
# 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 different 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)
# 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
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()
minutes, time.second = divmod(seconds, 60)
time.hour, time.minute = divmod(minutes, 60)
return time
def increment(time, addtime):
seconds = time_to_int(time)
return int_to_time(seconds + addtime)
def print_time (x):
print 'The time is %.2d : %.2d : %.2d' % (x.hour, x.minute, x.second)
print_time (time)
newtime = increment (time, 70)
print_time (newtime)
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()
minutes, time.second = divmod(seconds, 60)
time.hour, time.minute = divmod(minutes, 60)
return time
def mul_time(time, factor):
seconds = time_to_int(time)
seconds *= factor
seconds = int(seconds)
return int_to_time(seconds)
def average_pace(time, distance):
return mul_time(time, 1/distance)
編寫一個 Date 物件的類定義,該物件具有屬性 day、month 和 year。編寫一個名為 increment_date 的函式,它接受一個 Date 物件 date 和一個整數 n,並返回一個新的 Date 物件,表示 date 後 n 天。提示:“九月有三十天……”挑戰:你的函式是否正確處理了閏年?請檢視 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, 3, 2012
print_date(d1)
d2 = increment_date(d1, 7)
print_date(d2)
1. 使用 datetime 模組編寫一個程式,獲取當前日期並列印星期幾。
from datetime import date
def current_weekday():
i = date.today()
print i.strftime('%A')
current_weekday()
2. 編寫一個程式,以生日作為輸入,並列印使用者的年齡以及到他們下一個生日的天數、小時數、分鐘數和秒數。
# Python3 solution. Replace "input" by "raw_input" 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()
2.
from visual import scene, sphere
scene.range = (256, 256, 256)
scene.center = (128, 128, 128)
t = range(0, 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. 下載 http://thinkpython.com/code/color_list.py 並使用 read_colors 函式生成系統上可用顏色的列表,包括它們的名稱和 RGB 值。對於每個命名顏色,在對應於其 RGB 值的位置繪製一個球體。
# As there currently (2013-04-12) is no function read_colors in color_list.py
# I use a workaround and simply import the variable COLORS from color_list.py.
# I then use the function all_colors() on COLORS to get a list of the colors.
from color_list import 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 irrelevant lines
lines = colors_string.split('\n')[2:-2]
# split the individual lines and remove the names
numbers_only = [line.split()[:3] for line in lines]
# turn strings into ints and rgb-lists into tuples
rgb_tuples = [tuple([int(s) for s in lst]) for lst in numbers_only]
# return a list of unique tuples
return list(set(rgb_tuples))
def make_spheres(color_tuples=all_colors()):
scene.range = (256, 256, 256)
scene.center = (128, 128, 128)
for (r, g, b) in color_tuples:
sphere(pos=(r, g, b), radius=7, color=(r/255., g/255., b/255.))
if __name__ == '__main__':
make_spheres()
#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 find modulus\n""\n C=6 to find 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 first no here: ")
b=input("Enter your second no here: ")
add(a,b)
elif C==2:
a=input("Enter your first no here: ")
b=input("Enter your second no here: ")
sub(a,b)
elif C==3:
a=input("Enter your first no here: ")
b=input("Enter your second no here: ")
mul(a,b)
elif C==4:
a=input("Enter your first no here: ")
b=input("Enter your second no here: ")
div(a,b)
elif C==5:
a=input("Enter your first no here: ")
b=input("Enter your second no here: ")
mod(a,b)
def first(word):
return word[0]
def last(word):return word[-1]
def middle(word):
return word[1:-1]
def palindrome(word):
if first(word)==last(word):
word = middle(word)
n=len(word)
if n<2:
print "palindrome"
else:
return palindrome(word)
else:
print "not palindrome"
word=raw_input("Enter the string:")
palindrome(word)
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
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 shuffle(self):
import random
random.shuffle(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 []
# 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[i-5: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', 'Two-Pair',
'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(config = '', trials = 10000, n = 1):
"""Estimates probability that the
nth dealt hand will be config. A hand
consists of seven cards."""
successes = 0
for i in range(1, trials + 1):
deck = Deck('Deck %d' % i)
deck.shuffle()
box = Hand()
deck.move_cards(box, (n-1)*7)
hand = PokerHand('Poker Hand %d' % i)
deck.move_cards(hand, 7)
if hand.classify() == config:
successes += 1
return 1.0*successes/trials
#Iterate until first desired config.:
if __name__ == '__main__':
c = 1
while True:
deck = Deck()
deck.shuffle()
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
閱讀維基百科關於大 O 符號的頁面並回答以下問題
1. n³ + n² 的增長階數是多少?1000000n³ + n² 呢?n³ + 1000000n² 呢?
- 答:都是 O(n³)
2. (n² + n) · (n + 1) 的增長階數是多少?在你開始相乘之前,請記住你只需要最高階項。
- 答:O(n³)
3. 如果 f 屬於 O(g),對於某個未指定的函式 g,我們可以對 af + b 說些什麼,其中 a 和 b 是常數?
- 答:a 和 b 也屬於 O(g),因為 O 符號使用最高階係數。常數屬於 O(1),所以在這種情況下它們無關緊要。
4. 如果 f1 和 f2 屬於 O(g),我們可以對 f1 + f2 說些什麼?
- 答:假設作者的意思是本題中的 g 與上一題中的 g 不同,那麼 O(g) 保持不變。
5. 如果 f1 屬於 O(g) 且 f2 屬於 O(h),我們可以對 f1 + f2 說些什麼?
- 答:f1 + f2 可能匹配也可能不匹配 O(g) 和 O(h) 中的較高增長階數。如果 f1 或 f2 是最高階係數,那麼 f1 + f2 將具有與 O(g) 或 O(h) 中的較大增長階數相同的增長階數。如果不是這樣,那麼我們對 f1 + f2 的增長階數一無所知。也就是說,它們相加與否並不重要。
6. 如果 f1 屬於 O(g) 且 f2 屬於 O(h),我們可以對 f1 · f2 說些什麼?
- 答:這不同。如果 f1 和 f2 相乘(並且假設它們都包含 n),那麼 O(f1 · f2) 必須是 O(n) 或更大。如果 f1 是 n³,例如,它可能會更大,但它必須至少是 O(n)。
編寫一個名為 bisection 的函式,它接受一個排序列表和一個目標值,並在列表中返回該值的索引(如果存在),或者如果不存在則返回 None。
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, 3]
print(bisection(b, 2)) # expect None
c = [1, 2]
print(bisection(c, 3)) # expect None