2015-07-27 14 views
7

Próbuję uruchomić rekurencyjnie funkcję obtainingparams przez 5 razy. Jednak obecnie dane wyjściowe z mojego programu są następujące i nie jestem w stanie zrozumieć, dlaczego linia 32323232 w pętli while na końcu kodu nie jest drukowana po każdym zbiorze wyjściowym MATRIX, ,.Zrozumienie wyjścia z funkcji rekurencyjnej

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]))] 

I tak dalej. df to ramka danych.

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: Wywoływanie obtainingparams która jest funkcją w BondClass klasy:

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) 
+0

Gdzie po raz pierwszy nazywasz 'uzyskiwanieParams'? –

+0

@ M.Shaw Edytowałem pytanie, aby pokazać, gdzie to nazywam. – user131983

Odpowiedz

0
while self.obtainingparams(df, tau_1, tau_2, residuals).called < 5: 
    print('32323232') 
    self.obtainingparams(df, tau_1, tau_2, residuals) 

Moim pierwszym odruchem jest to, że self.obtainingparams().called musi zadzwonić self.obtainingparams() uzyskać własność .called. W ten sposób wywołujesz funkcję rekursywnie, ale nie możesz przejść do pętli while, zanim funkcja zostanie wywołana, wyjaśniając brak wyjścia.

Proponuję, aby zamiast używać zawartej zmiennej do zliczania wystąpień rekurencji, użyj zmiennej w zasięgu obejmującym, która może być inkrementowana dla każdego wywołania, i sprawdź bazową wartość tej zmiennej i return po osiągnięciu wartości kroki rekursji, które chcesz.

Przykład:

count = 0 

def recurse(): 
    count += 1 
    # Base case 
    if count >= 5: 
     return 
    else: 
     recurse() 

Wreszcie, trzeba mieć inny wygląd na to, co ta linia kodu faktycznie robi:

self.obtainingparams(df, tau_1, tau_2, residuals).called 

Twoja funkcja obtainingparams właściwie nie zwraca wartości, ale powiedzieć zwrócił on int. Ta linia naprawdę sprawdzi się pod numerem int.called, ale int nie ma atrybutu o nazwie called. Jeśli chciałbyś sprawdzić atrybut obiektu funkcji, chciałbyś sprawdzić self.obtainingparams.called, chociaż moim zdaniem istnieją lepsze sposoby robienia tego, co próbujesz zrobić z tym kodem.

+2

Co więcej, ten kod próbuje wyszukać 'wywołane' na ** wynik ** wywołania' obtainparams', a nie samą funkcję. A więc to by nie działało, nawet gdyby 'obtainparams' zwrócił wartość - ta wartość nie miałaby atrybutu" named ". – strubbly

+0

Bardzo dobrze, dodam to do odpowiedzi. – Dagrooms

1

Problem polega na tym, że nigdy nie wchodzisz w pętlę while, ponieważ w celu jej wprowadzenia wykonujesz wywołanie cykliczne. Zanim przetestujemy na called, już powtarzasz. Ten kod nie jest to, co chcesz:

while self.obtainingparams(df, tau_1, tau_2, residuals).called < 5: 

Wydaje się called w wyniku wywołania funkcji, a nie w samej funkcji. Po prostu zamień go na:

while self.obtainingparams.called < 5: 

i powinieneś już tam być.

Powiązane problemy