四則運算

軟件工程第三週做業 —— 四則運算git

 

1. 項目要求

1.1 要求闡述

  • 生成小學四則運算題題目,結果不能爲負數
  • 支持真分數的四則運算

1.2 詳細要求 【易知大學

1.3 詳細代碼 【GitHub

2. PSP表格

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. 解題思路描述

  將問題分解爲兩部分:第一部分生成算式,第二部分計算算式的值。

3.1 第一部分

  生成算式分爲三個小步驟。

  首先,使用隨機數生成操做數與運算符,經過參數設置操做數與運算符的數量,再將其拼接爲算式,如3×7+9÷3。

  其次,在算式上插入括號,括號插在有乘除附近的加減子算式中,如3×(7+9)÷3。

  最後,在算式的基礎上將其中的數字替換爲分數,若是不想使用分數則跳過此步驟。

3.2 第二部分

  計算算式的值,將算式轉爲逆波蘭式,以後使用棧計算算式結果,結果保留分數形式,如7/2。

4. 設計實現過程

4.1 參數說明

  建立OPT方法存儲相關參數,如操做數數值上限、操做數個數、使用的運算符種類、是否包含分數。

4.2 生成算式

  使用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)

整合生成算式的後綴表達式,帶括號

4.3 計算算式

  使用ComputeFormular類計算算式,經過將中綴表達式轉爲後綴表達式,使用棧計算結果。

 

 

方法

說明

1

def getPostFormular(self, formular)

中綴表達式轉爲後綴表達式

2

def calcFormular(self, formular)

計算算式的值

3

def solve(self, formular)

整合計算中綴表達式的值

 

5. 代碼示例

5.1 GeneralFormular.getOriginFormular()方法

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

 

5.2 GeneralFormular.insertBracket()方法

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

 

6. 測試運行

6.1 不包含分數

6.2 包含分數

7. 單元測試

 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()

 

 

8. 性能分析

8.1 GeneralFormular.getOriginFraction()方法

8.2 GeneralFormular.replaceFraction()方法

8.3   GeneralFormular.solve()方法

8.4 ComputeFormular.solve()方法

相關文章
相關標籤/搜索