From 42d414a0a4f7219e45a0a9e3e56f3c2e94bd86f9 Mon Sep 17 00:00:00 2001 From: "Brian S. Stephan" Date: Sat, 30 Apr 2011 15:37:16 -0500 Subject: [PATCH] Markov: consolidate _reply_to_line and _reply into _generate_line --- modules/Markov.py | 68 +++++++++-------------------------------------- 1 file changed, 13 insertions(+), 55 deletions(-) diff --git a/modules/Markov.py b/modules/Markov.py index 6121474..1e8b57b 100644 --- a/modules/Markov.py +++ b/modules/Markov.py @@ -182,10 +182,10 @@ class Markov(Module): addressed_re = re.compile(addressed_pattern) if addressed_re.match(what): # i was addressed directly, so respond, addressing the speaker - return self.reply(connection, event, '{0:s}: {1:s}'.format(nick, self._reply_to_line(addressed_re.match(what).group(1)))) + return self.reply(connection, event, '{0:s}: {1:s}'.format(nick, self._generate_line(line=addressed_re.match(what).group(1)))) else: # i wasn't addressed directly, so just respond - return self.reply(connection, event, '{0:s}'.format(self._reply_to_line(what))) + return self.reply(connection, event, '{0:s}'.format(self._generate_line(line=what))) def markov_train(self, connection, event, nick, userhost, what, admin_unlocked): """Learn lines from a file. Good for initializing a brain.""" @@ -229,9 +229,9 @@ class Markov(Module): if match.group(5) != '': line = match.group(6) - return self._reply_to_line(line, min_size=min_size, max_size=max_size) + return self._generate_line(line=line, min_size=min_size, max_size=max_size) else: - return self._reply(min_size=min_size, max_size=max_size) + return self._generate_line(min_size=min_size, max_size=max_size) def _learn_line(self, line, target=None): """Create Markov chains from the provided line.""" @@ -273,54 +273,7 @@ class Markov(Module): print("sqlite error: " + str(e)) raise - def _reply(self, min_size=15, max_size=100): - """Generate a totally random string from the chains, of specified limit of words.""" - - # if the limit is too low, there's nothing to do - if (max_size <= 3): - raise Exception("max_size is too small: %d" % max_size) - - # if the min is too large, abort - if (min_size > 20): - raise Exception("min_size is too large: %d" % min_size) - - # start with an empty chain, and work from there - gen_words = [self.start1, self.start2] - - # set up the number of times we've tried to hit the specified minimum - min_search_tries = 0 - - # walk a chain, randomly, building the list of words - while len(gen_words) < max_size + 2 and gen_words[-1] != self.stop: - key_hits = self._retrieve_chains_for_key(gen_words[-2], gen_words[-1]) - if len(gen_words) < min_size and len(filter(lambda a: a != self.stop, key_hits)) > 0: - # we aren't at min size yet and we have at least one chain path - # that isn't (yet) the end. take one of those. - gen_words.append(random.choice(filter(lambda a: a != self.stop, key_hits))) - min_search_tries = 0 - elif len(gen_words) < min_size and min_search_tries <= 10: - # we aren't at min size yet and the only path we currently have is - # a end, but we haven't retried much yet, so chop off our current - # chain and try again. - gen_words = gen_words[0:len(gen_words)-2] - min_search_tries = min_search_tries + 1 - else: - # either we have hit our min size requirement, or we haven't but - # we also exhausted min_search_tries. either way, just pick a word - # at random, knowing it may be the end of the chain - gen_words.append(random.choice(key_hits)) - min_search_tries = 0 - - # chop off the seed data at the start - gen_words = gen_words[2:] - - # chop off the end text, if it was the keyword indicating an end of chain - if gen_words[-1] == self.stop: - gen_words = gen_words[:-1] - - return ' '.join(gen_words).encode('utf-8', 'ignore') - - def _reply_to_line(self, line, min_size=15, max_size=100): + def _generate_line(self, line='', min_size=15, max_size=100): """Reply to a line, using some text in the line as a point in the chain.""" # if the limit is too low, there's nothing to do @@ -331,9 +284,13 @@ class Markov(Module): if (min_size > 20): raise Exception("min_size is too large: %d" % min_size) + words = [] + target_word = '' # get a random word from the input - words = line.split() - target_word = words[random.randint(0, len(words)-1)] + if line != '': + words = line.split() + target_word = words[random.randint(0, len(words)-1)] + print('target word ' + target_word) # start with an empty chain, and work from there gen_words = [self.start1, self.start2] @@ -341,8 +298,9 @@ class Markov(Module): # walk a chain, randomly, building the list of words while len(gen_words) < max_size + 2 and gen_words[-1] != self.stop: key_hits = self._retrieve_chains_for_key(gen_words[-2], gen_words[-1]) + print(key_hits) # use the chain that includes the target word, if it is found - if target_word in key_hits: + if target_word != '' and target_word in key_hits: gen_words.append(target_word) # generate new word target_word = words[random.randint(0, len(words)-1)]