Sina Media Lab commited on
Commit
d924141
·
1 Parent(s): 2a56f14

Add application file 3

Browse files
app.py CHANGED
@@ -1,242 +1,38 @@
1
  import streamlit as st
2
- import random
3
-
4
- # Module 1: Presentation in bases 2, 10, 8, and 16
5
- def generate_question_presentation_in_bases():
6
- num = random.randint(1, 20)
7
- base = random.choice([2, 8, 10, 16])
8
- if base == 2:
9
- representation = bin(num)[2:]
10
- elif base == 8:
11
- representation = oct(num)[2:]
12
- elif base == 16:
13
- representation = hex(num)[2:]
14
- else:
15
- representation = str(num)
16
-
17
- question = f"What is the representation of decimal number {num} in base {base}?"
18
- correct_answer = representation
19
- options = [correct_answer]
20
-
21
- # Generate incorrect options
22
- while len(options) < 10:
23
- fake_option = bin(random.randint(1, 20))[2:]
24
- if fake_option not in options:
25
- options.append(fake_option)
26
-
27
- random.shuffle(options)
28
- explanation = f"The number {num} in base {base} is represented as {representation}."
29
- return question, options, correct_answer, explanation
30
-
31
- # Module 2: Valid or invalid numbers in each base
32
- def generate_question_valid_or_invalid_numbers():
33
- base = random.choice([2, 8, 10, 16])
34
- length = random.randint(3, 5)
35
-
36
- def generate_valid_number():
37
- return ''.join([str(random.randint(0, base - 1)) for _ in range(length)])
38
-
39
- def generate_invalid_number():
40
- valid_digits = ''.join([str(random.randint(0, base - 1)) for _ in range(length - 1)])
41
- invalid_digit = str(random.randint(base, 9))
42
- return valid_digits + invalid_digit
43
-
44
- correct_answer = generate_invalid_number()
45
- options = [correct_answer]
46
-
47
- # Generate valid options
48
- while len(options) < 10:
49
- valid_option = generate_valid_number()
50
- if valid_option not in options:
51
- options.append(valid_option)
52
-
53
- random.shuffle(options)
54
- question = f"Which of the following is an invalid number in base {base}?"
55
- explanation = f"The number {correct_answer} is invalid in base {base} because it contains a digit outside the range 0-{base-1}."
56
- return question, options, correct_answer, explanation
57
-
58
- # Module 3: Conversion with and without fractions among four bases of 10, 2, 8, and 16
59
- def generate_question_conversion_bases():
60
- num = random.randint(1, 100)
61
- from_base = random.choice([2, 8, 10, 16])
62
- to_base = random.choice([2, 8, 10, 16])
63
-
64
- if from_base == 10:
65
- value = num
66
- elif from_base == 2:
67
- value = int(bin(num)[2:], 2)
68
- elif from_base == 8:
69
- value = int(oct(num)[2:], 8)
70
- else:
71
- value = int(hex(num)[2:], 16)
72
-
73
- if to_base == 2:
74
- correct_answer = bin(value)[2:]
75
- elif to_base == 8:
76
- correct_answer = oct(value)[2:]
77
- elif to_base == 16:
78
- correct_answer = hex(value)[2:]
79
- else:
80
- correct_answer = str(value)
81
-
82
- options = [correct_answer]
83
-
84
- # Generate incorrect options
85
- while len(options) < 10:
86
- fake_option = bin(random.randint(1, 100))[2:]
87
- if fake_option not in options:
88
- options.append(fake_option)
89
-
90
- random.shuffle(options)
91
- question = f"Convert {num} from base {from_base} to base {to_base}."
92
- explanation = f"The number {num} in base {from_base} is {correct_answer} in base {to_base}."
93
- return question, options, correct_answer, explanation
94
-
95
- # Module 4: Using grouping techniques for conversion between 2 and 8 and 16
96
- def generate_question_grouping_techniques():
97
- binary_num = bin(random.randint(1, 63))[2:]
98
- padded_binary = binary_num.zfill(len(binary_num) + (3 - len(binary_num) % 3) % 3)
99
-
100
- octal = ''.join([str(int(padded_binary[i:i+3], 2)) for i in range(0, len(padded_binary), 3)])
101
-
102
- question = f"Group the binary number {binary_num} into octal."
103
- correct_answer = octal
104
- options = [correct_answer]
105
-
106
- # Generate incorrect options
107
- while len(options) < 10:
108
- fake_option = ''.join([str(random.randint(0, 7)) for _ in range(len(octal))])
109
- if fake_option not in options:
110
- options.append(fake_option)
111
-
112
- random.shuffle(options)
113
- explanation = f"The binary number {binary_num} is grouped into octal as {octal}."
114
- return question, options, correct_answer, explanation
115
-
116
- # Module 5: Addition in base 2, 8, and 16
117
- def generate_question_addition_in_bases():
118
- base = random.choice([2, 8, 16])
119
- num1 = random.randint(1, 15)
120
- num2 = random.randint(1, 15)
121
-
122
- if base == 2:
123
- correct_answer = bin(num1 + num2)[2:]
124
- elif base == 8:
125
- correct_answer = oct(num1 + num2)[2:]
126
- else:
127
- correct_answer = hex(num1 + num2)[2:]
128
-
129
- question = f"Add {num1} and {num2} in base {base}."
130
- options = [correct_answer]
131
-
132
- # Generate incorrect options
133
- while len(options) < 10:
134
- fake_option = bin(random.randint(1, 30))[2:]
135
- if fake_option not in options:
136
- options.append(fake_option)
137
-
138
- random.shuffle(options)
139
- explanation = f"The sum of {num1} and {num2} in base {base} is {correct_answer}."
140
- return question, options, correct_answer, explanation
141
-
142
- # Module 6: 2's complement questions
143
- def generate_question_2s_complement():
144
- num = random.randint(-8, 7)
145
- bit_length = 4
146
- if num >= 0:
147
- binary = bin(num)[2:].zfill(bit_length)
148
- else:
149
- binary = bin((1 << bit_length) + num)[2:]
150
-
151
- question = f"What is the 2's complement representation of {num}?"
152
- correct_answer = binary
153
- options = [correct_answer]
154
-
155
- # Generate incorrect options
156
- while len(options) < 10:
157
- fake_option = bin(random.randint(-8, 7) & 0xF)[2:]
158
- if fake_option not in options:
159
- options.append(fake_option)
160
-
161
- random.shuffle(options)
162
- explanation = f"The 2's complement representation of {num} is {binary}."
163
- return question, options, correct_answer, explanation
164
-
165
- # Module 7: Negative binary numbers
166
- def generate_question_negative_binary_numbers():
167
- num = random.randint(-8, -1)
168
- bit_length = 4
169
- binary = bin((1 << bit_length) + num)[2:]
170
-
171
- question = f"What is the binary representation of {num} using 4 bits?"
172
- correct_answer = binary
173
- options = [correct_answer]
174
-
175
- # Generate incorrect options
176
- while len(options) < 10:
177
- fake_option = bin(random.randint(-8, -1) & 0xF)[2:]
178
- if fake_option not in options:
179
- options.append(fake_option)
180
-
181
- random.shuffle(options)
182
- explanation = f"The binary representation of {num} using 4 bits is {binary}."
183
- return question, options, correct_answer, explanation
184
-
185
- # Module 8: Subtraction in base 2 using 2's complement method
186
- def generate_question_subtraction_in_base_2():
187
- num1 = random.randint(1, 7)
188
- num2 = random.randint(1, 7)
189
-
190
- result = num1 - num2
191
- bit_length = 4
192
- if result >= 0:
193
- binary_result = bin(result)[2:].zfill(bit_length)
194
- else:
195
- binary_result = bin((1 << bit_length) + result)[2:]
196
-
197
- question = f"Subtract {num2} from {num1} in base 2 using 2's complement method."
198
- correct_answer = binary_result
199
- options = [correct_answer]
200
-
201
- # Generate incorrect options
202
- while len(options) < 10:
203
- fake_option = bin(random.randint(-7, 7) & 0xF)[2:]
204
- if fake_option not in options:
205
- options.append(fake_option)
206
-
207
- random.shuffle(options)
208
- explanation = f"The result of subtracting {num2} from {num1} in base 2 using 2's complement is {binary_result}."
209
- return question, options, correct_answer, explanation
210
-
211
- # Dictionary of modules
212
- modules = {
213
- "Presentation in bases 2, 10, 8, and 16": generate_question_presentation_in_bases,
214
- "Valid or invalid numbers in each base": generate_question_valid_or_invalid_numbers,
215
- "Conversion with and without fractions among four bases of 10, 2, 8, and 16": generate_question_conversion_bases,
216
- "Using grouping techniques for conversion between 2 and 8 and 16": generate_question_grouping_techniques,
217
- "Addition in base 2, 8, and 16": generate_question_addition_in_bases,
218
- "2's complement questions": generate_question_2s_complement,
219
- "Negative binary numbers": generate_question_negative_binary_numbers,
220
- "Subtraction in base 2 using 2's complement method": generate_question_subtraction_in_base_2,
221
  }
222
 
223
  # Streamlit interface
224
- st.title("Multiple Choice Quiz")
225
-
226
- module = st.radio("Choose a module:", list(modules.keys()))
227
-
228
- if module:
229
- generate_question = modules[module]
230
- question, options, correct_answer, explanation = generate_question()
231
-
232
- st.write(f"**Question:** {question}")
233
- answer = st.radio("Choose an answer:", options)
234
-
235
- if st.button("Submit"):
236
- if answer == correct_answer:
237
- st.success("Correct!")
238
- else:
239
- st.error("Incorrect.")
240
- st.write(f"**Explanation:** {explanation}")
241
-
242
- # The modular design allows for easy addition of new modules.
 
 
 
 
1
  import streamlit as st
2
+ import importlib
3
+
4
+ # List of available modules
5
+ module_names = {
6
+ "Presentation in bases 2, 10, 8, and 16": "presentation_bases",
7
+ "Valid or invalid numbers in each base": "valid_invalid_numbers",
8
+ "Conversion with and without fractions among four bases of 10, 2, 8, and 16": "conversion_bases",
9
+ "Using grouping techniques for conversion between 2 and 8 and 16": "grouping_techniques",
10
+ "Addition in base 2, 8, and 16": "addition_bases",
11
+ "2's complement questions": "twos_complement",
12
+ "Negative binary numbers": "negative_binary",
13
+ "Subtraction in base 2 using 2's complement method": "subtraction_bases",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  }
15
 
16
  # Streamlit interface
17
+ st.sidebar.title("Multiple Choice Quiz")
18
+ module_name = st.sidebar.radio("Choose a module:", list(module_names.keys()))
19
+
20
+ if module_name:
21
+ module_file = module_names[module_name]
22
+ try:
23
+ module = importlib.import_module(f'modules.{module_file}')
24
+ generate_question = module.generate_question
25
+ question, options, correct_answer, explanation = generate_question()
26
+
27
+ st.write(f"**Question:** {question}")
28
+ answer = st.radio("Choose an answer:", options)
29
+
30
+ if st.button("Submit"):
31
+ if answer == correct_answer:
32
+ st.success("Correct!", icon="✅")
33
+ st.write(f"**Explanation:** {explanation}")
34
+ else:
35
+ st.error("Incorrect.", icon="❌")
36
+ st.write(f"**Explanation:** {explanation}")
37
+ except ModuleNotFoundError:
38
+ st.error(f"The module '{module_name}' was not found. Please select another module.")
modules/addition_bases.py ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+
3
+ def generate_question():
4
+ num = random.randint(1, 100)
5
+ from_base = random.choice([2, 8, 10, 16])
6
+ to_base = random.choice([2, 8, 10, 16])
7
+
8
+ if from_base == 10:
9
+ value = num
10
+ elif from_base == 2:
11
+ value = int(bin(num)[2:], 2)
12
+ elif from_base == 8:
13
+ value = int(oct(num)[2:], 8)
14
+ else:
15
+ value = int(hex(num)[2:], 16)
16
+
17
+ if to_base == 2:
18
+ correct_answer = bin(value)[2:]
19
+ elif to_base == 8:
20
+ correct_answer = oct(value)[2:]
21
+ elif to_base == 16:
22
+ correct_answer = hex(value)[2:]
23
+ else:
24
+ correct_answer = str(value)
25
+
26
+ options = [correct_answer]
27
+
28
+ # Generate incorrect options
29
+ while len(options) < 5:
30
+ fake_option = bin(random.randint(1, 100))[2:]
31
+ if fake_option not in options:
32
+ options.append(fake_option)
33
+
34
+ random.shuffle(options)
35
+ question = f"Convert {num} from base {from_base} to base {to_base}."
36
+ explanation = (
37
+ f"The number {num} in base {from_base} is {correct_answer} in base {to_base}."
38
+ "\n\n**Step-by-step solution:**\n"
39
+ "1. Convert the number from the original base to decimal if necessary.\n"
40
+ "2. Convert the decimal number to the target base.\n"
41
+ "3. The correct answer is the result of the conversion."
42
+ )
43
+ return question, options, correct_answer, explanation
modules/conversion_bases.py ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+
3
+ def generate_question():
4
+ num = random.randint(1, 100)
5
+ from_base = random.choice([2, 8, 10, 16])
6
+ to_base = random.choice([2, 8, 10, 16])
7
+
8
+ if from_base == 10:
9
+ value = num
10
+ elif from_base == 2:
11
+ value = int(bin(num)[2:], 2)
12
+ elif from_base == 8:
13
+ value = int(oct(num)[2:], 8)
14
+ else:
15
+ value = int(hex(num)[2:], 16)
16
+
17
+ if to_base == 2:
18
+ correct_answer = bin(value)[2:]
19
+ elif to_base == 8:
20
+ correct_answer = oct(value)[2:]
21
+ elif to_base == 16:
22
+ correct_answer = hex(value)[2:]
23
+ else:
24
+ correct_answer = str(value)
25
+
26
+ options = [correct_answer]
27
+
28
+ # Generate incorrect options
29
+ while len(options) < 5:
30
+ fake_option = bin(random.randint(1, 100))[2:]
31
+ if fake_option not in options:
32
+ options.append(fake_option)
33
+
34
+ random.shuffle(options)
35
+ question = f"Convert {num} from base {from_base} to base {to_base}."
36
+ explanation = (
37
+ f"The number {num} in base {from_base} is {correct_answer} in base {to_base}."
38
+ "\n\n**Step-by-step solution:**\n"
39
+ "1. Convert the number from the original base to decimal if necessary.\n"
40
+ "2. Convert the decimal number to the target base.\n"
41
+ "3. The correct answer is the result of the conversion."
42
+ )
43
+ return question, options, correct_answer, explanation
modules/grouping_techniques.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+
3
+ def generate_question():
4
+ binary_num = bin(random.randint(1, 63))[2:]
5
+ padded_binary = binary_num.zfill(len(binary_num) + (3 - len(binary_num) % 3) % 3)
6
+
7
+ octal = ''.join([str(int(padded_binary[i:i+3], 2)) for i in range(0, len(padded_binary), 3)])
8
+
9
+ question = f"Group the binary number {binary_num} into octal."
10
+ correct_answer = octal
11
+ options = [correct_answer]
12
+
13
+ # Generate incorrect options
14
+ while len(options) < 5:
15
+ fake_option = ''.join([str(random.randint(0, 7)) for _ in range(len(octal))])
16
+ if fake_option not in options:
17
+ options.append(fake_option)
18
+
19
+ random.shuffle(options)
20
+ explanation = (
21
+ f"The binary number {binary_num} is grouped into octal as {octal}."
22
+ "\n\n**Step-by-step solution:**\n"
23
+ "1. Pad the binary number with leading zeros to make its length a multiple of 3.\n"
24
+ "2. Group the binary digits in groups of three, starting from the right.\n"
25
+ "3. Convert each group to its octal equivalent."
26
+ )
27
+ return question, options, correct_answer, explanation
modules/negative_binary.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+
3
+ def generate_question():
4
+ num = random.randint(-8, -1)
5
+ bit_length = 4
6
+ binary = bin((1 << bit_length) + num)[2:]
7
+
8
+ question = f"What is the binary representation of {num} using 4 bits?"
9
+ correct_answer = binary
10
+ options = [correct_answer]
11
+
12
+ # Generate incorrect options
13
+ while len(options) < 5:
14
+ fake_option = bin(random.randint(-8, -1) & 0xF)[2:]
15
+ if fake_option not in options:
16
+ options.append(fake_option)
17
+
18
+ random.shuffle(options)
19
+ explanation = (
20
+ f"The binary representation of {num} using 4 bits is {binary}."
21
+ "\n\n**Step-by-step solution:**\n"
22
+ "1. Convert the absolute value of the negative number to binary.\n"
23
+ "2. Find the 2's complement of the binary number to represent the negative number.\n"
24
+ "3. The result is the binary representation of the negative number."
25
+ )
26
+ return question, options, correct_answer, explanation
modules/presentation_bases.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+
3
+ def generate_question():
4
+ num = random.randint(1, 20)
5
+ base = random.choice([2, 8, 10, 16])
6
+ if base == 2:
7
+ representation = bin(num)[2:]
8
+ elif base == 8:
9
+ representation = oct(num)[2:]
10
+ elif base == 16:
11
+ representation = hex(num)[2:]
12
+ else:
13
+ representation = str(num)
14
+
15
+ question = f"What is the representation of decimal number {num} in base {base}?"
16
+ correct_answer = representation
17
+ options = [correct_answer]
18
+
19
+ # Generate incorrect options
20
+ while len(options) < 5:
21
+ fake_option = bin(random.randint(1, 20))[2:]
22
+ if fake_option not in options:
23
+ options.append(fake_option)
24
+
25
+ random.shuffle(options)
26
+ explanation = (
27
+ f"The number {num} in base {base} is represented as {representation}."
28
+ "\n\n**Step-by-step solution:**\n"
29
+ "1. Convert the number from decimal to the required base.\n"
30
+ "2. Match with the provided options.\n"
31
+ "3. The correct answer is the one that matches the conversion."
32
+ )
33
+ return question, options, correct_answer, explanation
modules/subtraction_bases.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+
3
+ def generate_question():
4
+ num1 = random.randint(1, 7)
5
+ num2 = random.randint(1, 7)
6
+
7
+ result = num1 - num2
8
+ bit_length = 4
9
+ if result >= 0:
10
+ binary_result = bin(result)[2:].zfill(bit_length)
11
+ else:
12
+ binary_result = bin((1 << bit_length) + result)[2:]
13
+
14
+ question = f"Subtract {num2} from {num1} in base 2 using 2's complement method."
15
+ correct_answer = binary_result
16
+ options = [correct_answer]
17
+
18
+ # Generate incorrect options
19
+ while len(options) < 5:
20
+ fake_option = bin(random.randint(-7, 7) & 0xF)[2:]
21
+ if fake_option not in options:
22
+ options.append(fake_option)
23
+
24
+ random.shuffle(options)
25
+ explanation = (
26
+ f"The result of subtracting {num2} from {num1} in base 2 using 2's complement is {binary_result}."
27
+ "\n\n**Step-by-step solution:**\n"
28
+ "1. Find the 2's complement of the subtracted number.\n"
29
+ "2. Add it to the first number.\n"
30
+ "3. If there's a carry, discard it. The result is the binary difference."
31
+ )
32
+ return question, options, correct_answer, explanation
modules/twos_complement.py ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+
3
+ def generate_question():
4
+ num = random.randint(1, 100)
5
+ from_base = random.choice([2, 8, 10, 16])
6
+ to_base = random.choice([2, 8, 10, 16])
7
+
8
+ if from_base == 10:
9
+ value = num
10
+ elif from_base == 2:
11
+ value = int(bin(num)[2:], 2)
12
+ elif from_base == 8:
13
+ value = int(oct(num)[2:], 8)
14
+ else:
15
+ value = int(hex(num)[2:], 16)
16
+
17
+ if to_base == 2:
18
+ correct_answer = bin(value)[2:]
19
+ elif to_base == 8:
20
+ correct_answer = oct(value)[2:]
21
+ elif to_base == 16:
22
+ correct_answer = hex(value)[2:]
23
+ else:
24
+ correct_answer = str(value)
25
+
26
+ options = [correct_answer]
27
+
28
+ # Generate incorrect options
29
+ while len(options) < 5:
30
+ fake_option = bin(random.randint(1, 100))[2:]
31
+ if fake_option not in options:
32
+ options.append(fake_option)
33
+
34
+ random.shuffle(options)
35
+ question = f"Convert {num} from base {from_base} to base {to_base}."
36
+ explanation = (
37
+ f"The number {num} in base {from_base} is {correct_answer} in base {to_base}."
38
+ "\n\n**Step-by-step solution:**\n"
39
+ "1. Convert the number from the original base to decimal if necessary.\n"
40
+ "2. Convert the decimal number to the target base.\n"
41
+ "3. The correct answer is the result of the conversion."
42
+ )
43
+ return question, options, correct_answer, explanation
modules/valid_invalid_numbers.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+
3
+ def generate_question():
4
+ base = random.choice([2, 8, 10, 16])
5
+ length = random.randint(3, 5)
6
+
7
+ def generate_valid_number():
8
+ return ''.join([str(random.randint(0, base - 1)) for _ in range(length)])
9
+
10
+ def generate_invalid_number():
11
+ valid_digits = ''.join([str(random.randint(0, base - 1)) for _ in range(length - 1)])
12
+ invalid_digit = str(random.randint(base, 9))
13
+ return valid_digits + invalid_digit
14
+
15
+ correct_answer = generate_invalid_number()
16
+ options = [correct_answer]
17
+
18
+ # Generate valid options
19
+ while len(options) < 5:
20
+ valid_option = generate_valid_number()
21
+ if valid_option not in options:
22
+ options.append(valid_option)
23
+
24
+ random.shuffle(options)
25
+ question = f"Which of the following is an invalid number in base {base}?"
26
+ explanation = (
27
+ f"The number {correct_answer} is invalid in base {base} because it contains a digit outside the range 0-{base-1}."
28
+ "\n\n**Step-by-step solution:**\n"
29
+ "1. Identify the valid digits for the base.\n"
30
+ "2. Check each option to see if it contains any invalid digits.\n"
31
+ "3. The correct answer will have a digit that is not allowed in the specified base."
32
+ )
33
+ return question, options, correct_answer, explanation