一板一眼就会滋生弱点。这份工作,不是为业余人士而准备的。自负会让每个人都屈膝下跪。要么打,要么跑,优柔寡断令人厌恶。为仆则忠,为主则殆,这便是道德。合适的话语胜过锋利的刀子。

_ A maoのBlog

软工实践寒假作业(2/2)

软工实践寒假作业(2/2)

这个作业属于哪个课程 2021春软件工程实践|S班 (福州大学)
这个作业要求在哪里 软工实践寒假作业(2/2)
这个作业的目标 重新阅读《构建之法》并提出问题,学会使用GitHub管理代码,按要求编写程序
其他参考文献 《腾讯C++代码规范》 、SCDN

目录

-Part1:重新阅读《构建之法》并提出问题
-Part2:实现WordCount程序
--- GitHub项目地址
--- PSP表格
--- 解题思路描述
--- 代码规范制定链接
--- 设计与实现过程
--- 单元测试
--- 异常处理说明
--- 心路历程与收获

Part1:重新阅读《构建之法》并提出问题

Q1、原文:P146.MSF团队模型

​ MSF模型定义了成员的角色和要职。疑问就是,成员不一定都是100%的高手,必然出现“短板”,不一定能达到质量目标,用雷达图来比喻就是图形不是正多边形。对于一个畸形的多边形,做出如何的选择才能让面积最大化,也就是目标最优化,这其中必然有取舍,如:牺牲时间,保证质量,但客户等不及;功能不完善,从而限制产品的使用方式,但很快就被市场淘汰......所以,在各种条件的约束下,怎样才做出好产品,满足需求?

Q2、原文:P176.计划、估计与决心

​ 我觉得这是一个很不常见的问题却又十分重要,因为在我的周围很少人会对写代码进行系统一样的行为,多是把好的idea进行实现,或许已经在脑海里进行了计划但自己不知道。于是,这两个名词,我是第一次听到,我自己都很难想象。但我觉得,大项目或任务是肯定要提前规划的吧?以至于都还没开始进行,脑海里就已经有了宏伟蓝图。所以,计划、规划在我脑海里没什么轻重的概念,那我想形成这种思维,应该如何计划,做什么样的的计划?

Q3、原文:P362.创新的时机

​ 对我来说创新的时机是一个很麻烦的事,我通常会在需求分析的进行创新。但现实是,一开始的创新或者过早的创新会对工作增加不成比例的难度,实现起来非常难,以至于严重阻塞任务进程。于是乎,放弃了一开始的不切实际的想法,尽量完成任务需求,直到完成。最后发现平平无奇的代码就产生了,然后又想进行创新,发现没地方下脚?或者一插足就立马遇到N多bug,然后工作又回到了原点。最后一种是我感觉最慢的方式,就是边进行工作边创新,毫无疑问问题是环环相扣的。所以,时机是在什么时候最恰当?

Q4、原文:P408.划分等级和公开刺激的做法

​ 对团队成员进行ABC等级划分并贴上标签的做法,我觉得有没有一种情况是:对A会A+,对C会C-呢?在中间得B因为觉得无所谓,他会变成A或是C,虽然我们可能会说得看他本人。话虽如此,但我得想法是,划分等级和贴标签的出发点是什么?是鼓励员工吗?还是在筛选员工,C淘汰,A和B留下?说到底ABC什么的确确实实会存在,但员工并不像商品那样随意拨动。我觉得程序员在社会中应该是以复数的形式存在,一个人能力如何出众,脑子都有累的时候,一个人是不可能项目开发的,从需求分析到维护都是一个人的话?谁又会进公司呢?既然这种方式各有利弊,那么划分等级对程序员来说是好是坏?

Q5、原文:P422.大马哈鱼洄游模型

​ 这个模型的名字挺有意思的,于是就仔细了解了一下。让我想起了我们大学里学专业课,貌似不是按照瀑布模型来的吧?从开学第一学期就在稳定阶段:学生开始写代码。可是没有在做需求分析阶段的事。这似乎很矛盾,《面向对象设计与分析》并不是入学的第一门课。假设,是第一门课的话,那么第一个学期内学生是不是都在对代码纸上谈兵呢?但又有人说,学好理论基础对敲代码不是好处更多吗?显然易见,一次瀑布模型感觉力度不够,于是多次瀑布模型才是大马哈鱼洄游模型。但是,这对普通的软件工程学生来说,我们不是成熟的大马哈鱼,洄游适合我们吗?还是说那是我们进社会的事了?(虽然我脑海里一直闪烁“优胜劣汰”)

Part2:实现WordCount程序

[GitHub项目地址](https://github.com/Lious-Rios/WordCount/tree/main/221801202)

PSP表格

  • PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
    Planning 计划
    • Estimate • 估计这个任务需要多少时间 4天 6天
    Development 开发
    • Analysis • 需求分析 (包括学习新技术) 120 150
    • Design Spec • 生成设计文档 30 50
    • Design Review • 设计复审 10 20
    • Coding Standard • 代码规范 (为目前的开发制定合适的规范 40 30
    • Design • 具体设计 60 70
    • Coding • 具体编码 720 1200
    • Code Review • 代码复审 50 40
    • Test • 测试(自我测试,修改代码,提交修改) 600 540
    Reporting 报告
    • Test Report • 测试报告 120 90
    • Size Measurement • 计算工作量 30 20
    • Postmortem & Process Improvement Plan • 事后总结, 并提出过程改进计划 90 60
    合计 4天内的1870min 6天内的2270min

解题思路描述

​ 刚看到题目的时候,已经初步想好了对几个功能的实现:1.定义一个文章类Paper,里面有两个函数:fread()和fwrite()对文件进行操作,用map接收单词。2.单词类Words定义了有效词频。3.判断是否为分隔符的函数。4.判断是否为有效单词的函数。5.字符统计、行数统计、单词统计、词频统计。6.先词频排序,然后字典排序。

代码规范制定链接

代码规范制定链接

设计与实现过程

  • Paper类
    class Paper{//文章类 
    public:
    	void fread(char * filename);
    	void fwrite(char * filename);
    private:
    	map<string,int> words;
    };
    
  • sort排序
    int cmpare(const pair<string, int>& x, const pair<string, int>& y){  //value比较 
        return x.second > y.second;   
    }  
       
    void sort(map<string, int>& tMap,vector<pair<string, int> >& tVector){  //排序 
        for (map<string, int>::iterator curr = tMap.begin(); curr != tMap.end(); curr++)   
            tVector.push_back(make_pair(curr->first, curr->second));    
        sort(tVector.begin(), tVector.end(), cmpare);  
    }  
    
  • 判断的关键函数
    bool isSeparator(char c){//判断分隔符:所有非数字且非字母 
    	return !(isupper(c)||islower(c)||isdigit(c));
    }
    
    bool isValidWord(string str){//判断有效单词 
    	if (str.length()<4)
    		return false;
    	char c[10000];
    	strcpy(c,str.c_str());//转为字符数组 
    	for (int i=0;i<4;i++){
    		if((!(isupper(c[i])||islower(c[i])))){	
    			return false;
    		}
    	}
    }
    
  • 行数获取
    int CountLines(char *filename){//获取行数 
    	ifstream ReadFile;
    	int n=0;
    	char line[wordsmax/wordsPerRow];
    	string temp;
    	ReadFile.open(filename,ios::in);//用只读的方式读取文件
    	if(ReadFile.fail()){//文件打开失败:返回0
    	   return 0;
    	}
    	else{//文件存在
            while(getline(ReadFile,temp)!=NULL){
               n++;
            }
    		return n;
    	}
    	ReadFile.close();
    }
    
  • 特别注意

    因为试了很多方法,最终选择了如下函数将FILE和file判断为同一个单词

    transform(word.begin(),word.end(),word.begin(),::tolower);//读字符串转为小写字母
    
     /*在fwrite()中对单词的操作*/
     while (fin >> word)  {  	
    	transform(word.begin(),word.end(),word.begin(),::tolower);
    	   if(isValidWord(word)){//判断为有效单词
    	       pair<map<string,int>::iterator,bool> ret = tMap.insert(make_pair(word, 1));  
    	       if (!ret.second)  
    	          ++ret.first->second; 
    			wcnt++;
    	}
     }   
     vector<pair<string,int> > tVector;  
     sort(tMap,tVector);
    

单元测试

  • 代码覆盖率如下图,我是挺意外的,不知该喜该悲

    coverage

异常处理说明

在对文件操作,方式为ios::in|ios::out时会覆盖原文件,因为我的几个统计函数是单独的,一直出现lines覆盖characters和words的情况,于是采用追加的方式。

	fin.open("input.txt",ios::app|ios::out);//打开文件 
	fout.open("output.txt",ios::app|ios::out);

文件打开失败

if(!fin.good()){//情况一
	cout<<"ifstream open file error"<<endl;
}

if(fin.fail()){//情况二
	cout<<"ifstream open file error"<<endl;
}

if(!fin){//情况三
	cout<<"ifstream open file error"<<endl;
	return -1;
}

心路历程与收获

  • 首先谈谈感触最深的地方:这次实践非常符合我内心的期望,尽管我绝对没做好,但是让“重新做人”的我认识到了,怎样去规划时间,想做快一点,实力不允许,效率地下;想做慢一点,时间不允许,效率低下。在期间,对于某个功能的实现让我陷入了死局,比如词频的排序(都还没涉及到字典),我第一个接触到的就是冒泡排序,这个的效率大家有目共睹。然后我尝试其他方法,什么都去尝试了,果然没让我失望,情理之中、意料之中的卡、死机,还有从没见过的error,我发誓,就算去百度了也只得到翻译,虽然看得懂。所以我把这种情况总结为:腿麻了的人想要奔跑——没实力。有点想自责,这是肯定的,而且并不归咎于其它因素。这一次战战兢兢地完成每一个功能,能实现到什么地步,心底没什么底,因此不能保证太高的正确率,因为瑕疵是有的,是真实存在的。那种“要是再给我一点时间,我肯定能完成”之类的没有自知之明的话,是极度不负责的,因为完成这道作业的时间是100%充裕的。完成作业后,我在深刻地反省。
  • 然后谈谈非常不错的收获:毋庸置疑的是,多多少少学会github的使用。其次,耐心是最大的收获,不再有轻浮、自大的自我意识过剩,哪怕敲得再烂、再臭,我都敲出来了,不会就学、查资料,搞懂为止!懒惰是我最大的敌人,畏首畏尾、不敢去尝试是我最致命的弱点。于是前段时间我把自己关进小黑屋里敲代码,物理意义上的小黑屋!我要改变自己!
posted @ 2021-03-04 23:52  蒲公英吹啊吹  阅读(125)  评论(4编辑  收藏  举报