上篇介绍到14行的文档测试,本文接着将剩余代码看完。(下面代码有些经过更改,不要太纠结行数)
15行:迭代工具(itertools)
代码:
from itertools import groupby
lines = '''
This is the
first paragraph.
This is the second.
'''.splitlines()
# Use itertools.groupby and bool to return groups of
# consecutive lines that either have content or don't.
for has_chars, frags in groupby(lines, bool):
if has_chars:
print (' '.join(frags))
# PRINTS:
# This is the first paragraph.
# This is the second.
运行结果:
This is the first paragraph.
This is the second.
16行:读写cvs文件。(现在是25行代码了,也许之前版本是16行)
代码:
import csv
# need to define cmp function in Python 3
def cmp(a, b):
return (a > b) - (a < b)
# write stocks data as comma-separated values
with open('stocks.csv', 'w', newline='') as stocksFileW:
writer = csv.writer(stocksFileW)
writer.writerows([
['GOOG', 'Google, Inc.', 505.24, 0.47, 0.09],
['YHOO', 'Yahoo! Inc.', 27.38, 0.33, 1.22],
['CNET', 'CNET Networks, Inc.', 8.62, -0.13, -1.4901]
])
# read stocks data, print status messages
with open('stocks.csv', 'r') as stocksFile:
stocks = csv.reader(stocksFile)
status_labels = {-1: 'down', 0: 'unchanged', 1: 'up'}
for ticker, name, price, change, pct in stocks:
status = status_labels[cmp(float(change), 0.0)]
print('%s is %s (%.2f)' % (name, status, float(pct)))
18行:八皇后问题(递归),递归式一种写函数的方法,后面会讲到。
代码:
BOARD_SIZE = 8
def under_attack(col, queens):
left = right = col
for r, c in reversed(queens):
left, right = left - 1, right + 1
if c in (left, col, right):
return True
return False
def solve(n):
if n == 0:
return [[]]
smaller_solutions = solve(n - 1)
return [solution + [(n, i + 1)]
for i in range(BOARD_SIZE)
for solution in smaller_solutions
if not under_attack(i + 1, solution)]
for answer in solve(BOARD_SIZE):
print(answer)
20.质数生成器 生成器(generator)是一种惰性的数据产生器,通常每次调用只会生成一个数据。
代码:
import itertools
def iter_primes():
# an iterator of all numbers between 2 and +infinity
numbers = itertools.count(2)
# generate primes forever
while True:
# get the first number from the iterator (always a prime)
prime = next(numbers)
yield prime
# this code iteratively builds up a chain of
# filters...slightly tricky, but ponder it a bit
numbers = filter(prime.__rmod__, numbers)
for p in iter_primes():
if p > 1000:
break
print (p)
21行:XML/HTML解析
代码:
dinner_recipe = '''<html><body><table>
<tr><th>amt</th><th>unit</th><th>item</th></tr>
<tr><td>24</td><td>slices</td><td>baguette</td></tr>
<tr><td>2+</td><td>tbsp</td><td>olive oil</td></tr>
<tr><td>1</td><td>cup</td><td>tomatoes</td></tr>
<tr><td>1</td><td>jar</td><td>pesto</td></tr>
</table></body></html>'''
# From http://effbot.org/zone/element-index.htm
import xml.etree.ElementTree as etree
tree = etree.fromstring(dinner_recipe)
# For invalid HTML use http://effbot.org/zone/element-soup.htm
# import ElementSoup, StringIO
# tree = ElementSoup.parse(StringIO.StringIO(dinner_recipe))
pantry = set(['olive oil', 'pesto'])
for ingredient in tree.getiterator('tr'):
amt, unit, item = ingredient
if item.tag == "td" and item.text not in pantry:
print ("%s: %s %s" % (item.text, amt.text, unit.text))
运行后报错,提示属性错误,没有该属性。
这也是运行Python程序时经常发生的,因为库的版本和代码的版本不一致,有些接口发生变化。一般复制错误去搜索都能找打解决方案。
根据找到的方法,将‘getiterator’修改为‘iter’:(在第18行)
for ingredient in tree.iter('tr'):
运行结果:
baguette: 24 slices
tomatoes: 1 cup
28行:八皇后问题。(自定义异常)
程序可能产生错误,可以通过定义异常来处理。
通过继承Exception异常类,自定义一个异常类。
代码:
BOARD_SIZE = 8
class BailOut(Exception):
pass
def validate(queens):
left = right = col = queens[-1]
for r in reversed(queens[:-1]):
left, right = left-1, right+1
if r in (left, col, right):
raise BailOut
def add_queen(queens):
for i in range(BOARD_SIZE):
test_queens = queens + [i]
try:
validate(test_queens)
if len(test_queens) == BOARD_SIZE:
return test_queens
else:
return add_queen(test_queens)
except BailOut:
pass
raise BailOut
queens = add_queen([])
print (queens)
print ("\n".join(". "*q + "Q " + ". "*(BOARD_SIZE-q-1) for q in queens))
运行结果:
33行:猜数游戏。通过random随机生成数字。
import random
guesses_made = 0
name = input('Hello! What is your name?\n')
number = random.randint(1, 20)
print ('Well, {0}, I am thinking of a number between 1 and 20.'.format(name))
while guesses_made < 6:
guess = int(input('Take a guess: '))
guesses_made += 1
if guess < number:
print ('Your guess is too low.')
if guess > number:
print ('Your guess is too high.')
if guess == number:
break
if guess == number:
print ('Good job, {0}! You guessed my number in {1} guesses!'.format(name, guesses_made))
else:
print ('Nope. The number I was thinking of was {0}'.format(number))