import pronouncing import string import itertools import gradio as gr CONSONANTS = set(string.ascii_uppercase) - set('AEIOU') def get_phones(word): phones_for_word = pronouncing.phones_for_word(word) if not phones_for_word: return None phones = phones_for_word[0].split() return phones def _get_rhyming_tail(phones, syllable_count=1): vowels = [phone for phone in phones if phone[0] in 'AEIOU'] if len(vowels) < syllable_count: return None # Not enough syllables for the rhyme return phones[-syllable_count * 2:] def get_exact_rhymes(phones, syllable_count=1): rhyming_tail = _get_rhyming_tail(phones, syllable_count) if not rhyming_tail: return [] rhyming_tail_str = " ".join(rhyming_tail) matches = pronouncing.search(rhyming_tail_str + "$") exact_rhymes = [match for match in matches if rhyming_tail == _get_rhyming_tail(get_phones(match), syllable_count)] return exact_rhymes def get_loose_rhymes(phones, syllable_count=1): """ Fallback function to find words with a similar ending sound by allowing slight variations. """ rhyming_tail = _get_rhyming_tail(phones, syllable_count) if not rhyming_tail: return [] # Allow for near matches by replacing the last character in each phoneme with a wildcard search_pattern = " ".join(phone[:-1] + "." for phone in rhyming_tail) matches = pronouncing.search(search_pattern) return matches def find_rhymes_for_phrase(phrase, syllable_count=1): words = phrase.split() rhyming_options = [] for word in words: phones = get_phones(word) if phones is None: rhyming_options.append([f"{word} (Not recognized)"]) continue # Try to find exact rhymes first exact_rhymes = get_exact_rhymes(phones, syllable_count) # If no exact rhymes are found, fallback to looser rhymes if exact_rhymes: rhyming_options.append(exact_rhymes) else: loose_rhymes = get_loose_rhymes(phones, syllable_count) if loose_rhymes: rhyming_options.append(loose_rhymes) else: rhyming_options.append([f"{word} (No rhymes found)"]) combined_results = list(itertools.product(*rhyming_options)) if combined_results: result_str = f"Rhyming combinations for '{phrase}':\n" result_str += "\n".join(" ".join(combination) for combination in combined_results) return result_str else: return f"No rhyming combinations found for '{phrase}'" # Gradio interface iface = gr.Interface( fn=lambda phrase, syllables: find_rhymes_for_phrase(phrase, syllables), inputs=[ gr.Textbox(label="Enter phrase (space-separated words)"), gr.Slider(1, 3, step=1, label="Number of Syllables") ], outputs="text", description="Enter a phrase with any number of words to find multisyllabic rhyming combinations and similar sounds." ) if __name__ == "__main__": iface.launch()