基于Python实现的四则运算生成程序
Github项目地址:传送门
小组成员:黄晓彬(代码实现) 黄钰城(代码审查)
需求:
1. 使用 -n 参数控制生成题目的个数。
2. 使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围。
3. 生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在形如e1 − e2的子表达式,那么e1 ≥ e2。
4. 生成的题目中如果存在形如e1 ÷ e2的子表达式,那么其结果应是真分数。
5. 每道题目中出现的运算符个数不超过3个。
6. 程序一次运行生成的题目不能重复,
生成的题目存入执行程序的当前目录下的Exercises.txt文件。
7. 在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件。
8. 程序应能支持一万道题目的生成。
9. 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计,输入参数如下:
Myapp.exe -e <exercisefile>.txt -a <answerfile>.txt
统计结果输出到文件Grade.txt,格式如下:
Correct: 5 (1, 3, 5, 7, 9)
Wrong: 5 (2, 4, 6, 8, 10)
其中“:”后面的数字5表示对/错的题目的数量,括号内的是对/错题目的编号。为简单起见,假设输入的题目都是按照顺序编号的符合规范的题目。(未实现)
PSP表格:
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
30 |
30 |
· Estimate |
· 估计这个任务需要多少时间 |
30 |
60 |
Development |
开发 |
480 |
520 |
· Analysis |
· 需求分析 (包括学习新技术) |
120 |
200 |
· Design Spec |
· 生成设计文档 |
60 |
70 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
30 |
60 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
30 |
30 |
· Design |
· 具体设计 |
60 |
60 |
· Coding |
· 具体编码 |
600 |
700 |
· Code Review |
· 代码复审 |
500 |
700 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
200 |
300 |
Reporting |
报告 |
60 |
30 |
· Test Report |
· 测试报告 |
30 |
30 |
· Size Measurement |
· 计算工作量 |
60 |
30 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
30 |
40 |
合计 |
2230 |
2860 |
效能分析:算法运行过程较慢,没有使用数据结构进行优化,并且还大量使用库函数,导致结果运行缓慢
设计实现过程:接收命令行参数-->获取数值和符号列表-->计算结果并生成题目和答案列表-->存入两个txt文件
函数 | 功能 |
get_num_sym(i,r) | 获取数值列表和符号列表 |
calculate(a,b,s) | 计算单元,a,b是数,s是符号 |
f(f) | 分数的转换 |
writeF(slist,num,hb) | 生成算术表达式 |
getF(n,r) | 用于生成题目和答案列表 |
save(fname, d) | 用于写入文件 |
main() | 主函数 |
代码说明:
用get_num_sym(i,r)函数循环遍历以获得随机分数列表和符号列表
def get_num_sym(i,r):#获取数值列表和符号列表
nlist=[]#数值列表
slist=[]#符号列表
hb=0#判断怎么加括号
l=0#判断是否是减数运算
for m in range(i+1):#根据i的值遍历输出数值列表
nlist.append(Fraction(random.randint(1, r), random.randint(1, r)))
for x in range(i):
sy=random.choice(['+','-','×','÷'])
if sy=='+'or sy=='-':
hb +=10**(i-x-1)
else :
hb += 2 * (10 ** (i - x - 1))
slist.append(sy)
if sy=='-':
l=1
return nlist,slist,hb,i,l
把分数转换为整数、真分数和带分数
def f(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)
用于四则运算
def calculate(a,b,s):#计算单元,a,b是数,s是符号
ans=0
if s=='+':#加法运算
ans=a+b
elif s=='-':#减法运算
a,b=max(a,b),min(a,b)#防止结果为负数
ans=a-b
elif s=='×':#乘法运算
ans=a*b
else:ans=a/b#除法运算
return ans
生成算术表达式
def writeF(slist,num,hb):#生成算术表达式
global j,k
s=''
if hb>100:#符号数为3
if j==1 and k==0:
s = '%s %s (%s %s %s) %s %s = ' % (f(num[0]), slist[0],
f(num[1]),slist[1], f(num[2]), slist[2], f(num[3]))
elif j==1 and k==1:
s = '%s %s (%s %s (%s %s %s)) = ' % (f(num[0]), slist[0],
f(num[1]),slist[1], f(num[2]), slist[2], f(num[3]))
elif j==0 and k==1:
s = '%s %s (%s %s %s %s %s) = ' % (f(num[0]), slist[0],
f(num[1]),slist[1], f(num[2]), slist[2], f(num[3]))
if hb == 112 or hb ==212:
s = '(%s %s %s %s %s) %s %s = ' % (f(num[0]), slist[0],
f(num[1]),slist[1], f(num[2]), slist[2], f(num[3]))
elif hb == 121 or hb ==122:
s = '(%s %s %s) %s %s %s %s = ' % (f(num[0]), slist[0],
f(num[1]),slist[1], f(num[2]), slist[2], f(num[3]))
else:
s = '%s %s %s %s %s %s %s = ' % (f(num[0]), slist[0],
f(num[1]),slist[1], f(num[2]), slist[2], f(num[3]))
elif hb>10:#符号数为2
if j==1 :
s = '%s %s (%s %s %s) = ' % (f(num[0]), slist[0],
f(num[1]), slist[1], f(num[2]))
if hb == 12:
s = '(%s %s %s)%s %s = ' % (f(num[0]), slist[0],
f(num[1]), slist[1], f(num[2]))
else:
s = '%s %s %s %s %s = ' % (f(num[0]), slist[0],
f(num[1]), slist[1], f(num[2]))
else :#符号数为1
s ='%s %s %s = ' % (f(num[0]),slist[0],f(num[1]))
return s
生成题目和答案列表
def getF(n,r):#用于生成题目和答案列表
E,A,E1,E2=[],[],[],[]
global j,k
x=1
while x<n+1:#循环生成题目和答案列表
i=random.randint(1, 3)#随机获取符号数目
num,slist,hb,i,l=get_num_sym(i,r)
num1=num
legal = True
if l==1: #用于防止除法运算出现负数
if num[0]<num[1]:
num1[0],num1[1]=num[1],num[0]
if i>=2 and calculate(num[0],num[1],slist[0])<num[2]:
num1[0],num1[1],num1[2]=num[2],num[0],num[1]
j=1
if i>=3 and calculate(calculate(num[0],num[1],slist[0]),num[2],slist[1])<num[3]:
num1[0],num1[1],num1[2],num1[3]=num[3],num[0],num[1],num[2]
k=1
ans=num1[0]
for y in range(i):
cal=calculate(ans,num[y+1],slist[y])
if cal>=0:#判断算式是否合法
ans=cal
else:
legal=False
break
if legal:
try:
num=A.index(ans)#第一个答案的索引
except ValueError as e:#可以写入
A.append(ans)
E1.append(slist)
E2.append(num1)
E.append('%d. %s'%(x,writeF(slist,num1,hb)))
x+=1
else:pass
return E,A
写入txt文件
def save(fname, d):#fname为写入文件的路径,d为要写入的数据列表.
file = open(fname,'a')
file.seek(0)
file.truncate() #清空
for i in range(len(d)):#循环写入文件fname
s = str(d[i]).replace('[','').replace(']','')
s = s.replace("'",'').replace(',','') +'\n'
file.write(s) file.close()
print('%s文件保存成功'%fname)
主函数(包括命令行参数的实现)
def main():#主函数
parser = argparse.ArgumentParser(description="this is auto calculator")#命令行参数控制
parser.add_argument('-n',help='控制生成题目的个数',type=int)
parser.add_argument('-r',help='控制题目中数值(自然数、真分数和真分数分母)的范围',type=int)
args = parser.parse_args()
if args.n:
n=args.n
print('n值为%d'%n)
if args.r:
r=args.r
print('r值为%d'%r)
E, A=getF(n,r)
for x in range(n):#循环生成答案列表
A[x]='%d. %s'%(x+1,f(A[x]))
save('Exercises.txt',E)
save('Answers.txt',A) end = time.clock()
print('运行时间: %s '%(end-start)) if __name__ == '__main__':
main()
测试运行:
一万道题目生成:
项目小结:由于我们两个Python水平有限,花了几天都想不出到底要怎么写这个程序,最后还是问了同学加上网看别人写的思路,通过先全部随机生成分数(分数包括了自然数),在用函数区分自然数、真分数和带分数,再用函数根据条件的不同生成不同的表达式,并通过单步循环计算出结果,最后再根据情况加括号(其实是前面忘了,后面为了这个花了很长时间),才完成了这个自动生成程序。通过这次编程,我深刻感受到自己写Python的技术有待提高,代码让钰诚看得一头包,bug更是跟修不完似的。两个人的编程和一个人的还是有很大的不同,意见的不统一,想法的不同都会让我们产生分歧甚至是争执,这种时候良好的沟通才是最重要的。
基于Python实现的四则运算生成程序的更多相关文章
- 基于Python Requests的数据驱动的HTTP接口测试
发表于:2017-8-30 11:56 作者:顾翔 来源:51Testing软件测试网原创 http://www.51testing.com/html/69/n-3720769-2.html ...
- 【Machine Learning】决策树案例:基于python的商品购买能力预测系统
决策树在商品购买能力预测案例中的算法实现 作者:白宁超 2016年12月24日22:05:42 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本 ...
- 基于Python+Django的Kubernetes集群管理平台
➠更多技术干货请戳:听云博客 时至今日,接触kubernetes也有一段时间了,而我们的大部分业务也已经稳定地运行在不同规模的kubernetes集群上,不得不说,无论是从应用部署.迭代,还是从资源调 ...
- 关于《selenium2自动测试实战--基于Python语言》
关于本书的类型: 首先在我看来技术书分为两类,一类是“思想”,一类是“操作手册”. 对于思想类的书,一般作者有很多年经验积累,这类书需要细读与品位.高手读了会深有体会,豁然开朗.新手读了不止所云,甚至 ...
- psutil一个基于python的跨平台系统信息跟踪模块
受益于这个模块的帮助,在这里我推荐一手. https://pythonhosted.org/psutil/#processes psutil是一个基于python的跨平台系统信息监视模块.在pytho ...
- 一次完整的自动化登录测试-基于python+selenium进行cnblog的自动化登录测试
Web登录测试是很常见的测试!手动测试大家再熟悉不过了,那如何进行自动化登录测试呢!本文作者就用python+selenium结合unittest单元测试框架来进行一次简单但比较完整的cnblog自动 ...
- 搭建基于python +opencv+Beautifulsoup+Neurolab机器学习平台
搭建基于python +opencv+Beautifulsoup+Neurolab机器学习平台 By 子敬叔叔 最近在学习麦好的<机器学习实践指南案例应用解析第二版>,在安装学习环境的时候 ...
- 《Selenium2自动化测试实战--基于Python语言》 --即将面市
发展历程: <selenium_webdriver(python)第一版> 将本博客中的这个系列整理为pdf文档,免费. <selenium_webdriver(python)第 ...
- 从Theano到Lasagne:基于Python的深度学习的框架和库
从Theano到Lasagne:基于Python的深度学习的框架和库 摘要:最近,深度神经网络以“Deep Dreams”形式在网站中如雨后春笋般出现,或是像谷歌研究原创论文中描述的那样:Incept ...
随机推荐
- Tkprof工具详解一(转载)
在数据库生成的oracle trace文件中,可读性是比较差的,此时可使用tkprof工具来格式化trace文件,tkprof是一个命令行工具,作用就是把原始的跟踪trace文件作为输入,然后格式化一 ...
- Python(递归)
递归函数 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. 举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n,用函数fact(n)表示,可以 ...
- s5_day13作业
#对之前文件进行的增删改查操作实现日志操作,日志输出用户进行过的操作. def log(): import logging logger_obj=logging.getLogger() logger_ ...
- Node.js API学习笔记(二)
本文发表于本人博客. 上一节笔记说到创建Buffer实例,这节继续讲Buffer.本节讲解下Buffer的一些静态方法.写入以及读取方法. Buffer.isEncoding(编码)判断nodejs是 ...
- LeetCode 53. Maximum Subarray 最大连续字段和问题
考察:最大连续字段和问题. 解决问题时间复杂度:O(n) 问题隐含条件:如果给出的数集都是负数,那么最大连续字段和就是,最大的那个负数. eg:{-2,-1} 结果应该输出 -1 而不是 0 int ...
- NIO复习01
NIO 概述: 1. Java NIO 由以下几个核心部分组成:Channels Buffers Selectors 2. 主要Channel的实现:FileChann ...
- QT的基本数据类型
QT的基本数据类型(转) qint8:signed char 有符号8比特数据 qint16:signed short 16位数据类型 qint32:signed int. 32位有符号数据类型 qi ...
- log4j日志的配置--Debug
############################### 日志记录器定义 ################################ 日志输出级别 OFF.DEBUG.INFO.WARN. ...
- [nowcoder]最长区间
链接:https://www.nowcoder.com/acm/contest/158/B 求最长连续严格递增序列 线段树模板题,码力弱的一匹调了半天.. 代码: #include<iostre ...
- JAVA基础补漏--反射
获得CLASS的三种方式: 1.Class.forname("全类名"):将字节码文件加载进内存,返回Class对象. 多用于配置文件,将类名放到配置文件中,读取配置文件,加载类 ...