天天看点

2019年结对编程项目结对编程项目之队友个人项目优缺点

结对编程项目之队友个人项目优缺点

子曰:三人行,必有我师焉;择其善者而从之,其不善者而改之。

虽然她给我找出bug时让我有点挫败感(因为当我费尽九牛二虎之力写完代码,实现要求中所有功能的时候,我感觉自己超级厉害,代码写得也很完美了),但是不得不承认,她说的都是对的。在需求分析中,我对要求有些误解,在代码实现中,又有些细节和特例没有考虑到。在她提出之后,我对自己的代码进行了完善。

她的代码有很多值得我学习的地方,但同样也有考虑不周的地方,我想,这大概就是结对编程的意义吧。

对方代码的思路

放个不是很规范的流程图来帮助理解吧

2019年结对编程项目结对编程项目之队友个人项目优缺点

这个流程图是队友画的,我个人觉这是一个很好的习惯,通过这个流程图可以清楚的看到队友代码的思路。

优点

1、括号考虑周全。在我的代码里,只考虑了一个题目中生成一个括号的情况。而她的代码,由于括号的位置和括号是否生成都是随机的,因此可以生成多个括号。这里以小学卷子的生成为例,附上代码进行详述。

for(k = 0; k < num; k++) { //题目数
			int num1 = rand()%4+2;    //操作数个数,小学的操作数一定是2-5个
			int bracket = 0;//判断生成左括号或右括号,为0时生成左括号然后立刻置1表明下一次生成右括号
			bool flag = 0;//排除一个括号将所有操作数都括住的这种特殊情况
			if(rand()%2==1) {//先处理第一个数
				flag = 1;
				result[k]+="(";
				bracket = 1;
				operand = rand()%100+1;       //生成操作数1~100
				sprintf(temp,"%d",operand);   //操作数转为字符串
				result[k] += temp;
			} else {
				operand = rand()%100+1;       //生成操作数1~100
				sprintf(temp,"%d",operand);   //操作数转为字符串
				result[k] += temp;
			}
			for(int i = 2; i < num1; i++) {
				if(rand()%2==1) {
					if(bracket == 0) {
						Oper = rand()%4;              //选择+,-,*,/
						result[k] += Operator1[Oper];
						result[k] += "(";    //生成"("
						operand = rand()%100+1;       //生成操作数1~100
						sprintf(temp,"%d",operand);   //操作数转为字符串
						result[k] += temp;
						bracket = 1;
					} else {
						if(flag == 1) {
							flag = 0;
						}
						Oper = rand()%4;              //选择+,-,*,/
						result[k] += Operator1[Oper];
						operand = rand()%100+1;       //生成操作数1~100
						sprintf(temp,"%d",operand);   //操作数转为字符串
						result[k] += temp;
						result[k] += ")";
						bracket = 0;
					}
				} else {
					Oper = rand()%4;              //选择+,-,*,/
					result[k] += Operator1[Oper];
					operand = rand()%100+1;       //生成操作数1~100
					sprintf(temp,"%d",operand);   //操作数转为字符串
					result[k] += temp;
				}
			}
			//对最后一个数的处理
			if(flag==1) {
				if(num1==2) {
					Oper = rand()%4;                //选择+,-,*,/
					result[k] += Operator1[Oper];
					operand = rand()%100+1;
					sprintf(temp,"%d",operand);
					result[k] += temp;
					result[k] += ")";

					Oper = rand()%4;                //选择+,-,*,/
					result[k] += Operator1[Oper];
					operand = rand()%100+1;
					sprintf(temp,"%d",operand);
					result[k] += temp;
				} else {		
					Oper = rand()%4;                //选择+,-,*,/
					result[k] += Operator1[Oper];
					operand = rand()%100+1;
					sprintf(temp,"%d",operand);
					result[k] += temp;
					result[k]+=")";
				}
			} else {
				if(bracket == 1) {
					Oper = rand()%4;              //选择+,-,*,/
					result[k] += Operator1[Oper];
					operand = rand()%100+1;       //生成操作数1~100
					sprintf(temp,"%d",operand);   //操作数转为字符串
					result[k] += temp;
					result[k]+=")";
				} else {
					Oper = rand()%4;              //选择+,-,*,/
					result[k] += Operator1[Oper];
					operand = rand()%100+1;       //生成操作数1~100
					sprintf(temp,"%d",operand);   //操作数转为字符串
					result[k] += temp;
				}
			}
			if(!Check(result[k],name,state)) {
				k=k-1;
			}
		}
           

这段代码很长,但是如果只看生成括号的那一部分其实很简单,比较复杂的是后面括号和操作数的结合,由于情况很多,她是按照情况分类来写的,所以会存在一些问题(说实话,我觉得操作数这一块我的处理稍微简单一些,可以和她的生成括号相结合可能就比较简洁了hhhh)。

2、程序在需要的时候自动生成文件夹。我是在放代码的文件夹里手动创建的文件夹,而不是由代码生成。这样子其实是有些取巧的,而且实用性不高,而队友的代码就很好,在没有文件夹创建文件夹,而文件夹存在的时候直接访问,无需创建文件夹了。

string path = "D:\\\\";
	path+=name;
	if(access(path.c_str(), 0) != 0) {
		mkdir(path.c_str());
	}
	if(state==1) {
		path+="\\\\小学\\\\";
	}
	if(state==2) {
		path+="\\\\初中\\\\";
	}
	if(state==3) {
		path+="\\\\高中\\\\";
	}
	if(access(path.c_str(), 0) != 0) {
		mkdir(path.c_str());
	}
	SYSTEMTIME sys;
	GetLocalTime(&sys);
	char tmp[64] ;
	sprintf(tmp,"%4d-%02d-%02d-%02d-%02d-%02d",sys.wYear,sys.wMonth,sys.wDay,sys.wHour,sys.wMinute,sys.wSecond);//以年月日时分秒对文件命名
	path += tmp;
	path += ".txt";
	ofstream outfile;
	outfile.open(path.c_str());
	if(!outfile) {
		cout<<"Unable to open outfile";
		exit(1);
	}
	for(int i=1; i<=num; i++) {
		outfile<<i<<"、"<<result[i-1]<<endl;
		outfile<<endl;
	}
           

3、思路清晰,函数的使用让代码结构清楚,各个模块的实现互不影响,但是模块与模块之间又紧密联系。

4、代码格式规范,注释简洁明了,变量名也一目了然。

缺点

1、忽略了一些小细节,例如输入-1时直接退出而不是重新登录,没有检查题目数目的有效范围,即当输入数字不在[10,30]之间时,也会生成卷子。

2、她的程序是先检查密码输入,所以当账号输入错误时程序就卡住了,无论输入什么都没有反应了。就这一点,我觉得还是应该先检查账号再检查密码,这样比较符合登录的习惯。

3、生成卷子的代码过于长,她的代码是分别处理小学、初中、高中的卷子,没有考虑代码重用。

继续阅读