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)
Related
I'm trying to run the code below but I get a NameError when running the code. The issue is that q seems not to be defined but this should not be true.
class SimpleNamespace():
pass
#Question 1
#i)
#Defining the parameters using SimpleNameSpace. par = Parameters
par = SimpleNamespace()
par.y = 1 #assets
par.p = 0.2 #probability
par.theta = -2 #elasticity
#Defining utility function for agent
def utility(z,par):
return (z**(1+par.theta))/(1+par.theta)
#Defining premium
def premium(q,par):
return par.p*q
#Defining expected value
#Note that z_1, z_2 represents first and second part of the objective function - just in a compressed version
def exp_value (i,q,par):
z_1 = par.y-i+q-premium(q,par)
z_2 = par.y-premium(q,par)
return par.p*utility(z_1,par)+(1-par.p)*utility(z_2,par)
def opt_q(i,q,par):
obj = lambda q: -exp_value(i,q,par) #defining the objective function
solution = optimize.minimize_scalar(obj, bounds=(0,0.9), method="bounded") #bounded solution within [0.01, 0.9]
q = solution.x
return q
for i in np.linspace(0.01,0.9,num=100):
res = opt_q(i,q,par)
print(res)
You are getting the NameError because you are not passing the q to opt_q in the last for-loop. Since it is already defined inside opt_q just remove q from its arguments and don't pass it in the for-loop as well as follows:
def opt_q(i,par):
obj = lambda q: -exp_value(i,q,par) #defining the objective function
solution = minimize_scalar(obj, bounds=(0,0.9), method="bounded") #bounded solution within [0.01, 0.9]
q = solution.x
return q
for i in np.linspace(0.01,0.9,num=100):
res = opt_q(i,par)
print(res)
This resolves your issue.
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
I am learning python and have one question about how to save a dictionary value via a python function.
import copy
def func():
b = {'1':'d'}
a = copy.deepcopy(b)
global a
a = {}
func()
print a
The printout is still {}, how to make it be {'1':'d'}?
You need to say that you are accessing the global variable a, inside the function, like this
def func():
global a
b = {'1': 'd'}
a = copy.deepcopy(b)
But, prefer not doing something like that. Instead, return the copy and then store it in the calling place, like this
import copy
a = {}
def func():
b = {'1': 'd'}
return copy.deepcopy(b)
a = func()
print a
i moved the global a into the function definition.
#! /usr/bin/python
import copy
def func():
global a
b = {'1':'d'}
a = copy.deepcopy(b)
a = {}
func()
print a
You are defining 'a' in two different scopes, one in the "global" scope, one in the function scope. You will need to return copy.deepcopy(b) and set that to the value of the outer defined 'a'.
import copy
def func():
b = {'1':'d'}
return copy.deepcopy(b)
global a
a = func()
print a
I can't proceed to my next task because of this error. I searched about the error already and did what others suggested but it doesn't work for my code. So I'm hoping that someone could help me about it. Here's my code:
if self.techskills == 11:
c = con.execute("SELECT Centroid FROM Centroid WHERE ItemID = 25")
TS_centroid = c.fetchone()[0]
TS_AA = (min(a1, a2) * TS_centroid) + (pow(a3,2))
TS_BB = (min(a1, a2) + a3)
TS_WA = TS_AA/TS_BB
elif self.techskills == 12:
c = con.execute("SELECT Centroid FROM Centroid WHERE ItemID = 24")
TS_centroid = c.fetchone()[0]
TS_AA = (min(a1, a2) * TS_centroid) + (pow(a3,2))
TS_BB = (min(a1, a2) + a3)
TS_WA = TS_AA/TS_BB
if self.qualityofwork == 11:
c = con.execute("SELECT Centroid FROM Centroid WHERE ItemID = 25")
QL_centroid = c.fetchone()[0]
QL_AA = (min(a4, a5) * QL_centroid) + (pow(a6,2))
QL_BB = (min(a4, a5) + a6)
QL_WA = QL_AA/QL_BB
elif self.qualityofwork == 12:
c = con.execute("SELECT Centroid FROM Centroid WHERE ItemID = 24")
QL_centroid = c.fetchone()[0]
QL_AA = (min(a4, a5) * QL_centroid) + (pow(a6,2))
QL_BB = (min(a4, a5) + a6)
QL_WA = QL_AA/QL_BB
overall = (TS_WA + QL_WA)/2
print(overall)
I just reduced the code to make it short. I got this code:
Traceback (most recent call last):
overall = (TS_WA + QL_WA)/2
UnboundLocalError: local variable 'QL_WA' referenced before assignment
If either of your statements don't evaluate to True, QL_WA never gets defined. You need to set a default value outside of the if checks or move the overall = (TS_WA + QL_WA)/2 inside the body of the statement.
if self.qualityofwork is neither 11 or 12 then it never gets assigned, you can set a default value as I mentioned or use an else where you assign it a value there then assign overall = (TS_WA + QL_WA)/2.
If you expect self.qualityofwork to always be 11 or 12 then you have a bug somewhere in your previous code.
You can set it to None:
QL_WA = None
if self.techskills == 11:
.....
Then use if QL_WA is not None:overall = (TS_WA + QL_WA)/2.
UnboundLocalError arises in three different conditions.
Condition 1;
As the previous post stated this code produces error.
'a' in globals()
False
def f():
if False:
a=1
print a
f() # UnboundLocalError
By the time python has parsed the identifier 'a' in the above if block it had learned a name but the name referrs to no objects. So produces an error when accessed in runtime.
Condition 2; A modified version of the above.
a=0
'a' in globals()
True
def f():
if False:
a=1
print a
f() # UnboundLocalError
If we want to make 'a' local when the 'if' condition is true and otherwise not, it can be coded as below;
if 'a' not in locals():
global a
print a
Condition 3; Python 3
'a' in globals()
False
def f1():
a=1
def f2():
a += 1 # 'a' is non-local and non-global
f2()
f1() # UnboundLocalError
here making 'a' global a triggers 'NameErro' because 'a' in globals() was False. Making 'a' nonlocal a gives access to 'a' in 'f1'.
Even if 'a' in globals() were True, nonlocal refers only to the outer scope.
Is there a simple way to make all variables in a function global?
I have 20 odd variables in a function and naming them global one by one doesn't make nice code... to me anyway :)
Warning: Don't try this at home, you might burn it down.
There is no legitimate reason to do the following in the course of normal day-to-day programming. Please review the other answers to this question for more realistic alternatives.
I can barely imagine why you would want to do this, but here is a way to do it:
def f(a, b, c):
d = 123
e = 'crazy, but possible'
globals().update(locals())
def g():
print a, b, c, d ,e
>>> globals()
{'g': <function g at 0x875230>, 'f': <function f at 0x8751b8>, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', '__doc__': None}
>>> g()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in g
NameError: global name 'a' is not defined
>>> f(10, 20, 'blah')
>>> g()
10 20 blah 123 crazy, but possible
>>> globals()
{'a': 10, 'c': 'blah', 'b': 20, 'e': 'crazy, but possible', 'd': 123, 'g': <function g at 0x875230>, 'f': <function f at 0x8751b8>, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', '__doc__': None}
The pythonic way to do this is either to keep the variables in local scope (i.e. define them within each function) and pass them between the functions as arguments / return values; or to keep your variables as attributes of an object or class making your "functions" methods in that class. Either way is OK, but the global keyword is designed specifically to put you off using it in the way you describe. Global variables are not just "bad style" but they make your code very difficult to maintain, as any invariants that your variables need to stick to need to be checked in every function.
Here is an example of good style (with functions):
def quads(a, b, c):
x1 = (-1.0 * b + math.sqrt(b * b - 4.0 * a * c)) / (2.0 * a)
x2 = (-1.0 * b - math.sqrt(b * b - 4.0 * a * c)) / (2.0 * a)
return x1, x2
def pretty(a, b, c, x1, x2):
eqn = "%fx^2 + %fx + %c" % (a, b, c)
print "The first solution to the equation %s is: %f" % (eqn, x1)
print "The second solution to the equation %s is: %f" % (eqn, x2)
return
def main():
a = 100
b = 200
c = 300
x1, x2 = quads(a, b, c)
pretty(a, b, c, x1, x2)
return
if __name__ == '__main__':
main()
Here is an example of good style (with OOP):
class Quadratic(object):
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
self.x1 = None
self.x2 = None
self.solve() # Set x1 and x2 to correct values
# To maintain the invariant between a, b, c and x1, x1
# we should override __setattr__ or use descriptors or
# properties so that self.solve() is called every time
# a, b, or c are updated.
return
def solve(self):
self.x1 = (-1.0 * self.b +
math.sqrt(self.b * self.b - 4.0 * self.a * self.c)) / (2.0 * self.a)
self.x2 = (-1.0 * self.b -
math.sqrt(self.b * self.b - 4.0 * self.a * self.c)) / 2.0 * self.a
return
def pretty(self):
eqn = "%fx^2 + %fx + %c" % (self.a, self.b, self.c)
print "The first solution to the equation %s is: %f" % (eqn, self.x1)
print "The second solution to the equation %s is: %f" % (eqn, self.x2)
return
def main():
quad = Quadratic(100, 200, 300)
quad.pretty()
return
if __name__ == '__main__':
main()
There's no way to declare them all as global, and you really don't want to. Those 20 variables probably should be turned into an object with 20 attributes instead.
The simplest solution is to have only a single global — or, better yet, to figure out how to pass it in to the function. Using it as a global would look like this (again, I am showing the simplest possible case, not necessarily the best use of Python):
class Info(object): # or whatever you want to name the container
"""Holder for global information."""
info = Info() # single instance we will use
def my_function():
print "Here is some info:"
print info.a, info.b, info.c
info.a = 3
info.b = 8
info.c = []
if __name__ == '__main__':
my_function()
Again, I would probably pass info to the function instead. But since your question was about a global, it's shown here as a global.
A niche example where I wanted to do this: use a function for importing.*
def temp():
a = "stays local value"
old_locs = locals().copy()
b = "is global value"
import math
new_locs = locals()
new_vars = {k: new_locs[k] for k in set(new_locs) - set(old_locs)
if k != 'old_locs'}
globals().update(new_vars)
temp()
print(b)
print(math.sqrt(3))
print(a)
gives
is global value
1.7320508075688772
NameError: name 'a' is not defined
This way only the specific 20 or so variables would get update the global namespace and intermediate variable names in the function wouldn't.
*I needed to import from a .ipynb file, and the process for doing so depends if called from google Collaboratory, a desktop .ipynb, or a desktop .py file; this involved the use of magics which are treated as invalid syntax in situation which wouldn't call those branches, so by importing my import function I can escape that issue.