PyKubeGrader 0.1.18__py3-none-any.whl → 0.1.19__py3-none-any.whl
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.
- {PyKubeGrader-0.1.18.dist-info → PyKubeGrader-0.1.19.dist-info}/METADATA +1 -1
- {PyKubeGrader-0.1.18.dist-info → PyKubeGrader-0.1.19.dist-info}/RECORD +7 -7
- pykubegrader/build/build_folder.py +24 -40
- {PyKubeGrader-0.1.18.dist-info → PyKubeGrader-0.1.19.dist-info}/LICENSE.txt +0 -0
- {PyKubeGrader-0.1.18.dist-info → PyKubeGrader-0.1.19.dist-info}/WHEEL +0 -0
- {PyKubeGrader-0.1.18.dist-info → PyKubeGrader-0.1.19.dist-info}/entry_points.txt +0 -0
- {PyKubeGrader-0.1.18.dist-info → PyKubeGrader-0.1.19.dist-info}/top_level.txt +0 -0
@@ -4,7 +4,7 @@ pykubegrader/telemetry.py,sha256=0nPdqvd70IACz3tz1lZmjwQhJByqLz9IUVmxKhfaWCw,569
|
|
4
4
|
pykubegrader/utils.py,sha256=dKw6SyRYU3DWRgD3xER7wq-C9e1daWPkqr901LpcwiQ,642
|
5
5
|
pykubegrader/validate.py,sha256=vEdNN386yFloDRcjMDrTAqfBmeCXGcDPNH_rLZScIm8,10945
|
6
6
|
pykubegrader/build/api_notebook_builder.py,sha256=GVi6hupfQaWeFMv6Bdela3FTRHvOQYXPIcICnkaLhgA,20119
|
7
|
-
pykubegrader/build/build_folder.py,sha256=
|
7
|
+
pykubegrader/build/build_folder.py,sha256=xiV3ps5yTnC2TJjGGmCqNK34tyAP7MAe2FTj9S1IjxU,66271
|
8
8
|
pykubegrader/log_parser/parse.ipynb,sha256=F3ZWi5_AOxEnSihY0VBz4jjqo0__GggjRgFvS0QCHTg,10611
|
9
9
|
pykubegrader/log_parser/parse.py,sha256=aON6tWj0dFJcYR9GmzXWfmZ4_t8LU1FTq6vbWCePgRs,6987
|
10
10
|
pykubegrader/widgets/__init__.py,sha256=s3ky3eJDa1RedFVdpKxmqv6mHBYpOSL9Z6qThSH9cbs,303
|
@@ -19,9 +19,9 @@ pykubegrader/widgets_base/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-
|
|
19
19
|
pykubegrader/widgets_base/multi_select.py,sha256=jzuK_1eLyhDOzR1jragLRBf_aO8IEaoixfozxBeMBs0,3975
|
20
20
|
pykubegrader/widgets_base/reading.py,sha256=4uTLmlPzCwxVzufFhPjM7W19uMGguRb6y4eAV3x-zAc,5314
|
21
21
|
pykubegrader/widgets_base/select.py,sha256=b5mmd-Cl1A2T2ePZ20-KLVyvP3bzvzYX36n3lMcrcFM,2456
|
22
|
-
PyKubeGrader-0.1.
|
23
|
-
PyKubeGrader-0.1.
|
24
|
-
PyKubeGrader-0.1.
|
25
|
-
PyKubeGrader-0.1.
|
26
|
-
PyKubeGrader-0.1.
|
27
|
-
PyKubeGrader-0.1.
|
22
|
+
PyKubeGrader-0.1.19.dist-info/LICENSE.txt,sha256=YTp-Ewc8Kems8PJEE27KnBPFnZSxoWvSg7nnknzPyYw,1546
|
23
|
+
PyKubeGrader-0.1.19.dist-info/METADATA,sha256=oOHnLxMY9b5jmI7AIkYJrqulNEWLV93UXouiNoPEoD4,2665
|
24
|
+
PyKubeGrader-0.1.19.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
25
|
+
PyKubeGrader-0.1.19.dist-info/entry_points.txt,sha256=Kd4Bh-i3hc4qlnLU1p0nc8yPw9cC5AQGOtkk2eLGnQw,78
|
26
|
+
PyKubeGrader-0.1.19.dist-info/top_level.txt,sha256=e550Klfze6higFxER1V62fnGOcIgiKRbsrl9CC4UdtQ,13
|
27
|
+
PyKubeGrader-0.1.19.dist-info/RECORD,,
|
@@ -64,7 +64,7 @@ class NotebookProcessor:
|
|
64
64
|
__name__
|
65
65
|
) # Create a logger instance specific to this module
|
66
66
|
self.logger = logger # Assign the logger instance to the class for use in instance methods
|
67
|
-
|
67
|
+
|
68
68
|
self.total_point_log = {}
|
69
69
|
|
70
70
|
def process_notebooks(self):
|
@@ -120,12 +120,10 @@ class NotebookProcessor:
|
|
120
120
|
|
121
121
|
# Process the notebook if it meets the criteria
|
122
122
|
self._process_single_notebook(notebook_path)
|
123
|
-
|
123
|
+
|
124
124
|
# Write the dictionary to a JSON file
|
125
125
|
with open(f"{self.solutions_folder}/total_points.json", "w") as json_file:
|
126
|
-
json.dump(
|
127
|
-
self.total_point_log, json_file, indent=4
|
128
|
-
) # `indent=4` for pretty formatting
|
126
|
+
json.dump(self.total_point_log, json_file, indent=4) # `indent=4` for pretty formatting
|
129
127
|
|
130
128
|
def _print_and_log(self, message):
|
131
129
|
"""
|
@@ -178,7 +176,7 @@ class NotebookProcessor:
|
|
178
176
|
Returns:
|
179
177
|
None
|
180
178
|
"""
|
181
|
-
|
179
|
+
|
182
180
|
self.select_many_total_points = 0
|
183
181
|
self.mcq_total_points = 0
|
184
182
|
self.tf_total_points = 0
|
@@ -290,16 +288,11 @@ class NotebookProcessor:
|
|
290
288
|
os.path.join(student_path, question_file_name_sanitized),
|
291
289
|
os.path.join(questions_folder_jbook, question_file_name_sanitized),
|
292
290
|
)
|
293
|
-
|
294
|
-
total_points =
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
+ self.otter_total_points
|
299
|
-
)
|
300
|
-
|
301
|
-
self.total_point_log.update({notebook_name: total_points})
|
302
|
-
|
291
|
+
|
292
|
+
total_points = self.select_many_total_points + self.mcq_total_points + self.tf_total_points + self.otter_total_points
|
293
|
+
|
294
|
+
self.total_point_log.update({notebook_name: total_points})
|
295
|
+
|
303
296
|
def free_response_parser(
|
304
297
|
self, temp_notebook_path, notebook_subfolder, notebook_name
|
305
298
|
):
|
@@ -316,7 +309,7 @@ class NotebookProcessor:
|
|
316
309
|
|
317
310
|
shutil.copy("./keys/.client_private_key.bin", client_private_key)
|
318
311
|
shutil.copy("./keys/.server_public_key.bin", server_public_key)
|
319
|
-
|
312
|
+
|
320
313
|
client_private_key = os.path.join(
|
321
314
|
notebook_subfolder,
|
322
315
|
".client_private_key.bin",
|
@@ -329,9 +322,7 @@ class NotebookProcessor:
|
|
329
322
|
shutil.copy("./keys/.client_private_key.bin", client_private_key)
|
330
323
|
shutil.copy("./keys/.server_public_key.bin", server_public_key)
|
331
324
|
|
332
|
-
out = FastAPINotebookBuilder(
|
333
|
-
notebook_path=temp_notebook_path, assignment_tag=self.assignment_tag
|
334
|
-
)
|
325
|
+
out = FastAPINotebookBuilder(notebook_path=temp_notebook_path, assignment_tag=self.assignment_tag)
|
335
326
|
|
336
327
|
debug_notebook = os.path.join(
|
337
328
|
notebook_subfolder,
|
@@ -409,6 +400,7 @@ class NotebookProcessor:
|
|
409
400
|
replace_cell_source(notebook_path, index, cell)
|
410
401
|
|
411
402
|
def multiple_choice_parser(self, temp_notebook_path, new_notebook_path):
|
403
|
+
|
412
404
|
### Parse the notebook for multiple choice questions
|
413
405
|
if self.has_assignment(temp_notebook_path, "# BEGIN MULTIPLE CHOICE"):
|
414
406
|
self._print_and_log(
|
@@ -428,9 +420,7 @@ class NotebookProcessor:
|
|
428
420
|
|
429
421
|
for data_ in data:
|
430
422
|
# Generate the solution file
|
431
|
-
self.mcq_total_points = self.generate_solution_MCQ(
|
432
|
-
data, output_file=solution_path
|
433
|
-
)
|
423
|
+
self.mcq_total_points = self.generate_solution_MCQ(data, output_file=solution_path)
|
434
424
|
|
435
425
|
question_path = (
|
436
426
|
f"{new_notebook_path.replace(".ipynb", "")}_questions.py"
|
@@ -470,9 +460,7 @@ class NotebookProcessor:
|
|
470
460
|
|
471
461
|
# for data_ in data:
|
472
462
|
# Generate the solution file
|
473
|
-
self.tf_total_points = self.generate_solution_MCQ(
|
474
|
-
data, output_file=solution_path
|
475
|
-
)
|
463
|
+
self.tf_total_points = self.generate_solution_MCQ(data, output_file=solution_path)
|
476
464
|
|
477
465
|
question_path = f"{new_notebook_path.replace(".ipynb", "")}_questions.py"
|
478
466
|
|
@@ -508,9 +496,7 @@ class NotebookProcessor:
|
|
508
496
|
|
509
497
|
# for data_ in data:
|
510
498
|
# Generate the solution file
|
511
|
-
self.select_many_total_points = self.generate_solution_MCQ(
|
512
|
-
data, output_file=solution_path
|
513
|
-
)
|
499
|
+
self.select_many_total_points = self.generate_solution_MCQ(data, output_file=solution_path)
|
514
500
|
|
515
501
|
question_path = f"{new_notebook_path.replace(".ipynb", "")}_questions.py"
|
516
502
|
|
@@ -716,7 +702,7 @@ class NotebookProcessor:
|
|
716
702
|
solutions.update(existing_module.solutions)
|
717
703
|
if hasattr(existing_module, "total_points"):
|
718
704
|
total_points.extend(existing_module.total_points)
|
719
|
-
|
705
|
+
|
720
706
|
question_points = 0
|
721
707
|
# Process new question data and update solutions and total_points
|
722
708
|
for question_set in data_list:
|
@@ -729,14 +715,14 @@ class NotebookProcessor:
|
|
729
715
|
# Write updated total_points and solutions back to the file
|
730
716
|
with open(output_file, "w", encoding="utf-8") as f:
|
731
717
|
f.write("from typing import Any\n\n")
|
732
|
-
f.write(f"total_points:
|
718
|
+
f.write(f"total_points: float = {total_points}\n\n")
|
733
719
|
|
734
720
|
f.write("solutions: dict[str, Any] = {\n")
|
735
721
|
for key, solution in solutions.items():
|
736
722
|
# For safety, we assume solutions are strings, but if not, repr would be safer
|
737
723
|
f.write(f' "{key}": {repr(solution)},\n')
|
738
724
|
f.write("}\n")
|
739
|
-
|
725
|
+
|
740
726
|
return question_points
|
741
727
|
|
742
728
|
def extract_MCQ(ipynb_file):
|
@@ -1453,7 +1439,7 @@ def generate_mcq_file(data_dict, output_file="mc_questions.py"):
|
|
1453
1439
|
keys = []
|
1454
1440
|
for i, (q_key, q_value) in enumerate(question_dict.items()):
|
1455
1441
|
# Write keys
|
1456
|
-
keys.append(f"q{q_value['subquestion_number']}-{q_value['name']}")
|
1442
|
+
keys.append(f"q{q_value['question number']}-q{q_value['subquestion_number']}-{q_value['name']}")
|
1457
1443
|
|
1458
1444
|
f.write(f" keys={keys},\n")
|
1459
1445
|
|
@@ -1522,7 +1508,7 @@ def generate_select_many_file(data_dict, output_file="select_many_questions.py")
|
|
1522
1508
|
keys = []
|
1523
1509
|
for i, (q_key, q_value) in enumerate(question_dict.items()):
|
1524
1510
|
# Write keys
|
1525
|
-
keys.append(f"q{q_value['subquestion_number']}-{q_value['name']}")
|
1511
|
+
keys.append(f"q{q_value['question number']}-q{q_value['subquestion_number']}-{q_value['name']}")
|
1526
1512
|
|
1527
1513
|
f.write(f" keys={keys},\n")
|
1528
1514
|
|
@@ -1597,7 +1583,7 @@ def generate_tf_file(data_dict, output_file="tf_questions.py"):
|
|
1597
1583
|
keys = []
|
1598
1584
|
for i, (q_key, q_value) in enumerate(question_dict.items()):
|
1599
1585
|
# Write keys
|
1600
|
-
keys.append(f"q{q_value['subquestion_number']}-{q_value['name']}")
|
1586
|
+
keys.append(f"q{q_value['question number']}-q{q_value['subquestion_number']}-{q_value['name']}")
|
1601
1587
|
|
1602
1588
|
f.write(f" keys={keys},\n")
|
1603
1589
|
|
@@ -1685,18 +1671,16 @@ def main():
|
|
1685
1671
|
parser.add_argument(
|
1686
1672
|
"root_folder", type=str, help="Path to the root folder to process"
|
1687
1673
|
)
|
1688
|
-
|
1674
|
+
|
1689
1675
|
parser.add_argument(
|
1690
1676
|
"--assignment-tag",
|
1691
1677
|
type=str,
|
1692
1678
|
help="assignment-tag used for calculating grades",
|
1693
1679
|
default="Reading-Week-X",
|
1694
1680
|
)
|
1695
|
-
|
1681
|
+
|
1696
1682
|
args = parser.parse_args()
|
1697
|
-
processor = NotebookProcessor(
|
1698
|
-
root_folder=args.root_folder, assignment_tag=args.assignment_tag
|
1699
|
-
)
|
1683
|
+
processor = NotebookProcessor(root_folder=args.root_folder, assignment_tag=args.assignment_tag)
|
1700
1684
|
processor.process_notebooks()
|
1701
1685
|
|
1702
1686
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|