Spaces:
Sleeping
Sleeping
# Extended Big Five questionnaire with subtraits and their questions | |
questionnaire = { | |
"openness": { | |
"imagination": [ | |
"Me gusta soñar despierto o pensar en ideas abstractas y fantásticas.", | |
"Al resolver problemas, a menudo se me ocurren soluciones creativas o poco convencionales." | |
], | |
"aesthetic_sensitivity": [ | |
"Me conmueve profundamente el arte, la música o la naturaleza.", | |
"A menudo busco la belleza en mi entorno, como disfrutar de las puestas de sol o de espacios bien diseñados." | |
], | |
"intellectual_curiosity": [ | |
"Me gusta aprender sobre nuevos temas solo por el placer de aprender.", | |
"Me atraen las ideas complejas o teóricas, como la filosofía o la mecánica cuántica." | |
], | |
"adventure_seeking": [ | |
"Prefiero probar nuevas actividades, como viajar a lugares desconocidos o probar comidas exóticas.", | |
"Me siento cómodo tomando riesgos para explorar nuevas oportunidades." | |
], | |
"emotional_openness": [ | |
"Estoy dispuesto a expresar mis sentimientos más profundos, incluso si son complicados o vulnerables.", | |
"A menudo reflexiono sobre cómo mis emociones dan forma a mis experiencias." | |
], | |
}, | |
"conscientiousness": { | |
"self_discipline": [ | |
"Puedo persistir con las tareas incluso cuando se vuelven aburridas o difíciles.", | |
"A menudo completo proyectos antes de las fechas límite." | |
], | |
"orderliness": [ | |
"Me gusta mantener mi espacio de trabajo, mi hogar o mi horario bien organizado.", | |
"Me siento incómodo en entornos desordenados o caóticos." | |
], | |
"dutifulness": [ | |
"Siento una fuerte obligación de cumplir con mis compromisos, incluso cuando es inconveniente.", | |
"A menudo me siento culpable si no cumplo con las expectativas de los demás." | |
], | |
"achievement_striving": [ | |
"Me fijo metas ambiciosas y trabajo duro para alcanzarlas.", | |
"Disfruto de sentirme productivo y realizado después de un día ajetreado." | |
], | |
"cautiousness": [ | |
"Me tomo el tiempo de sopesar los pros y los contras antes de tomar decisiones.", | |
"Tengo cuidado de evitar riesgos, incluso si pueden dar lugar a grandes recompensas." | |
], | |
}, | |
"extraversion": { | |
"sociability": [ | |
"Me siento con energía después de pasar tiempo con otras personas.", | |
"Disfruto de las reuniones grandes y de conocer gente nueva." | |
], | |
"assertiveness": [ | |
"Tengo confianza para expresar mis opiniones, incluso en entornos grupales.", | |
"A menudo tomo la iniciativa en la organización de eventos o actividades." | |
], | |
"energy_level": [ | |
"Tengo mucha energía física y mental durante todo el día.", | |
"Disfruto de los entornos de ritmo rápido con estimulación constante." | |
], | |
"excitement_seeking": [ | |
"Me atraen las actividades emocionantes, como las montañas rusas, el paracaidismo o los viajes de aventura.", | |
"Me aburro rápidamente en entornos rutinarios o de baja energía." | |
], | |
"positive_emotions": [ | |
"A menudo me siento alegre, entusiasta y optimista.", | |
"Soy bueno para levantar el ánimo de las personas que me rodean." | |
], | |
}, | |
"agreeableness": { | |
"trust": [ | |
"Creo que la mayoría de las personas tienen buenas intenciones.", | |
"Me siento cómodo confiando en que los demás hagan su parte en un proyecto grupal." | |
], | |
"altruism": [ | |
"Disfruto ayudando a los demás, incluso si requiere un esfuerzo o sacrificio adicional.", | |
"Encuentro satisfacción en el voluntariado o en apoyar una causa." | |
], | |
"modesty": [ | |
"Me siento incómodo alardeando de mis logros o habilidades.", | |
"Evito llamar la atención sobre mí mismo, incluso cuando merezco reconocimiento." | |
], | |
"compassion": [ | |
"Me doy cuenta rápidamente cuando los demás están molestos o necesitan consuelo.", | |
"Hago todo lo posible para que los demás se sientan cuidados y apoyados." | |
], | |
"cooperation": [ | |
"Estoy dispuesto a hacer concesiones para evitar conflictos.", | |
"Priorizo la armonía del grupo por encima de mis propias preferencias en entornos de equipo." | |
], | |
}, | |
"neuroticism": { | |
"anxiety": [ | |
"A menudo me preocupan los acontecimientos futuros o los posibles problemas.", | |
"Me siento tenso o nervioso en situaciones desconocidas o de mucha presión." | |
], | |
"anger": [ | |
"Me siento frustrado o irritado fácilmente.", | |
"A veces, las pequeñas molestias me hacen perder los estribos." | |
], | |
"depression": [ | |
"A menudo me siento triste, desanimado o desmotivado, incluso cuando no hay una razón clara.", | |
"Me resulta difícil disfrutar de actividades que antes me hacían feliz." | |
], | |
"self_consciousness": [ | |
"Me preocupa demasiado lo que los demás piensen de mí.", | |
"A menudo me siento avergonzado o juzgado en situaciones sociales." | |
], | |
"vulnerability": [ | |
"Me resulta difícil afrontar situaciones estresantes o grandes cambios en la vida.", | |
"Me siento abrumado cuando me enfrento a desafíos, incluso si son manejables." | |
], | |
}, | |
} | |
import json | |
import numpy as np | |
import gradio as gr | |
import plotly.graph_objects as go | |
from scipy.stats import percentileofscore | |
# Define TRAIT_COLORS | |
TRAIT_COLORS = { | |
"openness": "blue", | |
"conscientiousness": "green", | |
"extraversion": "orange", | |
"agreeableness": "purple", | |
"neuroticism": "red" | |
} | |
# Flatten questions dynamically | |
def build_questions(): | |
return [ | |
(trait, sub_trait, q) | |
for trait, sub_traits in questionnaire.items() | |
for sub_trait, qs in sub_traits.items() | |
for q in qs | |
] | |
questions = build_questions() | |
# Initialize state | |
state = {"current_question": 0, "responses": []} | |
# Compute scores with percentiles and z-scores | |
def compute_scores_and_percentiles(responses): | |
scores = {} | |
idx = 0 | |
for trait, sub_traits in questionnaire.items(): | |
for sub_trait, qs in sub_traits.items(): | |
mean_score = np.mean(responses[idx:idx + len(qs)]) | |
scores[f"{trait}_{sub_trait}"] = mean_score | |
idx += len(qs) | |
# Convert scores to arrays for percentile/z-score calculations | |
values = np.array(list(scores.values())) | |
z_scores = (values - np.mean(values)) / np.std(values) | |
percentiles = [percentileofscore(values, score) for score in values] | |
return scores, z_scores, percentiles | |
# Create chart with colors, percentiles, and z-scores | |
def create_chart(scores, z_scores, percentiles): | |
subtraits = [key.split("_")[1] for key in scores.keys()] | |
values = list(scores.values()) | |
trait_keys = [key.split("_")[0] for key in scores.keys()] | |
colors = [TRAIT_COLORS[trait] for trait in trait_keys] | |
# Create a bar chart | |
fig = go.Figure() | |
for i, (trait, color) in enumerate(TRAIT_COLORS.items()): | |
indices = [j for j, t in enumerate(trait_keys) if t == trait] | |
trait_subtraits = [subtraits[j] for j in indices] | |
trait_values = [values[j] for j in indices] | |
trait_z_scores = [z_scores[j] for j in indices] | |
trait_percentiles = [percentiles[j] for j in indices] | |
fig.add_trace( | |
go.Bar( | |
x=trait_subtraits, | |
y=trait_values, | |
name=trait.capitalize(), | |
marker_color=color, | |
text=[ | |
f"Score: {v:.2f}<br>Z-score: {z:.2f}<br>Percentile: {p:.1f}%" | |
for v, z, p in zip(trait_values, trait_z_scores, trait_percentiles) | |
], | |
hoverinfo="text" | |
) | |
) | |
fig.update_layout( | |
title="Trait Breakdown with Percentiles and Z-Scores", | |
xaxis_title="Subtraits", | |
yaxis_title="Average Score (1-10)", | |
plot_bgcolor="black", | |
paper_bgcolor="black", | |
font=dict(color="white"), | |
legend=dict( | |
title="Traits", | |
bgcolor="black", | |
bordercolor="gray", | |
borderwidth=1 | |
) | |
) | |
return fig | |
# Progress gauge | |
def plot_progress(current, total, question_text, question_num): | |
progress = (current / total) * 100 | |
fig = go.Figure(go.Indicator( | |
mode="gauge+number", | |
value=progress, | |
gauge={ | |
'axis': {'range': [0, 100]}, | |
'bar': {'color': 'purple'}, | |
'bgcolor': 'black', | |
'steps': [ | |
{'range': [0, 25], 'color': 'darkviolet'}, | |
{'range': [25, 50], 'color': 'violet'}, | |
{'range': [50, 75], 'color': 'magenta'}, | |
{'range': [75, 100], 'color': 'plum'} | |
], | |
}, | |
domain={'x': [0, 1], 'y': [0, 1]} | |
)) | |
fig.add_annotation( | |
x=0.5, y=-0.2, text=f"Question {question_num} / {total}", showarrow=False, | |
font=dict(size=14, color='white'), align="center" | |
) | |
fig.update_layout( | |
title={ | |
'text': f"<b>{question_text}</b>", | |
'font': {'size': 20, 'color': "white"}, | |
'x': 0.5, | |
'xanchor': 'center', | |
'y': 0.85, | |
}, | |
margin=dict(t=170), | |
plot_bgcolor='black', | |
paper_bgcolor='black', | |
font=dict(color='white'), | |
) | |
return fig | |
# Start test | |
def start_test(): | |
state["current_question"] = 0 | |
state["responses"] = [] | |
question = questions[state["current_question"]][2] | |
return ( | |
question, | |
plot_progress(0, len(questions), question, 1), | |
gr.update(visible=True), | |
gr.update(visible=False), | |
) | |
# Save Plotly chart as HTML | |
def save_plotly_html(chart, file_name="results_chart.html"): | |
chart.write_html(file_name) | |
print(f"Chart saved to {file_name}") | |
# Save test results as a JSON file | |
def save_results(responses, file_name="test_results.json"): | |
with open(file_name, "w") as f: | |
json.dump({"responses": responses}, f, indent=4) | |
print(f"Results saved to {file_name}") | |
# Modified next_question to save results and chart | |
def next_question(response): | |
state["responses"].append(int(response)) | |
state["current_question"] += 1 | |
if state["current_question"] >= len(questions): | |
scores, z_scores, percentiles = compute_scores_and_percentiles(state["responses"]) | |
result_chart = create_chart(scores, z_scores, percentiles) | |
# Save results and chart | |
save_results(state["responses"], "test_results.json") | |
save_plotly_html(result_chart, "results_chart.html") | |
return "Test Complete! Your results:", result_chart, gr.update(visible=False), gr.update(visible=True) | |
question = questions[state["current_question"]][2] | |
return ( | |
question, | |
plot_progress( | |
state["current_question"], len(questions), | |
question, state["current_question"] + 1 | |
), | |
gr.update(visible=True), | |
gr.update(visible=False), | |
) | |
def create_gradio_app(): | |
with gr.Blocks() as app: | |
gr.Markdown("## Extended Big Five Personality Test") | |
# UI Elements | |
start_button = gr.Button("Start Test") | |
question_text = gr.Textbox(label="Question", interactive=False, visible=True) | |
button_group = gr.Radio([str(i) for i in range(1, 11)], label="Your Response (1-10)", visible=True) | |
progress_gauge = gr.Plot() | |
result_output = gr.Textbox(label="Results", visible=True) | |
download_results = gr.File(label="Download Results JSON", visible=False) | |
download_chart = gr.File(label="Download Chart HTML", visible=True) | |
# Start Test Logic | |
start_button.click( | |
start_test, | |
outputs=[question_text, progress_gauge, button_group, result_output] | |
) | |
# Question Logic | |
def handle_next_question(response): | |
output = next_question(response) | |
# Check if the test is complete to enable downloads | |
if state["current_question"] >= len(questions): | |
return (*output, "test_results.json", "results_chart.html") | |
else: | |
return (*output, None, None) | |
# Respond to button changes and enable downloads after test completion | |
button_group.change( | |
handle_next_question, | |
inputs=button_group, | |
outputs=[ | |
question_text, progress_gauge, button_group, result_output, | |
download_results, download_chart | |
] | |
) | |
return app | |
# Launch the Gradio app | |
app = create_gradio_app() | |
# Launch the app locally | |
app.launch() |