今天是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!
向上向善,日进一步!
每天学习,努力成长!
定个小目标,开启成长的旅程,遇见更好的自己。
这是我们和自己的约定,许诺自己不负韶华。
路虽远,行则将至;事虽难,做则必成。
成长的最好时机,就是当下。
网友评论