File size: 6,620 Bytes
cbb5c88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# utils/helpers.py

import re
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Union
import json
import logging

# Configuração de logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

class ValidationError(Exception):
    """Exceção customizada para erros de validação"""
    pass

def validate_email(email: str) -> bool:
    """Valida formato de email"""
    pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    return bool(re.match(pattern, email))

def validate_date_format(date_str: str) -> bool:
    """Valida formato de data (YYYY-MM-DD)"""
    try:
        datetime.strptime(date_str, '%Y-%m-%d')
        return True
    except ValueError:
        return False

def format_time_delta(minutes: int) -> str:
    """Formata duração em minutos para formato legível"""
    hours = minutes // 60
    remaining_minutes = minutes % 60
    
    if hours > 0:
        return f"{hours}h{remaining_minutes:02d}min"
    return f"{minutes}min"

def calculate_study_efficiency(hours_studied: float, 
                             questions_answered: int,
                             correct_answers: int) -> float:
    """Calcula eficiência de estudo"""
    if hours_studied <= 0 or questions_answered == 0:
        return 0.0
        
    accuracy = correct_answers / questions_answered
    questions_per_hour = questions_answered / hours_studied
    
    # Fórmula personalizada para eficiência
    efficiency = (accuracy * 0.7 + (questions_per_hour / 20) * 0.3) * 100
    return round(min(efficiency, 100), 2)

def format_performance_message(score: float) -> str:
    """Gera mensagem motivacional baseada no desempenho"""
    if score >= 90:
        return "🌟 Excelente! Você está dominando o conteúdo!"
    elif score >= 80:
        return "💪 Ótimo trabalho! Continue assim!"
    elif score >= 70:
        return "👍 Bom progresso! Mantenha o foco!"
    elif score >= 60:
        return "📚 Você está no caminho certo! Continue estudando!"
    else:
        return "💡 Não desanime! Cada questão é uma oportunidade de aprendizado!"

def generate_study_recommendations(weak_areas: List[str], 
                                 hours_available: float) -> Dict[str, any]:
    """Gera recomendações de estudo baseadas em áreas fracas"""
    total_weight = len(weak_areas)
    hours_per_area = hours_available / total_weight if total_weight > 0 else 0
    
    recommendations = {
        "distribuicao_tempo": {},
        "prioridades": [],
        "recursos_sugeridos": []
    }
    
    for area in weak_areas:
        recommendations["distribuicao_tempo"][area] = round(hours_per_area, 1)
        recommendations["prioridades"].append({
            "area": area,
            "foco": ["Revisão teórica", "Questões práticas", "Casos clínicos"]
        })
    
    recommendations["recursos_sugeridos"] = [
        "Material teórico focado",
        "Questões comentadas",
        "Vídeo-aulas específicas",
        "Casos clínicos interativos"
    ]
    
    return recommendations

def parse_command_args(command: str) -> Dict[str, str]:
    """Processa argumentos de comandos do bot"""
    parts = command.split()
    if len(parts) < 1:
        return {}
        
    command_dict = {
        "command": parts[0]
    }
    
    # Processa argumentos nomeados (e.g., /comando area=pediatria tempo=2)
    for part in parts[1:]:
        if '=' in part:
            key, value = part.split('=', 1)
            command_dict[key.lower()] = value
        else:
            # Argumentos posicionais
            if 'args' not in command_dict:
                command_dict['args'] = []
            command_dict['args'].append(part)
    
    return command_dict

def format_question(question: Dict[str, any], 
                   number: Optional[int] = None) -> str:
    """Formata questão para exibição"""
    formatted = ""
    
    if number is not None:
        formatted += f"Questão {number}:\n"
        
    formatted += f"{question['texto']}\n\n"
    
    for letra, texto in question['opcoes'].items():
        formatted += f"{letra}) {texto}\n"
    
    return formatted

def calculate_remaining_time(target_date: str) -> Dict[str, int]:
    """Calcula tempo restante até a data alvo"""
    target = datetime.strptime(target_date, '%Y-%m-%d').date()
    today = datetime.now().date()
    
    difference = target - today
    
    return {
        "dias": difference.days,
        "semanas": difference.days // 7,
        "meses": difference.days // 30
    }

def format_study_summary(progress_data: Dict[str, any]) -> str:
    """Formata resumo de estudos para exibição"""
    summary = "📊 Resumo de Estudos:\n\n"
    
    # Total de horas
    total_hours = sum(progress_data.get('horas_por_area', {}).values())
    summary += f"⏱ Total de horas estudadas: {total_hours:.1f}h\n"
    
    # Desempenho por área
    summary += "\n📈 Desempenho por área:\n"
    for area, score in progress_data.get('desempenho_por_area', {}).items():
        summary += f"• {area}: {score:.1f}%\n"
    
    # Média geral
    if 'media_geral' in progress_data:
        summary += f"\n🎯 Média geral: {progress_data['media_geral']:.1f}%\n"
    
    return summary

def safe_json_loads(json_str: str, default: Union[Dict, List] = None) -> Union[Dict, List]:
    """Carrega JSON com segurança"""
    try:
        return json.loads(json_str)
    except Exception as e:
        logger.error(f"Erro ao carregar JSON: {e}")
        return default if default is not None else {}

def sanitize_input(text: str) -> str:
    """Sanitiza input do usuário"""
    # Remove caracteres potencialmente perigosos
    return re.sub(r'[<>&;]', '', text.strip())

def format_error_message(error: Exception) -> str:
    """Formata mensagem de erro para usuário"""
    return f"""❌ Ops! Ocorreu um erro:
{str(error)}

Por favor, tente novamente ou use /ajuda para ver os comandos disponíveis."""

if __name__ == "__main__":
    # Testes básicos
    print(validate_email("test@example.com"))  # True
    print(validate_email("invalid-email"))     # False
    
    print(format_time_delta(90))   # "1h30min"
    print(format_time_delta(45))   # "45min"
    
    test_question = {
        "texto": "Qual é o principal sintoma da condição X?",
        "opcoes": {
            "A": "Sintoma 1",
            "B": "Sintoma 2",
            "C": "Sintoma 3",
            "D": "Sintoma 4"
        }
    }
    print(format_question(test_question, 1))