1 #無盡模式訓練你,檢驗所掌握的面向對象的單詞和短語。 2 import random 3 from urllib.request import urlopen 4 import sys 5 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 = False 39 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 def convert(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 in snippet, phrase: 68 result = sentence[:] 69 #result = [snippet, phrase] 70 #扯句閑話,作者為了片段和代碼對應,替換詞匯的順序是固定的。。 71 #用這種方法替換,描述與代碼中詞匯的順序肯定是一樣的。 72 #fake class names 類名 73 for word in class_names: 74 result = result.replace("%%%", word, 1) #最后一位參數規定每次替換一個,保證%%%不重復。 75 76 #fake other names 對象、方法和其他 77 for word in other_names: 78 result = result.replace("***", word, 1) 79 80 #fake parameter lists 參數名 81 for word in param_names: 82 result = result.replace("@@@", word, 1) 83 84 results.append(result) 85 86 return results 87 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 if PHRASE_FIRST: 99 question, answer = answer, question 100 101 print (question) 102 103 input("> ") 104 print ("ANSWER: %s\n\n" % answer) 105 except EOFError: 106 print ("\nBye") 107 108 109

