Spaces:
Running
Running
| """ | |
| Student profile data models for TutorX-MCP. | |
| This module defines data structures for storing and managing | |
| student learning profiles, preferences, and characteristics. | |
| """ | |
| from datetime import datetime, timedelta | |
| from typing import Dict, List, Optional, Any | |
| from dataclasses import dataclass, field | |
| from enum import Enum | |
| import json | |
| class LearningStyle(Enum): | |
| """Learning style preferences.""" | |
| VISUAL = "visual" | |
| AUDITORY = "auditory" | |
| KINESTHETIC = "kinesthetic" | |
| READING_WRITING = "reading_writing" | |
| MULTIMODAL = "multimodal" | |
| class LearningPace(Enum): | |
| """Learning pace preferences.""" | |
| SLOW = "slow" | |
| MODERATE = "moderate" | |
| FAST = "fast" | |
| ADAPTIVE = "adaptive" | |
| class DifficultyPreference(Enum): | |
| """Difficulty progression preferences.""" | |
| GRADUAL = "gradual" | |
| MODERATE = "moderate" | |
| AGGRESSIVE = "aggressive" | |
| ADAPTIVE = "adaptive" | |
| class FeedbackPreference(Enum): | |
| """Feedback delivery preferences.""" | |
| IMMEDIATE = "immediate" | |
| DELAYED = "delayed" | |
| SUMMARY = "summary" | |
| MINIMAL = "minimal" | |
| class LearningPreferences: | |
| """Student learning preferences and settings.""" | |
| learning_style: LearningStyle = LearningStyle.MULTIMODAL | |
| learning_pace: LearningPace = LearningPace.ADAPTIVE | |
| difficulty_preference: DifficultyPreference = DifficultyPreference.ADAPTIVE | |
| feedback_preference: FeedbackPreference = FeedbackPreference.IMMEDIATE | |
| # Session preferences | |
| preferred_session_length: int = 30 # minutes | |
| max_session_length: int = 60 # minutes | |
| break_frequency: int = 20 # minutes between breaks | |
| # Content preferences | |
| gamification_enabled: bool = True | |
| hints_enabled: bool = True | |
| explanations_enabled: bool = True | |
| examples_enabled: bool = True | |
| # Notification preferences | |
| reminders_enabled: bool = True | |
| progress_notifications: bool = True | |
| achievement_notifications: bool = True | |
| def to_dict(self) -> Dict[str, Any]: | |
| """Convert to dictionary for serialization.""" | |
| return { | |
| 'learning_style': self.learning_style.value, | |
| 'learning_pace': self.learning_pace.value, | |
| 'difficulty_preference': self.difficulty_preference.value, | |
| 'feedback_preference': self.feedback_preference.value, | |
| 'preferred_session_length': self.preferred_session_length, | |
| 'max_session_length': self.max_session_length, | |
| 'break_frequency': self.break_frequency, | |
| 'gamification_enabled': self.gamification_enabled, | |
| 'hints_enabled': self.hints_enabled, | |
| 'explanations_enabled': self.explanations_enabled, | |
| 'examples_enabled': self.examples_enabled, | |
| 'reminders_enabled': self.reminders_enabled, | |
| 'progress_notifications': self.progress_notifications, | |
| 'achievement_notifications': self.achievement_notifications | |
| } | |
| def from_dict(cls, data: Dict[str, Any]) -> 'LearningPreferences': | |
| """Create from dictionary.""" | |
| return cls( | |
| learning_style=LearningStyle(data.get('learning_style', 'multimodal')), | |
| learning_pace=LearningPace(data.get('learning_pace', 'adaptive')), | |
| difficulty_preference=DifficultyPreference(data.get('difficulty_preference', 'adaptive')), | |
| feedback_preference=FeedbackPreference(data.get('feedback_preference', 'immediate')), | |
| preferred_session_length=data.get('preferred_session_length', 30), | |
| max_session_length=data.get('max_session_length', 60), | |
| break_frequency=data.get('break_frequency', 20), | |
| gamification_enabled=data.get('gamification_enabled', True), | |
| hints_enabled=data.get('hints_enabled', True), | |
| explanations_enabled=data.get('explanations_enabled', True), | |
| examples_enabled=data.get('examples_enabled', True), | |
| reminders_enabled=data.get('reminders_enabled', True), | |
| progress_notifications=data.get('progress_notifications', True), | |
| achievement_notifications=data.get('achievement_notifications', True) | |
| ) | |
| class StudentGoals: | |
| """Student learning goals and objectives.""" | |
| target_concepts: List[str] = field(default_factory=list) | |
| target_mastery_level: float = 0.8 | |
| target_completion_date: Optional[datetime] = None | |
| daily_time_goal: int = 30 # minutes per day | |
| weekly_concept_goal: int = 2 # concepts per week | |
| # Long-term goals | |
| grade_level_target: Optional[str] = None | |
| subject_focus_areas: List[str] = field(default_factory=list) | |
| career_interests: List[str] = field(default_factory=list) | |
| def to_dict(self) -> Dict[str, Any]: | |
| """Convert to dictionary for serialization.""" | |
| return { | |
| 'target_concepts': self.target_concepts, | |
| 'target_mastery_level': self.target_mastery_level, | |
| 'target_completion_date': self.target_completion_date.isoformat() if self.target_completion_date else None, | |
| 'daily_time_goal': self.daily_time_goal, | |
| 'weekly_concept_goal': self.weekly_concept_goal, | |
| 'grade_level_target': self.grade_level_target, | |
| 'subject_focus_areas': self.subject_focus_areas, | |
| 'career_interests': self.career_interests | |
| } | |
| def from_dict(cls, data: Dict[str, Any]) -> 'StudentGoals': | |
| """Create from dictionary.""" | |
| target_date = None | |
| if data.get('target_completion_date'): | |
| target_date = datetime.fromisoformat(data['target_completion_date']) | |
| return cls( | |
| target_concepts=data.get('target_concepts', []), | |
| target_mastery_level=data.get('target_mastery_level', 0.8), | |
| target_completion_date=target_date, | |
| daily_time_goal=data.get('daily_time_goal', 30), | |
| weekly_concept_goal=data.get('weekly_concept_goal', 2), | |
| grade_level_target=data.get('grade_level_target'), | |
| subject_focus_areas=data.get('subject_focus_areas', []), | |
| career_interests=data.get('career_interests', []) | |
| ) | |
| class StudentProfile: | |
| """Comprehensive student learning profile.""" | |
| student_id: str | |
| name: Optional[str] = None | |
| grade_level: Optional[str] = None | |
| age: Optional[int] = None | |
| # Learning characteristics | |
| preferences: LearningPreferences = field(default_factory=LearningPreferences) | |
| goals: StudentGoals = field(default_factory=StudentGoals) | |
| # Profile metadata | |
| created_at: datetime = field(default_factory=datetime.utcnow) | |
| last_updated: datetime = field(default_factory=datetime.utcnow) | |
| last_active: Optional[datetime] = None | |
| # Adaptive learning state | |
| current_difficulty_level: float = 0.5 | |
| learning_velocity: float = 0.0 # concepts per day | |
| engagement_level: float = 0.5 | |
| # Performance summary | |
| total_concepts_attempted: int = 0 | |
| total_concepts_mastered: int = 0 | |
| total_learning_time: int = 0 # minutes | |
| average_accuracy: float = 0.0 | |
| # Strengths and challenges | |
| strength_areas: List[str] = field(default_factory=list) | |
| challenge_areas: List[str] = field(default_factory=list) | |
| # Adaptive learning insights | |
| learning_patterns: List[str] = field(default_factory=list) | |
| recommended_strategies: List[str] = field(default_factory=list) | |
| def update_last_active(self): | |
| """Update last active timestamp.""" | |
| self.last_active = datetime.utcnow() | |
| self.last_updated = datetime.utcnow() | |
| def update_performance_summary(self, concepts_attempted: int, concepts_mastered: int, | |
| learning_time: int, accuracy: float): | |
| """Update performance summary statistics.""" | |
| self.total_concepts_attempted = concepts_attempted | |
| self.total_concepts_mastered = concepts_mastered | |
| self.total_learning_time = learning_time | |
| self.average_accuracy = accuracy | |
| self.last_updated = datetime.utcnow() | |
| def calculate_mastery_rate(self) -> float: | |
| """Calculate overall mastery rate.""" | |
| if self.total_concepts_attempted == 0: | |
| return 0.0 | |
| return self.total_concepts_mastered / self.total_concepts_attempted | |
| def calculate_daily_average_time(self, days: int = 30) -> float: | |
| """Calculate average daily learning time over specified period.""" | |
| if days <= 0: | |
| return 0.0 | |
| # This would need to be calculated from actual session data | |
| # For now, return a simple estimate | |
| return self.total_learning_time / max(1, days) | |
| def is_active_learner(self, days: int = 7) -> bool: | |
| """Check if student has been active in recent days.""" | |
| if not self.last_active: | |
| return False | |
| cutoff_date = datetime.utcnow() - timedelta(days=days) | |
| return self.last_active >= cutoff_date | |
| def get_learning_efficiency(self) -> float: | |
| """Calculate learning efficiency (mastery per hour).""" | |
| if self.total_learning_time == 0: | |
| return 0.0 | |
| hours = self.total_learning_time / 60.0 | |
| return self.total_concepts_mastered / hours | |
| def add_strength_area(self, area: str): | |
| """Add a strength area if not already present.""" | |
| if area not in self.strength_areas: | |
| self.strength_areas.append(area) | |
| self.last_updated = datetime.utcnow() | |
| def add_challenge_area(self, area: str): | |
| """Add a challenge area if not already present.""" | |
| if area not in self.challenge_areas: | |
| self.challenge_areas.append(area) | |
| self.last_updated = datetime.utcnow() | |
| def add_learning_pattern(self, pattern: str): | |
| """Add a detected learning pattern.""" | |
| if pattern not in self.learning_patterns: | |
| self.learning_patterns.append(pattern) | |
| self.last_updated = datetime.utcnow() | |
| def add_recommended_strategy(self, strategy: str): | |
| """Add a recommended learning strategy.""" | |
| if strategy not in self.recommended_strategies: | |
| self.recommended_strategies.append(strategy) | |
| self.last_updated = datetime.utcnow() | |
| def to_dict(self) -> Dict[str, Any]: | |
| """Convert to dictionary for serialization.""" | |
| return { | |
| 'student_id': self.student_id, | |
| 'name': self.name, | |
| 'grade_level': self.grade_level, | |
| 'age': self.age, | |
| 'preferences': self.preferences.to_dict(), | |
| 'goals': self.goals.to_dict(), | |
| 'created_at': self.created_at.isoformat(), | |
| 'last_updated': self.last_updated.isoformat(), | |
| 'last_active': self.last_active.isoformat() if self.last_active else None, | |
| 'current_difficulty_level': self.current_difficulty_level, | |
| 'learning_velocity': self.learning_velocity, | |
| 'engagement_level': self.engagement_level, | |
| 'total_concepts_attempted': self.total_concepts_attempted, | |
| 'total_concepts_mastered': self.total_concepts_mastered, | |
| 'total_learning_time': self.total_learning_time, | |
| 'average_accuracy': self.average_accuracy, | |
| 'strength_areas': self.strength_areas, | |
| 'challenge_areas': self.challenge_areas, | |
| 'learning_patterns': self.learning_patterns, | |
| 'recommended_strategies': self.recommended_strategies | |
| } | |
| def from_dict(cls, data: Dict[str, Any]) -> 'StudentProfile': | |
| """Create from dictionary.""" | |
| created_at = datetime.fromisoformat(data['created_at']) if data.get('created_at') else datetime.utcnow() | |
| last_updated = datetime.fromisoformat(data['last_updated']) if data.get('last_updated') else datetime.utcnow() | |
| last_active = datetime.fromisoformat(data['last_active']) if data.get('last_active') else None | |
| preferences = LearningPreferences.from_dict(data.get('preferences', {})) | |
| goals = StudentGoals.from_dict(data.get('goals', {})) | |
| return cls( | |
| student_id=data['student_id'], | |
| name=data.get('name'), | |
| grade_level=data.get('grade_level'), | |
| age=data.get('age'), | |
| preferences=preferences, | |
| goals=goals, | |
| created_at=created_at, | |
| last_updated=last_updated, | |
| last_active=last_active, | |
| current_difficulty_level=data.get('current_difficulty_level', 0.5), | |
| learning_velocity=data.get('learning_velocity', 0.0), | |
| engagement_level=data.get('engagement_level', 0.5), | |
| total_concepts_attempted=data.get('total_concepts_attempted', 0), | |
| total_concepts_mastered=data.get('total_concepts_mastered', 0), | |
| total_learning_time=data.get('total_learning_time', 0), | |
| average_accuracy=data.get('average_accuracy', 0.0), | |
| strength_areas=data.get('strength_areas', []), | |
| challenge_areas=data.get('challenge_areas', []), | |
| learning_patterns=data.get('learning_patterns', []), | |
| recommended_strategies=data.get('recommended_strategies', []) | |
| ) | |
| def to_json(self) -> str: | |
| """Convert to JSON string.""" | |
| return json.dumps(self.to_dict(), indent=2) | |
| def from_json(cls, json_str: str) -> 'StudentProfile': | |
| """Create from JSON string.""" | |
| data = json.loads(json_str) | |
| return cls.from_dict(data) | |