QuizGenerator 0.7.1__py3-none-any.whl → 0.8.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 (30) hide show
  1. QuizGenerator/contentast.py +6 -6
  2. QuizGenerator/generate.py +2 -1
  3. QuizGenerator/mixins.py +14 -100
  4. QuizGenerator/premade_questions/basic.py +24 -29
  5. QuizGenerator/premade_questions/cst334/languages.py +100 -99
  6. QuizGenerator/premade_questions/cst334/math_questions.py +112 -122
  7. QuizGenerator/premade_questions/cst334/memory_questions.py +621 -621
  8. QuizGenerator/premade_questions/cst334/persistence_questions.py +137 -163
  9. QuizGenerator/premade_questions/cst334/process.py +312 -322
  10. QuizGenerator/premade_questions/cst463/gradient_descent/gradient_calculation.py +34 -35
  11. QuizGenerator/premade_questions/cst463/gradient_descent/gradient_descent_questions.py +41 -36
  12. QuizGenerator/premade_questions/cst463/gradient_descent/loss_calculations.py +48 -41
  13. QuizGenerator/premade_questions/cst463/math_and_data/matrix_questions.py +285 -520
  14. QuizGenerator/premade_questions/cst463/math_and_data/vector_questions.py +149 -126
  15. QuizGenerator/premade_questions/cst463/models/attention.py +44 -50
  16. QuizGenerator/premade_questions/cst463/models/cnns.py +43 -47
  17. QuizGenerator/premade_questions/cst463/models/matrices.py +61 -11
  18. QuizGenerator/premade_questions/cst463/models/rnns.py +48 -50
  19. QuizGenerator/premade_questions/cst463/models/text.py +65 -67
  20. QuizGenerator/premade_questions/cst463/models/weight_counting.py +47 -46
  21. QuizGenerator/premade_questions/cst463/neural-network-basics/neural_network_questions.py +100 -156
  22. QuizGenerator/premade_questions/cst463/tensorflow-intro/tensorflow_questions.py +93 -141
  23. QuizGenerator/question.py +273 -202
  24. QuizGenerator/quiz.py +8 -5
  25. QuizGenerator/regenerate.py +14 -6
  26. {quizgenerator-0.7.1.dist-info → quizgenerator-0.8.0.dist-info}/METADATA +30 -2
  27. {quizgenerator-0.7.1.dist-info → quizgenerator-0.8.0.dist-info}/RECORD +30 -30
  28. {quizgenerator-0.7.1.dist-info → quizgenerator-0.8.0.dist-info}/WHEEL +0 -0
  29. {quizgenerator-0.7.1.dist-info → quizgenerator-0.8.0.dist-info}/entry_points.txt +0 -0
  30. {quizgenerator-0.7.1.dist-info → quizgenerator-0.8.0.dist-info}/licenses/LICENSE +0 -0
QuizGenerator/quiz.py CHANGED
@@ -206,10 +206,10 @@ class Quiz:
206
206
  if check_typst_available():
207
207
  try:
208
208
  # Render question to Typst
209
- question_ast = question.get_question(**kwargs)
209
+ instance = question.instantiate(**kwargs)
210
210
 
211
211
  # Get just the content body (without the #question wrapper which adds spacing)
212
- typst_body = question_ast.body.render("typst", **kwargs)
212
+ typst_body = instance.body.render("typst", **kwargs)
213
213
 
214
214
  # Measure the content
215
215
  measured_height = measure_typst_content(typst_body, page_width_cm=18.0)
@@ -236,7 +236,8 @@ class Quiz:
236
236
  spacing_height = question.spacing # cm
237
237
 
238
238
  # Estimate content height by rendering to LaTeX and analyzing structure
239
- question_ast = question.get_question(**kwargs)
239
+ instance = question.instantiate(**kwargs)
240
+ question_ast = question._build_question_ast(instance)
240
241
  latex_content = question_ast.render("latex")
241
242
 
242
243
  # Count content that adds height (rough estimates in cm)
@@ -451,9 +452,11 @@ class Quiz:
451
452
  # Generate a unique seed for this question from the master seed
452
453
  if master_seed is not None:
453
454
  question_seed = master_rng.randint(0, 2**31 - 1)
454
- question_ast = question.get_question(rng_seed=question_seed, **kwargs)
455
+ instance = question.instantiate(rng_seed=question_seed, **kwargs)
456
+ question_ast = question._build_question_ast(instance)
455
457
  else:
456
- question_ast = question.get_question(**kwargs)
458
+ instance = question.instantiate(**kwargs)
459
+ question_ast = question._build_question_ast(instance)
457
460
 
458
461
  # Add question number to the AST for QR code generation
459
462
  question_ast.question_number = question_number
@@ -241,10 +241,14 @@ def regenerate_question_answer(
241
241
  )
242
242
 
243
243
  # Generate question with the specific seed
244
- question_ast = question.get_question(rng_seed=seed)
244
+ instance = question.instantiate(rng_seed=seed)
245
+ question_ast = question._build_question_ast(instance)
245
246
 
246
247
  # Extract answers
247
- answer_kind, canvas_answers = question.get_answers()
248
+ answer_kind, canvas_answers = question._answers_for_canvas(
249
+ instance.answers,
250
+ instance.can_be_numerical
251
+ )
248
252
 
249
253
  result['answers'] = {
250
254
  'kind': answer_kind.value,
@@ -252,7 +256,7 @@ def regenerate_question_answer(
252
256
  }
253
257
 
254
258
  # Also store the raw answer objects for easier access
255
- result['answer_objects'] = question.answers
259
+ result['answer_objects'] = instance.answers
256
260
 
257
261
  resolved_upload_func = _resolve_upload_func(image_mode, upload_func)
258
262
 
@@ -400,10 +404,14 @@ def regenerate_from_metadata(
400
404
  )
401
405
 
402
406
  # Generate question with the specific seed
403
- question_ast = question.get_question(rng_seed=seed)
407
+ instance = question.instantiate(rng_seed=seed)
408
+ question_ast = question._build_question_ast(instance)
404
409
 
405
410
  # Extract answers
406
- answer_kind, canvas_answers = question.get_answers()
411
+ answer_kind, canvas_answers = question._answers_for_canvas(
412
+ instance.answers,
413
+ instance.can_be_numerical
414
+ )
407
415
 
408
416
  resolved_upload_func = _resolve_upload_func(image_mode, upload_func)
409
417
 
@@ -436,7 +444,7 @@ def regenerate_from_metadata(
436
444
  "kind": answer_kind.value,
437
445
  "data": canvas_answers
438
446
  },
439
- "answer_objects": question.answers,
447
+ "answer_objects": instance.answers,
440
448
  "answer_key_html": question_html,
441
449
  "explanation_markdown": explanation_markdown,
442
450
  "explanation_html": explanation_html
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: QuizGenerator
3
- Version: 0.7.1
3
+ Version: 0.8.0
4
4
  Summary: Generate randomized quiz questions for Canvas LMS and PDF exams
5
5
  Project-URL: Homepage, https://github.com/OtterDen-Lab/QuizGenerator
6
6
  Project-URL: Documentation, https://github.com/OtterDen-Lab/QuizGenerator/tree/main/documentation
@@ -144,6 +144,34 @@ questions:
144
144
 
145
145
  See [documentation/custom_questions.md](documentation/custom_questions.md) for complete guide.
146
146
 
147
+ ### Question Authoring Pattern (New)
148
+
149
+ All questions follow the same three‑method flow:
150
+
151
+ ```python
152
+ class MyQuestion(Question):
153
+ def _build_context(self, *, rng_seed=None, **kwargs):
154
+ context = super()._build_context(rng_seed=rng_seed, **kwargs)
155
+ rng = context["rng"]
156
+ context["value"] = rng.randint(1, 10)
157
+ return context
158
+
159
+ def _build_body(self, context):
160
+ body = ca.Section()
161
+ body.add_element(ca.Paragraph([f"Value: {context['value']}"]))
162
+ body.add_element(ca.AnswerTypes.Int(context["value"], label="Value"))
163
+ return body
164
+
165
+ def _build_explanation(self, context):
166
+ explanation = ca.Section()
167
+ explanation.add_element(ca.Paragraph([f"Answer: {context['value']}"]))
168
+ return explanation
169
+ ```
170
+
171
+ Notes:
172
+ - Always use `context["rng"]` for deterministic randomness.
173
+ - Avoid `refresh()`; it is no longer part of the API.
174
+
147
175
  ## Built-in Question Types
148
176
 
149
177
  ### Operating Systems (CST334)
@@ -262,4 +290,4 @@ If you use QuizGenerator in academic work, please cite:
262
290
 
263
291
  ---
264
292
 
265
- **Note**: This tool is designed for educational use. Ensure compliance with your institution's academic integrity policies when using automated quiz generation.
293
+ **Note**: This tool is designed for educational use. Ensure compliance with your institution's academic integrity policies when using automated quiz generation.
@@ -1,50 +1,50 @@
1
1
  QuizGenerator/__init__.py,sha256=8EV-k90A3PNC8Cm2-ZquwNyVyvnwW1gs6u-nGictyhs,840
2
2
  QuizGenerator/__main__.py,sha256=Dd9w4R0Unm3RiXztvR4Y_g9-lkWp6FHg-4VN50JbKxU,151
3
3
  QuizGenerator/constants.py,sha256=AO-UWwsWPLb1k2JW6KP8rl9fxTcdT0rW-6XC6zfnDOs,4386
4
- QuizGenerator/contentast.py,sha256=8i7iF3cxcYbrVkpK89WdwhNtH4Bo25_rqDCxrSc0z8s,86281
5
- QuizGenerator/generate.py,sha256=AWzNL0QTYDTcJFKaYfHIoRHvhx9MYRAbsD6z7E5_c9k,15733
4
+ QuizGenerator/contentast.py,sha256=6eqhgjAGrkFQUoEOnnEuGIyllGnNC4354aP8IvnGCx4,86316
5
+ QuizGenerator/generate.py,sha256=dqF-WWmWxyJmPHl0gTYr3gNNxyF877fvXYaMvYA3uA8,15790
6
6
  QuizGenerator/misc.py,sha256=MXrguUhhdrWSV4Hqdl4G21ktowODu1AcKy6-5mvy3aI,454
7
- QuizGenerator/mixins.py,sha256=aFn2573APCh-XKn6U7Xy95Iyj1a-BsRXnorjpN1FT6E,18711
7
+ QuizGenerator/mixins.py,sha256=B9Ee52wUCeclmBTgonasHNo0WHvVOcnILsz0iecrf78,15705
8
8
  QuizGenerator/performance.py,sha256=CM3zLarJXN5Hfrl4-6JRBqD03j4BU1B2QW699HAr1Ds,7002
9
9
  QuizGenerator/qrcode_generator.py,sha256=S3mzZDk2UiHiw6ipSCpWPMhbKvSRR1P5ordZJUTo6ug,10776
10
- QuizGenerator/question.py,sha256=CqKq_-HDzETrgEr-E8fQu1sRiMZv6ZoBAjig6gy34vw,31395
11
- QuizGenerator/quiz.py,sha256=4W_3xZMLx-pMzB5mn8GOhbmE-7bYiIqYLtsVYxJSdVc,21463
12
- QuizGenerator/regenerate.py,sha256=q8fGecZXx_sMUEpaMMmS8Zp3QW_m63WE9_5g6IKtKUk,19520
10
+ QuizGenerator/question.py,sha256=cfhCViOSI4p7rcQHE2igv1-aWZgyEKU6rUqJ25VHkfU,32304
11
+ QuizGenerator/quiz.py,sha256=CEWy7FB7BZiK33s_wYs6MqGKDetc6htUaqvP3--2HzI,21621
12
+ QuizGenerator/regenerate.py,sha256=ZAs1mtERmO8JXza2tBqJpd-uJs9V7gS1jJ9A9gSb8jo,19764
13
13
  QuizGenerator/typst_utils.py,sha256=JGQn_u5bEHd8HAtjAHuZoVJwLkx-Rd4ZCBWffwFZa3o,3136
14
14
  QuizGenerator/canvas/__init__.py,sha256=TwFP_zgxPIlWtkvIqQ6mcvBNTL9swIH_rJl7DGKcvkQ,286
15
15
  QuizGenerator/canvas/canvas_interface.py,sha256=StMcdXgLvTA1EayQ44m_le2GXGQpDQnduYXVeUYsqW0,24618
16
16
  QuizGenerator/canvas/classes.py,sha256=v_tQ8t_JJplU9sv2p4YctX45Fwed1nQ2HC1oC9BnDNw,7594
17
17
  QuizGenerator/premade_questions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- QuizGenerator/premade_questions/basic.py,sha256=hZCZHZxyTAQSDr-Hwo3xIMlU3L0-tyzfEZqvz7B-P64,3317
18
+ QuizGenerator/premade_questions/basic.py,sha256=F_Qsu14b2xERyibCAMP1NPgnmi1h2G2DDkKJoU_RS8g,3284
19
19
  QuizGenerator/premade_questions/cst334/__init__.py,sha256=BTz-Os1XbwIRKqAilf2UIva2NlY0DbA_XbSIggO2Tdk,36
20
- QuizGenerator/premade_questions/cst334/languages.py,sha256=t4LEfVeJei0xqOHjUb9vV4yG1Oyp-LE-wmF4AY_oMbk,14909
21
- QuizGenerator/premade_questions/cst334/math_questions.py,sha256=TW4VR6kmcYC8qMOn5vNwe1_7OCUKjPeOqJbwoKOWZ-s,9930
22
- QuizGenerator/premade_questions/cst334/memory_questions.py,sha256=S_Fndsq-RqWoFeIuKmMmCrdO7R1dFeQ0HrGWu93RRiE,53749
20
+ QuizGenerator/premade_questions/cst334/languages.py,sha256=ctemEAMkI8C6ASMIf59EHAW1ndFWi7hXzdEt-zOByUE,14114
21
+ QuizGenerator/premade_questions/cst334/math_questions.py,sha256=aUYbQxneL5MXE7Xo3tZX9-xcg71CXwvG3rrxcoh0l7A,8638
22
+ QuizGenerator/premade_questions/cst334/memory_questions.py,sha256=g0EFJ2HUogYnOYMWYyn-z4lEv15Pfv5IdSvj0xGoKbI,51050
23
23
  QuizGenerator/premade_questions/cst334/ostep13_vsfs.py,sha256=d9jjrynEw44vupAH_wKl57UoHooCNEJXaC5DoNYualk,16163
24
- QuizGenerator/premade_questions/cst334/persistence_questions.py,sha256=eyCIwfy3pmSm-XEwIV-7i9uU0-kZcuq1D0Apm0m2SfA,17163
25
- QuizGenerator/premade_questions/cst334/process.py,sha256=YrtrLZA8Uk63adpD2WOuXyIaJsFKoO5xZ0yYDzMFWqs,39593
24
+ QuizGenerator/premade_questions/cst334/persistence_questions.py,sha256=9mgsX-3oWDQgm_n2YwmFSil0QPyzsruHzuqB-hfGMuA,16220
25
+ QuizGenerator/premade_questions/cst334/process.py,sha256=J9sk-tXeuCDFk2hHm_h9XJE40avacQWPNGf92yp4EjA,37682
26
26
  QuizGenerator/premade_questions/cst463/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  QuizGenerator/premade_questions/cst463/gradient_descent/__init__.py,sha256=sH2CUV6zK9FT3jWTn453ys6_JTrUKRtZnU8hK6RmImU,240
28
- QuizGenerator/premade_questions/cst463/gradient_descent/gradient_calculation.py,sha256=6TzPi-NMI5CILcd3gbzRpEs3T_280SzA1kauTZMXC_g,13607
29
- QuizGenerator/premade_questions/cst463/gradient_descent/gradient_descent_questions.py,sha256=fEpYB4jFOJfyDdli0oh-zpsarC_w8fIGZBOXCkMOIGQ,10604
30
- QuizGenerator/premade_questions/cst463/gradient_descent/loss_calculations.py,sha256=Tq_-EVaVmuVz6-V9Wbcp-oIlc2BJ5ehN4MdCx8G_Dk4,21824
28
+ QuizGenerator/premade_questions/cst463/gradient_descent/gradient_calculation.py,sha256=laBeC0tMc2EaLzCotGHQNzePPPOKS1EGgQirigNyi9M,13479
29
+ QuizGenerator/premade_questions/cst463/gradient_descent/gradient_descent_questions.py,sha256=_2HlC0sqfGy__Qyzbw0PwMD_OkQiiQukl72LQFyPYx0,10939
30
+ QuizGenerator/premade_questions/cst463/gradient_descent/loss_calculations.py,sha256=8GtJX1DNNox-AgMvABFkRgmHB-lvrxMZKzv-3Ils_Jg,22380
31
31
  QuizGenerator/premade_questions/cst463/gradient_descent/misc.py,sha256=0R-nFeD3zsqJyde5CXWrF6Npjmpx6_HbzfCbThLi3os,2657
32
32
  QuizGenerator/premade_questions/cst463/math_and_data/__init__.py,sha256=EbIaUrx7_aK9j3Gd8Mk08h9GocTq_0OoNu2trfNwaU8,202
33
- QuizGenerator/premade_questions/cst463/math_and_data/matrix_questions.py,sha256=_oODuW4WMEVLuEJFmVjMWYTZn3RiE2MqlJSEIwRXNMo,28740
34
- QuizGenerator/premade_questions/cst463/math_and_data/vector_questions.py,sha256=nNu4Pqvy-zXO2Ly9UtqXIbx-gw2fUC40yii-PhuK-_c,12927
33
+ QuizGenerator/premade_questions/cst463/math_and_data/matrix_questions.py,sha256=4HsMflR1Fm-yjD0J3iW057_q3UHDRiW-swzOd5D73Ys,15647
34
+ QuizGenerator/premade_questions/cst463/math_and_data/vector_questions.py,sha256=VXQCLQEeNKxRDPn_fGW5nAPX-0betrZ8mURh0ElbNz0,12668
35
35
  QuizGenerator/premade_questions/cst463/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
- QuizGenerator/premade_questions/cst463/models/attention.py,sha256=i49u_bTbc_x0uLkmO-w7zQtLeoBpejVd78opVUnP9sg,5803
37
- QuizGenerator/premade_questions/cst463/models/cnns.py,sha256=yFqZJ-sKInGaFButUEuYiRRZkALqx8Tpv8I-fTfvQcU,6109
38
- QuizGenerator/premade_questions/cst463/models/matrices.py,sha256=H61_8cF1DGCt4Z4Ssoi4SMClf6tD5wHkOqY5bMdsSt4,699
39
- QuizGenerator/premade_questions/cst463/models/rnns.py,sha256=CXoXHMNIhJRD2MEZ0WNemTKQLQRV7ahTnGVRjOe77vU,6903
40
- QuizGenerator/premade_questions/cst463/models/text.py,sha256=vf9Lp9dvYs4Eok_ljt5MEw94O7YdhpP0JaDfDaPL0Vs,6705
41
- QuizGenerator/premade_questions/cst463/models/weight_counting.py,sha256=wz63jKluW3sFYOWUePgtcNQVpFJykyG3BxJzt0djrvY,7133
36
+ QuizGenerator/premade_questions/cst463/models/attention.py,sha256=iECxOoR0LEJAH_d7ZE3MoLOkdYVbGOKo4Dwf8Pww0tM,5443
37
+ QuizGenerator/premade_questions/cst463/models/cnns.py,sha256=_HSjgClNBBid5t52CDQfPUMdKOHFOXjy7VQ3sW-zW-Y,6030
38
+ QuizGenerator/premade_questions/cst463/models/matrices.py,sha256=21eNXUcIjFNZTGH18oH-x3MbCa4buNGQGer3a5yL85c,1938
39
+ QuizGenerator/premade_questions/cst463/models/rnns.py,sha256=5fKQuWnpSAoznZVJuCY4nICQ5KzB04Cz17hpccYiiVc,6673
40
+ QuizGenerator/premade_questions/cst463/models/text.py,sha256=BnW6qIB8pnQiFRyXxtX9cdsIfmjw99p6TI0WqI0AQzk,6605
41
+ QuizGenerator/premade_questions/cst463/models/weight_counting.py,sha256=sFnEvSs7ZwR4RZPltiMEElKJgoxHTaY427_g8Abi2uk,6912
42
42
  QuizGenerator/premade_questions/cst463/neural-network-basics/__init__.py,sha256=pmyCezO-20AFEQC6MR7KnAsaU9TcgZYsGQOMVkRZ-U8,149
43
- QuizGenerator/premade_questions/cst463/neural-network-basics/neural_network_questions.py,sha256=LTsUZqdP5zdG8VB10u5FYkQMm2Q1wvlaFAOOVQQesmg,45176
43
+ QuizGenerator/premade_questions/cst463/neural-network-basics/neural_network_questions.py,sha256=bit_HfAG4K6yh9SZZw_HAPhFUVFkOBdZ2odwt-Cdvmo,42868
44
44
  QuizGenerator/premade_questions/cst463/tensorflow-intro/__init__.py,sha256=G1gEHtG4KakYgi8ZXSYYhX6bQRtnm2tZVGx36d63Nmo,173
45
- QuizGenerator/premade_questions/cst463/tensorflow-intro/tensorflow_questions.py,sha256=KcYSDQQfbZcwNJQrBbcAmqIp69pYro8bJAWa1djDGsE,32263
46
- quizgenerator-0.7.1.dist-info/METADATA,sha256=OvjwBmgGzYvr9VhlQ2zgi-UzKdCY7qRn-h6VjmZZ4r4,7212
47
- quizgenerator-0.7.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
48
- quizgenerator-0.7.1.dist-info/entry_points.txt,sha256=aOIdRdw26xY8HkxOoKHBnUPe2mwGv5Ti3U1zojb6zxQ,98
49
- quizgenerator-0.7.1.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
50
- quizgenerator-0.7.1.dist-info/RECORD,,
45
+ QuizGenerator/premade_questions/cst463/tensorflow-intro/tensorflow_questions.py,sha256=jZRbEqb65BAtliv_V9VR4kvpwOt-o10ApN7RmOIg3XI,30464
46
+ quizgenerator-0.8.0.dist-info/METADATA,sha256=W3Cb-jkrgfxtWGBJ7zynREY_q-_3q53rKpQ0eFC9OCw,8113
47
+ quizgenerator-0.8.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
48
+ quizgenerator-0.8.0.dist-info/entry_points.txt,sha256=aOIdRdw26xY8HkxOoKHBnUPe2mwGv5Ti3U1zojb6zxQ,98
49
+ quizgenerator-0.8.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
50
+ quizgenerator-0.8.0.dist-info/RECORD,,