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.
- QuizGenerator/contentast.py +809 -117
- QuizGenerator/generate.py +219 -11
- QuizGenerator/misc.py +0 -556
- QuizGenerator/mixins.py +50 -29
- QuizGenerator/premade_questions/basic.py +3 -3
- QuizGenerator/premade_questions/cst334/languages.py +183 -175
- QuizGenerator/premade_questions/cst334/math_questions.py +81 -70
- QuizGenerator/premade_questions/cst334/memory_questions.py +262 -165
- QuizGenerator/premade_questions/cst334/persistence_questions.py +83 -60
- QuizGenerator/premade_questions/cst334/process.py +558 -79
- QuizGenerator/premade_questions/cst463/gradient_descent/gradient_calculation.py +39 -13
- QuizGenerator/premade_questions/cst463/gradient_descent/gradient_descent_questions.py +61 -36
- QuizGenerator/premade_questions/cst463/gradient_descent/loss_calculations.py +29 -10
- QuizGenerator/premade_questions/cst463/gradient_descent/misc.py +2 -2
- QuizGenerator/premade_questions/cst463/math_and_data/matrix_questions.py +60 -43
- QuizGenerator/premade_questions/cst463/math_and_data/vector_questions.py +173 -326
- QuizGenerator/premade_questions/cst463/models/attention.py +29 -14
- QuizGenerator/premade_questions/cst463/models/cnns.py +32 -20
- QuizGenerator/premade_questions/cst463/models/rnns.py +28 -15
- QuizGenerator/premade_questions/cst463/models/text.py +29 -15
- QuizGenerator/premade_questions/cst463/models/weight_counting.py +38 -30
- QuizGenerator/premade_questions/cst463/neural-network-basics/neural_network_questions.py +91 -111
- QuizGenerator/premade_questions/cst463/tensorflow-intro/tensorflow_questions.py +128 -55
- QuizGenerator/question.py +114 -20
- QuizGenerator/quiz.py +81 -24
- QuizGenerator/regenerate.py +98 -29
- {quizgenerator-0.4.2.dist-info → quizgenerator-0.6.0.dist-info}/METADATA +1 -1
- {quizgenerator-0.4.2.dist-info → quizgenerator-0.6.0.dist-info}/RECORD +31 -33
- QuizGenerator/README.md +0 -5
- QuizGenerator/logging.yaml +0 -55
- {quizgenerator-0.4.2.dist-info → quizgenerator-0.6.0.dist-info}/WHEEL +0 -0
- {quizgenerator-0.4.2.dist-info → quizgenerator-0.6.0.dist-info}/entry_points.txt +0 -0
- {quizgenerator-0.4.2.dist-info → quizgenerator-0.6.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import abc
|
|
3
3
|
import logging
|
|
4
4
|
|
|
5
|
-
from QuizGenerator.question import Question, QuestionRegistry
|
|
6
|
-
from QuizGenerator.contentast import ContentAST
|
|
5
|
+
from QuizGenerator.question import Question, QuestionRegistry
|
|
6
|
+
from QuizGenerator.contentast import ContentAST, AnswerTypes
|
|
7
7
|
from QuizGenerator.mixins import MathOperationQuestion
|
|
8
8
|
|
|
9
9
|
log = logging.getLogger(__name__)
|
|
@@ -21,7 +21,7 @@ class MatrixMathQuestion(MathOperationQuestion, Question):
|
|
|
21
21
|
- ContentAST.Matrix for mathematical matrices
|
|
22
22
|
- ContentAST.Equation.make_block_equation__multiline_equals for step-by-step solutions
|
|
23
23
|
- ContentAST.OnlyHtml for Canvas-specific content
|
|
24
|
-
- Answer.integer for numerical answers
|
|
24
|
+
- ContentAST.Answer.integer for numerical answers
|
|
25
25
|
"""
|
|
26
26
|
def __init__(self, *args, **kwargs):
|
|
27
27
|
kwargs["topic"] = kwargs.get("topic", Question.Topic.MATH)
|
|
@@ -36,15 +36,22 @@ class MatrixMathQuestion(MathOperationQuestion, Question):
|
|
|
36
36
|
return [[f"{prefix}{matrix[i][j]}" for j in range(len(matrix[0]))] for i in range(len(matrix))]
|
|
37
37
|
|
|
38
38
|
def _create_answer_table(self, rows, cols, answers_dict, answer_prefix="answer"):
|
|
39
|
-
"""Create a table with answer blanks for matrix results.
|
|
39
|
+
"""Create a table with answer blanks for matrix results.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
Tuple of (table, answers_list)
|
|
43
|
+
"""
|
|
40
44
|
table_data = []
|
|
45
|
+
answers = []
|
|
41
46
|
for i in range(rows):
|
|
42
47
|
row = []
|
|
43
48
|
for j in range(cols):
|
|
44
49
|
answer_key = f"{answer_prefix}_{i}_{j}"
|
|
45
|
-
|
|
50
|
+
ans = answers_dict[answer_key]
|
|
51
|
+
row.append(ans)
|
|
52
|
+
answers.append(ans)
|
|
46
53
|
table_data.append(row)
|
|
47
|
-
return ContentAST.Table(data=table_data, padding=True)
|
|
54
|
+
return ContentAST.Table(data=table_data, padding=True), answers
|
|
48
55
|
|
|
49
56
|
# Implement MathOperationQuestion abstract methods
|
|
50
57
|
|
|
@@ -64,23 +71,23 @@ class MatrixMathQuestion(MathOperationQuestion, Question):
|
|
|
64
71
|
return f"{operand_a_latex} {self.get_operator()} {operand_b_latex}"
|
|
65
72
|
|
|
66
73
|
def _add_single_question_answers(self, body):
|
|
67
|
-
"""Add Canvas-only answer fields for single questions.
|
|
74
|
+
"""Add Canvas-only answer fields for single questions.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
List of Answer objects that were added to the body.
|
|
78
|
+
"""
|
|
79
|
+
answers = []
|
|
80
|
+
|
|
68
81
|
# For matrices, we typically show result dimensions and answer table
|
|
69
82
|
if hasattr(self, 'result_rows') and hasattr(self, 'result_cols'):
|
|
70
83
|
# Matrix multiplication case with dimension answers
|
|
71
84
|
if hasattr(self, 'answers') and "result_rows" in self.answers:
|
|
85
|
+
rows_ans = self.answers["result_rows"]
|
|
86
|
+
cols_ans = self.answers["result_cols"]
|
|
87
|
+
answers.extend([rows_ans, cols_ans])
|
|
72
88
|
body.add_element(
|
|
73
89
|
ContentAST.OnlyHtml([
|
|
74
|
-
ContentAST.AnswerBlock([
|
|
75
|
-
ContentAST.Answer(
|
|
76
|
-
answer=self.answers["result_rows"],
|
|
77
|
-
label="Number of rows in result"
|
|
78
|
-
),
|
|
79
|
-
ContentAST.Answer(
|
|
80
|
-
answer=self.answers["result_cols"],
|
|
81
|
-
label="Number of columns in result"
|
|
82
|
-
)
|
|
83
|
-
])
|
|
90
|
+
ContentAST.AnswerBlock([rows_ans, cols_ans])
|
|
84
91
|
])
|
|
85
92
|
)
|
|
86
93
|
|
|
@@ -88,21 +95,27 @@ class MatrixMathQuestion(MathOperationQuestion, Question):
|
|
|
88
95
|
if hasattr(self, 'result') and self.result:
|
|
89
96
|
rows = len(self.result)
|
|
90
97
|
cols = len(self.result[0])
|
|
98
|
+
table, table_answers = self._create_answer_table(rows, cols, self.answers)
|
|
99
|
+
answers.extend(table_answers)
|
|
91
100
|
body.add_element(
|
|
92
101
|
ContentAST.OnlyHtml([
|
|
93
102
|
ContentAST.Paragraph(["Result matrix:"]),
|
|
94
|
-
|
|
103
|
+
table
|
|
95
104
|
])
|
|
96
105
|
)
|
|
97
106
|
elif hasattr(self, 'max_dim'):
|
|
98
107
|
# Matrix multiplication with max dimensions
|
|
108
|
+
table, table_answers = self._create_answer_table(self.max_dim, self.max_dim, self.answers)
|
|
109
|
+
answers.extend(table_answers)
|
|
99
110
|
body.add_element(
|
|
100
111
|
ContentAST.OnlyHtml([
|
|
101
112
|
ContentAST.Paragraph(["Result matrix (use '-' if cell doesn't exist):"]),
|
|
102
|
-
|
|
113
|
+
table
|
|
103
114
|
])
|
|
104
115
|
)
|
|
105
116
|
|
|
117
|
+
return answers
|
|
118
|
+
|
|
106
119
|
# Abstract methods that subclasses must implement
|
|
107
120
|
@abc.abstractmethod
|
|
108
121
|
def get_operator(self):
|
|
@@ -156,7 +169,7 @@ class MatrixAddition(MatrixMathQuestion):
|
|
|
156
169
|
for i in range(rows):
|
|
157
170
|
for j in range(cols):
|
|
158
171
|
answer_key = f"answer_{i}_{j}"
|
|
159
|
-
self.answers[answer_key] =
|
|
172
|
+
self.answers[answer_key] = AnswerTypes.Int(result[i][j])
|
|
160
173
|
else:
|
|
161
174
|
# For multipart questions, use subpart letter format
|
|
162
175
|
letter = chr(ord('a') + subpart_index)
|
|
@@ -165,7 +178,7 @@ class MatrixAddition(MatrixMathQuestion):
|
|
|
165
178
|
for i in range(rows):
|
|
166
179
|
for j in range(cols):
|
|
167
180
|
answer_key = f"subpart_{letter}_{i}_{j}"
|
|
168
|
-
self.answers[answer_key] =
|
|
181
|
+
self.answers[answer_key] = AnswerTypes.Int(result[i][j])
|
|
169
182
|
|
|
170
183
|
def refresh(self, *args, **kwargs):
|
|
171
184
|
"""Override refresh to set rows/cols for compatibility."""
|
|
@@ -286,7 +299,7 @@ class MatrixScalarMultiplication(MatrixMathQuestion):
|
|
|
286
299
|
for i in range(rows):
|
|
287
300
|
for j in range(cols):
|
|
288
301
|
answer_key = f"answer_{i}_{j}"
|
|
289
|
-
self.answers[answer_key] =
|
|
302
|
+
self.answers[answer_key] = AnswerTypes.Int(result[i][j])
|
|
290
303
|
else:
|
|
291
304
|
# For multipart questions, use subpart letter format
|
|
292
305
|
letter = chr(ord('a') + subpart_index)
|
|
@@ -295,7 +308,7 @@ class MatrixScalarMultiplication(MatrixMathQuestion):
|
|
|
295
308
|
for i in range(rows):
|
|
296
309
|
for j in range(cols):
|
|
297
310
|
answer_key = f"subpart_{letter}_{i}_{j}"
|
|
298
|
-
self.answers[answer_key] =
|
|
311
|
+
self.answers[answer_key] = AnswerTypes.Int(result[i][j])
|
|
299
312
|
|
|
300
313
|
def refresh(self, *args, **kwargs):
|
|
301
314
|
"""Override refresh to handle different scalars per subpart."""
|
|
@@ -488,27 +501,27 @@ class MatrixMultiplication(MatrixMathQuestion):
|
|
|
488
501
|
# For single questions, use the old answer format
|
|
489
502
|
# Dimension answers
|
|
490
503
|
if result is not None:
|
|
491
|
-
self.answers["result_rows"] =
|
|
492
|
-
self.answers["result_cols"] =
|
|
504
|
+
self.answers["result_rows"] = AnswerTypes.Int(self.result_rows, label="Number of rows in result")
|
|
505
|
+
self.answers["result_cols"] = AnswerTypes.Int(self.result_cols, label="Number of columns in result")
|
|
493
506
|
|
|
494
507
|
# Matrix element answers
|
|
495
508
|
for i in range(self.max_dim):
|
|
496
509
|
for j in range(self.max_dim):
|
|
497
510
|
answer_key = f"answer_{i}_{j}"
|
|
498
511
|
if i < self.result_rows and j < self.result_cols:
|
|
499
|
-
self.answers[answer_key] =
|
|
512
|
+
self.answers[answer_key] = AnswerTypes.Int(result[i][j])
|
|
500
513
|
else:
|
|
501
|
-
self.answers[answer_key] =
|
|
514
|
+
self.answers[answer_key] = AnswerTypes.String("-")
|
|
502
515
|
else:
|
|
503
516
|
# Multiplication not possible
|
|
504
|
-
self.answers["result_rows"] =
|
|
505
|
-
self.answers["result_cols"] =
|
|
517
|
+
self.answers["result_rows"] = AnswerTypes.String("-", label="Number of rows in result")
|
|
518
|
+
self.answers["result_cols"] = AnswerTypes.String("-", label="Number of columns in result")
|
|
506
519
|
|
|
507
520
|
# All matrix elements are "-"
|
|
508
521
|
for i in range(self.max_dim):
|
|
509
522
|
for j in range(self.max_dim):
|
|
510
523
|
answer_key = f"answer_{i}_{j}"
|
|
511
|
-
self.answers[answer_key] =
|
|
524
|
+
self.answers[answer_key] = AnswerTypes.String("-")
|
|
512
525
|
else:
|
|
513
526
|
# For multipart questions, use subpart letter format
|
|
514
527
|
letter = chr(ord('a') + subpart_index)
|
|
@@ -520,35 +533,39 @@ class MatrixMultiplication(MatrixMathQuestion):
|
|
|
520
533
|
for i in range(rows):
|
|
521
534
|
for j in range(cols):
|
|
522
535
|
answer_key = f"subpart_{letter}_{i}_{j}"
|
|
523
|
-
self.answers[answer_key] =
|
|
536
|
+
self.answers[answer_key] = AnswerTypes.Int(result[i][j])
|
|
524
537
|
|
|
525
538
|
def _add_single_question_answers(self, body):
|
|
526
|
-
"""Add Canvas-only answer fields for MatrixMultiplication with dash instruction.
|
|
539
|
+
"""Add Canvas-only answer fields for MatrixMultiplication with dash instruction.
|
|
540
|
+
|
|
541
|
+
Returns:
|
|
542
|
+
List of Answer objects that were added to the body.
|
|
543
|
+
"""
|
|
544
|
+
answers = []
|
|
545
|
+
|
|
527
546
|
# Dimension answers for matrix multiplication
|
|
528
547
|
if hasattr(self, 'answers') and "result_rows" in self.answers:
|
|
548
|
+
rows_ans = self.answers["result_rows"]
|
|
549
|
+
cols_ans = self.answers["result_cols"]
|
|
550
|
+
answers.extend([rows_ans, cols_ans])
|
|
529
551
|
body.add_element(
|
|
530
552
|
ContentAST.OnlyHtml([
|
|
531
|
-
ContentAST.AnswerBlock([
|
|
532
|
-
ContentAST.Answer(
|
|
533
|
-
answer=self.answers["result_rows"],
|
|
534
|
-
label="Number of rows in result"
|
|
535
|
-
),
|
|
536
|
-
ContentAST.Answer(
|
|
537
|
-
answer=self.answers["result_cols"],
|
|
538
|
-
label="Number of columns in result"
|
|
539
|
-
)
|
|
540
|
-
])
|
|
553
|
+
ContentAST.AnswerBlock([rows_ans, cols_ans])
|
|
541
554
|
])
|
|
542
555
|
)
|
|
543
556
|
|
|
544
557
|
# Matrix result table with dash instruction
|
|
558
|
+
table, table_answers = self._create_answer_table(self.max_dim, self.max_dim, self.answers)
|
|
559
|
+
answers.extend(table_answers)
|
|
545
560
|
body.add_element(
|
|
546
561
|
ContentAST.OnlyHtml([
|
|
547
562
|
ContentAST.Paragraph(["Result matrix (use '-' if cell doesn't exist):"]),
|
|
548
|
-
|
|
563
|
+
table
|
|
549
564
|
])
|
|
550
565
|
)
|
|
551
566
|
|
|
567
|
+
return answers
|
|
568
|
+
|
|
552
569
|
def refresh(self, *args, **kwargs):
|
|
553
570
|
"""Override refresh to handle matrix attributes."""
|
|
554
571
|
super().refresh(*args, **kwargs)
|