Spaces:
Sleeping
Sleeping
| import eng_to_ipa | |
| import pronouncing | |
| # US | |
| def convert_word_to_ipa(word): | |
| try: | |
| word_pron = eng_to_ipa.convert(word) | |
| if word_pron == word or '*' in word_pron: | |
| return None | |
| return word_pron | |
| except Exception: | |
| return None | |
| def get_stress_pattern(word): | |
| """ | |
| Args: | |
| word: str | |
| Returns: | |
| the stress position | |
| Explain: | |
| The function pronouncing.stresses_for_word returns a list where: | |
| 1 indicates primary stress (main stress), | |
| 2 indicates secondary stress, | |
| 0 indicates no stress. | |
| """ | |
| list_pattern = pronouncing.stresses_for_word(word) | |
| if list_pattern is None or list_pattern == []: | |
| return None | |
| pattern = list_pattern[0] | |
| if len(pattern) == 1: | |
| return None | |
| try: | |
| index = pattern.index('1') + 1 | |
| return index | |
| except ValueError: | |
| return None | |
| import random | |
| from typing import Optional | |
| import nltk | |
| nltk.download('wordnet') | |
| from nltk.corpus import wordnet as wn | |
| def ç(word: str) -> Optional[str]: | |
| """ | |
| Transform a word into another word by changing its type, tense, article-related form, | |
| or meaning to create an incorrect answer for a 'find the wrong word' question. | |
| Args: | |
| word (str): The input word to transform. | |
| Returns: | |
| Optional[str]: The transformed word, or None if no transformation is possible. | |
| """ | |
| # List of possible transformations | |
| transformation_methods = [ | |
| transform_preposition, # Handle prepositions | |
| transform_word_type, # Change word type (e.g., noun to verb) | |
| transform_tense, # Change verb tense | |
| transform_article, # Change article-related form | |
| transform_meaning # Change to a word with different meaning | |
| ] | |
| # Randomly select a transformation method | |
| random.shuffle(transformation_methods) | |
| for method in transformation_methods: | |
| transformed = method(word) | |
| if transformed and transformed != word: | |
| return transformed | |
| # Fallback: return a random word from nltk_words if no transformation works | |
| try: | |
| from src.factories.gen_question.types.base import nltk_words | |
| return random.choice(nltk_words) if nltk_words else None | |
| except ImportError: | |
| return None | |
| def transform_preposition(word: str) -> Optional[str]: | |
| """ | |
| Transform a preposition into another preposition that is likely to be incorrect in context. | |
| Args: | |
| word (str): The input word to check and transform. | |
| Returns: | |
| Optional[str]: A different preposition, or None if the input is not a preposition. | |
| """ | |
| # Common prepositions and their common incorrect substitutions | |
| preposition_map = { | |
| 'in': ['on', 'at', 'to'], | |
| 'on': ['in', 'at', 'over'], | |
| 'at': ['in', 'on', 'by'], | |
| 'to': ['in', 'at', 'for'], | |
| 'for': ['to', 'with', 'in'], | |
| 'with': ['for', 'by', 'in'], | |
| 'by': ['with', 'at', 'on'], | |
| 'from': ['to', 'in', 'at'], | |
| 'of': ['for', 'in', 'on'] | |
| } | |
| word_lower = word.lower() | |
| if word_lower in preposition_map: | |
| return random.sample(preposition_map[word_lower], 1)[0] | |
| return None | |
| def transform_word_type(word: str) -> Optional[str]: | |
| """ | |
| Transform a word by changing its part of speech (e.g., noun to verb). | |
| Uses WordNet to find related words with different POS. | |
| """ | |
| pos_map = { | |
| 'n': 'v', # Noun to verb | |
| 'v': 'n', # Verb to noun | |
| 'a': 'r', # Adjective to adverb | |
| 'r': 'a' # Adverb to adjective | |
| } | |
| # Get part of speech for the word | |
| synsets = wn.synsets(word) | |
| if not synsets: | |
| return None | |
| current_pos = synsets[0].pos() # Get the first synset's POS | |
| target_pos = pos_map.get(current_pos) | |
| if not target_pos: | |
| return None | |
| # Find a synset with the target POS | |
| for synset in wn.synsets(word): | |
| if synset.pos() == target_pos: | |
| return synset.lemmas()[0].name().replace('_', ' ') | |
| return None | |
| def transform_tense(word: str) -> Optional[str]: | |
| """ | |
| Transform a verb by changing its tense (e.g., present to past). | |
| Uses simple rules for common verb forms. | |
| """ | |
| # Simple past tense rules for regular verbs | |
| if word.endswith('e'): | |
| return word + 'd' # e.g., love -> loved | |
| elif word.endswith('y') and word[-2] not in 'aeiou': | |
| return word[:-1] + 'ied' # e.g., study -> studied | |
| elif word[-1] not in 'aeiou' and word[-2] not in 'aeiou': | |
| return word + 'ed' # e.g., walk -> walked | |
| else: | |
| # Irregular verbs (small hardcoded list for simplicity) | |
| irregular = { | |
| 'run': 'ran', | |
| 'go': 'went', | |
| 'see': 'saw', | |
| 'write': 'wrote', | |
| 'is': 'was', | |
| 'are': 'were' | |
| } | |
| return irregular.get(word, None) | |
| def transform_article(word: str) -> Optional[str]: | |
| """ | |
| Transform a word related to articles (e.g., 'a' to 'an' or remove article). | |
| For nouns, return a different noun that might cause article-related errors. | |
| """ | |
| if word.lower() in ['a', 'an']: | |
| return 'an' if word.lower() == 'a' else 'a' | |
| # For nouns, find another noun that might cause article confusion | |
| synsets = wn.synsets(word, pos='n') | |
| if not synsets: | |
| return None | |
| # Pick a random synonym or related noun | |
| synonyms = [] | |
| for synset in synsets: | |
| for lemma in synset.lemmas(): | |
| synonym = lemma.name().replace('_', ' ') | |
| if synonym != word: | |
| synonyms.append(synonym) | |
| return random.sample(synonyms, 1)[0] if synonyms else None | |
| def transform_meaning(word: str) -> Optional[str]: | |
| """ | |
| Transform a word to another with a different meaning (e.g., homophone or unrelated word). | |
| """ | |
| # Find a word with different meaning but the same POS | |
| synsets = wn.synsets(word) | |
| if not synsets: | |
| return None | |
| current_pos = synsets[0].pos() | |
| # Get all words with the same POS but different synsets | |
| different_words = [] | |
| for synset in wn.all_synsets(pos=current_pos): | |
| for lemma in synset.lemmas(): | |
| candidate = lemma.name().replace('_', ' ') | |
| if candidate != word and candidate not in different_words: | |
| different_words.append(candidate) | |
| return random.sample(different_words, 1)[0] if different_words else None | |