NSamson1 commited on
Commit
bcb66dc
Β·
verified Β·
1 Parent(s): 356a7d3

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +215 -154
src/streamlit_app.py CHANGED
@@ -1,43 +1,28 @@
 
1
  import streamlit as st
2
  import pandas as pd
3
  import os
4
  import zipfile
5
  from PIL import Image
 
6
  import time
7
  import tempfile
8
  import random
9
 
10
- # Disable all Streamlit animations and behaviors that might cause movement
11
  st.set_page_config(
12
  page_title="Math Adventure Land",
13
  layout="wide",
14
  initial_sidebar_state="expanded"
15
  )
16
 
17
- # MINIMAL CSS - NO GRADIENTS, NO ANIMATIONS, NO EFFECTS
18
  st.markdown("""
19
  <style>
20
- /* DISABLE ALL ANIMATIONS AND TRANSITIONS GLOBALLY */
21
- * {
22
- animation: none !important;
23
- transition: none !important;
24
- transform: none !important;
25
- -webkit-animation: none !important;
26
- -webkit-transition: none !important;
27
- -webkit-transform: none !important;
28
- -moz-animation: none !important;
29
- -moz-transition: none !important;
30
- -moz-transform: none !important;
31
- }
32
 
33
- /* DISABLE STREAMLIT BUILT-IN ANIMATIONS */
34
- .stApp {
35
- animation: none !important;
36
- }
37
-
38
- /* SIMPLE STATIC COLORS */
39
  .main-container {
40
- background: #FF6B6B;
41
  padding: 20px;
42
  border-radius: 25px;
43
  border: 8px dashed #FFD93D;
@@ -46,8 +31,9 @@ st.markdown("""
46
 
47
  .fun-title {
48
  font-size: 50px;
49
- color: white;
50
  text-align: center;
 
51
  margin-bottom: 30px;
52
  }
53
 
@@ -55,8 +41,9 @@ st.markdown("""
55
  border: 6px dotted #FF6B6B;
56
  padding: 25px;
57
  border-radius: 25px;
58
- background-color: white;
59
  font-size: 22px;
 
60
  margin: 20px 0;
61
  }
62
 
@@ -67,6 +54,8 @@ st.markdown("""
67
  border-radius: 15px;
68
  padding: 12px 25px;
69
  border: none;
 
 
70
  }
71
 
72
  .stTextInput > div > input {
@@ -74,6 +63,7 @@ st.markdown("""
74
  border-radius: 15px;
75
  border: 3px solid #4ECDC4;
76
  padding: 15px;
 
77
  }
78
 
79
  .progress-bar {
@@ -97,11 +87,12 @@ st.markdown("""
97
  }
98
 
99
  .help-box {
100
- background: white;
101
  padding: 20px;
102
  border-radius: 15px;
103
  border: 3px solid #FFD93D;
104
  margin-bottom: 20px;
 
105
  }
106
 
107
  .completion-message {
@@ -120,46 +111,32 @@ st.markdown("""
120
  text-align: center;
121
  margin: 10px 0;
122
  }
123
- </style>
124
- """, unsafe_allow_html=True)
125
-
126
- # NO JAVASCRIPT - completely removed
127
- st.markdown("""
128
- <script>
129
- function startAutoProgression(seconds) {
130
- let timeLeft = seconds;
131
- const countdownElement = document.getElementById('countdown-timer');
132
 
133
- const timer = setInterval(() => {
134
- if (countdownElement) {
135
- countdownElement.textContent = 'Next adventure in: ' + timeLeft + ' seconds';
136
- }
137
- timeLeft--;
138
-
139
- if (timeLeft < 0) {
140
- clearInterval(timer);
141
- window.location.reload();
142
- }
143
- }, 1000);
144
- }
145
- </script>
146
  """, unsafe_allow_html=True)
147
 
148
- # Initialize session state
149
  def initialize_session_state():
150
  if 'app_initialized' not in st.session_state:
151
  st.session_state.app_initialized = True
152
  st.session_state.temp_dir = tempfile.mkdtemp()
153
- st.session_state.age_group = None
154
- st.session_state.category = None
155
- st.session_state.question_index = 0
156
- st.session_state.show_answer = False
157
- st.session_state.show_steps = False
158
  st.session_state.auto_progress = True
 
 
 
 
159
 
 
160
  initialize_session_state()
161
 
162
- # SIMPLE STATIC WELCOME
163
  st.markdown("""
164
  <div class="main-container">
165
  <div class="animal-characters">
@@ -170,105 +147,139 @@ st.markdown("""
170
  <span>🐯</span>
171
  </div>
172
  <div class="fun-title">
173
- Math Adventure Land
174
  </div>
175
- <div style="text-align: center; font-size: 24px; color: white;">
176
- Learn Math with Fun!
177
  </div>
178
  </div>
179
  """, unsafe_allow_html=True)
180
 
181
  # Age group setup
182
  age_groups = {
183
- "Little Explorers (4-6)": {"dataset": "src/Datase_of_4-6_Age_Group.xlsx", "zip_file": "src/Image_for_group_4-6.zip", "image_folder": "Image_for_group_4-6"},
184
- "Math Adventurers (7-9)": {"dataset": "src/Datase_of_7-9_Age_Group.xlsx", "zip_file": "src/Image_for_group_7-9.zip", "image_folder": "Image_for_group_7-9"},
185
- "Math Wizards (13-15)": {"dataset": "src/Datase_of_13-15_Age_Group.xlsx", "zip_file": "src/Image_for_group_13-15.zip", "image_folder": "Image_for_group_13-15"}
186
  }
187
 
188
- # SIDEBAR
189
  with st.sidebar:
190
- st.markdown("### Quick Help")
191
 
192
  st.markdown("""
193
  <div class="help-box">
194
  <h4>How to Play:</h4>
195
  <p>1. Choose your age group<br>
196
  2. Pick a math category<br>
197
- 3. Solve the problems<br>
198
- 4. Get feedback</p>
199
  </div>
200
  """, unsafe_allow_html=True)
201
 
202
- auto_progress = st.toggle("Auto-Progress", value=st.session_state.auto_progress)
 
 
 
203
 
204
  if auto_progress != st.session_state.auto_progress:
205
  st.session_state.auto_progress = auto_progress
 
 
 
 
 
 
 
 
 
206
 
207
- # MAIN CONTENT
208
  col1, col2 = st.columns([3, 1])
209
 
210
  with col1:
211
- selected_age_group = st.selectbox("Choose Age Group:", list(age_groups.keys()))
 
 
 
 
212
 
213
- # Reset on age group change
214
- if st.session_state.age_group != selected_age_group:
215
- st.session_state.age_group = selected_age_group
216
- st.session_state.category = None
217
- st.session_state.question_index = 0
218
- st.session_state.show_answer = False
219
- st.session_state.show_steps = False
 
 
 
 
220
 
221
- # Load dataset
222
- group_info = age_groups[selected_age_group]
223
- dataset_path = group_info["dataset"]
224
- zip_path = group_info["zip_file"]
225
- image_folder = group_info["image_folder"]
 
 
 
 
 
 
 
 
 
226
 
227
- # Create image folder
228
- temp_image_folder = os.path.join(st.session_state.temp_dir, image_folder)
229
- os.makedirs(temp_image_folder, exist_ok=True)
230
 
231
- # Extract images if zip exists
232
- try:
233
- if os.path.exists(zip_path):
234
- with zipfile.ZipFile(zip_path, "r") as zip_ref:
235
- zip_ref.extractall(temp_image_folder)
236
- except Exception as e:
237
- pass # Silent fail
238
 
239
- if not os.path.exists(dataset_path):
240
- st.error(f"Dataset not found: {dataset_path}")
241
- st.stop()
242
 
243
- try:
244
- df = pd.read_excel(dataset_path)
245
- df['category'] = df['category'].astype(str).str.strip()
246
- except Exception as e:
247
- st.error(f"Error loading dataset: {e}")
248
- st.stop()
 
 
249
 
250
- categories = sorted(df['category'].dropna().unique())
251
- selected_category = st.selectbox("Choose Math Category:", options=categories)
 
252
 
253
  # Update session if category changes
254
- if st.session_state.category != selected_category:
255
- st.session_state.category = selected_category
256
- st.session_state.question_index = 0
257
- st.session_state.show_answer = False
258
- st.session_state.show_steps = False
 
259
 
260
- # Filter questions
261
- subset_df = df[df['category'] == selected_category].reset_index(drop=True)
262
 
263
- if not subset_df.empty and st.session_state.question_index < len(subset_df):
264
- question = subset_df.iloc[st.session_state.question_index]
265
- progress = int((st.session_state.question_index / len(subset_df)) * 100)
 
266
 
267
- # Progress bar
268
  st.markdown(f"""
269
  <div style="text-align: center; margin: 20px 0;">
270
- <div style="color: #FF6B6B; font-size: 18px;">
271
- Progress: {st.session_state.question_index + 1} of {len(subset_df)}
272
  </div>
273
  <div class="progress-bar">
274
  <div class="progress-fill" style="width: {progress}%;"></div>
@@ -276,21 +287,23 @@ with col1:
276
  </div>
277
  """, unsafe_allow_html=True)
278
 
279
- # Display question
 
280
  st.markdown(f"""
281
  <div class="question-box">
282
  <div style="text-align: center; font-size: 30px; margin-bottom: 15px;">
283
- Challenge {st.session_state.question_index + 1}
284
  </div>
285
- <b>Question:</b><br><br>
286
  {question['problem']}
287
  </div>
288
  """, unsafe_allow_html=True)
289
 
290
- # Display image
291
  if pd.notna(question.get('image')):
292
  image_name = str(question['image']).strip()
293
  image_found = False
 
294
  for root, _, files in os.walk(temp_image_folder):
295
  for file in files:
296
  if file.lower().startswith(image_name.lower()) or os.path.splitext(file)[0].lower() == image_name.lower():
@@ -300,85 +313,133 @@ with col1:
300
  break
301
  except:
302
  pass
 
 
303
 
304
  # Answer input
305
- user_ans = st.text_input("Your Answer:", key=f"ans_{st.session_state.question_index}")
306
 
307
  # Action buttons
308
  col_btn1, col_btn2, col_btn3 = st.columns([1, 1, 1])
309
 
310
  with col_btn1:
311
- if st.button("Submit Answer", key=f"submit_{st.session_state.question_index}", use_container_width=True):
 
312
  if str(user_ans).strip().lower() == str(question['answer']).strip().lower():
 
313
  st.success("CORRECT! Great job!")
314
- time.sleep(1)
315
- st.session_state.question_index += 1
316
- st.session_state.show_answer = False
317
- st.session_state.show_steps = False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
  st.rerun()
319
  else:
320
- st.error("Try again!")
321
- st.session_state.show_answer = True
 
322
 
323
  with col_btn2:
324
- if st.button("Show Hint", key=f"hint_{st.session_state.question_index}", use_container_width=True):
325
- st.session_state.show_answer = True
 
 
326
 
327
  with col_btn3:
328
- if st.button("Skip", key=f"skip_{st.session_state.question_index}", use_container_width=True):
329
- st.session_state.question_index += 1
330
- st.session_state.show_answer = False
331
- st.session_state.show_steps = False
 
 
 
332
  st.rerun()
333
 
334
  # Show answer
335
- if st.session_state.show_answer:
336
- st.info(f"Answer: {question['answer']}")
 
 
 
 
 
 
 
337
 
338
  elif subset_df.empty:
339
- st.warning("No questions in this category.")
340
  else:
341
- # Completion message
342
  st.markdown("""
343
  <div class="completion-message">
344
- <h1>CONGRATULATIONS!</h1>
345
- <p>You completed all challenges!</p>
 
 
 
 
346
  </div>
347
  """, unsafe_allow_html=True)
348
 
 
349
  if st.session_state.auto_progress:
350
  st.markdown("""
351
- <div class="countdown" id="countdown-timer">
352
- Next category in: 5 seconds
353
  </div>
354
- <script>
355
- startAutoProgression(5);
356
- </script>
357
  """, unsafe_allow_html=True)
 
358
  time.sleep(5)
359
- st.session_state.question_index = 0
360
- st.session_state.show_answer = False
361
- st.session_state.show_steps = False
362
- current_idx = categories.index(selected_category)
363
- if current_idx < len(categories) - 1:
364
- st.session_state.category = categories[current_idx + 1]
 
 
365
  else:
366
- st.session_state.category = categories[0]
 
367
  st.rerun()
368
  else:
369
- if st.button("Start New Adventure"):
370
- st.session_state.question_index = 0
371
- st.session_state.show_answer = False
372
- st.session_state.show_steps = False
 
373
  st.rerun()
374
 
375
  with col2:
 
 
 
 
 
 
 
376
  st.markdown("### Progress")
377
  if not subset_df.empty:
378
- completed = min(st.session_state.question_index, len(subset_df))
379
  st.metric("Completed", f"{completed}/{len(subset_df)}")
380
 
381
- # Cleanup
382
  def cleanup():
383
  import shutil
384
  if 'temp_dir' in st.session_state and os.path.exists(st.session_state.temp_dir):
 
1
+ import altair as alt
2
  import streamlit as st
3
  import pandas as pd
4
  import os
5
  import zipfile
6
  from PIL import Image
7
+ import sympy as sp
8
  import time
9
  import tempfile
10
  import random
11
 
12
+ # Page config with optimized settings
13
  st.set_page_config(
14
  page_title="Math Adventure Land",
15
  layout="wide",
16
  initial_sidebar_state="expanded"
17
  )
18
 
19
+ # COMPLETELY CLEAN CSS - NO ANIMATIONS, NO MOVEMENTS, NO TRANSITIONS
20
  st.markdown("""
21
  <style>
22
+ @import url('https://fonts.googleapis.com/css2?family=Comic+Neue:wght@700&display=swap');
 
 
 
 
 
 
 
 
 
 
 
23
 
 
 
 
 
 
 
24
  .main-container {
25
+ background: linear-gradient(45deg, #FF6B6B, #4ECDC4, #45B7D1, #96CEB4, #FFEAA7);
26
  padding: 20px;
27
  border-radius: 25px;
28
  border: 8px dashed #FFD93D;
 
31
 
32
  .fun-title {
33
  font-size: 50px;
34
+ color: #FF6B6B;
35
  text-align: center;
36
+ font-family: 'Comic Neue', cursive;
37
  margin-bottom: 30px;
38
  }
39
 
 
41
  border: 6px dotted #FF6B6B;
42
  padding: 25px;
43
  border-radius: 25px;
44
+ background-color: rgba(255, 255, 255, 0.9);
45
  font-size: 22px;
46
+ font-family: 'Comic Neue', cursive;
47
  margin: 20px 0;
48
  }
49
 
 
54
  border-radius: 15px;
55
  padding: 12px 25px;
56
  border: none;
57
+ font-family: 'Comic Neue', cursive;
58
+ font-weight: bold;
59
  }
60
 
61
  .stTextInput > div > input {
 
63
  border-radius: 15px;
64
  border: 3px solid #4ECDC4;
65
  padding: 15px;
66
+ font-family: 'Comic Neue', cursive;
67
  }
68
 
69
  .progress-bar {
 
87
  }
88
 
89
  .help-box {
90
+ background: rgba(255, 255, 255, 0.95);
91
  padding: 20px;
92
  border-radius: 15px;
93
  border: 3px solid #FFD93D;
94
  margin-bottom: 20px;
95
+ font-family: 'Comic Neue', cursive;
96
  }
97
 
98
  .completion-message {
 
111
  text-align: center;
112
  margin: 10px 0;
113
  }
 
 
 
 
 
 
 
 
 
114
 
115
+ /* DISABLE ALL ANIMATIONS GLOBALLY */
116
+ * {
117
+ animation: none !important;
118
+ transition: none !important;
119
+ transform: none !important;
120
+ }
121
+ </style>
 
 
 
 
 
 
122
  """, unsafe_allow_html=True)
123
 
124
+ # Initialize session state with proper age group management
125
  def initialize_session_state():
126
  if 'app_initialized' not in st.session_state:
127
  st.session_state.app_initialized = True
128
  st.session_state.temp_dir = tempfile.mkdtemp()
129
+ st.session_state.last_activity = time.time()
 
 
 
 
130
  st.session_state.auto_progress = True
131
+
132
+ # Initialize age group specific states
133
+ st.session_state.current_age_group = None
134
+ st.session_state.age_group_states = {}
135
 
136
+ # Initialize the app
137
  initialize_session_state()
138
 
139
+ # COMPLETELY STABLE WELCOME - NO MOVEMENT AT ALL
140
  st.markdown("""
141
  <div class="main-container">
142
  <div class="animal-characters">
 
147
  <span>🐯</span>
148
  </div>
149
  <div class="fun-title">
150
+ Welcome to Math Adventure Land!
151
  </div>
152
+ <div style="text-align: center; font-size: 24px; color: #FF6B6B; font-family: 'Comic Neue', cursive;">
153
+ Where Numbers Become Friends!
154
  </div>
155
  </div>
156
  """, unsafe_allow_html=True)
157
 
158
  # Age group setup
159
  age_groups = {
160
+ "πŸ‘Ά Little Explorers (4-6)": {"dataset": "src/Datase_of_4-6_Age_Group.xlsx", "zip_file": "src/Image_for_group_4-6.zip", "image_folder": "Image_for_group_4-6", "emoji": "πŸ‘Ά"},
161
+ "πŸš€ Math Adventurers (7-9)": {"dataset": "src/Datase_of_7-9_Age_Group.xlsx", "zip_file": "src/Image_for_group_7-9.zip", "image_folder": "Image_for_group_7-9", "emoji": "πŸš€"},
162
+ "🌟 Math Wizards (13-15)": {"dataset": "src/Datase_of_13-15_Age_Group.xlsx", "zip_file": "src/Image_for_group_13-15.zip", "image_folder": "Image_for_group_13-15", "emoji": "🌟"}
163
  }
164
 
165
+ # SIDEBAR - Clean and stable
166
  with st.sidebar:
167
+ st.markdown("### Quick Help Guide")
168
 
169
  st.markdown("""
170
  <div class="help-box">
171
  <h4>How to Play:</h4>
172
  <p>1. Choose your age group<br>
173
  2. Pick a math category<br>
174
+ 3. Solve the fun problems!<br>
175
+ 4. Get instant feedback</p>
176
  </div>
177
  """, unsafe_allow_html=True)
178
 
179
+ # Auto-progress toggle
180
+ st.markdown("### Settings")
181
+ auto_progress = st.toggle("Auto-Progress", value=st.session_state.auto_progress,
182
+ help="Automatically move to next category when finished")
183
 
184
  if auto_progress != st.session_state.auto_progress:
185
  st.session_state.auto_progress = auto_progress
186
+ st.rerun()
187
+
188
+ st.markdown("### Achievement Tips")
189
+ st.info("""
190
+ Pro Tips:
191
+ - Take your time with each problem
192
+ - Use the hints when you need help
193
+ - Practice makes perfect!
194
+ """)
195
 
196
+ # MAIN CONTENT AREA
197
  col1, col2 = st.columns([3, 1])
198
 
199
  with col1:
200
+ # Update activity timestamp
201
+ st.session_state.last_activity = time.time()
202
+
203
+ # Age group selection
204
+ selected_age_group = st.selectbox("Choose Your Adventure Level:", list(age_groups.keys()))
205
 
206
+ # Initialize or get age group state
207
+ if selected_age_group not in st.session_state.age_group_states:
208
+ st.session_state.age_group_states[selected_age_group] = {
209
+ 'category': None,
210
+ 'question_index': 0,
211
+ 'show_answer': False,
212
+ 'show_steps': False,
213
+ 'df_loaded': False,
214
+ 'df': None,
215
+ 'categories': []
216
+ }
217
 
218
+ # Get current age group state
219
+ age_state = st.session_state.age_group_states[selected_age_group]
220
+
221
+ # Reset if age group changed
222
+ if st.session_state.current_age_group != selected_age_group:
223
+ st.session_state.current_age_group = selected_age_group
224
+ # Don't reset the state, just use the stored state for this age group
225
+
226
+ # Load dataset if not already loaded for this age group
227
+ if not age_state['df_loaded']:
228
+ group_info = age_groups[selected_age_group]
229
+ dataset_path = group_info["dataset"]
230
+ zip_path = group_info["zip_file"]
231
+ image_folder = group_info["image_folder"]
232
 
233
+ # Create image folder in temp directory
234
+ temp_image_folder = os.path.join(st.session_state.temp_dir, image_folder)
235
+ os.makedirs(temp_image_folder, exist_ok=True)
236
 
237
+ # Extract images if zip exists
238
+ try:
239
+ if os.path.exists(zip_path):
240
+ with zipfile.ZipFile(zip_path, "r") as zip_ref:
241
+ zip_ref.extractall(temp_image_folder)
242
+ except Exception as e:
243
+ st.warning(f"Could not extract images: {e}")
244
 
245
+ if not os.path.exists(dataset_path):
246
+ st.error(f"Dataset not found: {dataset_path}")
247
+ st.stop()
248
 
249
+ try:
250
+ age_state['df'] = pd.read_excel(dataset_path)
251
+ age_state['df']['category'] = age_state['df']['category'].astype(str).str.strip()
252
+ age_state['categories'] = sorted(age_state['df']['category'].dropna().unique())
253
+ age_state['df_loaded'] = True
254
+ except Exception as e:
255
+ st.error(f"Error loading dataset: {e}")
256
+ st.stop()
257
 
258
+ # Category selection
259
+ category_emojis = {"Addition": "+", "Subtraction": "-", "Multiplication": "Γ—", "Division": "Γ·", "Geometry": "πŸ“", "Algebra": "πŸ“Š"}
260
+ selected_category = st.selectbox("Choose Your Math Quest:", options=age_state['categories'])
261
 
262
  # Update session if category changes
263
+ if age_state['category'] != selected_category:
264
+ age_state['category'] = selected_category
265
+ age_state['question_index'] = 0
266
+ age_state['show_answer'] = False
267
+ age_state['show_steps'] = False
268
+ st.rerun()
269
 
270
+ # Filter questions by selected category only
271
+ subset_df = age_state['df'][age_state['df']['category'] == selected_category].reset_index(drop=True)
272
 
273
+ # MATH QUESTIONS SECTION
274
+ if not subset_df.empty and age_state['question_index'] < len(subset_df):
275
+ question = subset_df.iloc[age_state['question_index']]
276
+ progress = int((age_state['question_index'] / len(subset_df)) * 100)
277
 
278
+ # Progress bar - NO ANIMATIONS
279
  st.markdown(f"""
280
  <div style="text-align: center; margin: 20px 0;">
281
+ <div style="font-family: 'Comic Neue', cursive; color: #FF6B6B; font-size: 18px;">
282
+ Progress: {age_state['question_index'] + 1} of {len(subset_df)}
283
  </div>
284
  <div class="progress-bar">
285
  <div class="progress-fill" style="width: {progress}%;"></div>
 
287
  </div>
288
  """, unsafe_allow_html=True)
289
 
290
+ # Display question - NO ANIMATIONS
291
+ category_emoji = category_emojis.get(selected_category, "?")
292
  st.markdown(f"""
293
  <div class="question-box">
294
  <div style="text-align: center; font-size: 30px; margin-bottom: 15px;">
295
+ Challenge {age_state['question_index'] + 1}
296
  </div>
297
+ <b>Math Quest:</b><br><br>
298
  {question['problem']}
299
  </div>
300
  """, unsafe_allow_html=True)
301
 
302
+ # Display image with error handling
303
  if pd.notna(question.get('image')):
304
  image_name = str(question['image']).strip()
305
  image_found = False
306
+ temp_image_folder = os.path.join(st.session_state.temp_dir, age_groups[selected_age_group]["image_folder"])
307
  for root, _, files in os.walk(temp_image_folder):
308
  for file in files:
309
  if file.lower().startswith(image_name.lower()) or os.path.splitext(file)[0].lower() == image_name.lower():
 
313
  break
314
  except:
315
  pass
316
+ if not image_found:
317
+ st.warning("Image not available")
318
 
319
  # Answer input
320
+ user_ans = st.text_input("Your Answer:", key=f"ans_{selected_age_group}_{selected_category}_{age_state['question_index']}")
321
 
322
  # Action buttons
323
  col_btn1, col_btn2, col_btn3 = st.columns([1, 1, 1])
324
 
325
  with col_btn1:
326
+ if st.button("Submit Answer", key=f"submit_{selected_age_group}_{selected_category}_{age_state['question_index']}", use_container_width=True):
327
+ st.session_state.last_activity = time.time()
328
  if str(user_ans).strip().lower() == str(question['answer']).strip().lower():
329
+ # SIMPLE SUCCESS MESSAGE - NO ANIMATIONS
330
  st.success("CORRECT! Great job!")
331
+
332
+ success_messages = [
333
+ "You're a math superstar!",
334
+ "Excellent work!",
335
+ "Brilliant answer!",
336
+ "Perfect!",
337
+ "Outstanding!"
338
+ ]
339
+
340
+ st.markdown(f"""
341
+ <div style="text-align: center; font-size: 24px; color: #FF6B6B; font-family: 'Comic Neue', cursive; padding: 20px;">
342
+ {random.choice(success_messages)}
343
+ </div>
344
+ """, unsafe_allow_html=True)
345
+
346
+ # Wait 2 seconds then continue
347
+ time.sleep(2)
348
+ age_state['question_index'] += 1
349
+ age_state['show_answer'] = False
350
+ age_state['show_steps'] = False
351
+ st.session_state.last_activity = time.time()
352
  st.rerun()
353
  else:
354
+ st.error("Not quite right. Try again!")
355
+ age_state['show_answer'] = True
356
+ age_state['show_steps'] = False
357
 
358
  with col_btn2:
359
+ if st.button("Show Hint", key=f"hint_{selected_age_group}_{selected_category}_{age_state['question_index']}", use_container_width=True):
360
+ st.session_state.last_activity = time.time()
361
+ age_state['show_answer'] = True
362
+ st.info("Need some help? Here's the answer below!")
363
 
364
  with col_btn3:
365
+ if st.button("Skip", key=f"skip_{selected_age_group}_{selected_category}_{age_state['question_index']}", use_container_width=True):
366
+ st.session_state.last_activity = time.time()
367
+ age_state['question_index'] += 1
368
+ age_state['show_answer'] = False
369
+ age_state['show_steps'] = False
370
+ st.info("Moving to next challenge...")
371
+ time.sleep(1)
372
  st.rerun()
373
 
374
  # Show answer
375
+ if age_state['show_answer']:
376
+ st.info(f"Correct Answer: {question['answer']}")
377
+
378
+ if selected_age_group in ["πŸš€ Math Adventurers (7-9)", "🌟 Math Wizards (13-15)"]:
379
+ if st.button("Show Steps", key=f"steps_{selected_age_group}_{selected_category}_{age_state['question_index']}"):
380
+ st.session_state.last_activity = time.time()
381
+ age_state['show_steps'] = True
382
+ if age_state['show_steps'] and pd.notna(question.get("steps", None)):
383
+ st.success(f"Step-by-Step Solution:\n{question['steps']}")
384
 
385
  elif subset_df.empty:
386
+ st.warning("No questions available in this category. Try another one!")
387
  else:
388
+ # COMPLETION MESSAGE - NO ANIMATIONS
389
  st.markdown("""
390
  <div class="completion-message">
391
+ <h1 style="font-family: 'Comic Neue', cursive;">
392
+ CONGRATULATIONS!
393
+ </h1>
394
+ <p style="font-size: 24px;">
395
+ You've completed all challenges in this category!
396
+ </p>
397
  </div>
398
  """, unsafe_allow_html=True)
399
 
400
+ # Auto-progress logic
401
  if st.session_state.auto_progress:
402
  st.markdown("""
403
+ <div class="countdown">
404
+ Next adventure starting in: 5 seconds
405
  </div>
 
 
 
406
  """, unsafe_allow_html=True)
407
+
408
  time.sleep(5)
409
+ age_state['question_index'] = 0
410
+ age_state['show_answer'] = False
411
+ age_state['show_steps'] = False
412
+
413
+ # Move to next category
414
+ current_idx = age_state['categories'].index(selected_category)
415
+ if current_idx < len(age_state['categories']) - 1:
416
+ age_state['category'] = age_state['categories'][current_idx + 1]
417
  else:
418
+ age_state['category'] = age_state['categories'][0]
419
+
420
  st.rerun()
421
  else:
422
+ if st.button("Start New Adventure", use_container_width=True):
423
+ st.session_state.last_activity = time.time()
424
+ age_state['question_index'] = 0
425
+ age_state['show_answer'] = False
426
+ age_state['show_steps'] = False
427
  st.rerun()
428
 
429
  with col2:
430
+ st.markdown("### Fun Zone")
431
+ st.markdown("""
432
+ <div style="text-align: center; font-size: 40px; margin: 20px 0;">
433
+ πŸŽͺ<br>✨<br>🌟
434
+ </div>
435
+ """, unsafe_allow_html=True)
436
+
437
  st.markdown("### Progress")
438
  if not subset_df.empty:
439
+ completed = min(age_state['question_index'], len(subset_df))
440
  st.metric("Completed", f"{completed}/{len(subset_df)}")
441
 
442
+ # Cleanup function
443
  def cleanup():
444
  import shutil
445
  if 'temp_dir' in st.session_state and os.path.exists(st.session_state.temp_dir):