个人项目互评

发布时间 2023-09-19 17:24:35作者: hwssss

一、简介

1、 项目名称:中小学数学卷子自动生成程序

2、 编程语言:C++

3、 完成情况:按照个人项目需求完成了要求的功能

4、 完成同学:贾媛媛,评价者:黄婉珊

二、功能及完成情况测试

1、 登录功能:在输入错误的用户名和密码时会提示错误,并能在输入正确后正常登入,功能完整、正确。

 

2、 题目生成功能:能正确生成文件名为当时时间的txt文档;

 

小学、初中、高中题目符合要求(如下图)

 

输入题目数量错误时会提示错误

 

可见生成题目功能完整、正确。

3、 切换类型功能:

输入正确的用户名和密码后,根据提示输入切换为xx,可以正确修改题目类型,可以看到正确切换后就能生成新更改类型的题目了。

 

如果输入的不符合格式,会提示错误。

 

总的来说,切换类型功能完整、正确。

三、代码结构

一共有三个cpp文件和两个.h头文件,分别负责登录、生成题目、切换类型

 

四、核心代码分析

头文件:

头文件中分别为Generator类和Teacher类;在public中存放函数,在private中存放变量。使用private能更好地保护数据,提供更好的封装性。

#ifndef INC_202126010313PERSONALPROJECT_GENERATOR_H
#define INC_202126010313PERSONALPROJECT_GENERATOR_H
#include <string>
class Generator{
private:
    std::string directory_path_;//文件夹路径
    std::string question_type_;//试题难度
    int question_account_{};//需要生成的题目的数量
public:
     Generator();
     Generator(const std::string& directory_name,std::string question_type);
     bool SetQuestionAccount(int num);//设置题目数量
     bool DirectoryGenerator();//生成文件夹
    void PaperGenerator();//生成试卷
    std::string GetTime();//获取系统时间
    void FileGenerator(const std::string& file_name);//生成文件
    static bool QuestionCheck(const std::string& generated_question,const std::string& existing_question);//题目重复性比对
    std::string QuestionGenerator();//生成题目
    bool GetExistingQuestions(std::string generating_question);//将当前生成题目与已存在的题目比对
};
View Code
#ifndef INC_202126010313PERSONALPROJECT_TEACHER_H
#define INC_202126010313PERSONALPROJECT_TEACHER_H
#include <string>
class Teacher{
private:
    std::string my_type_;
    std::string my_account_;
    std::string my_password_;
public:
     Teacher();
     Teacher(std::string type,std::string account,std::string password);
     std::string GetType();
     std::string GetAccount();
     bool ChangeType(std::string new_type);
     bool LoginCheck(std::string input_account,std::string input_password);
};
View Code

Generator.cpp:

生成题目只用了一个函数,可以按照需求生成小学、初中或高中题目,不需要使用三个函数分别生成,使得代码有较强的复用性。

std::string Generator::QuestionGenerator() {
    char low_symbol[4]={'+','-','*','/'};
    std::string moderate_symbol[2]={"^2",""};
    std::string high_symbol[3]={"sin","cos","tan"};
    int num_operator=rand()%4+2;//随机生成2-5的数字作为操作数个数
    std::string result[num_operator*2-1];//用来保存题目生成的最终结果
    std::string operators[num_operator];//保存生成题目中的操作数
    std::string symbols[num_operator-1];//保存生成题目中的符号
    for(int i=0;i<num_operator;i++) {
        operators[i] = std::to_string(rand() % 100 + 1);//随机生成1-100的数字作为操作数
        if (this->question_type_ == "高中") {
            if (rand() % 2 == 0) {
                operators[i] = high_symbol[rand() % 3] + operators[i];//随机在操作数前加上三角函数符号
            }
        }
        if (this->question_type_ == "初中" || this->question_type_ == "高中")
            if (rand() % 2 == 0)
                if (rand() % 2 == 0) {
                    operators[i] = operators[i] + moderate_symbol[0];//随机在操作数加上平方符合
                } else {
                    operators[i] = moderate_symbol[1] + operators[i];//随机在操作数前加上根号符号
                }


        result[i * 2] = operators[i];//将操作数保存到结果数组的对应位置
    }
    for(int i=0;i<num_operator-1;i++){
        symbols[i]=low_symbol[rand()%4];//随机生成题目中的运算符
        result[i*2+1]=symbols[i];//将运算符保存到结果数组的对应位置
    }
    if(num_operator>=3){
        int left=rand()%(num_operator-1)*2;//确定左括号的位置
        int tmp=num_operator-(left/2+1);
        int length=0;
        if(left!=0){
            length=(rand()%tmp+1)*2;//随机生成括号长度
        }
        else{
            length=(rand()%(tmp-1)+1)*2;//随机生成括号长度
        }
        int right=left+length;//确定右括号位置
        result[left]="("+result[left];
        result[right]=result[right]+")";//在操作数前后加上左右括号
    }
    std::string res;
    for(int i=0;i<num_operator*2-1;i++){
        res+=result[i];
    }
    res+="=( )";
    return res;
   /* if(GetExistingQuestions(res)){
        return res;
    }else{
        QuestionGenerator();
    }
*/
}
View Code

存放题目时采用的是相对路径

Teacher.cpp:

在切换类型时提前在main函数中抽取了“切换为”三个字,所以ChangeType简洁易懂。

bool Teacher::ChangeType(std::string new_type) {
    if(new_type=="小学"||new_type=="初中"||new_type=="高中"){
        this->my_type_=new_type;
        return true;
    }else{
        printf("%s\n","请输入小学、初中和高中三个选项中的一个");
        return false;
    }
}
View Code

Main.cpp:

Main函数里只有三行,调用login函数登录;main()函数应该专注于启动程序和协调不同模块或功能之间的交互,很符合单一职责原则。

五、代码优点

  1. 代码结构清晰简介,各功能分文件实现,耦合度较低,模块之间的依赖性低,代码更灵活、易于修改、维护。
  2. 生成的题目饱满、完整、合理,括号随机且正确
  3. 代码基本符合google编码规范,在关键操作处有注释
  4. 重用性高,函数的实现简洁高效

六、存在不足

1、 可以在函数声明处添加函数的功能注释

2、 可以进一步完善查重功能