201571030103/201571030105 软件工程结对项目
Github的仓库主页链接地址:https://github.com/djhdijd/bean1.git
201571030103/201571030105
个人项目实施过程:
(1)由计算机从题库文件中随机选择20道加减乘除混合算式,用户输入算式答案,程序检查答案是否正确,每道题正确计5分,错误不计分,20道题测试结束后给出测试总分;
(2)题库文件可采用实验二的方式自动生成,也可以手工编辑生成,文本格式如下:
(3)程序为用户提供三种进阶四则运算练习功能选择:百以内整数算式(必做)、带括号算式、真分数算式练习;
(4)程序允许用户进行多轮测试,提供用户多轮测试分数柱状图,示例如下:
(5)程序记录用户答题结果,当程序退出再启动的时候,可为用户显示最后一次测试的结果,并询问用户可否进行新一轮的测试;
(6)测试有计时功能,测试时动态显示用户开始答题后的消耗时间。
(7)程序人机交互界面是GUI界面(WEB页面、APP页面都可),界面支持中文简体(必做)/中文繁体/英语,用户可以进行语种选择。
2.软件设计
3.核心代码
(1)倒计时的设置,定义类为TimeProgressBar
1 public class TimeProgressBar extends JProgressBar implements ActionListener{ 2 public int maxTime = Param.time;// 设置最大时间 3 private Timer timer = new Timer(1000, this);// 计时器,int 4 // delay一秒减少一次和ActionListener监听器 5 public MainFrame mainFrame; 6 7 public TimeProgressBar(MainFrame mainFrame) { 8 this.mainFrame = mainFrame; 9 // mouseEvent(); 10 this.setMaximum(maxTime); 11 this.setValue(maxTime); 12 this.setBackground(Color.gray); 13 this.setStringPainted(true);// 设置 stringPainted 14 // 属性的值,该属性确定进度条是否应该呈现进度字符串。 15 this.setString(maxTime + "秒"); 16 } 17 18 19 public void actionPerformed(ActionEvent arg0) { 20 // TODO Auto-generated method stub 21 maxTime--; 22 this.setValue(maxTime); 23 this.setString(maxTime + "秒"); 24 25 //时间一到,计时停下来,不然会进入负数 26 if(maxTime==0){ 27 this.stop(); 28 mainFrame.answerArea.setEditable(false); 29 } 30 31 } 32 /** 33 * 开始 34 */ 35 public void start() { 36 timer.start(); 37 } 38 39 /** 40 * 暂停 41 */ 42 public void stop() { 43 timer.stop(); 44 } 45 /** 46 * 重新开始 47 */ 48 public void restart() { 49 maxTime = Param.time; 50 this.setMaximum(maxTime);// 重新设置JProgress的最大值 51 this.setValue(maxTime); 52 this.setString(maxTime + "秒"); 53 timer.start(); 54 } 55 }
(2)主框架界面设置
1 public class MainFrame extends JFrame{ 2 JPanel jpanel=new JPanel(); 3 MainMenuBar mainMenuBar=new MainMenuBar(this);//菜单 4 ButtonLabel generatingItemButton=new ButtonLabel(Param.generatingItem);//生成按钮 5 ButtonLabel beginButton=new ButtonLabel(Param.begin);//开始按钮 6 TimeProgressBar timeProgressBar=new TimeProgressBar(this); 7 JTextArea subjectArea=new JTextArea();//题目框 8 JTextArea answerArea=new JTextArea();//答题区 9 public ButtonLabel submitButton=new ButtonLabel(Param.submit);//提交按钮 10 11 //构造函数 12 public MainFrame(){ 13 init(); 14 mouseEvent(); 15 this.setJMenuBar(mainMenuBar);//添加菜单 16 this.setTitle(Param.title); 17 this.setSize(700,600); 18 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置默认关闭窗口方式 19 this.setLocationRelativeTo(null);//设置窗体相对居中 20 this.setResizable(false);//设置窗口不可调整 21 this.setVisible(true);//可视化 22 } 23 24 //初始化设置 25 public void init(){ 26 this.setLayout(null);//设置空布局 27 28 generatingItemButton.setBounds(20, 20, 100, 30); 29 this.add(generatingItemButton); 30 31 beginButton.setBounds(130, 20, 100, 30); 32 this.add(beginButton); 33 34 //进度条 35 timeProgressBar.setBounds(400, 20, 250, 30); 36 this.add(timeProgressBar); 37 38 39 subjectArea.setEditable(false); 40 //给试题框出现滚动条 41 JScrollPane jssubjectArea=new JScrollPane(subjectArea); 42 jssubjectArea.setBounds(20, 100, 600, 150); 43 this.add(jssubjectArea); 44 45 answerArea.setEditable(false); 46 //给答题框加设滚动条 47 JScrollPane jsanswerArea=new JScrollPane(answerArea); 48 jsanswerArea.setBounds(20, 300, 600, 150); 49 this.add(jsanswerArea); 50 51 52 submitButton.setBounds(300, 480, 100, 30); 53 this.add(submitButton); 54 55 jpanel.setBounds(0, 0, 700, 1000); 56 this.add(jpanel); 57 58 }
(3)“生成题目”答案产生的过程
1 //生成式子答案 2 public Number getAnswser() { 3 //先对式子的*和÷进行处理 4 int i = 0; 5 while (i < operatorList.size()) { 6 //如果数列里的数个数是0,则返回该方法 7 if (numberList.size()==1){ 8 return (Number) numberList.get(0); 9 } 10 //当算符出现*和÷的时候 11 if (operatorList.get(i).equals("*") || operatorList.get(i).equals("÷")) { 12 //取得运算符两侧的数 13 Number numberFront = (Number) numberList.get(i); 14 Number numberAfter = (Number) numberList.get(i + 1); 15 //求得运算符两侧数值的分子部分 16 int numberFrontMolecule = numberFront.getInteger() * numberFront.getDenominator() + numberFront.getMolecule(); 17 int numberAfterMolecule = numberAfter.getInteger() * numberAfter.getDenominator() + numberAfter.getMolecule(); 18 int endMolecule = 0; 19 int endDenominator = 0; 20 //算得两数相乘的分子值和分母值 21 if (operatorList.get(i).equals("*")) { 22 endMolecule = numberFrontMolecule * numberAfterMolecule; 23 endDenominator = numberFront.getDenominator() * numberAfter.getDenominator(); 24 } 25 if (operatorList.get(i).equals("÷")) { 26 endMolecule = numberFrontMolecule * numberAfter.getDenominator(); 27 endDenominator = numberAfterMolecule * numberFront.getDenominator(); 28 } 29 int endInteger = 0;//初始分子的整数部分为0 30 if (endMolecule > endDenominator) { 31 endInteger = endMolecule / endDenominator; 32 endMolecule = endMolecule % endDenominator; 33 } 34 //求最大公约数 35 int smaller = endMolecule > endDenominator ? endMolecule : endDenominator; 36 int maxCommonFactor = 1; 37 for (int j = 1; j <= smaller; j++) { 38 if (endMolecule % j == 0 && endDenominator % j == 0) { 39 maxCommonFactor = j; 40 } 41 } 42 endMolecule = endMolecule / maxCommonFactor; 43 endDenominator = endDenominator / maxCommonFactor; 44 Number endNumber = new Number(endInteger, endMolecule, endDenominator);//约分后的式子 45 this.numberList.add(i, endNumber); 46 this.numberList.remove(i + 1); 47 this.numberList.remove(i + 1); 48 this.operatorList.remove(i); 49 }else { 50 i++; 51 } 52 } 53 54 //进行完*÷处理后进行+-处理 55 while (operatorList.size()!=0){ 56 //取得运算符两侧的数 57 Number numberFront = (Number) numberList.get(0); 58 Number numberAfter = (Number) numberList.get(1); 59 //求得运算符两侧数值的分子部分 60 int numberFrontMolecule = numberFront.getInteger() * numberFront.getDenominator() + numberFront.getMolecule(); 61 int numberAfterMolecule = numberAfter.getInteger() * numberAfter.getDenominator() + numberAfter.getMolecule(); 62 //不管两式子的分母一样或不一样,都把两分母相乘 63 int endDenominator=numberFront.getDenominator()*numberAfter.getDenominator(); 64 //如果为+符,就进行+算 65 int allMolecule1=numberFrontMolecule*numberAfter.getDenominator(); 66 int allMolecule2=numberAfterMolecule*numberFront.getDenominator(); 67 int endMolecule=0;//定义未约分前的分子部分 68 if (operatorList.get(0).equals("+")){ 69 endMolecule=allMolecule1+allMolecule2; 70 } 71 if (operatorList.get(0).equals("-")){ 72 endMolecule=allMolecule1-allMolecule2; 73 } 74
4.运行测试
(1)运行程序后,弹出菜单对话框。有两项功能:生成题目,开始做题,提交答案,并显示进度条从300秒开始倒计时。
(2).点击“生成题目”项,有20道四则运算显示,同时点击“开始做题”,答题框可进行编辑做答,进度条开始变化。
2.
(3)答题的最终结果显示在Answers.txt中及正确率在文本框Grade.txt可得。
(4)当一轮答题结束之后,可以再次点击“生成题目”的选项,进行新一轮的答题。题目的历史记录保存在文档“Exercises.txt”中。
5.PSP展示
PSP2.1 |
任务内容 |
计划共完成需要的时间(min) |
实际完成需要的时间(min) |
Planning |
计划 |
15 |
20 |
· Estimate |
· 估计这个任务需要多少时间,并规划大致工作步骤 |
10 |
10 |
Development |
开发 |
220 |
240 |
·· Analysis |
需求分析 (包括学习新技术) |
10 |
10 |
· Design Spec |
· 生成设计文档 |
5 |
6 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
10 |
15 |
· Coding Standard |
代码规范 (为目前的开发制定合适的规范) |
5 |
10 |
· Design |
具体设计 |
10 |
15 |
· Coding |
具体编码 |
200 |
240 |
· Code Review |
· 代码复审 |
10 |
10 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
15 |
10 |
Reporting |
报告 |
15 |
25 |
·· Test Report |
· 测试报告 |
3 |
5 |
· Size Measurement |
计算工作量 |
5 |
5 |
· Postmortem & Process Improvement Plan |
· 事后总结 ,并提出过程改进计划 |
3 |
3 |
6. 请使用汉堡评价法给你的小伙伴一些点评。
俗话说,一个巴掌拍不响。结对项目更是如此,要两个人合作完成才会完成的更好。在项目完成过程中,我的同伴能及时的给予帮助和提示,并通过两个人的交流,查找资料,整合,并实际操作,这个过程虽然有点花费时间,但是项目完成的效率却更高,结合两个人好的意见使得功能更加完善。
7. 结对编程真的能够带来1+1>2的效果吗?通过这次结对编程,请谈谈你的感受和体会。
在这次软件工程项目我们共同完成了在图形用户界面下的四则运算设计。总体来说,两个人合力设计完成得更高效,自己不会,弄错的点经同伴提示,可以及时改正。再结合两个人对一个问题的看法以及所掌握的资料,择优选取,使得项目功能更加完善。这样来说,结对编程是可以产生1+1>2的效果的。