Spaces:
Build error
Build error
| import streamlit as st | |
| from datetime import datetime | |
| from typing import Dict, List, Optional | |
| import json | |
| class LearningPaths: | |
| def __init__(self): | |
| self.initialize_session_state() | |
| self.load_curriculum() | |
| def initialize_session_state(): | |
| """Initialize session state for learning paths if not already present""" | |
| if 'learning_state' not in st.session_state: | |
| st.session_state.learning_state = { | |
| 'current_path': None, | |
| 'current_module': None, | |
| 'completed_modules': set(), | |
| 'achievements': [], | |
| 'quiz_scores': {}, | |
| 'learning_streak': 0, | |
| 'last_active': None, | |
| 'mastery_levels': {} # Track concept mastery levels | |
| } | |
| def load_curriculum(self): | |
| """Load the complete curriculum structure""" | |
| self.curriculum = { | |
| 'python_basics': { | |
| 'name': 'Python Programming Basics', | |
| 'description': 'Master the fundamental concepts of Python programming.', | |
| 'prerequisites': [], | |
| 'modules': [ | |
| { | |
| 'id': 'intro_python', | |
| 'name': 'Introduction to Python', | |
| 'concepts': ['programming_basics', 'python_environment', 'basic_syntax'], | |
| 'difficulty': 'beginner', | |
| 'estimated_hours': 2 | |
| }, | |
| { | |
| 'id': 'variables_types', | |
| 'name': 'Variables and Data Types', | |
| 'concepts': ['variables', 'numbers', 'strings', 'type_conversion'], | |
| 'difficulty': 'beginner', | |
| 'estimated_hours': 3 | |
| }, | |
| { | |
| 'id': 'control_flow', | |
| 'name': 'Control Flow', | |
| 'concepts': ['conditionals', 'loops', 'break_continue'], | |
| 'difficulty': 'beginner', | |
| 'estimated_hours': 4 | |
| }, | |
| { | |
| 'id': 'functions_basics', | |
| 'name': 'Functions', | |
| 'concepts': ['function_definition', 'parameters', 'return_values'], | |
| 'difficulty': 'beginner', | |
| 'estimated_hours': 4 | |
| } | |
| ] | |
| }, | |
| 'data_structures': { | |
| 'name': 'Data Structures', | |
| 'description': 'Learn essential Python data structures and their operations.', | |
| 'prerequisites': ['python_basics'], | |
| 'modules': [ | |
| { | |
| 'id': 'lists_tuples', | |
| 'name': 'Lists and Tuples', | |
| 'concepts': ['list_operations', 'tuple_basics', 'sequence_types'], | |
| 'difficulty': 'intermediate', | |
| 'estimated_hours': 4 | |
| }, | |
| { | |
| 'id': 'dictionaries', | |
| 'name': 'Dictionaries', | |
| 'concepts': ['dict_operations', 'key_value_pairs', 'dict_methods'], | |
| 'difficulty': 'intermediate', | |
| 'estimated_hours': 3 | |
| }, | |
| { | |
| 'id': 'sets', | |
| 'name': 'Sets', | |
| 'concepts': ['set_operations', 'set_methods', 'set_theory'], | |
| 'difficulty': 'intermediate', | |
| 'estimated_hours': 3 | |
| }, | |
| { | |
| 'id': 'advanced_ops', | |
| 'name': 'Advanced Operations', | |
| 'concepts': ['comprehensions', 'generators', 'iterators'], | |
| 'difficulty': 'intermediate', | |
| 'estimated_hours': 5 | |
| } | |
| ] | |
| } | |
| } | |
| def display(self): | |
| """Display the learning paths interface""" | |
| st.header("Learning Paths") | |
| # Path selection | |
| selected_path = st.selectbox( | |
| "Select Learning Path", | |
| options=list(self.curriculum.keys()), | |
| format_func=lambda x: self.curriculum[x]['name'], | |
| key="path_selector" | |
| ) | |
| # Display selected path details | |
| if selected_path: | |
| self.display_path_details(selected_path) | |
| def display_path_details(self, path_id: str): | |
| """Display detailed view of a learning path""" | |
| path = self.curriculum[path_id] | |
| # Path header and description | |
| st.subheader(path['name']) | |
| st.write(path['description']) | |
| # Prerequisites check | |
| if path['prerequisites']: | |
| prereq_met = self.check_prerequisites(path['prerequisites']) | |
| if not prereq_met: | |
| st.warning("β οΈ Please complete the prerequisite paths first: " + | |
| ", ".join([self.curriculum[p]['name'] for p in path['prerequisites']])) | |
| return | |
| # Progress overview | |
| total_modules = len(path['modules']) | |
| completed_modules = len([m for m in path['modules'] | |
| if m['id'] in st.session_state.learning_state['completed_modules']]) | |
| progress = completed_modules / total_modules | |
| st.progress(progress, f"Progress: {completed_modules}/{total_modules} modules completed") | |
| # Display modules | |
| for module in path['modules']: | |
| self.display_module(module, path_id) | |
| def display_module(self, module: Dict, path_id: str): | |
| """Display individual module with its details and status""" | |
| completed = module['id'] in st.session_state.learning_state['completed_modules'] | |
| with st.expander( | |
| f"{'β ' if completed else 'π'} {module['name']} " | |
| f"({module['difficulty']} β’ {module['estimated_hours']}h)", | |
| expanded=not completed | |
| ): | |
| # Module description and concepts | |
| st.write("**Key Concepts:**") | |
| for concept in module['concepts']: | |
| mastery = self.get_concept_mastery(concept) | |
| st.write(f"- {concept.replace('_', ' ').title()}: {self.format_mastery(mastery)}") | |
| # Module actions | |
| cols = st.columns([1, 1, 1]) | |
| with cols[0]: | |
| if st.button("Start Learning", key=f"start_{module['id']}", | |
| disabled=completed): | |
| self.start_module(module['id'], path_id) | |
| with cols[1]: | |
| if st.button("Take Quiz", key=f"quiz_{module['id']}"): | |
| self.launch_quiz(module['id']) | |
| with cols[2]: | |
| if st.button("Mark Complete", key=f"complete_{module['id']}", | |
| disabled=completed): | |
| self.complete_module(module['id'], path_id) | |
| def start_module(self, module_id: str, path_id: str): | |
| """Handle module start action""" | |
| st.session_state.learning_state['current_module'] = module_id | |
| st.session_state.learning_state['current_path'] = path_id | |
| self.update_learning_streak() | |
| st.rerun() | |
| def complete_module(self, module_id: str, path_id: str): | |
| """Handle module completion""" | |
| state = st.session_state.learning_state | |
| # Mark module as completed | |
| state['completed_modules'].add(module_id) | |
| # Update concept mastery | |
| module = next(m for m in self.curriculum[path_id]['modules'] | |
| if m['id'] == module_id) | |
| for concept in module['concepts']: | |
| self.update_concept_mastery(concept) | |
| # Check for achievements | |
| self.check_achievements(module_id, path_id) | |
| # Update streak | |
| self.update_learning_streak() | |
| st.success(f"π Congratulations! You've completed {module['name']}!") | |
| st.rerun() | |
| def launch_quiz(self, module_id: str): | |
| """Initialize and launch module quiz""" | |
| st.session_state.quiz_active = True | |
| st.session_state.current_quiz_module = module_id | |
| st.rerun() | |
| def check_prerequisites(self, prerequisites: List[str]) -> bool: | |
| """Check if prerequisites are met""" | |
| for prereq in prerequisites: | |
| prereq_modules = {m['id'] for m in self.curriculum[prereq]['modules']} | |
| if not prereq_modules.issubset(st.session_state.learning_state['completed_modules']): | |
| return False | |
| return True | |
| def update_concept_mastery(self, concept: str, score: float = 0.8): | |
| """Update mastery level for a concept""" | |
| current = st.session_state.learning_state['mastery_levels'].get(concept, 0.0) | |
| st.session_state.learning_state['mastery_levels'][concept] = min(1.0, current + score) | |
| def get_concept_mastery(self, concept: str) -> float: | |
| """Get current mastery level for a concept""" | |
| return st.session_state.learning_state['mastery_levels'].get(concept, 0.0) | |
| def format_mastery(mastery: float) -> str: | |
| """Format mastery level for display""" | |
| if mastery >= 0.8: | |
| return "π Mastered" | |
| elif mastery >= 0.5: | |
| return "π In Progress" | |
| else: | |
| return "πΈ Not Started" | |
| def update_learning_streak(self): | |
| """Update the user's learning streak""" | |
| state = st.session_state.learning_state | |
| today = datetime.now().date() | |
| if state['last_active'] is None: | |
| state['learning_streak'] = 1 | |
| else: | |
| last_active = datetime.strptime(state['last_active'], "%Y-%m-%d").date() | |
| if (today - last_active).days == 1: | |
| state['learning_streak'] += 1 | |
| elif (today - last_active).days > 1: | |
| state['learning_streak'] = 1 | |
| state['last_active'] = today.strftime("%Y-%m-%d") | |
| def check_achievements(self, module_id: str, path_id: str): | |
| """Check and award achievements""" | |
| state = st.session_state.learning_state | |
| achievements = [] | |
| # First module completion | |
| if len(state['completed_modules']) == 1: | |
| achievements.append({ | |
| 'name': 'First Steps! π', | |
| 'description': 'Completed your first module', | |
| 'date': datetime.now().strftime("%Y-%m-%d") | |
| }) | |
| # Path completion | |
| path_modules = {m['id'] for m in self.curriculum[path_id]['modules']} | |
| if path_modules.issubset(state['completed_modules']): | |
| achievements.append({ | |
| 'name': f'Path Master: {self.curriculum[path_id]["name"]} π', | |
| 'description': f'Completed the entire {self.curriculum[path_id]["name"]} path', | |
| 'date': datetime.now().strftime("%Y-%m-%d") | |
| }) | |
| # Learning streak achievements | |
| streak_achievements = { | |
| 7: 'Week Warrior! ποΈ', | |
| 30: 'Monthly Master! π ', | |
| 100: 'Centurion! π―' | |
| } | |
| for days, name in streak_achievements.items(): | |
| if state['learning_streak'] >= days: | |
| achievement_exists = any(a['name'] == name for a in state['achievements']) | |
| if not achievement_exists: | |
| achievements.append({ | |
| 'name': name, | |
| 'description': f'Maintained a {days}-day learning streak', | |
| 'date': datetime.now().strftime("%Y-%m-%d") | |
| }) | |
| # Add new achievements | |
| state['achievements'].extend(achievements) | |
| # Display new achievements | |
| for achievement in achievements: | |
| st.balloons() | |
| st.success(f"π New Achievement: {achievement['name']} - {achievement['description']}") |