DHEIVER commited on
Commit
237f4d4
·
verified ·
1 Parent(s): c6bec6c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +154 -17
app.py CHANGED
@@ -6,30 +6,41 @@ from typing import Dict, List, Tuple
6
  from textblob import TextBlob
7
  import json
8
  import os
 
9
 
10
- # Load embeddings model
11
- model = SentenceTransformer('all-MiniLM-L6-v2')
12
-
13
- # Load data from JSON
14
- def load_coach_data():
 
 
15
  try:
 
16
  with open('coach_data.json', 'r', encoding='utf-8') as f:
17
  data = json.load(f)
18
- return data['perguntas'], data['tone_patterns'], data['respostas_coach']
19
- except FileNotFoundError:
20
- print("Error: coach_data.json not found")
21
- raise
 
22
  except json.JSONDecodeError:
23
- print("Error: Invalid JSON format in coach_data.json")
24
- raise
25
  except KeyError as e:
26
- print(f"Error: Missing required key in JSON data: {e}")
27
- raise
 
 
 
 
 
28
 
29
- PERGUNTAS, TONE_PATTERNS, RESPOSTAS_COACH = load_coach_data()
 
30
 
31
  class EnhancedCoach:
32
  def __init__(self):
 
33
  self.pergunta_atual = 0
34
  self.inicio = datetime.now()
35
  self.historico_respostas = []
@@ -38,6 +49,7 @@ class EnhancedCoach:
38
  self.response_quality_metrics = []
39
 
40
  def analyze_response_quality(self, text: str) -> Dict[str, float]:
 
41
  sentences = [s.strip() for s in text.split('.') if s.strip()]
42
  words = text.lower().split()
43
 
@@ -52,6 +64,7 @@ class EnhancedCoach:
52
  return metrics
53
 
54
  def _calculate_depth(self, text: str, words: List[str]) -> float:
 
55
  if not words:
56
  return 0.0
57
 
@@ -70,12 +83,14 @@ class EnhancedCoach:
70
  return min(1.0, depth_score)
71
 
72
  def _calculate_clarity(self, sentences: List[str]) -> float:
 
73
  if not sentences:
74
  return 0.0
75
  avg_length = sum(len(s.split()) for s in sentences) / len(sentences)
76
  return 1.0 if 10 <= avg_length <= 20 else 0.7
77
 
78
  def _calculate_specificity(self, text: str, words: List[str]) -> float:
 
79
  specific_indicators = [
80
  "exemplo", "especificamente", "concretamente",
81
  "situação", "caso", "quando", "onde", "como",
@@ -91,6 +106,7 @@ class EnhancedCoach:
91
  return min(1.0, (indicator_count * 0.7 + response_length_factor * 0.3))
92
 
93
  def _calculate_actionability(self, sentences: List[str]) -> float:
 
94
  action_verbs = [
95
  "implementar", "fazer", "criar", "desenvolver", "estabelecer",
96
  "planejar", "executar", "medir", "avaliar", "iniciar",
@@ -103,6 +119,7 @@ class EnhancedCoach:
103
  return min(1.0, actionable / len(sentences))
104
 
105
  def analisar_tom(self, texto: str) -> Tuple[str, float]:
 
106
  texto_lower = texto.lower()
107
  blob = TextBlob(texto)
108
 
@@ -115,6 +132,7 @@ class EnhancedCoach:
115
  return predominant_tone[0], predominant_tone[1]
116
 
117
  def analisar_sentimento(self, texto: str) -> str:
 
118
  positive_words = [
119
  "consegui", "superei", "aprendi", "melhorei", "efetivo",
120
  "cresci", "evoluí", "realizei", "alcancei", "progresso"
@@ -135,6 +153,7 @@ class EnhancedCoach:
135
  return "neutral"
136
 
137
  def extrair_acao_especifica(self, texto: str) -> str:
 
138
  sentences = texto.split('.')
139
  for sentence in sentences:
140
  if any(action in sentence.lower() for action in ["eu", "minha", "realizei", "fiz"]):
@@ -142,6 +161,7 @@ class EnhancedCoach:
142
  return texto.split('.')[0].strip()
143
 
144
  def encontrar_melhor_resposta(self, texto_usuario: str, categoria: str) -> str:
 
145
  sentimento = self.analisar_sentimento(texto_usuario)
146
  acao_especifica = self.extrair_acao_especifica(texto_usuario)
147
 
@@ -162,6 +182,7 @@ class EnhancedCoach:
162
  return melhor_resposta.format(specific_action=acao_especifica.lower())
163
 
164
  def gerar_resposta(self, texto_usuario: str) -> str:
 
165
  quality_metrics = self.analyze_response_quality(texto_usuario)
166
 
167
  if quality_metrics["depth"] < 0.15 and quality_metrics["specificity"] < 0.1:
@@ -205,9 +226,117 @@ Alguns aspectos que enriqueceriam sua reflexão:
205
  tempo = (datetime.now() - self.inicio).seconds // 60
206
  resposta += self.gerar_sumario_final(tempo)
207
 
208
- return
 
 
 
 
 
 
 
 
 
 
209
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  def criar_interface():
 
211
  coach = EnhancedCoach()
212
 
213
  with gr.Blocks(title="Coach de Liderança", theme=gr.themes.Soft()) as app:
@@ -241,6 +370,14 @@ def criar_interface():
241
 
242
  return app
243
 
 
 
 
 
 
 
 
 
 
244
  if __name__ == "__main__":
245
- app = criar_interface()
246
- app.launch()
 
6
  from textblob import TextBlob
7
  import json
8
  import os
9
+ from pathlib import Path
10
 
11
+ # Configuração inicial
12
+ def setup_environment():
13
+ """Configura o ambiente inicial e carrega os dados necessários."""
14
+ # Verifica se o arquivo JSON existe
15
+ if not Path("coach_data.json").exists():
16
+ raise FileNotFoundError("O arquivo coach_data.json não foi encontrado")
17
+
18
  try:
19
+ # Carrega os dados do JSON
20
  with open('coach_data.json', 'r', encoding='utf-8') as f:
21
  data = json.load(f)
22
+ return (
23
+ data['perguntas'],
24
+ data['tone_patterns'],
25
+ data['respostas_coach']
26
+ )
27
  except json.JSONDecodeError:
28
+ raise ValueError("Erro ao decodificar o arquivo JSON")
 
29
  except KeyError as e:
30
+ raise KeyError(f"Chave obrigatória não encontrada no JSON: {e}")
31
+
32
+ # Carrega o modelo de embeddings
33
+ try:
34
+ model = SentenceTransformer('all-MiniLM-L6-v2')
35
+ except Exception as e:
36
+ raise RuntimeError(f"Erro ao carregar o modelo de embeddings: {e}")
37
 
38
+ # Carrega os dados do coach
39
+ PERGUNTAS, TONE_PATTERNS, RESPOSTAS_COACH = setup_environment()
40
 
41
  class EnhancedCoach:
42
  def __init__(self):
43
+ """Inicializa o coach com os estados necessários."""
44
  self.pergunta_atual = 0
45
  self.inicio = datetime.now()
46
  self.historico_respostas = []
 
49
  self.response_quality_metrics = []
50
 
51
  def analyze_response_quality(self, text: str) -> Dict[str, float]:
52
+ """Analisa a qualidade da resposta do usuário."""
53
  sentences = [s.strip() for s in text.split('.') if s.strip()]
54
  words = text.lower().split()
55
 
 
64
  return metrics
65
 
66
  def _calculate_depth(self, text: str, words: List[str]) -> float:
67
+ """Calcula a profundidade da resposta."""
68
  if not words:
69
  return 0.0
70
 
 
83
  return min(1.0, depth_score)
84
 
85
  def _calculate_clarity(self, sentences: List[str]) -> float:
86
+ """Calcula a clareza da resposta."""
87
  if not sentences:
88
  return 0.0
89
  avg_length = sum(len(s.split()) for s in sentences) / len(sentences)
90
  return 1.0 if 10 <= avg_length <= 20 else 0.7
91
 
92
  def _calculate_specificity(self, text: str, words: List[str]) -> float:
93
+ """Calcula a especificidade da resposta."""
94
  specific_indicators = [
95
  "exemplo", "especificamente", "concretamente",
96
  "situação", "caso", "quando", "onde", "como",
 
106
  return min(1.0, (indicator_count * 0.7 + response_length_factor * 0.3))
107
 
108
  def _calculate_actionability(self, sentences: List[str]) -> float:
109
+ """Calcula a acionabilidade da resposta."""
110
  action_verbs = [
111
  "implementar", "fazer", "criar", "desenvolver", "estabelecer",
112
  "planejar", "executar", "medir", "avaliar", "iniciar",
 
119
  return min(1.0, actionable / len(sentences))
120
 
121
  def analisar_tom(self, texto: str) -> Tuple[str, float]:
122
+ """Analisa o tom predominante da resposta."""
123
  texto_lower = texto.lower()
124
  blob = TextBlob(texto)
125
 
 
132
  return predominant_tone[0], predominant_tone[1]
133
 
134
  def analisar_sentimento(self, texto: str) -> str:
135
+ """Analisa o sentimento geral da resposta."""
136
  positive_words = [
137
  "consegui", "superei", "aprendi", "melhorei", "efetivo",
138
  "cresci", "evoluí", "realizei", "alcancei", "progresso"
 
153
  return "neutral"
154
 
155
  def extrair_acao_especifica(self, texto: str) -> str:
156
+ """Extrai uma ação específica da resposta do usuário."""
157
  sentences = texto.split('.')
158
  for sentence in sentences:
159
  if any(action in sentence.lower() for action in ["eu", "minha", "realizei", "fiz"]):
 
161
  return texto.split('.')[0].strip()
162
 
163
  def encontrar_melhor_resposta(self, texto_usuario: str, categoria: str) -> str:
164
+ """Encontra a melhor resposta do coach baseada no texto do usuário."""
165
  sentimento = self.analisar_sentimento(texto_usuario)
166
  acao_especifica = self.extrair_acao_especifica(texto_usuario)
167
 
 
182
  return melhor_resposta.format(specific_action=acao_especifica.lower())
183
 
184
  def gerar_resposta(self, texto_usuario: str) -> str:
185
+ """Gera uma resposta completa do coach."""
186
  quality_metrics = self.analyze_response_quality(texto_usuario)
187
 
188
  if quality_metrics["depth"] < 0.15 and quality_metrics["specificity"] < 0.1:
 
226
  tempo = (datetime.now() - self.inicio).seconds // 60
227
  resposta += self.gerar_sumario_final(tempo)
228
 
229
+ return resposta
230
+
231
+ def _gerar_insight_tom(self, tom: str, intensidade: float) -> str:
232
+ """Gera insights baseados no tom da resposta."""
233
+ insights = {
234
+ "confiante": "Sua confiança ao abordar este tema é notável. Como você construiu esta segurança?",
235
+ "reflexivo": "Sua abordagem reflexiva traz profundidade à análise. Continue explorando diferentes perspectivas.",
236
+ "hesitante": "Percebo algumas incertezas naturais do processo. Que apoio ajudaria a fortalecer sua confiança?",
237
+ "pragmatico": "Seu foco em resultados práticos é valioso. Como você equilibra isso com visão de longo prazo?",
238
+ "emocional": "Sua conexão emocional com a liderança demonstra comprometimento genuíno."
239
+ }
240
 
241
+ if intensidade > 2:
242
+ return f"\n\n💡 {insights[tom]} Sua expressão é particularmente intensa neste aspecto."
243
+ return f"\n\n💡 {insights[tom]}"
244
+
245
+ def _analisar_padroes(self) -> str:
246
+ """Analisa padrões nas respostas do usuário."""
247
+ if len(self.historico_respostas) <= 1:
248
+ return ""
249
+
250
+ sentimento_atual = self.analisar_sentimento(self.historico_respostas[-1])
251
+ sentimento_anterior = self.analisar_sentimento(self.historico_respostas[-2])
252
+
253
+ if sentimento_atual == sentimento_anterior == "positive":
254
+ return "\n\n💡 Observo um padrão consistente de confiança em suas respostas. Continue desenvolvendo esses pontos fortes!"
255
+ elif sentimento_atual == sentimento_anterior == "improvement":
256
+ return "\n\n💡 Percebo que você está identificando áreas de desenvolvimento. Vamos focar em estratégias práticas para esses desafios."
257
+ return ""
258
+
259
+ def _gerar_pontos_aprofundamento(self) -> str:
260
+ """Gera pontos para aprofundamento da reflexão."""
261
+ return """
262
+
263
+ #### Pontos para Aprofundamento:
264
+ 1. Como essa experiência se conecta com seus valores de liderança?
265
+ 2. Que recursos específicos você identificou como necessários?
266
+ 3. Qual seria o próximo marco de desenvolvimento nessa área?"""
267
+
268
+ def _gerar_proxima_pergunta(self) -> str:
269
+ """Gera a próxima pergunta da sequência."""
270
+ proxima = PERGUNTAS[self.pergunta_atual]
271
+ return f"""\n\n### Próxima Reflexão: {proxima['categoria'].title()} 🎯\n\n{proxima['pergunta']}\n\nTome um momento para refletir e conectar com suas experiências..."""
272
+
273
+ def primeira_pergunta(self) -> str:
274
+ """Gera a mensagem inicial e primeira pergunta do coach."""
275
+ return f"""### 👋 Bem-vindo à sua Jornada de Desenvolvimento!
276
+
277
+ Vamos explorar aspectos importantes da sua liderança através de reflexões guiadas.
278
+
279
+ {PERGUNTAS[0]['pergunta']}
280
+
281
+ Tome um momento para conectar com suas experiências e compartilhe sua perspectiva..."""
282
+
283
+ def gerar_sumario_final(self, tempo: int) -> str:
284
+ """Gera o sumário final da sessão."""
285
+ sentimentos = [self.analisar_sentimento(resp) for resp in self.historico_respostas]
286
+ predominante = max(set(sentimentos), key=sentimentos.count)
287
+
288
+ tone_pattern = max(set(self.tone_history), key=self.tone_history.count)
289
+ tone_insight = f"\n\n#### Padrão de Comunicação:\nSeu estilo predominante é {tone_pattern}, o que sugere {self._interpretar_padrao_tom(tone_pattern)}"
290
+
291
+ avg_metrics = {
292
+ key: sum(m[key] for m in self.response_quality_metrics) / len(self.response_quality_metrics)
293
+ for key in ["depth", "clarity", "specificity", "actionability"]
294
+ }
295
+
296
+ quality_insights = "\n\n#### Insights de Qualidade das Respostas:"
297
+ if avg_metrics["depth"] > 0.7:
298
+ quality_insights += "\n- Suas reflexões demonstram profundidade significativa"
299
+ if avg_metrics["specificity"] > 0.7:
300
+ quality_insights += "\n- Você fornece exemplos concretos e detalhados"
301
+ if avg_metrics["actionability"] > 0.7:
302
+ quality_insights += "\n- Suas respostas são orientadas para ação"
303
+
304
+ if predominante == "positive":
305
+ perfil = "Você demonstra forte autoconhecimento e confiança em sua liderança."
306
+ elif predominante == "improvement":
307
+ perfil = "Você demonstra excelente capacidade de identificar oportunidades de desenvolvimento."
308
+ else:
309
+ perfil = "Você demonstra uma abordagem equilibrada entre conquistas e desafios."
310
+
311
+ return f"""
312
+ ### 🎉 Jornada de Desenvolvimento Concluída!
313
+
314
+ ⏱️ Tempo de reflexão: {tempo} minutos
315
+ 📝 Temas explorados: {len(PERGUNTAS)}
316
+
317
+ #### Perfil de Liderança Observado:
318
+ {perfil}{tone_insight}{quality_insights}
319
+
320
+ #### Recomendações Personalizadas:
321
+ 1. Implemente uma ação específica mencionada em suas reflexões esta semana
322
+ 2. Mantenha um diário de liderança focado nos temas discutidos
323
+ 3. Estabeleça checkpoints mensais para revisar seu progresso
324
+
325
+ Deseja iniciar uma nova jornada de desenvolvimento com outros temas?"""
326
+
327
+ def _interpretar_padrao_tom(self, tom: str) -> str:
328
+ """Interpreta o padrão de tom identificado nas respostas."""
329
+ interpretacoes = {
330
+ "confiante": "uma base sólida para influenciar e liderar equipes.",
331
+ "reflexivo": "uma capacidade valiosa de considerar múltiplas perspectivas.",
332
+ "hesitante": "uma oportunidade para fortalecer sua confiança através da prática.",
333
+ "pragmatico": "um foco valioso em resultados e implementação.",
334
+ "emocional": "uma forte conexão com o impacto humano da liderança."
335
+ }
336
+ return interpretacoes.get(tom, "um estilo único de liderança.")
337
+
338
  def criar_interface():
339
+ """Cria a interface do usuário usando Gradio."""
340
  coach = EnhancedCoach()
341
 
342
  with gr.Blocks(title="Coach de Liderança", theme=gr.themes.Soft()) as app:
 
370
 
371
  return app
372
 
373
+ def main():
374
+ """Função principal para iniciar a aplicação."""
375
+ try:
376
+ app = criar_interface()
377
+ app.launch()
378
+ except Exception as e:
379
+ print(f"Erro ao iniciar a aplicação: {e}")
380
+ raise
381
+
382
  if __name__ == "__main__":
383
+ main()