feature-quiz03 / app.py
MK-316's picture
Update app.py
134ed55 verified
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()