-
Notifications
You must be signed in to change notification settings - Fork 0
/
grading.py
165 lines (143 loc) · 5.22 KB
/
grading.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
from rubrics.Grader import Grader
from rubrics.Exercise1Rubric import buildExercise1Rubric
from rubrics.Exercise2Rubric import buildExercise2Rubric
from rubrics.Exercise3RubricGdp import buildExercise3RubricGdp
from rubrics.Exercise3RubricBondIssuance import buildExercise3RubricBondIssuance
from rubrics.Exercise4Rubric import buildExercise4Rubric
from rubrics.Exercise5Rubric import buildExercise5Rubric
import os
import sys
import sqlite3
import pandas as pd
from dataclasses import dataclass
@dataclass
class GradingSubject:
rubricFactory: callable
expectedOutputFile: str
expectedOutputTable: str
def gradeExercise(
exNumber: int,
expectedModel: str,
gradingSubjects: list[GradingSubject]
):
print(f"[INFO] Preparing feedback for EXERCISE {exNumber}:")
print(
"[INFO] If this exercise does not need to be submitted yet, you can ignore all output after this."
)
for gradingSubject in gradingSubjects:
if os.path.isfile(gradingSubject.expectedOutputFile):
os.remove(gradingSubject.expectedOutputFile)
print(f"\tLooking for {expectedModel} to execute.")
if not os.path.isfile(expectedModel):
print(f"\t[WARNING] Could not find file to grade: {expectedModel}")
return
print(f"\t[SUCCESS] Found {expectedModel}, executing.")
if not expectedModel.endswith(".jv"):
print(
f"\t[INFO] Could not find interpreter for model: {expectedModel}."
)
print("\tSkipping.")
return
os.system(f"jv {expectedModel}")
grader = Grader(exNumber)
for gradingSubject in gradingSubjects:
gradeSubject(gradingSubject, grader)
feedback = grader.getConsoleOutput()
print("")
print(feedback)
def gradeSubject(gradingSubject: GradingSubject, grader: Grader):
print(f"\tLooking for {gradingSubject.expectedOutputFile} to grade.")
if not os.path.isfile(gradingSubject.expectedOutputFile):
print(f"\t[ERROR] Can not find expected output file: {gradingSubject.expectedOutputFile}.")
print("\tMake sure your model generates it as described in the exercise!")
print("\tSkipping.")
gradedRubric = gradingSubject.rubricFactory()
grader.gradeMissingOutput(gradedRubric)
return
print(f"\t[SUCCESS] Found output file {gradingSubject.expectedOutputFile}, grading...")
connection = sqlite3.connect(gradingSubject.expectedOutputFile)
cursor = connection.cursor()
cursor.execute(f"SELECT name FROM sqlite_master WHERE type='table' AND name='{gradingSubject.expectedOutputTable}';")
table_exists = cursor.fetchone()
if not table_exists:
print(f"\t[ERROR] Table {gradingSubject.expectedOutputTable} does not exist in {gradingSubject.expectedOutputFile}.")
connection.close()
gradedRubric = gradingSubject.rubricFactory()
grader.gradeMissingOutput(gradedRubric)
return
try:
query = f"SELECT * FROM {gradingSubject.expectedOutputTable}"
df = pd.read_sql_query(query, connection)
except Exception as e:
print(f"Exception for {gradingSubject.expectedOutputFile}: {e}")
connection.close()
return
gradedRubric = gradingSubject.rubricFactory()
grader.gradeData(df, gradedRubric)
if len(sys.argv) < 1:
print("Missing argument.\nUsage: python grading.py <exerciseId> <dir (optional)>")
exit(1)
try:
exerciseId = int(sys.argv[1])
except ValueError:
print("The argument provided is not an integer.")
exit(1)
if len(sys.argv) > 2:
os.chdir(sys.argv[2])
match (exerciseId):
case 1:
gradeExercise(
1,
"exercises/exercise1.jv",
[GradingSubject(
expectedOutputFile="airports.sqlite",
expectedOutputTable="airports",
rubricFactory=buildExercise1Rubric
)],
)
case 2:
gradeExercise(
2,
"exercises/exercise2.jv",
[GradingSubject(
expectedOutputFile="trees.sqlite",
expectedOutputTable="trees",
rubricFactory=buildExercise2Rubric
)],
)
case 3:
gradeExercise(
3,
"exercises/exercise3.jv",
[GradingSubject(
expectedOutputFile="country-stats.sqlite",
expectedOutputTable="bondIssuance",
rubricFactory=buildExercise3RubricBondIssuance
), GradingSubject(
expectedOutputFile="country-stats.sqlite",
expectedOutputTable="gdpPerCapita",
rubricFactory=buildExercise3RubricGdp
)],
)
case 4:
gradeExercise(
4,
"exercises/exercise4.jv",
[GradingSubject(
expectedOutputFile="temperatures.sqlite",
expectedOutputTable="temperatures",
rubricFactory=buildExercise4Rubric
)],
)
case 5:
gradeExercise(
5,
"exercises/exercise5.jv",
[GradingSubject(
expectedOutputFile="gtfs.sqlite",
expectedOutputTable="stops",
rubricFactory=buildExercise5Rubric
)],
)
case _:
print(f"No grading found for exercise with id {exerciseId}")