软件工程2017第二次作业随笔-何保委

1.Github项目地址 : https://github.com/hebaowei/test

2.PSP表格

 

PSP2.1 Personal Software Process Stages 预估耗时(小时) 实际耗时(小时)
Planning 计划 0.5  0.5
Estimate 估计这个任务需要多少时间 5 6
Development 开发 20 24
Analysis 需求分析 (包括学习新技术) 1 2
Design Spec 生成设计文档 0.5 0.5
Design Review 设计复审 (和同事审核设计文档) 1 1
Coding Standard 代码规范 (为目前的开发制定合适的规范) 1 1
Design 具体设计 10 15
Coding 具体编码 5 6
Code Review 代码复审 2
Test 测试(自我测试,修改代码,提交修改) 1 1
Reporting 报告 0.5 0.5
Test Report 测试报告 0.5  0.5
Size Measurement 计算工作量 0.5  0.5
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划  0.5 1
合计    >40  >>50

3.解题思路:

 基于python编程

我最先的想法是先把软件的四个基本功能先用代码实现,然后在基本功能实现的情况下,将附加功能一个一个加上去,最终得到一个完整的“软件”。

基本功能:

1.参与运算的操作数(operands)除了100以内的整数以外,还要支持真分数的四则运算,例如:1/6 + 1/8 = 7/24。操作数必须随机生成。

2.运算符(operators)为 +, −, ×, ÷ (如运算符个数固定,则不得小于3)运算符的种类和顺序必须随机生成。

3.要求能处理用户的输入,并判断对错,打分统计正确率。

4.使用 -n 参数控制生成题目的个数,或通过用户交互过程确定题目个数,例如执行下面命令将生成5个题目。

对于基本功能1,操作数可以使用函数random.randiant(1,9)实现,而分数可以使用Fraction函数,最终得到一个真分数;

对于基本功能2,运算符可以用random函数来在在字符数组中任意选取;

对于基本功能3,将题目答案实先存在数组中,将用户输入的答案与正确答案比较,使用if语句来判断用户的输入答案是否正确,并且计算得分;

对于基本功能4,可以在最开始就设定好题目的个数n。

附加功能:

1.运算符个数随机生成(考虑小学生运算复杂度,范围在1~10)。

2.设计并实现一种合理的根据题目难度分配不同分值的方案。

3.设计并实现一种计时机制,能够实现超时停止答题,或者根据答题用时调整分数。

4.防止随机生成的题目发生重复。

对于附加功能1,首先用random函数随机产生一个9以内的整数,代表参与运算符的个数,有多少个符号就有多少个数字+1个;

对于附加功能2,用参与运算的数字个数来代表运算难度;

对于附加功能3,给每道题设定60s的作答时间,超过时间则自动显示下一题;

对于附加功能4,可以先定义一个题目字符串数组,将每次产生的题目字符串与之前的进行比较,若不相同,则打印出来并存储在数组中。

 

4.设计实现过程

我的想法是最先打印出n让用户输入题目数量,然后可以开始显示题目和分数,最终输出总得分。

在主函数中调用出产生题目的函数;

在产生题目函数中首先生成题目(将新生成题目与题目数组进行比对,查看是否重复),并且打印在屏幕上。同时调用计算答案的函数用于得到新生成题目的答案;同时设定计时功能,统计分数功能,再提示让用户输入答案,将用户所输入的答案与真实答案进行比较,输出结果;

个人觉得最困难的部分是计算答案的函数,大致思路是将算术表达式的运算符号通过遍历,按优先级进行计算(程序中没有括号)。

 

 

 

5.主要代码说明

  #得到一道题目 返回这道题的得分,有时间限制
def one_question():
opers = ['+', '-', '*', '÷']
timu = [] #存放每一题
oper_count = random.randint(1, 9) #参与操作的数字个数
timu.append(Fraction(random.randint(1, 9), 1))
for i in range(oper_count):
timu.append(opers[random.randint(0, 3)])
ch=random.randint(1,5) #有20%的机会产生分数,80%的机会产生整数
if ch==1:
a=random.randint(1,9)
b=random.randint(1,9)
if a>=b:
c=Fraction(b,a)
timu.append(Fraction(c))
else:
c=Fraction(a,b)
timu.append(Fraction(c))
else:
timu.append(Fraction (random.randint(1,9),1))
timu_str = toString(timu)
if timu_str in list_timu:
return one_question()
list_timu.append(timu_str)
print('题目: %s' % timu_str)
print('分值: %d分' % oper_count)
res= getResult(timu)
context['data'] = '超时'
t = threading.Thread(target=input_func, args=(context, ))
t.start() #计时功能
t.join(60) # 等待60秒
if str(res) == context['data']:
print('回答正确,加%d分' % oper_count)
return oper_count
else:
if context['data'] == '超时':
print('超时')
return 0
else:
print("回答错误,正确答案是: %s" % str(res))
return 0


#计算题目的结果,利用栈计算表达式的值。
def getResult(timu):
res = []
res.append(timu[0])
for i in range(1, len(timu), 2): #遍历所有操作符
if timu[i] == '+' or timu[i] == '-':#将操作符的优先级进行比较从而堆栈
res.append(timu[i])
res.append(timu[i+1])
elif timu[i] == '*':
res[len(res)-1] = res[len(res)-1] * timu[i+1]
elif timu[i] == '÷':
res[len(res)-1] = res[len(res)-1] / timu[i+1]
sum = res[0]
for i in range(1, len(res), 2):
if res[i] == '+':
sum = sum + res[i+1]
elif res[i] == '-':
sum = sum - res[i+1]
elif res[i] == '*':
sum = sum * res[i+1]
elif res[i] == '÷':
sum = sum / res[i+1]
return sum

6.测试运行

 

 答案正确,答案错误,超时三种情况都出现了。就能够过多次测试,程序可行。

 

7.项目小结

由于对编程基础学习掌握不牢,需要花费很多时间去重新学习,但是在期末备考的情况下,各种答疑和课程把课表安排得比较满,没有得到充分的一大块时间去好好编程,往往都是利用零碎时间去完成作业,交作业前的最后几天,都是中午没睡觉和晚上加班在进行代码编写和调试,最终完成的作业也算是勉强完成。

我想,这很大一部分原因是因为自己没有把全部精力放在这门课上,因为在本学期课程安排的很满的情况下,导师也会安排比较多的实验任务,很难完全放开投入到一门非专业课上面去;还有一部分原因是因为自己担任队内的足球队队长,由于要负责组织训练等活动,每天的自由时间都会被占用一大半,所以基本都是利用晚上零散的时间来进行学习;最后一个原因是因为最近安排了三门公共基础课的考试,备战期末的人物比较繁重,时间上我也进行了一定的安排,所以每天来完成作业的时间不够。

回到我这个程序的功能,题目要求的功能基本全部实现,但是我个人感觉最大的问题在于分数对于每道题的分配方面,本人的程序并没有做到总分在100分的前提下生成n道题,然后对每道题根据难度进行分数的分配,而是直接根据参与运算的数字个数来分配分数;第二个问题就是没有能对括号()进行优先级运算比较。

经过这次比较漫长的作业,我个人感觉最大的收获就是算是开始对python学习上手了,虽然花费在上面的时间占据了我其他学科的时间,但我相信有付出也会有回报。虽然花费了很多时间在编程上面,但最终程序能够调试出来,也是比较满意的。

关于时间分配这方面,我也和导师商量过,他说你就利用好这点时间好好把python学一学,将来对专业课也有一定作用。所以下一步我也打算好好学习利用python,在完成专业课学习的基础上更大可能地拓展自己的全面性。

原文地址:https://www.cnblogs.com/hbw188/p/8127567.html