第一次软件工程作业(改进版)
1、Github项目地址:https://github.com/HardenMVB/3.28
2、PSP
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
60 |
90 |
· Estimate |
· 估计这个任务需要多少时间 |
60 |
90 |
Development |
开发 |
1650 |
2050 |
· Analysis |
· 需求分析 (包括学习新技术) |
200 |
300 |
· Design Spec |
· 生成设计文档 |
50 |
60 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
20 |
30 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
20 |
30 |
· Design |
· 具体设计 |
60 |
50 |
· Coding |
· 具体编码 |
1200 |
1500 |
· Code Review |
· 代码复审 |
60 |
50 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
40 |
30 |
Reporting |
报告 |
90 |
60 |
· Test Report |
· 测试报告 |
50 |
10 |
· Size Measurement |
· 计算工作量 |
20 |
20 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
20 |
30 |
合计 |
|
1800 |
2200 |
3、解题思路
拿到题目后,先想它能实现哪些功能,再想代码能分成几个部分实现,分层次处理。本题中基础功能就是整数的四则运算,非负数,接着就是加入真分数的部分。
这两个功能完成后就可以考虑一些其他功能,比如如果出现假分数,如何转化成真分数,如何约分,以及判断题目有无重复等等。
4、设计实现
先建立命令控制模块,可以控制输入的题目数量以及数值范围。再创建一个函数,用来生成随机数与运算符(+ , - , × , ÷ ),再设计一个函数用来将假分数转换为真分数。接着生成表达式,进而生成题目和对应的答案,以及查找有无重复。
最后将题目及答案写入文件中,结果会在文件中显示出来。
5、代码说明
1、命令行控制模块
def get_Parameter():#命令行控制模块 parser = argparse.ArgumentParser() parser.add_argument('-n', help='设定题目数量',type=int) parser.add_argument('-r', help='设定数值范围',type=int) return parser.parse_args()
2、生成随机数和运算符
def get_num_sym(i,r):#获取数值列表和符号列表 nlist=[] #数值列表 slist=[] #符号列表 kh=0 #判断怎么加括号 jian=0 #判断是否是减数运算 for m in range(i+1): #根据i的值遍历输出数值列表 nlist.append(Fraction(random.randint(1, r), random.randint(1, r))) for x in range(i): sy=random.choice(['+','-','×','÷']) if sy=='+'or sy=='-': kh +=10**(i-x-1) else : kh += 2 * (10 ** (i - x - 1)) slist.append(sy) if sy=='-': l=1 return nlist,slist,kh,i,jian
3、分数转换及运算
def calculate(a,b,s):#计算单元,a,b是数,s是符号 ans=0 if s=='+': #加法运算 ans=a+b elif s=='-': #减法运算 a,b=max(a,b),min(a,b) #防止结果为负数 ans=a-b elif s=='×': #乘法运算 ans=a*b else:ans=a/b #除法运算 return ans
4、生成题目及答案
def gett(n,r): #用于生成题目和答案列表 E,A,E1,E2=[],[],[],[] global j,k x=1 while x<n+1: #循环生成题目和答案列表 i=random.randint(1, 3) #随机获取符号数目 num,slist,kh,i,jian=get_num_sym(i,r) num1=num legal = True if jian==1: #用于防止减法运算出现负数 if num[0]<num[1]: num1[0],num1[1]=num[1],num[0] if i>=2 and calculate(num[0],num[1],slist[0])<num[2]: num1[0],num1[1],num1[2]=num[2],num[0],num[1] j=1 if i>=3 and calculate(calculate(num[0],num[1],slist[0]),num[2],slist[1])<num[3]: num1[0],num1[1],num1[2],num1[3]=num[3],num[0],num[1],num[2] k=1 ans=num1[0] for y in range(i): cal=calculate(ans,num[y+1],slist[y]) if cal>=0: ans=cal else: legal=False break if legal: #判断算式是否重复 try: num=A.index(ans) #第一个答案的索引 except ValueError as e: #可以写入 A.append(ans) E1.append(slist) E2.append(num1) E.append('%d. %s'%(x,writet(slist,num1,kh))) x+=1 else:pass return E,A
5、写入文件
def savet(fname, d):#fname为写入文件的路径,d为要写入的数据列表 file = open(fname,'a') file.seek(0) file.truncate() #清空 for i in range(len(d)):#循环写入文件fname s = str(d[i]).replace('[','').replace(']','') s = s.replace("'",'').replace(',','') +'\n' file.write(s) file.close() print('%s文件已保存'%fname)
6、main函数
def main():#主函数 args = get_Parameter() if args.n: n=args.n print('共生成%d道题目'%n) if args.r: r=args.r print('均为%d以内的四则运算'%r) E, A=gett(n,r) for x in range(n):#循环生成答案列表 A[x]='%d. %s'%(x+1,fens(A[x])) savet('Exercises.txt',E) savet('Answers.txt',A) end = time.clock() print('运行时间: %s '%(end-start)) if __name__ == '__main__': main()
6、测试运行
7、效能分析
8、改进
程序一开始出现多元式子时,只计算第一个和最后一个的结果,于是我改进了程序,使得能计算出每个数的值。
此程序中我没有使用循环将出现负数结果的式子删除,而是简单的把此式子的被减数与减数交换,使之计算出正值。
9、收获
在这次实践中,我体会到了软件工程的不易。想要一个人真正做好一个项目是要花费大量时间的,想要一周完美的写好这个项目有点困难,还是有很多漏洞没有处理;做出的程序也不完整,有很多功能没有实现。
这也体现出了团队的重要性,一方面会有人监督,帮你找出错误,另一方面分工合作,花费的时间也会减少。不过我还是从这次项目中学到了很多技巧,希望下一次的项目可以完成的更好。