软件工程实践2019第五次作业——结对编程的编程实现
链接地址
031702211(结对同学):https://www.cnblogs.com/shan33/p/11604934.html
031702302(我):https://www.cnblogs.com/sweetiekiyo/p/11704403.html
Github项目地址:https://github.com/kiyo-me/031702211-031702302.git
具体分工
031702211:数据处理,数据输出
031702302:数据输入,美化页面
其余:共同完成
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 60 |
Estimate | 估计这个任务需要多少时间 | 60 | 60 |
Development | 开发 | 1305 | 2850 |
Analysis | 需求分析 (包括学习新技术) | 600 | 1500 |
Design Spec | 生成设计文档 | 60 | 45 |
Design Review | 设计复审 | 30 | 30 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | 15 |
Design | 具体设计 | 45 | 90 |
Coding | 具体编码 | 300 | 780 |
Code Review | 代码复审 | 90 | 90 |
Test | 测试(自我测试,修改代码,提交修改) | 150 | 300 |
Reporting | 报告 | 330 | 360 |
Test Repor | 测试报告 | 150 | 180 |
Size Measurement | 计算工作量 | 90 | 90 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 90 | 90 |
合计 | 1515 | 3270 |
解题思路描述与设计实现说明
代码组织
代码主要分为以下四个模块:
- 展示样式
- 数据输入
- 数据处理及渲染树
- 数据输出
算法的关键与关键实现部分流程图
算法的关键在于如何妥善地对输入的数据进行处理,即将其准确划分后,将数据组织成为一个树形数组,再以此渲染进框架内。
有价值的代码片段
function msg1()
{
var text;
text=$("#msg").val();
arr.length = 0;
var k=1;
var text1 = text.split("\n");
var len=text1.length;
var flag1;
for(var i=0;i<len;i++)
{
if(text1[i].length!=0)
{
var b=text1[i].split(/[::级、,,。. ]/); //将每一行的输入数据划分
if(b[0]=="导师")
{
arr[k-1]={id :k,name:"导师:"+b[1],fid:0};//id:自身id name:节点名称 fid:父节点id
flag1=k;
k++;
}
else if (b.length!=0)
{
var oj={id :k,name:b[1],fid:flag1} ; //博士生||硕士生||本科生
for(var j=flag1;j<k-1;j++) //判断是否已存在该类节点
{ //如:在之前的输入中已存在博士生输入,则不再建立博士生节点
if(oj.name==arr[j].name)
break;
}
if(j>=(k-1))
{
arr.push(oj);
k++;
}
oj={id:k,name:b[0]+"级",fid:j+1}; //年级
var z;
for(z=j;z<k-1;z++) //判断是否已存在该类节点
{
if(oj.name==arr[z].name&&arr[j].name==arr[arr[z].fid-1].name)
break;
}
var flag;
if(z>=(k-1))
{
flag=k;
arr.push(oj);
k++;
}
else
var flag=z+1;
for(var m=2;m<b.length;m++)
{
if(b[m].length!=0)
{
oj={id:k,name:b[m],fid:flag};
arr.push(oj);
k++;
}
}
}
}
}
console.log(arr);
}
附加特点设计与展示
设计的创意独到之处及意义
- 能够同时输出多个树:避免用户想要一次浏览多个树却需要不断刷新的困境
- 在用户输入数据前有提示框:用户可以按照提示的输入规范进行输入,加强保证输出正确的树
- 输出的树有背景框:使树更加美观,更易于用户浏览树
实现思路
- 能够同时输出多个树:在原有的单棵树基础上,对“导师”关键词再做判断,从何保证不同树的分离
- 提示框/背景框:利用css盒子模型对样式进行设定,背景框因为需要在确定后生成,故利用按钮来使其从“hidden”到“visible”
有价值的代码片段
- 输出多个树:代码同“算法中有价值的代码片段”
- 背景框利用jQuery和按钮实现从隐藏到展现的过程
$(document).ready(function() {
$('#butt').click(function(){ //butt是按钮的id
$(".hint").css("visibility","visible"); //hint是背景框利用的css样式
})
})
实现成果展示
-
提示框
-
背景框/输出多棵树
目录说明和使用说明
目录组织
- source文件夹:用于存储图片文件和利用的框架
- tree.html:主页面
- tree.js:html中引用的js代码文件
- readme.md:使用指南
如何运行
1.下载github项目中所有文件
2.利用谷歌浏览器打开tree.html
3.在文本框中按输入格式进行数据输入
4.点击“确定”,即可查看生成的师门树
单元测试
学习
选用qunit测试工具 官网:https://qunitjs.com/
参考资料:https://www.cnblogs.com/malinlin/p/4924687.html
https://blog.csdn.net/yichair/article/details/79241365
学习的方式主要就是跟着以上的资料一点一点做下来
简易教程:https://files.cnblogs.com/files/shan33/qunit简易教程.rar
代码&测试函数
- 测试的函数为上述的msg1
- 部分代码
<script type="text/javascript">
//在这里填写需要测试的函数模块
module("Test Module 1")
QUnit.test("pass 1", function (assert)
{
var qu="导师:黑糖,2019级博士生:珍珠。";
var ans=[{id: 1, name: "导师:黑糖", fid: 0}, {id: 2, name: "博士生", fid: 1},{id: 3, name: "2019级", fid: 2}, {id: 4, name: "珍珠", fid: 3}];
assert.deepEqual(msg(qu),ans ,"1 pass");
});
QUnit.test("pass 2", function (assert)
{
var qu="导师:白开水。";
var ans=[ {id: 1, name: "导师:白开水", fid: 0}];
assert.deepEqual(msg(qu),ans ,"2 pass");
});
QUnit.test("pass 3", function (assert)
{
var qu="导师:little白,2017级本科生。";
var ans=[ {id: 1, name: "导师:little白", fid: 0}, {id: 2, name: "本科生", fid: 1}, {id: 3, name: "2017级", fid: 2}];
assert.deepEqual(msg(qu),ans ,"3 pass");
});
QUnit.test("pass 4", function (assert)
{
var qu="导师:白状元,2012级本科生:白拉普,2019级本科生:徐坦.";
var ans=[ {id: 1, name: "导师:白状元", fid: 0}, {id: 2, name: "本科生", fid: 1}, {id: 3, name: "2012级", fid: 2}, {id: 4, name: "白拉普", fid: 3}, {id: 5, name: "2019级", fid: 2}, {id: 6, name: "徐坦", fid: 5}];
assert.deepEqual(msg(qu),ans ,"4 pass");
});
//其余的测试样例因为过长在此不放出
</script>
- 结果
思路
- 为了测试能尽可能覆盖所有的情况,所以在样例里除了正常的输入格式外,还添加了如“只有导师”,“有回车而无输入”,“同样学位同样年级”等类似的特殊输入以便于覆盖全部情况。
Github代码签入记录
困难及解决方法
- 困难
其实整个过程都很困难……[从0开始的悲伤,此处省略一万字]
最大的困难应该在于如何将数据渲染到树形组件上,在做好简单的数据划分以后,在如何渲染着一块花了非常长的时间。 - 解决方法
在经过长时间的探索后,不断搜寻的过程中,发现可以将数据首先存放于一个树形数组(包含自身id,自己的父节点id,name)中,进而继续寻找较为便捷的树形组件。最后找到了利用的ztree树形组件,能够直接对接树形数组完成渲染。 - 收获
第一次尝试利用外部ui组件,将自己的数据渲染,形成一个完整的东西,在过程中也搜索了解到了很多相关的知识。
评价队友
说实话,真的没有什么不足之处V毕竟有多年的情感和默契支撑,除了想夸就是想夸!我的队友超棒!考虑问题也很细致,学东西也好快。非要说有什么不足的话,大概是有时候改的太快让人有些反应不过来。