-
Notifications
You must be signed in to change notification settings - Fork 15
/
_corrigir.py
103 lines (83 loc) · 2.76 KB
/
_corrigir.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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from pathlib import Path
from subprocess import STDOUT, PIPE
import subprocess
import json
import os
import sys
def indent(st):
return "\n".join(" " + ln for ln in st.splitlines())
def error(inpt, out, expect, empty="*none*"):
return "\n".join(
[
"Input:",
indent(inpt or empty),
"Output:",
indent(out or empty),
"Expect:",
indent(expect or empty),
]
)
def check(script: str, inputs: str, expect) -> str:
try:
compile(open(script, encoding="utf-8").read(), script, "exec")
except SyntaxError:
return "Compilation error: not valid Python code!"
cmd = [sys.executable, script]
res = subprocess.run(cmd, input=inputs, stdout=PIPE, stderr=PIPE, text=True)
if res.stderr:
return error(inputs, res.stderr, expect)
elif not res.stdout and not expect.strip():
return None
elif not res.stdout:
return error(inputs, "", expect)
elif (out := res.stdout).strip() == expect.strip():
return None
else:
return error(inputs, out, expect)
def main():
root = Path(__file__).parent
if not (g_path := root / "grades.json").exists():
grades = {}
else:
grades = json.load(g_path.open())
valid_paths = [p.removesuffix(".py") for p in sys.argv[1:]]
filter_paths = bool(valid_paths)
has_errors = False
for path in (root / "tests").iterdir():
if not path.name.endswith(".input"):
continue
name = path.name.removesuffix(".input")
if filter_paths and name not in valid_paths:
continue
elif filter_paths:
valid_paths.remove(name)
with open(path, encoding="utf-8") as fd:
examples = fd.read().split("---\n")
out_path = path.parent / (name + ".output")
with open(out_path, encoding="utf-8") as fd:
results = fd.read().split("\n---")
script = path.parent.parent / (name + ".py")
errors = []
for (ex, out) in zip(examples, results):
err = check(script, ex, out)
if err:
has_errors = True
errors.append(err)
if errors:
print(f"\n\nERROR: {os.path.basename(path)}")
for error in errors:
print(error)
grades[name] = False
else:
grades[name] = True
if valid_paths:
not_found = ", ".join(valid_paths)
print(f"ERRO: Exercício(s) não encontrado: {not_found}")
elif not has_errors:
print("SUCESSO: Correção concluída sem encontrar erros")
g_path.write_text(json.dumps(grades), encoding="utf-8")
if __name__ == "__main__":
main()