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分)

  1. 前期思路的整理。一开始我自己认为会使用到栈,但是经过队友的提示、画图,最终确定使用二叉树存放数和操作符。
  2. 语言的选择。一开始准备用java写,但是基于之前我自己使用java过程出现一点困难,尝试花费一些时间试图解决,未果,遂放弃java。并且python的使用会方便许多,决定使用python,但期间多次还保留c的思维,还好队友多次耐心讲解。
  3. 括号的处理。括号是本程序容易出错的地方,也是我认为比较难的点。有几次以为编程结束,但是有括号的地方或多或少出现了一些问题,逻辑有漏洞,前期还是要需要思考的仔细一些。
  4. 较大收获是认识到前期需求分析的重要性,把问题划分几个点,这样才清楚每一步都需要做什么。慢慢来比较快。
  5. 代码规范。一些细节的规范可以通过工具实现。

 

 

要求2 给出结对开发的截图证据,要求截图能够证明你们是在结对编程。 (5分)

无人帮忙拍摄。

 

要求3 使用coding.net做版本控制。checkin 前要求清理 临时文件、可执行程序,通常执行 build-clean可以达到效果。(25分)

版本控制

coding:https://e.coding.net/qqq2/f4/f4.git

 

PSP:

 

posted @ 2020-10-07 09:49  Dul  阅读(158)  评论(0编辑  收藏  举报