PyKubeGrader 0.3.9__py3-none-any.whl → 0.3.10__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PyKubeGrader
3
- Version: 0.3.9
3
+ Version: 0.3.10
4
4
  Summary: Add a short description here!
5
5
  Home-page: https://github.com/pyscaffold/pyscaffold/
6
6
  Author: jagar2
@@ -5,8 +5,8 @@ pykubegrader/telemetry.py,sha256=0Is-LhpVoKcEjmgqEjCfNLCKJVGAmJaQmD2VHF8KI9w,163
5
5
  pykubegrader/utils.py,sha256=jlJklKvRhY3O7Hz2aaU1m0y3p_n9eMAXNnAF7LUEaPY,1275
6
6
  pykubegrader/validate.py,sha256=OKnItGyd-L8QPKcsE0KRuwBI_IxKiJzMLJKZiA2j3II,11184
7
7
  pykubegrader/build/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
8
- pykubegrader/build/api_notebook_builder.py,sha256=FVLnycCRLmZKbimw1FVwDVO-ufKUiAkcnb0O1NrUCEk,25997
9
- pykubegrader/build/build_folder.py,sha256=ecriZoXp5SzpCvP532vXfox61gyJOg9YAYNVoiNq4Ck,87803
8
+ pykubegrader/build/api_notebook_builder.py,sha256=vSnBEgHglKjNqwwQnsY0VrWhkwc6q5soJuszNfyKz9o,25748
9
+ pykubegrader/build/build_folder.py,sha256=UL5AzApDLRXD0EujHI5nsCbgaYo486SvL4_vYP_HsDE,87645
10
10
  pykubegrader/build/clean_folder.py,sha256=8N0KyL4eXRs0DCw-V_2jR9igtFs_mOFMQufdL6tD-38,1323
11
11
  pykubegrader/build/collate.py,sha256=cVvF7tf2U3iiH4R_dbghTcieedIx5w3Fyw9L_llInM8,6754
12
12
  pykubegrader/build/markdown_questions.py,sha256=cSh8mkHK3hh-etJdgrZu9UQi1WPrKQtofkzLCUp1Z-w,4676
@@ -39,9 +39,9 @@ pykubegrader/widgets_base/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-
39
39
  pykubegrader/widgets_base/multi_select.py,sha256=WhpS7a8V3BOuEfEyFPzcDhMbgr7p1a4FFh_mKU1HLbI,4226
40
40
  pykubegrader/widgets_base/reading.py,sha256=ChUS3NOTa_HLtNpxR8hGX80LPKMvYMypnR6dFknfxus,5430
41
41
  pykubegrader/widgets_base/select.py,sha256=qP31bjTWIn8LEgKwtNUJbgJnum6P7bx6A_At-u1ivFk,2750
42
- PyKubeGrader-0.3.9.dist-info/LICENSE.txt,sha256=YTp-Ewc8Kems8PJEE27KnBPFnZSxoWvSg7nnknzPyYw,1546
43
- PyKubeGrader-0.3.9.dist-info/METADATA,sha256=fPAObIviDbz7vOFs5JCQm_IBTI1lT8W_l2TRIqhkPhM,2757
44
- PyKubeGrader-0.3.9.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
45
- PyKubeGrader-0.3.9.dist-info/entry_points.txt,sha256=RR57KvzDRJrP4omy5heS5cZ3E7g56YxcxJhDnp57ZU0,253
46
- PyKubeGrader-0.3.9.dist-info/top_level.txt,sha256=e550Klfze6higFxER1V62fnGOcIgiKRbsrl9CC4UdtQ,13
47
- PyKubeGrader-0.3.9.dist-info/RECORD,,
42
+ PyKubeGrader-0.3.10.dist-info/LICENSE.txt,sha256=YTp-Ewc8Kems8PJEE27KnBPFnZSxoWvSg7nnknzPyYw,1546
43
+ PyKubeGrader-0.3.10.dist-info/METADATA,sha256=lM-bIik76huAUbqHX0y0fhftiNbaOUoDwDTt6Ut7b8Q,2758
44
+ PyKubeGrader-0.3.10.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
45
+ PyKubeGrader-0.3.10.dist-info/entry_points.txt,sha256=RR57KvzDRJrP4omy5heS5cZ3E7g56YxcxJhDnp57ZU0,253
46
+ PyKubeGrader-0.3.10.dist-info/top_level.txt,sha256=e550Klfze6higFxER1V62fnGOcIgiKRbsrl9CC4UdtQ,13
47
+ PyKubeGrader-0.3.10.dist-info/RECORD,,
@@ -1,11 +1,11 @@
1
1
  import ast
2
- import base64
3
2
  import json
4
3
  import re
5
4
  import shutil
6
- import sys
7
5
  from dataclasses import dataclass
8
6
  from pathlib import Path
7
+ from typing import Optional
8
+ import base64
9
9
  from typing import Any, Optional
10
10
 
11
11
  import nbformat
@@ -15,17 +15,17 @@ import nbformat
15
15
  class FastAPINotebookBuilder:
16
16
  notebook_path: str
17
17
  temp_notebook: Optional[str] = None
18
- assignment_tag: str = ""
19
- require_key: bool = False
20
- verbose: bool = False
18
+ assignment_tag: Optional[str] = ""
19
+ require_key: Optional[bool] = False
20
+ verbose: Optional[bool] = False
21
21
 
22
22
  def __post_init__(self) -> None:
23
23
  self.root_path, self.filename = FastAPINotebookBuilder.get_filename_and_root(
24
24
  self.notebook_path
25
25
  )
26
- self.total_points = 0.0
26
+ self.total_points = 0
27
27
 
28
- self.max_question_points: dict[str, float] = {}
28
+ self.max_question_points = {}
29
29
  self.run()
30
30
 
31
31
  def run(self) -> None:
@@ -87,17 +87,13 @@ class FastAPINotebookBuilder:
87
87
  for i, question in enumerate(self.max_question_points.keys()):
88
88
  index, source = self.find_question_description(question)
89
89
  try:
90
- modified_source = FastAPINotebookBuilder.add_text_after_double_hash(
91
- source,
92
- f"Question {i + 1} (Points: {self.max_question_points[question]}):",
93
- )
90
+ modified_source = FastAPINotebookBuilder.add_text_after_double_hash(source, f"Question {i+1} (Points: {self.max_question_points[question]}):")
94
91
  self.replace_cell_source(index, modified_source)
95
- except Exception as e:
96
- print(f"Error adding question description: {e}", file=sys.stderr)
92
+ except:
97
93
  pass
98
94
 
99
95
  for i, (cell_index, cell_dict) in enumerate(self.assertion_tests_dict.items()):
100
- if self.verbose:
96
+ if self.verbose:
101
97
  print(
102
98
  f"Processing cell {cell_index + 1}, {i} of {len(self.assertion_tests_dict)}"
103
99
  )
@@ -150,47 +146,41 @@ class FastAPINotebookBuilder:
150
146
  FastAPINotebookBuilder.construct_update_responses(cell_dict)
151
147
  )
152
148
 
153
- self.replace_cell_source(cell_index, updated_cell_source)
149
+ self.replace_cell_source(cell_index, updated_cell_source)
154
150
 
155
151
  def find_question_description(self, search_string):
156
- with open(self.temp_notebook, "r", encoding="utf-8") as f:
152
+ with open(self.temp_notebook, 'r', encoding='utf-8') as f:
157
153
  nb_data = json.load(f)
158
154
 
159
155
  found_raw = False
160
156
 
161
157
  for idx, cell in enumerate(nb_data.get("cells", [])):
162
- if (
163
- cell["cell_type"] == "raw"
164
- and any("# BEGIN QUESTION" in line for line in cell.get("source", []))
165
- and any(search_string in line for line in cell.get("source", []))
166
- ):
158
+ if cell["cell_type"] == "raw" and any("# BEGIN QUESTION" in line for line in cell.get("source", [])) and any(search_string in line for line in cell.get("source", [])):
167
159
  found_raw = True
168
160
  elif found_raw and cell["cell_type"] == "markdown":
169
- return idx, cell.get(
170
- "source", []
171
- ) # Return the index of the first matching markdown cell
161
+ return idx, cell.get("source", []) # Return the index of the first matching markdown cell
172
162
 
173
- return None, None # Return None if no such markdown cell is found
163
+ return None, None # Return None if no such markdown cell is found
174
164
 
175
165
  def add_total_points_to_notebook(self) -> None:
176
166
  self.max_question_points.keys()
177
167
 
178
168
  def get_max_question_points(self, cell_dict) -> float:
179
169
  return sum(
180
- cell["points"]
181
- for cell in self.assertion_tests_dict.values()
182
- if cell["question"] == cell_dict["question"]
183
- )
170
+ cell["points"]
171
+ for cell in self.assertion_tests_dict.values()
172
+ if cell["question"] == cell_dict["question"]
173
+ )
184
174
 
185
175
  @staticmethod
186
176
  def add_text_after_double_hash(markdown_source, insert_text):
187
177
  """
188
178
  Adds insert_text immediately after the first '##' in the first line that starts with '##'.
189
-
179
+
190
180
  Args:
191
181
  - markdown_source (list of str): The list of lines in the markdown cell.
192
182
  - insert_text (str): The text to be inserted.
193
-
183
+
194
184
  Returns:
195
185
  - list of str: The modified markdown cell content.
196
186
  """
@@ -199,9 +189,7 @@ class FastAPINotebookBuilder:
199
189
 
200
190
  for line in markdown_source:
201
191
  if not inserted and line.startswith("## "):
202
- modified_source.append(
203
- f"## {insert_text} {line[3:]}"
204
- ) # Insert text after '##'
192
+ modified_source.append(f"## {insert_text} {line[3:]}") # Insert text after '##'
205
193
  inserted = True # Ensure it only happens once
206
194
  else:
207
195
  modified_source.append(line)
@@ -216,9 +204,7 @@ class FastAPINotebookBuilder:
216
204
  max_question_points = self.get_max_question_points(cell_dict)
217
205
 
218
206
  # store the max points for the question
219
- self.max_question_points[f"{cell_dict['question']}"] = (
220
- max_question_points
221
- )
207
+ self.max_question_points[f"{cell_dict["question"]}"] = max_question_points
222
208
 
223
209
  self.total_points += max_question_points
224
210
 
@@ -344,9 +330,7 @@ class FastAPINotebookBuilder:
344
330
  return original_list[:index] + insert_list + original_list[index:]
345
331
 
346
332
  @staticmethod
347
- def add_import_statements_to_tests(
348
- cell_source: list[str], require_key: bool = False
349
- ) -> list[str]:
333
+ def add_import_statements_to_tests(cell_source: list[str], require_key:bool = False, assignment_tag = None) -> list[str]:
350
334
  """
351
335
  Adds the necessary import statements to the first cell of the notebook.
352
336
  """
@@ -83,7 +83,7 @@ class NotebookProcessor:
83
83
  self.require_key = assignment.get("require_key", False)
84
84
  self.assignment_tag = assignment.get(
85
85
  "assignment_tag",
86
- f"week{assignment.get('week')}-{self.assignment_type}",
86
+ f"week{assignment.get("week")}-{self.assignment_type}",
87
87
  )
88
88
  else:
89
89
  self.assignment_type = self.assignment_tag.split("-")[0].lower()
@@ -578,7 +578,7 @@ class NotebookProcessor:
578
578
 
579
579
  if self.require_key:
580
580
  # Add an additional line for validate_token()
581
- validate_token_line = f"from pykubegrader.tokens.validate_token import validate_token\nvalidate_token(assignment = '{self.assignment_tag}')\n"
581
+ validate_token_line =f"from pykubegrader.tokens.validate_token import validate_token\nvalidate_token(assignment = '{self.assignment_tag}')\n"
582
582
 
583
583
  # Define the Code cell
584
584
  code_cell = nbformat.v4.new_code_cell(
@@ -681,7 +681,7 @@ class NotebookProcessor:
681
681
  self.week,
682
682
  self.assignment_type,
683
683
  require_key=self.require_key,
684
- assignment_tag=self.assignment_tag,
684
+ assignment_tag = self.assignment_tag,
685
685
  )
686
686
 
687
687
  NotebookProcessor.replace_temp_in_notebook(
@@ -712,7 +712,7 @@ class NotebookProcessor:
712
712
  self.week,
713
713
  self.assignment_type,
714
714
  require_key=self.require_key,
715
- assignment_tag=self.assignment_tag,
715
+ assignment_tag = self.assignment_tag
716
716
  )
717
717
  NotebookProcessor.replace_temp_no_otter(
718
718
  temp_notebook_path, temp_notebook_path
@@ -744,9 +744,7 @@ class NotebookProcessor:
744
744
  nbformat.write(notebook, f)
745
745
 
746
746
  @staticmethod
747
- def add_validate_token_cell(
748
- notebook_path: str, require_key: bool, **kwargs
749
- ) -> None:
747
+ def add_validate_token_cell(notebook_path: str, require_key: bool, **kwargs) -> None:
750
748
  """
751
749
  Adds a new code cell at the top of a Jupyter notebook if require_key is True.
752
750
 
@@ -760,12 +758,8 @@ class NotebookProcessor:
760
758
  if not require_key:
761
759
  print("require_key is False. No changes made to the notebook.")
762
760
  return
763
-
764
- NotebookProcessor.add_validate_block(
765
- notebook_path,
766
- require_key,
767
- assignment_tag=kwargs.get("assignment_tag", None),
768
- )
761
+
762
+ NotebookProcessor.add_validate_block(notebook_path, require_key, assignment_tag = kwargs.get("assignment_tag", None))
769
763
 
770
764
  # Load the notebook
771
765
  with open(notebook_path, "r", encoding="utf-8") as f:
@@ -774,13 +768,13 @@ class NotebookProcessor:
774
768
  # Create the new code cell
775
769
  if kwargs.get("assignment_tag", None):
776
770
  new_cell = nbformat.v4.new_code_cell(
777
- "from pykubegrader.tokens.validate_token import validate_token\n"
778
- f"validate_token('type the key provided by your instructor here', assignment = '{kwargs.get('assignment_tag')}')\n"
771
+ "from pykubegrader.tokens.validate_token import validate_token\n"
772
+ f"validate_token('type the key provided by your instructor here', assignment = '{kwargs.get('assignment_tag')}')\n"
779
773
  )
780
774
  else:
781
775
  new_cell = nbformat.v4.new_code_cell(
782
- "from pykubegrader.tokens.validate_token import validate_token\n"
783
- "validate_token('type the key provided by your instructor here')\n"
776
+ "from pykubegrader.tokens.validate_token import validate_token\n"
777
+ "validate_token('type the key provided by your instructor here')\n"
784
778
  )
785
779
 
786
780
  # Add the new cell to the top of the notebook
@@ -825,11 +819,7 @@ class NotebookProcessor:
825
819
 
826
820
  @staticmethod
827
821
  def add_initialization_code(
828
- notebook_path,
829
- week,
830
- assignment_type,
831
- require_key=False,
832
- **kwargs,
822
+ notebook_path, week, assignment_type, require_key=False, **kwargs,
833
823
  ):
834
824
  # finds the first code cell
835
825
  index, cell = find_first_code_cell(notebook_path)
@@ -841,11 +831,7 @@ class NotebookProcessor:
841
831
  replace_cell_source(notebook_path, index, cell)
842
832
 
843
833
  if require_key:
844
- NotebookProcessor.add_validate_token_cell(
845
- notebook_path,
846
- require_key,
847
- assignment_tag=kwargs.get("assignment_tag", None),
848
- )
834
+ NotebookProcessor.add_validate_token_cell(notebook_path, require_key, assignment_tag = kwargs.get("assignment_tag", None))
849
835
 
850
836
  def multiple_choice_parser(self, temp_notebook_path, new_notebook_path):
851
837
  ### Parse the notebook for multiple choice questions