Animal Naming

My brother introduced me to a “game” he plays while walking to work: if you see an animal, think of a person’s name for it that follows the same vowel-consonant pattern as that animal’s name. For instance, a duck has the pattern C-V-C-C, which is matched by John, among other names. This can become quite difficult for certain animals (e.g. kestrel) and some seem to strain the bounds of possibility (e.g. squirrel).

Since fun exists to be destroyed, here is some code that plays this “game” far better than any person. I’ve broken it up to add some commentary on the development.

# -*- coding: utf-8 -*-

import re

re is Python's Regular Expressions module. Regexes are the obvious choice for tackling a string pattern matching problem.

vowel = '[aeiouAEIOU]'
consonant = '[^aeiouAEIOU \d]'
#Note: assuming y is typically a consonant, which isn't quite true - 
# but there's no good way to tell 'vowel y' (eg 'my') 
# from 'consonant y' (eg 'your') in such a simple program
# To use a vowel y instead, add yY to both the above 
# To use y as always both a vowel and a consonant, add yY to only the first one

def getVowelPattern(word):
    '''Returns the indices of the vowels in a word'''
    vwls = re.compile(vowel).finditer(word)
    positions = []
    for v in vwls:
        pos = v.start()
        positions.append(pos)
    return positions

We start by taking an animal name and decomposing it into a pattern of vowels and consonants, here represented by the positions of the vowels. Note that this assumes all letters are exclusively either a vowel or a consonant, which adds to the difficulty of handling 'y'.

def createPattern(vwPositions, length):
    '''Create a pattern to search for, from the positions of vowels in a word
    '''
    pattern = ""
    for i in range(0,length):
        if i in vwPositions:
            pattern += vowel
        else:
            pattern += consonant
    pattern += " "
    return pattern          

This composites a bunch of the 'vowel' and 'consonant' strings together to form a pattern matching the whole word. Fairly straightforward. This pattern will be used to search for any names matching this pattern.

def searchText(pattern, text):
    # Given a file of text, search for instances of the pattern
    p = re.compile(pattern)
    for line in text:
        m = p.match(line)
        if m:
            yield m.group()
    return
        
if __name__ == "__main__":
    animal = raw_input("What animal are we naming? \n")
    vwp = getVowelPattern(animal)
    ptr = createPattern(vwp, len(animal))
    # list of names from 
    # http://deron.meranda.us/data/census-derived-all-first.txt
    with open("firstnames.txt") as f:
        srh = searchText(ptr, f)
        cont = True
        n = 0
        while cont:
            n += 1
            try:
                name = srh.next()
                print name
                if n % 3 == 0:           
                    cont = (raw_input("Continue? y/n ") == "y")
            except StopIteration:
                print "End of file reached"
                cont = False

We take a list of first names (male and female) sorted by population frequency, and apply the regular expression created above to find matches. Three matches are returned at a time with the option to continue or stop; this seemed like a good compromise between simplicity and the conflicting desires to see many names, to see the most common matches without scrolling through a list of results, and just to see if there's any matches at all.

Well, that was a lot of fun, and I got to find out what the two matches for 'squirrel' are.

Advertisements
Animal Naming

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s