Print a list from another function [duplicate] - python

This question already has an answer here:
Python - Passing variables through functions
(1 answer)
Closed 1 year ago.
How can I get this to work
Should I use a gloabl variable or a args?
I'm very confused.
def getvenueurl():
# code as part of a loop
venueURList.append(tMD)
# end loop
def getraceurl():
print(venueURList)
getvenueurl()
getraceurl()

In this case you can define the variable outside of functions scope.
Exemple:
venueURList = []
def getvenueurl():
# code as part of a loop
venueURList.append(tMD)
# end loop
def getraceurl():
print(venueURList)
getvenueurl()
getraceurl()

Just return the list in a function. Store the returned value in a variable and pass it through a new function.
def getvenueurl():
# code as part of a loop
venueURList.append(tMD)
return venueURList
# end loop
def getraceurl(lst):
print(lst)
venueList = getvenueurl()
getraceurl(venueList)
Or another option would be to use global venueURList

In order to access a global variable inside a function, you must type:
global venueURList
before it is referenced or modified (in your case, append and print)
Generally, it is a better idea to pass the global variable into the parameter and return it instead.
def getvenueurl(venueList):
venueList.append(tMD)
return venueList

Related

return function not saving the value and later u call the variable it says variable not define [duplicate]

This question already has answers here:
Short description of the scoping rules?
(9 answers)
Closed 2 years ago.
I'm writing a function in Python where I take user input and validate it. Later I'm saving it to a variable using return.
But after calling the variable, it says variable not defined.
def user_input():
position = 'wrong'
position_range = range(1,10)
within_range = False
while position.isdigit == False or within_range == False:
position=input('select the postion from (1-10): ')
if position.isdigit()==False:
print('hey! thats not a valid input')
elif position.isdigit()==True:
if int(position) in position_range:
within_range=True
else:
print('hey! thats out of range')
within_range=False
return int(position)
user_input()
print(position)
The way return works is that you can do the following:
variable = function()
And whatever function() returns, will be assigned to the variable.
You should do the following:
position = user_input()
print(position)
By the way, I would recommend using a different name for position, as it is also used inside the function, but because that position was defined inside the function, it exists only in the function's scope, and is different from the position outside. As such, you should name them differently.
there is no position variable outside the function, so the code cannot recognize it.
You must
print(user_input())
at the end of your code to have the result you want, or more clearly you can assign the result of user_input() to a variable and print it
x=user_input()
print(x)
You cannot access the variable position outside of the function due to its limited scope. The scope of the variable is within the function user_input() and it can only be accessed within it. To access it outside you need to do something like:
position = user_input()
print(position)

Can a Python function remember its previous outputs? [duplicate]

This question already has answers here:
What is the Python equivalent of static variables inside a function?
(28 answers)
Closed 3 years ago.
Is there a way that a function can remember its previous output and use that value during the next call to the function? For instance, assume there is a function, runningTotal with a single argument x that returns x on the first call to runningTotal but x + prevOutput for every call after that. Is there a way to write such a function in python?
I am aware that this could be easily achieved by using a global variable in the function or by saving the previous value to a new variable, but I would like to avoid these solutions if possible. The reason I'm looking for an alternate solution is because this is one function in a program I'm working on with other people and I would like to avoid having to create more global variables than already established.
Yes, but to avoid too much hackery or GLOBAL variables we'll probably want to use a class.
In python a class can be treated as function with a magic function (method) inside the class named __call__.
Your question might be better written: what's the best way to have a function in python that has internal state?
Let's say we have the runningTotal function defined using a global variable as:
TOTAL = 0
def runningTotal(inc):
global TOTAL
TOTAL += inc
return TOTAL
Answer Ok so lets define a class that will behave the same way as the above function but without a global variable:
class StatefulFunction:
running_total = 0
def __call__(self, inc):
self.running_total += inc
return self.running_total
# create the stateful function variable
runningTotal = StatefulFunction()
# Use the stateful function
runningTotal(1)
# outputs: 1
runningTotal(5)
# outputs: 6
Another way to accomplish the same thing is with a Counter Dictionary
from collections import Counter
counter = Counter()
counter['runningTotal'] += 1
# in another part of the program
counter['runningTotal'] += 5
The output will be:
print(counter)
Counter({'runningTotal': 6})
Although there are ways of doing what you ask, it's not a good idea. As #JohnColeman pointed out, Simulate static variables in python with closures
But why not create a class?
class Accumulator:
total = 0
#classmethod
def add(cls, x):
cls.total += x
return cls.total
print(Accumulator.add(1))
print(Accumulator.add(2))
print(Accumulator.add(3))
Result:
1
3
6
You can set up a generator to maintain state and send values to it as well, as suggested by #HeapOverflow:
def get_running_total():
def _running_total():
value = 0
while True:
value += yield value
# get a generator instance
generator = _running_total()
# set it up to wait for input
next(generator)
# return the send method on the generator
return generator.send
# you can get a generator that functions similar to the Accumulator method
running_total = get_running_total()
print(running_total(1)) # prints 1
print(running_total(2)) # prints 3
print(running_total(3)) # prints 6

changing global variables within a function in python [duplicate]

This question already has answers here:
Using global variables in a function
(25 answers)
Closed last month.
I'm new to python.
I don't quite understand how I need to set variables and change them within a function to be used late. My script needs to get an x and y value from a function which are determined by the size of the chart the function creates. These variable need to be passed to a print command later in the script to output html. So let's say I have global variables:
originx_pct = 0.125
originy_pct = 0.11
But these will need to change when the funtion is run...
def makeplot(temp, entropy,preq):
originx_pct = origin.get_points()[0][0]
originy_pct = origin.get_points()[0][1]
Then printed within the javascript of the html page that is written later...
print('var originx_pct = {};'.format(originx_pct))
print('var originy_pct = {};'.format(originy_pct))
The 2 variables don't change and I just don't understand what I need to do to update them and be able to print them (outside the function). I'm assuming that the function does not know about the variables so it can't change them. If I feed the function the 2 variables as arguments, how do i get the values back out for the print part of the script?
You need to use the global keyword in your function.
originx_pct = 0.125
originy_pct = 0.11
def makeplot(temp, entropy,preq):
global originx_pct, originy_pct
originx_pct = origin.get_points()[0][0]
originy_pct = origin.get_points()[0][1]
You can read more about global here.
In your function, you need to return the values. Change your makeplot to the following:
def makeplot(temp, entropy, preq):
local_originx_pct = origin.get_points()[0][0]
local_originy_pct = origin.get_points()[0][1] # the local_ in the names doesn't mean anything, it is just for clarity.
return local_originx_pct, local_originy_pct
Then, when you call the function, set your variables to its return value.
originx_pct, originy_pct = makeplot(args_and_stuff)
This is considered better practice then directly changing global variables as in ltd9938's answer. It helps to prevent accidentally messing stuff up for other functions. More reasons not to use global
You can either declare the global variables in the function with the lines global originx_pct and global originy_pct, or you can return them when you run the function. To do that, you can do
def makeplot(temp, entropy,preq):
return (origin.get_points()[0][0],origin.get_points()[0][1])
Or
def makeplot(temp, entropy,preq):
return origin.get_points()[0][0:2]
If origin.get_points()[0] has only two elements, you do just this:
def makeplot(temp, entropy,preq):
return origin.get_points()[0]
Then, in your main function, put
originx_pct, originy_pct = makeplot(temp, entropy,preq)
Although I'm not clear on why you're passing temp, entropy, and preq to makeplot, since you don't seem to be using them.

Python - using a shared variable in a recursive function

I'm using a recursive function to sort a list in Python, and I want to keep track of the number of sorts/merges as the function continues. However, when I declare/initialize the variable inside the function, it becomes a local variable inside each successive call of the function. If I declare the variable outside the function, the function thinks it doesn't exist (i.e. has no access to it). How can I share this value across different calls of the function?
I tried to use the "global" variable tag inside and outside the function like this:
global invcount ## I tried here, with and without the global tag
def inv_sort (listIn):
global invcount ## and here, with and without the global tag
if (invcount == undefined): ## can't figure this part out
invcount = 0
#do stuff
But I cannot figure out how to check for the undefined status of the global variable and give it a value on the first recursion call (because on all successive recursions it should have a value and be defined).
My first thought was to return the variable out of each call of the function, but I can't figure out how to pass two objects out of the function, and I already have to pass the list out for the recursion sort to work. My second attempt to resolve this issue involved me adding the variable invcount to the list I'm passing as the last element with an identifier, like "i27". Then I could just check for the presence of the identifier (the letter i in this example) in the last element and if present pop() it off at the beginning of the function call and re-add it during the recursion. In practice this is becoming really convoluted and while it may work eventually, I'm wondering if there is a more practical or easier solution.
Is there a way to share a variable without directly passing/returning it?
There's couple of things you can do. Taking your example you should modify it like this:
invcount = 0
def inv_sort (listIn):
global invcount
invcount += 1
# do stuff
But this approach means that you should zero invcount before each call to inv_sort.
So actually its better to return invcount as a part of result. For example using tuples like this:
def inv_sort(listIn):
#somewhere in your code recursive call
recursive_result, recursive_invcount = inv_sort(argument)
# this_call_invcount includes recursive_invcount
return this_call_result, this_call_invcount
There's no such thing as an "undefined" variable in Python, and you don't need one.
Outside the function, set the variable to 0. Inside the loop, use the global keyword, then increment.
invcount = 0
def inv_sort (listIn):
global invcount
... do stuff ...
invcount += 1
An alternative might be using a default argument, e.g.:
def inv_sort(listIn, invcount=0):
...
invcount += 1
...
listIn, invcount = inv_sort(listIn, invcount)
...
return listIn, invcount
The downside of this is that your calls get slightly less neat:
l, _ = inv_sort(l) # i.e. ignore the second returned parameter
But this does mean that invcount automatically gets reset each time the function is called with a single argument (and also provides the opportunity to inject a value of invcount if necessary for testing: assert result, 6 == inv_sort(test, 5)).
Assuming that you don't need to know the count inside the function, I would approach this using a decorator function:
import functools
def count_calls(f):
#functools.wraps(f)
def func(*args):
func.count += 1
return f(*args)
func.count = 0
return func
You can now decorate your recursive function:
#count_calls
def inv_sort(...):
...
And check or reset the count before or after calling it:
inv_sort.count = 0
l = inv_sort(l)
print(inv_sort.count)

Why nested functions can access variables from outer functions, but are not allowed to modify them [duplicate]

This question already has answers here:
Is it possible to modify a variable in python that is in an outer (enclosing), but not global, scope?
(9 answers)
Closed 8 years ago.
In the 2nd case below, Python tries to look for a local variable. When it doesn't find one, why can't it look in the outer scope like it does for the 1st case?
This looks for x in the local scope, then outer scope:
def f1():
x = 5
def f2():
print x
This gives local variable 'x' referenced before assignment error:
def f1():
x = 5
def f2():
x+=1
I am not allowed to modify the signature of function f2() so I can not pass and return values of x. However, I do need a way to modify x. Is there a way to explicitly tell Python to look for a variable name in the outer scope (something similar to the global keyword)?
Python version: 2.7
In Python 3.x this is possible:
def f1():
x = 5
def f2():
nonlocal x
x+=1
return f2
The problem and a solution to it, for Python 2.x as well, are given in this post. Additionally, please read PEP 3104 for more information on this subject.
def f1():
x = { 'value': 5 }
def f2():
x['value'] += 1
Workaround is to use a mutable object and update members of that object. Name binding is tricky in Python, sometimes.

Categories