2015-07-27 15 views
7

Sto provando a eseguire la funzione obtainingparams in modo ricorsivo per 5 volte. Tuttavia, attualmente l'output del mio programma è il seguente e non sono in grado di capire perché la linea 32323232 nel ciclo while alla fine del codice non venga stampata dopo ogni serie di MATRIX, output.Capire l'output dalla funzione ricorsiva

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

E così via. df è un 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 che è una funzione all'interno del BondClass Classe:

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

Dove inizialmente si chiama 'gettingingParams'? –

+0

@ M.Shaw Ho modificato la domanda per mostrare dove la chiamo. – user131983

risposta

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

Il mio primo istinto è che il self.obtainingparams().called deve chiamare self.obtainingparams() per ottenere la proprietà .called. In questo modo, si sta chiamando la funzione in modo ricorsivo, ma non si è in grado di passare al ciclo while prima che la funzione venga chiamata, spiegando la mancanza di output.

Suggerirei invece di utilizzare una variabile contenuta per contare le istanze di ricorsione, utilizzare una variabile nell'ambito di inclusione che può essere incrementata su ogni chiamata e fare in modo che il caso di base controlli questa variabile e return una volta che raggiunge l'importo di passaggi di ricorsione che vuoi.

Esempio:

count = 0 

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

Infine, è necessario avere un altro sguardo a ciò che questa riga di codice in realtà fa:

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

La funzione obtainingparams in realtà non restituisce un valore, ma dire ha restituito un int. Questa linea controllerebbe davvero int.called, ma non ha un attributo denominato called. Se si desidera verificare l'attributo dell'oggetto funzione, è necessario verificare self.obtainingparams.called, sebbene a mio parere ci siano modi migliori per fare ciò che si sta tentando di fare con questo codice.

+2

Sì e inoltre, questo codice tenta di cercare 'called' sul ** risultato ** di chiamare' gettingingparams', non la funzione stessa. Quindi non funzionerebbe, anche se "gettingingparams' ha restituito un valore - quel valore non avrebbe un attributo' called'. – strubbly

+0

Ottimo punto, lo aggiungo alla risposta. – Dagrooms

1

Il problema è che non si entra mai nel ciclo while perché per inserirlo si effettua la chiamata ricorsiva. Quindi, prima che il test su called possa essere valutato, stai già ricorrendo. Questo codice non è ciò che si vuole:

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

Sembra fino called nel risultato della chiamata di funzione piuttosto che nella funzione stessa. Basta sostituirlo con:

while self.obtainingparams.called < 5: 

e si dovrebbe essere proprio lì.