【终于看懂了】笨办法学python——习题41

import random
from urllib.request import urlopen
import sys

WORD_URL = "http://learncodethehardway.org/words.txt"
WORDS = []

PHRASES = {
    "class %%%(%%%):":
        "Make a class named %%% that is-a %%%.",
    "class %%%(object): \n\t def __init__(self,***)":
        "class %%% has-a __init__ that takes self and *** params.",
    "class %%%(object): \n\t def ***(self,@@@)":
        "class %%% has-a function *** that takes self and @@@ params.",
    "*** = %%%()":
        "Set *** to an instance of class %%%.",
    "***.***(@@@)":
        "From *** get the *** function, call it with params self, @@@.",
    "***.*** = '***'":
        "From *** get the *** attribute and set it to '***'"
}   # 新建了一个字典

# do they want to drill phrases first
if len(sys.argv) == 2 and sys.argv[1] == "english":
    PHRASES_FIRST = True
else:
    PHRASES_FIRST = False  # 判断用户输入的参数是否符合要求:1. 必须为两个参数;2. 第二个参数必须为english

# 读取WORD文本中的内容
for word in urlopen(WORD_URL).readlines():
    WORDS.append(str(word.strip(), encoding="utf-8"))  # 使用strip函数移除字符串头尾的空格,并通过循环依次添加到WORD空列表


def convert(snippet, phrase):  # 定义一个含两个参数的函数
    class_names = [w.capitalize() for w in  # capitalize函数用于将字符串首字母大写,其余字母小写
                   random.sample(WORDS, snippet.count("***"))]  # random.sample用于随机无顺序截取snippet.count("***")个WORDS中的元素
    other_names = random.sample(WORDS, snippet.count("***"))  # count函数用于统计在snippet中"***"的出现次数
    results = []  # 新建两个空列表
    param_names = []
    # 本段代码的作用是:统计出snippet中有x个"***",然后随机无顺序截取x个WORDS中的元素,将其首字母大写,其余字母小写

    for i in range(0, snippet.count("@@@")):
        param_count = random.randint(1, 3)  # randint函数用于随机生成1到3之间的整数值,即1、2、3
        param_names.append(','.join(
            random.sample(WORDS, param_count)))  # join函数用','将后面的元素连起来
        # 本段代码的作用是:统计出snippet中有y个"@@@",然后循环y次,每次随机生成一个1到3之间的整数z,随机无顺序截取z个WORDS中的元素,
        # 用,连接,增加到param_names列表的尾部

    for sentence in snippet, phrase:
        result = sentence[:]  # sentence[:]表示获取sentence中的所有项

        # fake class names
        for word in class_names:
            result = result.replace("%%%", word, 1)  # 用word替换"%%%",替换次数不超过一次
        # 将result中的"%%%"用word替换,替换次数不超过一次

        # fake other names
        for word in other_names:
            result = result.replace("***", word, 1)
        # 将result中的"***"用word替换,替换次数不超过一次

        # fake parameter lists
        for word in param_names:
            result = result.replace("@@@", word, 1)
        # 将result中的"@@@"用word替换,替换次数不超过一次

        results.append(result)  # 将result的值追加到results列表的尾部

    return results


# keep going until they hit CTRL-D
try:  # 当为True时,执行下列代码,反之执行except中的代码(此处的True并不是指PHRASE_FIRST的值为True,而是指程序执行无异常)
    while True:
        snippets = list(PHRASES.keys())  # keys用于提取字典中的关键字
        random.shuffle(snippets)  # random.shuffle用于随机修改列表中元素的顺序
        # 提取出PHRASES中的关键字,并随机修改其顺序

        for snippet in snippets:
            phrase = PHRASES[snippet]  # 使用字典的关键词提取对应的值
            question, answer = convert(snippet, phrase)
            if PHRASES_FIRST:  # 此处才是判断PHRASES_FIRST的值是否为True,是True则调换顺序,否则不调换
                question, answer = answer, question  # 列表中元素位置互换

            print(question)

            input("> ")  # 这个input似乎没有作用,只是单纯地输入了一个值,也没有被赋给其他变量
            print(f"ANSWER: {answer} \n\n")
except EOFError:  # 当发生异常,即为False时,执行下列代码,输出Bye
    print("\nBye")

以上为修改后正确代码,第一次错误原因为capitalize、phrase拼写错误。

本节代码的逻辑与作用是:首先从网站上读取名为文档,并将其赋值给WORD。当输入参数满足要求时,即一共两个参数,第二个参数必须为“english”,执行以下操作:先提取出PHRASE中的键,随机改变顺序后提取其对应的取值(snippet被赋值为键,phrase被赋值为取值),然后将snippet,phrase作为实参调用convert函数。convert函数操作如下:一共有三个重要列表:class_names;other_names;param_names,它们分别是:随机无顺序截取WORDS中元素并首字母大写;随机无顺序截取WORDS中元素;随机截取WORDS中元素并用“,”连接。之后使用for循环将元素中的“***”,“@@@”用word代替,每次循环仅修改一个元素。最后将值加入results列表中,返回results。

概括来说就是将WORDS文件中的元素提取出来,用以替代PHRASES中的各种符号“***”,“@@@”,提取出的WORDS中的元素顺序和数量随机。最后判断输入是否为英文,如果为英文则调换顺序输出answer,否则不调换输出question。

这个代码的输入:出来一个类的定义,如何用户随便输入一个啥(不重要),然后继续输出对该代码语句的使用专有术语的解释。所以本节的作用就是帮助你熟悉用专有术语解释代码……

参考文章:Learn Python The Hard Way 习题41详解_moverzp的博客-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值