Day051|Python300例之生成隨機的測驗試卷及答案

今天是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!

向上向善,日進一步!

每天學習,努力成長!

定個小目標,開啓成長的旅程,遇見更好的自己。

這是我們和自己的約定,許諾自己不負韶華。

路雖遠,行則將至;事雖難,做則必成。

成長的最好時機,就是當下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章