import streamlit as st
import os
from groq import Groq
import json
import re
from typing import List, Dict, Optional
import time
import plotly.express as px
import plotly.graph_objects as go
import pandas as pd
from datetime import datetime, timedelta
import streamlit.components.v1 as components
# Configure page
st.set_page_config(
page_title="đ§Ž MathGenius Academy",
page_icon="đ§Ž",
layout="wide",
initial_sidebar_state="expanded"
)
# Custom CSS for enhanced UI
def load_custom_css():
st.markdown("""
""", unsafe_allow_html=True)
class MathOlympiadExam:
def __init__(self):
self.client = self._initialize_groq_client()
self.grade_levels = {
1: {"name": "Grade 1 (Ages 6-7)", "emoji": "đą", "color": "#FF6B6B"},
2: {"name": "Grade 2 (Ages 7-8)", "emoji": "đŋ", "color": "#4ECDC4"},
3: {"name": "Grade 3 (Ages 8-9)", "emoji": "đ", "color": "#45B7D1"},
4: {"name": "Grade 4 (Ages 9-10)", "emoji": "đŗ", "color": "#96CEB4"},
5: {"name": "Grade 5 (Ages 10-11)", "emoji": "đ¯", "color": "#FECA57"},
6: {"name": "Grade 6 (Ages 11-12)", "emoji": "đ", "color": "#FF9FF3"},
7: {"name": "Grade 7 (Ages 12-13)", "emoji": "â", "color": "#54A0FF"},
8: {"name": "Grade 8 (Ages 13-14)", "emoji": "đ", "color": "#5F27CD"},
9: {"name": "Grade 9 (Ages 14-15)", "emoji": "đ", "color": "#00D2D3"},
10: {"name": "Grade 10 (Ages 15-16)", "emoji": "đ", "color": "#FF6348"}
}
def _initialize_groq_client(self) -> Optional[Groq]:
"""Initialize Groq client with API key"""
try:
# Use Streamlit secrets for secure API key management
api_key = st.secrets["GROQ_API_KEY"]
if not api_key:
st.error("â ī¸ GROQ_API_KEY not found in secrets!")
return None
return Groq(api_key=api_key)
except Exception as e:
st.error(f"Failed to initialize Groq client: {e}")
return None
def generate_questions(self, grade: int, num_questions: int, difficulty: str = "medium") -> List[Dict]:
"""Generate math olympiad questions with enhanced difficulty options"""
if not self.client:
return []
try:
difficulty_map = {
1: "very basic arithmetic, counting 1-20, simple shapes recognition, basic patterns",
2: "addition and subtraction within 100, simple word problems, basic time and money",
3: "multiplication tables up to 10, basic division, simple fractions, pattern recognition",
4: "advanced multiplication and division, fractions, basic decimals, area and perimeter",
5: "advanced arithmetic, introduction to algebra, geometry, data interpretation",
6: "pre-algebra, ratios and proportions, percentages, coordinate geometry, statistics",
7: "algebra fundamentals, advanced geometry, probability, scientific notation",
8: "linear equations, quadratic basics, trigonometry introduction, advanced geometry",
9: "advanced algebra, geometry proofs, probability and statistics, trigonometry",
10: "pre-calculus, advanced trigonometry, complex numbers, advanced problem solving"
}
difficulty_modifiers = {
"easy": "Make questions slightly easier than typical olympiad level, focusing on fundamental concepts",
"medium": "Standard olympiad difficulty with moderate complexity",
"hard": "Advanced olympiad level with complex multi-step problems"
}
topics = difficulty_map.get(grade, "general math concepts")
modifier = difficulty_modifiers.get(difficulty, "")
prompt = f"""Generate exactly {num_questions} Math Olympiad-style multiple choice questions for Grade {grade} students.
Topics focus: {topics}
Difficulty: {modifier}
Format each question EXACTLY as follows:
**Question X:** [Question text here]
A) [Option A]
B) [Option B]
C) [Option C]
D) [Option D]
**Correct Answer:** [Letter only - A, B, C, or D]
**Explanation:** [Clear step-by-step solution]
**Hint:** [Helpful hint for students]
Make questions engaging and educational. Include varied problem types: word problems, visual problems, logical reasoning, and computational challenges."""
response = self.client.chat.completions.create(
model="llama-3.3-70b-versatile",
messages=[
{"role": "system", "content": "You are an expert Math Olympiad coach creating engaging, educational questions."},
{"role": "user", "content": prompt}
],
temperature=0.7,
max_tokens=3000
)
return self._parse_questions(response.choices[0].message.content)
except Exception as e:
st.error(f"Failed to generate questions: {e}")
return []
def _parse_questions(self, content: str) -> List[Dict]:
"""Enhanced question parsing with hints"""
questions = []
question_blocks = re.split(r'\*\*Question \d+:\*\*', content)[1:]
for i, block in enumerate(question_blocks, 1):
try:
lines = [line.strip() for line in block.strip().split('\n') if line.strip()]
if len(lines) < 6:
continue
question_text = lines[0]
options = []
correct_answer = None
explanation = ""
hint = ""
for line in lines[1:]:
if line.startswith(('A)', 'B)', 'C)', 'D)')):
options.append(line)
elif line.startswith('**Correct Answer:**'):
correct_answer = line.replace('**Correct Answer:**', '').strip()
elif line.startswith('**Explanation:**'):
explanation = line.replace('**Explanation:**', '').strip()
elif line.startswith('**Hint:**'):
hint = line.replace('**Hint:**', '').strip()
if len(options) == 4 and correct_answer:
questions.append({
'question_number': i,
'question_text': question_text,
'options': options,
'correct_answer': correct_answer,
'explanation': explanation,
'hint': hint,
'user_answer': None,
'time_taken': 0,
'difficulty': self._estimate_difficulty(question_text)
})
except Exception as e:
st.warning(f"Error parsing question {i}: {e}")
continue
return questions
def _estimate_difficulty(self, question_text: str) -> str:
"""Estimate question difficulty based on content"""
hard_keywords = ['prove', 'complex', 'advanced', 'multiple steps', 'system of']
easy_keywords = ['basic', 'simple', 'find', 'calculate', 'what is']
text_lower = question_text.lower()
if any(keyword in text_lower for keyword in hard_keywords):
return "Hard"
elif any(keyword in text_lower for keyword in easy_keywords):
return "Easy"
else:
return "Medium"
# Initialize session state
def initialize_session_state():
if 'questions' not in st.session_state:
st.session_state.questions = []
if 'exam_completed' not in st.session_state:
st.session_state.exam_completed = False
if 'grade_selected' not in st.session_state:
st.session_state.grade_selected = None
if 'exam_history' not in st.session_state:
st.session_state.exam_history = []
if 'current_question' not in st.session_state:
st.session_state.current_question = 0
if 'exam_mode' not in st.session_state:
st.session_state.exam_mode = 'practice'
if 'start_time' not in st.session_state:
st.session_state.start_time = None
if 'user_profile' not in st.session_state:
st.session_state.user_profile = {
'name': 'Math Explorer',
'total_exams': 0,
'total_questions': 0,
'correct_answers': 0,
'favorite_grade': 5,
'badges': [],
'streak': 0
}
if 'seen_questions' not in st.session_state:
st.session_state.seen_questions = set()
@st.cache_resource
def get_exam_system():
return MathOlympiadExam()
def render_hero_section():
"""Render the hero section with animations"""
st.markdown("""
""", unsafe_allow_html=True)
def render_dashboard():
"""Render user dashboard with statistics"""
profile = st.session_state.user_profile
st.markdown("### đ Your Learning Dashboard")
col1, col2, col3, col4 = st.columns(4)
with col1:
st.markdown(f"""
{profile['total_exams']}
Exams Taken
""", unsafe_allow_html=True)
with col2:
accuracy = (profile['correct_answers'] / max(profile['total_questions'], 1)) * 100
st.markdown(f"""
""", unsafe_allow_html=True)
with col3:
st.markdown(f"""
{profile['streak']}
Day Streak
""", unsafe_allow_html=True)
with col4:
st.markdown(f"""
{len(profile['badges'])}
Badges Earned
""", unsafe_allow_html=True)
# Progress Chart
if st.session_state.exam_history:
df = pd.DataFrame(st.session_state.exam_history)
col1, col2 = st.columns(2)
with col1:
st.markdown("#### đ Performance Trend")
fig = px.line(df, x='date', y='percentage',
title='Your Progress Over Time',
color_discrete_sequence=['#667eea'])
fig.update_layout(
plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)',
)
st.plotly_chart(fig, use_container_width=True)
with col2:
st.markdown("#### đ¯ Grade Distribution")
grade_counts = df['grade'].value_counts().sort_index()
fig = px.bar(x=grade_counts.index, y=grade_counts.values,
title='Exams by Grade Level',
color_discrete_sequence=['#764ba2'])
fig.update_layout(
plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)',
)
st.plotly_chart(fig, use_container_width=True)
def render_question_card(question, question_index, total_questions):
"""Render an individual question with enhanced UI"""
progress = ((question_index + 1) / total_questions) * 100
st.markdown(f"""
Question {question_index + 1} of {total_questions}
""", unsafe_allow_html=True)
st.markdown(f"""
Question {question['question_number']}
{question.get('difficulty', 'Medium')} Level
{question['question_text']}
""", unsafe_allow_html=True)
# Options with enhanced styling
option_labels = [opt.split(')', 1)[1].strip() for opt in question['options']]
option_keys = [opt.split(')', 1)[0].strip() for opt in question['options']]
selected = st.radio(
"Choose your answer:",
options=option_keys,
format_func=lambda x, labels=option_labels, keys=option_keys: f"{x}) {labels[keys.index(x)]}",
key=f"q_{question_index}",
index=None
)
# Hint system
if st.button(f"đĄ Need a hint?", key=f"hint_{question_index}"):
if question.get('hint'):
st.info(f"đĄ **Hint:** {question['hint']}")
else:
st.info("đĄ **Hint:** Try breaking down the problem step by step!")
return selected
def render_exam_interface():
"""Render the main exam interface"""
questions = st.session_state.questions
total_questions = len(questions)
if st.session_state.exam_mode == 'timed':
# Timer display
if st.session_state.start_time:
elapsed = time.time() - st.session_state.start_time
remaining = max(0, (total_questions * 120) - elapsed) # 2 minutes per question
mins, secs = divmod(int(remaining), 60)
st.markdown(f"""
â° {mins:02d}:{secs:02d}
""", unsafe_allow_html=True)
if remaining <= 0:
st.error("â° Time's up! Submitting your exam...")
st.session_state.exam_completed = True
st.rerun()
# Question navigation
if total_questions > 1:
st.markdown("#### đ Question Navigation")
cols = st.columns(min(10, total_questions))
for i in range(total_questions):
with cols[i % 10]:
status = "â
" if questions[i]['user_answer'] else "â"
if st.button(f"{status} Q{i+1}", key=f"nav_{i}"):
st.session_state.current_question = i
# Current question
current_q = st.session_state.current_question
if current_q < total_questions:
selected = render_question_card(questions[current_q], current_q, total_questions)
questions[current_q]['user_answer'] = selected
# Navigation buttons
col1, col2, col3 = st.columns([1, 2, 1])
with col1:
if current_q > 0:
if st.button("âŦ
ī¸ Previous", key="prev_btn"):
st.session_state.current_question -= 1
st.rerun()
with col3:
if current_q < total_questions - 1:
if st.button("Next âĄī¸", key="next_btn"):
st.session_state.current_question += 1
st.rerun()
else:
if st.button("đ¯ Submit Exam", key="submit_btn", type="primary"):
unanswered = [i+1 for i, q in enumerate(questions) if not q['user_answer']]
if unanswered:
st.error(f"â ī¸ Please answer all questions. Missing: {', '.join(map(str, unanswered))}")
else:
st.session_state.exam_completed = True
st.rerun()
def calculate_badges(score, total, grade):
"""Calculate badges earned based on performance"""
percentage = (score / total) * 100
badges = []
if percentage == 100:
badges.append("đ Perfect Score")
elif percentage >= 90:
badges.append("â Excellence")
elif percentage >= 80:
badges.append("đ¯ High Achiever")
elif percentage >= 70:
badges.append("đ Good Progress")
if grade >= 8:
badges.append("đ Advanced Level")
return badges
def render_results_section():
"""Render enhanced results with animations and insights - REMOVED ACTION BUTTONS"""
st.markdown("---")
st.markdown("### đ Exam Results")
questions = st.session_state.questions
correct_count = sum(1 for q in questions if q['user_answer'] == q['correct_answer'])
total_questions = len(questions)
percentage = (correct_count / total_questions) * 100
# Update user profile
profile = st.session_state.user_profile
profile['total_exams'] += 1
profile['total_questions'] += total_questions
profile['correct_answers'] += correct_count
# Add to history
st.session_state.exam_history.append({
'date': datetime.now(),
'grade': st.session_state.grade_selected,
'score': correct_count,
'total': total_questions,
'percentage': percentage
})
# Calculate badges
new_badges = calculate_badges(correct_count, total_questions, st.session_state.grade_selected)
profile['badges'].extend(new_badges)
# Animated score reveal
col1, col2, col3 = st.columns(3)
with col1:
st.markdown(f"""
{correct_count}/{total_questions}
Final Score
""", unsafe_allow_html=True)
with col2:
st.markdown(f"""
{percentage:.1f}%
Accuracy
""", unsafe_allow_html=True)
with col3:
if percentage >= 90:
grade_emoji = "đ"
grade_text = "Excellent!"
elif percentage >= 80:
grade_emoji = "â"
grade_text = "Great Job!"
elif percentage >= 70:
grade_emoji = "đ"
grade_text = "Good Work!"
else:
grade_emoji = "đ"
grade_text = "Keep Practicing!"
st.markdown(f"""
{grade_emoji}
{grade_text}
""", unsafe_allow_html=True)
# New badges notification
if new_badges:
st.success(f"đ New badges earned: {', '.join(new_badges)}")
# Detailed question review
st.markdown("#### đ Question Review")
for i, question in enumerate(questions):
is_correct = question['user_answer'] == question['correct_answer']
with st.expander(f"Question {i+1} - {'â
Correct' if is_correct else 'â Incorrect'} ({question.get('difficulty', 'Medium')} Level)"):
st.markdown(f"**Question:** {question['question_text']}")
col1, col2 = st.columns(2)
with col1:
st.markdown(f"**Your Answer:** {question['user_answer']}")
with col2:
st.markdown(f"**Correct Answer:** {question['correct_answer']}")
if question.get('explanation'):
st.markdown(f"**Explanation:** {question['explanation']}")
if not is_correct and question.get('hint'):
st.info(f"đĄ **Hint for next time:** {question['hint']}")
# Performance insights
exam_system = get_exam_system()
if exam_system.client:
st.markdown("#### đ§ AI Performance Analysis")
with st.spinner("Generating personalized insights..."):
summary = generate_enhanced_summary(
st.session_state.grade_selected,
questions,
correct_count,
total_questions,
exam_system
)
st.markdown(f"""
{summary}
""", unsafe_allow_html=True)
# Show completion message instead of action buttons
st.markdown("#### đ Exam Complete!")
st.info("Great job completing the exam! Use the sidebar to generate a new exam or check out the Dashboard tab to view your progress.")
def generate_enhanced_summary(grade, questions, score, total, exam_system):
"""Generate enhanced AI-powered performance summary"""
try:
# Analyze performance patterns
correct_questions = [q for q in questions if q['user_answer'] == q['correct_answer']]
incorrect_questions = [q for q in questions if q['user_answer'] != q['correct_answer']]
difficulty_analysis = {}
for q in questions:
diff = q.get('difficulty', 'Medium')
if diff not in difficulty_analysis:
difficulty_analysis[diff] = {'correct': 0, 'total': 0}
difficulty_analysis[diff]['total'] += 1
if q['user_answer'] == q['correct_answer']:
difficulty_analysis[diff]['correct'] += 1
percentage = (score / total * 100) if total > 0 else 0
prompt = f"""Analyze this Math Olympiad performance for a Grade {grade} student:
PERFORMANCE SUMMARY:
- Score: {score}/{total} ({percentage:.1f}%)
- Difficulty Breakdown: {difficulty_analysis}
SAMPLE INCORRECT QUESTIONS:
{chr(10).join([f"- {q['question_text'][:100]}..." for q in incorrect_questions[:2]])}
Please provide a concise summary (max 4-5 sentences) with:
- 1-2 key strengths
- 1 main area to improve
- 1 motivational message
Use simple, encouraging language for a Grade {grade} student. Avoid long lists or detailed study plans."""
response = exam_system.client.chat.completions.create(
model="llama-3.3-70b-versatile",
messages=[
{"role": "system", "content": "You are an expert Math Olympiad mentor providing detailed, encouraging feedback to help students improve."},
{"role": "user", "content": prompt}
],
temperature=0.3,
max_tokens=1000
)
return response.choices[0].message.content
except Exception as e:
return f"""
**Performance Summary:**
You scored {score} out of {total} ({percentage:.1f}%).
Great job! You showed strong skills in several areas. Focus on reviewing the questions you missed. Keep practicing and you'll get even better! đ
"""
def reset_exam():
"""Reset exam state for new attempt"""
st.session_state.questions = []
st.session_state.exam_completed = False
st.session_state.current_question = 0
st.session_state.start_time = None
st.rerun()
def render_sidebar():
"""Enhanced sidebar with user profile and settings"""
exam_system = get_exam_system()
with st.sidebar:
# User profile section
st.markdown(f"""
đ
{st.session_state.user_profile['name']}
Level {st.session_state.user_profile['favorite_grade']} Explorer
""", unsafe_allow_html=True)
st.markdown("### âī¸ Exam Configuration")
# Grade selection with enhanced UI
grade_options = list(exam_system.grade_levels.keys())
grade_labels = [f"{exam_system.grade_levels[g]['emoji']} {exam_system.grade_levels[g]['name']}" for g in grade_options]
grade = st.selectbox(
"đ¯ Select Grade Level:",
options=grade_options,
format_func=lambda x: f"{exam_system.grade_levels[x]['emoji']} {exam_system.grade_levels[x]['name']}",
key="grade_selector",
help="Choose your current grade level for appropriate difficulty"
)
# Exam mode
exam_mode = st.radio(
"đ Exam Mode:",
["practice", "timed", "challenge"],
format_func=lambda x: {
"practice": "đ¯ Practice Mode",
"timed": "â° Timed Mode",
"challenge": "đĨ Challenge Mode"
}[x],
help="Practice: No time limit | Timed: 2 min/question | Challenge: Extra hard questions"
)
st.session_state.exam_mode = exam_mode
# Number of questions
if exam_mode == "challenge":
num_questions = st.slider("đ Questions:", 5, 20, 10, help="Challenge mode: 5-20 questions")
else:
num_questions = st.slider("đ Questions:", 3, 15, 5, help="Choose number of questions")
# Difficulty level
difficulty = st.select_slider(
"⥠Difficulty:",
options=["easy", "medium", "hard"],
value="medium",
format_func=lambda x: {
"easy": "đĸ Easy",
"medium": "đĄ Medium",
"hard": "đ´ Hard"
}[x]
)
# Generate exam button
if st.button("đ Generate New Exam", type="primary", use_container_width=True):
if not exam_system.client:
st.error("đĢ API not available!")
else:
with st.spinner(f"đ Creating your {exam_mode} exam..."):
# Add loading animation
progress_bar = st.progress(0)
for i in range(100):
time.sleep(0.01)
progress_bar.progress(i + 1)
challenge_difficulty = "hard" if exam_mode == "challenge" else difficulty
questions = exam_system.generate_questions(grade, num_questions, challenge_difficulty)
if questions:
# Filter out previously seen questions
if 'seen_questions' in st.session_state:
new_questions = [q for q in questions if q['question_text'] not in st.session_state.seen_questions]
st.session_state.questions = new_questions
# Update seen_questions with the new questions
st.session_state.seen_questions.update(q['question_text'] for q in new_questions)
else:
st.session_state.questions = questions
st.session_state.exam_completed = False
st.session_state.grade_selected = grade
st.session_state.current_question = 0
st.session_state.start_time = time.time() if exam_mode == "timed" else None
st.success(f"⨠Generated {len(st.session_state.questions)} questions!")
st.balloons()
else:
st.error("â Failed to generate exam. Try again!")
st.markdown("---")
# Quick stats
profile = st.session_state.user_profile
st.markdown("### đ Quick Stats")
st.metric("đ¯ Total Exams", profile['total_exams'])
if profile['total_questions'] > 0:
accuracy = (profile['correct_answers'] / profile['total_questions']) * 100
st.metric("đĒ Accuracy", f"{accuracy:.1f}%")
st.metric("đĨ Streak", f"{profile['streak']} days")
# Recent badges
if profile['badges']:
st.markdown("### đ Recent Badges")
for badge in profile['badges'][-3:]:
st.markdown(f"- {badge}")
st.markdown("---")
# Settings
with st.expander("âī¸ Settings"):
new_name = st.text_input("Your Name:", value=profile['name'])
if new_name != profile['name']:
profile['name'] = new_name
st.success("Name updated!")
if st.button("đī¸ Reset Progress"):
if st.checkbox("I'm sure"):
initialize_session_state()
st.success("Progress reset!")
st.rerun()
def render_welcome_screen():
"""Render welcome screen for new users"""
# Main welcome container
st.markdown("""
đ
Welcome to MathGenius Academy!
Ready to embark on an exciting mathematical journey? Let's discover your potential!
""", unsafe_allow_html=True)
# Feature cards using Streamlit columns for better compatibility
st.markdown("### ⨠What Makes Us Special")
col1, col2, col3 = st.columns(3)
with col1:
st.markdown("""
đ¯
Adaptive Learning
Questions adjust to your skill level
""", unsafe_allow_html=True)
with col2:
st.markdown("""
đ
Progress Tracking
See your improvement over time
""", unsafe_allow_html=True)
with col3:
st.markdown("""
đ
Achievement System
Earn badges and unlock new levels
""", unsafe_allow_html=True)
# Getting started message
st.markdown("---")
st.info("đ Choose your grade level from the sidebar and click 'Generate New Exam' to begin your mathematical adventure!")
# Quick start tips
with st.expander("đ Quick Start Guide"):
st.markdown("""
**Ready to begin? Follow these simple steps:**
1. **đ¯ Choose Your Grade**: Select your current grade level from the sidebar
2. **đ Pick Your Mode**:
- đĸ **Practice Mode**: No time pressure, perfect for learning
- â° **Timed Mode**: Challenge yourself with time limits
- đĨ **Challenge Mode**: Extra difficult questions for advanced learners
3. **⥠Set Difficulty**: Easy, Medium, or Hard - pick what feels right
4. **đ Choose Questions**: 3-20 questions depending on your time
5. **đ Generate & Start**: Hit the generate button and begin!
**đĄ Pro Tips:**
- Start with Practice mode to get comfortable
- Use hints when you're stuck - learning is the goal!
- Review all explanations to understand concepts better
- Track your progress in the Dashboard tab
""")
# Motivational quote
st.markdown("""
"Mathematics is not about numbers, equations, or algorithms. It is about understanding." - William Paul Thurston
""", unsafe_allow_html=True)
def main():
# Load custom CSS
load_custom_css()
# Initialize session state
initialize_session_state()
# Get exam system
exam_system = get_exam_system()
# Render hero section
render_hero_section()
# Main navigation
tab1, tab2, tab3 = st.tabs(["đ¯ Exam", "đ Dashboard", "âšī¸ About"])
with tab1:
# Render sidebar
render_sidebar()
# Main exam interface
if not st.session_state.questions:
render_welcome_screen()
elif st.session_state.exam_completed:
render_results_section()
else:
st.markdown("### đ§Ž Math Olympiad Challenge")
if st.session_state.exam_mode == "timed" and st.session_state.start_time:
# Show exam info
col1, col2, col3 = st.columns(3)
with col1:
st.info(f"đ Grade {st.session_state.grade_selected}")
with col2:
st.info(f"âąī¸ {st.session_state.exam_mode.title()} Mode")
with col3:
st.info(f"đ {len(st.session_state.questions)} Questions")
render_exam_interface()
with tab2:
render_dashboard()
# Additional dashboard features
if st.session_state.exam_history:
st.markdown("#### đ¯ Detailed Analytics")
df = pd.DataFrame(st.session_state.exam_history)
col1, col2 = st.columns(2)
with col1:
st.markdown("##### đ Score Distribution")
fig = px.histogram(df, x='percentage', nbins=10,
title='Score Distribution',
color_discrete_sequence=['#667eea'])
fig.update_layout(plot_bgcolor='rgba(0,0,0,0)', paper_bgcolor='rgba(0,0,0,0)')
st.plotly_chart(fig, use_container_width=True)
with col2:
st.markdown("##### đ Improvement Trend")
df_trend = df.copy()
df_trend['moving_avg'] = df_trend['percentage'].rolling(window=3, min_periods=1).mean()
fig = go.Figure()
fig.add_trace(go.Scatter(x=df_trend['date'], y=df_trend['percentage'],
mode='markers+lines', name='Actual Score',
line=dict(color='#667eea')))
fig.add_trace(go.Scatter(x=df_trend['date'], y=df_trend['moving_avg'],
mode='lines', name='Trend',
line=dict(color='#764ba2', dash='dash')))
fig.update_layout(title='Performance Trend',
plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)')
st.plotly_chart(fig, use_container_width=True)
# Achievement showcase
profile = st.session_state.user_profile
if profile['badges']:
st.markdown("#### đ Your Achievements")
badge_cols = st.columns(min(4, len(profile['badges'])))
for i, badge in enumerate(profile['badges'][-8:]): # Show last 8 badges
with badge_cols[i % 4]:
st.markdown(f"""
{badge.split()[0]}
{' '.join(badge.split()[1:])}
""", unsafe_allow_html=True)
with tab3:
st.markdown("# đ About MathGenius Academy")
# Mission section
with st.container():
st.markdown("## đ¯ Our Mission")
st.markdown("""
To make mathematics accessible, engaging, and fun for students of all levels through
interactive Olympiad-style training. We believe every student can excel in mathematics
with the right guidance and practice.
""", unsafe_allow_html=True)
# Features section
st.markdown("## ⨠Key Features")
col1, col2 = st.columns(2)
with col1:
st.markdown(
"""
đ¤ AI-Powered Learning
- Adaptive Questions: Problems that match your skill level
- Smart Difficulty: Automatic adjustment based on performance
- Personalized Feedback: Detailed insights and recommendations
đŽ Multiple Game Modes
- Practice Mode: Learn at your own pace
- Timed Mode: Build speed and confidence
- Challenge Mode: Push your limits with hard problems
""",
unsafe_allow_html=True
)
with col2:
st.markdown(
"""
đ Progress & Analytics
- Performance Tracking: Monitor improvement over time
- Detailed Statistics: Accuracy, trends, and insights
- Visual Charts: Interactive graphs and analysis
đ Achievement System
- Badges & Rewards: Celebrate your success
- Streak Tracking: Build consistent study habits
- Level Progression: Unlock new challenges
""",
unsafe_allow_html=True
)
# Getting Started Guide
st.markdown("## đ Getting Started")
steps_col1, steps_col2 = st.columns(2)
with steps_col1:
st.markdown("""
đ Setup Steps
- Select Grade Level: Choose from Grade 1-10
- Pick Exam Mode: Practice, Timed, or Challenge
- Set Difficulty: Easy, Medium, or Hard
- Choose Questions: 3-20 questions per exam
- Generate Exam: Click the generate button
""", unsafe_allow_html=True)
with steps_col2:
st.markdown("""
đĄ Success Tips
- Start Easy: Begin with Practice mode
- Use Hints: Don't hesitate to ask for help
- Review Mistakes: Learn from wrong answers
- Track Progress: Check your Dashboard regularly
- Stay Consistent: Practice a little each day
""", unsafe_allow_html=True)
# Grade Level Guide
st.markdown("## đ¯ Grade Level Guide")
grade_col1, grade_col2, grade_col3 = st.columns(3)
with grade_col1:
st.markdown("""
đą Elementary (Grades 1-4)
- Basic arithmetic operations
- Simple word problems
- Pattern recognition
- Basic geometry shapes
- Counting and number sense
""", unsafe_allow_html=True)
with grade_col2:
st.markdown("""
đ Middle School (Grades 5-8)
- Pre-algebra concepts
- Fractions and decimals
- Basic statistics
- Coordinate geometry
- Problem-solving strategies
""", unsafe_allow_html=True)
with grade_col3:
st.markdown("""
â High School (Grades 9-10)
- Advanced algebra
- Geometry proofs
- Trigonometry basics
- Complex problem solving
- Mathematical reasoning
""", unsafe_allow_html=True)
# FAQ Section
with st.expander("â Frequently Asked Questions"):
st.markdown("""
**Q: How are the questions generated?**
A: We use advanced AI to create unique, grade-appropriate questions that follow Math Olympiad standards.
**Q: Can I retake exams?**
A: Yes! You can generate unlimited exams to practice and improve your skills.
**Q: How is my progress tracked?**
A: We track your accuracy, response times, difficulty preferences, and improvement trends over time.
**Q: What if I get stuck on a question?**
A: Use the hint feature! We provide helpful hints to guide your thinking without giving away the answer.
**Q: Is there a time limit?**
A: Only in Timed Mode. Practice and Challenge modes let you work at your own pace.
**Q: How do I earn badges?**
A: Badges are earned automatically based on your performance, consistency, and achievements.
""")
# Footer
st.markdown("---")
st.markdown("""
Ready to become a Math Genius? đ§Ž
Join thousands of students improving their mathematical skills every day!
""", unsafe_allow_html=True)
st.markdown("
", unsafe_allow_html=True)
st.markdown("**Made with â¤ī¸ for young mathematicians everywhere!**")
if __name__ == "__main__":
main()