Jason Wang: 结对编程 CountWord(第三次作业)

时间:2021-07-13 21:18:20
本次作业地址: https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/homework/2882
学号: 201731072323   partner: 201731062201
本人博客地址: https://www.cnblogs.com/jason5689/
Github地址: https://github.com/Jason98w/WordCount
伙伴作业地址: https://www.cnblogs.com/luomei/p/10657008.html

PSP表格

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

30

20

· Estimate

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

30

20

Development

开发

1230

855

· Analysis

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

90

70

· Design Spec

· 生成设计文档

60

40

· Design Review

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

30

60

· Coding Standard

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

30

15

· Design

· 具体设计

60

40

· Coding

· 具体编码

800

390

· Code Review

· 代码复审

60

40

· Test

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

100

200

Reporting

报告

100

150

· Test Report

· 测试报告

60

100

· Size Measurement

· 计算工作量

10

20

· Postmortem & Process Improvement Plan

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

30

30

合计

1360

1025

一起讨论照片:

Jason Wang: 结对编程  CountWord(第三次作业)

1.代码规范

1.1代码风格规范

1.缩进:4个空格。

2.空格:运算数与操作符之间要有空格。

3.括号:计算过程使用括号表示逻辑优先级。

4.断行:所有的’ { ‘ 和 ‘ } ’都独占一行。

5.分行:一条语句一行。

命名:

1.变量名:小驼峰命名法

2.循环的临时变量统一使用ijk,临时变量使用temp1 temp2 ……。

3.函数名:大驼峰命名法

4.接口:I+函数名。

5.注释:注释函数功能,输入输出。注释关键代码,且注释统一使用ASCII字符,不使用中文

 

1.2代码设计规范:

 

1.Main内只做初始化和函数调用,不写具体的功能性代码。

2.对关键代码做异常处理

3.对所有传递到函数中的参数都应该做正确性检验。

4.类中的成员按照public、protected、private的次序进行说明。

5.所有涉及到的清理工作都放在析构函数中。

6.在非必要的情况下不选择继承类。

2.需求分析

 

2.1基本功能

1. 统计字符数(只统计Ascii码,不考虑中文字符)

2. 统计有效行数(包括空白行)

3. 统计单词总数(至少以4个英文字母开头,跟上字母数字符号,单词以分隔符分割,不区分大小写)

英文字母:A-Z,a-z 字母数字符号:A-Z,a-z,0-9 分割符:空格,非字母数字符号

例:file123是一个单词,123file不是一个单词。file,File和FILE是同一个单词

4. 统计文件中各单词的出现次数,最终只输出频率最高的10个。频率相同的单词,优先输出字典序靠前的单词。

Tips:由于功能3可在功能4中得到使用,将其交与一人开发,可以提高开发的效率和正确性

 

2.2拓展功能

 

1. 能统计文件夹中指定长度的词组的词频

2. 能输出用户指定的前n多的单词与其数量

Tips:由于拓展功能2是基本功能4的普遍版本,建议直接对拓展功能进行开发,减少开发耗时。

3.接口设计及实现过程

 

对需求分析的进一步考虑,本次开发共设计两个类6个函数一个接口

3.1基本流程

Step1: 对基本功能设置一个基类(Version1),建立4个函数去描述4个基本功能的实现。

Step2: 对拓展功能设计另一个单独的类(Version2),通过面向对象的继承关系与基类建立联系,继承基类的方法和属性,建立1个函数去实现拓展功能1。

Step3: 为了满足不同环境对代码的使用,对基本功能1,3,4独立出来,进行接口封装。

Step4: 将每个函数功能独立出来,进行C#的组件封装,作为此项目的核心Core模块

3.2函数接口设计:

接口说明:

 public interface CountWord

 {

      //统计Ascii码的个数,传入参数为文本地址,传出参数为Ascii码的个数

     int CountAscii(string txtPathString);

     //统计行数,传入参数为文本地址,传出参数为行数

     int CountLine(string txtPathString);

     //输出频率最高的n个单词,传入参数为文本地址,传出参数为单词和个数

     Dictionary<string, int> OutputWord(string filePath, int outNumb);

     //输出频n个单词构成的词组,传入参数为文本地址,传出参数为词组和个数

     Dictionary<string, int> LengthDeterminingPhrases(string txtString);

     //打印所有结果,传入参数为ascii数,单词数,行数,频率最高的n个单词,n个单词构        成的词组

     void PrintWord(int asciiNum, int wordNum, int lineNum, Dictionary<string, int> wordFrequency, Dictionary<string, int> phraseFrequency, string outFilePath);

 }        

3.3关键函数设计思路及流程图:

例:OutputWord函数设计

Jason Wang: 结对编程  CountWord(第三次作业)

public class Outputword : IOutputWord
{
/// <summary>
/// this function is to count the frequency of all words and sort the output descendly
/// </summary>
/// <param name="filePath"></param>
/// <param name="outNum"></param>
/// <returns> word dictionary </returns>
public Dictionary<string, int> OutputWord(string filePath, int outNum)
{
if (!File.Exists(filePath))
{
Console.WriteLine("File does not exist!");
return null;
}
//StreamReader to read file
StreamReader sr = new StreamReader(filePath, System.Text.Encoding.UTF8); int wordNum = ;
string str = "";
string[] word = null;
List<string> res = new List<string>(); //Save all words
List<string> temp = new List<string>(); //Temporary word
List<int> num = new List<int>(); //Save words index
List<int> freqNum = new List<int>(); //Save the frequency
Dictionary<string, int> dictionary = new Dictionary<string, int>(); //Save the word and its frequency
Dictionary<string, int> outWord = new Dictionary<string, int>();
try
{ string line = sr.ReadLine();
//Read all characters in the file
while (line != null)
{
str = str + line + " ";
line = sr.ReadLine();
} //Delimiters are Spaces and special characters
word = Regex.Split(str, @"[^a-z|^A-Z|^0-9]", RegexOptions.IgnoreCase); for (int i = ; i < word.Length; i++)
{
//Determine if it is a word
if (word[i].Length >= && Regex.IsMatch(word[i].Substring(, ), @"^[A-Za-z]{4}$"))
{
res.Add(word[i]);
temp.Add(word[i]);
}
} //Words eliminate heavy
for (int i = ; i < res.Count - ; i++)
{
for (int j = i + ; j < res.Count; j++)
{
if ((res[j].ToLower() == res[i].ToLower()))
{
num.Add(j);
}
}
}
num.Sort();
num = num.Distinct().ToList();
num.Reverse();
for (int i = ; i < num.Count; i++)
{
res.RemoveAt(num[i]);
} //Count words frequency
for (int i = ; i < res.Count; i++)
{
wordNum = ;
for (int j = i; j < temp.Count; j++)
{
if ((temp[j].ToLower() == res[i].ToLower()))
{
wordNum++;
}
}
freqNum.Add(wordNum);
} //Write the types and frequencies of words into the dictionary
for (int i = ; i < res.Count; i++)
{
dictionary.Add(res[i], freqNum[i]);
} //Sort the value of the dictionary
dictionary = DictonarySort(dictionary); //Print outNumber words
for (int i = ; i < outNum; i++)
{
outWord.Add(dictionary.ElementAt(i).Key, dictionary.ElementAt(i).Value);
}
}
catch (IOException e)
{
Console.WriteLine(e.Message);
}
catch (ArgumentOutOfRangeException e)
{
Console.WriteLine(e.Message);
}
finally
{
sr.Close();
} return outWord;
} //Sort the value of the dictionary <linq dictionary .net 3.5>
private Dictionary<string, int> DictonarySort(Dictionary<string, int> dic)
{
var dicSort = from objDic in dic orderby objDic.Value descending select objDic;
return dicSort.ToDictionary(p => p.Key, o => o.Value);
}
}

4.代码复审

 

问题:经过双方对最终代码的复审,发现代码的逻辑都不存在较大问题,更多的问题在于对细节的处理上,如:数组索引溢出,文件忘记关闭等问题。程序的注释不够详细,不能熟练使用C#自带的方法,重复造*

改进: 对最初代码的设计应该更为细致,尽可能的不出现问题,通过使用断点的方式去调试程序会大大提高程序的正确性,并且能准确验证程序的逻辑性,代码还需添加更多的注释,让开发的双方都能够最快的理清程序的逻辑。掌握更多的C#方便的使用技巧,提高编码效率。

5.文件说明

最后上传到Github的文件如下,其中CountWord,OutputWord,PrintResult功能由我实现,分别建立3个类库,源代码在对应文件夹中,测试代码也在其中,CountAscii,CountLine,LengthDeteminingPhrase由罗梅实现,测试代码在对应文件夹中。将6个功能都封装成组件让Main函数调用,dll文件位于对应文件夹中。Interface specification文件为接口说明,test.txt,save.txt分别为测试用输入文件和输出文件。

Jason Wang: 结对编程  CountWord(第三次作业)

6.性能分析

 

将总程序通过多次循环调用,通过使用vs2017性能探查器查看运行程序时的CPU使用率 

Jason Wang: 结对编程  CountWord(第三次作业)

由诊断图即可看出程序34%的CPU占用率都集中在PrintResult(打印及保存结果到文本)函数,说明程序再逻辑上的效果较好,没有较多的额外CPU占用。

还有较多的CPU开销体现在System.IO类的使用上,具体的改进可以针对这方面去进行。

Jason Wang: 结对编程  CountWord(第三次作业)

主要CPU占用图

Jason Wang: 结对编程  CountWord(第三次作业)

CPU占用率随运行时间的变化

Jason Wang: 结对编程  CountWord(第三次作业)

大部分CPU占用图

通过查看更为详细的CPU占用报告即可看出具体代码的CPU占用率。以CountWord类为例,找出最多占用的程序代码,由下图可看出,该类CPU的使用主要集中在使用StreamReader去读取文件功能上,由此可以从更高的读取文件的方式去改进该程序,其他类的分析同理。

Jason Wang: 结对编程  CountWord(第三次作业)

7.单元测试

对关键类CountWord和OutPutWord进行全面的单元测试,使之满足各种复杂的情况,测试按如下方式创建0个不同的文本,对10中情况都执行单元测试,使所有的测试结果都满足预期值。

Jason Wang: 结对编程  CountWord(第三次作业)

CountWord类测试均通过

Jason Wang: 结对编程  CountWord(第三次作业)

OutputWord类测试均通过

Jason Wang: 结对编程  CountWord(第三次作业)

8.异常处理

 

对异常进行单元测试,

Jason Wang: 结对编程  CountWord(第三次作业)

9.结对过程

这次结对编程,确实呐,意义超大的,主要是颠覆了我对软件工程的看法,原来两个人一起开发项目的效率是那么的高,可以对每一个问题提出多种解决方案,能够总结方案的可行性,文档复审,代码复审都有利于提高项目开发的正确性。而且,结对编程时,精力是很集中的,因为每个人都对项目的完成起着至关重要的作用,不敢丝毫马虎,拒绝拖延,很棒的一次经历啊~~  咳咳咳…  关于1+1和2的关系  这个肯定是1+1>>>>>>2   ~~

10.最终结果

最终的结果就是下图了…利用cmd进行来运行程序,还参考了吕登名同学的help方法加了一个程序使用说明

运行效果图:

Jason Wang: 结对编程  CountWord(第三次作业)

程序使用说明:

Jason Wang: 结对编程  CountWord(第三次作业)

11.计算工作量

在完成了整个任务以后,对上述工作进行了一个回顾总结,并大致统计了各部分的工作时间量,填入了文章开头的psp表格中,在结对编程中,最终决定,以 人/天 为计算单位,最终的工作量统计下来是 8 人天

12.总结感悟

这次的项目做的是真爽,连续熬了好几个夜,终于圆满的把所有功能都实现咯,难得呀,感谢罗梅同学的合作~,一起改了很多Bug,分工也很明确,效率都挺高的,都主动承担了很多分工。感觉这次不仅仅将C#通通复习了一遍,还学习了新的知识,如:正则表达式linqDictionarty排序组件的熟练使用, cmd的简易操作,github结对编程技巧等等等。虽然花了很多时间,但觉得很值,对专业的兴趣更加浓厚了。

但由于最初对项目的规划不够完善,出现较多次“写了又该模式”,……有点尴尬,所以呀,以后敲代码之前,细心的分析更为重要,后面写了再改的代码确实有点大~~~

Jason Wang: 结对编程 CountWord(第三次作业)的更多相关文章

  1. Jason Wang&colon;记录自己所想所得(第一次作业)

    这个作业属于哪个课程 <课程的链接> 这个作业要求在哪里 <作业要求的链接> 我在这个课程的目标是 学会现代软件工程的思想,运用到实际中去 这个作业在哪个具体方面帮助我实现目标 ...

  2. 结对编程-四则运算GUI的实现

    一.项目成员以及coding地址: 洪灏捷(本人)201321122020  coding地址:https://git.coding.net/hoje/The-GUI-operation.git 白至 ...

  3. 2017-2018-2 165X 『Java程序设计』课程 结对编程练习&lowbar;四则运算

    2017-2018-2 165X 『Java程序设计』课程 结对编程练习_四则运算 经过第一阶段的学习,同学们已经熟悉了这门语言基本的用法.在一次又一次对着电脑编写并提交代码,进行练习的时候,有没有觉 ...

  4. 这就是小学生也会用的四则计算练习APP吗?- by软工结对编程项目作业

    结对编程项目 软件工程 这就是链接 作业要求 这就是链接 作业目标 熟悉在未结对情况下如何结对开发项目 Github与合作者 合作者(学号): 区德明:318005422 虚左以待 Github链接: ...

  5. 第三次作业-结对编程(wordcount)

    GIT地址 https://github.com/gentlemanzq/WordCount.git GIT用户名  gentlemanzq 结对伙伴博客地址 https://home.cnblogs ...

  6. 2017-2018-2 1723《程序设计与数据结构》第十一周作业 &amp&semi; 实验三 &amp&semi; (总体)第三周结对编程 总结

    作业地址 第十一次作业:https://edu.cnblogs.com/campus/besti/CS-IMIS-1723/homework/1933 (作业界面已评分,可随时查看,如果对自己的评分有 ...

  7. 20172325『Java程序设计』课程 结对编程练习&lowbar;四则运算第三周阶段总结

    20172325『Java程序设计』课程 结对编程练习_四则运算第三周阶段总结 结对伙伴 学号:20172306 姓名:刘辰 在这次项目的完成过程中刘辰同学付出了很多,在代码的实践上完成的很出色,在技 ...

  8. 结对编程学习fault、error、failure三种状态

    点滴成就 学习时间 新编写代码行数 博客量(篇) 学习知识点 第一周 10小时 0 0 了解软件工程 第二周 10小时 0 1 项目开题 第三周 15小时 0 1 开通博客.开展项目调查 第四周 20 ...

  9. 王译潇20162314 实验报告三plus结对编程四则运算第一阶段

    北京电子科技学院BESTI实验报告 课程:程序设计与数据结构 班级: 1623 姓名: 王译潇 学号:20162314 指导教师:娄佳鹏老师.王志强老师 实验日期:2017年5月12号 实验密级: 非 ...

随机推荐

  1. makefile 函数集

    1 if 函数 语法 $(if CONDITION,THEN-PART[,ELSE-PART]) 功能 第一个参数"CONDITION",在函数执行时忽略其前导和结尾空字符,如果包 ...

  2. storm坑之---同步问题

    最近在做一个监控系统,用来监控网站上各个业务功能的调用量以及处理时间,以便及时发现问题,及时处理.做这种实时统计处理系统,自然首先想到了storm,于是现学现用,自然遇到了一些坑,而且不少是网上也难以 ...

  3. mongo的insert和save比较

    insert仅仅是插入文档到集合中,如果记录不存在则插入,如果记录存在则忽略 save是在文档不存在时插入,存在时则是更新 下面代码不是为了演示insert和save的: foreach ($mens ...

  4. Linux 安装 jdk8

    切换目录 cd /usr 创建目录 mkdir java cd java 下载 jdk rz 或者 ftp 都行,只要能成功上传 解压 tar zxvf jdk-8u181-linux-x64.tar ...

  5. MySQL修改端口号操作

    在C盘下的program Files下找到MySQL文件夹 - my.ini配置文件有个port=3306 修改即可

  6. Ruby的DevKit名词解释

    为了加快运行速度,Ruby下好多扩展包都是用C语言写的二进制包,如果我们要安装就要重新编译,DevKit包主要就是将编译用的工具链打包,解决了众多依赖问题,方便了群众. 但是,在实际安装中,可能还会遇 ...

  7. Shiro和Spring 集合实现同一个账号只能一个人在线使用,其它人在使用进行剔除(八)

    1.实现原理其实就是自定义过滤器,然后登录时,A登录系统后,B也登录了,这个时候获取此账号之前的session给删除,然后将新的session放入到缓存里面去,一个账户对应一个有序的集合 编写自定义过 ...

  8. UOJ&num;80 二分图最大权匹配 &lbrack;模板题&rsqb;

    从前一个和谐的班级,有 nlnl 个是男生,有 nrnr 个是女生.编号分别为 1,…,nl1,…,nl 和 1,…,nr1,…,nr. 有若干个这样的条件:第 vv 个男生和第 uu 个女生愿意结为 ...

  9. 如何重新签名ipa文件

    http://www.cocoachina.com/bbs/read.php?tid=185963 求ipa文件修改后重新打包的方法,我已经有开发者账号了. 替换了ipa里的图片后,就无法安装了,似乎 ...

  10. PHP中create&lowbar;function的用法总结

    在php中,函数create_function主要用来创建匿名函数,有时候匿名函数可以发挥它的作用. 1.测试一 测试一主要用来循环替换数组中多个值的<与>,我们用array_map加上c ...