Spaces:
Runtime error
Runtime error
# models/question_models.py | |
from dataclasses import dataclass, field | |
from typing import Dict, List, Optional | |
from datetime import datetime | |
import json | |
class Question: | |
"""Modelo para questões do Revalida""" | |
id: int | |
text: str | |
options: Dict[str, str] | |
correct_answer: str | |
explanation: str | |
area: str | |
year: Optional[int] = None | |
difficulty: str = "medium" | |
tags: List[str] = field(default_factory=list) | |
references: List[str] = field(default_factory=list) | |
times_used: int = 0 | |
success_rate: float = 0.0 | |
def to_dict(self) -> Dict: | |
"""Converte para dicionário""" | |
return { | |
"id": self.id, | |
"text": self.text, | |
"options": self.options, | |
"correct_answer": self.correct_answer, | |
"explanation": self.explanation, | |
"area": self.area, | |
"year": self.year, | |
"difficulty": self.difficulty, | |
"tags": self.tags, | |
"references": self.references, | |
"times_used": self.times_used, | |
"success_rate": self.success_rate | |
} | |
def format_for_display(self, show_answer: bool = False) -> str: | |
"""Formata questão para exibição""" | |
formatted = f"📝 Questão {self.id}\n\n" | |
formatted += f"{self.text}\n\n" | |
for letra, texto in self.options.items(): | |
formatted += f"{letra}) {texto}\n" | |
if show_answer: | |
formatted += f"\n✅ Resposta: {self.correct_answer}\n" | |
formatted += f"📋 Explicação: {self.explanation}\n" | |
if self.references: | |
formatted += "\n📚 Referências:\n" | |
for ref in self.references: | |
formatted += f"• {ref}\n" | |
return formatted | |
class ClinicalCase: | |
"""Modelo para casos clínicos""" | |
id: int | |
title: str | |
description: str | |
area: str | |
steps: Dict[str, str] | |
expected_answers: Dict[str, str] | |
hints: Dict[str, List[str]] | |
difficulty: str = "medium" | |
references: List[str] = field(default_factory=list) | |
created_at: datetime = field(default_factory=datetime.now) | |
def to_dict(self) -> Dict: | |
"""Converte para dicionário""" | |
return { | |
"id": self.id, | |
"title": self.title, | |
"description": self.description, | |
"area": self.area, | |
"steps": self.steps, | |
"expected_answers": self.expected_answers, | |
"hints": self.hints, | |
"difficulty": self.difficulty, | |
"references": self.references, | |
"created_at": self.created_at.isoformat() | |
} | |
def get_step(self, step_number: int) -> Optional[Dict[str, str]]: | |
"""Retorna informações de uma etapa específica""" | |
step_key = str(step_number) | |
if step_key not in self.steps: | |
return None | |
return { | |
"description": self.steps[step_key], | |
"expected_answer": self.expected_answers.get(step_key, ""), | |
"hints": self.hints.get(step_key, []) | |
} | |
def format_step(self, step_number: int, show_answer: bool = False) -> str: | |
"""Formata uma etapa do caso clínico para exibição""" | |
step = self.get_step(step_number) | |
if not step: | |
return "Etapa não encontrada." | |
formatted = f"🏥 Caso Clínico: {self.title}\n" | |
formatted += f"Etapa {step_number}\n\n" | |
formatted += f"{step['description']}\n" | |
if show_answer: | |
formatted += f"\n✅ Resposta esperada:\n{step['expected_answer']}\n" | |
if step['hints']: | |
formatted += "\n💡 Dicas:\n" | |
for hint in step['hints']: | |
formatted += f"• {hint}\n" | |
return formatted | |
class Simulado: | |
"""Modelo para simulados""" | |
id: str | |
questions: List[Question] | |
difficulty: str | |
created_at: datetime = field(default_factory=datetime.now) | |
completed_at: Optional[datetime] = None | |
user_answers: Dict[int, str] = field(default_factory=dict) | |
score: Optional[float] = None | |
time_taken: Optional[int] = None | |
analysis: Dict = field(default_factory=dict) | |
def to_dict(self) -> Dict: | |
"""Converte para dicionário""" | |
return { | |
"id": self.id, | |
"questions": [q.to_dict() for q in self.questions], | |
"difficulty": self.difficulty, | |
"created_at": self.created_at.isoformat(), | |
"completed_at": self.completed_at.isoformat() if self.completed_at else None, | |
"user_answers": self.user_answers, | |
"score": self.score, | |
"time_taken": self.time_taken, | |
"analysis": self.analysis | |
} | |
def submit_answer(self, question_id: int, answer: str) -> bool: | |
"""Registra resposta do usuário""" | |
if not any(q.id == question_id for q in self.questions): | |
return False | |
self.user_answers[question_id] = answer | |
return True | |
def calculate_score(self) -> float: | |
"""Calcula pontuação do simulado""" | |
if not self.questions or not self.user_answers: | |
return 0.0 | |
correct = sum( | |
1 for q in self.questions | |
if q.id in self.user_answers and | |
q.correct_answer.upper() == self.user_answers[q.id].upper() | |
) | |
return (correct / len(self.questions)) * 100 | |
def generate_analysis(self) -> Dict: | |
"""Gera análise detalhada do desempenho""" | |
analysis = { | |
"total_questions": len(self.questions), | |
"answered_questions": len(self.user_answers), | |
"score": self.calculate_score(), | |
"performance_by_area": {}, | |
"weak_areas": [], | |
"recommendations": [] | |
} | |
# Análise por área | |
area_stats = {} | |
for question in self.questions: | |
if question.area not in area_stats: | |
area_stats[question.area] = {"total": 0, "correct": 0} | |
area_stats[question.area]["total"] += 1 | |
if (question.id in self.user_answers and | |
question.correct_answer.upper() == self.user_answers[question.id].upper()): | |
area_stats[question.area]["correct"] += 1 | |
# Calcula percentuais e identifica áreas fracas | |
for area, stats in area_stats.items(): | |
percentage = (stats["correct"] / stats["total"]) * 100 | |
analysis["performance_by_area"][area] = { | |
"total": stats["total"], | |
"correct": stats["correct"], | |
"percentage": percentage | |
} | |
if percentage < 60: | |
analysis["weak_areas"].append(area) | |
# Gera recomendações | |
if analysis["weak_areas"]: | |
analysis["recommendations"].append( | |
"Revisar os seguintes tópicos: " + ", ".join(analysis["weak_areas"]) | |
) | |
if analysis["score"] < 70: | |
analysis["recommendations"].append( | |
"Aumentar a quantidade de questões práticas" | |
) | |
return analysis | |
def load_question_from_dict(data: Dict) -> Question: | |
"""Cria instância de Question a partir de dicionário""" | |
return Question( | |
id=data["id"], | |
text=data["text"], | |
options=data["options"], | |
correct_answer=data["correct_answer"], | |
explanation=data["explanation"], | |
area=data["area"], | |
year=data.get("year"), | |
difficulty=data.get("difficulty", "medium"), | |
tags=data.get("tags", []), | |
references=data.get("references", []), | |
times_used=data.get("times_used", 0), | |
success_rate=data.get("success_rate", 0.0) | |
) | |
def load_clinical_case_from_dict(data: Dict) -> ClinicalCase: | |
"""Cria instância de ClinicalCase a partir de dicionário""" | |
return ClinicalCase( | |
id=data["id"], | |
title=data["title"], | |
description=data["description"], | |
area=data["area"], | |
steps=data["steps"], | |
expected_answers=data["expected_answers"], | |
hints=data["hints"], | |
difficulty=data.get("difficulty", "medium"), | |
references=data.get("references", []), | |
created_at=datetime.fromisoformat(data["created_at"]) | |
if "created_at" in data else datetime.now() | |
) | |
if __name__ == "__main__": | |
# Testes básicos | |
test_question = Question( | |
id=1, | |
text="Qual é o principal sintoma da hipertensão?", | |
options={ | |
"A": "Dor de cabeça", | |
"B": "Tontura", | |
"C": "Náusea", | |
"D": "Assintomático" | |
}, | |
correct_answer="D", | |
explanation="A hipertensão é frequentemente assintomática...", | |
area="ClínicaMédica" | |
) | |
print(test_question.format_for_display(show_answer=True)) |