0

I have a problem regarding recursive functions in Python 3. Consider the below code snippets:

Code snippet A

def select():
    player = input('Player 1: Do you want to be X or O? ')
    if player != 'X' and player != 'O':
        player = select()
        return player

Code snippet B

def select():
    player = input('Player 1: Do you want to be X or O? ')
    if player != 'X' and player != 'O':
        player = select()

    return player

While I somewhat understand the difference (Code A returns a 'None' Type while Code B returns an X or an O) why is that the case? For Code A, before it is returned, player is again reassigned to the select function, which prompts an input until an 'X' or 'O' is provided. Meaning, the return function should never execute as the select() function is recursively called until an X or an O is supplied.

Can you explain to me why snippet A is wrong and returns a None type? Thanks

Harshit
  • 1,510
  • 19
  • 42
Red Alert
  • 1
  • 1
  • You need to fix that code formatting first of all, it's giving me nausea. – Johnny May 12 '20 at 06:05
  • Please format your code strictly otherwise we cannot comment on its behavior (tabulations matters in pythono – Jean-Marc Volle May 12 '20 at 06:05
  • please check indentation – Harsha Biyani May 12 '20 at 06:11
  • Also note that this is not a valid use case to use recursion. You will run out of stack space if the user insists on making an invalid selection. See https://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response for better approaches to this problem. – Selcuk May 12 '20 at 06:14

3 Answers3

0

I reformatted your code into this:

def select():
  player = input('Player 1: Do you want to be X or O? ')

  if player != 'X' and player != 'O':
      player = select()

  return player

print(select())

I left print(select()) just so you could see the output. To specifically answer your question, you want to return player regardless, so that should be left outside the if conditional block.

tersrth
  • 861
  • 6
  • 18
Johnny
  • 211
  • 3
  • 15
  • I can understand why it works that way (that is the same as snippet B), but why doesn't it work when placed inside the if block - after calling the select() function again? – Red Alert May 12 '20 at 07:12
0

In Python if there is no return clause at the end of the function None is returned. Let's run snippet A and explain what's happened step by step:

1) Player 1: Do you want to be X or O? h  # -> invokes select() once more
2) Player 1: Do you want to be X or O? s  # -> invokes select() once more
3) Player 1: Do you want to be X or O? X  # -> if statement is not met, but after if there is no return statement, so return None
4) Going back to 2), player is now None because 3) returned None... so return None
5) Going back to 1), player is now None because 2) returned None... so return None

That is why "A snippet" returns None. What is more, it returns None even if You input correct character, because Python interpreter will not see any return clause

kajakIYD
  • 91
  • 5
0

Code snippet A returns player only if player != 'O' and player != 'X'. This is because it is inside the if statement. Because there is nothing to return if the if condition is not true, the code will by default return None.

Code snippet B changes the code so that return player is outside the if statement. Because of this, player is returned no matter what the user enters.

tersrth
  • 861
  • 6
  • 18