Spaces:
Sleeping
Sleeping
import gradio as gr | |
import random | |
# IPA features dictionary with full feature names | |
ipa_features = { | |
'p': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '-', 'anterior': '+', 'continuant': '-', 'nasal': '-', 'strident': '-', 'lateral': '-', 'delayed release': '-', 'voice': '-'}, | |
'b': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '-', 'anterior': '+', 'continuant': '-', 'nasal': '-', 'strident': '-', 'lateral': '-', 'delayed release': '-', 'voice': '+'}, | |
't': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '+', 'anterior': '+', 'continuant': '-', 'nasal': '-', 'strident': '-', 'lateral': '-', 'delayed release': '-', 'voice': '-'}, | |
'd': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '+', 'anterior': '+', 'continuant': '-', 'nasal': '-', 'strident': '-', 'lateral': '-', 'delayed release': '-', 'voice': '+'}, | |
'k': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '-', 'anterior': '-', 'continuant': '-', 'nasal': '-', 'strident': '-', 'lateral': '-', 'delayed release': '-', 'voice': '-'}, | |
'g': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '-', 'anterior': '-', 'continuant': '-', 'nasal': '-', 'strident': '-', 'lateral': '-', 'delayed release': '-', 'voice': '+'}, | |
'tʃ': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '+', 'anterior': '-', 'continuant': '-', 'nasal': '-', 'strident': '+', 'lateral': '-', 'delayed release': '+', 'voice': '-'}, | |
'dʒ': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '+', 'anterior': '-', 'continuant': '-', 'nasal': '-', 'strident': '+', 'lateral': '-', 'delayed release': '+', 'voice': '+'}, | |
'f': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '-', 'anterior': '-', 'continuant': '+', 'nasal': '-', 'strident': '+', 'lateral': '-', 'delayed release': '-', 'voice': '-'}, | |
'v': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '-', 'anterior': '-', 'continuant': '+', 'nasal': '-', 'strident': '+', 'lateral': '-', 'delayed release': '-', 'voice': '+'}, | |
'θ': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '-', 'anterior': '+', 'continuant': '+', 'nasal': '-', 'strident': '-', 'lateral': '-', 'delayed release': '-', 'voice': '-'}, | |
'ð': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '-', 'anterior': '+', 'continuant': '+', 'nasal': '-', 'strident': '-', 'lateral': '-', 'delayed release': '-', 'voice': '+'}, | |
's': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '+', 'anterior': '+', 'continuant': '+', 'nasal': '-', 'strident': '+', 'lateral': '-', 'delayed release': '-', 'voice': '-'}, | |
'z': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '+', 'anterior': '+', 'continuant': '+', 'nasal': '-', 'strident': '+', 'lateral': '-', 'delayed release': '-', 'voice': '+'}, | |
'ʃ': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '+', 'anterior': '-', 'continuant': '+', 'nasal': '-', 'strident': '+', 'lateral': '-', 'delayed release': '-', 'voice': '-'}, | |
'ʒ': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '+', 'anterior': '-', 'continuant': '+', 'nasal': '-', 'strident': '+', 'lateral': '-', 'delayed release': '-', 'voice': '+'}, | |
'h': {'syllabic': '-', 'consonantal': '+', 'sonorant': '-', 'coronal': '-', 'anterior': '-', 'continuant': '+', 'nasal': '-', 'strident': '-', 'lateral': '-', 'delayed release': '-', 'voice': '-'}, | |
'm': {'syllabic': '-', 'consonantal': '+', 'sonorant': '+', 'coronal': '-', 'anterior': '+', 'continuant': '-', 'nasal': '+', 'strident': '-', 'lateral': '-', 'delayed release': '-', 'voice': '+'}, | |
'n': {'syllabic': '-', 'consonantal': '+', 'sonorant': '+', 'coronal': '+', 'anterior': '+', 'continuant': '-', 'nasal': '+', 'strident': '-', 'lateral': '-', 'delayed release': '-', 'voice': '+'}, | |
'ŋ': {'syllabic': '-', 'consonantal': '+', 'sonorant': '+', 'coronal': '-', 'anterior': '-', 'continuant': '-', 'nasal': '+', 'strident': '-', 'lateral': '-', 'delayed release': '-', 'voice': '+'}, | |
'l': {'syllabic': '-', 'consonantal': '+', 'sonorant': '+', 'coronal': '+', 'anterior': '+', 'continuant': '-', 'nasal': '-', 'strident': '-', 'lateral': '+', 'delayed release': '-', 'voice': '+'}, | |
'r': {'syllabic': '-', 'consonantal': '+', 'sonorant': '+', 'coronal': '+', 'anterior': '+', 'continuant': '+', 'nasal': '-', 'strident': '-', 'lateral': '-', 'delayed release': '-', 'voice': '+'}, | |
'j': {'syllabic': '-', 'consonantal': '-', 'sonorant': '+', 'coronal': '+', 'anterior': '-', 'continuant': '+', 'nasal': '-', 'strident': '-', 'lateral': '-', 'delayed release': '-', 'voice': '+'}, | |
'w': {'syllabic': '-', 'consonantal': '-', 'sonorant': '+', 'coronal': '-', 'anterior': '-', 'continuant': '+', 'nasal': '-', 'strident': '-', 'lateral': '-', 'delayed release': '-', 'voice': '+'} | |
} | |
# Variables to keep track of progress | |
score = 0 | |
attempts = 0 | |
completed_symbols = set() | |
current_symbol = None | |
remaining_features = [] | |
current_feature = None | |
# Function to start or reset the quiz | |
def start_quiz(): | |
global score, attempts, completed_symbols, current_symbol, remaining_features, current_feature | |
score = 0 | |
attempts = 0 | |
completed_symbols = set() | |
current_symbol, remaining_features = select_new_symbol() | |
current_feature = remaining_features.pop(0) | |
score_display = f"{score} out of {attempts}" | |
return current_symbol, f"[+{current_feature}]", f"[-{current_feature}]", score_display, "" | |
# Function to select a new symbol that hasn't been completed yet | |
def select_new_symbol(): | |
available_symbols = [symbol for symbol in ipa_features if symbol not in completed_symbols] | |
if not available_symbols: | |
return None, [] # No symbols left to practice | |
symbol = random.choice(available_symbols) | |
features = list(ipa_features[symbol].keys()) | |
return symbol, features | |
# Function to handle answer checking and feedback | |
def check_answer(user_choice): | |
global score, attempts, completed_symbols, current_symbol, remaining_features, current_feature | |
correct_value = ipa_features[current_symbol][current_feature] | |
attempts += 1 | |
if user_choice == correct_value: | |
score += 1 | |
feedback = "Correct!" | |
else: | |
feedback = "Incorrect!" | |
# Update the score display | |
score_display = f"{score} out of {attempts}" | |
# Check if there are more features for the current symbol | |
if remaining_features: | |
next_feature_text = "Click 'Next Feature' to continue." | |
else: | |
completed_symbols.add(current_symbol) | |
next_feature_text = "Click 'Next Symbol' to continue." if select_new_symbol()[0] else "You've completed all symbols!" | |
return feedback, score_display, next_feature_text | |
# Function to load the next feature or symbol | |
def load_next(): | |
global current_symbol, remaining_features, current_feature | |
if remaining_features: | |
current_feature = remaining_features.pop(0) | |
return current_symbol, f"[+{current_feature}]", f"[-{current_feature}]", "", "" | |
else: | |
current_symbol, remaining_features = select_new_symbol() | |
if current_symbol: | |
current_feature = remaining_features.pop(0) | |
return current_symbol, f"[+{current_feature}]", f"[-{current_feature}]", "", "" | |
else: | |
return "You've completed all symbols!", "", "", "", "" | |
# Gradio Interface | |
with gr.Blocks() as quiz_app: | |
# Start Button | |
start_button = gr.Button("Start/Reset Quiz") | |
# Display the symbol, feature buttons, and score in a row | |
with gr.Row(): | |
symbol_box = gr.Markdown(label="Symbol", value="", elem_classes="symbol-box") | |
positive_button = gr.Button() | |
negative_button = gr.Button() | |
score_box = gr.Markdown(label="Score", value="", elem_classes="score-box") | |
# Feedback Display | |
feedback_area = gr.Markdown() | |
# Next Button | |
next_button = gr.Button("Next Feature/Symbol") | |
# Set up button actions | |
start_button.click(start_quiz, outputs=[symbol_box, positive_button, negative_button, score_box, feedback_area]) | |
positive_button.click(lambda: check_answer('+'), outputs=[feedback_area, score_box, feedback_area]) | |
negative_button.click(lambda: check_answer('-'), outputs=[feedback_area, score_box, feedback_area]) | |
next_button.click(load_next, outputs=[symbol_box, positive_button, negative_button, score_box, feedback_area]) | |
# Custom CSS for styling | |
quiz_app.css = """ | |
.symbol-box { | |
background-color: orange; | |
color: white; | |
padding: 15px; | |
text-align: center; | |
font-size: 20px; | |
font-weight: bold; | |
border-radius: 5px; | |
} | |
.score-box { | |
border: 1px solid gray; | |
padding: 10px; | |
text-align: center; | |
font-size: 16px; | |
border-radius: 5px; | |
font-weight: bold; | |
} | |
""" | |
# Launch the app | |
quiz_app.launch() | |