Spaces:
Runtime error
Runtime error
# simulado_system.py | |
import json | |
import uuid | |
import logging | |
from datetime import datetime, timedelta | |
from typing import Dict, List, Optional, Tuple | |
from difflib import SequenceMatcher | |
import numpy as np | |
# Configuração de logging | |
logging.basicConfig( | |
level=logging.INFO, | |
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' | |
) | |
logger = logging.getLogger(__name__) | |
class SimuladoConstants: | |
"""Constantes para configuração de simulados""" | |
TEMPO_PADRAO = 240 # minutos | |
QUESTOES_TOTAIS = 120 | |
NOTA_APROVACAO = 60 | |
NIVEIS = ["facil", "medio", "dificil", "mixed"] | |
PESO_SIMILARIDADE = 0.7 | |
class SimuladoSystem: | |
"""Sistema avançado de simulados e casos clínicos""" | |
def __init__(self, db_connection): | |
self.conn = db_connection | |
self.areas_simulado = { | |
"ClínicaMédica": 40, | |
"Cirurgia": 20, | |
"Pediatria": 15, | |
"GinecologiaObstetrícia": 15, | |
"MedicinaFamília": 5, | |
"SaúdeMental": 5 | |
} | |
self.simulados_ativos = {} # Cache de simulados em andamento | |
def create_simulado(self, difficulty: str = "mixed", | |
num_questions: int = SimuladoConstants.QUESTOES_TOTAIS) -> Dict: | |
"""Cria simulado personalizado com mais opções""" | |
try: | |
simulado_id = str(uuid.uuid4()) | |
simulado = { | |
"id": simulado_id, | |
"questoes": [], | |
"tempo_sugerido": self._calculate_time(num_questions), | |
"nivel": difficulty, | |
"data_criacao": datetime.now().isoformat(), | |
"status": "criado", | |
"estatisticas": { | |
"questoes_por_area": {}, | |
"distribuicao_dificuldade": {} | |
} | |
} | |
cursor = self.conn.cursor() | |
# Distribuição de questões por área | |
for area, percentual in self.areas_simulado.items(): | |
num_area_questions = int((percentual/100) * num_questions) | |
# Query considerando dificuldade | |
difficulty_clause = "" | |
if difficulty != "mixed": | |
difficulty_clause = "AND difficulty = ?" | |
params = (area, difficulty, num_area_questions) | |
else: | |
params = (area, num_area_questions) | |
cursor.execute(f''' | |
SELECT id, question_text, options, correct_answer, | |
explanation, difficulty, references | |
FROM previous_questions | |
WHERE area = ? {difficulty_clause} | |
ORDER BY RANDOM() | |
LIMIT ? | |
''', params) | |
questions = cursor.fetchall() | |
for q in questions: | |
question_data = { | |
"id": q[0], | |
"area": area, | |
"texto": q[1], | |
"opcoes": json.loads(q[2]), | |
"resposta": q[3], | |
"explicacao": q[4], | |
"dificuldade": q[5], | |
"referencias": json.loads(q[6]) if q[6] else [] | |
} | |
simulado["questoes"].append(question_data) | |
# Atualizar estatísticas | |
simulado["estatisticas"]["questoes_por_area"][area] = \ | |
simulado["estatisticas"]["questoes_por_area"].get(area, 0) + 1 | |
simulado["estatisticas"]["distribuicao_dificuldade"][q[5]] = \ | |
simulado["estatisticas"]["distribuicao_dificuldade"].get(q[5], 0) + 1 | |
self.simulados_ativos[simulado_id] = simulado | |
return simulado | |
except Exception as e: | |
logger.error(f"Erro ao criar simulado: {e}") | |
return None | |
def _calculate_time(self, num_questions: int) -> int: | |
"""Calcula tempo sugerido baseado no número de questões""" | |
return int(num_questions * 2) # 2 minutos por questão | |
def evaluate_simulado(self, simulado_id: str, | |
respostas: Dict[str, str], | |
tempo_usado: int = None) -> Dict: | |
"""Avalia respostas do simulado com análise detalhada""" | |
try: | |
if simulado_id not in self.simulados_ativos: | |
raise ValueError("Simulado não encontrado") | |
simulado = self.simulados_ativos[simulado_id] | |
resultado = { | |
"id": simulado_id, | |
"total_questoes": len(simulado["questoes"]), | |
"corretas": 0, | |
"tempo_usado": tempo_usado, | |
"desempenho_por_area": {}, | |
"analise_erros": [], | |
"recomendacoes": [], | |
"timestamp": datetime.now().isoformat() | |
} | |
# Análise detalhada por área | |
area_stats = {} | |
for area in self.areas_simulado: | |
area_stats[area] = { | |
"total": 0, | |
"corretas": 0, | |
"erros_comuns": [], | |
"tempo_medio": 0 | |
} | |
# Avaliação de cada resposta | |
for q_id, resp in respostas.items(): | |
questao = next((q for q in simulado["questoes"] if q["id"] == q_id), None) | |
if not questao: | |
continue | |
area = questao["area"] | |
area_stats[area]["total"] += 1 | |
if resp.upper() == questao["resposta"].upper(): | |
area_stats[area]["corretas"] += 1 | |
resultado["corretas"] += 1 | |
else: | |
# Análise do erro | |
area_stats[area]["erros_comuns"].append({ | |
"questao_id": q_id, | |
"resposta_dada": resp, | |
"resposta_correta": questao["resposta"], | |
"tema": questao.get("tema", ""), | |
"dificuldade": questao["dificuldade"] | |
}) | |
# Calcular porcentagens e gerar recomendações | |
for area, stats in area_stats.items(): | |
if stats["total"] > 0: | |
percentual = (stats["corretas"] / stats["total"]) * 100 | |
resultado["desempenho_por_area"][area] = { | |
"total": stats["total"], | |
"corretas": stats["corretas"], | |
"percentual": percentual, | |
"erros_comuns": stats["erros_comuns"] | |
} | |
if percentual < SimuladoConstants.NOTA_APROVACAO: | |
resultado["recomendacoes"].append( | |
self._generate_recommendations(area, stats) | |
) | |
# Salvar resultado no banco de dados | |
self._save_resultado(simulado_id, resultado) | |
return resultado | |
except Exception as e: | |
logger.error(f"Erro ao avaliar simulado: {e}") | |
return None | |
def _generate_recommendations(self, area: str, stats: Dict) -> Dict: | |
"""Gera recomendações detalhadas baseadas no desempenho""" | |
erros_comuns = self._analyze_common_errors(stats["erros_comuns"]) | |
return { | |
"area": area, | |
"sugestoes": [ | |
f"Revisar conceitos básicos de {area}", | |
f"Focar em {', '.join(erros_comuns[:3])}", | |
"Praticar questões similares", | |
"Revisar casos clínicos relacionados" | |
], | |
"recursos": [ | |
"banco de questões", | |
"casos clínicos", | |
"revisão teórica", | |
"videoaulas específicas" | |
], | |
"plano_acao": self._create_action_plan(area, stats) | |
} | |
def _analyze_common_errors(self, erros: List[Dict]) -> List[str]: | |
"""Analisa padrões comuns de erros""" | |
temas_errados = {} | |
for erro in erros: | |
tema = erro["tema"] | |
if tema in temas_errados: | |
temas_errados[tema] += 1 | |
else: | |
temas_errados[tema] = 1 | |
return sorted(temas_errados.keys(), | |
key=lambda x: temas_errados[x], | |
reverse=True) | |
def _create_action_plan(self, area: str, stats: Dict) -> Dict: | |
"""Cria plano de ação personalizado""" | |
return { | |
"prioridade": "alta" if len(stats["erros_comuns"]) > stats["corretas"] else "média", | |
"etapas": [ | |
"Revisão teórica dos temas com mais erros", | |
"Resolução de questões comentadas", | |
"Prática com casos clínicos", | |
"Simulado focado na área" | |
], | |
"tempo_sugerido": "2 semanas", | |
"material_sugerido": [ | |
"Bibliografia básica", | |
"Questões anteriores comentadas", | |
"Vídeo-aulas específicas" | |
] | |
} | |
def _save_resultado(self, simulado_id: str, resultado: Dict) -> None: | |
"""Salva resultado do simulado no banco de dados""" | |
try: | |
cursor = self.conn.cursor() | |
cursor.execute(''' | |
INSERT INTO resultados_simulados | |
(simulado_id, data, resultado_json) | |
VALUES (?, ?, ?) | |
''', ( | |
simulado_id, | |
datetime.now().isoformat(), | |
json.dumps(resultado) | |
)) | |
self.conn.commit() | |
except Exception as e: | |
logger.error(f"Erro ao salvar resultado: {e}") | |
def get_simulado_history(self, user_id: str) -> List[Dict]: | |
"""Obtém histórico de simulados do usuário""" | |
try: | |
cursor = self.conn.cursor() | |
cursor.execute(''' | |
SELECT simulado_id, data, resultado_json | |
FROM resultados_simulados | |
WHERE user_id = ? | |
ORDER BY data DESC | |
''', (user_id,)) | |
return [ | |
{ | |
"id": row[0], | |
"data": row[1], | |
"resultado": json.loads(row[2]) | |
} | |
for row in cursor.fetchall() | |
] | |
except Exception as e: | |
logger.error(f"Erro ao obter histórico: {e}") | |
return [] | |
# [O resto do código do CasoClinicoSystem continua o mesmo...] | |
def initialize_simulado_system(db_connection) -> Tuple[SimuladoSystem, CasoClinicoSystem]: | |
"""Inicializa o sistema de simulados""" | |
try: | |
simulado_sys = SimuladoSystem(db_connection) | |
caso_sys = CasoClinicoSystem(db_connection) | |
return simulado_sys, caso_sys | |
except Exception as e: | |
logger.error(f"Erro ao inicializar sistema de simulados: {e}") | |
return None, None | |
if __name__ == "__main__": | |
# Código para testes | |
import sqlite3 | |
try: | |
conn = sqlite3.connect('revalida.db') | |
simulado_sys, caso_sys = initialize_simulado_system(conn) | |
# Teste básico | |
simulado = simulado_sys.create_simulado() | |
if simulado: | |
print("Sistema funcionando corretamente") | |
print(f"Simulado criado: {json.dumps(simulado['estatisticas'], indent=2)}") | |
except Exception as e: | |
print(f"Erro nos testes: {e}") | |
finally: | |
conn.close() |