PyKubeGrader 0.1.18__tar.gz → 0.1.19__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {pykubegrader-0.1.18/src/PyKubeGrader.egg-info → pykubegrader-0.1.19}/PKG-INFO +1 -1
- {pykubegrader-0.1.18 → pykubegrader-0.1.19/src/PyKubeGrader.egg-info}/PKG-INFO +1 -1
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/build/build_folder.py +24 -40
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/.coveragerc +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/.github/workflows/main.yml +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/.gitignore +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/.readthedocs.yml +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/AUTHORS.rst +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/CHANGELOG.rst +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/CONTRIBUTING.rst +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/LICENSE.txt +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/README.rst +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/docs/Makefile +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/docs/_static/Drexel_blue_Logo_square_Dark.png +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/docs/_static/Drexel_blue_Logo_square_Light.png +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/docs/_static/custom.css +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/docs/authors.rst +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/docs/changelog.rst +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/docs/conf.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/docs/contributing.rst +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/docs/index.rst +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/docs/license.rst +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/docs/readme.rst +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/docs/requirements.txt +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/examples/.responses.json +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/examples/true_false.ipynb +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/pyproject.toml +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/setup.cfg +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/setup.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/PyKubeGrader.egg-info/SOURCES.txt +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/PyKubeGrader.egg-info/dependency_links.txt +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/PyKubeGrader.egg-info/entry_points.txt +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/PyKubeGrader.egg-info/not-zip-safe +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/PyKubeGrader.egg-info/requires.txt +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/PyKubeGrader.egg-info/top_level.txt +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/__init__.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/build/api_notebook_builder.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/initialize.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/log_parser/parse.ipynb +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/log_parser/parse.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/telemetry.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/utils.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/validate.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/widgets/__init__.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/widgets/multiple_choice.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/widgets/reading_question.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/widgets/select_many.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/widgets/student_info.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/widgets/style.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/widgets/true_false.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/widgets/types_question.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/widgets_base/__init__.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/widgets_base/multi_select.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/widgets_base/reading.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/src/pykubegrader/widgets_base/select.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/tests/conftest.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/tests/import_test.py +0 -0
- {pykubegrader-0.1.18 → pykubegrader-0.1.19}/tox.ini +0 -0
@@ -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
|
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
|
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
|
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
|