File size: 6,619 Bytes
b26367e
 
 
90b9b8b
b26367e
90b9b8b
 
3dd0f7b
8e36fab
90b9b8b
8e36fab
 
 
 
 
b26367e
90b9b8b
 
b26367e
2c1c1dd
b26367e
 
2c1c1dd
 
8e36fab
 
 
fbc6a6b
2c1c1dd
b26367e
8e36fab
2c1c1dd
 
 
 
260bbed
2c1c1dd
260bbed
 
2c1c1dd
b26367e
8e36fab
 
 
 
 
 
 
 
 
 
fbc6a6b
 
 
2c1c1dd
b26367e
8e36fab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2c1c1dd
90b9b8b
2c1c1dd
 
8e36fab
2c1c1dd
8e36fab
2c1c1dd
90b9b8b
 
 
 
 
 
 
 
fbc6a6b
90b9b8b
 
 
 
 
 
 
 
 
 
 
 
 
 
8e36fab
fbc6a6b
 
 
 
 
 
 
 
90b9b8b
2c1c1dd
fbc6a6b
 
 
90b9b8b
2c1c1dd
 
 
fbc6a6b
90b9b8b
fbc6a6b
 
2c1c1dd
fbc6a6b
 
 
8e36fab
2c1c1dd
fbc6a6b
 
 
8e36fab
90b9b8b
2c1c1dd
 
 
fbc6a6b
90b9b8b
fbc6a6b
 
90b9b8b
2c1c1dd
8e36fab
90b9b8b
 
 
 
 
 
2c1c1dd
 
 
8e36fab
2c1c1dd
 
 
 
8e36fab
 
 
 
b26367e
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import pandas as pd
import random
import gradio as gr
import asyncio

# Load the CSV data asynchronously
async def load_data():
    url = "IPA.csv"
    try:
        data = await asyncio.to_thread(pd.read_csv, url, encoding='utf-8')
        if 'IPA' not in data.columns:
            raise ValueError("The required 'IPA' column is missing in the data.")
        return data
    except Exception as e:
        raise ValueError(f"Error loading data: {e}")

# Initial empty dataframe
df = pd.DataFrame()

# Properties to ask about for each IPA symbol
properties = ['Voicing', 'Place', 'Centrality', 'Oro-nasal', 'Manner']

# Generate a new question
def generate_question(used_ipa_symbols):
    if df.empty or 'IPA' not in df.columns:
        raise ValueError("IPA data is not loaded properly or missing.")

    # Loop until we get a valid IPA symbol that hasn't been used yet
    while True:
        current_ipa = df.sample(1).iloc[0]
        if not pd.isnull(current_ipa['IPA']) and current_ipa['IPA'] not in used_ipa_symbols:
            available_properties = [prop for prop in properties if not pd.isnull(current_ipa[prop])]
            if available_properties:
                break

    used_ipa_symbols.append(current_ipa['IPA'])
    property_name = random.choice(available_properties)
    question = f"IPA Symbol: {current_ipa['IPA']}\nWhat is the {property_name.lower()} of this IPA symbol?"
    answer = current_ipa[property_name].lower()
    return question, answer, used_ipa_symbols

# Check the answer and update the score and trials
def quiz_function(user_answer, correct_answer, score, trials):
    if user_answer.lower() == correct_answer:
        score += 1
        result = f"Correct! The answer was '{correct_answer}'."
    else:
        result = f"Wrong! The correct answer was '{correct_answer}'."
    trials += 1
    return result, score, trials

# Initialize a dictionary to store session-specific data
user_sessions = {}

# Define the Gradio interface
def gradio_interface():
    with gr.Blocks(css="""
        #start_button, #submit_button, #quit_button {
            width: 200px;
            height: 50px;
            font-size: 16px;
            color: black;
            background-color: #f0f0f0;
            text-align: center;
            padding: 0;
            display: inline-block;
            font-family: Arial, sans-serif;
            vertical-align: middle;
            line-height: 50px;
        }
    """) as app:
        # Define the components with `elem_id` to apply custom CSS
        name_input = gr.Textbox(label="Enter your name", placeholder="Your name")
        start_button = gr.Button("Start Quiz", elem_id="start_button")
        question_label = gr.Textbox(label="Question", interactive=False)
        answer_input = gr.Textbox(label="Your Answer", placeholder="Type your answer here")
        submit_button = gr.Button("Submit", elem_id="submit_button")
        output_label = gr.Textbox(label="Result", interactive=False)
        quit_button = gr.Button("Quit", elem_id="quit_button")

        score_state = gr.State(0)
        trials_state = gr.State(0)
        used_ipa_symbols_state = gr.State([])
        current_answer_state = gr.State("")

        # Start quiz function with async loading
        async def start_quiz(name):
            global df
            if not name:
                yield gr.update(), gr.update(value="Please enter your name to start the quiz."), "", "", gr.update()

            if df.empty:
                # Display loading message
                yield gr.update(), gr.update(value="Loading data... Please wait."), "", "", gr.update()

                # Asynchronously load data
                try:
                    df = await load_data()
                    yield gr.update(), gr.update(value="Data loaded. Starting the quiz."), "", "", gr.update()
                except Exception as e:
                    yield gr.update(), gr.update(value=f"Failed to load data: {e}"), "", "", gr.update()
                    return  # Exit the function if data fails to load

            # Initialize user session for the current user
            if name not in user_sessions:
                user_sessions[name] = {
                    "score": 0,
                    "trials": 0,
                    "used_ipa_symbols": [],
                    "current_answer": ""
                }
            session = user_sessions[name]

            # Generate first question
            question, answer, used_ipa_symbols = generate_question(session["used_ipa_symbols"])
            session["current_answer"] = answer
            session["used_ipa_symbols"] = used_ipa_symbols
            yield gr.update(value=question), "", "", gr.update(value="Submit"), gr.update()

        # Submit answer function
        def submit_answer(name, user_answer):
            if name not in user_sessions:
                return gr.update(), gr.update(value="Please start the quiz first."), "", "", gr.update()

            session = user_sessions[name]
            # Check the answer
            result, score, trials = quiz_function(user_answer, session["current_answer"], session["score"], session["trials"])
            session["score"] = score
            session["trials"] = trials

            # Generate next question
            question, answer, used_ipa_symbols = generate_question(session["used_ipa_symbols"])
            session["current_answer"] = answer
            session["used_ipa_symbols"] = used_ipa_symbols

            return gr.update(value=question), "", gr.update(value=result), gr.update(value="Submit"), gr.update()

        # Quit quiz function
        def quit_quiz(name):
            if name not in user_sessions:
                return gr.update(value="You haven't started the quiz yet."), gr.update()

            session = user_sessions.pop(name)
            return gr.update(value=f"Quiz ended. Well done, {name}! Your total score: {session['score']}/{session['trials']} points."), gr.update()

        # Bind functions to buttons
        start_button.click(
            fn=start_quiz,
            inputs=[name_input],
            outputs=[question_label, answer_input, output_label, submit_button, quit_button]
        )

        submit_button.click(
            fn=submit_answer,
            inputs=[name_input, answer_input],
            outputs=[question_label, answer_input, output_label, submit_button, quit_button]
        )

        quit_button.click(
            fn=quit_quiz,
            inputs=[name_input],
            outputs=[output_label, quit_button]
        )

    return app

app = gradio_interface()
app.launch()