NSamson1 commited on
Commit
71797be
ยท
verified ยท
1 Parent(s): b6e28f4

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +336 -174
src/streamlit_app.py CHANGED
@@ -9,8 +9,12 @@ import time
9
  import tempfile
10
  import random
11
 
12
- # Page config
13
- st.set_page_config(page_title="๐ŸŽช Math Adventure Land", layout="wide")
 
 
 
 
14
 
15
  # Custom CSS with LOTS of fun animations and styles
16
  st.markdown("""
@@ -137,7 +141,7 @@ st.markdown("""
137
  }
138
 
139
  .calc-btn {
140
- padding: 10px 5px;
141
  border: none;
142
  border-radius: 8px;
143
  cursor: pointer;
@@ -147,6 +151,7 @@ st.markdown("""
147
  transition: all 0.2s ease;
148
  font-family: 'Comic Neue', cursive;
149
  font-weight: bold;
 
150
  }
151
 
152
  .calc-btn:hover {
@@ -164,7 +169,6 @@ st.markdown("""
164
 
165
  .calc-btn-equals {
166
  background: linear-gradient(45deg, #96CEB4, #4ECDC4);
167
- grid-column: span 2;
168
  }
169
 
170
  .calc-btn-zero {
@@ -219,58 +223,259 @@ st.markdown("""
219
  animation: bounce 2s infinite;
220
  }
221
 
222
- /* Sidebar styling */
223
- .sidebar-content {
224
- padding: 10px;
225
  }
226
 
227
- /* Main content area */
228
- .main-content {
229
- padding: 20px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  }
231
  </style>
232
  """, unsafe_allow_html=True)
233
 
234
- # JavaScript for animations and calculator
235
  st.markdown("""
236
  <script>
237
- // Celebration functions
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  function createEmojiRain() {
239
- const emojis = ['๐ŸŽ‰', '๐ŸŽˆ', 'โญ', '๐ŸŽŠ', '๐ŸŒˆ', '๐Ÿš€', '๐ŸŽจ', '๐Ÿฑ', '๐Ÿถ', '๐Ÿฆ„'];
240
  const container = document.createElement('div');
241
- container.className = 'emoji-rain';
242
  document.body.appendChild(container);
243
 
244
- for (let i = 0; i < 50; i++) {
 
 
245
  setTimeout(() => {
246
  const emoji = document.createElement('div');
247
  emoji.className = 'emoji';
248
  emoji.textContent = emojis[Math.floor(Math.random() * emojis.length)];
249
  emoji.style.left = Math.random() * 100 + 'vw';
250
- emoji.style.animationDuration = (Math.random() * 3 + 2) + 's';
251
  container.appendChild(emoji);
252
-
253
- setTimeout(() => emoji.remove(), 5000);
254
  }, i * 100);
255
  }
256
 
257
- setTimeout(() => container.remove(), 6000);
 
 
258
  }
259
 
260
  function createConfetti() {
 
 
 
 
261
  const colors = ['#FF6B6B', '#4ECDC4', '#FFD93D', '#45B7D1', '#96CEB4'];
262
- for (let i = 0; i < 150; i++) {
 
263
  setTimeout(() => {
264
  const confetti = document.createElement('div');
265
  confetti.className = 'confetti';
266
  confetti.style.background = colors[Math.floor(Math.random() * colors.length)];
267
  confetti.style.left = Math.random() * 100 + 'vw';
268
  confetti.style.animationDuration = (Math.random() * 2 + 1) + 's';
269
- document.body.appendChild(confetti);
270
-
271
- setTimeout(() => confetti.remove(), 3000);
272
- }, i * 10);
273
  }
 
 
 
 
274
  }
275
 
276
  function celebrate() {
@@ -278,129 +483,53 @@ function celebrate() {
278
  createConfetti();
279
  }
280
 
281
- // Calculator functionality
282
- let currentInput = '0';
283
- let previousInput = '';
284
- let operation = null;
285
- let resetScreen = false;
286
-
287
- function updateDisplay() {
288
- const display = document.getElementById('calc-display');
289
- if (display) {
290
- display.value = currentInput;
291
- }
292
- }
293
-
294
- function appendNumber(number) {
295
- if (currentInput === '0' || resetScreen) {
296
- currentInput = number;
297
- resetScreen = false;
298
- } else {
299
- currentInput += number;
300
- }
301
- updateDisplay();
302
- }
303
-
304
- function chooseOperation(op) {
305
- if (currentInput === '') return;
306
-
307
- if (previousInput !== '') {
308
- compute();
309
- }
310
- operation = op;
311
- previousInput = currentInput;
312
- resetScreen = true;
313
- }
314
-
315
- function compute() {
316
- let computation;
317
- const prev = parseFloat(previousInput);
318
- const current = parseFloat(currentInput);
319
-
320
- if (isNaN(prev) || isNaN(current)) return;
321
-
322
- switch (operation) {
323
- case '+':
324
- computation = prev + current;
325
- break;
326
- case '-':
327
- computation = prev - current;
328
- break;
329
- case '*':
330
- computation = prev * current;
331
- break;
332
- case '/':
333
- computation = prev / current;
334
- break;
335
- default:
336
- return;
337
- }
338
-
339
- currentInput = computation.toString();
340
- operation = undefined;
341
- previousInput = '';
342
- resetScreen = true;
343
- updateDisplay();
344
-
345
- // Mini celebration for big results
346
- if (Math.abs(computation) > 1000) {
347
- const miniEmoji = document.createElement('div');
348
- miniEmoji.textContent = '๐ŸŽ‰';
349
- miniEmoji.style.position = 'fixed';
350
- miniEmoji.style.fontSize = '20px';
351
- miniEmoji.style.left = Math.random() * 100 + 'vw';
352
- miniEmoji.style.animation = 'fall 2s linear forwards';
353
- document.body.appendChild(miniEmoji);
354
- setTimeout(() => miniEmoji.remove(), 2000);
355
  }
356
- }
357
-
358
- function clearCalculator() {
359
- currentInput = '0';
360
- previousInput = '';
361
- operation = null;
362
- updateDisplay();
363
- }
364
 
365
- function appendDecimal() {
366
- if (resetScreen) {
367
- currentInput = '0';
368
- resetScreen = false;
369
- }
370
- if (!currentInput.includes('.')) {
371
- currentInput += '.';
372
- }
373
- updateDisplay();
374
- }
375
-
376
- // Initialize calculator
377
- document.addEventListener('DOMContentLoaded', function() {
378
- updateDisplay();
379
- });
380
  </script>
381
  """, unsafe_allow_html=True)
382
 
383
- # Welcome title with fun characters
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
  st.markdown("""
385
  <div class="main-container">
386
  <div class="animal-characters">
387
- <span>๐Ÿฑ</span>
388
- <span>๐Ÿถ</span>
389
- <span>๐Ÿฆ„</span>
390
- <span>๐Ÿผ</span>
391
- <span>๐Ÿฏ</span>
 
 
 
392
  </div>
393
- <div class="fun-title">๐ŸŽช Welcome to Math Adventure Land! ๐ŸŽช</div>
394
  <div style="text-align: center; font-size: 24px; color: #FF6B6B; font-family: 'Comic Neue', cursive;">
395
- Where Numbers Become Friends! ๐Ÿค—
396
  </div>
397
  </div>
398
  """, unsafe_allow_html=True)
399
 
400
- # Initialize session state for temp directory
401
- if 'temp_dir' not in st.session_state:
402
- st.session_state.temp_dir = tempfile.mkdtemp()
403
-
404
  # Age group setup with fun descriptions
405
  age_groups = {
406
  "๐Ÿ‘ถ 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": "๐Ÿ‘ถ"},
@@ -413,62 +542,80 @@ with st.sidebar:
413
  st.markdown("### ๐Ÿงฎ Math Helper Calculator")
414
  st.markdown("Use this calculator to help with your math problems! โœจ")
415
 
416
- # Compact Calculator
417
  st.markdown("""
418
  <div class="calculator-container">
419
  <div class="calculator-title">โœจ Magic Calculator โœจ</div>
420
  <input type="text" id="calc-display" class="calculator-display" readonly value="0">
421
 
422
  <div class="calculator-buttons-compact">
423
- <button class="calc-btn calc-btn-clear" onclick="clearCalculator()">C</button>
424
- <button class="calc-btn calc-btn-clear" onclick="currentInput = currentInput.slice(0, -1) || '0'; updateDisplay();">โŒซ</button>
425
- <button class="calc-btn" onclick="chooseOperation('/')">/</button>
426
- <button class="calc-btn" onclick="chooseOperation('*')">ร—</button>
 
427
 
428
- <button class="calc-btn" onclick="appendNumber('7')">7</button>
429
- <button class="calc-btn" onclick="appendNumber('8')">8</button>
430
- <button class="calc-btn" onclick="appendNumber('9')">9</button>
431
- <button class="calc-btn" onclick="chooseOperation('-')">-</button>
 
432
 
433
- <button class="calc-btn" onclick="appendNumber('4')">4</button>
434
- <button class="calc-btn" onclick="appendNumber('5')">5</button>
435
- <button class="calc-btn" onclick="appendNumber('6')">6</button>
436
- <button class="calc-btn" onclick="chooseOperation('+')">+</button>
 
437
 
438
- <button class="calc-btn" onclick="appendNumber('1')">1</button>
439
- <button class="calc-btn" onclick="appendNumber('2')">2</button>
440
- <button class="calc-btn" onclick="appendNumber('3')">3</button>
441
- <button class="calc-btn calc-btn-equals" onclick="compute()" rowspan="2">=</button>
 
442
 
443
- <button class="calc-btn calc-btn-zero" onclick="appendNumber('0')">0</button>
444
- <button class="calc-btn" onclick="appendDecimal()">.</button>
 
445
  </div>
446
  </div>
447
  """, unsafe_allow_html=True)
448
 
449
  st.markdown("---")
450
- st.markdown("### ๐ŸŽฏ Quick Tips")
 
 
 
 
 
 
 
 
 
 
 
 
 
451
  st.info("""
452
- ๐Ÿ’ก **Calculator Help:**
453
  - Click numbers and operators
454
  - Press = to calculate
455
- - Press C to clear
456
- - Use backspace (โŒซ) to erase
 
457
  """)
458
-
459
- st.markdown("---")
460
- st.markdown("### ๐Ÿ“š Need Help?")
461
- st.write("Stuck on a problem? Use the calculator above or ask for hints! ๐Ÿฆธ")
462
 
463
  # MAIN CONTENT AREA
464
  col1, col2 = st.columns([3, 1])
465
 
466
  with col1:
 
 
 
467
  # Age group selection
468
  selected_age_group = st.selectbox("๐ŸŽฏ Choose Your Adventure Level:", list(age_groups.keys()))
469
 
470
  # Initialize session
471
- if "session_initialized" not in st.session_state or st.session_state.age_group != selected_age_group:
472
  st.session_state.age_group = selected_age_group
473
  st.session_state.category = None
474
  st.session_state.question_index = 0
@@ -526,7 +673,7 @@ with col1:
526
  question = subset_df.iloc[st.session_state.question_index]
527
  progress = int((st.session_state.question_index / len(subset_df)) * 100)
528
 
529
- # Fun progress bar
530
  st.markdown(f"""
531
  <div style="text-align: center; margin: 20px 0;">
532
  <div style="font-family: 'Comic Neue', cursive; color: #FF6B6B; font-size: 18px;">
@@ -574,6 +721,7 @@ with col1:
574
 
575
  with col_btn1:
576
  if st.button("๐ŸŽฏ Submit Answer", key=f"submit_{st.session_state.question_index}", use_container_width=True):
 
577
  if str(user_ans).strip().lower() == str(question['answer']).strip().lower():
578
  # MEGA CELEBRATION FOR CORRECT ANSWER!
579
  st.markdown("""
@@ -587,9 +735,8 @@ with col1:
587
  """)
588
 
589
  # Multiple balloons and effects
590
- st.balloons()
591
- st.balloons()
592
- st.balloons()
593
 
594
  # Fun success message with random emojis
595
  success_messages = [
@@ -606,10 +753,12 @@ with col1:
606
  </div>
607
  """, unsafe_allow_html=True)
608
 
 
609
  time.sleep(3)
610
  st.session_state.question_index += 1
611
  st.session_state.show_answer = False
612
  st.session_state.show_steps = False
 
613
  st.rerun()
614
  else:
615
  st.error("""
@@ -621,6 +770,7 @@ with col1:
621
 
622
  with col_btn2:
623
  if st.button("โญ๏ธ Skip Challenge", key=f"skip_{st.session_state.question_index}", use_container_width=True):
 
624
  st.session_state.question_index += 1
625
  st.session_state.show_answer = False
626
  st.session_state.show_steps = False
@@ -639,6 +789,7 @@ with col1:
639
 
640
  if selected_age_group in ["๐Ÿš€ Math Adventurers (7-9)", "๐ŸŒŸ Math Wizards (13-15)"]:
641
  if st.button("๐Ÿ” Show Magic Steps", key=f"steps_{st.session_state.question_index}"):
 
642
  st.session_state.show_steps = True
643
  if st.session_state.show_steps and pd.notna(question.get("steps", None)):
644
  st.success(f"""
@@ -670,11 +821,11 @@ with col1:
670
  </div>
671
  """, unsafe_allow_html=True)
672
 
673
- st.balloons()
674
- st.balloons()
675
- st.balloons()
676
 
677
  if st.button("๐Ÿ”„ Start New Adventure"):
 
678
  st.session_state.question_index = 0
679
  st.session_state.show_answer = False
680
  st.session_state.show_steps = False
@@ -684,7 +835,9 @@ with col2:
684
  st.markdown("### ๐ŸŽจ Fun Zone")
685
  st.markdown("""
686
  <div style="text-align: center; font-size: 40px; margin: 20px 0;">
687
- ๐ŸŽช<br>โœจ<br>๐ŸŒŸ
 
 
688
  </div>
689
  """, unsafe_allow_html=True)
690
 
@@ -693,11 +846,20 @@ with col2:
693
  completed = min(st.session_state.question_index, len(subset_df))
694
  st.metric("Challenges Completed", f"{completed}/{len(subset_df)}")
695
 
696
- st.markdown("### ๐Ÿ’ซ Pro Tip")
697
- st.info("""
698
- Use the calculator in the sidebar to help solve tricky problems!
699
- It's your math superhero sidekick! ๐Ÿฆธโ€โ™‚๏ธ
700
- """)
 
 
 
 
 
 
 
 
 
701
 
702
  # Cleanup function
703
  def cleanup():
 
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
  # Custom CSS with LOTS of fun animations and styles
20
  st.markdown("""
 
141
  }
142
 
143
  .calc-btn {
144
+ padding: 12px 8px;
145
  border: none;
146
  border-radius: 8px;
147
  cursor: pointer;
 
151
  transition: all 0.2s ease;
152
  font-family: 'Comic Neue', cursive;
153
  font-weight: bold;
154
+ min-height: 45px;
155
  }
156
 
157
  .calc-btn:hover {
 
169
 
170
  .calc-btn-equals {
171
  background: linear-gradient(45deg, #96CEB4, #4ECDC4);
 
172
  }
173
 
174
  .calc-btn-zero {
 
223
  animation: bounce 2s infinite;
224
  }
225
 
226
+ /* Active animations */
227
+ .pulse {
228
+ animation: pulse 2s infinite;
229
  }
230
 
231
+ @keyframes pulse {
232
+ 0% { transform: scale(1); }
233
+ 50% { transform: scale(1.05); }
234
+ 100% { transform: scale(1); }
235
+ }
236
+
237
+ .rotate {
238
+ animation: rotate 4s linear infinite;
239
+ }
240
+
241
+ @keyframes rotate {
242
+ from { transform: rotate(0deg); }
243
+ to { transform: rotate(360deg); }
244
+ }
245
+
246
+ /* Live activity indicator */
247
+ .live-indicator {
248
+ display: inline-block;
249
+ width: 12px;
250
+ height: 12px;
251
+ background: #4ECDC4;
252
+ border-radius: 50%;
253
+ margin-right: 8px;
254
+ animation: blink 1.5s infinite;
255
+ }
256
+
257
+ @keyframes blink {
258
+ 0%, 100% { opacity: 1; }
259
+ 50% { opacity: 0.3; }
260
+ }
261
+
262
+ /* Celebration container */
263
+ .celebration-container {
264
+ position: fixed;
265
+ top: 0;
266
+ left: 0;
267
+ width: 100%;
268
+ height: 100%;
269
+ pointer-events: none;
270
+ z-index: 9999;
271
+ animation: fadeOut 3s forwards;
272
+ }
273
+
274
+ @keyframes fadeOut {
275
+ 0% { opacity: 1; }
276
+ 80% { opacity: 1; }
277
+ 100% { opacity: 0; display: none; }
278
  }
279
  </style>
280
  """, unsafe_allow_html=True)
281
 
282
+ # JavaScript for animations, calculator, and continuous activity
283
  st.markdown("""
284
  <script>
285
+ // Calculator functionality - COMPLETELY REWRITTEN
286
+ class Calculator {
287
+ constructor() {
288
+ this.currentInput = '0';
289
+ this.previousInput = '';
290
+ this.operation = null;
291
+ this.resetScreen = false;
292
+ this.initializeCalculator();
293
+ }
294
+
295
+ initializeCalculator() {
296
+ this.updateDisplay();
297
+ this.setupEventListeners();
298
+ }
299
+
300
+ setupEventListeners() {
301
+ // Number buttons
302
+ for (let i = 0; i <= 9; i++) {
303
+ const btn = document.getElementById(`calc-btn-${i}`);
304
+ if (btn) {
305
+ btn.addEventListener('click', () => this.appendNumber(i.toString()));
306
+ }
307
+ }
308
+
309
+ // Operation buttons
310
+ document.getElementById('calc-btn-add')?.addEventListener('click', () => this.chooseOperation('+'));
311
+ document.getElementById('calc-btn-subtract')?.addEventListener('click', () => this.chooseOperation('-'));
312
+ document.getElementById('calc-btn-multiply')?.addEventListener('click', () => this.chooseOperation('*'));
313
+ document.getElementById('calc-btn-divide')?.addEventListener('click', () => this.chooseOperation('/'));
314
+
315
+ // Other buttons
316
+ document.getElementById('calc-btn-equals')?.addEventListener('click', () => this.compute());
317
+ document.getElementById('calc-btn-clear')?.addEventListener('click', () => this.clearCalculator());
318
+ document.getElementById('calc-btn-backspace')?.addEventListener('click', () => this.backspace());
319
+ document.getElementById('calc-btn-decimal')?.addEventListener('click', () => this.appendDecimal());
320
+ }
321
+
322
+ updateDisplay() {
323
+ const display = document.getElementById('calc-display');
324
+ if (display) {
325
+ display.value = this.currentInput;
326
+ }
327
+ }
328
+
329
+ appendNumber(number) {
330
+ if (this.currentInput === '0' || this.resetScreen) {
331
+ this.currentInput = number;
332
+ this.resetScreen = false;
333
+ } else {
334
+ this.currentInput += number;
335
+ }
336
+ this.updateDisplay();
337
+ }
338
+
339
+ chooseOperation(op) {
340
+ if (this.currentInput === '') return;
341
+
342
+ if (this.previousInput !== '') {
343
+ this.compute();
344
+ }
345
+ this.operation = op;
346
+ this.previousInput = this.currentInput;
347
+ this.resetScreen = true;
348
+ }
349
+
350
+ compute() {
351
+ let computation;
352
+ const prev = parseFloat(this.previousInput);
353
+ const current = parseFloat(this.currentInput);
354
+
355
+ if (isNaN(prev) || isNaN(current)) return;
356
+
357
+ switch (this.operation) {
358
+ case '+':
359
+ computation = prev + current;
360
+ break;
361
+ case '-':
362
+ computation = prev - current;
363
+ break;
364
+ case '*':
365
+ computation = prev * current;
366
+ break;
367
+ case '/':
368
+ if (current === 0) {
369
+ this.showError("Cannot divide by zero!");
370
+ return;
371
+ }
372
+ computation = prev / current;
373
+ break;
374
+ default:
375
+ return;
376
+ }
377
+
378
+ this.currentInput = this.roundNumber(computation).toString();
379
+ this.operation = undefined;
380
+ this.previousInput = '';
381
+ this.resetScreen = true;
382
+ this.updateDisplay();
383
+ }
384
+
385
+ roundNumber(num) {
386
+ return Math.round((num + Number.EPSILON) * 100000) / 100000;
387
+ }
388
+
389
+ showError(message) {
390
+ const display = document.getElementById('calc-display');
391
+ if (display) {
392
+ display.value = message;
393
+ setTimeout(() => {
394
+ this.clearCalculator();
395
+ }, 2000);
396
+ }
397
+ }
398
+
399
+ clearCalculator() {
400
+ this.currentInput = '0';
401
+ this.previousInput = '';
402
+ this.operation = null;
403
+ this.resetScreen = false;
404
+ this.updateDisplay();
405
+ }
406
+
407
+ backspace() {
408
+ if (this.currentInput.length > 1) {
409
+ this.currentInput = this.currentInput.slice(0, -1);
410
+ } else {
411
+ this.currentInput = '0';
412
+ }
413
+ this.updateDisplay();
414
+ }
415
+
416
+ appendDecimal() {
417
+ if (this.resetScreen) {
418
+ this.currentInput = '0';
419
+ this.resetScreen = false;
420
+ }
421
+ if (!this.currentInput.includes('.')) {
422
+ this.currentInput += '.';
423
+ }
424
+ this.updateDisplay();
425
+ }
426
+ }
427
+
428
+ // Initialize calculator when page loads
429
+ let calculator;
430
+ document.addEventListener('DOMContentLoaded', function() {
431
+ calculator = new Calculator();
432
+ });
433
+
434
+ // Celebration functions with 3-second limit
435
  function createEmojiRain() {
 
436
  const container = document.createElement('div');
437
+ container.className = 'celebration-container';
438
  document.body.appendChild(container);
439
 
440
+ const emojis = ['๐ŸŽ‰', '๐ŸŽˆ', 'โญ', '๐ŸŽŠ', '๐ŸŒˆ', '๐Ÿš€', '๐ŸŽจ', '๐Ÿฑ', '๐Ÿถ', '๐Ÿฆ„'];
441
+
442
+ for (let i = 0; i < 30; i++) {
443
  setTimeout(() => {
444
  const emoji = document.createElement('div');
445
  emoji.className = 'emoji';
446
  emoji.textContent = emojis[Math.floor(Math.random() * emojis.length)];
447
  emoji.style.left = Math.random() * 100 + 'vw';
448
+ emoji.style.animationDuration = (Math.random() * 2 + 1) + 's';
449
  container.appendChild(emoji);
 
 
450
  }, i * 100);
451
  }
452
 
453
+ setTimeout(() => {
454
+ container.remove();
455
+ }, 3000);
456
  }
457
 
458
  function createConfetti() {
459
+ const container = document.createElement('div');
460
+ container.className = 'celebration-container';
461
+ document.body.appendChild(container);
462
+
463
  const colors = ['#FF6B6B', '#4ECDC4', '#FFD93D', '#45B7D1', '#96CEB4'];
464
+
465
+ for (let i = 0; i < 100; i++) {
466
  setTimeout(() => {
467
  const confetti = document.createElement('div');
468
  confetti.className = 'confetti';
469
  confetti.style.background = colors[Math.floor(Math.random() * colors.length)];
470
  confetti.style.left = Math.random() * 100 + 'vw';
471
  confetti.style.animationDuration = (Math.random() * 2 + 1) + 's';
472
+ container.appendChild(confetti);
473
+ }, i * 30);
 
 
474
  }
475
+
476
+ setTimeout(() => {
477
+ container.remove();
478
+ }, 3000);
479
  }
480
 
481
  function celebrate() {
 
483
  createConfetti();
484
  }
485
 
486
+ // Continuous activity to prevent sleeping
487
+ let lastActivity = Date.now();
488
+ setInterval(() => {
489
+ if (Date.now() - lastActivity > 10000) {
490
+ lastActivity = Date.now();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
491
  }
492
+ }, 5000);
 
 
 
 
 
 
 
493
 
494
+ document.addEventListener('click', () => lastActivity = Date.now());
495
+ document.addEventListener('keypress', () => lastActivity = Date.now());
 
 
 
 
 
 
 
 
 
 
 
 
 
496
  </script>
497
  """, unsafe_allow_html=True)
498
 
499
+ # Initialize session state with better management
500
+ def initialize_session_state():
501
+ if 'app_initialized' not in st.session_state:
502
+ st.session_state.app_initialized = True
503
+ st.session_state.temp_dir = tempfile.mkdtemp()
504
+ st.session_state.last_activity = time.time()
505
+ st.session_state.age_group = None
506
+ st.session_state.category = None
507
+ st.session_state.question_index = 0
508
+ st.session_state.show_answer = False
509
+ st.session_state.show_steps = False
510
+ st.session_state.session_initialized = False
511
+
512
+ initialize_session_state()
513
+
514
+ # Welcome title with fun characters and live indicator
515
  st.markdown("""
516
  <div class="main-container">
517
  <div class="animal-characters">
518
+ <span class="rotate">๐Ÿฑ</span>
519
+ <span class="pulse">๐Ÿถ</span>
520
+ <span class="rotate">๐Ÿฆ„</span>
521
+ <span class="pulse">๐Ÿผ</span>
522
+ <span class="rotate">๐Ÿฏ</span>
523
+ </div>
524
+ <div class="fun-title">
525
+ <span class="live-indicator"></span>๐ŸŽช Welcome to Math Adventure Land! ๐ŸŽช
526
  </div>
 
527
  <div style="text-align: center; font-size: 24px; color: #FF6B6B; font-family: 'Comic Neue', cursive;">
528
+ Where Numbers Become Friends! ๐Ÿค— <span class="pulse">โœจ</span>
529
  </div>
530
  </div>
531
  """, unsafe_allow_html=True)
532
 
 
 
 
 
533
  # Age group setup with fun descriptions
534
  age_groups = {
535
  "๐Ÿ‘ถ 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": "๐Ÿ‘ถ"},
 
542
  st.markdown("### ๐Ÿงฎ Math Helper Calculator")
543
  st.markdown("Use this calculator to help with your math problems! โœจ")
544
 
545
+ # COMPLETELY REDESIGNED CALCULATOR
546
  st.markdown("""
547
  <div class="calculator-container">
548
  <div class="calculator-title">โœจ Magic Calculator โœจ</div>
549
  <input type="text" id="calc-display" class="calculator-display" readonly value="0">
550
 
551
  <div class="calculator-buttons-compact">
552
+ <!-- Row 1 -->
553
+ <button class="calc-btn calc-btn-clear" id="calc-btn-clear">C</button>
554
+ <button class="calc-btn calc-btn-clear" id="calc-btn-backspace">โŒซ</button>
555
+ <button class="calc-btn" id="calc-btn-divide">/</button>
556
+ <button class="calc-btn" id="calc-btn-multiply">ร—</button>
557
 
558
+ <!-- Row 2 -->
559
+ <button class="calc-btn" id="calc-btn-7">7</button>
560
+ <button class="calc-btn" id="calc-btn-8">8</button>
561
+ <button class="calc-btn" id="calc-btn-9">9</button>
562
+ <button class="calc-btn" id="calc-btn-subtract">-</button>
563
 
564
+ <!-- Row 3 -->
565
+ <button class="calc-btn" id="calc-btn-4">4</button>
566
+ <button class="calc-btn" id="calc-btn-5">5</button>
567
+ <button class="calc-btn" id="calc-btn-6">6</button>
568
+ <button class="calc-btn" id="calc-btn-add">+</button>
569
 
570
+ <!-- Row 4 -->
571
+ <button class="calc-btn" id="calc-btn-1">1</button>
572
+ <button class="calc-btn" id="calc-btn-2">2</button>
573
+ <button class="calc-btn" id="calc-btn-3">3</button>
574
+ <button class="calc-btn calc-btn-equals" id="calc-btn-equals">=</button>
575
 
576
+ <!-- Row 5 -->
577
+ <button class="calc-btn calc-btn-zero" id="calc-btn-0">0</button>
578
+ <button class="calc-btn" id="calc-btn-decimal">.</button>
579
  </div>
580
  </div>
581
  """, unsafe_allow_html=True)
582
 
583
  st.markdown("---")
584
+
585
+ # Live activity monitor
586
+ st.markdown("### ๐ŸŽฏ Activity Monitor")
587
+ activity_time = time.time() - st.session_state.last_activity
588
+ if activity_time < 10:
589
+ status = "๐ŸŸข Very Active"
590
+ elif activity_time < 30:
591
+ status = "๐ŸŸก Active"
592
+ else:
593
+ status = "๐Ÿ”ด Idle"
594
+
595
+ st.metric("Session Status", status)
596
+
597
+ st.markdown("### ๐Ÿ’ซ Quick Tips")
598
  st.info("""
599
+ ๐Ÿ’ก **Calculator Tips:**
600
  - Click numbers and operators
601
  - Press = to calculate
602
+ - C to clear everything
603
+ - โŒซ to erase last digit
604
+ - Perfect for checking answers! โœ…
605
  """)
 
 
 
 
606
 
607
  # MAIN CONTENT AREA
608
  col1, col2 = st.columns([3, 1])
609
 
610
  with col1:
611
+ # Update activity timestamp
612
+ st.session_state.last_activity = time.time()
613
+
614
  # Age group selection
615
  selected_age_group = st.selectbox("๐ŸŽฏ Choose Your Adventure Level:", list(age_groups.keys()))
616
 
617
  # Initialize session
618
+ if not st.session_state.session_initialized or st.session_state.age_group != selected_age_group:
619
  st.session_state.age_group = selected_age_group
620
  st.session_state.category = None
621
  st.session_state.question_index = 0
 
673
  question = subset_df.iloc[st.session_state.question_index]
674
  progress = int((st.session_state.question_index / len(subset_df)) * 100)
675
 
676
+ # Fun progress bar with animation
677
  st.markdown(f"""
678
  <div style="text-align: center; margin: 20px 0;">
679
  <div style="font-family: 'Comic Neue', cursive; color: #FF6B6B; font-size: 18px;">
 
721
 
722
  with col_btn1:
723
  if st.button("๐ŸŽฏ Submit Answer", key=f"submit_{st.session_state.question_index}", use_container_width=True):
724
+ st.session_state.last_activity = time.time() # Update activity
725
  if str(user_ans).strip().lower() == str(question['answer']).strip().lower():
726
  # MEGA CELEBRATION FOR CORRECT ANSWER!
727
  st.markdown("""
 
735
  """)
736
 
737
  # Multiple balloons and effects
738
+ for _ in range(3):
739
+ st.balloons()
 
740
 
741
  # Fun success message with random emojis
742
  success_messages = [
 
753
  </div>
754
  """, unsafe_allow_html=True)
755
 
756
+ # Wait exactly 3 seconds then continue
757
  time.sleep(3)
758
  st.session_state.question_index += 1
759
  st.session_state.show_answer = False
760
  st.session_state.show_steps = False
761
+ st.session_state.last_activity = time.time()
762
  st.rerun()
763
  else:
764
  st.error("""
 
770
 
771
  with col_btn2:
772
  if st.button("โญ๏ธ Skip Challenge", key=f"skip_{st.session_state.question_index}", use_container_width=True):
773
+ st.session_state.last_activity = time.time() # Update activity
774
  st.session_state.question_index += 1
775
  st.session_state.show_answer = False
776
  st.session_state.show_steps = False
 
789
 
790
  if selected_age_group in ["๐Ÿš€ Math Adventurers (7-9)", "๐ŸŒŸ Math Wizards (13-15)"]:
791
  if st.button("๐Ÿ” Show Magic Steps", key=f"steps_{st.session_state.question_index}"):
792
+ st.session_state.last_activity = time.time() # Update activity
793
  st.session_state.show_steps = True
794
  if st.session_state.show_steps and pd.notna(question.get("steps", None)):
795
  st.success(f"""
 
821
  </div>
822
  """, unsafe_allow_html=True)
823
 
824
+ for _ in range(3):
825
+ st.balloons()
 
826
 
827
  if st.button("๐Ÿ”„ Start New Adventure"):
828
+ st.session_state.last_activity = time.time() # Update activity
829
  st.session_state.question_index = 0
830
  st.session_state.show_answer = False
831
  st.session_state.show_steps = False
 
835
  st.markdown("### ๐ŸŽจ Fun Zone")
836
  st.markdown("""
837
  <div style="text-align: center; font-size: 40px; margin: 20px 0;">
838
+ <span class="pulse">๐ŸŽช</span><br>
839
+ <span class="rotate">โœจ</span><br>
840
+ <span class="pulse">๐ŸŒŸ</span>
841
  </div>
842
  """, unsafe_allow_html=True)
843
 
 
846
  completed = min(st.session_state.question_index, len(subset_df))
847
  st.metric("Challenges Completed", f"{completed}/{len(subset_df)}")
848
 
849
+ # Continuous activity indicator
850
+ st.markdown("### ๐Ÿ“Š Live Stats")
851
+ st.metric("Session Activity", "๐ŸŸข Always Active")
852
+ st.metric("Fun Level", "๐ŸŽ‰ Maximum!")
853
+
854
+ # Add periodic invisible updates to prevent sleeping
855
+ if 'update_counter' not in st.session_state:
856
+ st.session_state.update_counter = 0
857
+
858
+ st.session_state.update_counter += 1
859
+
860
+ # This creates a very subtle continuous activity
861
+ if st.session_state.update_counter % 10 == 0:
862
+ st.markdown(f'<div style="display:none">{random.random()}</div>', unsafe_allow_html=True)
863
 
864
  # Cleanup function
865
  def cleanup():