PyKubeGrader 0.1.18__py3-none-any.whl → 0.1.19__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- {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
|