I'm trying to calibrate a model that has 12 unknown parameters inside it and as input only 5. I'm building a class for it as for example:
class model:
def __init__(self,input_1,input_2,input_3,...):
self.input_1=input_1
self.input_2=input_2
self.input_3=input_3
.
.
. #Only inputs here, no pmts
Then I've defined the functions as:
def integral(self, input_1, pmt1, pm2, pm3.... )
integral,err= quad(f(input,pmt1,pmt2,pmt3)) #I'm simplifying here, the function is longer
return integral
def model_price(self,input_1,input_2,input_3):
price = pm3 + self.integral(self)/input_3
return price
def loss_function(self):
err = (self.input_1 - self.model_price)
pen = 0
return err + pen
def minimization(self,x0,bnds):
params = {"pm1": {"x0": 0.0746, "lbub": [1e-4,4.9]}, #1
"pmt2": {"x0": 0.3369, "lbub": [1e-4,4]}, #2
"pm3": {"x0": 0.3369, "lbub": [1e-4,4]}, #3
....
}
x0 = [param["x0"] for key, param in params.items()]
bnds = [param["lbub"] for key, param in params.items()]
results =minimize(self.loss_function(), x0, tol = 1e-3, method='SLSQP', options={'maxiter': 1e3 }, bounds=bnds)
return results
I tried passing the x0 and bounds outside the function when I tried to use but is not working. I always get:
TypeError: integral() missing 12 required positional arguments: 'pmt1, pmt2, pmt3,
Error message is pretty clear, you are trying to call method integral with single argument and you need to pass 12 arguments.
So instead of self.integral(self) you need self.integral(arg1, … , arg12)
Related
I am stuck on a problem and I would be grateful for help.
Consider the following example.
# can be changed
def inner(x):
x = 4
return x
# can not be changed
def outer(a, b):
b = b(b)
return a + b
# can be changed - I want to pass two parameters to inner
res = outer(
a = 3,
b = inner
)
print(res)
Now important to note is that I can not change the function outer(), because it comes from a common code base / package.
How can I pass multiple parameters to inner()? inner() can be changed as needed, but it needs to return the function, not the int since outer() expects a function.
Thank you in advance!
I tried passing multiple parameters, but outer() expects a function. This example illustrates the function ExternalTaskSensor of the python package airflow. The parameter
execution_date_fn
expects a function to be returned.
Let's say I have the following function:
def add(x, y):
return x+y
I would like to bind x=2 and y=2 to the function but not actually call it. What is the correct way to do this? I've done this sometimes with add_bound=lambda: add(2,3), but I'm wondering if this is the 'pythonic' approach or there is another way to do it (perhaps binding certain arguments, and then passing other arguments later.
Often this will be done with a decorator. Here is a general example:
add = lambda x,y: x+y
def wrap(outer_func, *outer_args, **outer_kwargs):
def inner_func(*inner_args, **inner_kwargs):
args = list(outer_args) + list(inner_args)
kwargs = {**outer_kwargs, **inner_kwargs}
return outer_func(*args, **kwargs)
return inner_func
In this case you can do things such as the following:
# pass both at once
>>> x=wrap(add,2,3)
>>> x()
5
# pass one at binding, second at call
>>> x=wrap(add,2)
>>> x(3)
5
# pass both when called
>>> x=wrap(add)
>>> x(2,3)
5
Note that the above is very similar to functools.partial:
The partial() is used for partial function application which “freezes” some portion of a function’s arguments and/or keywords resulting in a new object with a simplified signature. For example, partial() can be used to create a callable that behaves like the int() function where the base argument defaults to two:
from functools import partial
basetwo = partial(int, base=2)
basetwo.__doc__ = 'Convert base 2 string to an int.'
basetwo('10010')
18
def add(x=2, y=2):
return x+y
I am trying to use the output of one function in a second function then retrieving a variable from the second function to be used in the first function. The code below is a simplification of what I am trying to do
def function1():
x=15
return x
function2(y)
print(x+y)
def function2():
y=x-12
return y
function1()
I am not getting an actual value for y when I check by adding a print statement for x in function2. Is there a way to do this or do i need to make a 3rd function to handle this?
Pass variable x to function2, and store the return value from function2 in a local variable in function 1.
def function1():
x=15
y = function2(x)
print(x+y)
return x
def function2(x):
y=x-12
return y
function1()
I'm trying to be as efficient as possible with space while creating an array based deque. So, the array starts with size one, and I'll call a function called "grow" if the array is not large enough when I push new values to the deque (at either end). I then mod to preserve the front and back of the deque. Here is a sample of what I've done so far:
def __init__(self):
# capacity starts at 1; we will grow on demand.
self.__capacity = 1
self.__contents = [None] * self.__capacity
self.__front = 1
self.__back = 1
self.__size = 1
def __grow(self):
old_list = self.__contents
walk = self.__front
for k in range(self.__capacity):
self.__contents[k] = old_list[walk]
walk = (1 + walk) % len(old_list)
self.__front = 0
self.__capacity = self.__capacity * 2
def push_front(self, val):
if self.__size == len(self.__contents):
self.__grow(self.__capacity)
self.__front = (self.__front - 1) % len(self.__contents)
self.__contents[self.__front] = val
self.__size += 1
My question comes when I call the grow method. I keep getting the error that I am giving 'grow' two positional arguments, but I don't see where or how that's happening. If anyone has any ideas on how to improve this so that it only has one positional argument? Also, does my reasoning for a walk through to re-index in the grow method make sense as well as my reasoning for the push front method?
You need to add an argument to __grow if you are going to pass arguments to it, i.e.:
def __grow(self, size):
Currently, it only has a self argument, but you are also passing in self.__capacity when you call it. However, I think you really meant to call grow without arguments:
if self.__size == len(self.__contents):
self.__grow()
All instance methods in a class treat the calling instance as their first argument, unless you use the class to call the method in which case you must provide an instance as the first argument.
class A:
def __init__(self):
pass
def f(self, x):
print(self, x)
a = A()
a.f(1) # <A object at 0x7fa9a067da90> 1
A.f(a, 2) # <A object at 0x7fa9a067da90> 2
So when you call self.__grow(self.__capacity), that gets turned into Deque.__grow(self, self.__capacity). But your __grow method only takes self.
def areaOfRectangle (length,width):
area = length*width
sqArea = length**2
return area,sqArea
def areaOfSquare (length,):
areaOfRectangle (length,width)
return sqArea
#def radiusOfCircle (radius):
area = 3.14*(radius**2)
return area
#def volumeOfCylinder (radius,height):
volume = 3.14*(radius**2)*height
return volume
length = int(input("Input length: "))
width = int(input("Input width: "))
print()
print(areaOfRectangle (10,20))
print()
print(areaOfRectangle (24.3,6))
print()
print(areaOfRectangle (34.9,17.4))
print()
print(areaOfRectangle (length,width))
print()
print(areaOfSquare (10.3))
I need to make two functions, the first function to calculate the area of a rectangle given the length and width. The second function needs to calculate the area of a square given the length of one of its sides. The second function should call the previous function to perform the calculation. I know how to call a function within another function however I don't know how to bring a variable from the first function to the second.
I don't know how to bring a variable from the first function to the second
Typically, this is done through the use of parameters. Let's say you have a value x:
x = 0
You can pass the value to a function by inserting it into the call itself:
f(x)
Lastly, the function needs to be able to handle the parameter you give it:
def f(y): pass
A working example of what you describe:
def f2(y):
return y + 1
def f1():
x = 2
print(f2(x))
f1()
3 is printed.