Sina Media Lab
commited on
Commit
·
58956eb
1
Parent(s):
e6e6e74
Updates
Browse files- app.py +57 -42
- modules/valid_invalid_numbers.py +42 -204
app.py
CHANGED
@@ -1,5 +1,4 @@
|
|
1 |
import streamlit as st
|
2 |
-
import importlib
|
3 |
import os
|
4 |
from fpdf import FPDF
|
5 |
import uuid
|
@@ -22,6 +21,10 @@ if 'module_question_count' not in st.session_state:
|
|
22 |
st.session_state.module_question_count = {}
|
23 |
if 'pdf_data' not in st.session_state:
|
24 |
st.session_state.pdf_data = None
|
|
|
|
|
|
|
|
|
25 |
|
26 |
def reset_pdf_cache():
|
27 |
st.session_state.pdf_data = None
|
@@ -81,11 +84,12 @@ def load_modules():
|
|
81 |
for filename in os.listdir(module_dir):
|
82 |
if filename.endswith(".py") and filename != "__init__.py":
|
83 |
module_name = filename[:-3]
|
84 |
-
module
|
|
|
85 |
modules[module_name] = {
|
86 |
"title": getattr(module, "title", module_name),
|
87 |
"description": getattr(module, "description", "No description available."),
|
88 |
-
"generate_question": module.generate_question
|
89 |
}
|
90 |
return modules
|
91 |
|
@@ -104,34 +108,60 @@ def navigate_question(direction):
|
|
104 |
if direction == "prev" and st.session_state.current_index > 0:
|
105 |
st.session_state.current_index -= 1
|
106 |
elif direction == "next":
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
# Generate a new question if at the end of the list
|
111 |
-
new_question = generate_new_question(st.session_state.current_module, modules[st.session_state.current_module])
|
112 |
-
st.session_state.questions.append(new_question)
|
113 |
-
st.session_state.current_index += 1
|
114 |
|
115 |
# Load all modules dynamically
|
116 |
modules = load_modules()
|
117 |
|
118 |
# Streamlit interface
|
119 |
st.sidebar.title("Quiz Modules")
|
120 |
-
module_name = st.sidebar.radio("Choose a module:",
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
|
122 |
-
if
|
123 |
-
st.session_state.current_module =
|
124 |
st.session_state.current_index = 0
|
125 |
-
st.session_state.questions = [generate_new_question(
|
126 |
-
st.session_state.module_question_count[
|
127 |
-
st.session_state.module_correct_count[
|
|
|
|
|
128 |
|
129 |
# Load the current module's question
|
130 |
current_question = st.session_state.questions[st.session_state.current_index]
|
131 |
|
132 |
# Display module title and description
|
133 |
-
st.title(modules[
|
134 |
-
st.write(modules[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
st.write(current_question["question"])
|
136 |
|
137 |
# Use a form to prevent rerun on option selection
|
@@ -142,7 +172,10 @@ with st.form(key=f'question_form_{st.session_state.current_index}'):
|
|
142 |
key=f"question_{st.session_state.current_index}_options",
|
143 |
index=None # No pre-selection
|
144 |
)
|
145 |
-
submit_button = st.form_submit_button(label="Submit")
|
|
|
|
|
|
|
146 |
|
147 |
if submit_button and not current_question.get('answered', False):
|
148 |
if selected_answer is None:
|
@@ -151,11 +184,14 @@ if submit_button and not current_question.get('answered', False):
|
|
151 |
# Process the answer
|
152 |
current_question['selected'] = selected_answer
|
153 |
current_question['answered'] = True
|
154 |
-
st.session_state.module_question_count[
|
155 |
|
156 |
if selected_answer == current_question['correct_answer']:
|
157 |
st.session_state.correct_count += 1
|
158 |
-
st.session_state.module_correct_count[
|
|
|
|
|
|
|
159 |
|
160 |
# Show correct/incorrect feedback after submission
|
161 |
if current_question.get('answered', False):
|
@@ -172,24 +208,3 @@ if current_question.get('answered', False):
|
|
172 |
st.write("**Step-by-Step Solution:**")
|
173 |
for step in current_question['step_by_step_solution']:
|
174 |
st.write(step)
|
175 |
-
|
176 |
-
# Navigation buttons (placed after question and options)
|
177 |
-
col1, col2 = st.columns([1, 1])
|
178 |
-
with col1:
|
179 |
-
if st.button("⬅️ Prev", key=f'prev_button_{st.session_state.current_index}', disabled=st.session_state.current_index == 0):
|
180 |
-
navigate_question("prev")
|
181 |
-
|
182 |
-
with col2:
|
183 |
-
if st.button("➡️ Next", key=f'next_button_{st.session_state.current_index}'):
|
184 |
-
navigate_question("next")
|
185 |
-
|
186 |
-
# PDF Download Button (at the bottom)
|
187 |
-
if len(st.session_state.questions) > 0:
|
188 |
-
pdf = generate_pdf_report()
|
189 |
-
st.session_state.pdf_data = pdf # Reset PDF cache
|
190 |
-
st.download_button(
|
191 |
-
label="Download PDF Report 📄",
|
192 |
-
data=st.session_state.pdf_data,
|
193 |
-
file_name="quiz_report.pdf",
|
194 |
-
mime="application/pdf"
|
195 |
-
)
|
|
|
1 |
import streamlit as st
|
|
|
2 |
import os
|
3 |
from fpdf import FPDF
|
4 |
import uuid
|
|
|
21 |
st.session_state.module_question_count = {}
|
22 |
if 'pdf_data' not in st.session_state:
|
23 |
st.session_state.pdf_data = None
|
24 |
+
if 'submit_disabled' not in st.session_state:
|
25 |
+
st.session_state.submit_disabled = True
|
26 |
+
if 'next_disabled' not in st.session_state:
|
27 |
+
st.session_state.next_disabled = True
|
28 |
|
29 |
def reset_pdf_cache():
|
30 |
st.session_state.pdf_data = None
|
|
|
84 |
for filename in os.listdir(module_dir):
|
85 |
if filename.endswith(".py") and filename != "__init__.py":
|
86 |
module_name = filename[:-3]
|
87 |
+
# Dynamically import the module only when needed
|
88 |
+
module = __import__(f"{module_dir}.{module_name}", fromlist=[''])
|
89 |
modules[module_name] = {
|
90 |
"title": getattr(module, "title", module_name),
|
91 |
"description": getattr(module, "description", "No description available."),
|
92 |
+
"generate_question": module.generate_question # Access the generate_question function
|
93 |
}
|
94 |
return modules
|
95 |
|
|
|
108 |
if direction == "prev" and st.session_state.current_index > 0:
|
109 |
st.session_state.current_index -= 1
|
110 |
elif direction == "next":
|
111 |
+
new_question = generate_new_question(st.session_state.current_module, modules[st.session_state.current_module])
|
112 |
+
st.session_state.questions.append(new_question)
|
113 |
+
st.session_state.current_index = len(st.session_state.questions) - 1
|
|
|
|
|
|
|
|
|
114 |
|
115 |
# Load all modules dynamically
|
116 |
modules = load_modules()
|
117 |
|
118 |
# Streamlit interface
|
119 |
st.sidebar.title("Quiz Modules")
|
120 |
+
module_name = st.sidebar.radio("Choose a module:", [modules[module]["title"] for module in modules], index=0)
|
121 |
+
|
122 |
+
selected_module = None
|
123 |
+
for module in modules:
|
124 |
+
if modules[module]["title"] == module_name:
|
125 |
+
selected_module = module
|
126 |
+
break
|
127 |
|
128 |
+
if selected_module != st.session_state.current_module:
|
129 |
+
st.session_state.current_module = selected_module
|
130 |
st.session_state.current_index = 0
|
131 |
+
st.session_state.questions = [generate_new_question(selected_module, modules[selected_module])]
|
132 |
+
st.session_state.module_question_count[selected_module] = 0
|
133 |
+
st.session_state.module_correct_count[selected_module] = 0
|
134 |
+
st.session_state.submit_disabled = True
|
135 |
+
st.session_state.next_disabled = True
|
136 |
|
137 |
# Load the current module's question
|
138 |
current_question = st.session_state.questions[st.session_state.current_index]
|
139 |
|
140 |
# Display module title and description
|
141 |
+
st.title(modules[selected_module]["title"])
|
142 |
+
st.write(modules[selected_module]["description"])
|
143 |
+
|
144 |
+
# Navigation and PDF report buttons
|
145 |
+
col1, col2, col3 = st.columns([1, 1, 2])
|
146 |
+
with col1:
|
147 |
+
if st.button("⬅️ Prev", disabled=st.session_state.current_index == 0):
|
148 |
+
navigate_question("prev")
|
149 |
+
with col2:
|
150 |
+
if st.button("➡️ Next", disabled=st.session_state.next_disabled):
|
151 |
+
st.session_state.submit_disabled = True
|
152 |
+
st.session_state.next_disabled = True
|
153 |
+
navigate_question("next")
|
154 |
+
with col3:
|
155 |
+
if len(st.session_state.questions) > 0:
|
156 |
+
pdf = generate_pdf_report()
|
157 |
+
st.session_state.pdf_data = pdf # Reset PDF cache
|
158 |
+
st.download_button(
|
159 |
+
label="Download PDF Report 📄",
|
160 |
+
data=st.session_state.pdf_data,
|
161 |
+
file_name="quiz_report.pdf",
|
162 |
+
mime="application/pdf"
|
163 |
+
)
|
164 |
+
|
165 |
st.write(current_question["question"])
|
166 |
|
167 |
# Use a form to prevent rerun on option selection
|
|
|
172 |
key=f"question_{st.session_state.current_index}_options",
|
173 |
index=None # No pre-selection
|
174 |
)
|
175 |
+
submit_button = st.form_submit_button(label="Submit", disabled=st.session_state.submit_disabled)
|
176 |
+
|
177 |
+
if selected_answer and st.session_state.submit_disabled:
|
178 |
+
st.session_state.submit_disabled = False
|
179 |
|
180 |
if submit_button and not current_question.get('answered', False):
|
181 |
if selected_answer is None:
|
|
|
184 |
# Process the answer
|
185 |
current_question['selected'] = selected_answer
|
186 |
current_question['answered'] = True
|
187 |
+
st.session_state.module_question_count[selected_module] += 1
|
188 |
|
189 |
if selected_answer == current_question['correct_answer']:
|
190 |
st.session_state.correct_count += 1
|
191 |
+
st.session_state.module_correct_count[selected_module] += 1
|
192 |
+
|
193 |
+
st.session_state.submit_disabled = True
|
194 |
+
st.session_state.next_disabled = False
|
195 |
|
196 |
# Show correct/incorrect feedback after submission
|
197 |
if current_question.get('answered', False):
|
|
|
208 |
st.write("**Step-by-Step Solution:**")
|
209 |
for step in current_question['step_by_step_solution']:
|
210 |
st.write(step)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
modules/valid_invalid_numbers.py
CHANGED
@@ -1,210 +1,48 @@
|
|
1 |
-
|
2 |
-
import os
|
3 |
-
from fpdf import FPDF
|
4 |
-
import uuid
|
5 |
|
6 |
-
|
7 |
-
|
8 |
-
st.session_state.session_id = str(uuid.uuid4())
|
9 |
|
10 |
-
|
11 |
-
|
12 |
-
if 'current_index' not in st.session_state:
|
13 |
-
st.session_state.current_index = 0
|
14 |
-
if 'current_module' not in st.session_state:
|
15 |
-
st.session_state.current_module = None
|
16 |
-
if 'correct_count' not in st.session_state:
|
17 |
-
st.session_state.correct_count = 0
|
18 |
-
if 'module_correct_count' not in st.session_state:
|
19 |
-
st.session_state.module_correct_count = {}
|
20 |
-
if 'module_question_count' not in st.session_state:
|
21 |
-
st.session_state.module_question_count = {}
|
22 |
-
if 'pdf_data' not in st.session_state:
|
23 |
-
st.session_state.pdf_data = None
|
24 |
-
if 'submit_disabled' not in st.session_state:
|
25 |
-
st.session_state.submit_disabled = True
|
26 |
-
if 'next_disabled' not in st.session_state:
|
27 |
-
st.session_state.next_disabled = True
|
28 |
-
|
29 |
-
def reset_pdf_cache():
|
30 |
-
st.session_state.pdf_data = None
|
31 |
-
|
32 |
-
def generate_pdf_report():
|
33 |
-
pdf = FPDF()
|
34 |
-
pdf.add_page()
|
35 |
-
pdf.set_font("Arial", size=12)
|
36 |
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
question, options, selected, correct, explanation, step_by_step_solution = (
|
51 |
-
entry['question'],
|
52 |
-
entry['options'],
|
53 |
-
entry['selected'] if entry['selected'] is not None else "Not Answered",
|
54 |
-
entry['correct_answer'],
|
55 |
-
entry['explanation'],
|
56 |
-
entry['step_by_step_solution']
|
57 |
-
)
|
58 |
-
pdf.multi_cell(0, 10, f"Q: {question}")
|
59 |
-
for option in options:
|
60 |
-
if option == correct:
|
61 |
-
pdf.set_text_color(0, 128, 0) # Green for correct
|
62 |
-
pdf.multi_cell(0, 10, f"{option}")
|
63 |
-
elif option == selected:
|
64 |
-
pdf.set_text_color(255, 0, 0) # Red for incorrect
|
65 |
-
pdf.multi_cell(0, 10, f"{option}")
|
66 |
-
else:
|
67 |
-
pdf.set_text_color(0, 0, 0) # Default color for others
|
68 |
-
pdf.multi_cell(0, 10, f" {option}")
|
69 |
-
pdf.set_text_color(0, 0, 0) # Reset color
|
70 |
-
pdf.multi_cell(0, 10, f"Explanation: {explanation}")
|
71 |
-
pdf.ln(5)
|
72 |
-
pdf.multi_cell(0, 10, "Step-by-Step Solution:")
|
73 |
-
for step in step_by_step_solution:
|
74 |
-
pdf.multi_cell(0, 10, step)
|
75 |
-
pdf.ln(10)
|
76 |
-
|
77 |
-
pdf.ln(10) # Add space after each module
|
78 |
-
|
79 |
-
return pdf.output(dest='S').encode('latin1', 'replace')
|
80 |
-
|
81 |
-
def load_modules():
|
82 |
-
modules = {}
|
83 |
-
module_dir = "modules"
|
84 |
-
for filename in os.listdir(module_dir):
|
85 |
-
if filename.endswith(".py") and filename != "__init__.py":
|
86 |
-
module_name = filename[:-3]
|
87 |
-
# Dynamically import the module only when needed
|
88 |
-
module = __import__(f"{module_dir}.{module_name}", fromlist=[''])
|
89 |
-
modules[module_name] = {
|
90 |
-
"title": getattr(module, "title", module_name),
|
91 |
-
"description": getattr(module, "description", "No description available."),
|
92 |
-
"generate_question": module.generate_question # Access the generate_question function
|
93 |
-
}
|
94 |
-
return modules
|
95 |
-
|
96 |
-
def generate_new_question(module_name, module):
|
97 |
-
question_data = module['generate_question']()
|
98 |
-
# Ensure 'answered' is initialized to False and add the 'module' and 'selected' keys
|
99 |
-
question_data['answered'] = False
|
100 |
-
question_data['module'] = module_name # Add the module name to the question data
|
101 |
-
question_data['selected'] = None # Initialize 'selected' to None
|
102 |
-
# Ensure there are exactly 4 options
|
103 |
-
if len(question_data['options']) != 4:
|
104 |
-
st.warning(f"Question in module '{module_name}' does not have 4 options. Found {len(question_data['options'])}.")
|
105 |
-
return question_data
|
106 |
-
|
107 |
-
def navigate_question(direction):
|
108 |
-
if direction == "prev" and st.session_state.current_index > 0:
|
109 |
-
st.session_state.current_index -= 1
|
110 |
-
elif direction == "next":
|
111 |
-
new_question = generate_new_question(st.session_state.current_module, modules[st.session_state.current_module])
|
112 |
-
st.session_state.questions.append(new_question)
|
113 |
-
st.session_state.current_index = len(st.session_state.questions) - 1
|
114 |
-
|
115 |
-
# Load all modules dynamically
|
116 |
-
modules = load_modules()
|
117 |
-
|
118 |
-
# Streamlit interface
|
119 |
-
st.sidebar.title("Quiz Modules")
|
120 |
-
module_name = st.sidebar.radio("Choose a module:", [modules[module]["title"] for module in modules], index=0)
|
121 |
-
|
122 |
-
selected_module = None
|
123 |
-
for module in modules:
|
124 |
-
if modules[module]["title"] == module_name:
|
125 |
-
selected_module = module
|
126 |
-
break
|
127 |
-
|
128 |
-
if selected_module != st.session_state.current_module:
|
129 |
-
st.session_state.current_module = selected_module
|
130 |
-
st.session_state.current_index = 0
|
131 |
-
st.session_state.questions = [generate_new_question(selected_module, modules[selected_module])]
|
132 |
-
st.session_state.module_question_count[selected_module] = 0
|
133 |
-
st.session_state.module_correct_count[selected_module] = 0
|
134 |
-
st.session_state.submit_disabled = True
|
135 |
-
st.session_state.next_disabled = True
|
136 |
-
|
137 |
-
# Load the current module's question
|
138 |
-
current_question = st.session_state.questions[st.session_state.current_index]
|
139 |
-
|
140 |
-
# Display module title and description
|
141 |
-
st.title(modules[selected_module]["title"])
|
142 |
-
st.write(modules[selected_module]["description"])
|
143 |
-
|
144 |
-
# Navigation and PDF report buttons
|
145 |
-
col1, col2, col3 = st.columns([1, 1, 2])
|
146 |
-
with col1:
|
147 |
-
if st.button("⬅️ Prev", disabled=st.session_state.current_index == 0):
|
148 |
-
navigate_question("prev")
|
149 |
-
with col2:
|
150 |
-
if st.button("➡️ Next", disabled=st.session_state.next_disabled):
|
151 |
-
st.session_state.submit_disabled = True
|
152 |
-
st.session_state.next_disabled = True
|
153 |
-
navigate_question("next")
|
154 |
-
with col3:
|
155 |
-
if len(st.session_state.questions) > 0:
|
156 |
-
pdf = generate_pdf_report()
|
157 |
-
st.session_state.pdf_data = pdf # Reset PDF cache
|
158 |
-
st.download_button(
|
159 |
-
label="Download PDF Report 📄",
|
160 |
-
data=st.session_state.pdf_data,
|
161 |
-
file_name="quiz_report.pdf",
|
162 |
-
mime="application/pdf"
|
163 |
-
)
|
164 |
-
|
165 |
-
st.write(current_question["question"])
|
166 |
-
|
167 |
-
# Use a form to prevent rerun on option selection
|
168 |
-
with st.form(key=f'question_form_{st.session_state.current_index}'):
|
169 |
-
selected_answer = st.radio(
|
170 |
-
"Choose an answer:",
|
171 |
-
options=current_question['options'],
|
172 |
-
key=f"question_{st.session_state.current_index}_options",
|
173 |
-
index=None # No pre-selection
|
174 |
-
)
|
175 |
-
submit_button = st.form_submit_button(label="Submit", disabled=st.session_state.submit_disabled)
|
176 |
-
|
177 |
-
if selected_answer and st.session_state.submit_disabled:
|
178 |
-
st.session_state.submit_disabled = False
|
179 |
-
|
180 |
-
if submit_button and not current_question.get('answered', False):
|
181 |
-
if selected_answer is None:
|
182 |
-
st.warning("Please select an answer before submitting.")
|
183 |
-
else:
|
184 |
-
# Process the answer
|
185 |
-
current_question['selected'] = selected_answer
|
186 |
-
current_question['answered'] = True
|
187 |
-
st.session_state.module_question_count[selected_module] += 1
|
188 |
-
|
189 |
-
if selected_answer == current_question['correct_answer']:
|
190 |
-
st.session_state.correct_count += 1
|
191 |
-
st.session_state.module_correct_count[selected_module] += 1
|
192 |
|
193 |
-
|
194 |
-
|
195 |
|
196 |
-
#
|
197 |
-
|
198 |
-
|
199 |
-
if
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
|
|
|
|
|
1 |
+
# modules/valid_invalid_numbers.py
|
|
|
|
|
|
|
2 |
|
3 |
+
title = "Validity of Numbers in Bases"
|
4 |
+
description = "This module helps determine the validity of numbers in different bases like binary, octal, decimal, and hexadecimal."
|
|
|
5 |
|
6 |
+
def generate_question():
|
7 |
+
import random
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
|
9 |
+
base = random.choice([2, 8, 10, 16])
|
10 |
+
length = random.randint(3, 5)
|
11 |
+
|
12 |
+
def generate_valid_number():
|
13 |
+
return ''.join([str(random.randint(0, base - 1)) for _ in range(length)])
|
14 |
+
|
15 |
+
def generate_invalid_number():
|
16 |
+
valid_digits = ''.join([str(random.randint(0, base - 1)) for _ in range(length - 1)])
|
17 |
+
if base < 10:
|
18 |
+
invalid_digit = str(random.randint(base, 9)) # For bases < 10, pick an invalid digit from [base, 9]
|
19 |
+
else:
|
20 |
+
invalid_digit = random.choice('ABCDEF') # For bases >= 10, pick a hex digit to make it invalid
|
21 |
+
return valid_digits + invalid_digit
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
|
23 |
+
correct_answer = generate_invalid_number()
|
24 |
+
options = [correct_answer]
|
25 |
|
26 |
+
# Generate valid options
|
27 |
+
while len(options) < 4:
|
28 |
+
valid_option = generate_valid_number()
|
29 |
+
if valid_option not in options:
|
30 |
+
options.append(valid_option)
|
31 |
+
|
32 |
+
random.shuffle(options)
|
33 |
+
|
34 |
+
question = f"Which of the following is an invalid number in base {base}?"
|
35 |
+
explanation = f"The number {correct_answer} is invalid in base {base} because it contains a digit outside the range 0-{base-1}."
|
36 |
+
step_by_step_solution = [
|
37 |
+
"Step 1: Identify the valid digits for the base.",
|
38 |
+
"Step 2: Check each option to see if it contains any invalid digits.",
|
39 |
+
"Step 3: The correct answer will have a digit that is not allowed in the specified base."
|
40 |
+
]
|
41 |
|
42 |
+
return {
|
43 |
+
"question": question,
|
44 |
+
"options": options,
|
45 |
+
"correct_answer": correct_answer,
|
46 |
+
"explanation": explanation,
|
47 |
+
"step_by_step_solution": step_by_step_solution
|
48 |
+
}
|