Rhyme / app.py
JaeSwift's picture
Update app.py
bd23bae verified
raw
history blame
3.68 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):
"""
Automatically detect the syllable count based on vowel sounds,
then return the appropriate rhyming tail.
"""
vowels = [phone for phone in phones if phone[0] in 'AEIOU']
syllable_count = len(vowels)
if syllable_count < 1:
return None
return phones[-syllable_count * 2:] # Use the detected syllable count to get rhyming tail
def get_exact_rhymes(phones):
rhyming_tail = _get_rhyming_tail(phones)
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))]
return exact_rhymes
def get_filtered_loose_rhymes(phones):
"""
Fallback function to find words with a similar ending sound by allowing slight variations.
Applies additional filtering to avoid unrelated results.
"""
rhyming_tail = _get_rhyming_tail(phones)
if not rhyming_tail:
return []
search_pattern = " ".join(phone[:-1] + "." for phone in rhyming_tail)
matches = pronouncing.search(search_pattern)
# Filter matches to ensure they closely resemble the original word's rhyme structure
filtered_rhymes = [match for match in matches if match != phones]
return filtered_rhymes
def find_rhymes_for_phrase(phrase):
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)
# If no exact rhymes are found, fallback to filtered loose rhymes
if exact_rhymes:
rhyming_options.append(exact_rhymes)
else:
loose_rhymes = get_filtered_loose_rhymes(phones)
if loose_rhymes:
rhyming_options.append(loose_rhymes)
else:
rhyming_options.append([f"{word} (No rhymes found)"])
combined_results = list(itertools.product(*rhyming_options))
unique_results = set(" ".join(combination) for combination in combined_results)
# Return a list of unique rhyming combinations
return list(unique_results)
# Function to update the notepad with a selected rhyme
def add_to_notepad(notepad, selected_rhyme):
return notepad + " " + selected_rhyme
# Gradio Interface
with gr.Blocks() as demo:
gr.Markdown("## Interactive Rhyming Generator with Notepad")
# Inputs for the rhyming generator
phrase_input = gr.Textbox(label="Enter phrase (space-separated words)")
# Output areas
rhyme_output = gr.Dataframe(headers=["Rhyming Phrases"], interactive=False)
notepad = gr.Textbox(label="Notepad", lines=10, placeholder="Write your lyrics here...")
# Button for generating rhymes
generate_btn = gr.Button("Generate Rhymes")
# Functionality to select a rhyme and add it to the notepad
rhyme_output.change(add_to_notepad, inputs=[notepad, rhyme_output], outputs=notepad)
# Display rhyming results and update notepad on button click
generate_btn.click(find_rhymes_for_phrase, inputs=[phrase_input], outputs=rhyme_output)
demo.launch()