结对编程作业1

项目成员:邱文鑫 201421123043 + 念其锋 201421123045

码市地址:https://git.coding.net/qwx_hh/java-szys.git

一、需求分析

      随着课余娱乐项目的增加,现在的小孩子在学习上变得越来越不自觉,需要老师、家长在背后催着才会做作业,因此需要实现一个计时功能,以时间的流逝来给孩子一些紧迫感。另外,在经过长期的运算训练之后,如何才知道学生的运算水平是否有显著提高呢?将做题过程进行计时可以解决这个问题,从花费时间的长短就可以看出是否取得进步。同时,老师、家长也可以利用计时功能设立奖励机制。例如,规定在二十秒内完成十道题目的学生可以得到一个大大的奖励,激励学生一次又一次地挑战这个时间。

      为了让这个四则运算自动生成器的使用人群跨越国界,就需要我们实现语言切换功能。不仅让中国大陆的小孩可以简单上手这个小程序,同时还能让中国台湾以及外国的小孩同样可以使用。实现这样一个小小的功能,就可以让我们这个自动生成器的受众面遍布世界各地,不受语言的障碍,何乐而不为呢?

      大多数的时候我们都不能要求这些小孩子在一个时间段内持续不断地做计算题,而是让他们分次来完成。举个例子,当老师布置小孩子一周之内要完成200道的四则运算,并记录做对多少题,做错多少题时,绝大部分学生肯定会选择一天做几次,一次做几题,极少同学会选择一次性把这200道题做完。这样子就存在一个问题,如果分次做的话那每一次做对多少题做错多少题都要登记下来吗?这也太麻烦了。因此就需要我们能够记录用户做题的总数,即使在用户退出又再次启动时,可以做到把以前的对错数量保存并在此基础上进行增量计算。

二、程序设计

(1)、基础功能

         1、有计时功能,能显示用户开始答题后的消耗时间;

         2、界面支持中文简体/中文繁体/英语,用户可以选择一种;

(2)、扩展功能

           3、记录用户的对错总数,程序退出再启动的时候,能把以前的对错数量保存并在此基础上增量计算;

        4、对用户输入题数的内容设置了容错功能,只可以输入1~10之间的数字,输入字母或者不在范围内的数字将无法点击确定按钮;

(3)、高级功能

           5、实现了错题复习功能,可以将用户使用以来做错的题目保存在文档中,点击“复习”按钮,生成的题目将全部是之前用户做错的题目,达到用户复习的目的。

(4)、思维导图

                              

(4)、团队合作

             

我们之前就约定好的代码规范:

 1 Arithmetic类
 2 astr            返回答案字符串
 3 qstr            返回问题字符串
 4 int_operation()        整数计算函数
 5 fra_operation()        分数计算函数
 6 common_divisor(int m,int n)
 7 公约数计算函数
 8 toString()        输出函数
 9 Frame类
10 hs            实例化History
11 hh            实例化QA_List
12 timer            实例化Work_Time
13 Time            计时器动态窗口
14 answer1~10        输入窗口
15 Review            复习按钮
16 question1~10        题目显示标签
17 Right_answer1~10    正确答案显示标签
18 Tip1~10         提示正确与否标签
19 Time_cost         所花时间显示标签
20 Right_percent        正确率显示标签
21 Set_question         开始按钮
22 jLabel5            历史正确题数
23 jLabel7            历史总题数
24 rn            单次正确题数
25 tot            单次总题数
26 Frame()            Frame构造函数
27 initComponents()    窗体显示
28 xxxClicked(KeyEvent evt)    
29 点击事件
30 KeyPressed(JLabel i,JLabel j,JLabel l,int x,JTextField k)
31 点击事件批量处理函数
32 Hide()            使不需要的输入窗口关闭
33 Tip(String answer,int i)提示对错并计入
34 Histroy类
35 qstr            问题字符串
36 astr            答案字符串
37 str            答案+问题字符串(写入文件)
38 str2            正确题数+总题数字符串(写入文件)
39 tot            总题数
40 rn            正确题数
41 qstrlist        问题字符串列(读入文件)
42 astrlist        答案字符串列(读入文件)
43 scan(String qstr,String astr)
44 qstr+" "+astr
45 scan2(int tot,int rn)
46 tot+" "+rn
47 Histroy_create()    历史文档生成
48 Histroy_save()        存储历史题目与答案
49 Histroy_saveNum()    存储历史题目数目
50 Histroy_read()        读入历史题目与答案
51 History_num()        读入历史题目数目
52 QA_List类
53 i            加入列题目个数
54 Qusetion        问题字符串列
55 Answer            答案字符串列
56 QA_List()        QA_List构造函数
57 Test_Number类
58 i            显示Test_Number窗体次数
59 l            语言转化参数标识
60 Cancel_Button        取消按钮
61 Sure_Button        确定按钮
62 English            英文界面标签
63 Simplified_Chinese    简体中文界面标签
64 Traditional_Chinese    繁体中文界面标签
65 Number            所需题数
66 Test_Number()        Test_Number构造函数
67 initComponents()    Test_Number窗体显示
68 xxxClicked(KeyEvent evt)    
69 点击事件
70 Test类
71 main(String[] args)    
72 Work_Time类
73 x            00:00.x
74 y            00:y.00
75 z            z:00.00

 

(5)、psp表格

PSP2.1

Personal Software Process Stages

Time (m) Senior Student

Time (m)

Planning

计划

4

6

· Estimate

估计这个任务需要多少时间

4

6

Development

开发

70

82

· Analysis

需求分析 (包括学习新技术)

6

6

· Design Spec

生成设计文档

5

6

· Design Review

设计复审

4

6

· Coding Standard

代码规范

3

3

· Design

具体设计

5

6

· Coding

具体编码

35

50

· Code Review

代码复审

5

5

· Test

测试(自我测试,修改代码,提交修改)

7

5

Reporting

报告

10

14

·

测试报告

5

5

·

计算工作量

2

5

·

并提出过程改进计划

3

3

三、代码展示

(1)、计时功能

Work_Time类:

 

 1 package szys;
 2 import java.util.TimerTask;
 3 import javax.swing.JTextField;
 4 public class Work_Time extends TimerTask{
 5     static int y=0;
 6     static int z=0;
 7     @Override
 8     public void run() {
 9         // TODO Auto-generated method stub
10         String str_second = Frame.Time.getText().substring(6);
11         int x = Integer.parseInt(str_second);
12         if(Frame.Time.getText().equals("00:00.00")){
13             x=0;y=0;z=0;
14         }
15         x++;
16         if(z<10){
17             if(y<10)
18             {
19                 if(x<100)
20                     Frame.Time.setText("0"+z+":0"+y+"."+x);
21                 if(x==100)
22                 {
23                     y++;
24                     Frame.Time.setText("0"+z+":0"+y+".0");
25                     x=0;
26                     
27                 }
28             }
29             if(y<60&&y>=10)
30             {
31                 if(x<100)
32                     Frame.Time.setText("0"+z+":"+y+"."+x);
33                 if(x==100)
34                 {
35                     y++;
36                     Frame.Time.setText("0"+z+":"+y+".0");
37                     x=0;
38                     
39                 }
40             }
41             if(y==60){
42                 y=0;
43                 x=0;
44                 z++;
45             }
46         }
47         if(z<60&&z>=10){
48             if(y<10)
49             {
50                 if(x<100)
51                     Frame.Time.setText(z+":0"+y+"."+x);
52                 if(x==100)
53                 {
54                     y++;
55                     Frame.Time.setText(z+":0"+y+".0");
56                     x=0;
57                     
58                 }
59             }
60             if(y<60&&y>=10)
61             {
62                 if(x<100)
63                     Frame.Time.setText(z+":"+y+"."+x);
64                 if(x==100)
65                 {
66                     y++;
67                     Frame.Time.setText(z+":"+y+".0");
68                     x=0;
69                     
70                 }
71             }
72             if(y==60){
73                 y=0;
74                 x=0;
75                 z++;
76             }
77             else
78             {
79                 Frame.Time.setText("都一小时了放弃吧");
80             }
81         }
82     }
83     
84 }

在Frame类中的调用:

 Time.setText("00:00.00");
        timer.schedule(new Work_Time(), 10, 10);

(2)、语言切换功能

Test_Number类中:

 1  private void Simplified_ChineseMouseClicked(java.awt.event.MouseEvent evt) {                                                
 2         jLabel6.setText("语言:");
 3         jLabel1.setText("所需习题数:");
 4         jLabel2.setText("(1-10之内)");
 5         Cancel_Button.setText("取消");
 6         Sure_Button.setText("确定");
 7         l=0;
 8     }                                               
 9     private void Traditional_ChineseMouseClicked(java.awt.event.MouseEvent evt) {                                                 
10         jLabel6.setText("語言:");
11         jLabel1.setText("所需習題數:");
12         jLabel2.setText("(1-10之內)");
13         Cancel_Button.setText("取消");
14         Sure_Button.setText("確定");
15         l=1;
16     }                                                
17     private void EnglishMouseClicked(java.awt.event.MouseEvent evt) {                                     
18         jLabel6.setText("Language:");
19         jLabel1.setText("How many questions:");
20         jLabel2.setText("(1-10)");
21         Cancel_Button.setText("Cancel");
22         Sure_Button.setText("OK");
23         l=2;
24     }                                    

 在Frame类中:

 1 if(Test_Number.l==1){
 2             Set_qusetion.setText("開始");
 3             jLabel2.setText("計時:");
 4             jLabel1.setText("正確率:");
 5             jLabel3.setText("用時:");
 6             Review.setText("複習");
 7             jLabel4.setText("正確:");
 8             jLabel6.setText("全部:");
 9         }
10         if(Test_Number.l==2){
11             Set_qusetion.setText("Start");
12             jLabel2.setText("Timing:");
13             jLabel1.setText("Correct rate:");
14             jLabel3.setText("Time cost:");
15             Review.setText("Review");
16             jLabel4.setText("Right:");
17             jLabel6.setText("All:");
18         }

(3)、储存&读取功能、错题复习

  1 import java.io.File;
  2 import java.io.FileNotFoundException;
  3 import java.io.FileWriter;
  4 import java.io.IOException;
  5 import java.util.ArrayList;
  6 import java.util.List;
  7 import java.util.Scanner;
  8 public class Histroy {
  9     String qstr;
 10     String astr;
 11     String str;
 12     String str2="0 0";
 13     double tot=0;
 14     double rn=0;
 15     public List<String> qstrlist = new ArrayList<String>();
 16     public List<String> astrlist = new ArrayList<String>();
 17     public void scan(String qstr,String astr){
 18         str=(astr+" "+qstr);
 19     }
 20     public void scan2(int tot,int rn){
 21         str2=(tot+" "+rn);
 22     }
 23     public void Histroy_create(){
 24         String path = "d:\\Myapp";
 25         File f = new File(path);
 26         if(!f.exists()){
 27             f.mkdirs();
 28             String fileName="histroy.txt";
 29             File file = new File(f,fileName);
 30             if(!file.exists()){
 31                 try {
 32                 file.createNewFile();
 33                 } catch (IOException e) {
 34                 // TODO Auto-generated catch block
 35                 e.printStackTrace();
 36                 }
 37                 
 38             }
 39             f.mkdirs();
 40             String fileName2="histroy_num.txt";
 41             File file2 = new File(f,fileName2);
 42             if(!file2.exists()){
 43                 try {
 44                 file2.createNewFile();
 45                 } catch (IOException e) {
 46                 // TODO Auto-generated catch block
 47                 e.printStackTrace();
 48                 }
 49                 
 50             }
 51             Histroy_saveNum();
 52         }
 53         
 54     }
 55     public void Histroy_save(){
 56          FileWriter writer;
 57          String fileName = ("d:\\Myapp\\histroy.txt");
 58         try {
 59             writer = new FileWriter(fileName, true);
 60             writer.write(str);
 61             writer.write("\r\n");
 62             writer.close();
 63         } catch (IOException e) {
 64             // TODO Auto-generated catch block
 65             e.printStackTrace();
 66         }
 67         
 68     }
 69     public void Histroy_saveNum(){
 70         FileWriter writer2;
 71         String fileName2 = ("d:\\Myapp\\histroy_num.txt");
 72         try {
 73             writer2 = new FileWriter(fileName2, true);
 74             writer2.write(str2);
 75             writer2.write("\r\n");
 76             writer2.close();
 77         } catch (IOException e) {
 78             // TODO Auto-generated catch block
 79             e.printStackTrace();
 80         }
 81     }
 82     public void Histroy_read()  throws FileNotFoundException{
 83         Scanner in = new Scanner(new File("d:\\Myapp\\histroy.txt"));//为历史信息.tit这个File创建一个扫描器in
 84         while(in.hasNextLine()){
 85             String line = in.nextLine();//读出历史信息.txt的下一行
 86             Scanner lineScanner = new Scanner(line);//为每一行建立一个扫描器
 87             lineScanner.useDelimiter(" ");//使用空格作为分隔符
 88             qstr = lineScanner.next();//问题
 89             astr = lineScanner.next();//答案
 90             qstrlist.add(qstr);
 91             astrlist.add(astr);
 92         }
 93         in.close();
 94     }
 95     public void History_num() throws FileNotFoundException{
 96         Scanner in = new Scanner(new File("d:\\Myapp\\histroy_num.txt"));
 97         while(in.hasNextLine()){
 98             String line = in.nextLine();
 99             Scanner lineScanner = new Scanner(line);
100             lineScanner.useDelimiter(" ");
101             tot = Integer.parseInt(lineScanner.next());
102             rn = Integer.parseInt(lineScanner.next());
103         }
104         in.close();
105     }
106 }

四、程序运行

程序开始界面,此时是中文简体状态:

当鼠标单击标签时,切换成中文繁体或英文状态:

英语状态下的运行界面:

繁体状态下的错题复习:

错题保存在指定路径的文档中:

保存用户做的总题数和正确题数:

五、小结

      这是我们第一次使用结对编程的合作模式,在我们一直以来的认知里,两个人一起做一个项目,就应该是一个人负责实现这几种功能,另一个人负责实现另外几种功能,最后再将这些功能合并到一起,就形成我们俩一起合作完成的项目。因此在我们做这次作业的前四天里,我们都是以这种思维来做的,直到老师们周一的时候又再次跟我们强调了《构建之法》4.5节里对结对编程的定义,结对编程应该是类似于驾驶员和领航员的关系,这才让我意识到原来老师的初衷是想让两个人同时坐在同一台电脑前,一个人敲代码另一个帮忙复审和提建议,一段时间后再对调角色。我们真正开始结对编程是在周一中午,虽然只有短短一天半的时间,却让我感受到了许多不一样的感觉,具体有以下几点:

1、当我作为“领航员”的时候,我就坐在我队友的旁边看着他敲代码(我们俩就是上下铺,电脑桌也就在隔壁,所以异常方便),他经常嘴上念的是正确的代码,敲上去的时候却敲成另外一种名称的代码,还好我就盯着他敲,及时指出了这个低级错误,不然他一个人的话可能要浪费很多时间才能找出这个问题;

2、当我们在结对编程的时候,只要对方遇到问题,都不用解释问题的前因后果,我们就能一下子知道对方指的是什么,这就是结对编程给双方带来的对互相编程思路的熟悉度,这也是以前那种各做各的的模式所体验不到的感觉;

3、由于我们之前不知道两个人都要互相上传代码到git上面,所以最开始都是由一个人上传全部的代码,今天意识到这个问题后才开始亡羊补牢,各自都上传了一些自己敲的代码,可能跟老师的初衷还有点出入,还请老师见谅;

4、我们两个人在结对编程的时候,还是遇到了一些我们俩都无法解决的问题,不过这种感觉跟自己一个人遇到难题时的感觉完全不一样,竟然有一种“完全不虚,我们迟早会解决”的蜜汁自信,可能这就是两个人的力量与一个人力量的差别;

5、在实现用户输入题目数后开始计时的功能的时候,我们的程序出现了一个“延迟”的问题。例如,我第一次输入的题数是5,第二次是10,第三次是8,结果我在第二次输入10之后它只显示了5题,而在我第三次输入8题的时候它却显示了第二次的10题。这个问题让我们想了很久都没有想出来,后来把代码给学霸看完之后才发现可能是循环嵌套的问题,这让我明白了有时候当局者迷旁观者清,当自己费尽千辛万苦都找不到的问题时,可以让同学帮忙看一下,很有可能一下子就找到问题所在。

posted @ 2017-03-14 23:49  NianQiFeng  阅读(466)  评论(2编辑  收藏  举报