WordCount
合作者:201631062319,201631062424
代码地址:https://gitee.com/this-hui/WordCount
一、结对的PSP表格
PSP阶段 | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|
计划 |
30 |
60 |
估计这个任务需要多少时间 |
20 |
20 |
开发 |
100 |
150 |
需求分析 |
30 |
30 |
生成设计文档 |
20 |
20 |
设计复审 |
30 |
20 |
代码规范 |
20 |
20 |
具体设计 |
30 |
30 |
具体编码 |
60 |
90 |
代码复审 |
30 |
30 |
测试 |
30 |
40 |
报告 |
20 |
20 |
测试报告 |
20 |
20 |
计算工作量 |
10 |
20 |
事后总结 |
20 |
30 |
合计 |
470 |
600 |
在做项目的时候,我们自己预先估计的时间与实际时间之间还是存在着一些问题,比如在做项目计划
的时候,我们预先估计的是30分钟,没有想到由于两个人之间的分歧,导致我们用了60分钟才完成。
还有就是编程的时间也超过了我们的预期时间。
二、互审代码情况
1.代码复审前
在代码复审前,我们各自确定我们的代码能够在自己的机子上进行编译成功,然后各自对自己的
代码进行了测试,测试完成后,我们便开始了代码复审。
2.复审时
在代码复审时,我们每个人提供了新的代码,查看了双方代码的时间复杂度和空间复杂度。在复
审我的代码的时候,我控制着流程,讲述了修改代码的前因后果,我的合作者逐一提供了反馈意见。
同样,在审查他的代码的时候也是一样。
3.复审结果
我们代码复审的结果就是双方达成了一致的意见,再总结出了一份双方一致同意的程序代码。
三、设计过程
1.确定编程语言及编程工具
我们两人都对java比较熟悉,所以这次我们的程序决定用java语言来写,对于我们来说,eclipse
编程工具是我们最熟悉的,所以我们都选择了这个编程工具。
2.思考创建类的个数
在思考怎么编程的时候,我们考虑了创建5个类,分别是Creat_data类、test类、ToolUtil类、
View类、WordCount类。
3.实现项目功能
程序包含5个类,分别是Creat_data类、test类、ToolUtil类、View类、WordCount类。下面,
我会依次讲述每个类的功能及如何实现的。
四、代码说明
Creat_data类
用于创建文件列表

1 Creat_data 2 import java.io.BufferedReader; 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.InputStreamReader; 7 import java.util.HashSet; 8 import java.util.Set; 9 10 public class Creat_data { 11 12 13 Set<String> all_file =new HashSet<String>();//创建文件列表 14 String Output_file = "result.txt"; 15 String Result ="";//创建结果的字符集 16 boolean F_Characters=false; 17 boolean F_Lines =false; 18 boolean F_wods =false; 19 public boolean F_difine=false; 20 public boolean F_NULL=false; 21 public boolean F_Code=false; 22 23 String result = ""; 24 //创建可以操作的IO流 25 FileInputStream in = null; 26 InputStreamReader isr = null; 27 BufferedReader bis = null; 28 FileOutputStream os = null; 29 public int Count=0; 30 31 32 //关闭IO流 33 public void Close() { 34 35 try { 36 in.close(); 37 isr.close(); 38 bis.close(); 39 } catch (IOException e) { 40 // TODO Auto-generated catch block 41 e.printStackTrace(); 42 } 43 44 } 45 }
WordCount类
用于检查字符数、行数、单词数、代码行、注释行、空行

1 WordCount 2 import java.io.IOException; 3 4 public class WordCuont { 5 //主程序用于判断 6 public static void main(String [] args) { 7 Creat_data data =new Creat_data();//创建的数据类 8 ToolUtil toolUtil = new ToolUtil();//创建的工具类 9 for(int i=0 ;i<args.length;i++) 10 { 11 12 if(args[i].startsWith("-")) { 13 14 switch (args[i]) 15 { 16 case "-c"://检查字符数 17 data.F_Characters=true; 18 break; 19 case "-l"://检查行数 20 data.F_Lines=true; 21 break; 22 case "-w"://检查单词数 23 data.F_wods=true; 24 break; 25 case "-a"://检查代码行,注释行,空行, 26 data.F_difine=true; 27 break; 28 29 case "-o": 30 if(!args[i+1].startsWith("-")) 31 { 32 data.Output_file=args[i+1]; 33 i++; 34 }else { 35 System.out.println("Your intput is illigal!"); 36 System.exit(0); 37 } 38 break; 39 default: 40 System.out.println("Your intput is illigal!"); 41 break; 42 43 } 44 } 45 else data.all_file.add(args[i]); 46 47 48 } 49 //判断然后传入数据 50 if(data.F_Characters) 51 { 52 data.Result+=toolUtil.ReturnChara(data.all_file)+"\r\n"; 53 } 54 if(data.F_Lines) 55 { 56 data.Result+=toolUtil.ReturnLines(data.all_file)+"\r\n"; 57 58 } 59 if(data.F_wods) 60 { 61 data.Result+=toolUtil.ReturnWords(data.all_file)+"\r\n"; 62 } 63 if(data.F_difine) 64 { 65 try { 66 data.Result+=toolUtil.difflineGUI(data.all_file)+"\r\n"; 67 } catch (IOException e) { 68 // TODO Auto-generated catch block 69 e.printStackTrace(); 70 } 71 } 72 73 74 System.out.println(data.Result); 75 toolUtil.OutpuFile(data.Output_file,data.Result); 76 } 77 78 }
ToolUtil类
用于创建检查字符数,行数,单词数,空行,注释行的方法

import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.Set; import java.util.regex.Pattern; public class ToolUtil { //创建检查字符数,行数,单词数,空行,注释行的方法 public String ReturnChara(Set<String> all_file) { // TODO Auto-generated method stub] Creat_data data_R=new Creat_data(); //调用数据类创建数据和IO流 byte [] S_byte=new byte[20*1024]; int len =S_byte.length; int Byetes=0; try { for(String all_file1:all_file) { data_R.in =new FileInputStream(all_file1); while((Byetes = data_R.in .read(S_byte,0,len))!=-1) { data_R.Count+=Byetes; } data_R.result+=all_file1+",字符数:"+data_R.Count+" "; data_R.Count =0; } }catch(FileNotFoundException e) { System.out.println("文件输入错误请检查后重新输入"); System.exit(0); }catch(IOException e) { e.printStackTrace(); }finally { try { data_R.in.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return data_R.result; } public String ReturnLines(Set<String> all_file) { // TODO Auto-generated method stub Creat_data data_L=new Creat_data(); try { for(String all_file1:all_file) { data_L.in=new FileInputStream(all_file1); data_L.isr=new InputStreamReader(data_L.in); data_L.bis=new BufferedReader(data_L.isr); while(data_L.bis.readLine()!=null) { data_L.Count++; } data_L.result+=all_file1+",行数:"+data_L.Count+" "; data_L.Count=0; } }catch(FileNotFoundException e) { System.out.println("文件输入错误请检查后重新输入"); System.exit(0); }catch(IOException e) { e.printStackTrace(); }finally { data_L.Close(); } return data_L.result; } public String ReturnWords(Set<String> all_file) { // TODO Auto-generated method stub Creat_data data_W=new Creat_data(); StringBuffer saveString = new StringBuffer(); String tmp = ""; //缓存字符串 try { for(String all_file1:all_file) { data_W.in=new FileInputStream(all_file1); data_W.isr=new InputStreamReader(data_W.in); data_W.bis=new BufferedReader(data_W.isr); while((tmp=data_W.bis.readLine())!=null) { saveString.append(tmp); } tmp =saveString.toString(); String [] all= tmp.split("[\\s+,\\.\n]"); data_W.Count = all.length; data_W.result+=all_file1+",单词数:"+data_W.Count+" "; } }catch(FileNotFoundException e) { System.out.println("文件输入错误请检查后重新输入"); System.exit(0); }catch(IOException e) { e.printStackTrace(); }finally { data_W.Close(); } return data_W.result; } public boolean OutpuFile(String output_file, String Result) { // TODO Auto-generated method stub File OUtputFile =new File(output_file); FileOutputStream os =null; byte[] b=null; try { if(!OUtputFile.exists()) { OUtputFile.createNewFile(); } os = new FileOutputStream(OUtputFile); b= Result.getBytes(); os.write(b); }catch(IOException e) { e.printStackTrace(); }finally { try { os.close(); }catch(IOException e) { e.printStackTrace(); } } return true; } String difflineGUI(Set<String> all_file) throws IOException { int Sode_Line = 0; int Code_Line = 0; int Null_Line = 0; Creat_data data_n =new Creat_data(); BufferedReader bufr = null; for (String all_files : all_file) { bufr = new BufferedReader(new InputStreamReader(new FileInputStream(all_files))); Pattern nodeLinePattern = Pattern.compile("((//)|(/\\*+)|((^\\s)*\\*)|((^\\s)*\\*+/))+", Pattern.MULTILINE + Pattern.DOTALL); String line = null; while((line = bufr.readLine()) != null) { if (nodeLinePattern.matcher(line).find()) { Sode_Line++; } else if(line.matches("^\\s*$")){ Null_Line ++; } else Code_Line ++; } data_n.result+=all_files+",代码行:"+Code_Line+",注释行:"+Sode_Line+",空行数:"+Null_Line+" "; } return data_n.result; } /* String NULL(Set<String> all_file) throws IOException { int Sode_Line = 0; int Code_Line = 0; int Null_Line = 0; Creat_data data_n =new Creat_data(); BufferedReader bufr = null; for (String all_files : all_file) { bufr = new BufferedReader(new InputStreamReader(new FileInputStream(all_files))); Pattern nodeLinePattern = Pattern.compile("((//)|(/\\*+)|((^\\s)*\\*)|((^\\s)*\\*+/))+", Pattern.MULTILINE + Pattern.DOTALL); String line = null; while((line = bufr.readLine()) != null) { if (nodeLinePattern.matcher(line).find()) { Sode_Line++; } else if(line.matches("^\\s*$")){ Null_Line ++; } else Code_Line ++; } data_n.result+=all_files+",代码行:"+Code_Line+",注释行:"+Sode_Line+",空行数:"+Null_Line+" "; } return data_n.result; }*/ }
五、单元测试
单元测试代码:

1 import java.io.IOException; 2 import java.util.HashSet; 3 import java.util.Set; 4 5 import org.junit.Test; 6 7 8 public class test { 9 @org.junit.Test 10 public void testDifine() { 11 Set<String> all_files = new HashSet<String>(); 12 String file1 = "D:test.java"; 13 all_files.add(file1); 14 try { 15 16 System.out.println(new ToolUtil().difflineGUI(all_files)); 17 18 19 } catch (IOException e) { 20 // TODO Auto-generated catch block 21 e.printStackTrace(); 22 } 23 } 24 25 @org.junit.Test 26 public void testReturnCharacters() { 27 Set<String> all_files = new HashSet<String>(); 28 String file1 = "D:test.java"; 29 all_files.add(file1); 30 System.out.println(new ToolUtil().ReturnChara(all_files)); 31 } 32 33 @org.junit.Test 34 public void testReturnWords() { 35 Set<String> all_files = new HashSet<String>(); 36 37 String file1 = "D:test.java"; 38 all_files.add(file1); 39 System.out.println(new ToolUtil().ReturnWords(all_files)); 40 } 41 42 @org.junit.Test 43 public void testReturnLines() { 44 Set<String> all_files = new HashSet<String>(); 45 String file1 = "D:test.java";//哈哈哈哈 46 all_files.add(file1); 47 System.out.println(new ToolUtil().ReturnLines(all_files)); 48 } 49 50 51 @org.junit.Test 52 public void testOutputFile() { 53 String all_files = "result.txt"; 54 String context = "OutPutFile test !"; 55 new ToolUtil().OutpuFile(all_files, context); 56 } 57 58 }
六、可视化界面:
可视化界面代码:

1 import java.io.IOException; 2 import java.util.HashSet; 3 import java.util.Set; 4 5 import org.junit.Test; 6 7 8 public class test { 9 @org.junit.Test 10 public void testDifine() { 11 Set<String> all_files = new HashSet<String>(); 12 String file1 = "D:test.java"; 13 all_files.add(file1); 14 try { 15 16 System.out.println(new ToolUtil().difflineGUI(all_files)); 17 18 19 } catch (IOException e) { 20 // TODO Auto-generated catch block 21 e.printStackTrace(); 22 } 23 } 24 25 @org.junit.Test 26 public void testReturnCharacters() { 27 Set<String> all_files = new HashSet<String>(); 28 String file1 = "D:test.java"; 29 all_files.add(file1); 30 System.out.println(new ToolUtil().ReturnChara(all_files)); 31 } 32 33 @org.junit.Test 34 public void testReturnWords() { 35 Set<String> all_files = new HashSet<String>(); 36 37 String file1 = "D:test.java"; 38 all_files.add(file1); 39 System.out.println(new ToolUtil().ReturnWords(all_files)); 40 } 41 42 @org.junit.Test 43 public void testReturnLines() { 44 Set<String> all_files = new HashSet<String>(); 45 String file1 = "D:test.java";//哈哈哈哈 46 all_files.add(file1); 47 System.out.println(new ToolUtil().ReturnLines(all_files)); 48 } 49 50 51 @org.junit.Test 52 public void testOutputFile() { 53 String all_files = "result.txt"; 54 String context = "OutPutFile test !"; 55 new ToolUtil().OutpuFile(all_files, context); 56 } 57 58 }
七、运行结果展示:
创建1个文件1.txt,在文件中输入以下内容
运行程序,在文件这个运行框中定位文件位置D:1.txt,点击结果按钮
八、总结
这次的实验实在原来的基础上增添了高级的功能让我明白了软件并不是只把程序写出来就万事大吉了。在编写完程序后我们需要对每个单元模块进行测试,在尽可能的情况下做到减少bug避免bug。而在这次的结队编程中我接触到了新的知识——性能测试。虽然这次博客并没有把它写出来但是我真的尝试了很多攻击例如GC-View和Jprofile但是大多数的性能测试工具我发现很多数据我是不明白的,所以本着务实求真没弄明白的我尽量不往上贴图片以免误导他人。至于单元测试我们采用了Eclipse自带的单元测试工具Junit这个测试工具十分方便,可以单独对每个类进行测试然后报错到哪一个类中。在进行图形化操作时采用了Frame和Pannel来进行图形的绘制,这是一个非常好用的框架,能够进行画出简单的图形窗体而不是枯燥的黑白控制台。在结队编程最开始的时候两个人的分工不是很明确,都想去写代码完善功能而不是写博客,所以前期相当于我们是一人做了一个项目然后完善到一起的这样浪费了不少的时间,其实我觉得写博客也是一件非常重要的事情,这能在编写的时候发现自己不足的地方,也能使自己留下深刻的印象,然后能在以后回顾时看到自己以前的错误然后避免错误。这次结队项目过后我发现程序员并不是简单的写代码就可以了,还要做的事非常多,单元测试性能测试,和搭档交流这样才能写出一个完整的程序。