AlienBot Project (Building chatbots with Python)

Hello everyone,

I am trying to get this to work for more than an hour but I can’t figure out what is wrong. I felt confident writing and understanding the code, and I am really curious of why it does not work as intented!

It is a project from the “Build chatbots with Python” skill path.

This project includes 3 intents and corresponding functions, but I can’t match the cubed_intent regex with anything. I have tried to simplify it to just r'cube\s(\d+)' and type cube 5, but still does not work!

Any help would be extremely appreciated!

# importing regex and random libraries import re import random class AlienBot: # potential negative responses negative_responses = ("no", "nope", "nah", "naw", "not a chance", "sorry") # keywords for exiting the conversation exit_commands = ("quit", "pause", "exit", "goodbye", "bye", "later") # random starter questions random_questions = ( "Why are you here? ", "Are there many humans like you? ", "What do you consume for sustenance? ", "Is there intelligent life on this planet? ", "Does Earth have a leader? ", "What planets have you visited? ", "What technology do you have on this planet? " ) def __init__(self): self.alienbabble = { 'describe_planet_intent': r'.*\s*your planet.*', 'answer_why_intent': r'.*why\sare.*', 'cubed_intent': r'.*cube.*(\d+)', # this is the regex } # Define .greet() below: def greet(self): self.name = input("How do you call yourself? ") will_help = input(f"Hi {self.name}, I'm Etcetera. I'm not from this planet. Will you help me learn about your planet? ") if will_help in self.negative_responses: print("Ok, have a nice Earth day!") return self.chat() # Define .make_exit() here: def make_exit(self, reply): for word in self.exit_commands: if word in reply: print("Ok, have a nice Earth day!") return True # Define .chat() next: def chat(self): reply = input(random.choice(self.random_questions)).lower() while not self.make_exit(reply): reply = input(self.match_reply(reply)) # Define .match_reply() below: def match_reply(self, reply): for key, value in self.alienbabble.items(): intent, regex_pattern = key, value found_match = re.match(value, reply) if found_match and intent == 'describe_planet_intent': return self.describe_planet_intent() elif found_match and intent == 'answer_why_intent': return self.answer_why_intent() elif found_match and intent == 'cubed_intent': # this is the match which I cannot get into! return self.cubed_intent(found_match.groups()[0]) else: return self.no_match_intent() # Define .describe_planet_intent(): def describe_planet_intent(self): responses( "My planet is a utopia of diverse organisms and species.", "I am from Opidipus, the capital of the Wayward Galaxies." ) return random.choice(responses) # Define .answer_why_intent(): def answer_why_intent(self): responses( "I come in peace.", "I am here to collect data on your planet and its inhabitants.", "I heard the coffee is good.") return random.choice(responses) # Define .cubed_intent(): def cubed_intent(self, number): # this is the function number = int(number) number_cubed = number ** 3 return f"The cube of {number} is {number_cubed}. Isn't that cool?" # Define .no_match_intent(): def no_match_intent(self): responses = ( "Please tell me more", "Tell me more!", "Why do you say that?", "I see. Can you elaborate?", "Interesting. Can you tell me more?", "I see. How do you think?", "Why?", "How do you think I feel when you say that?", ) return random.choice(responses) # Create an instance of AlienBot below: alienbot = AlienBot() alienbot.greet()

Hello!

There are two non-connected problems in your code:

  1. In method match_reply you try to match only first alienbabble item and then always return. Try to figure out why that happens.
  2. In methods describe_planet_intent and answer_why_intent you did not use assign operator on responses.

Review your code and try to fix these problems.

Good luck!

1 Like

Hello @9509706156 and thanks for your answer.

I had fixed the 2nd issue with the responses assignments but copied the code before that! Good catch though!

Regarding the first issue, you are totally right. I was looking at my regular expressions only and because I find them a bit complicated for now I assumed that there would be an issue there. But it was in my general structure as you pointed out.

I changed the following parts on my code and, finally, is working as intented.

First, I added an additional intent for no matches:

def __init__(self): self.alienbabble = { 'describe_planet_intent': r'.*\s*your planet.*', 'answer_why_intent': r'.*why\sare.*', 'cubed_intent': r'.*cube.*(\d+)', 'no_match_intent:': r'', }

And then I added that to the match reply method:

# Define .match_reply() below: def match_reply(self, reply): for intent, regex_pattern in self.alienbabble.items(): print(intent, regex_pattern) found_match = re.match(regex_pattern, reply) if found_match and intent == 'describe_planet_intent': return self.describe_planet_intent() elif found_match and intent == 'answer_why_intent': return self.answer_why_intent() elif found_match and intent == 'cubed_intent': return self.cubed_intent(found_match.groups()[0]) elif found_match and intent == 'no_match_intent': return self.no_match_intent()

Thank you again for your help!

1 Like

For the 2nd issue there is another solution. Just put last return outside of loop:

  def match_reply(self, reply):

    for intent, regex_pattern in self.alienbabble.items():
      print(intent, regex_pattern)
      found_match = re.match(regex_pattern, reply)
      if found_match and intent == 'describe_planet_intent':
        return self.describe_planet_intent()
      elif found_match and intent == 'answer_why_intent':
        return self.answer_why_intent()
      elif found_match and intent == 'cubed_intent':
        return self.cubed_intent(found_match.groups()[0])
    return self.no_match_intent()

So if there is no match with alienbabble items, then function will return result of no_match_intent(). Matching against empty regex is some confusing.

Good work!

@9509706156 your proposed solution makes more sense.

The course itself had a solution with an empty key, so I thought that must be optimal for some reason:
alienbot

Thanks again for your taking the time to help me out, I really appreciate it.

Hi, im having the same issue but can’t seem to get it going with this solution