File size: 6,214 Bytes
5400c2e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""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__()