湖南大学结对编程个人项目互评
一、简介
本博客为对黄昇阳同学的个人项目代码的评价
开发环境devc++
二、代码优缺点分析
黄昇阳同学将题目分为了可以由5个小部分分别解决的问题

generate_question_table用于生成文件名并将其存储到对应位置

通过time库以及对 字符串的处理 以及文件夹的锁定来储存生成的题目
Symbol是以操作数为基础,来生成对应操作数的题目,分为5种情况,随机产生数来设计产生不同类型的题目
string create_question(int Type){
string str="";
int OperandNumber=rand()%5+1;
if(OperandNumber==1&&Type==1) {
OperandNumber=rand()%4+2;
}
int oNum=OperandNumber;
int bracket_left=0;
int bracket_num=0;
if(OperandNumber>2&&rand()%2==1) { //生成的题目有括号
if(OperandNumber==3) {
bracket_left=rand()%2+1;
bracket_num=2;
} else if(OperandNumber==4) {
bracket_left=rand()%3+1;
if(bracket_left==3) bracket_num=2;//位于最后,最多只能括住两个数
else bracket_num=rand()%2+2;//位于前面,可以括住2-3个数
} else {
bracket_left=rand()%4+1;
if(bracket_left==4) bracket_num=2;//只能括住两个的情况
else if(bracket_left==3) bracket_num=rand()%2+2;//可以括住2-3个的情况
else bracket_num=rand()%3+2;//可以括住2-4个的情况
}
}
bool flag=false;//确保初中的每道题目中都至少有平方或者根号,高中的每道题都至少有sin,cos或tan中的一个
while(oNum!=0) {
oNum--;
if(oNum==OperandNumber-bracket_left) str+="(";
int option;
if(Type==1) option=0;
else if(Type==2) {
option=rand()%3;
if(option!=0) flag=true;//说明已经生成了平方或者根号中的一个了
if(oNum==0&&flag==false) option=rand()%2+1;
} else if(Type==3) {
option=rand()%6;
if(option>2) flag=true;//说明已经生成了平sin,cos或tan中的一个了
if(oNum==0&&flag==false) option=rand()%5+1;//说明一直到最后一个操作数都没有sin,cos或tan,则最后一个必须有
}
int Operand=rand()%100+1;
string str1=Symbol(option,Operand);
str+=str1;
if(oNum==OperandNumber-bracket_left-bracket_num+1) str+=")";
if(oNum!=0) {
int opt=rand()%4;
switch(opt) {
case 0:
str+="+";
break;
case 1:
str+="-";
break;
case 2:
str+="*";
break;
case 3:
str+="/";
break;
}
} else str+="=";
}
return str;
}
通过rand()随机产生数来产生题目,比如产生加减,产生操作数,产生题目类型,产生括号 等等,通过这种方法来产生题目具有一定的随机性,很好的符合了 产生题目 这一思想
create_question是自动生成题目,包括生成操作数,产生括号,运算符号

其中调用了symbol函数来产生运算 ,之后也通过随机产生的opt来产生 加减乘除运算
main就是主要运行程序,从输入账号密码并进行判断,到调用以上4个函数来产生试卷,切换账户,功能齐全,但在main函数中的笔墨太多,函数封装性比较差,这一部分看上去 有一些眼花缭乱,一些代码如果也可以作为功能的一部分写成函数调用,在检查代码错误是也会更加方便一些。
while(1) { system("cls"); while(1) { cout<<"*******************欢迎来到出题系统登录界面*******************"<<endl; cout<<"*******************请输入您的账号以及密码*********************"<<endl; string str1,str2; cin>>str1>>str2; //define区 ,尽可能把定义一次性完成 //将输入处理为字符数组 int e;//后面输入的题目数量 int l1=str1.length(); int l2=str2.length(); char a1[l1]={""},a2[l2]={""}; memset(a1,0,sizeof(a1)); memset(a2,0,sizeof(a2)); strtochar(str1,a1,l1); strtochar(str2,a2,l2); //处理完毕,开始与创建的九个教师账户一一比对,如果不匹配,则账号密码异常,请重新登录。 if(!login(a1,a2)) { cout<<"登陆失败,请检查用户名密码是否有误"<<endl; system("pause"); break; } cout<<"登录成功..."<<endl; system("pause"); system("cls"); while(1) { cout<<"请选择"<<endl<<"1.生成题目 2.切换类型 "<<endl; string str; cin>>str; if(str=="生成题目") { system("CLS"); //输入10-30间,打开对应的文件并按要求写入。-1则退出登录,返回登陆界面 cout<<"准备生成"<<p[t0->rt()]<<"题目,请输入出题数量"<<endl; cout<<"注:您可以选择生成10到30任意一个数目的题目,如果您想退出当前账号请按-1"<<endl; cin>>e; if(e==-1) { //退出登录,并且返回登陆界面 t0->leave(); t0=NULL; break; } else if(e>=10&&e<=30)//向相应文件夹中加入出题的记录 { //打开相应的文件夹,在该文件夹中创建一个以日期为名的txt文件 // 写一个函数,生成一系列表达式并输入到该文件中 //ofstream of; //of.open(t0->rfn(),ios::out); generate_question_table(e,t0); } else { //输入不符合规范,强行退出重新登录 cout<<"输入有误,强行退出,请重新登录"<<endl; t0->leave(); t0=NULL; system("pause"); break; } } else if(str=="切换出题类型") { //切换出题类型 system("CLS"); cin>>str; if(str=="小学") e=1; else if(str=="中学") e=2; else if(str=="高中") e=3; t0->change_Type(e); system("CLS"); cout<<"转换成功"; system("pause"); system("CLS"); cout<<"操作完成,即将返回操作界面"<<endl; system("pause"); }
代码框架总的来说清晰明了,代码命名也容易理解
优点:
代码分段清晰,阅读起来并不会特别麻烦。
在生成题目函数部分,先生成数字和加减乘除的简单组合也就是小学难度的题,之后是随机生成根号和平方,再往下就检测难度如果是高中,就加入三角函数,这样就让代码特别的简洁高效
缺点分析:
运行程序时的文字引导做的不是特别贴切,容易产生误解

当我第一次运行 时我下意识是 输入1来选择生成题目但正确的输入应该是输入“生成题目”,而切换类型时的 输入是 输入“切换出题类型”
部分地方缩减不是特别清楚,在代码检查来说可能有点困难
封装性较低
浙公网安备 33010602011771号