MySCS-3 #
同学们,在上一次的迭代中,我们已经完成了管理端的命令开发,接下来我们需要完成学生端的命令了。
编写好的代码需要使用patpat进行评测,AC后即可上传到云平台以完成本次的实验内容。希望大家认真且保质保量的完成,请勿抄袭,如有发现抄袭现象将取消迭代作业成绩。
题目背景 #
软件学院云平台(青春版),即MySCS,是一款更加轻量化的命令行操作的云平台,屏幕前的你拥有完全的自主知识产权,有极大的使用价值和收藏价值。本平台模拟一台操作机上的命令行,所有操作均在本地进行,不支持联网操作,同一时间的使用者有且仅有一个。
MySCS分为管理端(老师端和助教端)和学生端,可以实现传统的scs的大部分功能。本次迭代需要完成的内容为学生端命令的开发,请尽可能直接基于AC后的MySCS-2代码编写,否则可能发生其他异常情况,另外注意此前迭代AC了也不能确保你的程序是完全正确的。
注意在这次的迭代中修改了部分输出格式,同时也为部分之前的命令增添了新的功能。
整体约束 #
当输入的命令未定义时,输出
command '$命令' not found
例如: 输入
loggin 19375030 123456
由于命令 loggin 未定义,所以输出
command 'loggin' not found
若以下 功能描述中有明确给出输出顺序,则以它为准
若不满足第二条,则保持原输出顺序不改变
当输入的命令有定义,但是参数的个数不合法要求时,输出
arguments illegal
输入:
login 19375030 123456 haha
和login 19375030
都对应着arguments illegal
当命令有定义,参数个数正确时,才会输出
Bye~
或者user id illegal
等成功或失败输出当一句命令存在多种非法情况,按上述顺序只输出最先发生的非法信息
例如,注册时学号和姓名均非法,按上述顺序,输出
user id illegal
,而不是user name illegal
评测时,请将所有文件放到patpat可执行文件相同路径下。例如:
MySCS\example ├─LAB1.md ├─Lesson1.txt ├─19376054.task ├─T191743.ans ├─patpat.exe ├─3-学号-姓名 │ ├─out │ └─src │ └─Test.java └─test ├─test.yaml └─judge.yaml
提交代码时,请保持以上目录结构
不要使用word,vsc等软件修改文件,可能会导致格式混乱
请注意:PatPat仅支持单个Scanner对象,使用Scanner读入文件可能导致测评结果错误,请采用其他方式读入!
总体说明 #
- 仅提到的需要修改的命令才需要修改,其余未提到的命令均保持不变
- 当你涉及文件的操作评测时出现行数问题的时候,可以试试把
println()
的输出结果trim()
一下,去掉多余的换行 - 每次评测之后记得把生成的文件夹删掉以还原最初的评测环境(比如在
QUIT
之后增加一个删除./data/
的逻辑再退出程序) - 输出顺序即为优先级
- 命令中的
[]
代表可选项,该项可出现,也可空缺 - 命令中的
...
表示省略的语义,紧跟的前一项(若存在)可重复出现任意次数 - 命令中的
|
代表或的语义 - 命令中的
()
代表这是一个整体 - 命令中的
<
和>
代表重定向输入/输出,特别地,>
表示覆盖,>>
表示追加,重定向的意思可以简单的理解为将原本需要System.out.println()
的内容转而写入到指定的文件中,倘若指定的文件不存在默认新建一个 - 在示例中看到的
$variable
和${variable}
表示这是一个变量,需要替换成实际值 - 在示例中看到的
...
表示省略的语义,并不是实际输出 - 在示例中看到
$ 命令
格式,表示这是你在IDEA的运行窗口中输入的命令,输入内容不应包括$
和紧跟其后的空格
命令概览 #
需求 | 命令 | 功能描述 |
---|---|---|
修改 | listCourse | 列出所有课程 |
修改 | selectCourse 课程编号 | 选择课程 |
修改 | listAdmin | 列出课程管理端成员 |
修改 | addWare 资料编号 资料路径地址 | 添加课程资料 |
修改 | removeWare 资料编号 | 移除课程资料 |
修改 | listWare | 列出课程资料 |
修改 | addTask 作业编号 作业名称 作业开始时间 作业截至时间 | 添加课程作业 |
修改 | removeTask 作业编号 | 移除课程作业 |
修改 | listTask | 列出课程作业 |
新增 | downloadFile [保存路径地址] 文件编号 [(> | >>) 路径地址] | 下载课程文件 |
新增 | openFile [路径地址] | [< 路径地址] | 打开文件 |
新增 | submitTask [作业路径地址] 课程作业编号 [< 作业路径地址] | 提交课程作业 |
新增 | addAnswer [答案路径地址] 课程作业编号 [< 答案路径地址] | 添加作业答案 |
新增 | queryScore 课程作业编号 [学号] | 查询作业成绩 |
功能描述 #
列出所有课程 #
命令 |
---|
listCourse |
- 使用对象:所有人
- 功能:列出与自己相关的所有课程,学生使用列出学生加入的课程,助教和老师使用列出其名下管理的课程
- 前置条件:已登录
其余不变
选择课程 #
命令 | 参数1 |
---|---|
selectCourse | 课程编号 |
- 使用对象:所有人
- 功能:选择当前需要操作的课程
- 前置条件:已登录
- 更新:学生可以使用该命令来选择当前需要操作的课程
其余不变
Hint:
- 注意在切换身份以及退出登录时清空选择课程。
列出课程管理端成员 #
命令 |
---|
listAdmin |
使用对象:所有人
功能:查询当前课程的所有管理员信息,包括老师和助教
前置条件:已登录、已选择课程
成功输出变更
注意:按照
ID
字符串的字典序排序输出,特殊的是,当学生使用此功能时,为了保护老师和助教的信息安全,需隐去学工号,即输出:[Name:$姓 $名] [Type:$身份] [Email:$邮箱] ...
顺序不变
其余不变
添加课程资料 #
命令 | 参数1 | 参数2 |
---|---|---|
addWare | 资料编号 | 资料路径地址 |
使用对象:老师端、助教端
功能:管理端可以为课程添加资料,添加的资料会统一存放在
./data/$课程编号/wares/
中(需要复制路径地址的文件到指定文件夹下,若存在非本次命令添加的同资料编号文件,则覆盖),并重命名为$资料编号_$资料名称
,其中资料名称被定义为文件名称(不是路径而是文件名,且包含后缀名,思考用什么方法获得)前置条件:已登录、已选择课程
更新:助教也可以添加资料,且涉及文件操作
失败输出变更
ware id duplication
从原来的失败原因中剔除,因为可以通过添加同ID的资料来修改原资料(对资料名是否相同没有限制,但要注意删除旧的资料,保证同ID的资料仅有一个)
以下新增的失败输出的判定均在原有判定之后,新增的失败输出的输出顺序即为下文中从上往下出现的顺序
- 新增
ware file does not exist
当且仅当资料路径地址指向的文件不存在时输出 - 新增
ware file operation failed
当且仅当文件操作失败时输出 - 新增
unexpected error
当且仅当其他异常抛出时输出
其余不变
Hint:
- 你需要通过路径地址获取文件,然后使用原来的方法判断资料编号与文件名是否合法,并记录失败原因,最后在执行文件操作的时候仍需要try-catch,对捕获的异常进行记录并输出
- 考虑使用
java.io.File
来进行文件查看,考虑使用java.nio.file.Files
进行文件操作,或者利用文件流进行操作
举例说明:
将提供的压缩包中的文件解压缩到当前目录下(patpat评测则在patpat同级目录下,IDE运行则在项目文件夹下)。
./ 表示当前目录,因此实际参数中的资料路径地址只会有例如"a.txt"和"./a.txt"两种情况,如果判断出是后者,我们需要你从中提取出文件名"a.txt"。
例如此时选择课程的编号为 C2101,执行指令:
addWare W210101 ./a.txt
若指令执行成功,则需要你将 a.txt 文件拷贝到 ./data/C2101/wares/ 文件夹下(这些文件夹是由你在程序运行时自动创建),并命名为 W210101_a.txt。
移除课程资料 #
此项改动较小,仅指出不同部分。
- 使用对象:老师端、助教端
- 更新:移除课程资料的时候会同步删除对应文件,部分输出格式变更
- 失败输出(这就是全部的失败输出了,因为下面没写其余不变):
当参数数量不正确时,输出:
arguments illegal
当系统目前没有用户登录时,输出:
not logged in
当系统目前登录用户不是使用对象时,输出:
permission denied
当系统目前没有用户选择课程时,输出:
no course selected
当课程资料编号未被注册或不在课程中时,系统输出:
ware not found
当删除文件失败时,系统输出:
delete file failed
Hint:
- 注意在删除文件前确保文件未在被使用(例如关闭文件IO流,类似于在电脑上你不能删除你正在打开的文件),最好在删除文件后获取其方法返回值来检验文件是否成功被删除,若未被删除则手动报错。
成功输出不变
列出课程资料 #
命令 |
---|
listWare |
使用对象:所有人
功能:列出当前课程的所有资料
前置条件:已登录、已选择课程
更新:助教端和学生端可以使用此命令
失败输出
当参数数量不正确时,输出:
arguments illegal
当系统目前没有用户登录时,输出:
not logged in
当用户没有选择课程时,输出:
no course selected
特殊情况
当课程中没有资料时,输出:
total 0 ware
成功输出不变
成功Example
$ listWare [ID:W210101] [Name:Lesson1.txt]
Name
依旧是原来的$资料名称
,而不是$资料编号_$资料名称
添加课程作业 #
此项改动较小,仅指出不同部分。
命令更新:作业名称变更为作业路径地址,可参考 添加课程资料
使用对象:管理端
功能:管理端可以为课程添加作业,添加的作业会统一存放在
./data/$课程编号/tasks/$作业编号/
中(需要复制路径地址的文件到指定文件夹下,若系统中存在非本次命令添加的同作业编号文件,则覆盖原文件,系统中对应的数据结构记录新的作业名称,保证下次索引的时候能索引到最新的作业文件即可,旧的文件删不删对后续评测无影响),命名为$作业名称
,其中作业名称被定义为文件名称(包含后缀名)前置条件:已登录、已选择课程
功能更新:涉及文件操作,部分输出变更
失败输出变更
task id duplication
移除,当作业编号重复时,系统会覆盖旧的作业
以下新增的失败输出的判定均在原有判定之后,新增的失败输出的输出顺序即为下文中从上往下出现的顺序
如果文件并不存在,系统输出:
task file not found
最后,如果文件操作失败,系统输出:
file operation failed
其余输出不变,输出顺序不变
移除课程作业 #
此项改动较小,仅指出不同部分。
- 使用对象:管理端
- 更新:移除课程作业的时候会同步删除对应文件(指添加课程作业中添加的文件,不包括后续上传的答案、学生提交的作业以及成绩),部分输出格式变更
- 失败输出(这就是全部的失败输出了):
当参数数量不正确时,输出:
arguments illegal
当系统目前没有用户登录时,输出:
not logged in
当系统目前登录用户不是老师或助教时,输出:
permission denied
当系统目前没有用户选择课程时,输出:
no course selected
当课程作业编号未被注册或不在课程中时,系统输出:
task not found
当删除文件失败时,系统输出:
delete file failed
成功输出不变
列出课程作业 #
命令 |
---|
listTask |
使用对象:所有人
功能:列出当前课程的所有作业
前置条件:已登录、已选择课程
更新:助教端和学生端可以使用此命令
成功输出
助教端和老师端
[ID:$课程作业编号] [Name:$课程作业名称] [SubmissionStatus:$接收作业份数/$课程总人数] [StartTime:$开始时间] [EndTime:$截止时间] ...
学生端
[ID:$课程作业编号] [Name:$课程作业名称] [Status:undone/done] [StartTime:$开始时间] [EndTime:$截止时间] ...
- 补充:作业已经提交过,则状态为
done
,否则为undone
,提交命令见 提交课程作业
- 补充:作业已经提交过,则状态为
失败输出
当参数数量不正确时,输出:
arguments illegal
当系统目前没有用户登录时,输出:
not logged in
当用户没有选择课程时,输出:
no course selected
特殊情况
当课程中没有作业时,输出:
total 0 task
下载课程文件 #
命令 | 可选参数1 | 参数2 | 可选重定向符号 | 可选重定向路径 |
---|---|---|---|---|
downloadFile | [保存路径地址] | 文件编号 | [> | >>] | [路径地址] |
使用对象:所有人
功能:下载当前课程的指定文件编号文件(资料或作业)到保存路径地址下,默认覆盖同名文件,并输出文件内容,可选择将输出文件内容重定向到另一路径地址文件中,此时可选择不保存文件(Hint:本质复制/写入或追加写入);可选参数1和重定向可同时使用,不冲突,但是两者必须有至少一个
前置条件:已登录、已选择课程
备注:评测会保证仅操作文本文件,
>/>>
后不会出现超过1个参数的情况(这种情况比较复杂,本次不要求实现,故评测不涉及此情景,无需考虑,更不会出现有多个>/>>
的情况成功Example
$ # temp.txt 内容为 this is a temp $ downloadFile temp.txt T210201 # 下载文件到当前目录下的temp.txt this is a temp $ downloadFile T210201 > temp.txt # 同上,但没有输出 $ downloadFile T210201 >> temp.txt # 追加写入到temp.txt $ downloadFile temp.txt T210201 > result.md # 下载文件到当前目录下的temp.txt,并把输出写入到result.md $ downloadFile temp.txt T210201 >> result.md # 同上,但追加写入到result.md
失败Example
$ downloadFile # 参数数量不正确 arguments illegal $ downloadFile T210201 # 参数数量不正确 arguments illegal $ downloadFile 1 1 1 # 参数数量不正确 arguments illegal $ downloadFile > please input the path to redirect the file $ downloadFile temp.txt T210201 > temp.txt input file is output file $ downloadFile 114514 > 9m.c # 不存在的文件编号 $ # 9m.c 内容为 file not found
成功输出
未使用重定向时
$文件内容
使用重定向时,输出到指定文件中,控制台无输出
失败输出
使用重定向且成功时,输出到指定文件中,控制台无输出
其他情况
当使用了重定向时缺失重定向文件路径,输出:
please input the path to redirect the file
当可选参数1和重定向同时使用,且两者路径相同时,输出:
input file is output file
当参数数量不正确时,输出:
arguments illegal
当系统目前没有用户登录时,输出:
not logged in
当用户没有选择课程时,输出:
no course selected
当文件编号不合法或不存在时,输出:
file not found
当文件操作失败时,输出:
file operation failed
Hint:
- 仅供参考,后面命令同理:在考虑参数数量时,优先判断重定向是否存在,若不存在则参数数量固定;若存在则判断其位置,若是最后一个则缺失重定向路径,倒数第二个则考虑其他,若都不是则参数数量错误(重定向符号后面至多跟着一个参数)。
打开文件 #
命令 | 可选参数1 | 可选重定向符号 | 可选重定向路径 |
---|---|---|---|
openFile | [路径地址] | [<] | [路径地址] |
使用对象:所有人
功能:打开指定文件并输出文件内容,可选择搭配可选参数1来指定要打开的文件,也可以选择使用重定向来指定打开哪个文件(两种效果一致,后续涉及指定打开文件的命令同理),如果使用可选参数1同时使用重定向输入,忽略重定向输入,下同
前置条件:无
备注:评测会保证仅操作文本文件,
<
后不会出现超过1个参数的情况(这种情况比较复杂,本次不要求实现,故评测不涉及此情景,无需考虑,感兴趣的可以用cat
命令来实验一下各种情况的结果),更不会出现有多个<
的情况,后续同理成功Example
$ openFile test.txt # 打开当前目录下的test.txt this is a test $ openFile < test.txt # 同上 this is a test $ openFile test.txt < another.txt # 同上,但忽略重定向 this is a test
成功输出
$文件内容
失败输出
当未使用重定向时缺失文件路径,输出:
please input the path to open the file
当使用了重定向时缺失重定向文件路径,输出:
please input the path to redirect the file
当参数数量不正确时,输出:
arguments illegal
当文件打开失败时,输出:
file open failed
提交课程作业 #
命令 | 可选参数1 | 参数2 | 可选重定向符号 | 可选重定向路径 |
---|---|---|---|---|
submitTask | [作业路径地址] | 课程作业编号 | [<] | [作业路径地址] |
使用对象:学生端
功能:提交指定作业并进行评测,作业需要保存到
./data/$课程编号/tasks/$作业编号/
文件夹下(需要复制路径地址的文件到指定文件夹下),并重命名为$学号.task
,如果作业已经存在,则询问是否覆盖。如果使用可选参数1同时使用重定向输入,忽略重定向输入前置条件:已登录、已选择课程
简化条件:为了减轻大家的负担,本平台的作业仅为选择题、填空题、判断题,每题的答案可为任意字符,且不区分大小写,题号即为行号,答案即为行中的字母;分数的计算按百分制,每题分数均等,得分保留到小数点后一位
限制 你的文件应为如下格式:
[答案1] [答案2] ...
Example:
T F T T a G d Z Y 114514 1919810 69 996 007 have a nice day! ~/Desktop/submitTask 1
特殊需求:当助教还未上传答案时,分数暂填None,当 查询得分时,如果助教已上传答案,则重新评分,否则不变
成功输出
submit success your score is: $分数
失败输出
当使用了重定向时缺失重定向文件路径,输出:
please input the path to redirect the file
当参数数量不正确时,输出:
arguments illegal
Hint:因为该命令不同于 openFile只有一个可选参数1,所以当只有一个参数的时候并不方便判断这个参数到底是路径还是课程作业编号(需要用到正则,考点重复,这里就不再增加不必要的工作量),所以这里不再特化一个单独的错误输出,直接将所有参数缺失或参数过多相关的问题归为
arguments illegal
。提供一种解题思路:通过有无<
来分别,若有,则<
前只接受1-2个参数的情况,<
后缺失参数的情况上一条中已经判断过了,<
后不会出现超过1个参数的情况(这种情况比较复杂,本次不要求实现,故评测不涉及此情景,无需考虑,感兴趣的可以用cat
命令来实验一下各种情况的结果),更不会出现有多个<
的情况; 若无<
,则只接受2个参数的情形;其余情况一律报arguments illegal
,下面的命令可以用相同的思路考虑当系统目前没有用户登录时,输出:
not logged in
当系统用户不在使用对象中时,输出:
operation not allowed
当用户没有选择课程时,输出:
no course selected
当课程作业编号不合法或不存在时,输出:
task not found
当文件操作失败时,输出:
file operation failed
特殊情况
当作业已经存在时,先询问:
task already exists, do you want to overwrite it? (y/n)
对于输入的非
yY\n
的字符,认为是n
,输出:submit canceled
否则进行文件操作,然后给出成功/文件操作失败输出
Hint:
- 建议为学生维护一个例如: 作业编号->作业文件路径 的映射集合,通过判断对应作业编号的作业文件路径是否存在来判断文件是否存在,若通过文件判断则可能被其他数据点生成的文件影响,则需在每次程序 QUIT 时删除所有提交的作业文件(简单点直接递归删除 data 文件夹)。
添加作业答案 #
命令 | 可选参数1 | 参数2 | 可选重定向符号 | 可选重定向路径 |
---|---|---|---|---|
addAnswer | [答案路径地址] | 课程作业编号 | [<] | [答案路径地址] |
使用对象:管理端
功能:为指定作业添加答案,答案需要保存到
./data/$课程编号/answers/
文件夹下(需要复制路径地址的文件到指定文件夹下),并重命名为$作业编号.ans
,重复添加答案时,覆盖原有答案。如果使用可选参数1同时使用重定向输入,忽略重定向输入前置条件:已登录、已选择课程
简化条件:同 提交课程作业
限制:同 提交课程作业
成功输出
add answer success
Example
$ openFile ans.txt B B C $ addAnswer ans.txt T212101 add answer success $ # 这里省略执行了登出命令并登录了所在课程下的学生账号 $ openFile < 1.md B A C $ submitTask T212101 < 1.md submit success your score is: 66.7 $ # 这里假定同学经过思考后修改了答案 $ openFile < 1.md B B C $ submitTask T212101 < 1.md task already exists, do you want to overwrite it? (y/n) y submit success your score is: 100.0
失败输出
当使用了重定向时缺失重定向文件路径,输出:
please input the path to redirect the file
当参数数量不正确时,输出:
arguments illegal
当系统目前没有用户登录时,输出:
not logged in
当系统用户不在使用对象中时,输出:
permission denied
当用户没有选择课程时,输出:
no course selected
当课程作业编号不合法或不存在时,输出:
task not found
当文件操作失败时,输出:
file operation failed
查询作业成绩 #
命令 | 可选参数1 | 可选参数2 |
---|---|---|
queryScore | [课程作业编号] | [学号] |
- 使用对象:所有人
- 功能:查询作业的成绩,如果不指定作业编号,则查询该课程下所有作业的成绩;指定学号功能仅管理端可用,可以查询指定学号学生的成绩;同一个作业的成绩仅显示最高分;对于得分为None的作业,如果助教已上传答案,则重新评分,否则不变;顺序为课程作业编号按照字典序升序排列,课程作业编号相同按成绩分数降序排列,分数相同则按照学号字典序升序排列
合法查询:
管理端:
不指定 → 查询所有作业的所有学生的成绩
指定学号 → 查询对应学生下所有作业的成绩
指定作业编号 → 查询对应作业下所有学生的成绩
指定作业编号和学号 → 查询对应作业下对应学生的成绩
学生端:
不指定 → 查询自己所有作业的成绩
指定作业编号 → 查询自己在对应作业的成绩
前置条件:已登录、已选择课程
成功输出
total $查询到的结果数量 results [1] [ID:$学号] [Name:$姓 $名] [Task_ID:$课程作业编号] [Score:$成绩] ...
失败输出
当参数数量不正确时,输出:
arguments illegal
当系统目前没有用户登录时,输出:
not logged in
当用户没有选择课程时,输出:
no course selected
当学生指定学号查询时,输出:
permission denied
当在可选参数1号位识别到课程作业编号(即字母T后跟6位数字)且不合法或不存在时,或有两个参数时第一个课程作业编号参数不合法或不存在时,输出:
task not found
对于其他情况将参数视为学号,当学号不合法或不存在时,输出:
student not found
特殊情况
当查询到的结果数量为0时,输出:
total 0 result
当查询到的结果数量为1时,输出第一行变更为:
total 1 result
Hint:
- 实际上并不会出现 None 和分数比较的情况,因为对于同一个作业,有分数说明助教已经上传答案,此时就会重新评判,原本 None 的也会得到相应分数。