diff --git a/doge_poetry.py b/doge_poetry.py index 1e35085..e2c22ac 100644 --- a/doge_poetry.py +++ b/doge_poetry.py @@ -2,17 +2,16 @@ NAME: EMILY YEH DATE: MARCH 12, 2016 DESCRIPTION: Generates a poem using words from Shakespeare's texts (which I mined from Project Gutenberg's website). - ADDITIONAL NOTES: Sorry this is late! Since everyone else was working on this during the two weeks I was in the hospital, I thought that it would probably be okay if I worked on it during the week of spring break, after Mini-Project 4 was over. Thanks for your patience and understanding! + ADDITIONAL NOTES: I added a 'clean_gutenberg_text' function, added more prepositions to my list, made the final 'poem' function loopable (so it is a little more readable now), and added a bunch of fun new functions! Now, you can choose to feed doge a treat to get happy poems! If you don't feed doge a treat, then doge generates a sad poem! """ +from pattern.en import sentiment from string import * from random import * -def get_word_list(file_name): - """ Strips punctuation and whitespace. Returns a list of the words used in the book as a list. All words are converted to lower case. +def clean_gutenberg_text(file_name): + """ Cleans up text from a Gutenberg text file. """ - new_list = [] - f = open(file_name,'r') lines = f.readlines() curr_line = 0 @@ -22,16 +21,17 @@ def get_word_list(file_name): while lines[end_line].find("End of the Project Gutenberg EBook") == -1: end_line -= 1 lines = lines[curr_line + 1:end_line] # Cleaning up the text - long_lines = ''.join(str(e) for e in lines) long_lines = long_lines.replace("<>", "") - long_lines = long_lines.lower() - long_lines = long_lines.translate(None, punctuation) - - words = long_lines.split() - for item in words: - new_list.append(item) + return long_lines +def get_word_list(text): + """ Strips punctuation and whitespace. Returns a list of the words used in the book as a list. All words are converted to lower case. + """ + modified_text = text.lower() + modified_text = modified_text.translate(None, punctuation) + words = modified_text.split() + new_list = [item for item in words] return new_list def get_top_n_words(word_list, n): @@ -40,18 +40,14 @@ def get_top_n_words(word_list, n): word_counts = dict() for word in word_list: word_counts[word] = 1 + word_counts.get(word,0) - words_list = word_counts sorted_list = sorted(words_list.items(), key = lambda x: x[1]) final_list = [] - i = -1 while i > ((-1 * n) - 1): final_list.append(sorted_list[i]) i -= 1 - list_without_numbers = [x[0] for x in final_list] - return list_without_numbers rhymes = [] @@ -60,50 +56,82 @@ def rhymes_with_wow(word): """ Takes a word and checks to see if it rhymes with wow by checking if the last two letters are 'o' and 'w'. (Note: Some words that end in -ow don't actually rhyme with wow, but that's okay.) """ j = ['o', 'w'] - blank = [] - for i in word: - blank.append(i) + blank = [i for i in word] if blank[-2:] == j: rhymes.append(word) return rhymes else: pass -def poem(text, n): +def poem(text, n, stanzas): """ Where the magic happens! Takes a text (in this case, Shakespeare, but it can be anything) and a value for the number of words to retrieve, and spits out a doge-ified poem. The poem almost certainly will not make sense, but that's supposed to be a feature, not a bug. """ - word_list = get_top_n_words(get_word_list(text), n) + word_list = get_top_n_words(get_word_list(clean_gutenberg_text(text)), n) for x in word_list: rhymes_with_wow(x) - prepositions = ["above", "across", "after", "at", "upon", "under", "beneath", "over", "beyond", "past", "of", "to", "with", "without", "from"] + prepositions = ["above", "across", "after", "at", "upon", "under", "beneath", "over", "beyond", "past", "of", "to", "with", "without", "from", "underneath", "about", "against", "along", "among", "around", "down", "during", "except", "for", "in", "inside", "into", "like", "near", "off", "on", "since", "toward", "through", "upon", "within"] i = randint(120, n) # Will give a list of mostly nouns j = randint(2, len(prepositions)-1) # Will give a random preposition k = randint(8, 120) # Will give mostly personal pronouns, articles, etc. r = randint(2, len(rhymes)-1) # Will give a word that rhymes (ish) with wow - poem = "mini-project 3: doge writes poetry!\n\n" - poem += "title: {} {}'s {} {}\n\n".format(word_list[0], word_list[i-200], word_list[i-400], word_list[i-600]) + poem = "MINI-PROJECT 3: DOGE WRITES POETRY!\n\n" + poem += "TITLE: {} {}'s {} {}\n\n".format(word_list[0], word_list[i-200], word_list[i-400], word_list[i-600]) - # Stanza 1 - poem += "{} {}, {} {}, {} {}\n".format(word_list[0], word_list[i], word_list[0], word_list[i-1], word_list[0], word_list[i-2]) - poem += "{} {}, {}, {}\n".format(prepositions[j], word_list[i-3], word_list[i-4], rhymes[r]) - poem += "{} {}, {} {}, {} {}\n".format(word_list[k], word_list[i-5], word_list[k-1], word_list[i-6], word_list[k-2], word_list[i-7]) - poem += "much {}, very {}, wow\n\n".format(word_list[i-8], word_list[i-9]) - - # Stanza 2 - poem += "{} {}, {} {}, {} {}\n".format(word_list[1], word_list[i-10], word_list[1], word_list[i-11], word_list[1], word_list[i-12]) - poem += "{} {}, {}, {}\n".format(prepositions[j-1], word_list[i-13], word_list[i-14], rhymes[r-1]) - poem += "{} {}, {} {}, {} {}\n".format(word_list[k-3], word_list[i-15], word_list[k-4], word_list[i-16], word_list[k-5], word_list[i-17]) - poem += "so {}, such {}, wow\n\n".format(word_list[i-18], word_list[i-19]) - - # Stanza 3 - poem += "{} {}, {} {}, {} {}\n".format(word_list[9], word_list[i-20], word_list[9], word_list[i-21], word_list[9], word_list[i-22]) - poem += "{} {}, {}, {}\n".format(prepositions[j-2], word_list[i-23], word_list[i-24], rhymes[r-2]) - poem += "{} {}, {} {}, {} {}\n".format(word_list[k-6], word_list[i-25], word_list[k-7], word_list[i-26], word_list[k-8], word_list[i-27]) - poem += "much {}, VERY {}, wow".format(word_list[i-28], word_list[i-29]) + for y in range(stanzas): + poem += "{} {}, {} {}, {} {}\n".format(word_list[y], word_list[i-(7*y)], word_list[y], word_list[i-1-(7*y)], word_list[y], word_list[i-2-(7*y)]) + poem += "{} {}, {}, {}\n".format(prepositions[j-y], word_list[i-3-(97*y)], word_list[i-4-(97*y)], rhymes[r-y]) + poem += "{} {}, {} {}, {} {}\n".format(word_list[k-y], word_list[i-5-(47*y)], word_list[k-1-y], word_list[i-6-(47*y)], word_list[k-2-y], word_list[i-7-(47*y)]) + poem += "much {}, very {}, wow\n\n".format(word_list[i-8-(47*y)], word_list[i-9-(5*y)]) + # Why such wonky numbers? Well, 7, 47, and 97 are all prime numbers, so I thought that if I used them, it'd be less likely for the indices to overlap. + poem += "how did doge do? (such poetry) (many wurdz) (((wow)))\n" return poem -print poem("Shakespeare.txt", 10000) \ No newline at end of file +def positive_sentiment(text, n, stanzas): + """ Return an AWESOME poem! Because you gave doge a treat! + """ + generated_poem = poem(text, n, stanzas) + poem_sentiment = sentiment(generated_poem)[0] + if poem_sentiment > 0: + polarity = poem_sentiment + else: + while poem_sentiment <= 0: + generated_poem = poem(text, n, stanzas) # Continue generating poems until we get one with a positive polarity + if sentiment(generated_poem)[0] > 0: + polarity = sentiment(generated_poem)[0] + break + response = "doge's poem... was... AWESOME!!!!!! yayayayay" + generated_poem += "happiness rating (-1 to +1): {}\n{}\n".format(polarity, response) + return generated_poem + +def negative_sentiment(text, n, stanzas): + """ Return a sad poem... because you didn't give doge a treat... + """ + generated_poem = poem(text, n, stanzas) + poem_sentiment = sentiment(generated_poem)[0] + if poem_sentiment < 0: + polarity = poem_sentiment + else: + while poem_sentiment >= 0: + generated_poem = poem(text, n, stanzas) # Continue generating poems until we get one with a positive polarity + if sentiment(generated_poem)[0] < 0: + polarity = sentiment(generated_poem)[0] + break + response = "doge's poem...\nwas...\nnot gud... because sad doge is still sad...\ntry feeding doge a treat!" + generated_poem += "happiness rating (-1 to +1): {}\n{}\n".format(polarity, response) + return generated_poem + +def poem_and_treat(text, n, stanzas): + """ Allows user to give doge a treat in order to make the poem have a positive polarity (in other words, an awesome poem). Alternatively, if doge is not given a treat, the poem will have a negative polarity (in other words, a sad poem). + """ + treat = raw_input("Give doge a treat? (y/n) ") # Feed doge a treat! + if treat == "y": + treat_poem = "\nTREAT!!!!!!!1!!!ONE!!!!!\nDOGE WILL MAKE AWESOME POEM!!! FOR TREAT!!!!!!\n\n" + positive_sentiment(text, n, stanzas) + else: + treat_poem = "\ntreat? treat??? no...?\nsad doge is sad...\n\n" + negative_sentiment(text, n, stanzas) + return treat_poem + +print poem_and_treat("Shakespeare.txt", 10000, 2) # Takes as input the text, the number of words to include in the word bank, and the number of stanzas \ No newline at end of file