Spaces:
Build error
Build error
File size: 8,883 Bytes
e205871 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
from datetime import datetime
from typing import Dict, List, Set
import streamlit as st
from src.utils.session import get_user_progress
class LearningService:
def __init__(self):
self.load_curriculum()
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 check_prerequisites(self, prerequisites: List[str]) -> bool:
"""Check if prerequisites are met"""
state = get_user_progress()
for prereq in prerequisites:
prereq_modules = {m['id'] for m in self.curriculum[prereq]['modules']}
if not prereq_modules.issubset(state['completed_modules']):
return False
return True
def get_path_progress(self, path_id: str) -> float:
"""Get progress percentage for a path"""
state = get_user_progress()
path_modules = {m['id'] for m in self.curriculum[path_id]['modules']}
completed = path_modules.intersection(state['completed_modules'])
return len(completed) / len(path_modules)
def is_module_completed(self, module_id: str) -> bool:
"""Check if a module is completed"""
state = get_user_progress()
return module_id in state['completed_modules']
def get_concept_mastery(self, concept: str) -> float:
"""Get mastery level for a concept"""
state = get_user_progress()
return state['mastery_levels'].get(concept, 0.0)
def format_mastery(self, 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 start_module(self, module_id: str, path_id: str):
"""Start a learning module"""
state = get_user_progress()
state['current_module'] = module_id
state['current_path'] = path_id
self.update_learning_streak()
def complete_module(self, module_id: str, path_id: str):
"""Complete a learning module"""
state = get_user_progress()
# 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()
def update_concept_mastery(self, concept: str, score: float = 0.8):
"""Update mastery level for a concept"""
state = get_user_progress()
current = state['mastery_levels'].get(concept, 0.0)
state['mastery_levels'][concept] = min(1.0, current + score)
def launch_quiz(self, module_id: str):
"""Initialize module quiz"""
st.session_state.quiz_active = True
st.session_state.current_quiz_module = module_id
def update_learning_streak(self):
"""Update learning streak"""
state = get_user_progress()
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 = get_user_progress()
new_achievements = []
# First module achievement
if len(state['completed_modules']) == 1:
new_achievements.append({
'name': 'First Steps! π',
'description': 'Completed your first module',
'date': datetime.now().strftime("%Y-%m-%d")
})
# Path completion achievement
path_modules = {m['id'] for m in self.curriculum[path_id]['modules']}
if path_modules.issubset(state['completed_modules']):
new_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:
new_achievements.append({
'name': name,
'description': f'Maintained a {days}-day learning streak',
'date': datetime.now().strftime("%Y-%m-%d")
})
# Add and display new achievements
for achievement in new_achievements:
if achievement not in state['achievements']:
state['achievements'].append(achievement)
st.balloons()
st.success(f"π New Achievement: {achievement['name']} - {achievement['description']}") |