任务1源码在Github的仓库主页链接地址:https://github.com/zhanghh2018/201571030135-201571030137
账号 admin 密码 123456
一、需求分析。
(1)由计算机从题库文件中随机选择20道加减乘除混合算式,用户输入算式答案,程序检查答案是否正确,每道题正确计5分,错误不计分,20道题测试结束后给出测试总分;
(2)题库文件可采用实验二的方式自动生成,也可以手工编辑生成。
(3)程序为用户提供三种进阶四则运算练习功能选择:百以内整数算式(必做)、带括号算式、真分数算式练习;
(4)程序允许用户进行多轮测试,提供用户多轮测试分数柱状图,示例如下:
(5)程序记录用户答题结果,当程序退出再启动的时候,可为用户显示最后一次测试的结果,并询问用户可否进行新一轮的测试;
(6)测试有计时功能,测试时动态显示用户开始答题后的消耗时间。
(7)程序人机交互界面是GUI界面(WEB页面、APP页面都可),界面支持中文简体(必做)/中文繁体/英语,用户可以进行语种选择
二、软件设计:
(1)流程图
(2)类图(ContentToTxt():将内容写入文件 、ContinuTest():询问是否进行下一轮测试 、DTimeFrame():计时功能 、LoginIn():登录界面、 PrintChart():绘制分数图、 ReadFile():一行一行读文件 、UI():答题界面)
三、核心功能代码展示:展示核心功能代码。
核心代码一:自动计时功能
import java.util.Date; import java.awt.Dimension; import java.text.SimpleDateFormat; import java.util.Calendar; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; /** * @author zhanghh * @time 2018.03.28 */ public class DTimeFrame extends JFrame implements Runnable{ private JFrame frame; private JPanel timePanel; private JLabel timeLabel; private JLabel displayArea; private String DEFAULT_TIME_FORMAT = "ss"; private int ONE_SECOND = 1000; public DTimeFrame(){ timePanel = new JPanel(); timeLabel = new JLabel("您当前用时: "); displayArea = new JLabel(); timePanel.add(timeLabel); timePanel.add(displayArea); this.add(timePanel); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setSize(new Dimension(200,100)); this.setBounds(900, 100, 200, 100); } public void run(){ int time=1; while(true){ SimpleDateFormat dateFormatter = new SimpleDateFormat(DEFAULT_TIME_FORMAT); displayArea.setText(time+"s"); try{ time++; Thread.sleep(ONE_SECOND); }catch(Exception e) { displayArea.setText("Error!!!"); } } } }
核心代码二:柱状图显示
import java.awt.Font; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartFrame; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis3D; import org.jfree.chart.axis.NumberAxis3D; import org.jfree.chart.axis.NumberTickUnit; import org.jfree.chart.labels.ItemLabelAnchor; import org.jfree.chart.labels.ItemLabelPosition; import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.renderer.category.BarRenderer3D; import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.ui.TextAnchor; /** * * @author zhanghh * @time:2018.03.29 * @function:Display histogram * */ public class PrintChart { public static void print(int[] Score,int SubmissionsNum){ DefaultCategoryDataset dataset = new DefaultCategoryDataset(); //添加数据 for(int i=1;i<=SubmissionsNum;i++){ dataset.addValue(Score[i],"分数"+i, "第"+i+"轮"); } JFreeChart chart = ChartFactory.createBarChart3D("分数统计图", //主标题的名称 "测试次数", //X轴的标签 "测试分数(分数)", //Y轴的标签 dataset, //图标显示的数据集合 PlotOrientation.VERTICAL,//图像的显示形式(水平或者垂直) true, //是否显示子标题 true, //是否生成提示的标签 true);//是否生成url链接 //处理图形上的乱码 //处理主标题的乱码 chart.getTitle().setFont(new Font("宋体",Font.BOLD,18)); //处理子标题乱码 chart.getLegend().setItemFont(new Font("宋体",Font.BOLD,15)); //获取图表区域对象 CategoryPlot categoryPlot = (CategoryPlot) chart.getPlot(); //获取X轴的对象 CategoryAxis3D categoryAxis3D = (CategoryAxis3D) categoryPlot.getDomainAxis(); //获取Y轴的对象 NumberAxis3D numberAxis3D = (NumberAxis3D) categoryPlot.getRangeAxis(); //处理X轴上的乱码 categoryAxis3D.setTickLabelFont(new Font("宋体",Font.BOLD,15)); //处理X轴外的乱码 categoryAxis3D.setLabelFont(new Font("宋体",Font.BOLD,15)); //处理Y轴上的乱码 numberAxis3D.setTickLabelFont(new Font("宋体",Font.BOLD,15)); //处理Y轴外的乱码 numberAxis3D.setLabelFont(new Font("宋体",Font.BOLD,15)); //处理Y轴上显示的刻度,以1作为1格 numberAxis3D.setAutoTickUnitSelection(false); NumberTickUnit unit = new NumberTickUnit(100); numberAxis3D.setTickUnit(unit); //获取绘图区域对象 BarRenderer3D barRenderer3D = (BarRenderer3D) categoryPlot.getRenderer(); //设置柱形图的宽度 barRenderer3D.setMaximumBarWidth(0.07); //在图形上显示数字 barRenderer3D.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator()); barRenderer3D.setBaseItemLabelsVisible(true); //设置 barRenderer3D.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE1,TextAnchor.CENTER)); barRenderer3D.setBaseItemLabelFont(new Font("宋体",Font.BOLD,15)); //使用chartFrame对象显示图像 ChartFrame frame = new ChartFrame("测试分数统计", chart); frame.setVisible(true); frame.pack(); } }
核心代码三:测试成绩以及询问是否进行下一轮测试
import java.awt.event.*; import java.awt.*; import java.io.File; import java.io.FileWriter; import java.io.IOException; import javax.swing.*; /* * @auther:zhangkang * @time:2018.03.27 * function:Continue to test */ public class ContinuTest extends JFrame implements ActionListener{ JFrame jf; JPanel jp; JButton jb1,jb2,jb3; JLabel jlb1=null,jlb2=null,jlb3=null; JPanel jp1,jp2=null; DTimeFrame df2=new DTimeFrame(); Thread thread1=new Thread(df2); public ContinuTest(int sum) { String s=sum+""; jf = new JFrame(); jp = new JPanel(); jlb2=new JLabel("您本次测试成绩为:"); if(sum>60&&sum<=100){ jlb3=new JLabel(s+"分 "+"你真的太棒啦!"); } else{ jlb3=new JLabel(s+"分 "+"还要继续努力哦!"); } jlb1 = new JLabel("要不要再测试一次呢?"); jb1 = new JButton("当然要"); jb2 = new JButton("不要啦"); jb3=new JButton("查看测试结果"); jp1=new JPanel(); jp2=new JPanel(); jp1.add(jlb2); jp1.add(jlb3); jp1.add(jlb1); jp2.add(jb1); jp2.add(jb2); jp2.add(jb3); this.add(jp1); this.add(jp2); this.add(jp); jp1.setBounds(40,20,200,80); jp2.setBounds(40,100,200,100); jb1.addActionListener(this); jb2.addActionListener(this); jb3.addActionListener(this); this.setVisible(true); this.setResizable(false); this.setTitle("小学生四则运算"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setBounds(500, 200, 300, 220); } public void actionPerformed(ActionEvent e) { if (e.getActionCommand() == "当然要") { new UI(); this.dispose(); df2.setVisible(true); thread1.start(); } else if (e.getActionCommand() == "不要啦") { File f = new File("score.txt"); // 输入要删除的文件位置 if(f.exists()) f.delete(); df2.setVisible(false); thread1.stop(); this.dispose(); }else if(e.getActionCommand() == "查看测试结果"){ PrintChart pc=new PrintChart(); //读文件 ReadFile file = new ReadFile("score.txt"); String line = null; int[] score=new int[500]; int titleNum=0; while ((line = file.ReadLine()) != null) { titleNum++; score[titleNum]=Integer.parseInt(line); } pc.print(score,titleNum); file.close(); } } }
四、程序运行:程序运行时每个功能界面截图。
功能一:登录该系统界面
功能二:实现小学生四则运算(整数以及带括号题目)随机出题,点击开始答题按钮显示题目。
功能三:实现小学生四则运算答案生成以及成绩计算与显示
功能四:实现成绩测试柱状图
功能五:实现测试自动计时
功能六:实现询问是否进行下一轮测试
五、描述结对的过程,提供两人在讨论、细化和编程时的结对照片(非摆拍)。
六、结对作业的PSP。
PSP2.1 | 任务内容 | 计划共完成需要的时间(min) | 实际完成需要的时间(min) |
Planning | 计划 | 20 | 15 |
Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 20 | 15 |
Development | 开发 | 470 | 500 |
Analysis | 需求分析 (包括学习新技术) | 10 | 10 |
Design Spec |
生成设计文档 |
15 | 20 |
Design Review | 设计复审 (和同事审核设计文档) | 5 | 10 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
Design | 具体设计 | 360 | 365 |
Coding | 具体编码 | 10 | 10 |
Code Review | 代码复审 | 20 | 25 |
Test | 测试(自我测试,修改代码,提交修改) | 30 | 30 |
Reporting | 报告 | 180 | 185 |
Test Report | 测试报告 | 10 | 10 |
Size Measurement | 计算工作量 | 20 | 20 |
Postmortem & Process Improvement Plan | 事后总结 ,并提出过程改进计划 | 150 | 155 |
七、请给你的小伙伴一些点评
在合作的过程中是非常愉快的,她比较细心,学习能力非常强,喜欢追求完美,遇到难题的时候她总是可以想到解决的方法。当然在合作的工程中总会出现交流的问题,她是比较擅长交流的,在交流的工程中无形加强了我们合作解决问题的能力。同时非常感谢她在这个过程中对于我的帮助。
八、结对编程真的能够带来1+1>2的效果吗?通过这次结对编程,请谈谈你的感受和体会。
在这次结对编程中,使我感到1+1>2的效果,两个人在同时想解决一个问题方法的时候,就会出现当一个人想到一个方法时,同时也会激发另一个人的想法。这就会让我们有更多解决这个问题的方法。同时这次实验使我明白了合作非常的重要,只有合作才会共赢。