廖雪峰 Python3 练习

随着学习的深入,才知道 Python 的厉害之处,居然可以写得这么简洁。


第一个Python程序

Python 代码运行助手

1
2
3
4
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

print('Hello, world!')

输入和输出

1
2
3
4
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

print('1024 * 768 =', 1024 * 78)

Python 基础

数据类型和变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

n = 123
f = 456.789
s1 = 'Hello, world'
s2 = 'Hello, \'Adam\''
s3 = r'Hello, "Bart"'
s4 = r'''Hello,
Lisa!'''

print('n =', n)
print('f =', f)
print('s1 =', s1)
print('s2 =', s2)
print('s3 =', s3)
print('s4 =', s4)

字符串和编码

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

s1 = 72
s2 = 85

r = (s2 - s1) / s1 * 100

print('小明成绩提升的百分点:%.1f%%' % r)

使用 list 和 tuple

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

L = [
['Apple', 'Google', 'Microsoft'],
['Java', 'Python', 'Ruby', 'PHP'],
['Adam', 'Bart', 'Lisa']
]

print(L[0][0])
print(L[1][1])
print(L[2][2])

条件判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

height = 1.75
weight = 80.5

bmi = weight / (height * height)

if bmi <= 18.5:
print('过轻')
elif bmi <= 25:
print('正常')
elif bmi <= 28:
print('过重')
elif bmi <= 32:
print('肥胖')
else:
print('严重肥胖')

循环

1
2
3
4
5
6
7
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

L = ['Bart', 'Lisa', 'Adam']

for name in L:
print('Hello, %s!' % name)

函数

调用函数

1
2
3
4
5
6
7
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

n1 = 255
n2 = 1000

print('hex(%d) = %s, hex(%d) = %s' % (n1, hex(n1), n2, hex(n2)))

定义函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import cmath, math

def quadratic(a, b, c):
if a == 0:
return 'A cannot be zero!'
Δ = b * b - 4 * a * c
if Δ > 0:
x1 = (-b + math.sqrt(Δ)) / (2 * a)
x2 = (-b - math.sqrt(Δ)) / (2 * a)
return x1, x2
elif Δ == 0:
x1 = -b / (2 * a)
return x1
else:
x1 = (-b + cmath.sqrt(Δ)) / (2 * a)
x2 = (-b - cmath.sqrt(Δ)) / (2 * a)
return x1, x2

print(quadratic(2, 3, 1))
print(quadratic(1, 3, -4))

递归函数

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def move(n, a, b, c):
if n <= 0:
return
move(n - 1, a, c, b)
print(a, '-->', c)
move(n - 1, b, a, c)

move(3, 'A', 'B', 'C')

高级特性

列表生成式

第一版

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

L1 = ['Hello', 'World', 18, 'Apple', None]
L2 = []

for x in L1:
if isinstance(x, str):
L2.append(x)

L2 = [x.lower() for x in L2]

print(L2)

第二版

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

L1 = ['Hello', 'World', 18, 'Apple', None]
L2 = []

for x in L1:
if isinstance(x, str):
L2.append(x.lower())

print(L2)

第三版

1
2
3
4
5
6
7
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

L1 = ['Hello', 'World', 18, 'Apple', None]
L2 = [x.lower() for x in L1 if isinstance(x, str)]

print(L2)

生成器

第一版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def triangles():
L = [1]
while True:
yield L
L.append(0)
L = [L[x] + L[x - 1] for x in range(len(L))]

n = 0

for t in triangles():
print(t)
n = n + 1
if n == 10:
break

第二版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def triangles():
L = [1]
while True:
yield L
L = [1] + [L[x] + L[x + 1] for x in range(len(L) - 1)] + [1]

n = 0

for t in triangles():
print(t)
n = n + 1
if n == 10:
break

第三版

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def triangles(s):
L = [1]
while len(L) <= s:
yield L
L.append(0)
L = [L[x] + L[x - 1] for x in range(len(L))]

for t in triangles(10):
print(t)

第四版

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def triangles(s):
L = [1]
while len(L) <= s:
yield L
L = [1] + [L[x] + L[x + 1] for x in range(len(L) - 1)] + [1]

for t in triangles(10):
print(t)

函数式编程

map / reduce

第一题

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def normalize(name):
name = name[0].upper() + name[1:].lower()
return name

L1 = ['adam', 'LISA', 'barT']
L2 = list(map(normalize, L1))

print(L2)

第二题第一版

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from functools import reduce

def prod(L):
return reduce(lambda x, y: x * y, L)

print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9]))

第二题第二版

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from functools import reduce

def prod(x, y):
return x * y

print('3 * 5 * 7 * 9 =', reduce(prod, [3, 5, 7, 9]))

第三题第一版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from functools import reduce

def char2num(s):
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]

def str2float(s):
L = s.split('.')
integer = reduce(lambda x, y: x * 10 + y, map(char2num, L[0]))
decimal = reduce(lambda x, y: x * 0.1 + y, map(char2num, reversed(L[1])))
return integer + decimal * 0.1

print('str2float(\'123.456\') =', str2float('123.456'))

第三题第二版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from functools import reduce

def char2num(s):
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]

def str2int(s):
return reduce(lambda x, y: x * 10 + y, map(char2num, s))

def str2float(s):
return reduce(lambda x, y: str2int(x) + str2int(y) / 10 ** len(y), s.split('.'))

print('str2float(\'123.456\') =', str2float('123.456'))

第三题第三版

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from functools import reduce

def char2num(s):
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]

def str2float(s):
return reduce(lambda x, y: x * 10 + y, map(char2num, s.replace('.', ''))) / 10 ** len(s[s.find('.') + 1:])

print('str2float(\'123.456\') =', str2float('123.456'))

filter

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def is_palindrome(n):
return n == int(str(n)[::-1])

output = filter(is_palindrome, range(1, 1000))

print(list(output))

sorted

第一题第一版

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]

def by_name(t):
return t[0]

L2 = sorted(L, key = by_name)

print(L2)

第一题第二版

1
2
3
4
5
6
7
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
L2 = sorted(L, key = lambda x: x[0])

print(L2)

第二题第一版

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]

def by_score(t):
return t[1]

L2 = sorted(L, key = by_score, reverse = True)

print(L2)

第二题第二版

1
2
3
4
5
6
7
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
L2 = sorted(L, key = lambda x: x[1], reverse = True)

print(L2)

面向对象高级编程

使用 @property

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

class Screen(object):
@property
def width(self):
return self._width

@width.setter
def width(self, value):
if not isinstance(value, int):
raise ValueError('width must be an integer!')
if value <= 0:
raise ValueError('width must be greater than 0!')
self._width = value

@property
def height(self):
return self._height

@height.setter
def height(self, value):
if not isinstance(value, int):
raise ValueError('height must be an integer!')
if value <= 0:
raise ValueError('height must be greater than 0!')
self._height = value

@property
def resolution(self):
return self._width * self._height

s = Screen()
s.width = 1024
s.height = 768

print(s.resolution)
assert s.resolution == 786432, '1024 * 768 = %d ?' % s.resolution

错误、调试和测试

文档测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def fact(n):
'''
>>> fact('1')
Traceback (most recent call last):
...
TypeError: unorderable types: str() < int()

>>> fact(-1)
Traceback (most recent call last):
...
ValueError

>>> fact(0)
Traceback (most recent call last):
···
ValueError

>>> fact(1)
1

>>> fact(10)
3628800
'''
if n < 1:
raise ValueError()
if n == 1:
return 1
return n * fact(n - 1)

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

IO 编程

操作文件和目录

第一题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
from datetime import datetime

print('LastWriteTime Length Name')
print('-----------------------------------------------')

for f in os.listdir():
mtime = datetime.fromtimestamp(os.path.getmtime(f))
fsize = os.path.getsize(f)
flag = '/' if os.path.isdir(f) else ''
print('%s %8s %s%s' % (mtime, fsize, f, flag))

第二题第一版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os

key = input('Please enter what you want to search:\n')

def find_files(path, key):
abspath = os.path.abspath(path)
for x in os.listdir(path):
absfile = os.path.join(path, x)
if os.path.isfile(absfile):
if key in os.path.split(x)[1]:
print(os.path.abspath(absfile))
if os.path.isdir(absfile):
find_files(absfile, key)

find_files('.', key)

第二题第二版

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os

key = input('Please enter what you want to search:\n')

for x in os.walk('.'):
for y in x[2]:
if key in os.path.split(y)[1]:
print(os.path.join(os.path.abspath(x[0]), y))

正则表达式

第一题

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import re

text = '''[email protected]
[email protected]'''
re_email = '([a-zA-Z][\w.-][email protected][\w.]+[a-zA-Z])'

re.match(re_email, text)

print('Pass.')

第二题

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import re

text = '<Tom Paris> [email protected]'
re_email = '(<[a-zA-Z\s]+>) ([a-zA-Z][\w.-][email protected][\w.]+[a-zA-Z])'

re.match(re_email, text).group(2)

print('Pass.')

常用内建模块

datetime

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import re
from datetime import datetime, timezone, timedelta

def to_timestamp(dt_str, tz_str):
tz = re.match('UTC([+-]\d+)', tz_str).group(1)
tz = timezone(timedelta(hours = int(tz)))
dt = datetime.strptime(dt_str, '%Y-%m-%d %H:%M:%S')
dt = dt.replace(tzinfo = tz).timestamp()
return dt

t1 = to_timestamp('2015-6-1 08:10:30', 'UTC+7:00')
assert t1 == 1433121030.0, t1

t2 = to_timestamp('2015-5-31 16:10:30', 'UTC-09:00')
assert t2 == 1433121030.0, t2

print('Pass.')

base64

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import base64

def safe_base64_decode(s):
s += b'=' * (len(s) % 4)
return base64.b64decode(s)

assert b'abcd' == safe_base64_decode(b'YWJjZA=='), safe_base64_decode('YWJjZA==')
assert b'abcd' == safe_base64_decode(b'YWJjZA'), safe_base64_decode('YWJjZA')

print('Pass.')

struct

1
2
3
4
5
6
7
8
9
10
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import struct

with open('test.bmp', 'rb') as file:
info = struct.unpack('<ccIIIIIIHH', file.read(30))

if info[0] == b'B' and info[1] == b'M':
print('Size: %d * %d, Color: %d' % (info[6], info[7], info[9]))

hashlib

第一题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import hashlib

def calc_md5(password):
return hashlib.md5(password.encode('utf-8')).hexdigest()

def login(user, password):
if user in db:
if calc_md5(password) == db[user]:
print('Username and password are true.')
else:
print('Password is not true.')
else:
print('%s is not registered.' % user)

db = {'michael': 'e10adc3949ba59abbe56e057f20f883e',
'bob': '878ef96e86145580c38c87f0410ad153',
'alice': '99b1c2188db85afee403b1536010c2c9'}

user = input('Please enter your username:\n')
password = input('Please enter your password:\n')

login(user, password)

第二题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import hashlib

def ask():
global choice
choice = input('Do you want to login(l) or to register(r)?\n')
if choice == 'l':
user_input()
login(username, password)
elif choice == 'r':
user_input()
register(username, password)
else:
print('Error!')

def user_input():
global username, password
username = input('Please enter your username:\n')
password = input('Please enter your password:\n')

def get_md5(pw):
return hashlib.md5(pw.encode('utf-8')).hexdigest()

def login(username, password):
if username in db:
if get_md5(password + username + 'the-Salt') == db[username]:
print('Username and password are true.')
else:
print('Password is not true.')
else:
print('%s is not registered.' % username)

def register(username, password):
if username not in db:
db[username] = get_md5(password + username + 'the-Salt')
else:
print('%s is registered.' % username)

db = {}

ask()
ask() if choice == 'r' else None

XML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from xml.parsers.expat import ParserCreate

class WeatherSaxHandler(object):
info = {}

def start_element(self, name, attrs):
if name == 'yweather:location':
self.info['city'] = attrs['city']
self.info['country'] = attrs['country']
if name == 'yweather:forecast':
if 'today' not in self.info:
self.info['today'] = {}
self.info['today']['low'] = int(attrs['low'])
self.info['today']['high'] = int(attrs['high'])
self.info['today']['text'] = attrs['text']
elif 'tomorrow' not in self.info:
self.info['tomorrow'] = {}
self.info['tomorrow']['low'] = int(attrs['low'])
self.info['tomorrow']['high'] = int(attrs['high'])
self.info['tomorrow']['text'] = attrs['text']

def parse_weather(xml):
handler = WeatherSaxHandler()
parser = ParserCreate()
parser.StartElementHandler = handler.start_element
parser.Parse(xml)
return handler.info

data = r'''<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
<channel>
<title>Yahoo! Weather - Beijing, CN</title>
<lastBuildDate>Wed, 27 May 2015 11:00 am CST</lastBuildDate>
<yweather:location city="Beijing" region="" country="China"/>
<yweather:units temperature="C" distance="km" pressure="mb" speed="km/h"/>
<yweather:wind chill="28" direction="180" speed="14.48" />
<yweather:atmosphere humidity="53" visibility="2.61" pressure="1006.1" rising="0" />
<yweather:astronomy sunrise="4:51 am" sunset="7:32 pm"/>
<item>
<geo:lat>39.91</geo:lat>
<geo:long>116.39</geo:long>
<pubDate>Wed, 27 May 2015 11:00 am CST</pubDate>
<yweather:condition text="Haze" code="21" temp="28" date="Wed, 27 May 2015 11:00 am CST" />
<yweather:forecast day="Wed" date="27 May 2015" low="20" high="33" text="Partly Cloudy" code="30" />
<yweather:forecast day="Thu" date="28 May 2015" low="21" high="34" text="Sunny" code="32" />
<yweather:forecast day="Fri" date="29 May 2015" low="18" high="25" text="AM Showers" code="39" />
<yweather:forecast day="Sat" date="30 May 2015" low="18" high="32" text="Sunny" code="32" />
<yweather:forecast day="Sun" date="31 May 2015" low="20" high="37" text="Sunny" code="32" />
</item>
</channel>
</rss>
'''

weather = parse_weather(data)

assert weather['city'] == 'Beijing', weather['city']
assert weather['country'] == 'China', weather['country']
assert weather['today']['text'] == 'Partly Cloudy', weather['today']['text']
assert weather['today']['low'] == 20, weather['today']['low']
assert weather['today']['high'] == 33, weather['today']['high']
assert weather['tomorrow']['text'] == 'Sunny', weather['tomorrow']['text']
assert weather['tomorrow']['low'] == 21, weather['tomorrow']['low']
assert weather['tomorrow']['high'] == 34, weather['tomorrow']['high']

print('Weather:', str(weather))

HTMLParser

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from urllib import request
from html.parser import HTMLParser

class MyHTMLParser(HTMLParser):
_title = False
_time = False
_location = False

def handle_starttag(self, tag, attrs):
if ('class', 'event-title') in attrs:
self._title = True
if tag == 'time':
self._time = True
self.time = ''
if ('class', 'event-location') in attrs:
self._location = True

def handle_data(self, data):
if self._title:
print(data)
if self._time:
self.time += data
if self._location:
print(data + '\n')

def handle_endtag(self, tag):
if tag == 'h3':
self._title = False
if tag == 'time':
print(self.time)
self._time = False
if tag == 'span':
self._location = False

html = request.urlopen('https://www.python.org/events/python-events/').read()

parser = MyHTMLParser()
parser.feed(str(html))

urllib

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from urllib import request
from xml.parsers.expat import ParserCreate

class WeatherSaxHandler(object):
info = {}

def start_element(self, name, attrs):
if name == 'yweather:location':
self.info['city'] = attrs['city']
self.info['country'] = attrs['country']
if name == 'yweather:forecast':
if 'today' not in self.info:
self.info['today'] = {}
self.info['today']['low'] = int(attrs['low'])
self.info['today']['high'] = int(attrs['high'])
self.info['today']['text'] = attrs['text']
elif 'tomorrow' not in self.info:
self.info['tomorrow'] = {}
self.info['tomorrow']['low'] = int(attrs['low'])
self.info['tomorrow']['high'] = int(attrs['high'])
self.info['tomorrow']['text'] = attrs['text']

def fetch_xml(url):
handler = WeatherSaxHandler()
parser = ParserCreate()
parser.StartElementHandler = handler.start_element
parser.Parse(request.urlopen(url).read())
return handler.info

print(fetch_xml('http://xml.weather.yahoo.com/forecastrss?u=c&w=2151330'))

访问数据库

使用 SQLite

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os, sqlite3

db_file = os.path.join(os.path.dirname(__file__), 'test.db')
if os.path.isfile(db_file):
os.remove(db_file)

conn = sqlite3.connect(db_file)
cursor = conn.cursor()
cursor.execute('create table user(id varchar(20) primary key, name varchar(20), score int)')
cursor.execute(r"insert into user values ('A-001', 'Adam', 95)")
cursor.execute(r"insert into user values ('A-002', 'Bart', 62)")
cursor.execute(r"insert into user values ('A-003', 'Lisa', 78)")
cursor.close()
conn.commit()
conn.close()

def get_score_in(low, high):
try:
conn = sqlite3.connect(db_file)
cursor = conn.cursor()
cursor.execute('select * from user where score between ? and ?', (low, high))
values = cursor.fetchall()
finally:
cursor.close()
conn.close()
return list(map(lambda x: x[1], sorted(values, key = lambda x: x[2])))

assert get_score_in(80, 95) == ['Adam'], get_score_in(80, 95)
assert get_score_in(60, 80) == ['Bart', 'Lisa'], get_score_in(60, 80)
assert get_score_in(60, 100) == ['Bart', 'Lisa', 'Adam'], get_score_in(60, 100)

print('Pass.')

异步 IO

async / await

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import asyncio

async def wget(host):
print('wget %s...' % host)
connect = asyncio.open_connection(host, 80)
reader, writer = await connect
header = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % host
writer.write(header.encode('utf-8'))
await writer.drain()
while True:
line = await reader.readline()
if line == b'\r\n':
break
print('%s header > %s' % (host, line.decode('utf-8').rstrip()))
writer.close()

loop = asyncio.get_event_loop()
tasks = [wget(host) for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()