1
votes

I am trying to pass arguments to a function and I think I'm doing it correctly but it still gives the error: TypeError: p_vinet() takes 2 positional arguments but 4 were given

Here's the pieces of my code first and then I'll give the part that gives the error.

volumeMgO is a previously calculated array consisting of:

array([ 7.64798549,  7.67153344,  7.67153344,  7.8068763 ,  7.97288941,
8.14781986,  8.33321177,  8.53118834,  8.74433596,  8.97545339,
9.22826581,  9.50740563,  9.81962839])

params_MgO is this:

params_MgO    = [11.244, 160., 4.0]

The vinet function is:

def p_vinet(v, params):
  """
  This function will calculate pressure from Vinet equation.

  Parameters
  ==========
  v = volume
  params = [V0, K0, K0']

  Returns
  =======
  Pressure calculated from Vinet equation
  """
  f_v = np.power( v/params[0], 1./3.)
  eta = 1.5 * (params[2] - 1.)

  P = 3 * params[1] * ((1 - f_v) / np.power(f_v, 2) ) * np.exp(eta * (1 - 
  f_v))

  return P

Finally, the slope function is just a simple way of taking a derivative:

def slope(func, x, h, args=()):
  """
  find a slope for function f at point x

  Parameters
  =========
  f = function
  x = independent variable for f
  h = distance along x to the neighboring points

  Returns
  =======
  slope
  """

  rise = func(x+h, *args) - func(x-h, *args)
  run = 2.*h

  s = rise/run

  return s

Now here is where the issue comes. When I type:

BulkModulus_MgO = np.zeros(volumeMgO.size)
for i in range(volumeMgO.size):
   BulkModulus_MgO[i] = slope(p_vinet, volumeMgO[i], volumeMgO[i]*0.0001, 
   args=(params_MgO)) 

I get this error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-116-60467d989bbc> in <module>()
  1 BulkModulus_MgO = np.zeros(volumeMgO.size)
  2 for i in range(volumeMgO.size):
----> 3     BulkModulus_MgO[i] = slope(p_vinet, volumeMgO[i], 
volumeMgO[i]*0.0001, args=(params_MgO))

<ipython-input-100-618f25e85d34> in slope(func, x, h, args)
 15     """
 16 
---> 17     rise = func(x+h, *args) - func(x-h, *args)
 18     run = 2.*h
 19 

TypeError: p_vinet() takes 2 positional arguments but 4 were given

I don't get it. p_vinet needs arguments v and params, and I supply v through the x+h and x-h in the slope function, and the params is a list with 3 entries that p_vinet unpacks. So that's 2 arguments. Why is it saying I'm supplying 4?

Sorry if it's slightly confusing how I'm presenting the code. I'm coding in jupyter notebook and all the functions are separate. volumeMgO is calculated separately from previous code with no issues.

1

1 Answers

0
votes

Let's look at this line of code:

BulkModulus_MgO[i] = slope(p_vinet, volumeMgO[i], volumeMgO[i]*0.0001, 
   args=(params_MgO))

args should be like this: args=(params_MgO,) (tuple with one element in it) instead of args=(params_MgO) (not tuple, just array of 3 elements) because in second case unpacking *args in slope() function gives you 3 additional arguments (each element of params_MgO). That's why you got 4 arguments in slope() function. In first case unpacking gives you entire array as single parameter (like params in p_vinet() function).