趣味微项目,轻松学Python_8-15章读书心得
[复制链接]
第八章内容是找到并替换,作者通过《苹果和香蕉》这个歌曲引出本章的内容。
本章中我们将实现一个程序,该程序选取某个文本并把该文本中的所有元音都替换成给定的-v或—vowel选项。
主要内容包括:更该字符串、使用str.replace()方法、使用str.translate()、其他变更字符串的方法、替换元音的6中方法、用测试进行重构等内容。
通过本章的学习,我们将进一步学习到文本的处理方法,学习多种替换文本的方法:包括迭代每个字符、使用str.replace()方法、使用str.translate()方法、使用列表推导式、使用带有函数的列表推导式、使用map()函数、使用带有具名函数的map()、使用正则表达式。程序一种方式实现如下:
#!/usr/bin/env python3
"""Apples and Bananas"""
import argparse
import os
# --------------------------------------------------
def get_args():
"""get command-line arguments"""
parser = argparse.ArgumentParser(
description='Apples and bananas',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('text', metavar='text', help='Input text or file')
parser.add_argument('-v',
'--vowel',
help='The vowel to substitute',
metavar='vowel',
type=str,
default='a',
choices=list('aeiou'))
args = parser.parse_args()
if os.path.isfile(args.text):
args.text = open(args.text).read().rstrip()
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
text = args.text
vowel = args.vowel
new_text = []
for char in text:
if char in 'aeiou':
new_text.append(vowel)
elif char in 'AEIOU':
new_text.append(vowel.upper())
else:
new_text.append(char)
print(''.join(new_text))
# --------------------------------------------------
if __name__ == '__main__':
main()
第九章内容是用单词列表生成随机嘲讽话。作者通过拨号诅咒引出本章随机事件处理的内容。
本章中我们将实现一个程序。它将随机选择形容词和名词来创建诽谤绰号来嘲讽用户。
主要内容包括:编写abuse.py、验证实参、导入随机模块并生成种子、定义形容词和名词、采集随机样本并选择、对输出进行格式化、使用parser.error()、程序退出值和STDERR、使用random.seed()控制随机性、用range()进行迭代并使用抛弃变量、构建嘲讽语句等内容。
通过本章的学习,我们将学会使用来自argpars的parser.error(),抛出错误、用随机种子控制随机性、从python列表中随机选择和采样、用for循环把一个算法迭代特定次数、对输出字符串进行格式化。程序实现如下:
#!/usr/bin/env python3
"""Heap abuse"""
import argparse
import random
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Heap abuse',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-a',
'--adjectives',
help='Number of adjectives',
metavar='adjectives',
type=int,
default=2)
parser.add_argument('-n',
'--number',
help='Number of insults',
metavar='insults',
type=int,
default=3)
parser.add_argument('-s',
'--seed',
help='Random seed',
metavar='seed',
type=int,
default=None)
args = parser.parse_args()
if args.adjectives < 1:
parser.error(f'--adjectives "{args.adjectives}" must be > 0')
if args.number < 1:
parser.error(f'--number "{args.number}" must be > 0')
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
random.seed(args.seed)
adjectives = """
bankrupt base caterwauling corrupt cullionly detestable dishonest false
filthsome filthy foolish foul gross heedless indistinguishable infected
insatiate irksome lascivious lecherous loathsome lubbery old peevish
rascaly rotten ruinous scurilous scurvy slanderous sodden-witted
thin-faced toad-spotted unmannered vile wall-eyed
""".strip().split()
nouns = """
Judas Satan ape ass barbermonger beggar block boy braggart butt
carbuncle coward coxcomb cur dandy degenerate fiend fishmonger fool
gull harpy jack jolthead knave liar lunatic maw milksop minion
ratcatcher recreant rogue scold slave swine traitor varlet villain worm
""".strip().split()
for _ in range(args.number):
adjs = ', '.join(random.sample(adjectives, k=args.adjectives))
print(f'You {adjs} {random.choice(nouns)}!')
# --------------------------------------------------
if __name__ == '__main__':
main()
第十章内容是随机变更字符串。作者通过电话游戏程序引出本章内容。
本章中我们将模拟这个电话游戏程序,该游戏中一排或一圈人以耳语的方式传播一个秘密消息,每次传播该消息都以一种不可预知的方式改变,最后一个接收到消息的人将他大声说出来。
主要内容包括:编写telephone.py、计算变更的数量、变更的空间、选择要变更的字符、变更字符串、使用list代替str等内容。
通过本章的学习,我们将学会数字取整、使用srting模块、修改字符串和列表,进行随机变更。程序实现如下:
#!/usr/bin/env python3
"""Telephone"""
import argparse
import os
import random
import string
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Telephone',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('text', metavar='text', help='Input text or file')
parser.add_argument('-s',
'--seed',
help='Random seed',
metavar='seed',
type=int,
default=None)
parser.add_argument('-m',
'--mutations',
help='Percent mutations',
metavar='mutations',
type=float,
default=0.1)
args = parser.parse_args()
if not 0 <= args.mutations <= 1:
parser.error(f'--mutations "{args.mutations}" must be between 0 and 1')
if os.path.isfile(args.text):
args.text = open(args.text).read().rstrip()
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
text = args.text
random.seed(args.seed)
alpha = ''.join(sorted(string.ascii_letters + string.punctuation))
len_text = len(text)
num_mutations = round(args.mutations * len_text)
new_text = text
for i in random.sample(range(len_text), num_mutations):
new_char = random.choice(alpha.replace(new_text[i], ''))
new_text = new_text[:i] + new_char + new_text[i + 1:]
print(f'You said: "{text}"\nI heard : "{new_text}"')
# --------------------------------------------------
if __name__ == '__main__':
main()
第十一章的内容是编写和测试函数。作者通过《墙上有九十九瓶啤酒》之歌引出本章内容。
本章中我们将实现一个歌曲生成程序。它采用一个选项-n或—num,必须是正的int,该程序打印从—num反向计数到1的所有小节。每个小节之间应该有两个新行。最后一个小节之后只能有一个新行,并打印“No more bottles of beer on the wall”。
主要内容包括:编写bottles.py、反向计数、函数的编写、为verse()编写测试、使用verse()函数、测试驱动开发、verse()函数、遍历歌曲小节等内容。
通过本章学习,我们将学会如何产生一个由递减数字构成的列表、编写一个函数来创建歌曲的一个小节,使用测试来验证该小节何时正确、探索如何把for循环写成列表推导式,进而写成map()。程序实现如下:
#!/usr/bin/env python3
"""Bottles of beer song"""
import argparse
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Bottles of beer song',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-n',
'--num',
metavar='number',
type=int,
default=10,
help='How many bottles')
args = parser.parse_args()
if args.num < 1:
parser.error(f'--num "{args.num}" must be greater than 0')
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
print('\n\n'.join(map(verse, range(args.num, 0, -1))))
# --------------------------------------------------
def verse(bottle):
"""Sing a verse"""
next_bottle = bottle - 1
s1 = '' if bottle == 1 else 's'
s2 = '' if next_bottle == 1 else 's'
num_next = 'No more' if next_bottle == 0 else next_bottle
return '\n'.join([
f'{bottle} bottle{s1} of beer on the wall,',
f'{bottle} bottle{s1} of beer,',
f'Take one down, pass it around,',
f'{num_next} bottle{s2} of beer on the wall!',
])
# --------------------------------------------------
def test_verse():
"""Test verse"""
last_verse = verse(1)
assert last_verse == '\n'.join([
'1 bottle of beer on the wall,', '1 bottle of beer,',
'Take one down, pass it around,',
'No more bottles of beer on the wall!'
])
two_bottles = verse(2)
assert two_bottles == '\n'.join([
'2 bottles of beer on the wall,', '2 bottles of beer,',
'Take one down, pass it around,', '1 bottle of beer on the wall!'
])
# --------------------------------------------------
if __name__ == '__main__':
main()
第十二章内容是随机大写文本。作者通过绑匪寄赎金条这个故事引入本章内容。
本章中我们要实现一个程序。它可以将文本替换为随机大写字母。
主要内容包括:编写ransom.py、修改文本、投掷硬币、创建新字符串、遍历序列中的元素、编写函数来选择字母、编写list.append()的另一种方法、使用str代替list、使用列表解析式、使用map()函数方法比较等内容。
通过本章学习我们将学会使用random模块来形象地“掷硬币”,在两个选择之间取舍、探索从现有字符串中生成新字符串的方法,并于随机决策相结合、研究for循环、列表推导和map()函数相似性。程序一种实现如下:
#!/usr/bin/env python3
"""Ransom note"""
import argparse
import os
import random
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Ransom Note',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('text', metavar='text', help='Input text or file')
parser.add_argument('-s',
'--seed',
help='Random seed',
metavar='int',
type=int,
default=None)
args = parser.parse_args()
if os.path.isfile(args.text):
args.text = open(args.text).read().rstrip()
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
random.seed(args.seed)
# Method 1: Iterate each character, add to list
ransom = []
for char in args.text:
ransom.append(choose(char))
print(''.join(ransom))
# --------------------------------------------------
def choose(char):
"""Randomly choose an upper or lowercase letter to return"""
return char.upper() if random.choice([0, 1]) else char.lower()
# --------------------------------------------------
def test_choose():
"""Test choose"""
state = random.getstate()
random.seed(1)
assert choose('a') == 'a'
assert choose('b') == 'b'
assert choose('c') == 'C'
assert choose('d') == 'd'
random.setstate(state)
# --------------------------------------------------
if __name__ == '__main__':
main()
第十三章内容是算法设计。作者通过《圣诞节的十二天》这首歌曲引出本章的主题。
本章中我们就要实现这样一个算法。为给定的天数生成一首歌。它将生成直到给定的日期的《圣诞节的十二天》,这一天由-n或—num实参指定。
主要内容包括:编写twelve_days.py、计数、创建序数值、制作小节、使用verse()函数、生成小节、打印小节等内容。
通过本章学习我们将学会创建一个用1-12范围内给定天数生成歌曲的算法、逆序排列一个列表、使用range()函数、把文本写到一个文件或写到STDOUT。程序实现如下:
#!/usr/bin/env python3
"""Twelve Days of Christmas"""
import argparse
import sys
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Twelve Days of Christmas',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-n',
'--num',
help='Number of days to sing',
metavar='days',
type=int,
default=12)
parser.add_argument('-o',
'--outfile',
help='Outfile',
metavar='FILE',
type=argparse.FileType('wt'),
default=sys.stdout)
args = parser.parse_args()
if args.num not in range(1, 13):
parser.error(f'--num "{args.num}" must be between 1 and 12')
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
verses = map(verse, range(1, args.num + 1))
print('\n\n'.join(verses), file=args.outfile)
# --------------------------------------------------
def verse(day):
"""Create a verse"""
ordinal = [
'first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh',
'eighth', 'ninth', 'tenth', 'eleventh', 'twelfth'
]
gifts = [
'A partridge in a pear tree.',
'Two turtle doves,',
'Three French hens,',
'Four calling birds,',
'Five gold rings,',
'Six geese a laying,',
'Seven swans a swimming,',
'Eight maids a milking,',
'Nine ladies dancing,',
'Ten lords a leaping,',
'Eleven pipers piping,',
'Twelve drummers drumming,',
]
lines = [
f'On the {ordinal[day - 1]} day of Christmas,',
'My true love gave to me,'
]
lines.extend(reversed(gifts[:day]))
if day > 1:
lines[-1] = 'And ' + lines[-1].lower()
return '\n'.join(lines)
# --------------------------------------------------
def test_verse():
"""Test verse"""
assert verse(1) == '\n'.join([
'On the first day of Christmas,', 'My true love gave to me,',
'A partridge in a pear tree.'
])
assert verse(2) == '\n'.join([
'On the second day of Christmas,', 'My true love gave to me,',
'Two turtle doves,', 'And a partridge in a pear tree.'
])
# --------------------------------------------------
if __name__ == '__main__':
main()
第十四章的内容是使用正则表达式创建押韵单词。作者通过电影《公主新娘》中涉及到的一个押韵游戏引入本章内容。
本章中我们要实现一个程序,选取给定的单词,并创建与它押韵的单词,当然是使用正则表达式的方式。
主要内容包括:编写rhymer.py、分解单词、使用正则表达式、使用捕获组、真实性、取单词词干、对正则表达式进行格式化和注释、在程序之外使用stemmer()函数、创建押韵字符串、不带正则表达式的stemmer().
通过本章的学习我们将学会编写和使用正则表达式、把守卫语句(guard)用在列表推导式中、探索带有守卫语句的列表推导式与filter()函数的相似性、在布尔语境中评估python类型时,考虑“真实性”。程序实现如下:
#!/usr/bin/env python3
"""Make rhyming words"""
import argparse
import re
import string
# --------------------------------------------------
def get_args():
"""get command-line arguments"""
parser = argparse.ArgumentParser(
description='Make rhyming "words"',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('word', metavar='word', help='A word to rhyme')
return parser.parse_args()
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
prefixes = list('bcdfghjklmnpqrstvwxyz') + (
'bl br ch cl cr dr fl fr gl gr pl pr sc '
'sh sk sl sm sn sp st sw th tr tw thw wh wr '
'sch scr shr sph spl spr squ str thr').split()
start, rest = stemmer(args.word)
if rest:
print('\n'.join(sorted([p + rest for p in prefixes if p != start])))
else:
print(f'Cannot rhyme "{args.word}"')
# --------------------------------------------------
def stemmer(word):
"""Return leading consonants (if any), and 'stem' of word"""
word = word.lower()
vowels = 'aeiou'
consonants = ''.join(
[c for c in string.ascii_lowercase if c not in vowels])
pattern = (
'([' + consonants + ']+)?' # capture one or more, optional
'([' + vowels + '])' # capture at least one vowel
'(.*)' # capture zero or more of anything
)
pattern = f'([{consonants}]+)?([{vowels}])(.*)'
match = re.match(pattern, word)
if match:
p1 = match.group(1) or ''
p2 = match.group(2) or ''
p3 = match.group(3) or ''
return (p1, p2 + p3)
else:
return (word, '')
# --------------------------------------------------
def test_stemmer():
"""test the stemmer"""
assert stemmer('') == ('', '')
assert stemmer('cake') == ('c', 'ake')
assert stemmer('chair') == ('ch', 'air')
assert stemmer('APPLE') == ('', 'apple')
assert stemmer('RDNZL') == ('rdnzl', '')
assert stemmer('123') == ('123', '')
# --------------------------------------------------
if __name__ == '__main__':
main()
第十五章的内容是关于正则表达式的更多故事。作者通过当地人会省略以“ing”结尾的单词末尾的“g”引入本章内容。
本章中我们将实现一个程序。它接收某个输入作为单个位置实参,并把文本中以“ing”结尾的双音节词用(')替换,并将“you”改为“y’all”。
主要内容包括:编写friar.py、使用正则表达式拆解文本、简写类、否定简写类、使用带有已捕获的正则表达式的re.split()、编写fry()函数、使用fry()函数、编写带有正则表达式的fry()函数。
通过本章学习我们将学到更多关于正则表达式的知识、学会分别使用re.match()和re.search()查找锚定于字符串开头或字符串中任意位置的模式、了解正则表达式中$符号如何把模式锚定与字符的末尾、学会如何使用re.split()来拆解字符串、探索如何编写找到双音节“ing”或单词“you”手动解决方案。程序实现如下:
#!/usr/bin/env python3
"""Kentucky Friar"""
import argparse
import os
import re
# --------------------------------------------------
def get_args():
"""Get command-line arguments"""
parser = argparse.ArgumentParser(
description='Southern fry text',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('text', metavar='text', help='Input text or file')
args = parser.parse_args()
if os.path.isfile(args.text):
args.text = open(args.text).read()
return args
# --------------------------------------------------
def main():
"""Make a jazz noise here"""
args = get_args()
for line in args.text.splitlines():
print(''.join(map(fry, re.split(r'(\W+)', line.rstrip()))))
# --------------------------------------------------
def fry(word):
"""Drop the `g` from `-ing` words, change `you` to `y'all`"""
ing_word = re.search('(.+)ing$', word)
you = re.match('([Yy])ou$', word)
if ing_word:
prefix = ing_word.group(1)
if re.search('[aeiouy]', prefix, re.IGNORECASE):
return prefix + "in'"
elif you:
return you.group(1) + "'all"
return word
# --------------------------------------------------
def test_fry():
"""Test fry"""
assert fry('you') == "y'all"
assert fry('You') == "Y'all"
assert fry('your') == 'your'
assert fry('fishing') == "fishin'"
assert fry('Aching') == "Achin'"
assert fry('swing') == "swing"
# --------------------------------------------------
if __name__ == '__main__':
main()
|