skip to Main Content

In trying to generate a list of words with a specific number of syllables from datamuse api, and choosing a random one of those words to print, I often recieve an index error while I know the list cannot possibly be empty. Each subsequent word relies on parameters pertaining to the previous word. My full code has 7 words but all are essentially a copy of the second word. With all 7 words, yes, a list will sometimes be empty, but in the case with only 2 words and the given parameters I don’t understand why it is happenening.

`import json, requests, random


# FIRST WORD
related_word = input("word: ")
#create list for related words
parameters = {
    'rel_trg': related_word,
    'md': 's'  # Request the number of syllables for each word
}
response = requests.get('https://api.datamuse.com/words', params=parameters)
related = response.json()

three_syllable_words = [] # creates list for three syllable words

for word in related:
    num_syllables = word.get('numSyllables', 0)
    if num_syllables == 3:                          #filters list to only 3 syllable words
        three_syllable_words.append(word)       

#select random three_syllable_word
first_three_sylword = random.choice(three_syllable_words)
first_word = first_three_sylword['word'] #use only word data
#print(first_word)

# Second Word
parameters2 = {
    'rel_rhy':first_word,  # Rhymes
    'lc':first_word,  # Left context to the original word entered by the user
    'md': 's'  # Request the number of syllables for each word
    }

response2 = requests.get('https://api.datamuse.com/words', params=parameters2)
lcrhyme = response2.json()

two_syllable_words = []

for word in lcrhyme:
    num_syllables = word.get('numSyllables', 0)
    if num_syllables == 3:
        two_syllable_words.append(word)


first_two_syl_word = random.choice((two_syllable_words))
second_word = first_two_syl_word['word']
print(second_word, first_word)`

2

Answers


  1. I often recieve an index error while I know the list cannot possibly be empty.

    Why do you think so?

    
    response = requests.get('https://api.datamuse.com/words', params=parameters)
    related = response.json()
    
    print(related)
    
    three_syllable_words = [] # creates list for three syllable words
    
    for word in related:
        num_syllables = word.get('numSyllables', 0)
        if num_syllables == 3:                          #filters list to only 3 syllable words
            three_syllable_words.append(word)       
    
    #select random three_syllable_word
    first_three_sylword = random.choice(three_syllable_words)
    
    

    What do you think happens if related is empty?

    Try

    random.choice([])
    
    Login or Signup to reply.
  2. As pointed out by @daviid in the answer here, the issue is that sometimes the API cannot find "related" or "rhyming" words for a given word. In those cases, calls to random.choice() get passed an empty list and that is going to throw the error you see.

    You need to guard against those instances. Perhaps like:

    word  = random.choice(words)["word"] if words else ""
    

    Here is how I might initially address the task:

    import random
    import requests
    
    def get_related_rhyme(word, related_syllables=3, rhyme_syllables=2):
        related_word = get_related_word(word, related_syllables)
        related_rhyme = get_rhyming_word(related_word, rhyme_syllables)
        return (related_word, related_rhyme)
    
    def get_related_word(word, syllables):
        if not word or not syllables:
            return ""
    
        url = "https://api.datamuse.com/words"
        parameters = {"rel_trg": word, "md": "s"}
        response = requests.get(url, params=parameters)
        words = response.json()
        return get_random_word(words, syllables)
    
    def get_rhyming_word(word, syllables):
        if not word or not syllables:
            return ""
    
        url = "https://api.datamuse.com/words"
        parameters = {"rel_rhy":word, "lc":word, "md": "s"}
        response = requests.get(url, params=parameters)
        words = response.json()
        return get_random_word(words, syllables)
    
    def get_random_word(words, syllables):
        syllable_words = [
            word
            for word
            in words
            if word.get("numSyllables", 0) == syllables
        ]
        return random.choice(syllable_words)["word"] if syllable_words else ""
    
    TEMPLATE = '''word: "{w}", related: "{rw}", related rhyme: "{rr}"'''
    
    word = "parkinglot"
    related_word, related_rhyme = get_related_rhyme(word)
    print(TEMPLATE.format(w=word, rw=related_word, rr=related_rhyme))
    
    word = "apartment"
    related_word, related_rhyme = get_related_rhyme(word)
    print(TEMPLATE.format(w=word, rw=related_word, rr=related_rhyme))
    

    That will likely give you a result like:

    word: "parkinglot", related: "", related rhyme: ""
    word: "apartment", related: "manhattan", related rhyme: "patin"
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search