Spaces:
Sleeping
Sleeping
| '''import gradio as gr | |
| import random | |
| # 📚 Language learning data | |
| WORDS = { | |
| "Spanish": { | |
| "hello": "hola", | |
| "thank you": "gracias", | |
| "please": "por favor", | |
| "goodbye": "adios", | |
| "cat": "gato" | |
| }, | |
| "French": { | |
| "hello": "bonjour", | |
| "thank you": "merci", | |
| "please": "s'il vous plaît", | |
| "goodbye": "au revoir", | |
| "cat": "chat" | |
| }, | |
| "German": { | |
| "hello": "hallo", | |
| "thank you": "danke", | |
| "please": "bitte", | |
| "goodbye": "auf wiedersehen", | |
| "cat": "katze" | |
| }, | |
| "Hindi": { | |
| "hello": "namaste", | |
| "thank you": "dhanyavaad", | |
| "please": "kripya", | |
| "goodbye": "alvida", | |
| "cat": "billi" | |
| }, | |
| "Japanese": { | |
| "hello": "konnichiwa", | |
| "thank you": "arigatou", | |
| "please": "onegai shimasu", | |
| "goodbye": "sayonara", | |
| "cat": "neko" | |
| } | |
| } | |
| # 🌟 Flashcard display | |
| def show_flashcards(language): | |
| if language not in WORDS: | |
| return f"No flashcards available for {language}." | |
| result = "" | |
| for word, translation in WORDS[language].items(): | |
| result += f"{word.capitalize()} → {translation.capitalize()}\n" | |
| return result.strip() | |
| # ❓ Quiz generator | |
| def generate_quiz(language): | |
| if language not in WORDS: | |
| return f"No quiz available for {language}." | |
| quiz_data = [] | |
| items = list(WORDS[language].items()) | |
| for word, correct in random.sample(items, min(4, len(items))): | |
| options = [correct] + random.sample([val for _, val in items if val != correct], k=3) | |
| random.shuffle(options) | |
| quiz_data.append((word, correct, options)) | |
| return quiz_data | |
| # ✅ Quiz logic | |
| def quiz_interface(language): | |
| quiz = generate_quiz(language) | |
| interface = [] | |
| for i, (word, correct, options) in enumerate(quiz): | |
| interface.append(gr.Textbox(label=f"Translate: {word}")) | |
| interface.append(gr.Radio(choices=options, label=f"Options for '{word}'", type="value", interactive=True)) | |
| return interface | |
| # 🎯 Main interface | |
| def launch_app(): | |
| with gr.Blocks(theme=gr.themes.Soft()) as app: | |
| gr.Markdown("# 🌍 Language Learning App with Flashcards & Quizzes") | |
| gr.Markdown("Learn basic vocabulary in 5 languages: Spanish, French, German, Hindi, and Japanese.") | |
| with gr.Tabs(): | |
| with gr.TabItem("🧠 Flashcards"): | |
| lang = gr.Dropdown(choices=list(WORDS.keys()), label="Select a Language") | |
| output = gr.Textbox(label="Flashcards", lines=10) | |
| lang.change(fn=show_flashcards, inputs=lang, outputs=output) | |
| with gr.TabItem("🎯 Quiz"): | |
| quiz_lang = gr.Dropdown(choices=list(WORDS.keys()), label="Select Language for Quiz") | |
| quiz_output = gr.Textbox(label="Quiz Questions will appear below.") | |
| def run_quiz(language): | |
| quiz = generate_quiz(language) | |
| if isinstance(quiz, str): | |
| return quiz | |
| formatted = "" | |
| for word, answer, options in quiz: | |
| formatted += f"Translate '{word}': {', '.join(options)} (Answer: {answer})\n" | |
| return formatted.strip() | |
| quiz_lang.change(fn=run_quiz, inputs=quiz_lang, outputs=quiz_output) | |
| return app | |
| if __name__ == "__main__": | |
| launch_app().launch() | |
| import gradio as gr | |
| import random | |
| # 🌍 Vocabulary Dataset (expandable or from API later) | |
| vocab_data = { | |
| "Spanish": { | |
| "Hello": "Hola", | |
| "Thank you": "Gracias", | |
| "Please": "Por favor", | |
| "Yes": "Sí", | |
| "No": "No" | |
| }, | |
| "French": { | |
| "Hello": "Bonjour", | |
| "Thank you": "Merci", | |
| "Please": "S'il vous plaît", | |
| "Yes": "Oui", | |
| "No": "Non" | |
| }, | |
| "German": { | |
| "Hello": "Hallo", | |
| "Thank you": "Danke", | |
| "Please": "Bitte", | |
| "Yes": "Ja", | |
| "No": "Nein" | |
| }, | |
| "Hindi": { | |
| "Hello": "नमस्ते", | |
| "Thank you": "धन्यवाद", | |
| "Please": "कृपया", | |
| "Yes": "हाँ", | |
| "No": "नहीं" | |
| }, | |
| "Japanese": { | |
| "Hello": "こんにちは", | |
| "Thank you": "ありがとう", | |
| "Please": "お願いします", | |
| "Yes": "はい", | |
| "No": "いいえ" | |
| } | |
| } | |
| # 🔁 Flashcards UI | |
| def flashcard_interface(language): | |
| eng, trans = random.choice(list(vocab_data[language].items())) | |
| return f"{eng} ➜ {trans}" | |
| # ❓ Quiz UI | |
| def quiz_interface(language): | |
| eng, correct = random.choice(list(vocab_data[language].items())) | |
| options = list(set([correct] + random.sample(list(vocab_data[language].values()), 3))) | |
| random.shuffle(options) | |
| return eng, options, correct | |
| def evaluate_quiz(user_choice, correct): | |
| if user_choice == correct: | |
| return "✅ Correct!" | |
| return f"❌ Incorrect! Correct answer was: {correct}" | |
| # 🎨 UI Layout | |
| def build_ui(): | |
| with gr.Blocks(theme="soft") as app: | |
| gr.Markdown("# 🧠 Language Learning App\nLearn basic vocabulary with flashcards and quizzes.") | |
| with gr.Tabs(): | |
| with gr.TabItem("📇 Flashcards"): | |
| lang_fc = gr.Dropdown(choices=list(vocab_data.keys()), label="Select Language", value="Spanish") | |
| card_output = gr.Textbox(label="Flashcard", interactive=False) | |
| card_btn = gr.Button("🔁 Show Me a Card") | |
| card_btn.click(flashcard_interface, inputs=lang_fc, outputs=card_output) | |
| with gr.TabItem("❓ Quiz"): | |
| lang_quiz = gr.Dropdown(choices=list(vocab_data.keys()), label="Select Language", value="French") | |
| quiz_word = gr.Textbox(label="Translate this word", interactive=False) | |
| quiz_opts = gr.Radio(choices=[], label="Choose the correct translation") | |
| quiz_ans = gr.Textbox(label="Result", interactive=False) | |
| quiz_btn = gr.Button("🎯 Submit Answer") | |
| refresh_btn = gr.Button("🔁 New Question") | |
| def setup_quiz(language): | |
| word, opts, correct = quiz_interface(language) | |
| return word, gr.update(choices=opts, value=None), correct | |
| quiz_state = gr.State(value="") | |
| refresh_btn.click(setup_quiz, inputs=lang_quiz, outputs=[quiz_word, quiz_opts, quiz_state]) | |
| quiz_btn.click(evaluate_quiz, inputs=[quiz_opts, quiz_state], outputs=quiz_ans) | |
| return app | |
| if __name__ == "__main__": | |
| build_ui().launch() | |
| import gradio as gr | |
| import random | |
| from gtts import gTTS | |
| import tempfile | |
| import os | |
| # 🌍 Vocabulary Dataset (expandable or from API later) | |
| vocab_data = { | |
| "Spanish": { | |
| "Hello": ("Hola", "https://upload.wikimedia.org/wikipedia/commons/8/89/Hola.ogg"), | |
| "Thank you": ("Gracias", "https://upload.wikimedia.org/wikipedia/commons/5/5e/Gracias.ogg"), | |
| "Please": ("Por favor", "https://upload.wikimedia.org/wikipedia/commons/3/3f/Por_favor.ogg"), | |
| "Yes": ("Sí", "https://upload.wikimedia.org/wikipedia/commons/b/bb/Spanish_yes.ogg"), | |
| "No": ("No", "https://upload.wikimedia.org/wikipedia/commons/3/3d/Spanish_no.ogg") | |
| }, | |
| "French": { | |
| "Hello": ("Bonjour", "https://upload.wikimedia.org/wikipedia/commons/0/0f/Bonjour.ogg"), | |
| "Thank you": ("Merci", "https://upload.wikimedia.org/wikipedia/commons/d/d2/Merci.ogg"), | |
| "Please": ("S'il vous plaît", "https://upload.wikimedia.org/wikipedia/commons/0/0c/S'il_vous_plait.ogg"), | |
| "Yes": ("Oui", "https://upload.wikimedia.org/wikipedia/commons/6/6f/Oui.ogg"), | |
| "No": ("Non", "https://upload.wikimedia.org/wikipedia/commons/e/e3/Non.ogg") | |
| }, | |
| "German": { | |
| "Hello": ("Hallo", "https://upload.wikimedia.org/wikipedia/commons/1/1d/Hallo.ogg"), | |
| "Thank you": ("Danke", "https://upload.wikimedia.org/wikipedia/commons/5/5f/Danke.ogg"), | |
| "Please": ("Bitte", "https://upload.wikimedia.org/wikipedia/commons/8/8a/Bitte.ogg"), | |
| "Yes": ("Ja", "https://upload.wikimedia.org/wikipedia/commons/2/2e/Ja.ogg"), | |
| "No": ("Nein", "https://upload.wikimedia.org/wikipedia/commons/9/92/Nein.ogg") | |
| }, | |
| "Hindi": { | |
| "Hello": ("नमस्ते", None), | |
| "Thank you": ("धन्यवाद", None), | |
| "Please": ("कृपया", None), | |
| "Yes": ("हाँ", None), | |
| "No": ("नहीं", None) | |
| }, | |
| "Japanese": { | |
| "Hello": ("こんにちは", None), | |
| "Thank you": ("ありがとう", None), | |
| "Please": ("お願いします", None), | |
| "Yes": ("はい", None), | |
| "No": ("いいえ", None) | |
| } | |
| } | |
| # Flashcard Logic | |
| def flashcard_interface(language): | |
| eng, (trans, audio_url) = random.choice(list(vocab_data[language].items())) | |
| return f"{eng} ➜ {trans}", audio_url or "" | |
| # Quiz Logic | |
| def quiz_interface(language): | |
| eng, (correct, _) = random.choice(list(vocab_data[language].items())) | |
| options = list(set([correct] + [val[0] for _, val in random.sample(list(vocab_data[language].items()), 3)])) | |
| random.shuffle(options) | |
| return eng, options, correct | |
| def evaluate_quiz(user_choice, correct): | |
| if user_choice == correct: | |
| return "✅ Correct!" | |
| return f"❌ Incorrect! Correct answer was: {correct}" | |
| # Build UI | |
| def build_ui(): | |
| with gr.Blocks(theme="soft") as app: | |
| gr.Markdown(""" | |
| # 🧠 Language Learning App | |
| Learn basic vocabulary with flashcards and quizzes. | |
| """) | |
| with gr.Tabs(): | |
| with gr.TabItem("📇 Flashcards"): | |
| lang_fc = gr.Dropdown(choices=list(vocab_data.keys()), label="Select Language", value="Spanish") | |
| card_output = gr.Textbox(label="Flashcard", interactive=False) | |
| audio_output = gr.Audio(label="Pronunciation (if available)", interactive=False) | |
| card_btn = gr.Button("🔁 Show Me a Card") | |
| def show_card(language): | |
| text, audio_url = flashcard_interface(language) | |
| return text, audio_url | |
| card_btn.click(show_card, inputs=lang_fc, outputs=[card_output, audio_output]) | |
| with gr.TabItem("❓ Quiz"): | |
| lang_quiz = gr.Dropdown(choices=list(vocab_data.keys()), label="Select Language", value="French") | |
| quiz_word = gr.Textbox(label="Translate this word", interactive=False) | |
| quiz_opts = gr.Radio(choices=[], label="Choose the correct translation") | |
| quiz_ans = gr.Textbox(label="Result", interactive=False) | |
| quiz_btn = gr.Button("🎯 Submit Answer") | |
| refresh_btn = gr.Button("🔁 New Question") | |
| score_tracker = gr.Number(label="Your Score", value=0, interactive=False) | |
| def setup_quiz(language): | |
| word, opts, correct = quiz_interface(language) | |
| return word, gr.update(choices=opts, value=None), correct | |
| quiz_state = gr.State(value="") | |
| score_state = gr.State(value=0) | |
| refresh_btn.click(setup_quiz, inputs=lang_quiz, outputs=[quiz_word, quiz_opts, quiz_state]) | |
| def submit_answer(user_choice, correct, score): | |
| feedback = evaluate_quiz(user_choice, correct) | |
| updated_score = score + 1 if user_choice == correct else score | |
| return feedback, updated_score | |
| quiz_btn.click(submit_answer, inputs=[quiz_opts, quiz_state, score_state], outputs=[quiz_ans, score_tracker]) | |
| return app | |
| if __name__ == "__main__": | |
| build_ui().launch() | |
| '' | |
| import gradio as gr | |
| import random | |
| from gtts import gTTS | |
| import tempfile | |
| import os | |
| import urllib.request | |
| # ✅ Extended Vocabulary with Categories | |
| vocab_data = { | |
| "Spanish": { | |
| "Greetings": { | |
| "Hello": ("Hola", "https://upload.wikimedia.org/wikipedia/commons/8/89/Hola.ogg"), | |
| "Goodbye": ("Adiós", None), | |
| "Thank you": ("Gracias", None), | |
| "Please": ("Por favor", None), | |
| "Yes": ("Sí", None), | |
| "No": ("No",None) | |
| }, | |
| "Food": { | |
| "Bread": ("Pan", None), | |
| "Water": ("Agua", None) | |
| } | |
| }, | |
| "French": { | |
| "Greetings": { | |
| "Hello": ("Bonjour", "https://upload.wikimedia.org/wikipedia/commons/0/0f/Bonjour.ogg"), | |
| "Goodbye": ("Au revoir", None), | |
| "Thank you": ("Merci", None), | |
| "Please": ("S'il vous plaît", None), | |
| "Yes": ("Oui",None), | |
| "No": ("Non", None) | |
| }, | |
| "Food": { | |
| "Bread": ("Pain", None), | |
| "Water": ("Eau", None) | |
| } | |
| }, | |
| "German": { | |
| "Greetings": { | |
| "Hello": ("Hallo", "https://upload.wikimedia.org/wikipedia/commons/1/1d/Hallo.ogg"), | |
| "Goodbye": ("Auf Wiedersehen", None), | |
| "Thank you": ("Danke",None), | |
| "Please": ("Bitte", None), | |
| "Yes": ("Ja", None), | |
| "No": ("Nein", None) | |
| }, | |
| "Food": { | |
| "Bread": ("Brot", None), | |
| "Water": ("Wasser", None) | |
| } | |
| }, | |
| "Hindi": { | |
| "Greetings": { | |
| "Hello": ("नमस्ते", None), | |
| "Goodbye": ("अलविदा", None), | |
| "Thank you": ("धन्यवाद", None), | |
| "Please": ("कृपया", None), | |
| "Yes": ("हाँ", None), | |
| "No": ("नहीं", None) | |
| }, | |
| "Food": { | |
| "Bread": ("रोटी", None), | |
| "Water": ("पानी", None) | |
| } | |
| }, | |
| "Japanese": { | |
| "Greetings": { | |
| "Hello": ("こんにちは", None), | |
| "Goodbye": ("さようなら", None), | |
| "Thank you": ("ありがとう", None), | |
| "Please": ("お願いします", None), | |
| "Yes": ("はい", None), | |
| "No": ("いいえ", None) | |
| }, | |
| "Food": { | |
| "Bread": ("パン", None), | |
| "Water": ("水", None) | |
| } | |
| } | |
| } | |
| # Flashcard Logic | |
| def flashcard_interface(language, category): | |
| items = vocab_data[language][category] | |
| eng, (trans, audio_url) = random.choice(list(items.items())) | |
| return f"{eng} ➜ {trans}", audio_url or "" | |
| # Quiz Logic | |
| def quiz_interface(language, category): | |
| items = vocab_data[language][category] | |
| eng, (correct, _) = random.choice(list(items.items())) | |
| options = list(set([correct] + [val[0] for _, val in random.sample(list(items.items()), min(3, len(items)))])) | |
| random.shuffle(options) | |
| return eng, options, correct | |
| def evaluate_quiz(user_choice, correct): | |
| if user_choice == correct: | |
| return "✅ Correct!" | |
| return f"❌ Incorrect! Correct answer was: {correct}" | |
| # Build UI | |
| def build_ui(): | |
| with gr.Blocks(theme="soft") as app: | |
| gr.Markdown(""" | |
| # 🧠 Language Learning App | |
| Learn vocabulary with flashcards and quizzes categorized by topic. | |
| """) | |
| with gr.Tabs(): | |
| with gr.TabItem("📇 Flashcards"): | |
| lang_fc = gr.Dropdown(choices=list(vocab_data.keys()), label="Select Language", value="Spanish") | |
| category_fc = gr.Dropdown(choices=["Greetings", "Food"], label="Select Category", value="Greetings") | |
| card_output = gr.Textbox(label="Flashcard", interactive=False) | |
| audio_output = gr.Audio(label="Pronunciation (if available)", interactive=False) | |
| card_btn = gr.Button("🔁 Show Me a Card") | |
| def show_card(language, category): | |
| text, audio_url = flashcard_interface(language, category) | |
| if audio_url: | |
| tmp_audio = tempfile.NamedTemporaryFile(delete=False, suffix=".ogg") | |
| urllib.request.urlretrieve(audio_url, tmp_audio.name) | |
| return text, tmp_audio.name | |
| return text, None | |
| card_btn.click(show_card, inputs=[lang_fc, category_fc], outputs=[card_output, audio_output]) | |
| with gr.TabItem("❓ Quiz"): | |
| lang_quiz = gr.Dropdown(choices=list(vocab_data.keys()), label="Select Language", value="French") | |
| category_quiz = gr.Dropdown(choices=["Greetings", "Food"], label="Select Category", value="Greetings") | |
| quiz_word = gr.Textbox(label="Translate this word", interactive=False) | |
| quiz_opts = gr.Radio(choices=[], label="Choose the correct translation") | |
| quiz_ans = gr.Textbox(label="Result", interactive=False) | |
| quiz_btn = gr.Button("🎯 Submit Answer") | |
| refresh_btn = gr.Button("🔁 New Question") | |
| score_tracker = gr.Number(label="Your Score", value=0, interactive=False) | |
| def setup_quiz(language, category): | |
| word, opts, correct = quiz_interface(language, category) | |
| return word, gr.update(choices=opts, value=None), correct | |
| quiz_state = gr.State(value="") | |
| score_state = gr.State(value=0) | |
| refresh_btn.click(setup_quiz, inputs=[lang_quiz, category_quiz], outputs=[quiz_word, quiz_opts, quiz_state]) | |
| def submit_answer(user_choice, correct, score): | |
| feedback = evaluate_quiz(user_choice, correct) | |
| updated_score = score + 1 if user_choice == correct else score | |
| return feedback, updated_score, updated_score | |
| quiz_btn.click(submit_answer, inputs=[quiz_opts, quiz_state, score_state], outputs=[quiz_ans, score_tracker, score_state]) | |
| return app | |
| if __name__ == "__main__": | |
| build_ui().launch() | |
| '' | |
| import gradio as gr | |
| import random | |
| from gtts import gTTS | |
| import tempfile | |
| import os | |
| import urllib.request | |
| from collections import defaultdict | |
| # ML-like feedback tracker (basic stats) | |
| user_stats = defaultdict(lambda: {"attempts": 0, "correct": 0}) | |
| # ✅ Extended Vocabulary with Categories | |
| vocab_data = { | |
| "Spanish": { | |
| "Greetings": { | |
| "Hello": ("Hola", "https://upload.wikimedia.org/wikipedia/commons/8/89/Hola.ogg"), | |
| "Goodbye": ("Adiós", None) | |
| }, | |
| "Food": { | |
| "Bread": ("Pan", None), | |
| "Water": ("Agua", None) | |
| } | |
| }, | |
| "French": { | |
| "Greetings": { | |
| "Hello": ("Bonjour", "https://upload.wikimedia.org/wikipedia/commons/0/0f/Bonjour.ogg"), | |
| "Goodbye": ("Au revoir", None) | |
| }, | |
| "Food": { | |
| "Bread": ("Pain", None), | |
| "Water": ("Eau", None) | |
| } | |
| }, | |
| "German": { | |
| "Greetings": { | |
| "Hello": ("Hallo", "https://upload.wikimedia.org/wikipedia/commons/1/1d/Hallo.ogg"), | |
| "Goodbye": ("Auf Wiedersehen", None) | |
| }, | |
| "Food": { | |
| "Bread": ("Brot", None), | |
| "Water": ("Wasser", None) | |
| } | |
| }, | |
| "Hindi": { | |
| "Greetings": { | |
| "Hello": ("नमस्ते", None), | |
| "Goodbye": ("अलविदा", None) | |
| }, | |
| "Food": { | |
| "Bread": ("रोटी", None), | |
| "Water": ("पानी", None) | |
| } | |
| }, | |
| "Japanese": { | |
| "Greetings": { | |
| "Hello": ("こんにちは", None), | |
| "Goodbye": ("さようなら", None) | |
| }, | |
| "Food": { | |
| "Bread": ("パン", None), | |
| "Water": ("水", None) | |
| } | |
| } | |
| } | |
| # Flashcard Logic | |
| def flashcard_interface(language, category): | |
| items = vocab_data[language][category] | |
| eng, (trans, audio_url) = random.choice(list(items.items())) | |
| return f"{eng} ➜ {trans}", audio_url or "" | |
| # Quiz Logic | |
| def quiz_interface(language, category): | |
| items = vocab_data[language][category] | |
| eng, (correct, _) = random.choice(list(items.items())) | |
| distractors = [val[0] for _, val in random.sample(list(items.items()), min(3, len(items)))] | |
| if correct not in distractors: | |
| distractors = distractors[:-1] + [correct] | |
| options = list(set(distractors)) | |
| random.shuffle(options) | |
| return eng, options, correct | |
| def evaluate_quiz(user_choice, correct, user_id): | |
| user_stats[user_id]["attempts"] += 1 | |
| if user_choice == correct: | |
| user_stats[user_id]["correct"] += 1 | |
| return "✅ Correct!" | |
| return f"❌ Incorrect! Correct answer was: {correct}" | |
| def generate_feedback(user_id): | |
| stats = user_stats[user_id] | |
| if stats["attempts"] == 0: | |
| return "Start learning to see your progress." | |
| accuracy = (stats["correct"] / stats["attempts"]) * 100 | |
| if accuracy >= 80: | |
| return f"🌟 Excellent progress! Accuracy: {accuracy:.1f}%" | |
| elif accuracy >= 50: | |
| return f"👍 Good job! Keep practicing. Accuracy: {accuracy:.1f}%" | |
| else: | |
| return f"📘 Keep going! Accuracy: {accuracy:.1f}% - Review your flashcards." | |
| # Build UI | |
| def build_ui(): | |
| with gr.Blocks(theme="soft") as app: | |
| gr.Markdown(""" | |
| # 🧠 Language Learning App | |
| Learn vocabulary with flashcards and quizzes categorized by topic. | |
| """) | |
| with gr.Tabs(): | |
| with gr.TabItem("📇 Flashcards"): | |
| lang_fc = gr.Dropdown(choices=list(vocab_data.keys()), label="Select Language", value="Spanish") | |
| category_fc = gr.Dropdown(choices=["Greetings", "Food"], label="Select Category", value="Greetings") | |
| card_output = gr.Textbox(label="Flashcard", interactive=False) | |
| audio_output = gr.Audio(label="Pronunciation (if available)", interactive=False) | |
| card_btn = gr.Button("🔁 Show Me a Card") | |
| def show_card(language, category): | |
| text, audio_url = flashcard_interface(language, category) | |
| if audio_url: | |
| tmp_audio = tempfile.NamedTemporaryFile(delete=False, suffix=".ogg") | |
| urllib.request.urlretrieve(audio_url, tmp_audio.name) | |
| return text, tmp_audio.name | |
| return text, None | |
| card_btn.click(show_card, inputs=[lang_fc, category_fc], outputs=[card_output, audio_output]) | |
| with gr.TabItem("❓ Quiz"): | |
| user_id = gr.Textbox(label="User ID (for tracking)", value="default_user") | |
| lang_quiz = gr.Dropdown(choices=list(vocab_data.keys()), label="Select Language", value="French") | |
| category_quiz = gr.Dropdown(choices=["Greetings", "Food"], label="Select Category", value="Greetings") | |
| quiz_word = gr.Textbox(label="Translate this word", interactive=False) | |
| quiz_opts = gr.Radio(choices=[], label="Choose the correct translation") | |
| quiz_ans = gr.Textbox(label="Result", interactive=False) | |
| quiz_btn = gr.Button("🎯 Submit Answer") | |
| refresh_btn = gr.Button("🔁 New Question") | |
| score_tracker = gr.Number(label="Your Score", value=0, interactive=False) | |
| feedback_out = gr.Textbox(label="📊 Feedback", interactive=False) | |
| quiz_state = gr.State(value="") | |
| score_state = gr.State(value=0) | |
| def setup_quiz(language, category): | |
| word, opts, correct = quiz_interface(language, category) | |
| return word, gr.update(choices=opts, value=None), correct | |
| refresh_btn.click(setup_quiz, inputs=[lang_quiz, category_quiz], outputs=[quiz_word, quiz_opts, quiz_state]) | |
| def submit_answer(user_choice, correct, score, uid): | |
| feedback = evaluate_quiz(user_choice, correct, uid) | |
| updated_score = score + 1 if user_choice == correct else score | |
| user_feedback = generate_feedback(uid) | |
| return feedback, updated_score, updated_score, user_feedback | |
| quiz_btn.click(submit_answer, inputs=[quiz_opts, quiz_state, score_state, user_id], outputs=[quiz_ans, score_tracker, score_state, feedback_out]) | |
| return app | |
| if __name__ == "__main__": | |
| build_ui().launch() | |
| '' | |
| import gradio as gr | |
| import random | |
| from gtts import gTTS | |
| import tempfile | |
| import os | |
| import urllib.request | |
| from collections import defaultdict | |
| import requests | |
| # ML-like feedback tracker (basic stats) | |
| user_stats = defaultdict(lambda: {"attempts": 0, "correct": 0}) | |
| # Vocabulary Topics | |
| categories = ["Greetings", "Food", "Animals", "Places", "Phrases"] | |
| # Supported Languages | |
| supported_languages = ["Spanish", "French", "German", "Hindi", "Japanese"] | |
| # Vocabulary API (placeholder example using Datamuse-like API, mocked) | |
| def fetch_vocab(language, category): | |
| # Placeholder - Ideally replace with real API integration | |
| vocab = { | |
| "Greetings": {"Hello": f"Hello in {language}", "Goodbye": f"Goodbye in {language}"}, | |
| "Food": {"Bread": f"Bread in {language}", "Water": f"Water in {language}"}, | |
| "Animals": {"Dog": f"Dog in {language}", "Cat": f"Cat in {language}"}, | |
| "Places": {"School": f"School in {language}", "Home": f"Home in {language}"}, | |
| "Phrases": {"Thank you": f"Thank you in {language}", "Sorry": f"Sorry in {language}"}, | |
| } | |
| return vocab.get(category, {}) | |
| # Flashcard Logic | |
| def flashcard_interface(language, category): | |
| items = fetch_vocab(language, category) | |
| eng, trans = random.choice(list(items.items())) | |
| try: | |
| tts = gTTS(trans, lang='en') | |
| audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name | |
| tts.save(audio_path) | |
| return f"{eng} ➜ {trans}", audio_path | |
| except: | |
| return f"{eng} ➜ {trans}", None | |
| # Quiz Logic | |
| def quiz_interface(language, category): | |
| items = fetch_vocab(language, category) | |
| eng, correct = random.choice(list(items.items())) | |
| distractors = list(items.values()) | |
| if correct not in distractors: | |
| distractors.append(correct) | |
| options = random.sample(distractors, min(4, len(distractors))) | |
| random.shuffle(options) | |
| return eng, options, correct | |
| def evaluate_quiz(user_choice, correct, user_id): | |
| user_stats[user_id]["attempts"] += 1 | |
| if user_choice == correct: | |
| user_stats[user_id]["correct"] += 1 | |
| return "✅ Correct!" | |
| return f"❌ Incorrect! Correct answer was: {correct}" | |
| def generate_feedback(user_id): | |
| stats = user_stats[user_id] | |
| if stats["attempts"] == 0: | |
| return "Start learning to see your progress." | |
| accuracy = (stats["correct"] / stats["attempts"]) * 100 | |
| if accuracy >= 80: | |
| return f"🌟 Excellent progress! Accuracy: {accuracy:.1f}%" | |
| elif accuracy >= 50: | |
| return f"👍 Good job! Keep practicing. Accuracy: {accuracy:.1f}%" | |
| else: | |
| return f"📘 Keep going! Accuracy: {accuracy:.1f}% - Review your flashcards." | |
| # Build UI | |
| def build_ui(): | |
| with gr.Blocks(theme="soft") as app: | |
| gr.Markdown(""" | |
| # 🧠 Language Learning App | |
| Learn vocabulary with flashcards and quizzes categorized by topic. | |
| """) | |
| with gr.Tabs(): | |
| with gr.TabItem("📇 Flashcards"): | |
| lang_fc = gr.Dropdown(choices=supported_languages, label="Select Language", value="Spanish") | |
| category_fc = gr.Dropdown(choices=categories, label="Select Category", value="Greetings") | |
| card_output = gr.Textbox(label="Flashcard", interactive=False) | |
| audio_output = gr.Audio(label="Pronunciation", interactive=False) | |
| card_btn = gr.Button("🔁 Show Me a Card") | |
| def show_card(language, category): | |
| text, audio_path = flashcard_interface(language, category) | |
| return text, audio_path | |
| card_btn.click(show_card, inputs=[lang_fc, category_fc], outputs=[card_output, audio_output]) | |
| with gr.TabItem("❓ Quiz"): | |
| user_id = gr.Textbox(label="User ID", value="default_user") | |
| lang_quiz = gr.Dropdown(choices=supported_languages, label="Select Language", value="French") | |
| category_quiz = gr.Dropdown(choices=categories, label="Select Category", value="Greetings") | |
| quiz_word = gr.Textbox(label="Translate this word", interactive=False) | |
| quiz_opts = gr.Radio(choices=[], label="Choose the correct translation") | |
| quiz_ans = gr.Textbox(label="Result", interactive=False) | |
| quiz_btn = gr.Button("🎯 Submit Answer") | |
| refresh_btn = gr.Button("🔁 New Question") | |
| score_tracker = gr.Number(label="Your Score", value=0, interactive=False) | |
| feedback_out = gr.Textbox(label="📊 Feedback", interactive=False) | |
| quiz_state = gr.State(value="") | |
| score_state = gr.State(value=0) | |
| def setup_quiz(language, category): | |
| word, opts, correct = quiz_interface(language, category) | |
| return word, gr.update(choices=opts, value=None), correct | |
| refresh_btn.click(setup_quiz, inputs=[lang_quiz, category_quiz], outputs=[quiz_word, quiz_opts, quiz_state]) | |
| def submit_answer(user_choice, correct, score, uid): | |
| feedback = evaluate_quiz(user_choice, correct, uid) | |
| updated_score = score + 1 if user_choice == correct else score | |
| user_feedback = generate_feedback(uid) | |
| return feedback, updated_score, updated_score, user_feedback | |
| quiz_btn.click(submit_answer, inputs=[quiz_opts, quiz_state, score_state, user_id], outputs=[quiz_ans, score_tracker, score_state, feedback_out]) | |
| return app | |
| if __name__ == "__main__": | |
| build_ui().launch() | |
| '' | |
| import gradio as gr | |
| import random | |
| from gtts import gTTS | |
| import tempfile | |
| import os | |
| import urllib.request | |
| from collections import defaultdict | |
| import requests | |
| from deep_translator import GoogleTranslator | |
| # Set FFMPEG path if not in PATH | |
| os.environ["PATH"] += os.pathsep + r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin" | |
| # Feedback Tracker | |
| user_stats = defaultdict(lambda: {"attempts": 0, "correct": 0, "best_score": 0}) | |
| # Topics and Words | |
| categories = { | |
| "Greetings": ["Hello", "Goodbye", "Please", "Thanks", "Sorry"], | |
| "Food": ["Bread", "Water", "Apple", "Rice", "Milk"], | |
| "Animals": ["Dog", "Cat", "Bird", "Horse", "Elephant"], | |
| "Places": ["School", "Home", "Market", "Park", "Hospital"], | |
| "Phrases": ["How are you?", "What's your name?", "I don't understand", "Can you help me?", "Where is the restroom?"] | |
| } | |
| supported_languages = { | |
| "Spanish": "es", | |
| "French": "fr", | |
| "German": "de", | |
| "Hindi": "hi", | |
| "Japanese": "ja" | |
| } | |
| # Translation + Pronunciation | |
| def get_translation(word, lang_code): | |
| try: | |
| return GoogleTranslator(source='en', target=lang_code).translate(word) | |
| except: | |
| return f"[No translation for {word}]" | |
| def create_audio(text, lang_code): | |
| try: | |
| tts = gTTS(text, lang=lang_code) | |
| audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name | |
| tts.save(audio_path) | |
| return audio_path | |
| except: | |
| return None | |
| # Flashcard Logic | |
| def flashcard_interface(language, category): | |
| eng_word = random.choice(categories[category]) | |
| lang_code = supported_languages[language] | |
| translated = get_translation(eng_word, lang_code) | |
| audio = create_audio(translated, lang_code) | |
| return f"{eng_word} ➜ {translated}", audio | |
| # Quiz Logic | |
| def quiz_interface(language, category): | |
| words = categories[category] | |
| lang_code = supported_languages[language] | |
| eng_word = random.choice(words) | |
| correct = get_translation(eng_word, lang_code) | |
| options = list(set([get_translation(w, lang_code) for w in random.sample(words, k=4)])) | |
| if correct not in options: | |
| options[random.randint(0, 3)] = correct | |
| random.shuffle(options) | |
| return eng_word, options, correct | |
| def evaluate_quiz(user_choice, correct, user_id): | |
| stats = user_stats[user_id] | |
| stats["attempts"] += 1 | |
| if user_choice == correct: | |
| stats["correct"] += 1 | |
| score = stats["correct"] | |
| stats["best_score"] = max(stats["best_score"], score) | |
| return "✅ Correct!" | |
| return f"❌ Incorrect! Correct answer: {correct}" | |
| def generate_feedback(user_id): | |
| stats = user_stats[user_id] | |
| if stats["attempts"] == 0: | |
| return "Start learning to see progress." | |
| accuracy = (stats["correct"] / stats["attempts"]) * 100 | |
| if accuracy >= 80: | |
| return f"🌟 Excellent! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| elif accuracy >= 50: | |
| return f"👍 Keep it up! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| else: | |
| return f"📘 Review more! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| # Gradio UI | |
| def build_ui(): | |
| with gr.Blocks(theme=gr.themes.Soft(), css="body { background: linear-gradient(to right, #f3f4f6, #e0f7fa); }") as app: | |
| gr.Markdown(""" | |
| # 🌍 Smart Language Learning | |
| Flashcards and quizzes with pronunciation, topics, and smart tracking. | |
| """) | |
| with gr.Tabs(): | |
| with gr.TabItem("📇 Flashcards"): | |
| lang_fc = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="Spanish") | |
| category_fc = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Greetings") | |
| card_output = gr.Textbox(label="Flashcard") | |
| audio_output = gr.Audio(label="Pronunciation") | |
| card_btn = gr.Button("🔁 New Card") | |
| card_btn.click(flashcard_interface, [lang_fc, category_fc], [card_output, audio_output]) | |
| with gr.TabItem("❓ Quiz"): | |
| user_id = gr.Textbox(label="User ID", value="user1") | |
| lang_qz = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="French") | |
| cat_qz = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Food") | |
| word_display = gr.Textbox(label="Translate This:", interactive=False) | |
| options = gr.Radio(choices=[], label="Choose Translation") | |
| correct_holder = gr.State() | |
| feedback = gr.Textbox(label="Result") | |
| score_display = gr.Number(label="Score", value=0, interactive=False) | |
| feedback_bar = gr.Textbox(label="📊 Progress Feedback", interactive=False) | |
| refresh = gr.Button("🔄 New Quiz") | |
| submit = gr.Button("🎯 Submit") | |
| def new_quiz(language, category): | |
| w, opts, corr = quiz_interface(language, category) | |
| return w, gr.update(choices=opts), corr | |
| refresh.click(new_quiz, [lang_qz, cat_qz], [word_display, options, correct_holder]) | |
| def submit_answer(choice, correct, uid): | |
| result = evaluate_quiz(choice, correct, uid) | |
| score = user_stats[uid]["correct"] | |
| fb = generate_feedback(uid) | |
| return result, score, fb | |
| submit.click(submit_answer, [options, correct_holder, user_id], [feedback, score_display, feedback_bar]) | |
| return app | |
| if __name__ == "__main__": | |
| build_ui().launch() | |
| '' | |
| import gradio as gr | |
| import random | |
| from gtts import gTTS | |
| import tempfile | |
| import os | |
| from collections import defaultdict | |
| from deep_translator import GoogleTranslator | |
| from pydub import AudioSegment | |
| import time | |
| # Set FFMPEG path if not in PATH | |
| os.environ["PATH"] += os.pathsep + r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin" | |
| AudioSegment.converter = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffmpeg.exe" | |
| AudioSegment.ffprobe = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffprobe.exe" | |
| # Feedback Tracker | |
| user_stats = defaultdict(lambda: {"attempts": 0, "correct": 0, "best_score": 0}) | |
| # Topics and Words | |
| categories = { | |
| "Greetings": ["Hello", "Goodbye", "Please", "Thanks","Good Morning" , "Good afternoon" , "Good evening" , "Good night" , "Sorry"], | |
| "Food": ["Bread", "Water", "Apple", "Rice", "Milk", "Egg" , "Sugar" , "Salt" , "Potato" , "Tomato"], | |
| "Animals": ["Dog", "Cat", "Bird", "Horse", "Elephant" ,"Lion" , "Pigeon" , "Rabbit" , "Fish" , "Turtle" , "Octopus"], | |
| "Places": ["School", "Home", "Market", "Park", "Hospital", "College" , "Shop"], | |
| "Phrases": [ "How are you?", "What's your name?", "I don't understand", "Can you help me?", "Where is the restroom?", "I am sorry"] | |
| } | |
| # Updated and grouped language list | |
| indian_languages = { | |
| "Hindi (hi)": "hi", | |
| "Tamil (ta)": "ta", | |
| "Telugu (te)": "te", | |
| "Kannada (kn)": "kn", | |
| "Bengali (bn)": "bn", | |
| "Gujarati (gu)": "gu", | |
| "Marathi (mr)": "mr", | |
| "Punjabi (pa)": "pa", | |
| "Malayalam (ml)": "ml", | |
| "Urdu (ur)": "ur" | |
| } | |
| foreign_languages = { | |
| "Spanish (es)": "es", | |
| "French (fr)": "fr", | |
| "German (de)": "de", | |
| "Japanese (ja)": "ja", | |
| "Chinese (zh-CN)": "zh-CN", | |
| "Russian (ru)": "ru", | |
| "Korean (ko)": "ko", | |
| "Portuguese (pt)": "pt", | |
| "Italian (it)": "it", | |
| "Arabic (ar)": "ar" | |
| } | |
| supported_languages = {**indian_languages, **foreign_languages} | |
| # Translation + Pronunciation | |
| def get_translation(word, lang_code): | |
| try: | |
| return GoogleTranslator(source='en', target=lang_code).translate(word) | |
| except: | |
| return f"[No translation for {word}]" | |
| def create_audio(text, lang_code): | |
| try: | |
| tts = gTTS(text, lang=lang_code) | |
| audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name | |
| tts.save(audio_path) | |
| return audio_path | |
| except: | |
| return None | |
| def create_feedback_audio(correct): | |
| if correct: | |
| return create_audio("👏 Correct! Well done!", "en") | |
| else: | |
| return create_audio("❌ Incorrect! Try again!", "en") | |
| # Flashcard Logic | |
| def flashcard_interface(language, category): | |
| eng_word = random.choice(categories[category]) | |
| lang_code = supported_languages[language] | |
| translated = get_translation(eng_word, lang_code) | |
| audio = create_audio(translated, lang_code) | |
| return f"{eng_word} ➜ {translated}", audio | |
| # Quiz Logic | |
| def quiz_interface(language, category): | |
| words = categories[category] | |
| lang_code = supported_languages[language] | |
| eng_word = random.choice(words) | |
| correct = get_translation(eng_word, lang_code) | |
| options = list(set([get_translation(w, lang_code) for w in random.sample(words, k=4)])) | |
| if correct not in options: | |
| options[random.randint(0, 3)] = correct | |
| random.shuffle(options) | |
| return eng_word, options, correct | |
| def evaluate_quiz(user_choice, correct, user_id): | |
| stats = user_stats[user_id] | |
| stats["attempts"] += 1 | |
| if user_choice == correct: | |
| stats["correct"] += 1 | |
| score = stats["correct"] | |
| stats["best_score"] = max(stats["best_score"], score) | |
| return "✅ Correct!", score, create_feedback_audio(True) | |
| return f"❌ Incorrect! Correct answer: {correct}", stats["correct"], create_feedback_audio(False) | |
| def generate_feedback(user_id): | |
| stats = user_stats[user_id] | |
| if stats["attempts"] == 0: | |
| return "Start learning to see progress." | |
| accuracy = (stats["correct"] / stats["attempts"]) * 100 | |
| if accuracy >= 80: | |
| return f"🌟 Excellent! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| elif accuracy >= 50: | |
| return f"👍 Keep it up! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| else: | |
| return f"📘 Review more! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| # Gradio UI | |
| def build_ui(): | |
| with gr.Blocks(theme=gr.themes.Soft(), css="body { background: linear-gradient(to right, #f3f4f6, #e0f7fa); font-family: 'Segoe UI'; animation: fadeIn 1.5s ease-in; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }") as app: | |
| gr.Markdown(""" | |
| # 🌍 Smart Language Learning | |
| Flashcards and quizzes with pronunciation, topics, smart tracking, and journey-style progress. | |
| """) | |
| with gr.Tabs(): | |
| with gr.TabItem("📇 Flashcards"): | |
| lang_fc = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="Spanish (es)") | |
| category_fc = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Greetings") | |
| card_output = gr.Textbox(label="Flashcard") | |
| audio_output = gr.Audio(label="Pronunciation") | |
| card_btn = gr.Button("🔁 New Card") | |
| card_btn.click(flashcard_interface, [lang_fc, category_fc], [card_output, audio_output]) | |
| with gr.TabItem("❓ Quiz"): | |
| user_id = gr.Textbox(label="User ID", value="user1") | |
| lang_qz = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="French (fr)") | |
| cat_qz = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Food") | |
| word_display = gr.Textbox(label="Translate This:", interactive=False) | |
| options = gr.Radio(choices=[], label="Choose Translation") | |
| correct_holder = gr.State() | |
| feedback = gr.Textbox(label="Result") | |
| score_display = gr.Number(label="Score", value=0, interactive=False) | |
| feedback_bar = gr.Textbox(label="📊 Progress Feedback", interactive=False) | |
| feedback_audio = gr.Audio(label="Audio Feedback") | |
| refresh = gr.Button("🔄 New Quiz") | |
| submit = gr.Button("🎯 Submit") | |
| def new_quiz(language, category): | |
| w, opts, corr = quiz_interface(language, category) | |
| return w, gr.update(choices=opts), corr | |
| refresh.click(new_quiz, [lang_qz, cat_qz], [word_display, options, correct_holder]) | |
| def submit_answer(choice, correct, uid): | |
| result, score, sound = evaluate_quiz(choice, correct, uid) | |
| fb = generate_feedback(uid) | |
| return result, score, fb, sound | |
| submit.click(submit_answer, [options, correct_holder, user_id], [feedback, score_display, feedback_bar, feedback_audio]) | |
| return app | |
| if __name__ == "__main__": | |
| build_ui().launch() | |
| '' | |
| import gradio as gr | |
| import random | |
| from gtts import gTTS | |
| import tempfile | |
| import os | |
| from collections import defaultdict | |
| from deep_translator import GoogleTranslator | |
| from pydub import AudioSegment | |
| import time | |
| # Set FFMPEG path if not in PATH | |
| os.environ["PATH"] += os.pathsep + r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin" | |
| AudioSegment.converter = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffmpeg.exe" | |
| AudioSegment.ffprobe = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffprobe.exe" | |
| # Feedback Tracker | |
| user_stats = defaultdict(lambda: {"attempts": 0, "correct": 0, "best_score": 0}) | |
| # Topics and Words | |
| categories = { | |
| "Greetings": ["Hello", "Goodbye", "Please", "Thanks","Good Morning" , "Good afternoon" , "Good evening" , "Good night" , "Sorry"], | |
| "Food": ["Bread", "Water", "Apple", "Rice", "Milk", "Egg" , "Sugar" , "Salt" , "Potato" , "Tomato"], | |
| "Animals": ["Dog", "Cat", "Bird", "Horse", "Elephant" ,"Lion" , "Pigeon" , "Rabbit" , "Fish" , "Turtle" , "Octopus"], | |
| "Places": ["School", "Home", "Market", "Park", "Hospital", "College" , "Shop"], | |
| "Phrases": [ "How are you?", "What's your name?", "I don't understand", "Can you help me?", "Where is the restroom?", "I am sorry"] | |
| } | |
| # Updated and grouped language list | |
| indian_languages = { | |
| "Hindi (hi)": "hi", | |
| "Tamil (ta)": "ta", | |
| "Telugu (te)": "te", | |
| "Kannada (kn)": "kn", | |
| "Bengali (bn)": "bn", | |
| "Gujarati (gu)": "gu", | |
| "Marathi (mr)": "mr", | |
| "Punjabi (pa)": "pa", | |
| "Malayalam (ml)": "ml", | |
| "Urdu (ur)": "ur" | |
| } | |
| foreign_languages = { | |
| "Spanish (es)": "es", | |
| "French (fr)": "fr", | |
| "German (de)": "de", | |
| "Japanese (ja)": "ja", | |
| "Chinese (zh-CN)": "zh-CN", | |
| "Russian (ru)": "ru", | |
| "Korean (ko)": "ko", | |
| "Portuguese (pt)": "pt", | |
| "Italian (it)": "it", | |
| "Arabic (ar)": "ar" | |
| } | |
| supported_languages = {**indian_languages, **foreign_languages} | |
| # Translation + Pronunciation | |
| def get_translation(word, lang_code): | |
| try: | |
| return GoogleTranslator(source='en', target=lang_code).translate(word) | |
| except: | |
| return f"[No translation for {word}]" | |
| def create_audio(text, lang_code): | |
| try: | |
| tts = gTTS(text, lang=lang_code) | |
| audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name | |
| tts.save(audio_path) | |
| return audio_path | |
| except: | |
| return None | |
| def create_feedback_audio(correct, lang_code): | |
| try: | |
| msg = "Correct! Well done!" if correct else "Incorrect! Try again!" | |
| return create_audio(msg, lang_code) | |
| except: | |
| return None | |
| # Flashcard Logic | |
| def flashcard_interface(language, category): | |
| eng_word = random.choice(categories[category]) | |
| lang_code = supported_languages[language] | |
| translated = get_translation(eng_word, lang_code) | |
| audio = create_audio(translated, lang_code) | |
| return f"{eng_word} ➜ {translated}", audio | |
| # Quiz Logic | |
| def quiz_interface(language, category): | |
| words = categories[category] | |
| lang_code = supported_languages[language] | |
| eng_word = random.choice(words) | |
| correct = get_translation(eng_word, lang_code) | |
| options = list(set([get_translation(w, lang_code) for w in random.sample(words, k=4)])) | |
| if correct not in options: | |
| options[random.randint(0, 3)] = correct | |
| random.shuffle(options) | |
| return eng_word, options, correct | |
| def evaluate_quiz(user_choice, correct, user_id, lang_code): | |
| stats = user_stats[user_id] | |
| stats["attempts"] += 1 | |
| if user_choice == correct: | |
| stats["correct"] += 1 | |
| score = stats["correct"] | |
| stats["best_score"] = max(stats["best_score"], score) | |
| return "✅ Correct!", score, create_feedback_audio(True, lang_code) | |
| return f"❌ Incorrect! Correct answer: {correct}", stats["correct"], create_feedback_audio(False, lang_code) | |
| def generate_feedback(user_id): | |
| stats = user_stats[user_id] | |
| if stats["attempts"] == 0: | |
| return "Start learning to see progress." | |
| accuracy = (stats["correct"] / stats["attempts"]) * 100 | |
| if accuracy >= 80: | |
| return f"🌟 Excellent! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| elif accuracy >= 50: | |
| return f"👍 Keep it up! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| else: | |
| return f"📘 Review more! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| # Gradio UI | |
| def build_ui(): | |
| with gr.Blocks(theme=gr.themes.Soft(), css="body { background: linear-gradient(to right, #f3f4f6, #e0f7fa); font-family: 'Segoe UI'; animation: fadeIn 1.5s ease-in; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }") as app: | |
| gr.Markdown(""" | |
| # 🌍 Smart Language Learning | |
| Flashcards and quizzes with pronunciation, topics, smart tracking, and journey-style progress. | |
| """) | |
| with gr.Tabs(): | |
| with gr.TabItem("📇 Flashcards"): | |
| lang_fc = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="Spanish (es)") | |
| category_fc = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Greetings") | |
| card_output = gr.Textbox(label="Flashcard") | |
| audio_output = gr.Audio(label="Pronunciation") | |
| card_btn = gr.Button("🔁 New Card") | |
| card_btn.click(flashcard_interface, [lang_fc, category_fc], [card_output, audio_output]) | |
| with gr.TabItem("❓ Quiz"): | |
| user_id = gr.Textbox(label="User ID", value="user1") | |
| lang_qz = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="French (fr)") | |
| cat_qz = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Food") | |
| word_display = gr.Textbox(label="Translate This:", interactive=False) | |
| options = gr.Radio(choices=[], label="Choose Translation") | |
| correct_holder = gr.State() | |
| feedback = gr.Textbox(label="Result") | |
| score_display = gr.Number(label="Score", value=0, interactive=False) | |
| feedback_bar = gr.Textbox(label="📊 Progress Feedback", interactive=False) | |
| feedback_audio = gr.Audio(label="Audio Feedback") | |
| refresh = gr.Button("🔄 New Quiz") | |
| submit = gr.Button("🎯 Submit") | |
| def new_quiz(language, category): | |
| w, opts, corr = quiz_interface(language, category) | |
| return w, gr.update(choices=opts), corr | |
| refresh.click(new_quiz, [lang_qz, cat_qz], [word_display, options, correct_holder]) | |
| def submit_answer(choice, correct, uid, lang): | |
| result, score, sound = evaluate_quiz(choice, correct, uid, supported_languages[lang]) | |
| fb = generate_feedback(uid) | |
| return result, score, fb, sound | |
| submit.click(submit_answer, [options, correct_holder, user_id, lang_qz], [feedback, score_display, feedback_bar, feedback_audio]) | |
| return app | |
| if __name__ == "__main__": | |
| build_ui().launch() | |
| '' | |
| import gradio as gr | |
| import random | |
| from gtts import gTTS | |
| import tempfile | |
| import os | |
| from collections import defaultdict | |
| from deep_translator import GoogleTranslator | |
| from pydub import AudioSegment | |
| import time | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| import uuid | |
| from io import BytesIO | |
| from PIL import Image | |
| import requests | |
| # Set FFMPEG path if not in PATH | |
| os.environ["PATH"] += os.pathsep + r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin" | |
| AudioSegment.converter = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffmpeg.exe" | |
| AudioSegment.ffprobe = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffprobe.exe" | |
| # Feedback Tracker | |
| user_stats = defaultdict(lambda: {"attempts": 0, "correct": 0, "best_score": 0}) | |
| # Topics and Words | |
| categories = { | |
| "Greetings": ["Hello", "Goodbye", "Please", "Thanks", "Good Morning", "Good afternoon", "Good evening", "Good night", "Sorry"], | |
| "Food": ["Bread", "Water", "Apple", "Rice", "Milk", "Egg", "Sugar", "Salt", "Potato", "Tomato"], | |
| "Animals": ["Dog", "Cat", "Bird", "Horse", "Elephant", "Lion", "Pigeon", "Rabbit", "Fish", "Turtle", "Octopus"], | |
| "Places": ["School", "Home", "Market", "Park", "Hospital", "College", "Shop"], | |
| "Phrases": ["How are you?", "What's your name?", "I don't understand", "Can you help me?", "Where is the restroom?", "I am sorry"] | |
| } | |
| indian_languages = { | |
| "Hindi (hi)": "hi", | |
| "Tamil (ta)": "ta", | |
| "Telugu (te)": "te", | |
| "Kannada (kn)": "kn", | |
| "Bengali (bn)": "bn", | |
| "Gujarati (gu)": "gu", | |
| "Marathi (mr)": "mr", | |
| "Punjabi (pa)": "pa", | |
| "Malayalam (ml)": "ml", | |
| "Urdu (ur)": "ur" | |
| } | |
| foreign_languages = { | |
| "Spanish (es)": "es", | |
| "French (fr)": "fr", | |
| "German (de)": "de", | |
| "Japanese (ja)": "ja", | |
| "Chinese (zh-CN)": "zh-CN", | |
| "Russian (ru)": "ru", | |
| "Korean (ko)": "ko", | |
| "Portuguese (pt)": "pt", | |
| "Italian (it)": "it", | |
| "Arabic (ar)": "ar" | |
| } | |
| supported_languages = {**indian_languages, **foreign_languages} | |
| # Translation + Pronunciation | |
| def get_translation(word, lang_code): | |
| try: | |
| return GoogleTranslator(source='en', target=lang_code).translate(word) | |
| except: | |
| return f"[No translation for {word}]" | |
| def create_audio(text, lang_code): | |
| try: | |
| tts = gTTS(text, lang=lang_code) | |
| audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name | |
| tts.save(audio_path) | |
| return audio_path | |
| except: | |
| return None | |
| def create_feedback_audio(correct, lang_code): | |
| try: | |
| msg = GoogleTranslator(source='en', target=lang_code).translate("Correct! Well done!" if correct else "Incorrect! Try again!") | |
| return create_audio(msg, lang_code) | |
| except: | |
| return None | |
| def get_image_from_unsplash(word): | |
| try: | |
| url = f"https://source.unsplash.com/400x300/?{word}" | |
| response = requests.get(url) | |
| return Image.open(BytesIO(response.content)) | |
| except: | |
| return None | |
| # Flashcard Logic | |
| def flashcard_interface(language, category): | |
| eng_word = random.choice(categories[category]) | |
| lang_code = supported_languages[language] | |
| translated = get_translation(eng_word, lang_code) | |
| audio = create_audio(translated, lang_code) | |
| image = get_image_from_unsplash(eng_word) | |
| return f"{eng_word} ➜ {translated}", audio, image | |
| # Quiz Logic | |
| def quiz_interface(language, category): | |
| words = categories[category] | |
| lang_code = supported_languages[language] | |
| eng_word = random.choice(words) | |
| correct = get_translation(eng_word, lang_code) | |
| options = list(set([get_translation(w, lang_code) for w in random.sample(words, k=4)])) | |
| if correct not in options: | |
| options[random.randint(0, 3)] = correct | |
| random.shuffle(options) | |
| return eng_word, options, correct | |
| def evaluate_quiz(user_choice, correct, user_id, lang_code): | |
| stats = user_stats[user_id] | |
| stats["attempts"] += 1 | |
| if user_choice == correct: | |
| stats["correct"] += 1 | |
| score = stats["correct"] | |
| stats["best_score"] = max(stats["best_score"], score) | |
| return "✅ Correct!", score, create_feedback_audio(True, lang_code) | |
| return f"❌ Incorrect! Correct answer: {correct}", stats["correct"], create_feedback_audio(False, lang_code) | |
| def generate_feedback(user_id): | |
| stats = user_stats[user_id] | |
| if stats["attempts"] == 0: | |
| return "Start learning to see progress." | |
| accuracy = (stats["correct"] / stats["attempts"]) * 100 | |
| if accuracy >= 80: | |
| return f"🌟 Excellent! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| elif accuracy >= 50: | |
| return f"👍 Keep it up! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| else: | |
| return f"📘 Review more! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| # Gradio UI | |
| def build_ui(): | |
| with gr.Blocks(theme=gr.themes.Soft(), css="body { background: linear-gradient(to right, #f3f4f6, #e0f7fa); font-family: 'Segoe UI'; animation: fadeIn 1.5s ease-in; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }") as app: | |
| gr.Markdown(""" | |
| # 🌍 Smart Language Learning | |
| Flashcards and quizzes with pronunciation, images, smart tracking, and journey-style progress. | |
| """) | |
| with gr.Tabs(): | |
| with gr.TabItem("📇 Flashcards"): | |
| lang_fc = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="Spanish (es)") | |
| category_fc = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Greetings") | |
| card_output = gr.Textbox(label="Flashcard") | |
| audio_output = gr.Audio(label="Pronunciation") | |
| image_output = gr.Image(label="Visual Aid") | |
| card_btn = gr.Button("🔁 New Card") | |
| card_btn.click(flashcard_interface, [lang_fc, category_fc], [card_output, audio_output, image_output]) | |
| with gr.TabItem("❓ Quiz"): | |
| user_id = gr.Textbox(label="User ID", value="user1") | |
| lang_qz = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="French (fr)") | |
| cat_qz = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Food") | |
| word_display = gr.Textbox(label="Translate This:", interactive=False) | |
| options = gr.Radio(choices=[], label="Choose Translation") | |
| correct_holder = gr.State() | |
| feedback = gr.Textbox(label="Result") | |
| score_display = gr.Number(label="Score", value=0, interactive=False) | |
| feedback_bar = gr.Textbox(label="📊 Progress Feedback", interactive=False) | |
| feedback_audio = gr.Audio(label="Audio Feedback") | |
| refresh = gr.Button("🔄 New Quiz") | |
| submit = gr.Button("🎯 Submit") | |
| def new_quiz(language, category): | |
| w, opts, corr = quiz_interface(language, category) | |
| return w, gr.update(choices=opts), corr | |
| refresh.click(new_quiz, [lang_qz, cat_qz], [word_display, options, correct_holder]) | |
| def submit_answer(choice, correct, uid, lang): | |
| result, score, sound = evaluate_quiz(choice, correct, uid, supported_languages[lang]) | |
| fb = generate_feedback(uid) | |
| return result, score, fb, sound | |
| submit.click(submit_answer, [options, correct_holder, user_id, lang_qz], [feedback, score_display, feedback_bar, feedback_audio]) | |
| return app | |
| if __name__ == "__main__": | |
| build_ui().launch() | |
| '' | |
| import gradio as gr | |
| import random | |
| from gtts import gTTS | |
| import tempfile | |
| import os | |
| from collections import defaultdict | |
| from deep_translator import GoogleTranslator | |
| from pydub import AudioSegment | |
| import time | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| import uuid | |
| from io import BytesIO | |
| from PIL import Image | |
| import requests | |
| # Set FFMPEG path if not in PATH | |
| os.environ["PATH"] += os.pathsep + r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin" | |
| AudioSegment.converter = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffmpeg.exe" | |
| AudioSegment.ffprobe = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffprobe.exe" | |
| # Feedback Tracker | |
| user_stats = defaultdict(lambda: {"attempts": 0, "correct": 0, "best_score": 0}) | |
| # Topics and Words | |
| categories = { | |
| "Greetings": ["Hello", "Goodbye", "Please", "Thanks", "Good Morning", "Good afternoon", "Good evening", "Good night", "Sorry"], | |
| "Food": ["Bread", "Water", "Apple", "Rice", "Milk", "Egg", "Sugar", "Salt", "Potato", "Tomato"], | |
| "Animals": ["Dog", "Cat", "Bird", "Horse", "Elephant", "Lion", "Pigeon", "Rabbit", "Fish", "Turtle", "Octopus"], | |
| "Places": ["School", "Home", "Market", "Park", "Hospital", "College", "Shop"], | |
| "Phrases": ["How are you?", "What's your name?", "I don't understand", "Can you help me?", "Where is the restroom?", "I am sorry"] | |
| } | |
| indian_languages = { | |
| "Hindi (hi)": "hi", | |
| "Tamil (ta)": "ta", | |
| "Telugu (te)": "te", | |
| "Kannada (kn)": "kn", | |
| "Bengali (bn)": "bn", | |
| "Gujarati (gu)": "gu", | |
| "Marathi (mr)": "mr", | |
| "Punjabi (pa)": "pa", | |
| "Malayalam (ml)": "ml", | |
| "Urdu (ur)": "ur" | |
| } | |
| foreign_languages = { | |
| "Spanish (es)": "es", | |
| "French (fr)": "fr", | |
| "German (de)": "de", | |
| "Japanese (ja)": "ja", | |
| "Chinese (zh-CN)": "zh-CN", | |
| "Russian (ru)": "ru", | |
| "Korean (ko)": "ko", | |
| "Portuguese (pt)": "pt", | |
| "Italian (it)": "it", | |
| "Arabic (ar)": "ar" | |
| } | |
| supported_languages = {**indian_languages, **foreign_languages} | |
| # Translation + Pronunciation | |
| def get_translation(word, lang_code): | |
| try: | |
| return GoogleTranslator(source='en', target=lang_code).translate(word) | |
| except: | |
| return f"[No translation for {word}]" | |
| def create_audio(text, lang_code): | |
| try: | |
| tts = gTTS(text, lang=lang_code) | |
| audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name | |
| tts.save(audio_path) | |
| return audio_path | |
| except: | |
| return None | |
| def create_feedback_audio(correct, lang_code): | |
| try: | |
| msg = GoogleTranslator(source='en', target=lang_code).translate("Correct! Well done!" if correct else "Incorrect! Try again!") | |
| return create_audio(msg, lang_code) | |
| except: | |
| return None | |
| def get_image_from_unsplash(word): | |
| try: | |
| url = f"https://source.unsplash.com/400x300/?{word}" | |
| response = requests.get(url) | |
| if response.status_code == 200: | |
| return Image.open(BytesIO(response.content)) | |
| return None | |
| except: | |
| return None | |
| # Flashcard Logic | |
| def flashcard_interface(language, category): | |
| eng_word = random.choice(categories[category]) | |
| lang_code = supported_languages[language] | |
| translated = get_translation(eng_word, lang_code) | |
| audio = create_audio(translated, lang_code) | |
| image = get_image_from_unsplash(translated) | |
| return f"{eng_word} ➜ {translated}", audio, image | |
| # Quiz Logic | |
| def quiz_interface(language, category): | |
| words = categories[category] | |
| lang_code = supported_languages[language] | |
| eng_word = random.choice(words) | |
| correct = get_translation(eng_word, lang_code) | |
| options = list(set([get_translation(w, lang_code) for w in random.sample(words, k=4)])) | |
| if correct not in options: | |
| options[random.randint(0, 3)] = correct | |
| random.shuffle(options) | |
| return eng_word, options, correct | |
| def evaluate_quiz(user_choice, correct, user_id, lang_code): | |
| stats = user_stats[user_id] | |
| stats["attempts"] += 1 | |
| if user_choice == correct: | |
| stats["correct"] += 1 | |
| score = stats["correct"] | |
| stats["best_score"] = max(stats["best_score"], score) | |
| return "✅ Correct!", score, create_feedback_audio(True, lang_code) | |
| return f"❌ Incorrect! Correct answer: {correct}", stats["correct"], create_feedback_audio(False, lang_code) | |
| def generate_feedback(user_id): | |
| stats = user_stats[user_id] | |
| if stats["attempts"] == 0: | |
| return "Start learning to see progress." | |
| accuracy = (stats["correct"] / stats["attempts"]) * 100 | |
| if accuracy >= 80: | |
| return f"🌟 Excellent! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| elif accuracy >= 50: | |
| return f"👍 Keep it up! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| else: | |
| return f"📘 Review more! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| # Gradio UI | |
| def build_ui(): | |
| with gr.Blocks(theme=gr.themes.Soft(), css="body { background: linear-gradient(to right, #f3f4f6, #e0f7fa); font-family: 'Segoe UI'; animation: fadeIn 1.5s ease-in; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }") as app: | |
| gr.Markdown(""" | |
| # 🌍 Smart Language Learning | |
| Flashcards and quizzes with pronunciation, images, smart tracking, and journey-style progress. | |
| """) | |
| with gr.Tabs(): | |
| with gr.TabItem("📇 Flashcards"): | |
| lang_fc = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="Spanish (es)") | |
| category_fc = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Greetings") | |
| card_output = gr.Textbox(label="Flashcard") | |
| audio_output = gr.Audio(label="Pronunciation") | |
| image_output = gr.Image(label="Visual Aid") | |
| card_btn = gr.Button("🔁 New Card") | |
| card_btn.click(flashcard_interface, [lang_fc, category_fc], [card_output, audio_output, image_output]) | |
| with gr.TabItem("❓ Quiz"): | |
| user_id = gr.Textbox(label="User ID", value="user1") | |
| lang_qz = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="French (fr)") | |
| cat_qz = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Food") | |
| word_display = gr.Textbox(label="Translate This:", interactive=False) | |
| options = gr.Radio(choices=[], label="Choose Translation") | |
| correct_holder = gr.State() | |
| feedback = gr.Textbox(label="Result") | |
| score_display = gr.Number(label="Score", value=0, interactive=False) | |
| feedback_bar = gr.Textbox(label="📊 Progress Feedback", interactive=False) | |
| feedback_audio = gr.Audio(label="Audio Feedback") | |
| refresh = gr.Button("🔄 New Quiz") | |
| submit = gr.Button("🎯 Submit") | |
| def new_quiz(language, category): | |
| w, opts, corr = quiz_interface(language, category) | |
| return w, gr.update(choices=opts), corr | |
| refresh.click(new_quiz, [lang_qz, cat_qz], [word_display, options, correct_holder]) | |
| def submit_answer(choice, correct, uid, lang): | |
| result, score, sound = evaluate_quiz(choice, correct, uid, supported_languages[lang]) | |
| fb = generate_feedback(uid) | |
| return result, score, fb, sound | |
| submit.click(submit_answer, [options, correct_holder, user_id, lang_qz], [feedback, score_display, feedback_bar, feedback_audio]) | |
| return app | |
| if __name__ == "__main__": | |
| build_ui().launch() | |
| '' | |
| import gradio as gr | |
| import random | |
| import os | |
| from gtts import gTTS | |
| from PIL import Image | |
| from pathlib import Path | |
| # ----------------------------- | |
| # Vocabulary Database | |
| # ----------------------------- | |
| vocabulary = { | |
| "Greetings": { | |
| "English": {"Hello": "Hello", "Goodbye": "Goodbye"}, | |
| "Hindi": {"Hello": "नमस्ते", "Goodbye": "अलविदा"}, | |
| "Spanish": {"Hello": "Hola", "Goodbye": "Adiós"}, | |
| "French": {"Hello": "Bonjour", "Goodbye": "Au revoir"}, | |
| "German": {"Hello": "Hallo", "Goodbye": "Auf Wiedersehen"} | |
| }, | |
| "Food": { | |
| "English": {"Bread": "Bread", "Apple": "Apple"}, | |
| "Hindi": {"Bread": "रोटी", "Apple": "सेब"}, | |
| "Spanish": {"Bread": "Pan", "Apple": "Manzana"}, | |
| "French": {"Bread": "Pain", "Apple": "Pomme"}, | |
| "German": {"Bread": "Brot", "Apple": "Apfel"} | |
| } | |
| } | |
| # Map language to audio language codes for gTTS | |
| audio_lang_codes = { | |
| "English": "en", | |
| "Hindi": "hi", | |
| "Spanish": "es", | |
| "French": "fr", | |
| "German": "de" | |
| } | |
| # ----------------------------- | |
| # Flashcard Component | |
| # ----------------------------- | |
| def generate_flashcard(topic, language): | |
| word, translation = random.choice(list(vocabulary[topic][language].items())) | |
| lang_code = audio_lang_codes.get(language, "en") | |
| tts = gTTS(text=translation, lang=lang_code) | |
| path = f"temp_audio_{random.randint(0,10000)}.mp3" | |
| tts.save(path) | |
| return word, translation, path | |
| # ----------------------------- | |
| # Matching Quiz | |
| # ----------------------------- | |
| def generate_matching_quiz(topic, language): | |
| items = list(vocabulary[topic][language].items()) | |
| words = [w for w, t in items] | |
| translations = [t for w, t in items] | |
| random.shuffle(translations) | |
| return words, translations | |
| # ----------------------------- | |
| # Sentence Fill Quiz | |
| # ----------------------------- | |
| def generate_fill_quiz(topic, language): | |
| item = random.choice(list(vocabulary[topic][language].items())) | |
| return f"Translate: {item[0]}", item[1] | |
| # ----------------------------- | |
| # Picture Recognition Quiz (stub, using emoji as placeholder) | |
| # ----------------------------- | |
| def generate_picture_quiz(): | |
| image_map = { | |
| "Dog": "🐶", | |
| "Cat": "🐱", | |
| "Apple": "🍎", | |
| "Bread": "🍞" | |
| } | |
| word, emoji = random.choice(list(image_map.items())) | |
| return word, emoji | |
| # ----------------------------- | |
| # Gradio Interface | |
| # ----------------------------- | |
| def flashcard_app(topic, language): | |
| word, translation, audio_path = generate_flashcard(topic, language) | |
| return f"{word} → {translation}", audio_path | |
| def matching_app(topic, language, user_matches): | |
| correct = vocabulary[topic][language] | |
| score = sum(1 for k, v in user_matches.items() if correct.get(k) == v) | |
| lang_code = audio_lang_codes.get(language, "en") | |
| msg = "Well done!" if score == len(user_matches) else "Try again!" | |
| feedback_audio = gTTS(text=msg, lang=lang_code) | |
| feedback_path = f"feedback_{random.randint(0,10000)}.mp3" | |
| feedback_audio.save(feedback_path) | |
| return f"Score: {score}/{len(user_matches)}", feedback_path | |
| def fill_app(topic, language, answer): | |
| prompt, correct_answer = generate_fill_quiz(topic, language) | |
| is_correct = (answer.strip().lower() == correct_answer.strip().lower()) | |
| feedback = "Correct!" if is_correct else f"Wrong. Correct: {correct_answer}" | |
| lang_code = audio_lang_codes.get(language, "en") | |
| tts = gTTS(text=feedback, lang=lang_code) | |
| path = f"fill_audio_{random.randint(0,10000)}.mp3" | |
| tts.save(path) | |
| return feedback, path | |
| # ----------------------------- | |
| # Interface Layout | |
| # ----------------------------- | |
| topic_choices = list(vocabulary.keys()) | |
| language_choices = list(audio_lang_codes.keys()) | |
| with gr.Blocks(title="Language Learning App") as app: | |
| gr.Markdown("# 🌍 Interactive Language Learning App") | |
| gr.Markdown("Choose topic, language and explore quizzes and flashcards.") | |
| with gr.Row(): | |
| topic = gr.Dropdown(topic_choices, label="📘 Topic") | |
| language = gr.Dropdown(language_choices, label="🈶 Language") | |
| with gr.Tab("🔤 Flashcard"): | |
| flashcard_btn = gr.Button("Show Flashcard") | |
| flashcard_output = gr.Textbox() | |
| flashcard_audio = gr.Audio() | |
| flashcard_btn.click(fn=flashcard_app, inputs=[topic, language], outputs=[flashcard_output, flashcard_audio]) | |
| with gr.Tab("🧩 Matching Quiz"): | |
| match_words, match_translations = gr.State(), gr.State() | |
| match_result = gr.Textbox() | |
| match_audio = gr.Audio() | |
| def setup_matching(topic, language): | |
| words, translations = generate_matching_quiz(topic, language) | |
| return words, translations | |
| setup_btn = gr.Button("Generate Matching Quiz") | |
| word_inputs = [gr.Textbox(label=f"Match for word {i+1}") for i in range(2)] | |
| user_input_dict = gr.Textbox(label="Enter JSON of your matches e.g. {'Hello':'Hola'}") | |
| submit_match = gr.Button("Submit Match") | |
| setup_btn.click(fn=setup_matching, inputs=[topic, language], outputs=[match_words, match_translations]) | |
| submit_match.click(fn=matching_app, inputs=[topic, language, user_input_dict], outputs=[match_result, match_audio]) | |
| with gr.Tab("✏️ Fill-in-the-blank Quiz"): | |
| prompt_text = gr.Textbox(label="Prompt") | |
| answer_input = gr.Textbox(label="Your Answer") | |
| fill_result = gr.Textbox() | |
| fill_audio = gr.Audio() | |
| fill_btn = gr.Button("Check Answer") | |
| def show_prompt(topic, language): | |
| prompt, _ = generate_fill_quiz(topic, language) | |
| return prompt | |
| prompt_text.change(fn=show_prompt, inputs=[topic, language], outputs=prompt_text) | |
| fill_btn.click(fn=fill_app, inputs=[topic, language, answer_input], outputs=[fill_result, fill_audio]) | |
| with gr.Tab("🖼️ Picture Quiz"): | |
| picture_label = gr.Textbox(label="What is this?") | |
| emoji_display = gr.Textbox(label="Picture (emoji placeholder)") | |
| generate_pic_btn = gr.Button("New Picture") | |
| generate_pic_btn.click(fn=generate_picture_quiz, inputs=[], outputs=[picture_label, emoji_display]) | |
| app.launch() | |
| ' | |
| import gradio as gr | |
| import random | |
| from gtts import gTTS | |
| import tempfile | |
| import os | |
| from collections import defaultdict | |
| from deep_translator import GoogleTranslator | |
| from pydub import AudioSegment | |
| import time | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| import uuid | |
| from io import BytesIO | |
| from PIL import Image | |
| import requests | |
| # Set FFMPEG path if not in PATH | |
| os.environ["PATH"] += os.pathsep + r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin" | |
| AudioSegment.converter = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffmpeg.exe" | |
| AudioSegment.ffprobe = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffprobe.exe" | |
| # Feedback Tracker | |
| user_stats = defaultdict(lambda: {"attempts": 0, "correct": 0, "best_score": 0}) | |
| # Topics and Words | |
| categories = { | |
| "Greetings": ["Hello", "Goodbye", "Please", "Thanks", "Good Morning", "Good afternoon", "Good evening", "Good night", "Sorry"], | |
| "Food": ["Bread", "Water", "Apple", "Rice", "Milk", "Egg", "Sugar", "Salt", "Potato", "Tomato"], | |
| "Animals": ["Dog", "Cat", "Bird", "Horse", "Elephant", "Lion", "Pigeon", "Rabbit", "Fish", "Turtle", "Octopus"], | |
| "Places": ["School", "Home", "Market", "Park", "Hospital", "College", "Shop"], | |
| "Phrases": ["How are you?", "What's your name?", "I don't understand", "Can you help me?", "Where is the restroom?", "I am sorry"] | |
| } | |
| indian_languages = { | |
| "Hindi (hi)": "hi", | |
| "Tamil (ta)": "ta", | |
| "Telugu (te)": "te", | |
| "Kannada (kn)": "kn", | |
| "Bengali (bn)": "bn", | |
| "Gujarati (gu)": "gu", | |
| "Marathi (mr)": "mr", | |
| "Punjabi (pa)": "pa", | |
| "Malayalam (ml)": "ml", | |
| "Urdu (ur)": "ur" | |
| } | |
| foreign_languages = { | |
| "Spanish (es)": "es", | |
| "French (fr)": "fr", | |
| "German (de)": "de", | |
| "Japanese (ja)": "ja", | |
| "Chinese (zh-CN)": "zh-CN", | |
| "Russian (ru)": "ru", | |
| "Korean (ko)": "ko", | |
| "Portuguese (pt)": "pt", | |
| "Italian (it)": "it", | |
| "Arabic (ar)": "ar" | |
| } | |
| supported_languages = {**indian_languages, **foreign_languages} | |
| # Translation + Pronunciation | |
| def get_translation(word, lang_code): | |
| try: | |
| return GoogleTranslator(source='en', target=lang_code).translate(word) | |
| except: | |
| return f"[No translation for {word}]" | |
| def create_audio(text, lang_code): | |
| try: | |
| tts = gTTS(text, lang=lang_code) | |
| audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name | |
| tts.save(audio_path) | |
| return audio_path | |
| except: | |
| return None | |
| def create_feedback_audio(correct, lang_code): | |
| try: | |
| msg = GoogleTranslator(source='en', target=lang_code).translate("Correct! Well done!" if correct else "Incorrect! Try again!") | |
| return create_audio(msg, lang_code) | |
| except: | |
| return None | |
| def get_image_from_unsplash(word): | |
| try: | |
| url = f"https://source.unsplash.com/400x300/?{word}" | |
| response = requests.get(url) | |
| if response.status_code == 200: | |
| return Image.open(BytesIO(response.content)) | |
| return None | |
| except: | |
| return None | |
| # Flashcard Logic | |
| def flashcard_interface(language, category): | |
| eng_word = random.choice(categories[category]) | |
| lang_code = supported_languages[language] | |
| translated = get_translation(eng_word, lang_code) | |
| audio = create_audio(translated, lang_code) | |
| image = get_image_from_unsplash(translated) | |
| return f"{eng_word} ➜ {translated}", audio, image | |
| # Quiz Logic | |
| def quiz_interface(language, category): | |
| words = categories[category] | |
| lang_code = supported_languages[language] | |
| eng_word = random.choice(words) | |
| correct = get_translation(eng_word, lang_code) | |
| options = list(set([get_translation(w, lang_code) for w in random.sample(words, k=4)])) | |
| if correct not in options: | |
| options[random.randint(0, 3)] = correct | |
| random.shuffle(options) | |
| return eng_word, options, correct | |
| def evaluate_quiz(user_choice, correct, user_id, lang_code): | |
| stats = user_stats[user_id] | |
| stats["attempts"] += 1 | |
| if user_choice == correct: | |
| stats["correct"] += 1 | |
| score = stats["correct"] | |
| stats["best_score"] = max(stats["best_score"], score) | |
| return "✅ Correct!", score, create_feedback_audio(True, lang_code) | |
| return f"❌ Incorrect! Correct answer: {correct}", stats["correct"], create_feedback_audio(False, lang_code) | |
| def generate_feedback(user_id): | |
| stats = user_stats[user_id] | |
| if stats["attempts"] == 0: | |
| return "Start learning to see progress." | |
| accuracy = (stats["correct"] / stats["attempts"]) * 100 | |
| if accuracy >= 80: | |
| return f"🌟 Excellent! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| elif accuracy >= 50: | |
| return f"👍 Keep it up! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| else: | |
| return f"📘 Review more! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| # Gradio UI | |
| def build_ui(): | |
| with gr.Blocks(theme=gr.themes.Soft(), css="body { background: linear-gradient(to right, #f3f4f6, #e0f7fa); font-family: 'Segoe UI'; animation: fadeIn 1.5s ease-in; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }") as app: | |
| gr.Markdown(""" | |
| # 🌍 Smart Language Learning | |
| Flashcards and quizzes with pronunciation, images, smart tracking, and journey-style progress. | |
| """) | |
| with gr.Tabs(): | |
| with gr.TabItem("📇 Flashcards"): | |
| lang_fc = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="Spanish (es)") | |
| category_fc = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Greetings") | |
| card_output = gr.Textbox(label="Flashcard") | |
| audio_output = gr.Audio(label="Pronunciation") | |
| image_output = gr.Image(label="Visual Aid") | |
| card_btn = gr.Button("🔁 New Card") | |
| card_btn.click(flashcard_interface, [lang_fc, category_fc], [card_output, audio_output, image_output]) | |
| with gr.TabItem("❓ Quiz"): | |
| user_id = gr.Textbox(label="User ID", value="user1") | |
| lang_qz = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="French (fr)") | |
| cat_qz = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Food") | |
| word_display = gr.Textbox(label="Translate This:", interactive=False) | |
| options = gr.Radio(choices=[], label="Choose Translation") | |
| correct_holder = gr.State() | |
| feedback = gr.Textbox(label="Result") | |
| score_display = gr.Number(label="Score", value=0, interactive=False) | |
| feedback_bar = gr.Textbox(label="📊 Progress Feedback", interactive=False) | |
| feedback_audio = gr.Audio(label="Audio Feedback") | |
| refresh = gr.Button("🔄 New Quiz") | |
| submit = gr.Button("🎯 Submit") | |
| def new_quiz(language, category): | |
| w, opts, corr = quiz_interface(language, category) | |
| return w, gr.update(choices=opts), corr | |
| refresh.click(new_quiz, [lang_qz, cat_qz], [word_display, options, correct_holder]) | |
| def submit_answer(choice, correct, uid, lang): | |
| result, score, sound = evaluate_quiz(choice, correct, uid, supported_languages[lang]) | |
| fb = generate_feedback(uid) | |
| return result, score, fb, sound | |
| submit.click(submit_answer, [options, correct_holder, user_id, lang_qz], [feedback, score_display, feedback_bar, feedback_audio]) | |
| return app | |
| if __name__ == "__main__": | |
| build_ui().launch() | |
| '' | |
| import gradio as gr | |
| import random | |
| from gtts import gTTS | |
| import tempfile | |
| import os | |
| from collections import defaultdict | |
| from deep_translator import GoogleTranslator | |
| from pydub import AudioSegment | |
| import time | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| import uuid | |
| from io import BytesIO | |
| from PIL import Image | |
| import requests | |
| # Set FFMPEG path if not in PATH | |
| os.environ["PATH"] += os.pathsep + r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin" | |
| AudioSegment.converter = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffmpeg.exe" | |
| AudioSegment.ffprobe = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffprobe.exe" | |
| # Feedback Tracker | |
| user_stats = defaultdict(lambda: {"attempts": 0, "correct": 0, "best_score": 0}) | |
| # Topics and Words | |
| categories = { | |
| "Greetings": ["Hello", "Goodbye", "Please", "Thanks", "Good Morning", "Good afternoon", "Good evening", "Good night", "Sorry"], | |
| "Food": ["Bread", "Water", "Apple", "Rice", "Milk", "Egg", "Sugar", "Salt", "Potato", "Tomato"], | |
| "Animals": ["Dog", "Cat", "Bird", "Horse", "Elephant", "Lion", "Pigeon", "Rabbit", "Fish", "Turtle", "Octopus"], | |
| "Places": ["School", "Home", "Market", "Park", "Hospital", "College", "Shop"], | |
| "Phrases": ["How are you?", "What's your name?", "I don't understand", "Can you help me?", "Where is the restroom?", "I am sorry"] | |
| } | |
| indian_languages = { | |
| "Hindi (hi)": "hi", | |
| "Tamil (ta)": "ta", | |
| "Telugu (te)": "te", | |
| "Kannada (kn)": "kn", | |
| "Bengali (bn)": "bn", | |
| "Gujarati (gu)": "gu", | |
| "Marathi (mr)": "mr", | |
| "Punjabi (pa)": "pa", | |
| "Malayalam (ml)": "ml", | |
| "Urdu (ur)": "ur" | |
| } | |
| foreign_languages = { | |
| "Spanish (es)": "es", | |
| "French (fr)": "fr", | |
| "German (de)": "de", | |
| "Japanese (ja)": "ja", | |
| "Chinese (zh-CN)": "zh-CN", | |
| "Russian (ru)": "ru", | |
| "Korean (ko)": "ko", | |
| "Portuguese (pt)": "pt", | |
| "Italian (it)": "it", | |
| "Arabic (ar)": "ar" | |
| } | |
| supported_languages = {**indian_languages, **foreign_languages} | |
| # Translation + Pronunciation | |
| def get_translation(word, lang_code): | |
| try: | |
| return GoogleTranslator(source='en', target=lang_code).translate(word) | |
| except: | |
| return f"[No translation for {word}]" | |
| def create_audio(text, lang_code): | |
| try: | |
| tts = gTTS(text, lang=lang_code) | |
| audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name | |
| tts.save(audio_path) | |
| return audio_path | |
| except: | |
| return None | |
| def create_feedback_audio(correct, lang_code): | |
| try: | |
| msg = GoogleTranslator(source='en', target=lang_code).translate("Correct! Well done!" if correct else "Incorrect! Try again!") | |
| return create_audio(msg, lang_code) | |
| except: | |
| return None | |
| def get_image_from_unsplash(word): | |
| try: | |
| url = f"https://source.unsplash.com/400x300/?{word}" | |
| response = requests.get(url) | |
| if response.status_code == 200: | |
| return Image.open(BytesIO(response.content)) | |
| return None | |
| except: | |
| return None | |
| # Flashcard Logic | |
| def flashcard_interface(language, category): | |
| eng_word = random.choice(categories[category]) | |
| lang_code = supported_languages[language] | |
| translated = get_translation(eng_word, lang_code) | |
| audio = create_audio(translated, lang_code) | |
| image = get_image_from_unsplash(translated) | |
| return f"{eng_word} ➜ {translated}", audio, image | |
| # Matching Quiz Logic | |
| def matching_quiz_interface(language, category): | |
| words = random.sample(categories[category], 4) | |
| lang_code = supported_languages[language] | |
| translations = [get_translation(w, lang_code) for w in words] | |
| shuffled_translations = translations.copy() | |
| random.shuffle(shuffled_translations) | |
| return words, shuffled_translations, translations | |
| def evaluate_matching_quiz(eng_words, shuffled_translations, user_matches, correct_translations): | |
| correct = 0 | |
| for e, u, c in zip(eng_words, user_matches, correct_translations): | |
| if u == c: | |
| correct += 1 | |
| return f"✅ You matched {correct} out of {len(eng_words)} correctly." | |
| # Gradio UI | |
| def build_ui(): | |
| with gr.Blocks(theme=gr.themes.Soft(), css="body { background: linear-gradient(to right, #f3f4f6, #e0f7fa); font-family: 'Segoe UI'; animation: fadeIn 1.5s ease-in; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }") as app: | |
| gr.Markdown(""" | |
| # 🌍 Smart Language Learning | |
| Flashcards and quizzes with pronunciation, images, smart tracking, and journey-style progress. | |
| """) | |
| with gr.Tabs(): | |
| with gr.TabItem("📇 Flashcards"): | |
| lang_fc = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="Spanish (es)") | |
| category_fc = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Greetings") | |
| card_output = gr.Textbox(label="Flashcard") | |
| audio_output = gr.Audio(label="Pronunciation") | |
| image_output = gr.Image(label="Visual Aid") | |
| card_btn = gr.Button("🔁 New Card") | |
| card_btn.click(flashcard_interface, [lang_fc, category_fc], [card_output, audio_output, image_output]) | |
| with gr.TabItem("🧠 Matching Quiz"): | |
| lang_mq = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="French (fr)") | |
| cat_mq = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Animals") | |
| match_button = gr.Button("🎲 Generate Pairs") | |
| eng_words = gr.Textbox(label="English Words") | |
| shuffled = gr.Textbox(label="Shuffled Translations") | |
| matches = gr.Textbox(label="Enter Matched Translations in Order (comma-separated)") | |
| correct_matches = gr.State() | |
| result = gr.Textbox(label="Result") | |
| match_button.click(matching_quiz_interface, [lang_mq, cat_mq], [eng_words, shuffled, correct_matches]) | |
| check_btn = gr.Button("✅ Check Matches") | |
| check_btn.click(evaluate_matching_quiz, [eng_words, shuffled, matches, correct_matches], result) | |
| return app | |
| if __name__ == "__main__": | |
| build_ui().launch() | |
| '' | |
| import gradio as gr | |
| import random | |
| from gtts import gTTS | |
| import tempfile | |
| import os | |
| from collections import defaultdict | |
| from deep_translator import GoogleTranslator | |
| from pydub import AudioSegment | |
| import time | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| import uuid | |
| from io import BytesIO | |
| from PIL import Image | |
| import requests | |
| # Set FFMPEG path if not in PATH | |
| os.environ["PATH"] += os.pathsep + r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin" | |
| AudioSegment.converter = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffmpeg.exe" | |
| AudioSegment.ffprobe = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffprobe.exe" | |
| # Feedback Tracker | |
| user_stats = defaultdict(lambda: {"attempts": 0, "correct": 0, "best_score": 0}) | |
| # Topics and Words | |
| categories = { | |
| "Greetings": ["Hello", "Goodbye", "Please", "Thanks", "Good Morning", "Good afternoon", "Good evening", "Good night", "Sorry"], | |
| "Food": ["Bread", "Water", "Apple", "Rice", "Milk", "Egg", "Sugar", "Salt", "Potato", "Tomato"], | |
| "Animals": ["Dog", "Cat", "Bird", "Horse", "Elephant", "Lion", "Pigeon", "Rabbit", "Fish", "Turtle", "Octopus"], | |
| "Places": ["School", "Home", "Market", "Park", "Hospital", "College", "Shop"], | |
| "Phrases": ["How are you?", "What's your name?", "I don't understand", "Can you help me?", "Where is the restroom?", "I am sorry"] | |
| } | |
| indian_languages = { | |
| "Hindi (hi)": "hi", | |
| "Tamil (ta)": "ta", | |
| "Telugu (te)": "te", | |
| "Kannada (kn)": "kn", | |
| "Bengali (bn)": "bn", | |
| "Gujarati (gu)": "gu", | |
| "Marathi (mr)": "mr", | |
| "Punjabi (pa)": "pa", | |
| "Malayalam (ml)": "ml", | |
| "Urdu (ur)": "ur" | |
| } | |
| foreign_languages = { | |
| "Spanish (es)": "es", | |
| "French (fr)": "fr", | |
| "German (de)": "de", | |
| "Japanese (ja)": "ja", | |
| "Chinese (zh-CN)": "zh-CN", | |
| "Russian (ru)": "ru", | |
| "Korean (ko)": "ko", | |
| "Portuguese (pt)": "pt", | |
| "Italian (it)": "it", | |
| "Arabic (ar)": "ar" | |
| } | |
| supported_languages = {**indian_languages, **foreign_languages} | |
| # Translation + Pronunciation | |
| def get_translation(word, lang_code): | |
| try: | |
| return GoogleTranslator(source='en', target=lang_code).translate(word) | |
| except: | |
| return f"[No translation for {word}]" | |
| def create_audio(text, lang_code): | |
| try: | |
| tts = gTTS(text, lang=lang_code) | |
| audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name | |
| tts.save(audio_path) | |
| return audio_path | |
| except: | |
| return None | |
| def create_feedback_audio(correct, lang_code): | |
| try: | |
| msg = GoogleTranslator(source='en', target=lang_code).translate("Correct! Well done!" if correct else "Incorrect! Try again!") | |
| return create_audio(msg, lang_code) | |
| except: | |
| return None | |
| def get_image_from_unsplash(word): | |
| try: | |
| url = f"https://source.unsplash.com/400x300/?{word}" | |
| response = requests.get(url) | |
| if response.status_code == 200: | |
| return Image.open(BytesIO(response.content)) | |
| return None | |
| except: | |
| return None | |
| # Flashcard Logic | |
| def flashcard_interface(language, category): | |
| eng_word = random.choice(categories[category]) | |
| lang_code = supported_languages[language] | |
| translated = get_translation(eng_word, lang_code) | |
| audio = create_audio(translated, lang_code) | |
| image = get_image_from_unsplash(translated) | |
| return f"{eng_word} ➜ {translated}", audio, image | |
| # Matching Quiz Logic | |
| def matching_quiz_interface(language, category): | |
| words = random.sample(categories[category], 3) | |
| lang_code = supported_languages[language] | |
| translations = [get_translation(w, lang_code) for w in words] | |
| pairs = list(zip([f"{i+1}. {w}" for i, w in enumerate(words)], [f"{chr(105+i)}. {t}" for i, t in enumerate(translations)])) | |
| answer_key = {str(i+1): chr(105+i) for i in range(len(words))} # { '1': 'i', '2': 'j', ... } | |
| formatted_a = "\n".join(p[0] for p in pairs) | |
| formatted_b = "\n".join(p[1] for p in pairs) | |
| return formatted_a, formatted_b, answer_key | |
| def check_matching_answers(user_input, correct_map): | |
| correct = 0 | |
| total = len(correct_map) | |
| try: | |
| pairs = dict(pair.strip().split(':') for pair in user_input.split(',')) | |
| for k, v in pairs.items(): | |
| if correct_map.get(k.strip()) == v.strip(): | |
| correct += 1 | |
| except: | |
| return "⚠️ Invalid format. Use 1:i, 2:j, ..." | |
| return f"✅ {correct}/{total} correct matches" | |
| # Gradio UI | |
| def build_ui(): | |
| with gr.Blocks(theme=gr.themes.Soft()) as app: | |
| gr.Markdown(""" | |
| # 🌍 Smart Language Learning | |
| Flashcards, multiple quizzes, matching, and audio/image features. | |
| """) | |
| with gr.Tabs(): | |
| with gr.TabItem("📇 Flashcards"): | |
| lang_fc = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="Spanish (es)") | |
| category_fc = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Greetings") | |
| card_output = gr.Textbox(label="Flashcard") | |
| audio_output = gr.Audio(label="Pronunciation") | |
| image_output = gr.Image(label="Visual Aid") | |
| card_btn = gr.Button("🔁 New Card") | |
| card_btn.click(flashcard_interface, [lang_fc, category_fc], [card_output, audio_output, image_output]) | |
| with gr.TabItem("🧠 Matching Quiz"): | |
| lang_m = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="German (de)") | |
| cat_m = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Greetings") | |
| list_a = gr.Textbox(label="List A (English)", interactive=False) | |
| list_b = gr.Textbox(label="List B (Translated)", interactive=False) | |
| match_input = gr.Textbox(label="Enter Matches (e.g. 1:i, 2:j, 3:k)") | |
| result = gr.Textbox(label="Result") | |
| correct_map = gr.State() | |
| gen_btn = gr.Button("🎯 Generate Matching") | |
| gen_btn.click(matching_quiz_interface, [lang_m, cat_m], [list_a, list_b, correct_map]) | |
| eval_btn = gr.Button("✅ Check Answer") | |
| eval_btn.click(check_matching_answers, [match_input, correct_map], result) | |
| return app | |
| if __name__ == "__main__": | |
| build_ui().launch() | |
| '' | |
| import gradio as gr | |
| import random | |
| from gtts import gTTS | |
| import tempfile | |
| import os | |
| from collections import defaultdict | |
| from deep_translator import GoogleTranslator | |
| from pydub import AudioSegment | |
| import time | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| import uuid | |
| from io import BytesIO | |
| from PIL import Image | |
| import requests | |
| # Set FFMPEG path if not in PATH | |
| os.environ["PATH"] += os.pathsep + r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin" | |
| AudioSegment.converter = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffmpeg.exe" | |
| AudioSegment.ffprobe = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffprobe.exe" | |
| # Feedback Tracker | |
| user_stats = defaultdict(lambda: {"attempts": 0, "correct": 0, "best_score": 0}) | |
| # Topics and Words | |
| categories = { | |
| "Greetings": ["Hello", "Goodbye", "Please", "Thanks", "Good Morning", "Good afternoon", "Good evening", "Good night", "Sorry"], | |
| "Food": ["Bread", "Water", "Apple", "Rice", "Milk", "Egg", "Sugar", "Salt", "Potato", "Tomato"], | |
| "Animals": ["Dog", "Cat", "Bird", "Horse", "Elephant", "Lion", "Pigeon", "Rabbit", "Fish", "Turtle", "Octopus"], | |
| "Places": ["School", "Home", "Market", "Park", "Hospital", "College", "Shop"], | |
| "Phrases": ["How are you?", "What's your name?", "I don't understand", "Can you help me?", "Where is the restroom?", "I am sorry"] | |
| } | |
| indian_languages = { | |
| "Hindi (hi)": "hi", | |
| "Tamil (ta)": "ta", | |
| "Telugu (te)": "te", | |
| "Kannada (kn)": "kn", | |
| "Bengali (bn)": "bn", | |
| "Gujarati (gu)": "gu", | |
| "Marathi (mr)": "mr", | |
| "Punjabi (pa)": "pa", | |
| "Malayalam (ml)": "ml", | |
| "Urdu (ur)": "ur" | |
| } | |
| foreign_languages = { | |
| "Spanish (es)": "es", | |
| "French (fr)": "fr", | |
| "German (de)": "de", | |
| "Japanese (ja)": "ja", | |
| "Chinese (zh-CN)": "zh-CN", | |
| "Russian (ru)": "ru", | |
| "Korean (ko)": "ko", | |
| "Portuguese (pt)": "pt", | |
| "Italian (it)": "it", | |
| "Arabic (ar)": "ar" | |
| } | |
| supported_languages = {**indian_languages, **foreign_languages} | |
| # Translation + Pronunciation | |
| def get_translation(word, lang_code): | |
| try: | |
| return GoogleTranslator(source='en', target=lang_code).translate(word) | |
| except: | |
| return f"[No translation for {word}]" | |
| def create_audio(text, lang_code): | |
| try: | |
| tts = gTTS(text, lang=lang_code) | |
| audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name | |
| tts.save(audio_path) | |
| return audio_path | |
| except: | |
| return None | |
| def create_feedback_audio(correct, lang_code): | |
| try: | |
| msg = GoogleTranslator(source='en', target=lang_code).translate("Correct! Well done!" if correct else "Incorrect! Try again!") | |
| return create_audio(msg, lang_code) | |
| except: | |
| return None | |
| def get_image_from_unsplash(word): | |
| try: | |
| url = f"https://source.unsplash.com/400x300/?{word}" | |
| response = requests.get(url) | |
| if response.status_code == 200: | |
| return Image.open(BytesIO(response.content)) | |
| return None | |
| except: | |
| return None | |
| # Flashcard Logic | |
| def flashcard_interface(language, category): | |
| eng_word = random.choice(categories[category]) | |
| lang_code = supported_languages[language] | |
| translated = get_translation(eng_word, lang_code) | |
| audio = create_audio(translated, lang_code) | |
| #image = get_image_from_unsplash(translated) | |
| return f"{eng_word} ➜ {translated}", audio | |
| # Matching Quiz Logic | |
| def matching_quiz_interface(language, category): | |
| words = random.sample(categories[category], 3) | |
| lang_code = supported_languages[language] | |
| translations = [get_translation(w, lang_code) for w in words] | |
| pairs = list(zip([f"{i+1}. {w}" for i, w in enumerate(words)], [f"{chr(105+i)}. {t}" for i, t in enumerate(translations)])) | |
| answer_key = {str(i+1): chr(105+i) for i in range(len(words))} # { '1': 'i', '2': 'j', ... } | |
| formatted_a = "\n".join(p[0] for p in pairs) | |
| formatted_b = "\n".join(p[1] for p in pairs) | |
| return formatted_a, formatted_b, answer_key | |
| def check_matching_answers(user_input, correct_map): | |
| correct = 0 | |
| total = len(correct_map) | |
| try: | |
| pairs = dict(pair.strip().split(':') for pair in user_input.split(',')) | |
| for k, v in pairs.items(): | |
| if correct_map.get(k.strip()) == v.strip(): | |
| correct += 1 | |
| except: | |
| return "⚠️ Invalid format. Use 1:i, 2:j, ..." | |
| return f"✅ {correct}/{total} correct matches" | |
| # Quiz Logic | |
| def quiz_interface(language, category): | |
| words = categories[category] | |
| lang_code = supported_languages[language] | |
| eng_word = random.choice(words) | |
| correct = get_translation(eng_word, lang_code) | |
| options = list(set([get_translation(w, lang_code) for w in random.sample(words, k=4)])) | |
| if correct not in options: | |
| options[random.randint(0, 3)] = correct | |
| random.shuffle(options) | |
| return eng_word, options, correct | |
| def evaluate_quiz(user_choice, correct, user_id, lang_code): | |
| stats = user_stats[user_id] | |
| stats["attempts"] += 1 | |
| if user_choice == correct: | |
| stats["correct"] += 1 | |
| score = stats["correct"] | |
| stats["best_score"] = max(stats["best_score"], score) | |
| return "✅ Correct!", score, create_feedback_audio(True, lang_code) | |
| return f"❌ Incorrect! Correct answer: {correct}", stats["correct"], create_feedback_audio(False, lang_code) | |
| def generate_feedback(user_id): | |
| stats = user_stats[user_id] | |
| if stats["attempts"] == 0: | |
| return "Start learning to see progress." | |
| accuracy = (stats["correct"] / stats["attempts"]) * 100 | |
| if accuracy >= 80: | |
| return f"🌟 Excellent! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| elif accuracy >= 50: | |
| return f"👍 Keep it up! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| else: | |
| return f"📘 Review more! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| # Gradio UI | |
| def build_ui(): | |
| with gr.Blocks(theme=gr.themes.Soft()) as app: | |
| gr.Markdown(""" | |
| # 🌍 Smart Language Learning | |
| Flashcards, multiple quizzes, matching, and audio/image features. | |
| """) | |
| with gr.Tabs(): | |
| with gr.TabItem("📇 Flashcards"): | |
| lang_fc = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="Spanish (es)") | |
| category_fc = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Greetings") | |
| card_output = gr.Textbox(label="Flashcard") | |
| audio_output = gr.Audio(label="Pronunciation") | |
| #image_output = gr.Image(label="Visual Aid") | |
| card_btn = gr.Button("🔁 New Card") | |
| card_btn.click(flashcard_interface, [lang_fc, category_fc], [card_output, audio_output]) | |
| with gr.TabItem("🧠 Matching Quiz"): | |
| lang_m = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="German (de)") | |
| cat_m = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Greetings") | |
| list_a = gr.Textbox(label="List A (English)", interactive=False) | |
| list_b = gr.Textbox(label="List B (Translated)", interactive=False) | |
| match_input = gr.Textbox(label="Enter Matches (e.g. 1:i, 2:j, 3:k)") | |
| result = gr.Textbox(label="Result") | |
| correct_map = gr.State() | |
| gen_btn = gr.Button("🎯 Generate Matching") | |
| gen_btn.click(matching_quiz_interface, [lang_m, cat_m], [list_a, list_b, correct_map]) | |
| eval_btn = gr.Button("✅ Check Answer") | |
| eval_btn.click(check_matching_answers, [match_input, correct_map], result) | |
| with gr.TabItem("❓ Quiz"): | |
| user_id = gr.Textbox(label="User ID", value="user1") | |
| lang_qz = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="French (fr)") | |
| cat_qz = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Food") | |
| word_display = gr.Textbox(label="Translate This:", interactive=False) | |
| options = gr.Radio(choices=[], label="Choose Translation") | |
| correct_holder = gr.State() | |
| feedback = gr.Textbox(label="Result") | |
| score_display = gr.Number(label="Score", value=0, interactive=False) | |
| feedback_bar = gr.Textbox(label="📊 Progress Feedback", interactive=False) | |
| feedback_audio = gr.Audio(label="Audio Feedback") | |
| refresh = gr.Button("🔄 New Quiz") | |
| submit = gr.Button("🎯 Submit") | |
| def new_quiz(language, category): | |
| w, opts, corr = quiz_interface(language, category) | |
| return w, gr.update(choices=opts), corr | |
| refresh.click(new_quiz, [lang_qz, cat_qz], [word_display, options, correct_holder]) | |
| def submit_answer(choice, correct, uid, lang): | |
| result, score, sound = evaluate_quiz(choice, correct, uid, supported_languages[lang]) | |
| fb = generate_feedback(uid) | |
| return result, score, fb, sound | |
| submit.click(submit_answer, [options, correct_holder, user_id, lang_qz], [feedback, score_display, feedback_bar, feedback_audio]) | |
| return app | |
| if __name__ == "__main__": | |
| build_ui().launch() | |
| ''' | |
| import gradio as gr | |
| import random | |
| from gtts import gTTS | |
| import tempfile | |
| import os | |
| from collections import defaultdict | |
| from deep_translator import GoogleTranslator | |
| from pydub import AudioSegment | |
| import time | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| import uuid | |
| from io import BytesIO | |
| from PIL import Image | |
| import requests | |
| import speech_recognition as sr | |
| import difflib | |
| import io | |
| # Set FFMPEG path if not in PATH | |
| os.environ["PATH"] += os.pathsep + r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin" | |
| AudioSegment.converter = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffmpeg.exe" | |
| AudioSegment.ffprobe = r"C:\\Users\\milin\\Downloads\\ffmpeg-2025-06-16-git-e6fb8f373e-full_build\\bin\\ffprobe.exe" | |
| # UTF-8 Sanitizer | |
| def sanitize_text(text): | |
| if isinstance(text, str): | |
| return text.encode('utf-8', errors='replace').decode('utf-8', errors='ignore') | |
| return text | |
| # Feedback Tracker | |
| user_stats = defaultdict(lambda: {"attempts": 0, "correct": 0, "best_score": 0}) | |
| # Topics and Words | |
| categories = { | |
| "Greetings": ["Hello", "Goodbye", "Please", "Thanks", "Good Morning", "Good afternoon", "Good evening", "Good night", "Sorry"], | |
| "Food": ["Bread", "Water", "Apple", "Rice", "Milk", "Egg", "Sugar", "Salt", "Potato", "Tomato"], | |
| "Animals": ["Dog", "Cat", "Bird", "Horse", "Elephant", "Lion", "Pigeon", "Rabbit", "Fish", "Turtle", "Octopus"], | |
| "Places": ["School", "Home", "Market", "Park", "Hospital", "College", "Shop"], | |
| "Phrases": ["How are you?", "What's your name?", "I don't understand", "Can you help me?", "Where is the restroom?", "I am sorry"] | |
| } | |
| indian_languages = { | |
| "Hindi (hi)": "hi", | |
| "Tamil (ta)": "ta", | |
| "Telugu (te)": "te", | |
| "Kannada (kn)": "kn", | |
| "Bengali (bn)": "bn", | |
| "Gujarati (gu)": "gu", | |
| "Marathi (mr)": "mr", | |
| "Punjabi (pa)": "pa", | |
| "Malayalam (ml)": "ml", | |
| "Urdu (ur)": "ur" | |
| } | |
| foreign_languages = { | |
| "Spanish (es)": "es", | |
| "French (fr)": "fr", | |
| "German (de)": "de", | |
| "Japanese (ja)": "ja", | |
| "Chinese (zh-CN)": "zh-CN", | |
| "Russian (ru)": "ru", | |
| "Korean (ko)": "ko", | |
| "Portuguese (pt)": "pt", | |
| "Italian (it)": "it", | |
| "Arabic (ar)": "ar" | |
| } | |
| supported_languages = {**indian_languages, **foreign_languages} | |
| # Translation + Pronunciation | |
| def get_translation(word, lang_code): | |
| try: | |
| return sanitize_text(GoogleTranslator(source='en', target=lang_code).translate(word)) | |
| except: | |
| return f"[No translation for {word}]" | |
| def create_audio(text, lang_code): | |
| try: | |
| tts = gTTS(text, lang=lang_code) | |
| audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name | |
| tts.save(audio_path) | |
| return audio_path | |
| except: | |
| return None | |
| def create_feedback_audio(correct, lang_code): | |
| try: | |
| msg = get_translation("Correct! Well done!" if correct else "Incorrect! Try again!", lang_code) | |
| return create_audio(msg, lang_code) | |
| except: | |
| return None | |
| def get_image_from_unsplash(word): | |
| try: | |
| url = f"https://source.unsplash.com/400x300/?{word}" | |
| response = requests.get(url) | |
| if response.status_code == 200: | |
| return Image.open(BytesIO(response.content)) | |
| return None | |
| except: | |
| return None | |
| # Flashcard Logic | |
| def flashcard_interface(language, category): | |
| eng_word = random.choice(categories[category]) | |
| lang_code = supported_languages[language] | |
| translated = get_translation(eng_word, lang_code) | |
| audio = create_audio(translated, lang_code) | |
| image = get_image_from_unsplash(translated) | |
| return f"{eng_word} ➜ {translated}", audio | |
| # Matching Quiz Logic | |
| def matching_quiz_interface(language, category, num_pairs): | |
| num_pairs = max(3, min(10, num_pairs)) | |
| words = random.sample(categories[category], num_pairs) | |
| lang_code = supported_languages[language] | |
| translations = [get_translation(w, lang_code) for w in words] | |
| shuffled = list(zip(words, translations)) | |
| random.shuffle(translations) | |
| list_a = [f"{i+1}. {w}" for i, w in enumerate(words)] | |
| list_b = [f"{chr(105+i)}. {t}" for i, t in enumerate(translations)] | |
| answer_key = {str(i+1): chr(105 + translations.index(get_translation(w, lang_code))) for i, w in enumerate(words)} | |
| formatted_a = "\n".join(list_a) | |
| formatted_b = "\n".join(list_b) | |
| return formatted_a, formatted_b, answer_key | |
| def check_matching_answers(user_input, correct_map): | |
| correct = 0 | |
| total = len(correct_map) | |
| try: | |
| pairs = dict(pair.strip().split(':') for pair in user_input.split(',')) | |
| for k, v in pairs.items(): | |
| if correct_map.get(k.strip()) == v.strip(): | |
| correct += 1 | |
| except: | |
| return "⚠️ Invalid format. Use 1:i, 2:j, ..." | |
| return f"✅ {correct}/{total} correct matches" | |
| # Quiz Logic with Hint & Skip | |
| def get_hint(correct_answer): | |
| if len(correct_answer) > 2: | |
| return correct_answer[0] + "_" * (len(correct_answer) - 2) + correct_answer[-1] | |
| return correct_answer[0] + "_" | |
| def quiz_session(language, category, count): | |
| words = random.sample(categories[category], count) | |
| lang_code = supported_languages[language] | |
| questions = [] | |
| for word in words: | |
| correct = get_translation(word, lang_code) | |
| options = list(set([get_translation(w, lang_code) for w in random.sample(categories[category], k=4)])) | |
| if correct not in options: | |
| options[random.randint(0, 3)] = correct | |
| random.shuffle(options) | |
| questions.append((word, options, correct)) | |
| return questions | |
| def generate_feedback(user_id): | |
| stats = user_stats[user_id] | |
| if stats["attempts"] == 0: | |
| return "Start learning to see progress." | |
| accuracy = (stats["correct"] / stats["attempts"]) * 100 | |
| if accuracy >= 80: | |
| return f"🌟 Excellent! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| elif accuracy >= 50: | |
| return f"👍 Keep it up! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| else: | |
| return f"📘 Review more! Accuracy: {accuracy:.1f}% | Best Score: {stats['best_score']}" | |
| def evaluate_quiz(user_choice, correct, user_id, lang_code): | |
| stats = user_stats[user_id] | |
| stats["attempts"] += 1 | |
| if user_choice == correct: | |
| stats["correct"] += 1 | |
| score = stats["correct"] | |
| stats["best_score"] = max(stats["best_score"], score) | |
| return "✅ Correct!", score, create_feedback_audio(True, lang_code) | |
| return f"❌ Incorrect! Correct answer: {correct}", stats["correct"], create_feedback_audio(False, lang_code) | |
| ''' | |
| # Pronunciation Practice | |
| def recognize_user_speech(audio): | |
| recognizer = sr.Recognizer() | |
| if isinstance(audio, dict) and "name" in audio: | |
| audio_path = audio["name"] | |
| elif isinstance(audio, str): | |
| audio_path = audio | |
| else: | |
| return "[Invalid audio input]" | |
| with sr.AudioFile(audio_path) as source: | |
| audio_data = recognizer.record(source) | |
| try: | |
| return recognizer.recognize_google(audio_data) | |
| except: | |
| return "[Could not understand audio]" | |
| def compare_pronunciation(expected, user_spoken): | |
| expected = expected.lower().strip() | |
| user_spoken = user_spoken.lower().strip() | |
| ratio = difflib.SequenceMatcher(None, expected, user_spoken).ratio() | |
| feedback = f"🗣 You said: {user_spoken}\nExpected: {expected}\nSimilarity: {ratio*100:.1f}%" | |
| if ratio > 0.8: | |
| feedback += "\n✅ Good pronunciation!" | |
| else: | |
| feedback += "\n❌ Try again for better clarity." | |
| return feedback | |
| ''' | |
| # Pronunciation Practice | |
| def create_audio(text, lang_code): | |
| try: | |
| tts = gTTS(text, lang=lang_code) | |
| path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3").name | |
| tts.save(path) | |
| return path | |
| except: | |
| return None | |
| def recognize_speech_from_audio(audio_path, lang_code): | |
| if not audio_path or not os.path.isfile(audio_path): | |
| return "[No audio file found]" | |
| recognizer = sr.Recognizer() | |
| try: | |
| with sr.AudioFile(audio_path) as source: | |
| audio = recognizer.record(source) | |
| return recognizer.recognize_google(audio, language=lang_code) | |
| except: | |
| return "[Unrecognized]" | |
| ''' | |
| def evaluate_pronunciation(audio_path, word, lang_choice): | |
| global stats | |
| if not audio_path or not os.path.isfile(audio_path): | |
| return "❌ No valid audio received.", None | |
| print("Audio path received:", audio_path) | |
| print("Audio file exists:", os.path.isfile(audio_path)) | |
| print("Word expected:", word) | |
| print("Language chosen:", lang_choice) | |
| lang_code = supported_languages.get(lang_choice, "en") | |
| predicted = recognize_speech_from_audio(audio_path, lang_code) | |
| correct = word.lower().strip() | |
| prediction = predicted.lower().strip() | |
| is_correct = correct in prediction | |
| result = "✅ Correct!" if is_correct else f"❌ You said: '{predicted}'" | |
| translated_word = get_translation(word, lang_code) | |
| correct_audio = create_audio(translated_word, lang_code) | |
| # Only update stats if everything is valid | |
| try: | |
| stats["category_stats"]["Pronunciation"]["attempted"] += 1 | |
| if is_correct: | |
| stats["category_stats"]["Pronunciation"]["correct"] += 1 | |
| except Exception as e: | |
| print("Stats update error:", e) | |
| return result, correct_audio | |
| ''' | |
| import difflib | |
| def evaluate_pronunciation(audio_path, word, lang_choice, attempted, correct): | |
| if not audio_path or not os.path.isfile(audio_path): | |
| return "❌ No valid audio received.", None, attempted, correct | |
| lang_code = supported_languages.get(lang_choice, "en") | |
| predicted = recognize_speech_from_audio(audio_path, lang_code) | |
| if not isinstance(predicted, str) or predicted in ["[Unrecognized]", "[No audio file found]"]: | |
| predicted = "[unrecognized]" | |
| correct_translated = get_translation(word, lang_code) | |
| prediction = predicted.lower().strip() | |
| correct_word = correct_translated.lower().strip() # <- renamed to avoid conflict | |
| matcher = difflib.SequenceMatcher(None, correct_word, prediction) | |
| similarity_score = round(matcher.ratio() * 100) | |
| if similarity_score >= 85: | |
| feedback = f"✅ Excellent pronunciation! Match: {similarity_score}%" | |
| elif similarity_score >= 70: | |
| feedback = f"👍 Good job! Match: {similarity_score}%" | |
| elif similarity_score >= 50: | |
| feedback = f"⚠️ Getting there. Match: {similarity_score}%\nYou said: '{prediction}'\nExpected: '{correct_word}'" | |
| else: | |
| feedback = f"❌ Needs improvement. Match: {similarity_score}%\nYou said: '{prediction}'\nExpected: '{correct_word}'" | |
| attempted += 1 | |
| if similarity_score >= 70: | |
| correct += 1 | |
| correct_audio = create_audio(correct_translated, lang_code) | |
| return feedback, correct_audio, attempted, correct | |
| #dashboard | |
| def generate_dashboard(attempted, correct): | |
| fig, ax = plt.subplots() | |
| categories = ["Pronunciation"] # Add more later if needed | |
| attempted_vals = [attempted] | |
| correct_vals = [correct] | |
| ax.bar(categories, attempted_vals, label='Attempted', alpha=0.6) | |
| ax.bar(categories, correct_vals, label='Correct', alpha=0.6) | |
| ax.set_ylabel("Count") | |
| ax.set_title("Performance Overview") | |
| ax.legend() | |
| buf = io.BytesIO() | |
| plt.tight_layout() | |
| plt.savefig(buf, format='png') | |
| buf.seek(0) | |
| img = Image.open(buf) | |
| return img | |
| #generate stories | |
| def generate_story_questions(passage, lang_code, count): | |
| lines = [s.strip() for s in passage.split('.') if s.strip()] | |
| random.shuffle(lines) | |
| selected = lines[:count * 2] | |
| questions = [] | |
| for line in selected: | |
| try: | |
| translated = get_translation(line, lang_code) | |
| qtype = random.choice(["fill", "mcq", "match"]) | |
| if qtype == "fill": | |
| words = translated.split() | |
| if len(words) > 3: | |
| idx = random.randint(0, len(words) - 2) | |
| answer = words[idx] | |
| words[idx] = "_____" | |
| questions.append(("Fill in the blank:", sanitize_text(" ".join(words)), [answer], answer)) | |
| continue | |
| if qtype == "mcq": | |
| correct = translated | |
| distractors = set() | |
| while len(distractors) < 3: | |
| candidate = get_translation(random.choice(random.choice(list(categories.values()))), lang_code) | |
| if candidate != correct and len(candidate.split()) >= len(correct.split()) - 2: | |
| distractors.add(candidate) | |
| options = list(distractors) + [correct] | |
| random.shuffle(options) | |
| questions.append(("Choose the correct translation:", sanitize_text(line), options, correct)) | |
| continue | |
| if qtype == "match": | |
| words = line.split() | |
| if len(words) >= 4: | |
| sample = random.sample(words, 3) | |
| translations = [get_translation(w, lang_code) for w in sample] | |
| random.shuffle(translations) | |
| left = [f"{i+1}. {w}" for i, w in enumerate(sample)] | |
| right = [f"{chr(105+i)}. {t}" for i, t in enumerate(translations)] | |
| question = "Match the following:\n" + "\n".join(left) + "\n" + "\n".join(right) | |
| answer = {} | |
| for i, w in enumerate(sample): | |
| correct_translation = get_translation(w, lang_code) | |
| match_index = translations.index(correct_translation) | |
| answer[str(i+1)] = chr(105 + match_index) | |
| questions.append(("Matching:", sanitize_text(question), answer, answer)) | |
| except Exception as e: | |
| print(f"❌ Failed to generate question for line: '{line}' — {e}") | |
| if len(questions) >= count: | |
| break | |
| return questions[:count] | |
| predefined_stories = [ | |
| "Maria went to the market. She met an old friend. They talked about school. The weather was hot. She bought tomatoes and potatoes. Her friend bought apples. They decided to walk home. They laughed on the way. They reached home safely. They were tired. They promised to meet again.", | |
| "John loves reading. He reads every night. His favorite books are about planets. He dreams to go to Mars. He studies hard. His room is full of posters. He talks to his dog about space. He builds rockets from cardboard. He wants to be an astronaut. He is very passionate.", | |
| "A dog chased a butterfly. It ran across the garden. The cat watched silently. The butterfly flew up. The dog jumped high. It missed and fell down. The cat laughed quietly. The dog barked playfully. They both ran after the butterfly. It was a joyful sight.", | |
| "Riya visited her grandmother. She lives in a village. The air was fresh. Birds chirped loudly. Riya helped in the garden. She watered the plants. She learned to cook. Grandmother told stories. They went for a walk. Riya had a great time.", | |
| "A teacher entered the class. The students stood up. She smiled warmly. Today was a science quiz. Everyone was excited. The quiz began. Questions were tricky. Some answered correctly. Some were confused. The bell rang soon.", | |
| "The train was late. Passengers were waiting. A boy played with his toy. His sister read a book. A vendor sold snacks. A dog slept under the bench. A cool breeze blew. Everyone looked at the clock. Finally, the train arrived. People rushed to board.", | |
| "In the jungle, animals roamed freely. A lion roared loudly. Birds flew in flocks. Monkeys jumped on trees. A river flowed quietly. A deer drank water. The sun set beautifully. Crickets chirped. Night fell slowly. Stars appeared in the sky.", | |
| "It was a festival day. Houses were decorated. Children wore new clothes. Sweets were prepared. Music played everywhere. Everyone danced. People visited neighbors. Fireworks lit the sky. Smiles were shared. It was a happy day.", | |
| "Rohan was learning to swim. The water was cold. His coach encouraged him. He tried floating. Then practiced strokes. He was scared. But he didn’t give up. He swam one lap. Everyone clapped. He felt proud.", | |
| "The robot cleaned the room. It moved smoothly. It picked up toys. It dusted shelves. It vacuumed the carpet. It made no noise. The kids watched amazed. They wanted one too. It saved time. Robots are helpful." | |
| ] | |
| # Gradio UI | |
| def build_ui(): | |
| with gr.Blocks(theme=gr.themes.Soft()) as app: | |
| gr.Markdown(""" | |
| # 🌍 Smart Language Learning | |
| Flashcards, multiple quizzes, matching, and audio/image features. | |
| """) | |
| with gr.Tabs(): | |
| with gr.TabItem("📇 Flashcards"): | |
| lang_fc = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="Spanish (es)") | |
| category_fc = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Greetings") | |
| card_output = gr.Textbox(label="Flashcard") | |
| audio_output = gr.Audio(label="Pronunciation") | |
| card_btn = gr.Button("🔁 New Card") | |
| card_btn.click(flashcard_interface, [lang_fc, category_fc], [card_output, audio_output]) | |
| with gr.TabItem("🧠 Matching Quiz"): | |
| lang_m = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="German (de)") | |
| cat_m = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Greetings") | |
| num_m = gr.Slider(minimum=3, maximum=10, step=1, label="Number of Pairs", value=3) | |
| list_a = gr.Textbox(label="List A (English)", interactive=False) | |
| list_b = gr.Textbox(label="List B (Translated)", interactive=False) | |
| match_input = gr.Textbox(label="Enter Matches (e.g. 1:i, 2:j, 3:k)") | |
| result = gr.Textbox(label="Result") | |
| correct_map = gr.State() | |
| gen_btn = gr.Button("🎯 Generate Matching") | |
| gen_btn.click(matching_quiz_interface, [lang_m, cat_m, num_m], [list_a, list_b, correct_map]) | |
| eval_btn = gr.Button("✅ Check Answer") | |
| eval_btn.click(check_matching_answers, [match_input, correct_map], result) | |
| with gr.TabItem("❓ Quiz"): | |
| gr.Markdown("""Choose how many questions to attempt, use Hint or Skip if needed.""") | |
| uid = gr.Textbox(label="User ID", value="user1") | |
| lang = gr.Dropdown(choices=list(supported_languages.keys()), label="Language", value="German (de)") | |
| cat = gr.Dropdown(choices=list(categories.keys()), label="Category", value="Greetings") | |
| qcount = gr.Slider(minimum=1, maximum=10, step=1, label="Number of Questions", value=3) | |
| quiz_area = gr.Textbox(label="Question") | |
| options = gr.Radio(choices=[], label="Choose Translation") | |
| correct = gr.State() | |
| questions = gr.State() | |
| index = gr.State(value=0) | |
| score = gr.Number(label="Score", value=0, interactive=False) | |
| result = gr.Textbox(label="📊 Result") | |
| audio_feedback = gr.Audio(label="Audio Feedback") | |
| hint_btn = gr.Button("💡 Hint") | |
| skip_btn = gr.Button("⏭️ Skip") | |
| next_btn = gr.Button("➡️ Next") | |
| def start_quiz(language, category, count): | |
| qs = quiz_session(language, category, count) | |
| if qs: | |
| word, opts, corr = qs[0] | |
| return qs, 0, word, gr.update(choices=opts), corr | |
| return [], 0, "", gr.update(choices=[]), "" | |
| def check_answer(choice, questions, index, uid, lang): | |
| if not questions or index >= len(questions): | |
| return "Finished", gr.update(value=0), None | |
| word, opts, corr = questions[index] | |
| result, sc, sound = evaluate_quiz(choice, corr, uid, supported_languages[lang]) | |
| #fb = generate_feedback(uid) | |
| return result, sc, sound | |
| def show_hint(correct): | |
| return get_hint(correct) | |
| def skip_question(questions, index): | |
| idx = index + 1 | |
| if idx < len(questions): | |
| word, opts, corr = questions[idx] | |
| return idx, word, gr.update(choices=opts), corr | |
| return idx, "End of Quiz", gr.update(choices=[]), "" | |
| def next_question(questions, index): | |
| return skip_question(questions, index) | |
| start = gr.Button("🚀 Start Quiz") | |
| start.click(start_quiz, [lang, cat, qcount], [questions, index, quiz_area, options, correct]) | |
| hint_btn.click(show_hint, correct, result) | |
| skip_btn.click(skip_question, [questions, index], [index, quiz_area, options, correct]) | |
| next_btn.click(next_question, [questions, index], [index, quiz_area, options, correct]) | |
| options.change(check_answer, [options, questions, index, uid, lang], [result, score, audio_feedback]) | |
| for title in ["📚 Story Quiz"]: | |
| with gr.TabItem(title): | |
| lang = gr.Dropdown(list(supported_languages.keys()), label="Language", value="Spanish (es)") | |
| num_questions = gr.Slider(1, 5, step=1, value=3, label="Number of Questions") | |
| story_display = gr.Textbox(label="Story", lines=6, interactive=False) | |
| question_box = gr.Textbox(label="Question", lines=3) | |
| options_radio = gr.Radio(choices=[], label="Options", visible=False) | |
| match_input = gr.Textbox(label="Your Answer (1:i, 2:j)", visible=False) | |
| feedback_output = gr.Textbox(label="Feedback", interactive=False) | |
| submit_btn = gr.Button("Submit") | |
| next_btn = gr.Button("Next") | |
| start_btn = gr.Button("Start Quiz") | |
| audio_output = gr.Audio(label="Listen", visible=(title == "🎧 Audio Story Quiz")) | |
| state_qs = gr.State([]) | |
| state_index = gr.State(0) | |
| def start_story_quiz_with_audio(lang, count): | |
| story = random.choice(predefined_stories) | |
| lang_code = supported_languages[lang] | |
| questions = generate_story_questions(story, lang_code, count) | |
| audio = create_audio(story, lang_code) if title == "🎧 Audio Story Quiz" else None | |
| return story, questions, 0, audio | |
| def show_story_question(qs, index): | |
| if index >= len(qs): | |
| return "Quiz Completed!", gr.update(visible=False), gr.update(visible=False), "✅ Well done!" | |
| qtype, qtext, options, _ = qs[index] | |
| if qtype.startswith("Matching") or qtype.startswith("Fill"): | |
| return qtext, gr.update(visible=False), gr.update(visible=True), "" | |
| else: | |
| return qtext, gr.update(choices=options, visible=True), gr.update(visible=False), "" | |
| def check_story_answer(opt, txt, qs, index): | |
| qtype, _, _, correct = qs[index] | |
| user_ans = txt if qtype.startswith("Fill") or qtype.startswith("Matching") else opt | |
| is_correct = str(user_ans).strip().lower() == str(correct).strip().lower() | |
| feedback = "✅ Correct!" if is_correct else f"❌ Correct: {correct}" | |
| return feedback, index + 1 | |
| start_btn.click(start_story_quiz_with_audio, [lang, num_questions], [story_display, state_qs, state_index, audio_output]) | |
| start_btn.click(show_story_question, [state_qs, state_index], [question_box, options_radio, match_input, feedback_output]) | |
| next_btn.click(show_story_question, [state_qs, state_index], [question_box, options_radio, match_input, feedback_output]) | |
| submit_btn.click(check_story_answer, [options_radio, match_input, state_qs, state_index], [feedback_output, state_index]) | |
| with gr.Tab("🔊 Audio Story Quiz"): | |
| lang = gr.Dropdown(list(supported_languages.keys()), label="Language", value="Spanish (es)") | |
| num_questions = gr.Slider(1, 5, step=1, value=3, label="Number of Questions") | |
| question_box = gr.Textbox(label="Question", lines=3) | |
| options_radio = gr.Radio(choices=[], label="Options", visible=True) | |
| match_input = gr.Textbox(label="Your Answer (1:i, 2:j)", visible=False) | |
| feedback_output = gr.Textbox(label="Feedback", interactive=False) | |
| submit_btn = gr.Button("Submit") | |
| next_btn = gr.Button("Next") | |
| start_btn = gr.Button("Start Quiz") | |
| audio_output = gr.Audio(label="Listen", visible=True) | |
| state_qs = gr.State([]) | |
| state_index = gr.State(0) | |
| def start_story_quiz_with_audio(lang, count): | |
| story = random.choice(predefined_stories) | |
| lang_code = supported_languages[lang] | |
| translated_story = get_translation(story, lang_code) | |
| questions = generate_story_questions(story, lang_code, count) | |
| audio = create_audio(translated_story, lang_code) | |
| return audio, questions, 0 | |
| def show_story_question(qs, index): | |
| if index >= len(qs): | |
| return "Quiz Completed!", gr.update(choices=[], visible=False), gr.update(visible=False), "✅ Well done!" | |
| qtype, qtext, options, _ = qs[index] | |
| if qtype.startswith("Matching") or qtype.startswith("Fill"): | |
| return qtext, gr.update(visible=False), gr.update(visible=True), "" | |
| else: | |
| return qtext, gr.update(choices=options, visible=True), gr.update(visible=False), "" | |
| def check_story_answer(opt, txt, qs, index): | |
| qtype, _, _, correct = qs[index] | |
| user_ans = txt if qtype.startswith("Fill") or qtype.startswith("Matching") else opt | |
| is_correct = str(user_ans).strip().lower() == str(correct).strip().lower() | |
| feedback = "✅ Correct!" if is_correct else f"❌ Correct: {correct}" | |
| return feedback, index + 1 | |
| start_btn.click(start_story_quiz_with_audio, [lang, num_questions], [audio_output, state_qs, state_index]) | |
| start_btn.click(show_story_question, [state_qs, state_index], [question_box, options_radio, match_input, feedback_output]) | |
| next_btn.click(show_story_question, [state_qs, state_index], [question_box, options_radio, match_input, feedback_output]) | |
| submit_btn.click(check_story_answer, [options_radio, match_input, state_qs, state_index], [feedback_output, state_index]) | |
| with gr.Tab("🗣 Pronunciation Test"): | |
| lang_select = gr.Dropdown(list(supported_languages.keys()), label="Select Language") | |
| word_to_pronounce = gr.Textbox(label="Word to Pronounce", interactive=False) | |
| word_state = gr.State() # Hidden state to store selected word | |
| generate_word_btn = gr.Button("Get Word") | |
| user_audio = gr.Audio(type="filepath", label="Speak Now") | |
| feedback = gr.Textbox(label="Feedback", interactive=False) | |
| correct_audio_output = gr.Audio(label="Correct Pronunciation") | |
| state_attempted = gr.State(0) | |
| state_correct = gr.State(0) | |
| def generate_word(): | |
| category = random.choice(list(categories.values())) | |
| word = random.choice(category) | |
| return word, word | |
| generate_word_btn.click(generate_word, outputs=[word_to_pronounce, word_state]) | |
| user_audio.change(evaluate_pronunciation,[user_audio, word_to_pronounce, lang_select, state_attempted, state_correct],[feedback, correct_audio_output, state_attempted, state_correct]) | |
| ''' | |
| with gr.Tab("User Dashboard"): | |
| user_input = gr.Textbox(label="User ID", value="user1") | |
| dash_btn = gr.Button("Generate Dashboard") | |
| dash_output = gr.Textbox(label="Stats") | |
| dash_btn.click(generate_dashboard, [user_input], dash_output) | |
| ''' | |
| ''' | |
| with gr.Tab("✍️ Writing Practice"): | |
| lang_write = gr.Dropdown(list(supported_languages.keys()), label="Language") | |
| word_to_write = gr.Textbox(label="Word to Practice", interactive=False) | |
| generate_write_btn = gr.Button("Get Word") | |
| user_written_input = gr.Textbox(label="Your Writing") | |
| write_feedback = gr.Textbox(label="Feedback", interactive=False) | |
| def evaluate_written(word, lang_choice, user_input): | |
| lang_code = supported_languages[lang_choice] | |
| correct_translation = get_translation(word, lang_code).lower().strip() | |
| user_clean = user_input.lower().strip() | |
| score = round(difflib.SequenceMatcher(None, correct_translation, user_clean).ratio() * 100) | |
| if score >= 85: | |
| return "✅ Excellent!" | |
| elif score >= 70: | |
| return "👍 Good attempt." | |
| else: | |
| return f"❌ Expected: {correct_translation}" | |
| generate_write_btn.click(generate_word, outputs=word_to_write) | |
| user_written_input.change(evaluate_written, [word_to_write, lang_write, user_written_input], write_feedback) | |
| ''' | |
| with gr.Tab("📝 Writing Practice"): | |
| lang_write_test = gr.Dropdown(list(supported_languages.keys()), label="Language") | |
| sentence_prompt = gr.Textbox(label="Translate this sentence", interactive=False) | |
| generate_sent_btn = gr.Button("Generate Sentence") | |
| user_sentence_input = gr.Textbox(label="Your Translation") | |
| sent_feedback = gr.Textbox(label="Feedback", interactive=False) | |
| def generate_sentence(): | |
| sentence = random.choice(["The cat drinks water.", "The cat is sleeping.","I like apples.", "He goes to school.", "It is raining today.", "She sings well.", "We are friends.", "They play football.", "Open the window.", "I read a book.", "The sun is bright.", "This is my bag.", "Where is the pen?", "Close the door.", "I am learning German.", "The dog is barking.", "She is very kind.", "Water the plants.", "He loves music.", "Look at the sky.", "Let’s go home.", "Please give me bread.", "The horse runs fast."]) | |
| return sentence | |
| def evaluate_sentence(sentence, lang_choice, user_input): | |
| lang_code = supported_languages[lang_choice] | |
| expected = get_translation(sentence, lang_code).lower().strip() | |
| typed = user_input.lower().strip() | |
| score = round(difflib.SequenceMatcher(None, expected, typed).ratio() * 100) | |
| if score >= 90: | |
| return "✅ Perfect!" | |
| elif score >= 75: | |
| return f"👍 Good try. \nExpected: {expected}" | |
| else: | |
| return f"❌ Needs improvement.\nExpected: {expected}" | |
| generate_sent_btn.click(generate_sentence, outputs=sentence_prompt) | |
| user_sentence_input.change(evaluate_sentence, [sentence_prompt, lang_write_test, user_sentence_input], sent_feedback) | |
| with gr.TabItem("📈 Dashboard"): | |
| dashboard_output = gr.Image(label="User Progress Dashboard") # ✅ define first | |
| gr.Button("📊 Show Dashboard").click(generate_dashboard,[state_attempted, state_correct],dashboard_output) | |
| return app | |
| if __name__ == "__main__": | |
| build_ui().launch() | |