I have the following loop structure and also the problem, that it is not possible to increment a variable inside of this code due to UnboundLocalError:
while True:
def function_1():
def function_2():
x += 1
print(x)
function_2()
function_1()
My solution was now this one:
x = 0
while True:
def function_1():
def function_2():
global x
x += 1
print(x)
function_2()
function_1()
Is there another solution without global?
use a mutable value.
x = []
x.append(0)
while True:
def function_1():
def function_2():
x[0]= x[0]+1
print x[0]
function_2()
function_1()
Pass and return x to all the functions.
x = 0
while True:
def function_1(x1):
def function_2(x2):
x2 += 1
print(x2)
return x2
return function_2(x1)
x = function_1(x)
Related
I have the following code:
class MyFirstClass:
def myDef(self):
global x, y
x = 'some_str'
y = 0
class MySecondClass:
def myOtherDef(self):
for i in range(10):
y += 1
if y % 2 == 0:
y = 0
x = 'new_str'
However, y += 1 errors with local variable 'y' defined in an enclosing scope on line 4 referenced before assignment
How can I re-assign variable y in the new class?
There are 2 issues with this. The first is that you need to define x and y as members of MyFirstClass, not as globals in a method. You won't be able to access them that way. The second is that you need an instance of MyFirstClass in MySecondClass:
class MyFirstClass:
x = 'some_str'
y = 0
class MySecondClass:
myFirstClass = MyFirstClass()
def myOtherDef(self):
for i in range(10):
self.myFirstClass.y += 1
if self.myFirstClass.y % 2 == 0:
self.myFirstClass.y = 0
self.myFirstClass.x = 'new_str'
print(self.myFirstClass.x)
mySecondClass = MySecondClass()
mySecondClass.myOtherDef()
Output:
new_str
new_str
new_str
new_str
new_str
I have the following generator function which adds two numbers:
def add():
while True:
x = yield "x="
y = yield "y="
print (x+y)
And I can call it like this:
x=add()
next(x)
'x='
x.send(2)
'y='
x.send(3)
# 5
I thought it would be trivial to add in an init so that I don't have to do the next and I can just start sending it values, and so I did:
def init(_func):
def func(*args, **kwargs):
x=_func(*args, **kwargs)
next(x)
return x
return func
Or, simplifying it to receive no input variables like the function above:
def init(func):
x=func()
next(x)
return x
I thought that doing:
x=init(add) # doesn't print the "x=" line.
x.send(2)
'y='
x.send(3)
5
Would work, but it seems it acts just like as if the init is not there at all. Why does this occur, and how can I get rid of that behavior?
It seems to work for me. Tried
def add():
while True:
x = yield 'x='
y = yield 'y='
print (x+y)
def init(func):
x=func()
next(x)
return x
a = init(add)
a.send(5)
a.send(10)
For me this returns 15, as expected.
[update]
After your update, I think you might just want to print out the a.send():
def add():
while True:
x = yield 'x='
y = yield 'y='
print (x+y)
def init(func):
x=func()
print(next(x))
return x
a = init(add)
print(a.send(5))
a.send(10)
Your code works as-is, however, if you want to print the output that occurs before the field yield statement, then you can adapt the init method to do just that. For example:
def init(func):
x=func()
a=next(x)
if a: print (a) # this line will print the output, in your case 'x='
return x
And now you have:
>>> x=init(add)
x=
>>> x.send(2)
'y='
>>> x.send(3)
5
And finally, to keep your more generalized approach, you can do something like the following with a decorator:
def init_coroutine(_func):
def func(*args, **kwargs):
x=_func(*args, **kwargs)
_ = next(x)
if _: print (_)
return x
return func
#init_coroutine
def add():
while True:
x = yield "x="
y = yield "y="
print (x+y)
>>> x=add()
x=
>>> x.send(2)
'y='
>>> x.send(3)
5
Consider this example:
def func1():
val = 1
res = [1]
def fun2():
print(res)
print(val)
val = 2
fun2()
print(val)
func1()
It raises the following exception:
UnboundLocalError: local variable 'val' referenced before assignment
List res can be accessed by fun2, but val cannot. I know list is mutable and int is not, but is there a way to make val accessible by fun2 as well? In a class, I could easily achieve that with self.val, but is there a way to do it inside a function?
Use the nonlocal statement to make a variable defined in an enclosing function accesible inside the inner function, like so:
def func1():
val = 1
res = [1]
def fun2():
nonlocal val
print(res)
print(val)
val = 2
fun2()
print(val)
func1()
See also: earlier SO question.
You can do it in the following way:
def func1():
val = 1
res = [1]
def fun2(val=val, res=res):
print(res)
print(val)
val = 2
return val
val = fun2()
print(val)
Output is then
>>> func1()
[1]
1
2
a=0
def r(x):
global a
if len(str(x))==1:
print(a)
b=int(a)
a=0
return b
else:
a+=1
print(a)
r(reduce(lambda z, y: int(z)*int(y), list(str(x))))
def persistence(n):
if len(str(n))==1:
return 0
else:
return r(n)
(This is a challenge on codewars.com)
Why is the type(r(n))==NoneType?
The variable b is an integer so why isn't the type of the function integer too?
I believe your problem is that you are not returning a value from the function in the else case. So you should add the return keyword as shown below:
a=0
def r(x):
global a
if len(str(x))==1:
print(a)
b=int(a)
a=0
return b
else:
a+=1
print(a)
return r(reduce(lambda z, y: int(z)*int(y), list(str(x))))
def persistence(n):
if len(str(n))==1:
return 0
else:
return r(n)
I have a function that needs input as True/False that will be fed in from another function. I would like to know what is the best practice to do this. Here is the example I am trying:
def feedBool(self, x):
x = a_function_assigns_values_of_x(x = x)
if x=="val1" or x == "val2" :
inp = True
else
inp = False
feedingBool(self, inp)
return
def feedingBool(self, inp) :
if inp :
do_something
else :
dont_do_something
return
You can do:
def feedBool(self, x):
x = a_function_assigns_values_of_x(x = x)
feedingBool(self, bool(x=="val1" or x == "val2"))
Or, as pointed out in the comments:
def feedBool(self, x):
x = a_function_assigns_values_of_x(x = x)
feedingBool(self, x in ("val1","val2"))
why not just:
inp = x in ("val1", "val2")
of cause it can be compacted even more directly in the call to the next function, but that will be at the cost of some readability, imho.
You usually put the test in a function and spell out the consequence:
def test(x):
# aka `return x in ("val1", "val2")` but thats another story
if x=="val1" or x == "val2" :
res = True
else
res = False
return res
def dostuff(inp):
# i guess this function is supposed to do something with inp
x = a_function_assigns_values_of_x(inp)
if test(x):
do_something
else :
dont_do_something
dostuff(inp)