Sina Media Lab commited on
Commit
7ef2742
·
1 Parent(s): 0133c15
Files changed (1) hide show
  1. app.py +64 -138
app.py CHANGED
@@ -2,7 +2,6 @@ import streamlit as st
2
  import os
3
  from fpdf import FPDF
4
  import uuid
5
- import importlib
6
 
7
  # Initialize session state variables
8
  if 'session_id' not in st.session_state:
@@ -39,10 +38,12 @@ def generate_pdf_report():
39
  pdf.ln(10)
40
 
41
  for module, data in st.session_state.module_question_count.items():
42
- pdf.set_text_color(0, 0, 0) # Reset to default color
43
- pdf.set_font("Arial", size=12, style='B')
44
  pdf.cell(200, 10, txt=f"Module: {module}", ln=True, align="L")
45
  pdf.ln(5)
 
 
46
 
47
  for entry in st.session_state.questions:
48
  if entry['module'] == module:
@@ -54,43 +55,23 @@ def generate_pdf_report():
54
  entry['explanation'],
55
  entry['step_by_step_solution']
56
  )
57
-
58
- # Draw a border around the question and options with a light background
59
- pdf.set_draw_color(0, 0, 0) # Black border
60
- pdf.set_fill_color(240, 240, 240) # Light gray background for question
61
- pdf.set_line_width(0.3)
62
-
63
- # Question
64
- pdf.multi_cell(0, 10, f"Q: {question}", border=1, align='L', fill=True)
65
- pdf.ln(5)
66
-
67
- # Options with distinct background
68
  for option in options:
69
  if option == correct:
70
  pdf.set_text_color(0, 128, 0) # Green for correct
71
- pdf.set_fill_color(200, 255, 200) # Light green background
72
- pdf.multi_cell(0, 10, f"{option}", border=1, align='L', fill=True)
73
  elif option == selected:
74
  pdf.set_text_color(255, 0, 0) # Red for incorrect
75
- pdf.set_fill_color(255, 200, 200) # Light red background
76
- pdf.multi_cell(0, 10, f"{option}", border=1, align='L', fill=True)
77
  else:
78
  pdf.set_text_color(0, 0, 0) # Default color for others
79
- pdf.set_fill_color(240, 240, 240) # Light gray background
80
- pdf.multi_cell(0, 10, f" {option}", border=1, align='L', fill=True)
 
81
  pdf.ln(5)
82
-
83
- # Explanation with background
84
- pdf.set_text_color(0, 0, 0) # Reset to black
85
- pdf.set_fill_color(230, 230, 250) # Light blue background
86
- pdf.multi_cell(0, 10, f"Explanation: {explanation}", border=1, align='L', fill=True)
87
- pdf.ln(5)
88
-
89
- # Step-by-step solution with background
90
- pdf.set_fill_color(250, 235, 215) # Light tan background
91
- pdf.multi_cell(0, 10, "Step-by-Step Solution:", border=1, align='L', fill=True)
92
  for step in step_by_step_solution:
93
- pdf.multi_cell(0, 10, step, border=1, align='L', fill=True)
94
  pdf.ln(10)
95
 
96
  pdf.ln(10) # Add space after each module
@@ -104,7 +85,7 @@ def load_modules():
104
  if filename.endswith(".py") and filename != "__init__.py":
105
  module_name = filename[:-3]
106
  # Dynamically import the module only when needed
107
- module = importlib.import_module(f"modules.{module_name}")
108
  modules[module_name] = {
109
  "title": getattr(module, "title", module_name),
110
  "description": getattr(module, "description", "No description available."),
@@ -123,6 +104,14 @@ def generate_new_question(module_name, module):
123
  st.warning(f"Question in module '{module_name}' does not have 4 options. Found {len(question_data['options'])}.")
124
  return question_data
125
 
 
 
 
 
 
 
 
 
126
  # Load all modules dynamically
127
  modules = load_modules()
128
 
@@ -156,10 +145,10 @@ st.write(modules[selected_module]["description"])
156
  col1, col2, col3 = st.columns([1, 1, 2])
157
  with col1:
158
  if st.button("⬅️ Prev", disabled=st.session_state.current_index == 0):
159
- st.session_state.current_index -= 1
160
  with col2:
161
  if st.button("➡️ Next", disabled=st.session_state.current_index >= len(st.session_state.questions) - 1):
162
- st.session_state.current_index += 1
163
  with col3:
164
  if len(st.session_state.questions) > 0:
165
  pdf = generate_pdf_report()
@@ -171,69 +160,7 @@ with col3:
171
  mime="application/pdf"
172
  )
173
 
174
- # Web Page Presentation Styling
175
- def display_question_with_styles(question_data):
176
- st.markdown(f"""
177
- <style>
178
- .question-box {{
179
- border: 2px solid #000;
180
- padding: 10px;
181
- margin-bottom: 20px;
182
- background-color: #f0f0f0;
183
- }}
184
- .option {{
185
- border: 1px solid #000;
186
- padding: 5px;
187
- margin-bottom: 5px;
188
- }}
189
- .correct {{
190
- background-color: #c8e6c9;
191
- color: green;
192
- }}
193
- .incorrect {{
194
- background-color: #ffcdd2;
195
- color: red;
196
- }}
197
- .explanation-box {{
198
- border: 2px solid #000;
199
- padding: 10px;
200
- background-color: #e3f2fd;
201
- margin-top: 20px;
202
- }}
203
- .step-box {{
204
- border: 1px solid #000;
205
- padding: 5px;
206
- background-color: #fff3e0;
207
- margin-top: 10px;
208
- }}
209
- </style>
210
- """, unsafe_allow_html=True)
211
-
212
- st.markdown(f"""
213
- <div class="question-box">
214
- <strong>Q:</strong> {question_data['question']}
215
- </div>
216
- """, unsafe_allow_html=True)
217
-
218
- # Display options with correct/incorrect marking if answered
219
- for option in question_data['options']:
220
- option_class = ''
221
- if question_data['answered']:
222
- if option == question_data['correct_answer']:
223
- option_class = 'correct'
224
- elif option == question_data['selected']:
225
- option_class = 'incorrect'
226
- st.markdown(f"""
227
- <div class="option {option_class}">
228
- {option}
229
- </div>
230
- """, unsafe_allow_html=True)
231
-
232
- # Display the current question with styles
233
- display_question_with_styles(current_question)
234
-
235
- # Disable the radio buttons if the question is already answered
236
- disabled_options = current_question['answered']
237
 
238
  # Create the form for the question
239
  with st.form(key=f'question_form_{st.session_state.current_index}'):
@@ -241,49 +168,48 @@ with st.form(key=f'question_form_{st.session_state.current_index}'):
241
  "Choose an answer:",
242
  options=current_question['options'],
243
  index=current_question['options'].index(current_question['selected']) if current_question['answered'] else None,
244
- disabled=disabled_options, # Disable if the question has been answered
245
  key=f"question_{st.session_state.current_index}_options"
246
  )
247
 
248
- submit_button = st.form_submit_button(label="Submit")
249
- generate_button = st.form_submit_button(label="Generate")
250
 
251
  # Handle button state and answer submission
252
- if submit_button and not current_question['answered']:
253
- if selected_answer is not None:
254
- # Process the answer
255
- current_question['selected'] = selected_answer
256
- current_question['answered'] = True
257
- st.session_state.module_question_count[selected_module] += 1
258
-
259
- if selected_answer == current_question['correct_answer']:
260
- st.session_state.correct_count += 1
261
- st.session_state.module_correct_count[selected_module] += 1
262
-
263
- # Show correct/incorrect feedback after submission
264
- display_question_with_styles(current_question)
265
-
266
- # Display the explanation and step-by-step solution only after the question is answered
267
- st.markdown(f"""
268
- <div class="explanation-box">
269
- <strong>Explanation:</strong> {current_question['explanation']}
270
- </div>
271
- """, unsafe_allow_html=True)
272
-
273
- st.markdown(f"""
274
- <div class="step-box">
275
- <strong>Step-by-Step Solution:</strong>
276
- <ul>
277
- """, unsafe_allow_html=True)
278
-
279
- for step in current_question['step_by_step_solution']:
280
- st.markdown(f"<li>{step}</li>", unsafe_allow_html=True)
281
-
282
- st.markdown("</ul></div>", unsafe_allow_html=True)
283
-
284
- if generate_button:
285
- new_question = generate_new_question(selected_module, modules[selected_module])
286
- st.session_state.questions.append(new_question)
287
- st.session_state.current_index = len(st.session_state.questions) - 1
288
- st.session_state.answered = False
289
- st.experimental_rerun() # Rerun to load the new question
 
2
  import os
3
  from fpdf import FPDF
4
  import uuid
 
5
 
6
  # Initialize session state variables
7
  if 'session_id' not in st.session_state:
 
38
  pdf.ln(10)
39
 
40
  for module, data in st.session_state.module_question_count.items():
41
+ correct_count = st.session_state.module_correct_count.get(module, 0)
42
+ total_count = data
43
  pdf.cell(200, 10, txt=f"Module: {module}", ln=True, align="L")
44
  pdf.ln(5)
45
+ pdf.cell(200, 10, txt=f"Correct Answers: {correct_count}/{total_count}", ln=True, align="L")
46
+ pdf.ln(5)
47
 
48
  for entry in st.session_state.questions:
49
  if entry['module'] == module:
 
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
 
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."),
 
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
+ st.session_state.answered = True
111
+ elif direction == "next" and st.session_state.current_index < len(st.session_state.questions) - 1:
112
+ st.session_state.current_index += 1
113
+ st.session_state.answered = True
114
+
115
  # Load all modules dynamically
116
  modules = load_modules()
117
 
 
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.current_index >= len(st.session_state.questions) - 1):
151
+ navigate_question("next")
152
  with col3:
153
  if len(st.session_state.questions) > 0:
154
  pdf = generate_pdf_report()
 
160
  mime="application/pdf"
161
  )
162
 
163
+ st.write(current_question["question"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
 
165
  # Create the form for the question
166
  with st.form(key=f'question_form_{st.session_state.current_index}'):
 
168
  "Choose an answer:",
169
  options=current_question['options'],
170
  index=current_question['options'].index(current_question['selected']) if current_question['answered'] else None,
171
+ disabled=current_question['answered'], # Disable if the question has been answered
172
  key=f"question_{st.session_state.current_index}_options"
173
  )
174
 
175
+ submit_button = st.form_submit_button(label="Submit/Next")
 
176
 
177
  # Handle button state and answer submission
178
+ if submit_button:
179
+ if not current_question['answered']:
180
+ if selected_answer is not None:
181
+ # Process the answer
182
+ current_question['selected'] = selected_answer
183
+ current_question['answered'] = True
184
+ st.session_state.module_question_count[selected_module] += 1
185
+
186
+ if selected_answer == current_question['correct_answer']:
187
+ st.session_state.correct_count += 1
188
+ st.session_state.module_correct_count[selected_module] += 1
189
+
190
+ # Set answered to true to disable options
191
+ st.session_state.questions[st.session_state.current_index]['answered'] = True
192
+ st.session_state.selected_answer = selected_answer
193
+
194
+ else:
195
+ # If already answered, move to the next question
196
+ new_question = generate_new_question(selected_module, modules[selected_module])
197
+ st.session_state.questions.append(new_question)
198
+ st.session_state.current_index = len(st.session_state.questions) - 1
199
+ st.session_state.answered = False
200
+
201
+ # Show correct/incorrect feedback after submission
202
+ if current_question.get('answered', False):
203
+ for option in current_question['options']:
204
+ if option == current_question['correct_answer']:
205
+ st.markdown(f"<span style='color:green;'>{option} ✅</span>", unsafe_allow_html=True)
206
+ elif option == current_question['selected']:
207
+ st.markdown(f"<span style='color:red;'>{option} ❌</span>", unsafe_allow_html=True)
208
+ else:
209
+ st.markdown(f"{option}")
210
+
211
+ # Show explanation and step-by-step solution
212
+ st.write(f"**Explanation:** {current_question['explanation']}")
213
+ st.write("**Step-by-Step Solution:**")
214
+ for step in current_question['step_by_step_solution']:
215
+ st.write(step)