201871010109-胡欢欢 实验三 软件工程结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告
博文名称:201871010109-胡欢欢 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告(1分)
博文开头(1分)
项目 | 内容 |
---|---|
课程班级博客链接 | https://edu.cnblogs.com/campus/xbsf/2018CST |
这个作业要求链接 | https://www.cnblogs.com/nwnu-daizh/p/14604444.html |
我的课程学习目标 | 1、学习使用flask框架开发项目 2、了解遗传算法 3、掌握结对开发软件项目的基本方法 |
这个作业在哪些方面帮助我实现学习目标 | 1、本次作业促使我初步学习了flask框架的使用 2、本次作业使我基本掌握了多人结对开发的基本方法3、这里还有一个收获到的小知识,在开发本次项目前我一直不明白程序测评的原理,在设计测评接口时通过查阅资料加思考,我终于明白了,相信在以后遇到类似的需求会更加得心应手 |
结对方学号-姓名 | 201871010114-李岩松 201871010106-丁宣元 |
结对方本次博客作业链接 | https://www.cnblogs.com/budinge/p/14630602.html https://www.cnblogs.com/liyansong0198/p/14644940.html |
本项目Github的仓库链接地址 | https://github.com/budinge/Exercise-homework1.git |
任务一:阅读《现代软件工程—构建之法》第3-4章内容,理解并掌握代码风格规范、代码设计规范、代码复审、结对编程概念;
通过阅读,做出如下总结:
- 代码风格规范。主要是文字上的规定,看似表面文章,实际上非常重要。代码风格的原则是:简明,易读,无二义性
- 代码设计规范:牵扯到程序设计、模块之间的关系、设计模式等。比如针对函数,他的最重要的原则就是:只做一件事,并且要做好。
- 代码复审:看代码是否在代码规范的框架内正确地解决了问题。代码复审的三种形式:自我复审、同伴复审、团队复审。目的是找出代码错误、发现逻辑错误、发现算法错误、发现潜在的错误和回归性错误、发现可能需要改进的地方、传授经验;代码复审后把记录整理出来:更正明显的错误、记录无法很快更正的错误、把所有的错误记在自己的一个“我常犯的错误”表中,作为以后自我复审的第一步。
- 结对编程是一种敏捷软件开发的方法,两个程序员在一个计算机上共同工作。一个人输入代码,而另一个人审查他输入的每一行代码。输入代码的人称作驾驶员,审查代码的人称作观察员(或导航员)。两个程序员经常互换角色。在结对编程模式下,两个人肩并肩地、平等地、互补地进行开发工作。
任务二两两自由结对,对结对方《实验二 软件工程个人项目》的项目成果进行评价:
任务三
- 需求分析陈述(5分)
对于本次作业,考虑到实现的难易程度以及用户体验,我们决定采用前后端分离思想,结合使用flask+Amaze UI框架+MySQL数据库完成开发。
-
框架说明
flask用于开发服务端接口,Amaze UI用于开发前端界面,发送请求获取数据并完成数据渲染。数据库采用MySQL。 -
接口说明
后端有5大接口,分别是:散点图绘制接口,排序接口,回溯求解接口,动态规划求解接口,用户算法评测接口。 -
界面说明
针对这5大接口,分别对应前端的5个界面,各界面需要完成请求数据,解析响应结果,响应结果数据渲染。 -
代码规范说明
- 软件设计说明(5分)
-
后端接口设计说明,如图
-
后端接口目录结构,如图,其中,src文件夹存放项目源代码,static文件夹存放静态资源,upload文件夹存放测评文件与测评代码,app.py为程序的主文件
-
界面设计说明
- 软件实现及核心功能代码展示(5分)
- 散点图绘制接口代码展示
# 更新散点图接口
@app.route('/show',methods=['post','get'])
def photo():
# 获取请求参数
fileName = json.loads(request.get_data())['fileName']
seriesNumber = json.loads(request.get_data())['seriesNumber']
# 创建数据库操作对象
db = dbManger.dbManger(fileName,seriesNumber)
# 从数据库读取信息
pList = db.profitThrre()
wList = db.weightThrre()
# 绘制散点图
path = show.show(pList,wList)
# 返回图片路径
return path
- 排序接口代码展示
# 排序接口
@app.route('/sort',methods=['post','get'])
def sort():
reDict = {}
# 获取请求参数
fileName = json.loads(request.get_data())['fileName']
seriesNumber = json.loads(request.get_data())['seriesNumber']
# 创建数据库操作对象
db = dbManger.dbManger(fileName, seriesNumber)
pwList = db.pwNine()
# 排序
sortList = sortData.sort(pwList)
# 构造响应数据
for item in range(len(sortList)):
p1 = sortList[item][0]
p2 = sortList[item][1]
p3 = sortList[item][2]
w1 = sortList[item][3]
w2 = sortList[item][4]
w3 = sortList[item][5]
pw1 = sortList[item][6]
pw2 = sortList[item][7]
pw3 = sortList[item][8]
data = {"p1":p1,"p2":p2,"p3":p3,"w1":w1,"w2":w2,"w3":w3,"pw1":pw1,"pw2":pw2,"pw3":pw3}
reDict.update({str(item):str(data)})
re = json.dumps(reDict)
print(re)
# 返回排序结果
return re
- 回溯算法求解接口展示
# 回溯法求解接口
@app.route('/flashBack',methods=['post','get'])
def fBack():
# 获取请求参数
fileName = json.loads(request.get_data())['fileName']
seriesNumber = json.loads(request.get_data())['seriesNumber']
maxWeight = json.loads(request.get_data())['maxWeight']
# 创建数据库操作对象
db = dbManger.dbManger(fileName, seriesNumber)
# 读取数据
pList = db.profitThrre()
wList = db.weightThrre()
# 回溯法求解
time1 = time.time()
flashBack.flashBack(maxWeight,-1,3,0,0,pList,wList)
time2 = time.time()
# 获取返回值
re = flashBack.re()
# 构造响应数据
reDict = {'maxProfit':re,'time':time2-time1}
# 返回求解结果
return reDict
- 动态规划算法求解接口展示
# 动态规划求解接口
@app.route('/dp',methods=['post','get'])
def d():
# 获取请求数据
fileName = json.loads(request.get_data())['fileName']
seriesNumber = json.loads(request.get_data())['seriesNumber']
maxWeight = json.loads(request.get_data())['maxWeight']
# 创建数据库操作对象
db = dbManger.dbManger(fileName, seriesNumber)
# 读取数据
pList = db.profitThrre()
wList = db.weightThrre()
#动态规划求解
time1 = time.time()
re = dp.dp(maxWeight,pList,wList)
time2 = time.time()
# 构造响应对象
reDict = {'maxProfit':re,'time':time2-time1}
# 返回求解结果
return reDict
- 动态测评接口代码展示
# 动态测评接口
@app.route('/upload',methods=['post','get'])
def upPrograme():
# 读取的文件名
fileName = json.loads(request.get_data())['fileName']
# 第几组数据
seriesNumber = json.loads(request.get_data())['seriesNumber']
# 代码类型
fileType = json.loads(request.get_data())['fileType']
# 代码
value = json.loads(request.get_data())['value']
# 最大价值
maxWeight = json.loads(request.get_data())['maxWeight']
# 数据库读取数据
db = dbManger.dbManger(fileName, seriesNumber)
pList = db.profitThrre()
wList = db.weightThrre()
# 拼接得到文件名
file = 'userTest.'+fileType
# 保存代码到文件
upload.up(file,value)
# 运行测试代码
reDict = {'outStr':runPy.runP(pList,wList,maxWeight).split('----')[0].strip('\n'),'userOutStr':runPy.runP(pList,wList,maxWeight).split('----')[1].strip('\n')}
# 返回测评结果
return json.dumps(reDict)
- 程序运行(2分)
-
散点图绘制,如图
-
回溯法求解,如图
-
动态规划求解,如图
-
动态测评,如图
-
保存历史测评数据到服务端,类似于日志,如图
-
描述结对的过程,提供两人在讨论、细化和编程时的结对照片(3分)
-
提供此次结对作业的PSP(4分)
PSP2.1 | 任务内容 | 计划共完成需要的时间(h) | 实际完成需要的时间(h) |
---|---|---|---|
Planning | 计划 | 0.5 | 0.5 |
nbsp; Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 0.5 | 0.5 |
Development | 开发 | 22 | 28 |
nbsp; Analysis | 需求分析(包括学习新的技术) | 8 | 14 |
nbsp; Design Spec | 生成设计文档 | 1 | 1 |
nbsp; Design Review | 设计复审 | 0.5 | 0.5 |
nbsp; Coding Standard | 代码规范(为开发制定合适的规范) | 1 | 0.5 |
nbsp; Design | 具体设计 | 1.5 | 0.5 |
nbsp; Coding | 具体编码 | 67 | 10 |
nbsp; Code Review | 代码复审 | 1 | 0.5 |
nbsp; Test | 测试(自我测试,修改代码,提交修改) | 2 | 4 |
Reporting | 报告 | 2 | 1.2 |
nbsp; Test Report | 测试报告 | 1 | 0.5 |
nbsp; Size Measurement | 计算工作量 | 0.5 | 0.2 |
nbsp; Postmortem & Process Improvement Plan | 事后总结 ,并提出过程改进计划 | 0.5 | 0.5 |
- 小结感受(4分)
通过本次结对编程作业,我感受到多人合作开发如果制定一个良好的计划,就可以极大的提高开发效率,反之,如果没有计划好,事先没有商议,则会为开发带来极大的困难,另外,交流和讨论时可以采取线上交流的方式,线上交流陈本要低很多,而且更加灵活,在本次开发过程中,我们就是因为事先通过在线交流等,明确了每个人的任务以及代码规范,才使得互相看代码时不至于看不懂,还有前后端数据交互的格式的提前制定,也使得前后端对接相对得心应手。