################################################################################### ################################################################################### # Rhymatron V2- A generative, autonamous rap-phenomenon # Concept and Code by Noah King, 3/12/2010 # Mid-Term Project for Reading and Writing Electronic Text - Spring 2010 # Professor Adam Parrish ################################################################################### ################################################################################### ################################################ ################ setup and variable declaration ################################################ import sys import random diction = dict() phonemes = list() finishedLines = list() buildDictionary = 1 parseInput = 1 i = 0 wordList = list() wordList1 = list() wordList2 = list() wordList3 = list() wordList4 = list() lines = list() punct = list() words = set() wordsTemp = list() wordsNull = set() rhymeWords = list() xchars = [".", ",", ";", ":", "!", "?", "'", '"', "(", ")", "[", "]", "*"] badwords = ["i", "la", "m", "re", "et", "am", "t", "fro", "and", "dr", "um", "le", "is", "the", "she", "he", "for", "me", "to", "you", "but", "of","they", "them", "no", "yes", "d", "g"] ################################################ ################ parse/optimize input text ################################################ for line in open("twain.txt"): line = line.strip() line = line.lower() line_words = line.split(" ") for word in line_words: words.add(word) for word in words: if "-" in word or "_" in word or ".." in word or "'" in word: wordsNull.add(word) for word in wordsNull: words.remove(word) for word in words: wordsTemp.append(word) total = len(wordsTemp) for i in range(0,total): for k in range(0,5): for j in range(0,13): if len(wordsTemp[i]) > 0: if xchars[j] in wordsTemp[i][-1]: wordsTemp[i] = wordsTemp[i][0:-1] for k in range(0,5): for j in range(0,13): if len(wordsTemp[i]) > 0: if xchars[j] in wordsTemp[i][0]: wordsTemp[i] = wordsTemp[i][1:] words.clear() for word in wordsTemp: words.add(word.lower()) for word in badwords: words.remove(word) #print words ################################################ ################ build dictionary ################################################ if buildDictionary == 1: for line in open("CMU_dict.txt"): #if i < 10: #i = i + 1 line = line.strip() line = line.lower() line = line.split(" ") if line[0] in words: diction[line[0]] = line[2:] #print diction for line in open("CMU_phoneme_vowels.txt"): line = line.strip() line = line.lower() phonemes.append(line) #print phonemes ################################################ ################ count syllables ################################################ sylList = list() for key, val in diction.iteritems(): for sound in val: if sound in phonemes: sylList.append(sound) val.append(sylList) sylList = list() if 1 == 1: # AB Find all the words with one syllable, for key, val in diction.iteritems(): if len(val[-1]) == 1: wordList1.append(key) # AB Find all the words with two syllables, for key, val in diction.iteritems(): if len(val[-1]) == 2: wordList2.append(key) # AB Find all the words with three syllables, for key, val in diction.iteritems(): if len(val[-1]) == 3: wordList3.append(key) # AB Find all the words with four syllables, for key, val in diction.iteritems(): if len(val[-1]) == 4: wordList4.append(key) ################################################ ################ sample dictionary ################################################ # sample dict entries : 'revolvers': ['r', 'ih0', 'v', 'aa1', 'l', 'v', 'er0', 'z', ['ih0', 'aa1', 'er0']] # sample explained: 'word': [ phoneme list [syllable phoneme list]] ################################################ ################ define functions ################################################ def rhymer( syllableCount, rhymeList, val ): trueCount = 0 if syllableCount >= 1: if rhymeList[0] == "free": trueCount = trueCount + 1 else: if val[-1][0] == storedSyllables[rhymeList[0]]: trueCount = trueCount + 1 if syllableCount >= 2: if rhymeList[1] == "free": trueCount = trueCount + 1 else: if val[-1][1] == storedSyllables[rhymeList[1]]: trueCount = trueCount + 1 if syllableCount >= 3: if rhymeList[2] == "free": trueCount = trueCount + 1 else: if val[-1][2] == storedSyllables[rhymeList[2]]: trueCount = trueCount + 1 if syllableCount >= 4: if rhymeList[3] == "free": trueCount = trueCount + 1 else: if val[-1][3] == storedSyllables[rhymeList[3]]: trueCount = trueCount + 1 return trueCount def alliterater( alliterationBinary ): # <---- this is buggy alliteration = 0 if alliterationBinary == 1 and len(finishedLines) > 0: if val[0] == diction[finishedLines[-1]][0]: alliteration = 1 return alliteration def safeMaker(syllableCount, rhymeList): # <---- this alliterator work-around is buggy too :( wordList = list() for key, val in diction.iteritems(): if len(val[-1]) == syllableCount: if rhymer(syllableCount, rhymeList, val) == syllableCount: wordList.append(key) return wordList def matchMaker(syllableCount, rhymeList, alliterationBinary): wordList = list() if syllableCount != len(rhymeList): print "Error! Please check that there is a rhyme key for each syllable" else: for key, val in diction.iteritems(): if len(val[-1]) == syllableCount: if rhymer(syllableCount, rhymeList, val) == syllableCount: if alliterationBinary == 0: wordList.append(key) else: if alliterater(1) == 1: wordList.append(key) if len(wordList) == 0: for word in safeMaker(syllableCount,rhymeList): wordList.append(word) random.shuffle(wordList) finishedLines.append(wordList[0]) ################################################ ################ run functions ################################################ # The below four verses by rapper Mos Def were analyzed and broken down into a rhyme template # Two words, United States, no love, no breaks # Low brow, high stakes, crack smoke, black folks # Big Macs, fat folks, ecstasy capsules # Presidential scandals, everybody MOVE # Two words, Mos Deaf, K West, hot shit # Calm down, get back, ghetto people, got this # Game pawn, lock shit, gun pulled, cock shit # We won't stop shit, everybody MOVE # Two words, B K, N Y, bed sty # Two hard, too hungry, too many, that's why # These streets know game, can't ball, don't play # Heavy traffic, one lane, everybody MOVE # Two words, Mos Deaf, black jack, hot shit # Calm down, get back, ghetto people, got this # Game point lock, long pump cocked # We won't stop, everybody MOVE # this is the template, where "-" is a free syllable # A B, ---C, D B, D C, # D B, - C, E C, E C, # - E, E C, --- EC, # ---- EC, ---- A storedSyllables = dict() # the first time the words are selected rhyme keys are undefined as free syllables # then immediately afterwards they are recorded as rhyme keys matchMaker(1,["free"],0) storedSyllables["A"] = diction[finishedLines[-1]][-1][0] matchMaker(1,["free"],0) storedSyllables["B"] = diction[finishedLines[-1]][-1][0] matchMaker(4,["free", "free", "free", "free"],0) tempSyllable = diction[finishedLines[-1]][-1][3] # <---- this workaround was needed if "1" in tempSyllable: # <---- because of issues around the final syllable storedSyllables["C"] = tempSyllable # <---- being accented or not. else: # <---- changing a final syllable from unaccented tempSyllable = tempSyllable[0:-1] + "1" # <---- to accented made for a better rhyme key, storedSyllables["C"] = tempSyllable # <---- particularly for single syllable words. matchMaker(1,["free"],0) storedSyllables["D"] = diction[finishedLines[-1]][-1][0] matchMaker(1,["B"],0) matchMaker(1,["D"],0) matchMaker(1,["C"],0) matchMaker(1,["D"],0) matchMaker(1,["B"],0) matchMaker(1,["free"],0) matchMaker(1,["C"],0) matchMaker(1,["free"],0) storedSyllables["E"] = diction[finishedLines[-1]][-1][0] matchMaker(1,["C"],0) matchMaker(1,["E"],0) matchMaker(1,["C"],0) matchMaker(1,["free"],0) matchMaker(1,["E"],0) matchMaker(1,["E"],0) matchMaker(1,["C"],0) matchMaker(3,["free", "free", "free"],0) matchMaker(2,["free", "C"],0) matchMaker(4,["free", "free", "free", "free"],0) matchMaker(2,["free", "C"],0) matchMaker(4,["free", "free", "free", "free"],0) matchMaker(1,["A"],0) ######second through fourth verses for i in range (0,4): matchMaker(1,["A"],0) matchMaker(1,["B"],0) matchMaker(4,["free", "free", "free", "free"],0) matchMaker(1,["D"],0) matchMaker(1,["B"],0) matchMaker(1,["D"],0) matchMaker(1,["C"],0) matchMaker(1,["D"],0) matchMaker(1,["B"],0) matchMaker(1,["free"],0) matchMaker(1,["C"],0) matchMaker(1,["free"],0) matchMaker(1,["C"],0) matchMaker(1,["E"],0) matchMaker(1,["C"],0) matchMaker(1,["free"],0) matchMaker(1,["E"],0) matchMaker(1,["E"],0) matchMaker(1,["C"],0) matchMaker(3,["free", "free", "free"],0) matchMaker(2,["free", "C"],0) matchMaker(4,["free", "free", "free", "free"],0) matchMaker(2,["free", "C"],0) matchMaker(4,["free", "free", "free", "free"],0) matchMaker(1,["A"],0) #print finishedLines ################################################ ################ print words ################################################ if 1 == 1: fl = finishedLines tempCounter = [0, 25, 50, 75] for i in tempCounter: print fl[i + 0] + " " + fl[i + 1] + ", " + fl[i + 2] + ", " + fl[i + 3] + " " + fl[i + 4] + ", " + fl[i + 5] + " " + fl[i + 6] + "," print fl[i + 7] + " " + fl[i + 8] + ", " + fl[i + 9] + " " + fl[i + 10] + ", " + fl[i + 11] + " " + fl[i + 12] + ", " + fl[i + 13] + " " + fl[i + 14] + "," print fl[i + 15] + " " + fl[i + 16] + ", " + fl[i + 17] + " " + fl[i + 18] + ", " + fl[i + 19] + " " + fl[i + 20] + "," print fl[i + 21] + " " + fl[i + 22] + ", " + fl[i + 23] + " " + fl[i + 24] + ".\n"