2019软工作业五-实现师门树

结对编程成员

031702101 王茜葶:https://www.cnblogs.com/lingluoyu/
031702113 陶俊宇:https://www.cnblogs.com/M031702113/



作业链接

031702101 王茜葶:https://www.cnblogs.com/lingluoyu/p/11704901.html
031702113 陶俊宇:https://www.cnblogs.com/M031702113/p/11704841.html



GitHub项目地址

https://github.com/DreamFeather/031702101-031702113



博客内容最新修改记录

201910/20 :完善博客内容,增加新段落“say something?”




结对分工

陶俊宇:主要是js偏后端方面,树的框架构建,树的输出显示,树的点击操作,树节点增加
王茜葶:负责界面方面,网页元素设计,css style,以及素材搜索与整理




PSP表格

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



解题思路

对于师门树这一概念我是不太陌生的,早在软工作业四中我们就已经讨论过了如何以师生关系建立关系网,也就是所谓的师门树。这次作业最大的挑战还是来源于对前端语言的首次接触,从作业发布到提交,仅有10天左右的时间,要入门html+css+js三门语言(没入门的时候觉得是三门,现在觉得是一门)并完成相关作业对我们这些小白来说无疑是千斤重担。而我们并未从框架入手,其实本来想的,但是想看懂框架就得先学习语言,结果语言学会了有思路,就没心思去搞框架了。所以本次作业我们并未使用任何框架,所有代码纯手打。

function Student(name="student") {                  //Student构建函数-学生
            this.name = name;
        }
        function Tag(name="tag") {                          //Tag构建函数-标签
            this.name = name;
            this.list = new Array();                            //该数组存放学生对象
            this.show = false;                                   //默认不展开
        }
        function Teacher(name="teacher") {                  //Teacher构建函数-导师
            this.name = name;
            this.studentTag = new Array();                   //该数组存放学生标签
            this.show = false;                                //默认不展开
        }

类图:

算法解释:
之前我并未想到合适的算法来解决树的输出的问题,我一直认为树应该是动态的,能够随时添加删除节点,这样一来如果用html写的输出就把内容格式限死了,表的增改不灵活。也许html可以动态管理输出,但是我不会用。所以我当即确定了,输出应交给偏后端的js来处理,同时js输出的文字需要有带有css动态效果,要能接受鼠标点击触发属性值变化。
输出显示方案及原理:在js控制输出但是本质还是html在输出,所以js需要获取html的标签的id。只要通过document.getElementById('html').innerHTML 修改标签内的值就可以了。另外一个,在html内将文字绑定onclick函数非常的简单<a onclick="function()"></a>即可,但是用document.getElementById('html').innerHTML=str; 的形式输出没问题,可是onclick我就怎么试都没反应,不能唤起相关的函数,最后查了very very very long 的time才找到解决方案,使用JSON.stringify()将对象转换成字符串的形式插入到.innerHTML中,使之成为某个函数值的参数。

function DisplayTable(arr) {                        //输出导师表     即树
            var i = 0;
            ptr_obj = arr;                                //ptr_obj是全局变量,指向当前状态的root
            var StdOut_Front = "<a class ='normal' onclick='Click_teacher(";            //特效在class里改,这里只会改到导师
            var StdOut_Mid=") '>";
            var StdOut_Back = "</a>";
            var str="";
            while (i < arr.length) {
                //document.write(arr.name);
                str += StdOut_Front + JSON.stringify(arr) + "," + i + StdOut_Mid + arr[i].name + StdOut_Back;        //这样一来onclick里的函数就可以把arr当作参数
                str += "<br>";                  //输出换行 导师名独占一行
                if (arr[i].show == true) {
                    str += DisplayTag(arr, i);
                }
                i++;
            }
            document.getElementById('html').innerHTML = str;    //将html里内容改为str。或者说将str输出到html网页

本来我是想用root一个全局变量,所有函数对其进行增删改查,输出只用DisplayTable(root)就行,但是实际在调试的过程中发现,改操作死活都不能更改传进去对象的属性,然后点击操作改的只是形参里的值,原对象任凭风吹雨打,沉着安稳如山。网上求解,我想传对象引用改变原对象的值,结果网上都是一堆关于“如何让函数不改变对象里的值,传个对象进去结果发现数据被改了……”等等话题。我觉得是我对js语法掌握得不够彻底。但是急需一个解决方案,所以我就想,干脆用传进来的对象做输出算了。

function Click_teacher(a, i) {      //鼠标点到了导师姓名就修改标签展开状态
            a[i].show = !a[i].show;
            ptr_obj = a;            //全局变量指向root当前状态,需要实时更新
            DisplayTable(a);
        }

倒还真可以了,但是缺陷是非常的明显的,由于是递归式调用,参数为形参,每调用一次复制一份,永不返回,这样操作极耗内存,不推荐采用。其中ptr_obj的作用是,当前显示的root不再是全局的root,用全局的ptr_obj指向当前作为参数的root,即代码中的a,在进行插入操作时,需要将数据插入到显示的root这一层数据上。否则,插入的数据不可见。
递归式显示:改了之后输出改了的,输出后再等待被改

整体流程图:

重要代码:
在建树的时候,我觉得树的结构搭建是非常关键的,最为重要。可是当我做到输出的时候,才发现,用js来控制输出时html标签的插入处理难度高出天际,因为我实在不懂格式。可是最后,到了做输入处理的时候,这个处理量真是看了脑壳昏,写出来我也并不知道它为什么能正常运行,代码如下

function check_tch(str, i) {                  //在str【i】这里检查后面字符串内容是否为“导师:”
            var j = 0;
            var daoshi = "导师";
            var sign1 = ":", sign2 = ":";        //圆角半角符号通吃
            while (j < 2) {
                if (str[i + j] != daoshi[j]) return false;
                j++;
            }
            if (str[i + j] != sign1 && str[i + j] != sign2) return false;
            return true;
        }
        function check_tag(str, i) {                //在str【i】这里提取输入的字符串作为学生标签
            if (str[i] == '\n')++i;
            if (str[i] == undefined) return false;
            var tagname = "";
            while (str[i] != ":" && str[i] != ":" && str[i] != "," && str[i] != "," && str[i] != "、" && str[i] != "\n" && str[i] != undefined) {        //中英文逗号、冒号,顿号,换行符,末尾,都是截断符
                tagname += str[i++];
            }
            var tg = new Tag(tagname);          //从输入中提取出的tagname,用来新建标签
            if (str[i] == "\n" || str[i] == undefined) return tg;
            ++i;
            var stname = "";
            while (1) {
                if (str[i] != ":" && str[i] != ":" && str[i] != "," && str[i] != "," && str[i] != "、" && str[i] != "\n" && str[i] != undefined) {
                    stname += str[i];
                }
                else {
                    var std = new Student(stname);
                    tg.list.push(std);             //将学生名放入标签表中
                    stname = "";
                }
                if (str[i] == "\n"|| str[i] == undefined) break;
                i++;
            }
            return tg; //返回建好的标签
        }
        function Get_input(a) {                 //鼠标点击确认后,将框内的文本读入到树中
            var str = document.getElementById("inputbox").value;
            document.getElementById("inputbox").value = ""; //获取文本框内容后清空
            var i = 0;
            var teachername="";
            var line_break = '\n';
            while (str[i] != undefined) {
                if (check_tch(str, i)) {            //找“导师:”
                    i += 3;
                    while (str[i] != line_break && str[i] != undefined) {
                        teachername += str[i];
                        i++;
                    }
                    var t = new Teacher(teachername);
                    teachername = "";               //找到导师名后新建导师对象
                    a.push(t);                      //放入树中
                    while (str[i] != undefined) {
                        var tg = check_tag(str, i);
                        if (tg != false) {
                            t.studentTag.push(tg);  //再将导师后面的标签也放入该导师的student.Tag中
                            if (str[i] == line_break) i++;
                            while (str[i] != line_break && str[i] != undefined)++i;
                        }
                        i++;
                    }
                }
                i++;
            }
            DisplayTable(a);
        }

首先从字符串里找到“导师:”这三个符号,那么后面就是导师姓名,再往下就是学生的标签,标签后面是学生名。整个字符串处理过程相当繁琐。




目录及使用说明

简单的目录
一张背景图 123.png
少许css式样 styleshee.css
以及页面主体 Tch-Stu_tree.html

操作说明
在网页的输入框内输入导师信息,标签信息,学生信息
点击左下角的完成即可生成相应的师门树

输入格式:

导师:张三
2016级博士生:天一、王二、吴五
2015级硕士生:李四、王五、许六
2016级硕士生:刘一、李二、李三
2017级本科生:刘六、琪七、司四

导师姓名与学生标签可点击,点击效果为展开/收缩
鼠标在导师姓名,学生标签或者学生姓名上悬停,会触发css hover效果
举个例子

.stu {
    font-size: 22px;
    color:cyan;
}
.stu:hover {
    font-size: 27px;
    color:gold;
    transition-duration: 600ms;        //转换时间:600ms
}

这是学生姓名的显示效果,上面的.stu是正常状态下的字体像素为22px,颜色cyan偏青色。而.stu:hover则是鼠标在学生姓名上悬停的效果,字体变大为27px,颜色gold金黄色,变化时间600ms。

或者直接试试这段文字




签入记录

可能还会有更新




遇到的问题

遇到的问题不仅有,而且还挺多的。由于语言的不熟悉产生的问题,例如之前提到过的输出问题,怎样不让html把输出定死,用js,用了js又如何实现css效果,这些问题我们都是不了解的,只能从网上查找方案,还不一定能看懂。看不懂的代码就先拿去跑下试试结果!也是由于js语言的特性,动态编译运行,使得我们很快就能看到运行结果,大大减少了学习耗时。结对编程对于我们来说,确实也很大的不便,由于两个人很少聚到一起,少有机会讨论,要合作分工的话,也基本上以文件来分比较合适,分工不均是时有的事,我们处于结对初期,还需要时间去磨合。




评价你的队友

我觉得我的队友是一个性格强悍的女汉子,而实际上内心又很柔弱,但是表现得还真的挺强悍,额,咳咳……
值得学习的地方嘛,idea挺多的,开发经验比我多,善于代码重用,懂得使用框架,利用外部资源,善用工具作图等等等等。
需要改进的地方,唉,人的评价都是感性的,她对我的评价是我学习能力很强,我可能会觉得她的学习能力稍弱等等,一个人的能力是有限的,这些并不是需要改进的地方,也不是说想改进就能的,更多的,我觉得她有时候太专注于手中的事,而容易忽略身边更有意思的东西。所以我觉得她应该要学会观察,观察生活中的事务,抓住事物的核心点下手去做事,效率会更高。即使你懂得多,但是在找到完整思路之前,可以妄下结论,但不要轻易动手。唉,这些都是次要的,她要是能学会一点撒娇卖萌,就……




say something?

这次结对编程作业我收获还是蛮多的,从对前端有着错误的理解到不了解前端,再到前端入门,实际上只用了5天,这5天里,我和我的小伙伴都很忙,都没有什么时间来做这个作业,即便是今晚,我也要在团队编程作业上分出一点心思。每天睡得晚起得早,就像战争一样,精神高度紧张,我感觉到了时间的重要性,一天其实很短,5天也是,作业都是逼着自己赶出来的。这是一段痛苦而值得留恋的回忆,我大部分时间都在盯着网页刷资料,大脑飞速运转,只为解决这个难点,满足那个需求。但即使晚上想着问题难以入眠,脑细胞活跃的兴奋却在告诉我,我在成长,“加油,孩子”。面对困难,根本就没有什么“无法解决”,只是看你有没有这个精力,愿不愿意花精力而已。

博客从始至终,你都可以看到我说得眉色飞舞,但是我却没有贴出一张我做的页面是怎么样的图,我直白的说,成品没有我们想象的那么美好,简陋了点,如果要与同学们对比那我们更觉得自己做的不堪入目,可这同样是我们花了大量时间和精力去完成的一项作业。你要是问我,我觉得满意吗?我会说结果不太满意,因为我们还能做得更好,毕竟我们当时只有那么点精力,不过中间付出的辛勤劳动我是一定满意的。看了此次的评分标准,对美观度还是有较大的要求,那我觉得,我们分数又要往下压一压了,但正如某位伟人所说过的:“分数不是衡量收获的唯一标准”。我们没有用任何的框架,真正从零起步,我们收获了多少我们心里清楚,我对此感到满意。
逐字编写简陋的曲谱,也能唱响打动心灵的旋律。
想看看到底长啥样么?就酱

posted @ 2019-10-19 22:12  梦幻魅羽  阅读(290)  评论(5编辑  收藏  举报