Matthew Kaney at ITP

Assignment 4: Pronouncing Module

Reading and Writing Electronic Text


For this assignment, I focused on extending the functionality of my CMU pronouncing dictionary work from earlier in the semester, and wrapping up everything in a module I called “”.


My module can be used to test whether two words rhyme. Note that both words must be in the CMU speaking dictionary. If they’re not, then the function returns false.

>>> pronouncer.rhymingWords(‘apple’, ‘orange’)

You can also search the pronouncing dictionary for rhymes:

>>> pronouncer.findWordsWithRhyme(‘persuasive’)

Or, if you want to work within an existing corpus, you can specify a list of words to search within:

>>> pronouncer.findWordsWithRhyme(‘lemon’, [‘demon’, ‘yemen’, ‘salmon’])


Based on the stress information in the pronouncing dictionary, the module can do incredibly simple scansion-type analysis (expressed as a list of 1s, 2s, and 0s, for primary stress, secondary stress, and no stress, respectively). Currently, the system makes no attempt to guess meter for words it doesn’t know, so this isn’t always that helpful.

>>> pronouncer.getMeter(‘To sit in solemn silence’)
[1, 1, 0, 1, 0, 1, 0]

More helpful is the ability to search for words that have a given stress. Like the rhyme functions, this can either search the entire pronouncing dictionary, or a provided word list.

>>> pronouncer.findWordsWithMeter([1, 0, 1, 0, 0])

Module Code

import string

# Array of all vowel sounds in the CMU speaking dictionary
vowelSounds = ["AA", "AE", "AH", "AO", "AW", "AY", "EH", "ER", "EY",
               "IH", "IY", "OW", "OY", "UH", "UW"]

# Now, import and populate the CMU speaking dictionary
cmu = open('cmudict', 'r')

phoneticDict = {}

for line in cmu:
    tokens = line.split()
    # Only grab the first pronunciation in the dictionary, for now
    if tokens[1] == "1":
        key = tokens[0]
        phonemes = []
        stresses = []

        # Some phonemes have a number indicating stress (e.g. "EH1").
        for phoneme in tokens[2:]:
            # If this is one of those, split the phoneme from the stress
            if not phoneme.isalpha():
                phoneme = phoneme[:-1]


        phoneticDict[key] = (phonemes, stresses)


# Convert tokens (with attached whitespace, punctuation, and irregular
# capitalization) to a clean, all-caps form
def cleanWord(word):
    newWord = word.upper()
    newWord = newWord.strip(string.punctuation)
    return newWord

# Check whether two words are both a) in the pronouncing dictionary and
# b) rhyming. Returns True or False.
def rhymingWords(firstWord, secondWord):
    if firstWord == secondWord:
        return False
    firstWord = cleanWord(firstWord)
    secondWord = cleanWord(secondWord)
    if firstWord in phoneticDict:
        searchSyllables, searchStresses = phoneticDict[firstWord]
        return False
    if secondWord in phoneticDict:
        wordSyllables, wordStresses = phoneticDict[secondWord]
        return False
    lastPhoneme = ''
    stressCounter = 1
    lastStress = 0

    for i in range(1, 1 + min(len(searchSyllables), len(wordSyllables))):
        if (searchSyllables[-i] == wordSyllables[-i] and
           stressCounter <= len(wordStresses) and
           stressCounter <= len(searchStresses)):
            lastPhoneme = searchSyllables[-i]

            if lastPhoneme in vowelSounds:
                lastStress = (wordStresses[-1 * stressCounter] and
                             searchStresses[-1 * stressCounter])

                stressCounter += 1

    if (lastPhoneme in vowelSounds) and (lastStress > 0):
        return True
        return False

# For a given string, split the string into individual words and then return
# the meter of the entire string of words, in terms of stresses where
# 0 = no stress, 1 = primary stress, and 2 = secondary stress.
# For example, [1, 0, 1, 1, 0, 2]
def getMeter(line):
    words = line.strip().split()
    meter = [];
    for word in words:
        currWord = cleanWord(word);
        if currWord in phoneticDict:
            meter += phoneticDict[currWord][1]
    return meter

# Get a list of words that rhyme with a certain word. The first parameter
# is the word that the results should rhyme with. The optional second
# parameter is the list of words for searching in. If no list is specified,
# the function will search the entire pronouncing dictionary.
def findWordsWithRhyme(rhyme, searchList=phoneticDict.keys()):
    result = [];
    for word in searchList:
        if rhymingWords(rhyme, word):
    return result;

# Return a list of words that have the given pattern of stresses. The first
# parameter is a list of stresses (0, 1, or 2). The optional second parameter
# is the list of words for searching in. If no list is specified, the
# function will search the entire pronouncing dictionary.
def findWordsWithMeter(meter, searchList=phoneticDict.keys()):
    result = [];
    for word in searchList:
        cleaned = cleanWord(word);
        if cleaned in phoneticDict and phoneticDict[cleaned][1] == meter:
    return result;


  1. cheap ffxiv gil on November 23, 2015 at 9:30 am

    cheap ffxiv gil

    If he shows up, we stick with him.

  2. eso gold store on November 26, 2015 at 9:34 pm

    eso gold store

    I’ll take care of it.

  3. cheap fifa coins on December 3, 2015 at 6:40 pm

    cheap fifa coins

    The youre very professional .

  4. resource on December 30, 2015 at 6:45 pm


    Up yours!

  5. fifa coins for sale on December 31, 2015 at 8:24 pm

    fifa coins for sale

    That’s not the point.

  6. buy MUT Coins on January 3, 2016 at 11:55 am

    buy MUT Coins

    You are so cute.

  7. blade & soul gold on May 14, 2016 at 3:59 am

    blade & soul gold

    Do you have a good sense of humor .

  8. u4fifa twitter on June 7, 2016 at 1:56 pm

    u4fifa twitter

    You always know the right thing to say.

  9. u4fifa on June 7, 2016 at 7:15 pm


    nice going!

  10. on June 14, 2016 at 12:48 pm

    My way or the highway.

  11. on June 17, 2016 at 11:02 am

    hi!this is very good site!

  12. on July 9, 2016 at 4:16 am

    Leave me alone !

  13. on July 19, 2016 at 1:50 pm

    You did a good job .

  14. cheapest fifa 17 points on July 20, 2016 at 1:45 pm

    cheapest fifa 17 points

    The youre really talented .

  15. FIFA17 Android 900k coins on August 24, 2016 at 2:49 am

    FIFA17 Android 900k coins

    You have a good taste.

  16. cheapest and fastest nba 2k mt store on October 6, 2016 at 11:12 am

    cheapest and fastest nba 2k mt store

    it’s very helpful for me searching for this website!

  17. albion online gold on December 23, 2016 at 8:25 pm

    albion online gold

    The youre very eloquent .

  18. buy Final Fantasy XIV Gil on June 5, 2017 at 11:13 am

    buy Final Fantasy XIV Gil

    I have no idea what you have said

  19. Click Here on January 15, 2018 at 8:42 am

    Click Here

    be a man

  20. path of exile orbs on February 27, 2018 at 2:15 pm

    path of exile orbs

    I do not know what you are saying

The comments are closed.