四则运算生成器项目

1.项目链接以及队友博客链接

项目链接:
https://github.com/AmnesiaWu/AutoCal
队友博客链接:
https://blog.csdn.net/SaltyFishLu/article/details/104034857

2.预计时间表格

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

3. 解题思路描述

3.1 项目要求

3.1.1 第一阶段
  • 写一个能自动生成小学四则运算题目的命令行“软件”
  • 用-i num实现一次性生成的题目个数
  • 实现对一个最多10个运算符表达式的求值
  • 支持真分数的四则运算
  • 实现判定对错,并最后给出总共对/错数量。
3.1.2 第二阶段
  • 支持乘方运算,命令行参数-m 1为^表示乘方,命令行参数-m 2为**表示乘方。
3.1.3 第三阶段
  • 把程序编程一个Windows上的电脑图形界面程序
  • 增加倒计时功能,每道题必须要20s内完成,否则得0分并开始下一题
  • 增加历史记录功能,把用户做题的成绩记录下来并可以展现历史记录

3.2 思考过程

题目主要有几个难点:

  • 生成不同的表达式
  • 求解表达式
  • 命令行参数的设置
  • 图形界面,倒计时和历史记录
3.2.1 生成表达式

需要生成随机数,随机运算符,随机括号,还要保证表达式的正确性和唯一性。

生成表达式的时候,感觉还是中缀表达式最直观,最简单。而且不管怎样,最后呈现在用户面前的肯定也要是中缀表达式。当然,为了便于计算表达式,我们制定了了以下生成表达式时的规则:

  1. 一个表达式中最多只有一个乘方运算
  2. 除号和幂运算后不生成左括号,防止括号内的值为0
  3. 乘方幂的范围为1,2,3
  4. 生成左括号的概率为1/5
  5. 在有左括号的情况下,生成右括号的概率为1/3,且配对的右括号和左括号之间至少隔一个运算符

为了消除括号,也为了求解表达式方便,程序首先将中缀表达式转换成了后缀表达式。

最后就是要为表达式去重,所采用的数据结构是二叉树。每一个算式对应一个二叉树,所有的叶子节点为数值,所有的非叶节点为符号。有限次交换加号和乘号左右的算术表达式即所有二叉树的+和根节点的左右子节点任意交换次数不能得到相同的二叉树结构。

3.2.2 求解表达式

从二叉树底向上求解,体现在代码中就是从根节点递归求解。

3.2.3 图形界面,倒计时,历史记录

图形界面最终用的是tkinter库。倒计时和历史记录未实现。

4. 设计实现过程

4.1 类模块说明

4.1.1 Num类

不管用户选择的是什么模式,我们都用Num类来存放数字。因为即使是整数,也可以用分母为1的分数来表示。

  • int numerator //分子
  • int denominator //分母
  • int sign //符号,正数为1,负数为-1
  • int gcd //分子分母的最大公约数,在化简的时候可以用到

方法:

  • +, -, *, /, **, ==, <, str()运算符的重载
  • __gcd() //求解分子分母的最大公因数
  • __reduction() //化简操作,保证分子分母均为正数,符号由sign来定
4.1.2 ExpressionBuilder类

属性:

  • int[] exp_elements_infix //中缀表达式数组,每个符号数字都对应其中一项
  • int[] exp_elements_suffix //后缀表达式数组,去除了括号
  • BinaryTree tree //二叉树形式
  • Num ans //答案

方法:

  • __rand_op_num() //随机出1到10的随机数个数
  • __rand_op() //随机出一个运算符
  • __rand_num() //随机出一个0到100的数字
  • __rand_pow_num() //随机出一个1到3的数字作为幂
  • build_exp_infix() //生成中缀表达式
  • infix_to_sufix() //将中缀表达式转成后缀表达式
  • suffix_to_tree() //将后缀表达式转成树
  • get_ans() //求解表达式
  • build() //留给外部调用的函数,依次调用上述提到的函数
4.1.3 BinaryTree类

内部类:Node
python里没有内部类的概念,这里仅是这么叫而已。二叉树的节点,type代表节点是数字还是字符(是否为叶节点),如果是非叶节点,op为操作数;如果是叶节点,num为数字,left表示左孩子,right表示右孩子。

属性:

  • root //表达式树的根节点
  • op_num //表达式中运算符的个数

方法:

  • adjust_tree() //在计算完之后对数进行调整,以便后生成的表达式树预期对比看是否相同
  • is_same_tree() //判断两颗表达式树是否相同
4.1.4 Const

专门存放常数的类,增强代码的可读性。

4.1.5 Stack

python没有现成的stack,写了一个简易版的,基本功能都有。

4.1.6 Main

解析输入参数,调用其他类,实现与用户的交互

4.2 程序执行流程图

Created with Raphaël 2.2.0 开始 输入生成要求 随机生成运算式 是否无重复 求解 存储运算式和答案 选取题目并显示 判断答案 输出结果并记分数 结束 yes no

5. 单元测试

  • 单元测试用例设计如下
    1.输入测试
    主要测试程序的合法输入以及不合法输入情况。
编号输入格式预期输出
1简单模式 + max_num整数运算式
2中等模式 + max_num分数、整数运算式
3困难模式 + max_num分数、整数乘方运算式

2.输入测试
检测四则运算器中每一种算符的运算正确性

编号操作数1操作数2运算符预测结果
121/2+5/2
221/2-3/2
323/2*3
421/2/4
533^27
630^1
71/21^1/2

3.题目查重测试

编号算式1算式2预测结果
12+3+44+(2+3)重复
21+2+33+2+1不重复
32*33*2重复
4(1 + 2) * 33* (1 + 2)不重复
5(1+2)*(3+4)(3+4)*(1+2)不重复
6(2-1)/(5-3)(5-3)/(2-1)不重复
7(3+6)/(5-3)(6+3)/(5-3)重复
8(1/2+2/3)+3/41/2+(2/3+3/4)重复
9(1/2+2/3)* 3/43/4 *(1/2+2/3)重复

6.性能分析

性能分析图
由分析报告可见,该项目的Gui.py里的main函数占用时间最多。build函数是生成运算表达式的函数,可从图看出调用了1000次(即生成了1000个算式),时间花了总时间的2.1%,可见主要时间花在与用户的交互上

7.程序扩展

我们用python做了个简单图形界面
主界面如下:
主界面
输入格式错误:
格式错误
开始答题:
答题界面
回答错误:
回答错误界面
回答正确
退出并显示分数界面:
分数显示
点击确定后程序结束

8.PSP表格

PSP2.1Personal Software Process Stages预估耗时 (分钟)实际耗时(分钟)
Planning计划3040
Estimate估计这个任务需要多少时间3040
Development开发19301350
Analysis需求分析(包括学习新技术)9060
Design Spec生成设计文档6050
Design Review设计复审(和同事审核设计文档)3060
Coding Standard代码规范(为目前的开发制定合适的规范)3010
Design具体设计12060
Coding具体编码1200900
Code Review代码复审6040
Test测试(自我测试,修改代码,提交修改)24060
Reporting报告190150
Test Report测试报告12060
Size Measurement计算工作量1010
Postmortem & Process Improvement Plan事后总结,并提出过程改进计划6010
Total合计21501520

9.实验总结

本次结对项目中,我掌握了四则表达式的正确生成方法,学会了python的Tkinter的界面设计,同时我也意识到了队友协作的重要性。虽然过程中遇到各种苦难,如运算表达式的重复、界面提取不到数据等。但是在1+1>2的BUFF增益下,我们最终克服了重重困难。也体会到了严格按照标准的软件开发流程进行开发的重要性。总的来说,收获远大于付出

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值