Bank saving account class in Python (pandas) I am setting up a kids bank account class to teach them how to save, and myself how to write a class in Python. The original idea was to create a pandas DataFrame that will show how the money gains interest by loading:

&lt;AccountName&gt;.df 


First I created the DataFrame of 365 days with datetime.date.today() + datetime.timedelta(days=236) as the indices which I guess made the looking up of index for the daily interest increment a bit cumbersome... to say the least.

class  Account:


    def __init__(self, holder, start_date):
        import datetime 
        import pandas as pd

        self.df = pd.DataFrame(index=pd.date_range(start_date, start_date + datetime.timedelta(365), freq='D'), columns=['deposit', 'withdrawl', 'balance'])
        self.df.withdrawl = 0.0
        self.df.deposit = 0.0
        self.df.balance = 0.0
        self.df.dif = 0.0

        for i in self.df.index[1:]:
            self.df.loc[i,('balance')] = self.df.loc[str(datetime.datetime.strptime(str(i)[:10], '%Y-%m-%d') - datetime.timedelta(days=1))[:10], ('balance')] * (1+(0.08 / 365))

        self.history = []

        self.holder = holder

    def __str__(self):
        return 'The account of: {0}, balance is: {1} '.format(self.holder, self.df.loc[str(datetime.datetime.today())[:10], 'balance'])

    def __repr__(self):
        return '{0.__class__.__name__}(name={0.holder})(balance={1})'.format(self, self.df.loc[str(datetime.datetime.today())[:10], 'balance'])

    def get_balance(self):
        return self.df.loc[str(datetime.datetime.today())[:10], 'balance']

    def make_deposit(self, amount, date):
        self.history.append((amount, date))
        if type(date) is datetime.datetime or datetime.date:
            self.df.loc[date.strftime('%Y-%m-%d'), ('deposit')] += amount
            self.df.loc[date.strftime('%Y-%m-%d'), ('balance')] += amount
        for i in self.df.index[self.df.index.slice_locs(date + datetime.timedelta(days=1))[0] :]:
            self.df.loc[i, 'balance'] = self.df.loc[i-datetime.timedelta(days=1), 'balance']* (1+(0.08 / 365)) + self.df.loc[i, 'deposit'] - self.df.loc[i, 'withdrawl']

    def withdraw_money(self, amount, date):
        self.history.append((amount*-1, date))
        if type(date) is datetime.datetime or datetime.date:
            self.df.loc[date.strftime('%Y-%m-%d'), ('withdrawl')] += amount
            self.df.loc[date.strftime('%Y-%m-%d'), ('balance')] -= amount
        for i in self.df.index[self.df.index.slice_locs(date + datetime.timedelta(days=1))[0] :]:
            self.df.loc[i, 'balance'] = self.df.loc[i-datetime.timedelta(days=1), 'balance']* (1+(0.08 / 365)) + self.df.loc[i, 'deposit'] - self.df.loc[i, 'withdrawl']


I am looking for improvement ideas for that (also repeating in all the functions). I am also looking for a neater way, within pandas of assigning yesterday's balance + todays deposit - today's withdraw + the daily interest rate. (I know it's an extremely generous interest, but they are my kids after all and with the little pennies they manage to collect it doesn't amount to much...)

I start an account like so:

import datetime
test = Account('my_name', datetime.date.today())


I've improved my __str__ and __repr__ methods after I read all the suggestions suggested on this question, didn't do anything about privacy and properties but first thing first.

Wouldn't changing the date from the index to its own column and using integer indices make it easier to access and lookup data?
I think your design is a bit "overkill". After all, banks don't keep empty records for each day of the year, waiting for you to come along and perform a transaction.
Rather than using a DataFrame, I think you'd be better off separating the data record into a class of its own, with the increment and decrement functions.  

The display functionality is not part of the data record, it would be a separate class itself, and inheritable by ATMs or a Teller/Bank Manager/technician's computer. Regardless, this is something for kids, so it's fine to violate some SOLID principals.

Regarding def __init__(self, holder, start_date): you could probably make start_date = date.today() as transactions tend to happen on the same day, unless you're performing some cheque activity (which is delayed).

As to your question, if you change the date from the index into its own column, you're shifting the column[:loc] as the lookup, essentially adding an extra step.
For using integer indices to lookup data, it's a bad idea as you should try to keep any [lookup_integer] values as defined constants - so they're not arbitrary numbers (you'd be surprised how often people make simple input mistakes when coding, and as they're usually valid integers, people are scratching their heads why a date is in the address of a decimal number (addition and subtraction would then still be valid operations, so it's not picked up immediately unless you're performing tests on data as part of your CI process, and you go live with faulty code).

Good luck!