Alienbot - feedback and capturing multi-digit numbers with regex?

Hey folks! I just finished the alienbot project but I have one last issue:

The cube-function only works for single digit numbers but I want it also to work on numbers like 100 or 0.001. I thought that the given regex (r"\d+") would at least capture all non-decimal numbers, but somehow it doesn’t work. Maybe its also an issue concerning the capturing with found_match.groups (I did not really get, how it works).

Also, I’m really thankful for improvement for my code!

Thanks for your help!
The code is below, you can find the task here: https://www.codecademy.com/paths/build-chatbots-with-python/tracks/rule-based-chatbots/modules/rule-based-chatbots/projects/python-chatbot-alienbot

# 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?\n",
        "Are there many humans like you?\n",
        "What do you consume for sustenance?\n",
        "Is there intelligent life on this planet?\n",
        "Does Earth have a leader?\n",
        "What planets have you visited?\n",
        "What technology do you have on this planet?\n"
    )

  def __init__(self):
    self.alienbabble = {'describe_planet_intent': r'.*\syour planet.*',
                        'answer_why_intent': r'.*why\sare',
                        'cubed_intent': r'.*cube.*(\d+)' #HERE IS THE ISSUE: it doesnt work for 55, it only takes 5 for calculating...

                            }

  # Define .greet() below:
  def greet(self):
    self.name = input("What's your name?\n")
    will_help = input(f"Hi {self.name}, I'm Etcetera. I'm not from this planet. Will you help me learn about it?\n")
    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 exit_command in self.exit_commands:
      if exit_command in reply:
        print("Ok, have a nice Earth day!")
        return True

    return False

  # Define .chat() next:
  def chat(self):
    reply = input(random.choice(self.random_questions)).lower()
    while self.make_exit(reply) == False:
      reply = input(self.match_reply(reply))


  # Define .match_reply() below:
  def match_reply(self, reply):
    for key, value in self.alienbabble.items():
      intent = key
      regex_pattern = value
      found_match = re.match(regex_pattern, reply)
      #print(found_match)

      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()

      


  # 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.\n", "I am here to collect data on your planet and its inhabitants.\n", "I heard the weed is good here!\n")
    return random.choice(responses)
       
  # Define .cubed_intent():
  def cubed_intent(self, number):
    number = int(number)
    cubed_number = number**3
    return f"The cube of {number} is {cubed_number}. This was easy though.\n"

  # Define .no_match_intent():
  def no_match_intent(self):
    responses = ("Please tell me more.\n", "Why do you think so?\n", "I see, can you explain that more in depth?\n", "Why exactly?\n", "You know, I do not really support your opinion. Please just shut up and let me eat my veggies!\n")
    return random.choice(responses)

# Create an instance of AlienBot below:
alienbot = AlienBot()
alienbot.greet()

You’ll probably get an issue from your regex r'.*cube.*(\d+). Remember that * is greedy.

I’m also a little confused by the current match_reply set-up. Is there a benefit to using both loop and logic? Could you perhaps simplify this with just the dictionary lookup? I’m not saying you can but having both loop and logic when you know most of your expressions evaluate to False seems like it could be cleaned up.

Thanks for your reply! But what exactly do you mean by “loop and logic”? Loop is the for-loop, I get that. How would you optimize the logic? Simply not checking found_match in every if-term?

Thanks!

I was curious about the set-up where you loop through the dictionary of alien_babble but then also filter the replies with an if statement with multiple clauses (that are the keys of the same dictionary). I didn’t spend too long looking at it but perhaps you could use one or the other (loop OR logic) instead of both. I think it’s worth considering.

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.