四则运算器——软件工程的第五次作业

Github项目地址:    https://github.com/cliohl/calculator

PSP

PSP2.1

personal Software Process Stages

预估时间(分钟)

实际耗时(分钟)

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("请输入类型:1、测试 2 、练习 3、退出")
 3     t = int(input())
 4     if t == 3:
 5         break
 6     elif t == 1:           # 测试
 7         print("请输入你想要的四则运算:1、整数 2、分数 3、混合 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("请输入你想要的四则运算:1、整数 2、分数 3、混合 4、退出")
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章,清楚的认识到自己的水平,日后还有待加油。希望明天的自己会比今天的自己更好。

posted @ 2018-04-19 01:08  chanhuiling  阅读(276)  评论(0编辑  收藏  举报