how to call an inner method - python

in the below code i am trying to understand the differences between global and local variables. At the runtime the following error is generated:#
File "m:\python lessons\globalAndLocal_1.py", line 21, in globalVsLocal_1
self.g2()
NameError: name 'self' is not defined
Note
i want to call g2 from within g1
please tell me how to call method g2()
code:
class globalVsLocal_1:
def f1(self):
global a #this is to reference a variable declared in the global context.
print ("f1 a = %s"%(a)) # if global a was not declared in the first line, generates this line an error as variable a not defined is
a = a + 10
print ("f1 a = %s"%(a))
def f2(self):
print("f2 a = %s"%(a))
def f3(self):
print("f3 b = %s"%(b))
#b = b + 1 #activating this line will yield an error. Because the absence of the keyword global. the print statement works immaculately without global keyword because it just reads the value without
#manipulate it
print("f3 b = %s"%(b))
def g1(self):
def g2():
print("g2 b = %s "%(b))
g2()
a = 1
b = 20
obj = globalVsLocal_1()
obj.f1()
obj.f2()
obj.f3()
obj.g1()

The scope of g2() is local to the function g1() so you cannot call it outside. It's also unusual that you try to call g2() in the middle of the class definition.
class ...
def g1(self):
def g2():
print("g2 b = %s "%(b))
g2()

class globalVsLocal_1:
def f1(self):
global a #this is to reference a variable declared in the global context.
print ("f1 a = %s"%(a)) # if global a was not declared in the first line, generates this line an error as variable a not defined is
a = a + 10
print ("f1 a = %s"%(a))
def f2(self):
print("f2 a = %s"%(a))
def f3(self):
print("f3 b = %s"%(b))
#b = b + 1 #activating this line will yield an error. Because the absence of the keyword global. the print statement works immaculately without global keyword because it just reads the value without
#manipulate it
print("f3 b = %s"%(b))
def g1(self):
def g2():
print("g2 b = %s "%(b))
g2()
a = 1
b = 20
obj = globalVsLocal_1()
obj.f1()
obj.f2()
obj.f3()
obj.g1()
You were missing indentation while called g2.
This gives the following output
f1 a = 1
f1 a = 11
f2 a = 11
f3 b = 20
f3 b = 20
g2 b = 20

Related

Name error while trying to generate some report

def state_from_record(state_name):
state_split = state_name.split(",")
return state_split
def cases_from_record(covid_cases):
covid_split = covid_cases.split(",")
return covid_split
def deaths_from_record(covid_deaths):
death_split = covid_deaths.split(",")
return death_split
result1 = state_from_record(result[0])
print(result1)
This is the second part of the code which continues on:
import random
def state_report(state, data_list):
if state_split is random:
states = choice(state_split)
for s in states:
if states == state_split:
return states + "\n" + "Total Confirmed Cases: " + covid_split + "Total Deaths: " + death_split
else:
return "No record found for " + states
result2 = state_report(states, state_split)
print(result2)
I am trying to use a previous code and it keeps on coming as a name error saying that "states" doesn't exist.
here is my output:
NameError Traceback (most recent call last)
<ipython-input-20-8fee8f642c90> in <module>()
10 return "No record found for " + states
11
---> 12 result2 = state_report(states, state_split)
13 print(result2)
NameError: name 'states' is not defined
What you are bumping into is a programming concept called the scope
Imagine these two functions:
def first_func():
foo = "abc"
print(foo)
def second_func():
print(foo)
second_func()
Running this code will raise NameError, because variable foo is out of the scope of the second_func, since it is defined within the boundaries of the first_func.
If you move the variable foo out of the first function, like so:
foo = "abc"
def first_func():
print(foo)
def second_func():
print(foo)
second_func()
Both functions will run fine. Because variable foo is now defined in a broader scope and accessible from within both functions.

Function as class attribute

I am writing a class where I would like to pass function as a class attribute and later use it, like that:
class Nevronska_mreza:
def __init__(self, st_vhodni, st_skriti, st_izhod, prenosna_funkcija=pf.sigmoid):
self.mreza = []
self.st_vhodni = st_vhodni
self.st_skriti = st_skriti
self.st_izhodni = st_izhod
self.prenosna_funckija = prenosna_funkcija
self.mreza.append([{'utezi': [random() for i in range(st_vhodni + 1)]} for j in range(st_skriti)])
self.mreza.append([{'utezi': [random() for i in range(st_skriti + 1)]} for j in range(st_izhod)])
def razsirjanje_naprej(self, vhod):
for sloj in self.mreza:
nov_vhod = []
for nevron in sloj:
nevron['izhod'] = self.prenosna_funkcija(self.aktivacijska_funkcija(nevron['utezi'], vhod))
nov_vhod.append(nevron['izhod'])
vhod = nov_vhod
return vhod
but it seems like this isn't the right way, I get the following error:
AttributeError: 'Nevronska_mreza' object has no attribute 'prenosna_funkcija'
Is it possible to do something like that?
Yes you can pass a function around as an argument however you have made a couple of mistakes.
Firstly you have used the word function, although not a reserved word it should be avoided as a name of an entity such as a variable.
Secordly you have used an optional parameter before mandatory parameters which will cause an error such as:
File "test.py", line 5
def __init__(self, function=fun1, data1, data2):
^
SyntaxError: non-default argument follows default argument
Thirdly when calling the method you have not specified the scope, the function name is in the self scope of the object.
Taking all of these into account the following is working code
def fun1(x):
return x+1
class A:
def __init__(self, data1, data2, fn=fun1):
self.fn = fn
self.data1 = data1
self.data2 = data2
def some_method(self):
y = self.fn(self.data1)
print(y)
b = A(1, 2, fun1)
b.some_method()
After posting your full code I can see that you currently have self.prenosna_funckija instead of prenosna_funkcija in the following line:
self.prenosna_funckija = prenosna_funkcija
This would explain the attribute error as when you are calling self.prenosna_funkcija it genuinely does not exist.
You're close:
def fun1(x):
return x+1
class A:
def __init__(self, function=fun1, data1=None, data2=None):
self.function = function
self.data1 = data1
self.data2 = data2
def some_method(self):
y = self.function(self.data1)
return y
a = A(data1 = 41)
result = a.some_method()
print(result)
prints
42

how to i get my function to recognise a dataframe?

This is my function
def PredictCorner(Home_Team, Away_Team):
Home_Average = Table_Current_Normalised.loc["Average", "Att_Home"]
Away_Average = Table_Current_Normalised.loc["Average", "Att_Away"]
AH = Table_Current_Normalised.loc[Home_Team, "Att_Home"] / Home_Average
DH = Table_Current_Normalised.loc[Home_Team, "Def_Home"] / Away_Average
AA = Table_Current_Normalised.loc[Away_Team, "Att_Away"] / Away_Average
DA = Table_Current_Normalised.loc[Away_Team, "Def_Away"] / Home_Average
Rate_Home = AH * DA * Home_Average
Rate_Away = AA * DH * Away_Average
return [Rate_Home,Rate_Away]
and the df in question is Table_Current_Normalised.
This is the error I get
NameError: name 'Table_Current_Normalised' is not defined
Thanks in advance, am new to python.
As the error suggests, the function can't find any object with the name Table_Current_Normalised. Because this name isn't a parameter or assigned within your function, it's assumed to be a globally defined variable. IE it is defined or imported somewhere in the body of the module, not inside a function.
More than likely, the problem you have is either:
(1) you have called this function before the global df exists
(2) You have defined the df in a local scope (within another function)
(3) there is a typo in the name.
For instance, here, the function do_something is called before the name d is defined:
def do_something():
d['foo'] = 'bar'
do_something() # NameError
d = {}
Or if you define d in the local scope of another function, you'll have a similar problem.
def do_something():
d['foo'] = 'bar'
def main():
d = {} # d is _local_ to the function ``main``
do_something() # NameError
This results in both cases is the error NameError: name 'd' is not defined
To address, we make sure that d is defined globally before calling the function:
def do_something():
d['foo'] = 'bar'
d = {}
def main():
do_something()
print(d)
main()
This works as expected.
Further, you should consider rewriting this function to accept the dataframe as an argument. That way, it won't rely on some globally-defined variable.
def PredictCorner(Home_Team, Away_Team, table_current):
Home_Average = table_current.loc["Average", "Att_Home"]
Away_Average = table_current.loc["Average", "Att_Away"]
AH = table_current.loc[Home_Team, "Att_Home"] / Home_Average
DH = table_current.loc[Home_Team, "Def_Home"] / Away_Average
AA = table_current.loc[Away_Team, "Att_Away"] / Away_Average
DA = table_current.loc[Away_Team, "Def_Away"] / Home_Average
Rate_Home = AH * DA * Home_Average
Rate_Away = AA * DH * Away_Average
return [Rate_Home,Rate_Away]
Then call it like so:
PredictCorner(home_team, away_team, Table_Current_Normalised)

Is it possible to assign a variable to use in functions but it should not be global

So what I'm trying to do is I need to assign a variable to use in several functions. But that variable should not be a global variable. How can I do that if it is possible?
Edit: I did forgot one thing. This is for my project and most of it is finished but this. My code needs to be non-repeated as much as it can. I have 5 variables and 15 functions to use some or all of that variables.
Edit2: Let me just post a function here.
def draw_stairs(top_stair_wide, stair_height, stair_count, character):
for o in range(stair_count):
for b in range(stair_height):
draw_straight_line(top_stair_wide, character)
print("")
top_stair_wide += 3
What I need to do is when I use that function, I need to fill "top_stair_wide", "stair_height", "stair_count" with a variable that is not global. I can't just put numbers because I will use those variables in 14 different functions again with maths.
I have a function that draws straight line and before, it inputs and returns character so those are not the problem.
Create a class, make the variables instance variables and turn the functions into methods. Then you can access the instance variables in each method without the explicit need to pass them around.
class C:
def __init__(self, var1, var2, var3):
self.var1 = var1
self.var2 = var2
self.var3 = var3
def add_them(self):
return self.var1 + self.var2 + self.var3
def multiply_them(self):
return self.var1 * self.var2 * self.var3
And so on.
You need parameter(s) in your function definition and then pass your variable(s) as argument(s) when you call it.
Using a main function as you told me in a comment, you could write it like this:
def main():
# Here are your NOT GLOBAL variables:
top_stair_wide = 1
stair_height = 2
stair_count = 3
character = "O"
def draw_stairs(top_stair_wide, stair_height, stair_count, character):
for o in range(stair_count):
for b in range(stair_height):
draw_straight_line(top_stair_wide, character)
print("")
top_stair_wide += 3
# ... more definitions follow
# Then call the functions...
# Job done when you execute the program:
main()
Alternatively:
def main(top_stair_wide, stair_height, stair_count, character): # <-- cram all the expected arguments there
def draw_stairs(top_stair_wide, stair_height, stair_count, character):
for o in range(stair_count):
for b in range(stair_height):
draw_straight_line(top_stair_wide, character)
print("")
top_stair_wide += 3
# ... more definitions follow
# Then call the functions...
# Job done when you execute the program:
main(1, 2, 3, "O")
It's also possible using kwargs, because then you have to know the arguments when you call main() and not when you define it:
def main(**kwargs):
def draw_stairs(**kwargs):
for o in range(kwargs["stair_count"]):
for b in range(kwargs["stair_height"]):
draw_straight_line(kwargs["top_stair_wide"], kwargs["character"])
print("")
kwargs["top_stair_wide"] += 3
# ... more definitions follow
# Then call the functions...
function1(**kwargs)
function2(**kwargs)
function3(**kwargs)
# Job done when you execute the program:
main(top_stair_wide = 1,
stair_height = 2,
stair_count = 3,
character = "O")
You can pass it to your functions like:
def func1(variable):
# your logic here with variable
return 'something'
def func2(variable):
# your logic here with variable
return 'something'
Or you can set it as constant in current file as:
VARIABLE = 'variable'
def func1():
# your logic here with VARIABLE
return 'something'
def func2():
# your logic here with VARIABLE
return 'something'
Another option is using a dictionary storing the shared parameters and only passing this dictionary (rather than all variables separately) as an argument:
def add_params(params):
return params['var1'] + params['var2'] + params['var3']
def multiply_params(params):
return params['var1'] * params['var2'] * params['var3']
>>> params = {'var1': 1, 'var2', 2, 'var3': 3}
>>> add_params(params)
6
>>> multiply_params(params)
6

Python how to reference variable

I'm getting a problem when referencing variables on a python file. Here is the code:
FG_E = 9
FG_R = 8
START = 7
READY = 9
MC = 3
BRAKE = 5
ERROR = 6
a = 2
b = 3
position = 0
def build_message(signal):
message = position
message = message | (0b1<<signal)
s = bin(message)
s = s[2:len(s)]
s = (16-len(s))*'0' + s
s0 = s[0:len(s)/2]
s1 = s[len(s)/2:len(s)]
s0 = s0[::-1]
s1 = s1[::-1]
s_final = int(s0 + s1, 2)
position = s_final
print bin(s_final)
return s_final
build_message(FG_R)
The error I get is:
UnboundLocalError: local variable 'position' referenced berofe assigment
The problematic line is actually position = s_final in the function build_message.
If it wasn't there then message = position would work because the Python interpreter would know to which position variable you are referring.
But in this case it is ambiguous because you're are later reassigning to position (position = s_final).
You should either re think the design of the code, or add global position as the first line in build_message. Keep in mind that as it says, it would make position a global variable and build_message will change the value of position every where throughout your code.
EDIT A quick demo:
global_var = 0
def foo1():
print(global_var)
def foo2():
print(global_var)
global_var = 1
def foo3():
global global_var
print(global_var)
global_var = 1
print(global_var)
foo1()
>> 0
foo2()
>> UnboundLocalError: local variable 'global_var' referenced before assignment
foo3()
>> 0
1
You need to use global keyword to access global variable.
def build_message(signal):
global position
message = position
If you are using an outside variable into a function maybe you should consider passing it as an argument, like:
def build_message(signal,position):
pass

Categories

Resources