自动生成小学四则算术题练习项目(新增真分数优化)
优化前:https://github.com/BlackJack1020/RJGCWorkTeam9527/commit/e8fc3a6dddb6e1cbea6c71538fc8d43338014048
优化后:https://github.com/BlackJack1020/RJGCWorkTeam9527/commit/fda39b7844c413a6d64f01eb8d2bb064008ff1bb
二、项目PSP表格
PSP表格指标 |
预估耗时(分钟) |
实际耗时(分钟) |
预估项目花费时间 |
170 |
175 |
需求分析与思路解析 |
20 |
17 |
代码实现 |
70 |
85 |
代码测试 |
30 |
22 |
代码优化 |
20 |
25 |
写博客 |
30 |
26 |
三、解题思路叙述
问题重述:
1.能自动生成小学四则运算题目(注意是给小学生用的,要是结果出现负数的话他们会迷茫的!)
2.除了整数外,还要支持真分数的四则运算
从上述项目要求,我们不难得知项目要求是编写出一个随机生成小学四则运算算术题的代码。
俗话说得好,不打无准备的仗。先把我们会用到的变量给罗列出来:
随机整数:rdnum (运用Python库中的random库中的randint方法随机生成一个整数)考虑到服务于小学水平,数字不宜过大,且简单四则运算可以为0(需注意除数不能为零即可),故设置范围为0~100
随机真分数分子:sdnum,随机真分数分母:mdnum,随机真分数即可表示为Fraction(sdnum, mdnum)(同样运用random库中的randint方法随机生成)
随机四则运算符:rdsign(通过random.choice(['+','-','*','/']) 来实现)
出题数:qesd(每次可以出多道题目,qesd必须为正整数)
理清我们所需的变量后,我们再来看代码运行过程:
1.用户输入计算类型(整数or真分数)
2.判断输入是否符合判断类型
3.用户输入题量qesd
4.通过qesd迭代,随机生成随机数和随机运算符的组合,剔除不符合条件的组合
5.计算结果后输出
6.效能分析
四、设计实现过程
实现类:三个类(除主类)分别为封装函数一:整数求解函数:zsResult();封装函数二:真分数求解函数:zsResult();运算函数:result(s,n1,n2)
其中,zsResult()和zsResult()中都调用运算函数result(s,n1,n2)来进行四则运算,同时result(s,n1,n2)类还负责输出结果
其中,运用random库中的randint方法随机生成整数,用random.choice(['+','-','*','/']) 来实现符号的随机生成,使用max()min()函数防止生成小数
五、关键代码说明
1.求解真分数:zsResult()
def zfsResult(): qesd = int(input()) for b in range(qesd): rdsign = random.choice(['+','-','*','/']) sdnum1 = random.randint(0,100) mdnum1 = random.randint(1,100) zfs1 = Fraction(sdnum1, mdnum1) sdnum2 = random.randint(1,100) mdnum2 = random.randint(1,100) zfs2 = Fraction(sdnum2, mdnum2) if zfs1 < zfs2: zfs1 = max(zfs1, zfs2) zfs2 = min(zfs1, zfs2) result(rsign,zfs1,zfs2) else: result(rsign,zfs1,zfs2)
2.求解整数:zsResult()
def zsResult(): qesd = int(input()) for a in range(qesd): rdsign = random.choice(['+','-','*','/']) rdnum1 = random.randint(0,100) rdnum2 = random.randint(0,100) if rdnum1 < rdnum2: rdnum1 = max(rdnum1, rdnum2) rdnum2 = min(rdnum1, rdnum2) rdesult(rdsign,rndum1,rdnum2) else: result(rdsign,rdnum1,rdnum2)
3.result(s,n1,n2)
def result(s,n1,n2): if s == '+': print('{} + {} = {}'.format(n1,n2,n1 + n2)) elif s == '-': print('{} - {} = {}'.format(n1,n2,n1 - n2)) elif s == '*': print('{} * {} = {}'.format(n1,n2,n1 * n2)) elif s == '/': if n2 == 0: print('***除数不能为零***') else: print('{} / {} = {}'.format(n1,n2,n1 / n2)) else: print('输入有误,请重新输入!')
用一个简单的主函数将上面的运算串联起来就能实现项目需求
六、测试运行
1.整数运算测试
2.真分数运算测试
七、代码优化
鉴于原本的真分数运算中,算式中出现有假分数出现,故对负责假分数运算的函数进行修改
def zfsResult(): qesd = int(input()) for b in range(qesd): rdsign = random.choice(['+','-','*','/']) sdnum1 = random.randint(0,100) mdnum1 = random.randint(1,100) if sdnum1<mdnum1: zfs1 = Fraction(sdnum1, mdnum1) else: zfs1 = Fraction(mdnum1, sdnum1) sdnum2 = random.randint(1,100) mdnum2 = random.randint(1,100) if sdnum2<mdnum2: zfs2 = Fraction(sdnum2, mdnum2) else: zfs2 = Fraction(mdnum2, sdnum2) if zfs1 < zfs2: zfs1 = max(zfs1, zfs2) zfs2 = min(zfs1, zfs2) result(rsign,zfs1,zfs2) else: result(rdsign,zfs1,zfs2)
测试结果如下
可以发现计算结果中仍旧有假分数,为了将假分数结果化成带分数,所以需要进一步的优化
我从两方面出发,一是将真分数和整数的运算函数分开,
#新增的真分数结果运算函数
def zfsResult(zfss,m1,m2): if zfss == '+': print('{} + {} = {}'.format(m1,m2,jhd(m1 + m2))) elif zfss == '-': print('{} - {} = {}'.format(m1,m2,jhd(m1 - m2))) elif zfss == '*': print('{} * {} = {}'.format(m1,m2,jhd(m1 * m2))) elif zfss == '/': if m2 == 0: print('***除数不能为零***') else: print('{} / {} = {}'.format(m1,m2,jhd(m1 / m2))) else: print('输入有误,请重新输入!')
二是增加一个将假分数运算结果转化成带分数的转化函数。
#假分数转化带分数
def jhd(f): a=f.numerator b=f.denominator if a%b==0: return '%d'%(a/b) elif a<b: return '%d%s%d' % (a,'/',b) else: c=int(a/b) a = a - c * b return '%d%s%d%s%d' % (c,'’',a,'/',b)
优化后测试结果如下
八、总结分析
经过这次的项目练习,我能感觉到规范的编程习惯对一个项目的重要性,比起过去的我,现在的我更有耐心去编程,但是这只是个人学习的一小步,在软件工程上来说,我还有很多东西要下功夫去学习。