I am trying to run the function obtainingparams
recursively for 5 times. However, currently the output from my program is as follows, and I am actually unable to understand why the line 32323232
in the while
loop at the end of the code is not being printed out after every set of MATRIX
, PARAMS
, VALUES
output.
MATRIX [[ 1. 7.53869055 7.10409234 -0.2867544 ]
[ 1. 7.53869055 7.10409234 -0.2867544 ]
[ 1. 7.53869055 7.10409234 -0.2867544 ]
...,
[ 1. 0.43010753 0.43010753 0.09642396]]
PARAMS [ 5.12077446 8.89859946 -10.26880411 -9.58965259]
VALUES [(0.5, 1.5, 206.59958540866882, array([ 5.12077446, 8.89859946, -10.26880411, -9.58965259]))]
MATRIX [[ 1. 3.14775472 2.54122406 -0.43709966]
[ 1. 3.14775472 2.54122406 -0.43709966]
[ 1. 3.14775472 2.54122406 -0.43709966]
...,
[ 1. 0.25806447 0.25806428 0.07982733]]
PARAMS [ 4.90731466 4.41623398 -7.65250737 -6.01128351]
VALUES [(0.5, 1.5, 206.59958540866882, array([ 5.12077446, 8.89859946, -10.26880411, -9.58965259])), (0.7, 1.7, 206.46228694927203, array([ 4.90731466, 4.41623398, -7.65250737, -6.01128351]))]
And so on. df
is a Dataframe.
values = []
def counted(fn):
def wrapper(*args, **kwargs):
wrapper.called+= 1
return fn(*args, **kwargs)
wrapper.called= 0
wrapper.__name__= fn.__name__
return wrapper
@counted
def obtainingparams(self, df, tau_1, tau_2, residuals):
global values
no_of_bonds = df.shape[0]
yields = df['coupon'].values
matrix_of_params = np.empty(shape=[1, 4])
months_to_maturity_matrix = df.months_to_maturity.values
count = 0
for x, value in np.ndenumerate(months_to_maturity_matrix):
if count < months_to_maturity_matrix.shape[0]:
months_to_maturity_array = months_to_maturity_matrix[count]
years_to_maturity_array = months_to_maturity_array/12
newrow = [1, ((1-np.exp(-years_to_maturity_array/tau_1))/years_to_maturity_array/tau_1), ((1-np.exp(-years_to_maturity_array/tau_1))/years_to_maturity_array/tau_1)-np.exp(-years_to_maturity_array/tau_1), ((1-np.exp(-years_to_maturity_array/tau_2))/years_to_maturity_array/tau_2)-np.exp(-years_to_maturity_array/tau_2)]
count = count + 1
matrix_of_params = np.vstack([matrix_of_params, newrow])
matrix_of_params = np.delete(matrix_of_params, (0), axis=0)
print('MATRIX', matrix_of_params)
params = np.linalg.lstsq(matrix_of_params,yields)[0]
print('PARAMS', params)
residuals = np.sqrt(((yields - matrix_of_params.dot(params))**2).sum())
tau_1 = tau_1 + 0.2
tau_2 = tau_2 + 0.2
values.append((tau_1, tau_2, residuals, params))
print('VALUES', values)
while self.obtainingparams(df, tau_1, tau_2, residuals).called < 5:
print('32323232')
self.obtainingparams(df, tau_1, tau_2, residuals)
Edit : Calling obtainingparams
which is a function within the BondClass
Class:
tau_1 = 0.3
tau_2 = 1.3
BOND_OBJECT = BondClass.GeneralBondClass(price, coupon, coupon_frequecy, face_value, monthstomaturity, issue_date)
residuals = [0, 0, 0, 0, 0]
df1 = Exc.ExcelFileReader() #Read the Dataframe in from an Excel File
BOND_OBJECT.obtainingparams(df1, tau_1, tau_2, residuals)
The problem is that you never enter the while loop because in order to enter it you make the recursive call. So before the test on called
can be evaluated you are already recursing. This code is not what you want:
while self.obtainingparams(df, tau_1, tau_2, residuals).called < 5:
It looks up called
in the result of the function call rather than in the function itself. Just replace it with:
while self.obtainingparams.called < 5:
and you should be just about there.
while self.obtainingparams(df, tau_1, tau_2, residuals).called < 5:
print('32323232')
self.obtainingparams(df, tau_1, tau_2, residuals)
My first instinct is that the self.obtainingparams().called
has to call self.obtainingparams()
to get the .called
property. In this way, you're calling the function recursively, but not able to pass into the while loop before the function is called, explaining the lack of output.
I would suggest that instead of using a contained variable to count recursion instances, use a variable in the enclosing scope that can be incremented on each call, and have the base case check this variable and return
once it reaches the amount of recursion steps you want.
Example:
count = 0
def recurse():
count += 1
# Base case
if count >= 5:
return
else:
recurse()
Lastly, you need to have another look at what this line of code actually does:
self.obtainingparams(df, tau_1, tau_2, residuals).called
Your function obtainingparams
doesn't actually return a value, but say it returned an int
. This line would really be checking int.called
, but int
does not have an attribute named called
. If you wanted to check the attribute of the function object, you would want to check self.obtainingparams.called
, although in my opinion there are better ways to do what you're trying to do with this code.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.