任务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 | 估计这个任务需要多少时间,并规划大致工作步骤 | ||
Development | 开发 | 470 | 500 |
Analysis | 需求分析 (包括学习新技术) | 10 | |
Design Spec | 生成设计文档 | ||
Design Review | 设计复审 (和同事审核设计文档) | 5 | |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | |
Design | 具体设计 | 360 | 365 |
Coding | 具体编码 | ||
Code Review | 代码复审 | 25 | |
Test | 测试(自我测试,修改代码,提交修改) | ||
Reporting | 报告 | 180 | 185 |
Test Report | 测试报告 | ||
Size Measurement | 计算工作量 | ||
Postmortem & Process Improvement Plan | 事后总结 ,并提出过程改进计划 | 150 | 155 |
七、请给你的小伙伴一些点评
在合作的过程中是非常愉快的,她比较细心,学习能力非常强,喜欢追求完美,遇到难题的时候她总是可以想到解决的方法。当然在合作的工程中总会出现交流的问题,她是比较擅长交流的,在交流的工程中无形加强了我们合作解决问题的能力。同时非常感谢她在这个过程中对于我的帮助。
八、结对编程真的能够带来1+1>2的效果吗?通过这次结对编程,请谈谈你的感受和体会。
在这次结对编程中,使我感到1+1>2的效果,两个人在同时想解决一个问题方法的时候,就会出现当一个人想到一个方法时,同时也会激发另一个人的想法。这就会让我们有更多解决这个问题的方法。同时这次实验使我明白了合作非常的重要,只有合作才会共赢。