zoukankan      html  css  js  c++  java
  • 合作就是不断磨合的过程!

    一、Fork仓库的Github项目地址和伙伴的地址

    Github项目地址:https://github.com/WHYNOTEN/WordCount.git

    合作同学作业地址:https://www.cnblogs.com/SW-P-WY/p/10657136.html

    合作人:wnagyang、zhourong


    二、PSP表格(事实上实际耗费时间比预估时间要长)

     

    PSP2.1

    Personal Software Process Stages

    预估耗时(分钟)

    实际耗时(分钟)

    Planning

    计划

    890  1435

    · Estimate

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

    890  1435

    Development

    开发

    770   1270

    · Analysis

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

    40   50

    · Design Spec

    · 生成设计文档

    30   35

    · Design Review

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

    50   60

    · Coding Standard

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

    20   15

    · Design

    · 具体设计

    30   50

    · Coding

    · 具体编码

    420   900

    · Code Review

    · 代码复审

    60   40

    · Test

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

    120   120

    Reporting

    报告

    120   165

    · Test Report

    · 测试报告

     60  80

    · Size Measurement

    · 计算工作量

    30   60

    · Postmortem & Process Improvement Plan

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

    30   25
     

    合计

    900   1435

    绘制PSP表格总结:以前编写项目的时候并未有设计和预算的过程,个人感觉编写表格和事先设计好进程,更有利于完成项目。因为在完成的过程中对自己进行到那个地方心里有个数。


    三.计算接口模块的设计与实现过程

     1.需求分析(由两人共同商议)

      基础功能

          1.统计文件字符数(统计字符这一块,对提取文本中字符问题,出现了乱码,后来商讨了下解决不同文本转码的问题)

        2.统计单词总数(单词必须四个英文字母开头,后面可以为数字,不区分大小写)

        3.统计文件中有效行数

        4.统计文件中单词单词总数,按频率排序,对于相同频率单词按字典顺序排列

        5.按照字典顺序输出到文件中

        6.调用程序时,通过命令行传入文件读取和写入路径

      新功能:

            1.输出前n个频率最高的单词(直接新增加一个列表保存输出的前n个单词)

             2.指定一个词组长度,输出词组及其出现频率

             3.多参数混合使用(封装)

      实现所有需求思路:

    1. 需求主要是对于文本中内容的提取,这里就要用到正则表达,之前没有涉及到过就看了下群里同学分享的链接。(用到正则的部分是伙伴编写的,个人不是很会使用正则)
    2. 对于行数提取则可以通过读取文件(按行提取内容)时,判断提取内容是否为null来解决。
    3. 统计频率可以通过字典这种Key,Value这种存储方式来进行统计,排序则通过字典排序实现。
    4. 对于命令行传入参数可以通过Main(string[] args)中对args进行解析来实现。
    5. 新功能输出前n个频率最高可以直接输出字典内容即可。
    6. 伙伴询问助教老师后确定同样可以利用字典统计词组并输出(-m的功能是和伙伴“吵了一架的”,因为他觉得构架和基础功能无异,由我编写)
    7. 第三个功能主要是对于Main方法args参数的解析,可以利用字典保存参数及其内容

    最终确定主要写两个.cs文件,其中一个对功能实现,另外一个进行功能类调用,这样测试时即只需要对功能类函数进行测试即可,基本功能由笔者实现,对于新功能有合作者实现,最终整合在功能中:

    Function.cs:主要实现对文本内容的提取筛选实现需求功能;

    Program.cs:对命令行参数进行分析(GetMand()),调用Function.cs对文本内容分析,实现功能(Main()).

     算法关键在于正则表达式的书写以及将内容写入字典整合:

    文件读取代码:

    //读取文件中的字符数目并保存文件内容
            public void GetChar()
            {
                //打开文件
                FileInfo file = new FileInfo(this.path);
                //定义读取文件对象
                StreamReader sw = file.OpenText();
                //按行进行读取,不为空行记录行数并保存内容,返回null打断循环
                while (true)
                {
                    //对文件读取内容进行判断,如果不为空用变量接收,行数加一
                    string temp = sw.ReadLine();
                    if (temp != null)
                    {
                        account++;
                        this.content += temp;
                    }
                    //为空则停止
                    else
                    {
                        break;
                    }
    
                }
            }
    View Code

    正则匹配函数:

    public void ExtractChar()
            {
                //利用正则进行匹配,以字母开头,可以数字结尾
                MatchCollection rel = Regex.Matches(this.content, @"([a-zA-Z]{4}w*)");
                for (int i = 0; i < rel.Count; i++)
                {
                    //匹配到的单词进入列表
                    this.result.Add(Convert.ToString(rel[i]));
                }
            }
    View Code

    字典写入代码: 

    //利用字典统计单词出现次数
            public void Statistical()
            {
                //建立临时字典保存单词以及出现次数
                Dictionary<string, int> words = new Dictionary<string, int>();
                for (int i = 0; i < this.result.Count; i++)
                {
                    if (words.ContainsKey(this.result[i]))
                    {
                        words[this.result[i]]++;
                    }
                    else
                    {
                        words[this.result[i]] = 1;
                    }
                }
                //对字典内容排序,并赋值给类变量
                this.words_sort = words.OrderByDescending(p => p.Value).ToDictionary(p => p.Key, o => o.Value);
                //清空临时字典内容
                words.Clear();
    
            }
    View Code

    四、代码复审

      代码规范:详情请查看链接

      这部分在这次合作中我深有体会,之前在课程学习中,本人认为自己的代码自己看。符合自己规范就行,但是在这次合作中,深切地体会到代码规范的问题,好在伙伴的编程规范很好,他所编写的我都能看懂,审核。此方面我也该向他学习。

     


    五、性能改进

    从性能分析图看出Program.Main()与Function.ToFile()分配最多,但由于这两个函数都是调用了其余函数,所以减去其余调用函数分配,得出Function.ToFile()分配最多,为786,其次是Function.ExtractChar()(PS:之前和伙伴在-m新增功能中有争议,他说会影响性能,硬是要删除,被本人留了下来,后来代码复审的过程中我发现,确实功能和基础功能用法无异)

    //将内容写入文件中
            public void ToFile(string path)
            {
                //运行先行函数,将需要的文件内容保存至变量中
                this.GetChar();
                this.ExtractChar();
                this.ToLow();
                this.Statistical();
                //获取当前文件路径
                string filepath = Directory.GetCurrentDirectory();
                //定义文件输出路径
                filepath += path;
                FileInfo file = new FileInfo(@filepath);
                StreamWriter sw = file.AppendText();
                sw.WriteLine("characters: {0}", this.CharNum());
                sw.WriteLine("words: {0}", this.WordsNum());
                sw.WriteLine("lines: {0}", this.account);
                //遍历字典将内容写入文件
                foreach(KeyValuePair<string,int> kvp in this.words_sort)
                {
                    sw.WriteLine("{0,-10}:{1,-3}", kvp.Key, kvp.Value);
                }
                //关闭文件
                sw.Close();
                Console.WriteLine("结果文件保存于:{0}", filepath);
            }
    View Code

    分析代码发现在ToFile()函数中进行了当前文件路径读取,读取文件,并多次写入文件(特别是遍历字典同时进行写入文件),由此可见循环写入文件是导致性能变差的原因。改进方法是将需要写入的内容保存至一个临时字符串中,遍历字典后再对整个字符串进行写入文件操作。ExtractChar()函数使用了正则进行匹配,由于对Regex类具体实现不清楚,暂时无法进行性能优化。(PS:在合作过程中,伙伴普及很多知识于本人,正则很耗费内存,还有封装,本人在重新加入-m功能的时候被伙伴吐槽,代码复用太多,难以封装)

     


     六、单元测试

     百度了下静态测试,前一次作业单元测试是无效的,通过伙伴的知识普及,了解到一个有效的单元测试是要有断言的。(PS:伙伴将封装后的代码文件发送给我,然后在自己电脑上测试并不能通过,因为电脑配置问题,还在其他同学的帮助下百度了问题。修改了配置文件,还是不行,最后用伙伴的电脑进行的测试)

     


    七、异常处理

    异常处理主要针对命令行传入参数的判定:

    1.文件传入路径

    //对得到内容进行处理 - i参数确定文件是否存在
                try
                {
                    StreamReader sw = new StreamReader(command["-i"]);
                }
                catch
                {
                    Console.WriteLine("需处理的文件不存在!请检查路径重新运行!");
                }

    2.-m 与-n 参数内容是否为整数

    //对-m -n 参数内容进行强制转换看是否为整数
    if (command.ContainsKey("-n") && command.ContainsKey("-m"))
                {
                    try
                    {
                        int nums = Convert.ToInt32(command["-n"]);
                        int length = Convert.ToInt32(command["-m"]);
                    }
                    catch
                    {
                        Console.WriteLine("参数输入有误,请重新运行!");
                    }
                }
                else if (command.ContainsKey("-m") && !command.ContainsKey("-n"))
                {
                    try
                    {
                        int length = Convert.ToInt32(command["-m"]);
                    }
                    catch
                    {
                        Console.WriteLine("参数输入有误,请重新运行!");
                    }
    
                }
                else if (!command.ContainsKey("-m") && command.ContainsKey("-n"))
                {
                    try
                    {
                        int length = Convert.ToInt32(command["-n"]);
                    }
                    catch
                    {
                        Console.WriteLine("参数输入有误,请重新运行!");
                    }
                }
                else { }

    八、结对过程

       在进行项目之前,和伙伴就约在了思学楼商讨了规则,当时没人给拍照,商讨了之后构建了PSP表格,进行编程。其实本人很清楚,此次编程中,伙伴花费了很多精力,最然本人也在参与,但是编程能力远远不如他,有趣的是在第一次商讨的时候我们在一起编写基础功能,然后他永远比本人快。(附上基础功能完成后,一起改进的照片)


     十、总结

    本来和伙伴的编程能力就相差甚远,在这次编程中,个人是羞愧的,觉得1+1<2,没有自己的参与伙伴也许会更快的完成项目,在这次过程中于本人而言,1+1>2,因为伙伴普及了很多知识,包容我的过失等。为大学前两年没有好好学习感到懊悔,为自己拖后退感到抱歉,经过此次,我找到了好好学习的另一个理由,没有人为你的过失买单,想要好好的与人合作,更要提升自己,加油!期待下次和他合作的自己更好!

     

  • 相关阅读:
    [Javascript]史上最短的IE浏览器判断代码
    初学者必看:精心整理的Javascript操作JSON总结
    用实例一步步教你写Jquery插件
    学习一种新编程语言要做的14个练习
    一些实战中总结的 javascript 开发经验
    JavaScript开发规范
    jQuery性能优化
    不到30行JS代码实现的Excel表格
    javascript 执行顺序详解
    Java基础知识强化之IO流笔记58:内存操作流
  • 原文地址:https://www.cnblogs.com/Mchandu/p/10657935.html
Copyright © 2011-2022 走看看