PyKubeGrader 0.2.0__tar.gz → 0.2.2__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {pykubegrader-0.2.0/src/PyKubeGrader.egg-info → pykubegrader-0.2.2}/PKG-INFO +1 -1
- {pykubegrader-0.2.0 → pykubegrader-0.2.2/src/PyKubeGrader.egg-info}/PKG-INFO +1 -1
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/build/build_folder.py +7 -2
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/telemetry.py +19 -11
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/.coveragerc +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/.github/workflows/main.yml +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/.gitignore +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/.readthedocs.yml +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/AUTHORS.rst +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/CHANGELOG.rst +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/CONTRIBUTING.rst +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/LICENSE.txt +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/README.rst +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/docs/Makefile +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/docs/_static/Drexel_blue_Logo_square_Dark.png +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/docs/_static/Drexel_blue_Logo_square_Light.png +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/docs/_static/custom.css +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/docs/authors.rst +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/docs/changelog.rst +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/docs/conf.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/docs/contributing.rst +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/docs/index.rst +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/docs/license.rst +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/docs/readme.rst +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/docs/requirements.txt +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/examples/.responses.json +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/examples/true_false.ipynb +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/pyproject.toml +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/setup.cfg +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/setup.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/PyKubeGrader.egg-info/SOURCES.txt +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/PyKubeGrader.egg-info/dependency_links.txt +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/PyKubeGrader.egg-info/entry_points.txt +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/PyKubeGrader.egg-info/not-zip-safe +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/PyKubeGrader.egg-info/requires.txt +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/PyKubeGrader.egg-info/top_level.txt +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/__init__.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/build/__init__.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/build/api_notebook_builder.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/build/clean_folder.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/graders/__init__.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/graders/late_assignments.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/initialize.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/log_parser/__init__.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/log_parser/parse.ipynb +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/log_parser/parse.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/utils.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/validate.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/widgets/__init__.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/widgets/multiple_choice.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/widgets/reading_question.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/widgets/select_many.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/widgets/student_info.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/widgets/style.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/widgets/true_false.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/widgets/types_question.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/widgets_base/__init__.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/widgets_base/multi_select.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/widgets_base/reading.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/src/pykubegrader/widgets_base/select.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/tests/conftest.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/tests/import_test.py +0 -0
- {pykubegrader-0.2.0 → pykubegrader-0.2.2}/tox.ini +0 -0
@@ -503,6 +503,9 @@ class NotebookProcessor:
|
|
503
503
|
NotebookProcessor.add_initialization_code(
|
504
504
|
temp_notebook_path, self.week, self.assignment_type
|
505
505
|
)
|
506
|
+
NotebookProcessor.replace_temp_in_notebook(
|
507
|
+
temp_notebook_path, temp_notebook_path
|
508
|
+
)
|
506
509
|
return None, 0
|
507
510
|
|
508
511
|
@staticmethod
|
@@ -535,7 +538,7 @@ class NotebookProcessor:
|
|
535
538
|
index, cell = find_first_code_cell(notebook_path)
|
536
539
|
cell = cell["source"]
|
537
540
|
import_text = "from pykubegrader.initialize import initialize_assignment\n"
|
538
|
-
|
541
|
+
import_text += f'\nresponses = initialize_assignment("{os.path.splitext(os.path.basename(notebook_path))[0]}", "{week}", "{assignment_type}" )\n'
|
539
542
|
cell = f"{import_text}\n" + cell
|
540
543
|
replace_cell_source(notebook_path, index, cell)
|
541
544
|
|
@@ -1398,6 +1401,8 @@ def clean_notebook(notebook_path):
|
|
1398
1401
|
cell.metadata["editable"] = cell.metadata.get("editable", False)
|
1399
1402
|
cell.metadata["deletable"] = cell.metadata.get("deletable", False)
|
1400
1403
|
if cell.cell_type == "code":
|
1404
|
+
if "grader.check(" in cell.source:
|
1405
|
+
continue
|
1401
1406
|
cell.metadata["tags"] = cell.metadata.get("tags", [])
|
1402
1407
|
if "skip-execution" not in cell.metadata["tags"]:
|
1403
1408
|
cell.metadata["tags"].append("skip-execution")
|
@@ -1563,7 +1568,7 @@ def generate_mcq_file(data_dict, output_file="mc_questions.py"):
|
|
1563
1568
|
)
|
1564
1569
|
f.write(" def __init__(self):\n")
|
1565
1570
|
f.write(" super().__init__(\n")
|
1566
|
-
f.write(f
|
1571
|
+
f.write(f' title=f"{q_value['question_text']}",\n')
|
1567
1572
|
f.write(" style=MCQ,\n")
|
1568
1573
|
f.write(
|
1569
1574
|
f" question_number={q_value['question number']},\n"
|
@@ -10,6 +10,7 @@ import requests
|
|
10
10
|
from IPython.core.interactiveshell import ExecutionInfo
|
11
11
|
from requests import Response
|
12
12
|
from requests.auth import HTTPBasicAuth
|
13
|
+
from requests.exceptions import RequestException
|
13
14
|
|
14
15
|
#
|
15
16
|
# Logging setup
|
@@ -122,7 +123,6 @@ def update_responses(key: str, value) -> dict:
|
|
122
123
|
#
|
123
124
|
|
124
125
|
|
125
|
-
# TODO: Improve error handling
|
126
126
|
def score_question(
|
127
127
|
term: str = "winter_2025",
|
128
128
|
base_url: str = "https://engr-131-api.eastus.cloudapp.azure.com",
|
@@ -140,16 +140,24 @@ def score_question(
|
|
140
140
|
"responses": responses,
|
141
141
|
}
|
142
142
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
143
|
+
try:
|
144
|
+
res = requests.post(url, json=payload, auth=HTTPBasicAuth("student", "capture"))
|
145
|
+
res.raise_for_status()
|
146
|
+
|
147
|
+
res_data: dict[str, tuple[float, float]] = res.json()
|
148
|
+
|
149
|
+
for question, (points_earned, max_points) in res_data.items():
|
150
|
+
log_variable(
|
151
|
+
assignment_name=responses["assignment"],
|
152
|
+
value=f"{points_earned}, {max_points}",
|
153
|
+
info_type=question,
|
154
|
+
)
|
155
|
+
except RequestException as e:
|
156
|
+
raise RuntimeError("Failed to access question-scoring endpoint") from e
|
157
|
+
except ValueError as e:
|
158
|
+
raise ValueError("Failed to parse question-scoring JSON response") from e
|
159
|
+
except Exception as e:
|
160
|
+
raise RuntimeError("Failed to score question") from e
|
153
161
|
|
154
162
|
|
155
163
|
def submit_question(
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|