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)函数循环遍历以获得随机分数列表和符号列表

  1. def get_num_sym(i,r):#获取数值列表和符号列表
  2. nlist=[]#数值列表
  3. slist=[]#符号列表
  4. hb=0#判断怎么加括号
  5. l=0#判断是否是减数运算
  6. for m in range(i+1):#根据i的值遍历输出数值列表
  7. nlist.append(Fraction(random.randint(1, r), random.randint(1, r)))
  8. for x in range(i):
  9. sy=random.choice(['+','-','×','÷'])
  10. if sy=='+'or sy=='-':
  11. hb +=10**(i-x-1)
  12. else :
  13. hb += 2 * (10 ** (i - x - 1))
  14. slist.append(sy)
  15. if sy=='-':
  16. l=1
  17. return nlist,slist,hb,i,l

把分数转换为整数、真分数和带分数

  1. def f(f):#分数的转换
  2. a=f.numerator
  3. b=f.denominator
  4. if a%b==0:#为整数
  5. return '%d'%(a/b)
  6. elif a<b:#为真分数
  7. return '%d%s%d' % (a,'/',b)
  8. else:#为带分数
  9. c=int(a/b)
  10. a = a - c * b
  11. return '%d%s%d%s%d' % (c,'’',a,'/',b)

用于四则运算

  1. def calculate(a,b,s):#计算单元,ab是数,s是符号
  2. ans=0
  3. if s=='+':#加法运算
  4. ans=a+b
  5. elif s=='-':#减法运算
  6. a,b=max(a,b),min(a,b)#防止结果为负数
  7. ans=a-b
  8. elif s=='×':#乘法运算
  9. ans=a*b
  10. else:ans=a/b#除法运算
  11. return ans

生成算术表达式

  1. def writeF(slist,num,hb):#生成算术表达式
  2. global j,k
  3. s=''
  4. if hb>100:#符号数为3
  5. if j==1 and k==0:
  6. s = '%s %s (%s %s %s) %s %s = ' % (f(num[0]), slist[0],
  7. f(num[1]),slist[1], f(num[2]), slist[2], f(num[3]))
  8. elif j==1 and k==1:
  9. s = '%s %s (%s %s (%s %s %s)) = ' % (f(num[0]), slist[0],
  10. f(num[1]),slist[1], f(num[2]), slist[2], f(num[3]))
  11. elif j==0 and k==1:
  12. s = '%s %s (%s %s %s %s %s) = ' % (f(num[0]), slist[0],
  13. f(num[1]),slist[1], f(num[2]), slist[2], f(num[3]))
  14. if hb == 112 or hb ==212:
  15. s = '(%s %s %s %s %s) %s %s = ' % (f(num[0]), slist[0],
  16. f(num[1]),slist[1], f(num[2]), slist[2], f(num[3]))
  17. elif hb == 121 or hb ==122:
  18. s = '(%s %s %s) %s %s %s %s = ' % (f(num[0]), slist[0],
  19. f(num[1]),slist[1], f(num[2]), slist[2], f(num[3]))
  20. else:
  21. s = '%s %s %s %s %s %s %s = ' % (f(num[0]), slist[0],
  22. f(num[1]),slist[1], f(num[2]), slist[2], f(num[3]))
  23. elif hb>10:#符号数为2
  24. if j==1 :
  25. s = '%s %s (%s %s %s) = ' % (f(num[0]), slist[0],
  26. f(num[1]), slist[1], f(num[2]))
  27. if hb == 12:
  28. s = '(%s %s %s)%s %s = ' % (f(num[0]), slist[0],
  29. f(num[1]), slist[1], f(num[2]))
  30. else:
  31. s = '%s %s %s %s %s = ' % (f(num[0]), slist[0],
  32. f(num[1]), slist[1], f(num[2]))
  33. else :#符号数为1
  34. s ='%s %s %s = ' % (f(num[0]),slist[0],f(num[1]))
  35. return s

生成题目和答案列表

  1. def getF(n,r):#用于生成题目和答案列表
  2. E,A,E1,E2=[],[],[],[]
  3. global j,k
  4. x=1
  5. while x<n+1:#循环生成题目和答案列表
  6. i=random.randint(1, 3)#随机获取符号数目
  7. num,slist,hb,i,l=get_num_sym(i,r)
  8. num1=num
  9. legal = True
  10. if l==1: #用于防止除法运算出现负数
  11. if num[0]<num[1]:
  12. num1[0],num1[1]=num[1],num[0]
  13. if i>=2 and calculate(num[0],num[1],slist[0])<num[2]:
  14. num1[0],num1[1],num1[2]=num[2],num[0],num[1]
  15. j=1
  16. if i>=3 and calculate(calculate(num[0],num[1],slist[0]),num[2],slist[1])<num[3]:
  17. num1[0],num1[1],num1[2],num1[3]=num[3],num[0],num[1],num[2]
  18. k=1
  19. ans=num1[0]
  20. for y in range(i):
  21. cal=calculate(ans,num[y+1],slist[y])
  22. if cal>=0:#判断算式是否合法
  23. ans=cal
  24. else:
  25. legal=False
  26. break
  27. if legal:
  28. try:
  29. num=A.index(ans)#第一个答案的索引
  30. except ValueError as e:#可以写入
  31. A.append(ans)
  32. E1.append(slist)
  33. E2.append(num1)
  34. E.append('%d. %s'%(x,writeF(slist,num1,hb)))
  35. x+=1
  36. else:pass
  37. return E,A

写入txt文件

  1. def save(fname, d):#fname为写入文件的路径,d为要写入的数据列表.
  2. file = open(fname,'a')
  3. file.seek(0)
  4. file.truncate() #清空
  5. for i in range(len(d)):#循环写入文件fname
  6. s = str(d[i]).replace('[','').replace(']','')
  7. s = s.replace("'",'').replace(',','') +'\n'
  8. file.write(s)
  9.  
  10. file.close()
  11. print('%s文件保存成功'%fname)

主函数(包括命令行参数的实现)

  1. def main():#主函数
  2. parser = argparse.ArgumentParser(description="this is auto calculator")#命令行参数控制
  3. parser.add_argument('-n',help='控制生成题目的个数',type=int)
  4. parser.add_argument('-r',help='控制题目中数值(自然数、真分数和真分数分母)的范围',type=int)
  5. args = parser.parse_args()
  6. if args.n:
  7. n=args.n
  8. print('n值为%d'%n)
  9. if args.r:
  10. r=args.r
  11. print('r值为%d'%r)
  12. E, A=getF(n,r)
  13. for x in range(n):#循环生成答案列表
  14. A[x]='%d. %s'%(x+1,f(A[x]))
  15. save('Exercises.txt',E)
  16. save('Answers.txt',A)
  17.  
  18. end = time.clock()
  19. print('运行时间: %s '%(end-start))
  20.  
  21. if __name__ == '__main__':
  22. main()

测试运行:

一万道题目生成:

 

项目小结:由于我们两个Python水平有限,花了几天都想不出到底要怎么写这个程序,最后还是问了同学加上网看别人写的思路,通过先全部随机生成分数(分数包括了自然数),在用函数区分自然数、真分数和带分数,再用函数根据条件的不同生成不同的表达式,并通过单步循环计算出结果,最后再根据情况加括号(其实是前面忘了,后面为了这个花了很长时间),才完成了这个自动生成程序。通过这次编程,我深刻感受到自己写Python的技术有待提高,代码让钰诚看得一头包,bug更是跟修不完似的。两个人的编程和一个人的还是有很大的不同,意见的不统一,想法的不同都会让我们产生分歧甚至是争执,这种时候良好的沟通才是最重要的。

基于Python实现的四则运算生成程序的更多相关文章

  1. 基于Python Requests的数据驱动的HTTP接口测试

    发表于:2017-8-30 11:56  作者:顾翔   来源:51Testing软件测试网原创 http://www.51testing.com/html/69/n-3720769-2.html   ...

  2. 【Machine Learning】决策树案例:基于python的商品购买能力预测系统

    决策树在商品购买能力预测案例中的算法实现 作者:白宁超 2016年12月24日22:05:42 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本 ...

  3. 基于Python+Django的Kubernetes集群管理平台

    ➠更多技术干货请戳:听云博客 时至今日,接触kubernetes也有一段时间了,而我们的大部分业务也已经稳定地运行在不同规模的kubernetes集群上,不得不说,无论是从应用部署.迭代,还是从资源调 ...

  4. 关于《selenium2自动测试实战--基于Python语言》

    关于本书的类型: 首先在我看来技术书分为两类,一类是“思想”,一类是“操作手册”. 对于思想类的书,一般作者有很多年经验积累,这类书需要细读与品位.高手读了会深有体会,豁然开朗.新手读了不止所云,甚至 ...

  5. psutil一个基于python的跨平台系统信息跟踪模块

    受益于这个模块的帮助,在这里我推荐一手. https://pythonhosted.org/psutil/#processes psutil是一个基于python的跨平台系统信息监视模块.在pytho ...

  6. 一次完整的自动化登录测试-基于python+selenium进行cnblog的自动化登录测试

    Web登录测试是很常见的测试!手动测试大家再熟悉不过了,那如何进行自动化登录测试呢!本文作者就用python+selenium结合unittest单元测试框架来进行一次简单但比较完整的cnblog自动 ...

  7. 搭建基于python +opencv+Beautifulsoup+Neurolab机器学习平台

    搭建基于python +opencv+Beautifulsoup+Neurolab机器学习平台 By 子敬叔叔 最近在学习麦好的<机器学习实践指南案例应用解析第二版>,在安装学习环境的时候 ...

  8. 《Selenium2自动化测试实战--基于Python语言》 --即将面市

    发展历程: <selenium_webdriver(python)第一版>   将本博客中的这个系列整理为pdf文档,免费. <selenium_webdriver(python)第 ...

  9. 从Theano到Lasagne:基于Python的深度学习的框架和库

    从Theano到Lasagne:基于Python的深度学习的框架和库 摘要:最近,深度神经网络以“Deep Dreams”形式在网站中如雨后春笋般出现,或是像谷歌研究原创论文中描述的那样:Incept ...

随机推荐

  1. 超过两行显示省略号 -webkit-line-clamp、-webkit-box-orient vue打包后不起作用

    为了实现两行显示缩略显示,但是本地是可以显示,打包后不起作用 word-break: break-all; text-overflow: ellipsis; display: -webkit-box; ...

  2. Authentication Overview

    Authentication Overview Service accounts User accounts API keys

  3. T25健身视频全集+课表

    http://jianfei.39.net/thread-3639251-1.html T25健身视频全集+课表 强度适中 不伤膝盖! [复制链接]     zytttt         主题 好友 ...

  4. LeetCode:验证二叉搜索树【98】

    LeetCode:验证二叉搜索树[98] 题目描述 给定一个二叉树,判断其是否是一个有效的二叉搜索树. 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当 ...

  5. java项目地址和服务器地址区分

    项目地址String filePath = request.getSession().getServletContext().getRealPath("/") + "up ...

  6. Ubuntu 16.04 安装Django

    > pip install django==1.10.3......或者:> pip3 install django==1.10.3(我采用)......或者:>python3 -m ...

  7. Java遍历List集合的三种方法

    Java遍历List集合的三种方法 List<String> list = new ArrayList<String>(); list.add("aaa") ...

  8. [pixhawk笔记]4-如何写一个简单的应用程序

    本文主要内容来自于:https://dev.px4.io/en/tutorials/tutorial_hello_sky.html,并对文档中的部分问题进行更正. 本文假设已经建立好开发环境并能正确编 ...

  9. 【传感器】BMA253 数字,三轴加速度传感器

    参考文档:BMA253E DataSheet 参考文档链接 密码:9new BMA253 数字,三轴加速度传感器 关键特性: 关键特性   封装方式 LGA封装(12pins),长*宽(2mm*2mm ...

  10. zabbix监控实现电话报警OneAlert

    http://www.ttlsa.com/zabbix/zabbix-onealert-msg-compress/