Skip to content

Commit d56c8e0

Browse files
committed
feat: version 0.1.4, fix bug by removing try-finally
1 parent b7ad9cf commit d56c8e0

File tree

4 files changed

+45
-61
lines changed

4 files changed

+45
-61
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ homepage = "https://github.com/ryanlinjui/cpGrader"
33

44
[tool.poetry]
55
name = "cpGrader"
6-
version = "0.1.3"
6+
version = "0.1.4"
77
description = "A Python Package to Grade Programming Assignments Automatically."
88
authors = ["ryanlinjui <ryanlinjui@gmail.com>"]
99
readme = "README.md"

src/cpGrader/cpGrader.py

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
from typing import (
66
List,
77
Callable,
8-
Union
8+
Union,
9+
Optional
910
)
1011

1112
import toml
@@ -28,10 +29,7 @@
2829
)
2930

3031
class Grader:
31-
def __init__(
32-
self,
33-
config_file: Union[str, None] = DEFAULT_CONFIG_FILE
34-
):
32+
def __init__(self, config_file: Optional[str] = DEFAULT_CONFIG_FILE):
3533
self.grade_report: List[List[str]] = []
3634

3735
# Initialize Test Cases Configuration
@@ -41,7 +39,6 @@ def __init__(
4139
self.__read_config(config_file)
4240

4341
def __read_config(self, config_file: str) -> None:
44-
4542
config = toml.load(config_file)
4643

4744
# Global Test Cases Configuration
@@ -83,17 +80,12 @@ def __read_config(self, config_file: str) -> None:
8380
)
8481
)
8582

86-
def setcase(
87-
self,
88-
match_case: Union[str, List[str]] = ALL_MATCH_CASE
89-
) -> Callable:
90-
83+
def setcase(self, match_case: Union[str, List[str]] = ALL_MATCH_CASE) -> Callable:
9184
def wrapper(func: Callable) -> None:
9285
match_case_list = match_case if isinstance(match_case, list) else [match_case]
9386
for _case in self.case_list:
9487
if any(fnmatch.fnmatchcase(_case.name, name) for name in match_case_list):
9588
_case.verify_func = func
96-
9789
return wrapper
9890

9991
def run(
@@ -128,7 +120,9 @@ def run(
128120

129121
# Build Student File
130122
logging.info(f"Building {student_id}: {not disable_build}")
131-
if disable_build: continue
123+
if disable_build:
124+
continue
125+
132126
build(folder=student_dir, copy_file=self.support_files)
133127

134128
# Execute and Verify Student File
@@ -140,15 +134,14 @@ def run(
140134
exception_signal = _case.execute(student_dir=student_dir)
141135

142136
logging.info(f"Verifying: {student_id}: {not disable_verify}, case: {_case.name}, exception: {exception_signal}")
143-
if exception_signal == ExecuteException.NoFile: break
144-
elif disable_verify or exception_signal != None: continue
137+
if exception_signal == ExecuteException.NoFile:
138+
break
139+
elif disable_verify or exception_signal != None:
140+
continue
145141

146142
_case.verify()
147143

148144
logging.info(f"Grading Complete: {student_id}, grade report: {self.grade_report[-1]}")
149145

150146
logging.info(f"Generating Grade Report: {save_path}")
151-
grade(
152-
grade_report=self.grade_report,
153-
save_path=save_path
154-
)
147+
grade(grade_report=self.grade_report, save_path=save_path)

src/cpGrader/testcase.py

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
from typing import (
77
List,
88
Callable,
9-
Union
9+
Union,
10+
Optional
1011
)
1112

1213
from .utils import (
@@ -23,25 +24,24 @@ class Case:
2324
def __init__(
2425
self,
2526
name: str,
26-
case_file: Union[str, None],
27-
command: Union[str, None],
27+
case_file: Optional[str],
28+
command: Optional[str],
2829
pts: Union[int, float],
29-
correct_file: Union[str, None],
30-
verify_func: Union[Callable, None]
30+
correct_file: Optional[str],
31+
verify_func: Optional[Callable]
3132
):
3233
self.name: str = name
33-
self.case_file: Union[str, None] = case_file
34-
self.command: Union[str, None] = command
34+
self.case_file: Optional[str] = case_file
35+
self.command: Optional[str] = command
3536
self.pts: Union[int, float] = pts
36-
self.correct_file: Union[str, None] = correct_file
37-
self.verify_func: Union[Callable, None] = verify_func
37+
self.correct_file: Optional[str] = correct_file
38+
self.verify_func: Optional[Callable] = verify_func
3839

3940
self.case_data: List[str] = []
4041
self.student_output: str = ""
4142
self.correct_output: str = ""
4243

4344
def __correct_setup(self) -> None:
44-
4545
# No correct file
4646
if self.correct_file == None:
4747
logging.debug(f"No correct file")
@@ -61,12 +61,8 @@ def __correct_setup(self) -> None:
6161

6262
if correct_file.endswith(".c"): # C correct program
6363
logging.debug(f"C correct program runnning")
64-
6564
logging.debug(f"Buidling: {correct_dir}, support_files: {support_files}")
66-
build(
67-
folder=correct_dir,
68-
copy_file=support_files
69-
)
65+
build(folder=correct_dir, copy_file=support_files)
7066

7167
command = f"./{correct_file}".replace(".c", "")
7268
logging.debug(f"Execute: {correct_dir}, command: {command}")
@@ -79,23 +75,21 @@ def __correct_setup(self) -> None:
7975

8076
elif correct_file.endswith(".py"): # Python correct program
8177
logging.debug(f"Python correct program running")
82-
8378
command = f"{executable} {correct_file}"
8479
logging.debug(f"Excute: {correct_dir}, command: {command}")
8580
self.correct_output = execute(
8681
folder=correct_dir,
8782
command=command,
8883
stdin_list=self.case_data
8984
)
90-
9185
logging.debug(f"Python correct program finished")
9286

9387
output_filepath = os.path.join(correct_dir, f"{self.name}.txt")
9488
logging.debug(f"Write correct output: {output_filepath}")
9589
with open(output_filepath, "w+") as f:
9690
f.write(self.correct_output)
9791

98-
def execute(self, student_dir: str) -> Union[None, ExecuteException]:
92+
def execute(self, student_dir: str) -> Optional[ExecuteException]:
9993
# setup case data and build/execute correct file
10094
if self.case_file != None:
10195
self.case_data = [line.strip() for line in open(self.case_file, "r").readlines()]
@@ -130,23 +124,25 @@ def execute(self, student_dir: str) -> Union[None, ExecuteException]:
130124
comment = f"{self.name}: {comment}"
131125
exception_signal = ExecuteException.ProgramError
132126

133-
finally:
134-
if len(output) > MAX_OUTPUT_SIZE:
135-
logging.warning(f"In {student_dir}, {self.name}: outputs are truncated to {MAX_OUTPUT_SIZE} characters")
136-
output = output[:MAX_OUTPUT_SIZE]
137-
138-
output_filepath = os.path.join(student_dir, f"{self.name}.txt")
139-
logging.debug(f"Write student output: {output_filepath}")
140-
with open(output_filepath, "w+") as f:
141-
f.write(output)
142-
self.student_output = output
143-
144-
# Append to grade report
145-
logging.debug(f"Exception Signal: {exception_signal}")
146-
if exception_signal:
147-
(lambda x: (x[1].append(0), x[2].append(comment), x))(currentframe().f_back.f_locals["self"].grade_report[-1])
148-
149-
return exception_signal
127+
except Exception as e:
128+
logging.error(f"Exception: {str(e)}")
129+
130+
if len(output) > MAX_OUTPUT_SIZE:
131+
logging.warning(f"In {student_dir}, {self.name}: outputs are truncated to {MAX_OUTPUT_SIZE} characters")
132+
output = output[:MAX_OUTPUT_SIZE]
133+
134+
output_filepath = os.path.join(student_dir, f"{self.name}.txt")
135+
logging.debug(f"Write student output: {output_filepath}")
136+
with open(output_filepath, "w+") as f:
137+
f.write(output)
138+
self.student_output = output
139+
140+
# Append to grade report
141+
logging.debug(f"Exception Signal: {exception_signal}")
142+
if exception_signal:
143+
(lambda x: (x[1].append(0), x[2].append(comment), x))(currentframe().f_back.f_locals["self"].grade_report[-1])
144+
145+
return exception_signal
150146

151147
def verify(self) -> None:
152148
if self.verify_func == None:

src/cpGrader/utils.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ def extract(src_folder:str, dest_folder:str) -> list:
1717
target_key = ["*akefile", "hw0*0*.c", "README*", "bonus*", "*.pdf"]
1818
filter_dir = ["__MACOSX", ".vscode"]
1919
exclude_folder_name = ["NTU", "NTUST"]
20-
2120
student_list = []
2221

2322
root = os.getcwd()
@@ -166,11 +165,7 @@ def execute(folder:str, command:str, stdin_list:list=[]) -> str:
166165

167166
return output
168167

169-
def grade(
170-
grade_report: List[Tuple[str, List[Union[int, str]], List[str]]],
171-
save_path: str
172-
) -> None:
173-
168+
def grade(grade_report: List[Tuple[str, List[Union[int, str]], List[str]]], save_path: str) -> None:
174169
for student in grade_report:
175170
student[1] = sum(student[1])
176171
student[2] = "\n".join(student[2])

0 commit comments

Comments
 (0)