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
<joelmonte...@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.

_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to