Github项目地址:

https://github.com/JtvDeemo/elementary-arithmetic

PSP

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 10 10
· Estimate · 估计这个任务需要多少时间 1440 920
Development 开发 700 200
· Analysis · 需求分析 (包括学习新技术) 180 240
· Design Spec · 生成设计文档 5 5
· Design Review · 设计复审 (和同事审核设计文档) 10 15
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 5 5
· Design · 具体设计 40 60
· Coding · 具体编码 300 380
· Code Review · 代码复审 30 30
· Test · 测试(自我测试,修改代码,提交修改) 30 30
Reporting 报告 120 120
· Test Report · 测试报告+博客 120 120
· Size Measurement · 计算工作量 10 10
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 40 50
合计 3040 2195

题目要求:

  • 能自动生成小学四则运算题目
  • 除了整数外,还要支持真分数的四则运算

    除了以上的基本需求,还有
  • 生成的算式长度随机
  • 能处理分数的运算,结果能用分数(字符串类型)表示出来,能与用户输入相对应

解题思路:

  • 定义一个函数用于随机生成随机长度的算式
  • 把字符串型的算式转换为逆波兰式(RPN,也称后缀表达式)
  • 再把后缀表达式利用栈结构计算出结果
  • 最后再与用户的输入做比较

重点难点:

  1. 分数的表示与计算
  2. 后缀表达式的生成和计算
  3. 结果为负数的情况

如何解决:

  1. Python的分数计算可以用 fractions 库
  2. https://blog.csdn.net/qq_36763635/article/details/72627601 这里介绍了如何将中缀表达式转换为后缀表达式(RPN)
  3. https://blog.csdn.net/yangquanhui1991/article/details/52187375 图解后缀表达式的计算过程
  4. 对于结果为负数的情况,只能生成算式之后验算一遍,若为负数的情况,重新生成一遍(可能是个人水平有限)

设计实现:

具体程序设计:

成员变量

成员名 类型 功能
op list 存放运算符
quest str 存放算式
lens int 2到9的随机长度
teop str 存放当前运算符
tstr str 存放当前算式
tint int 存放当前运算数

成员函数

函数名 输入 输出 依赖函数 功能
get_string 字符串 随机生成一个算式
get_ans str 返回布尔类型 get_string 将用户输入与正确答案比较
to_rpn str 返回后缀表达式 get_ans 将随机生成的算式转换为RPN
this_bigger str,str 返回布尔表达式 冇啊 比较两个运算符的优先级
slove_rpn str 返回计算结果 get_ans 将后缀表达式计算出来

核心代码:

#随机生成一个算式
def get_string(self):
self.lens = random.randint(2, 9)
self.teop = ''
self.tstr = []
for i in range(self.lens):
if self.teop == '÷':
self.tint = random.randint(1, 8)
self.teop = random.choice(self.op)
elif self.teop == '/':
self.tint = random.randint(self.tint+1, 9)
self.teop = random.choice(self.op[:-1])
else:
self.tint = random.randint(0, 8)
self.teop = random.choice(self.op)
self.tstr.append(str(self.tint))
self.tstr.append(self.teop)
self.tstr[-1] = '='
self.tstr = ''.join(self.tstr)
self.quest = self.tstr
return self.tstr
#将随机生成的算式转换为RPN
def to_rpn(self, ques): #Reverse Polish notation
self.stack = []
s = ''
for x in ques:
if x != '+' and x != '-' and x != '×' and x != '÷' and x != '/':
s += x #若为数字,直接输出
else: # 若为运算符,进栈
if not self.stack: #栈空
self.stack.append(x)
else:
if self.this_bigger(x, self.stack[-1]): #运算级高于栈顶元素
self.stack.append(x) #直接进栈
else:
while self.stack:
if self.this_bigger(x, self.stack[-1]):
break
s += self.stack.pop()
self.stack.append(x)
while self.stack:
s += self.stack.pop()
# print('在to_rpn函数中,rpn:',s)
return s
#将后缀表达式计算出来
def slove_rpn(self, rpn):
#print('进入slove_rpn函数:')
self.stack1 = [] #用于保存运算数
for x in rpn:
if x != '+' and x != '-' and x != '×' and x != '÷' and x != '/':
self.stack1.append(int(x))
elif x == '+':
second = self.stack1.pop()
first = self.stack1.pop()
self.stack1.append(first + second)
elif x == '-':
second = self.stack1.pop()
first = self.stack1.pop()
self.stack1.append(first - second)
elif x == '×':
second = self.stack1.pop()
first = self.stack1.pop()
self.stack1.append(first * second)
elif x == '÷':
second = self.stack1.pop()
first = self.stack1.pop()
self.stack1.append(Fraction(first, second))
elif x == '/':
second = self.stack1.pop()
first = self.stack1.pop()
self.stack1.append(Fraction(first, second))
resault = self.stack1[0]
if resault >= 0:
#print('--------------题结束----------------')
return resault
elif resault < 0:
s = self.get_string()
rpn = self.to_rpn(s[:-1])
return self.slove_rpn(rpn)

运行效果:

单元测试

《构建之法》第二章中详细提及了好的单元测试的标准。

  • 单元测试应该在最基本的功能/参数上检验程序的正确性。
  • 单元测试必须由最熟悉代码的人来写。
  • 单元测试过后,机器状态保持不变。
  • 单元测试要快。
  • 单元测试应该产生可重复、一致的结果。
  • 独立性-单元测试的运行/通过/失败不依赖于别的测试,可以人为构造数据,以保持测试的独立性。
  • 单元测试应该覆盖所有代码路径。

效能分析图

Pycharm中运行profiler,次数为10W次

可以看到所用的时间长度为16.04s

软工第五次作业——Python效能分析之四则运算生成器的更多相关文章

  1. 第五次作业——python效能分析与几个问题(个人作业)

    第五次作业--效能分析与几个问题(个人作业) 前言 阅读了大家对于本课程的目标和规划之后,想必很多同学都跃跃欲试,迫不及待想要提高自身实践能力,那么就从第一个个人项目开始吧,题目要求见下. 阅读 阅读 ...

  2. FZU软工第五次作业-词组频率分析

    目录 00.前言: 01.分工: 02.PSP表格: 03.解题思路描述与设计实现说明: 解题思路简述: 关键代码 04.附加题设计与展示: 设计的创意独到之处 实现思路 实现成果展示 05.关键代码 ...

  3. 2020BUAA软工个人博客作业-软件案例分析

    2020BUAA软工个人博客作业-软件案例分析 17373010 杜博玮 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人博客作业-软件案例分 ...

  4. FZU软工第十一次作业-软件产品案例分析

    目录 前言: 第一部分.调研,评测: 1.1.初次感觉: 1.2.企业号bug: 1.3.你觉得为什么这个产品组的人没有发现这些bug: 1.4.假设你们团队需要开发这套系统,需要注意哪些方面: 2. ...

  5. 福大软工 · 第十一次作业 - Alpha 事后诸葛亮(团队)

    福大软工·第十一次作业-Alpha事后诸葛亮 组长博客链接 本次作业博客链接 项目Postmortem 模板 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描 ...

  6. 福大软工·第十一次作业-Alpha事后诸葛亮

    福大软工·第十一次作业-Alpha事后诸葛亮 组长博客链接 本次作业博客链接 项目Postmortem 模板 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描 ...

  7. 软工网络15个人作业4——alpha阶段个人总结

    软工网络15个人作业4--alpha阶段个人总结 一.个人总结 用自我评价表:http://www.cnblogs.com/xinz/p/3852177.html 总结Alpha冲刺过程. 由于直接用 ...

  8. 软工 · 第十一次作业 - Alpha 事后诸葛亮(团队)

    软工 · 第十一次作业 - Alpha 事后诸葛亮(团队) 组长本次作业链接 现代软件工程 项目Postmortem 设想和目标 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场 ...

  9. 【软工】个人项目作业——个人软件流程(PSP)

    [软工]个人项目作业--个人软件流程(PSP) 项目 内容 班级:北航2020春软件工程 006班(罗杰.任健 周五) 博客园班级博客 作业:设计程序求几何对象的交点集合 个人项目作业 个人课程目标 ...

随机推荐

  1. UILabel-UITextField-UIBotton&nbsp;UI_…

    注意:AppDelegate是类,所以self在这个类中指的就是AppDelegate对象 - (BOOL)application:(UIApplication *)application didFi ...

  2. 大多数时候是软件的Bug,但是... 有时候的确是硬件的问题!

    在我们性能最好的服务器中,有一台是从之前的64位测试项目中遗留下来的.那台机器配有皓龙250双核处理器,内存有8 GB.服役了一年之后,那种配置仍然是相当不错的.它还有贴心的升级方案可选:它的泰安Th ...

  3. python的sorted

    读入后,要进行组内排序,按groupseq字段排序后,然后统计前后两个项的个数,累加到全局. sorted函数使用如下: def sortlist(alllist):     sorted_key1_ ...

  4. android binder机制详解

    摘要 Binder是android中一个很重要且很复杂的概念,它在系统的整体运作中发挥着极其重要的作用,不过本文并不打算从深层次分析Binder机制,有两点原因:1是目前网上已经有2篇很好的文章了,2 ...

  5. 【UML 建模】UML入门 之 交互图 -- 时序图 协作图详解

    . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/17927131 . 动态图概念 : 从静态图中抽取瞬间值 ...

  6. Linux系统的shell是什么

    shell是用户和Linux操作系统之间的接口.Linux中有多种shell,其中缺省使用的是Bash.本章讲述了shell的工作原理,shell的种类,shell的一般操作及Bash的特性. 什么是 ...

  7. Java进阶(五十一)必须记住的Myeclipse快捷键

    Java进阶(五十一)必须记住的Myeclipse快捷键 在调试程序的时候,我们经常需要注释一些代码,在用Myeclipse编程时,就可以用 Ctrl+/ 为选中的一段代码加上以 // 打头的注释:当 ...

  8. LoadRunner压力测试实例

    1 LoadRunner 概要介绍... 2 .项目背景介绍... 5 .使用LoadRunner进行负载/ 实施测试... 16 6.1 Memory相关... 22 6.2 Processor相关 ...

  9. Handler学习小结

    在android消息机制中Handler扮演着举足轻重的作用,(AsnyTask其实也是对Handler+Thread做了一层封装),ui线程超过5s就会报出ANR,一般耗时操作操作需要放在子线程中处 ...

  10. 【一天一道LeetCode】 #3 Longest Substring Without Repeating Characters

    一天一道LeetCode (一)题目 Given a string, find the length of the longest substring without repeating charac ...