ygrader 2.5.1__tar.gz → 2.5.2__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.5.1/ygrader.egg-info → ygrader-2.5.2}/PKG-INFO +1 -1
- {ygrader-2.5.1 → ygrader-2.5.2}/setup.py +1 -1
- {ygrader-2.5.1 → ygrader-2.5.2}/ygrader/deductions.py +107 -1
- {ygrader-2.5.1 → ygrader-2.5.2}/ygrader/score_input.py +11 -1
- {ygrader-2.5.1 → ygrader-2.5.2/ygrader.egg-info}/PKG-INFO +1 -1
- {ygrader-2.5.1 → ygrader-2.5.2}/LICENSE +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/setup.cfg +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/test/test_interactive.py +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/test/test_unittest.py +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/ygrader/__init__.py +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/ygrader/feedback.py +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/ygrader/grader.py +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/ygrader/grades_csv.py +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/ygrader/grading_item.py +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/ygrader/grading_item_config.py +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/ygrader/send_ctrl_backtick.ahk +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/ygrader/student_repos.py +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/ygrader/upstream_merger.py +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/ygrader/utils.py +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/ygrader.egg-info/SOURCES.txt +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/ygrader.egg-info/dependency_links.txt +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/ygrader.egg-info/requires.txt +0 -0
- {ygrader-2.5.1 → ygrader-2.5.2}/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.5.
|
|
7
|
+
version="2.5.2",
|
|
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",
|
|
@@ -214,9 +214,14 @@ class StudentDeductions:
|
|
|
214
214
|
# Not found, create a new one
|
|
215
215
|
return self.add_deduction_type(message, points)
|
|
216
216
|
|
|
217
|
-
def create_deduction_type_interactive(
|
|
217
|
+
def create_deduction_type_interactive(
|
|
218
|
+
self, max_points: Optional[float] = None
|
|
219
|
+
) -> int:
|
|
218
220
|
"""Interactively prompt the user to create a new deduction type.
|
|
219
221
|
|
|
222
|
+
Args:
|
|
223
|
+
max_points: Optional maximum points for validation.
|
|
224
|
+
|
|
220
225
|
Returns:
|
|
221
226
|
The ID of the created deduction type, or -1 if cancelled.
|
|
222
227
|
"""
|
|
@@ -236,6 +241,18 @@ class StudentDeductions:
|
|
|
236
241
|
return -1
|
|
237
242
|
try:
|
|
238
243
|
points = float(points_str)
|
|
244
|
+
if points < 0:
|
|
245
|
+
print_color(
|
|
246
|
+
TermColors.YELLOW,
|
|
247
|
+
"Deduction cannot be negative. Try again.",
|
|
248
|
+
)
|
|
249
|
+
continue
|
|
250
|
+
if max_points is not None and points > max_points:
|
|
251
|
+
print_color(
|
|
252
|
+
TermColors.YELLOW,
|
|
253
|
+
f"Deduction ({points}) cannot exceed max points ({max_points}). Try again.",
|
|
254
|
+
)
|
|
255
|
+
continue
|
|
239
256
|
break
|
|
240
257
|
except ValueError:
|
|
241
258
|
print("Invalid number. Try again.")
|
|
@@ -330,6 +347,95 @@ class StudentDeductions:
|
|
|
330
347
|
print(f"Deleted deduction type [{deduction_id}]: {deduction_type.message}")
|
|
331
348
|
return True
|
|
332
349
|
|
|
350
|
+
def change_deduction_value(self, deduction_id: int, new_points: float) -> bool:
|
|
351
|
+
"""Change the point value of an existing deduction type.
|
|
352
|
+
|
|
353
|
+
Args:
|
|
354
|
+
deduction_id: The ID of the deduction type to modify.
|
|
355
|
+
new_points: The new point value.
|
|
356
|
+
|
|
357
|
+
Returns:
|
|
358
|
+
True if successful, False if deduction_id not found.
|
|
359
|
+
"""
|
|
360
|
+
if deduction_id not in self.deduction_types:
|
|
361
|
+
return False
|
|
362
|
+
|
|
363
|
+
self.deduction_types[deduction_id].points = new_points
|
|
364
|
+
self._save()
|
|
365
|
+
return True
|
|
366
|
+
|
|
367
|
+
def change_deduction_value_interactive(
|
|
368
|
+
self, max_points: Optional[float] = None
|
|
369
|
+
) -> bool:
|
|
370
|
+
"""Interactively prompt the user to change a deduction type's point value.
|
|
371
|
+
|
|
372
|
+
Args:
|
|
373
|
+
max_points: Optional maximum points for validation.
|
|
374
|
+
|
|
375
|
+
Returns:
|
|
376
|
+
True if a deduction value was changed, False otherwise.
|
|
377
|
+
"""
|
|
378
|
+
if not self.deduction_types:
|
|
379
|
+
print("No deduction types to modify.")
|
|
380
|
+
return False
|
|
381
|
+
|
|
382
|
+
print("\nChange deduction value (empty input to cancel):")
|
|
383
|
+
print("Available deduction types:")
|
|
384
|
+
for deduction_id, deduction_type in self.deduction_types.items():
|
|
385
|
+
in_use = " (IN USE)" if self.is_deduction_in_use(deduction_id) else ""
|
|
386
|
+
print(
|
|
387
|
+
f" [{deduction_id}] -{deduction_type.points}: {deduction_type.message}{in_use}"
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
id_str = input(" Enter ID to modify: ").strip()
|
|
391
|
+
if not id_str:
|
|
392
|
+
print("Cancelled.")
|
|
393
|
+
return False
|
|
394
|
+
|
|
395
|
+
try:
|
|
396
|
+
deduction_id = int(id_str)
|
|
397
|
+
except ValueError:
|
|
398
|
+
print("Invalid ID.")
|
|
399
|
+
return False
|
|
400
|
+
|
|
401
|
+
if deduction_id not in self.deduction_types:
|
|
402
|
+
print("Deduction type not found.")
|
|
403
|
+
return False
|
|
404
|
+
|
|
405
|
+
deduction_type = self.deduction_types[deduction_id]
|
|
406
|
+
print(f" Current value: {deduction_type.points} points")
|
|
407
|
+
|
|
408
|
+
while True:
|
|
409
|
+
points_str = input(" Enter new points value: ").strip()
|
|
410
|
+
if not points_str:
|
|
411
|
+
print("Cancelled.")
|
|
412
|
+
return False
|
|
413
|
+
|
|
414
|
+
try:
|
|
415
|
+
new_points = float(points_str)
|
|
416
|
+
if new_points < 0:
|
|
417
|
+
print_color(
|
|
418
|
+
TermColors.YELLOW,
|
|
419
|
+
"Deduction cannot be negative. Try again.",
|
|
420
|
+
)
|
|
421
|
+
continue
|
|
422
|
+
if max_points is not None and new_points > max_points:
|
|
423
|
+
print_color(
|
|
424
|
+
TermColors.YELLOW,
|
|
425
|
+
f"Deduction ({new_points}) cannot exceed max points ({max_points}). Try again.",
|
|
426
|
+
)
|
|
427
|
+
continue
|
|
428
|
+
break
|
|
429
|
+
except ValueError:
|
|
430
|
+
print("Invalid number. Try again.")
|
|
431
|
+
|
|
432
|
+
old_points = deduction_type.points
|
|
433
|
+
self.change_deduction_value(deduction_id, new_points)
|
|
434
|
+
print(
|
|
435
|
+
f"Changed deduction [{deduction_id}] from {old_points} to {new_points} points"
|
|
436
|
+
)
|
|
437
|
+
return True
|
|
438
|
+
|
|
333
439
|
def get_student_deductions(self, net_ids: tuple) -> List[DeductionType]:
|
|
334
440
|
"""Get the list of deductions applied to a student.
|
|
335
441
|
|
|
@@ -92,6 +92,9 @@ def get_score(
|
|
|
92
92
|
|
|
93
93
|
right_items.append(("[0]", "Clear deductions"))
|
|
94
94
|
|
|
95
|
+
right_items.append(("[v]", "Change deduction value"))
|
|
96
|
+
allowed_cmds["v"] = "change_value"
|
|
97
|
+
|
|
95
98
|
# Accept score at the bottom of right column
|
|
96
99
|
right_items.append(("[Enter]", "Accept score"))
|
|
97
100
|
|
|
@@ -167,7 +170,9 @@ def get_score(
|
|
|
167
170
|
|
|
168
171
|
# Handle special cases that need to loop back
|
|
169
172
|
if result == "create":
|
|
170
|
-
deduction_id = student_deductions.create_deduction_type_interactive(
|
|
173
|
+
deduction_id = student_deductions.create_deduction_type_interactive(
|
|
174
|
+
max_points=max_points
|
|
175
|
+
)
|
|
171
176
|
if deduction_id >= 0:
|
|
172
177
|
# Auto-apply the new deduction to this student
|
|
173
178
|
student_deductions.apply_deduction_to_student(
|
|
@@ -177,6 +182,11 @@ def get_score(
|
|
|
177
182
|
if result == "delete":
|
|
178
183
|
student_deductions.delete_deduction_type_interactive()
|
|
179
184
|
continue
|
|
185
|
+
if result == "change_value":
|
|
186
|
+
student_deductions.change_deduction_value_interactive(
|
|
187
|
+
max_points=max_points
|
|
188
|
+
)
|
|
189
|
+
continue
|
|
180
190
|
if result == "manage":
|
|
181
191
|
_manage_grades_interactive(student_deductions, names_by_netid)
|
|
182
192
|
continue
|
|
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
|