第4次作业-结对编程之实验室程序实现
目录
- 团队成员
- 1、相关链接
- 2、具体分工
- 3、PSP表格
- 4、解题思路描述与设计实现说明
- 5、附加特点设计与展示
- 6、在博客中给出目录说明和使用说明
- 7、单元测试
- 8、github 签入记录
- 9、遇到的代码模块异常或结对困难及解决方法
- 10、评价队友
正文
这个作业属于哪里 | https://edu.cnblogs.com/campus/fzu/SE2020 |
---|---|
这个作业要求在哪里 | https://edu.cnblogs.com/campus/fzu/SE2020/homework/11277 |
这个作业的目标 | 结对编程,学习前端,单元测试,github |
学号 | 031802409-031802408 |
团队成员
学号 | 姓名 |
---|---|
03182409 | 江启良 |
03182408 | 黄文松 |
1.相关链接
标题 | 链接 |
---|---|
结对同学博客链接 | https://www.cnblogs.com/dronw/p/13771602.html |
本作业博客的连接 | https://www.cnblogs.com/jql666/p/13797006.html |
仓库地址 | https://github.com/jql0108/031802408-031802409 |
2.具体分工
031802408完成js部分和单元测试,主要的核心代码以及布局等方面
031802409完成html,css和美化页面,以及博客园编写和部分算法
3.PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 20 |
Estimate | 估计这个任务需要多少时间 | 600 | 900 |
Development | 开发 | 120 | 200 |
Analysis | 需求分析 (包括学习新技术) | 200 | 300 |
Design Spec | 生成设计文档 | 20 | 20 |
Design Review | 设计复审 | 20 | 20 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 20 | 0 |
Design | 具体设计 | 20 | 10 |
Coding | 具体编码 | 60 | 80 |
Code Review | 代码复审 | 20 | 10 |
Test | 测试(自我测试,修改代码,提交修改) | 20 | 40 |
Reporting | 报告 | 20 | 10 |
Test Report | 测试报告 | 20 | 20 |
Size Measurement | 计算工作量 | 10 | 10 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 15 | 15 |
合计 | 585 | 755 |
4、解题思路描述与设计实现说明
程序总体思路
导师节点的流程图
学生节点的流程图
带技能学生节点的流程图
根据在树中不同的分类,来增加主节点。
根据正则表达式来分割文本,并将这些文本存入ss数组当中。
//输入处理
var s =document.getElementById("text1").value;//将文本框的内容读入
//将导师:,级研究生:的冒号去掉
var reg = new RegExp(/导师:/g);
s=s.replace(reg,"导师,");
var reg = new RegExp(/级博士生:/g);
s=s.replace(reg,"级博士生,");
var reg = new RegExp(/级硕士生:/g);
s=s.replace(reg,"级硕士生,");
var reg = new RegExp(/级本科生:/g);
s=s.replace(reg,"级本科生,");
var reg = new RegExp(" ","g");
s=s.replace(reg,"");
var reg = new RegExp(":","g");
//根据冒号来确定学生拥有的技能
s=s.replace(reg,"?:");
var length=s.length;
if (s[length-1].match(/\n|\r/g))//文末的空行判断
{
alert("文本末不能有空行!");
return;
}
var reg = /\n(\n)*( )*(\n)*\n/g;
s = s.replace(reg,"\n");
var dic={}//节点的名字与id 相对应的字典
var ss = s.split(/、|\n|:|,|\r|\t|\ +/g); //通过符号来分割字符
console.log(ss);//调试
导师节点的处理
while(i<ss.length){
for(;i<ss.length;i++){
console.log(ss[i]);
if(i==0){
if(ss[i]=="导师"){//第一个导师
ele='<li id="id4'+num4+'">'+
'<span id="id5'+num5+'" class="badge badge-success"> '+ss[i]+'</span>'+
'</li>';
$("#Tree").html(ele);
num4++;
i++;
ele='<ul><li id="tc9'+tc9+'">'+
'<span id="teacher"> '+ss[i]+'</span>'+
'</li></ul>';
$('#id5'+num5).after(ele);
dic[ss[i]]="tc9"+tc9.toString();//记录导师节点的id
num5++;
}
else{
break;
}
console.log(ss[i]);
}
else{//非第一个导师
if(ss[i]=="导师"){
ele='<li id="id4'+num4+'">'+
'<span id="id5'+num5+'" class="badge badge-success"> 导师</span>'+
'</li>';
$('#id4'+(num4-1)).after(ele);
num4++;
i++;
ele='<ul><li id="tc9'+tc9+'">'+
'<span id="teacher"> '+ss[i]+'</span></li></u1>';
$('#id5'+num5).after(ele);
dic[ss[i]]="tc9"+tc9.toString();
num5++;
}
else{
break;
}
console.log(ss[i]);
}
}
学生节点处理
if(ss[i].match(/(([0-9]+)级博士生)|(([0-9]+)级硕士生)|(([0-9]+)级本科生)/g)){
ele='<li><span id="id1'+num1+'" class="badge badge-success"> </span></li>';
$('#tc9'+tc9).after(ele);
$('#id1'+num1).html(ss[i]);
dic[ss[i]]="id1"+num1.toString();//根据节点值存id
console.log(ss[i]);
i++;
var j=1;
for(;i<ss.length;i++){
console.log(ss[i]);
if(ss[i].match(/(([0-9]+)级博士生)|?$|(([0-9]+)级硕士生)|(([0-9]+)级本科生)|导师/)){
i--;
break;
}
if(j==1){
ele='<ul><li id="id3'+num3+'"><span id="id2'+num2+'"> </span></li></u1>';
$('#id1'+num1).after(ele);
dic[ss[i]]="id3"+num3.toString();//
j++;
}
else{
ele='<li id="id3'+num3+'"><span id="id2'+num2+'"> </span></li>';
dic[ss[i]]="id3"+num3.toString();//
$('#id3'+(num3-1)).after(ele);
}
$('#id2'+num2).html(ss[i]);
num2=num2+1;
num3=num3+1;
console.log(ss[i]);
}
num1=num1+1;
}
else{
break;
}
i++;
if(ss[i]=="导师"){
break;
}
console.log(ss[i]);
}
有技能的学生节点处理
if(ss[i].match(/?$/g)){//通过?来区分拥有技能的节点
console.log(ss[i]);
ss[i]=ss[i].replace("?","");
var j=1;
var k=1;
for(;j<ss.length;j++){//搜索拥有技能的那个节点
if(ss[i]==ss[j]){
break;
}
}
for(;i<ss.length;i++)
{
if(ss[i].match(/?$/g)){
break;
}
if(k==1){
k++;
}
else if(k==2){
ele='<ul ><li id="id6'+num6+'"><span id="id7'+num7+'"></span></li></ul>';
$('#'+dic[ss[j]]).after(ele);
$('#id7'+num7).html(ss[i]);
num6++;
num7++;
k++;
}
else{
ele='<li id="id6'+num6+'"><span id="id7'+num7+'"> </span></li>';
$('#id6'+(num6-1)).after(ele);
$('#id7'+num7).html(ss[i]);
num6++;
num7++;
}
}
}
5、附加特点设计与展示
- 结点收缩展开
- 可支持多组数据同时输入,多棵树并存;
- 每次输入的数据所生成的树可以覆盖上一次输入生成的树,无需在后续测试和使用时多次刷新;
部分代码:
折叠部分:
$('.tree li:has(ul)').addClass('parent_li').find(' > span').attr('title', 'Collapse this branch');
$('.tree li.parent_li > span').on('click', function (e) {
var children = $(this).parent('li.parent_li').find(' > ul > li');
if (children.is(":visible")) {
children.hide('fast');
$(this).attr('title', 'Expand this branch').find(' > i').addClass('icon-plus-sign').removeClass('icon-minus-sign');
}
else {
children.show('fast');
$(this).attr('title', 'Collapse this branch').find(' > i').addClass('icon-minus-sign').removeClass('icon-plus-sign');
}
e.stopPropagation();
});
$(document).ready(function()
{
$("#Tree ul li").next("ul").hide();
$("#Tree ul li").click(function()
{
$(this).next("ul").toggle();
成果展示
6、在博客中给出目录说明和使用说明
####目录组织:
all文件:
主体是1.html,style.css是自己编码的样式,jquery-3.4.1.min.js是我们所使用的框架
图3.jpg是自己用PS加工的装饰图片
其余:
是之前使用的素材图片
####测试人员运行:
在总目录下下载all文件
运行1.html
7、单元测试
1.测试工具:Mocha
学习网站:http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html
在学习网站下载好mocha
简易教程:
1、在要测试的文件目录下进入git,并提前下载好node.js
2、在安装Node的前提下,在git Bash Here运行命令:
cd mocha-demos
npm install
3、安装全面环境:
npm install --global mocha
4、安装断言库chai:
npm install chai
5、对分割文字操作的测试,并运行测试文件:
mocha test.js
构造测试数据的思路:
- 考虑到单组输入和多组输入
- 考虑到老师只有一个类别的学生时的输入
- 考虑到无老师,只有学生时的输入
- 考虑到文末不小心添加空行的输入
以下是部分测试代码以及结果
var analysis = require('./work.js');
var expect = require('chai').expect;
var message1="李二";
var message2="琪七";
var message3="司四";
var message4="王五";
var message5="刘六";
var message6="许六";
var message7="张三";
var message8="刘一";
var message9="天一";
var message10="吴五";
describe('测试',function(){
it('学生节点测试', function() {//测试实例
expect(analysis()).to.include(message1);//expect断言:analysis函数返回的数组中包含学生姓名“李二”
});
it('学生节点测试', function() {
expect(analysis()).to.include(message2);
});
it('学生节点测试', function() {
expect(analysis()).to.include(message3);
});
it('学生节点测试', function() {
expect(analysis()).to.include(message4);
});
it('学生节点测试', function() {
expect(analysis()).to.include(message5);
});
it('学生节点测试', function() {
expect(analysis()).to.include(message6);
});
it('导师节点测试', function() {//expect断言:analysis函数返回的数组中包含导师姓名“张三”
expect(analysis()).to.include(message7);
});
it('学生节点测试', function() {
expect(analysis()).to.include(message8);
});
it('学生节点测试', function() {
expect(analysis()).to.include(message9);
});
it('学生节点测试', function() {
expect(analysis()).to.include(message10);
});
});
单组输入和多组输入
导师只有一类学生
当开头没有导师时,报错
当结尾有空行时,报错
8、github 签入记录
9、遇到的代码模块异常或结对困难及解决方法
在用html和css进行排版的时候,对于样式,水平分块,以及一些动画有一些疑问
解决方法:CSDN大法好
一开始是用<table>来解决排版问题,后面改成了用<div>加css解决,其余有很多细小的问题
但最后都从菜鸟教程上学习到了
10、评价队友
是一个可靠的队友,对于算法部分相当精通且乐于花时间学习,互相监督的学习很有效果
不足:对于一些额外的功能有心无力,且有过两个人一起摸鱼的时候