# hitsz_autograde **Repository Path**: ftutorials/hitsz_autograde ## Basic Information - **Project Name**: hitsz_autograde - **Description**: 一个通用代码自动评测/查重脚本。 - **Primary Language**: Python - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2022-05-07 - **Last Updated**: 2023-11-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 批量评测脚本使用说明 ## 命令行参数 如果命令行参数和配置文件均修改了同一个配置项,命令行参数设置将**覆写**配置文件设置。 参数 | 含义 ----------------------------------------------------|------------------------------------------------------ `-h, --help` | 输出帮助 `--parallel PARALLEL, -p PARALLEL` | 指定并行任务数量。可以不存在,默认为1。建议数值小于等于评测机CPU线程数量。 `-v, --verbose` | 输出等级。v越多,输出越多。支持-v -vv -vvv -vvvv。一般-vv就好。 `--codex CODEX, -c CODEX` | 指定输出编码。可以不存在,由配置文件指定。 `--moss-userid MOSS_USERID` | 指定moss评测id。可以不存在,由配置文件指定。 `--plagiarism-threshold THRESHOLD, -t THRESHOLD` | 指定抄袭判定的阈值。 `--anonymous, -a` | 启用可视化结果匿名化输出。需要注意的是,点进链接依旧能看到原文件名,内有学号和名字。 `--skip-clone` | 跳过下载评测环境,使用缓存内容执行评测。 `--skip-judge` | 跳过评测,使用缓存内容进行查重和可视化生成。 `--skip-moss-vis` | 跳过查重结果可视化生成。 `--skip-zip` | 跳过评测结果打包 `--repository REPOSITORY, -r REPOSITORY` | 评测环境仓库。支持本地文件与远程git链接。可以不存在,由配置文件指定。 `--branch BRANCH, -b BRANCH` | 评测环境仓库分支。可以不存在,由配置文件指定。 `--student-files STUDENT_FILES, -f STUDENT_FILES` | 学生文件压缩包所在的文件夹。可以不存在,由配置文件指定。 `--output-dir OUTPUT_DIR, -o OUTPUT_DIR` | 评测得分输出文件夹。默认位于./grading_envs config | json配置文件,格式见下 ## 依赖 ```console pip install mosspy sudo apt install unrar sudo apt install graphviz sudo apt install unzip ``` ## 配置文件内容速查 ```json { "file_list": { "文件名1": { "copy_to_env": "拷贝至评测环境的该相对路径下", "copy_to_output": "拷贝至输出文件夹的该相对路径下", "plagiarism_test": { "language": "编程语言", "template": "教师提供的模板文件", "known_solutions": [ "已知的解答1", "已知的解答2" ] } }, "文件名2": { "copy_to_env": "拷贝至评测环境的该相对路径下", "copy_to_output": "拷贝至输出文件夹的该相对路径下", "plagiarism_test": { "language": "编程语言", "template": "教师提供的模板文件", "known_solutions": [ "已知的解答1", "已知的解答2" ] } }, }, "overrides": { "要覆写的评测环境文件1": { "type": "alteration", "original": "原字串", "altered": "新字串" }, "要创建的评测环境文件2": { "type": "creation", "content": "文件内容" } }, "moss_userid": "moss用户id(不要带双引号)", "test_script": [ ["评测", "用的", "命令1"], ["评测", "用的", "命令2"] ], "result_regex": "匹配分数用的正则表达式", "repository": "评测环境地址", "branch": "评测环境分支", "plagiarism_threshold": "查重判定阈值", "student_files": "学生压缩文件所在文件夹", "output_dir": "输出所在文件夹" } ``` ## 示例:xv6实验一 ```json { "file_list": { "pingpong.c": { "copy_to_env": "user/pingpong.c", "plagiarism_test": { "language": "c", } }, "primes.c": { "copy_to_env": "user/primes.c", "plagiarism_test": { "language": "c" } }, "find.c": { "copy_to_env": "user/find.c", "plagiarism_test": { "language": "c" } }, "xargs.c": { "copy_to_env": "user/xargs.c", "plagiarism_test": { "language": "c" } }, "sleep.c": { "copy_to_env": "user/sleep.c" }, "Makefile": { "copy_to_env": "Makefile" }, "time.txt": { "copy_to_output": "time/{stu_id}_{stu_name}_time.txt" } }, "overrides": { "Makefile": { "type": "alteration", "original": "GDBPORT = $(shell expr `id -u` % 5000 + 25000)", "altered": "GDBPORT = $(shell expr {env_id} + 30000)" } }, "moss_userid": 507639744, "test_script": [ ["make", "clean"], ["./grade-lab-util"] ], "result_regex": "^Score: ([0-9]{1,3})/100$", "repository": "git@gitee.com:hitsz-lab/xv6-labs-2020.git", "branch": "util", "plagiarism_threshold": 90, "student_files": "student_files", "output_dir": "result" } ``` ## 内容详述 ### file_list 该项描述提交文件的评测与查重机制。该配置项内容为许多组对象,每一个对象的键为文件名,值为相关配置。 ```json "file_list": { "文件名1": { "配置项1": "配置内容1", "配置项2": "配置内容2", "配置项3": "配置内容3", }, "文件名2": { "配置项1": "配置内容1", "配置项2": "配置内容2", "配置项3": "配置内容3", } }, ``` #### file_list中的copy_to_env配置项 指示脚本应当把该文件拷贝至目标环境何处。支持下列转义项: * `{env_id}`:评测环境编号。 * `{stu_id}`:学生学号 * `{stu_name}`:学生姓名 例如,如果某甲(学号1234abc)的提交文件被分配到第11号评测环境,那么原字符串`test/{stu_id}_{stu_name}_{env_id}_testfile`将被转义为`test/1234abc_某甲_11_testfile`,亦即该文件将被拷贝至此处。 该项可以不存在,此时将不会把该文件拷贝至评测环境中。 #### file_list中的copy_to_output配置项 指示脚本应当把该文件拷贝至输出环境何处。支持下列转义项: * `{env_id}`:评测环境编号。 * `{stu_id}`:学生学号 * `{stu_name}`:学生姓名 例如,如果某甲(学号1234abc)的提交文件被分配到第11号评测环境,那么原字符串`test/{stu_id}_{stu_name}_{env_id}_testfile`将被转义为`test/1234abc_某甲_11_testfile`,亦即该文件将被拷贝至输出环境此处。 该项可以不存在,此时将不会把该文件拷贝至输出环境中。 #### file_list中的plagiarism_test配置项 该配置项代表代码查重配置,可以不存在,此时将不会对该文件进行查重。若该配置存在,则其由以下三个键值对组成: ##### plagiarism_test中的language配置项 配置代码查重时其所用的语言。如果该项不存在,脚本会自动尝试从后缀中推断出所用的语言,但是有失败的可能。 ##### plagiarism_test中的template配置项 配置代码查重时其所用的模板,限一个模板文件。该项可以不存在,代表未为该代码文件提供模板。该文件可以用绝对路径描述,或者使用相对于该配置文件的相对路径。 ##### plagiarism_test中的known_solutions配置项 配置代码查重时已知的解答,可以包括上一届同学的作业、网上的答案等等,是一个数组。该项可以不存在,代表未提供任何已知解答。这些文件可以用绝对路径描述,或者使用相对于该配置文件的相对路径。**这些文件的命名请依照如下规律:出处_已知解法{序号}_{文件名}**,例如,一个名为`primes.c`的文件的已知解法应当被命名为: * `csdn_已知解法1_primes.c` * `github_已知解法2_primes.c` * `博客园_已知解法3_primes.c` ### overrides 该项描述如何覆写评测环境内容。该配置项内容为许多组对象,每一个对象的键为一个评测环境文件,值为相关配置。目前支持两种配置:替换和新建。 ```json "overrides": { "文件路径1": { "type": "类型", "配置项2": "配置内容2", "配置项3": "配置内容3", }, "文件路径2": { "type": "类型", "配置项2": "配置内容2", "配置项3": "配置内容3", } }, ``` #### 替换文件内容 使用该配置时,必须指定`type`字段为`"alteration"`,并必须包含`original`字段和`altered`字段。 `original`字段代表需要被替换的字串内容。`altered`表明要被换入的字串内容。`altered`支持下列转义项: * `{env_id}`:评测环境编号。 * `{stu_id}`:学生学号 * `{stu_name}`:学生姓名 #### 创建文件 使用该配置时,必须指定`type`字段为`"creation"`,并必须包含`content`字段,其代表所创建的文件的内容。`content`支持下列转义项: * `{env_id}`:评测环境编号。 * `{stu_id}`:学生学号 * `{stu_name}`:学生姓名 ### result_regex 用于匹配输出结果的正则表达式,其中的第一个分组作为结果。需要注意的是,这里的`^`代表行起始,`$`代表行终止,而非全输出的起点/终点。 例如,以xv6自动评测脚本为例,自动评测的输出形式为: ```none sleep, no arguments: OK (11.2s) sleep, returns: OK (2.0s) sleep, makes syscall: OK (2.2s) pingpong: OK (1.0s) primes: OK (2.2s) find, in current directory: OK (1.4s) find, recursive: OK (2.6s) xargs: OK (3.1s) Score: 100/100 ``` 那么,自动评测用的正则表达式应该为`"^Score: (\d+)/100$"`。 又例如,输出形式为: ```none 自动评测开始运行 评测过程输出... 评测过程输出... 评测过程输出... 自动评测结果:通过! 评测结束。 ``` 那么,匹配用的正则表达式应该为`"^自动评测结果:([通过|不通过]{2,})!$"`。 自动评测如果输出多条符合正则表达式的结果,那么最后一条结果将被记录。 ### repository 实验评测环境仓库。可以是一个文件夹(绝对路径,或者相对于脚本的相对路径),或者是一个链接(gitee或者github)。 ### branch 实验评测环境分支。例如,在xv6实验上,会需要在`util`、`fs`等等多个分支上切换。 ### plagiarism_threshold 查重阈值。可以不存在。默认为90. ### plagiarism_threshold 查重阈值。可以不存在。默认为90. ### output_dir 输出文件夹。可以不存在。默认为脚本同文件夹下的`result`文件夹。 ### cache_dir 指定缓存与评测环境文件夹。可以不存在。默认为脚本同文件夹下的`cache`文件夹。 ### student_files 指定学生提交文件所在的文件夹。**所有提交文件必须全部直接放在该文件夹下,该文件夹不能包含任何其他文件和/或子文件夹**。 同时,所有学生的提交文件均应为**`zip`**格式,且文件名遵循以下格式:`学号_姓名_自定义内容.zip`。例如,`1234abcd_某某甲_file.zip`就是一个合法的文件名,但`某某甲_提交.rar`就不是。 ### codex 指定输出编码。可以不存在。由于许多老师使用Windows操作系统,默认输出codex为GB18030。