Reputation: 8072
The class below gets a string as input and produces another string via the answer()
method.
class Question:
a = ["hello", "hi"]
b = ["how are you", "how do you do"]
c = ["how is the weather", "is it cold today"]
def __init__(self, question):
self.question = question
def get_greeting(self):
if self.question in Question.a:
return "Hi There!"
def get_health(self):
if self.question in Question.b:
return "I am fine"
def get_weather(self):
if self.question in Question.c:
return "It is warm"
def answer(self):
if self.get_greeting():
return self.get_greeting()
elif self.get_health():
return self.get_health()
elif self.get_weather():
return self.get_weather()
else:
return "I don't understand"
question = Question("how is the weather")
print(question.answer()) # getting the output
To me the above is bad because the code inside answer()
it's long and it calls each method twice.
Therefore, I came up with a "better" answer()
method that calls the methods only once, but it's still a lot of if conditionals.
def answer(self):
result = self.get_greeting()
if result:
return result
result = self.get_health()
if result:
return result
result = self.get_weather()
if result:
return result
return "I don't understand"
I think there might be some other technique that I am missing here. Anyone can suggest something?
Upvotes: 0
Views: 35
Reputation: 6359
You can make a tuple of all methods and then call them until one returns something:
def answer(self):
methods = (self.get_greeting, self.get_health, self.get_weather)
for m in methods:
res = m()
if res:
return res
return "I don't understand"
Edit
If you really want to create a lot of methods and have your answer()
function try them all without explicitly telling it, you can use this code:
def answer(self):
getters = (v for k, v in self.__class__.__dict__.items() if k.startswith("get_"))
for method in getters:
res = method(self)
if res:
return res
return "I don't understand"
Edit 2
If your system just gets a string as an input and generates predefined outputs from it, you may be able to simplify it quite a bit:
knowledge = [
(["hello", "hi"], "Hi There"),
(["how are you", "how do you do"], "I am fine"),
(["how is the weather", "is it cold today"], "It is warm")
]
def answer(question):
for inputs, answer in knowledge:
if question in inputs:
return answer
return "I don't understand"
print(answer("hello"))
Using this approach, adding a new phrase to the chatbot is as easy as adding a line to the knowledge data structure.
Upvotes: 2
Reputation: 66441
The result of or
is the left-hand operand if it's not "false-y", otherwise the right-hand operand.
It also evaluates the right-hand operand only when it's needed.
def answer(self):
return self.get_greeting() \
or self.get_health() \
or self.get_weather() \
or "I don't understand"
Upvotes: 3