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

Joel Montes de Oca joelmontes01 at gmail.com
Mon Oct 31 18:09:16 CET 2011


On Mon 31 Oct 2011 12:14:40 PM EDT, Hugo Arts wrote:
>
> 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

Hey Hugo,

I think I understand your explanation. Let me see if I get it.

The code:

def  UserChoice  ():  *# I WILL CALL THIS FUNCTION A*
     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'):
         print  'I am sorry, you entered\''  +  choice.upper()  +  '\'  which is an invalid response. Please try again.'
         raw_input('Press Enter to try again.')
         UserChoice  ()  *# I WILL CALL THIS FUNCTION B*
     else:
         return  choice*# I WILL CALL THE ORIGINAL CALLING FUNCTION, FUNCTION MAIN*


OK so when the user uses a valid letter, the variable choice gets 
returned to FUNCTION MAIN. Everything works fine.

When the user enters an invalid letter, FUNCTION B calls FUNCTION A. 
FUNCTION A returns choice to FUNCTION B. FUNCTION B does nothing with 
the return, FUNCTION MAIN gets nothing to returned to it, thus choice is 
NONE.

FUN MAIN
   |
   |
   |__ FUN A
           |
           |
           |_ FUN B

This is how I understand it. So if I want this to work, I need FUN B to 
give something back to FUN A so that FUN A will have something to give 
back to FUN MAIN but that doesn't feel right.

Is there a way to say GO TO FUN A instead of calling the function?



I also found this Youtube video on the topic of recursion in python. 
http://www.youtube.com/watch?v=72hal4Cp_2I

-- 
-Joel M.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20111031/cc7564ff/attachment-0001.html>


More information about the Tutor mailing list