ygrader 2.3.0__tar.gz → 2.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ygrader-2.3.0/ygrader.egg-info → ygrader-2.4.0}/PKG-INFO +1 -1
- {ygrader-2.3.0 → ygrader-2.4.0}/setup.py +1 -1
- {ygrader-2.3.0 → ygrader-2.4.0}/ygrader/feedback.py +38 -2
- {ygrader-2.3.0 → ygrader-2.4.0/ygrader.egg-info}/PKG-INFO +1 -1
- {ygrader-2.3.0 → ygrader-2.4.0}/LICENSE +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/setup.cfg +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/test/test_interactive.py +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/test/test_unittest.py +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/ygrader/__init__.py +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/ygrader/deductions.py +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/ygrader/grader.py +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/ygrader/grades_csv.py +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/ygrader/grading_item.py +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/ygrader/grading_item_config.py +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/ygrader/score_input.py +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/ygrader/send_ctrl_backtick.ahk +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/ygrader/student_repos.py +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/ygrader/upstream_merger.py +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/ygrader/utils.py +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/ygrader.egg-info/SOURCES.txt +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/ygrader.egg-info/dependency_links.txt +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/ygrader.egg-info/requires.txt +0 -0
- {ygrader-2.3.0 → ygrader-2.4.0}/ygrader.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ setup(
|
|
|
4
4
|
name="ygrader",
|
|
5
5
|
packages=["ygrader"],
|
|
6
6
|
package_data={"ygrader": ["*.ahk"]},
|
|
7
|
-
version="2.
|
|
7
|
+
version="2.4.0",
|
|
8
8
|
description="Grading scripts used in BYU's Electrical and Computer Engineering Department",
|
|
9
9
|
author="Jeff Goeders",
|
|
10
10
|
author_email="jeff.goeders@gmail.com",
|
|
@@ -7,6 +7,7 @@ from typing import Callable, Dict, Optional, Tuple
|
|
|
7
7
|
|
|
8
8
|
import numpy as np
|
|
9
9
|
import pandas
|
|
10
|
+
import yaml
|
|
10
11
|
|
|
11
12
|
from .deductions import StudentDeductions
|
|
12
13
|
from .grading_item_config import LearningSuiteColumn
|
|
@@ -17,6 +18,36 @@ from .utils import warning, print_color, TermColors
|
|
|
17
18
|
LatePenaltyCallback = Callable[[int, float, float], float]
|
|
18
19
|
|
|
19
20
|
|
|
21
|
+
def _load_due_date_exceptions(
|
|
22
|
+
exceptions_path: pathlib.Path,
|
|
23
|
+
) -> Dict[str, datetime.datetime]:
|
|
24
|
+
"""Load due date exceptions from YAML file.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
exceptions_path: Path to the deadline_exceptions.yaml file.
|
|
28
|
+
Expected format is: net_id: "YYYY-MM-DD HH:MM:SS"
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
Mapping from net_id to exception datetime.
|
|
32
|
+
"""
|
|
33
|
+
if not exceptions_path.exists():
|
|
34
|
+
return {}
|
|
35
|
+
|
|
36
|
+
with open(exceptions_path, "r", encoding="utf-8") as f:
|
|
37
|
+
data = yaml.safe_load(f)
|
|
38
|
+
|
|
39
|
+
if not data:
|
|
40
|
+
return {}
|
|
41
|
+
|
|
42
|
+
exceptions = {}
|
|
43
|
+
for net_id, exception_date in data.items():
|
|
44
|
+
if net_id and exception_date:
|
|
45
|
+
exceptions[net_id] = datetime.datetime.strptime(
|
|
46
|
+
exception_date, "%Y-%m-%d %H:%M:%S"
|
|
47
|
+
)
|
|
48
|
+
return exceptions
|
|
49
|
+
|
|
50
|
+
|
|
20
51
|
def _calculate_late_days(
|
|
21
52
|
submit_time_str: Optional[str],
|
|
22
53
|
due_date: datetime.datetime,
|
|
@@ -188,7 +219,7 @@ def assemble_grades(
|
|
|
188
219
|
output_csv_path: Optional[pathlib.Path] = None,
|
|
189
220
|
late_penalty_callback: Optional[LatePenaltyCallback] = None,
|
|
190
221
|
due_date: Optional[datetime.datetime] = None,
|
|
191
|
-
|
|
222
|
+
due_date_exceptions_path: Optional[pathlib.Path] = None,
|
|
192
223
|
) -> Tuple[Optional[pathlib.Path], Optional[pathlib.Path]]:
|
|
193
224
|
"""Generate feedback zip and/or grades CSV from deductions.
|
|
194
225
|
|
|
@@ -201,12 +232,17 @@ def assemble_grades(
|
|
|
201
232
|
late_penalty_callback: Optional callback function that takes
|
|
202
233
|
(late_days, max_score, actual_score) and returns the adjusted score.
|
|
203
234
|
due_date: The default due date for the assignment. Required for late penalty.
|
|
204
|
-
|
|
235
|
+
due_date_exceptions_path: Path to YAML file with due date exceptions (net_id: "YYYY-MM-DD HH:MM:SS").
|
|
205
236
|
|
|
206
237
|
Returns:
|
|
207
238
|
Tuple of (feedback_zip_path or None, grades_csv_path or None).
|
|
208
239
|
"""
|
|
209
240
|
yaml_path = pathlib.Path(yaml_path)
|
|
241
|
+
|
|
242
|
+
# Load due date exceptions if path provided
|
|
243
|
+
due_date_exceptions: Dict[str, datetime.datetime] = {}
|
|
244
|
+
if due_date_exceptions_path:
|
|
245
|
+
due_date_exceptions = _load_due_date_exceptions(due_date_exceptions_path)
|
|
210
246
|
ls_column = LearningSuiteColumn(yaml_path)
|
|
211
247
|
|
|
212
248
|
# Get the lab name from the YAML file's parent directory
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|