QuizGenerator 0.4.2__py3-none-any.whl → 0.6.0__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.
Files changed (33) hide show
  1. QuizGenerator/contentast.py +809 -117
  2. QuizGenerator/generate.py +219 -11
  3. QuizGenerator/misc.py +0 -556
  4. QuizGenerator/mixins.py +50 -29
  5. QuizGenerator/premade_questions/basic.py +3 -3
  6. QuizGenerator/premade_questions/cst334/languages.py +183 -175
  7. QuizGenerator/premade_questions/cst334/math_questions.py +81 -70
  8. QuizGenerator/premade_questions/cst334/memory_questions.py +262 -165
  9. QuizGenerator/premade_questions/cst334/persistence_questions.py +83 -60
  10. QuizGenerator/premade_questions/cst334/process.py +558 -79
  11. QuizGenerator/premade_questions/cst463/gradient_descent/gradient_calculation.py +39 -13
  12. QuizGenerator/premade_questions/cst463/gradient_descent/gradient_descent_questions.py +61 -36
  13. QuizGenerator/premade_questions/cst463/gradient_descent/loss_calculations.py +29 -10
  14. QuizGenerator/premade_questions/cst463/gradient_descent/misc.py +2 -2
  15. QuizGenerator/premade_questions/cst463/math_and_data/matrix_questions.py +60 -43
  16. QuizGenerator/premade_questions/cst463/math_and_data/vector_questions.py +173 -326
  17. QuizGenerator/premade_questions/cst463/models/attention.py +29 -14
  18. QuizGenerator/premade_questions/cst463/models/cnns.py +32 -20
  19. QuizGenerator/premade_questions/cst463/models/rnns.py +28 -15
  20. QuizGenerator/premade_questions/cst463/models/text.py +29 -15
  21. QuizGenerator/premade_questions/cst463/models/weight_counting.py +38 -30
  22. QuizGenerator/premade_questions/cst463/neural-network-basics/neural_network_questions.py +91 -111
  23. QuizGenerator/premade_questions/cst463/tensorflow-intro/tensorflow_questions.py +128 -55
  24. QuizGenerator/question.py +114 -20
  25. QuizGenerator/quiz.py +81 -24
  26. QuizGenerator/regenerate.py +98 -29
  27. {quizgenerator-0.4.2.dist-info → quizgenerator-0.6.0.dist-info}/METADATA +1 -1
  28. {quizgenerator-0.4.2.dist-info → quizgenerator-0.6.0.dist-info}/RECORD +31 -33
  29. QuizGenerator/README.md +0 -5
  30. QuizGenerator/logging.yaml +0 -55
  31. {quizgenerator-0.4.2.dist-info → quizgenerator-0.6.0.dist-info}/WHEEL +0 -0
  32. {quizgenerator-0.4.2.dist-info → quizgenerator-0.6.0.dist-info}/entry_points.txt +0 -0
  33. {quizgenerator-0.4.2.dist-info → quizgenerator-0.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -5,8 +5,8 @@ import abc
5
5
  import difflib
6
6
  import logging
7
7
 
8
- from QuizGenerator.question import Question, Answer, QuestionRegistry
9
- from QuizGenerator.contentast import ContentAST
8
+ from QuizGenerator.question import Question, QuestionRegistry
9
+ from QuizGenerator.contentast import ContentAST, AnswerTypes
10
10
  from QuizGenerator.mixins import TableQuestionMixin, BodyTemplatesMixin
11
11
 
12
12
  log = logging.getLogger(__name__)
@@ -36,25 +36,21 @@ class HardDriveAccessTime(IOQuestion, TableQuestionMixin, BodyTemplatesMixin):
36
36
  self.disk_access_delay = self.access_delay * self.number_of_reads + self.transfer_delay
37
37
 
38
38
  self.answers.update({
39
- "answer__rotational_delay": Answer.float_value(
40
- "answer__rotational_delay",
41
- self.rotational_delay
42
- ),
43
- "answer__access_delay": Answer.float_value(
44
- "answer__access_delay",
45
- self.access_delay
46
- ),
47
- "answer__transfer_delay": Answer.float_value(
48
- "answer__transfer_delay",
49
- self.transfer_delay
50
- ),
51
- "answer__disk_access_delay": Answer.float_value(
52
- "answer__disk_access_delay",
53
- self.disk_access_delay
54
- ),
39
+ "answer__rotational_delay" : AnswerTypes.Float(self.rotational_delay),
40
+ "answer__access_delay" : AnswerTypes.Float(self.access_delay),
41
+ "answer__transfer_delay" : AnswerTypes.Float(self.transfer_delay),
42
+ "answer__disk_access_delay" : AnswerTypes.Float(self.disk_access_delay),
55
43
  })
56
44
 
57
- def get_body(self, *args, **kwargs) -> ContentAST.Section:
45
+ def _get_body(self, *args, **kwargs):
46
+ """Build question body and collect answers."""
47
+ answers = [
48
+ self.answers["answer__rotational_delay"],
49
+ self.answers["answer__access_delay"],
50
+ self.answers["answer__transfer_delay"],
51
+ self.answers["answer__disk_access_delay"],
52
+ ]
53
+
58
54
  # Create parameter info table using mixin
59
55
  parameter_info = {
60
56
  "Hard Drive Rotation Speed": f"{self.hard_drive_rotation_speed}RPM",
@@ -84,8 +80,8 @@ class HardDriveAccessTime(IOQuestion, TableQuestionMixin, BodyTemplatesMixin):
84
80
  intro_text = "Given the information below, please calculate the following values."
85
81
 
86
82
  instructions = (
87
- f"Make sure your answers are rounded to {Answer.DEFAULT_ROUNDING_DIGITS} decimal points "
88
- f"(even if they are whole numbers), and do so after you finish all your calculations! "
83
+ f"Make sure that if you round your answers you use the unrounded values for your final calculations, "
84
+ f"otherwise you may introduce error into your calculations."
89
85
  f"(i.e. don't use your rounded answers to calculate your overall answer)"
90
86
  )
91
87
 
@@ -96,9 +92,14 @@ class HardDriveAccessTime(IOQuestion, TableQuestionMixin, BodyTemplatesMixin):
96
92
  additional_instructions=instructions
97
93
  )
98
94
 
95
+ return body, answers
96
+
97
+ def get_body(self, *args, **kwargs) -> ContentAST.Section:
98
+ """Build question body (backward compatible interface)."""
99
+ body, _ = self._get_body(*args, **kwargs)
99
100
  return body
100
-
101
- def get_explanation(self) -> ContentAST.Section:
101
+
102
+ def _get_explanation(self):
102
103
  explanation = ContentAST.Section()
103
104
 
104
105
  explanation.add_element(
@@ -150,6 +151,11 @@ class HardDriveAccessTime(IOQuestion, TableQuestionMixin, BodyTemplatesMixin):
150
151
  f"= {self.number_of_reads} \\cdot {self.access_delay:0.2f} + {self.transfer_delay:0.2f} "
151
152
  f"= {self.disk_access_delay:0.2f}ms")
152
153
  ])
154
+ return explanation, []
155
+
156
+ def get_explanation(self) -> ContentAST.Section:
157
+ """Build question explanation (backward compatible interface)."""
158
+ explanation, _ = self._get_explanation()
153
159
  return explanation
154
160
 
155
161
 
@@ -172,13 +178,21 @@ class INodeAccesses(IOQuestion, TableQuestionMixin, BodyTemplatesMixin):
172
178
  self.inode_index_in_block = int(self.inode_address_in_block / self.inode_size)
173
179
 
174
180
  self.answers.update({
175
- "answer__inode_address": Answer.integer("answer__inode_address", self.inode_address),
176
- "answer__inode_block": Answer.integer("answer__inode_block", self.inode_block),
177
- "answer__inode_address_in_block": Answer.integer("answer__inode_address_in_block", self.inode_address_in_block),
178
- "answer__inode_index_in_block": Answer.integer("answer__inode_index_in_block", self.inode_index_in_block),
181
+ "answer__inode_address": AnswerTypes.Int(self.inode_address),
182
+ "answer__inode_block": AnswerTypes.Int(self.inode_block),
183
+ "answer__inode_address_in_block": AnswerTypes.Int(self.inode_address_in_block),
184
+ "answer__inode_index_in_block": AnswerTypes.Int(self.inode_index_in_block),
179
185
  })
180
186
 
181
- def get_body(self) -> ContentAST.Section:
187
+ def _get_body(self):
188
+ """Build question body and collect answers."""
189
+ answers = [
190
+ self.answers["answer__inode_address"],
191
+ self.answers["answer__inode_block"],
192
+ self.answers["answer__inode_address_in_block"],
193
+ self.answers["answer__inode_index_in_block"],
194
+ ]
195
+
182
196
  # Create parameter info table using mixin
183
197
  parameter_info = {
184
198
  "Block Size": f"{self.block_size} Bytes",
@@ -206,21 +220,21 @@ class INodeAccesses(IOQuestion, TableQuestionMixin, BodyTemplatesMixin):
206
220
  # Use mixin to create complete body with both tables
207
221
  intro_text = "Given the information below, please calculate the following values."
208
222
 
209
- instructions = (
210
- "(hint: they should all be round numbers). "
211
- "Remember, demonstrating you know the equations and what goes into them is generally sufficient."
212
- )
213
-
214
223
  body = self.create_parameter_calculation_body(
215
224
  intro_text=intro_text,
216
225
  parameter_table=parameter_table,
217
226
  answer_table=answer_table,
218
- additional_instructions=instructions
227
+ # additional_instructions=instructions
219
228
  )
220
229
 
230
+ return body, answers
231
+
232
+ def get_body(self) -> ContentAST.Section:
233
+ """Build question body (backward compatible interface)."""
234
+ body, _ = self._get_body()
221
235
  return body
222
-
223
- def get_explanation(self) -> ContentAST.Section:
236
+
237
+ def _get_explanation(self):
224
238
  explanation = ContentAST.Section()
225
239
 
226
240
  explanation.add_element(
@@ -292,7 +306,12 @@ class INodeAccesses(IOQuestion, TableQuestionMixin, BodyTemplatesMixin):
292
306
  f"{self.inode_index_in_block}"
293
307
  ]
294
308
  ))
295
-
309
+
310
+ return explanation, []
311
+
312
+ def get_explanation(self) -> ContentAST.Section:
313
+ """Build question explanation (backward compatible interface)."""
314
+ explanation, _ = self._get_explanation()
296
315
  return explanation
297
316
 
298
317
 
@@ -303,7 +322,7 @@ class VSFS_states(IOQuestion):
303
322
 
304
323
  def __init__(self, *args, **kwargs):
305
324
  super().__init__(*args, **kwargs)
306
- self.answer_kind = Answer.AnswerKind.MULTIPLE_DROPDOWN
325
+ self.answer_kind = ContentAST.Answer.CanvasAnswerKind.MULTIPLE_DROPDOWN
307
326
 
308
327
  self.num_steps = kwargs.get("num_steps", 10)
309
328
 
@@ -325,45 +344,44 @@ class VSFS_states(IOQuestion):
325
344
  ))
326
345
  self.rng.shuffle(wrong_answers)
327
346
 
328
- self.answers["answer__cmd"] = Answer(
329
- "answer__cmd",
347
+ self.answers["answer__cmd"] = ContentAST.Answer.dropdown(
330
348
  f"{operations[-1]['cmd']}",
331
- kind=Answer.AnswerKind.MULTIPLE_DROPDOWN,
332
- correct=True,
333
- baffles=list(set([op['cmd'] for op in operations[:-1] if op != operations[-1]['cmd']]))
349
+ baffles=list(set([op['cmd'] for op in operations[:-1] if op != operations[-1]['cmd']])),
350
+ label="Command"
334
351
  )
335
352
 
336
- def get_body(self) -> ContentAST.Section:
353
+ def _get_body(self):
354
+ """Build question body and collect answers."""
355
+ answers = [self.answers["answer__cmd"]]
356
+
337
357
  body = ContentAST.Section()
338
-
358
+
339
359
  body.add_element(ContentAST.Paragraph(["What operation happens between these two states?"]))
340
-
360
+
341
361
  body.add_element(
342
362
  ContentAST.Code(
343
363
  self.start_state,
344
364
  make_small=True
345
365
  )
346
366
  )
347
-
348
- body.add_element(
349
- ContentAST.AnswerBlock(
350
- ContentAST.Answer(
351
- self.answers["answer__cmd"],
352
- label="Command"
353
- )
354
- )
355
- )
356
-
367
+
368
+ body.add_element(ContentAST.AnswerBlock(self.answers["answer__cmd"]))
369
+
357
370
  body.add_element(
358
371
  ContentAST.Code(
359
372
  self.end_state,
360
373
  make_small=True
361
374
  )
362
375
  )
363
-
376
+
377
+ return body, answers
378
+
379
+ def get_body(self) -> ContentAST.Section:
380
+ """Build question body (backward compatible interface)."""
381
+ body, _ = self._get_body()
364
382
  return body
365
-
366
- def get_explanation(self) -> ContentAST.Section:
383
+
384
+ def _get_explanation(self):
367
385
  explanation = ContentAST.Section()
368
386
 
369
387
  log.debug(f"self.start_state: {self.start_state}")
@@ -446,6 +464,11 @@ class VSFS_states(IOQuestion):
446
464
  highlight_changes(self.start_state, self.end_state)
447
465
  )
448
466
  )
449
-
467
+
468
+ return explanation, []
469
+
470
+ def get_explanation(self) -> ContentAST.Section:
471
+ """Build question explanation (backward compatible interface)."""
472
+ explanation, _ = self._get_explanation()
450
473
  return explanation
451
474