2015-06-07 20:27:59 +00:00
|
|
|
import nltk
|
|
|
|
import random
|
2015-07-14 04:03:05 +00:00
|
|
|
import re
|
|
|
|
from textstat.textstat import textstat
|
|
|
|
#from stat_parser import Parser
|
2015-06-07 20:27:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
class PoemGenerator():
|
|
|
|
def __init__(self, corpus):
|
2015-07-14 04:03:05 +00:00
|
|
|
#self.sents = corpus.sents('austen-emma.txt')
|
|
|
|
self.bigrams = list(nltk.bigrams(corpus.words('shakespeare-hamlet.txt')))
|
|
|
|
self.only_punctuation = re.compile(r'[^\w\s]+$')
|
|
|
|
self.all_words = [bigram[0] for bigram in self.bigrams
|
|
|
|
if not self.only_punctuation.match(bigram[0])]
|
2015-06-07 20:27:59 +00:00
|
|
|
self.cfd = nltk.ConditionalFreqDist(self.bigrams)
|
2015-07-14 04:03:05 +00:00
|
|
|
#self.parser = Parser()
|
2015-06-07 20:27:59 +00:00
|
|
|
self.history = []
|
|
|
|
|
2015-07-14 04:03:05 +00:00
|
|
|
def markov(self, word, n):
|
|
|
|
if n > 0:
|
|
|
|
print word,
|
|
|
|
n = n - 1
|
|
|
|
self.markov(random.choice(self.cfd[word].items())[0], n)
|
|
|
|
else:
|
|
|
|
print ''
|
|
|
|
|
2015-06-07 20:27:59 +00:00
|
|
|
def generate_poem(self):
|
2015-07-14 04:03:05 +00:00
|
|
|
#sent = random.choice(self.sents)
|
|
|
|
#parsed = self.parser.parse(' '.join(sent))
|
2015-06-07 20:27:59 +00:00
|
|
|
word = random.choice(self.bigrams)[0]
|
2015-07-14 04:03:05 +00:00
|
|
|
self.markov(word, 15)
|
|
|
|
|
|
|
|
def haiku_line(self, line, current_syllables, next_words,
|
|
|
|
target_syllables):
|
|
|
|
if next_words == []:
|
|
|
|
# this branch failed
|
|
|
|
return None
|
|
|
|
else:
|
|
|
|
word = random.choice(next_words)
|
|
|
|
new_line = line[:]
|
|
|
|
new_line.append(word)
|
|
|
|
new_syllables = textstat.syllable_count(' '.join(new_line))
|
|
|
|
if new_syllables == target_syllables:
|
|
|
|
return new_line
|
|
|
|
elif new_syllables > target_syllables:
|
|
|
|
new_next_words = next_words[:]
|
|
|
|
new_next_words.remove(word)
|
|
|
|
return self.haiku_line(line, current_syllables, new_next_words,
|
|
|
|
target_syllables)
|
|
|
|
else:
|
|
|
|
new_next_words = [freq[0] for freq in self.cfd[word].items()
|
|
|
|
if not self.only_punctuation.match(freq[0])]
|
|
|
|
branch = self.haiku_line(new_line, new_syllables, new_next_words,
|
|
|
|
target_syllables)
|
|
|
|
if branch:
|
|
|
|
return branch
|
|
|
|
else:
|
|
|
|
new_next_words = next_words[:]
|
|
|
|
new_next_words.remove(word)
|
|
|
|
return self.haiku_line(line, current_syllables, new_next_words,
|
|
|
|
target_syllables)
|
|
|
|
|
|
|
|
def generate_haiku(self):
|
|
|
|
first = self.haiku_line([], 0, self.all_words, 5)
|
|
|
|
print ' '.join(first)
|
|
|
|
next_words = [freq[0] for freq in self.cfd[first[-1]].items()
|
|
|
|
if not self.only_punctuation.match(freq[0])]
|
|
|
|
second = self.haiku_line([], 0, next_words, 7)
|
|
|
|
print ' '.join(second)
|
|
|
|
next_words = [freq[0] for freq in self.cfd[first[-1]].items()
|
|
|
|
if not self.only_punctuation.match(freq[0])]
|
|
|
|
third = self.haiku_line([], 0, next_words, 5)
|
|
|
|
print ' '.join(third)
|
2015-06-07 20:27:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
generator = PoemGenerator(nltk.corpus.gutenberg)
|
2015-07-14 04:03:05 +00:00
|
|
|
#generator.generate_poem()
|
|
|
|
generator.generate_haiku()
|