Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,276 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
def analyze_sentiment_trend(respostas: List[str]) -> plt.Figure:
|
2 |
+
"""Generate sentiment analysis plot"""
|
3 |
+
coach = EnhancedCoach()
|
4 |
+
sentimentos = [coach.analisar_sentimento(resp) for resp in respostas]
|
5 |
+
|
6 |
+
# Convert sentiments to numeric values
|
7 |
+
valor_sentimento = {
|
8 |
+
'positive': 1,
|
9 |
+
'neutral': 0,
|
10 |
+
'improvement': -1
|
11 |
+
}
|
12 |
+
valores = [valor_sentimento[s] for s in sentimentos]
|
13 |
+
|
14 |
+
# Create the plot
|
15 |
+
fig, ax = plt.subplots(figsize=(8, 4))
|
16 |
+
sns.lineplot(data=valores, marker='o', ax=ax)
|
17 |
+
|
18 |
+
ax.set_title('Tendência de Sentimento nas Respostas')
|
19 |
+
ax.set_xlabel('Número da Resposta')
|
20 |
+
ax.set_ylabel('Sentimento')
|
21 |
+
ax.set_ylim(-1.5, 1.5)
|
22 |
+
ax.grid(True)
|
23 |
+
|
24 |
+
# Add horizontal lines for reference
|
25 |
+
ax.axhline(y=0, color='gray', linestyle='--', alpha=0.5)
|
26 |
+
|
27 |
+
return fig
|
28 |
+
|
29 |
+
def generate_word_cloud(respostas: List[str]) -> plt.Figure:
|
30 |
+
"""Generate word cloud visualization"""
|
31 |
+
# Combine all responses
|
32 |
+
texto_completo = ' '.join(respostas)
|
33 |
+
|
34 |
+
# Create word cloud
|
35 |
+
wordcloud = WordCloud(
|
36 |
+
width=800,
|
37 |
+
height=400,
|
38 |
+
background_color='white',
|
39 |
+
colormap='viridis',
|
40 |
+
max_words=100
|
41 |
+
).generate(texto_completo)
|
42 |
+
|
43 |
+
# Create the plot
|
44 |
+
fig, ax = plt.subplots(figsize=(10, 5))
|
45 |
+
ax.imshow(wordcloud, interpolation='bilinear')
|
46 |
+
ax.axis('off')
|
47 |
+
ax.set_title('Nuvem de Palavras das Reflexões')
|
48 |
+
|
49 |
+
return fig
|
50 |
+
|
51 |
+
def analyze_themes(respostas: List[str]) -> Tuple[str, str]:
|
52 |
+
"""Analyze strong themes and development areas"""
|
53 |
+
coach = EnhancedCoach()
|
54 |
+
temas_fortes = []
|
55 |
+
areas_desenvolvimento = []
|
56 |
+
|
57 |
+
for resp in respostas:
|
58 |
+
sentimento = coach.analisar_sentimento(resp)
|
59 |
+
if sentimento == "positive":
|
60 |
+
temas_fortes.append("- " + coach.extrair_acao_especifica(resp))
|
61 |
+
elif sentimento == "improvement":
|
62 |
+
areas_desenvolvimento.append("- " + coach.extrair_acao_especifica(resp))
|
63 |
+
|
64 |
+
temas_fortes_str = "\n".join(temas_fortes[:3]) if temas_fortes else "Análise em andamento..."
|
65 |
+
areas_desenvolvimento_str = "\n".join(areas_desenvolvimento[:3]) if areas_desenvolvimento else "Análise em andamento..."
|
66 |
+
|
67 |
+
return temas_fortes_str, areas_desenvolvimento_str
|
68 |
+
|
69 |
+
def criar_interface():
|
70 |
+
coach = EnhancedCoach()
|
71 |
+
|
72 |
+
with gr.Blocks(title="Coach de Liderança", theme=gr.themes.Soft()) as app:
|
73 |
+
with gr.Row():
|
74 |
+
with gr.Column(scale=2):
|
75 |
+
gr.Markdown("""
|
76 |
+
# 🚀 Coach de Liderança
|
77 |
+
|
78 |
+
Desenvolva sua liderança através de reflexão guiada e feedback personalizado.
|
79 |
+
""")
|
80 |
+
|
81 |
+
with gr.Column(scale=1):
|
82 |
+
timer = gr.Number(
|
83 |
+
value=0,
|
84 |
+
label="⏱️ Tempo de Reflexão (minutos)",
|
85 |
+
interactive=False
|
86 |
+
)
|
87 |
+
progress = gr.Slider(
|
88 |
+
value=0,
|
89 |
+
minimum=0,
|
90 |
+
maximum=len(PERGUNTAS),
|
91 |
+
step=1,
|
92 |
+
label="📊 Progresso",
|
93 |
+
interactive=False
|
94 |
+
)
|
95 |
+
|
96 |
+
with gr.Tabs() as tabs:
|
97 |
+
with gr.Tab("💭 Sessão Atual"):
|
98 |
+
chat = gr.Chatbot(
|
99 |
+
value=[[None, coach.primeira_pergunta()]],
|
100 |
+
height=500,
|
101 |
+
show_label=False,
|
102 |
+
type="messages"
|
103 |
+
)
|
104 |
+
|
105 |
+
with gr.Row():
|
106 |
+
with gr.Column(scale=4):
|
107 |
+
txt = gr.Textbox(
|
108 |
+
placeholder="Compartilhe sua reflexão aqui...",
|
109 |
+
lines=4,
|
110 |
+
label="Sua Resposta"
|
111 |
+
)
|
112 |
+
|
113 |
+
with gr.Column(scale=1, min_width=100):
|
114 |
+
with gr.Row():
|
115 |
+
btn = gr.Button("Enviar", variant="primary")
|
116 |
+
clear = gr.Button("Limpar")
|
117 |
+
|
118 |
+
with gr.Row():
|
119 |
+
tema_atual = gr.Textbox(
|
120 |
+
value="Autoconhecimento",
|
121 |
+
label="🎯 Tema Atual",
|
122 |
+
interactive=False
|
123 |
+
)
|
124 |
+
tempo_resposta = gr.Textbox(
|
125 |
+
value="0:00",
|
126 |
+
label="⏱️ Tempo nesta resposta",
|
127 |
+
interactive=False
|
128 |
+
)
|
129 |
+
|
130 |
+
with gr.Tab("📊 Insights"):
|
131 |
+
with gr.Row():
|
132 |
+
with gr.Column():
|
133 |
+
sentiment_chart = gr.Plot(label="Análise de Sentimento")
|
134 |
+
with gr.Column():
|
135 |
+
word_cloud = gr.Plot(label="Nuvem de Palavras")
|
136 |
+
|
137 |
+
with gr.Row():
|
138 |
+
temas_fortes = gr.Textbox(
|
139 |
+
label="���� Temas com Mais Confiança",
|
140 |
+
interactive=False,
|
141 |
+
lines=3
|
142 |
+
)
|
143 |
+
areas_desenvolvimento = gr.Textbox(
|
144 |
+
label="🎯 Áreas para Desenvolvimento",
|
145 |
+
interactive=False,
|
146 |
+
lines=3
|
147 |
+
)
|
148 |
+
|
149 |
+
with gr.Tab("📝 Notas & Recursos"):
|
150 |
+
with gr.Row():
|
151 |
+
notas = gr.Textbox(
|
152 |
+
placeholder="Faça anotações durante sua jornada...",
|
153 |
+
label="📝 Minhas Notas",
|
154 |
+
lines=5
|
155 |
+
)
|
156 |
+
|
157 |
+
with gr.Row():
|
158 |
+
with gr.Accordion("📚 Recursos por Tema", open=False):
|
159 |
+
gr.Markdown("""
|
160 |
+
### 🎯 Autoconhecimento
|
161 |
+
- [Artigo] Desenvolvendo Autoconsciência na Liderança
|
162 |
+
- [Exercício] Reflexão sobre Valores e Propósito
|
163 |
+
- [Ferramenta] Template de Diário de Liderança
|
164 |
+
|
165 |
+
### 💬 Comunicação
|
166 |
+
- [Guia] Comunicação Assertiva na Liderança
|
167 |
+
- [Checklist] Preparação para Feedbacks Difíceis
|
168 |
+
- [Framework] Estrutura de Comunicação Situacional
|
169 |
+
|
170 |
+
### 🤔 Tomada de Decisão
|
171 |
+
- [Modelo] Framework para Decisões Complexas
|
172 |
+
- [Exercício] Análise de Decisões Passadas
|
173 |
+
- [Template] Documentação de Decisões Importantes
|
174 |
+
""")
|
175 |
+
|
176 |
+
def atualizar_timer():
|
177 |
+
"""Update session timer"""
|
178 |
+
tempo = int((datetime.now() - coach.inicio).total_seconds() / 60)
|
179 |
+
return tempo
|
180 |
+
|
181 |
+
def responder(mensagem, historico):
|
182 |
+
"""Process user response and update interface"""
|
183 |
+
if not mensagem.strip():
|
184 |
+
return {
|
185 |
+
txt: "",
|
186 |
+
chat: historico
|
187 |
+
}
|
188 |
+
|
189 |
+
# Format user message
|
190 |
+
msg_usuario = {
|
191 |
+
"role": "user",
|
192 |
+
"content": mensagem
|
193 |
+
}
|
194 |
+
|
195 |
+
# Generate and format coach response
|
196 |
+
resposta = coach.gerar_resposta(mensagem)
|
197 |
+
|
198 |
+
# Update history
|
199 |
+
historico.append([msg_usuario, resposta])
|
200 |
+
|
201 |
+
# Update visualizations
|
202 |
+
sentiment_analysis = None
|
203 |
+
word_cloud_plot = None
|
204 |
+
strong_themes = ""
|
205 |
+
development_areas = ""
|
206 |
+
|
207 |
+
if len(coach.historico_respostas) > 1:
|
208 |
+
sentiment_analysis = analyze_sentiment_trend(coach.historico_respostas)
|
209 |
+
word_cloud_plot = generate_word_cloud(coach.historico_respostas)
|
210 |
+
strong_themes, development_areas = analyze_themes(coach.historico_respostas)
|
211 |
+
|
212 |
+
tempo_atual = int((datetime.now() - coach.inicio).total_seconds() / 60)
|
213 |
+
|
214 |
+
return {
|
215 |
+
txt: "",
|
216 |
+
chat: historico,
|
217 |
+
timer: tempo_atual,
|
218 |
+
progress: coach.pergunta_atual,
|
219 |
+
tema_atual: PERGUNTAS[min(coach.pergunta_atual, len(PERGUNTAS)-1)]["categoria"].title(),
|
220 |
+
tempo_resposta: "0:00",
|
221 |
+
sentiment_chart: sentiment_analysis,
|
222 |
+
word_cloud: word_cloud_plot,
|
223 |
+
temas_fortes: strong_themes,
|
224 |
+
areas_desenvolvimento: development_areas
|
225 |
+
}
|
226 |
+
|
227 |
+
def limpar_chat():
|
228 |
+
"""Reset chat and all related components"""
|
229 |
+
coach.__init__()
|
230 |
+
primeira_mensagem = coach.primeira_pergunta()
|
231 |
+
return {
|
232 |
+
chat: [[None, primeira_mensagem]],
|
233 |
+
txt: "",
|
234 |
+
progress: 0,
|
235 |
+
tema_atual: "Autoconhecimento",
|
236 |
+
tempo_resposta: "0:00",
|
237 |
+
sentiment_chart: None,
|
238 |
+
word_cloud: None,
|
239 |
+
temas_fortes: "",
|
240 |
+
areas_desenvolvimento: ""
|
241 |
+
}
|
242 |
+
|
243 |
+
# Event handlers
|
244 |
+
txt.submit(
|
245 |
+
responder,
|
246 |
+
[txt, chat],
|
247 |
+
[txt, chat, timer, progress, tema_atual, tempo_resposta,
|
248 |
+
sentiment_chart, word_cloud, temas_fortes, areas_desenvolvimento]
|
249 |
+
)
|
250 |
+
|
251 |
+
btn.click(
|
252 |
+
responder,
|
253 |
+
[txt, chat],
|
254 |
+
[txt, chat, timer, progress, tema_atual, tempo_resposta,
|
255 |
+
sentiment_chart, word_cloud, temas_fortes, areas_desenvolvimento]
|
256 |
+
)
|
257 |
+
|
258 |
+
clear.click(
|
259 |
+
limpar_chat,
|
260 |
+
None,
|
261 |
+
[chat, txt, progress, tema_atual, tempo_resposta,
|
262 |
+
sentiment_chart, word_cloud, temas_fortes, areas_desenvolvimento]
|
263 |
+
)
|
264 |
+
|
265 |
+
# Timer update
|
266 |
+
gr.on(
|
267 |
+
triggers=[gr.EventListener(every=1)],
|
268 |
+
fn=atualizar_timer,
|
269 |
+
outputs=[timer]
|
270 |
+
)
|
271 |
+
|
272 |
+
return app
|
273 |
+
|
274 |
+
if __name__ == "__main__":
|
275 |
+
app = criar_interface()
|
276 |
+
app.launch()
|