DISC.ai / app.py
DHEIVER's picture
Update app.py
f33f8df verified
raw
history blame
10.9 kB
import gradio as gr
import numpy as np
from transformers import pipeline
import pandas as pd
# CSS personalizado para melhorar a aparência
CUSTOM_CSS = """
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.header-box {
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
color: white;
padding: 2rem;
border-radius: 10px;
margin-bottom: 2rem;
text-align: center;
}
.question-box {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
padding: 1.5rem;
margin-bottom: 1rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.category-title {
color: #2a5298;
border-bottom: 2px solid #2a5298;
padding-bottom: 0.5rem;
margin-bottom: 1rem;
}
.results-container {
background: white;
border-radius: 10px;
padding: 2rem;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.profile-card {
background: #f8f9fa;
border-radius: 8px;
padding: 1.5rem;
margin-bottom: 1rem;
text-align: center;
}
.slider-container {
margin: 10px 0;
}
.button-primary {
background: #2a5298 !important;
color: white !important;
padding: 12px 24px !important;
font-weight: bold !important;
}
.results-title {
font-size: 1.5rem;
color: #2a5298;
text-align: center;
margin-bottom: 1rem;
}
"""
class DiscAnalyzer:
def __init__(self):
self.disc_profiles = {
'D': 'Dominância',
'I': 'Influência',
'S': 'Estabilidade',
'C': 'Conformidade'
}
self.profile_descriptions = {
'D': """
## Perfil Dominância (D)
### Características Principais:
- Direto e decisivo
- Focado em resultados
- Assume riscos calculados
- Forte senso de liderança
### Pontos Fortes:
- Tomada de decisão rápida
- Determinação
- Orientação para resultados
- Iniciativa
### Sugestões de Desenvolvimento:
- Desenvolver paciência
- Considerar opiniões alheias
- Praticar escuta ativa
""",
'I': """
## Perfil Influência (I)
### Características Principais:
- Comunicativo e entusiasta
- Sociável e otimista
- Persuasivo
- Foco em relacionamentos
### Pontos Fortes:
- Networking
- Comunicação
- Motivação de equipes
- Criatividade
### Sugestões de Desenvolvimento:
- Melhorar organização
- Focar em detalhes
- Gerenciar melhor o tempo
""",
'S': """
## Perfil Estabilidade (S)
### Características Principais:
- Paciente e consistente
- Bom ouvinte
- Leal e confiável
- Trabalho em equipe
### Pontos Fortes:
- Cooperação
- Confiabilidade
- Suporte a equipe
- Planejamento
### Sugestões de Desenvolvimento:
- Ser mais assertivo
- Adaptar-se a mudanças
- Expressar opiniões
""",
'C': """
## Perfil Conformidade (C)
### Características Principais:
- Analítico e preciso
- Foco em qualidade
- Organizado
- Atenção aos detalhes
### Pontos Fortes:
- Análise crítica
- Precisão
- Organização
- Controle de qualidade
### Sugestões de Desenvolvimento:
- Ser mais flexível
- Tomar decisões mais rápidas
- Desenvolver habilidades sociais
"""
}
# Inicializar modelo
self.generator = pipeline(
"text-generation",
model="facebook/opt-125m",
device="cpu"
)
def generate_llm_report(self, scores, perfil_principal):
"""
Gera relatório personalizado usando modelo do Hugging Face baseado nos scores DISC.
Combina a saída do modelo com descrições predefinidas para maior qualidade.
"""
base_description = self.profile_descriptions[perfil_principal]
prompt = f"""Analise o perfil DISC:
D:{scores['D']:.1f}% I:{scores['I']:.1f}% S:{scores['S']:.1f}% C:{scores['C']:.1f}%
Perfil Principal: {self.disc_profiles[perfil_principal]}
"""
try:
llm_output = self.generator(
prompt,
max_length=300,
num_return_sequences=1,
temperature=0.7,
top_p=0.9,
do_sample=True
)
ai_insights = llm_output[0]['generated_text'].replace(prompt, "").strip()
# Combinar descrição base com insights da IA
complete_report = f"""
{base_description}
### Análise Personalizada:
{ai_insights}
"""
return complete_report
except Exception as e:
return base_description
def avaliar_disc(self, *args):
"""
Avalia o perfil DISC baseado nas respostas do questionário.
"""
responses = [int(arg) for arg in args]
scores = {
'D': sum(responses[i] for i in [0, 4, 8, 12]) / 16 * 100,
'I': sum(responses[i] for i in [1, 5, 9, 13]) / 16 * 100,
'S': sum(responses[i] for i in [2, 6, 10, 14]) / 16 * 100,
'C': sum(responses[i] for i in [3, 7, 11, 15]) / 16 * 100
}
perfil_principal = max(scores, key=scores.get)
relatorio_llm = self.generate_llm_report(scores, perfil_principal)
# Criar DataFrame para o gráfico
df = pd.DataFrame({
"Dimensão": list(scores.keys()),
"Score": list(scores.values()),
"Descrição": [self.disc_profiles[k] for k in scores.keys()]
})
return (
f"### Seu perfil principal é: {self.disc_profiles[perfil_principal]} ({perfil_principal})",
relatorio_llm,
df,
gr.update(visible=True), # Mostrar seção de resultados
gr.update(visible=False) # Esconder questionário
)
def create_disc_interface():
"""
Cria a interface Gradio para o analisador DISC.
"""
analyzer = DiscAnalyzer()
with gr.Blocks(
title="Análise de Perfil DISC",
theme=gr.themes.Soft(
primary_hue="blue",
secondary_hue="purple",
),
css=CUSTOM_CSS
) as interface:
# Cabeçalho
with gr.Box(elem_classes=["header-box"]):
gr.Markdown(
"""
# 🎯 Análise de Perfil DISC Profissional
#### Descubra suas características comportamentais através de IA
"""
)
# Container do questionário
with gr.Box(elem_classes=["container"]) as questionnaire_container:
gr.Markdown(
"""
### 📝 Questionário DISC
Avalie cada afirmação de acordo com sua identificação:
- 1 = Discordo totalmente
- 2 = Discordo parcialmente
- 3 = Concordo parcialmente
- 4 = Concordo totalmente
"""
)
# Questões organizadas por categoria
questions = {
"Dominância (D)": [
"Sou direto e decisivo",
"Gosto de assumir riscos",
"Tomo iniciativa",
"Busco resultados"
],
"Influência (I)": [
"Sou sociável e entusiasta",
"Sou bom comunicador",
"Sou persuasivo",
"Sou motivador"
],
"Estabilidade (S)": [
"Sou paciente e cooperativo",
"Sou bom ouvinte",
"Trabalho bem em equipe",
"Sou confiável"
],
"Conformidade (C)": [
"Sou preciso e analítico",
"Sou organizado",
"Sou detalhista",
"Sou sistemático"
]
}
sliders = []
for categoria, perguntas in questions.items():
with gr.Box(elem_classes=["question-box"]):
gr.Markdown(f"#### {categoria}", elem_classes=["category-title"])
for i, pergunta in enumerate(perguntas, 1):
with gr.Box(elem_classes=["slider-container"]):
slider = gr.Slider(
minimum=1,
maximum=4,
value=2,
step=1,
label=pergunta,
interactive=True
)
sliders.append(slider)
analyze_btn = gr.Button(
"📊 Analisar Perfil",
variant="primary",
elem_classes=["button-primary"],
size="lg"
)
# Container dos resultados (inicialmente oculto)
with gr.Box(visible=False, elem_classes=["results-container"]) as results_container:
gr.Markdown("### 📊 Resultados da Análise", elem_classes=["results-title"])
with gr.Row():
with gr.Column(scale=1):
perfil_output = gr.Markdown(
label="Perfil Principal",
elem_classes=["profile-card"]
)
with gr.Row():
with gr.Column(scale=2):
plot_output = gr.BarPlot(
x="Dimensão",
y="Score",
title="Perfil DISC",
tooltip=["Descrição", "Score"],
height=400,
color="Dimensão"
)
with gr.Column(scale=3):
relatorio_output = gr.Markdown(
label="Análise Detalhada",
elem_classes=["report-content"]
)
# Botão para novo teste
new_test_btn = gr.Button(
"🔄 Fazer Novo Teste",
variant="secondary",
size="lg"
)
# Conexões dos botões
analyze_btn.click(
fn=analyzer.avaliar_disc,
inputs=sliders,
outputs=[
perfil_output,
relatorio_output,
plot_output,
results_container,
questionnaire_container
]
)
new_test_btn.click(
fn=lambda: [2] * 16 + [gr.update(visible=True), gr.update(visible=False)],
inputs=None,
outputs=sliders + [questionnaire_container, results_container]
)
return interface
if __name__ == "__main__":
interface = create_disc_interface()
interface.launch(
server_name="0.0.0.0",
server_port=7860,
share=True
)