|
1 #---------------------------------------------------------------------- |
|
2 # eliza.py |
|
3 # |
|
4 # a cheezy little Eliza knock-off by Joe Strout <joe@strout.net> |
|
5 # with some updates by Jeff Epler <jepler@inetnebr.com> |
|
6 # hacked into a module and updated by Jez Higgins <jez@jezuk.co.uk> |
|
7 # last revised: 28 February 2005 |
|
8 #---------------------------------------------------------------------- |
|
9 |
|
10 import string |
|
11 import re |
|
12 import random |
|
13 |
|
14 class eliza: |
|
15 def __init__(self): |
|
16 self.keys = map(lambda x:re.compile(x[0], re.IGNORECASE),gPats) |
|
17 self.values = map(lambda x:x[1],gPats) |
|
18 |
|
19 #---------------------------------------------------------------------- |
|
20 # translate: take a string, replace any words found in dict.keys() |
|
21 # with the corresponding dict.values() |
|
22 #---------------------------------------------------------------------- |
|
23 def translate(self,str,dict): |
|
24 words = string.split(string.lower(str)) |
|
25 keys = dict.keys(); |
|
26 for i in range(0,len(words)): |
|
27 if words[i] in keys: |
|
28 words[i] = dict[words[i]] |
|
29 return string.join(words) |
|
30 |
|
31 #---------------------------------------------------------------------- |
|
32 # respond: take a string, a set of regexps, and a corresponding |
|
33 # set of response lists; find a match, and return a randomly |
|
34 # chosen response from the corresponding list. |
|
35 #---------------------------------------------------------------------- |
|
36 def respond(self,str): |
|
37 # find a match among keys |
|
38 for i in range(0,len(self.keys)): |
|
39 match = self.keys[i].match(str) |
|
40 if match: |
|
41 # found a match ... stuff with corresponding value |
|
42 # chosen randomly from among the available options |
|
43 resp = random.choice(self.values[i]) |
|
44 # we've got a response... stuff in reflected text where indicated |
|
45 pos = string.find(resp,'%') |
|
46 while pos > -1: |
|
47 num = string.atoi(resp[pos+1:pos+2]) |
|
48 resp = resp[:pos] + \ |
|
49 self.translate(match.group(num),gReflections) + \ |
|
50 resp[pos+2:] |
|
51 pos = string.find(resp,'%') |
|
52 # fix munged punctuation at the end |
|
53 if resp[-2:] == '?.': resp = resp[:-2] + '.' |
|
54 if resp[-2:] == '??': resp = resp[:-2] + '?' |
|
55 return resp |
|
56 |
|
57 #---------------------------------------------------------------------- |
|
58 # gReflections, a translation table used to convert things you say |
|
59 # into things the computer says back, e.g. "I am" --> "you are" |
|
60 #---------------------------------------------------------------------- |
|
61 gReflections = { |
|
62 "am" : "are", |
|
63 "was" : "were", |
|
64 "i" : "you", |
|
65 "i'd" : "you would", |
|
66 "i've" : "you have", |
|
67 "i'll" : "you will", |
|
68 "my" : "your", |
|
69 "are" : "am", |
|
70 "you've": "I have", |
|
71 "you'll": "I will", |
|
72 "your" : "my", |
|
73 "yours" : "mine", |
|
74 "you" : "me", |
|
75 "me" : "you" |
|
76 } |
|
77 |
|
78 #---------------------------------------------------------------------- |
|
79 # gPats, the main response table. Each element of the list is a |
|
80 # two-element list; the first is a regexp, and the second is a |
|
81 # list of possible responses, with group-macros labelled as |
|
82 # %1, %2, etc. |
|
83 #---------------------------------------------------------------------- |
|
84 gPats = [ |
|
85 [r'I need (.*)', |
|
86 [ "Why do you need %1?", |
|
87 "Would it really help you to get %1?", |
|
88 "Are you sure you need %1?"]], |
|
89 |
|
90 [r'Why don\'?t you ([^\?]*)\??', |
|
91 [ "Do you really think I don't %1?", |
|
92 "Perhaps eventually I will %1.", |
|
93 "Do you really want me to %1?"]], |
|
94 |
|
95 [r'Why can\'?t I ([^\?]*)\??', |
|
96 [ "Do you think you should be able to %1?", |
|
97 "If you could %1, what would you do?", |
|
98 "I don't know -- why can't you %1?", |
|
99 "Have you really tried?"]], |
|
100 |
|
101 [r'I can\'?t (.*)', |
|
102 [ "How do you know you can't %1?", |
|
103 "Perhaps you could %1 if you tried.", |
|
104 "What would it take for you to %1?"]], |
|
105 |
|
106 [r'I am (.*)', |
|
107 [ "Did you come to me because you are %1?", |
|
108 "How long have you been %1?", |
|
109 "How do you feel about being %1?"]], |
|
110 |
|
111 [r'I\'?m (.*)', |
|
112 [ "How does being %1 make you feel?", |
|
113 "Do you enjoy being %1?", |
|
114 "Why do you tell me you're %1?", |
|
115 "Why do you think you're %1?"]], |
|
116 |
|
117 [r'Are you ([^\?]*)\??', |
|
118 [ "Why does it matter whether I am %1?", |
|
119 "Would you prefer it if I were not %1?", |
|
120 "Perhaps you believe I am %1.", |
|
121 "I may be %1 -- what do you think?"]], |
|
122 |
|
123 [r'What (.*)', |
|
124 [ "Why do you ask?", |
|
125 "How would an answer to that help you?", |
|
126 "What do you think?"]], |
|
127 |
|
128 [r'How (.*)', |
|
129 [ "How do you suppose?", |
|
130 "Perhaps you can answer your own question.", |
|
131 "What is it you're really asking?"]], |
|
132 |
|
133 [r'Because (.*)', |
|
134 [ "Is that the real reason?", |
|
135 "What other reasons come to mind?", |
|
136 "Does that reason apply to anything else?", |
|
137 "If %1, what else must be true?"]], |
|
138 |
|
139 [r'(.*) sorry (.*)', |
|
140 [ "There are many times when no apology is needed.", |
|
141 "What feelings do you have when you apologize?"]], |
|
142 |
|
143 [r'Hello(.*)', |
|
144 [ "Hello... I'm glad you could drop by today.", |
|
145 "Hi there... how are you today?", |
|
146 "Hello, how are you feeling today?"]], |
|
147 |
|
148 [r'I think (.*)', |
|
149 [ "Do you doubt %1?", |
|
150 "Do you really think so?", |
|
151 "But you're not sure %1?"]], |
|
152 |
|
153 [r'(.*) friend (.*)', |
|
154 [ "Tell me more about your friends.", |
|
155 "When you think of a friend, what comes to mind?", |
|
156 "Why don't you tell me about a childhood friend?"]], |
|
157 |
|
158 [r'Yes', |
|
159 [ "You seem quite sure.", |
|
160 "OK, but can you elaborate a bit?"]], |
|
161 |
|
162 [r'(.*) computer(.*)', |
|
163 [ "Are you really talking about me?", |
|
164 "Does it seem strange to talk to a computer?", |
|
165 "How do computers make you feel?", |
|
166 "Do you feel threatened by computers?"]], |
|
167 |
|
168 [r'Is it (.*)', |
|
169 [ "Do you think it is %1?", |
|
170 "Perhaps it's %1 -- what do you think?", |
|
171 "If it were %1, what would you do?", |
|
172 "It could well be that %1."]], |
|
173 |
|
174 [r'It is (.*)', |
|
175 [ "You seem very certain.", |
|
176 "If I told you that it probably isn't %1, what would you feel?"]], |
|
177 |
|
178 [r'Can you ([^\?]*)\??', |
|
179 [ "What makes you think I can't %1?", |
|
180 "If I could %1, then what?", |
|
181 "Why do you ask if I can %1?"]], |
|
182 |
|
183 [r'Can I ([^\?]*)\??', |
|
184 [ "Perhaps you don't want to %1.", |
|
185 "Do you want to be able to %1?", |
|
186 "If you could %1, would you?"]], |
|
187 |
|
188 [r'You are (.*)', |
|
189 [ "Why do you think I am %1?", |
|
190 "Does it please you to think that I'm %1?", |
|
191 "Perhaps you would like me to be %1.", |
|
192 "Perhaps you're really talking about yourself?"]], |
|
193 |
|
194 [r'You\'?re (.*)', |
|
195 [ "Why do you say I am %1?", |
|
196 "Why do you think I am %1?", |
|
197 "Are we talking about you, or me?"]], |
|
198 |
|
199 [r'I don\'?t (.*)', |
|
200 [ "Don't you really %1?", |
|
201 "Why don't you %1?", |
|
202 "Do you want to %1?"]], |
|
203 |
|
204 [r'I feel (.*)', |
|
205 [ "Good, tell me more about these feelings.", |
|
206 "Do you often feel %1?", |
|
207 "When do you usually feel %1?", |
|
208 "When you feel %1, what do you do?"]], |
|
209 |
|
210 [r'I have (.*)', |
|
211 [ "Why do you tell me that you've %1?", |
|
212 "Have you really %1?", |
|
213 "Now that you have %1, what will you do next?"]], |
|
214 |
|
215 [r'I would (.*)', |
|
216 [ "Could you explain why you would %1?", |
|
217 "Why would you %1?", |
|
218 "Who else knows that you would %1?"]], |
|
219 |
|
220 [r'Is there (.*)', |
|
221 [ "Do you think there is %1?", |
|
222 "It's likely that there is %1.", |
|
223 "Would you like there to be %1?"]], |
|
224 |
|
225 [r'My (.*)', |
|
226 [ "I see, your %1.", |
|
227 "Why do you say that your %1?", |
|
228 "When your %1, how do you feel?"]], |
|
229 |
|
230 [r'You (.*)', |
|
231 [ "We should be discussing you, not me.", |
|
232 "Why do you say that about me?", |
|
233 "Why do you care whether I %1?"]], |
|
234 |
|
235 [r'Why (.*)', |
|
236 [ "Why don't you tell me the reason why %1?", |
|
237 "Why do you think %1?" ]], |
|
238 |
|
239 [r'I want (.*)', |
|
240 [ "What would it mean to you if you got %1?", |
|
241 "Why do you want %1?", |
|
242 "What would you do if you got %1?", |
|
243 "If you got %1, then what would you do?"]], |
|
244 |
|
245 [r'(.*) mother(.*)', |
|
246 [ "Tell me more about your mother.", |
|
247 "What was your relationship with your mother like?", |
|
248 "How do you feel about your mother?", |
|
249 "How does this relate to your feelings today?", |
|
250 "Good family relations are important."]], |
|
251 |
|
252 [r'(.*) father(.*)', |
|
253 [ "Tell me more about your father.", |
|
254 "How did your father make you feel?", |
|
255 "How do you feel about your father?", |
|
256 "Does your relationship with your father relate to your feelings today?", |
|
257 "Do you have trouble showing affection with your family?"]], |
|
258 |
|
259 [r'(.*) child(.*)', |
|
260 [ "Did you have close friends as a child?", |
|
261 "What is your favorite childhood memory?", |
|
262 "Do you remember any dreams or nightmares from childhood?", |
|
263 "Did the other children sometimes tease you?", |
|
264 "How do you think your childhood experiences relate to your feelings today?"]], |
|
265 |
|
266 [r'(.*)\?', |
|
267 [ "Why do you ask that?", |
|
268 "Please consider whether you can answer your own question.", |
|
269 "Perhaps the answer lies within yourself?", |
|
270 "Why don't you tell me?"]], |
|
271 |
|
272 [r'quit', |
|
273 [ "Thank you for talking with me.", |
|
274 "Good-bye.", |
|
275 "Thank you, that will be $150. Have a good day!"]], |
|
276 |
|
277 [r'(.*)', |
|
278 [ "Please tell me more.", |
|
279 "Let's change focus a bit... Tell me about your family.", |
|
280 "Can you elaborate on that?", |
|
281 "Why do you say that %1?", |
|
282 "I see.", |
|
283 "Very interesting.", |
|
284 "%1.", |
|
285 "I see. And what does that tell you?", |
|
286 "How does that make you feel?", |
|
287 "How do you feel when you say that?"]] |
|
288 ] |
|
289 |
|
290 #---------------------------------------------------------------------- |
|
291 # command_interface |
|
292 #---------------------------------------------------------------------- |
|
293 def command_interface(): |
|
294 print "Therapist\n---------" |
|
295 print "Talk to the program by typing in plain English, using normal upper-" |
|
296 print 'and lower-case letters and punctuation. Enter "quit" when done.' |
|
297 print '='*72 |
|
298 print "Hello. How are you feeling today?" |
|
299 s = "" |
|
300 therapist = eliza(); |
|
301 while s != "quit": |
|
302 try: s = raw_input(">") |
|
303 except EOFError: |
|
304 s = "quit" |
|
305 print s |
|
306 while s[-1] in "!.": s = s[:-1] |
|
307 print therapist.respond(s) |
|
308 |
|
309 |
|
310 if __name__ == "__main__": |
|
311 command_interface() |