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()