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
@@ -3,8 +3,8 @@ import abc
3
3
  import logging
4
4
  import math
5
5
 
6
- from QuizGenerator.question import Question, QuestionRegistry, Answer
7
- from QuizGenerator.contentast import ContentAST
6
+ from QuizGenerator.question import Question, QuestionRegistry
7
+ from QuizGenerator.contentast import ContentAST, AnswerTypes
8
8
  from QuizGenerator.constants import MathRanges
9
9
 
10
10
  log = logging.getLogger(__name__)
@@ -31,11 +31,16 @@ class BitsAndBytes(MathQuestion):
31
31
  self.num_bytes = int(math.pow(2, self.num_bits))
32
32
 
33
33
  if self.from_binary:
34
- self.answers = {"answer" : Answer.integer("num_bytes", self.num_bytes)}
34
+ self.answers = {"answer": AnswerTypes.Int(self.num_bytes,
35
+ label="Address space size", unit="Bytes")}
35
36
  else:
36
- self.answers = {"answer" : Answer.integer("num_bits", self.num_bits)}
37
+ self.answers = {"answer": AnswerTypes.Int(self.num_bits,
38
+ label="Number of bits in address", unit="bits")}
37
39
 
38
- def get_body(self, **kwargs) -> ContentAST.Section:
40
+ def _get_body(self, **kwargs):
41
+ """Build question body and collect answers."""
42
+ answers = [self.answers['answer']]
43
+
39
44
  body = ContentAST.Section()
40
45
  body.add_element(
41
46
  ContentAST.Paragraph([
@@ -45,31 +50,17 @@ class BitsAndBytes(MathQuestion):
45
50
  f"{'do we need to address our memory' if not self.from_binary else 'of memory can be addressed'}?"
46
51
  ])
47
52
  )
48
-
49
- if self.from_binary:
50
- body.add_element(
51
- ContentAST.AnswerBlock(
52
- ContentAST.Answer(
53
- answer=self.answers['answer'],
54
- label="Address space size",
55
- unit="Bytes"
56
- ),
57
- )
58
- )
59
- else:
60
- body.add_element(
61
- ContentAST.AnswerBlock(
62
- ContentAST.Answer(
63
- answer=self.answers['answer'],
64
- label="Number of bits in address",
65
- unit="bits"
66
- ),
67
- )
68
- )
69
-
53
+
54
+ body.add_element(ContentAST.AnswerBlock(self.answers['answer']))
55
+
56
+ return body, answers
57
+
58
+ def get_body(self, **kwargs) -> ContentAST.Section:
59
+ """Build question body (backward compatible interface)."""
60
+ body, _ = self._get_body(**kwargs)
70
61
  return body
71
-
72
- def get_explanation(self, **kwargs) -> ContentAST.Section:
62
+
63
+ def _get_explanation(self, **kwargs):
73
64
  explanation = ContentAST.Section()
74
65
 
75
66
  explanation.add_element(
@@ -94,7 +85,12 @@ class BitsAndBytes(MathQuestion):
94
85
  explanation.add_element(
95
86
  ContentAST.Equation(f"log_{{2}}({self.num_bytes} \\text{{bytes}}) = \\textbf{{{self.num_bits}}}\\text{{bits}}")
96
87
  )
97
-
88
+
89
+ return explanation, []
90
+
91
+ def get_explanation(self, **kwargs) -> ContentAST.Section:
92
+ """Build question explanation (backward compatible interface)."""
93
+ explanation, _ = self._get_explanation(**kwargs)
98
94
  return explanation
99
95
 
100
96
 
@@ -115,13 +111,18 @@ class HexAndBinary(MathQuestion):
115
111
  self.binary_val = f"0b{self.value:0{4*self.number_of_hexits}b}"
116
112
 
117
113
  if self.from_binary:
118
- self.answers['answer'] = Answer.string("hex_val", self.hex_val)
114
+ self.answers['answer'] = AnswerTypes.String(self.hex_val,
115
+ label="Value in hex")
119
116
  else:
120
- self.answers['answer'] = Answer.string("binary_val", self.binary_val)
117
+ self.answers['answer'] = AnswerTypes.String(self.binary_val,
118
+ label="Value in binary")
121
119
 
122
- def get_body(self, **kwargs) -> ContentAST.Section:
120
+ def _get_body(self, **kwargs):
121
+ """Build question body and collect answers."""
122
+ answers = [self.answers['answer']]
123
+
123
124
  body = ContentAST.Section()
124
-
125
+
125
126
  body.add_element(
126
127
  ContentAST.Paragraph([
127
128
  f"Given the number {self.hex_val if not self.from_binary else self.binary_val} "
@@ -129,19 +130,17 @@ class HexAndBinary(MathQuestion):
129
130
  "Please include base indicator all padding zeros as appropriate (e.g. 0x01 should be 0b00000001)",
130
131
  ])
131
132
  )
132
-
133
- body.add_element(
134
- ContentAST.AnswerBlock([
135
- ContentAST.Answer(
136
- answer = self.answers['answer'],
137
- label=f"Value in {'hex' if self.from_binary else 'binary'}: ",
138
- )
139
- ])
140
- )
141
-
133
+
134
+ body.add_element(ContentAST.AnswerBlock(self.answers['answer']))
135
+
136
+ return body, answers
137
+
138
+ def get_body(self, **kwargs) -> ContentAST.Section:
139
+ """Build question body (backward compatible interface)."""
140
+ body, _ = self._get_body(**kwargs)
142
141
  return body
143
-
144
- def get_explanation(self, **kwargs) -> ContentAST.Section:
142
+
143
+ def _get_explanation(self, **kwargs):
145
144
  explanation = ContentAST.Section()
146
145
 
147
146
  paragraph = ContentAST.Paragraph([
@@ -188,10 +187,15 @@ class HexAndBinary(MathQuestion):
188
187
  f"Which gives us our binary value of: 0b{binary_str}"
189
188
  ])
190
189
  )
191
-
190
+
191
+ return explanation, []
192
+
193
+ def get_explanation(self, **kwargs) -> ContentAST.Section:
194
+ """Build question explanation (backward compatible interface)."""
195
+ explanation, _ = self._get_explanation(**kwargs)
192
196
  return explanation
193
-
194
-
197
+
198
+
195
199
  @QuestionRegistry.register()
196
200
  class AverageMemoryAccessTime(MathQuestion):
197
201
 
@@ -219,7 +223,7 @@ class AverageMemoryAccessTime(MathQuestion):
219
223
  self.amat = self.hit_rate * self.hit_latency + (1 - self.hit_rate) * self.miss_latency
220
224
 
221
225
  self.answers = {
222
- "amat": Answer.float_value("answer__amat", self.amat)
226
+ "amat": AnswerTypes.Float(self.amat, label="Average Memory Access Time", unit="cycles")
223
227
  }
224
228
 
225
229
  # Finally, do the self.rngizing of the question, to avoid these being non-deterministic
@@ -228,15 +232,18 @@ class AverageMemoryAccessTime(MathQuestion):
228
232
  # At this point, everything in the question should be set.
229
233
  pass
230
234
 
231
- def get_body(self, **kwargs) -> ContentAST.Section:
235
+ def _get_body(self, **kwargs):
236
+ """Build question body and collect answers."""
237
+ answers = [self.answers["amat"]]
238
+
232
239
  body = ContentAST.Section()
233
-
240
+
234
241
  # Add in background information
235
242
  body.add_element(
236
243
  ContentAST.Paragraph([
237
244
  ContentAST.Text("Please calculate the Average Memory Access Time given the below information. "),
238
245
  ContentAST.Text(
239
- f"Please round your answer to {Answer.DEFAULT_ROUNDING_DIGITS} decimal points. ",
246
+ f"Please round your answer to {ContentAST.Answer.DEFAULT_ROUNDING_DIGITS} decimal points. ",
240
247
  hide_from_latex=True
241
248
  )
242
249
  ])
@@ -245,32 +252,31 @@ class AverageMemoryAccessTime(MathQuestion):
245
252
  ["Hit Latency", f"{self.hit_latency} cycles"],
246
253
  ["Miss Latency", f"{self.miss_latency} cycles"]
247
254
  ]
248
-
255
+
249
256
  # Add in either miss rate or hit rate -- we only need one of them
250
257
  if self.show_miss_rate:
251
258
  table_data.append(["Miss Rate", f"{100 * (1 - self.hit_rate): 0.2f}%"])
252
259
  else:
253
260
  table_data.append(["Hit Rate", f"{100 * self.hit_rate: 0.2f}%"])
254
-
261
+
255
262
  body.add_element(
256
263
  ContentAST.Table(
257
264
  data=table_data
258
265
  )
259
266
  )
260
-
261
- body.add_element(
262
- ContentAST.AnswerBlock([
263
- ContentAST.Answer(
264
- answer=self.answers["amat"],
265
- label="Average Memory Access Time",
266
- unit="cycles"
267
- )
268
- ])
269
- )
270
-
267
+
268
+ body.add_element(ContentAST.LineBreak())
269
+
270
+ body.add_element(ContentAST.AnswerBlock(self.answers["amat"]))
271
+
272
+ return body, answers
273
+
274
+ def get_body(self, **kwargs) -> ContentAST.Section:
275
+ """Build question body (backward compatible interface)."""
276
+ body, _ = self._get_body(**kwargs)
271
277
  return body
272
-
273
- def get_explanation(self, **kwargs) -> ContentAST.Section:
278
+
279
+ def _get_explanation(self, **kwargs):
274
280
  explanation = ContentAST.Section()
275
281
 
276
282
  # Add in General explanation
@@ -288,10 +294,15 @@ class AverageMemoryAccessTime(MathQuestion):
288
294
  lhs="AMAT",
289
295
  rhs=[
290
296
  r"(hit\_rate)*(hit\_cost) + (1 - hit\_rate)*(miss\_cost)",
291
- f"({self.hit_rate: 0.{Answer.DEFAULT_ROUNDING_DIGITS}f})*({self.hit_latency}) + ({1 - self.hit_rate: 0.{Answer.DEFAULT_ROUNDING_DIGITS}f})*({self.miss_latency}) = {self.amat: 0.{Answer.DEFAULT_ROUNDING_DIGITS}f}\\text{{cycles}}"
297
+ f"({self.hit_rate: 0.{ContentAST.Answer.DEFAULT_ROUNDING_DIGITS}f})*({self.hit_latency}) + ({1 - self.hit_rate: 0.{ContentAST.Answer.DEFAULT_ROUNDING_DIGITS}f})*({self.miss_latency}) = {self.amat: 0.{ContentAST.Answer.DEFAULT_ROUNDING_DIGITS}f}\\text{{cycles}}"
292
298
  ]
293
299
  )
294
300
  )
295
-
301
+
302
+ return explanation, []
303
+
304
+ def get_explanation(self, **kwargs) -> ContentAST.Section:
305
+ """Build question explanation (backward compatible interface)."""
306
+ explanation, _ = self._get_explanation(**kwargs)
296
307
  return explanation
297
308