HNU中小学数学卷子自动生成程序——队友个人项目分析

2022/9/14 14:19:05

本文主要是介绍HNU中小学数学卷子自动生成程序——队友个人项目分析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一、概要

本博客是对结对编程队友郭冬妮同学的个人项目代码的分析和总结,郭同学用的是c++语言,我用的是java语言。虽然编程语言不同,但c++和java的类似性方便我们相互学习,也加深另一种编程语言的掌握,相互借鉴。

二、代码架构

郭同学使用的是面向对象编程,文件分为三部分,层次分明

  • User.h
  • User.cpp
  • main.cpp

 User.h

 1 class User{
 2     private:
 3         string Name;//用户名 
 4         string Password;//密码 
 5         string Type;//账号类型 
 6         int Quecount;//题目数量 
 7         ofstream out;
 8     public:
 9         void Sign();//登录函数 
10         void Create_paperfolder();//生成用户文件夹函数 
11         void Create_questions(int n);//生成题目函数 
12         bool Check(string question,string Name);
13         void Change_type();
14 };

 

在头文件中声明了User类,变量里设置了用户必须的属性:用户名,密码,账号类型。但是也申明了没必要的变量Quecount(题目数量)

不必要原因如下

  1. 逻辑定义不符,一个老师可以生成很多卷子,卷子的题目数量可以各不相同。老师与题数的对应关系没那么紧密,如果有卷子这个Class,那么可以将题数作为卷子的一个属性

申明函数:郭同学在将所有用户需要的函数封装载User中,从而使得main函数简洁。值得学习!函数具体内容在后面分析

User.cpp

郭同学在User.h中只写入函数声明,在User.cpp中对函数进行定义,使得代码较为清晰,值得我们的学习。

现在来分析每个函数的优缺或者是否优雅

  1. Sign()
 1 while(true) {
 2         cout<<"=====登录====="<<endl;
 3         cin>>Name>>Password;
 4         if(Name=="张三1"||Name=="张三2"||Name=="张三3") {
 5             if(Password=="123") {
 6                 Type="小学";
 7 
 8                 break;
 9             }
10         } else if(Name=="李四1"||Name=="李四2"||Name=="李四3") {
11             if(Password=="123") {
12                 Type="初中";
13 
14                 break;
15             }
16         } else if(Name=="王五1"||Name=="王五2"||Name=="王五3") {
17             if(Password=="123") {
18                 Type="高中";
19 
20                 break;
21             }
22         } else {
23             cout<<"=====请输入正确的用户名、密码!====="<<endl;
24             cout<<endl;
25         }
26     }
27     cout<<endl;
28     cout<<"=====当前选择为"<<Type<<"出题====="<<endl;
29     cout<<endl;
30     Change_type();
31     Create_paperfolder();

这段代码我一直觉得可以说是相当丑陋,不像是美丽漂亮的郭同学应该写出的代码(doge)。

  1. 代码扩展性极差,一但用户增加或者减少,或者是密码不都是123,代码都要进行很大的改动,不符合规范化编程的要求

用户的账号密码等信息应该是需要保存在本地,不然一但系统奔溃或者系统重启数据就会丢失。因此小声建议郭同学可以将用户数据放在本地,然后用文件流进行读取,在放到程序的数据结构中

  2.登录之后没有类似于"请输入账号和密码的提示语",不具有用户亲和性

   2.Create_paperfolder()和Check()

Create_paperfolder()

 1 if(access(Name.c_str(), 0) != 0) { //创建用户名对应的文件夹
 2         mkdir(Name.c_str());
 3     }
 4 
 5     cout<<"=====准备生成"<<Type<<"数学题目====="<<endl;
 6     cout<<"=====请输入生成题目数量(输入-1将退出当前用户,重新登录):"<<endl;
 7     cin>>Quecount;
 8 
 9     while(Quecount>30||Quecount<10) {
10         if(Quecount==-1) {
11             Sign();
12             break;
13         } else {
14             cout<<"=====输入的题目数量无效,请重新输入:"<<endl;
15             cin>>Quecount;
16         }
17     }
18 
19     char Filename[50];
20     time_t It=time(NULL);
21     strftime(Filename, 50, "%Y-%m-%d-%H-%M-%S.txt", localtime(&It));
22     string Path=Name+"\\"+Filename;
23 
24     out.open(Path.c_str());//创建文件,以年月日格式命名
25     out<<"试卷科目:数学"<<"====="<<"难度:"<<Type<<"====="<<"题目数量:"<<Quecount<<endl;
26 
27     Create_questions(Quecount);//题目生成函数
28 
29     out.close();

Check()

 1 bool User::Check(string question,string Name) {
 2     string Checkpath=Name+"\\"+"Allquestion.txt";
 3     ifstream Checkin;
 4     Checkin.open(Checkpath.c_str());
 5     string existquestion;
 6     while(Checkin >> existquestion) {
 7         if(existquestion==question) {
 8             return false;
 9         }
10     }
11     Checkin.close();
12 
13     ofstream Checkout;
14     Checkout.open(Checkpath.c_str(),ios::app);
15     Checkout<<question<<endl;
16     Checkout.close();
17 
18     return true;
19 }

这里得夸一下郭同学,

优点如下:

  1. 这两个代码都是对输入输出流以及文件对象的操作,郭同学这两端代码写的都很好,无论是文件的格式化命名,还是输出输出流的操作,没有冗余的部分,我从中也回顾了c++的流操作和文件操作,谢谢郭同学。
  2. 这两个代码的功能都很好的实现了。第一个生成文件夹,命名规范,第二个查重,每次生成一个题目的时候都会放到张三的题库中,同时放进去的时候也对这个题目进行查重,设计很好。

当然也有缺点,这个缺点也是我自己代码存在的,

  1.我们的查重都是对所有题目进行直接遍历,当题目越来越多的时候,性能难免会受到影响。我之前想过将题目放进Hashmap中,题目这个String就作为Hashmap的key,从而查重的时候每个题目查重的复杂度变成了O(1),而且复杂度不会随着题目容量的变大而变大。希望后面和郭同学一起改进。

Create_questions() 这里是生成题目的函数,也是程序实现功能的部分,根据测试可以知道代码功能实现的很好。但明显的是代码可读性较差,因为不遵守Google代码规范造成的。也狠狠的提醒我了要好好遵守代码规范,不规范的代码真的dog都不看。建议郭同学好好阅读Google C++ Style。

 main.cpp

1 int main() {
2     User teacher;
3     teacher.Sign();
4     return 0;
5 }

因为郭同学程序结构分明和包装性好,main函数简洁明了!

 三、功能测试

  • 登录,登录后的显示,账号密码错误的显示

 缺点

  1. 没有显示“中小学生数学卷子自动生成系统”的字样,就一个简单的登录,引导性偏弱
  2. 登录的时候没有说“请输入账号和密码”,用户可能不知道操作
  3. 账号密码错了之后,也只是显示登录,应该显示账号或密码错误请重新登录,不然用户可能以为是系统问题而不是自己输入有误
  • 切换功能(不完全实现)
  1. 原因:郭同学的系统只能生成一次试卷,生成第二章试卷的时候可以生成,但系统关闭。从而导致无法连续生成试卷

  ToDO:建议郭同学查看自己的整个流程,查看哪里没有该循环的地方没有循环等等

  

 

 

   该图输入回车后直接退出!

  • 文件夹和试卷生成(完美实现)
  1. 功能实现完整,文件夹命名符合要求,试卷文件名符合要求。题目类型格式符合要求,卷子内容也经过查重没有重复存在

 

 

 

 

 

四、总结

   郭同学的代码采用了结构化和面向对象的思想,使得整体结构清晰易懂。但功能实现不完全,细节方面还有很多需要注意。例如代码规范和代码可读性,用户体验,引导性,以及程序优化性和可扩展性。这些都是郭同学在个人项目中表现不足的地方。在进行互评的时候我也去回想我的代码,有没有相同的问题,以及如何解决郭同学的问题。这些都给我带来了很多思考机会和体验。在之后的结对编程中,我也会和郭同学好好沟通,争取做出优秀的程序。

 



这篇关于HNU中小学数学卷子自动生成程序——队友个人项目分析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程