201571030130/201571030124《小学生四则运算练习软件》结对项目报

Github的仓库主页链接地址:https://github.com/Opalus-wangs/Pair-Programming

一、需求分析

   (1)由计算机从题库文件中随机选择20道加减乘除混合算式,用户输入算式答案,程序检查答案是否正确,每道题正确计5分,错误不计分,20道题测试结束后给出测试总分;     (2)题库文件可采用实验二的方式自动生成,也可以手工编辑生成,文本格式如下图:

     

  (3)程序为用户提供三种进阶四则运算练习功能选择:百以内整数算式、带括号算式、真分数算式练习;

  (4)程序允许用户进行多轮测试,提供用户多轮测试分数柱状图,如下图所示;

                

  (5)程序记录用户答题结果,当程序退出再启动的时候,可为用户显示最后一次测试的结果,并询问用户可否进行新一轮的测试;

  (6)测试有计时功能,测试时动态显示用户开始答题后的消耗时间;

  (7)程序人机交互界面是GUI界面(WEB页面、APP页面都可),界面支持中文简体/中文繁体/英语,用户可以进行语种选择。

 

二、软件功能设计及实现

  a、流程图

                                              

  b、类图

   

三、程序运行截图

  a、主界面:可以选择简单算式运算和复杂(带括号)算式运算,也可以查看所有答题学生的得分情况

        

  b、学生信息界面:输入学生编号及姓名

         

  c、答题界面:界面显示学生姓名及学号,学生在此界面进行答题(根据此前选择的算式的难易程度出题),点击“开始计时”按钮,进行计时功能,学生输入算式答案,答题完毕点击“确定提交”按钮提交答案。

         

  d、得分及柱状图界面:该界面显示答题学生成绩以及错误题号,点击“继续”按钮可以进行多轮测试

          

         

      点击“查看”按钮可以查看所有答题学生的信息以及分数

        

 四、关键代码

  a、答题界面的算式获取方法及监听

  1       //文件路径
  2       File file = new File("F:\小学生四则运算\小学生四则运算\Text.txt");//Text文件
  3       BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件
  4       String s = null;
  5       while((s = br.readLine())!=null)
  6       {
  7           READ[i]=s;
  8           i++;
  9       }
 10         br.close();;
 11         /*String s1 =READ[1].toString();
 12         name1.setText(s1);*/
 13          try {
 14                  
 15                 name1.setText(READ[0].toString()+"=");
 16                 name2.setText(READ[1].toString()+"=");
 17                 name3.setText(READ[2].toString()+"=");
 18                 name4.setText(READ[3].toString()+"=");
 19                 name5.setText(READ[4].toString()+"=");
 20                 name6.setText(READ[5].toString()+"=");
 21                 name7.setText(READ[6].toString()+"=");
 22                 name8.setText(READ[7].toString()+"=");
 23                 name9.setText(READ[8].toString()+"=");
 24                 name10.setText(READ[9].toString()+"=");    
 25                 name111.setText(READ[10].toString()+"=");
 26                 name12.setText(READ[11].toString()+"=");
 27                 name13.setText(READ[12].toString()+"=");
 28                 name14.setText(READ[13].toString()+"=");
 29                 name15.setText(READ[14].toString()+"=");
 30                 name16.setText(READ[15].toString()+"=");
 31                 name17.setText(READ[16].toString()+"=");
 32                 name18.setText(READ[17].toString()+"=");
 33                 name19.setText(READ[18].toString()+"=");
 34                 name20.setText(READ[19].toString()+"=");     
 35          } catch(NullPointerException e) {
 36                System.out.println("读入文件有错!");
 37                
 38             }
 39     
 40          button1.addActionListener(new ActionListener()
 41             {
 42             public void actionPerformed(ActionEvent event)
 43             {
 44                 
 45                 final time time=new time();
 46                 new Thread(new Runnable(){
 47                      @Override
 48                      public void run() {
 49                          try {
 50                              for(int i=0;i<1000;i++) {
 51                                  Time.setText(String.format(time.a, i));
 52                                  Thread.sleep(1000);    
 53                              }
 54                          } catch (InterruptedException e) {
 55                              e.printStackTrace();
 56                          }
 57                      }
 58                  }).start();
 59                 //记录开始测试的时间
 60             }
 61          });
 62             
 63         
 64          
 65       btn.addActionListener(new ActionListener()
 66         {
 67           String [] S =new String[20];
 68 
 69         public void actionPerformed(ActionEvent event)
 70         {
 71             try
 72             {
 73                     S[0] = na1.getText();//得到答案
 74                     S[1] = na2.getText();
 75                     S[2] = na3.getText();
 76                     S[3] = na4.getText();
 77                     S[4] = na5.getText();
 78                     S[5] = na6.getText();
 79                     S[6] = na7.getText();
 80                     S[7] = na8.getText();
 81                     S[8] = na9.getText();
 82                     S[9]= na10.getText();
 83                     S[10] =na111.getText();
 84                     S[11] =na12.getText();
 85                     S[12]= na13.getText();
 86                     S[13] = na14.getText();
 87                     S[14] = na15.getText();
 88                     S[15] = na16.getText();
 89                     S[16] = na17.getText();
 90                     S[17] = na18.getText();
 91                     S[18] = na19.getText();
 92                     S[19] = na20.getText();
 93                    //判空        
 94                     if(S[0].equals("")||S[1].equals("")||S[2].equals("")||S[3].equals("")||S[4].equals("")||S[5].equals("")||S[6].equals("")||S[7].equals("")||S[8].equals("")||S[9].equals("")
 95                         ||S[10].equals("")||S[11].equals("")||S[12].equals("")||S[13].equals("")||S[14].equals("")||S[15].equals("")||S[16].equals("")||S[17].equals("")||S[18].equals("")||S[19].equals("")    
 96                             
 97                             )
 98                     {
 99                         throw new FormatException1();
100                         
101                     }
102               }
103               catch(FormatException1 a)
104               {
105                  JOptionPane.showMessageDialog(null,"请输入计算结果");
106               }
107          
108             
109              //将算式的计算结果保存到数组k1[]
110              for(int k=0;k<20;k++)
111              {
112                 k1[k]=calculate.arithmetic(READ[k]);
113              }
114              win.setVisible(false);
115                 
116             for(int t=0;t<20;t++)
117             {
118                 //记录错误题数以及错误题号
119                 if(k1[t]!=Integer.parseInt(S[t]))
120                 {                  
121                     kk[count]=t;
122                     count ++;
123                 }        
124             }
125                 
126             Student ug = new Student(name11,number11,kk, count);
127             students.add(ug);
128             
129             final JFrame win = new JFrame("小学生四则运算");
130                final JPanel pan = new JPanel();
131                new SeeFrame(win,pan,name11,number11,kk,count,students);
132                win.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
133                win.setVisible(true);
134                win.setLocationRelativeTo(null);
135            }
136         
137      });

  b、计时器代码

 1 public  class time {
 2     public Timer timer=new Timer();
 3     public boolean is_pause=false;
 4     public timetask mytimetask=new timetask();
 5     public int hh,mm,ss;
 6     String a;    
 7     public time()
 8     {
 9         timer.scheduleAtFixedRate(mytimetask, 0, 1000);    
10     }
11     public class timetask extends TimerTask{
12     public int count_time=0;
13     public String date;
14     @Override
15     public void run() 
16     {
17         if(!is_pause)
18         {
19             count_time++;
20             hh=count_time/3600;
21             mm=(count_time%3600)/60;
22             ss=count_time%60;
23             date=hh+":"+mm+":"+ss;    
24             a=date;    
25         }
26     }
27 }
28 }

  c、成绩柱状图

 1 //绘制柱状图
 2 public class Picture extends JFormattedTextField
 3 {
 4         int [] a=new int[20];
 5         int j=0;
 6         int i=0;
 7         int x=0;
 8         int aa=0;
 9         //绘制柱形统计图
10         private Random ran;
11         public Picture(ArrayList<Student> students)
12         {    
13             super();
14             for(Student e: students )
15              {
16                     a[j]=(e.getw());
17                     j++;    
18              }
19             ran = new Random();
20             setName("绘制柱形图");
21             setBounds(100,85,270,210);
22         }
23         @Override
24         public void paint(Graphics g){
25             int Width = getWidth();
26             int Height = getHeight();
27             int leftMargin = 2;//柱形图左边界
28             int topMargin = 5;//柱形图上边界
29             Graphics2D g2 = (Graphics2D) g;
30             int ruler = Height-topMargin-5;
31             int rulerStep = ruler/10;//将当前的高度评分为10个单位
32             g2.setColor(Color.WHITE);//绘制白色背景
33             g2.fillRect(0, 0, Width, Height);//绘制矩形图
34             g2.setColor(Color.LIGHT_GRAY);
35             for(int i=0;i<=10;i++){//绘制灰色横线和百分比
36                 g2.drawString((100-10*i)+"%", 5, topMargin+rulerStep*i);//写下百分比
37                 g2.drawLine(5, topMargin+rulerStep*i, Width, topMargin+rulerStep*i);//绘制灰色横线
38             }
39             g2.setColor(Color.RED);
40 
41             for(i=0;i<j;i++){//绘制柱形图
42                 int value =(20-a[i])*10+5;
43                 int step = (i+1)*20;//设置每隔柱形图的水平间隔为40
44                 //绘制矩形
45             
46                 g2.fillRoundRect(leftMargin+step*2, Height-value, 20, value, 20, 20);
47                 //列出产品的编号
48                 g2.drawString("C"+(i+1)+"-"+(20-a[i])*5+"%", leftMargin+step*2, Height-value-5);
49             
50             }
51         }        
52 }
53     

五、结对编程过程

                                            

六、PSP

PSP2.1任务内容计划完成的时间(min)实际完成需要的时间(min)
PLanning 计划 60 80
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 60 80
Developmet 开发 450 520
Analysis 需求分析(包括学习新技术) 30 40
Design Spec 生成设计文档 10 20
Design Revie 设计复审(和同事审核设计文档) 30 30
Coding Standard 代码规范 30 30
Design 具体设计 60 60
Coding 具体编码 240 290
Code Review 代码复审 30 30
Test 测试(自我测试,修改代码,提交修改) 20 20
Reporting 报告 40 40
Test Report 测试报告 20 20
Size Measurement 计算工作量 5 5
Postmortem & Process Improvement Plan 事后总结,并提出过程改机计划 15 15

 七、对小伙伴的评价

  这次我的结对项目的partner是我再熟悉不过的人了,这不是我们的第一次合作了,在之前其他的课程学习过程中我们一也一起合作过,所以配合起来也是相当的默契。他是一个动手能力很强的人,而且对于细节特别的执着,我们在完成这个结对项目的过程中有的时候在一些细节上在实验室/图书馆没有完成的部分,回到宿舍后也是会继续的来完成,说到这里,为大家安利一个很好用的软件TeamView,一款可以远程访问的软件,这样我们可以利用在宿舍的时间也一起编程,一起思考,就像是在使用同一台计算机,同一个鼠标,完美的解决了空间上的问题,在项目开始的过程中我们互相表达我们各自的想法,提出一些好的建议,在实现的过程中,难免也有意见不合的情况,但是我们都是通过协商最后达成一致,这是一次非常不错的体验,期待下一次的合作。

八、 结对编程真的能够带来1+1>2的效果吗?通过这次结对编程,请谈谈你的感受和体会。

   答案是肯定的,1+1肯定是大于2的,为什么呢?举个例子来说,当你手握一根筷子的时候你可以很轻松的把它折断,两根筷子的时候也可能很轻松的做到,但是当筷子的数量增加的时候,你就很难再折断它,这也是群体的力量,一个人的编程设计往往会出现很多的问题,比如一些代码上的漏洞和设计功能等考虑的不全面,当两个人甚至是多个人的智慧集中在一起的时候,往往漏洞就会急剧减少,这就是为什么一个强大的项目后面往往有一个优秀的团队。

 

原文地址:https://www.cnblogs.com/Opalus-wangs/p/8679061.html