结对项目
结对项目 ———— 四则运算的实现
这个作业属于哪个课程 | https://edu.cnblogs.com/campus/gdgy/CSGrade22-34 |
---|---|
这个作业要求在哪 | https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13230 |
这个作业的目标 | 设计一个四则运算生成器 |
项目成员一 | 梁俊轩 3122004575 |
项目成员 | 雷棋皓 3122004868 |
github地址 | 项目地址 |
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 22 |
· Estimate | · 估计这个任务需要多少时间 | 500 | 511 |
Development | 开发 | 300 | 350 |
· Analysis | · 需求分析 (包括学习新技术) | 20 | 13 |
· Design Spec | · 生成设计文档 | 13 | 9 |
· Design Review | · 设计复审 | 9 | 10 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 5 | 6 |
· Design | · 具体设计 | 10 | 8 |
· Coding | · 具体编码 | 60 | 65 |
· Code Review | 代码复审 | 10 | 8 |
· Test | 测试(自我测试,修改代码,提交修改) | 60 | 50 |
Reporting | 报告 | 50 | 36 |
· Test Repor | 测试报告 | 20 | 30 |
· Size Measurement | 计算工作量 | 10 | 11 |
· Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 20 | 18 |
合计 | 500 | 511 |
性能分析
这里引入了cProfile进行性能分析
生成题目的过程:
生成题目的makeExe函数总体用了0.006秒,其中生成三个数运算题耗时最多。
核对答案的过程:
耗时0.002秒,性能较好
代码及设计
进行运算题操作的模块exercise:
类定义:
class exercise: def __init__(self, account=100, range=10): self.account = account self.range = range
生成题目函数:
def makeExe(self):
localtime = time.asctime(time.localtime(time.time()))
# 清理文件内容
with open("Exercise.txt", 'w') as exercise_file:
exercise_file.write("题目数量 : " + str(self.account) + "\t时间 :" + localtime + "\n")
exercise_file.close()
with open("Answer.txt", 'w') as Answer_file:
Answer_file.close()
que_order = 0
repeat = testRepeat()
makeQue = randomMake(repeat, self.range)
# 生成account道题
while que_order < self.account:
choose2_3 = 2 + random.randint(0, 1)
# 两个数的运算题生成
if choose2_3 == 2:
makeQue.question_2bits(que_order + 1)
# 三个数的运算题生成
elif choose2_3 == 3:
makeQue.question_3bits(que_order + 1)
que_order = que_order + 1
算法流程图:
核对答案函数:
def confirmExe(self, exeFile, userFile):
corrctQue = [] # 记录用户的错题和对题
wrongQue = []
try:
with open(exeFile) as exeFile: # 读取题目文件
with open(userFile) as userFile: # 读取用户文件
orderLine = 1 # 记录核对的第几道题
lineExe = exeFile.__next__()
fracAcc = fracHandle()
for lineExe in exeFile: # 遍历题目
lineExe = lineExe.strip()
div = lineExe.split(" ")
# 两个数的题目
if len(div) == 5:
frac1 = fracAcc.strToFrac(div[1])
frac2 = fracAcc.strToFrac(div[3])
rightAnswer = fracAcc.fracAccount(frac1, frac2, div[2])
rightAnswer = fracAcc.fracToStr(rightAnswer)
# 三个数
elif len(div) == 7:
# 如果式子中有括号
if '(' in lineExe:
for locate in range(7):
# 如果式子中有括号
if '(' in div[locate]:
# 如果括号在左边
if locate == 1:
leftFrac = fracAcc.strToFrac(div[1].replace("(", ""))
rightFrac = fracAcc.strToFrac(div[3].replace(")", ""))
thirdFrac = fracAcc.strToFrac(div[5])
firstSum = fracAcc.fracAccount(leftFrac, rightFrac, div[2])
rightAnswer = fracAcc.fracToStr(
fracAcc.fracAccount(firstSum, thirdFrac, div[4]))
else:
leftFrac = fracAcc.strToFrac(div[3].replace("(", ""))
rightFrac = fracAcc.strToFrac(div[5].replace(")", ""))
thirdFrac = fracAcc.strToFrac(div[1])
firstSum = fracAcc.fracAccount(leftFrac, rightFrac, div[4])
rightAnswer = fracAcc.fracToStr(
fracAcc.fracAccount(thirdFrac, firstSum, div[2]))
# 如果式子没括号
else:
leftFrac = fracAcc.strToFrac(div[1])
rightFrac = fracAcc.strToFrac(div[3])
thirdFrac = fracAcc.strToFrac(div[5])
if (div[2] == '+' or div[2] == '-') and (div[4] == '*' or div[4] == "÷"):
firstSum = fracAcc.fracAccount(rightFrac, thirdFrac, div[4])
rightAnswer = fracAcc.fracToStr(fracAcc.fracAccount(leftFrac, firstSum, div[2]))
else:
firstSum = fracAcc.fracAccount(leftFrac, rightFrac, div[2])
rightAnswer = fracAcc.fracToStr(fracAcc.fracAccount(firstSum, thirdFrac, div[4]))
else:
print("题目出错。")
try:
userAnswer = userFile.__next__().split(' ', 2)
# 如果用户答案还存在的话
if userAnswer[0] != '\n':
if (userAnswer[1].strip() == rightAnswer.strip()):
corrctQue.append(orderLine)
else:
wrongQue.append(orderLine)
# 用户答案已空
else:
print("同学,你第" + str(orderLine) + "题未完成。")
wrongQue.append(orderLine)
orderLine = orderLine + 1
except StopIteration:
print("同学,你第" + str(orderLine) + "题未完成。")
wrongQue.append(orderLine)
orderLine = orderLine + 1
print()
print("批卷完毕,答题情况如下:")
print("Correct: " + str(len(corrctQue)))
print(str(corrctQue))
print("Wrong: " + str(len(wrongQue)))
print(str(wrongQue))
# 答题情况写入Grade.txt
with open("Grade.txt", 'w') as grade_file:
grade_file.write("Correct: " + str(len(corrctQue)))
grade_file.write(str(corrctQue) + '\n')
grade_file.write("Wrong: " + str(len(wrongQue)))
grade_file.write(str(wrongQue) + '\n')
except FileNotFoundError:
print("找不到文件!请重新输入!")
算法流程图:
主函数
inputLen = len(argv)
if (inputLen == 5) and ('-r' in argv) and ('-n' in argv):
# 获取题目的数量和范围
for i in range(inputLen):
if argv[i] == '-r':
userRange = int(argv[i + 1])
elif argv[i] == '-n':
userAccount = int(argv[i + 1])
else:
continue
mathExercise = exercise(userAccount, userRange)
mathExercise.makeExe()
print("四则计算题已生成完毕,请在文件Exercise.txt中按格式完成。")
# 如果需要对答案
elif (inputLen == 5) and (argv[1] == '-e') and (argv[3] == '-a'):
mathExercise = exercise()
exerciseFile = argv[2] # 获取题目文件
answerFile = argv[4] # 获取用户需要核对的文件
mathExercise.confirmExe(exerciseFile, answerFile)
print("同学,您的答题情况已存入Grade.txt中")
else:
print("输入错误!正确的输入格式:python Myapp.py -n (...) -r (...)(n代表题目数量,r代表数字范围,请在括号内填写正确的数字)")
通过输入命令行语句,可进行题目生成与答案核对两个功能。
运行结果
这里采用了图形化设计:
界面整体:
输入题目数量与数值范围:
点击生成题目后,提示计算题生成完毕:
生成的exercise文件Exercise.txt:
生成的标准答案文件Answer.txt:
此时填写一个对应格式的用户答题的文件,此处取名为user.txt:
此处我故意把2、5、9题的答案写为错误答案
之后在程序中填写上题目文件名与用户填写的答案的文件名:
点击批阅题目后:
显示正确与错误的题目数与具体题号:
最后生成对应的Grade.txt文件:
项目小结
· 这次的结对项目让我们收获颇丰,因为之前我们都很少有这种双人合作共同完成一个项目的经验。
· 两个人合作的项目可以更好地帮助对方解决困难,二人之间的交流也可以提升代码的质量。
· 这次项目丰富了我们进行合作项目的经验,更好地体会到了如何进行多人的项目开发。