dlai-grader 1.19.0__tar.gz → 1.21.0__tar.gz

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.

Potentially problematic release.


This version of dlai-grader might be problematic. Click here for more details.

Files changed (21) hide show
  1. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/PKG-INFO +3 -1
  2. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/dlai_grader/__init__.py +1 -1
  3. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/dlai_grader/compiler.py +34 -2
  4. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/dlai_grader/templates.py +48 -46
  5. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/dlai_grader.egg-info/PKG-INFO +3 -1
  6. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/setup.py +1 -1
  7. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/LICENSE +0 -0
  8. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/README.md +0 -0
  9. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/dlai_grader/cli.py +0 -0
  10. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/dlai_grader/config.py +0 -0
  11. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/dlai_grader/grading.py +0 -0
  12. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/dlai_grader/io.py +0 -0
  13. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/dlai_grader/notebook.py +0 -0
  14. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/dlai_grader/py.typed +0 -0
  15. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/dlai_grader/types.py +0 -0
  16. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/dlai_grader.egg-info/SOURCES.txt +0 -0
  17. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/dlai_grader.egg-info/dependency_links.txt +0 -0
  18. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/dlai_grader.egg-info/entry_points.txt +0 -0
  19. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/dlai_grader.egg-info/requires.txt +0 -0
  20. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/dlai_grader.egg-info/top_level.txt +0 -0
  21. {dlai-grader-1.19.0 → dlai_grader-1.21.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dlai-grader
3
- Version: 1.19.0
3
+ Version: 1.21.0
4
4
  Summary: Grading utilities for DLAI courses
5
5
  Home-page: https://github.com/https-deeplearning-ai/grader
6
6
  Author: Andres Zarta
@@ -11,6 +11,8 @@ Classifier: License :: OSI Approved :: MIT License
11
11
  Classifier: Operating System :: OS Independent
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
+ Requires-Dist: nbformat>=5.1.3
15
+ Requires-Dist: jupytext>=1.13.0
14
16
 
15
17
  # grader
16
18
  Automatic grading for DLAI courses. Designed to be compatible with Coursera's grading requirements.
@@ -6,6 +6,6 @@ from . import grading
6
6
  from . import types
7
7
 
8
8
 
9
- __version__ = "1.19.0"
9
+ __version__ = "1.21.0"
10
10
  __author__ = "Andres Zarta"
11
11
  __credits__ = "DeepLearning.AI"
@@ -1,7 +1,7 @@
1
1
  import ast
2
- import sys
3
2
  from types import ModuleType
4
3
  from contextlib import nullcontext
4
+ from nbformat.notebooknode import NotebookNode
5
5
  from .io import suppress_stdout_stderr
6
6
 
7
7
 
@@ -32,6 +32,38 @@ def compile_module(
32
32
  with nullcontext() if verbose else suppress_stdout_stderr():
33
33
  module = ModuleType(module_name)
34
34
  code = compile(code_ast, f"{module_name}.py", "exec")
35
- sys.modules[module_name] = module
36
35
  exec(code, module.__dict__)
37
36
  return module
37
+
38
+
39
+ def compile_partial_module(
40
+ notebook: NotebookNode,
41
+ module_name: str,
42
+ verbose: bool = True,
43
+ ) -> ModuleType:
44
+ """Iterates over the code cells of a notebook and includes the ones that run to the compiled module.
45
+ Args:
46
+ notebook (NotebookNode): Notebook from learner.
47
+ module_name (str): Name of the module.
48
+ verbose (bool): Whether to print out streams as a result of compilation. Defaults to True.
49
+ Returns:
50
+ ModuleType: The actual module that can be used to call functions/variables/etc.
51
+ """
52
+ code_cells = [cell.source for cell in notebook.cells if cell.cell_type == "code"]
53
+ module = ModuleType(module_name)
54
+
55
+ for i, cell_code in enumerate(code_cells):
56
+ try:
57
+ compiled_code = compile(cell_code, f"<cell {i}>", "exec")
58
+
59
+ with nullcontext() if verbose else suppress_stdout_stderr():
60
+ exec(compiled_code, module.__dict__)
61
+
62
+ except Exception as e:
63
+ if verbose:
64
+ print(
65
+ f"Error during execution of cell. Aborting full compilation.\n\nContents:\n\n{cell_code}\n\nException:\n\n{e}\n"
66
+ )
67
+ break
68
+
69
+ return module
@@ -17,6 +17,8 @@ def load_templates() -> Dict[str, str]:
17
17
  print("invalid option selected")
18
18
  exit(1)
19
19
 
20
+ unit_test_filename = input("Filename for unit tests (leave empty for unittests): ")
21
+ unit_test_filename = "unittests" if not unit_test_filename else unit_test_filename
20
22
  version = input("Version of the grader (leave empty for version 1): ")
21
23
  version = "1" if not version else version
22
24
 
@@ -56,6 +58,7 @@ def load_templates() -> Dict[str, str]:
56
58
 
57
59
  conf = f"""
58
60
  ASSIGNMENT_NAME=C{course}{W_OR_M}{W_OR_M_num}_Assignment
61
+ UNIT_TESTS_NAME={unit_test_filename}
59
62
  IMAGE_NAME={specialization}c{course}{W_OR_M.lower()}{W_OR_M_num}-grader
60
63
  GRADER_VERSION={version}
61
64
  TAG_ID=V$(GRADER_VERSION)
@@ -64,66 +67,66 @@ def load_templates() -> Dict[str, str]:
64
67
  """
65
68
 
66
69
  makefile = """
67
- .PHONY: learner build entry submit-solution upgrade test grade mem zip clean upload move-zip move-learner tag undeletable uneditable versioning upgrade sync
70
+ .PHONY: learner build entry submit-solution upgrade test grade mem zip clean upload move-zip move-learner tag undeletable uneditable versioning upgrade sync
68
71
 
69
- include .conf
72
+ include .conf
70
73
 
71
- PARTIDS = ""
72
- OS := $(shell uname)
74
+ PARTIDS = ""
75
+ OS := $(shell uname)
73
76
 
74
- sync:
75
- cp mount/submission.ipynb ../$(ASSIGNMENT_NAME)_Solution.ipynb
76
- cp learner/$(ASSIGNMENT_NAME).ipynb ../$(ASSIGNMENT_NAME).ipynb
77
- cp mount/unittests.py ../unittests.py
77
+ sync:
78
+ cp mount/submission.ipynb ../$(ASSIGNMENT_NAME)_Solution.ipynb
79
+ cp learner/$(ASSIGNMENT_NAME).ipynb ../$(ASSIGNMENT_NAME).ipynb
80
+ cp mount/$(UNIT_TESTS_NAME).py ../$(UNIT_TESTS_NAME).py
78
81
 
79
- learner:
80
- dlai_grader --learner --output_notebook=./learner/$(ASSIGNMENT_NAME).ipynb
82
+ learner:
83
+ dlai_grader --learner --output_notebook=./learner/$(ASSIGNMENT_NAME).ipynb
81
84
 
82
- build:
83
- docker build -t $(IMAGE_NAME):$(TAG_ID) .
85
+ build:
86
+ docker build -t $(IMAGE_NAME):$(TAG_ID) .
84
87
 
85
- debug:
86
- docker run -it --rm --mount type=bind,source=$(PWD)/mount,target=/shared/submission --mount type=bind,source=$(PWD),target=/grader/ --entrypoint ash $(IMAGE_NAME):$(TAG_ID)
88
+ debug:
89
+ docker run -it --rm --mount type=bind,source=$(PWD)/mount,target=/shared/submission --mount type=bind,source=$(PWD),target=/grader/ --entrypoint ash $(IMAGE_NAME):$(TAG_ID)
87
90
 
88
- submit-solution:
89
- cp solution/solution.ipynb mount/submission.ipynb
91
+ submit-solution:
92
+ cp solution/solution.ipynb mount/submission.ipynb
90
93
 
91
- versioning:
92
- dlai_grader --versioning
94
+ versioning:
95
+ dlai_grader --versioning
93
96
 
94
- tag:
95
- dlai_grader --tag
97
+ tag:
98
+ dlai_grader --tag
96
99
 
97
- undeletable:
98
- dlai_grader --undeletable
100
+ undeletable:
101
+ dlai_grader --undeletable
99
102
 
100
- uneditable:
101
- dlai_grader --uneditable
103
+ uneditable:
104
+ dlai_grader --uneditable
102
105
 
103
- upgrade:
104
- dlai_grader --upgrade
106
+ upgrade:
107
+ dlai_grader --upgrade
105
108
 
106
- test:
107
- docker run -it --rm --mount type=bind,source=$(PWD)/mount,target=/shared/submission --mount type=bind,source=$(PWD),target=/grader/ --entrypoint pytest $(IMAGE_NAME):$(TAG_ID)
109
+ test:
110
+ docker run -it --rm --mount type=bind,source=$(PWD)/mount,target=/shared/submission --mount type=bind,source=$(PWD),target=/grader/ --entrypoint pytest $(IMAGE_NAME):$(TAG_ID)
108
111
 
109
- grade:
110
- dlai_grader --grade --partids=$(PARTIDS) --docker=$(IMAGE_NAME):$(TAG_ID) --memory=$(MEMORY_LIMIT) --submission=$(SUB_DIR)
112
+ grade:
113
+ dlai_grader --grade --partids=$(PARTIDS) --docker=$(IMAGE_NAME):$(TAG_ID) --memory=$(MEMORY_LIMIT) --submission=$(SUB_DIR)
111
114
 
112
- mem:
113
- memthis $(PARTIDS)
115
+ mem:
116
+ memthis $(PARTIDS)
114
117
 
115
- zip:
116
- zip -r $(IMAGE_NAME)$(TAG_ID).zip .
118
+ zip:
119
+ zip -r $(IMAGE_NAME)$(TAG_ID).zip .
117
120
 
118
- clean:
119
- find . -maxdepth 1 -type f -name "*.zip" -exec rm {} +
120
- docker rm $$(docker ps -qa --no-trunc --filter "status=exited")
121
- docker rmi $$(docker images --filter "dangling=true" -q --no-trunc)
121
+ clean:
122
+ find . -maxdepth 1 -type f -name "*.zip" -exec rm {} +
123
+ docker rm $$(docker ps -qa --no-trunc --filter "status=exited")
124
+ docker rmi $$(docker images --filter "dangling=true" -q --no-trunc)
122
125
 
123
- upload:
124
- coursera_autograder --timeout 1800 upload --grader-memory-limit $(MEMORY_LIMIT) --grading-timeout 1800 $(IMAGE_NAME)$(TAG_ID).zip $(COURSE_ID) $(ITEM_ID) $(PART_ID)
126
+ upload:
127
+ coursera_autograder --timeout 1800 upload --grader-memory-limit $(MEMORY_LIMIT) --grading-timeout 1800 $(IMAGE_NAME)$(TAG_ID).zip $(COURSE_ID) $(ITEM_ID) $(PART_ID)
125
128
 
126
- """
129
+ """
127
130
 
128
131
  grader_py = """
129
132
  from types import ModuleType, FunctionType
@@ -162,7 +165,7 @@ def load_templates() -> Dict[str, str]:
162
165
 
163
166
  entry_py = """
164
167
  from dlai_grader.config import Config
165
- from dlai_grader.compiler import compile_module
168
+ from dlai_grader.compiler import compile_partial_module
166
169
  from dlai_grader.io import read_notebook, copy_submission_to_workdir, send_feedback
167
170
 
168
171
  from dlai_grader.notebook import (
@@ -201,14 +204,13 @@ def load_templates() -> Dict[str, str]:
201
204
  for t in transformations:
202
205
  nb = t(nb)
203
206
 
204
- script = notebook_to_script(nb)
205
-
206
207
  try:
207
- learner_mod = compile_module(script, "learner_mod", verbose=False)
208
+ learner_mod = compile_partial_module(nb, "learner_mod", verbose=False)
208
209
  except Exception as e:
209
210
  send_feedback(
210
211
  0.0,
211
212
  f"There was a problem compiling the code from your notebook, please check that you saved before submitting. Details:\\n{str(e)}",
213
+ err=True,
212
214
  )
213
215
 
214
216
  solution_nb = read_notebook(c.solution_file_path)
@@ -237,7 +239,7 @@ def load_templates() -> Dict[str, str]:
237
239
 
238
240
  send_feedback(
239
241
  0.0,
240
- f"Unable to find object required for grading in your code.\\n{additional_msg}",
242
+ f"Object required for grading not found. If you haven't completed the exercise this is expected. Otherwise, check your solution as grader omits cells that throw errors.\n{additional_msg}",
241
243
  err=True,
242
244
  )
243
245
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dlai-grader
3
- Version: 1.19.0
3
+ Version: 1.21.0
4
4
  Summary: Grading utilities for DLAI courses
5
5
  Home-page: https://github.com/https-deeplearning-ai/grader
6
6
  Author: Andres Zarta
@@ -11,6 +11,8 @@ Classifier: License :: OSI Approved :: MIT License
11
11
  Classifier: Operating System :: OS Independent
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
+ Requires-Dist: nbformat>=5.1.3
15
+ Requires-Dist: jupytext>=1.13.0
14
16
 
15
17
  # grader
16
18
  Automatic grading for DLAI courses. Designed to be compatible with Coursera's grading requirements.
@@ -5,7 +5,7 @@ with open("README.md", "r") as f:
5
5
 
6
6
  setup(
7
7
  name="dlai-grader",
8
- version="1.19.0",
8
+ version="1.21.0",
9
9
  description="Grading utilities for DLAI courses",
10
10
  url="https://github.com/https-deeplearning-ai/grader",
11
11
  author="Andres Zarta",
File without changes
File without changes
File without changes