Package nltk :: Package chat :: Module util
[hide private]
[frames] | no frames]

Source Code for Module nltk.chat.util

  1  # Natural Language Toolkit: Chatbot Utilities 
  2  # 
  3  # Copyright (C) 2001-2008 NLTK Project 
  4  # Authors: Steven Bird <[email protected]> 
  5  # URL: <http://nltk.org> 
  6  # For license information, see LICENSE.TXT 
  7   
  8  # Based on an Eliza implementation by Joe Strout <[email protected]>, 
  9  # Jeff Epler <[email protected]> and Jez Higgins <[email protected]>. 
 10   
 11  import string 
 12  import re 
 13  import random 
 14   
 15  reflections = { 
 16    "am"     : "are", 
 17    "was"    : "were", 
 18    "i"      : "you", 
 19    "i'd"    : "you would", 
 20    "i've"   : "you have", 
 21    "i'll"   : "you will", 
 22    "my"     : "your", 
 23    "are"    : "am", 
 24    "you've" : "I have", 
 25    "you'll" : "I will", 
 26    "your"   : "my", 
 27    "yours"  : "mine", 
 28    "you"    : "me", 
 29    "me"     : "you" 
 30  } 
 31   
32 -class Chat(object):
33 - def __init__(self, pairs, reflections={}):
34 """ 35 Initialize the chatbot. Pairs is a list of patterns and responses. Each 36 pattern is a regular expression matching the user's statement or question, 37 e.g. r'I like (.*)'. For each such pattern a list of possible responses 38 is given, e.g. ['Why do you like %1', 'Did you ever dislike %1']. Material 39 which is matched by parenthesized sections of the patterns (e.g. .*) is mapped to 40 the numbered positions in the responses, e.g. %1. 41 42 @type pairs: C{list} of C{tuple} 43 @param pairs: The patterns and responses 44 @type reflections: C{dict} 45 @param reflections: A mapping between first and second person expressions 46 @rtype: C{None} 47 """ 48 49 self._pairs = [(re.compile(x, re.IGNORECASE),y) for (x,y) in pairs] 50 self._reflections = reflections
51 52 # bug: only permits single word expressions to be mapped
53 - def _substitute(self, str):
54 """ 55 Substitute words in the string, according to the specified reflections, 56 e.g. "I'm" -> "you are" 57 58 @type str: C{string} 59 @param str: The string to be mapped 60 @rtype: C{string} 61 """ 62 63 words = "" 64 for word in string.split(string.lower(str)): 65 if self._reflections.has_key(word): 66 word = self._reflections[word] 67 words += ' ' + word 68 return words
69
70 - def _wildcards(self, response, match):
71 pos = string.find(response,'%') 72 while pos >= 0: 73 num = string.atoi(response[pos+1:pos+2]) 74 response = response[:pos] + \ 75 self._substitute(match.group(num)) + \ 76 response[pos+2:] 77 pos = string.find(response,'%') 78 return response
79
80 - def respond(self, str):
81 """ 82 Generate a response to the user input. 83 84 @type str: C{string} 85 @param str: The string to be mapped 86 @rtype: C{string} 87 """ 88 89 # check each pattern 90 for (pattern, response) in self._pairs: 91 match = pattern.match(str) 92 93 # did the pattern match? 94 if match: 95 resp = random.choice(response) # pick a random response 96 resp = self._wildcards(resp, match) # process wildcards 97 98 # fix munged punctuation at the end 99 if resp[-2:] == '?.': resp = resp[:-2] + '.' 100 if resp[-2:] == '??': resp = resp[:-2] + '?' 101 return resp
102 103 # Hold a conversation with a chatbot
104 - def converse(self, quit="quit"):
105 input = "" 106 while input != quit: 107 input = quit 108 try: input = raw_input(">") 109 except EOFError: 110 print input 111 if input: 112 while input[-1] in "!.": input = input[:-1] 113 print self.respond(input)
114