軟件工程第三週做業 —— 四則運算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()