一、Github项目地址:https://github.com/1078862512/Software-Engineering
直接打开程序:http://123.57.234.212/
结对成员:尚通311805105 李彦霆3118005056
二、PSP表格:在程序各个模块的开发上估计耗费的时间
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
20 |
|
· Estimate |
· 估计这个任务需要多少时间 |
20 |
|
Development |
开发 |
2210 |
|
· Analysis |
· 需求分析 (包括学习新技术) |
200 |
|
· Design Spec |
· 生成设计文档 |
60 |
|
· Design Review |
· 设计复审 (和同事审核设计文档) |
30 |
|
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
40 |
|
· Design |
· 具体设计 |
100 |
|
· Coding |
· 具体编码 |
1200 |
|
· Code Review |
· 代码复审 |
200 |
|
· Test |
· 测试(自我测试,修改代码,提交修改) |
480 |
|
Reporting |
报告 |
240 |
|
· Test Report |
· 测试报告 |
160 |
|
· Size Measurement |
· 计算工作量 |
20 |
|
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
60 |
|
合计 |
2470 |
四、设计实现过程
使用语言:JavaScript
程序实现的核心算法部分,使用了多函数复合嵌套的方式,具体结构如下图:
每个n元的算式生成都有这样几个对应函数嵌套而成。
五、代码说明
1.随机生成函数:生成算式的一个因数。
function GetRandomNum(Min,Max)//核心,用于生成指定范围内随机整数 { var Range = Max - Min; var Rand = Math.random(); return(Min + Math.round(Rand * Range)); }
2.n元启动函数:为算式准备所有因数(和上一个函数其实可以看做一起的)。
function Two(Min,Max)//二元启动函数 { var num1=GetRandomNum(Min,Max); var num2=GetRandomNum(Min,Max); var sona=TwoOperations(num1,num2); return sona; } function Three(Min,Max)//三元启动函数 { var num1=GetRandomNum(Min,Max); var num2=GetRandomNum(Min,Max); var num3=GetRandomNum(Min,Max); var mata=ThreeOperations(num1,num2,num3); return mata; } function Four(Min,Max)//四元启动函数 { var num1=GetRandomNum(Min,Max); var num2=GetRandomNum(Min,Max); var num3=GetRandomNum(Min,Max); var num4=GetRandomNum(Min,Max); var icey=FourOperations(num1,num2,num3,num4); return icey; }
3.n元四则算式生成函数:生成四则运算的算式。
function TwoOperations(num1,num2)//用于生成二元运算题 { var sign=["+","-","*","/"];//并没有实际作用,用来提醒我顺序 var choose=GetRandomNum(0,3); switch(choose) { case 0: { var sum=num1+num2; var question=(num1+"+"+num2+"="+sum); return question; break; } case 1: { var t=0; if(num1<num2) { t=num1; num1=num2; num2=t; } var sum=num1-num2; var question=(num1+"-"+num2+"="+sum); return question; break; } case 2: { var sum=num1*num2; var question=(num1+"*"+num2+"="+sum); return question; break; } case 3: { var t=0; if(num1>num2) { t=num1; num1=num2; num2=t; } var question=(num1+"/"+num2+"="+num1+"/"+num2); return question; break; } } } function TwoOperations_s(num1,num2)//三元/四元运算附属函数,用于生成二元计算式 { var choose=GetRandomNum(0,3); switch(choose) { case 0: { var question=(num1+"+"+num2); return question; break; } case 1: { var t=0; if(num1<num2) { t=num1; num1=num2; num2=t; } var question=(num1+"-"+num2); return question; break; } case 2: { var question=(num1+"*"+num2); return question; break; } case 3: { var t=0; if(num1>num2) { t=num1; num1=num2; num2=t; } var question=(num1+"/"+num2); return question; break; } } } function FourOperations(num1,num2,num3,num4)//用于生成四元计算题 { var choose=GetRandomNum(0,3); switch(choose) { case 0: { var A=TwoOperations_s(num1,num2); var B=TwoOperations_s(num3,num4); var sum=eval(A+"+"+B); var question=(A+"+"+B+"="+sum); return question; break; } case 1: { var A=TwoOperations_s(num1,num2); var B=TwoOperations_s(num3,num4); var sumA=eval(A); var sumB=eval(B); if(sumA<sumB) { var t=A; A=B; B=t; } var sum=eval(A+"-"+B); var question=(A+"-"+B+"="+sum); return question; break; } case 2: { var A=TwoOperations_s(num1,num2); var B=TwoOperations_s(num3,num4); var sum=eval("("+A+")"+"*"+"("+B+")"); var question=("("+A+")"+"*"+"("+B+")"+"="+sum); return question; break; } case 3: { var A=TwoOperations_s(num1,num2); var B=TwoOperations_s(num3,num4); var t=0; if(A>B) { t=A; A=B; B=t; } var a=eval(A);var b=eval(B); var question=("("+A+")"+"/"+"("+B+")"+"="+a+"/"+b); return question; break; } } } function ThreeOperations(num1,num2,num3)//用于生成三元计算题 { var choose=GetRandomNum(0,3); switch(choose) { case 0: { var A=TwoOperations_s(num1,num2); var sum=eval(A+"+"+num3); var question=(A+"+"+num3+"="+sum); return question; break; } case 1: { var A=TwoOperations_s(num1,num2); var sum=eval(A+"-"+num3); if(sum<0) { var t=A; A=num3; num3=A; sum=eval(A+"-"+num3); } var question=(A+"-"+num3+"="+sum); return question; break; } case 2: { var A=TwoOperations_s(num1,num2); var sum=eval("("+A+")"+"*"+num3); var question=("("+A+")"+"*"+num3+"="+sum); return question; break; } case 3: { var A=TwoOperations_s(num1,num2); var sum=eval("("+A+")"+"/"+num3); if(sum>1) { var t=A; A=num3; num3=t; sum=eval(num3); } else { sum=num3; } var a=eval(A); var question=("("+A+")"+"/"+num3+"="+a+"/"+sum); return question; break; } } }
4.运行函数。
function Start() { var max=document.getElementById("max").value; var n=document.getElementById("count").value; var min=1; for(var i=0;i<n;i++) { var choose=GetRandomNum(2,4); switch(choose) { case 2: { var T=Two(min,max); var ouput=document.getElementById("output"); output.innerHTML+=("第"+(i+1)+"题:"+T+"</br>"); break; } case 3: { var T=Three(min,max); var ouput=document.getElementById("output"); output.innerHTML+=("第"+(i+1)+"题:"+T+"</br>"); break; } case 4: { var T=Four(min,max); var ouput=document.getElementById("output"); output.innerHTML+=("第"+(i+1)+"题:"+T+"</br>"); break; } } }
六、测试运行
1.程序界面
2.题目生成
3.答案输出
4.运行说明
界面还是比较友好的,看着就可以会使用,点击save as file就可以把生成的题目和答案另存为电脑中了。
七、PSP表格:在程序各个模块的开发上实际耗费的时间
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
20 |
10 |
· Estimate |
· 估计这个任务需要多少时间 |
20 |
10 |
Development |
开发 |
2210 |
2470 |
· Analysis |
· 需求分析 (包括学习新技术) |
200 |
500 |
· Design Spec |
· 生成设计文档 |
60 |
30 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
30 |
20 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
40 |
40 |
· Design |
· 具体设计 |
100 |
100 |
· Coding |
· 具体编码 |
1200 |
1200 |
· Code Review |
· 代码复审 |
200 |
200 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
480 |
480 |
Reporting |
报告 |
240 |
240 |
· Test Report |
· 测试报告 |
160 |
160 |
· Size Measurement |
· 计算工作量 |
20 |
20 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
60 |
60 |
合计 |
2470 |
2720 |
八、项目小结
几个需求都已基本实现,我们采用了图像界面,实现了相似功能。不过没有真正项目的经验,我们也不能判断,这个“相似功能”能否完全满足真实的需求。
项目主体程序的实现,并不算太过复杂,在这个项目里要新学习的内容主要在于JavaScript里文件的输入输出。开始选定JavaScript作为这个项目的编程语言,主要是基于它在用户使用界面方面比较容易完成,我的搭档尚同学对于这门语言也比较热衷,当然我是一窍不通。于是我就需要不断跟上他的脚步,一边学习他写出来的部分,一边学习需要帮他补足的部分。
结对项目还是有很多好处的,比如一个的难题,可以两个人讨论解决;一个人遇到问题,另一个人可以指正,旁观者清嘛。结对编程使我们思维更加全面,编程效率也更高。主要的难点还是在于我这个JS小白需要跟上搭档的节奏,在合作的磨合中倒没有存在太大的问题,包括分工、综合等等,我们还是相处得很好。
在这个项目里,我个人是学到了一门全新的语言,磕磕绊绊的能写出一点JS代码,我的搭档我觉得他应该学到了如何领导并带起一个并不厉害的队友吧,哈哈。这个项目给了我很多乐趣,结对项目还是很开心的。
( 简单概括一下项目实现过程是这样的:
—————这里是分割线—————
搭档:我们开始做吧!
我:好的!
——————第二天———————
搭档:我把这个程序主要的算法部分都写好了,你把文件输出什么的写一写。
我:好的,马上学!
——————过了几天——————
我:这里好像有点问题啊,你看看我写的对不对!
搭档:啊,这个我写好了,你去调一调程序的用户界面吧。
我:…好,马上学!
——————又过了一天——————
搭档:啊,程序我弄好了,这里有点bug你看看改改。
我:………好!
——————一天后————————
搭档:啊,我改好了,你还看看哪有问题。
我:…………(可能是我有问题8)
所以完成一个项目,还是那个围绕着核心主题不断编写,然后产生问题并解决问题的过程。只不过,当你有一个带飞的队友,可能你就不大需要自己解决问题,只要提出问题给他解决就好了(笑)。
最后,十分感谢我的搭档——通鸽鸽同学!