Rhyme / app.py
JaeSwift's picture
Update app.py
6b49f37 verified
raw
history blame
3.08 kB
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()