2017年秋,第三次使用邹欣老师的《构建之法:现代软件工程》作为教材,授课对象是计算机系研究生一年级学生。班级在这里[https://edu.cnblogs.com/campus/nenu/SWE2017FALL]。
在本轮授课中,有以下几方面印象较为深刻。
1. 工具
工欲善其事,必先利其器。
在课程中我们要求学生使用特定的工具,不仅希望这些工具能减少重复工作,更重要的是约束学生的操作,通过操作传授软件工程概念的组织结构和流程,好工具同时也是好的过程的示范。这些工具包括 GUI原型工具 墨刀、进度管理中看板和燃尽图工具 leangoo、版本控制工具git、tortoisegit。PSP中也应该包括时间记录工具atimelogger(toggl也不错,最近被墙了)。
1.0 原则
在软件工程的教学中,教师和助教也应该注意工具使用。
原则一 DRY[https://en.wikipedia.org/wiki/Don%27t_repeat_yourself]。
这是我们经常在课程中灌输给学生的,教师本身也应该以身作责,不然是件很人格分裂的事情。凡是通过profile发现占用大块时间的,特别是其中有重复工作的,应该优化这一部分。
原则二 过早优化是万恶之源。不熟悉的工作不应该写脚本或者做系统,妄图提高工作效率。在重复若干次以前,不应该盲目尝试创新。需要多次尝试,总结规律,然后写脚本。如果能熟悉大家的工作习惯,还应该写出软件来供大家用。
在本学期中,我完善和使用了一些半成品的脚本工具自用,用以提高工作效率。
目前仍需改进的是,手写的这些脚本仍然只是工具而不是工程,更不是产品,有不少硬编码和对环境的要求,不易为他人所用。好的工具还应该约束用户的行为,向用户指出设计者的意图(组织结构、流程),并且避免反复操作中的失误甚至避免反复操作本身。
1.1 投票统计-邮件AHK脚本
在课程中有同学们投票的活动,如在选题、alpha发布、beta发布、final发布中,有全体同学对作品投票排名次的要求。
为减少同学们投票的顾虑,采用匿名制。以往的学期中,曾经对投票人匿名,但是类似于唱票,公布过所有投票内容。但是教师低估了人性的聪明,同学们居然能猜出哪个票是谁投的。大致的原理是利益相关,会如何投票。这一原理导致不能公布所有投票,只能假设同学们可以信任教师可以保护匿名,由教师统计和发布。
要求投票的内容与一般问卷系统不同,是作品的名次(并且不得有并列),以确保分值差异化,或者人名,用于投票领跑黄衫获得者,既非多选,也非单选。所以目前没有找到适合的软件系统,由同学用电子邮件投票,发送给教师。没有用微信私聊,是因为不应假设所有同学都希望加教师为好友。
邮件有格式要求,比如下面这个。
本作业截止前每位同学向教师 ([email protected]) 发送1封邮件投票, 作为投票者的一次成绩5分。不投票或投票不符合要求 (包括不限于标题错误、 正文格式不符、小组名字写错) 的,视为未提交,倒扣分数。 投票 1名 你最感谢的同学。 收到感谢最多的同学将获颁“感谢多”黄色领跑衫。如果王超同学收到感谢最多,则由收到感谢第二多的同学获得。 -------邮件样例开始------------------ 邮件标题为: 我最感谢的同学 邮件正文为: 姓名:杨贵福 邹欣 -------邮件样例结束------------------
这次投票结果
收到投票34份,废票1张,重复投票1张,有效票共32票。
教师收到的邮件,比如下面这张截图。“姓名”之后是投票者的姓名,教师要用来登记完成投票这一作业的分数并避免重复投票,“排序”之后是这位投票者给出的各团队名次。
我对了件主题过滤,运行AHK写的脚本,遍历所有投票邮件,把每封邮件的正文复制添加到excel里。在excel中统一字体格式然后统计。
因为投票这一作业规定了截止期限,所以,AHK脚本在截止期限后运行。此后收到的邮件不必手工处理,而是丢弃。
邮件的正文在作业中有格式要求,凡是不符合格式要求的,作业不计分,投票视为废票。在实际操作中,有拼写错误、大小写错误、冒号半角全角错误的,一概按不符合格式要求处理,即使教师手动发现了这张投票。所以不需要处理更多的容错,同时这也是对同学们训练合规的一个机会。
不少地方非常粗糙,使得脚本仍然只是小工具,而不是适合更多人使用的软件。这本身有违软件工程的精神,不过符合重复次数不够多的情况下暂勿抽象的原则。比如,遍历邮件的个数是硬编码的;每封邮件打开以后停留一下,以保证正文载入完成。没有用中断/回调之类的机制,就只是等待;点击“下一封”按钮的位置与屏幕分辨率有关,也是硬编码的。
脚本如下。
; precodition: ; web邮箱录,搜索""选题 视频展示投票""结果页,打开第一封邮件,AHK脚本会循环开始下一封 ; excel打开,光标置于左上 MsgBox, 4,, "Press Yes to go on if you have setup the env." (press Yes or No) IfMsgBox Yes dump() else return dump() { SplashTextOn,,, "Working, please standby.". sleep 2000 SplashTextOff Loop, 31 { ; 复制邮件正文 MouseClick, left, 299, 421 Send ^{a} Send ^{c} ; 切换到excel IfWinExist, ahk_class XLMAIN WinActivate ; use the window found above else MsgBox Please run Excel. ; 右移一列 Send {Right} ; 粘贴邮件正文 Send ^{v} ; 切换到firefox IfWinExist, ahk_class MozillaWindowClass WinActivate ; use the window found above else MsgBox Firefox lost. ; 下一封 ;MouseClick, left, 1839, 226 ; home MouseClick, left, 1833, 212 ; xxhb sleep 2000 ; 等网页载入完毕 } } Escape:: ExitApp Return
上学期一共统计投票200余次,每次30余张票,节省了不少时间。
统计得票时,分别统计某一团队名次第1、名次第2、名次第3、名次第4的票数,然后求得平均名次。最下一行的27,是用于交叉检验的。
1.2 pull脚本
单人任务和结对编程两个项目,需要把同学的代码成批从 coding.net中获取到教师机编译运行检查结果。这也是检验同学们是否能够正确使用版本控制工具的时机。
我写了shell脚本为每位同学分别建立目录和pull代码。还有脚本用于批量执行和对比,效果不佳,因为同学们普遍地没有按作业的spec要求放置文件。此处略。
以下是pull脚本。第一次作业时有相当数量的同学git不符合要求,执行扣分,以后的作业有所好转。
#mkdir 翟宇豪 #cd 翟宇豪 #git init #git pull https://git.coding.net/Rio56/wf.git master declare -A map=(["冉华"]="https://git.coding.net/Dawnfox/wf4_2.git" ["刘淑霞"]="https://git.coding.net/liusx0303/CountWords__standardinput.git" ["胡佑蓉"]="https://coding.net/u/huyr000/p/countWords/git" ["王超"]="https://git.coding.net/SuperCodingChao/wfProject.git" ["高远博"]="https://coding.net/u/Rainbows/p/wc/git" #old ["陈建宇"]=" https://coding.net/u/MR__Chen/p/Demo/git" #old ["代秋彤"]="https://git.coding.net/a284617374/soft.git" ["方铭"]="https://coding.net/u/MingZi-/p/cipingtongji/git" ["葛美义"]="https://coding.net/u/gmyznb/p/wordcount1/git" ["黄泽宇"]="https://coding.net/u/huangzy_95/p/wf/git" ["贾男男"]="git://git.coding.net/lynlynyess/wf.git" ["贾雅杰"]="https://git.coding.net/jyj5951/wf.git" ["姜珊"]="https://git.coding.net/js2017102865/wf_c.git" ["阚博文"]="https://git.coding.net/zbwd666/zbwd.git" # old ["李传康"]="https://git.coding.net/lick468/wf.git" ["李圆圆"]="https://git.coding.net/lyy181/count.git" #old ["蔺依铭"]="https://git.coding.net/Hitagi123/word-count.git" ["刘成志"]="https://git.coding.net/liuchengzhi0944/wf.git" # ["刘耀泽"]="https://coding.net/u/liuyz349/p/word_count/git" # 未交作业 ["米赫"]="https://git.coding.net/immixiaomi/wf.git" #old ["苗威"]="https://git.coding.net/Vrocker/wf.git" ["任思佳"]="https://coding.net/u/rensijia/p/count-words/git" ["邵朔"]="https://git.coding.net/ss505072461/wf.git" ["宋雨"]="https://git.coding.net/songyuu/wf.git" ["田继平"]="https://git.coding.net/tianjiping/11111.git" #old ["王航"]="https://git.coding.net/wangh013/wf.git" ["王磊"]="https://git.coding.net/137911934/SE20170914.git" ["王伟东"]="https://git.coding.net/wangwd/SecondAssignment.git" ["王玉玲"]="https://coding.net/u/tutu123/p/tutu1234/git" #old ["吴雨丹"]="https://git.coding.net/clairewyd/wf.git" ["徐劭斌"]="https://git.coding.net/xushaobin/xushaobin_gongneng_4_2.git" ["杨梓瑞"]="https://git.coding.net/Vector121/homework.git" #old ["袁玥"]="https://coding.net/u/yuanyue2017102885/p/wf-part420170926/git" ["翟宇豪"]="https://git.coding.net/Rio56/wf.git" #old ["张恩聚"]="https://git.coding.net/ZhangEJ/wf.git" ["邹双黛"]="https://git.coding.net/szjzsd/123.git" #old ) for key in ${!map[@]} ; do mkdir $key cd $key git init git pull ${map[$key]} master cd .. done #echo ${!map[@]} # #echo ${map[@]} # # for key in ${!map[@]} ; do # # echo ${map[$key]} # echo $key; # done # 语法学习自 [https://coding.net/u/ZhangEJ/p/wf/git/tree/master/wf11]
1.3 excel
我用excel计算每周的作业成绩。函数lookup和vlookup在作业计算中起了重要作用,用于查 某作品被投票的分数、某同学的团队归属(以便累加团队得分)、某团队的单项作业得分等。
例如,在冉华同学的团队一列中,“王者荣耀交流协会”的取值,来自另一个名为“归属”的工作表。不hardcode有利于alpha阶段后换人。
又如冉华同学的视频展示得分,来自所在团队的“final视频”单项得分,查找自另一工作表“scrum+todolist+burndown”第14列匹配团队名“王者荣耀交流协会”。
除vlookup以外,在统计得票时countif、sum等也常用,match也有用到。
1.4 excel导出成markdown格式
构建之法课程群统一在cnblogs.com上发布成绩,该网站支持markdown格式。幻飞龙博士开发有exceltk[http://www.cnblogs.com/math/p/exceltk.html]可以完成excel导出成markdown格式,大大方便了这一工作。极其方便,强烈推荐,非常感谢。
1.5 仍存在的困难
在算分时常犯错误,被同学们纠正过几次。1.本周成绩没有累积到总成绩,2.修正学生得分时担心错,3.使用错误的sheet,因此排序错误(数据没错)。这些都应可以通过数据检验或交叉检验完成,不过仍未找到可行的方法。
------------------------------------------------------
博客会手工同步到以下地址:
[http://zhuanlan.zhihu.com/younggift]
[https://younggift.net/]
//[http://blog.csdn.net/younggift]
//[http://giftdotyoung.blogspot.com]