-
Notifications
You must be signed in to change notification settings - Fork 1
/
turtle_judge.py
executable file
·115 lines (99 loc) · 4.73 KB
/
turtle_judge.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
"""turtle judge main script."""
import base64
import os
import sys
from judge.dodona_command import (
Context,
DodonaException,
ErrorType,
Judgement,
MessageFormat,
MessagePermission,
Tab,
Test,
TestCase,
)
from judge.dodona_config import DodonaConfig
from judge.runtime import diff_images, generate_png_image, generate_svg_byte_stream
from judge.translator import Translator
# extract info from exercise configuration
config = DodonaConfig.from_json(sys.stdin.read())
with Judgement():
config.sanity_check()
# Initiate translator
config.translator = Translator.from_str(config.natural_language)
# Set 'canvas_width' to 400 if not set
config.canvas_width = int(getattr(config, "canvas_width", "400"))
# Set 'canvas_height' to 250 if not set
config.canvas_height = int(getattr(config, "canvas_height", "250"))
# Set 'solution_file' to "./solution.py" if not set
config.solution_file = str(getattr(config, "solution_file", "./solution.py"))
config.solution_file = os.path.join(config.resources, config.solution_file)
if not os.path.exists(config.solution_file):
raise DodonaException(
config.translator.error_status(ErrorType.RUNTIME_ERROR),
permission=MessagePermission.STAFF,
description=f"Could not find solution file: '{config.solution_file}'.",
format=MessageFormat.TEXT,
)
with Tab(config.translator.translate(Translator.Text.COMPARING_IMAGES)):
with Context(), TestCase(
format=MessageFormat.PYTHON,
description="",
):
try:
svg_submission = generate_svg_byte_stream(config.source, config.canvas_width, config.canvas_height)
except BaseException as error:
raise DodonaException(
config.translator.error_status(ErrorType.COMPILATION_ERROR),
description=config.translator.translate(Translator.Text.SOLUTION_EXECUTION_ERROR, error=error),
format=MessageFormat.CODE,
) from error
try:
svg_solution = generate_svg_byte_stream(config.solution_file, config.canvas_width, config.canvas_height)
except BaseException as error:
raise DodonaException(
config.translator.error_status(ErrorType.COMPILATION_ERROR),
permission=MessagePermission.STAFF,
description=config.translator.translate(Translator.Text.SUBMISSION_EXECUTION_ERROR, error=error),
format=MessageFormat.CODE,
) from error
png_submission = generate_png_image(svg_submission, config.canvas_width, config.canvas_height)
png_solution = generate_png_image(svg_solution, config.canvas_width, config.canvas_height)
correct_pixels, total_pixels, expected_total = diff_images(png_submission, png_solution)
# base64_submission = base64.b64encode(svg_submission).decode("utf-8")
# base64_solution = base64.b64encode(svg_solution).decode("utf-8")
svg_submission_str = svg_submission.decode("utf-8")
svg_solution_str = svg_solution.decode("utf-8")
html = f"""
<div style="display:inline-block;width:50%;">
<p style="padding:10px">{config.translator.translate(Translator.Text.SUBMISSION_TITLE)}</p>
<div style="width:98%;background-color:#fff">{svg_submission_str}</div>
</div>
<div style="display:inline-block;float:right;width:50%;">
<p style="padding:10px">{config.translator.translate(Translator.Text.SOLUTION_TITLE)}</p>
<div style="width:98%;background-color:#fff">{svg_solution_str}</div>
</div>
"""
with Test(
{
"format": MessageFormat.HTML,
"description": " ".join(html.split()),
},
config.translator.translate(
Translator.Text.FOREGROUND_PIXELS_CORRECT,
correct_pixels=expected_total,
total_pixels=expected_total,
fraction=1,
),
) as test:
test.generated = config.translator.translate(
Translator.Text.FOREGROUND_PIXELS_CORRECT,
correct_pixels=correct_pixels,
total_pixels=total_pixels,
fraction=correct_pixels / total_pixels,
)
if correct_pixels < total_pixels:
test.status = config.translator.error_status(ErrorType.WRONG)
else:
test.status = config.translator.error_status(ErrorType.CORRECT)