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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ygrader
3
- Version: 2.5.1
3
+ Version: 2.5.2
4
4
  Summary: Grading scripts used in BYU's Electrical and Computer Engineering Department
5
5
  Home-page: https://github.com/byu-cpe/ygrader
6
6
  Author: Jeff Goeders
@@ -4,7 +4,7 @@ setup(
4
4
  name="ygrader",
5
5
  packages=["ygrader"],
6
6
  package_data={"ygrader": ["*.ahk"]},
7
- version="2.5.1",
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(self) -> int:
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ygrader
3
- Version: 2.5.1
3
+ Version: 2.5.2
4
4
  Summary: Grading scripts used in BYU's Electrical and Computer Engineering Department
5
5
  Home-page: https://github.com/byu-cpe/ygrader
6
6
  Author: Jeff Goeders
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