0
def confirm_board_size():
    print()
    num = input("What size board would you like to play on? 3, 4, or 5: ")
    while num not in range(3, 6):
        try:
            num = int(num)
        except ValueError:
            print(f"{num} is not a valid input. Please enter 3, 4, or 5.")
            confirm_board_size()
        else:
            if num not in range(3, 6):
                print(f"{num} is not a valid input. Please enter 3, 4, or 5.")
                confirm_board_size()
    sample_board = Board(num)
    sample_board.create_board()
    sample_board.show_board()
    confirm = input("You will be playing on this board. Is that OK? ")
    confirm = confirm.lower()
    if confirm == 'y':
        return int(num)
    else:
        confirm_board_size()

I ran this code through a debugger. On the first call to the confirm_board_size function if the confirm variable is anything other than 'y', the function gets called again and asks for the relevant inputs and those all get overwritten. However, when the confirm variable's input call comes up again and I enter input, the confirm variable remains the same and the confirm_board_size function returns a None value and exits. Why is this occurring? I'm using Python 3.11.3

Omace
  • 42
  • 3
  • 4
    The codes a bit messy, but I believe the issue is that you are ignoring the return values of the recursive calls. – 001 Jun 22 '23 at 20:29
  • 2
    Making a recursive call and then neither using nor returning the result is like baking a cake and then dropping it on the floor when it's done. – pjs Jun 22 '23 at 20:43
  • A recursive call is not just a goto to the beginning of the function; it starts a *completely seperate* invocation of the function. – chepner Jun 22 '23 at 20:54
  • 1
    Using recursion is the completely wrong approach for this task. Please read: [Asking the user for input until they give a valid response](https://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response) – Matthias Jun 22 '23 at 21:16

2 Answers2

0

The issue you're experiencing lies in the recursive calls to confirm_board_size() within the function. When you recursively call the function, you correctly gather the inputs and perform the necessary checks. However, you haven't accounted for the return value of the recursive calls.

In the else block where confirm == 'y' is not true, you have confirm_board_size() without a return statement. This causes the function to return None by default. To fix this, you should return the result of the recursive call, like this:

else:
    return confirm_board_size()

By adding the return keyword, you ensure that the return value from the recursive call is propagated back up the call stack correctly.

With this change, the function will properly return the value of int(num) when confirm == 'y', and it will continue to recursively call itself until a valid input is provided.

Additionally, please note that you need to convert the user input num to an integer before checking its range. You can move the line num = int(num) before the while loop to ensure that you're working with an integer value.

num = int(num)
while num not in range(3, 6):
    # rest of the code...

Hope this helps!

  • 1
    Welcome to Stack Overflow! Most or all of your answers appear likely to have been entirely or partially written by AI (e.g., ChatGPT). Please be aware that [posting of AI-generated content is banned here](//meta.stackoverflow.com/q/421831). If you used an AI tool to assist with any answer, I would encourage you to delete it. Thanks! – NotTheDr01ds Jun 22 '23 at 21:09
  • 1
    **Readers should review this answer carefully and critically, as AI-generated information often contains fundamental errors and misinformation.** If you observe quality issues and/or have reason to believe that this answer was generated by AI, please leave feedback accordingly. The moderation team can use your help to identify quality issues. m – NotTheDr01ds Jun 22 '23 at 21:10
0

To expand on what the others are saying, you are calling confirm_board_size() inside of itself. This concept is called recursion, and it requires the programmer to be extra careful.

To answer your question, each time you call confirm_board_size() you are entering a new function scope, meaning your local variables from the outside function are not accessible to the variables within the next layer of recursion.

Next I'll take a crack at trying to fix your code... I'll do this both recursively and without recursion.

Without recursion:

def confirm_board_size():
    print()
    
    while True:
        try:
            num = input("What size board would you like to play on? 3, 4, or 5: ")
            num = int(num)
            if num not in range(3, 6):
                # User provided number other than 3, 4, 5
                print(f"{num} is not a valid input. Please enter 3, 4, or 5.")
                continue # start at top of while loop and ask user to input number again

            sample_board = Board(num)
            sample_board.create_board()
            sample_board.show_board()

            confirm = input("You will be playing on this board. Is that OK? ")
            confirm = confirm.lower()
            if confirm == 'y':
                '''
                With this return we exit the While True loop. We can do this
                because if the user inputs incorrect data, we will catch it 
                in either the if cases above or the Except block below
                '''
                return num
            else:
                continue # start at top of while loop and ask user to input number again

        except ValueError:
            # User did not provide a number
            print(f"{num} is not a numerical input. Please enter 3, 4, or 5.")
            continue # start at top of while loop and ask user to input number again

With recursion:

def confirm_board_size():
    print()
    
    try:
        num = input("What size board would you like to play on? 3, 4, or 5: ")
        num = int(num)
    except ValueError:
        print(f"{num} is not a valid input. Please enter 3, 4, or 5.")
        return confirm_board_size()
    if num not in range(3, 6):
        print(f"{num} is not a valid input. Please enter 3, 4, or 5.")
        return confirm_board_size()
    
    sample_board = Board(num)
    sample_board.create_board()
    sample_board.show_board()
    confirm = input("You will be playing on this board. Is that OK? ")
    confirm = confirm.lower()
    if confirm == 'y':
        return int(num) # base case
    else:
        return confirm_board_size()

The issue with your original code is that you were not returning the result of confirm_board_size(), so when you hit your base case, the value wasn't making it back up through your functions.

Matt
  • 973
  • 8
  • 10