Spaces:
Runtime error
Runtime error
Create study_generators.py
Browse files- study_generators.py +159 -0
study_generators.py
ADDED
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
mport json
|
2 |
+
from datetime import datetime, timedelta
|
3 |
+
from typing import Dict, List, Optional
|
4 |
+
import logging
|
5 |
+
|
6 |
+
logging.basicConfig(level=logging.INFO)
|
7 |
+
logger = logging.getLogger(__name__)
|
8 |
+
|
9 |
+
class StudyMaterialGenerator:
|
10 |
+
def __init__(self, db):
|
11 |
+
self.db = db
|
12 |
+
|
13 |
+
def generate_daily_questions(self, user_id: str, num_questions: int = 10) -> List[Dict]:
|
14 |
+
"""Gera questões diárias baseadas no perfil do usuário"""
|
15 |
+
try:
|
16 |
+
conn = self.db.get_connection()
|
17 |
+
cursor = conn.cursor()
|
18 |
+
|
19 |
+
# Busca áreas fracas do usuário
|
20 |
+
user_profile = self.db.get_user_profile(user_id)
|
21 |
+
weak_areas = user_profile.get('weak_areas', []) if user_profile else []
|
22 |
+
|
23 |
+
# Prioriza questões das áreas fracas
|
24 |
+
query = '''
|
25 |
+
SELECT * FROM previous_questions
|
26 |
+
WHERE area IN (?)
|
27 |
+
ORDER BY RANDOM()
|
28 |
+
LIMIT ?
|
29 |
+
'''
|
30 |
+
|
31 |
+
cursor.execute(query, (','.join(weak_areas), num_questions))
|
32 |
+
questions = cursor.fetchall()
|
33 |
+
|
34 |
+
return [dict(q) for q in questions]
|
35 |
+
|
36 |
+
except Exception as e:
|
37 |
+
logger.error(f"Erro ao gerar questões: {e}")
|
38 |
+
return []
|
39 |
+
|
40 |
+
def generate_study_material(self, topic: str) -> Dict:
|
41 |
+
"""Gera material de estudo para um tópico específico"""
|
42 |
+
try:
|
43 |
+
conn = self.db.get_connection()
|
44 |
+
cursor = conn.cursor()
|
45 |
+
|
46 |
+
# Busca casos clínicos relacionados
|
47 |
+
cursor.execute('''
|
48 |
+
SELECT * FROM clinical_cases
|
49 |
+
WHERE area = ?
|
50 |
+
ORDER BY RANDOM()
|
51 |
+
LIMIT 3
|
52 |
+
''', (topic,))
|
53 |
+
|
54 |
+
cases = cursor.fetchall()
|
55 |
+
|
56 |
+
return {
|
57 |
+
'topic': topic,
|
58 |
+
'clinical_cases': [dict(case) for case in cases],
|
59 |
+
'key_points': self._generate_key_points(topic),
|
60 |
+
'references': self._get_references(topic)
|
61 |
+
}
|
62 |
+
|
63 |
+
except Exception as e:
|
64 |
+
logger.error(f"Erro ao gerar material: {e}")
|
65 |
+
return {}
|
66 |
+
|
67 |
+
def _generate_key_points(self, topic: str) -> List[str]:
|
68 |
+
"""Gera pontos-chave para um tópico"""
|
69 |
+
# Implementar lógica para extrair pontos-chave
|
70 |
+
return []
|
71 |
+
|
72 |
+
def _get_references(self, topic: str) -> List[str]:
|
73 |
+
"""Busca referências para um tópico"""
|
74 |
+
# Implementar lógica para buscar referências
|
75 |
+
return []
|
76 |
+
|
77 |
+
class StudyPlanGenerator:
|
78 |
+
def __init__(self, db):
|
79 |
+
self.db = db
|
80 |
+
|
81 |
+
def generate_plan(self, user_id: str, duration_days: int = 30) -> Dict:
|
82 |
+
"""Gera um plano de estudos personalizado"""
|
83 |
+
try:
|
84 |
+
# Busca perfil do usuário
|
85 |
+
user_profile = self.db.get_user_profile(user_id)
|
86 |
+
if not user_profile:
|
87 |
+
return {}
|
88 |
+
|
89 |
+
# Calcula distribuição de tempo
|
90 |
+
weak_areas = user_profile.get('weak_areas', [])
|
91 |
+
study_hours = user_profile.get('study_hours', 4)
|
92 |
+
|
93 |
+
plan = {
|
94 |
+
'user_id': user_id,
|
95 |
+
'duration_days': duration_days,
|
96 |
+
'daily_schedule': self._create_daily_schedule(study_hours, weak_areas),
|
97 |
+
'weekly_goals': self._create_weekly_goals(weak_areas),
|
98 |
+
'start_date': datetime.now().date(),
|
99 |
+
'end_date': (datetime.now() + timedelta(days=duration_days)).date()
|
100 |
+
}
|
101 |
+
|
102 |
+
# Salva o plano no banco
|
103 |
+
self._save_plan(user_id, plan)
|
104 |
+
|
105 |
+
return plan
|
106 |
+
|
107 |
+
except Exception as e:
|
108 |
+
logger.error(f"Erro ao gerar plano: {e}")
|
109 |
+
return {}
|
110 |
+
|
111 |
+
def _create_daily_schedule(self, hours: int, areas: List[str]) -> Dict:
|
112 |
+
"""Cria cronograma diário"""
|
113 |
+
schedule = {}
|
114 |
+
hours_per_area = hours / len(areas) if areas else hours
|
115 |
+
|
116 |
+
for area in areas:
|
117 |
+
schedule[area] = {
|
118 |
+
'hours': hours_per_area,
|
119 |
+
'questions_goal': int(hours_per_area * 10), # 10 questões por hora
|
120 |
+
'review_time': hours_per_area * 0.2 # 20% do tempo para revisão
|
121 |
+
}
|
122 |
+
|
123 |
+
return schedule
|
124 |
+
|
125 |
+
def _create_weekly_goals(self, areas: List[str]) -> List[Dict]:
|
126 |
+
"""Cria metas semanais"""
|
127 |
+
goals = []
|
128 |
+
for area in areas:
|
129 |
+
goals.append({
|
130 |
+
'area': area,
|
131 |
+
'questions_target': 70, # 10 questões por dia
|
132 |
+
'mock_exam_target': 1, # 1 simulado por semana
|
133 |
+
'review_sessions': 2 # 2 sessões de revisão
|
134 |
+
})
|
135 |
+
return goals
|
136 |
+
|
137 |
+
def _save_plan(self, user_id: str, plan: Dict) -> None:
|
138 |
+
"""Salva o plano no banco de dados"""
|
139 |
+
try:
|
140 |
+
conn = self.db.get_connection()
|
141 |
+
cursor = conn.cursor()
|
142 |
+
|
143 |
+
cursor.execute('''
|
144 |
+
INSERT INTO study_sessions
|
145 |
+
(user_id, start_time, end_time, topic, activity_type, notes)
|
146 |
+
VALUES (?, ?, ?, ?, ?, ?)
|
147 |
+
''', (
|
148 |
+
user_id,
|
149 |
+
datetime.now(),
|
150 |
+
datetime.now() + timedelta(days=plan['duration_days']),
|
151 |
+
'multiple',
|
152 |
+
'study_plan',
|
153 |
+
json.dumps(plan)
|
154 |
+
))
|
155 |
+
|
156 |
+
conn.commit()
|
157 |
+
|
158 |
+
except Exception as e:
|
159 |
+
logger.error(f"Erro ao salvar plano: {e}")
|