Home > Software engineering >  Class method called in __init__ not giving same output as the same function used outside the class
Class method called in __init__ not giving same output as the same function used outside the class

Time:11-20

I'm sure I'm missing something in how classes work here, but basically this is my class:

import pandas as pd
import numpy as np
import scipy

#example DF with OHLC columns and 100 rows
gold = pd.DataFrame({'Open':[i for i in range(100)],'Close':[i for i in range(100)],'High':[i for i in range(100)],'Low':[i for i in range(100)]})

class Backtest:
    
    def __init__(self, ticker, df):
        self.ticker = ticker
        self.df = df
        self.levels = pivot_points(self.df)
    
    def pivot_points(self,df,period=30):
        highs = scipy.signal.argrelmax(df.High.values,order=period)
        lows = scipy.signal.argrelmin(df.Low.values,order=period)
        return list(df.High[highs[0]])   list(df.Low[lows[0]])



inst = Backtest('gold',gold) #gold is a Pandas Dataframe with Open High Low Close columns and data
inst.levels # This give me the whole dataframe (inst.df) instead of the expected output of the pivot_point function (a list of integers)

The problem is inst.levels returns the whole DataFrame instead of the return value of the function pivot_points (which is supposed to be a list of integers)

When I called the pivot_points function on the same DataFrame outside this class I got the list I expected

I expected to get the result of the pivot_points() function after assigning it to self.levels inside the init but instead I got the entire DataFrame

CodePudding user response:

You would have to address pivot_points() as self.pivot_points()

And there is no need to add period as an argument if you are not changing it, if you are, its okay there.

I'm not sure if this helps, but here are some tips about your class:

class Backtest:

    def __init__(self, ticker, df):
        self.ticker = ticker
        self.df = df

        # no need to define a instance variable here, you can access the method directly
        # self.levels = pivot_points(self.df)

    def pivot_points(self):
        period = 30
        # period is a local variable to pivot_points so I can access it directly
        print(f'period inside Backtest.pivot_points: {period}')
        # df is an instance variable and can be accessed in any method of Backtest after it is instantiated
        print(f'self.df inside Backtest.pivot_points(): {self.df}')
        # to get any values out of pivot_points we return some calcualtions
        return 1   1

    # if you do need an attribute like level to access it by inst.level you could create a property
    @property
    def level(self):
        return self.pivot_points()


gold = 'some data'
inst = Backtest('gold', gold)  # gold is a Pandas Dataframe with Open High Low Close columns and data
print(f'inst.pivot_points() outside the class: {inst.pivot_points()}')
print(f'inst.level outside the class: {inst.level}')

This would be the result:

period inside Backtest.pivot_points: 30
self.df inside Backtest.pivot_points(): some data
inst.pivot_points() outside the class: 2
period inside Backtest.pivot_points: 30
self.df inside Backtest.pivot_points(): some data
inst.level outside the class: 2

CodePudding user response:

Thanks to the commenter Henry Ecker I found that I had the function by the same name defined elsewhere in the file where the output is the df. After changing that my original code is working as expected

  • Related