2

I want to return the variable aRoll, and use it as the argument for the next function. In this case, aRoll holds the answer to the question "Let's roll your ability scores. ready? (y/n)" Once the question is answered, it raw input is stored in the variable aRoll and returned.

import random

pAbility = ['Str', 'Dex', 'Con', 'Int', 'Wis', 'Cha']
pScore = []

i = 0

def pQuestion():
    aRoll = raw_input("Let's roll your ability scores. ready? (y/n)")
    if aRoll not in ('y', 'n'): 
        print "Please type 'y' or 'n'"
        return pQuestion()
    else:
        return aRoll

def pStats(aRoll):
    while aRoll == "y":
        while i < 6:
            pScore.append(random.randint(7, 18))
            i = i + 1

        for score, ability in zip(pAbility, pScore):
            print str(score) + ":\t\t " + str(ability)

def pReroll():
    aRoll = raw_input("Do you wish to reroll? (y/n)")
    aRoll = aRoll.lower()
    if aRoll not in ('y', 'n'):
        print "Please type 'y' or 'n'"
        return pReroll()

pQuestion()

pStats()

pReroll()

When putting print aRoll after pQuestion(), at the bottom of the script, it tells me aRoll isn't defined. Am I not returning aRoll correctly?

Kevin J. Chase
  • 3,856
  • 4
  • 21
  • 43
RuleofThree
  • 121
  • 2

5 Answers5

2

aRoll as defined is a separate local variable in each function. You either need to declare it as a global (not a good idea), or explicitly pass the return value of one function as an argument to the next. For example,

rv = pQuestion()
rv2 = pStats(rv)
rv3 = pReroll(rv2)

(Note the change in the definition of pReroll this requires.)

chepner
  • 497,756
  • 71
  • 530
  • 681
1

A couple of the other answers have it partly right, but you have to put their answers together to get what you want. At the bottom, it should look like this:

aRoll = pQuestion()
pStats(aRoll)

First, you're assigning what pQuestion() returns to aRoll. Next, you're passing that in as a parameter to pStats(). There are a couple things that will happen if you don't do this:

  1. Since you defined a parameter for pstats(), the interpreter will tell you that you're missing a parameter when you try to run this.
  2. Due to the local scope of aRoll, that variable is not defined outside of the function pQuestion().

For more information about variable scope, look here. This page may also prove useful:

http://gettingstartedwithpython.blogspot.com/2012/05/variable-scope.html

Community
  • 1
  • 1
McGlothlin
  • 2,059
  • 1
  • 15
  • 28
  • Yea. I just forgot that when a variable is given a value in a function. the entire function holds that value now, not just that variable. So rather than trying to call out the specific variable used (aRoll), I had to call the entire function, as is the one that holds the value. Thanks for the help. – RuleofThree Nov 03 '15 at 22:54
0

pQuestion() returns aRoll but you never assign the return value. pStats() expects you to pass in aRoll but you never do.

Josh J
  • 6,813
  • 3
  • 25
  • 47
  • I just noticed that myself, sorry. I'm still confused as to why aRoll is not holding the 'y' or 'n' answer when returned. Breaking the code down, and just running only the def pQuestion() function, then asking it to print aRoll... ...aRoll is still undefined. If I label it globally as 'aRoll = None' It will print 'none' obviously. There is something really simple here I am missing, but I can't see it. – RuleofThree Nov 03 '15 at 21:43
0

You don't return "the variable" but the value of the variable at the point of the return statement. The name of the variable in the function is completely irrelevant. This is a Good Thing: functions are a way to encapsulate pieces of code. Imagine a simple function that adds two numbers:

def add(a, b):
  result = a+b
  return result

and then the author changes his mind and renames the variable inside the function:

def add(a, b):
  sum = a+b
  return sum

and finally, he's clever and just does

def add(a, b):
  return a+b

As a user of this function, you should not bother about the names inside the function. You use the add function because you expect it to return the sum of the arguments, no matter how the function works internally.

If you want to use the result of a function, you must store it in a variable yourself:

sum_of_2_and_3 = add(2,3)
print(sum_of_2_and_3)
Jasper
  • 3,939
  • 1
  • 18
  • 35
0

Not to be discouraging, but your code is a long way from working even once we correct the issue with aRoll. You'll probably have to follow up with some other questions.

As for your immediate problem:

aRoll is defined in pQuestion() and only exists for the duration of that function call (it is in scope only within that function).

When you return aRoll in the function the name aRoll is lost and the value of aRoll "pops out" of the function into the calling code. Unfortunately, you're not catching that value so it basically dissolves into the ether, never to be seen again.

In order to catch the value you need to assign it, like this:

 answer = pQuestion()

Now, you have a new variable called answer containing the value "popped out" of the function pQuestion() (y or n in this case). Note that you could also write aRoll = pQuestion() and you'd have a variable named aRoll containing the value from pQuestion() but, importantly, it would not be the same variable as the one INSIDE pQuestion() because that one was already lost. While you're learning, it's probably a better idea to use different variable names everywhere so you don't get confused and believe that the same-named variables are actually the same (rather than variables in different scopes that coincidentally share a name)

That's thing one. Next, you have somehow get the value of answer or aRoll or foobar or whatever name you gave to that value into pStats(). You've already told pStats() to expect to receive one value and to name that value aRoll -- but this aRoll, like the first one, is in scope only inside the pStats() function. The problem is, you're not actually supplying the value to pStats(), which you would do like this:

 pStats(answer)

or

 pStats(aRoll)

or

 pStats(foobar)

or whatever name you chose for the variable.

There is another solution to this problem which is to declare the variables as global and not pass them around. I urge you not to pursue this solution as it leads to very bad programming habits and should only be used in rare circumstances after you fully understand the idea of local scope.

Larry Lustig
  • 49,320
  • 14
  • 110
  • 160
  • No. I understand this is far, far, faaar from a 'perfect' code. I am re-learning code after a long hiatus. I know there are other issues. Like, for example, the 'while aRoll == y' statement, once I correct it to carry over the answer 'y', will create an infinate loop. There is also the matter of turning it in to a class to use in a larger program. At the risk of sounding like a guy trying to cover his tracks...the moment you mentioned ' aRoll = pQuestion' I knew where my error was. I'm sure there are other errors other than the infinite loop. But thanks for the help regardless. – RuleofThree Nov 03 '15 at 22:45