Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -31,7 +31,7 @@ class MotivationalCoach:
|
|
31 |
self.dicas_estudo = [
|
32 |
"📌 Faça pequenas pausas a cada 45 minutos de estudo",
|
33 |
"💡 Revise o conteúdo do dia antes de dormir",
|
34 |
-
"🎯 Estabeleça metas diárias pequenas e alcançáveis",
|
35 |
"📊 Alterne entre diferentes tópicos para manter o interesse",
|
36 |
"🌟 Pratique questões antigas do Revalida regularmente",
|
37 |
"💪 Mantenha uma rotina regular de estudos",
|
@@ -45,22 +45,58 @@ class MotivationalCoach:
|
|
45 |
def get_study_tip(self) -> str:
|
46 |
return random.choice(self.dicas_estudo)
|
47 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
class CRMJABot:
|
49 |
def __init__(self):
|
50 |
self.db = DatabaseManager()
|
51 |
|
52 |
-
# Inicializa sistema de performance
|
53 |
self.performance, self.material_generator, self.tracker = initialize_performance_system(
|
54 |
self.db.get_connection()
|
55 |
)
|
56 |
|
57 |
self.planner = StudyPlanGenerator(self.db)
|
58 |
self.coach = MotivationalCoach()
|
|
|
|
|
59 |
|
60 |
try:
|
61 |
self.qa_pipeline = pipeline(
|
62 |
"question-answering",
|
63 |
-
model="pierreguillou/bert-base-cased-squad-v1.1-portuguese",
|
64 |
device=-1
|
65 |
)
|
66 |
except Exception as e:
|
@@ -76,27 +112,80 @@ class CRMJABot:
|
|
76 |
print(f"Erro na inicialização: {str(e)}")
|
77 |
|
78 |
def process_message(self, message, user_id, history):
|
79 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
try:
|
81 |
-
# Obtém métricas detalhadas usando o novo sistema
|
82 |
metrics = self.performance.get_performance_metrics(user_id)
|
83 |
streak_info = self.tracker.calculate_study_streak(user_id)
|
84 |
|
85 |
response = f"""📊 Análise Detalhada do seu Progresso:
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
|
93 |
for topic, data in metrics['topic_metrics'].items():
|
94 |
-
avg_score =
|
95 |
response += f"\n ▪ {topic}: {avg_score:.1f}% ({data['total_hours']}h)"
|
96 |
|
97 |
-
# Adiciona recomendações baseadas no desempenho
|
98 |
weak_topics = [topic for topic, data in metrics['topic_metrics'].items()
|
99 |
-
if
|
100 |
|
101 |
if weak_topics:
|
102 |
response += "\n\n📚 Áreas que precisam de mais atenção:"
|
@@ -105,7 +194,7 @@ class CRMJABot:
|
|
105 |
topic, metrics['topic_metrics'][topic]
|
106 |
)
|
107 |
response += f"\n ▪ {topic}:"
|
108 |
-
for resource in resources[:2]:
|
109 |
response += f"\n - {resource}"
|
110 |
|
111 |
response += f"\n\n{self.coach.get_motivational_message()}"
|
@@ -114,8 +203,8 @@ class CRMJABot:
|
|
114 |
|
115 |
except Exception as e:
|
116 |
return f"Erro ao verificar progresso: {str(e)}"
|
117 |
-
|
118 |
-
def study_mode(self, message
|
119 |
try:
|
120 |
parts = message.split()
|
121 |
if len(parts) < 3:
|
@@ -123,32 +212,29 @@ class CRMJABot:
|
|
123 |
|
124 |
Formato: /estudo área horas
|
125 |
Exemplo: /estudo ClínicaMédica 2.5"""
|
126 |
-
|
127 |
area = parts[1]
|
128 |
horas = float(parts[2])
|
129 |
-
|
130 |
-
# Registra a sessão
|
131 |
cursor = self.db.get_connection().cursor()
|
132 |
cursor.execute('''
|
133 |
-
INSERT INTO study_progress
|
134 |
(user_id, date, topic, horas_estudadas, performance_score)
|
135 |
VALUES (?, ?, ?, ?, ?)
|
136 |
''', (user_id, datetime.now().date(), area, horas, 0.0))
|
137 |
self.db.get_connection().commit()
|
138 |
-
|
139 |
-
|
140 |
-
metrics = self.performance.get_performance_metrics(user_id)
|
141 |
streak_info = self.tracker.calculate_study_streak(user_id)
|
142 |
-
|
143 |
-
# Gera plano personalizado para próxima sessão
|
144 |
next_plan = self.material_generator.generate_daily_plan(
|
145 |
user_id, horas, metrics['topic_metrics']
|
146 |
)
|
147 |
-
|
148 |
response = f"""✅ Ótimo trabalho! Registrei {horas}h de estudo em {area}
|
149 |
|
150 |
📊 Status atual:
|
151 |
-
⭐ Total de horas: {metrics['overall_metrics']['total_hours']:.1f}h
|
152 |
🔥 Sequência: {streak_info['current_streak']} dias
|
153 |
🏆 Recorde: {streak_info['longest_streak']} dias
|
154 |
|
@@ -156,33 +242,33 @@ Exemplo: /estudo ClínicaMédica 2.5"""
|
|
156 |
|
157 |
for area, horas in next_plan['distribuicao_horas'].items():
|
158 |
response += f"\n ▪ {area}: {horas}h"
|
159 |
-
|
160 |
response += f"\n\n{self.coach.get_motivational_message()}"
|
161 |
response += f"\n\n💡 Dica: {self.coach.get_study_tip()}"
|
162 |
-
|
163 |
return response
|
164 |
-
|
165 |
except Exception as e:
|
166 |
return f"Erro ao registrar estudo: {str(e)}"
|
167 |
|
168 |
-
def get_summary(self,
|
169 |
try:
|
170 |
metrics = self.performance.get_performance_metrics(user_id)
|
171 |
streak_info = self.tracker.calculate_study_streak(user_id)
|
172 |
-
|
173 |
response = f"""📊 Resumo Completo do seu Desempenho:
|
174 |
|
175 |
⏱ Métricas Gerais:
|
176 |
▪ Total de horas estudadas: {metrics['overall_metrics']['total_hours']:.1f}h
|
177 |
▪ Média de desempenho: {metrics['overall_metrics']['avg_performance']:.1f}%
|
178 |
-
▪ Dias de estudo: {metrics['overall_metrics']['study_days']}
|
179 |
▪ Sequência atual: {streak_info['current_streak']} dias
|
180 |
▪ Maior sequência: {streak_info['longest_streak']} dias
|
181 |
|
182 |
📈 Progresso por Área:"""
|
183 |
-
|
184 |
for topic, data in metrics['topic_metrics'].items():
|
185 |
-
avg_score =
|
186 |
last_study = data['last_study']
|
187 |
response += f"\n\n📌 {topic}:"
|
188 |
response += f"\n ▪ Desempenho: {avg_score:.1f}%"
|
@@ -190,12 +276,27 @@ Exemplo: /estudo ClínicaMédica 2.5"""
|
|
190 |
response += f"\n ▪ Último estudo: {last_study}"
|
191 |
|
192 |
response += f"\n\n{self.coach.get_motivational_message()}"
|
193 |
-
|
194 |
return response
|
195 |
-
|
196 |
except Exception as e:
|
197 |
return f"Erro ao gerar resumo: {str(e)}"
|
198 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
199 |
def create_interface():
|
200 |
bot = CRMJABot()
|
201 |
|
@@ -218,14 +319,9 @@ def create_interface():
|
|
218 |
clear = gr.ClearButton([msg, chatbot])
|
219 |
|
220 |
def respond(message, history):
|
|
|
|
|
|
|
221 |
bot_message = bot.process_message(message, user_id.value or "default_user", history)
|
222 |
history.append((message, bot_message))
|
223 |
-
return "", history
|
224 |
-
|
225 |
-
msg.submit(respond, [msg, chatbot], [msg, chatbot])
|
226 |
-
|
227 |
-
return interface
|
228 |
-
|
229 |
-
if __name__ == "__main__":
|
230 |
-
interface = create_interface()
|
231 |
-
interface.launch()
|
|
|
31 |
self.dicas_estudo = [
|
32 |
"📌 Faça pequenas pausas a cada 45 minutos de estudo",
|
33 |
"💡 Revise o conteúdo do dia antes de dormir",
|
34 |
+
"🎯 Estabeleça metas diárias pequenas e alcançáveis",
|
35 |
"📊 Alterne entre diferentes tópicos para manter o interesse",
|
36 |
"🌟 Pratique questões antigas do Revalida regularmente",
|
37 |
"💪 Mantenha uma rotina regular de estudos",
|
|
|
45 |
def get_study_tip(self) -> str:
|
46 |
return random.choice(self.dicas_estudo)
|
47 |
|
48 |
+
class AdminPanel:
|
49 |
+
def __init__(self, db: DatabaseManager):
|
50 |
+
self.db = db
|
51 |
+
|
52 |
+
def process_command(self, message: str, user_id: str) -> str:
|
53 |
+
if not self.db.is_admin(user_id):
|
54 |
+
return "Desculpe, apenas administradores têm acesso a este comando."
|
55 |
+
|
56 |
+
command = message.split(maxsplit=1)[1].strip() if len(message.split()) > 1 else ""
|
57 |
+
|
58 |
+
if command.startswith("adicionar_questao"):
|
59 |
+
try:
|
60 |
+
questao_data = json.loads(command.split(maxsplit=1)[1])
|
61 |
+
self.db.add_question(questao_data)
|
62 |
+
return "Questão adicionada com sucesso!"
|
63 |
+
except (json.JSONDecodeError, KeyError, IndexError):
|
64 |
+
return "Erro ao adicionar questão. Verifique o formato dos dados."
|
65 |
+
elif command.startswith("atualizar_questao"):
|
66 |
+
try:
|
67 |
+
questao_id, questao_data = command.split(maxsplit=2)[1:]
|
68 |
+
questao_data = json.loads(questao_data)
|
69 |
+
self.db.update_question(int(questao_id), questao_data)
|
70 |
+
return "Questão atualizada com sucesso!"
|
71 |
+
except (json.JSONDecodeError, KeyError, IndexError, ValueError):
|
72 |
+
return "Erro ao atualizar questão. Verifique o formato dos dados."
|
73 |
+
elif command.startswith("remover_questao"):
|
74 |
+
try:
|
75 |
+
questao_id = int(command.split(maxsplit=1)[1])
|
76 |
+
self.db.remove_question(questao_id)
|
77 |
+
return "Questão removida com sucesso!"
|
78 |
+
except (IndexError, ValueError):
|
79 |
+
return "Erro ao remover questão. Verifique o ID fornecido."
|
80 |
+
else:
|
81 |
+
return "Comando inválido. Comandos disponíveis: adicionar_questao, atualizar_questao, remover_questao."
|
82 |
+
|
83 |
class CRMJABot:
|
84 |
def __init__(self):
|
85 |
self.db = DatabaseManager()
|
86 |
|
|
|
87 |
self.performance, self.material_generator, self.tracker = initialize_performance_system(
|
88 |
self.db.get_connection()
|
89 |
)
|
90 |
|
91 |
self.planner = StudyPlanGenerator(self.db)
|
92 |
self.coach = MotivationalCoach()
|
93 |
+
self.admin_panel = AdminPanel(self.db)
|
94 |
+
self.user_info = {}
|
95 |
|
96 |
try:
|
97 |
self.qa_pipeline = pipeline(
|
98 |
"question-answering",
|
99 |
+
model="pierreguillou/bert-base-cased-squad-v1.1-portuguese",
|
100 |
device=-1
|
101 |
)
|
102 |
except Exception as e:
|
|
|
112 |
print(f"Erro na inicialização: {str(e)}")
|
113 |
|
114 |
def process_message(self, message, user_id, history):
|
115 |
+
if user_id not in self.user_info:
|
116 |
+
self.user_info[user_id] = {'name': None, 'email': None}
|
117 |
+
|
118 |
+
if not self.user_info[user_id]['name']:
|
119 |
+
self.user_info[user_id]['name'] = message
|
120 |
+
return f"Prazer em conhecê-lo(a), {message}! Por favor, me informe também seu email para que eu possa personalizar melhor sua experiência."
|
121 |
+
elif not self.user_info[user_id]['email']:
|
122 |
+
self.user_info[user_id]['email'] = message
|
123 |
+
self.db.add_user(user_id, self.user_info[user_id]['name'], self.user_info[user_id]['email'])
|
124 |
+
return f"Obrigado, {self.user_info[user_id]['name']}! Agora estou pronto para ajudá-lo(a) com sua preparação para o Revalida. O que você gostaria de fazer? Digite /help para ver as opções."
|
125 |
+
|
126 |
+
if message.strip() == "":
|
127 |
+
return ""
|
128 |
+
|
129 |
+
if message.startswith("/"):
|
130 |
+
command = message.split()[0]
|
131 |
+
if command == "/start":
|
132 |
+
return f"Bem-vindo de volta, {self.user_info[user_id]['name']}! Como posso ajudar hoje?"
|
133 |
+
elif command == "/help":
|
134 |
+
return """Comandos disponíveis:
|
135 |
+
/start - Inicia o bot
|
136 |
+
/help - Mostra os comandos disponíveis
|
137 |
+
/progresso - Verifica seu progresso
|
138 |
+
/resumo - Mostra um resumo do seu desempenho
|
139 |
+
/estudo - Registra uma sessão de estudo
|
140 |
+
/lembretes - Configura lembretes de estudo
|
141 |
+
/admin - Acessa o painel de administração (apenas para administradores)"""
|
142 |
+
elif command == "/progresso":
|
143 |
+
return self.check_progress(user_id)
|
144 |
+
elif command == "/resumo":
|
145 |
+
return self.get_summary(user_id)
|
146 |
+
elif command == "/estudo":
|
147 |
+
return self.study_mode(message, user_id)
|
148 |
+
elif command == "/lembretes":
|
149 |
+
return self.set_reminders(message, user_id)
|
150 |
+
elif command == "/admin":
|
151 |
+
return self.admin_panel.process_command(message, user_id)
|
152 |
+
else:
|
153 |
+
return "Comando inválido. Digite /help para ver os comandos disponíveis."
|
154 |
+
else:
|
155 |
+
return self.generate_response(message, user_id, history)
|
156 |
+
|
157 |
+
def generate_response(self, message, user_id, history):
|
158 |
+
if self.qa_pipeline:
|
159 |
+
try:
|
160 |
+
question = message
|
161 |
+
context = " ".join([msg[1] for msg in history[-5:]])
|
162 |
+
answer = self.qa_pipeline(question=question, context=context)
|
163 |
+
return answer['answer']
|
164 |
+
except Exception as e:
|
165 |
+
print(f"Erro ao gerar resposta: {e}")
|
166 |
+
return "Desculpe, não consegui entender sua pergunta. Poderia reformular?"
|
167 |
+
else:
|
168 |
+
return "Desculpe, ainda estou aprendendo a responder perguntas gerais. Por enquanto, posso ajudar com comandos específicos. Digite /help para ver o que sei fazer!"
|
169 |
+
|
170 |
+
def check_progress(self, user_id):
|
171 |
try:
|
|
|
172 |
metrics = self.performance.get_performance_metrics(user_id)
|
173 |
streak_info = self.tracker.calculate_study_streak(user_id)
|
174 |
|
175 |
response = f"""📊 Análise Detalhada do seu Progresso:
|
176 |
+
⭐ Total de horas estudadas: {metrics['overall_metrics']['total_hours']:.1f}h
|
177 |
+
🎯 Média de desempenho: {metrics['overall_metrics']['avg_performance']:.1f}%
|
178 |
+
📅 Dias de estudo: {metrics['overall_metrics']['study_days']}
|
179 |
+
🔥 Sequência atual: {streak_info['current_streak']} dias
|
180 |
+
🏆 Maior sequência: {streak_info['longest_streak']} dias
|
181 |
+
📈 Desempenho por área:"""
|
182 |
|
183 |
for topic, data in metrics['topic_metrics'].items():
|
184 |
+
avg_score = pd.Series(data['scores']).mean() if data['scores'] else 0
|
185 |
response += f"\n ▪ {topic}: {avg_score:.1f}% ({data['total_hours']}h)"
|
186 |
|
|
|
187 |
weak_topics = [topic for topic, data in metrics['topic_metrics'].items()
|
188 |
+
if pd.Series(data['scores']).mean() < 70]
|
189 |
|
190 |
if weak_topics:
|
191 |
response += "\n\n📚 Áreas que precisam de mais atenção:"
|
|
|
194 |
topic, metrics['topic_metrics'][topic]
|
195 |
)
|
196 |
response += f"\n ▪ {topic}:"
|
197 |
+
for resource in resources[:2]:
|
198 |
response += f"\n - {resource}"
|
199 |
|
200 |
response += f"\n\n{self.coach.get_motivational_message()}"
|
|
|
203 |
|
204 |
except Exception as e:
|
205 |
return f"Erro ao verificar progresso: {str(e)}"
|
206 |
+
|
207 |
+
def study_mode(self, message, user_id):
|
208 |
try:
|
209 |
parts = message.split()
|
210 |
if len(parts) < 3:
|
|
|
212 |
|
213 |
Formato: /estudo área horas
|
214 |
Exemplo: /estudo ClínicaMédica 2.5"""
|
215 |
+
|
216 |
area = parts[1]
|
217 |
horas = float(parts[2])
|
218 |
+
|
|
|
219 |
cursor = self.db.get_connection().cursor()
|
220 |
cursor.execute('''
|
221 |
+
INSERT INTO study_progress
|
222 |
(user_id, date, topic, horas_estudadas, performance_score)
|
223 |
VALUES (?, ?, ?, ?, ?)
|
224 |
''', (user_id, datetime.now().date(), area, horas, 0.0))
|
225 |
self.db.get_connection().commit()
|
226 |
+
|
227 |
+
metrics = self.performance.get_performance_metrics(user_id)
|
|
|
228 |
streak_info = self.tracker.calculate_study_streak(user_id)
|
229 |
+
|
|
|
230 |
next_plan = self.material_generator.generate_daily_plan(
|
231 |
user_id, horas, metrics['topic_metrics']
|
232 |
)
|
233 |
+
|
234 |
response = f"""✅ Ótimo trabalho! Registrei {horas}h de estudo em {area}
|
235 |
|
236 |
📊 Status atual:
|
237 |
+
⭐ Total de horas: {metrics['overall_metrics']['total_hours']:.1f}h
|
238 |
🔥 Sequência: {streak_info['current_streak']} dias
|
239 |
🏆 Recorde: {streak_info['longest_streak']} dias
|
240 |
|
|
|
242 |
|
243 |
for area, horas in next_plan['distribuicao_horas'].items():
|
244 |
response += f"\n ▪ {area}: {horas}h"
|
245 |
+
|
246 |
response += f"\n\n{self.coach.get_motivational_message()}"
|
247 |
response += f"\n\n💡 Dica: {self.coach.get_study_tip()}"
|
248 |
+
|
249 |
return response
|
250 |
+
|
251 |
except Exception as e:
|
252 |
return f"Erro ao registrar estudo: {str(e)}"
|
253 |
|
254 |
+
def get_summary(self, user_id):
|
255 |
try:
|
256 |
metrics = self.performance.get_performance_metrics(user_id)
|
257 |
streak_info = self.tracker.calculate_study_streak(user_id)
|
258 |
+
|
259 |
response = f"""📊 Resumo Completo do seu Desempenho:
|
260 |
|
261 |
⏱ Métricas Gerais:
|
262 |
▪ Total de horas estudadas: {metrics['overall_metrics']['total_hours']:.1f}h
|
263 |
▪ Média de desempenho: {metrics['overall_metrics']['avg_performance']:.1f}%
|
264 |
+
▪ Dias de estudo: {metrics['overall_metrics']['study_days']}
|
265 |
▪ Sequência atual: {streak_info['current_streak']} dias
|
266 |
▪ Maior sequência: {streak_info['longest_streak']} dias
|
267 |
|
268 |
📈 Progresso por Área:"""
|
269 |
+
|
270 |
for topic, data in metrics['topic_metrics'].items():
|
271 |
+
avg_score = pd.Series(data['scores']).mean() if data['scores'] else 0
|
272 |
last_study = data['last_study']
|
273 |
response += f"\n\n📌 {topic}:"
|
274 |
response += f"\n ▪ Desempenho: {avg_score:.1f}%"
|
|
|
276 |
response += f"\n ▪ Último estudo: {last_study}"
|
277 |
|
278 |
response += f"\n\n{self.coach.get_motivational_message()}"
|
279 |
+
|
280 |
return response
|
281 |
+
|
282 |
except Exception as e:
|
283 |
return f"Erro ao gerar resumo: {str(e)}"
|
284 |
|
285 |
+
def set_reminders(self, message, user_id):
|
286 |
+
parts = message.split()
|
287 |
+
if len(parts) < 3:
|
288 |
+
return """📅 Para configurar lembretes de estudo:
|
289 |
+
|
290 |
+
Formato: /lembretes hora frequência
|
291 |
+
Exemplo: /lembretes 20:00 diariamente"""
|
292 |
+
|
293 |
+
reminder_time = parts[1]
|
294 |
+
frequency = parts[2]
|
295 |
+
|
296 |
+
self.db.set_reminder(user_id, reminder_time, frequency)
|
297 |
+
|
298 |
+
return f"✅ Lembrete de estudo configurado com sucesso para as {reminder_time}, {frequency}!"
|
299 |
+
|
300 |
def create_interface():
|
301 |
bot = CRMJABot()
|
302 |
|
|
|
319 |
clear = gr.ClearButton([msg, chatbot])
|
320 |
|
321 |
def respond(message, history):
|
322 |
+
if message.strip() == "":
|
323 |
+
return "", history
|
324 |
+
|
325 |
bot_message = bot.process_message(message, user_id.value or "default_user", history)
|
326 |
history.append((message, bot_message))
|
327 |
+
return "", history
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|