File size: 9,020 Bytes
bcb4967
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# 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))