2020软工第四次结对编程作业

2020软工第四次结对编程作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/SE2020/
这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/SE2020/homework/11277
这个作业的目标 利用html+css+js实现校园师生树
学号 151803103-171809006

GitHub项目地址:https://github.com/BGL245/151803103-171809006

结对同学的博客链接:https://www.cnblogs.com/bgl245/p/13800081.html

PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 20 20
Estimate 估计这个任务需要多少时间 10 10
Development 开发 300 360
Analysis 需求分析 (包括学习新技术)
Design Spec 生成设计文档 60 60
Design Review 设计复审
Coding Standard 代码规范 (为目前的开发制定合适的规范)
Design 具体设计 30 40
Coding 具体编码 300 300
Code Review 代码复审 20 30
Test 测试(自我测试,修改代码,提交修改) 60 70
Reporting 报告 30 40
Test Report 测试报告
Size Measurement 计算工作量
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 30 30
合计 860 960

结对人员和分工

151803103 张雨晗(css和html设计。美化页面)

171809006 白耿龙(js核心代码实现,单元测试)

解题思路与设计说明

1、js实现核心思想,包括树的构建,结点的传递。

2、html和css负责实现页面的布局和美化。

3、首先定义树的结点信息,包括name,parent,children信息。

4、初始化函数用来构建生成树的动画,定义树的全局属性(参考了js的生成树代码),新建画布,包括结点的颜色大小,结点之间的link,结点展开和收拢。设置在展开和收拢时的动画等。使用到了d3.v3.min.js

数据流图如下:

5、构建函数:对文本进行分析,根据换行符\n和冒号:将信息分割,加入不同的结点数组,再细分导师和学生,读取“导师”和学员的信息,以及学员掌握的技能或工作经历,完成之后,检查函数,遍历之前所有树的所有子节点,查找是否有导师的学生也是导师的情况,若有此种情况则此树重构,最后判断是否为关联树,若为关联树,就新加入当前的结点,最后生成一棵完整的树。

核心代码如下:

count = 0;//儿子节点编号
                all_flag = 0;//全局变量,判断是否独立
                count_tree[j] = 0;
                skills_data = model_data[j].split("\n\n");//空一行 技能或经历
                sclice_data = skills_data[0].split("\n"); //不空行 人员信息
                for (var i = 0; i < sclice_data.length; i++ ) {
                    var head_tmp = "";
                    var body_tmp = "";
                    var hb = sclice_data[i].split(":"); //从冒号分割一层字符串
                    head_tmp = hb[0];
                    body_tmp = hb[1];
                     //处理冒号前的部分
                    if (head_tmp == "导师") {
                        var tutor = {
                             "name": body_tmp,
                             "parent": "null",
                             "children": [{}]
                        }
                        treeData[j] = tutor; //将导师嵌入节点
                     } else {
                         var children = {
                             "name": head_tmp,
                             "parent": "null",
                             "children": [{}]
                         }
                        treeData[j].children[count] = children; //将年级及职业嵌入节点
                        //处理冒号后的部分
                        var bodies = body_tmp.split("、");
                        for (var k = 0; k < bodies.length; k++ ) {
                            var sign=0;
                            for(var l=1; l < skills_data.length; l++ ){ 
                                var shead_tmp = "";
                                var sbody_tmp = "";
                                var hs = skills_data[l].split(":"); //从冒号分割一层字符串
                                shead_tmp = hs[0];
                                sbody_tmp = hs[1];
                                //判断是否有技能或经历信息
                                if(shead_tmp == bodies[k]){
                                    sign=1;
                                    var children = {
                                        "name": bodies[k],
                                        "parent": "null",
                                        "children": [{}]
                                    }
                                    treeData[j].children[count].children[k] = children; //将姓名嵌入节点
                                    var sbodies = sbody_tmp.split("、");
                                    for(var m = 0; m < sbodies.length; ++m){
                                        var children = {    
                                            "name": sbodies[m],
                                            "parent": "null",
                                            //"children":[{}]
                                        }
                                        treeData[j].children[count].children[k].children[m] = children;
                                    } 
                                    break;
                                }
                            }
                            if(sign==0){
                                var children = {
                                    "name": bodies[k],
                                    "parent": "null",
                                    //"children": [{}]
                                }
                                treeData[j].children[count].children[k] = children; //将姓名嵌入节点
                              }
                            }
                        count++; //第二子节点编号加一,生成下一个第二子节点
                    }
                }
				var tree_tmp = treeData[j];
                var name_tmp = treeData[j].name;
                for (num_tmp = 0; num_tmp < j; num_tmp++) {
                    check(treeData[num_tmp], name_tmp, tree_tmp);
                    if (all_flag == 1){
                        count_tree[j] = 1;
                        break;
                    }
                }

其中Check()为检查函数,遍历之前所有树的所有子节点,查找是否有导师的学生也是导师的情况,若有此种情况则此树重构,最后判断是否为关联树,若为关联树,就新加入当前的结点,最后生成一棵完整的树

 			function check(old_tree, find_name, new_tree) {
            var length_now = getJsonLength(old_tree.children);
            for (var l = 0; l < length_now; l++) {
                if (old_tree.children[l].name == find_name) { //第l个子节点的名字是否与要查找的相同
                    all_flag = 1;
                    old_tree.children[l] = new_tree; //将该json树添加到儿子节点作为关联
                } else {
                    check(old_tree.children[l], find_name, new_tree);
                }
            }

其中getJsonLength()函数为获取树的长度,检查时可便利所有节点

	function getJsonLength(jsonData) {
            var jsonLength = 0;
            for (var item in jsonData) {
                jsonLength++;
            }
            return jsonLength;
        }

附加特点设计与展示

1、核心代码js上,可以进行树的合并操作,比如第一位导师为张三,他有研究生李四,李四如果也带学生,那么李四的学生信息会直接显示在“李四”名称的后面。实现思路为关联树函数,判断学生中是否有可以关联的对象,然后加入。
文本写入,生成树:

加入新文本,连结显示:

2、加入了一些美化程序,利用JS生成树时,可以点击人名生成更多的结点,也可以点击这些结点收回信息,使用node下的相关库函数实现。

收缩节点:

目录说明和使用说明

目录说明:

background.jpg:背景文件

d3.v3.min.js:框架

inde.html:运行网页文件

style.css:css代码

tree.js:JS代码

使用说明

clone仓库到本地,解压 tree.zip,解压后用chrome打开 tree.html, 在文本框中输入家族树文本,点击提交即可生成相应家族树

文本格式

学术家族树以文本形式输入,web页面需要提供一个文本框;考虑学术家族树的文本格式是这样的:

导师:张三

2016级博士生:天一、王二、吴五

2015级硕士生:李四、王五、许六

2016级硕士生:刘一、李二、李三

2017级本科生:刘六、琪七、司四

刘六:JAVA、数学建模

李二:字节跳动、京东云

导师:赵四

2015级博士生:...

……

其中,"导师:","级博士生:","级硕士生:","级本科生:"和"、"当做关键词处理;

若有多组输入,中间空两行

每组上半部分是人员信息,不空行

下半部分是技能树或所在公司历程,空一行

一定要严格按照输入格式输入,不然生成不了树! ! !

单元测试

选用了mocha作为测试工具,先下载node进行相关安装配置,然后在命令行输入nmp install -g mocha 安装mocha 就可以开始单元测试具体的代码编写可参考作业中给出的http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html

之前个人编程作业也有单元测试,但是没能实现,这次简单的学习了一下,首先对整个CreateTree()函数进行测试,一直报错,发现时因为在单元测试中输入的是json,但是CreateTree()输入的是文本,然后解析成json。改了之后还是实现不了,不知道是什么原因,没有时间再去检查了,所以只能这样。。。

单元测试的问题:

Github签入截图

代码困难和解决

一开始尝试编程css时,对模块的大小和位置调整不是很好,查阅一些网站设计资料后解决。

刚开始编写html时有些混乱,直接接入js程序后页面连背景都无法显示,之后将js和css都独立出来,再各个编写,解决了上述问题。

单元测试一直写的不是很好,之前的代码边学边写,作业量太大了体会到了社会996的感觉。。。

评价队友

1、JS程序写得很好,在CSS上也帮助我理解一些代码

2、我们的网页制作有些空,想再加一个刷新功能没有来得及加。

posted @ 2020-10-11 22:34  count001  阅读(96)  评论(0编辑  收藏  举报