实验二 结对编程之第二阶段
一、实验目标
1)体验敏捷开发中的两人合作。
2)进一步提高个人编程技巧与实践。
二 、实验内容
1)根据以下问题描述,练习结对编程(pair programming)实践;
2)要求学生两人一组,自由组合。每组使用一台计算机,二人共同编码,完成实验要求。
3)要求在结对编程工作期间,两人的角色至少切换 4 次;
4)编程语言不限,版本不限。建议使用 Python 或 JAVA 进行编程。
三、队员信息
|
称 |
队员 |
博客地址 |
GitHub仓库地址 |
选择课题 |
|
XYZ |
王慧 |
生命游戏 |
||
|
叶啟文 |
四、代码规范
参考:https://www.cnblogs.com/niansi/p/7751374.html
1.代码编排
a.缩进。4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格。
b.每行最大长度79,换行可以使用反斜杠,最好使用圆括号。换行点要在操作符的后边敲回车。
c.如无特殊情况,文件一律使用UTF-8编码。
2.文档编排
a.模块内容的顺序:模块说明和docstring—import—globals&constants—其他定义。其中import部分,又按标准、三方和自己编写顺序依次排放,每组之间空一行。
b.不要在一句import中多个库
3.空格的使用(总体原则,避免不必要的空格。)
a.逗号、冒号、分号前不要加空格。
b.操作符左右各加一个空格,不要为了对齐增加空格。
c.不要将多句语句写在同一行,尽管使用‘;’也不允许。
4.注释(总体原则,错误的注释不如没有注释。)
a.块注释,在一段代码前增加的注释。在‘#’后加一空格。段落之间以只有‘#’的行间隔。
b .行注释,在一句代码后加注释。
c. 至少使用两个空格和语句分开,避免无谓的注释。
5.命名规范
a. 尽量单独使用小写字母‘l’,大写字母‘O’等容易混淆的字母。
b.函数命名使用全部小写的方式,可以使用下划线; 常量命名使用全部大写的方式,可以使用下划线。
c.类名使用驼峰命名风格,首字母大写,私有类可用一个下划线开头。
五、程序的总体设计
六、结对编程过程
我们小组通过QQ屏幕分享来通过实现代码编程,通过在GitHub上托管代码来实现代码保存与更新。
1.针对python代码讨论代码规范

2.针对代码不同模块进行结对编程
|
交互 |
驾驶员 |
观察员 |
编程内容 |
|
第1次 |
王慧 |
叶啟文 |
细胞生命初始化模块 |
|
第2次 |
叶啟文 |
王慧 |
游戏规则设置模块 |
|
第3次 |
王慧 |
叶啟文 |
接收动图长度值 |
|
第4次 |
叶啟文 |
王慧 |
绘制动图模块 |
|
第5次 |
王慧 |
叶啟文 |
代码升级,实现地图从N* N到N* M |
|
第6次 |
叶啟文 |
王慧 |
代码优化,删除冗余代码、简化注释等 |
部分过程记录:

七、功能模块
1.细胞生命初始化模块
# 初始化细胞生命状态
def randomGrid(N):# returns a grid of NxN random values
return np.random.choice(vals, N * N, p=[0.2, 0.8]).reshape(N, N)
2.游戏规则设置模块
#更新细胞生命状态
def update(frameNum, img, grid, N):
newGrid = grid.copy()
for i in range(N):
for j in range(N):# 检测网格的8个边缘。用取模运算符让值在边缘折返
total = int((grid[i, (j - 1) % N] + grid[i, (j + 1) % N] +
grid[(i - 1) % N, j] + grid[(i + 1) % N, j] +
grid[(i - 1) % N, (j - 1) % N] + grid[(i - 1) % N, (j + 1) % N] +
grid[(i + 1) % N, (j - 1) % N] + grid[(i + 1) % N, (j + 1) % N]))
if grid[i, j] == ON:
if (total < 2) or (total > 3):
newGrid[i, j] = OFF
else:
if total == 3:
newGrid[i, j] = ON
# update data
img.set_data(newGrid)
grid[:] = newGrid[:]
return img
3.绘制动图模块
# declare grid
grid = randomGrid(N)
parser = argparse.ArgumentParser()
parser.add_argument('--interval', dest='interval', required=False) # 设置动画更新间隔的毫秒数
args = parser.parse_args()
# 设置动画
fig, ax = plt.subplots(facecolor='Lavender') # 配置 matplotlib 的绘图和动画参数
img = ax.imshow(grid, cmap=cmap,interpolation='nearest') # 用plt.show()方法将这个矩阵的值显示为图像,并给 interpolation 选项传入'nearest'值,以得到尖锐的边缘(否则是模糊的)
ani =animation.FuncAnimation(fig, update, fargs=(img, grid, N,),frames=10,interval=50,save_count=50)
# animation.FuncAnimation()调用函数 update(),该函数在前面的程序中定义,根据命游戏的规则更新网格。
plt.show()
4.接收动图长度值
print("请输入一个地图的大小值:")
N = input()
try:
if N and int(N) > 8:
N = int(N)
except ValueError:
print('The input is not a number!')
sys.exit(0)
5.代码升级,实现地图从N* N到N* M
# set grid size
print("请输入一个地图的长与宽:")
M = input()
N = input()
try:
if M and int(M) > 8:
M = int(M)
if N and int(N) > 8:
N = int(N)
except ValueError:
print('The input is not a number!')
sys.exit(0)
# 实现环形边界条件
def update(frameNum, img, grid, N ,M):
newGrid = grid.copy()
for i in range(N):
for j in range(M): # 检测网格的8个边缘。用取模运算符让值在边缘折返
total = int((grid[i, (j - 1) % M] + grid[i, (j + 1) % M] +
grid[(i - 1) % N, j] + grid[(i + 1) % N, j] +
grid[(i - 1) % N, (j - 1) % M] + grid[(i - 1) % N, (j + 1) % M] +
grid[(i + 1) % N, (j - 1) % M] + grid[(i + 1) % N, (j + 1) % M]))
if grid[i, j] == ON:
if (total < 2) or (total > 3):
newGrid[i, j] = OFF
else:
if total == 3:
newGrid[i, j] = ON
# update data
img.set_data(newGrid)
grid[:] = newGrid[:]
return img
结果显示:
1.输入参数有误时:

2.N*N的动图
3.N*M的动图

4.动图显示为:

八、项目github地址

commit记录:

九、问题解决
1.python模块下载慢
此次实验中我们用到了numpy和matplotlib两个模块,但是在python的官方网站下载模块不仅速度特别慢,中途还会无缘无故发生无法下载的情况。为了下载这两个模块我们花了比较长的时间,也尝试过在CSDN中下载,最后终于下载过来。
2.python安装模块pip需升级
参考教程我先在python中安装模块(在cmd中进入python安装的文件位置,输入命令:python -m pip install numpy),结果报错提示:pip需要先升级。

根据提示我输入命令:python -m pip install --upgrade pip,但是更新到一半又报错了。后查找资料,有博主给出新的命令:python -m pip install -U pip,但是执行还是在中途中断。
最后看见别人说命令需要多尝试几次,我用系统提示的命令运行了3、4次后,最终pip升级成功。

接下来进入python的scripts中安装两个模块都成功了。

3.pycharm安装模块报错
参考在pycharm中导入模块的教程,我在本次实验的项目中安装两个模块,但是一直不成功。参考很多教程后,找到了问题所在:由于python与pycharm安装路径不同,导致pycharm的sys.path中少了三个重要的路径。
解决方法为:file->setting->project->Project Interpreter-> 小齿轮 ->Show All-> 加号->System Interpreter->找到python安装文件中的python.exe->点击确定。然后再导入两个模块即可。

4.无法生成动态地图
每次执行代码,结果都只显示一张静态图,我们一直以为是代码有问题。针对绘制动图的animation模块的函数,我们在详细学习后还是找不到问题出现的原因。最后查找资料发现pycharm只显示一帧的解决方案,通过设置后成功显示动图。

5.设置地图长宽颠倒
在升级代码从N*N的地图到N* M的地图时,我们以N为长(横轴),M为宽(纵轴)来执行时,在游戏规则模块发现有数组下标越界的情况,且结果显示的一张静态图的长与宽与我们设想的不一致,所以我们发现长与宽颠倒了。我们将NM交换后,运行成功。
例:我们输入长N为20,宽M为30,结果报错下标越界,长宽颠倒了。
十、实验总结
1.在进行代码编辑之前的准备工作,我们就面临了很多问题,比如模块下载不成功、模块导入不成功等。寻找能正真解决问题的方法也比较漫长,不是方法不适用就是方法不正确,我们参考多个平台(百度、CSDN、博客园等)最终找到解决问题的方法。在成功导入模块之后,我们感觉之前所遇到的问题都不算什么,遇到错误不要怕也不要烦躁,主动去了解都能解决,不要把问题看得过于困难,正是因为我们不懂才会觉得难。解决问题的过程中,我们学习到很多,不仅仅是理论知识,更多的是解决问题的方法与面对错误时的态度。
2.由于之前学习python只是比较浅显的知识,对于实验中导入的numpy和matplotlib模块了解甚少,所以即使是在参考别人的代码时理解起来还是比较吃力。遇到不会的函数通过查资料,理解其中每个参数的作用,由来及去向,疏通了整个代码的实现流程。在理解得基础上,我们通过调试代码,删除冗余的数据,简化复杂的代码,增加注释最后使代码实现更高效。我们还成功将地图从固定的大小升级为自定义的地图大小。
3.最终我们的代码实现只有仅仅六十几行,相对比其他代码而言是非常简洁的,可以发现python在可视化方面有着很大的功能与作用。
结对编程第一阶段:https://www.cnblogs.com/yqw0710/p/12542668.html
参考文献:
1、python模块下载地址:https://pypi.org/project https://www.lfd.uci.edu/~gohlke/pythonlibs
2、pip升级解决:https://blog.csdn.net/lanluyug/article/details/82878152
3、python numpy安装方法:https://blog.csdn.net/swjian1997/article/details/82027013?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
4、pycharm中导入模块报错解决:https://www.cnblogs.com/zhiyuanxiong/p/8948500.html
5、python设置执行参数argparse介绍:https://blog.csdn.net/Samaritan_x/article/details/84146029
6、python绘制动图animation模块的使用:https://blog.csdn.net/u013180339/article/details/77002254
7、pycharm 无法显示动态图片解决:https://www.jianshu.com/p/c6b362fde21c
浙公网安备 33010602011771号