0

I'm having some odd behaviour with a recursive function, and I can't quite figure out whats going wrong.

def setGM():

  global guild_master
  guild_master = input('>>> Enter your name: ').strip()
  
  # This statement is triggered by hitting enter to the guild_master input without typing anything, it calls setGM() again to force the user to set a name correctly.
  if guild_master == '':
      print('We need to know what to call you!')
      setGM()

  # Once the user enters a valid name, the verify function will be called to confirm the input.
  # For some reason, on the second loop/recursion it will igore the elif statement here
  def verify():
    confirm = input(f'So your name is {guild_master}, is that correct? \n>>> Please type yes or no: ').strip().lower()
    if confirm == 'no':
      setGM()
    elif confirm == 'yes':
      print(f'Yes, my name is {guild_master}')
    else:
      print('I\'m sorry, I didn\'t understand that...')
      verify()
    return

  verify()

The above code prompts the user to enter a name when setGM() is called. The name is stored in the guild_master variable. If the name is a non-empty string, ie not "", the verify() function is called to check if the string is 'yes', 'no', or something else. If the string is yes, the function is complete.

The problem arises when the initial string is empty. This happens when a user hits enter to the name prompt without typing anything. An if statement is used to check if the string is equal to "", if so it calls the setGM() function again to force the user to set a valid name. The problem seems to be with this recursion. The user will presumably enter a valid name at this point, then the verify function will check the answer. At this point its expected that a value of 'yes' will complete the function as before. Instead it again prompts the user to confirm.

# To simulate the correct output:
# first enter a name
# on the next prompt type yes
# console outputs "yes, my name is..."
# To simulate the incorrect output:
# when prompted to enter a name, simply hit enter without any text
# you will be prompted to enter a name again, go ahead and type something - press enter.
# console outputs "So your name is... Please type yes or no:"
# type yes
# console outputs "yes, my name is..."
# console incorrecty prompts to confirm name again
# typing 'yes' here will return the correct output and end the script.

# note, if on the first step you trigger the "Enter your name" prompt x times by hitting enter with no input, it will ask you to confirm your name x+1 times even if your answer is yes to the confirmation prompt

See it in action here -> https://repl.it/@ShawnMichael2/recursivebug#main.py

Shawn R.
  • 161
  • 1
  • 3
  • 13
  • 1
    Why do you want to use a recursive function for this? Why not simply use https://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response? – tripleee Jan 26 '21 at 18:35
  • 2
    When you run recursively on line 11, it continues running from that point onward after your inner function is complete. Just put a `return` immediately after it. – Axe319 Jan 26 '21 at 18:39
  • @tripleee try/catch would certainly be an option here, but for me it was simpler to user recursion to force the input again. – Shawn R. Jan 26 '21 at 18:46
  • @Axe319 brilliant, a return statement did the trick. I didnt realize what was happening, mostly due to my own inexperience. Thanks mate! – Shawn R. Jan 26 '21 at 18:47

1 Answers1

0

Answered by Axe319 in a comment above:

Python wasn't "ignoring" my if statement, it was actually running it twice. Once inside the recursion, and afterwords the initial function picked up where it left off without me realizing it. A return statement after the second call stopped the duplicate check.

if guild_master == '':
      print('We need to know what to call you!')
      setGM()
      return
Shawn R.
  • 161
  • 1
  • 3
  • 13