DHEIVER commited on
Commit
81baf26
·
verified ·
1 Parent(s): 5bfab3a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +224 -123
app.py CHANGED
@@ -2,11 +2,61 @@ import gradio as gr
2
  from sentence_transformers import SentenceTransformer
3
  from sklearn.metrics.pairwise import cosine_similarity
4
  import numpy as np
 
5
 
6
  # Initialize model
7
  model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
8
 
9
- # Enhanced knowledge base with more detailed descriptions and combinations
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  DISC_PROFILES = {
11
  'D': {
12
  'nome': 'Dominância',
@@ -244,16 +294,61 @@ def get_profile_description(perfil, percentual):
244
  'recomendacoes': recomendacoes
245
  }
246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  def gerar_relatorio_personalizado(percentuais):
248
  """Gera relatório detalhado e personalizado baseado nos percentuais DISC."""
249
  perfis_ordenados = dict(sorted(percentuais.items(), key=lambda x: x[1], reverse=True))
250
  perfis_desc = {k: get_profile_description(k, v) for k, v in perfis_ordenados.items()}
251
 
252
- # Perfil dominante e secundário
253
  perfil_dominante = list(perfis_ordenados.keys())[0]
254
  perfil_secundario = list(perfis_ordenados.keys())[1]
255
 
256
- # Gerar relatório
257
  relatorio = f"""ANÁLISE DE PERFIL COMPORTAMENTAL DISC
258
 
259
  VISÃO GERAL
@@ -281,21 +376,6 @@ OBSERVAÇÃO: Este perfil representa suas tendências comportamentais naturais.
281
 
282
  return relatorio
283
 
284
- # Atualizar a função de processamento do questionário
285
- def processar_questionario(*args):
286
- """Processa as respostas do questionário e gera o relatório personalizado."""
287
- respostas = list(args)
288
- percentuais = calcular_perfil(respostas)
289
- return gerar_relatorio_personalizado(percentuais)
290
-
291
- # Manter o resto do código original (interface Gradio) como está...
292
-
293
- import gradio as gr
294
- from sentence_transformers import SentenceTransformer
295
- import numpy as np
296
-
297
- # Manter a base DISC_PROFILES do código anterior...
298
-
299
  # Temas e estilos personalizados
300
  CUSTOM_CSS = """
301
  .container {
@@ -315,8 +395,21 @@ CUSTOM_CSS = """
315
  background-color: #ffffff;
316
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
317
  }
 
 
 
 
 
 
 
 
 
 
 
 
318
  """
319
 
 
320
  THEME = gr.themes.Soft(
321
  primary_hue="blue",
322
  secondary_hue="gray",
@@ -330,12 +423,21 @@ THEME = gr.themes.Soft(
330
  block_title_text_size="xl",
331
  )
332
 
333
- # Componente de progresso
334
  def update_progress(progress, total_questions=5):
335
  """Atualiza a barra de progresso."""
336
  answered = sum(1 for p in progress if p is not None)
337
  return f"{answered}/{total_questions} questões respondidas", answered / total_questions
338
 
 
 
 
 
 
 
 
 
 
 
339
  def create_interface():
340
  """Cria interface moderna do Gradio."""
341
  with gr.Blocks(theme=THEME, css=CUSTOM_CSS) as iface:
@@ -344,14 +446,22 @@ def create_interface():
344
  with gr.Column():
345
  gr.Markdown("""
346
  # 🎯 Análise de Perfil Comportamental DISC
347
- Descubra seu perfil comportamental respondendo às questões abaixo.
348
- Escolha as opções que melhor representam seu comportamento natural.
 
 
 
 
 
 
 
 
349
  """)
350
 
351
  # Container principal
352
  with gr.Column(elem_classes="container"):
353
  # Barra de progresso
354
- with gr.Row():
355
  progress_text = gr.Markdown("0/5 questões respondidas")
356
  progress_bar = gr.Progress()
357
 
@@ -360,18 +470,19 @@ def create_interface():
360
  for i, questao in enumerate(DISC_QUESTIONS, 1):
361
  with gr.Box(elem_classes="question-card"):
362
  gr.Markdown(f"### Questão {i}: {questao['pergunta']}")
363
- radio = gr.Radio(
364
- choices=[f"{perfil} - {desc}" for perfil, desc in questao['opcoes']],
365
- label="Selecione a opção mais adequada",
366
- scale=0,
367
- interactive=True
368
- )
369
- radio_components.append(radio)
 
370
 
371
  # Botão de análise
372
- with gr.Row():
373
  analyze_btn = gr.Button(
374
- "Analisar Perfil",
375
  variant="primary",
376
  scale=0,
377
  min_width=200
@@ -379,7 +490,7 @@ def create_interface():
379
 
380
  # Área de resultados
381
  with gr.Box(visible=False, elem_classes="result-card") as result_box:
382
- gr.Markdown("### 📊 Resultado da Análise")
383
 
384
  with gr.Row():
385
  # Gráfico de distribuição
@@ -387,16 +498,18 @@ def create_interface():
387
 
388
  # Métricas principais
389
  with gr.Column():
390
- perfil_dominante = gr.Textbox(
391
- label="Perfil Dominante",
392
- show_label=True,
393
- interactive=False
394
- )
395
- perfil_secundario = gr.Textbox(
396
- label="Perfil Secundário",
397
- show_label=True,
398
- interactive=False
399
- )
 
 
400
 
401
  # Relatório detalhado
402
  with gr.Accordion("📝 Relatório Detalhado", open=True):
@@ -404,95 +517,83 @@ def create_interface():
404
 
405
  # Botões de ação
406
  with gr.Row():
407
- reset_btn = gr.Button("🔄 Reiniciar", variant="secondary")
408
- download_btn = gr.Button("⬇️ Download PDF", variant="secondary")
 
409
 
410
- # Lógica de atualização da interface
411
- def update_display(*answers):
412
- if all(a is not None for a in answers):
413
- return {
414
- result_box: gr.update(visible=True),
415
- analyze_btn: gr.update(interactive=False)
416
- }
417
- return {
418
- result_box: gr.update(visible=False),
419
- analyze_btn: gr.update(interactive=True)
420
- }
421
-
422
- # Funções de processamento
423
- def process_and_visualize(*answers):
424
- """Processa respostas e gera visualizações."""
425
- percentuais = calcular_perfil(answers)
426
-
427
- # Criar gráfico
428
- fig = create_disc_plot(percentuais)
429
-
430
- # Gerar relatório
431
- report = gerar_relatorio_personalizado(percentuais)
432
-
433
- # Identificar perfis principais
434
- sorted_profiles = dict(sorted(percentuais.items(), key=lambda x: x[1], reverse=True))
435
- main_profile = list(sorted_profiles.keys())[0]
436
- secondary_profile = list(sorted_profiles.keys())[1]
437
-
438
  return {
439
- plot: fig,
440
- perfil_dominante: f"{main_profile} ({sorted_profiles[main_profile]:.1f}%)",
441
- perfil_secundario: f"{secondary_profile} ({sorted_profiles[secondary_profile]:.1f}%)",
442
- output: report
443
  }
444
-
445
- def reset_interface():
446
- """Reinicia a interface."""
447
- return [None] * len(radio_components) + [
448
- gr.update(visible=False),
449
- gr.update(interactive=True),
450
- None, None, None, None,
451
- "0/5 questões respondidas"
452
- ]
453
-
454
- # Event listeners
455
- for radio in radio_components:
456
- radio.change(
457
- lambda *args: update_progress(args),
458
- inputs=radio_components,
459
- outputs=[progress_text, progress_bar]
460
- )
461
- radio.change(
462
- update_display,
463
- inputs=radio_components,
464
- outputs=[result_box, analyze_btn]
465
- )
466
-
467
- analyze_btn.click(
468
- process_and_visualize,
469
  inputs=radio_components,
470
- outputs=[plot, perfil_dominante, perfil_secundario, output]
471
  )
472
-
473
- reset_btn.click(
474
- reset_interface,
475
- outputs=radio_components + [
476
- result_box,
477
- analyze_btn,
478
- plot,
479
- perfil_dominante,
480
- perfil_secundario,
481
- output,
482
- progress_text
483
- ]
484
- )
485
-
486
- # Download handler (exemplo simples)
487
- download_btn.click(
488
- lambda x: f"disc_report_{x}.pdf",
489
- inputs=[perfil_dominante],
490
- outputs=gr.File()
491
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
492
 
493
  return iface
494
 
495
- # Criar e lançar a interface
496
  if __name__ == "__main__":
497
  iface = create_interface()
498
- iface.launch(share=True)
 
2
  from sentence_transformers import SentenceTransformer
3
  from sklearn.metrics.pairwise import cosine_similarity
4
  import numpy as np
5
+ import plotly.graph_objects as go
6
 
7
  # Initialize model
8
  model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
9
 
10
+ # Questionário DISC
11
+ DISC_QUESTIONS = [
12
+ {
13
+ "pergunta": "Em situações de trabalho em equipe, você geralmente:",
14
+ "opcoes": [
15
+ ("D", "Assume a liderança e toma decisões rápidas"),
16
+ ("I", "Motiva o grupo e mantém o ambiente animado"),
17
+ ("S", "Apoia os colegas e mantém a harmonia"),
18
+ ("C", "Analisa detalhadamente antes de agir")
19
+ ]
20
+ },
21
+ {
22
+ "pergunta": "Quando enfrenta um desafio no trabalho, você:",
23
+ "opcoes": [
24
+ ("D", "Enfrenta diretamente e busca soluções imediatas"),
25
+ ("I", "Discute com outros e busca diferentes perspectivas"),
26
+ ("S", "Mantém a calma e segue um processo estabelecido"),
27
+ ("C", "Pesquisa todas as informações disponíveis primeiro")
28
+ ]
29
+ },
30
+ {
31
+ "pergunta": "Em reuniões profissionais, você costuma:",
32
+ "opcoes": [
33
+ ("D", "Ir direto ao ponto e focar em resultados"),
34
+ ("I", "Participar ativamente e compartilhar ideias"),
35
+ ("S", "Ouvir atentamente e contribuir quando solicitado"),
36
+ ("C", "Tomar notas e questionar os detalhes")
37
+ ]
38
+ },
39
+ {
40
+ "pergunta": "Ao lidar com mudanças no ambiente de trabalho, você:",
41
+ "opcoes": [
42
+ ("D", "Abraça a mudança e lidera a implementação"),
43
+ ("I", "Entusiasma os outros sobre as novas possibilidades"),
44
+ ("S", "Adapta-se gradualmente seguindo o processo"),
45
+ ("C", "Analisa os impactos antes de aceitar")
46
+ ]
47
+ },
48
+ {
49
+ "pergunta": "Sob pressão no trabalho, você tende a:",
50
+ "opcoes": [
51
+ ("D", "Tornar-se mais direto e focado em resultados"),
52
+ ("I", "Buscar apoio e interação com a equipe"),
53
+ ("S", "Manter a calma e seguir metodicamente"),
54
+ ("C", "Concentrar-se em detalhes e procedimentos")
55
+ ]
56
+ }
57
+ ]
58
+
59
+ # Enhanced knowledge base
60
  DISC_PROFILES = {
61
  'D': {
62
  'nome': 'Dominância',
 
294
  'recomendacoes': recomendacoes
295
  }
296
 
297
+ def calcular_perfil(respostas):
298
+ """Calcula os percentuais de cada perfil DISC."""
299
+ contagem = {'D': 0, 'I': 0, 'S': 0, 'C': 0}
300
+
301
+ for resposta in respostas:
302
+ if resposta:
303
+ perfil = resposta.split()[0]
304
+ contagem[perfil] += 1
305
+
306
+ total = sum(contagem.values())
307
+ if total > 0:
308
+ percentuais = {k: (v/total) * 100 for k, v in contagem.items()}
309
+ else:
310
+ percentuais = {k: 0 for k in contagem.keys()}
311
+
312
+ return percentuais
313
+
314
+ def create_disc_plot(percentuais):
315
+ """Cria um gráfico de barras para visualização do perfil DISC."""
316
+ colors = {
317
+ 'D': '#FF4B4B',
318
+ 'I': '#FFD700',
319
+ 'S': '#4CAF50',
320
+ 'C': '#2196F3'
321
+ }
322
+
323
+ fig = go.Figure(data=[
324
+ go.Bar(
325
+ x=list(percentuais.keys()),
326
+ y=list(percentuais.values()),
327
+ marker_color=[colors[k] for k in percentuais.keys()],
328
+ text=[f'{v:.1f}%' for v in percentuais.values()],
329
+ textposition='auto',
330
+ )
331
+ ])
332
+
333
+ fig.update_layout(
334
+ title='Distribuição do Perfil DISC',
335
+ yaxis_title='Percentual (%)',
336
+ yaxis_range=[0, 100],
337
+ showlegend=False,
338
+ template='plotly_white',
339
+ height=400
340
+ )
341
+
342
+ return fig
343
+
344
  def gerar_relatorio_personalizado(percentuais):
345
  """Gera relatório detalhado e personalizado baseado nos percentuais DISC."""
346
  perfis_ordenados = dict(sorted(percentuais.items(), key=lambda x: x[1], reverse=True))
347
  perfis_desc = {k: get_profile_description(k, v) for k, v in perfis_ordenados.items()}
348
 
 
349
  perfil_dominante = list(perfis_ordenados.keys())[0]
350
  perfil_secundario = list(perfis_ordenados.keys())[1]
351
 
 
352
  relatorio = f"""ANÁLISE DE PERFIL COMPORTAMENTAL DISC
353
 
354
  VISÃO GERAL
 
376
 
377
  return relatorio
378
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
379
  # Temas e estilos personalizados
380
  CUSTOM_CSS = """
381
  .container {
 
395
  background-color: #ffffff;
396
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
397
  }
398
+ .progress-bar {
399
+ margin: 20px 0;
400
+ padding: 10px;
401
+ background: #eef2ff;
402
+ border-radius: 8px;
403
+ }
404
+ .footer {
405
+ margin-top: 30px;
406
+ text-align: center;
407
+ font-size: 0.9em;
408
+ color: #666;
409
+ }
410
  """
411
 
412
+ # Configuração do tema
413
  THEME = gr.themes.Soft(
414
  primary_hue="blue",
415
  secondary_hue="gray",
 
423
  block_title_text_size="xl",
424
  )
425
 
 
426
  def update_progress(progress, total_questions=5):
427
  """Atualiza a barra de progresso."""
428
  answered = sum(1 for p in progress if p is not None)
429
  return f"{answered}/{total_questions} questões respondidas", answered / total_questions
430
 
431
+ def reset_interface():
432
+ """Reinicia a interface para um novo teste."""
433
+ return [None] * 5 + [
434
+ gr.update(visible=False),
435
+ gr.update(interactive=True),
436
+ None, None, None, None,
437
+ "0/5 questões respondidas",
438
+ 0
439
+ ]
440
+
441
  def create_interface():
442
  """Cria interface moderna do Gradio."""
443
  with gr.Blocks(theme=THEME, css=CUSTOM_CSS) as iface:
 
446
  with gr.Column():
447
  gr.Markdown("""
448
  # 🎯 Análise de Perfil Comportamental DISC
449
+
450
+ ### Descubra seu perfil comportamental único!
451
+
452
+ Este teste ajudará você a entender melhor seu estilo de comportamento natural
453
+ e como você pode aproveitar seus pontos fortes no ambiente profissional.
454
+
455
+ #### Instruções:
456
+ - Responda todas as questões pensando em seu comportamento mais natural
457
+ - Não existe resposta certa ou errada
458
+ - Escolha a opção que melhor representa como você normalmente age
459
  """)
460
 
461
  # Container principal
462
  with gr.Column(elem_classes="container"):
463
  # Barra de progresso
464
+ with gr.Row(elem_classes="progress-bar"):
465
  progress_text = gr.Markdown("0/5 questões respondidas")
466
  progress_bar = gr.Progress()
467
 
 
470
  for i, questao in enumerate(DISC_QUESTIONS, 1):
471
  with gr.Box(elem_classes="question-card"):
472
  gr.Markdown(f"### Questão {i}: {questao['pergunta']}")
473
+ with gr.Column():
474
+ radio = gr.Radio(
475
+ choices=[f"{perfil} - {desc}" for perfil, desc in questao['opcoes']],
476
+ label="Selecione a opção mais adequada:",
477
+ scale=0,
478
+ interactive=True
479
+ )
480
+ radio_components.append(radio)
481
 
482
  # Botão de análise
483
+ with gr.Row(elem_classes="center"):
484
  analyze_btn = gr.Button(
485
+ "📊 Analisar Perfil",
486
  variant="primary",
487
  scale=0,
488
  min_width=200
 
490
 
491
  # Área de resultados
492
  with gr.Box(visible=False, elem_classes="result-card") as result_box:
493
+ gr.Markdown("## 📊 Resultado da Análise")
494
 
495
  with gr.Row():
496
  # Gráfico de distribuição
 
498
 
499
  # Métricas principais
500
  with gr.Column():
501
+ with gr.Box():
502
+ gr.Markdown("### Perfis Principais")
503
+ perfil_dominante = gr.Textbox(
504
+ label="Perfil Dominante",
505
+ show_label=True,
506
+ interactive=False
507
+ )
508
+ perfil_secundario = gr.Textbox(
509
+ label="Perfil Secundário",
510
+ show_label=True,
511
+ interactive=False
512
+ )
513
 
514
  # Relatório detalhado
515
  with gr.Accordion("📝 Relatório Detalhado", open=True):
 
517
 
518
  # Botões de ação
519
  with gr.Row():
520
+ download_btn = gr.Button("⬇️ Baixar Relatório PDF", variant="secondary")
521
+ reset_btn = gr.Button("🔄 Fazer Novo Teste", variant="secondary")
522
+ share_btn = gr.Button("📤 Compartilhar Resultado", variant="secondary")
523
 
524
+ # Footer
525
+ with gr.Row(elem_classes="footer"):
526
+ gr.Markdown("""
527
+ 💡 **Observação:** Este é um teste comportamental indicativo.
528
+ Os resultados representam tendências naturais de comportamento,
529
+ que podem variar dependendo do contexto e situação.
530
+ """)
531
+
532
+ # Event handlers
533
+ def update_display(*answers):
534
+ """Atualiza a visibilidade dos componentes baseado nas respostas."""
535
+ if all(a is not None for a in answers):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
536
  return {
537
+ result_box: gr.update(visible=True),
538
+ analyze_btn: gr.update(interactive=False)
 
 
539
  }
540
+ return {
541
+ result_box: gr.update(visible=False),
542
+ analyze_btn: gr.update(interactive=True)
543
+ }
544
+
545
+ # Event bindings
546
+ for radio in radio_components:
547
+ radio.change(
548
+ lambda *args: update_progress(args),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
549
  inputs=radio_components,
550
+ outputs=[progress_text, progress_bar]
551
  )
552
+ radio.change(
553
+ update_display,
554
+ inputs=radio_components,
555
+ outputs=[result_box, analyze_btn]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
556
  )
557
+
558
+ analyze_btn.click(
559
+ process_and_visualize,
560
+ inputs=radio_components,
561
+ outputs=[plot, perfil_dominante, perfil_secundario, output]
562
+ )
563
+
564
+ reset_btn.click(
565
+ reset_interface,
566
+ outputs=radio_components + [
567
+ result_box,
568
+ analyze_btn,
569
+ plot,
570
+ perfil_dominante,
571
+ perfil_secundario,
572
+ output,
573
+ progress_text,
574
+ progress_bar
575
+ ]
576
+ )
577
+
578
+ # Exemplo simples de geração de PDF (você precisará implementar a função real)
579
+ def generate_pdf(report_text):
580
+ # Implementar geração real de PDF aqui
581
+ return "report.pdf"
582
+
583
+ download_btn.click(
584
+ generate_pdf,
585
+ inputs=[output],
586
+ outputs=gr.File()
587
+ )
588
+
589
+ # Função de compartilhamento (exemplo)
590
+ def share_results():
591
+ return gr.Info("Link de compartilhamento copiado!")
592
+
593
+ share_btn.click(share_results)
594
 
595
  return iface
596
 
 
597
  if __name__ == "__main__":
598
  iface = create_interface()
599
+ iface.launch(show_error=True)