Spaces:
Sleeping
Sleeping
| """ | |
| Speech Therapy Exercises Database | |
| Categories: Fundamentals, Speech Practice | |
| Languages: English (en), French (fr) | |
| """ | |
| from typing import List, Dict, Optional | |
| from pydantic import BaseModel | |
| from enum import Enum | |
| class ExerciseType(str, Enum): | |
| # Fundamentals | |
| PHONEME = "phoneme" | |
| # Speech Practice | |
| WORD_REPETITION = "word_repetition" | |
| SENTENCE_READING = "sentence_reading" | |
| TONGUE_TWISTER = "tongue_twister" | |
| class Difficulty(str, Enum): | |
| EASY = "easy" | |
| MEDIUM = "medium" | |
| HARD = "hard" | |
| class Category(BaseModel): | |
| id: str | |
| name: Dict[str, str] | |
| description: Dict[str, str] | |
| icon: str | |
| subcategories: List[str] | |
| class Exercise(BaseModel): | |
| id: str | |
| type: ExerciseType | |
| category: str | |
| subcategory: str | |
| difficulty: Difficulty | |
| title: Dict[str, str] | |
| target_text: Dict[str, str] | |
| instructions: Dict[str, str] | |
| phoneme_focus: Optional[List[str]] = None | |
| # ============================================================================= | |
| # CATEGORIES | |
| # ============================================================================= | |
| CATEGORIES: List[Dict] = [ | |
| { | |
| "id": "fundamentals", | |
| "name": {"en": "Fundamentals", "fr": "Fondamentaux"}, | |
| "description": { | |
| "en": "Master specific sounds and phonemes", | |
| "fr": "Maîtrisez des sons et phonèmes spécifiques" | |
| }, | |
| "icon": "🎯", | |
| "subcategories": ["phoneme"] | |
| }, | |
| { | |
| "id": "speech_practice", | |
| "name": {"en": "Speech Practice", "fr": "Pratique de la Parole"}, | |
| "description": { | |
| "en": "Practice words, sentences, and tongue twisters", | |
| "fr": "Pratiquez des mots, des phrases et des virelangues" | |
| }, | |
| "icon": "📖", | |
| "subcategories": ["word_repetition", "sentence_reading", "tongue_twister"] | |
| } | |
| ] | |
| SUBCATEGORIES: Dict[str, Dict] = { | |
| "phoneme": { | |
| "name": {"en": "Phoneme Practice", "fr": "Pratique des Phonèmes"}, | |
| "description": {"en": "Master specific sounds like R, S, TH", "fr": "Maîtrisez des sons spécifiques comme R, S, CH"} | |
| }, | |
| "word_repetition": { | |
| "name": {"en": "Word Repetition", "fr": "Répétition de Mots"}, | |
| "description": {"en": "Repeat words clearly", "fr": "Répétez les mots clairement"} | |
| }, | |
| "sentence_reading": { | |
| "name": {"en": "Sentence Reading", "fr": "Lecture de Phrases"}, | |
| "description": {"en": "Read complete sentences", "fr": "Lisez des phrases complètes"} | |
| }, | |
| "tongue_twister": { | |
| "name": {"en": "Tongue Twisters", "fr": "Virelangues"}, | |
| "description": {"en": "Challenge yourself with tricky phrases", "fr": "Défiez-vous avec des phrases difficiles"} | |
| } | |
| } | |
| # ============================================================================= | |
| # EXERCISES DATABASE | |
| # ============================================================================= | |
| EXERCISES: List[Dict] = [ | |
| # ========================================================================= | |
| # FUNDAMENTALS - Phoneme Practice | |
| # ========================================================================= | |
| { | |
| "id": "phon-r-001", | |
| "type": "phoneme", | |
| "category": "fundamentals", | |
| "subcategory": "phoneme", | |
| "difficulty": "medium", | |
| "title": {"en": "R Sound Practice", "fr": "Pratique du Son R"}, | |
| "target_text": {"en": "Run, red, rain, rabbit, river", "fr": "Rue, rouge, rire, rat, rivière"}, | |
| "instructions": {"en": "Focus on the 'R' sound at the beginning of each word. Let your tongue vibrate slightly.", "fr": "Concentrez-vous sur le son 'R' au début de chaque mot. Laissez votre langue vibrer légèrement."}, | |
| "phoneme_focus": ["R"] | |
| }, | |
| { | |
| "id": "phon-s-001", | |
| "type": "phoneme", | |
| "category": "fundamentals", | |
| "subcategory": "phoneme", | |
| "difficulty": "easy", | |
| "title": {"en": "S Sound Practice", "fr": "Pratique du Son S"}, | |
| "target_text": {"en": "Sun, see, song, seven, smile", "fr": "Sol, sac, sept, soir, sourire"}, | |
| "instructions": {"en": "Make a hissing sound like a snake. Keep your tongue behind your teeth.", "fr": "Faites un son sifflant comme un serpent. Gardez la langue derrière les dents."}, | |
| "phoneme_focus": ["S"] | |
| }, | |
| { | |
| "id": "phon-th-001", | |
| "type": "phoneme", | |
| "category": "fundamentals", | |
| "subcategory": "phoneme", | |
| "difficulty": "hard", | |
| "title": {"en": "TH Sound Practice", "fr": "Pratique du Son TH"}, | |
| "target_text": {"en": "Think, this, that, three, thank", "fr": "Think, this, that, three, thank"}, | |
| "instructions": {"en": "Put your tongue between your teeth and blow air. This sound doesn't exist in French!", "fr": "Mettez la langue entre les dents et soufflez. Ce son n'existe pas en français!"}, | |
| "phoneme_focus": ["TH"] | |
| }, | |
| { | |
| "id": "phon-l-001", | |
| "type": "phoneme", | |
| "category": "fundamentals", | |
| "subcategory": "phoneme", | |
| "difficulty": "easy", | |
| "title": {"en": "L Sound Practice", "fr": "Pratique du Son L"}, | |
| "target_text": {"en": "Love, light, look, lion, lake", "fr": "Lune, livre, lac, lion, lait"}, | |
| "instructions": {"en": "Touch the roof of your mouth with the tip of your tongue.", "fr": "Touchez le palais avec le bout de la langue."}, | |
| "phoneme_focus": ["L"] | |
| }, | |
| { | |
| "id": "phon-ch-001", | |
| "type": "phoneme", | |
| "category": "fundamentals", | |
| "subcategory": "phoneme", | |
| "difficulty": "medium", | |
| "title": {"en": "CH Sound Practice", "fr": "Pratique du Son CH"}, | |
| "target_text": {"en": "Chair, cheese, chicken, chocolate, church", "fr": "Chat, chien, chose, chou, chaud"}, | |
| "instructions": {"en": "Push air through your teeth with rounded lips.", "fr": "Poussez l'air entre vos dents avec les lèvres arrondies."}, | |
| "phoneme_focus": ["CH", "SH"] | |
| }, | |
| # ========================================================================= | |
| # SPEECH PRACTICE - Word Repetition | |
| # ========================================================================= | |
| { | |
| "id": "word-001", | |
| "type": "word_repetition", | |
| "category": "speech_practice", | |
| "subcategory": "word_repetition", | |
| "difficulty": "easy", | |
| "title": {"en": "Greetings", "fr": "Salutations"}, | |
| "target_text": {"en": "Hello, Goodbye, Please, Thank you", "fr": "Bonjour, Au revoir, S'il vous plaît, Merci"}, | |
| "instructions": {"en": "Say each word clearly with a pause between them.", "fr": "Dites chaque mot clairement avec une pause entre eux."}, | |
| }, | |
| { | |
| "id": "word-002", | |
| "type": "word_repetition", | |
| "category": "speech_practice", | |
| "subcategory": "word_repetition", | |
| "difficulty": "easy", | |
| "title": {"en": "Numbers 1-10", "fr": "Chiffres 1-10"}, | |
| "target_text": {"en": "One, two, three, four, five, six, seven, eight, nine, ten", "fr": "Un, deux, trois, quatre, cinq, six, sept, huit, neuf, dix"}, | |
| "instructions": {"en": "Count clearly and steadily. Don't rush!", "fr": "Comptez clairement et régulièrement. Ne vous précipitez pas!"}, | |
| }, | |
| { | |
| "id": "word-003", | |
| "type": "word_repetition", | |
| "category": "speech_practice", | |
| "subcategory": "word_repetition", | |
| "difficulty": "medium", | |
| "title": {"en": "Days of the Week", "fr": "Jours de la Semaine"}, | |
| "target_text": {"en": "Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday", "fr": "Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi, Dimanche"}, | |
| "instructions": {"en": "Say each day with emphasis on the first syllable.", "fr": "Dites chaque jour en accentuant la première syllabe."}, | |
| }, | |
| # ========================================================================= | |
| # SPEECH PRACTICE - Sentence Reading | |
| # ========================================================================= | |
| { | |
| "id": "sent-001", | |
| "type": "sentence_reading", | |
| "category": "speech_practice", | |
| "subcategory": "sentence_reading", | |
| "difficulty": "easy", | |
| "title": {"en": "Simple Introduction", "fr": "Introduction Simple"}, | |
| "target_text": {"en": "Hello, my name is... Nice to meet you!", "fr": "Bonjour, je m'appelle... Enchanté!"}, | |
| "instructions": {"en": "Replace '...' with your name. Speak clearly and smile!", "fr": "Remplacez '...' par votre nom. Parlez clairement et souriez!"}, | |
| }, | |
| { | |
| "id": "sent-002", | |
| "type": "sentence_reading", | |
| "category": "speech_practice", | |
| "subcategory": "sentence_reading", | |
| "difficulty": "easy", | |
| "title": {"en": "How Are You?", "fr": "Comment Allez-Vous?"}, | |
| "target_text": {"en": "How are you today? I am fine, thank you.", "fr": "Comment allez-vous aujourd'hui? Je vais bien, merci."}, | |
| "instructions": {"en": "Practice this common conversation with natural intonation.", "fr": "Pratiquez cette conversation courante avec une intonation naturelle."}, | |
| }, | |
| { | |
| "id": "sent-003", | |
| "type": "sentence_reading", | |
| "category": "speech_practice", | |
| "subcategory": "sentence_reading", | |
| "difficulty": "medium", | |
| "title": {"en": "Weather Talk", "fr": "Parler de la Météo"}, | |
| "target_text": {"en": "The weather is beautiful today. The sun is shining brightly.", "fr": "Il fait beau aujourd'hui. Le soleil brille."}, | |
| "instructions": {"en": "Read the sentences with expression. Sound happy about the weather!", "fr": "Lisez avec expression. Montrez que vous êtes content du temps!"}, | |
| }, | |
| { | |
| "id": "sent-004", | |
| "type": "sentence_reading", | |
| "category": "speech_practice", | |
| "subcategory": "sentence_reading", | |
| "difficulty": "hard", | |
| "title": {"en": "At the Restaurant", "fr": "Au Restaurant"}, | |
| "target_text": {"en": "I would like to order the fish, please. Could I also have some water?", "fr": "Je voudrais commander le poisson, s'il vous plaît. Puis-je aussi avoir de l'eau?"}, | |
| "instructions": {"en": "Practice polite restaurant phrases. Speak clearly to be understood.", "fr": "Pratiquez les phrases polies au restaurant. Parlez clairement pour être compris."}, | |
| }, | |
| # ========================================================================= | |
| # SPEECH PRACTICE - Tongue Twisters | |
| # ========================================================================= | |
| { | |
| "id": "twist-001", | |
| "type": "tongue_twister", | |
| "category": "speech_practice", | |
| "subcategory": "tongue_twister", | |
| "difficulty": "medium", | |
| "title": {"en": "She Sells Seashells", "fr": "Les Chaussettes de l'Archiduchesse"}, | |
| "target_text": {"en": "She sells seashells by the seashore", "fr": "Les chaussettes de l'archiduchesse sont-elles sèches ou archi-sèches"}, | |
| "instructions": {"en": "Start slowly, then try to speed up while staying clear.", "fr": "Commencez lentement, puis essayez d'accélérer tout en restant clair."}, | |
| "phoneme_focus": ["S", "SH"] | |
| }, | |
| { | |
| "id": "twist-002", | |
| "type": "tongue_twister", | |
| "category": "speech_practice", | |
| "subcategory": "tongue_twister", | |
| "difficulty": "hard", | |
| "title": {"en": "Peter Piper", "fr": "Un Chasseur"}, | |
| "target_text": {"en": "Peter Piper picked a peck of pickled peppers", "fr": "Un chasseur sachant chasser sait chasser sans son chien"}, | |
| "instructions": {"en": "Focus on the 'P' sounds. Keep your lips tight.", "fr": "Concentrez-vous sur les sons 'CH'. Gardez la langue stable."}, | |
| "phoneme_focus": ["P"] | |
| }, | |
| { | |
| "id": "twist-003", | |
| "type": "tongue_twister", | |
| "category": "speech_practice", | |
| "subcategory": "tongue_twister", | |
| "difficulty": "hard", | |
| "title": {"en": "Red Lorry Yellow Lorry", "fr": "Trois Tortues"}, | |
| "target_text": {"en": "Red lorry, yellow lorry, red lorry, yellow lorry", "fr": "Trois tortues trottaient sur trois toits très étroits"}, | |
| "instructions": {"en": "Practice the R and L sounds alternating. This is challenging!", "fr": "Pratiquez les sons T et R en alternance. C'est un défi!"}, | |
| "phoneme_focus": ["R", "L"] | |
| }, | |
| { | |
| "id": "twist-004", | |
| "type": "tongue_twister", | |
| "category": "speech_practice", | |
| "subcategory": "tongue_twister", | |
| "difficulty": "medium", | |
| "title": {"en": "Unique New York", "fr": "Panier Piano"}, | |
| "target_text": {"en": "Unique New York, you know you need unique New York", "fr": "Piano panier, panier piano"}, | |
| "instructions": {"en": "Focus on the 'N' and 'Y' sounds.", "fr": "Concentrez-vous sur les sons 'P' et 'N'."}, | |
| "phoneme_focus": ["N", "Y"] | |
| }, | |
| ] | |
| def get_all_categories() -> List[Dict]: | |
| """Return all exercise categories.""" | |
| return CATEGORIES | |
| def get_subcategory_info(subcategory_id: str) -> Optional[Dict]: | |
| """Return information about a specific subcategory.""" | |
| return SUBCATEGORIES.get(subcategory_id) | |
| def get_all_exercises(language: str = "en") -> List[Dict]: | |
| """Return all exercises in the specified language.""" | |
| exercises = [] | |
| for ex in EXERCISES: | |
| exercises.append({ | |
| "id": ex["id"], | |
| "type": ex["type"], | |
| "category": ex["category"], | |
| "subcategory": ex["subcategory"], | |
| "difficulty": ex["difficulty"], | |
| "title": ex["title"].get(language, ex["title"]["en"]), | |
| "target_text": ex["target_text"].get(language, ex["target_text"]["en"]), | |
| "instructions": ex["instructions"].get(language, ex["instructions"]["en"]), | |
| "phoneme_focus": ex.get("phoneme_focus", []) | |
| }) | |
| return exercises | |
| def get_exercises_by_category(category: str, language: str = "en") -> List[Dict]: | |
| """Return exercises filtered by category.""" | |
| all_exercises = get_all_exercises(language) | |
| return [ex for ex in all_exercises if ex["category"] == category] | |
| def get_exercises_by_subcategory(subcategory: str, language: str = "en") -> List[Dict]: | |
| """Return exercises filtered by subcategory.""" | |
| all_exercises = get_all_exercises(language) | |
| return [ex for ex in all_exercises if ex["subcategory"] == subcategory] | |
| def get_exercises_by_difficulty(difficulty: str, language: str = "en") -> List[Dict]: | |
| """Return exercises filtered by difficulty.""" | |
| all_exercises = get_all_exercises(language) | |
| return [ex for ex in all_exercises if ex["difficulty"] == difficulty] | |
| def get_exercise_by_id(exercise_id: str, language: str = "en") -> Optional[Dict]: | |
| """Return a specific exercise by ID.""" | |
| all_exercises = get_all_exercises(language) | |
| for ex in all_exercises: | |
| if ex["id"] == exercise_id: | |
| return ex | |
| return None | |