danielraynaud commited on
Commit
97d12e6
·
verified ·
1 Parent(s): a6d3af7

Create performance_system.py

Browse files
Files changed (1) hide show
  1. performance_system.py +238 -0
performance_system.py ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # performance_system.py
2
+ from datetime import datetime, timedelta
3
+ import pandas as pd
4
+ import numpy as np
5
+ from typing import Dict, List, Optional, Tuple
6
+ import json
7
+ import logging
8
+
9
+ # Configuração de logging
10
+ logging.basicConfig(
11
+ level=logging.INFO,
12
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
13
+ )
14
+ logger = logging.getLogger(__name__)
15
+
16
+ class PerformanceConstants:
17
+ """Constantes para análise de desempenho"""
18
+ MINIMUM_STUDY_HOURS = 4.0
19
+ IDEAL_CONSISTENCY = 0.7
20
+ LOW_PERFORMANCE_THRESHOLD = 0.3
21
+ MEDIUM_PERFORMANCE_THRESHOLD = 0.6
22
+ MIN_DAYS_FOR_TREND = 7
23
+ MAX_DAYS_ANALYSIS = 30
24
+
25
+ class PerformanceAnalyzer:
26
+ # [O código existente permanece o mesmo]
27
+
28
+ def get_performance_metrics(self, user_id: str, days: int = 30) -> Dict:
29
+ """Obtém métricas detalhadas de desempenho"""
30
+ try:
31
+ cursor = self.conn.cursor()
32
+ end_date = datetime.now().date()
33
+ start_date = end_date - timedelta(days=days)
34
+
35
+ cursor.execute('''
36
+ SELECT date, topic, horas_estudadas, performance_score
37
+ FROM study_progress
38
+ WHERE user_id = ? AND date BETWEEN ? AND ?
39
+ ORDER BY date
40
+ ''', (user_id, start_date, end_date))
41
+
42
+ data = cursor.fetchall()
43
+
44
+ metrics = {
45
+ "daily_metrics": {},
46
+ "topic_metrics": {},
47
+ "overall_metrics": {
48
+ "total_hours": 0,
49
+ "avg_performance": 0,
50
+ "study_days": 0
51
+ }
52
+ }
53
+
54
+ for date, topic, hours, score in data:
55
+ # Métricas diárias
56
+ if date not in metrics["daily_metrics"]:
57
+ metrics["daily_metrics"][date] = {
58
+ "hours": 0,
59
+ "topics": set()
60
+ }
61
+ metrics["daily_metrics"][date]["hours"] += hours
62
+ metrics["daily_metrics"][date]["topics"].add(topic)
63
+
64
+ # Métricas por tópico
65
+ if topic not in metrics["topic_metrics"]:
66
+ metrics["topic_metrics"][topic] = {
67
+ "total_hours": 0,
68
+ "scores": [],
69
+ "last_study": None
70
+ }
71
+ metrics["topic_metrics"][topic]["total_hours"] += hours
72
+ metrics["topic_metrics"][topic]["scores"].append(score)
73
+ metrics["topic_metrics"][topic]["last_study"] = date
74
+
75
+ # Métricas gerais
76
+ metrics["overall_metrics"]["total_hours"] += hours
77
+
78
+ # Calcular médias e estatísticas
79
+ if data:
80
+ all_scores = [score for _, _, _, score in data]
81
+ metrics["overall_metrics"]["avg_performance"] = np.mean(all_scores)
82
+ metrics["overall_metrics"]["study_days"] = len(metrics["daily_metrics"])
83
+
84
+ return metrics
85
+
86
+ except Exception as e:
87
+ logger.error(f"Erro ao obter métricas de desempenho: {e}")
88
+ return None
89
+
90
+ class StudyMaterialGenerator:
91
+ # [O código existente permanece o mesmo]
92
+
93
+ def generate_daily_plan(self, user_id: str,
94
+ available_hours: float,
95
+ performance_data: Dict) -> Dict[str, any]:
96
+ """Gera plano de estudos diário personalizado"""
97
+ try:
98
+ weak_areas = sorted(
99
+ performance_data["topic_metrics"].items(),
100
+ key=lambda x: np.mean(x[1]["scores"]) if x[1]["scores"] else 0
101
+ )
102
+
103
+ plan = {
104
+ "distribuicao_horas": {},
105
+ "prioridades": [],
106
+ "recursos_sugeridos": []
107
+ }
108
+
109
+ # Distribuir horas disponíveis
110
+ remaining_hours = available_hours
111
+ for area, metrics in weak_areas:
112
+ if remaining_hours <= 0:
113
+ break
114
+
115
+ # Áreas com desempenho mais baixo recebem mais tempo
116
+ weight = 1 - (np.mean(metrics["scores"]) if metrics["scores"] else 0)
117
+ hours_allocated = min(remaining_hours, available_hours * weight)
118
+
119
+ plan["distribuicao_horas"][area] = round(hours_allocated, 1)
120
+ remaining_hours -= hours_allocated
121
+
122
+ # Adicionar recursos recomendados
123
+ plan["recursos_sugeridos"].extend(
124
+ self.get_recommended_resources(area, metrics)
125
+ )
126
+
127
+ return plan
128
+
129
+ except Exception as e:
130
+ logger.error(f"Erro ao gerar plano diário: {e}")
131
+ return None
132
+
133
+ def get_recommended_resources(self, area: str,
134
+ metrics: Dict) -> List[str]:
135
+ """Retorna recursos recomendados baseados no desempenho"""
136
+ resources = []
137
+ avg_score = np.mean(metrics["scores"]) if metrics["scores"] else 0
138
+
139
+ if avg_score < 0.3:
140
+ resources.extend([
141
+ "📚 Material básico teórico",
142
+ "📝 Resumos esquematizados",
143
+ "🎥 Vídeo-aulas introdutórias"
144
+ ])
145
+ elif avg_score < 0.6:
146
+ resources.extend([
147
+ "📋 Questões comentadas",
148
+ "🏥 Casos clínicos simples",
149
+ "📊 Mapas mentais avançados"
150
+ ])
151
+ else:
152
+ resources.extend([
153
+ "🎯 Questões complexas",
154
+ "🏥 Casos clínicos avançados",
155
+ "📑 Artigos científicos"
156
+ ])
157
+
158
+ return resources
159
+
160
+ class ProgressTracker:
161
+ # [O código existente permanece o mesmo]
162
+
163
+ def calculate_study_streak(self, user_id: str) -> Dict[str, any]:
164
+ """Calcula sequência atual de estudos"""
165
+ try:
166
+ cursor = self.conn.cursor()
167
+ cursor.execute('''
168
+ SELECT DISTINCT date
169
+ FROM study_progress
170
+ WHERE user_id = ?
171
+ ORDER BY date DESC
172
+ ''', (user_id,))
173
+
174
+ dates = [row[0] for row in cursor.fetchall()]
175
+
176
+ if not dates:
177
+ return {
178
+ "current_streak": 0,
179
+ "longest_streak": 0,
180
+ "last_study_date": None
181
+ }
182
+
183
+ current_streak = 1
184
+ longest_streak = 1
185
+ current_date = datetime.strptime(dates[0], '%Y-%m-%d').date()
186
+
187
+ for i in range(1, len(dates)):
188
+ date = datetime.strptime(dates[i], '%Y-%m-%d').date()
189
+ if (current_date - date).days == 1:
190
+ current_streak += 1
191
+ longest_streak = max(longest_streak, current_streak)
192
+ else:
193
+ break
194
+ current_date = date
195
+
196
+ return {
197
+ "current_streak": current_streak,
198
+ "longest_streak": longest_streak,
199
+ "last_study_date": dates[0]
200
+ }
201
+
202
+ except Exception as e:
203
+ logger.error(f"Erro ao calcular sequência de estudos: {e}")
204
+ return None
205
+
206
+ def initialize_performance_system(db_connection) -> Tuple[PerformanceAnalyzer,
207
+ StudyMaterialGenerator,
208
+ ProgressTracker]:
209
+ """Inicializa o sistema de performance completo"""
210
+ try:
211
+ analyzer = PerformanceAnalyzer(db_connection)
212
+ material_gen = StudyMaterialGenerator(db_connection)
213
+ tracker = ProgressTracker(db_connection)
214
+
215
+ return analyzer, material_gen, tracker
216
+
217
+ except Exception as e:
218
+ logger.error(f"Erro ao inicializar sistema de performance: {e}")
219
+ return None, None, None
220
+
221
+ if __name__ == "__main__":
222
+ # Código para testes
223
+ import sqlite3
224
+
225
+ try:
226
+ conn = sqlite3.connect('revalida.db')
227
+ analyzer, material_gen, tracker = initialize_performance_system(conn)
228
+
229
+ # Teste básico
230
+ test_user = "test_user_1"
231
+ metrics = analyzer.get_performance_metrics(test_user)
232
+ if metrics:
233
+ print("Sistema funcionando corretamente")
234
+ print(f"Métricas obtidas: {json.dumps(metrics, indent=2)}")
235
+ except Exception as e:
236
+ print(f"Erro nos testes: {e}")
237
+ finally:
238
+ conn.close()