Spaces:
Sleeping
Sleeping
| """ | |
| Vietnamese Pronunciation Tips for English Learners | |
| Mẹo phát âm tiếng Anh dành cho người Việt Nam | |
| This module provides detailed pronunciation guidance in Vietnamese | |
| for common English phonemes that are challenging for Vietnamese speakers. | |
| """ | |
| from typing import Dict, List, Optional, Tuple | |
| from dataclasses import dataclass | |
| import random | |
| class PronunciationTip: | |
| """Structured pronunciation tip with detailed guidance""" | |
| phoneme: str | |
| vietnamese_name: str | |
| mouth_position: str | |
| tongue_position: str | |
| breathing: str | |
| common_mistakes: List[str] | |
| practice_words: List[str] | |
| detailed_instruction: str | |
| difficulty_level: int # 1-5, where 5 is most difficult | |
| class VietnameseTipsProvider: | |
| """Provides detailed pronunciation tips in Vietnamese for English learners""" | |
| def __init__(self): | |
| self.tips_database = self._initialize_tips_database() | |
| self.error_patterns = self._initialize_error_patterns() | |
| def _initialize_tips_database(self) -> Dict[str, PronunciationTip]: | |
| """Initialize comprehensive tips database""" | |
| tips = { | |
| # Consonants that are difficult for Vietnamese speakers | |
| "θ": PronunciationTip( | |
| phoneme="θ", | |
| vietnamese_name="âm th không thanh (như trong 'think')", | |
| mouth_position="Miệng mở vừa phải, môi tự nhiên", | |
| tongue_position="Đưa lưỡi ra ngoài, đặt giữa răng trên và răng dưới", | |
| breathing="Thổi khí nhẹ qua khe giữa lưỡi và răng", | |
| common_mistakes=[ | |
| "Phát âm thành /f/ (như 'think' thành 'fink')", | |
| "Phát âm thành /s/ (như 'think' thành 'sink')", | |
| "Phát âm thành /t/ (như 'think' thành 'tink')", | |
| ], | |
| practice_words=["think", "three", "thank", "thing", "throw"], | |
| detailed_instruction=""" | |
| Cách luyện tập chi tiết: | |
| 1. Đưa lưỡi ra ngoài sao cho đầu lưỡi chạm nhẹ vào răng trên | |
| 2. Thổi khí nhẹ qua khe giữa lưỡi và răng - KHÔNG rung dây thanh | |
| 3. Luyện tập từ 'think' - bắt đầu chậm, sau đó tăng tốc | |
| 4. Đặt gương trước mặt để kiểm tra vị trí lưỡi | |
| 5. Luyện tập 10-15 phút mỗi ngày | |
| """, | |
| difficulty_level=5, | |
| ), | |
| "ð": PronunciationTip( | |
| phoneme="ð", | |
| vietnamese_name="âm th có thanh (như trong 'this')", | |
| mouth_position="Miệng mở vừa phải, môi tự nhiên", | |
| tongue_position="Đưa lưỡi ra ngoài, đặt giữa răng trên và răng dưới", | |
| breathing="Rung dây thanh và thổi khí nhẹ", | |
| common_mistakes=[ | |
| "Phát âm thành /d/ (như 'this' thành 'dis')", | |
| "Phát âm thành /z/ (như 'this' thành 'zis')", | |
| "Phát âm thành /v/ (như 'this' thành 'vis')", | |
| ], | |
| practice_words=["this", "that", "they", "there", "mother"], | |
| detailed_instruction=""" | |
| Cách luyện tập chi tiết: | |
| 1. Giống như âm /θ/ nhưng phải rung dây thanh | |
| 2. Đặt tay lên cổ họng để cảm nhận rung động | |
| 3. Bắt đầu với âm /z/, sau đó đưa lưỡi ra giữa răng | |
| 4. Luyện cặp từ: 'sink/think' và 'zis/this' | |
| 5. Tập đọc câu: 'This is the thing they threw' | |
| """, | |
| difficulty_level=5, | |
| ), | |
| "v": PronunciationTip( | |
| phoneme="v", | |
| vietnamese_name="âm v (như trong 'very')", | |
| mouth_position="Môi dưới chạm nhẹ vào răng trên", | |
| tongue_position="Lưỡi ở vị trí tự nhiên, không chạm răng", | |
| breathing="Rung dây thanh, khí thổi qua khe môi-răng", | |
| common_mistakes=[ | |
| "Phát âm thành /w/ (như 'very' thành 'wery')", | |
| "Phát âm thành /f/ (như 'very' thành 'fery')", | |
| "Dùng cả hai môi như âm /w/ trong tiếng Việt", | |
| ], | |
| practice_words=["very", "voice", "video", "love", "have"], | |
| detailed_instruction=""" | |
| Cách luyện tập chi tiết: | |
| 1. CHỈ dùng môi dưới chạm răng trên - đây là điểm khác biệt chính | |
| 2. Đừng dùng cả hai môi như âm 'u' trong tiếng Việt | |
| 3. Luyện phân biệt: 'west/vest', 'wine/vine' | |
| 4. Đặt ngón tay lên môi trên để tránh cử động | |
| 5. Tập đọc: 'Very valuable video' | |
| """, | |
| difficulty_level=4, | |
| ), | |
| "w": PronunciationTip( | |
| phoneme="w", | |
| vietnamese_name="âm w (như trong 'water')", | |
| mouth_position="Cả hai môi chu tròn như âm 'u'", | |
| tongue_position="Lưỡi co lại ở phía sau", | |
| breathing="Rung dây thanh, thổi qua môi tròn", | |
| common_mistakes=[ | |
| "Phát âm thành /v/ (như 'water' thành 'vater')", | |
| "Không chu môi đủ tròn", | |
| "Lưỡi đặt sai vị trí", | |
| ], | |
| practice_words=["water", "wind", "wall", "woman", "sweet"], | |
| detailed_instruction=""" | |
| Cách luyện tập chi tiết: | |
| 1. Bắt đầu với âm 'u' trong tiếng Việt, sau đó chuyển sang âm tiếp theo | |
| 2. Cả hai môi phải chu tròn - không chỉ môi dưới | |
| 3. Luyện phân biệt: 'vest/west', 'vine/wine' | |
| 4. Tập nói chậm: 'W-A-T-E-R' rồi tăng tốc | |
| 5. Luyện câu: 'We went to the west wall' | |
| """, | |
| difficulty_level=3, | |
| ), | |
| "r": PronunciationTip( | |
| phoneme="r", | |
| vietnamese_name="âm r tiếng Anh (như trong 'red')", | |
| mouth_position="Miệng mở vừa, không mỉm cười", | |
| tongue_position="Cuộn lưỡi lên không chạm vòm miệng", | |
| breathing="Rung dây thanh, khí đi qua lưỡi cuộn", | |
| common_mistakes=[ | |
| "Cuộn lưỡi quá mạnh như tiếng Việt", | |
| "Lưỡi chạm vào vòm miệng", | |
| "Phát âm thành /l/", | |
| "Rung lưỡi như âm 'r' tiếng Việt", | |
| ], | |
| practice_words=["red", "run", "right", "car", "very"], | |
| detailed_instruction=""" | |
| Cách luyện tập chi tiết: | |
| 1. Cuộn lưỡi lên NHƯNG KHÔNG chạm vào vòm miệng | |
| 2. Âm /r/ tiếng Anh mềm hơn nhiều so với tiếng Việt | |
| 3. Luyện phân biệt: 'light/right', 'long/wrong' | |
| 4. Bắt đầu với âm 'ơ' rồi cuộn lưỡi nhẹ | |
| 5. Tập từ cuối: 'car', 'far', 'star' - đây dễ hơn | |
| """, | |
| difficulty_level=4, | |
| ), | |
| "l": PronunciationTip( | |
| phoneme="l", | |
| vietnamese_name="âm l tiếng Anh (như trong 'love')", | |
| mouth_position="Miệng mở tự nhiên", | |
| tongue_position="Đầu lưỡi chạm vào nướu răng trên", | |
| breathing="Rung dây thanh, khí đi qua hai bên lưỡi", | |
| common_mistakes=[ | |
| "Phát âm thành /r/", | |
| "Đầu lưỡi không chạm đúng vị trí", | |
| "Phát âm quá nặng như tiếng Việt", | |
| ], | |
| practice_words=["love", "light", "blue", "apple", "wall"], | |
| detailed_instruction=""" | |
| Cách luyện tập chi tiết: | |
| 1. Đầu lưỡi phải chạm vào nướu răng trên, không phải răng | |
| 2. Âm /l/ tiếng Anh nhẹ hơn tiếng Việt | |
| 3. Luyện phân biệt: 'right/light', 'wrong/long' | |
| 4. Tập âm /l/ cuối từ: 'wall', 'ball', 'call' | |
| 5. Luyện câu: 'Lucy loves blue apples' | |
| """, | |
| difficulty_level=3, | |
| ), | |
| "z": PronunciationTip( | |
| phoneme="z", | |
| vietnamese_name="âm z (như trong 'zero')", | |
| mouth_position="Miệng như âm /s/ nhưng rung dây thanh", | |
| tongue_position="Đầu lưỡi gần răng trên nhưng không chạm", | |
| breathing="Rung dây thanh, khí đi qua khe nhỏ", | |
| common_mistakes=[ | |
| "Phát âm thành /s/ (không rung dây thanh)", | |
| "Phát âm thành /dʒ/ (như 'gi' trong tiếng Việt)", | |
| "Quá to, quá rõ", | |
| ], | |
| practice_words=["zero", "zoo", "easy", "buzz", "maze"], | |
| detailed_instruction=""" | |
| Cách luyện tập chi tiết: | |
| 1. Giống hệt âm /s/ nhưng phải rung dây thanh | |
| 2. Đặt tay lên cổ họng để kiểm tra rung động | |
| 3. Luyện cặp: 'sip/zip', 'seal/zeal' | |
| 4. Bắt đầu với âm 's' rồi thêm rung dây thanh | |
| 5. Tập câu: 'Zero zebras in the zoo' | |
| """, | |
| difficulty_level=3, | |
| ), | |
| "ʒ": PronunciationTip( | |
| phoneme="ʒ", | |
| vietnamese_name="âm zh (như trong 'measure')", | |
| mouth_position="Môi chu tròn nhẹ", | |
| tongue_position="Đầu lưỡi gần vòm miệng nhưng không chạm", | |
| breathing="Rung dây thanh, khí đi qua khe rộng hơn /z/", | |
| common_mistakes=[ | |
| "Phát âm thành /ʃ/ (như 'sh' nhưng không thanh)", | |
| "Phát âm thành /z/", | |
| "Quá giống âm 'gi' tiếng Việt", | |
| ], | |
| practice_words=["measure", "pleasure", "vision", "usual", "garage"], | |
| detailed_instruction=""" | |
| Cách luyện tập chi tiết: | |
| 1. Giống âm /ʃ/ (sh) nhưng có rung dây thanh | |
| 2. Luyện cặp: 'ship/vision', 'cash/casual' | |
| 3. Bắt đầu với 'sh' rồi thêm thanh âm | |
| 4. Âm này ít gặp ở đầu từ, nhiều ở giữa và cuối | |
| 5. Tập câu: 'It's my pleasure to measure' | |
| """, | |
| difficulty_level=4, | |
| ), | |
| "ʃ": PronunciationTip( | |
| phoneme="ʃ", | |
| vietnamese_name="âm sh (như trong 'ship')", | |
| mouth_position="Môi chu tròn nhẹ, hơi thụt vào", | |
| tongue_position="Lưỡi cong lên gần vòm miệng", | |
| breathing="Không rung dây thanh, thổi khí mạnh", | |
| common_mistakes=[ | |
| "Phát âm thành /s/", | |
| "Không chu môi", | |
| "Lưỡi đặt sai vị trí", | |
| ], | |
| practice_words=["ship", "shoe", "wash", "fish", "shell"], | |
| detailed_instruction=""" | |
| Cách luyện tập chi tiết: | |
| 1. Chu môi như chuẩn bị huýt sáo nhưng nhẹ hơn | |
| 2. Lưỡi cong lên, tạo khoảng rộng hơn âm /s/ | |
| 3. Luyện phân biệt: 'sip/ship', 'sass/shash' | |
| 4. Âm /ʃ/ dài hơn và êm hơn âm /s/ | |
| 5. Tập câu: 'She sells seashells' | |
| """, | |
| difficulty_level=3, | |
| ), | |
| # Vowels challenging for Vietnamese speakers | |
| "æ": PronunciationTip( | |
| phoneme="æ", | |
| vietnamese_name="âm ae (như trong 'cat')", | |
| mouth_position="Miệng mở rộng, góc miệng kéo ra", | |
| tongue_position="Lưỡi thấp, phẳng ở đáy miệng", | |
| breathing="Rung dây thanh", | |
| common_mistakes=[ | |
| "Phát âm thành /ɛ/ (như 'bet')", | |
| "Phát âm thành /a/ (như 'car')", | |
| "Không mở miệng đủ rộng", | |
| ], | |
| practice_words=["cat", "hat", "bad", "man", "apple"], | |
| detailed_instruction=""" | |
| Cách luyện tập chi tiết: | |
| 1. Mở miệng rộng như đang cười nhưng kéo dài | |
| 2. Lưỡi phải thấp xuống đáy miệng | |
| 3. Luyện phân biệt: 'bet/bat', 'pen/pan' | |
| 4. Âm này không có trong tiếng Việt | |
| 5. Tập câu: 'The fat cat sat on the mat' | |
| """, | |
| difficulty_level=4, | |
| ), | |
| "ɪ": PronunciationTip( | |
| phoneme="ɪ", | |
| vietnamese_name="âm i ngắn (như trong 'bit')", | |
| mouth_position="Miệng mở hẹp hơn âm /i/", | |
| tongue_position="Lưỡi hơi thấp hơn âm /i/ dài", | |
| breathing="Rung dây thanh, âm ngắn", | |
| common_mistakes=[ | |
| "Phát âm thành /i/ dài (như 'bee')", | |
| "Kéo dài âm quá mức", | |
| "Lưỡi đặt quá cao", | |
| ], | |
| practice_words=["bit", "sit", "big", "fish", "list"], | |
| detailed_instruction=""" | |
| Cách luyện tập chi tiết: | |
| 1. Ngắn và thư giãn hơn âm /i/ dài | |
| 2. Miệng mở hơi rộng hơn âm /i/ | |
| 3. Luyện phân biệt: 'bit/beat', 'sit/seat' | |
| 4. Đừng kéo dài như âm 'i' tiếng Việt | |
| 5. Tập câu: 'The big fish sits in the dish' | |
| """, | |
| difficulty_level=3, | |
| ), | |
| "ʊ": PronunciationTip( | |
| phoneme="ʊ", | |
| vietnamese_name="âm u ngắn (như trong 'book')", | |
| mouth_position="Môi chu tròn nhẹ, không căng", | |
| tongue_position="Lưỡi co lại ở phía sau, thấp hơn /u/", | |
| breathing="Rung dây thanh, âm ngắn", | |
| common_mistakes=[ | |
| "Phát âm thành /u/ dài (như 'boot')", | |
| "Chu môi quá mạnh", | |
| "Kéo dài âm", | |
| ], | |
| practice_words=["book", "look", "good", "put", "could"], | |
| detailed_instruction=""" | |
| Cách luyện tập chi tiết: | |
| 1. Thư giãn hơn âm /u/ dài | |
| 2. Môi chu tròn nhẹ, không căng | |
| 3. Luyện phân biệt: 'book/boot', 'look/Luke' | |
| 4. Âm ngắn và êm dịu | |
| 5. Tập câu: 'Look at the good book' | |
| """, | |
| difficulty_level=3, | |
| ), | |
| "ŋ": PronunciationTip( | |
| phoneme="ŋ", | |
| vietnamese_name="âm ng (như trong 'sing')", | |
| mouth_position="Miệng mở tự nhiên", | |
| tongue_position="Phần sau lưỡi chạm vào vòm miệng mềm", | |
| breathing="Rung dây thanh, khí đi qua mũi", | |
| common_mistakes=[ | |
| "Thêm âm /g/ ở cuối (sing thành 'singg')", | |
| "Phát âm thành /n/", | |
| "Không dùng mũi", | |
| ], | |
| practice_words=["sing", "ring", "long", "thing", "walking"], | |
| detailed_instruction=""" | |
| Cách luyện tập chi tiết: | |
| 1. Phần sau lưỡi chạm vòm miệng mềm - như chuẩn bị nuốt | |
| 2. KHÔNG phát âm /g/ ở cuối | |
| 3. Khí ra qua mũi, không qua miệng | |
| 4. Luyện: 'sin' vs 'sing' - cảm nhận khác biệt | |
| 5. Tập câu: 'The king is singing a long song' | |
| """, | |
| difficulty_level=2, | |
| ), | |
| } | |
| return tips | |
| def _initialize_error_patterns(self) -> Dict[str, List[str]]: | |
| """Initialize common error patterns for Vietnamese speakers""" | |
| return { | |
| "th_sounds": [ | |
| "Âm /θ/ và /ð/ là khó nhất với người Việt - hãy kiên nhẫn luyện tập", | |
| "Đặt gương trước mặt để kiểm tra vị trí lưỡi khi phát âm /θ/ và /ð/", | |
| "Luyện tập /θ/ và /ð/ ít nhất 10 phút mỗi ngày", | |
| ], | |
| "v_w_confusion": [ | |
| "Nhớ: âm /v/ chỉ dùng môi dưới, âm /w/ dùng cả hai môi", | |
| "Luyện cặp từ: 'very/wary', 'vest/west' để phân biệt /v/ và /w/", | |
| "Đặt ngón tay lên môi trên khi tập âm /v/ để tránh cử động", | |
| ], | |
| "r_l_confusion": [ | |
| "Âm /r/ tiếng Anh không rung lưỡi như tiếng Việt", | |
| "Âm /l/ cần đầu lưỡi chạm nướu răng trên", | |
| "Luyện từ có cả /r/ và /l/: 'really', 'library', 'world'", | |
| ], | |
| "final_consonants": [ | |
| "Phát âm âm cuối rõ ràng nhưng không thêm nguyên âm", | |
| "Tập nhóm âm cuối: -st, -nd, -th, -ng", | |
| "Đừng nuốt âm cuối như trong tiếng Việt", | |
| ], | |
| "vowel_length": [ | |
| "Phân biệt nguyên âm dài/ngắn: /i/ vs /ɪ/, /u/ vs /ʊ/", | |
| "Nguyên âm tiếng Anh có nhiều biến thể hơn tiếng Việt", | |
| "Luyện các cặp tối thiểu: 'bit/beat', 'book/boot'", | |
| ], | |
| } | |
| def get_detailed_tip(self, phoneme: str) -> Optional[PronunciationTip]: | |
| """Get detailed pronunciation tip for a specific phoneme""" | |
| return self.tips_database.get(phoneme) | |
| def get_error_pattern_tips(self, error_phonemes: List[str]) -> List[str]: | |
| """Get tips based on common error patterns""" | |
| tips = [] | |
| # Analyze error patterns | |
| has_th_sounds = any(p in ["θ", "ð"] for p in error_phonemes) | |
| has_v_w = any(p in ["v", "w"] for p in error_phonemes) | |
| has_r_l = any(p in ["r", "l"] for p in error_phonemes) | |
| if has_th_sounds: | |
| tips.extend(random.sample(self.error_patterns["th_sounds"], 2)) | |
| if has_v_w: | |
| tips.extend(random.sample(self.error_patterns["v_w_confusion"], 1)) | |
| if has_r_l: | |
| tips.extend(random.sample(self.error_patterns["r_l_confusion"], 1)) | |
| return tips | |
| def get_comprehensive_feedback( | |
| self, incorrect_phonemes: List[str], difficulty_threshold: float = 0.7 | |
| ) -> Dict[str, any]: | |
| """ | |
| Generate comprehensive feedback with detailed tips | |
| Args: | |
| incorrect_phonemes: List of phonemes that were pronounced incorrectly | |
| difficulty_threshold: Score threshold below which to provide detailed tips | |
| Returns: | |
| Dictionary with comprehensive feedback and tips | |
| """ | |
| if not incorrect_phonemes: | |
| return { | |
| "status": "excellent", | |
| "message": "Phát âm xuất sắc! Bạn đã phát âm chính xác.", | |
| "tips": [], | |
| "practice_suggestions": [ | |
| "Tiếp tục luyện tập để duy trì độ chính xác", | |
| "Thử các từ khó hơn để thách thức bản thân", | |
| ], | |
| } | |
| # Get detailed tips for each problematic phoneme | |
| detailed_tips = [] | |
| practice_words = set() | |
| for phoneme in incorrect_phonemes[:3]: # Limit to top 3 problematic phonemes | |
| tip = self.get_detailed_tip(phoneme) | |
| if tip: | |
| detailed_tips.append( | |
| { | |
| "phoneme": phoneme, | |
| "vietnamese_name": tip.vietnamese_name, | |
| "instruction": tip.detailed_instruction, | |
| "common_mistakes": tip.common_mistakes, | |
| "difficulty": tip.difficulty_level, | |
| } | |
| ) | |
| practice_words.update(tip.practice_words[:3]) | |
| # Get pattern-based tips | |
| pattern_tips = self.get_error_pattern_tips(incorrect_phonemes) | |
| # Generate practice suggestions | |
| practice_suggestions = [ | |
| f"Luyện tập các từ này: {', '.join(list(practice_words)[:5])}", | |
| "Tập phát âm trước gương để kiểm tra vị trí môi và lưỡi", | |
| "Thu âm và nghe lại để so sánh với bản gốc", | |
| "Luyện tập 10-15 phút mỗi ngày cho mỗi âm khó", | |
| ] | |
| return { | |
| "status": "needs_improvement", | |
| "message": f"Cần cải thiện {len(incorrect_phonemes)} âm. Đừng nản lòng, cứ luyện tập từ từ!", | |
| "detailed_tips": detailed_tips, | |
| "pattern_tips": pattern_tips, | |
| "practice_suggestions": practice_suggestions, | |
| "priority_phonemes": incorrect_phonemes[ | |
| :2 | |
| ], # Focus on top 2 most problematic | |
| } | |
| def get_encouragement_message(self, score: float) -> str: | |
| """Get encouraging message based on score""" | |
| if score >= 0.9: | |
| messages = [ | |
| "Tuyệt vời! Phát âm của bạn rất chuẩn!", | |
| "Xuất sắc! Bạn đã tiến bộ rất nhiều!", | |
| "Hoàn hảo! Tiếp tục duy trì nhé!", | |
| ] | |
| elif score >= 0.8: | |
| messages = [ | |
| "Rất tốt! Chỉ còn một vài điểm nhỏ cần cải thiện.", | |
| "Tuyệt! Bạn đang trên đúng con đường.", | |
| "Giỏi lắm! Tiếp tục cố gắng nhé!", | |
| ] | |
| elif score >= 0.6: | |
| messages = [ | |
| "Khá tốt! Hãy tập trung vào những âm được gạch chân.", | |
| "Bạn đang tiến bộ! Cứ luyện tập đều đặn.", | |
| "Tốt đấy! Từ từ sẽ chuẩn thôi.", | |
| ] | |
| elif score >= 0.4: | |
| messages = [ | |
| "Đừng nản lòng! Mọi người đều phải trải qua giai đoạn này.", | |
| "Tiếp tục cố gắng! Luyện tập là chìa khóa thành công.", | |
| "Bạn đang học! Mỗi lần luyện là một bước tiến.", | |
| ] | |
| else: | |
| messages = [ | |
| "Bạn đang bắt đầu hành trình! Hãy luyện chậm và rõ ràng.", | |
| "Đừng vội! Phát âm cần thời gian để hoàn thiện.", | |
| "Cứ bình tĩnh luyện tập, bạn sẽ tiến bộ nhanh thôi!", | |
| ] | |
| return random.choice(messages) | |
| def get_audio_quality_tips(self) -> List[str]: | |
| """Get tips for better audio recording quality""" | |
| return [ | |
| "Nói to và rõ ràng hơn - microphone cần âm thanh đủ mạnh", | |
| "Tìm nơi yên tĩnh để thu âm, tránh tiếng ồn xung quanh", | |
| "Giữ khoảng cách 15-20cm từ miệng đến microphone", | |
| "Nói chậm rãi và phát âm từng âm một cách rõ ràng", | |
| "Kiểm tra microphone có hoạt động tốt không", | |
| "Thử thu âm lại nếu âm thanh không rõ ràng", | |
| ] | |
| def get_retry_encouragement(self) -> str: | |
| """Get encouraging message for retry attempts""" | |
| messages = [ | |
| "Không sao! Hãy thử lại và nói to hơn một chút.", | |
| "Microphone không nghe rõ. Bạn có thể nói rõ ràng hơn không?", | |
| "Thử nói chậm và to hơn để hệ thống có thể nhận diện tốt hơn.", | |
| "Đừng lo! Hãy thở sâu và thử lại một lần nữa.", | |
| "Có thể do tiếng ồn xung quanh. Hãy tìm nơi yên tĩnh hơn và thử lại.", | |
| ] | |
| return random.choice(messages) | |
| # Global instance for easy access | |
| vietnamese_tips = VietnameseTipsProvider() | |
| def get_phoneme_tip(phoneme: str) -> Optional[str]: | |
| """Quick access function to get tip for a phoneme""" | |
| tip = vietnamese_tips.get_detailed_tip(phoneme) | |
| return tip.detailed_instruction if tip else None | |
| def get_quick_tips(phonemes: List[str]) -> List[str]: | |
| """Get quick tips for a list of phonemes""" | |
| tips = [] | |
| for phoneme in phonemes[:3]: # Limit to 3 most important | |
| tip = vietnamese_tips.get_detailed_tip(phoneme) | |
| if tip: | |
| tips.append(f"Âm /{phoneme}/: {tip.vietnamese_name} - {tip.mouth_position}") | |
| return tips | |