第三次作业——结对编程

第三次作业——结对编程

 

github地址 https://github.com/LipeishanDawn/WordCount
结对伙伴作业地址

一、结对过程

 

1.下图是我和我的结对伙伴一起讨论时的照片

二、PSP表格

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

 30

 35

· Estimate

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

 720

 750

Development

开发

 60

 50

· Analysis

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

 60

70

· Design Spec

· 生成设计文档

 30

 30

· Design Review

· 设计复审 (和同事审核设计文档)

 60

 55

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

 30

30 

· Design

· 具体设计

 60

50 

· Coding

· 具体编码

 300

390 

· Code Review

· 代码复审

 60

60 

· Test

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

 60

 130

Reporting

报告

 60

 60

· Test Report

· 测试报告

 60

 90

· Size Measurement

· 计算工作量

 20

 30

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

 10

 10

 

合计

 1620

 1840

三、解题思路

       我和我的结对伙伴首先一起对整个程序的功能进行了分析,然后进行分工。整个程序可以分为四个部分,分别是统计文件的字符数Charnum,统计文件行数Filelines,统计文件里面的单词总数和指定长度的词组的功能Wordnum,包含根据字典顺序输出出现次数最多的前n个数和将结果输出功能的Program。经过分工,我的伙伴主要负责Filelines和Wordnum,而我负责Charnum和Program。由于我对于字典顺序不是很了解,所以我首先百度了字典对象的用法。之前在学习C#的时候,对于文件的部分用法,这次的代码对文件的要求很高,所以我通过翻阅书籍和百度学习了文件。

四、设计实验过程

1、本次的代码分为了四个部分,具体的分工在上一点我有说到。整个函数分为了三个类,分别是Charnum,Fileline和Wordnum。对于我自己的部分Charnum中只有一个getCharCount函数,Program里面也只有一个Main函数。

Charnum

:

Program:

其他具体的设计,以及函数的关系,可详见我伙伴的作业:https://www.cnblogs.com/230332663abcd/p/10626290.html

2、单元测试详见:https://www.cnblogs.com/230332663abcd/p/10626290.html

五、代码制定规范

      我们主要参照“http://www.cnblogs.com/xinz/archive/2011/11/20/2255971.html”进行代码规范和复审。

1、互审的模块:我是审查我结对伙伴写的filelines和wordnum这两个类。

2、互审的问题:

       即使我们要求按照邹欣老师写的代码规范进行的,但还是避免不了一两处的不规范。

    (1)我们规定注释是另起一行,但还是出现了在代码后面直接注释的情况。

    (2)对于变量的命名风格不同意。比如我喜欢取每个单词的首字母进行命名,我的同伴习惯使用单词的前几个字母进行命名。后来经过我们讨论,决定采用同伴的命名方式,这样更直观一点。

    (3)我们在查看对方代码的时候多有对代码的疑惑,对于这些不是很清楚的地方我们又重新添加了注释。

六、改进程序性能

       该部分可详见我伙伴的博客中:https://www.cnblogs.com/230332663abcd/p/10626290.html

七、代码说明

       在Charnum里面,主要是将文件中的内容存入一个数组然后通过循环判断Ascii码来统计字符数。

 class CharNum   {
        public int getCharCount(string FilePath)
        {
            int charCount = 0;
            FileStream fsRead = new FileStream(FilePath, FileMode.Open);//流方式读取文件
            int fsLen = (int)fsRead.Length;//判断文件长度
            byte[] heByte = new byte[fsLen];//创建对应长度的byte数组
            int r = fsRead.Read(heByte, 0, heByte.Length);//文件内容放到数组里
            foreach(byte b in heByte)  //循环数组判断 是不是在ASCII表内
            {
                if (b >= 0 && b <= 126 )
                {
                    charCount++; // 是就+1

                }
            }
            fsRead.Close();
            return charCount;
        }
    }

       在主函数里面首先建立各个类的对象,定义词组长度,单词数量、输出内容output等之后会用到的对象。

CharNum charNum = new CharNum();
            WordNum wordNum = new WordNum();
            FileLines fileLine = new FileLines();
            string filePath = "input.txt";//默认文件为 input.txt
            int wordLength = 0;
            int wordCount = 0;
            string outFile = "";
            string outPut = "";

        判断输入的参数,通过“-i”,"-m","-o","-n"后面紧跟的内容来对文件路径Filepath、词组的长度、要求输出的次数最多个前worldcount个单词和输出文件的路径outfile进行赋值。

       再用多个if语句来判断输入内容是否含有多个参数,然后用switch和case来处理参数不同的先后顺序。

if (args.Length > 0 ) // 判断输入参数   
            {
                switch (args[0]) 
                {
                    case "-i":
                        filePath = args[1];
//读入的文件路径 break; case "-m": wordLength = int.Parse(args[1]);
//m个单词组成一个词组 break; case "-n": wordCount = int.Parse(args[1]);
//输出出现次数最多的前worldCount个单词 break; case "-o": outFile = args[1];
//生成的文件路径 break; } if(args.Length > 2) switch (args[2]) { case "-i": filePath = args[3]; break; case "-m": wordLength = int.Parse(args[3]); break; case "-n": wordCount = int.Parse(args[3]); break; case "-o": outFile = args[3]; break; } if (args.Length > 4) switch (args[4]) { case "-i": filePath = args[5]; break; case "-m": wordLength = int.Parse(args[5]); break; case "-n": wordCount = int.Parse(args[5]); break; case "-o": outFile = args[5]; break; } if (args.Length > 6) switch (args[6]) { case "-i": filePath = args[7]; break; case "-m": wordLength = int.Parse(args[7]); break; case "-n": wordCount = int.Parse(args[7]); break; case "-o": outFile = args[7]; break; }

       调用之前定义的对象的各自的函数,以文件路径作为参数,完成它们相应的功能,将返回值存入output中。

                outPut +="characters:" + charNum.getCharCount(filePath) + "\n";
                outPut += "words:" + wordNum.getWordCount(filePath) + "\n";
                outPut += "lines:" + fileLine.getFileLineCount(filePath) + "\n";

       最后用字典顺序,将要输出的内容赋值给output。

wordNum.getWordCount(filePath, wordLength);//先调用方法把单词处理完成   
                Dictionary<string, int> dict = wordNum.getLinq();//再调用排序 

                int i = 10;
                if (wordCount != 0)
                    i = wordCount;
                foreach (KeyValuePair<string, int> kvp in dict)
                {
                    if (i == 0)
                        break;
                    else
                    {
                        outPut += "<" + kvp.Key + ">:" + kvp.Value+"\n";
                        i--;
                    }
                }

        最后再将output的内容存入到输出文件的路径outfile。

       如果outfile=“”,则直接输出output即可。

 if (outFile == "")
                {
                    Console.WriteLine(outPut);
                }
                else
                {
                    FileStream fs = new FileStream(outFile, FileMode.Create);
                    //获得字节数组
                    byte[] data = System.Text.Encoding.Default.GetBytes(outPut);
                    //开始写入
                    fs.Write(data, 0, data.Length);
                    //清空缓冲区、关闭流
                    fs.Flush();
                    fs.Close();
                }
                Console.ReadKey();
            }

八、总结

         这次的结对编程项目让我学会了如何去和结对伙伴沟通,两个人一起思考得到的效果是比一个人要好得多,因此在整个程序设计水平上都比我以前有了很大的进展。在这次的解决问题中,我们对每一个出现的问题都分析了其出现的原因,对于以后避免此类问题出现有很大的帮助。同时我也从我的同伴的不同思路中得到了新的启发,总体来说这是一次1+1>2的经历。

posted @ 2019-04-05 18:16  lpsss  阅读(205)  评论(1编辑  收藏  举报