"""Core module for managing learning context (memory -> LOs, prior cases, knowledge gaps, feedback preferences)""" # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/00_learning_context.ipynb. # %% auto 0 __all__ = ['logger', 'LearningContext'] # %% ../nbs/00_learning_context.ipynb 4 from typing import Dict, List, Optional, Any, Tuple from datetime import datetime import json from pathlib import Path from .utils import setup_logger, load_context_safely, save_context_safely # %% ../nbs/00_learning_context.ipynb 5 logger = setup_logger(__name__) # %% ../nbs/00_learning_context.ipynb 8 class LearningContext: """ Manages the dynamic learning context for each student. Tracks: - Current rotation details - Learning objectives and progress - Knowledge gaps and strengths - Custom feedback preferences """ def __init__(self, context_file: Optional[Path] = None): """ Initialize learning context, optionally loading from file. Args: context_file: Optional path to saved context """ # Initialize current rotation self.current_rotation = { "specialty": "", "start_date": None, "end_date": None, "key_focus_areas": [] } # Initialize learning objectives list self.learning_objectives = [] # [{"objective": str, "status": "active"|"completed", "added": datetime}] # Initialize knowledge profile self.knowledge_profile = { "gaps": {}, # topic -> confidence level "strengths": [], "recent_progress": [] # [{topic, improvement, date}] } # Initialize feedback preferences self.feedback_preferences = [] # [{"focus": str, "active": bool}] if context_file and context_file.exists(): self.load_context(context_file) logger.info("Learning context initialized") def update_rotation(self, rotation_details: Dict[str, Any]) -> None: """Update current rotation details""" self.current_rotation.update(rotation_details) def add_learning_objective(self, objective: str) -> None: """Add new learning objective""" self.learning_objectives.append({ "objective": objective, "status": "active", "added": datetime.now().isoformat() }) def complete_objective(self, objective: str) -> None: """Mark learning objective as completed""" for obj in self.learning_objectives: if obj["objective"] == objective and obj["status"] == "active": obj["status"] = "completed" obj["completed"] = datetime.now().isoformat() break def update_knowledge_gap(self, topic: str, confidence: float) -> None: """Update knowledge gap confidence level""" old_confidence = self.knowledge_profile["gaps"].get(topic) self.knowledge_profile["gaps"][topic] = confidence # Track progress if confidence improved if old_confidence and confidence > old_confidence: self.knowledge_profile["recent_progress"].append({ "topic": topic, "improvement": confidence - old_confidence, "date": datetime.now().isoformat() }) # Keep only recent progress self.knowledge_profile["recent_progress"] = \ self.knowledge_profile["recent_progress"][-5:] def add_strength(self, topic: str) -> None: """Add identified strength""" if topic not in self.knowledge_profile["strengths"]: self.knowledge_profile["strengths"].append(topic) def toggle_feedback_focus(self, focus: str, active: bool) -> None: """Toggle feedback focus area""" # Update if exists for pref in self.feedback_preferences: if pref["focus"] == focus: pref["active"] = active return # Add if new self.feedback_preferences.append({ "focus": focus, "active": active }) def save_context(self, file_path: Path) -> None: """Save context to file""" context_data = { "current_rotation": self.current_rotation, "learning_objectives": self.learning_objectives, "knowledge_profile": self.knowledge_profile, "feedback_preferences": self.feedback_preferences } save_context_safely(context_data, file_path) def load_context(self, file_path: Path) -> None: """Load context from file""" try: context_data = load_context_safely(file_path) # Use .get() with default values to handle missing keys self.current_rotation = context_data.get("current_rotation", { "specialty": "", "start_date": None, "end_date": None, "key_focus_areas": [] }) # Ensure required keys exist for key in ["specialty", "start_date", "end_date", "key_focus_areas"]: if key not in self.current_rotation: self.current_rotation[key] = None if key != "key_focus_areas" else [] self.learning_objectives = context_data.get("learning_objectives", []) self.knowledge_profile = context_data.get("knowledge_profile", { "gaps": {}, "strengths": [], "recent_progress": [] }) self.feedback_preferences = context_data.get("feedback_preferences", []) logger.info(f"Context loaded successfully from {file_path}") except Exception as e: logger.error(f"Error loading context: {str(e)}") # Initialize with defaults on error self.__init__()