|
import gradio as gr |
|
from sentence_transformers import SentenceTransformer |
|
from sklearn.metrics.pairwise import cosine_similarity |
|
import numpy as np |
|
import plotly.graph_objects as go |
|
|
|
|
|
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2') |
|
|
|
|
|
DISC_QUESTIONS = [ |
|
{ |
|
"pergunta": "Em situações de trabalho em equipe, você geralmente:", |
|
"opcoes": [ |
|
("D", "Assume a liderança e toma decisões rápidas"), |
|
("I", "Motiva o grupo e mantém o ambiente animado"), |
|
("S", "Apoia os colegas e mantém a harmonia"), |
|
("C", "Analisa detalhadamente antes de agir") |
|
] |
|
}, |
|
{ |
|
"pergunta": "Quando enfrenta um desafio no trabalho, você:", |
|
"opcoes": [ |
|
("D", "Enfrenta diretamente e busca soluções imediatas"), |
|
("I", "Discute com outros e busca diferentes perspectivas"), |
|
("S", "Mantém a calma e segue um processo estabelecido"), |
|
("C", "Pesquisa todas as informações disponíveis primeiro") |
|
] |
|
}, |
|
{ |
|
"pergunta": "Em reuniões profissionais, você costuma:", |
|
"opcoes": [ |
|
("D", "Ir direto ao ponto e focar em resultados"), |
|
("I", "Participar ativamente e compartilhar ideias"), |
|
("S", "Ouvir atentamente e contribuir quando solicitado"), |
|
("C", "Tomar notas e questionar os detalhes") |
|
] |
|
}, |
|
{ |
|
"pergunta": "Ao lidar com mudanças no ambiente de trabalho, você:", |
|
"opcoes": [ |
|
("D", "Abraça a mudança e lidera a implementação"), |
|
("I", "Entusiasma os outros sobre as novas possibilidades"), |
|
("S", "Adapta-se gradualmente seguindo o processo"), |
|
("C", "Analisa os impactos antes de aceitar") |
|
] |
|
}, |
|
{ |
|
"pergunta": "Sob pressão no trabalho, você tende a:", |
|
"opcoes": [ |
|
("D", "Tornar-se mais direto e focado em resultados"), |
|
("I", "Buscar apoio e interação com a equipe"), |
|
("S", "Manter a calma e seguir metodicamente"), |
|
("C", "Concentrar-se em detalhes e procedimentos") |
|
] |
|
} |
|
] |
|
|
|
|
|
DISC_PROFILES = { |
|
'D': { |
|
'nome': 'Dominância', |
|
'caracteristicas': { |
|
'alto': [ |
|
"Focado em resultados e ação imediata", |
|
"Direto e assertivo na comunicação", |
|
"Competitivo e determinado", |
|
"Assume naturalmente posições de liderança", |
|
"Orientado para desafios e conquistas" |
|
], |
|
'baixo': [ |
|
"Mais colaborativo e menos confrontador", |
|
"Prefere ambientes harmoniosos", |
|
"Tende a evitar conflitos", |
|
"Mais cauteloso na tomada de decisões", |
|
"Busca consenso em vez de imposição" |
|
] |
|
}, |
|
'ambiente_ideal': { |
|
'alto': [ |
|
"Ambientes competitivos", |
|
"Situações que exigem decisões rápidas", |
|
"Projetos desafiadores", |
|
"Autonomia na execução", |
|
"Oportunidades de liderança" |
|
], |
|
'baixo': [ |
|
"Ambientes colaborativos", |
|
"Trabalho em equipe", |
|
"Projetos estruturados", |
|
"Suporte de liderança", |
|
"Foco em cooperação" |
|
] |
|
}, |
|
'recomendacoes': { |
|
'alto': [ |
|
"Desenvolver mais empatia e paciência", |
|
"Praticar escuta ativa", |
|
"Considerar diferentes perspectivas", |
|
"Equilibrar assertividade com diplomacia", |
|
"Fortalecer habilidades de trabalho em equipe" |
|
], |
|
'baixo': [ |
|
"Desenvolver mais assertividade", |
|
"Praticar tomada de decisão", |
|
"Expressar opiniões com mais confiança", |
|
"Assumir mais riscos calculados", |
|
"Fortalecer liderança situacional" |
|
] |
|
} |
|
}, |
|
'I': { |
|
'nome': 'Influência', |
|
'caracteristicas': { |
|
'alto': [ |
|
"Comunicativo e expressivo", |
|
"Entusiasta e otimista", |
|
"Sociável e carismático", |
|
"Persuasivo e inspirador", |
|
"Criativo e inovador" |
|
], |
|
'baixo': [ |
|
"Mais reservado e analítico", |
|
"Prefere comunicação objetiva", |
|
"Foco em fatos e dados", |
|
"Mais formal nas relações", |
|
"Prioriza resultados sobre relacionamentos" |
|
] |
|
}, |
|
'ambiente_ideal': { |
|
'alto': [ |
|
"Ambientes sociais e dinâmicos", |
|
"Oportunidades de networking", |
|
"Trabalho com pessoas", |
|
"Reconhecimento público", |
|
"Liberdade criativa" |
|
], |
|
'baixo': [ |
|
"Ambientes mais formais", |
|
"Trabalho individual", |
|
"Projetos técnicos", |
|
"Foco em processos", |
|
"Estrutura definida" |
|
] |
|
}, |
|
'recomendacoes': { |
|
'alto': [ |
|
"Desenvolver foco e organização", |
|
"Melhorar gestão do tempo", |
|
"Praticar conclusão de tarefas", |
|
"Equilibrar socialização e produtividade", |
|
"Fortalecer análise de dados" |
|
], |
|
'baixo': [ |
|
"Desenvolver habilidades de networking", |
|
"Praticar comunicação expressiva", |
|
"Participar mais em grupos", |
|
"Explorar criatividade", |
|
"Fortalecer relações interpessoais" |
|
] |
|
} |
|
}, |
|
'S': { |
|
'nome': 'Estabilidade', |
|
'caracteristicas': { |
|
'alto': [ |
|
"Paciente e consistente", |
|
"Colaborativo e prestativo", |
|
"Leal e confiável", |
|
"Bom ouvinte", |
|
"Focado em harmonia" |
|
], |
|
'baixo': [ |
|
"Mais flexível e adaptável", |
|
"Aberto a mudanças rápidas", |
|
"Multitarefa eficiente", |
|
"Dinâmico e versátil", |
|
"Aprecia variedade" |
|
] |
|
}, |
|
'ambiente_ideal': { |
|
'alto': [ |
|
"Ambientes estáveis e previsíveis", |
|
"Trabalho em equipe", |
|
"Rotinas estabelecidas", |
|
"Mudanças graduais", |
|
"Relacionamentos duradouros" |
|
], |
|
'baixo': [ |
|
"Ambientes dinâmicos", |
|
"Mudanças frequentes", |
|
"Projetos variados", |
|
"Novos desafios", |
|
"Flexibilidade de rotina" |
|
] |
|
}, |
|
'recomendacoes': { |
|
'alto': [ |
|
"Desenvolver adaptabilidade", |
|
"Praticar iniciativa", |
|
"Expressar opiniões", |
|
"Lidar melhor com mudanças", |
|
"Fortalecer tomada de decisão" |
|
], |
|
'baixo': [ |
|
"Desenvolver mais paciência", |
|
"Praticar consistência", |
|
"Fortalecer relacionamentos", |
|
"Melhorar escuta ativa", |
|
"Criar rotinas efetivas" |
|
] |
|
} |
|
}, |
|
'C': { |
|
'nome': 'Conformidade', |
|
'caracteristicas': { |
|
'alto': [ |
|
"Analítico e preciso", |
|
"Organizado e sistemático", |
|
"Focado em qualidade", |
|
"Atento aos detalhes", |
|
"Orientado por dados" |
|
], |
|
'baixo': [ |
|
"Mais flexível com regras", |
|
"Foco em resultados rápidos", |
|
"Prático e objetivo", |
|
"Adaptável a mudanças", |
|
"Tolerante a ambiguidades" |
|
] |
|
}, |
|
'ambiente_ideal': { |
|
'alto': [ |
|
"Ambientes estruturados", |
|
"Processos claros", |
|
"Foco em qualidade", |
|
"Análise detalhada", |
|
"Padrões definidos" |
|
], |
|
'baixo': [ |
|
"Ambientes flexíveis", |
|
"Liberdade de processo", |
|
"Foco em resultados", |
|
"Decisões rápidas", |
|
"Adaptabilidade" |
|
] |
|
}, |
|
'recomendacoes': { |
|
'alto': [ |
|
"Desenvolver flexibilidade", |
|
"Praticar decisões rápidas", |
|
"Lidar melhor com ambiguidade", |
|
"Equilibrar análise e ação", |
|
"Fortalecer relacionamentos" |
|
], |
|
'baixo': [ |
|
"Desenvolver atenção aos detalhes", |
|
"Melhorar organização", |
|
"Criar sistemas e processos", |
|
"Fortalecer análise crítica", |
|
"Praticar planejamento" |
|
] |
|
} |
|
} |
|
} |
|
|
|
def get_intensity_level(percentual): |
|
"""Determina o nível de intensidade baseado no percentual.""" |
|
if percentual >= 75: |
|
return "muito alto" |
|
elif percentual >= 60: |
|
return "alto" |
|
elif percentual >= 40: |
|
return "moderado" |
|
elif percentual >= 25: |
|
return "baixo" |
|
else: |
|
return "muito baixo" |
|
|
|
def get_profile_description(perfil, percentual): |
|
"""Gera descrição personalizada baseada no perfil e sua intensidade.""" |
|
nivel = "alto" if percentual >= 50 else "baixo" |
|
caracteristicas = DISC_PROFILES[perfil]['caracteristicas'][nivel] |
|
ambiente = DISC_PROFILES[perfil]['ambiente_ideal'][nivel] |
|
recomendacoes = DISC_PROFILES[perfil]['recomendacoes'][nivel] |
|
|
|
intensidade = get_intensity_level(percentual) |
|
|
|
return { |
|
'nome': DISC_PROFILES[perfil]['nome'], |
|
'intensidade': intensidade, |
|
'caracteristicas': caracteristicas, |
|
'ambiente': ambiente, |
|
'recomendacoes': recomendacoes |
|
} |
|
|
|
def calcular_perfil(respostas): |
|
"""Calcula os percentuais de cada perfil DISC.""" |
|
contagem = {'D': 0, 'I': 0, 'S': 0, 'C': 0} |
|
|
|
for resposta in respostas: |
|
if resposta: |
|
perfil = resposta.split()[0] |
|
contagem[perfil] += 1 |
|
|
|
total = sum(contagem.values()) |
|
if total > 0: |
|
percentuais = {k: (v/total) * 100 for k, v in contagem.items()} |
|
else: |
|
percentuais = {k: 0 for k in contagem.keys()} |
|
|
|
return percentuais |
|
|
|
def create_disc_plot(percentuais): |
|
"""Cria um gráfico de barras para visualização do perfil DISC.""" |
|
colors = { |
|
'D': '#FF4B4B', |
|
'I': '#FFD700', |
|
'S': '#4CAF50', |
|
'C': '#2196F3' |
|
} |
|
|
|
fig = go.Figure(data=[ |
|
go.Bar( |
|
x=list(percentuais.keys()), |
|
y=list(percentuais.values()), |
|
marker_color=[colors[k] for k in percentuais.keys()], |
|
text=[f'{v:.1f}%' for v in percentuais.values()], |
|
textposition='auto', |
|
) |
|
]) |
|
|
|
fig.update_layout( |
|
title='Distribuição do Perfil DISC', |
|
yaxis_title='Percentual (%)', |
|
yaxis_range=[0, 100], |
|
showlegend=False, |
|
template='plotly_white', |
|
height=400 |
|
) |
|
|
|
return fig |
|
|
|
def gerar_relatorio_personalizado(percentuais): |
|
"""Gera relatório detalhado e personalizado baseado nos percentuais DISC.""" |
|
perfis_ordenados = dict(sorted(percentuais.items(), key=lambda x: x[1], reverse=True)) |
|
perfis_desc = {k: get_profile_description(k, v) for k, v in perfis_ordenados.items()} |
|
|
|
perfil_dominante = list(perfis_ordenados.keys())[0] |
|
perfil_secundario = list(perfis_ordenados.keys())[1] |
|
|
|
relatorio = f"""ANÁLISE DE PERFIL COMPORTAMENTAL DISC |
|
|
|
VISÃO GERAL |
|
Seu perfil apresenta uma combinação única de características, com {perfis_desc[perfil_dominante]['nome']} ({perfil_dominante}) como traço dominante em nível {perfis_desc[perfil_dominante]['intensidade']} ({perfis_ordenados[perfil_dominante]:.1f}%), seguido por {perfis_desc[perfil_secundario]['nome']} ({perfil_secundario}) em nível {perfis_desc[perfil_secundario]['intensidade']} ({perfis_ordenados[perfil_secundario]:.1f}%). |
|
|
|
CARACTERÍSTICAS PRINCIPAIS |
|
Seu estilo comportamental é marcado por: |
|
• {' e '.join(perfis_desc[perfil_dominante]['caracteristicas'][:3])} |
|
• Com influência secundária de: {' e '.join(perfis_desc[perfil_secundario]['caracteristicas'][:2])} |
|
|
|
AMBIENTE IDEAL DE TRABALHO |
|
Você tende a prosperar em ambientes que oferecem: |
|
• {' e '.join(perfis_desc[perfil_dominante]['ambiente'][:3])} |
|
• Complementados por: {' e '.join(perfis_desc[perfil_secundario]['ambiente'][:2])} |
|
|
|
RECOMENDAÇÕES PARA DESENVOLVIMENTO |
|
Para maximizar seu potencial, considere: |
|
• {' e '.join(perfis_desc[perfil_dominante]['recomendacoes'][:3])} |
|
• Adicionalmente: {' e '.join(perfis_desc[perfil_secundario]['recomendacoes'][:2])} |
|
|
|
DISTRIBUIÇÃO COMPLETA DO PERFIL DISC: |
|
{', '.join([f'{k} ({DISC_PROFILES[k]["nome"]}): {v:.1f}%' for k, v in perfis_ordenados.items()])} |
|
|
|
OBSERVAÇÃO: Este perfil representa suas tendências comportamentais naturais. Lembre-se que comportamentos podem ser adaptados conforme o contexto e as necessidades específicas de cada situação.""" |
|
|
|
return relatorio |
|
|
|
|
|
CUSTOM_CSS = """ |
|
.container { |
|
max-width: 800px; |
|
margin: auto; |
|
} |
|
.question-card { |
|
padding: 20px; |
|
margin: 15px 0; |
|
border-radius: 10px; |
|
background-color: #f8f9fa; |
|
} |
|
.result-card { |
|
padding: 25px; |
|
margin-top: 20px; |
|
border-radius: 10px; |
|
background-color: #ffffff; |
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); |
|
} |
|
.progress-bar { |
|
margin: 20px 0; |
|
padding: 10px; |
|
background: #eef2ff; |
|
border-radius: 8px; |
|
} |
|
.footer { |
|
margin-top: 30px; |
|
text-align: center; |
|
font-size: 0.9em; |
|
color: #666; |
|
} |
|
""" |
|
|
|
|
|
THEME = gr.themes.Soft( |
|
primary_hue="blue", |
|
secondary_hue="gray", |
|
neutral_hue="slate", |
|
font=["Source Sans Pro", "ui-sans-serif", "system-ui"] |
|
).set( |
|
button_primary_background_fill="*primary_500", |
|
button_primary_background_fill_hover="*primary_600", |
|
button_secondary_background_fill="*neutral_100", |
|
block_label_text_size="lg", |
|
block_title_text_size="xl", |
|
) |
|
|
|
def update_progress(progress, total_questions=5): |
|
"""Atualiza a barra de progresso.""" |
|
answered = sum(1 for p in progress if p is not None) |
|
return f"{answered}/{total_questions} questões respondidas", answered / total_questions |
|
|
|
def reset_interface(): |
|
"""Reinicia a interface para um novo teste.""" |
|
return [None] * 5 + [ |
|
gr.update(visible=False), |
|
gr.update(interactive=True), |
|
None, None, None, None, |
|
"0/5 questões respondidas", |
|
0 |
|
] |
|
|
|
def create_interface(): |
|
"""Cria interface moderna do Gradio.""" |
|
with gr.Blocks(theme=THEME, css=CUSTOM_CSS) as iface: |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
gr.Markdown(""" |
|
# 🎯 Análise de Perfil Comportamental DISC |
|
|
|
### Descubra seu perfil comportamental único! |
|
|
|
Este teste ajudará você a entender melhor seu estilo de comportamento natural |
|
e como você pode aproveitar seus pontos fortes no ambiente profissional. |
|
|
|
#### Instruções: |
|
- Responda todas as questões pensando em seu comportamento mais natural |
|
- Não existe resposta certa ou errada |
|
- Escolha a opção que melhor representa como você normalmente age |
|
""") |
|
|
|
|
|
with gr.Column(elem_classes="container"): |
|
|
|
with gr.Row(elem_classes="progress-bar"): |
|
progress_text = gr.Markdown("0/5 questões respondidas") |
|
progress_bar = gr.Progress() |
|
|
|
|
|
radio_components = [] |
|
for i, questao in enumerate(DISC_QUESTIONS, 1): |
|
with gr.Box(elem_classes="question-card"): |
|
gr.Markdown(f"### Questão {i}: {questao['pergunta']}") |
|
with gr.Column(): |
|
radio = gr.Radio( |
|
choices=[f"{perfil} - {desc}" for perfil, desc in questao['opcoes']], |
|
label="Selecione a opção mais adequada:", |
|
scale=0, |
|
interactive=True |
|
) |
|
radio_components.append(radio) |
|
|
|
|
|
with gr.Row(elem_classes="center"): |
|
analyze_btn = gr.Button( |
|
"📊 Analisar Perfil", |
|
variant="primary", |
|
scale=0, |
|
min_width=200 |
|
) |
|
|
|
|
|
with gr.Box(visible=False, elem_classes="result-card") as result_box: |
|
gr.Markdown("## 📊 Resultado da Análise") |
|
|
|
with gr.Row(): |
|
|
|
plot = gr.Plot(label="Distribuição DISC") |
|
|
|
|
|
with gr.Column(): |
|
with gr.Box(): |
|
gr.Markdown("### Perfis Principais") |
|
perfil_dominante = gr.Textbox( |
|
label="Perfil Dominante", |
|
show_label=True, |
|
interactive=False |
|
) |
|
perfil_secundario = gr.Textbox( |
|
label="Perfil Secundário", |
|
show_label=True, |
|
interactive=False |
|
) |
|
|
|
|
|
with gr.Accordion("📝 Relatório Detalhado", open=True): |
|
output = gr.Markdown() |
|
|
|
|
|
with gr.Row(): |
|
download_btn = gr.Button("⬇️ Baixar Relatório PDF", variant="secondary") |
|
reset_btn = gr.Button("🔄 Fazer Novo Teste", variant="secondary") |
|
share_btn = gr.Button("📤 Compartilhar Resultado", variant="secondary") |
|
|
|
|
|
with gr.Row(elem_classes="footer"): |
|
gr.Markdown(""" |
|
💡 **Observação:** Este é um teste comportamental indicativo. |
|
Os resultados representam tendências naturais de comportamento, |
|
que podem variar dependendo do contexto e situação. |
|
""") |
|
|
|
|
|
def update_display(*answers): |
|
"""Atualiza a visibilidade dos componentes baseado nas respostas.""" |
|
if all(a is not None for a in answers): |
|
return { |
|
result_box: gr.update(visible=True), |
|
analyze_btn: gr.update(interactive=False) |
|
} |
|
return { |
|
result_box: gr.update(visible=False), |
|
analyze_btn: gr.update(interactive=True) |
|
} |
|
|
|
|
|
for radio in radio_components: |
|
radio.change( |
|
lambda *args: update_progress(args), |
|
inputs=radio_components, |
|
outputs=[progress_text, progress_bar] |
|
) |
|
radio.change( |
|
update_display, |
|
inputs=radio_components, |
|
outputs=[result_box, analyze_btn] |
|
) |
|
|
|
analyze_btn.click( |
|
process_and_visualize, |
|
inputs=radio_components, |
|
outputs=[plot, perfil_dominante, perfil_secundario, output] |
|
) |
|
|
|
reset_btn.click( |
|
reset_interface, |
|
outputs=radio_components + [ |
|
result_box, |
|
analyze_btn, |
|
plot, |
|
perfil_dominante, |
|
perfil_secundario, |
|
output, |
|
progress_text, |
|
progress_bar |
|
] |
|
) |
|
|
|
|
|
def generate_pdf(report_text): |
|
|
|
return "report.pdf" |
|
|
|
download_btn.click( |
|
generate_pdf, |
|
inputs=[output], |
|
outputs=gr.File() |
|
) |
|
|
|
|
|
def share_results(): |
|
return gr.Info("Link de compartilhamento copiado!") |
|
|
|
share_btn.click(share_results) |
|
|
|
return iface |
|
|
|
if __name__ == "__main__": |
|
iface = create_interface() |
|
iface.launch(show_error=True) |