20200924-5 四则运算试题生成,结对
此作业的要求参见[https://edu.cnblogs.com/campus/nenu/2020Fall/homework/11245]
版本控制
coding:https://e.coding.net/qqq2/f4/f4.git
要求1 参考《构建之法》第4章两人合作,结对编程上述功能,要求每人发布随笔1篇 (代码是共同完成的,随笔有以下两种方式:(①允许两人写一份,得一份分数,二人均分;②如果每人写一份,内容不得抄袭,体会需要是自己的,分别得到自己博客的分数)。
(1) 给出每个功能的重点、难点、编程收获。
结对伙伴:谢文强、杜蕾
功能1. 四则运算
浏览了四个功能,我们将功能一、二合并。随机数以及括号的处理。
重点:处理随机数
难点:数据的存储的方式。由于只出四个数字的题目,我们采用二叉树的方式。操作符有三个,可以列出了五种完全二叉树的组合,随机选出一棵树,且叶子结点都为操作数。并且树的后序遍历为逆波兰表达式,中序遍历为中缀表达式。
编程收获:没有想到可以用二叉树的方式。
重要代码:
1 def init_tree(root: Node) -> None: 2 if root.left == None and root.right == None: 3 root.data = Fraction(random.randint(0, 9), 1) # random.randint(1, 9) 4 else: 5 root.data = ops[random.randint(0, len(ops) - 1)] 6 init_tree(root.left) 7 init_tree(root.right) 8 9 10 def tree_lrn(root: Node) -> None: 11 if root == None: 12 return list() 13 14 nodes_left = tree_lrn(root.left) 15 nodes_right = tree_lrn(root.right) 16 return nodes_left + nodes_right + [root.data]
功能2. 支持括号
重点:括号的处理。
难点:括号的处理耗费了很多时间,我们先将括号放一对数字之间,再将不需要存在的括号进行删除。难在括号需要去掉的地方,开始认为同优先级的符号可以去掉,忽略了减法和除法的特性,多次确认结果,重新思考进行修改。
编程收获:收获在于一开始的思考要仔细,由于粗心大意导致部分题目结果不对,又消耗一些时间。
重要代码:
1 def tree_lnr(root: Node) -> None: 2 if root == None: 3 return [], None 4 elif root.left == None and root.right == None: 5 return [root.data], None 6 7 nodes_left, op_left = tree_lnr(root.left) 8 nodes_right, op_right = tree_lnr(root.right) 9 10 if op_left != None and ops_level[root.data.__name__] > ops_level[op_left.__name__]: 11 nodes_left = [LeftBracket()] + nodes_left + [RightBrackt()] 12 13 if ( 14 op_right != None 15 and ops_level[root.data.__name__] > ops_level[op_right.__name__] 16 ): 17 nodes_right = [LeftBracket()] + nodes_right + [RightBrackt()] 18 19 if ( 20 op_right != None 21 and ops_level[root.data.__name__] == ops_level[op_right.__name__] 22 and (root.data.__name__ == "sub" or root.data.__name__ == "truediv") 23 ): 24 nodes_right = [LeftBracket()] + nodes_right + [RightBrackt()] 25 26 return nodes_left + [root.data] + nodes_right, root.data
功能一和二运行截图:
功能3. 限定题目数量,"精美"打印输出,避免重复
重点:输出对齐。
难点:python输出的格式,找了几篇博客才得到想要的输出格式。https://www.cnblogs.com/zhz-8919/p/9767357.html
编程收获:遇到不会的就去找,卡着解决不了问题。
重要代码:
1 if not str(args.c).isnumeric(): 2 print("题目数量必须是 正整数。") 3 sys.exit(0) 4 5 tplt = "{0:{3}^10}\t{1:{3}^10}" 6 num = int(args.c) 7 8 all_count = 0 9 ques_list = [] 10 f = open("question.txt", "w+") 11 while all_count < num: 12 try: 13 tree = copy.deepcopy(trees[random.randint(0, len(trees) - 1)]) 14 init_tree(tree) 15 lrn = tree_lrn(tree) 16 lnr, op = tree_lnr(tree) 17 ans = calc_list(lrn) 18 if ans in ques_list: 19 continue 20 21 ques_list.append(ans) 22 string = list2string(lnr) + " = " 23 string = format(string, " <30") 24 25 question_str = f"{string}{mixed_number(ans)}\n" 26 print(question_str, end="") 27 all_count = all_count + 1 28 if f != None: 29 f.write(question_str) 30 except Exception as ex: 31 continue 32 f.close()
功能4. 支持分数出题和运算
重点:分数的处理,本次编程使用的是python,python自带fractions模块。我们使用的是Fraction()这个方法。
难点:分数的结果会以小数点的形式输出。然后对于结果的处理是使用带分数,我们开始想对结果大于1的数进行处理,但忽略了负数,又将结果处理成绝对值的形式。运行的时候发现结果中存在2.0整数的情况,又重新将结果分成了两种情况,即整数或分数进行处理。
编程收获:还是需要仔细,培养逻辑思维。
重要代码:
1 def mixed_number(frac: Fraction) -> str: 2 string = f"{frac}" 3 if abs(frac) > 1: 4 mixed = frac.numerator // frac.denominator 5 6 if frac - mixed == 0: 7 string = f"{frac}" 8 else: 9 string = f"{mixed} {frac - mixed}" 10 11 return string
功能三和功能四运行截图:
(2)给出结对编程的体会
队友很厉害,在编程前没有直接上手,而是把所有问题功能综合一起看,整理思路,一步一步找到解决办法。所以我们用了一整快的时间都在做需求分析以及沟通、讨论,这就直接使我们后面编程的进展的十分顺利,思路也非常的明确,知道每一步都是做什么。这是我所需要学习的地方。遇到的问题就可以讨论,以前我的思路是做出一点然后再想下一步,也总会常常一个地方卡的太久,导致进展总是不顺利。这次的合作非常顺利,通过这次编程的合作,我发现两个人的合作效率也可以很高,并且同时可以学习队友身上的有点,以后对方的思考方式,很多时候可以让我们跳出自己的固有思维,呈现出1+1>2的效果。
(3) 至少5项在编码、争论、复审等活动中花费时间较长,给你较大收获的事件。 (10分)
- 前期思路的整理。一开始我自己认为会使用到栈,但是经过队友的提示、画图,最终确定使用二叉树存放数和操作符。
- 语言的选择。一开始准备用java写,但是基于之前我自己使用java过程出现一点困难,尝试花费一些时间试图解决,未果,遂放弃java。并且python的使用会方便许多,决定使用python,但期间多次还保留c的思维,还好队友多次耐心讲解。
- 括号的处理。括号是本程序容易出错的地方,也是我认为比较难的点。有几次以为编程结束,但是有括号的地方或多或少出现了一些问题,逻辑有漏洞,前期还是要需要思考的仔细一些。
- 较大收获是认识到前期需求分析的重要性,把问题划分几个点,这样才清楚每一步都需要做什么。慢慢来比较快。
- 代码规范。一些细节的规范可以通过工具实现。
要求2 给出结对开发的截图证据,要求截图能够证明你们是在结对编程。 (5分)
无人帮忙拍摄。
要求3 使用coding.net做版本控制。checkin 前要求清理 临时文件、可执行程序,通常执行 build-clean可以达到效果。(25分)
版本控制
coding:https://e.coding.net/qqq2/f4/f4.git
PSP: