一、项目源码
GitHub的链接地址:https://github.com/13993013291/Shiyan3.git
二、项目报告
1、需求分析
(1)程序能够从题库随机选择20道混合运算,用户输入答案,程序检查答案是否正确,每道题正确计5分,测试结束后给出总分;
(2)题库文件生成采用实验二的方式自动生成,也可以手工编辑生成,文本格式如下:
(3)程序提供三种练习功能选择:百以内整数算式(必做)、带括号算式、真分数算式练习;
(4)程序允许进行多轮测试,并用柱状图显示多轮测试分数;示例如下:
(5)程序记录用户答题结果,当程序退出再启动的时候,可为用户显示最后一次测试的结果,并询问用户可否进行新一轮的测试;
(6)测试有计时功能,测试时动态显示用户开始答题后的消耗时间;
(7)程序人机交互界面是GUI界面(WEB页面、APP页面都可),界面支持中文简体(必做)/中文繁体/英语,用户可以进行语种选择。
2、软件设计
程序设计类图如下:
3、程序核心代码
public static void One() throws IOException { hehe=9; for (int i = 0; realCount < number; i++) {// 当已产生的题目个数<共需要的题目个数 if (realCount == 0) {// 题目数=0时 One[0][0] = new Random().nextInt(range);// 产生第一个元素 twoPlus(remainmember);// 执行后,产生一个运算符和一个元素 used[realCount]=(remainmember*2-1); realCount++;// 题目数+1 File file = new File("Exercises.txt"); FileWriter fw = new FileWriter(file, true); PrintWriter pw = new PrintWriter(fw); pw.print( realCount + "." + One[realCount - 1][0] + (char) One[realCount - 1][1] + One[realCount - 1][2]); pw.println(); pw.close(); } else { temp[0] = new Random().nextInt(range); tempPlus(remainmember);// 用数组temp[]存放一个"待查重的题目" if (!compare2()) { One[realCount][0] = temp[0];// 将temp[]里的题目放入“已查重数组 One[]” twoWithTemp(remainmember);// 将temp[]里的题目放入“已查重数组 One[]” used[realCount]=(remainmember*2-1);//2-3 3-5 4-7 5-9 realCount++;// 题目个数+1 File file = new File("Exercises.txt"); FileWriter fw = new FileWriter(file, true); PrintWriter pw = new PrintWriter(fw); pw.print(realCount + "." + One[realCount - 1][0] + (char) One[realCount - 1][1] + One[realCount - 1][2]); pw.println(); pw.close(); } } if (i == 2) { remainmember++; oneMore(number - realCount); } } File file = new File("Exercises.txt"); readFile(file); } // 产生多个运算符的题目 public static void oneMore(int remainNumber) throws IOException { int index = 1; if (realCount == number) return; else { count = 0; for (int i = 0; count < remainNumber; i++) { if (i == 0) { One[realCount][0] = new Random().nextInt(range); twoPlus(remainmember); count++; used[realCount]=(remainmember*2-1); realCount++; File file = new File("Exercises.txt"); FileWriter fw = new FileWriter(file, true); PrintWriter pw = new PrintWriter(fw); pw.print(realCount + "." + One[realCount - 1][0]); for (int i3 = 0; i3 < remainmember - 1; i3++) { pw.print((char) One[realCount - 1][index]); pw.print(One[realCount - 1][index + 1]); index += 2; } pw.println(); pw.close(); index = 1; } else { temp[0] = new Random().nextInt(range); tempPlus(remainmember); if (!compare2()) { One[realCount][0] = temp[0]; twoWithTemp(remainmember); count++; used[realCount]=(remainmember*2-1); realCount++; File file = new File("Exercises.txt"); FileWriter fw = new FileWriter(file, true); PrintWriter pw = new PrintWriter(fw); pw.print(realCount + "." + One[realCount - 1][0]); for (int i3 = 0; i3 < remainmember - 1; i3++) { pw.print((char) One[realCount - 1][index]); pw.print(One[realCount - 1][index + 1]); index += 2; } pw.println(); pw.close(); index = 1; } } if (i == 3) { remainmember++; oneMore(number - realCount); break; } } } }
public static void myGUI() throws IOException{ //计时器代码 class shishi3 extends Thread { private long noww = 0l; private long start = System.currentTimeMillis();// 程序启动时间的毫秒值 private long time; public void run() { int i=0; while (true) { noww = System.currentTimeMillis();// 获取一秒之后的毫秒值 time=noww-start; timetime=time; String ssss=String.format("%02d:%02d:%02d\n", time / (1000 * 60 * 60) % 60/* 时 */, time / (1000 * 60)% 60/* 分 */, (time / 1000 % 60)/* 秒 */); l1.setText(ssss); i++; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.*; import java.util.ArrayList; import java.util.Random; import javax.swing.*; public class zhuzhuangtu extends JFrame { private static final int DEFAULT_WIDTH=500; private static final int DEFAULT_HEIGHT=600; int[] save = new int[4]; public zhuzhuangtu() { setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("小学生四则运算系统"); setLocation(500,100); setVisible(true); } public void paint(Graphics g) { File file = new File("tongji.txt"); StringBuilder result = new StringBuilder(); try { BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 String s = new String(); do {//使用readLine方法,一次读一行 for(int i=0;i<4;i++) { s = br.readLine() ; save[i] = Integer.parseInt(s); System.out.println(save[i]); } }while((s = br.readLine())!=null); br.close(); }catch(Exception e){ e.printStackTrace(); } int Width = 400; int Height = 450; Random ran = new Random(); int leftMargin = 15;//柱形图左边界 int topMargin = 50;//柱形图上边界 Graphics2D g2 = (Graphics2D) g; g2.translate(50, 100); int ruler = Height-topMargin-5; int rulerStep = ruler/10;//将当前的高度评分为10个单位 g2.setColor(Color.WHITE);//绘制白色背景 g2.fillRect(0, 0, Width, Height);//绘制矩形图 g2.setColor(Color.LIGHT_GRAY); for(int i=0;i<=10;i++){//绘制灰色横线和百分比 g2.drawString((100-10*i)+"", 10, topMargin+rulerStep*i);//写下百分比 g2.drawLine(10, topMargin+rulerStep*i, Width, topMargin+rulerStep*i);//绘制灰色横线 } g2.setColor(Color.PINK); for(int i=0;i<4;i++){//绘制柱形图 int value =save[i]*4*5;// ran.nextInt(Height-topMargin-10)+10;//随机产生柱形的百分比 int step = (i+1)*35;//设置每隔柱形图的水平间隔为40 //绘制矩形 g2.fillRoundRect(leftMargin+step*2, Height-value-10, 40, value, 40, 10); //g2.fillRoundRect(leftMargin+step*2, Height-value, 40, value, 40, 10); //列出产品的编号 g2.drawString("测试"+(i+1), leftMargin+step*2, Height-value-15); } JPanel south = new JPanel(); JButton btn2 = new JButton("结束"); south.add(btn2); add(south,BorderLayout.SOUTH); btn2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { System.exit(0); } }); } }
4、运行结果展示
4.1 输入题目数与运算表达式的数字范围:
4.2 开始答题:
4.3 当一轮结束后,按“结束”按钮,系统给出答对的题数与答错的题数,并给出用时:
4.4 当一轮结束后有相应的柱状图:
4.5 完成四轮测试之后的结果分析统计图:
5、结对编程伙伴
6、PSP展示
PSP2.1 | 任务内容 | 计划完成的时间(min) | 实际完成需要的时间(min) |
---|---|---|---|
PLanning | 计划 | 60 | 90 |
Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 60 | 65 |
Developmet | 开发 | 480 | 600 |
Analysis | 需求分析(包括学习新技术) | 20 | 30 |
Design Spec | 生成设计文档 | 20 | 30 |
Design Revie | 设计复审(和同事审核设计文档) | 30 | 30 |
Coding Standard | 代码规范 | 20 | 30 |
Design | 具体设计 | 60 | 80 |
Coding | 具体编码 | 300 | 400 |
Code Review | 代码复审 | 30 | 50 |
Test | 测试(自我测试,修改代码,提交修改) | 20 | 40 |
Reporting | 报告 | 30 | 40 |
Test Report | 测试报告 | 20 | 30 |
Size Measurement | 计算工作量 | 5 | 10 |
Postmortem & Process Improvement Plan | 事后总结,并提出过程改机计划 | 30 | 35 |
7、小结
本次实验采用全新的编程模式——结对编程,我们一起对老师的要求进行分析,因为我们两个人的编程能力都不太好,所以我们打算对一些非必做项目舍弃。我们花了很长时间探讨和分析项目,在编程过程中由于基础不扎实,遇到了很多困难,代码也不规范。在结对编程过程中,我们感觉都不错,在学习上的交流比较多,坐在电脑旁交流就是有关项目的,不会说其他的话。因为我的partner想法比较多,所以两人遇到分支的比较多,我们会一起商量解决。这次我们相互补短,基本完成了对于我两来说有些困难的项目,换做一个人,我们两无法单独完成。因此,结对编程带来的不仅仅是1+1>2的效果,它能让我们写出质量更高的代码。每个人都有各自的编程风格,写代码时也有各自的一些小技巧,因此结对编程也是一个相互学习、相互补短的过程。