Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

**kwargs not passing variables to function, what's wrong? [duplicate]

Tags:

python

For some reason, I can't get the variables passed in **kwargs in Python to be seen by the receiving function. (RESOLVED - see edit). This illustrates the problem - the **kwargs parameters are passed through several functions and make it to the integrand function. I put a print(kwargs) in there which displays the whole dictionary I created in the first few lines below. BUT these variables aren't seen by the integrand function and it errors out. What is the correct way to make these variables accessable to the final function? Much appreciated, searched quite a few posts on SO but couldn't find something directly relevant to my case.

def integrand(x, F, K, T1, T2, vol, flag):
    print(kwargs)
    d1 = (np.log(x / (x+K)) + 0.5 * (vol**2) * (T2-T1)) / (vol * np.sqrt(T2 - T1))
    d2 = d1 - vol*np.sqrt(T2 - T1)
    mu = np.log(F) - 0.5 *vol**2 * T1
    sigma = vol * np.sqrt(T1)
    value = lognorm.pdf(x, scale=np.exp(mu), s=sigma) * (flag * x*norm.cdf(flag * d1) - flag * (x+K)*norm.cdf(flag * d2))
    return value

def integrate(x, w, a, **kwargs): 
    return np.sum(w*transform_integral_negative1_1_to_0_1(x, a, **kwargs))

def transform_integral_0_1_to_Infinity(x, a, **kwargs): 
    return integrand(a+(x/(1-x)), **kwargs) *(1/(1-x)**2); 

def transform_integral_negative1_1_to_0_1(x, a, **kwargs): 
    return 0.5 * transform_integral_0_1_to_Infinity((x+1)/2, a, **kwargs)

flag = current_opt[i,0]
F = current_opt[i,1]
K = current_opt[i,2]   
T2 = current_opt[i,3]
T1 = current_opt[i,4]
r = current_opt[i,5]
vol = current_opt[i,6]

a = 0
b = np.Inf
kwargs = {'flag':flag, 'F':F, 'K':K, 'vol':vol, 'T2':T2, 'T1':T1}
integrate(x, w, a, **kwargs)

And this is what is printed before it errors out print(kwargs):

{'F': 1.2075, 'flag': -1.0, 'K': 0.12509999999999999, 'T2': 0.068500000000000005, 'vol': 0.42999999999999999, 'T1': 0.041099999999999998}

And the error, despite K being defined above:

NameError: name 'K' is not defined

The solution was to define each input rather than extract each value from the dictionary... The **kwargs passed to the last function extracts all the keyword arguments automatically.

like image 812
Matt Avatar asked May 09 '26 12:05

Matt


1 Answers

**kwargs is passed as a dict to the function, it doesn't automatically populate the function's locals.

e.g.:

kwargs = {'K': 1}

def foo(**kwargs):
    print(K)

def bar(**kwargs):
    print(kwargs['K'])

foo(**kwargs)  # NameError
bar(**kwargs)  # Works Ok.
like image 60
mgilson Avatar answered May 18 '26 05:05

mgilson