crmjarevalida / models /question_models.py
danielraynaud's picture
Create models/question_models.py
bcb4967 verified
raw
history blame
9.02 kB
# models/question_models.py
from dataclasses import dataclass, field
from typing import Dict, List, Optional
from datetime import datetime
import json
@dataclass
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
@dataclass
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
@dataclass
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))