软件工程第三周做业 —— 四则运算git
PSP2.1github |
Personal Software Process Stagesdom |
预估耗时(分钟)性能 |
实际耗时(分钟)单元测试 |
Planning学习 |
计划测试 |
15编码 |
25spa |
Estimate设计 |
估计这个任务须要多少时间 |
15 |
25 |
Development |
开发 |
247 |
395 |
Analysis |
需求分析 (包括学习新技术) |
30 |
45 |
Design Spec |
生成设计文档 |
30 |
30 |
Design Review |
设计复审 (和同事审核设计文档) |
15 |
10 |
Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
12 |
10 |
Design |
具体设计 |
30 |
35 |
Coding |
具体编码 |
60 |
180 |
Code Review |
代码复审 |
30 |
20 |
Test |
测试(自我测试,修改代码,提交修改) |
40 |
65 |
Reporting |
报告 |
85 |
60 |
Test Report |
测试报告 |
30 |
25 |
Size Measurement |
计算工做量 |
30 |
10 |
Postmortem & Process Improvement Plan |
过后总结, 并提出过程改进计划 |
25 |
25 |
合计 |
|
347 |
480 |
将问题分解为两部分:第一部分生成算式,第二部分计算算式的值。
生成算式分为三个小步骤。
首先,使用随机数生成操做数与运算符,经过参数设置操做数与运算符的数量,再将其拼接为算式,如3×7+9÷3。
其次,在算式上插入括号,括号插在有乘除附近的加减子算式中,如3×(7+9)÷3。
最后,在算式的基础上将其中的数字替换为分数,若是不想使用分数则跳过此步骤。
计算算式的值,将算式转为逆波兰式,以后使用栈计算算式结果,结果保留分数形式,如7/2。
建立OPT方法存储相关参数,如操做数数值上限、操做数个数、使用的运算符种类、是否包含分数。
使用GeneralFormular类生成算式的中缀表达式,其中包含8个方法。
|
方法 |
说明 |
1 |
def catFormula(self, operand1, operator, operand2) |
链接算式 |
2 |
def getRandomIntOperand(self) |
返回随机整数操做数 |
3 |
def getRandomFractionOperand(self) |
返回随机分数操做数 |
4 |
def getRandomOperator(self) |
返回随机运算符 |
5 |
def getOriginFormular(self) |
生成整数源算式 |
6 |
def insertBracket(self, formular) |
插入括号 |
7 |
def replaceFraction(self, formular) |
带入分数 |
8 |
def solve(self) |
整合生成算式的后缀表达式,带括号 |
使用ComputeFormular类计算算式,经过将中缀表达式转为后缀表达式,使用栈计算结果。
|
方法 |
说明 |
1 |
def getPostFormular(self, formular) |
中缀表达式转为后缀表达式 |
2 |
def calcFormular(self, formular) |
计算算式的值 |
3 |
def solve(self, formular) |
整合计算中缀表达式的值 |
def getOriginFormular(self): ''' * 生成整数源算式 * @return {str} ''' # 经过self.opt.oper_num控制操做数个数,循环调用catFormula()方法构造算式 tmp = self.getRandomIntOperand() for i in range(self.opt.oper_num-1): tmp = self.catFormula(tmp, self.getRandomOperator(), self.getRandomIntOperand()) # 去掉'÷0' while(True): if '÷0' in tmp: tmp = tmp.replace('÷0', '÷'+str(self.getRandomIntOperand())) else: break return tmp
def insertBracket(self, formular): ''' * 插入括号 * @param formular {str} 源算式 * @return {str} ''' # print(formular) # 若只包含+号 或 只有两个操做数 则不用加括号 if self.opt.oper_variety <= 2 or self.opt.oper_num == 2: return formular # 若不包含×÷ 则不用加括号 if '×' not in formular and '÷' not in formular: return formular # 操做数列表 operand_list = re.split("[-|+|×|÷]", formular) # 操做符列表 operator_list = re.split("[!0-9]", formular) # 去掉空字符 while '' in operator_list: operator_list.remove('') # print(operand_list, operator_list) # 存储添加括号的算式 new_formular = "" # flag表示是否已存在左括号,做用在于构造出一对括号 flag = 0 # 添加括号 for i in range(len(operator_list)): oper = operator_list.pop(0) # 若下一个符号为 + or - , 则插入括号 if oper == '-' or oper == '+': if flag == 0: new_formular += "(" flag = 1 new_formular += (str(operand_list.pop(0)) + str(oper)) else: new_formular += str(operand_list.pop(0)) if flag == 1: new_formular += ")" flag = 0 new_formular += str(oper) # print(operand_list, operator_list, new_formular) new_formular += str(operand_list.pop(0)) if flag == 1: new_formular += ")" return new_formular
1 import unittest 2 from formula import OPT, GeneralFormular, ComputeFormular 3 4 class FormulaUnitTest(unittest.TestCase): 5 def test_gf_catFormular(self): 6 ''' 7 * 测试拼接算式 8 ''' 9 gf = GeneralFormular(OPT()) 10 self.assertEqual(gf.catFormula("12", "+", "34"), "12+34") 11 self.assertEqual(gf.catFormula("23", "+", "456"), "23+456") 12 self.assertEqual(gf.catFormula("1z", "+", "32"), "1z+32") 13 14 def test_cf_getPostFormular(self): 15 ''' 16 * 测试中缀表达式转为后缀表达式 17 ''' 18 cf = ComputeFormular() 19 self.assertEqual(cf.getPostFormular("3+7"), "3#7#+") 20 self.assertEqual(cf.getPostFormular("3×(7+2+1)"), "3#7#2#+1#+×") 21 self.assertEqual(cf.getPostFormular("6×(2+1)÷(9-2+3)"), "6#2#1#+×9#2#-3#+÷") 22 self.assertEqual(cf.getPostFormular("6×(2+1)÷0"), "6#2#1#+×0#÷") 23 24 def test_cf_calcFormular(self): 25 ''' 26 * 测试后缀表达式计算为数值 27 ''' 28 cf = ComputeFormular() 29 self.assertEqual(cf.calcFormular("3#7#+"), "10") 30 self.assertEqual(cf.calcFormular("3#7#2#+1#+×"), "30") 31 self.assertEqual(cf.calcFormular("6#2#1#+×9#2#-3#+÷"), "9/5") 32 self.assertEqual(cf.calcFormular("6#2#1#+×0#÷"), "NaN") 33 34 35 if __name__ == "__main__": 36 unittest.main()