2020软件工程作业_04
第4次作业-结对编程之实验室程序实现
一、作业概述
这个作业属于哪个课程 | http://dwz.date/cts4 |
---|---|
这个作业要求在哪里 | https://edu.cnblogs.com/campus/fzu/SE2020/homework/11277 |
这个作业的目标 | 熟悉前端的开发流程,熟悉HTML、CSS、JAVASCRIPT语言以及部分框架 |
结对同学 | 031802233_王振宇 031802225_沈润佳 |
结对同学的博客链接 | https://www.cnblogs.com/runrun225/p/13800631.html |
GitHub项目地址 | https://github.com/2441461233/031802225_031802233 |
二、具体分工
031802225 沈润佳:前期资料的收集、前期思路的设计、前期代码的编写、美化代码、博客撰写。
031802233 王振宇:主要代码的编写、单元测试。
三、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 30 |
Estimate | 估计这个任务需要多少时间 | 10 | 10 |
Development | 开发 | 560 | 600 |
Analysis | 需求分析 (包括学习新技术) | 400 | 480 |
Design Spec | 生成设计文档 | 30 | 60 |
Design Review | 设计复审 | 30 | 40 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 20 | 20 |
Design | 具体设计 | 120 | 360 |
Coding | 具体编码 | 480 | 480 |
Code Review | 代码复审 | 60 | 60 |
Test | 测试(自我测试,修改代码,提交修改) | 120 | 240 |
Reporting | 报告 | 120 | 120 |
Test Report | 测试报告 | 30 | 30 |
Size Measurement | 计算工作量 | 20 | 10 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | 2050 | 2570 |
四、解题思路描述与设计实现说明
分析需求可知,需要对输入内容进行处理,并且生成师门树和技能树,鉴于本组小朋友开发经验都不足,在上网查阅大量资料之后,决定使用jQuery 框架有着详细教程上手较快的 antv G6,即一个图可视化的引擎,先用html编写文本框,对输入内容进行分析生成 json 对象后引入G6,生成师门树和技能树。
整体思路鱼骨图展示如下:
数据流图如下:
第0层DFD:
第1层DFD:
各模块详解:
1. 解析文本框内容:
针对每行不同输入(导师、学生信息、学生技能)进行不同处理提取相应信息存于数组。并统计相应的数量,以便之后循环程序的编写。
function submittext() { //解析输入 每个人赋予一个IDD和相应信息数组
var Text = document.getElementById("inputtext").value;
var Lines = Text.split("\n");
var teacher = new Array(), nameLine = new Array();
var name = new Array();
// teacher标识是否是导师,degree标识学位,year标识年级,
// nameLine存每行完整信息,nameString存:后内容,name存名字
var branch = 0;
for (var i = 0; i < Lines.length; i++) {
if (Lines[i].length == 0) { //跳过空行
continue;
}
teacher[i] = Lines[i].substr(0, 2); //分割前两个字,判断是否是“导师”
if (teacher[i] == "导师") { //导师处理
ID++; //每个人独有ID
degree[ID] = "导师"; //degree导师
NAME[ID] = Lines[i].substring(3);
degreenum[teachernum] = 0;
teachernum++;
}
else if(/^\d+$/.test(teacher[i])) { //非导师处理
var temp1 = Lines[i].substring(0, 4); //temp1为年级
var temp2 = Lines[i].substr(5, 2); //temp2为学位等级
var tempNameString = Lines[i].substring(Lines[i].search(":") + 1);
name[i] = tempNameString.split("、");
degreenum[teachernum - 1]++;
for (var j = 0; j < name[i].length; j++) { //每个人分配ID 并且存储相关信息
ID++;
year[ID] = temp1;
degree[ID] = temp2;
NAME[ID] = name[i][j];
// studentnum[branch]++;
}
studentnum[branch] = name[i].length;
branch++;
}
//技能树生成
else {
linestr = Lines[i];
var posi = linestr.search(":");
var stuName = linestr.substring(0, posi);
var tempAttris = linestr.substring(posi+1).split("、");
attris[stuName] = tempAttris;
console.log(attris);
}
}
}
2.将文本框获取内容生成json对象
G6 的数据源要求为json对象。因此需将所获信息转换json对象。我们采用动态创建,根据之后生成的树创建父子节点。下一层为上一层的孩子结点。
var IDD = 0; var kk = 0; var kkk = 0;
for (var k = 0; k < teachernum; k++) {
IDD++;
// console.log("teacher="+teachernum);
var test2 = { id: NAME[IDD], children: [] };
for (var i = 1; i <= degreenum[kk]; i++) {
// console.log(kk+" =="+degreenum[kk]);
var xxx = new Object();
xxx.id = year[IDD + 1] + degree[IDD + 1];
xxx.children = new Array();
for (var j = 1; j <= studentnum[kkk]; j++) {
var yyy = new Object();
IDD++;
yyy.id = NAME[IDD];
yyy.children = new Array();
// 增加个人经历
if(attris.hasOwnProperty(yyy.id)) {
console.log("has");
for(var k = 0; k < attris[yyy.id].length; k++) {
var yyychild = new Object();
yyychild.id = attris[yyy.id][k];
yyychild.children = new Array();
yyy.children.push(yyychild);
}
}
xxx.children.push(yyy);
}
test2.children.push(xxx);
kkk++;
}
kk++;
hell = JSON.stringify(test2);
3.根据json对象,使用G6引擎并生成师门树
function pk(data) {
// function test2(hell){
// console.log("xxxx");
// console.log("typeof data is "+typeof data);
// console.log(data);
// console.log("yyyyy");
// function pick (data=hell) {
var graph = new G6.TreeGraph({
container: 'mountNode',
width: 800,
height: 1200,
pixelRatio: 2,
modes: {
default: [{
type: 'collapse-expand',
onChange: function onChange(item, collapsed) {
var data = item.get('model').data;
// console.log("type of this shit is",typeof data);
// console.log(data);
data.collapsed = collapsed;
return true;
}
}, 'drag-canvas', 'zoom-canvas']
},
}
参考链接:
使用其中的 TreeGraph
参考链接:https://antv-g6.gitee.io/zh/docs/manual/getting-started
使用 JQuery UI 组件库
参考链接:https://www.runoob.com/jqueryui/jqueryui-use.html
注意
-
区分json字符串和json对象!
-
引入 G6 的数据源为 JSON 格式的对象
-
jquery ui 是基于 jquery 的 UI 库,提供的是UI组件库;
而jquery是工具库;
五、附加特点设计与展示
设计意义
- 任意拖动生成树 ,支持结点缩放→ 帮助老师同学快速了解自己的同门学长学姐学弟学妹,以及快速了解自己和同学伙伴们的技能。
- 师门技能树可以变大变小 → 万一有同学近视呢?
- 一键清空按钮 → 便于同学一键删除所有信息,重新输入
- 贴心的输入格式导航→方便同学按照规定格式输入文本内容
实现思路
- 一键清空:引入清空的函数
- 处理用户输入
- 生成树的优化:使用 G6 引擎
代码详解
-
一键清空的函数
function cleartext() { location.reload(); }
-
使用G6 引擎美化图图
function pk(data) { // function test2(hell){ // console.log("xxxx"); // console.log("typeof data is "+typeof data); // console.log(data); // console.log("yyyyy"); // function pick (data=hell) { var graph = new G6.TreeGraph({ container: 'mountNode', width: 800, height: 1200, pixelRatio: 2, modes: { default: [{ type: 'collapse-expand', onChange: function onChange(item, collapsed) { var data = item.get('model').data; // console.log("type of this shit is",typeof data); // console.log(data); data.collapsed = collapsed; return true; } }, 'drag-canvas', 'zoom-canvas'] }, /******************美化****************/ defaultNode: { size: 16, anchorPoints: [[0, 0.5], [1, 0.5]], style: { fill: '#CCFF00', stroke: '#d91808' } }, defaultEdge: { shape: 'cubic-horizontal', style: { stroke: '#000000' } }, layout: { type: 'compactBox', direction: 'LR', // nodeSep:30, // rankSep:100, getId: function getId(d) { return d.id; }, getHeight: function getHeight() { return 16; }, getWidth: function getWidth() { return 16; }, getVGap: function getVGap() { return 10; }, getHGap: function getHGap() { return 100; } } }); graph.node(function (node) { return { size: 26, style: { fill: '#CCFF00', //节点颜色 stroke: '#2BD54D' //节点边框 }, label: node.id, labelCfg: { position: node.children && node.children.length > 0 ? 'left' : 'right' } }; });
实现成果展示
六、目录说明和使用说明
目录组织形式
zy2.html 为HTML代码编写
zy2.js 为js代码编写
其余为支撑库
运行网页的方法
下载库中所有文件并保证本地相对路径的一致性,打开zy2.html即可运行。
输入内容请按照文本框内的提示输入。
得到生成树后可任意拖拽,并可用滚轮调整页面。
七、单元测试
测试工具:
Mocha
教程
-
安装配置node.js
-
安装配置mocha
-
.test.js的编写
-
配置好单元测试的目录文件
-
进行单元测试
参考链接:
部分单元测试代码
var submittext = require('../attritest.js');
var expect = require('chai').expect;
describe('技能树测试', function() {
it('刘六:JAVA、数学建模', function() {
expect(submittext("刘六:JAVA、数学建模")['刘六']).to.include('JAVA');
});
it('李二:字节跳动、京东云', function() {
expect(submittext("李二:字节跳动、京东云")['李二']).to.include('京东云');
});
});
构造测试数据的思路,如何应对测试人员的***难
首先输入数据必须满足格式要求,在此基础上构建数据
- 名字过长? → 并不影响 √
- 技能过多? →并不影响 √
如果是测试人员的故意***难?
- 不好好按照规定格式输入数据? → 和测试人员好好沟通!
- 输入无关数据(并非师门关系或者技能)→ 那就微笑这看着测试人员!
八、GitHub代码签入记录截图
九、困难以及克服困难
- 对前端知识不熟悉
- 做出尝试:查阅教程、游览大量博客。
- 目前解决 √
- 收获:
- 学会速读教程,需要什么学什么
- github进一步熟悉体会到了其方便之处
- 单元测试进一步熟悉
- 明白了一个道理:编程语言语法并不十分重要,重要的是思想,有时候思想在,即便熟悉这种语言也可以很快实现
十、评价队友
评价沈润佳同学:
* 做事认真仔细
* 收集、整理资料能力强
* 文字撰写能力强
* 规划性强,能够及时提醒队友