File size: 6,718 Bytes
b23184c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a89dc50
b23184c
5726cc9
 
b23184c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gradio as gr
import random

# Define your IPA data with additional attributes
ipa_data = {
    'p': {'Voicing': 'voiceless', 'Place': 'bilabial', 'Manner': 'stop','Oro-nasal': '(oral)','Centrality':'(central)'},
    'b': {'Voicing': 'voiced', 'Place': 'bilabial', 'Manner': 'stop','Oro-nasal': '(oral)','Centrality':'(central)'},
    't': {'Voicing': 'voiceless', 'Place': 'alveolar', 'Manner': 'stop','Oro-nasal': '(oral)','Centrality':'(central)'},
    'd': {'Voicing': 'voiced', 'Place': 'alveolar', 'Manner': 'stop','Oro-nasal': '(oral)','Centrality':'(central)'},
    'k': {'Voicing': 'voiceless', 'Place': 'velar', 'Manner': 'stop','Oro-nasal': '(oral)','Centrality':'(central)'},
    'g': {'Voicing': 'voiced', 'Place': 'velar', 'Manner': 'stop','Oro-nasal': '(oral)','Centrality':'(central)'},
    'f': {'Voicing': 'voiceless', 'Place': 'labio-dental', 'Manner': 'fricative','Oro-nasal': '(oral)','Centrality':'(central)'},
    'v': {'Voicing': 'voiced', 'Place': 'labio-dental', 'Manner': 'fricative','Oro-nasal': '(oral)','Centrality':'(central)'},
    'θ': {'Voicing': 'voiceless', 'Place': 'dental', 'Manner': 'fricative','Oro-nasal': '(oral)','Centrality':'(central)'},
    'ð': {'Voicing': 'voiced', 'Place': 'dental', 'Manner': 'fricative','Oro-nasal': '(oral)','Centrality':'(central)'},
    's': {'Voicing': 'voiceless', 'Place': 'alveolar', 'Manner': 'fricative','Oro-nasal': '(oral)','Centrality':'(central)'},
    'z': {'Voicing': 'voiced', 'Place': 'alveolar', 'Manner': 'fricative','Oro-nasal': '(oral)','Centrality':'(central)'},
    'ʃ': {'Voicing': 'voiceless', 'Place': 'palato-alveolar', 'Manner': 'fricative','Oro-nasal': '(oral)','Centrality':'(central)'},
    'ʒ': {'Voicing': 'voiced', 'Place': 'palato-alveolar', 'Manner': 'fricative','Oro-nasal': '(oral)','Centrality':'(central)'},
    'tʃ': {'Voicing': 'voiceless', 'Place': 'palato-alveolar', 'Manner': 'affricate','Oro-nasal': '(oral)','Centrality':'(central)'},
    'dʒ': {'Voicing': 'voiced', 'Place': 'palato-alveolar', 'Manner': 'affricate','Oro-nasal': '(oral)','Centrality':'(central)'},
    'h': {'Voicing': 'voiceless', 'Place': 'glottal', 'Manner': 'fricative','Oro-nasal': '(oral)','Centrality':'(central)'},
    'm': {'Voicing': 'voiced', 'Place': 'bilabial', 'Manner': 'stop','Oro-nasal': 'nasal','Centrality':'(not applicable)'},
    'n': {'Voicing': 'voiced', 'Place': 'alveolar', 'Manner': 'stop','Oro-nasal': 'nasal','Centrality':'(not applicable)'},
    'ŋ': {'Voicing': 'voiced', 'Place': 'velar', 'Manner': 'stop','Oro-nasal': 'nasal','Centrality':'(not applicable)'},
    'ɹ': {'Voicing': 'voiced', 'Place': 'alveolar', 'Manner': 'approximant','Oro-nasal': '(oral)','Centrality':'(central)'},
    'l': {'Voicing': 'voiced', 'Place': 'alveolar', 'Manner': 'approximant','Oro-nasal': '(oral)','Centrality':'lateral'},
    'j': {'Voicing': 'voiced', 'Place': 'palatal', 'Manner': 'approximant','Oro-nasal': '(oral)','Centrality':'(central)'},
    'w': {'Voicing': 'voiced', 'Place': 'labio-velar', 'Manner': 'approximant','Oro-nasal': '(oral)','Centrality':'(central)'}
}

def select_random_symbol():
    """ Select a random IPA symbol """
    symbol = random.choice(list(ipa_data.keys()))
    return symbol, ipa_data[symbol]

def validate_selections(ipa_symbol, user_voicing, user_place, user_manner, user_oronasal, user_centrality, correct_count, attempts):
    """ Check user's selections against the actual IPA symbol properties """
    correct_data = ipa_data[ipa_symbol]
    correct = (correct_data['Voicing'] == user_voicing and
               correct_data['Place'] == user_place and
               correct_data['Manner'] == user_manner and
               correct_data['Oro-nasal'] == user_oronasal and
               correct_data['Centrality'] == user_centrality)
    attempts += 1
    if correct:
        correct_count += 1
        return "Correct!", correct_count, attempts
    else:
        return "Incorrect! Correct values are: \n- Voicing: {}, \n- Place: {}, \n- Manner: {}, \n- Oro-nasal: {}, \n- Centrality: {}"\
            .format(correct_data['Voicing'], correct_data['Place'], correct_data['Manner'], correct_data['Oro-nasal'], correct_data['Centrality']), correct_count, attempts

def setup_interface():
    with gr.Blocks() as app:
        gr.Markdown("### IPA Practice App")

        new_symbol_button = gr.Button("Display a New Symbol")
        symbol_display = gr.Textbox(label="IPA Symbol", interactive=False)

        voicing_radio = gr.Radio(label="Voicing", choices=['voiceless', 'voiced'])
        place_radio = gr.Radio(label="Place", choices=['bilabial', 'labio-dental', 'labio-velar', 'dental', 'alveolar', 'palato-alveolar', 'palatal', 'velar', 'glottal'])
        centrality_radio = gr.Radio(label="Centrality", choices=['(central)', 'lateral', '(not applicable)'])
        oronasal_radio = gr.Radio(label="Oro-nasal", choices=['(oral)', 'nasal'])
        manner_radio = gr.Radio(label="Manner", choices=['stop', 'fricative', 'affricate', 'approximant'])

        submit_button = gr.Button("Submit")
        result_display = gr.Textbox(label="Result", interactive=False)
        correct_count = gr.State(0)
        attempts = gr.State(0)

        quit_button = gr.Button("See the total score")
        score_display = gr.Textbox(label="Score", interactive=False)

        def update_display():
            symbol, _ = select_random_symbol()
            symbol_display.value = symbol
            return symbol

        def submit_results(ipa_symbol, voicing, place, manner, oronasal, centrality, correct_count, attempts):
            result, updated_correct_count, updated_attempts = validate_selections(ipa_symbol, voicing, place, manner, oronasal, centrality, correct_count, attempts)
            return result, updated_correct_count, updated_attempts

        def quit_session(correct_count, attempts):
            final_score = f"Final Score: {correct_count}/{attempts}"
            return final_score

        new_symbol_button.click(
            fn=update_display,
            inputs=[],
            outputs=[symbol_display]
        )

        submit_button.click(
            fn=submit_results,
            inputs=[symbol_display, voicing_radio, place_radio, manner_radio, oronasal_radio, centrality_radio, correct_count, attempts],
            outputs=[result_display, correct_count, attempts]
        )

        quit_button.click(
            fn=quit_session,
            inputs=[correct_count, attempts],
            outputs=[score_display]
        )

        gr.Row(new_symbol_button, symbol_display)
        gr.Row(submit_button, quit_button)
        gr.Row(result_display, score_display)

    return app

app = setup_interface()
app.launch(debug=True)