Skip to content

Commit

Permalink
Use ScoreDict rather than TotalScore for flexible
Browse files Browse the repository at this point in the history
Close #9
  • Loading branch information
aben20807 committed Feb 10, 2021
1 parent 0feac41 commit 0e3bfc8
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 27 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
env/
venv/
.vscode/
__pycache__/
extract/
Expand Down
6 changes: 6 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- repo: https://github.com/psf/black
rev: 20.8b1 # Replace by any tag/version: https://github.com/psf/black/tags
hooks:
- id: black
language_version: python3 # Should be a command that runs python3.6+
files: \.py$
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Given source code, Makefile (or build commands), input files, and answer files t
+ `AnswerDir`: the directory where contains the answer files corresponding to the input files
+ `AnswerExtension`: the extension of the answer files
+ `ExitOrLog`: exit when any error occurred or just log the error
+ `TotalScore`: the total score of the assignment
+ `ScoreDict`: the dictionary for the mapping of correctness and score
+ `Timeout`: execution timeout for each test case
+ Example config file:
```conf
Expand All @@ -89,7 +89,7 @@ Given source code, Makefile (or build commands), input files, and answer files t
AnswerDir = answer
AnswerExtension = .out
ExitOrLog = exit
TotalScore = 100
ScoreDict = {"0":"0","1":"30","2":"60","3":"90","4":"100"}
Timeout = 5
```

Expand Down Expand Up @@ -150,7 +150,7 @@ optional arguments:
AnswerDir = answer
AnswerExtension = .out
ExitOrLog = exit
TotalScore = 100
ScoreDict = {"0":"0","1":"30","2":"60","3":"90","4":"100"}
Timeout = 5
[TaConfig]
Expand Down
2 changes: 1 addition & 1 deletion examples/student/correct/judge.conf
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ TempOutputDir = /tmp/output
DeleteTempOutput = true

ExitOrLog = exit
TotalScore = 100
ScoreDict = {"0":"0","1":"30","2":"60","3":"90","4":"100"}
Timeout = 10
2 changes: 1 addition & 1 deletion examples/student/wrong/judge.conf
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ TempOutputDir = /tmp/output
DeleteTempOutput = true

ExitOrLog = exit
TotalScore = 100
ScoreDict = {"0":"0","1":"30","2":"60","3":"90","4":"100"}
Timeout = 10
8 changes: 8 additions & 0 deletions examples/ta/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,12 @@ Finished

+ excel output

```bash
$ in2csv hw1.xlsx | column -t -n -s,
name student_id a b gg hide xxxx total in_log log_msg
S1 F12345678 True True True True True 100 False
OuO3 OU2345679 0 True not submit
OuO OU2345678 True True True True False 90 False
```

![](./screenshot.png)
2 changes: 1 addition & 1 deletion examples/ta/ta_judge.conf
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ DeleteTempOutput = true
AnswerDir = ./judge_resources/answer
AnswerExtension = .out
ExitOrLog = exit
TotalScore = 100
ScoreDict = {"0":"0","1":"30","2":"60","3":"80","4":"90","5":"100"}
Timeout = 10

[TaConfig]
Expand Down
29 changes: 17 additions & 12 deletions judge/judge.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
SOFTWARE.
"""

__version__ = "2.1.0"
__version__ = "2.2.0"

import sys

Expand All @@ -48,6 +48,7 @@
from shutil import copyfile
from shutil import copymode
import signal
import json


GREEN = "\033[32m"
Expand Down Expand Up @@ -142,6 +143,7 @@ def __init__(self, config, error_handler):
self._ans_dir = self._config["AnswerDir"]
self._ans_ext = self._config["AnswerExtension"]
self.timeout = self._config["Timeout"]
self.score_dict = json.loads(self._config["ScoreDict"])
self.error_handler = error_handler
# tests contains corresponding input and answer path
self.tests = self.inputs_to_tests(self._config["Inputs"])
Expand Down Expand Up @@ -327,11 +329,14 @@ def compare(


class Report:
def __init__(self, report_verbose=0, total_score=100):
self.total_score = total_score
def __init__(self, report_verbose=0, score_dict=None):
self.score_dict = score_dict
self.report_verbose = report_verbose
self.table = []

def get_score_by_correct_cnt(self, correct_cnt: int):
return int(self.score_dict[str(correct_cnt)])

def print_report(self):
"""Print the report into table view."""
self.table.sort(key=lambda x: x["test"])
Expand Down Expand Up @@ -367,15 +372,14 @@ def print_report(self):
print(row["diff"])
print(doubledash)
correct_cnt = [row["accept"] for row in self.table].count(True)
correct_rate = float(100 * correct_cnt / len(tests))
obtained_score = float(self.total_score) * correct_cnt / len(tests)
obtained_score = self.get_score_by_correct_cnt(correct_cnt)
total_score = int(self.score_dict[str(len(tests))])
print(
"Correct rate: {}%\nObtained/Total scores: {}/{}".format(
str(correct_rate), str(obtained_score), self.total_score
)
f"Correct/Total problems:\t{correct_cnt}/{len(tests)}\n"
f"Obtained/Total scores:\t{obtained_score}/{total_score}"
)
returncode = 0
if obtained_score < float(self.total_score) and int(self.report_verbose) < 1:
if obtained_score < total_score and int(self.report_verbose) < 1:
print("\n[INFO] set `-v 1` to get diff result.")
print("For example: `python3 judge/judge.py -v 1`")
returncode = 1
Expand Down Expand Up @@ -412,15 +416,15 @@ def get_args():
return parser.parse_args()


def judge_all_tests(judge: LocalJudge, verbose_level, total_score):
def judge_all_tests(judge: LocalJudge, verbose_level, score_dict):
"""Judge all tests for given program.
If `--input` is set, there is only one input in this judgement.
"""

judge.build()

report = Report(report_verbose=verbose_level, total_score=total_score)
report = Report(report_verbose=verbose_level, score_dict=score_dict)
for test in judge.tests:
returncode, output_filepath = judge.run(test.input_filepath)
accept, diff = judge.compare(output_filepath, test.answer_filepath, returncode)
Expand Down Expand Up @@ -481,5 +485,6 @@ def copy_output_to_dir(judge: LocalJudge, output_dir, delete_temp_output, ans_ex
)
exit(returncode)

returncode = judge_all_tests(judge, args.verbose, config["Config"]["TotalScore"])
score_dict = json.loads(config["Config"]["ScoreDict"])
returncode = judge_all_tests(judge, args.verbose, score_dict)
exit(returncode)
25 changes: 16 additions & 9 deletions judge/ta_judge.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
SOFTWARE.
"""

__version__ = "2.1.0"
__version__ = "2.2.0"

import sys

Expand All @@ -50,6 +50,8 @@
import multiprocessing
import signal
import time
import json
from judge import Report

Student = namedtuple("Student", ("id", "zip_type", "zip_path", "extract_path"))

Expand Down Expand Up @@ -160,6 +162,7 @@ def judge_one_student(
print(student.id)
student_path = student.extract_path + os.sep
correctness = [0] * len(lj.tests)
correct_cnt = 0
report_table = []
tj.extract_student(student)
if not os.path.isdir(student_path):
Expand All @@ -184,7 +187,12 @@ def judge_one_student(
report_table.append(
{"test": lj.tests[i].test_name, "accept": accept, "diff": diff}
)
correctness[i] = 1 if accept else 0
if accept:
correct_cnt += 1
correctness[i] = 1
else:
correctness[i] = 0
correctness.append(int(lj.score_dict[str(correct_cnt)]))
result = append_log_msg(correctness, lj.error_handler.get_error(student.id))
if not all_student_results is None:
all_student_results[student.id] = result
Expand All @@ -201,7 +209,9 @@ def write_to_sheet(score_output_path, student_list_path, all_student_results, te
book = load_workbook(student_list_path)
sheet = book.active
new_title = (
["name", "student_id"] + [t.test_name for t in tests] + ["in_log", "log_msg"]
["name", "student_id"]
+ [t.test_name for t in tests]
+ ["total", "in_log", "log_msg"]
)
for idx, val in enumerate(new_title):
sheet.cell(row=1, column=idx + 1).value = val
Expand All @@ -215,11 +225,12 @@ def write_to_sheet(score_output_path, student_list_path, all_student_results, te

this_student_result = [""] * len(tests)
if not this_student_id in all_student_results.keys():
this_student_result.append(0) # not submit: total score is 0
this_student_result = append_log_msg(this_student_result, "not submit")
else:
this_student_result = all_student_results[this_student_id]
for idx, test_result in enumerate(this_student_result):
sheet.cell(row=row[1].row, column=idx + 3).value = test_result
sheet.cell(row=row[1].row, column=idx + 3).value = str(test_result)

book.save(score_output_path)

Expand Down Expand Up @@ -305,11 +316,7 @@ def setup():
res_dict = judge_one_student(student, None, tj, lj, False)
report_table = res_dict["report_table"]

from judge import Report

report = Report(
report_verbose=args.verbose, total_score=ta_config["Config"]["TotalScore"]
)
report = Report(report_verbose=args.verbose, score_dict=lj.score_dict)
report.table = report_table
report.print_report()

Expand Down

0 comments on commit 0e3bfc8

Please sign in to comment.