# Account Example with Attribute Access Decorator
# Python 3 Reflexive Metaprogramming
# H. Conrad Cunningham

# Developed for CSci 658, Software Language Engineering, Spring 2018

#234567890123456789012345678901234567890123456789012345678901234567890

# 2018-04-02: (V1) debugattr decorator adapted from Beazley's 2013
#             Metaprogramming tutorial

def debugattr(cls):
    orig_getattribute = cls.__getattribute__
    def __getattribute__(self, name):
        print(f'Get: {name}')
        return orig_getattribute(self, name)
    cls.__getattribute__ = __getattribute__
    return cls

@debugattr
class Account:
    def __init__(self):
        self._bal = 0

    def deposit(self,amt):
        self._bal += amt

    def withdraw(self,amt):
        if amt <= self._bal:
            self._bal -= amt
        else:
            print(f'Insufficient funds for withdrawal of {amt}')

    def get_balance(self):
        return self._bal

    def __str__(self):
        return f'Account with balance {self._bal}'
    
if __name__ == '__main__':
    acct = Account()
    print(f'Account: {acct}')
    acct.deposit(100)
    print(f'Depost 10: {acct.get_balance()}')
    acct.withdraw(60)
    print(f'Withdraw 60: {acct.get_balance()}')
