Spaces:
Sleeping
Sleeping
| """ | |
| EdTech Extensions - Student Profile Management | |
| This module provides functionality for managing student profiles in the MCP EdTech system. | |
| It includes classes and functions for creating, retrieving, updating, and analyzing student profiles. | |
| """ | |
| from datetime import datetime | |
| from typing import Dict, List, Optional, Any, Set | |
| from uuid import uuid4 | |
| import json | |
| import os | |
| from enum import Enum | |
| from pydantic import BaseModel, Field | |
| from ..mcp_core.protocol import EducationalLevel, LearningObjective, StudentProfile | |
| class LearningStyle(str, Enum): | |
| """Learning styles for student profile customization.""" | |
| VISUAL = "visual" | |
| AUDITORY = "auditory" | |
| READING = "reading" | |
| KINESTHETIC = "kinesthetic" | |
| class StudentProfileManager: | |
| """ | |
| Manages student profiles in the MCP EdTech system. | |
| This class provides functionality for creating, retrieving, updating, | |
| and analyzing student profiles. | |
| """ | |
| def __init__(self, storage_dir: str = "./storage/students"): | |
| """ | |
| Initialize a new StudentProfileManager. | |
| Args: | |
| storage_dir: Directory to store student profiles in. | |
| """ | |
| self.storage_dir = storage_dir | |
| os.makedirs(storage_dir, exist_ok=True) | |
| self.profiles: Dict[str, StudentProfile] = {} | |
| def _get_profile_path(self, student_id: str) -> str: | |
| """ | |
| Get the file path for a student profile. | |
| Args: | |
| student_id: The ID of the student. | |
| Returns: | |
| The file path for the student profile. | |
| """ | |
| return os.path.join(self.storage_dir, f"{student_id}.json") | |
| async def create_profile( | |
| self, | |
| name: str, | |
| educational_level: EducationalLevel, | |
| learning_style: Optional[str] = None, | |
| interests: Optional[List[str]] = None, | |
| strengths: Optional[List[str]] = None, | |
| areas_for_improvement: Optional[List[str]] = None | |
| ) -> StudentProfile: | |
| """ | |
| Create a new student profile. | |
| Args: | |
| name: Student's name. | |
| educational_level: Student's educational level. | |
| learning_style: Student's preferred learning style. | |
| interests: Student's interests. | |
| strengths: Student's academic strengths. | |
| areas_for_improvement: Areas where the student needs improvement. | |
| Returns: | |
| The newly created StudentProfile. | |
| """ | |
| student_id = str(uuid4()) | |
| profile = StudentProfile( | |
| id=student_id, | |
| name=name, | |
| educational_level=educational_level, | |
| learning_style=learning_style or "", | |
| interests=interests or [], | |
| strengths=strengths or [], | |
| areas_for_improvement=areas_for_improvement or [], | |
| completed_objectives=[], | |
| current_objectives=[] | |
| ) | |
| # Save to memory and disk | |
| self.profiles[student_id] = profile | |
| await self._save_profile(profile) | |
| return profile | |
| async def _save_profile(self, profile: StudentProfile) -> bool: | |
| """ | |
| Save a student profile to disk. | |
| Args: | |
| profile: The StudentProfile to save. | |
| Returns: | |
| True if the save was successful, False otherwise. | |
| """ | |
| try: | |
| with open(self._get_profile_path(profile.id), 'w') as f: | |
| json.dump(profile.dict(), f, indent=2) | |
| return True | |
| except Exception as e: | |
| print(f"Error saving student profile: {e}") | |
| return False | |
| async def get_profile(self, student_id: str) -> Optional[StudentProfile]: | |
| """ | |
| Get a student profile by ID. | |
| Args: | |
| student_id: The ID of the student. | |
| Returns: | |
| The StudentProfile if found, None otherwise. | |
| """ | |
| # Check memory cache first | |
| if student_id in self.profiles: | |
| return self.profiles[student_id] | |
| # Try to load from disk | |
| try: | |
| path = self._get_profile_path(student_id) | |
| if not os.path.exists(path): | |
| return None | |
| with open(path, 'r') as f: | |
| data = json.load(f) | |
| profile = StudentProfile(**data) | |
| self.profiles[student_id] = profile | |
| return profile | |
| except Exception as e: | |
| print(f"Error loading student profile: {e}") | |
| return None | |
| async def update_profile( | |
| self, | |
| student_id: str, | |
| updates: Dict[str, Any] | |
| ) -> Optional[StudentProfile]: | |
| """ | |
| Update a student profile. | |
| Args: | |
| student_id: The ID of the student. | |
| updates: Dictionary of updates to apply. | |
| Returns: | |
| The updated StudentProfile if found, None otherwise. | |
| """ | |
| profile = await self.get_profile(student_id) | |
| if not profile: | |
| return None | |
| # Apply updates | |
| profile_dict = profile.dict() | |
| for key, value in updates.items(): | |
| if key in profile_dict: | |
| setattr(profile, key, value) | |
| # Save updated profile | |
| await self._save_profile(profile) | |
| self.profiles[student_id] = profile | |
| return profile | |
| async def delete_profile(self, student_id: str) -> bool: | |
| """ | |
| Delete a student profile. | |
| Args: | |
| student_id: The ID of the student. | |
| Returns: | |
| True if the deletion was successful, False otherwise. | |
| """ | |
| try: | |
| # Remove from memory | |
| if student_id in self.profiles: | |
| del self.profiles[student_id] | |
| # Remove from disk | |
| path = self._get_profile_path(student_id) | |
| if os.path.exists(path): | |
| os.remove(path) | |
| return True | |
| return False | |
| except Exception as e: | |
| print(f"Error deleting student profile: {e}") | |
| return False | |
| async def list_profiles(self) -> List[StudentProfile]: | |
| """ | |
| List all student profiles. | |
| Returns: | |
| List of StudentProfile objects. | |
| """ | |
| profiles = [] | |
| # Load all profiles from disk | |
| try: | |
| for filename in os.listdir(self.storage_dir): | |
| if filename.endswith('.json'): | |
| student_id = filename[:-5] # Remove .json extension | |
| profile = await self.get_profile(student_id) | |
| if profile: | |
| profiles.append(profile) | |
| except Exception as e: | |
| print(f"Error listing student profiles: {e}") | |
| return profiles | |
| async def add_completed_objective( | |
| self, | |
| student_id: str, | |
| objective_id: str | |
| ) -> Optional[StudentProfile]: | |
| """ | |
| Add a completed learning objective to a student profile. | |
| Args: | |
| student_id: The ID of the student. | |
| objective_id: The ID of the completed learning objective. | |
| Returns: | |
| The updated StudentProfile if found, None otherwise. | |
| """ | |
| profile = await self.get_profile(student_id) | |
| if not profile: | |
| return None | |
| # Add to completed objectives if not already there | |
| if objective_id not in profile.completed_objectives: | |
| profile.completed_objectives.append(objective_id) | |
| # Remove from current objectives if present | |
| if objective_id in profile.current_objectives: | |
| profile.current_objectives.remove(objective_id) | |
| # Save updated profile | |
| await self._save_profile(profile) | |
| self.profiles[student_id] = profile | |
| return profile | |
| async def add_current_objective( | |
| self, | |
| student_id: str, | |
| objective_id: str | |
| ) -> Optional[StudentProfile]: | |
| """ | |
| Add a current learning objective to a student profile. | |
| Args: | |
| student_id: The ID of the student. | |
| objective_id: The ID of the learning objective. | |
| Returns: | |
| The updated StudentProfile if found, None otherwise. | |
| """ | |
| profile = await self.get_profile(student_id) | |
| if not profile: | |
| return None | |
| # Add to current objectives if not already there and not completed | |
| if (objective_id not in profile.current_objectives and | |
| objective_id not in profile.completed_objectives): | |
| profile.current_objectives.append(objective_id) | |
| # Save updated profile | |
| await self._save_profile(profile) | |
| self.profiles[student_id] = profile | |
| return profile | |