个人项目WC

---恢复内容开始---

                       个人项目:WC

一,GitHub地址:https://github.com/Cercis-chinensis/wc

                                      

二 ,                                                    PSP表格             

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)    耗时占比
Planning 计划 30 20  1
Estimate · 估计这个任务需要多少时间 30 20  1
Development 开发  890  1710  92
Analysis · 需求分析  30 20  1
Design Spec · 生成设计文档 30 20  1
Design Review · 设计复审  40 20  1
Coding Standard · 代码规范 50 10  0.5
Design · 具体设计 60 170  10
Coding · 具体编码 600 1500  80
Code Review · 代码复审 20 60  3
Test · 测试(自我测试,修改代码,提交修改) 60 80  4
Reporting 报告  110  130  7
Test Report · 测试报告 60 80  4
Size Measurement · 计算工作量 40 30   1.5
Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 10 20  1
Total 合计    1860  

 

 三,解题思路

   在看到题目要求后,我对应着个人开发流程(PSP)来作为思考的方向。所以,对题目分析需求,初步分析时,我将需求之间的关系大致分为三部分。然后进行相应的计划设计。初步设计时,将这个项目的代码关于类的设计主要分为四部分。分别时基本功能类(统计字符,行数,单词数、查看空行、注释行、代码行),扩展功能类expand(递归查看文件),高级功能类(显示GUI),还有主类(主要来接受控制台传输的字符串,提取并处理传输给各种调用类)。

  在考虑好各类的所要实现的功能后,进一步大致考虑类之间的相互关系与调用。通过考虑上面这些,对此写下设计计划。

  之后对四个类进行大致设计,根据各类所要实现功能以及各类之间的关系来设计各种类的形式,同时,思考该如何实现分配给各个类的功能,同时联想到相应的语言知识,思考着如何构建知识储备与所要实现功能之间的关联,将如何实现功能的操作逐步细分,当细分后的操作与已知知识点有所联系时,稍作记录,遇到不懂的部分时,在网上查找各种资料。

  在对各类所实现功能的编写有着大概掌握后,对每个类的内部进行更详尽的编写。在编写时,我设置一个另外用于测试的test主类,目的是用来测试我所要写的逻辑,相关代码块,以及所引用各种包等等操作是否符合实际应用。

  完成一个功能,就进行测试,为避免后面引起混乱。同时,在编写过程中,根据实际来对类的结构,方法的结构经行一些修改,来更好地完成项目。

  在做此次项目的过程中,思路大致如上。

四,实现设计过程

  根据需求之间的联系,将此次项目分为四个类,分别是基本功能类(实现行,字符,单词的统计),扩展功能类(实现递归处理文件)高级功能类(GUI),以及主类。

基本功能类Base();

扩展功能类Expand();

高级功能类CFrame();

主类wc();

类之间的关系图:

各类的内部大致描述:

主类wc:

   接受控制台所输入的字符串(“-c” “-w”等等以及文件路径),对字符串进行处理,首先是将标识符与路径分开存储,根据标识符使用switch——case来创建相应的对象,调用相应的方法。

以下为主类的主要代码部分:

String[] st = {""};
        Expand ep;
        
        while(!st[0].equals("end")){
            System.out.print("\nwc.exe:");
            st=inp.nextLine().split("\\s+");
            
            switch(st[0]){
            case "-c":
                if(Files.notExists(Paths.get(st[1]),LinkOption.NOFOLLOW_LINKS))
                    System.out.println("输入出错");
                else System.out.println("字符数为:"+Base.count(st[1], 'c'));
            
                continue;
                
                
            
            case "-w":
                if(Files.notExists(Paths.get(st[1]),LinkOption.NOFOLLOW_LINKS))
                    System.out.println("输入出错");
                else System.out.println("词数为:"+Base.count(st[1], 'w'));
                continue;
                
                
            case "-l":
                if(Files.notExists(Paths.get(st[1]),LinkOption.NOFOLLOW_LINKS))
                    System.out.println("输入出错");
                else System.out.println("行数为:"+Base.count(st[1], 'l'));
                continue;
            
                
            case "-s":
                if(Files.notExists(Paths.get(st[1]),LinkOption.NOFOLLOW_LINKS))
                    System.out.println("输入出错");
                else   ep = new Expand(st[1]);
                continue;
                
                
                
                
            case "-x":
                CFrame fr=new CFrame();
                continue;
                
            case "-n":
                if(Files.notExists(Paths.get(st[1]),LinkOption.NOFOLLOW_LINKS))
                    System.out.println("输入出错");
                else System.out.println("空行数为:"+Base.count(st[1], 'n'));
                continue;
                
            case "-e":
                if(Files.notExists(Paths.get(st[1]),LinkOption.NOFOLLOW_LINKS))
                    System.out.println("输入出错");
                else System.out.println("单行注释行数为:"+Base.count(st[1], 'e'));
                continue;
                
            case "-o":
                if(Files.notExists(Paths.get(st[1]),LinkOption.NOFOLLOW_LINKS))
                    System.out.println("输入出错");
                else System.out.println("代码行行数为:"+Base.count(st[1], 'o'));
                continue;
                
            default:
                System.out.println("出错!请按所设定的形式输入!");
                continue;
            }  
            
        }
        inp.close();
        System.out.println("程序结束");
    }

基本功能类Base:
统计字符数,单词数,行数,空行数,注释行数,代码行数,同时通过主类传给base类的标识符,返回不同的值。

public static int count(String path,char c) throws IOException{
    
    BufferedReader brfile;
    //注意int的上限》?
    int cnum=0;
    int wnum=0;
    int lnum=0;
    int nline=0;
    int eline=0;
    int oline=0;
        
        
        brfile= new BufferedReader(new InputStreamReader(new FileInputStream(path)));
        //改先分。分析效能时
        String str1=null;
        while((str1=brfile.readLine())!=null) {
        cnum +=str1.length();
        wnum +=str1.split("\\W+").length;    
        if(str1.matches("\\s*")) nline++;
        if(str1.matches("\\s*//.*")) eline++;  //单行注释, 多行注释待解决
        lnum++;
        }
        oline=lnum-nline-eline;
        brfile.close();
        if(c=='w')return wnum;
        else if(c=='c')return cnum;
        else if (c=='l')return lnum;
        else if(c=='n') return nline;
        else if(c=='e')return eline;
        else if(c=='o')return oline;
        else return 0;
    

Expand类

递归进入文件夹,如果目录下还有文件夹,则进入其中,并识别运行符合条件的文件,在这里,我将符合条件的文件设为,以.txt  .java  .c  .py   .doc结尾的文件,当然,还可以进行相应的扩充。

递归进入文件夹读取文件:

private static void findf(String str) throws IOException {
        File fl=new File(str);
        File[] flist=fl.listFiles();
         for(File f :flist) {
             if(f.isDirectory()) {
                 findf(f.getAbsolutePath());
             }else if(isfind(f.getName())) {
                 System.out.println(f.getName());
                 System.out.println("字符数为:"+Base.count(f.getAbsolutePath(), 'c'));
                 System.out.println("单词数为:"+Base.count(f.getAbsolutePath(),'w'));
                 System.out.println("行数为:"+Base.count(f.getAbsolutePath(), 'l')+
                         "  其中,空行数为:"+Base.count(f.getAbsolutePath(), 'n')+
                         "  单行注释行数为:"+Base.count(f.getAbsolutePath(), 'e')+
                         "  代码行为:"+Base.count(f.getAbsolutePath(), 'o'));
             }
         }

上面代码中,的isfind()方法来用于识别符合条件文件:

static boolean isfind(String name) {
        if(name.endsWith(".java"))return true;
        else if(name.endsWith(".txt"))return true;
        else if(name.endsWith(".c"))return true;
        else if(name.endsWith(".py"))return true;
        else if(name.endsWith(".doc"))return true;
        else return false;
        
        
    }

CFrame类:

主要是调用 文件选择器 来通过图形界面选择文件,同时通过提示框JOptionPane来返回处理后信息

JFileChooser fc=new JFileChooser();
        fc.showOpenDialog(null);
        file=fc.getSelectedFile();



JOptionPane.showMessageDialog(null,
                    "字符数为:"+Base.count(path,'c')+"\n字数为"+Base.count(path, 'w')+"\n行数为:"+Base.count(path, 'l')+"\n空行数:"+Base.count(path, 'n')+"\n单行注释行数:"+Base.count(path, 'e')+"\n代码行:"+Base.count(path, 'o'),"处理结果",
                    JOptionPane.INFORMATION_MESSAGE);
            

五,测试

控制台界面:

测试-c:

 分别测试的是空文件,一个字符文件,一行字符的文件,以及一个源程序文件

测试-l:

测试-s:递归

文件夹视图: 

 

 直接对-s测试可以对Base中其他标识符有关代码进行测试,篇幅有限,尽可能提高测试代码率;

 上面doc文件有关统计有错,说明doc格式与这种计算不符,同时,这可以说明可以匹配到.doc结尾的,以及可以递归进入文件夹。

 测试-x:GUI

 选择t4.java后的处理结果界面:

测试end:结束程序;

 返回结果符合所预设结果。

六,总结

    经历这次项目后,无疑的是,自己在有关编程方面的能力有着很大的提升。同时对旧知识的回忆,以及对新知识的学习与应用有着很大的帮助。这次作业经历,增加了个人对软件开发过程的认识,特别是PSP的过程,编码前的准备比编码的过程更为重要。在编码前的准备越是充分,编码的过程越是容易。

   同时,也切实看到自身的不足,各方面的欠缺。导致这次试验效率非常低,前期设计的准备不足,导致后面编码时要经常对前面进行改动。各种能力,素养还需要更多地磨练。

 任重而道远

猜你喜欢

转载自www.cnblogs.com/2Cercis/p/11588605.html