四則運算器——軟件工程的第五次做業

Github項目地址:    https://github.com/cliohl/calculatorpython

PSPgit

PSP2.1github

personal Software Process Stagesapp

預估時間(分鐘)dom

實際耗時(分鐘)ide

Planning函數

計劃工具

 20性能

 30單元測試

· Estimate

· 估計這個任務須要多少時間

20

 30

Development

開發

 190

 268

· Analysis

· 需求分析 (包括學習新技術)

 10

 8

· Design Spec

· 生成設計文檔

 /

 /

· Design Review

· 設計複審 (和同事審覈設計文檔)

 /

 /

· Coding Standard

· 代碼規範 (爲目前的開發制定合適的規範)

 /

 /

· Design

· 具體設計

 60

 90

· Coding

· 具體編碼

 120

 150

· Code Review

· 代碼複審

 /

 /

· Test

· 測試(自我測試,修改代碼,提交修改)

 10

 20

Reporting

報告

 80

 60

· Test Report

· 測試報告+博客

 60

 50

· Size Measurement

· 計算工做量

 /

 /

· Postmortem & Process Improvement Plan

· 過後總結, 並提出過程改進計劃

 20

 10

合計

 

 300

 358

 

題目描述:

       (1)能自動生成小學四則運算題目,而且不能出現負數;

  (2)能支持真分數的四則運算;

思路:

        (1)四則運算加減乘除:因爲基礎不紮實,現只能實現兩個隨機正數的四則運算。

        (2)因爲不能出現負數,在進行減法運算的時候,我用了2種不一樣的方法實現,一種是先隨機生成減數,而後在0到減數之間隨機生成被減數,這樣能夠控制被減數必定小於減數,第二種是隨機生成兩個數,而後比較大小,大的數做爲減數,小的數做爲被減數。

        (3)在進行除法運算時,由於被除數不能爲零,因此在被除數的隨機取值範圍內不能包括0,在取隨機分數的時候,分母不能爲零,因此分母的隨機取值範圍也不包括0。

        (4)在進行真分數運算的時候,導入python自帶的fractions庫。

        (5)由於不包含假分數,因此在進行分數生成的時候也須要對分子和分母比較大小,大的數爲分子,小的數爲分母。

實現過程:

設計兩個函數:

        def create1(q,ans) 生成整數四則運算

        def create2(q,ans) 生成真分數四則運算

        def createf() 生成兩個真分數

函數關係:

        create1(q,ans)和create2(q,ans)均爲獨立的函數,負責生成四則運算。

        主函數部分主要分爲2大部分,第一個爲測試部分,第二個爲練習部分。測試部分能夠自定義題目數量及測試類型,測試完畢給出測試的分數,而且能夠選擇是否查看答案。練習部分也能夠自定義題目數量及測試類型,每完成一提都會判斷結果對錯,若是錯誤會給出正確答案。

代碼說明:

詳細代碼以下所示:

 1    def create1(q,ans)函數

 1 def create1(q, ans):   # 兩個整數的四則運算
 2     symbol = random.choice(['+', '-', '*', '/']) # 生成隨機符號
 3     if symbol == '+':
 4         n1 = random.randint(0, 100)  # 隨機生成0到100的整數
 5         n2 = random.randint(0, 100)
 6         q.append(str(n1) + ' + ' + str(n2)+' = ')
 7         ans.append(n1 + n2)
 8     elif symbol == '-':
 9         n1 = random.randint(0, 100)  # 隨機生成0到100的整數
10         n2 = random.randint(0, n1)
11         q.append(str(n1) + ' - ' + str(n2)+' = ')
12         ans.append(n1 - n2)
13     elif symbol == '*':
14         n1 = random.randint(0, 50)  # 隨機生成0到100的整數
15         n2 = random.randint(0, 50)
16         q.append(str(n1) + ' × ' + str(n2)+' = ')
17         ans.append(n1 * n2)
18     else:
19         n1 = random.randint(0, 50)  # 隨機生成0到100的整數
20         if n1 == 0:
21             n2 = random.randint(1, 50)
22         else:
23             n2 = random.randint(1, n1)
24             while n1 % n2 != 0:
25                 n1 = random.randint(1, 50)
26                 n2 = random.randint(1, n1)
27         q.append(str(n1) + ' ÷ ' + str(n2)+' = ')
28         ans.append(Fraction(n1, n2))

2    def createf()函數

 1 def createf():
 2     # 生成2個分數
 3     fz = random.randint(0, 20)
 4     if fz == 0:
 5         fm = random.randint(1, 20)
 6     else:
 7         fm = random.randint(fz,20)
 8     f1 = Fraction(fz, fm) # 第一個分數
 9     fz = random.randint(1, 20)
10     fm = random.randint(fz, 20)
11     f2 = Fraction(fz, fm) # 第二個分數
12     return f1, f2

3    def create2(q,ans)函數

 1 def create2(q, ans):   # 兩個分數的四則運算
 2     symbol = random.choice(['+', '-', '*', '/'])  # 生成隨機符號
 3     f1, f2 = createf()
 4     if symbol == '+':
 5         while f1 + f2 > 1:
 6             f1, f2 = createf()
 7         q.append(str(f1) + ' + ' + str(f2)+' = ')
 8         ans.append(f1 + f2)
 9     elif symbol == '-':
10         f1, f2 = max(f1, f2), min(f1, f2)
11         q.append(str(f1) + ' - ' + str(f2)+' = ')
12         ans.append(f1 - f2)
13     elif symbol == '*':
14         while f1 * f2 > 1:
15             f1, f2 = createf()
16         q.append(str(f1) + ' × ' + str(f2)+' = ')
17         ans.append(f1 * f2)
18     else:
19         while Fraction(f1, f2) > 1:
20             f1, f2 = createf()
21         q.append(str(f1) + ' ÷ ' + str(f2)+' = ')
22         ans.append(Fraction(f1, f2))

4    主函數

 1 while 1:
 2     print("請輸入類型:一、測試 2 、練習 三、退出")
 3     t = int(input())
 4     if t == 3:
 5         break
 6     elif t == 1:           # 測試
 7         print("請輸入你想要的四則運算:一、整數 二、分數 三、混合 4 、退出")
 8         n = int(input())
 9         while n > 4:
10             print("選擇類型有誤!請從新選擇")
11             n = int(input())
12         if n == 4:
13             break
14         print("請輸入你想要的題目數量(5的倍數):", end='   ')
15         qu = int(input())
16         while qu % 5 != 0:
17             print("輸入數目有誤,請從新輸入!")
18             qu = int(input())
19         pscore = 100 / qu
20         sscore = 0
21         ques = []
22         ans = []
23         if n == 1:         # 整數測試題目
24 
25             for i in range(qu):
26                 create1(ques, ans)
27         elif n == 2:        #分數測試題目
28             for i in range(qu):
29                 create2(ques, ans)
30         elif n == 3:            # 混合測試題目
31             for i in range(qu):
32                 n = random.randint(0, 3)
33                 if n == 0:
34                     create2(ques, ans)
35                 else:
36                     create1(ques, ans)
37         for i in range(qu):
38             print("第{}題:{}".format(i + 1, ques[i]),end='  ')
39             a = input()
40             if a == str(ans[i]):
41                 sscore = sscore + pscore
42         print("你所得分數爲:{}".format(sscore))
43         print("是否查看正確答案? y/n", end='  ')
44         pan = input()
45         if pan == 'y':
46             for i in range(qu):
47                 print(ques[i] + str(ans[i]))
48     elif t == 2:
49         print("請輸入你想要的四則運算:一、整數 二、分數 三、混合 四、退出")
50         n = int(input())
51         while n > 4:
52             print("選擇類型有誤!請從新選擇")
53             n = int(input())
54         if n == 4:
55             break
56         print("請輸入你想要的題目數量:")
57         qu = int(input())
58         ques = []
59         ans = []
60         if n == 1:                # 整數練習題目
61             for i in range(qu):
62                 create1(ques, ans)
63         elif n == 2:               # 分數練習題目
64             for i in range(qu):
65                 create2(ques, ans)
66         elif n == 3:                     # 混合練習題目
67             for i in range(qu):
68                 n = random.randint(0,3)
69                 if n == 0:
70                     create2(ques, ans)
71                 else:
72                     create1(ques, ans)
73         else:
74             print("選擇類型有誤!請從新選擇")
75         for i in range(qu):
76             print("第{}題:{}".format(i + 1, ques[i]),end='  ')
77             a = input()
78             if a == str(ans[i]):
79                 print("回答正確!")
80             else:
81                 print("回答錯誤!正確答案爲:{}".format(ans[i]))
82     else:
83         print("選擇類型有誤!請從新選擇")
View Code

測試運行:

單元測試:

            測試create1(q,ans)函數,通過查找發現錯誤以下:

            

            這裏我忽略了當n1爲0時的狀況,致使運行出錯。

            改進以下:

            

            問題解決。

            測試create2(q,ans)函數,通過查找發現錯誤以下:

            

            這裏我沒有考慮到當結果大於1成爲假分數的狀況,改進以下:

           

           問題解決。     

全體測試運行結果以下:

           

           

             

效能分析: 

PyCharm提供了性能分析工具Run——Profile。

以下圖所示:

        

 性能統計界面由Name、Call Count、Time(ms)、Own Time(ms) 4列組成一個表格,見下圖。

 (表頭Name顯示被調用的模塊或者函數;Call Count顯示被調用的次數;Time(ms)顯示運行時間和時間百分比,時間單位爲毫秒(ms)。)

能夠看到,用戶輸入佔用了100%的時間,說明本代碼的絕大部分時間都是在等待用戶輸入。        

如今來看看create1(q,ans)函數,create2(q,ans)函數,create1()函數的性能測試。以下圖所示:

能夠看到,生成整數題目調用了20次,生成分數調用了8次,生成分數題目調用了5次,所佔時間都爲0,說明函數調用佔比只佔了不多的一部分。

本代碼還有很大的改進空間,礙於能力與時間問題,就先不進行改進,往後有時間再修改代碼及分析。

我的感想:

        看到這個題目以後的第一感受好像很簡單,但是真正動手去作才知道有不少細節是須要注意的。剛開始我是想作一個能夠自由控制多項式項數的,可以進行混合運算的四則運算器,但是後來發現有不少的小細節都卡住了思路,無奈之下只能先完成兩項的混合運算,等往後有空再鑽研混合運算及能夠添加括號的四則運算器。經過此次這個小項目,能夠發現本身許多的不足之處。原來作個項目是須要通過這麼多的步驟才能夠慢慢實現,經過閱讀構建之法的前3章,清楚的認識到本身的水平,往後還有待加油。但願明天的本身會比今天的本身更好。

相關文章
相關標籤/搜索