[Tutor] Paper Rock Scissors game - User's choice not returned properly

Hugo Arts hugo.yoshi at gmail.com
Mon Oct 31 17:14:40 CET 2011


On Mon, Oct 31, 2011 at 4:41 PM, Joel Montes de Oca
<joelmontes01 at gmail.com> wrote:
> Hello everyone,
>
> I am having a little trouble with a block of code that isn't behaving the
> way I would expect. Maybe you can give me a hand and point where it is going
> wrong.
>
> The function that is not working correctly belongs to a Paper Rock Scissor
> game I am making.
>
> This particular function is responsible to:
>   a) Get the user's choice (Paper, Rock, or Scissors)
>   b) Return the user's choice within the variable choice to the function
> that called it.
>
> The function works correctly as long as the user does not try to enter a
> string other than 'P', 'R', or 'S'.
>
> Logic:
>     Take the user's string and put it in the variable choice.
>     If choice is not 'P', 'R', or 'S' then pass a message to the user and
> call the function again.
>     If the choice is 'P', 'R', or 'S' then return choice to where it was
> called from.
>
> The problem is this.
>
> When the user enters a string other than the valid ones, the if statements
> catches it and calls the same function again so the user can enter a valid
> string. But the variable choice does not get assigned the new string entered
> by the user, instead it is empty.
>
> I would expect if the function runs again, the variable choice would be
> updated to the last value given by the user.
>
> The function: ( http://dpaste.com/644857/)
>
> def UserChoice ():	# The function that returns the choice from the user
> 	print 'Please select (P) for paper, (R) for Rock, or (S) for Scissors.'
> 	choice = raw_input('What is your selection?: ')
>
> 	if choice.lower() not in ('p', 'r','s'):	# Converts the user's choice to
> lowercase and confirms the choice is valid
> 		print 'I am sorry, you entered \'' + choice.upper() + '\' which is an
> invalid response. Please try again.'
> 		raw_input('Press Enter to try again.')
> 		UserChoice ()		# If the choice is not valid, run the function over
> 	else:
> 		return choice
>

Your problem is that you don't quite understand recursion.

When a function calls itself, it's not actually any different from
when a function A calls another function B. Once function B is done
running and returns, control goes back to function A. It doesn't
matter if function B is actually the same function as A. In fact, even
if A and B are the same function, they don't "share" any variables and
are totally separate as if they were two different functions that just
happened to do the same thing.

So, how does this apply to your function? Let's go through a run of
it. We call UserChoice (this is function A) and we input a wrong
letter. So, A calls UserChoice again (this is function B), and this
time we input something valid. So, function B runs the line "return
choice."

Control now returns to function A, right at the point where we called
function B. So what do we do here with the choice that was just
returned from function B? Well, looking at the line where it's called,
it's just "UserChoice()". So we do nothing. We just throw it away.
Then, we continue on with function A, move out of the if statement,
and "fall off the end" of the function. And when that happens, Python
returns None from function A to show you that nothing was returned.

If you understood all that, you should be able to fix your problem.

Hugo


More information about the Tutor mailing list