结对编程 - 队友代码分析
此次项目,我们都是基于 python 来实现的,所以代码看起来十分亲切。
说实话,好久没看别人的代码了,当我拿到搭档的代码时,不禁发出感叹:“居然没有面向对象编程!”。细看之后,其实就差封装一下嘛,整体代码写的优雅而不失端庄,含蓄而又不失奔放,平淡中显示出不凡的编程功底,可谓是逻辑严谨,条条有理,字字珠玑,句句经典,代码风格确实登得大雅之堂,是我辈应领悟之典范 (๑•̀ㅂ•́)و✧
工程文件
接下来我解读一下搭档的项目,他本来打算用一个模块(文件)实现,在本人强烈建议下分了模块写,整个工程由 4 个文件组成:
- Account_information.xlsx:
- Formula.py:编写了生成式子会用到的方法
- Utils.py:有点潦草,里面只有一个返回指定格式的日期和时间的方法 - -
- main.py:交互层,也是要运行主文件,编写的是一些和用户交互的方法,包括登录、选择、查重、生成/保存试卷
测试结果
提供了一个可执行文件 main.exe 可以直接测试程序,结果是实现了所有指定的功能 ୧(๑•̀◡•́๑)
优点
- 输出的提示好看,交互良好
虽然规定了只能用控制台展示,但就凭 cmd 的交互提示也比我的好看哎。

- 容错性强,还算是靠谱的
比如我不按照格式输入,也不会使程序报错而停止运行。


- 编码规范,可读性强
毕竟这代码不是只给自己看的,所以搭档的程序中变量、方法的命名严格按照编程规范,见名知意。代码块之间的空行和缩进也严格遵守 python 的编码风格,让人看了如沐春风。
- 代码低耦合,高内聚,重用性好
每个文件中一个方法只实现一个功能;且与其他模块不相交;方便修改和找 bug;基本上没有重复冗余的代码,抽象程度适当,每个方法体都不算庞大。
- 生成式子的算法新颖可靠,值得学习
生成逆波兰表达式:依据后缀表达式的计算流程(遍历表达式,遇到数字压栈,遇到操作符取栈顶两个数字出栈计算后压栈)易知,任意逆波兰表达式的前两项必定为数字,最后一项必定为操作符,且计算过程中遇到符号至少保证栈中要有两个数字。
所以满足以下要求即可生成随机的合法逆波兰表达式:
-
初始化状态下,随机生成两个数字,并为最后的操作符预留一个位置
-
用一个变量记录此时栈中的元素个数,每次生成一个数字,栈中个数加一,每次生成一个操作符,栈中个数减一。每一次生成都需要判断此时栈中元素个数,如果小于2,则只能随机生成一个操作数;如果大于2,则先随机选择是生成操作数还是操作符。
-
1 def InversePolish(): 2 """ 3 生成随机的合法逆波兰表达式 4 """ 5 if g_operand_num == 1: 6 operand = random.randint(1, 100) 7 g_inverse_polish.append(operand) 8 9 elif g_operand_num == 2: 10 for _ in range(2): 11 operand = random.randint(1, 100) 12 g_inverse_polish.append(operand) 13 14 operator_index = random.randint(0, 3) 15 g_inverse_polish.append(g_operator_lib[operator_index]) 16 17 else: 18 while g_operand_num > 0 or g_operator_num > 1: 19 20 if g_stack_num < 2: 21 RandomOperand() 22 else: 23 type_random = random.randint(0, 1) 24 if type_random == 0 and g_operand_num > 0: 25 RandomOperand() 26 else: 27 RandomOperator() 28 29 RandomOperator()
逆波兰表达式转化为中缀表达式:算法思想是模拟后缀表达式的计算过程(但过程中入栈的不是计算结果而是计算表达式),为每个操作符和入栈的表达式记录一个优先级,依据优先级判断表达式是否需要添加括号。
缺点
人无完人,代码也肯定会存在一些缺点,下面来盘一盘。
- 这个程序是面向过程的,没有使用到类;因此倘若变更需求,代码需要改动的可能较多。
- 检查密码是否正确这里有点潦草,就是判断密码是否等于 “123”,不是很通用。
- 保存试卷采用的是生成一个式子就打开文件保存一次,这会使得整个程序文件 I/O 次数过多,其实可以先存在数据结构中,生成完指定数量的式子再一次读入文件。
- 查重那里的逻辑不够好:项目中查重的设计是,生成式子过程中如果查到有式子重复了就把已生成的式子都作废了,重新生成整个试卷,这会使得一个式子重复导致很大的代价,然而只需要重新生成一个不重的式子就行了。
- 生成的式子的一些不足之处:由于生成初中和高中式子中用到的符号都是随机生成的,可能不包含指定有的操作符:1.生成初中题目时不能保证一定包含一个中级符号;2.生成高中题目时不能保证一定含有一个高级符号,且不会包含中级符号。
- 用户名存在于外部本地文件,可能造成一定的依赖,存于云端数据库中能够减少依赖,这也是我们下一步结对编程想要改进的地方。(还有 Utils.py 文件略微有凑工程之嫌疑,就不多说了吧...)
感想
总的来看,整个程序还是稍稍有些许不足,我觉得使用面向对象思维会更好,然后还可以继续分模块实现,比如将用户和用户管理分开定义到一个类中,这样使得代码看起来更加有结构,层次分明。
不过也让我在对自己的项目中的某些地方的实现有了新的认识,让自己发现了新大陆,每一个人的代码思路与风格都不相同,但我们都能从别人的代码中学习到很多,进而实现对自己代码思路与风格的改进,希望以后写的代码能更加符合规范。
执笔至此,不再多言,前路漫漫,下次再聊。

浙公网安备 33010602011771号