组员
涂家瑜 201422122031
陈宏辉 201421122020
代码地址:https://coding.net/u/rovinglight/p/sums-generator/git
本次作业的完成内容
本次作业基于个人作业一的四则运算程序做增量开发,新增了如下功能
1、添加了用户界面,并带有切换语言和计时的功能
2、新增加了四则运算计算器
3、记录做题的正确率
需求分析
这是一个简单的四则运算计算器,不但可以生成四则运算的式子,也可以计算除了随机生成四则运算的式子。有时候我们做练习题不仅需要得到题目的正确率,还需要在限定时间内完成练习,这时候需要这个程序有一个计时功能,在开始练习的时候开始计时,到练习完成计算所花时间。
思维导图
代码展示:
(基于python计算四则运算)
#!/usr/bin/python # coding=utf-8 # 本程序由用户输入一个表达式字符串,然后计算这个表达式的值 # 表达式是一个四则运算表达式,可以包含^操作符 # 注意:乘方用^运算符,支持".3"这种表示小数的形式。负数需要用括号扩起来 # 思路:利用栈的方法,先将表达式从中缀表达式转换成后缀表达式,再进行计算 def isNum(value): try: value + 1 except TypeError: return False else: return True def cal(strexpp): ''' 本函数由一个四则运算表达式字符串计算表达式的值 strexpr为一个四则运算表达式,如果这个表达式正确,则函数返回这个表达式的值,否则返回NULL ''' seqLegalChar = ( '+', '-', '*', '/', '(', ')', '^', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.') # 表达式中合法的字符集 seqOpr = seqLegalChar[0:7] # 运算符序列 seqOpa = seqLegalChar[7:18] # 操作数序列 # 表达式为空,则返回Null if len(strexpp) == 0: return Null # 去掉字符串中的空格,使用replace(old,new[,max]) strexpr = strexpp.replace(' ', '') # 表达式包含不合法的支付,则返回Null for ch in strexpr: if ch not in seqLegalChar: return Null # 将表达式变成一个数字和符号的序列 numstart = -1 # 标识数字的起始位置为numstart+1 seqExpr = [] # 表达式序列 for i in range(0, len(strexpr)): # 将表达式的数字和符号依次输出到序列 # 本位置指向的是一个操作数, if (strexpr[i] in seqOpa): if numstart < 0: # 如果numstart小于0,使numstart指向本位置数字开始的地方 numstart = i if i == len(strexpr) - 1: # 已读取到表达式最后一个字符,将数字转换后入列 seqExpr.append(float(strexpr[numstart:len(strexpp)])) continue # 本次读取的字符是一个符号 if numstart >= 0: # 如果numstart大于0,则说明numstart与本位置之间是数字,需要提取数字。如果numstart==-1,则表明中间都是符号 seqExpr.append(float(strexpr[numstart:i])) # 中间是数字,将数字转换后输出到序列 seqExpr.append(strexpr[i]) # 将本次符号输出到序列 numstart = -1 # 将numstart指针修改为本次位置 # 将中缀表达式转换成为后缀表达式 seqPosfix = [] # 后缀表达式序列,完成后seqPosfix中即为后缀表达式 stkOpra = [] # 转换中所需要的符号栈 for op in seqExpr: if isNum(op): # 如果是数字,则直接输出到后缀表达式序列 seqPosfix.append(op) continue if not stkOpra: # 如果符号栈为空,则直接压入第一个符号 stkOpra.append(op) continue if op == ')': # 如果是')',需要匹配以前的'(',栈顶元素依次出栈输出,知道'('为止 while stkOpra[len(stkOpra) - 1] != '(': seqPosfix.append(stkOpra.pop()) # 将'('弹出 stkOpra.pop() elif op in ['+', '-']: # 如果是'+'或者'-',优先级最低 while (stkOpra and (stkOpra[len(stkOpra) - 1] != '(')): seqPosfix.append(stkOpra.pop()) stkOpra.append(op) elif op in ['*', '/']: # 如果是'*','/',栈顶是'*','/','^'则弹出,否则入栈 while (stkOpra and (stkOpra[len(stkOpra) - 1] == '^')): seqPosfix.append(stkOpra.pop()) stkOpra.append(op) elif op in ['^', '(']: # 如果是'^'和'(',优先级最高,则直接入栈 stkOpra.append(op) while stkOpra: # 到最后如果符号栈不为空,则将符号栈的符号全部出栈 seqPosfix.append(stkOpra.pop()) # 根据后缀表达式seqPosfix计算值 stkNumb = [] # 装载操作数和值的栈 for op in seqPosfix: if isNum(op): stkNumb.append(op) # 如果是数字,直接进栈 continue p1 = stkNumb.pop() # 弹出两个操作数 p2 = stkNumb.pop() if op == '^': # 根据运算符计算操作数的值 p = p2 ** p1 elif op == '*': p = p2 * p1 elif op == '/': p = p2 / p1 elif op == '+': p = p2 + p1 elif op == '-': p = p2 - p1 stkNumb.append(p) # 将计算结果入栈 return stkNumb.pop() # 最后的结果 expr = input("请输入一个四则运算表达式(负数需要用括号扩起来,乘方用'^'运算符):") res = cal(expr) if not res: print("你输入的四则运算表达式包含有不正确的字符,请检查后重新输入。") else: print("结果为:%f" % res)
代码演示
小结感受
这次作业对于我来说并不算成功,没能及时在交作业前把python学到django的部分,所以网页上还没办法掉我我做的部分只能先把编译器上运行成功的先拿来演示,这也是我后面需要在加快脚步避免影响到下一次作业出现同样的问题。个人认为结对变成对提高手写能力是有很大的帮助的,从开学python懵懵懂懂到现在能写出一个四则运算是一个很明显的进步,但是进度还是太慢了。第一次次作业就做的很吃力。这次又需要在上次的基础上优化,时间也是不太够,还需要其它事情要做,所有没使用django。程序的基本功能在这个程序有体现,由于是控制台,有一些操作无法实现。
评价合作伙伴
陈宏辉和我在大学期间有过多次课程设计的组队经验,他很好的帮助完成了很多功能的实现,他知道我在尝试新的语言完成作业会比较吃力,所以他也用他的强项来弥补我在python编程上经验不足的问题
展示PSP
PSP2.1 |
Personal Software Process Stages |
Time Senior Student |
Time |
Planning |
计划 |
18 |
29 |
· Estimate |
估计这个任务需要多少时间 |
20 |
28 |
Development |
开发 |
552 |
573 |
·Analysis |
需求分析 (包括学习新技术) |
40 |
35 |
· Design Spec |
生成设计文档 |
35 |
30 |
· Design Review |
设计复审 |
18 |
26 |
· Coding Standard |
代码规范 |
19 |
15 |
· Design |
具体设计 |
46 |
35 |
· Coding |
具体编码 |
264 |
263 |
· Code Review |
代码复审 |
40 |
26 |
· Test |
测试(自我测试,修改代码,提交修改) |
40 |
50 |
Reporting |
报告 |
63 |
84 |
|
测试报告 |
10 |
8 |
|
计算工作量 |
28 |
20 |
|
并提出过程改进计划 |
15 |
17 |