今天是Andy學Python的第51 天哦!
大家好,我是Andy。
這兩天看書,學習了《python編程快速上手——讓繁瑣工作自動化》第8章《讀寫文件》。抄書上作業,計劃生成10份試卷,每份試卷20道單選題,題目與答案隨機,確保每份試卷都是獨一無二,防止作弊。
01.
項目需求
假如你是一位地理老師,班上有10名學生,你希望進行中國各省省會的一個小測驗。不妙的是,班裏有幾個調皮學生,你無法確信學生不會作弊。你希望隨機調整問題和選項的次序,這樣每份試卷都是獨一無二的,這讓任何人都不能從其他人那裏抄襲答案。
當然,手工完成這件事又費時又無聊。好在,你懂一些Python。
02.
任務拆解
2.1 創建10份不同的測驗試卷。
2.2 爲每份試卷創建20個單項選擇題,次序隨機。
2.3 爲每個問題提供一個正確答案和3個隨機的錯誤答案,次序隨機。
2.4 將測試試卷寫到10個文本文件中。
2.5 將答案寫到10個文件文件中。
03.
代碼逐步實現
首先,將各省和它們的省會保存在一個字典中。
其次,針對測驗文本文件和答案文本文件,調用 open()、write()和 close()。
最後,利用 random.shuffle()隨機調整問題和多重選項的次序。
第 1 步:將測驗數據保存在一個字典中
第一步是創建一個腳本框架,並填入測驗數據。
# 創建一個包含測驗問題及答案的數據,引入隨機
import random
# 測驗數據,key爲各省名稱,value爲各省對應的省會
capitals ={"北京市":"北京", "上海市":"上海", "天津市":"天津", "重慶市":"重慶", "黑龍江省":"哈爾濱","吉林省":"長春", "遼寧省":"瀋陽", "內蒙古":"呼和浩特", "河北省":"石家莊", "新疆":"烏魯木齊","甘肅省":"蘭州", "青海省":"西寧", "陝西省":"西安", "寧夏":"銀川", "河南省":"鄭州","山東省":"濟南", "山西省":"太原", "安徽省":"合肥", "湖北省":"武漢", "湖南省":"長沙","江蘇省":"南京", "四川省":"成都", "貴州省":"貴陽", "雲南省":"昆明", "廣西省":"南寧","西藏":"拉薩", "浙江省":"杭州", "江西省":"南昌", "廣東省":"廣州", "福建省":"福州","臺灣省":"臺北", "海南省":"海口", "香港":"香港", "澳門":"澳門"}
# 創建10份測驗文件
for quizNum in range(10):
# TODO: 創建試卷和答案的文件夾
# TODO: 寫下試卷的標題信息
# TODO: 打亂各省順序
# TODO: 遍歷各省,爲每份試卷提供一份答案
因爲這個程序將隨機安排問題和答案的次序,所以需要導入 random 模塊,以便利用其中的函數。capitals 變量是一個字典,以中國省份作爲鍵,以省會作爲值。因爲你希望創建 10 份測驗試卷,所以實際生成測驗試卷和答案文件的代碼(暫時用 TODO 註釋標註)會放在一個 for 循環中,循環 10 次(這個數字可以改變,生成任何數目的測驗試卷文件)。
第 2 步:創建測驗文件,並打亂問題的次序
循環中的代碼將重複執行 10 次(每次生成一份測驗試卷),所以在循環中,你只需要考慮一份測驗試卷。首先你要創建一個實際的測驗試卷文件,它需要有唯一的文件名,並且有某種標準的標題部分,留出位置,讓學生填寫姓名、日期和班級。然後需要得到隨機排列的省份的列表,稍後將用它來創建測驗試卷的問題和答案。
# 創建10份測驗文件
for quizNum in range(10):
# 創建試卷和答案的文件夾
quizFile = open('省會測驗%s.txt' % (quizNum + 1), 'w') # 創建試卷文件,寫模式
answerKeyFile = open('省會測驗答案%s.txt' % (quizNum + 1), 'w') # 創建答案文件,寫模式
# 寫下試卷的標題信息
quizFile.write('姓名:\n\n日期:\n\n年級:\n\n') # 創建測驗標題,讓學生填寫
quizFile.write((' ' * 20) + '省會測驗(試卷 %s)' % (quizNum + 1))
quizFile.write('\n\n')
# 打亂各省順序
states = list(capitals.keys())
random.shuffle(states)
# TODO: 遍歷各省,爲每份試卷提供一份答案
測驗試卷的文件名將是省會測驗<N>.txt,其中是該測驗試卷的唯一編號,來自於quizNum,即for循環的計數器。針對省會測驗<N>.txt的答案將保存在一個文本文件中,名爲省會測驗答案<N>.txt。每次執行循環,'省會測驗%s.txt'和'省會測驗答案%s.txt'中的佔位符%s都將被(quizNum+1)取代,所以第一個測驗試卷和答案將是省會測驗1.txt和省會測驗答案1.txt。
第 3 步:創建答案選項
現在需要爲每個問題生成答案選項,這將是 A 到 D 的單項選擇。你需要創建 另一個 for 循環,該循環生成測驗試卷的 20 個問題的內容。然後裏面會嵌套第三個 for 循環,爲每個問題生成多重選項。
# 遍歷各省,爲各省出一道問題
for questionNum in range(20):
# 獲取正確和錯誤的選項
correctAnswer = capitals[states[questionNum]]
wrongAnswers = list(capitals.values())
del wrongAnswers[wrongAnswers.index(correctAnswer)]
wrongAnswers = random.sample(wrongAnswers, 3)
answerOptions = wrongAnswers + [correctAnswer]
random.shuffle(answerOptions)
# TODO: 創建試卷中的答案和選項
# TODO: 創建試題答案
正確的答案很容易得到,它作爲一個值保存在capitals字典中。這個循環將遍歷打亂過的states列表中的省,從states[0]到states[19],在capitals中找到每個省,將該省對應的省會保存在correctAnswer中。
可能的錯誤答案列表需要一點技巧。你可以從capitals字典中複製所有的值,刪除正確的答案,然後從該列表中選擇3個隨機的值。random.sample()函數使得這種選擇很容易,它的第一個參數是你希望選擇的列表,第二個參數是你希望選擇的值的個數。完整的答案選項列表是這3個錯誤答案與正確答案的組合。
最後,答案需要隨機排列,這樣正確的答案就不會總是選項D。
第 4 步:將內容寫入測驗試卷和答案文件
剩下來就是將問題寫入測驗試卷文件,將答案寫入答案文件。
# 創建試卷中的答案和選項
quizFile.write('%s. %s省會是哪裏?\n' % (questionNum + 1,states[questionNum]))
for i in range(4): # 一個遍歷整數 0 到 3 的 for 循環,將答案選項寫入 answerOptions 列表。
quizFile.write(' %s. %s\n' % ('ABCD'[i], answerOptions[i]))
quizFile.write('\n')
# 創建試題答案到文件
answerKeyFile.write('%s. %s\n' % (questionNum + 1, 'ABCD'[
answerOptions.index(correctAnswer)]))
quizFile.close()
answerKeyFile.close()
04.
代碼彙總
# 彙總
# 創建一個包含測驗問題及答案的數據,引入隨機,
import random
# 測驗數據,key爲各省名稱,value爲各省對應的省會
capitals ={"北京市":"北京", "上海市":"上海", "天津市":"天津", "重慶市":"重慶", "黑龍江省":"哈爾濱","吉林省":"長春", "遼寧省":"瀋陽", "內蒙古":"呼和浩特", "河北省":"石家莊", "新疆":"烏魯木齊","甘肅省":"蘭州", "青海省":"西寧", "陝西省":"西安", "寧夏":"銀川", "河南省":"鄭州","山東省":"濟南", "山西省":"太原", "安徽省":"合肥", "湖北省":"武漢", "湖南省":"長沙","江蘇省":"南京", "四川省":"成都", "貴州省":"貴陽", "雲南省":"昆明", "廣西省":"南寧","西藏":"拉薩", "浙江省":"杭州", "江西省":"南昌", "廣東省":"廣州", "福建省":"福州","臺灣省":"臺北", "海南省":"海口", "香港":"香港", "澳門":"澳門"}
# 創建10份測驗文件
for quizNum in range(10):
# 創建試卷和答案的文件夾
quizFile = open('省會測驗%s.txt' % (quizNum + 1), 'w') # 創建試卷文件,寫模式
answerKeyFile = open('省會測驗答案%s.txt' % (quizNum + 1), 'w') # 創建答案文件,寫模式
# 寫下試卷的標題信息
quizFile.write('姓名:\n\n日期:\n\n年級:\n\n') # 創建測驗標題,讓學生填寫
quizFile.write((' ' * 20) + '省會測驗(試卷 %s)' % (quizNum + 1))
quizFile.write('\n\n')
# 打亂各省順序
states = list(capitals.keys())
random.shuffle(states)
# TODO: 遍歷各省,爲每份試卷提供一份答案
# 遍歷各省,爲各省出一道問題
for questionNum in range(20):
# 獲取正確和錯誤的選項
correctAnswer = capitals[states[questionNum]]
wrongAnswers = list(capitals.values())
del wrongAnswers[wrongAnswers.index(correctAnswer)]
wrongAnswers = random.sample(wrongAnswers, 3)
answerOptions = wrongAnswers + [correctAnswer]
random.shuffle(answerOptions)
# 創建試卷中的答案和選項
quizFile.write('%s. %s省會是哪裏?\n' % (questionNum + 1,
states[questionNum]))
for i in range(4): # 一個遍歷整數 0 到 3 的 for 循環,將答案選項寫入 answerOptions 列表。
quizFile.write(' %s. %s\n' % ('ABCD'[i], answerOptions[i]))
quizFile.write('\n')
# 創建試題答案到文件
answerKeyFile.write('%s. %s\n' % (questionNum + 1, 'ABCD'[
answerOptions.index(correctAnswer)]))
quizFile.close()
answerKeyFile.close()
生成效果
試卷示例
答案示例
PS:
抄作業也很辛苦。
第一遍抄作業,生成了10份試卷及答案,問題是每份試卷只有一道題目。Bug出在:第二層for questionNum in range(20)循環沒有嵌套好。
第二遍抄作業,生成了10份試卷及答案,每份試卷也是20道題,但答案每份出現了1道目4次重複答案,Bug出在:答案不應該放入for i in range(4)循環。
第三遍抄作業,終於實現了項目需求,大功告成。
51Day Day up!
向上向善,日進一步!
每天學習,努力成長!
定個小目標,開啓成長的旅程,遇見更好的自己。
這是我們和自己的約定,許諾自己不負韶華。
路雖遠,行則將至;事雖難,做則必成。
成長的最好時機,就是當下。