1 #无尽模式训练你,检验所掌握的面向对象的单词和短语。
2 importrandom3 from urllib.request importurlopen4 importsys5
6 WORD_URL = "http://learncodethehardway.org/words.txt" #网页中全是单独成行的单词
7 WORDS =[]8
9 PHRASES ={10 #创建一个叫%%%的类,并继承%%%。
11 "class %%%(%%%):":12 "Make a class named %%% that is-a %%%.",13 #类%%%有一个__init__方法,该方法有self和***两个参数。
14 "class %%%(object):\n\tdef __init__(self, ***)":15 "class %%% has-a __init__ that takes self and *** parameters.",16 #类%%%有一个叫***的函数,该函数有self和@@@两个参数。
17 "class %%%(object):\n\tdef ***(self, @@@)":18 "class %%% has-a function named *** that takes self and @@@ parameters.",19 #给***赋值为类%%%的一个实例。
20 "*** = %%%()":21 "Set *** to an instance of class %%%.",22 #从***里调用***函数,传递的参数为self和@@@。
23 "***.***(@@@)":24 "From *** get the *** function, and call it with parameters self, @@@.",25 #从***里调用***属性,并将其设置为***。
26 "***.*** = '***'":27 "From *** get the *** attribute and set it to '***'."
28 }29
30 #do they want to drill phrases first
31 #由答题者选择是要根据描述编码还是根据代码描述。
32
33
34 #sys.argv为从命令行接收的参数,第一个参数默认为文件名。
35 if len(sys.argv) == 2 and sys.argv[1] == "english":36 PHRASE_FIRST = True #True表示先打印value,按下任意键后再打印key
37 else:38 PHRASE_FIRST =False39
40
41 #load up the words from the website
42 #将词汇们载入到列表WORDS中
43 for word in urlopen(WORD_URL).readlines(): #一行一行从网页中读取数据
44 WORDS.append(word.strip().decode("utf-8")) #删除每一行开始和结尾的空格,只留下单词并加入到words列表中
45 """Python strip() 方法用于移除字符串头尾指定的字符(默认为空格)。46 str->bytes:encode编码,字符串通过编码成为字节码,47 bytes->str:decode解码,字节码通过解码成为字符串。"""
48
49 #定义(覆盖描述和代码中预留位置的)函数,参数为片段、短语。
50 #最后返回一个列表results
51 #先将预留放置词汇的位置分类
52 #参数为key或value,两个总是相对
53 defconvert(snippet, phrase):54 class_names = [w.capitalize() for w in random.sample(WORDS, snippet.count("%%%"))]55 other_names = random.sample(WORDS, snippet.count("***"))56 """random.sample(sequence, k) 从指定序列中随机获取指定长度的片断。sample函数不会修改原有序列"""
57 results =[]58 param_names =[]59
60 for i in range(0, snippet.count("@@@")):61 #参数的个数为1-3个随机。
62 param_count = random.randint(1,3)63 #随机到几个参数就从WORDS中获取几个词
64 param_names.append(','.join(random.sample(WORDS, param_count)))65
66 #准备好要进行替换的PHRASES
67 for sentence insnippet, phrase:68 result =sentence[:]69 #result = [snippet, phrase]
70 #扯句闲话,作者为了片段和代码对应,替换词汇的顺序是固定的。。
71 #用这种方法替换,描述与代码中词汇的顺序肯定是一样的。
72 #fake class names 类名
73 for word inclass_names:74 result = result.replace("%%%", word, 1) #最后一位参数规定每次替换一个,保证%%%不重复。
75
76 #fake other names 对象、方法和其他
77 for word inother_names:78 result = result.replace("***", word, 1)79
80 #fake parameter lists 参数名
81 for word inparam_names:82 result = result.replace("@@@", word, 1)83
84 results.append(result)85
86 returnresults87
88 #keep going until they hit CTRL-D
89 #这里才是重点,是作者的编程逻辑。
90 try:91 while True: #循环抽题
92 snippets = list(PHRASES.keys()) #字典 keys() 方法:以列表返回一个字典所有的键。
93 random.shuffle(snippets) #随机打乱顺序
94
95 for snippet in snippets: #抽题
96 phrase =PHRASES[snippet]97 question, answer =convert(snippet, phrase)98 ifPHRASE_FIRST:99 question, answer =answer, question100
101 print(question)102
103 input(">")104 print ("ANSWER: %s\n\n" %answer)105 exceptEOFError:106 print ("\nBye")107
108
109