Referencing variable from a def block in another def block - python

Basically I have this section of code that goes like so:
def start():
def blockA():
y = 3
x = 4
print("hello")
blockA()
def blockB():
if x !=y:
print("not the same")
blockB()
start()
However, this gives me an error saying that x and y are not defined. How would I go about referencing the x and y variables in blockB?

You need to return the variables in blockA function and call that function in your second function.
def blockA():
y = 3
x = 4
print("hello")
return x,y
def blockB():
x,y=blockA()
if x !=y:
print("not the same")
This should work for you.

Related

Is it possible store return value of one function as Global Variable?

I Have function register a patient that will Return Medical record Number , Need store this as Global Variable to so that use the same for Different Functions Eg: Create Vital Sign , Create Lab Order etc.
aqTestCase.Begin(" User able to Register a Unknown patient")
Log.AppendFolder("Unknown Registeration Logs")
ERPage=Aliases.MedBrowser.pageER
ReusableFunctions.ClickonObject(ERPage.RegisterUnknownPatientIcon)
ReusableFunctions.ClickonObject(ERPage.UnknownRegMaleLabel)
ReusableFunctions.setTextValue(ERPage.txtAge, "20")
ReusableFunctions.ClickonObject(ERPage.UnknownRegregistrBtn)
ReusableFunctions.ClickonButton(ERPage.AssignBuutonclose)
AppReusableFunctions.getToastMsgs(ERPage)
labelER = Aliases.VidaPlusBrowser.pageER.FindElement("//span[.='ER']")
ReusableFunctions.ClickonObject(labelER)
mrn = ERPage.FindElement("//div[10]/div[5]/app-er-patient-grid-mrn/span").contentText
aqUtils.Delay(2000)
ReusableFunctions.ClickonObject(ERPage.ERArrvialTime)
Log.Message(" Unknown Patient Registred MRN is : " +mrn)
return mrn
You can set the variable as a global variable and return it.
def foo():
global X
X = 1
return X
In your case, creating a class may work better.
class Foo:
def __init__(self, x):
self.x = x
def bar(self):
return self.x
f = Foo(1)
f.bar()
x = "awesome"
def myfunc():
global x
x = "fantastic"
myfunc()
print("Python is " + x)

Value being updated in a different function doesn't return its updated value

This is a simplified version I made of the problem I'm having
I have my Game() function that calls the other UpdateScore() and Score() functions, UpdateScore() adds 1 to computerScore, and Score() prints that updated value.
But that value either doesn't get updated, what am I doing wrong?
import time
def Game():
condition = True
computerScore = 0
while (condition):
time.sleep(2)
UpdateScore(computerScore)
Score(computerScore)
def UpdateScore(computerScore):
computerScore = computerScore+1
return
def Score(computerScore):
computerScore = UpdateScore(computerScore)
print(computerScore)
Game()
Python doesn't pass variables by value. It doesn't pass it by reference either. It passes variables by assignment.
Refer to the code snippet below.
>>> def main():
... n = 9001
... print(f"Initial address of n: {id(n)}")
... increment(n)
... print(f"Final address of n: {id(n)}")
...
>>> def increment(x):
... print(f"Initial address of x: {id(x)}")
... x += 1
... print(f"Final address of x: {id(x)}")
...
>>> main()
Initial address of n: 140562586057840
Initial address of x: 140562586057840
Final address of x: 140562586057968
Final address of n: 140562586057840
You can notice how the address remains the same after passing to the function but only changes after the increment.
There is a simple fix to this. You can simply return computerScore from the updateScore() function and assign it to the original variable in the Game() function. Check the modified code below.
import time
def Game():
condition = True
computerScore = 0
while (condition):
time.sleep(2)
computerScore = UpdateScore(computerScore)
Score(computerScore)
def UpdateScore(computerScore):
computerScore = computerScore+1
return computerScore
def Score(computerScore):
computerScore = UpdateScore(computerScore)
print(computerScore)
Game()
Cheers.
UpdateScore is not returning the updated value. Add a return statement there
The below code gives an output of 1,2
import time
def Game():
condition = True
computerScore = 0
while (computerScore < 2): #Change condition to avoid infinite loop
computerScore = UpdateScore(computerScore)
Score(computerScore)
def UpdateScore(computerScore):
computerScore = computerScore+1
return computerScore
def Score(computerScore): # Score is just printing the o/p
print(computerScore)
Game()
"computerScore" is a value thats being passed around, so any changes that you make to it in subsequent function calls will not affect the original value, you will have to return the updated value for the change to be reflected, which in your case is not being done.
A working sample can look something like below.
import time
def Game():
condition = True
computerScore = 0
while (condition):
time.sleep(2)
computerScore = UpdateScore(computerScore)
Score(computerScore)
def UpdateScore(computerScore):
computerScore = computerScore+1
return computerScore
def Score(computerScore):
print(computerScore)
Game()
I am not sure what you are trying to do here.
So, when you call the UpdateScore function, you are creating & updating a new variable, that's why your original one does not get updated. Why not just put computerScore=computerScore+1 (computerScore += 1 also works) in your original code instead of creating a new function? Also, you can just print() at the end with no extra function.
You might want to use a class in that particular case.
I hope this helps.

Python variable's value doesn't get changed outside the function

I'm working on a school project. I made a test version of my program, because I'm new to Python and I only have experience with C#, so I'm still learning te basics. My problem is the following:
Before the function "Fill_Array()" I declared a variable (" max_element_var") that is supposed to store the max number of elements that can be stored in the array ("content_array"). Later in the function I change it's value to the input of the console, which happens, and the function runs as it should, the only problem being is that outside the function the value of " max_element_var" stays "None". What should I do in order to fix this?
#__Test__#
def Test():
class Que:
def __init__(self, content, max_element ,actual_elements):
self.content = content
self.max_element = max_element
self.actual_elements = actual_elements
max_element_var = None
content_array = []
def Fill_array():
print("What should be the max number of elements that can be stored in the array? (Type in an integer!)")
max_element_var = int(input())
if(max_element_var>0):
import random
random_var = random.randrange(0,max_element_var)
for x in range(max_element_var-random_var):
content_array.append(x)
else:
print("It has to be more than 0!")
Fill_array()
Fill_array()
actual_elements_var = len(content_array)
que = Que (content_array, max_element_var, actual_elements_var)
print("Content: ", que.content)
print("Max number of elements: ", que.max_element)
print("Actual number of elements: ", que.actual_elements)
#__Test__#
#__Full__#
def Full():
pass
#__Full__#
#__Version_selector__#
def Version_selector():
print("Which version should be used? (Type in the number!)")
print("1 - Test")
print("2 - Full")
answer = int(input())
if(answer == 1):
Test()
Version_selector()
elif(answer == 2):
Full()
Version_selector()
#__Version_selector__#
Version_selector()
In python variables are automatically created as local, in the scope of the function which used them alone.
To solve your problem you may either
(1) return the variable, passing it from one function the other explicitly.
(2) declare it as global so all functions have access to it.
More about scopes here and here.
Consider the following code. In the code below you persumably change the value of x but in fact there is a big difference between the x inside the function and outside. The x inside the function is a local variable and will "disappear" once the function ends. If you want to save the value of x you must use return x and save the outcome to a variable. For example, See the function a_saving_example(x)
you may also use a global variable though some say it is bad practice and it is better to use return in your function.
def times_two(x):
x = x * 2
x = 5
print(x)
times_two(x)
print(x)
output:
5
5
saving example:
def a_saving_example(x):
x = x * 2
return x
x = 5
print(x)
x = a_saving_example(x)
print(x)
output:
5
10
Modified code to correct some issues.
Import normally done at top of module (not within functions)
Remove nested class definition inside function (obfuscates things in simple code)
Changed recursive calls to a while loop (a better way to repeat execution of a function from beginning in Python since no tail recursion).
Code Refactoring
import random
class Que:
def __init__(self, content, max_element ,actual_elements):
self.content = content
self.max_element = max_element
self.actual_elements = actual_elements
def Fill_array():
" Returns requested size and array "
while True:
prompt = """"What should be the max number of elements that can be stored in the array? Type in an integer!: """
max_element_var = int(input(prompt))
if max_element_var > 0:
random_var = random.randrange(0,max_element_var)
return max_element_var, [x for x in range(max_element_var-random_var)]
else:
print("It has to be more than 0!")
def Test():
max_element_var, content_array = Fill_array()
actual_elements_var = len(content_array)
que = Que (content_array, max_element_var, actual_elements_var)
print("Content: ", que.content)
print("Max number of elements: ", que.max_element)
print("Actual number of elements: ", que.actual_elements)
#__Test__#
#__Full__#
def Full():
pass
#__Full__#
#__Version_selector__#
def Version_selector():
while True:
prompt = """Which version should be used? (Type in the number!)
1 - Test
2 - Full
3 - Quit\n\t"""
answer = int(input(prompt))
if answer == 1:
Test()
elif answer == 2:
Full()
else:
break
#__Version_selector__#
Version_selector()

Abstracting if statement and return by a function

I have a function like this:
def test():
x = "3" # In actual code, this is computed
if x is None:
return None
y = "3"
if y is None:
return None
z = "hello"
if z is None:
return None
Is there a way of making the if statement go away and abstract it with some function. I'm expecting something like this:
def test():
x = "3"
check_None(x)
y = "3"
check_None(y)
z = "hello"
check_None(z)
Ideally, check_None should alter the control flow if the parameter passed to it is None. Is this possible?
Note: Working on Python 2.7.
You can easily code it in some thing like this.
def test():
#compute x, y, z
if None in [x, y, z]:
return None
# proceed with rest of code
An even better way would be to use an generator to generate value x, y, z so that you only does computation for one value at a time.
def compute_values():
yield compute_x()
yield compute_y()
yield compute_z()
def test():
for value in compute_values():
if value is None:
return None
I am not really sure if we should do it like this, but one of the hacks could be like this, Also create your own exception class and only catch that particular exception so that no other exceptions are accidentally caught by the except and return None.
class MyException(Exception):
pass
def check_none(x):
if x is None:
raise MyException
def test():
try:
z=None
check_none(z)
except MyException, e:
return None
return_value = test()

python run code that is in a function once

I am trying to make a variable in Python go up by one continuously, but inside a function. What I am using is something like this:
def func1():
def set1():
x=5
y=10
##lots of code
x+=1
y+=1
def func2():
while True:
func1()
set1()
func2()
I'm wondering if there is a much better way to do this?
Probably the best way to do this is to put the definition of x and y into function 2, and have them be inputs and outputs of function 1.
def func1(x, y):
##lots of code
x+=1
y+=1
return x, y
def func2():
x = 5
y = 10
while True:
x, y = func1(x, y)
Other alternatives include defining x and y globally and using global x, global y or using mutable default arguments to make the function retain state, but generally better to not resort to these options if you don't have to.
A bit of code review and recommendations:
def func1():
def set1():
x=5
y=10
##lots of code
x+=1
y+=1
def func2():
while True:
func1()
set1() # This won't work because set1 is in the local scope of func1
# and hidden from the global scope
func2()
Looks like you want the function to count each time it is called. May I suggest something like this?:
x=5
y=10
def func1():
global x, y
x+=1
y+=1
print x, y
def func2():
while True:
func1()
func2()
Better than using a global variable, stick them in a mutable object in a nested scope:
Counts = dict(x=5, y=10)
def func1():
Counts['x'] += 1
Counts['y'] += 1
print Counts['x'], Counts['y']
def func2():
while True:
func1()
func2()
x = None
y = None
def set1():
global x, y
x=5
y=10
def func1():
global x, y
x+=1
y+=1
def func2():
while True:
func1()
set1()
func2()
** just saw the edit on going up instead of down - modified code to suit**
It's hard to tell from your question what your actual use case is but I think a Python generator may be the right solution for you.
def generator(x, y):
yield x,y
x += 1
y += 1
Then to use:
if __name__ == "__main__":
my_gen = generator(10,5)
for x,y in my_gen:
print x,y
if x+y > 666:
break
This may be a slightly advanced for someone new to Python. You can read up on generators here: http://anandology.com/python-practice-book/iterators.html
First of all, the set1 function doesn't seem to do much at all, so you could take it away.
If you want to keep count of the number of calls or keep state between calls, the best, more readable way is to keep this inside an object:
class State(object):
def __init__(self):
self._call_count = 0
self.x = 5
def func1(self):
self._call_count += 1
self.x = ... Whatever
def func2():
state = State()
while True:
state.func1()

Categories

Resources