项目要求
项目名称:中小学数学卷子自动生成程序
用户:
小学、初中和高中数学老师。
功能:
1、命令行输入用户名和密码,两者之间用空格隔开(程序预设小学、初中和高中各三个账号,具体见附表),如果用户名和密码都正确,将根据账户类型显示“当前选择为XX出题”,XX为小学、初中和高中三个选项中的一个。否则提示“请输入正确的用户名、密码”,重新输入用户名、密码;
2、登录后,系统提示“准备生成XX数学题目,请输入生成题目数量:”,XX为小学、初中和高中三个选项中的一个,用户输入所需出的卷子的题目数量,系统默认将根据账号类型进行出题。每道题目的操作数在1-5个之间,操作数取值范围为1-100;
3、题目数量的有效输入范围是“10-30”(含10,30),程序根据输入的题目数量生成符合小学、初中和高中难度的题目的卷子(具体要求见附表)。同一个老师的卷子中的题目不能与以前的已生成的卷子中的题目重复(以指定文件夹下存在的文件为准,见5);
4、在登录状态下,如果用户需要切换类型选项,命令行输入“切换为XX”,XX为小学、初中和高中三个选项中的一个,输入项不符合要求时,程序控制台提示“请输入小学、初中和高中三个选项中的一个”;输入正确后,显示“”系统提示“准备生成XX数学题目,请输入生成题目数量”,用户输入所需出的卷子的题目数量,系统新设置的类型进行出题;
5、生成的题目将以“年-月-日-时-分-秒.txt”的形式保存,每个账号一个文件夹。每道题目有题号,每题之间空一行;
附表-1:账户、密码
账户类型 |
账户 |
密码 |
备注 |
小学 |
张三1 |
123 |
|
张三2 |
123 |
||
张三3 |
123 |
||
初中 |
李四1 |
123 |
|
李四2 |
123 |
||
李四3 |
123 |
||
高中 |
王五1 |
123 |
|
王五2 |
123 |
||
王五3 |
123 |
附表-2:小学、初中、高中题目难度要求
小学 |
初中 |
高中 |
||
难度要求 |
+,-,*./ |
平方,开根号 |
sin,cos,tan |
|
备注 |
只能有+,-,*./和() |
题目中至少有一个平方或开根号的运算符 |
题目中至少有一个sin,cos或tan的运算符 |
代码分析
·优点
1、变量名、函数名命名准确,符合代码规范要求,通俗易懂无歧义;
2、语句书写符合规范要求;
3、总体结构较清楚,包括小学、初中和高中的三个出题函数,以及最后的主函数。
·缺点
队友之前因个人原因导致完成项目时间较少,项目结束的仓促,故留下了许多问题,在此正好进行分析,希望大家以后不要再犯。
1、代码无注释
虽然原则上是应尽量减少程序体内代码的注释,应该保持代码本身的直接可读性,但是完全没有注释是非常不好的习惯, 程序员枪击了解一下。良好的代码注释习惯,不仅增强了代码的可读性,提高编程效率,还可以增强自己本身对代码的理解,不管多久之后还是能够快速上手自己的代码。
2、代码重复
判断语句中的代码重复性非常高,完全可以替换成带参数的函数,使代码更加简洁美观,拷代码可是程序可维护性的杀手。
string s; while(cin>>s) { if(s=="切换为小学") { cout<<"准备生成小学数学题目,请输入生成题目数量"<<endl; cin>>count; time_t t=time(0); char buffer[128]; struct tm *timeinfo; timeinfo= localtime (&t); strftime(buffer, sizeof(buffer), "%Y-%m-%d-%H-%M-%S", timeinfo); string a="/Users/jamesruio/Desktop/试卷集/"; string path=a+username+‘/‘+buffer; string filename=path+".txt"; for(int i=0;i<count;i++) { ofstream out1; out1.open(filename,ios::app); out1<<"第"<<i+1<<"题:"; out1.close(); PrimarySchool(filename); out1.open(filename,ios::app); out1<<endl; out1.close(); } } else if(s=="切换为初中") { cout<<"准备生成初中数学题目,请输入生成题目数量"<<endl; cin>>count; time_t t=time(0); char buffer[128]; struct tm *timeinfo; timeinfo= localtime (&t); strftime(buffer, sizeof(buffer), "%Y-%m-%d-%H-%M-%S", timeinfo); string a="/Users/jamesruio/Desktop/试卷集/"; string path=a+username+‘/‘+buffer; string filename=path+".txt"; for(int i=0;i<count;i++) { ofstream out1; out1.open(filename,ios::app); out1<<"第"<<i+1<<"题:"; out1.close(); JuniorHighSchool(filename); out1.open(filename,ios::app); out1<<endl; out1.close(); } } else if(s=="切换为高中") { cout<<"准备生成高中数学题目,请输入生成题目数量"<<endl; cin>>count; time_t t=time(0); char buffer[128]; struct tm *timeinfo; timeinfo= localtime (&t); strftime(buffer, sizeof(buffer), "%Y-%m-%d-%H-%M-%S", timeinfo); string a="/Users/jamesruio/Desktop/试卷集/"; string path=a+username+‘/‘+buffer; string filename=path+".txt"; for(int i=0;i<count;i++) { ofstream out1; out1.open(filename,ios::app); out1<<"第"<<i+1<<"题:"; out1.close(); SeniorHighSchool(filename); out1.open(filename,ios::app); out1<<endl; out1.close(); } }
3、过长函数
主函数有百多行代码,大大提高了程序的理解难度,建议Extract Method(提炼函数) 适用于 99% 的过长函数情况, 只要将函数中冗长的部分提取出来, 放到另外一个函数中即可。小函数具有更强的解释能力, 共享能力, 选择能力, 小函数维护性比较好, 拥有小函数的类活的比较长。
如时间获取完全可以写为一个函数而不是多次插入在主函数中
time_t t=time(0); char buffer[128]; struct tm *timeinfo; timeinfo= localtime (&t); strftime(buffer, sizeof(buffer), "%Y-%m-%d-%H-%M-%S", timeinfo);
4、部分代码效率低
代码中还有许多可以优化的地方,如以下代码可以修改成switch()语句以提高程序效率。
if(nandu==1) { for(int i=0;i<count;i++) { ofstream out1; out1.open(filename,ios::app); out1<<"第"<<i+1<<"题:"; out1.close(); PrimarySchool(filename); out1.open(filename,ios::app); out1<<endl; out1.close(); } } else if(nandu==2) { for(int i=0;i<count;i++) { ofstream out1; out1.open(filename,ios::app); out1<<"第"<<i+1<<"题:"; out1.close(); JuniorHighSchool(filename); out1.open(filename,ios::app); out1<<endl; out1.close(); } } else{ for(int i=0;i<count;i++){ ofstream out1; out1.open(filename,ios::app); out1<<"第"<<i+1<<"题:"; out1.close(); SeniorHighSchool(filename); out1.open(filename,ios::app); out1<<endl; out1.close(); } }
switch(nandu) { case 1: statements; break; case 2: statements; break; case 3: statements; break; }
5、代码逻辑不清晰
有可以放入函数的部分,不应该写在主函数中引起逻辑混乱,如下代码打开关闭文件多次,其实可以写在PrimarySchool(filename)中,只需打开一次即可,提高效率同时也使代码更加简洁美观。
if(nandu==1) { for(int i=0;i<count;i++) { ofstream out1; out1.open(filename,ios::app); out1<<"第"<<i+1<<"题:"; out1.close(); PrimarySchool(filename); out1.open(filename,ios::app); out1<<endl; out1.close(); } }
6、缺少项目要求功能
项目要求同一个老师的卷子中的题目不能与以前的已生成的卷子中的题目重复,而代码中缺少题目查重功能的实现。
总结
编程习惯是编程非常重要的一部分,好的习惯能够大大提升程序效率,使得代码规模小,简洁美观,可读性强,也提升了代码扩展性。最后希望在结对编程中能够与队友互相学习,使得自身都能得到最大的提升。
原文地址:https://www.cnblogs.com/jiangjiangjiang/p/9708410.html