第五次作业
这个作业的要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/2232
我的github地址:https://github.com/065lihaochun/lihaochun
【软件工程实践】结对项目-四则运算 “软件”之升级版
一、需求分析
基本要求:
- 生成题目,单个题目最多不能超过4个运算符,操作数小于100。
- 用户可以输入答案
- 若用户输入答案正确,则提示正确;若答案错误,则提示错误,并要提示正确答案是多少。
4个扩展方向:
- 用户答题结束以后,程序可以显示用户答题所用的时间
- 用户在第一次答题时,需要用户输入用户名,用户下次启动后,程序需要记住用户前一次输入的用户名
- 程序可以设置答题时间,时间设置为整数,单位为秒,最大不能超过120秒,若超过了答题时间未答题,则提示:时间已到,不能答题。
- 程序可以设置皮肤功能,可以改变界面的颜色即可。
二、功能设计
开发语言:java
开发工具:IntelliJ IDEA Community Edition 2017.2.3 x64
开发环境:jdk1.8.0_112
开发时间:2018.10.23-2018.10.25
1、功能实现
项目包含的功能基本包含上述几类:
- 用户在第一次答题时,需要用户输入用户名,用户下次启动后,记住上一次用户的名字
- 用户输入用户名后,可以查询历史答题记录和分数情况
- 生成随机10道题目,单个题目最多不能超过4个运算符,操作数小于100。
- 用户可以输入答案,若用户输入答案正确,则提示正确;若答案错误,则提示错误,并要提示正确答案是多少。
- 用户可以选择自己喜欢的颜色界面
- 答题倒计时,最多不得超过120s,时间到则答题禁止,显示答案和分数
- 用户可以选择当前10道题目重新做
- 答题结束,显示用户已用时间和获得的分数
2、类的设计
本次实验中只用到了3个类,分别是ArithmeticTest主类,CalculateGenerator随机运算业务类,MyExGUI面板类。对应的功能实现如下:
ArithmeticTest主类:没有更多功能,只负责调用面板类;
CalculateGenerator随机运算业务类:仅由面板类调用,负责随机产生10个运算式题目,运算数小于100,运算符随机产生,最多4位;
可供调用的方法是 public static ArrayList produceExercises() throws ScriptException (无参数,返回一个ArrayList集合,包含10条随机运算题目);
可供获取到的值是 public static List<String> answerList=new ArrayList<>();(存放10条随机运算题目的答案集合)
为了更好的封装性,其他方法和变量都设置为私有private
MyExGUI面板类:仅有主类调用,负责生成窗口,布局标签和按钮,监听按钮事件,读写入文件等,包含的方法有:
public MyExGUI() throws IOException 布局与监听
public void start() throws ScriptException 在面板上产生10到随机题目
public void printAnswer() 在面板上显示每题的正确答案、得分和用时,并且将每次做题的记录写入文件
3、流程图
三、详细设计
1、界面的生成
本次实验的可视化界面主要由 javax.swing包类中的各种组件构成,主要由画布,文本标签,按钮,输入框和下拉框构成的视图界面。
接下来对这些控件进行布局,窗口主面板是左右对称的布局,左边布局设置5到题目的显示文本标签和对应的答案输入框以及正确答案、正确或错误提醒的标签,右边布局也是同样的设置。底部为命令面板线性布局,主要由“剩余时间”、“已用时间“”的文本标签以及“开始做题”、“重做”、“查看记录”等命令按钮组成。
2、为按钮控件设置监听器
设置的监听器主要有“设置皮肤”下拉框、“开始做题”按钮、“重做”按钮、“查看记录”按钮等。
3、运算式子的生成
定义final字符变量及数组储存操作符图形、操作符、操作符数量和操作数最大值。
操作符和操作数的随机产生,传入操作符和操作数的数量作为参数,在前面定义的final字符数组里面随机获取操作符和操作数,for循环写进函数定义好的集合,并返回一个包含操作符和操作数的集合给调用对象。
四则运算的生成,随机获取操作符和操作数的数量(操作数=操作符+1),定义两个集合对象获取上述的操作符集合和操作数集合,定义一个集合存储新的运算式,在for循环中分别将2个集合中的操作数和操作符按照先后顺序添加进运算式的集合中,此外还增加了除数如果为0和不能减数大于被减数的判断。返回一个完整的式子给调用对象。
4、数据的存储与访问
在随机式子产生的业务代码中主要涉及到的两个可访问数据,一个是放回值,放回一个存储10道随机式子的集合给面板类,另一个是静态集合变量,存储着10道题目的答案,答案和题目是对应的,只要题目一更新,答案集合中的元素就被重新赋值。
返回给面板类10道随机式子的函数,返回值:expressionList
公开变量answerList,存储10个答案,数据类型:List<String>
对答案集合answerList做判断,如果答案每满10个就进行清除元素处理,新增新答案
其他细节逻辑代码这里不做赘述,详情请看github仓库Java代码。
四、部分代码
1 //按开始按钮,在面板上显示10道题目 2 public void start() throws ScriptException { 3 //清除TextField和答案标签的内容 4 CalculateGenerator exercises = new CalculateGenerator(); 5 6 expressionList=exercises.produceExercises(); 7 for (int i = 0; i < 10; i++) { 8 JLBQuestions[i].setText(expressionList.get(i)); 9 JTFUsersAnswer[i].setText(""); 10 JLBAnswers[i].setText(""); 11 JLBIsTrue[i].setText(""); 12 JLBScores.setText(""); 13 JLBTime.setText("用时:"); 14 15 } 16 } 17 18 19 //在面板上显示每题的正确答案、得分和用时,并且将每次做题的记录写入文件 20 public void printAnswer() { 21 //创建用户文件 22 pFile.mkdirs(); 23 String filename = JTFUserName.getText()+".his"; 24 String userListName="userList"; 25 26 File aUserRec = new File(pFile,filename); 27 File usersList=new File(pFile,userListName); 28 //创建用户的成绩记录文件 29 if(! (aUserRec.exists())) 30 { 31 try{ 32 aUserRec.createNewFile(); 33 }catch(Exception e){ 34 e.printStackTrace(); 35 JFrame jf = new JFrame(); 36 JOptionPane.showMessageDialog(jf,"用户文件创建失败"); 37 } 38 } 39 40 41 //创建一个记录所有使用过的用户名文件 42 if(! (usersList.exists())) 43 { 44 try{ 45 usersList.createNewFile(); 46 }catch(Exception e){ 47 e.printStackTrace(); 48 JFrame jf = new JFrame(); 49 JOptionPane.showMessageDialog(jf,"用户文件创建失败"); 50 } 51 } 52 53 //定义CalculateGenerator类的一个对象answer,获取10道题的答案集合 54 CalculateGenerator answer=new CalculateGenerator(); 55 56 List<String> answerList ; //用来记录正确答案的集合 57 answerList=answer.answerList; //赋值 58 59 //成绩初始值为100 60 scores = 100; 61 62 //对于每道题 63 for(int i = 0; i < 10;i++) 64 { 65 //给用户的答案这一数组赋值(getText的结果为String) 66 userAnswer[i] = String.valueOf(Integer.valueOf(JTFUsersAnswer[i].getText())); 67 //使正确答案显示在面板上 68 JLBAnswers[i].setText("正确答案:"+answerList.get(i)); 69 //在面板上显示答案是否正确 70 if(userAnswer[i].equals(answerList.get(i))==true){ 71 JLBIsTrue[i].setText("答案正确"); 72 }else{ 73 JLBIsTrue[i].setText("答案错误"); 74 } 75 //错误则改变字体颜色为红色,正确则改为黑色 76 if(JLBIsTrue[i].getText().equals("答案错误")) 77 { 78 JLBAnswers[i].setForeground(Color.RED); 79 JLBIsTrue[i].setForeground(Color.RED); 80 scores-=10; 81 } else 82 { 83 JLBAnswers[i].setForeground(Color.BLACK); 84 JLBIsTrue[i].setForeground(Color.BLACK); 85 } 86 } 87 88 //分数标签显示成绩 89 JLBScores.setText("你的成绩为:"+ scores); 90 if(scores==100){ 91 JFrame nullFileWarning = new JFrame(); 92 JOptionPane.showMessageDialog(nullFileWarning,"恭喜你答对所有题目!"); 93 } 94 //将得分和用时写入对应的文件 95 try 96 { 97 PrintWriter out = new PrintWriter(new FileWriter(aUserRec,true)); 98 out.println(JTFUserName.getText()); 99 out.println("你此次的得分是:"+scores+" "+"所用时间为:"+usedTime+"秒"); 100 out.println(""); 101 out.close(); 102 //同时记录当前用户名到userList中 103 out = new PrintWriter(new FileWriter(usersList,true)); 104 out.println(JTFUserName.getText()); 105 out.close(); 106 }catch(FileNotFoundException e){ 107 System.err.println("File not found!" ); 108 }catch(IOException e2){ 109 e2.printStackTrace(); 110 } 111 }
五、运行结果截图
运行界面
点击开始做题,切换背景颜色
点击提交,切换背景
点击重做
时间到
全部题目答对
查看记录
六、结对同伴
姓名:陈锦泓
他的博客地址:http://www.cnblogs.com/183289879qq/
结对学习照片:
七、总结
结对编程需要花费的时间比个人编程更长,但产生的 bug 比个人编程少;它需要付出多一倍的时间和精力,但编程的效率会比个人编程高。同伴之间可以互相鼓励,不容易轻言放弃,团队工作能增加成员的工作积极性。因为在面对问题的时候,会有人一起分担,共同尝试新的策略。还可以互相学习编程技巧,在编程中,相互讨论,可以更快更有效地解决问题,互相请教对方,可以得到能力上的互补。多双眼睛,少点 bug,两人互相监督工作,可以增强代码和产品质量,并有效的减少 BUG。
八、结对软件过程耗时估计与统计表
PSP2.1 | Personal Software Process Stages | Time Senior Student(h) | Time(h) |
Planning | 计划 | 3 | 3 |
· Estimate | 估计这个任务需要多少时间 | 10 | 24 |
Development | 开发 | 8 | 12 |
· Analysis | 需求分析 (包括学习新技术) | 2 | 1 |
· Design Spec | 生成设计文档 | 2 | 1 |
· Design Review | 设计复审 | 1 | 1 |
· Coding Standard | 代码规范 | 0.5 | 1.5 |
· Design | 具体设计 | 4 | 4.5 |
· Coding | 具体编码 | 12 | 16 |
· Code Review | 代码复审 | 1 | 1.5 |
· Test | 测试(自我测试,修改代码,提交修改) | 1 | 1 |
Reporting | 报告 | 1 | 3 |
· | 测试报告 | 0 | 0 |
· | 计算工作量 | 1 | 1 |
· | 并提出过程改进计划 | 0 | 1 |