Spaces:
Sleeping
Sleeping
| # Extended Big Five questionnaire with subtraits and their questions | |
| questionnaire = { | |
| "openness": { | |
| "imagination": [ | |
| "I enjoy daydreaming or thinking about abstract, fantastical ideas.", | |
| "When solving problems, I often come up with creative or unconventional solutions." | |
| ], | |
| "aesthetic_sensitivity": [ | |
| "I am deeply moved by art, music, or nature.", | |
| "I often seek beauty in my surroundings, such as enjoying sunsets or well-designed spaces." | |
| ], | |
| "intellectual_curiosity": [ | |
| "I enjoy learning about new topics just for the sake of knowledge.", | |
| "I am drawn to complex or theoretical ideas, like philosophy or quantum mechanics." | |
| ], | |
| "adventure_seeking": [ | |
| "I prefer trying new activities, like traveling to unfamiliar places or sampling exotic foods.", | |
| "I am comfortable taking risks to explore new opportunities." | |
| ], | |
| "emotional_openness": [ | |
| "I am willing to express my deeper feelings, even if they’re complicated or vulnerable.", | |
| "I often reflect on how my emotions shape my experiences." | |
| ], | |
| }, | |
| "conscientiousness": { | |
| "self_discipline": [ | |
| "I can persist with tasks even when they become boring or difficult.", | |
| "I often complete projects ahead of deadlines." | |
| ], | |
| "orderliness": [ | |
| "I like to keep my workspace, home, or schedule well-organized.", | |
| "I feel uncomfortable in cluttered or chaotic environments." | |
| ], | |
| "dutifulness": [ | |
| "I feel a strong obligation to fulfill my commitments, even when it’s inconvenient.", | |
| "I often feel guilty if I don’t meet others’ expectations." | |
| ], | |
| "achievement_striving": [ | |
| "I set ambitious goals for myself and work hard to achieve them.", | |
| "I enjoy feeling productive and accomplished after a busy day." | |
| ], | |
| "cautiousness": [ | |
| "I take time to weigh the pros and cons before making decisions.", | |
| "I am careful to avoid risks, even if they might lead to big rewards." | |
| ], | |
| }, | |
| "extraversion": { | |
| "sociability": [ | |
| "I feel energized after spending time with others.", | |
| "I enjoy large gatherings and meeting new people." | |
| ], | |
| "assertiveness": [ | |
| "I am confident in expressing my opinions, even in group settings.", | |
| "I often take the lead in organizing events or activities." | |
| ], | |
| "energy_level": [ | |
| "I have a lot of physical and mental energy throughout the day.", | |
| "I enjoy fast-paced environments with constant stimulation." | |
| ], | |
| "excitement_seeking": [ | |
| "I am drawn to thrilling activities, such as roller coasters, skydiving, or adventurous travel.", | |
| "I get bored quickly in routine or low-energy settings." | |
| ], | |
| "positive_emotions": [ | |
| "I often feel cheerful, enthusiastic, and optimistic.", | |
| "I am good at lifting the mood of people around me." | |
| ], | |
| }, | |
| "agreeableness": { | |
| "trust": [ | |
| "I believe most people have good intentions.", | |
| "I am comfortable relying on others to do their part in a group project." | |
| ], | |
| "altruism": [ | |
| "I enjoy helping others, even if it requires extra effort or sacrifice.", | |
| "I find satisfaction in volunteering or supporting a cause." | |
| ], | |
| "modesty": [ | |
| "I feel uncomfortable boasting about my achievements or skills.", | |
| "I avoid drawing attention to myself, even when I deserve recognition." | |
| ], | |
| "compassion": [ | |
| "I am quick to notice when others are upset or in need of comfort.", | |
| "I go out of my way to make others feel cared for and supported." | |
| ], | |
| "cooperation": [ | |
| "I am willing to compromise to avoid conflict.", | |
| "I prioritize group harmony over my own preferences in team settings." | |
| ], | |
| }, | |
| "neuroticism": { | |
| "anxiety": [ | |
| "I often worry about future events or possible problems.", | |
| "I feel tense or nervous in unfamiliar or high-pressure situations." | |
| ], | |
| "anger": [ | |
| "I feel frustrated or irritated easily.", | |
| "Small annoyances sometimes make me lose my temper." | |
| ], | |
| "depression": [ | |
| "I often feel sad, discouraged, or unmotivated, even when there’s no clear reason.", | |
| "I find it hard to enjoy activities that used to make me happy." | |
| ], | |
| "self_consciousness": [ | |
| "I am overly concerned about what others think of me.", | |
| "I often feel embarrassed or judged in social situations." | |
| ], | |
| "vulnerability": [ | |
| "I find it difficult to cope with stressful situations or major life changes.", | |
| "I feel overwhelmed when dealing with challenges, even if they’re manageable." | |
| ], | |
| }, | |
| } | |
| 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() |