So I wrote a short and simple chat bot in Python, however there's an irritating issue. The program will only call the posResponses() function initially.
In context, if I respond to its initial question with 'sad', 'terrible' or even 'asdfasdfasdf' I will still get a positive response.
What should happen is if I input a negative/ambiguous keyword the negResponses()/ambiguousResponses() function should be called. That is not the case. What did I do wrong, and how do I fix it? Code is as follows:
import random
import time
def opening():
print('Hello!')
def responseType():
responseType = str(input('How are you ?'))
if responseType == 'good' or 'great' or 'fantastic' or 'decent' or 'fine' or 'ok' or 'okay': posResponses()
elif responseType == 'bad' or 'terrible' or 'sad' or 'grumpy' or 'angry' or 'irritated' or 'tired': negResponses()
else: ambiguousResponses()
def posResponses():
number = random.randint(1, 4)
if number == 1:
print('That\'s great! So what\'s up?')
input()
ambiguousResponses()
if number == 2:
print('Really? I\'d like to hear more.')
input()
ambiguousResponses()
if number == 3:
print('I\'m glad to hear that. What\'s going on?')
input()
ambiguousResponses()
if number == 4:
print('Ah, me too. You should begin a topic discussion.')
input()
ambiguousResponses()
def negResponses():
number2 = random.randint(5, 8)
if number2 == 5:
print('That\'s really too bad. Care to elaborate?')
input()
ambiguousResponses()
if number2 == 6:
print('Awww. Why?')
input()
ambiguousResponses()
if number2 == 7:
print('That sucks! How come?')
input()
ambiguousResponses()
if number2 == 8:
print('What a shame! You should explain why.')
input()
ambiguousResponses()
def ambiguousResponses():
number = random.randint(1, 4)
if number == 1:
print('Interesting. Carry on.')
input()
ambiguousResponses()
if number == 2:
print('Wow, elaborate!')
input()
ambiguousResponses()
if number == 3:
print('What an astute remark! Continue.')
input()
ambiguousResponses()
if number == 4:
print('How interesting. Please do explain further.')
input()
ambiguousResponses()
if __name__ == "__main__":
opening()
responseType()
2 Answers 2
Python is parsing it like this:
if (responseType == 'good') or 'great' or 'fantastic' or 'decent' or 'fine' or 'ok' or 'okay': posResponses()
elif (responseType == 'bad') or 'terrible' or 'sad' or 'grumpy' or 'angry' or 'irritated' or 'tired': negResponses()
else: ambiguousResponses()
'great' is a truthy value, so that if statement always succeeds. You probably want to rewrite it like:
if responseType == 'good' or responseType == 'great' or responseType == 'fantastic' or responseType == 'decent' or responseType == 'fine' or responseType == 'ok' or responseType == 'okay':
posResponses()
elif responseType == 'bad' or responseType == 'terrible' or responseType == 'sad' or responseType == 'grumpy' or responseType == 'angry' or responseType == 'irritated' or responseType == 'tired':
negResponses()
else:
ambiguousResponses()
Or, preferably:
if responseType in {'good', 'great', 'fantastic', 'decent', 'fine', 'ok', 'okay'}:
posResponses()
elif responseType in {'bad', 'terrible', 'sad', 'grumpy', 'angry', 'irritated', 'tired'}:
negResponses()
You could even move those responses into a constant:
# near the top of the file:
GOOD_RESPONSES = {'good', 'great', 'fantastic', 'decent', 'fine', 'ok', 'okay'}
BAD_RESPONSES = {'bad', 'terrible', 'sad', 'grumpy', 'angry', 'irritated', 'tired'}
# when you need to judge a response:
if responseType in GOOD_RESPONSES:
posResponses()
elif responseType in BAD_RESPONSES:
negResponses()
else:
ambiguousResponses()
8 Comments
(5, 3) makes sense. If you start using tuples for list-purposes, you could confuse readers of your code who are expecting the order of the items in the tuple to have some meaning, when there is none. It probably won't have any change to the running of the code (it won't cause errors or anything like that).posResponses is only being called once, because in posResponses you call ambiguousResponses, and in ambiguousResponses you call ambiguousResponses. So it will never exit ambiguousResponses, it will just keep calling ambiguousResponses until you run out of stack and the program crashes.
You have tried to make this program recursive. It shouldn't be, there should be a loop centered around the input() call, of which you only need one in the whole program, not 15 or whatever you have now.
But more blatantly wrong than that, your test of responses to see if they are positive or negative is not included in the recursion, hence the program only checks what response to output once.
ifs usingelifs will be clearer (and more efficient). Also the indentation in your listing is off (but probably due to being posted here)