From c46c65a329bb14640783c7d6b0f686918c28b7b9 Mon Sep 17 00:00:00 2001 From: iotang <3057244225@qq.com> Date: Tue, 14 Jan 2020 22:49:59 +0800 Subject: [PATCH] =?UTF-8?q?=E7=8E=B0=E5=9C=A8=E8=83=BD=E5=AF=BC=E5=87=BA?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E4=BF=A1=E6=81=AF=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 30 +-- contest.cpp | 2 +- contestant.cpp | 20 +- forms/lemon.ui | 14 + guide/guidedata/about.md | 13 - guide/guidedata/contest.md | 333 ------------------------ guide/guidedata/judge.md | 80 ------ guide/guidedata/settings.md | 93 ------- guide/guidedata/specialjudge.md | 146 ----------- guide/guidedata/welcome.md | 7 - lemon.cpp | 10 + lemon.h | 1 + lemon_zh_CN.qm | Bin 50218 -> 50682 bytes lemon_zh_CN.ts | 441 +++++++++++++++++--------------- settings.cpp | 2 +- statisticsbrowser.cpp | 59 +++++ statisticsbrowser.h | 4 + 17 files changed, 345 insertions(+), 910 deletions(-) delete mode 100755 guide/guidedata/about.md delete mode 100755 guide/guidedata/contest.md delete mode 100755 guide/guidedata/judge.md delete mode 100755 guide/guidedata/settings.md delete mode 100755 guide/guidedata/specialjudge.md delete mode 100755 guide/guidedata/welcome.md diff --git a/README.md b/README.md index ee32575a..5c3c7cf2 100755 --- a/README.md +++ b/README.md @@ -60,8 +60,6 @@ # 构建 -由于叛逃到 Manjaro,只给 `Qt Creator 4.11.0 based on Qt 5.14.0` 版本,所以 QT 版本必须是 `5.14` 或者以上才能编译出来。 - ## 如果 Github 太慢… 你也许可以到 ``码云(Gitee)`` 去下载。 @@ -82,29 +80,9 @@ #### Ubuntu -先 `sudo apt install build-essential libgl1-mesa-dev`。 - -然后去 `http://mirrors.ustc.edu.cn/qtproject/archive/qt/5.14/5.14.0/` 下载 `qt-opensource-linux-x64-5.14.0.run`, - -然后 `sudo chmod +x qt-opensource-linux-x64-5.14.0.run`, - -然后 `sudo ./qt-opensource-linux-x64-5.14.0.run`。 - -#### Ubuntu 的另外一种简便的方法 - -```bash -sudo apt install qt5-default build-essential -``` - -然后把所有文件的 `swapItemsAt` 换成 `swap`。 - -这是因为 apt 安装的 Qt 5 版本太低。 - -#### Arch - - ```bash -sudo pacman -S gcc make qt5-base qt5-doc +Ubuntu: sudo apt install qt5-default build-essential +Arch: sudo pacman -S gcc make qt5-base qt5-doc ``` ### 下载源代码,在源代码目录中依次执行 @@ -120,8 +98,8 @@ make 当然如果你装有 Qt Creator,也可以用它编译 release 版本。 ```bash -Ubuntu: sudo apt install qtcreator -Arch: sudo pacman -S qtcreator +Ubuntu: sudo apt install qtcreator +Arch: sudo pacman -S qtcreator ``` ## macOS(!?!?!?) diff --git a/contest.cpp b/contest.cpp index 27cdbf33..6887b84c 100644 --- a/contest.cpp +++ b/contest.cpp @@ -77,7 +77,7 @@ void Contest::swapTask(int a, int b) { if (0 <= b && b < taskList.size()) { - taskList.swapItemsAt(a, b); + taskList.swap(a, b); } } diff --git a/contestant.cpp b/contestant.cpp index a2c900ff..3c48b5d0 100644 --- a/contestant.cpp +++ b/contestant.cpp @@ -181,16 +181,16 @@ void Contestant::swapTask(int a, int b) if (a < 0 || a >= checkJudged.size())return; if (b < 0 || b >= checkJudged.size())return; - checkJudged.swapItemsAt(a, b); - compileState.swapItemsAt(a, b); - sourceFile.swapItemsAt(a, b); - compileMesaage.swapItemsAt(a, b); - inputFiles.swapItemsAt(a, b); - result.swapItemsAt(a, b); - message.swapItemsAt(a, b); - score.swapItemsAt(a, b); - timeUsed.swapItemsAt(a, b); - memoryUsed.swapItemsAt(a, b); + checkJudged.swap(a, b); + compileState.swap(a, b); + sourceFile.swap(a, b); + compileMesaage.swap(a, b); + inputFiles.swap(a, b); + result.swap(a, b); + message.swap(a, b); + score.swap(a, b); + timeUsed.swap(a, b); + memoryUsed.swap(a, b); } int Contestant::getTaskScore(int index) const diff --git a/forms/lemon.ui b/forms/lemon.ui index 848cf2eb..e4e05ca4 100755 --- a/forms/lemon.ui +++ b/forms/lemon.ui @@ -448,6 +448,8 @@ + + @@ -843,6 +845,18 @@ How to make Communication Tasks... + + + false + + + + :/icon/document-export.svg:/icon/document-export.svg + + + Export &Statistics + + diff --git a/guide/guidedata/about.md b/guide/guidedata/about.md deleted file mode 100755 index fae6958c..00000000 --- a/guide/guidedata/about.md +++ /dev/null @@ -1,13 +0,0 @@ -# 关于 LemonLime - -## 协议 - -GPL 3.0 - -## 贡献者 - -Lemon v1.2 by Zhipeng Jia, 2011 - -LemonPlus by Dust1404, 2018 ~ - -LemonLime by iotang, 2019 ~ \ No newline at end of file diff --git a/guide/guidedata/contest.md b/guide/guidedata/contest.md deleted file mode 100755 index 3be2dcc9..00000000 --- a/guide/guidedata/contest.md +++ /dev/null @@ -1,333 +0,0 @@ -# 比赛 - -在左上角选中 `试题` ,进入试题编辑。 - -对 Lemon 而言,一场比赛分为 2 个部分:题目,与选手。 - -## 创建比赛 - -假设你将创建一个叫 `contest` 的比赛。 - -去 `文件 > 新建比赛` ,在 `比赛标题` 写上你的比赛的名字,在 `保存文件名` 写上你想保存的位置(这个名字不一定和你的比赛标题相同,你也可以把你的 `比赛标题` 取名为 `奥里与彩虹摇滚重金属炫彩中二小王子的阿克之战`。) - -> 现在,你已经可以在``文件 > 更改比赛标题``里更改``比赛标题``了。 - -`比赛目录` 默认在你的个人的主文件夹下。你也可以进行更改。可以点击 `...` 按钮来选择。 - -在你的 `比赛目录` 下,将会有 2 个文件夹产生: `data` 和 `source` 。 - -`data` 存放你的题目相关的文件。 - -`source` 存放你的选手相关的文件。 - -## 添加题目 - -假设你的 `contest` 有 3 道题: `题1` ,`题2` 和 `题3` ,选手提交的文件名字分别为 `t1` ,`t2` 和 `t3` 。它们分别是传统题,提交答案题和交互题。 - -### 开始 - -把 LemonLime 页面切换到 `试题` 页面(另一个是 `选手` 页面)。 - -右键 `概要` 下面的白色框,选择 `添加新试题` ,并为你的题目命名。 - -### 传统题配置 - -现在你配置的试题是 `题1` 。 - -添加题目之后,在右侧 `详情` 的 `试题类型` 勾选 `传统题` 。 - -在 `源文件名称` 写上 `t1` 。 - -根据你的需要选择是否 `在子文件夹内寻找` 。 - -`输入文件名` 和 `输出文件名` 会被自动填写,也可以根据你的需要进行改动。 - -选择你的题目的 `比较模式` 。 - -调整你的 `编译器设置` ,可以 启用/禁用 某种语言,或是 打开/关闭 优化。 - -#### 比较模式 - -LemonLime 内嵌了 3 种比较模式,还提供了 2 种扩展模式。 - -##### 逐行比较模式 - -对每一行进行比较。 - -可选 忽略/不忽略 行末回车 和 多余的空格。 - -##### 实数比较模式 - -比较单个实数。 - -对 `nan` 和 `inf` 作出识别。 - -##### 自定义校验器模式 - -参见文档 `specialjudge` 。 - -#### 添加测试点 - -右键 `概要` 下面的白色框,选择 `添加新测试点` 。 - -假设你的 `contest` 目录的结构是这样的: - -```plain -contest -| data -| | t1 -| | | t1_1.in -| | | t1_1.ans -| | | t1_2.in -| | | t1_2.ans -| | t2 -| | t3 -| source -``` - -而你此时想添加一组包含 `t1_1` 的测试点,那么在 `输入文件名` 输入 `t1/t1_1.in` , 在 `输出文件名` 输入 `t1/t1_1.out` (如你所见,它们以 `data` 为根文件夹。),然后点击 `添加` 。 - -如果你把 `t1_2` 也加进去,那么它们将会构成一个 `subtask` 。 - -在下面设置你的这个测试点的 `分值`,`时间限制` 和 `空间限制`。 - -#### 批量添加多组测试点 - -在 `概要` 右键,点击 `添加多组测试点…`。 - -##### 如何写一个语法正确的正则表达式 - -下面是一个例子: - -输入文件:`matrix/matrix<1>.in` - -输出文件:`matrix/matrix<1>.out` - -把`<1>`设为`\d*`。 - -> 提示: -> -> `\d` 表示匹配一个数字。 -> -> 匹配任意数量的数字: `\d*` -> -> `.` 表示匹配任意一个字符。 -> -> `*` 表示把之前的那个表达式重复 0 到无限大遍。 - -#### 子任务依赖 - -对于一个测试点,你可以设置 `子任务依赖` ,具体效果就是只有当 `子任务依赖` 内的所有测试点都通过后才会测试这个测试点。 - -测试点的编号可以在左侧 `概要` 查看。 - -对于测试点 10 ,一个合法的 `子任务依赖` 为 `1,2,3,6,9` 。不能依赖之后的测试点,并且每个数字之间要以半角逗号隔开。 - -### 提交答案题配置 - -现在你配置的试题是 `题2` 。 - -添加题目之后,在右侧 `详情` 的 `试题类型` 勾选 `提交答案题` 。 - -所有的 `编译器设置` 被禁用。 - -编辑 `选手答案文件扩展名` 。 - -选手提交的文件名将为 `源文件名称` + `数据序号` + `.` + `选手答案文件扩展名` , 比如对于 `题2` 的第 5 个测试点,选手应该提交 `t25.out` (当 `选手答案文件扩展名` 为 `out` )。 - -### 交互题配置 - -现在你配置的试题是 `题3` 。 - -添加题目之后,在右侧 `详情` 的 `试题类型` 勾选 `交互题` 。 - -选项和传统题的配置没有多大差别。 - -你需要提供你的 `交互库` 和 `接口` ,它们的路径以 `data` 文件夹为根进行填写。 - -假设你的 `contest` 目录的结构是这样的: - -```plain -contest -| data -| | t1 -| | t2 -| | t3 -| | | t3.h -| | | t3.cpp -| source -``` - -那么你应该这么填写: - -`交互库路径` : `t3/t3.h` - -`交互库名称` : `t3.h` - -`接口实现(grader)路径` : `t3/t3.cpp` - -如果你真的要出一道交互题,那么应该知道 `grader` 是什么。 - -### 自动添加试题 - -当你的 `data` 存放方式符合一般规律,可以使用 `自动添加试题` 来快速添加试题。 - -去 `控制` > `自动添加试题` 。 - -### * 移动试题 - -在试题列表下面有一对按键,分别有个向下箭头和向上箭头的标志。 - -点击它们可以移动当前选中的题目。 - -## 选手 - -假设你有一位选手,名字为 `Mona` 。 - -`Mona` 很强,把你的题目阿克了。 - -假设 `Mona` 的选手目录是这样的: - -```plain -Mona -| t1 -| | t1.cpp -| t2 -| | t21.out -| | t22.out -| t3 -| | t3.cpp -| t1.cpp -| t21.out -| t22.out -| t3.cpp -``` - -当你的 3 个题目都使用了 `在子文件夹寻找` ,那么以下文件是有用的: - -```plain -Mona -| t1 -| | t1.cpp <<< -| t2 -| | t21.out <<< -| | t22.out <<< -| t3 -| | t3.cpp <<< -| t1.cpp -| t21.out -| t22.out -| t3.cpp -``` - -否则的话,以下文件是有用的: - -```plain -Mona -| t1 -| | t1.cpp -| t2 -| | t21.out -| | t22.out -| t3 -| | t3.cpp -| t1.cpp <<< -| t21.out <<< -| t22.out <<< -| t3.cpp <<< -``` - -请把 `Mona` 放在 `source` 目录下。 - -```plain -contest -| data -| source -| | Mona -``` - -在左上角选中 `选手` 栏,点击 `刷新` ,`Mona` 将会出现在选手名单中。 - -### 整理文件 - -> **! 注意** -> -> 如果子文件夹里面的文件有文件名和子文件夹外面的文件相同的,子文件夹**外面的文件会丢失**! -> -> **大部分**无关文件也将**全部丢失**! -> -> 最好在整理文件之前备份一份,以防不测。 - -假设 `Mona` 的选手目录是这样的: - -```plain -Mona -| .vscode -| | extensions -| | | ... -| t1 -| | t1.cpp -| | t1.in -| | t1.out -| | t1.exe -| t2 -| | t21.out -| | t22.out -| ex_t1.cpp -| t1.exe -| t23.out -| t3 -| t3.cpp -| t4.cpp -| notice.txt -| 支持 Krita! -| xzy被阿视频.avi -| 三角符文 - Deltarune 绿色免安装硬盘版.zip -``` - -在左上角选中 `选手` ,点击 `整理文件` 。 - -`Mona` 就会变成这样: - -```plain -Mona -| t1 -| | t1.cpp -| t2 -| | t21.out -| | t22.out -| | t23.out -| t3 -| | t3.cpp -| t1.cpp -| t21.out -| t22.out -| t23.out -| t3.cpp -``` - -## 导出成绩 - -去 `控制` > `导出成绩` 。 - -它将导出一个 HTML 或 CSV (Windows 中还有 XLS) 文件,记录所有选手的成绩。 - -导出 HTML 有两种模式:完整版和压缩版。 - -完整版 HTML 有更多的颜色,支持题目跳转; - -压缩版 HTML 体积更小,比原来的还要小 20% 到 50%。 - -使用后缀 `*.html` 的时候启用完整版,使用后缀 `*.htm` 的时候使用压缩版。 - - - -## 比赛统计信息 - -在作者用了一下 Arbiter,受到它的刺激之后,作者写了个统计功能。 - -这意味着,LemonLime 的栏数增加到 3 栏。 - -如果比赛题目和选手都不为空,那么每次操作后都会更新统计信息。 - -当前只有分数-人数统计和平均分功能,更多内容~~在路上了~~ \ No newline at end of file diff --git a/guide/guidedata/judge.md b/guide/guidedata/judge.md deleted file mode 100755 index 8ab9f6ba..00000000 --- a/guide/guidedata/judge.md +++ /dev/null @@ -1,80 +0,0 @@ -# 评测 - -在左上角选中 `选手` ,进入选手名单。 - -点击选手名单的表头可以对某一个参数排序。 - -## 背景颜色 - -正常评测的成绩将会拥有以绿色为基础颜色的背景颜色。 - -颜色从白到绿对应分数从低到高,总分的颜色会更深。这个配色方案大体来自 IOI。 - -如果出现 `编译错误`、`编译超时` 等不正常情况,背景颜色将会是粉色。 - -如果出现 `未找到选手程序`,背景颜色将会是灰色。 - -## 整理文件 - -> **! 注意** -> -> 如果子文件夹里面的文件有文件名和子文件夹外面的文件相同的,子文件夹**外面的文件会丢失**! -> -> **大部分**无关文件也将**全部丢失**! -> -> 最好在整理文件之前备份一份,以防不测。 - -为每个选手的每一个文件创建它的子文件夹内的文件和子文件夹外的文件,无论它们以前是在子文件夹内还是子文件夹外,并且删除大部分无用文件。 - - -## 刷新 - -刷新选手列表。 - -## 测试选中 - -可以选中任意选手的任意题目。 - -在选手列表中选中一些选手的一些题目,点击 `测试选中` 就能测试它们。 - -如果选中了某选手的排名、名称、总分、总用时、测试时间的其中某一个,那么将默认测试这个选手的所有题目。 - -## 测试全部 - -测试全部选手的全部题目。 - -## 测试未测试 - -测试所有选手的还没有测试的题目,并且更新成绩。 - -## 测试未找到文件的 - -测试所有选手的未找到文件的情况的题目。 - -## 测试编译出错的 - -测试所有选手的编译出错的情况(编译错误、编译超时等)的题目。 - -## 测试情况对话框 - -这个对话框会实时显示当前评测的情况。 - -不同的评测结果的字体颜色会不相同。 - -如果选手在某一个测试点 `答案正确` 或者 `答案部分正确`,那么会显示它的得分、用时和所使用的空间。 - -进度条上会显示当前进度和总时间限制。 - -### * 跳过这一题 - -当你肯定某个选手是卡评测或者其它原因,或者这个题的评测结果无关紧要(比如自己自娱自乐的时候),那么可以点击 `跳过这一题` 。 - -这会打断当前评测的题目,并跳过这道题之后的所有测试点。 - -跳过的测试点会显示 `超过时间限制`。(如果显示 `被跳过`,那被跳过的人看到了肯定会很不高兴然后 D 评测人员。) - -注意:LemonLime 使用 GPLV3 许可证,``There is no warranty for this free software``。 - -### 停止测试 - -点击后将停止测试,保留之前测试过后得到的所有分数数据。 \ No newline at end of file diff --git a/guide/guidedata/settings.md b/guide/guidedata/settings.md deleted file mode 100755 index ed39342d..00000000 --- a/guide/guidedata/settings.md +++ /dev/null @@ -1,93 +0,0 @@ -# 设置 - -选择 `工具` > `选项` , 进入设置栏。 - -## 常规 - -这里来设置 LemonLime 的各种默认参数。 - -### 默认分值 - -这是给题目新增测试点的时候,这个测试点的默认分值。 - -### 默认时间限制 - -这是自动添加题目的时候,给所有识别到的测试点的默认时间限制。 - -### 默认空间限制 - -这是自动添加题目的时候,给所有识别到的测试点的默认空间限制。 - -> 为了迎合时代的发展,这个值被默认设成 512 (MB)。 - -### 编译时间限制 - -编译选手源程序的时间限制。 - -如果编译时间超过这个限制,那么将显示 `编译超时`。 - -### 校验器时间限制 - -校验器检查选手输出文件的时间限制。 - -如果校验器所使用的时间超过这个限制,那么将显示 `校验器超过时间限制`。 - -### 源程序大小限制 - -大于这个大小的源程序将不会被识别。 - -> 1 KB = 1024 B - -### 最大重测次数 - -由于计算机的性能波动,在极端情况下可能会有选手的答案在超时与不超时之间徘徊。 - -如果有选手超时但只比时间限制多一点点,那么就会开始重新测试,直到有一次跑进时间限制,或者次数达到了最大重测次数。 - -> 这个值默认是 1 (次)。最多可以设置成 12 (次)。 - -### 输入文件扩展名 - -在自动添加题目的时候的默认输入文件扩展名。 - -### 输出文件扩展名 - -在自动添加题目的时候的默认输出文件扩展名。 - -## 编译器 - -### 编译器名称 - -改变选中的编译器的名字。 - -这不会影响它对应的编译器/解释器名称。 - -### 源程序扩展名 - -如果选手的源程序是这些扩展名,那么就会采用这个编译器来测试。 - -排在前面(上方)的编译器更优先。 - -### 高级选项 - -> 这个界面被大改过。 - -#### 位置 - -改变编译器/解释器的位置。 - -#### 时间、内存限制 - -评测时,真正的时间限制和空间限制会乘上这个参数。 - -#### 参数 - -可以调节编译器参数和解释器参数。 - -点击 `添加…`来添加新的配置。 - -每一道题目只能对应一种配置。 - -#### 环境变量 - -编译程序的时候提供环境变量。 diff --git a/guide/guidedata/specialjudge.md b/guide/guidedata/specialjudge.md deleted file mode 100755 index d65c4f9d..00000000 --- a/guide/guidedata/specialjudge.md +++ /dev/null @@ -1,146 +0,0 @@ -# 自定义校验器 (Special Judge) - -LemonLime 的校验器和其它版本的 Lemon 通用。 - -你的校验器需要接收6个参数流: - -argv[1] : (输入)标准输入文件 - -argv[2] : (输入)选手的输出文件 - -argv[3] : (输入)答案文件 - -argv[4] : (输入)这个测试点的满分 - -argv[5] : (输出)得到的分数(一个整数) - -argv[6] : (输出)额外信息 - -下面是一个例子。 - -```cpp -#include -using namespace std; - -ifstream fin, fout, fstd; -ofstream fscore, freport; - -inline void quit(int score, const char *msg) -{ - fscore << score; - freport << msg; - - fin.close(); - fout.close(); - fstd.close(); - fscore.close(); - freport.close(); - - exit(0); -} - -int main(int argc, char **argv) -{ - fin.open(argv[1]); - fout.open(argv[2]); - fstd.open(argv[3]); - int fullScore = atoi(argv[4]); - fscore.open(argv[5]); - freport.open(argv[6]); - - string ps, js; - fout >> ps; - fstd >> js; - - int P = js.length(); - int Q = ps.length(); - - int K = 0; - for (int i = 0; i < min(P, Q); i++) - if (js[i] == ps[i]) K++; - - if (Q > P) K -= Q - P; - - if (K >= P) - { - quit(fullScore, "Success: All Charming! Pure Memory! Million Master! YOU WILL AK IOI!"); - return 0; - } - - double ratio = 1.00 * K / P; - - if (ratio >= 0.9999) { quit(0.9 * fullScore, "Almost Success: 90%!"); return 0; } - if (ratio >= 0.999) { quit(0.8 * fullScore, "Nearly Success: 80%!"); return 0; } - if (ratio >= 0.99) { quit(0.7 * fullScore, "Partly Success: 70%!"); return 0; } - if (ratio >= 0.95) { quit(0.6 * fullScore, "Passed Success: 60%!"); return 0; } - if (ratio >= 0.9) { quit(0.5 * fullScore, "Half Success: 50%!"); return 0; } - if (ratio >= 0.6) { quit(0.4 * fullScore, "Great: 40%!"); return 0; } - if (ratio >= 0.4) { quit(0.3 * fullScore, "Good: 30%!"); return 0; } - if (ratio >= 0.1) { quit(0.2 * fullScore, "Poor: 20%."); return 0; } - if (ratio >= 0.0000001145141919810) { quit(0.1 * fullScore, "Miss: 10%."); return 0; } - - quit(0, "Failed: @_@????????"); - - return 0; -} - -``` - -(你猜这是什么题) - -## testlib - -在 LemonLime 源代码可以找到 `testlib_for_lemons.h` 。 - -具体使用参照其它的资料。 - -把上面的 spj 重写后如下所示: - -```cpp -#include -#include"testlib_for_lemons.h" - -using namespace std; - -int main(int argc, char **argv) -{ - registerLemonChecker(argc, argv); - int fullScore = perfectScore; - - string ps = ouf.readToken(); - string js = ans.readToken(); - - int P = js.length(); - int Q = ps.length(); - - int K = 0; - for (int i = 0; i < min(P, Q); i++) - if (js[i] == ps[i]) K++; - - if (Q > P) K -= Q - P; - - if (K >= P) - { - quitf(_ok, "Success: All Charming! Pure Memory! Million Master! YOU WILL AK IOI!"); - return 0; - } - - double ratio = 1.00 * K / P; - - if (ratio >= 0.9999) { quitp(0.9 * fullScore, "Almost Success: 90%%!"); return 0; } - if (ratio >= 0.999) { quitp(0.8 * fullScore, "Nearly Success: 80%%!"); return 0; } - if (ratio >= 0.99) { quitp(0.7 * fullScore, "Partly Success: 70%%!"); return 0; } - if (ratio >= 0.95) { quitp(0.6 * fullScore, "Passed Success: 60%%!"); return 0; } - if (ratio >= 0.9) { quitp(0.5 * fullScore, "Half Success: 50%%!"); return 0; } - if (ratio >= 0.6) { quitp(0.4 * fullScore, "Great: 40%%!"); return 0; } - if (ratio >= 0.4) { quitp(0.3 * fullScore, "Good: 30%%!"); return 0; } - if (ratio >= 0.1) { quitp(0.2 * fullScore, "Poor: 20%%."); return 0; } - if (ratio >= 0.0000001145141919810) { quitp(0.1 * fullScore, "Miss: 10%%."); return 0; } - - quitf(_wa, "Failed: @_@????????"); - - return 0; -} - -``` - diff --git a/guide/guidedata/welcome.md b/guide/guidedata/welcome.md deleted file mode 100755 index 939a253a..00000000 --- a/guide/guidedata/welcome.md +++ /dev/null @@ -1,7 +0,0 @@ -# 欢迎使用 LemonLime - -LemonLime 是基于 LemonPlus (更前身是 Lemon)的一个为 OIer 提供本地评测环境的软件。 - -LemonLime 的协议为 GPL 3.0。 - -曾经使用的名称为 LemonPt。 \ No newline at end of file diff --git a/lemon.cpp b/lemon.cpp index 7c480857..d31eebbe 100644 --- a/lemon.cpp +++ b/lemon.cpp @@ -134,6 +134,8 @@ Lemon::Lemon(QWidget *parent) : this, SLOT(addTasksAction())); connect(ui->exportAction, SIGNAL(triggered()), this, SLOT(exportResult())); + connect(ui->actionExportStatistics, SIGNAL(triggered()), + this, SLOT(exportStatstics())); connect(ui->aboutAction, SIGNAL(triggered()), this, SLOT(aboutLemon())); @@ -902,6 +904,7 @@ void Lemon::loadContest(const QString &filePath) ui->saveAction->setEnabled(true); ui->addTasksAction->setEnabled(true); ui->exportAction->setEnabled(true); + ui->actionExportStatistics->setEnabled(true); ui->actionChangeContestName->setEnabled(true); ui->cleanupAction->setEnabled(false); ui->refreshAction->setEnabled(false); @@ -943,6 +946,7 @@ void Lemon::newContest(const QString &title, const QString &savingName, const QS ui->saveAction->setEnabled(true); ui->addTasksAction->setEnabled(true); ui->exportAction->setEnabled(true); + ui->actionExportStatistics->setEnabled(true); ui->actionChangeContestName->setEnabled(true); ui->cleanupAction->setEnabled(false); ui->refreshAction->setEnabled(false); @@ -980,6 +984,7 @@ void Lemon::closeAction() ui->saveAction->setEnabled(false); ui->addTasksAction->setEnabled(false); ui->exportAction->setEnabled(false); + ui->actionExportStatistics->setEnabled(false); ui->actionChangeContestName->setEnabled(false); ui->cleanupAction->setEnabled(false); ui->refreshAction->setEnabled(false); @@ -1191,6 +1196,11 @@ void Lemon::exportResult() ExportUtil::exportResult(this, curContest); } +void Lemon::exportStatstics() +{ + StatisticsBrowser::exportStatstics(this, curContest); +} + void Lemon::aboutLemon() { QString text; diff --git a/lemon.h b/lemon.h index 5a1dca06..dacc7a7a 100755 --- a/lemon.h +++ b/lemon.h @@ -87,6 +87,7 @@ private slots: void loadAction(); void addTasksAction(); void exportResult(); + void exportStatstics(); void aboutLemon(); void actionChangeContestName(); void actionCompileFeatures(); diff --git a/lemon_zh_CN.qm b/lemon_zh_CN.qm index b838ed24f012eff03b9394c62df4d8aa5ac50216..9fd6c8fc6097367f48e7829aafb77644a666fc8b 100755 GIT binary patch delta 3021 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 - - + + LemonLime Lemon LemonLime @@ -1820,7 +1820,7 @@ 编译选项(&C) - + Single &Judge Single Judge 测试某一题(&J) @@ -1830,7 +1830,7 @@ 测试 - + Judge &All 测试全部(&A) @@ -1859,7 +1859,7 @@ 控制(&C) - + &Tools 工具(&T) @@ -1868,74 +1868,74 @@ 设置语言(&U) - + &Guides Guides 指南(&G) - + Export the result... 导出成绩… - + Judge &Unjudged Judge &Single Task 测试未测试(&U) - + Open Current Contest &Folder 打开当前比赛的目录(&F) - + Open the folder of this contest with file manager... 在文件管理器中打开这个比赛的目录… - + &Save Current Contest 保存比赛文件(&S) - + Save this contest... 保存这个比赛… - + How to make Interaction Tasks... 如何添加交互题… - + How to make Subtasks... 如何创建打包的测试点(Subtasks)… - + What is Cleanup Files... 什么是整理文件… - + The difference in compiling between Lemon and LemonLime... LemonLime 编译文件的不同… - + What is Skip... 什么是“跳过这一题”… - + How to write Special Judge... 如何写一个校验器… - + New features of Exporting Result... LemonLime 新加的关于导出文件的特性… @@ -1944,7 +1944,7 @@ 更多(&M) - + Online Guides... 在线帮助… @@ -1953,7 +1953,7 @@ 测试未找到文件的(&G) - + Judge "No Source"... 测试“未测试”… @@ -1962,26 +1962,26 @@ 测试编译出错的(&M) - + Judge "Compile Error", "Compile Time Limit Exceeded", etc... 测试“编译错误”、“编译超时”等… - + C&hange Contest Name Change Contest Name 更改比赛标题(&H) - - + + Interaction &Interaction 交互题设置 - - + + Compile Features &Compile Features 编译选项 @@ -2006,22 +2006,22 @@ 界面语言 - + &Help 帮助(&H) - + &New Contest 新建比赛(&N) - + &Open Existing Contest 打开已有的比赛(&O) - + E&xit 退出(&X) @@ -2030,24 +2030,24 @@ 选项(&O) - + &About 关于(&A) - + &Judge Selected 测试选中选手(&J) - - - - - - - - + + + + + + + + Clean up Files &Clean up Files 整理文件 @@ -2089,7 +2089,7 @@ - + Cleanup the files of all contestants... 整理所有选手文件… @@ -2100,13 +2100,13 @@ - + Refresh the contestant list... 刷新选手列表… - + Judge unjudged... 测试未测试… @@ -2118,13 +2118,13 @@ - + Judge selected area... 测试指定区域… - + Judge all contestants... 测试所有选手… @@ -2144,153 +2144,162 @@ 打开 / 关闭 / 重命名比赛等 - + Switch Language... 切换语言… - + UI &Language 设置语言(&L) - + LemonLime Guides... LemonLime 教程… - + Make a new contest... 创建新的比赛… - + Open an existing contest... 找到一场比赛,并打开它… - + Exit LemonLime... 退出 LemonLime… - + &Settings 设置(&S) - + LemonLime Settings... LemonLime 设置… - + About LemonLime... 关于 LemonLime… - + &Close Current Contest 关闭当前的比赛(&C) - + Close this contest... 关闭这个比赛… - + Add &Tasks Automatically 自动添加试题(&T) - + Find your tasks in ./data and add them automatically... 在 ./data 里寻找题目,并且自动添加它们… - + &Make Self-testing Folder 创建批处理测试目录(&M) - + &Export Result 导出成绩(&E) - + Subtasks 打包的测试点 - + Skip 跳过这一题 - + Special Judge 自定义校验器(SPJ) - + Export Result 导出成绩 - + More 更多 - + Judge &No Source 测试无源文件(&N) - + Judge &Compile Failed 测试编译问题(&C) - + Change the name of this contest... 修改这场比赛的名字… - + Clean Up &Files 整理文件(&F) - + &Refresh 刷新(&R) - - + + Communication 通信题 - + How to make Communication Tasks... 如何添加通信题… - + + Export &Statistics + 导出统计信息(&S) + + + Export Statistics + 导出统计信息 + + + English 简体中文 - + Are you sure to Clean up Files? 确定要整理文件吗? - + Reading guide are recommended. 建议参看教程后再确认操作。 @@ -2299,7 +2308,7 @@ 创建备份文件到 <br> `source.bak'? - + Aborted. 没有进行整理。 @@ -2312,105 +2321,105 @@ 没有进行整理:没法创建 `source.bak'。 - + Making Backup... 备份中… - + Cleaning 整理中 - + Working on it... 正在整理… - + Fetching Data... 抓取题目数据… - + Initing... 预处理中… - + Now Cleaning... 整理文件中… - + Finished. 整理完成。 - + Aborted 没有进行整理 - - - - - + + + + + Error 出错了 - - + + Cannot open file %1 无法打开 %1 - + Save Failed 保存失败 - + Saved 已保存 - - + + File %1 is broken %1 已损坏 - - - + + + LemonLime - %1 LemonLime - %1 - + UNSTABLE VERISON 不稳定版本 - + Rename Contest 重命名比赛 - + Input the name you prefer. 输入你想要的名字。 - + New name... 新名字… - + Notice that you may use `atoi(argv[4])' to get the correct full score. Notice that you may use `atoi(argv[4])' to get the correct full score. 你可能得用 `atoi(argv[4])' 来获得正确的总分。 @@ -2424,173 +2433,173 @@ 注意 - + Aborted: Cannot make dir `%1'. 没有进行整理:没法创建 `%1'。 - - + + The paths are based on your "/data". 你需要提供你的交互库和接口。最好还有一个SPJ-以lemon族评测系统的标准来进行编写。它们的路径以 data 文件夹为根进行填写。 - + There is a example of how to use Interaction type tasks: 下面是一个使用交互型的题目的配置例子: - + Interactor Path: matrix/matrix.h 交互库路径: matrix/matrix.h - + Interactor Name: matrix.h 交互库名称: matrix.h - + Grader Path: matrix/grader.cpp 接口实现(grader)路径: matrix/grader.cpp - + Contestants should provide source files. 选手要提供源文件。 - + Problem setters should provide grader files. 评测端要提供接口文件。 - + There is a example of how to use Communication type tasks: 下面是一个例子: - + Source Files: 源程序列表: - + Alice.cpp Alice.cpp Alice.cpp Alice.cpp - + Bob.cpp Bob.cpp Bob.cpp Bob.cpp - + Grader Files: 接口文件列表: - + taskname/Alice.h Alice.h taskname/Alice.h Alice.h - + taskname/Bob.h Bob.h taskname/Bob.h Bob.h - + taskname/Grader.cpp Grader.cpp taskname/Grader.cpp Grader.cpp - + About Communication 关于通信题 - + Something about how to make Subtasks 关于创建打包的测试点的一些经验 - + How to make a valid Regular Expression: 如何写一个语法正确的正则表达式: - + Numbers: \d* 匹配任意数量的数字: \d* - + Notes: 提示: - + "\d" means a number. "\d" 表示匹配一个数字。 - + "." means a character. "." 表示匹配任意一个字符。 - + "*" means repeat previous order 0~inf times. "*" 表示把之前的那个表达式重复 0 到无限大遍。 - + Something about Exporting Result 关于导出成绩的特性 - + HTML, CSV, XLS (Windows only) are supported. 支持导出HTML, CSV, XLS (仅Windows)。 - + There are two modes of exported HTML: Full and Compressed. 导出 HTML 有两种模式:完整版和压缩版。 - + Full HTML has more hrefs and color; 完整版 HTML 有更多的颜色,支持题目跳转; - + Compressed HTML has smaller size. 压缩版 HTML 体积更小,比原来的还要小 20% 到 50%。 - + Enable Full mode with suffix *.html and enable Compressed mode with suffix *.htm. 使用后缀“*.html”的时候启用完整版,使用后缀“*.htm”的时候使用压缩版。 - + About Exporting Result 关于导出成绩 - + What is Clean Up Files 什么是整理文件 - + It can make all of the source files have a copy in the subdirs. 为每个选手的每一个文件创建它的子文件夹内的文件和子文件夹外的文件,无论它们以前是在子文件夹内还是子文件夹外。 - + When there are files both inside the subdirs and outside of subdirs, the one INSIDE will cover another one. 当文件夹内外都有文件的时候,文件夹里面的文件会覆盖文件夹外面的。 @@ -2599,7 +2608,7 @@ 当文件夹内外都有文件的时候,文件夹外面的文件会覆盖文件夹里面的。 - + Be Careful : May Cause Unexpected File Damage. 当心使用:原有的子文件夹内的本来的文件会丢失。 @@ -2608,12 +2617,12 @@ 当心使用:原有的子文件夹的本来的文件会丢失。 - + About Clean Up Files 关于 整理文件 - + Use it when you have no time ONLY. 只在你想节省时间的时候使用。 @@ -2626,7 +2635,7 @@ 你也可以选定指定的人来重测它们的某一道题。 - + How to make a Special Judge for Lemon 如何写一个 Lemon 的校验器 @@ -2635,23 +2644,23 @@ LemonLime - %1 - + Cannot make contest path 无法创建比赛目录 - + No task found 找不到任何试题 - + A tiny judging environment for OI contest based on Project Lemon A tiny judging environment for OI contest 基于Lemon的简易OI竞赛测试环境 - + Based on Project Lemon version 1.2 Beta by Zhipeng Jia, 2011 Base on Project Lemon version 1.2 Beta by Zhipeng Jia, 2011 基于Lemon v1.2 by Zhipeng Jia, 2011 @@ -2665,19 +2674,19 @@ 由Dust1404更新 - + Update by Dust1404 and iotang Featured by iotang 由 Dust1404 和 iotang 更新 - + We have made stack space equals to memory limit. If the memory limit is unlimited, stack space will be 2.00 GB. 我们把栈空间设置成和内存限制相同。 如果内存限制为无限制,那么栈空间会被设置成 2.00 GB。 - + About Compile Features 关于 编译选项 @@ -2699,7 +2708,7 @@ 接口实现(grader)路径 matrix/grader.cpp - + About Interaction 关于 交互题 @@ -2717,23 +2726,23 @@ 匹配任意数量的数字: \d* - + <a href="http://www.runoob.com/java/java-regular-expressions.html">More Regular Expression Rules</a> More : <a href="http://www.runoob.com/java/java-regular-expressions.html"> <a href="http://www.runoob.com/java/java-regular-expressions.html">更多正则表达式规则</a> - + There is a example of how to use regular expressions to make subtasks: 下面是一个例子: - + Making backup files to dir <br> `%1'? 创建备份文件到 <br> `%1'? - + Aborted: `%1' already exist. 没有进行整理:`%1' 已经存在。 @@ -2742,25 +2751,25 @@ 没有进行整理:没法创建 `%1'。 - + Data(in): matrix/matrix&lt;1&gt;.in Data(in): matrix/matrix<1>.in 输入文件:matrix/matrix&lt;1&gt;.in - + Data(out): matrix/matrix&lt;1&gt;.out Data(out): matrix/matrix<1>.out 输出文件:matrix/matrix&lt;1&gt;.out - + And the "&lt;1&gt;" is "\d*". And the "<1>" is "\d*". 把"&lt;1&gt;"设为"\d*"。 - + About Subtasks 关于 打包的测试点 @@ -2778,17 +2787,17 @@ 关于 整理文件 - + What is Skip 什么是“跳过这一题” - + It can stop a judging task. 这可以中断一个题目的评测。当前正在测试的点测完后,在后面的点被生效。中断的时候所有没有评测的点会显示为“超过时间限制”。 - + The tasks which are not tested will be displayed as "Time Limit Exceeded". 而还没有测试的点也会被显示成“超过时间限制”。 @@ -2797,7 +2806,7 @@ 在你想节省时间的时候使用。 - + About Skip 关于 “跳过这一题” @@ -2818,37 +2827,37 @@ 怎么写自定义校验器(SPJ) - + The special judge should take 6 arguments below: 你的校验器需要接收6个参数流: - + argv[1] : (in) Standard Input argv[1] : (输入)标准输入文件 - + argv[2] : (in) Participant's Answer argv[2] : (输入)选手的输出文件 - + argv[3] : (in) Jury's Answer argv[3] : (输入)答案文件 - + argv[4] : (in) Full score of this task argv[4] : (输入)这个测试点的满分 - + argv[5] : (out) The score (A integer only) argv[5] : (输出)得到的分数(一个整数) - + argv[6] : (out) Notes argv[6] : (输出)额外信息 @@ -2857,7 +2866,7 @@ Lemon Pt 的SPJ标准和所有Lemon族的测试器的标准是一样的。下面的SPJ样例展示了接口的编号对应的内容。 - + About Special Judge 关于 自定义校验器(SPJ) @@ -2866,7 +2875,7 @@ 项目地址 - + About LemonLime About LemonPlus 关于 LemonLime @@ -2876,7 +2885,7 @@ v1.2 测试版 - + Build Date: %1 构建日期:%1 @@ -2885,7 +2894,7 @@ Copyright (c) 2011 Zhipeng Jia - + This program is under the <a href="http://www.gnu.org/licenses/gpl-3.0.html">GPLv3</a> license 本程序基于<a href="http://www.gnu.org/licenses/gpl-3.0.html">GPLv3</a>许可协议 @@ -3159,130 +3168,162 @@ p, li { white-space: pre-wrap; } - + + No contest yet 还没有比赛 - + + No task yet 还没有题目 - + + No contestant yet 还没有参赛者 - + Contest 比赛 - + Overall 总览 - + Score 得分 - + Count 数量 - + Ratio 占比 - + Prefix 前缀和 - + Suffix 后缀和 - - + + Average 平均 - + Standard Deviation 标准差 - + Score Discrimination Power 区分度 - + No. 编号. - + Input 输入 - + Output 输出 - + Pure Arcaea Pure - + Far Arcaea Far - + Lost Arcaea Lost - + Files 个文件 - + Warning: Judgement is not finished. 警告:没有测试完全部选手。 - + Problems 题目 - + Task 试题 - + Number of answer submitted 提交人数 + + + + + + + LemonLime + LemonLime + + + + Cannot open file %1 + 无法打开 %1 + + + + Export is done + 导出完成 + + + + HTML Document (*.html) + HTML文档 (*.html) + + + + Export Statstics + 导出统计信息 + SummaryTree diff --git a/settings.cpp b/settings.cpp index f059859b..d5d99faf 100644 --- a/settings.cpp +++ b/settings.cpp @@ -205,7 +205,7 @@ void Settings::swapCompiler(int a, int b) { if (0 <= b && b < compilerList.size()) { - compilerList.swapItemsAt(a, b); + compilerList.swap(a, b); } } } diff --git a/statisticsbrowser.cpp b/statisticsbrowser.cpp index 87f875fa..986daa99 100644 --- a/statisticsbrowser.cpp +++ b/statisticsbrowser.cpp @@ -30,6 +30,7 @@ #include #include #include +#include StatisticsBrowser::StatisticsBrowser(QWidget *parent) : QWidget(parent), @@ -273,4 +274,62 @@ void StatisticsBrowser::refresh() buffer += ""; ui->textBrowser->setHtml(buffer); + nowBrowserText = buffer; +} + +void StatisticsBrowser::exportStatsticsHtml(QWidget *widget, const QString &fileName) +{ + QFile file(fileName); + + if (! file.open(QFile::WriteOnly)) + { + QMessageBox::warning(widget, tr("LemonLime"), tr("Cannot open file %1").arg(QFileInfo(file).fileName()), + QMessageBox::Ok); + return; + } + + QApplication::setOverrideCursor(Qt::WaitCursor); + QTextStream out(&file); + + out.setCodec("UTF-8"); + out << nowBrowserText; + + QApplication::restoreOverrideCursor(); + QMessageBox::information(widget, tr("LemonLime"), tr("Export is done"), QMessageBox::Ok); +} + +void StatisticsBrowser::exportStatstics(QWidget *widget, Contest *curContest) +{ + QString buffer; + + if (! curContest) + { + QMessageBox::warning(widget, tr("LemonLime"), tr("No contest yet"), QMessageBox::Ok); + return; + } + + QList taskList = curContest->getTaskList(); + QList contestantList = curContest->getContestantList(); + + if (taskList.size() <= 0) + { + QMessageBox::warning(widget, tr("LemonLime"), tr("No task yet"), QMessageBox::Ok); + return; + } + + if (contestantList.size() <= 0) + { + QMessageBox::warning(widget, tr("LemonLime"), tr("No contestant yet"), QMessageBox::Ok); + return; + } + + QString filter = tr("HTML Document (*.html)"); + + QString fileName = QFileDialog::getSaveFileName(widget, tr("Export Statstics"), + QDir::currentPath() + QDir::separator() + "statstics.html", filter); + + if (fileName.isEmpty()) return; + + if (QFileInfo(fileName).suffix() == "html") exportStatsticsHtml(widget, fileName); + } diff --git a/statisticsbrowser.h b/statisticsbrowser.h index 04172a96..0401a440 100644 --- a/statisticsbrowser.h +++ b/statisticsbrowser.h @@ -32,6 +32,8 @@ namespace Ui class Contest; class TestCase; +static QString nowBrowserText; + class StatisticsBrowser : public QWidget { Q_OBJECT @@ -39,6 +41,7 @@ class StatisticsBrowser : public QWidget public: explicit StatisticsBrowser(QWidget *parent = nullptr); void setContest(Contest *); + static void exportStatstics(QWidget *, Contest *); ~StatisticsBrowser(); public slots: @@ -49,6 +52,7 @@ public slots: Contest *curContest; QString getScoreNormalChart(QMap, int, int); QString getTestcaseScoreChart(QList, QList>>, QList>>); + static void exportStatsticsHtml(QWidget *, const QString &); }; #endif // STATISTICSBROWSER_H