Git地址 | https://github.com/F0urty-Tw0 |
Git用户名 | F0urty-Tw0 |
学号后五位 | 61109 |
博客地址 | https://www.cnblogs.com/FourtyTwo/ |
做业连接 | https://edu.cnblogs.com/campus/xnsy/Autumn2019SoftwareEngineeringFoundation/homework/7590 |
因为想进一步巩固一下Python,这次做业打算用它来写,原先要求的Visual Studio 2017
的环境配置就由PyCharm
来代替python
PyCharm是由JetBrains打造的一款Python IDE,进入官网https://www.jetbrains.com/pycharm/,选择免费的community版本下载便可,如图所示:
git
安装过程较为简单,未遇到问题,安装完成效果以下:程序员
进入Windows版git下载地址:https://git-scm.com/download/win,通常来讲打开即自动开始下载任务,若长时间未开始,可手动点击:github
接下来点击安装程序一步步来便可,安装成功后应能够在桌面或文件夹空白处右键下拉菜单中出现Git GUI here以及Git Bash here,以下图所示:express
再安装好Git以后,咱们就能够再Github上克隆指定的项目,首先进入本次做业指定的仓库地址:https://github.com/Cherish599/AchaoCalculator,点击右上角的Fork
以后,便可拷贝到本身的同名仓库中。bash
接下来在个人电脑中任意路径下点击鼠标右键,选择Git Bash here,输入命令行git clone https://github.com/Cherish599/AchaoCalculator.git
,(git clone后的连接即为仓库地址)以下图所示:
app
以后须要在刚刚的路径下新建一个与Github帐户名相同的文件夹,以下图所示:dom
因为以前经过Github搭建过我的博客,有了安装及使用Git的经验,因此本次做业在Git安装及项目克隆方面没有出现什么问题函数
阿超家里的孩子上小学一年级了,这个暑假老师给家长们布置了一个做业:家长天天要给孩子出一些合理的,但要有些难度的四则运算题目,而且家长要对孩子的做业打分记录。工具
做为程序员的阿超心想,既然天天都须要出题,那何不作一个能够自动生成小学四则运算题目与解决题目的命令行 “软件”呢。他把老师的话翻译一下,就造成了这个软件的需求:
根据题目背景,得知设计需求为一个能够自订题目数量的四则运算生成器,且结果只能为整数,还要将全部的算式和正确答案输出到一个文件中。由此,这个题目的关键由三部分构成:表达式的随机生成、表达式的计算、表达式及答案打印输出
(程序由包含表达式生成、打印输出及main()函数的caculator.py文件与包含表达式计算函数的caculate_func.py文件构成)
表达式的随机生成思路及代码实现
题目中要求表达式有两到三个运算符,因此在表达式生成以前应先设定在2和3之间的随机数,并经过条件分支语句判断该随机数为2仍是3以进行后续的随机表达式生成。
具体代码:
r = random.randint(2, 3)
再肯定运算符数量后,声明一个列表“op”,其元素即为["+", "-", "*", "/"]四个运算符(此处乘号与除号未直接采用“×”与“÷”是为了方便后续的计算操做),接着将0到100的随机数存入另外一列表以便后续插入。在以后的表达式生成时,先取数值列表中的一个随机值,后经过for in语句将数值循环插入,运算符除插入位置变动外同理。
具体代码:
for i in range(0, 3): tmp = random.choice(num) formula_list.append(tmp) for i in [1, 3]: tmp = random.choice(op) formula_list.insert(i, tmp)
该功能完整代码以下:
def new_form(): # 生成新的表达式 op = ["+", "-", "*", "/"] r = random.randint(2, 3) if r == 2: # 经过判断随机生成的r来肯定表达式中运算符数量 num = random_num(10) formula_list = [] for i in range(0, 3): tmp = random.choice(num) formula_list.append(tmp) for i in [1, 3]: tmp = random.choice(op) formula_list.insert(i, tmp) elif r == 3: num1 = random_num(10) formula_list = [] for i in range(0, 4): tmp = random.choice(num1) formula_list.append(tmp) for i in [1, 3, 5]: tmp = random.choice(op) formula_list.insert(i, tmp) return formula_list
经过网上查阅,发现python中可使用flatten()函数或list(itertools.chain.from_iterable(zip(l,m)))
语句来直接实现列表的交叉合并,这样一来表达式的生成一两条语句即可实现,但我在实际使用过程当中出现报错语句:TypeError: zip argument #1 must support iteration
而且一直没法解决(T_T),只能采用上述较为原始的方法。。。
表达式的计算思路及代码实现
未避免代码看起来冗长,将实现这一功能的函数写入了另外一个文件中,及“calculate_func.py”,并经过python from calculate_func import gen_list, calculate
语句引入至原文件
因为运算符有加减乘除四个,要将表达式的答案计算出来就要考虑到运算符的优先级,本来想着要用栈实现,但在网上搜索的过程当中发现也能够利用python的列表加递归实现简单加减乘除的计算。
具体原理为经过new_form()生成的表达式以列表形式存储,以后从左向右计算全部乘除号两边的数值,而后删除运算符及其左右两个数值,再把运算结果保存在第一个数值原先存在的位置,而后第二次循环计算剩下的加减法运行,直至只剩下一个数,即表达式的运算结果,因为不能出现分数,可让强转int后的结果与原结果比较,若相同则正常返回结果
具体代码以下:
def calculate(expression, isFirst=True): i = 0 while i < len(expression) - 3: a = expression[i] # 获取操做数1 b = expression[i + 2] # 获取操做数2 op1 = expression[i + 1] # 获取运算符 result = None if op1 == "*": result = a * b elif op1 == "/": result = a / b elif not isFirst and op1 == "+": result = a + b elif not isFirst and op1 == "-": result = a - b if result is not None: expression[i] = result # 将第一个操做数替换问运算结果 del (expression[i + 1: i + 3]) # 删除运算符号和后一个操做数 else: i += 2 # 下标偏移 if isFirst: return calculate(expression, False) elif int(expression[0]) == expression[0]: return expression[0] # 返回结果
表达式打印输出思路及代码实现
因为new_form()函数return了的表达式以列表形式存储,而且乘号与除号还只是用"*"与"/"表示,因此首先要遍历生成好的表达式找到乘号与除号,将其替换为“×”与“÷”。具体能够利用python中的字典来实现。
首先再定义一个字典op_dictm,即op_dict = {"+": "+", "-": "-", "*": "×", "/": "*"}
,以后经过for in语句遍历表达式列表,若其中存在"*"与"/",则直接替换字典中对应的value,
具体代码:
for i in range(length): if form_list[i] in op: form_list[i] = op_dict[form_list[i]]
以后在经过append直接将"="尾插进替换后的表达式。最后,经过"".join(str(i) for i in form_list)
直接将列表中的元素拼接为字符串再输出。在此以前,若表达式运算结果为整数则调用save_to_file()函数将该表达式存入文件,若不为整数,则再次调用new_form()函数与form_display()函数来从新生成并输出表达式,直至该表达式答案为整数。
具体代码以下:
def form_display(form_list): # 将生成的表达式打印 expression = "".join(str(i) for i in form_list) expression1 = gen_list(expression) result = calculate(expression1, isFirst=True) if result: # 若经过calculate()函数计算表达式结果为整数,则进行后续的打印输出 op_dict = {"+": "+", "-": "-", "*": "×", "/": "÷"} op = ["+", "-", "*", "/"] length = len(form_list) for i in range(length): if form_list[i] in op: form_list[i] = op_dict[form_list[i]] # 经过op_dict字典将原有表达式中的乘除运算符替换为"X"与"÷" form_list.append("=") form_list = "".join(str(i) for i in form_list) # 将form_list列表中的元素拼接为字符串输出 print (form_list) save_to_file('subject.txt', form_list+str(result)) else: # 若表达式计算结果不为整数则不打印任何数据 form_list = new_form() form_display(form_list)
运行结果
首先选中想要进行单元测试的函数,选中后ctrl+shift+T,如图:
选择Create New Test.....,以后再弹出的选项框中勾选test method为:test_new_form
以后在新建的文件中补全对函数进行测试的代码,在已经设定的类中添加测试函数的方法便可。
如图所示:
form_display()函数测试结果以下:
在进行单元测试时发现如何测试都不能经过,但本身的程序却能正常执行,网上查阅后发现要经过PyCharm对函数进行测试,必须按照特定的步骤方法,有些单元测试还要另外安装特定的模块,在按照正确的步骤进行后单元测试也能够正常运行
在一开始进行单元测试时,想固然的添加main函数,认为测试和正常的代码执行无异,但尝试了几回且确认测试代码没有问题后测试仍是没法正常开始,网上查阅后才发现Pycharm中进行单元测试时不会执行main()函数,在已经设定好的类中添加测试函数的方法便可。
回归测试是指修改了旧代码后,从新进行测试已确认修改没有引入新的错误或致使其余代码产生错误的一种测试方法。具体流程就是在当前版本中对上一版本中测过的功能再重复测试一遍
在本次做业中,我在form_display()中新增了判断语句以在运算结果为整数时执行save_to_file()函数,,为了肯定功能添加后没有产生新bug,再次对form_display的打印功能进行了测试。
首先在git clone下来的文件路径出右键,选择Git bash here
,输入命令行Git status
检查仓库状态,以下图所示:
接着输入命令行Git push
即可以将代码上传至GitHub仓库中,以下图所示:
以后即可以看到GitHub上的仓库中多出了与本身帐户名相同的包含程序源码的文件夹,点击本身仓库界面的New Pull Request
:
在弹出的新页面中选择Create pull request
便可成功将做业源码提交,以下图所示:
虽然此次做业占比较小,但却也用了较长时间而且查阅网上得资料来完成,而且虽然使用了python来完成,却没有用到面向对象的思想经过建立类来实现程序,深入体会到了目前能力的不足≡(▔﹏▔)≡。但经过完成此次做业,体会到了软件设计到实现到测试到发布的大致流程,熟悉了各类工具的使用,而且在代码实现过程当中也巩固了前段时间自学的Python,走了一遍较为完整的项目设计的流程,由衷地感觉到了邹欣老师所推崇的“作中学”的思想(ง •_•)ง。