软件工程实践2019第五次作业——结对编程的编程实现
学术家族树
博客地址:
结对分工
031702212:主要编码,美工(设计/css)
031702208:部分编码,单元测试,博客编写
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 30 |
Estimate | 估计这个任务需要多少时间 | 30 | 30 |
Development | 开发 | 1130 | 1870 |
Analysis | 需求分析 (包括学习新技术) | 480 | 600 |
Design Spec | 生成设计文档 | 120 | 120 |
Design Review | 设计复审 | 30 | 30 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 20 | 20 |
Design | 具体设计 | 180 | 180 |
Coding | 具体编码 | 300 | 800 |
Code Review | 代码复审 | 60 | 60 |
Test | 测试(自我测试,修改代码,提交修改) | 120 | 60 |
Reporting | 报告 | 250 | 440 |
Test Repor | 测试报告 | 60 | 180 |
Size Measurement | 计算工作量 | 10 | 20 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 180 | 240 |
合计 | 1410 | 2340 |
解题思路描述与设计实现说明
- 解题思路:
- 1.获取并处理输入的数据
→实现:使用data=$("#stxt").val();获取数据,再用split分割每行存入Arr数组,要使用的时候再对Arr数组内数据处理 - 2.用获取的数据生成一棵树
→实现:初始化树→设置插入树的中介节点→设置导师根节点→选中父节点→插入二级节点→选中父节点→插入三级节点 - 3.拓展生成多棵树
→实现:利用"导师"关键字确认要生成的树数,使用for函数实现生成树循环 - 4.添加功能及美化页面
- 1.获取并处理输入的数据
- 核心代码实现流程图
- 重要的/有价值的代码片段
按下“creat the tree”按钮所触发的函数:
$("#butt").click(function() {
$(".invisable").hide();
toLine();//提取每一行进Arr
teacherNum();//树的个数
if(n>4)
alert("您输入的树超过显示上限,仅显示前四棵树");
moveplace();//根据树的个数排版
for(var treeCirle=0;treeCirle<treeNum.length-1;treeCirle++){
zNodes=[{menuName:"导师" ,open:true}];//开始一棵新树时初始化zNodes
zNodes[0].menuName=(Arr[treeNum[treeCirle]]);//Arr2[0]
zTreeObj=$.fn.zTree.init($("#regionZTree"+treeCirle),setting,zNodes);//初始化zTreeObj
secondLayer(treeNum[treeCirle],treeNum[treeCirle+1]);//xx级xx生
thirdLayer(treeNum[treeCirle],treeNum[treeCirle+1]);//xxx、xxx、xxx
zTreeObj.cancelSelectedNode();
zTreeObj.cancelEditName("tObj"+treeCirle);
}
$("#texts").val("");//处理完数据后清除文本框
})
我们认为有价值的代码片段是secondLayer()和thirdLayer()两个函数,这两个函数的关键就在于secondLayer()函数实现存储所有二级节点的存储以便三级节点的插入.代码如下,代码解释可见注释.
secondLayer()函数实现调用后实现二级节点(即xx级xx生)的插入
function secondLayer(first,last){
//first和last为要处理的对应这棵树内容的Arr数组下标
for(var ii=first+1;ii<last;ii++){
getSname(Arr[ii]);
/*分割xx级xx生和学生名字的函数,其中令before=xx级xx生,将学生名字用split("、")分割存放入Arr2数组(Arr2数组只存放一行数据的名字,每次刷新)*/
zNodes=zTreeObj.getNodes();
zTreeObj.selectNode(zNodes[0]);
var parentZNode=zTreeObj.getSelectedNodes();
//选定二级节点要插入的父节点即导师节点
zTreeObj.addNodes(parentZNode[0], [{menuName:before}], true);
zTreeObj.expandAll(true); //展开节点
}
zzNodes=zTreeObj.getNodes()[0].children;//用zzNodes数组存放所有二级节点用于thirdLayer()中三级节点插入二级节点
}
thirdLayer()函数实现调用后实现三级节点(即人名)的插入
function thirdLayer(first,last){
var iii=0;
for(var ii=first+1;ii<last;ii++){//二级数
getSname(Arr[ii]);//获取一行数据中的人名存入Arr2
zTreeObj.selectNode(zzNodes[iii]);
var parentZNode = zTreeObj.getSelectedNodes();
//选定三级节点要插入的父节点
for(var jj=0;jj<Arr2.length;jj++)
zTreeObj.addNodes(parentZNode[0], [{menuName:Arr2[jj]}], true);
zTreeObj.expandAll(true);
iii++;
}
}
附加特点设计与展示
- 设计的创意及意义
我们设置有一个学生及导师查找框,当在查找框输入学生姓名时,该名学生的名字会在其所在的家族树所在位置中橘色标亮,并在查找框下显示导师名字,使用者可以轻易的找到学生所在位置.我们认为这对于数据量大的时候查找家族树成员很有帮助. - 实现思路
遍历n棵树→通过getNodesByParam()函数按节点名称查找匹配节点→通过selectNode()、getSelectedNodes()、getNodes()多次转换位置最后找到根节点→输出根节点名即导师名 - 重要的/有价值的代码片段
输入学生名字查询导师
function find(){
var flag=0;
var f=false;
for(var a=0;a<n;a++){
searchObj=$.fn.zTree.getZTreeObj("regionZTree"+a);
searchObj.cancelSelectedNode();//取消上一次查找所选的节点
}
data=$("#stxt").val();
for(var a=0;a<n;a++){//遍历n棵树
searchObj=$.fn.zTree.getZTreeObj("regionZTree"+a);
searnodes=searchObj.getNodesByParam("menuName",data,null);//根据名字查找到的节点searnodes[0]
searchObj.selectNode(searnodes[0]);//名字符合的节点设为选中状态
ssnodes=searchObj.getSelectedNodes();//被选中的节点ssnodes[0]
if(ssnodes.length>0){//有选中的节点
flag++;f=true;
if(flag==1){//只输出一次导师
searchObj.selectNode(ssnodes[0]);
ssnodes=searchObj.getNodes();//ssnodes更新为整棵树的节点
$("#result").text(ssnodes[0].menuName);//ssnodes[0]此时为根节点
}
}
if(!f)
$("#result").text("NONE");//没有选中的节点
}
}
- 界面展示
打开html文件显示初始页面:
重新输入数据前刷新页面
输入学生名字查询导师
目录说明和使用说明
目录是如何组织的
如何运行我的网页
- 下载(Clone or download→Download ZIP)至您的电脑并解压成文件夹,请确保完整下载了所有文件
- 在解压出的文件夹中找到Tree.html 右键→打开方式→Google Chrome
- 成功打开html文件后可看到页面上的具体操作提示,请认真阅读
- 某些可能影响页面显示效果的因素:
- chrome浏览器缩放比例:100%
- 屏幕比例
- 不保证您已安装了的英文字体:Matura MT Script Capitals
单元测试
-
选用的测试工具
mocha -
如何学习单元测试
我根据mocha学习写了一个mocha简易教程,可以点击查看 -
项目部分单元测试代码,并说明测试的函数
mocha进行单元测试我们是懂了,但是由于我们的建树函数比较奇特,各个函数、变量相互关联,在单元测试的过程中难以对单一个函数进行测试,在经过多次尝试仍然没有成功
-
构造测试数据的思路
构造测试数据的思路是测试正常数据及一切有可能的异常输入,之前的测试打算是
1.输入一棵树的数据;
2.输入两颗树的数据;
3.只输入导师,没有学生。如:输入“导师:张三”;
4.只输入学生不输入导师
5.输入两棵树,其中一个学生是属于两颗树的;
6.输入关联树数据;
7.输入重复二级节点,如“导师:张三
2015级博士生:天一、王二、吴五
2015级博士生:李四、王五、许六
”
Github代码签入记录
遇到的困难及解决方法
- 问题1:对需要用到的各种语言及工具的不熟悉
解决的途径:看菜鸟教程。菜鸟教程上对js、jQuery、html各种语言的知识模块分类的很清楚,包括每个例子都有一个试一试的简单代码可以让我们直观的了解各个知识点,我们在开始编码之前看了两三天的菜鸟教程来恶补需要的知识。至于zTree的学习我们则是参考zTree的API文档 - 问题2:如何动态的获取文本框中的内容生成树,而不是依靠已有的数据
做过的尝试:我们一开始选择设置一个根节点,输入数据后在这个节点上修改添加。我们通过百度及zTree提供的Dome代码看各种生成树的例子,但是我们找到的例子全部都是根据事先初始化好的节点建树,所以选择这种方法。
是否解决:在解决生成多棵树的时候由于需要多次初始化树,发现原来初始化树就是凭空造树(而不是在已有节点添加),就意外的解决了这个问题。 - 问题3:如何生成多颗树
解决的途径:联想到了之前学习java的时候看到有将字符串+数字表示一个变量。就选择尝试zTreeObj=$.fn.zTree.init($("#regionZTree"+treeCirle),setting,zNodes);其中"#regionZTree"+treeCirle在一次次建成一棵树循环中实现表示并初始化regionZtree0、regionZtree1、regionZtree2... - 问题4:如何实现节点查询
这一点的实现及思路体现在我们的附加特点设计中 - 问题5:如何实现不用刷新网页的情况下多次生成树
做过的尝试:在生成树函数的开头用destroy()销毁当前页面全部的 zTree、手动通过removeNode()移除所有节点,虽然界面上已生成的树会消失,但再次输入数据生成还是会有问题
解决的途径:目前还没找到,所以还是要手动刷新...
有何收获:最大的收获应该就是不放弃的去尝试一切可能,和信息的获取。由于我们对要用到的知识了解很少,我们的进程推进的很慢,以上讲到的遇到的问题可能事后回想起来就是一个小问题,但是当时可能是花了一个下午去解决的。但是我们抱着能做一点是一点的心态,没有放弃过尝试,最后也才能够解决这么多问题。
人生感悟:
learning by teaching
learning by doing
learning by killing √
评价你的队友
-
2212:
可以吹的地方:
小姐,你像仙女一样- 漫长而痛苦的十天嘴上说不行但身体一直没有停下来→坚韧不拔
- idea挺多德也挺好德,会及时提意见→思维活跃
- 写
大作文博客超强→文思敏捷 - 作为十天来载我奔波于世界各地自习处的司机→技能丰富
- 其实做了很多事情但老说自己屁事没干→为人谦虚
- 单元测试辛辛苦苦勤勤恳恳努努力力
需要改进的地方:
仙女需要什么改进- 坐没靠背的椅子久了就说腰酸→身体素质需要加强
- 电动车不够持久(?
- 没有成为让我可以躺过的大佬←我做梦
-
2208
值得学习的地方- 学习新知识很快,一起开始看那些要学到的语言的时候她能比我更快找到切入口
- 耐心善良(;´༎ຶД༎ຶ`),在我看了2、3天菜鸟教程还找不到切入点毫无进展的时候也有没被责怪
需要改进的地方
太重了,把我车都坐没电了- 跟我太默契了,两个人都没有交流冲突,以后要是跟别人结对会让我很痛苦