跳转到内容

像计算机科学家一样思考:用 Python 学习 第 2 版/解决方案

来自维基教科书,开放世界中的开放书籍

以下部分包含本书练习的答案。

第 1 章

[编辑 | 编辑源代码]

练习 1

print("5 ** 5 is", 5**2)
print("9 * 5 is", 9 * 5)
print("15 / 12 is", 15 / 12)
print("12 / 15 is", 12 / 15)
print("15 // 12 is", 15 // 12)
print("12 // 15 is", 12 // 15)
print("5 % 2 is", 5 % 2)
print("9 % 5 is", 9 % 5)
print("15 % 12 is", 15 % 12)
print("12 % 15 is", 12 % 15)
print("6 % 6 is", 6 % 6)
print("0 % 7 is", 0 % 7)

练习 2

time_start=14  #  Use 24 hour clock.  Makes life a lot easier.
wait=51
time_hours= time_start + wait
days=time_hours//24
clock=time_hours-(days*24) 
print("The alarm goes of at", str(clock)+":00")

练习 3

#  24 hour clock
t1=input("Enter the current time's hour using 24 hour clock: ")
t1=int(t1)
wait=input("Enter wait in hours for next alarm: ")
wait=int(wait)
t2_hrs=wait+t1
days=t2_hrs//24
t2_time=t2_hrs-(days*24) 
print("The alarm goes of at", str(t2_time)+":00")

def main()

   nowtime = int(raw_input("what time now: "))
   t = int(raw_input("Input the hour go off your wanted: "))
   time = t + nowtime
   days = time//24
   hour = time % 24
   print "The hour will go off after days: ", days, " at hour: ", hour
   pass

if __name__ == '__main__'

   main()

第 3 章

[编辑 | 编辑源代码]

解决方案 4 def cat_n_times(s, n)

   string=s
   print string*n

第 4 章 练习 5

[编辑 | 编辑源代码]
def dispatch(choice):
	if choice == 'a':
		function_a()
	elif choice == 'b':
		function_b()
	elif choice == 'c':
		function_c()
	else:
		print "Invalid choice."
def function_a():
	print "function_a was called ..."
def function_b():
	print "function_b was called ..."
def function_c():
	print "function_c was called ..."

choice = raw_input ("Please Enter a Function.")  #had to ask about this,  choice is raw input.  
print dispatch(choice)

第 4 章 练习 7

[编辑 | 编辑源代码]
def is_divisible_by_3(x):
	if x % 3 == 0:
		print x, "This number is divisible by three."
	else:
		print x, "This number is not divisible by three."
x = input ("Enter a number")
print is_divisible_by_3(x)




def is_divisible_by_5(y):
	if y % 5 == 0:
		print y, "This number is divisible by five."
	else:
		print y, "This number is not divisible by five."
y = input ("Enter a number")
print is_divisible_by_5(y)

def is_divisible_by_n(c,z):
	if c % z == 0:
		print "Yes", c, "divisible by", z
	else:
		print "No", c, "is not divisible by", z
c = input ("Enter number")
z = input ("Enter another number")
print is_divisible_by_n(c,z)

第 5 章

[编辑 | 编辑源代码]

第 5 章 - 解决方案 1

[编辑 | 编辑源代码]
def compare(a, b):
    """
        >>> compare(5, 4)
        1
        >>> compare(7, 7)
        0
        >>> compare(2, 3)
        -1
        >>> compare(42, 1)
        1
    """
    if a > b:
        return 1
    elif a == b:
        return 0
    elif a < b:
        return -1


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

第 5 章 - 解决方案 2

[编辑 | 编辑源代码]
def hypotenuse(a, b):
    """
        >>> hypotenuse(3, 4)
        5.0
        >>> hypotenuse(12, 5)
        13.0
        >>> hypotenuse(7, 24)
        25.0
        >>> hypotenuse(9, 12)
        15.0
    """
    import math
    return math.sqrt(a**2 + b**2)
    # You could also use    
    # return (a**2 + b**2)**0,5

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

第 5 章 - 解决方案 3 第 1 部分

[编辑 | 编辑源代码]
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
    """
    return float(y2 - y1)/(x2 - x1)

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

第 5 章 - 解决方案 3 第 2 部分

[编辑 | 编辑源代码]
def slope(x1, y1, x2, y2):
    return float(y2 - y1)/(x2 - x1)

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
    """
    m = slope(x1, y1, x2, y2)
    return float(y1 - m*x1)

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

第 5 章 - 解决方案 4

[编辑 | 编辑源代码]
def is_even(n):
    """
        >>> is_even(2)
        True
        >>> is_even(3)
        False
        >>> is_even(7)
        False
        >>> is_even(10)
        True
    """
    # You could also type just
    # return n % 2 == 0
    if n % 2 == 0:
        return True
    else:
        return False

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

第 5 章 - 解决方案 5 第 1 部分

[编辑 | 编辑源代码]
def is_odd(n):
    """
        >>> is_odd(2)
        False
        >>> is_odd(3)
        True
        >>> is_odd(7)
        True
        >>> is_odd(10)
        False
    """
    if n % 2 != 0:
        return True
    else:
        return False

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

第 5 章 - 解决方案 5 第 2 部分

[编辑 | 编辑源代码]
def is_even(n):
    if n % 2 == 0:
        return True
    else:
        return False

def is_odd(n):
    """
        >>> is_odd(2)
        False
        >>> is_odd(3)
        True
        >>> is_odd(7)
        True
        >>> is_odd(10)
        False
    """
    if is_even(n) is True:
        return False
    else:
        return True
 
if __name__ == '__main__':
    import doctest
    doctest.testmod()

第 5 章 - 解决方案 6

[编辑 | 编辑源代码]
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
    """
    if n % f == 0:
        return True
    else:
        return False

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

第 5 章 - 解决方案 7

[编辑 | 编辑源代码]
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
    """
    if m % n == 0:
        return True
    else:
        return False

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

第 5 章 - 解决方案 8

[编辑 | 编辑源代码]
def f2c(t):
    """
      >>> f2c(212)
      100
      >>> f2c(32)
      0
      >>> f2c(-40)
      -40
      >>> f2c(36)
      2
      >>> f2c(37)
      3
      >>> f2c(38)
      3
      >>> f2c(39)
      4
    """
    return int(round((t - 32.0) * 5.0/9))

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

第 5 章 - 解决方案 9

[编辑 | 编辑源代码]
def c2f(t):
    """
      >>> c2f(0)
      32
      >>> c2f(100)
      212
      >>> c2f(-40)
      -40
      >>> c2f(12)
      54
      >>> c2f(18)
      64
      >>> c2f(-48)
      -54
    """
    return int(round((t * 9.0/5) + 32.0))

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

第 6 章

[编辑 | 编辑源代码]

第 6 章 - 解决方案 1

[编辑 | 编辑源代码]

$ cat ch0601.py

print '产生', '\n', '这个', '\n', '输出'


$ python ch0601.py

产生

这个

输出

第 6 章 - 解决方案 2

[编辑 | 编辑源代码]

$ cat ch0602.py

def sqrt(n)

   approx = n/2.0
   better = (approx + n/approx)/2.0
   while better != approx:
       print better
       approx = better
       better = (approx + n/approx)/2.0
   return approx

print sqrt(25)


$ python ch0602.py

7.25 5.34913793103 5.01139410653 5.00001295305 5.00000000002 5.0

第 6 章 - 解决方案 3

[编辑 | 编辑源代码]

def print_multiples(n, high)

   i = 1
   while i <= high:
       print n*i, '\t',
       i += 1
   print

def print_mult_table(high)

   i = 1
   while i <= high:
       print_multiples(i, high)
       i += 1

if __name__ == "__main__"

   high = input("Enter a number : ")
   print_mult_table(high)

第 6 章 - 解决方案 4

[编辑 | 编辑源代码]
def print_triangular_numbers(x):
   i = 1
   while i <= x:
       print i, '\t', i*(i+1)/2
       i += 1

第 6 章 - 解决方案 5 v1

[编辑 | 编辑源代码]
def is_prime(n):
    """
        >>> is_prime(2)
        True
        >>> is_prime(3)
        True
        >>> is_prime(4)
        False
        >>> is_prime(41)
        True
        >>> is_prime(42)
        False
    """
    count = 2
    #so counting starts at 2
    #as all numbers can be divided by 1 and remainder = 0; and because nothing can be divided by 0
    while count <= n:
        if n % count == 0 and count != n:
            #if when n divided by count remainder is 0
            #for example when 4 is divided by 2
            #and to make sure count != n because any number divided by itself then remainder = 0;
            #then return False
            return False
        #if above is not applicable then return true for doctest to pass
        elif count == n:
            return True
        #to make sure it doesnt exit after one try, and it counts
        elif n % count != 0:
            count = count + 1

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

第 6 章 - 解决方案 5 v2

[编辑 | 编辑源代码]
def is_prime(n):
    """
        >>> is_prime(2)
        True
        >>> is_prime(3)
        True
        >>> is_prime(4)
        False
        >>> is_prime(41)
        True
        >>> is_prime(42)
        False
    """
    count = 2
    while count <= n:
        if n % count == 0 and count != n:
            return False
        else:
            count = count + 1
    return True

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

第 6 章 - 解决方案 6 第 1 部分

[编辑 | 编辑源代码]

num_digits(0) 将返回什么?

def num_digits(n):
    """
        >>> num_digits(12345)
        5
        >>> num_digits(0)
        1
        >>> num_digits(-12345)
        5
    """
    count = 0
    while n != 0:
        count = count + 1
        n = n / 10
    return count

#num_digits(0) returns 0 because the while statement is not run,
#and therefore it returns count.

第 6 章 - 解决方案 6 第 2 部分

[编辑 | 编辑源代码]

修改它,使其在这种情况下返回 1。

def num_digits(n):
    """
        >>> num_digits(12345)
        5
        >>> num_digits(0)
        1
        >>> num_digits(-12345)
        5
    """
    if n == 0:
        return 1
    
#the program checks if n == 0. if it's 0, it simply returns 1.
#if not, count below is initialized, then, after the calculation, 
#count is returned with the final result

    count = 0
    while n != 0:
        count = count + 1
        n = n / 10
    return count

CH 6 - Solution 6 Part 3

[编辑 | 编辑源代码]

为什么调用 num_digits(-24) 会导致无限循环(提示:-1/10 等于 -1)?

>>> -24/10
-3
>>> -3/10
-1
>>> -1/10
-1
>>>

当 n = 0 时,循环将结束,根据上面的提示,-1/10 == -1,导致无限循环。

CH 6 - Solution 6 Part 4

[编辑 | 编辑源代码]
def num_digits(n):
    """
        >>> num_digits(12345)
        5
        >>> num_digits(0)
        1
        >>> num_digits(-12345)
        5
    """
#        >>> num_digits(-100)    #The code must be checked with this value for assurance
#        3
#        >>> num_digits(-9999)    #The code must be checked with this value for assurance
#        4

    count = 0
    if n == 0:
        return 1

    elif n < 0:
        n = -n
        while n:
            count = count + 1
            n = n/10
        return count

    else:
        while n:
            count = count + 1
            n = n/10
        return count

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

CH 6 - Solution 7

[编辑 | 编辑源代码]
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
    """
    count = 0
    while n != 0:
        digit = n % 2
        if digit == 0:
            count = count + 1
        n = n / 10
    return count

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

CH 6 - Solution 8

[编辑 | 编辑源代码]
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
    """
   def print_digits(n):
    new = []
    index = ' '
    number = str(n)
    for char in reversed(number):
        new.append(char)
    for w in new:
        index = index + w
    return int(index)

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

CH 6 - Solution 9

[编辑 | 编辑源代码]
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
    """
    sumof = 0
    while n != 0:
        sumof += (n % 10)**2
        n = n/10
    return sumof

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

第 7 章

[编辑 | 编辑源代码]

CH 7 - Question 1

[编辑 | 编辑源代码]

修改

prefixes = "JKLMNOPQ"
suffix = "ack"

for letter in prefixes:
    print letter + suffix

以便 Ouack 和 Quack 的拼写正确。

CH 7 - Notes regarding Question 1

[编辑 | 编辑源代码]

注意,for letter in prefixes: 是遍历的替代,例如

index = 0
while index < len(fruit):
    letter = fruit[index]
    print letter
    index += 1
#fruit = "banana"
#while index is less than 6.
#6 is the length of fruit
#letter = fruit[index]
#Since index = 0, "b" is equal to letter in loop 1
#letter is printed
#1 is added to whatever the value of index is
#the loop continues until index < 6

被替换为

for char in fruit:
    print char

CH 7 - Solution 1 v1

[编辑 | 编辑源代码]
prefixes = "JKLMNOPQ"
suffix = "ack"
 
for letter in prefixes:
    if letter == "O" or letter == "Q":
        print letter + "u" + suffix
    else:
        print letter + suffix

CH 7 - Solution 1 v2

[编辑 | 编辑源代码]
prefixes = "JKLMNOPQ"
suffix = "ack"
 
for letter in prefixes:
    if letter in "OQ":
        print letter + "u" + suffix
    else:
        print letter + suffix


CH 7 - Question 2

[编辑 | 编辑源代码]

封装

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

在一个名为 count_letters 的函数中,并将其泛化,使其接受字符串和字母作为参数。

CH 7 - Solution 2

[编辑 | 编辑源代码]
def count_letters(strng, letter):
\

=== CH 7 - Question 3===

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.

=== CH 7 - Solution 3===
<syntaxhighlight lang="python">
def find(strng, ch, start=0):
    index = start
    while index < len(strng):
        if strng[index] == ch:
            return index
        index += 1
    return -1

#for example strng = "banana"
#letter = "a"
#x = find(strng, letter, start) will return 1
#we need to modify count_letters so it returns 3
#the start variable can thus be used to our advantage
#the loop will end at the last letter of the string by returning -1

def count_letters(strng, letter, start=0):
    count = 0
    x = find(strng, letter, start)
    while x != -1:
        count += 1
        x = find(strng, letter, x + 1)
    return count

跟踪程序

#in our traceback, x = 1
#x = find(strng, letter, 2)
#x above will be assigned new value find(strng, letter, 2) 

>>> find("banana", "a", 1)
1
>>> find("banana", "a", 2)
3
>>> find("banana", "a", 4)
5
>>> find("banana", "a", 6)
-1
>>>

CH 7 - Solution 4

[编辑 | 编辑源代码]

关于 is_lower 的版本

def is_lower(ch):
    return string.find(string.lowercase, ch) != -1


def is_lower(ch):
    return ch in string.lowercase
  1. 这是最快的!
def is_lower(ch):
    return 'a' <= ch <= 'z'

CH 7 - Question 5

[编辑 | 编辑源代码]

创建一个名为 stringtools.py 的文件,并将以下内容放入其中

def reverse(s):
    """
      >>> reverse('happy')
      'yppah'
      >>> reverse('Python')
      'nohtyP'
      >>> reverse("")
      ''
      >>> reverse("P")
      'P'
    """

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

在 reverse 中添加函数体,使 doctests 通过。

CH 7 - Solution 5

[编辑 | 编辑源代码]
def reverse(s):
    """
      >>> reverse('happy')
      'yppah'
      >>> reverse('Python')
      'nohtyP'
      >>> reverse("")
      ''
      >>> reverse("P")
      'P'
    """

#we need to use len(s) to make it output letters
#length = len(happy) = 6
#print last = happy[length - 1] will return y
#we need to make it such that [length - 2] and so on
#we need the while loop to stop when length - x = 0
#if len(s) is 6

    x = 1
    while x <= len(s):
        length = len(s)
        lastoutput = s[length - x]
        print lastoutput,
        x += 1


#Why is x <= len(s)?
#because if x < len(s):
>>> reverse("happy")
y p p a
>>>
#with x<= len(s)
>>> reverse("happy")
y p p a h
>>>

现在为了使 doctest 通过,我们需要将我们的输出包含在字符串中。这里我们使用一个占位符字符串:lastoutput = ""。

其次,我们删除冗余代码

    x = 1
    while x <= len(s):
        length = len(s)
        lastoutput = s[length - x]

根据

length = len(fruit)
last = fruit[length-1]

使用负索引,例如

fruit[-1]

and

fruit[-2]

    x = 1
    while x <= len(s):
        lastoutput = s[-x]


def reverse(s):
    """
      >>> reverse('happy')
      'yppah'
      >>> reverse('Python')
      'nohtyP'
      >>> reverse("")
      ''
      >>> reverse("P")
      'P'
    """
    last = ""
    x = 1
    while x <= len(s):
        lastoutput = s[-x]
        last += lastoutput
        x += 1
    return last

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

CH 7 - Solution 6

[编辑 | 编辑源代码]
def reverse(s):
    last = ""
    x = 1
    while x <= len(s):
        lastoutput = s[-x]
        last += lastoutput
        x += 1
    return last

def mirror(s):
    """
      >>> mirror("good")
      'gooddoog'
      >>> mirror("yes")
      'yessey'
      >>> mirror('Python')
      'PythonnohtyP'
      >>> mirror("")
      ''
      >>> mirror("a")
      'aa'
    """
#we will be calling function reverse
#first we need it to ouput everything
    s_back = reverse(s)
    return s + s_back

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

CH 7 - Solution 7

[编辑 | 编辑源代码]
def reverse(s):
    last = ""
    x = 1
    while x <= len(s):
        lastoutput = s[-x]
        last += lastoutput
        x += 1
    return last

def mirror(s):
    out = reverse(s)
    out2 = reverse(out)
    return out2 + out

def remove_letter(letter, strng):
    """
      >>> remove_letter('a', 'apple')
      'pple'
      >>> remove_letter('a', 'banana')
      'bnn'
      >>> remove_letter('z', 'banana')
      'banana'
      >>> remove_letter('i', 'Mississippi')
      'Msssspp'
    """
    without_letter = ""
    for c in strng:
        if c not in letter:
            without_letter += c
    return without_letter
        

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

CH 7 - Solution 8

[编辑 | 编辑源代码]
def reverse(s):
    """
      >>> reverse('happy')
      'yppah'
      >>> reverse('Python')
      'nohtyP'
      >>> reverse("")
      ''
      >>> reverse("P")
      'P'
    """
    last = ""
    x = 1
    while x <= len(s):
        lastoutput = s[-x]
        last += lastoutput
        x += 1
    return last

def mirror(s):
    """
      >>> mirror("good")
      'gooddoog'
      >>> mirror("yes")
      'yessey'
      >>> mirror('Python')
      'PythonnohtyP'
      >>> mirror("")
      ''
      >>> mirror("a")
      'aa'
    """
    out = reverse(s)
    out2 = reverse(out)
    return out2 + out

def remove_letter(letter, strng):
    """
      >>> remove_letter('a', 'apple')
      'pple'
      >>> remove_letter('a', 'banana')
      'bnn'
      >>> remove_letter('z', 'banana')
      'banana'
      >>> remove_letter('i', 'Mississippi')
      'Msssspp'
    """
    without_letter = ""
    for c in strng:
        if c not in letter:
            without_letter += c
    return without_letter


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
    """
    half = len(s)/2
    fronthalf = s[:half]
    backhalf = s[-half:] #N.B no need to compare middle letter
    return fronthalf == reverse(backhalf)

    # We can make this even simpler by not bothering to split the word
    # into halves. Simplest solution is the single line:
    #     return s == reverse(s)
    # This will return True if word is the same forwards as backwards. 
    # Although might be slower for v. long words?



def count(sub, s):
    """
      >>> count('is', 'Mississippi')
      2
      >>> count('an', 'banana')
      2
      >>> count('ana', 'banana')
      2
      >>> count('nana', 'banana')
      1
      >>> count('nanan', 'banana')
      0
    """
    count = 0
    x = s.find(sub)
    while x != -1:
        count += 1
        x = s.find(sub, x + 1)
    return count

def remove(sub, s):
    """
      >>> remove('an', 'banana')
      'bana'
      >>> remove('cyc', 'bicycle')
      'bile'
      >>> remove('iss', 'Mississippi')
      'Missippi'
      >>> remove('egg', 'bicycle')
      'bicycle'
    """
    x = s.find(sub)
    if x != -1:
        out1 = s[:x]
        y = len(sub)
        out2 = s[x + y:]
        return out1 + out2
    else:
        return s

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'
    """
    while s.find(sub) != -1:
        s = remove(sub, s)
    return s
        
if __name__ == '__main__':
    import doctest
    doctest.testmod()

CH 7 - Solution 9

[编辑 | 编辑源代码]
>>> "%s %d %f" % (5, 5, 5)
'5 5 5.000000'
#note %f outputs 6 decimal places of 0s


>>> "%-.2f" % 3
'3.00'
#note .2 before f causes decimal output at 2 places (.00)


>>> "%-10.2f%-10.2f" % (7, 1.0/2)
'7.00      0.50      '
#note "The - after each % in the converstion specifications indicates left justification. 
#The numerical values specify the minimum length, 
#so %-13d is a left justified number at least 13 characters wide."
#Here if we count from index 0 @ 7 we will reach to index 10, before 
#the next string formatting operator


>>> print " $%5.2fn $%5.2fn $%5.2f" % (3, 4.5, 11.2)
 $ 3.00n $ 4.50n $11.20

CH 7 - Solution 10

[编辑 | 编辑源代码]
>>> "%s %s %s %s" % ('this', 'that', 'something')
Traceback (most recent call last):
  File "<pyshell#24>", line 1, in <module>
    "%s %s %s %s" % ('this', 'that', 'something')
TypeError: not enough arguments for format string


>>> "%s %s %s" % ('this', 'that', 'something')
'this that something'


>>> "%s %s %s" % ('yes', 'no', 'up', 'down')
Traceback (most recent call last):
  File "<pyshell#27>", line 1, in <module>
    "%s %s %s" % ('yes', 'no', 'up', 'down')
TypeError: not all arguments converted during string formatting


>>> "%s %s %s %s" % ('yes', 'no', 'up', 'down')
'yes no up down'


>>> "%d %f %f" % (3, 3, "three")
Traceback (most recent call last):
  File "<pyshell#29>", line 1, in <module>
    "%d %f %f" % (3, 3, "three")
TypeError: float argument required, not str


>>> "%d %f %f" % (3, 3, 3)
'3 3.000000 3.000000'

第 8 章

[编辑 | 编辑源代码]

CH 8 - Solution 4

[编辑 | 编辑源代码]

尚未完全完成,但...

<syntaxhighlight lang="python">
fruit = "banana"

def count_letters(array, n):
    count = 0
    for i in range(len(array)):
        m = array.find(n,i)
        if( i == m ):
            count += 1
    print(count)

count_letters(fruit,"a")

第 9 章

[编辑 | 编辑源代码]

CH 9 - 解决方案 1

[编辑 | 编辑源代码]
x = ['spam!', 1, ['Brie', 'Roquefort', 'Pol le Veq'], [1, 2, 3]]

for i in x:
    print len(i)


>>> 
5
Traceback (most recent call last):
  File "C:\Python26\ch9.py", line 5, in <module>
    print len(i)
TypeError: object of type 'int' has no len()
>>>


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

for i in x:
    print len(i)


>>> 
5
3
3
3
>>>

CH 9 - 解决方案 2

[编辑 | 编辑源代码]

CH 9 - 解决方案 2.1

[编辑 | 编辑源代码]
"""
  >>> a_list[3]
  42
  >>> a_list[6]
  'Ni!'
  >>> len(a_list)
  8
"""


a_list = [1, 2, 3, 42, 5, 6, 'Ni!', 8]


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

CH 9 - 解决方案 2.2

[编辑 | 编辑源代码]
"""
  >>> b_list[1:]
  ['Stills', 'Nash']
  >>> group = b_list + c_list
  >>> group[-1]
  'Young'
"""

b_list = ['Crosby', 'Stills', 'Nash'] 
c_list = ['Young']

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

CH 9 - 解决方案 2.3

[编辑 | 编辑源代码]
"""
  >>> '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
"""

mystery_list = ['peace', 'justice', 'equality']


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

CH 9 - 解决方案 2.4

[编辑 | 编辑源代码]
"""
  >>> range(a, b, c)
  [5, 9, 13, 17]
"""

a = 5
b = 18
c = 4


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

CH 9 - 解决方案 3

[编辑 | 编辑源代码]
>>> range(10, 0, -2)
[10, 8, 6, 4, 2]

如果 start 小于 stop 且 step 小于 0 会发生什么?

结果将是一个空列表。

编写一个关于 start、stop 和 step 之间关系的规则。

CH 9 - 解决方案 4

[编辑 | 编辑源代码]
>>> a = [1, 2, 3]
>>> b = a[:]
>>> id(a)
18484400
>>> id(b)
18594872
>>> b[0]
1
>>> b[0] = 5
>>> id(a)
18484400
>>> id(b)
18594872
>>> b
[5, 2, 3]
>>> a
[1, 2, 3]

CH 9 - 解决方案 5

[编辑 | 编辑源代码]
>>> this = ['I', 'am', 'not', 'a', 'crook']
>>> that = ['I', 'am', 'not', 'a', 'crook']
>>> print "Test 1: %s" % (id(this) == id(that))
Test 1: False
>>> that = this
>>> print "Test 2: %s" % (id(this) == id(that))
Test 2: True
>>>

CH 9 - 解决方案 6

[编辑 | 编辑源代码]

CH 9 - 解决方案 6.1

[编辑 | 编辑源代码]
"""
  >>> 13 in junk
  True
  >>> del junk[4]
  >>> junk
  [3, 7, 9, 10, 17, 21, 24, 27]
  >>> del junk[a:b]
  >>> junk
  [3, 7, 27]
"""

junk = [3, 7, 9, 10, 13, 17, 21, 24, 27]
a = 2
b = (len(junk) - 2)

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

CH 9 - 解决方案 6.2

[编辑 | 编辑源代码]
"""
  >>> nlist[2][1]
  0
  >>> nlist[0][2]
  17
  >>> nlist[1][1]
  5
"""

nlist = [[1, 2, 17], [4, 5, 6], [7, 0, 9]]

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

CH 9 - 解决方案 6.3

[编辑 | 编辑源代码]
"""
  >>> import string
  >>> string.split(message, '??')
  ['this', 'and', 'that']
"""

message = "this??and??that"

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

CH 9 - 解决方案 7

[编辑 | 编辑源代码]
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]
    """
    
    new_list = []
    for index, value in enumerate(u):
        for index2, value2 in enumerate(v):
            if index == index2:
                new_list += [value + value2]
    return new_list

    #However, a less complex solution follows:
    new_list = []
    for index, value in enumerate(u):
        new_list += [u[index] + z[index]]
    return new_list

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

CH 9 - 解决方案 8

[编辑 | 编辑源代码]
def mult_lists(a, b):
    """
      >>> mult_lists([1, 1], [1, 1])
      2
      >>> mult_lists([1, 2], [1, 4])
      9
      >>> mult_lists([1, 2, 1], [1, 4, 3])
      12
    """
    sm = 0
    new_list = []
    for x, elmt1 in enumerate(a):
        for y, elmt2 in enumerate(b):
            if x == y:
                new_list += [elmt1 * elmt2]
    q = len(new_list) - 1
    while q != -1:
        sm += new_list[q]
        q += -1
    return sm

if __name__ == '__main__':
    import doctest
    doctest.testmod()
#Simpler Code
#new_list = []
#for index, value in enumerate(b):
#new_list += [a*value]
#return new_list

CH 9 - 解决方案 9

[编辑 | 编辑源代码]

CH 9 - 解决方案 9.1

[编辑 | 编辑源代码]
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]]
    """
    y = len(matrix[0])

    matrix2 = matrix[:]
    for z in range(1):
        matrix2 += [[0] * y]
    return matrix2

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

CH 9 - 解决方案 9.2

[编辑 | 编辑源代码]
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)
      [[3, 2, 0], [5, 1, 0], [4, 7, 0]]
      >>> n
      [[3, 2], [5, 1], [4, 7]]
    """
    x = len(matrix)

    matrix2 = [d[:] for d in matrix]
    for z in range(x):
        matrix2[z] += [0]
    return matrix2
      
if __name__ == '__main__':
    import doctest
    doctest.testmod()

CH 9 - 解决方案 10

[编辑 | 编辑源代码]
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]]
   """

    new_matrix = []
    for i, row in enumerate(m1):
        new_row = []        
        for j, m1_value in enumerate(row):
            m2_value = m2[i][j]
            new_row += [m1_value + m2[i][j]]
        new_matrix += [new_row]
    return new_matrix
      
if __name__ == '__main__':
    import doctest
    doctest.testmod()

CH 9 - 解决方案 11

[编辑 | 编辑源代码]
def scalar_mult(n, m):
    """
      >>> a = [[1, 2], [3, 4]]
      >>> 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]]
    """

    new_matrix = []
    for row in m:
        new_row = []        
        for value in row:
            new_row += [value*n]
        new_matrix += [new_row]
    return new_matrix    

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

CH 9 - 解决方案 12

[编辑 | 编辑源代码]
# Once we have obtained lists for the relevant rows and columns
# in row_times_column function, we will re-use the mult_lists
# function from question 8:

def mult_lists(a, b):
    sum = 0
    for i, a_value in enumerate(a):
        sum += a_value * b[i]
    return sum


def row_times_column(m1, row, m2, column):
    """
      >>> 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
    """
    m1_row = m1[row]
    m2_col = []
    for m2_row in m2:
        m2_col += [m2_row[column]]
    return mult_lists(m1_row, m2_col)

#This code may also be used to bypass the mult_lists code

def row_times_column(m1, row, m2, column):
	x = 0
	y = 0
	for a in m1[row]:
		t = a * m2[x][column]
		y += t
		x += 1
	return y

def matrix_mult(m1, m2):
   """
      >>> matrix_mult([[1, 2], [3,  4]], [[5, 6], [7, 8]])
      [[19, 22], [43, 50]]
      >>> matrix_mult([[1, 2, 3], [4,  5, 6]], [[7, 8], [9, 1], [2, 3]])
      [[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]]
    """

#To pass these tests, the function needs to multiply each each m1 row
#by each m2 column, to produce a new matrix with with the same number
#of rows as m1, and the same number of columns as m2. (This is the way
#matrices are commonly multiplied in mathematics). We can use
#row_times_column for each row/column combination

   m1_num_rows = len(m1)
   m2_num_cols = len(m2[0])
   product_matrix = []
   for row in range(m1_num_rows): 
       new_row = []
       for column in range(m2_num_cols):
           new_row += [row_times_column(m1, row, m2, column)]
       product_matrix += [new_row]
   return product_matrix


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

CH 9 - 解决方案 13

[编辑 | 编辑源代码]

第 9 章 - 解答 14

[编辑 | 编辑源代码]
import string

def replace(s, old, new):
    """
      >>> 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!'
    """
    s_without_old = string.split(s, old)
    s_with_new = string.join(s_without_old, new)
    return s_with_new

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

你也可以做

def myreplace(s, old, new):
    """
      >>> myreplace('Mississippi', 'i', 'I')
      'MIssIssIppI'
      >>> s = 'I love spom!  Spom is my favorite food.  Spom, spom, spom, yum!'
      >>> myreplace(s, 'om', 'am')
      'I love spam!  Spam is my favorite food.  Spam, spam, spam, yum!'
      >>> myreplace(s, 'o', 'a')
      'I lave spam!  Spam is my favarite faad.  Spam, spam, spam, yum!'
    """
    new_string = ""
    counter = 0
    while counter<len(s): 
        
        # check if old equals a slice of len(old)

        if old == s[counter:counter+len(old)]:
            new_string += new #s[counter+len(old):]
            counter+=len(old)
        else:
            new_string += s[counter]
            counter += 1
    return new_string

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

第 10 章

[编辑 | 编辑源代码]

第 10 章 - 解答 1

[编辑 | 编辑源代码]

第 10 章 - 解答 1.1

[编辑 | 编辑源代码]
>>> import calendar
>>> year = calendar.calendar(2008)
>>> print year
                                  2008

      January                   February                   March
Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
    1  2  3  4  5  6                   1  2  3                      1  2
 7  8  9 10 11 12 13       4  5  6  7  8  9 10       3  4  5  6  7  8  9
14 15 16 17 18 19 20      11 12 13 14 15 16 17      10 11 12 13 14 15 16
21 22 23 24 25 26 27      18 19 20 21 22 23 24      17 18 19 20 21 22 23
28 29 30 31               25 26 27 28 29            24 25 26 27 28 29 30
                                                    31

       April                      May                       June
Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
    1  2  3  4  5  6                1  2  3  4                         1
 7  8  9 10 11 12 13       5  6  7  8  9 10 11       2  3  4  5  6  7  8
14 15 16 17 18 19 20      12 13 14 15 16 17 18       9 10 11 12 13 14 15
21 22 23 24 25 26 27      19 20 21 22 23 24 25      16 17 18 19 20 21 22
28 29 30                  26 27 28 29 30 31         23 24 25 26 27 28 29
                                                    30

        July                     August                  September
Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
    1  2  3  4  5  6                   1  2  3       1  2  3  4  5  6  7
 7  8  9 10 11 12 13       4  5  6  7  8  9 10       8  9 10 11 12 13 14
14 15 16 17 18 19 20      11 12 13 14 15 16 17      15 16 17 18 19 20 21
21 22 23 24 25 26 27      18 19 20 21 22 23 24      22 23 24 25 26 27 28
28 29 30 31               25 26 27 28 29 30 31      29 30

      October                   November                  December
Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
       1  2  3  4  5                      1  2       1  2  3  4  5  6  7
 6  7  8  9 10 11 12       3  4  5  6  7  8  9       8  9 10 11 12 13 14
13 14 15 16 17 18 19      10 11 12 13 14 15 16      15 16 17 18 19 20 21
20 21 22 23 24 25 26      17 18 19 20 21 22 23      22 23 24 25 26 27 28
27 28 29 30 31            24 25 26 27 28 29 30      29 30 31

>>>


第 10 章 - 解答 1.2

[编辑 | 编辑源代码]

isleap(year) - 返回闰年为 1,非闰年为 0。


>>> from calendar import *
>>> isleap(2008)
True
>>> isleap(2009)
False
>>>

第 10 章 - 解答 2

[编辑 | 编辑源代码]

第 10 章 - 解答 2.1

[编辑 | 编辑源代码]
 python C:\Python26\Lib\pydoc.py -p 7464 

第 10 章 - 解答 2.2

[编辑 | 编辑源代码]

math 模块中有 35 个函数。

第 10 章 - 解答 2.3

[编辑 | 编辑源代码]

floor 函数找到小于或等于 x 的最大整数。ceil 函数找到大于或等于 x 的最小整数。

第 10 章 - 解答 2.4

[编辑 | 编辑源代码]

第 10 章 - 解答 2.5

[编辑 | 编辑源代码]

math 模块中的两个数据常量是:'e' 和 'pi'。

第 10 章 - 解答 3

[编辑 | 编辑源代码]
"""
Interface summary:

        import copy

        x = copy.copy(y)        # make a shallow copy of y
        x = copy.deepcopy(y)    # make a deep copy of y

For module specific errors, copy.Error is raised.

The difference between shallow and deep copying is only relevant for
compound objects (objects that contain other objects, like lists or
class instances).

- A shallow copy constructs a new compound object and then (to the
  extent possible) inserts *the same objects* into it that the
  original contains.

- A deep copy constructs a new compound object and then, recursively,
  inserts *copies* into it of the objects found in the original."""

deepcopy 在你不需要解决的关于对象引用的练习中会派上用场,因此这里不需要答案。

第 10 章 - 解答 4

[编辑 | 编辑源代码]

第 10 章 - 解答 5

[编辑 | 编辑源代码]

第 10 章 - 解答 6

[编辑 | 编辑源代码]

命名空间是一个很棒的想法——我们应该多做一些!

第 10 章 - 解答 7

[编辑 | 编辑源代码]

第 10 章 - 解答 8

[编辑 | 编辑源代码]

def matrix_mult(m1, m2)

  """
     >>> matrix_mult([[1, 2], [3,  4]], [[5, 6], [7, 8]])
     [[19, 22], [43, 50]]
     >>> matrix_mult([[1, 2, 3], [4,  5, 6]], [[7, 8], [9, 1], [2, 3]])
     [[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]]
   """
  
  qr = len(m1)
  qc = len(m2[0])
  NewMtx = []
  for row in range(qr):
      newRow = []
      for column in range(qc):
          newRow.append(row_times_column(m1, row, m2, column))
      NewMtx.append(newRow)
  return NewMtx

return NewMtx

     qr = len(m1)
  qc = len(m2[0])
  NewMtx = []
  for row in range(qr):
      newRow = []
      for column in range(qc):
          newRow.append(row_times_column(m1, row, m2, column))
      NewMtx.append(newRow)

第 10 章 - 解答 9

[编辑 | 编辑源代码]

第 10 章 - 解答 10

[编辑 | 编辑源代码]
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.'
      
    """
    old_removed = s.split(old)
    new_added = new.join(old_removed)
    return new_added
# Shorter version
#    new_added = new.join(s.split(old))

第 10 章 - 解答 11

[编辑 | 编辑源代码]
def cleanword(word):
    """
      >>> cleanword('what?')
      'what'
      >>> cleanword('"now!"')
      'now'
      >>> cleanword('?+="word!,@$()"')
      'word'
    """
    cleaned_word = ''
    for i in range(len(word)):
        char = word[i]
        if char.isalpha():
            cleaned_word += char
    return cleaned_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
    """
    return s.find('--') != -1


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']
    """
    if has_dashdash(s):
        s = myreplace('--', ' ', s) #using myreplace function from Q. 10
    words_punc = s.split()
    cleanlist = []
    for word in words_punc:
        cleanedword = cleanword(word).lower()
        cleanlist.append(cleanedword)
    return cleanlist
        
        
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]
    """

    return [word, wordlist.count(word)]


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']
    """

    for word in wordlist:
        count = wordcount(word, wordlist)[1]
        if count > 1:
            for a in range(count - 1):
                wordlist.remove(word)
    wordlist.sort()
    return wordlist
            

def longestword(wordset):
    """
      >>> longestword(['a', 'apple', 'pear', 'grape'])
      5
      >>> longestword(['a', 'am', 'I', 'be'])
      2
      >>> longestword(['this', 'that', 'supercalifragilisticexpialidocious'])
      34
    """
    longest = 0
    for word in wordset:
        length = len(word)
        if length > longest:
            longest = length
    return longest


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

第 10 章 - 解答 12

[编辑 | 编辑源代码]
#sort_fruits.py

source = open('unsorted_fruits.txt', 'r')
fruits = source.readlines()
source.close()
fruits.sort()
newfile = open('sorted_fruits.txt', 'w')
newfile.writelines(fruits)
newfile.close()

第 10 章 - 解答 13

[编辑 | 编辑源代码]

第 10 章 - 解答 14

[编辑 | 编辑源代码]
#mean.py

from sys import argv

nums = argv[1:]

for i, value in enumerate(nums):
    nums[i] = float(value)

mean = sum(nums) / len(nums)

print mean

第 10 章 - 解答 15

[编辑 | 编辑源代码]
#median.py

from sys import argv
nums = argv[1:]

for i, value in enumerate(nums):
    nums[i] = float(value)

nums.sort()
size = len(nums)
middle = size / 2

if size % 2 == 0:
    median = (nums[middle - 1] + nums[middle]) / 2
else:
    median = nums[middle]

if median == float(int(median)):
    median = int(median)

print median

第 10 章 - 解答 16

[编辑 | 编辑源代码]
#
# countletters.py
#

def display(i):
    if i == 10: return 'LF'
    if i == 13: return 'CR'
    if i == 32: return 'SPACE'
    return chr(i)

from sys import argv

filename = argv[1]

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

counts = 128 * [0]

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

filenamesplit = filename.split('.') # splits 'name.txt' -> ['name', 'txt']
count_file = filenamesplit[0] + '_counts.dat' # 'name' -> 'name_counts.dat'

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

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

outfile.close()

第 11 章

[编辑 | 编辑源代码]

第 11 章 - 解答 1

[编辑 | 编辑源代码]

第 11 章 - 解答 2

[编辑 | 编辑源代码]

第 11 章 - 解答 3

[编辑 | 编辑源代码]
#
#seqtools.py
#

def remove_at(pos, seq):
    return seq[:pos] + seq[pos+1:]


def encapsulate(val, seq):
    """
      >>> encapsulate((1, 'a'), [0 , 'b'])
      [(1, 'a')]
      >>> encapsulate(42, 'string')
      '42'
      >>> tup = 1, 2, 3                   # NB. Testmod seems to report this
      >>> encapsulate(5, tup)             # as a fail, despite returning the
      (5,)                                # correct result?
    """

    if type(seq) == type(""):
        return str(val)
    if type(seq) == type([]):
        return [val]
    return (val,)


def insert_in_middle(val, seq):
    """
      >>> insert_in_middle('two', (1,3))
      (1, 'two', 3)
      >>> insert_in_middle(4, 'two  six')
      'two 4 six'
      >>> insert_in_middle((2, 4), [(1, 2), (3, 6)])
      [(1, 2), (2, 4), (3, 6)]
    """
    middle = len(seq)/2
    return seq[:middle] + encapsulate(val, seq) + seq[middle:]
    

def make_empty(seq):
    """
      >>> make_empty([1, 2, 3, 4])
      []
      >>> make_empty(('a', 'b', 'c'))
      ()
      >>> make_empty("No, not me!")
      ''
    """
    if type(seq) == type(""):
        return ''
    if type(seq) == type([]):
        return []
    return ()


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)) # NB. Testmod seems to report this as a fail
      (1, 3, 4, 6, 5)                    # despite returning the correct result
    """
    return seq + encapsulate(val, seq)
    

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'
    """
    return encapsulate(val, seq) + seq


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
      >>> 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
    """
    for i in range(start, len(seq)):
        if seq[i] == val:
            return i
    return -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'
    """
    return seq[:index] + seq[index + 1:]


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')
    """
    return remove_at(index_of(val, seq), seq)


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'
    """
    while index_of(val, seq) != -1:
        seq = remove_val(val, seq)
    return seq
    

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
    """
    count = 0
    for item in seq:
        if item == val:
            count += 1
    return count


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'
    """
    output = make_empty(seq)
    for item in seq:
        output = insert_in_front(item, output)
    return output
    
    

def sort_sequence(seq):
    """
      >>> 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'
    """
    listseq = list(seq)
    listseq.sort()
    output = make_empty(seq)
    for item in listseq:
        output = insert_at_end(item, output)
    return output


第 11 章 - 解答 4

[编辑 | 编辑源代码]
def recursive_min(nested_num_list):
    """
      >>> 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
    """
    smallest = nested_num_list[0]
    while type(smallest) == type([]):
        smallest = smallest[0]

    for element in nested_num_list:
        if type(element) == type([]):
            min_of_elem = recursive_min(element)
            if smallest > min_of_elem:
                smallest = min_of_elem
        else:
            if smallest > element:
                smallest = element
                
    return smallest

第 11 章 - 解答 5

[编辑 | 编辑源代码]
def recursive_count(target, nested_num_list):
    """
      >>> 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
    """
    count = 0
    
    for element in nested_num_list:
        if type(element) == type([]):
            count += recursive_count(target, element)
        else:
            if element == target:
                count += 1
                
    return count

第 11 章 - 解答 6

[编辑 | 编辑源代码]
def flatten(nested_num_list):
    """
      >>> 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]
    """
    flat_num_list = []
    
    for element in nested_num_list:
        if type(element) == type([]):
            flat_num_list += flatten(element)
        else:
            flat_num_list += [element]
            
    return flat_num_list

第 11 章 - 解答 7

[编辑 | 编辑源代码]
def readposint(prompt = 'Please enter a positive integer: '):
    while True:
        posint = raw_input(prompt)
        try:
            posint = float(posint)
            if posint != int(posint):
                raise ValueError, '%s is not an integer' % posint
            elif posint < 1:
                raise ValueError, '%s is not positive' % posint
            break
        except:
            print '%s is not a positive integer. Try again.' % posint
            
    return int(posint)

第 11 章 - 解答 8

[编辑 | 编辑源代码]

第 11 章 - 解答 9

[编辑 | 编辑源代码]

第 11 章 - 解答 10

[编辑 | 编辑源代码]
def factorial(n):
    nshriek = 1       # n factorial is sometimes called 
    while n > 1:      # 'n shriek' because of the 'n!' notation
        nshriek *= n
        n -= 1
    return nshriek

第 11 章 - 解答 11

[编辑 | 编辑源代码]
#
# litter.py
#

import os
import sys


def getroot():
    if len(sys.argv) == 1:
        path = ''
    else:
        path = sys.argv[1]

    if os.path.isabs(path):
        tree_root = path
    else:
        tree_root = os.path.join(os.getcwd(), path)

    return tree_root


def getdirlist(path):
    dirlist = os.listdir(path)
    dirlist = [name for name in dirlist if name[0] != '.']
    dirlist.sort()
    return dirlist


def traverse(path, t=0):
    dirlist = getdirlist(path)

    for num, file in enumerate(dirlist):
        dirsize = len(dirlist)

        path2file = os.path.join(path, file)

        if os.path.isdir(path2file):
            t += 1
            newtrash = open(path2file + '\\trash.txt', 'w')
            newtrash.close()
            
            if getdirlist(path2file):
                t = traverse(path2file, t)

    return t


if __name__ == '__main__':
    root =  getroot()
    trashes = traverse(root)

    if trashes == 1:
        filestring = 'file'
    else:
        filestring = 'files'

    print '%d trash.txt %s created' % (trashes, filestring)
#
# cleanup.py
#

import os
import sys


def getroot():
    if len(sys.argv) == 1:
        path = ''
    else:
        path = sys.argv[1]

    if os.path.isabs(path):
        tree_root = path
    else:
        tree_root = os.path.join(os.getcwd(), path)

    return tree_root


def getdirlist(path):
    dirlist = os.listdir(path)
    dirlist = [name for name in dirlist if name[0] != '.']
    dirlist.sort()
    return dirlist


def traverse(path, t = 0):
    dirlist = getdirlist(path)

    for num, file in enumerate(dirlist):
        dirsize = len(dirlist)
        path2file = os.path.join(path, file)
        
        if file == 'trash.txt':
            t += 1
            os.remove(path2file)
            
        elif os.path.isdir(path2file):
            t += traverse(path2file)

    return t


if __name__ == '__main__':
    root =  getroot()
    trashed = traverse(root)

    if trashed == 1:
        filestring = 'file'
    else:
        filestring = 'files'

    print '%d trash.txt %s deleted' % (trashed, filestring)

第 12 章

[编辑 | 编辑源代码]

第 12 章 解答 1

[编辑 | 编辑源代码]
#
# letter_counts.py
#

import sys

def count_letters(s):
    letter_counts = {}
    for letter in s:
        if letter.isalpha():
            letter_counts[letter.lower()] = letter_counts.get(letter.lower(), 0) + 1
    return letter_counts

def print_counts(letter_counts):
    letter_items = letter_counts.items()
    letter_items.sort()
    for item in letter_items:
        print item[0], item[1]

if len(sys.argv) > 1:
    letter_counts = count_letters(sys.argv[1])
    print_counts(letter_counts)
else: 
    print 'No argument supplied'

第 12 章 解答 2

[编辑 | 编辑源代码]
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']
       35
     """
     if inventory.has_key(fruit):
         inventory[fruit] += quantity
     else:
         inventory[fruit] = quantity

第 12 章 解答 3

[编辑 | 编辑源代码]
#
# alice_words.py
#

import string

filename = 'alice_in_wonderland.txt'
countfile = 'alice_counts.txt'

def add_word(counts, word):
    if counts.has_key(word):
        counts[word] += 1
    else:
        counts[word] = 1

def get_word(item):  
    word = ''
    item = item.strip(string.digits)
    item = item.lstrip(string.punctuation)
    item = item.rstrip(string.punctuation)
    word = item.lower()
    return word
        

def count_words(text):
    text = ' '.join(text.split('--')) #replace '--' with a space
    items = text.split() #leaves in leading and trailing punctuation,
                         #'--' not recognised by split() as a word separator
    counts = {}
    for item in items:
        word = get_word(item)
        if not word == '':
            add_word(counts, word)
    return counts

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

counts = count_words(text)

outfile = open(countfile, 'w')
outfile.write("%-18s%s\n" %("Word", "Count"))
outfile.write("=======================\n")

counts_list = counts.items()
counts_list.sort()
for word in counts_list:
    outfile.write("%-18s%d\n" %(word[0], word[1]))

outfile.close

单词 "alice" 出现了 386 次(不包括 12 次 "alice's")

第 12 章 解答 4

[编辑 | 编辑源代码]

列表中最长的 "单词" 是 "bread-and-butter",有 16 个字符。可以通过将以下代码添加到 alice_words.py 程序中来找到它

longest = ('', 0)
for word in counts:
    if len(word) > longest[1]:
        longest = (word, len(word))
print longest

稍微修改一下,我们可以找到最长的无连字符的单词 "disappointment",它有 14 个字符。

longest = ('', 0)
for word in counts:
    if len(word) > longest[1] and word.find('-') == -1
        longest = (word, len(word))
print longest

第 12 章 解答 5

[编辑 | 编辑源代码]

第 12 章 解答 6

[编辑 | 编辑源代码]

第 12 章 解答 7

[编辑 | 编辑源代码]

第 12 章 解答 8

[编辑 | 编辑源代码]

第 12 章 解答 9

[编辑 | 编辑源代码]

第 12 章 解答 10

[编辑 | 编辑源代码]

第 12 章 解答 11

[编辑 | 编辑源代码]

第 12 章 解答 12

[编辑 | 编辑源代码]

第 13 章

[编辑 | 编辑源代码]
  1. 日期: 2015-5-3
  2. 作者: [email protected]
  3. 此程序将反转任何给定文件的行

for line in reversed(open('test.txt').readlines()):

   print(line.rstrip())

第 13 章 解答 2

[编辑 | 编辑源代码]
def distance(p1, p2):
    dx = p2.x - p1.x
    dy = p2.y - p1.y
    dsquared = dx**2 + dy**2
    result = dsquared**0.5
    return result

第 13 章 解答 3

[编辑 | 编辑源代码]
def move_rect(rect, dx, dy):
    rect.corner.x += dx
    rect.corner.y += dy

第 13 章 解答 4

[编辑 | 编辑源代码]
def move_rect(rect, dx, dy):
    import copy
    new_rect = copy.deepcopy(rect)
    new_rect.corner.x += dx
    new_rect.corner.y += dy
    return new_rect

第 14 章

[编辑 | 编辑源代码]

第 14 章 解答 1

[编辑 | 编辑源代码]
def print_time(t):
    print "%i:%i:%i" % (t.hours, t.minutes, t.seconds)

第 14 章 解答 2

[编辑 | 编辑源代码]
def after(t1, t2):
    return convert_to_seconds(t1) > convert_to_seconds(t2)

第 14 章 解答 3

[编辑 | 编辑源代码]
def increment(time, seconds):
    sum = convert_to_seconds(time) + seconds
    newtime = make_time(sum)
    time.hours = newtime.hours
    time.minutes = newtime.minutes
    time.seconds = newtime.seconds

>>> increment(t1, 180)

第 14 章 解答 4

[编辑 | 编辑源代码]
def increment(time, seconds):
    sum = convert_to_seconds(time) + seconds
    newtime = make_time(sum)
    return newtime

>>> increment(t1, 180)
<__main__.Time instance at 0x91ceeac>

>>> t1 = increment(t1, 180)

第 15 章

[编辑 | 编辑源代码]

第 15 章 解答 1

[编辑 | 编辑源代码]
class Time():

# other method definitions here

    def convertToSeconds(self):
        minutes = self.hours * 60 + self.minutes
        seconds = minutes * 60 + self.seconds
        return seconds

第 15 章 解答 2

[编辑 | 编辑源代码]
def find(str, ch, start=0, end = "None"):
    index = start
    if end == "None":
        end = len(str)
    while index < end:
        if str[index] == ch:
            return index
        index = index + 1
    return -1

第 16 章

[编辑 | 编辑源代码]

第 16 章 解答 1

[编辑 | 编辑源代码]
class Card:
...
    def __cmp__(self, other):
        # check the suits
        if self.suit > other.suit: return 1
        if self.suit < other.suit: return -1
        # suits are the same... check ranks
        if self.rank > other.rank:
            if other.rank == 1: return -1 #other is Ace (and self is not)
            return 1
        if self.rank < other.rank:
            if self.rank == 1: return 1 #self is Ace (and other is not)
            return -1
        # ranks are the same... it's a tie
        return 0

第 17 章

[编辑 | 编辑源代码]

第 17 章 解答 1

[编辑 | 编辑源代码]
class OldMaidGame(CardGame):
...
    def printHands(self):
        for hand in self.hands:
            print hand

第 18 章

[编辑 | 编辑源代码]

第 18 章 解答 1

[编辑 | 编辑源代码]
def print_list(node):
    s = '['
    while node:
        s += str(node.cargo)
        node = node.next
        if node:
            s += ', '
    s += ']'
    print s

第 19 章

[编辑 | 编辑源代码]

第 19 章 解答 1

[编辑 | 编辑源代码]
>>> print eval_postfix("1 2 + 3 *")
9

第 19 章 解答 2

[编辑 | 编辑源代码]
>>> print eval_postfix("1 2 3 * +")
7

第 20 章

[编辑 | 编辑源代码]
class listQueue:
    def __init__(self):
        self.items = []

    def is_empty(self):
        return self.items == []

    def insert(self, item):
        self.items.append(item)

    def remove(self):
        if self.is_empty():
            return None
        return self.items.pop()
class llPriorityQueue:
    def __init__(self):  # NB, self.last is no longer needed because
        self.length = 0  # the linked list will be ordered with
        self.head = None # the next item to be removed at the head

    def is_empty(self):
        return (self.length == 0)

    def insert(self, cargo):   # insert() needs to keep the list ordered to
        node = Node(cargo)     # make remove() constant time. So insert()
        if self.head == None:  # must traverse the list. Now insert() is
            self.head = node   # linear time instead of remove()!
        else:
            if cargo > self.head.cargo:
                node.next = self.head
                self.head = node
            else:
                smaller = self.head          
                while smaller.cargo >= cargo:# traverse queue until we 
                    previous = smaller       # find first node with cargo
                    smaller = smaller.next   # smaller than the new node
                    if smaller == None:      #<--(or we get to the end
                        break                #    of the list)
                previous.next = node         # insert node ahead of first
                node.next = smaller          # smaller item
        self.length += 1

    def remove(self):
        if self.is_empty():
            return None
        cargo = self.head.cargo
        self.head = self.head.next
        self.length = self.length - 1
        return cargo

第 21 章

[编辑 | 编辑源代码]

第 21 章 解答 1

[编辑 | 编辑源代码]
def print_tree_inorder(tree):
    if tree == None: return
    if tree.left:
        print '(',
    print_tree_inorder(tree.left),
    print tree.cargo,
    print_tree_inorder(tree.right),
    if tree.right:
        print ')',

# The output from this function is correct and unambiguous, but many 
# brackets are not really necessary and look messy. For example:
>>> token_list =['(',3, '+', 7, ')', '*', '(', 5, '+', 3, ')', '+', 4, '*', 5, 'end']
>>> tree = get_sum(token_list)
>>> print_tree_inorder(tree)
( ( ( 3 + 7 ) * ( 5 + 3 ) ) + ( 4 * 5 ) )
# The ideal output would be something like: (3 + 7) * (5 + 3) + 4 * 5

第 21 章 解答 2

[编辑 | 编辑源代码]
def make_token_list(s):
    token_list = []
    for char in s:
        if char == ' ':
            continue
        elif char.isdigit():
            token_list.append(int(char))
        else:
            token_list.append(char)
    token_list.append('end')
    return token_list

第 21 章 解答 3

[编辑 | 编辑源代码]

第 21 章 解答 4

[编辑 | 编辑源代码]
# ... (only modified functions shown)

def dump(tree):                  
    # returns string representation of tree in postfix-style
    # order with commas separating nodes. Leaves are
    # represented with two preceding commas, corresponding to
    # the empty tree.left & tree.right attributes.
    if tree == None: return ','  
    s = ''                       
    s += dump(tree.left)        
    s += dump(tree.right)
    s += str(tree) + ','   
    return s

def restore_tree(token_list):
    # Recreate tree from token list generated from save file
    cargo = token_list.pop()
    if cargo == '': return
    right = restore_tree(token_list)
    left = restore_tree(token_list)
    tree = Tree(cargo, left, right)
    return tree

def animal():
    #start with a singleton
    root = Tree("bird")

    # or use save file if it exists
    try:
        infile = open(savefile, 'r')
        s = infile.read()
        infile.close()
        token_list = s.split(',')
        token_list.pop() #remove empty item at end
        root = restore_tree(token_list)
    except IOError: 
        pass
    
    # loop until the user quits
    while True:
        print
        if not yes("Are you thinking of an animal? "): break

        # walk the tree
        tree = root
        while tree.left != None:
            prompt = tree.cargo + "? "
            if yes(prompt):
                tree = tree.right
            else:
                tree = tree.left

        # make a guess
        guess = tree.cargo
        prompt = "Is it a " + guess + "? "
        if yes(prompt):
            print "Yatta!"
            continue

        # get new information
        prompt  = "What is the animal's name? "
        animal  = raw_input(prompt)
        prompt  = "What question would distinguish a %s from a %s? "
        question = raw_input(prompt % (animal, guess)).strip('?').capitalize()

        # add new information to the tree
        tree.cargo = question
        prompt = "If the animal were %s the answer would be? "
        if yes(prompt % animal):
            tree.left = Tree(guess)
            tree.right = Tree(animal)
        else:
            tree.left = Tree(animal)
            tree.right = Tree(guess)

    # save the tree
    s = dump(root)
    outfile = open(savefile, 'w')
    outfile.write(s)
    outfile.close()
华夏公益教科书