第三次作业
1.在文章开头给出你们Fork仓库的Github项目地址
我的结对伙伴张欣 学号为201731035120作业地址https://www.cnblogs.com/xinzcover8520/p/10650115.html
我们的github地址是: https://github.com/jmddd/WordCount
2.描述结对的过程,提供非摆拍的两人在讨论的结对照片(一起工作编码时的照片)。
结对时一起在图书馆和寝室查资料,写代码,而且会互相监督。
3. 给出结对的PSP表格。
PSP是卡耐基梅隆大学(CMU)的专家们针对软件工程师所提出的一套模型:Personal Software Process (PSP, 个人开发流程,或称个体软件过程)。
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
75 | 90 |
· Estimate |
· 估计这个任务需要多少时间 |
75 | 90 |
Development |
开发 |
1005 | 1026 |
· Analysis |
· 需求分析 (包括学习新技术) |
60 | 90 |
· Design Spec |
· 生成设计文档 |
30 | 45 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
60 | 75 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
60 | 45 |
· Design |
· 具体设计 |
60 | 60 |
· Coding |
· 具体编码 |
480 | 600 |
· Code Review |
· 代码复审 |
90 | 120 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
150 | 225 |
Reporting |
报告 |
145 | 145 |
· Test Report |
· 测试报告 | 75 | 65 |
· Size Measurement |
· 计算工作量 |
25 | 35 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
45 | 45 |
合计 |
1225 | 1495 |
4.解题思路描述。即刚开始拿到题目后,如何思考,如何找资料的过程。
1.拿到题目后,我个人的思考如下
第一步实现基本功能:因为读文件里面的内容,所以先考虑到了从命令行读取文件路径,把文件内容以字符串的形式提取出来。把三个基本功能归到一个类里,对提取出的字符串进行操作、输出。
第二步增加新功能:因为新功能所需要的基本方法在前面差不多都实现了,所以可以在之前的类里面增加一个新的方法,来判断命令行输入的-m,-n [i],-o等命令,然后在这个方法里面取调用前面写的基本方法,只需要定义好合适的参数即可。
第三步接口封装:修改前面的public变量为private类型的,然后对每一个变量定义属性,并且新建一个类,把之前定义的类与Program分开;
2.实现基本统计的时候我在CSND中查找了如何读取到.txt文件中的内容,如何从字符串中分离出满足条件的单词和怎样按照字典序输出等问题,同时在统计字符数量的时候查找了C语言书上的ASCII码表格。
3.要实现输出内容到txt文件的时候,我在网上查找了如何正确的建立StreamWrit使程序在txt已有内容的后面按ASCII码输出内容;
4.查找如何正确的使用Dictionary<>和foreach,利用键\值排序、输出、统计,并且在输出到文件的时候也利用到了Dictionary<>。
5.设计实现过程。设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?单元测试是怎么设计的
代码实现:
1.main()读取文件提取为字符串形式;
2.建立WC()类,里面包含BaseCount(string str)统计字符数,行数单词数;
3.CountWords(string y, int v)统计各个单词出现的次数;
4.Put()通过StreamWriter()将输入内容到文件;
5.Display()分析命令从而调取前面三个函数并输出;
在命令行没有输入-n、-m等指令时仅输出由main调用的方法实现基本功能(统计单词数,字符数,行数并输入结果到文件);
单元测试:
主要针对WC类里的BaseCount()、CountWords()、 Display()等方法功能;
6.给出你们制定的代码规范或链接,记录你们代码互审的情况,审查的模块名、发现的问题等。
代码规范:
1.命名
1.类型命名:类名可以是该类的所包含的核心内容或作用的一个单词或几个单词的缩写,没有合适英文的时候可以拼音代 替;如一个包含家加、减、乘等算法方法的类可命名为Opertion,首字符大写;
2.所有命名空间、类型名称使用Pascal风格(单词首字母大写)
3.方法命名:方法名应体现出该方法是用来做什么的,最好使用一个英文单词或缩写,首字符大写;
4.属性命名:属性或者字段的命名可用对应的变量名首字符大写后表示;
5.变量与对象命名:此类命名必须小写,命名对象的时候可为其对应类的小写字母表示,若有多个对象便在后面加上数字表示;命名一些重要变量是最好能体现出该变量的含义,若是一些中间变量或累计变量等,可用一个字母表示;
6.本地变量、方法参数名称使用Camel风格(首字母小写,其后每个单词的首字母大写)
2.注释
1.在某些变量、方法等定义后,应根据需要添加注释,简单说明方法的作用(方便他人读懂代码);
2.如果类型、属性、事件、方法、方法参数的名称已经是自解释了,不需要加注释;
3.方法、类型等的注释必须位于所解释内容的上面一行,如果注释定义的变量,可位于同一行;
4.注释应使用完整的句子,且应该阐明代码不能增加代码的多义性;
3.代码书写
1.代码使用Tab作为缩进,并设置缩进大小为4,而且尽量不要在代码中使用Tab字符;
2.每个类或方法之间应有空行;
3.每行最多只有一个语句;
4.foreach、switch、while、if等必须严格按照语句体的要求加花括号,写语句内容,必须要有层次;若if语句体中只有一行语句,花括号和语句体可以在同一行;
5.类型成员的排列顺序必须分别按照要求:字段:私有字段、受保护字段属性:私有属性、受保护属性、公有属性事件:私有事件、受保护事件、公有事件;
6.尽量不使用强制类型转化,不使用goto语句;
7.尽量不要提供public 和 protected的成员变量,使用属性代替他们;
代码互审:
1.在代码互审的时候,发现对方有挺多注释的代码,这样不利于以后代码的查看。
2.代码审查时主要审查的模块是包含基本方法的类和主函数中方法的调用情况;
7.记录在改进程序性能上所花费的时间,描述你改进的思路,并展示一张性能分析图(由VS 2017的性能分析工具自动生成),并展示你程序中消耗最大的函数。
8.代码说明。展示出项目关键代码,并解释思路与注释说明。
统计单词个数:按照需求分割单词,并加入到Dictionary<>中,然后按照字典序、键值排序;
1 //统计单词个数; 2 public void CountWords(string y, int v) 3 { 4 Dictionary<string, int> fre = new Dictionary<string, int>(); 5 string x = y.ToLower(); 6 8 foreach (string word in words) 9 { 10 if (fre.ContainsKey(word)) 11 { 12 fre[word]++; 13 } 14 else 15 { 16 fre[word] = 1; 17 } 18 } 19 //字典序(新建了一个var ,fre是要被排序的Dictionary<string, int> fre,) 20 var frac = (from ac in fre orderby ac.Key ascending select ac); 21 //按值的排序 22 var fres = (from ob in frac orderby ob.Value descending select ob); 23 int j = 0; 24 foreach (KeyValuePair<string, int> k in fres) 25 { 26 Console.WriteLine("{0}:{1}", k.Key, k.Value); 27 putout2.Add(k.Key, k.Value); 28 j++; 29 if (j == v) break; 30 } 31 }
输出到文件
1 public Dictionary<string, int> putout1 = new Dictionary<string, int>(); 2 public Dictionary<string, int> putout2 = new Dictionary<string, int>(); 3 //把需要输出的加入putout1,putout2 4 5 public void Put(string Filename) 6 { 7 FileStream file = new FileStream(Filename, FileMode.Open, FileAccess.Write); 8 9 StreamWriter sw = new StreamWriter(file); 10 sw.BaseStream.Seek(0, SeekOrigin.End); 11 foreach (var f in putout1) //putout1,putout2是,把要输出的东西加到 Dictionary<string, int> putout1里 12 { 13 sw.WriteLine("{0}:{1}", f.Key, f.Value); 14 } 15 foreach (var f in putout2) 16 { 17 sw.WriteLine("{0}:{1}", f.Key, f.Value); 18 } 19 sw.Close(); 20 file.Close(); 21 22 }
9.结合在构建之法中学习到的相关内容与结对项目的实践经历,撰写解决项目的心路历程与收获,以及结对感受,是否1+1>2。
经过这次结对编程。我感受到了1+1>2的,尤其是找不到自己代码出现的错误的时,可能自己已经进入到一个误区,而同伴可以很快的找出来。对于不懂的问题与同伴讨论也许可以更快的找出答案。