Using returned variables in other functions - python

I am pretty new to python, and I was wondering about return and the stuff inside () when defining a new function. I do not want to run any code inside if __name__ == '__main__':. I want a function to do it. Why won't this work?
def money():
coins = 100
return coins
def doubleMoney(coins):
doubleCoins = int(coins * 2)
return doubleCoins
def printMoney(doubleCoins):
print("Your coins doubled are:", doubleCoins)
if __name__ == '__main__':
money()
doubleMoney(coins)
printMoney(doubleCoins)

No, that will not work. Think of a function as a machine. You put things in one end (arguments, aka "the stuff in () when defining a new function), and you get something out at the other end. What you get out is a value. It doesn't create a variable with a certain name or anything like that.
So if you want to use the value of doubleMoney(coins), you have to do something with it. In your example, you just call doubleMoney(coins). This will result in a value, but you don't do anything with it. If you want one function to use a value that another function returns, you have to link them up somehow. What you probably are looking for is something like:
coins = money()
doubleCoins = doubleMoney(coins)
printMoney(doubleCoins)
You could also do it all in one line with printMoney(doubleMoney(money())).
They key thing is that just because you did return coins doesn't mean a variable with that name is created when money() returns. Only the value is returned; if you want to make a variable, you have to do that yourself outside the function, like in the example I showed.

Related

Python 3 changing variable inside function without using global variables

So i am currently working on a university project, therefore i can't really paste my code to be more specific, but we have this stupid rule that global variables are not allowed and using them would lead to points removal. So my question is:
I am making a roll the dice game, where a couple of players take turns and i need a variable that identifies which player is on turn. I have a function, which represents each turn and a second, which calls the first function multiple times, which is equal to the number of players. Lets say i have 3 players:
def func1():
player_on_turn = 1
result = 0
print('Player',player_on_turn,'is on turn.')
#something
return result
def func2():
players = 3
for player in range(1,players+1):
player = func1()
func2()
So this variable player_on_turn has to change 3 times, meaning for each call of the function. The first call it is equal to 1, the second to 2, etc.
I've done this already with global variable, but apparently i can't use them, because "it makes the code hard to read". In the first function i am already using return for a one value which changes inside the function and is being reset each call. Is there a way i could probably do this? Thanks in advance!
You can use Function Parameters to pass data between functions.
You can also use a Class to create objects that store data without global variables.

Return variable from a function

This section of a program I am writing is supposed to take the random choice and then print it outside the function (I can't print from within as I need the variable later).
I am sure there is a simple solution to this, but I am unsure what it is.
#python2
def CompTurn():
RandTurn = [Column1,Column2,Column3,Column4]
Choice = random.choice(RandTurn)
return(Choice)
print Choice
Thank you.
Add the line
Choice = CompTurn()
before your print statement. Because the variables you declare within the function are not known outside of it, you have to store (or print directly, but then you cannot store it) the returned variable in a new variable.
You have defined your function correctly, but you never executed it! (You'll see that if you make it print something as a diagnostic.) You must run it to get the result:
chosen = CompTurn()
print chosen
Note that I used a different variable name. You could use the same variable name as a variable in your function, but it's still a different variable than the one in your function.
It is also important to realize that your function returns a value, not a variable. You can assign the value to a variable (as above) or print it immediately.
print CompTurn()
About your program, you don't need the brackets for return. It's s statement, not a function.
def CompTurn():
RandTurn = [Column1,Column2,Column3,Column4]
Choice = random.choice(RandTurn)
return Choice
Shorter:
def CompTurn():
RandTurn = [Column1,Column2,Column3,Column4]
return random.choice(RandTurn)
To print the return value, You can save it in a variable and print it
ret = CompTurn()
print ret
Or print directly:
print CompTurn()

Local Function Call on itself

Learning python, searched for this problem, and having a hard time figuring out why I'm getting the behavior that I am. I'm getting the correct output, but I'm not sure why, I'd just like to know going forward just to better understand this concept. Let me explain:
if create a function such as
def function(list):
and I then call this function on a list x
print function(x)
if I were then to recall this function with the function itself like so:
def function(list):
function(list)
why does that recursive call still hold the values for x which was called globablly?
The "list" in the parameter list is then passed to the next call. Each one is a direct copy of x. It's not the global x; it's the local copy in the variable list that gets passed down.
Note that this is a direct example of infinite recursion: there's no way to stop the chain of the function calling itself. Instead, you might want something like
def function(list):
if len(list) == 0:
return "end"
else
return function(list[1:]) + list[0]
A recursive function needs a terminating condition and something to return.

NameError when using a variable returned by a function

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?
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.)
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:
Since you defined a parameter for pstats(), the interpreter will tell you that you're missing a parameter when you try to run this.
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
pQuestion() returns aRoll but you never assign the return value. pStats() expects you to pass in aRoll but you never do.
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)
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.

Parentheses in Python's functions and decorators(wrappers)

Thanks for reading my question. As I'm still new to Python, I would like to ask about the () in Python.
def addOne(myFunc):
def addOneInside():
return myFunc() + 1
return addOneInside # <-----here is the question
#addOne
def oldFunc():
return 3
print oldFunc()
Please note that on line four, although the programme returns a function, it does not need parentheses(). Why does it NOT turn out with an error for syntax error? Thank you very much for your answers in advance!
The parentheses are used to run a function, but without them the name still refers to the function just like a variable.
return myFunc() + 1
This will evaluate the myFunc function, add 1 to its value and then return that value. The brackets are needed in order to get the function to run and return a numeric value.
return addOneInside
This is not actually running addOneInside, it is merely returning the function as a variable. You could assign this to another name and store it for later use. You could theoretically do this:
plusOne = addOneInside
plusOne()
And it will actually call the addOneInside function.
The particular instance in your initial question is known as a Decorator, and it's a way for you to perform code on the parameters being passed to your function. Your example is not very practical, but I can modify it to show a simple use case.
Let's say that you want to only have positive numbers passed to your function. If myFunc is passed a negative number, you want it to be changed to 0. You can manage this with a decorator like this.
def addOne(myFunc):
def addOneInside(num):
if num < 0:
num = 0
return myFunc(num)
return addOneInside # <-----here is the question
#addOne
def oldFunc(number):
return number
To explain, the #addOne is the decorator syntax, and it's attaching the addOneInside function to be called on the argument/s of oldFunc whenever you call it. So now here's some sample output:
oldFunc(-12)
>>> 0
oldFunc(12)
>>> 12
So now you could add logic to oldFunc that operates independently of the parameter parsing logic. You could also relatively easily change what parameters are permitted. Maybe there's also a maximum cap to hit, or you want it to log or note that the value shouldn't be negative. You can also apply this decorator to multiple functions and it will perform the same on all of them.
This blogpost explained a lot for me, so if this information is too brief to be clear, try reading the long detailed explanation there.
Your indentation in function addOne() was incorrect (I have fixed it), but I don't think that this was your problem.
If you are using Python3, then print is a function and must be called like this:
print(oldFunc())

Categories