Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 71 additions & 24 deletions abcbank/account.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,90 @@
from abcbank.transaction import Transaction
import datetime as D

CHECKING = 0
SAVINGS = 1
MAXI_SAVINGS = 2

DEP_WITH = 0
TRANSFER = 1

"""
1) transfer between their accounts
2) Change Maxi-Savings accounts to have an interest rate of 5% assuming
no withdrawals in the past 10 days otherwise 0.1%
3) Interest rates should accrue daily (incl. wknds), rates above are per-annum"""


def compound_interest(principal, rate, times_per_year, years):
body = 1 + (rate / times_per_year) # (1 + r/n)
exponent = times_per_year * years # P(1 + r/n)^nt
intEarned = (principal * pow(body, exponent)) - principal
return intEarned

class Account:
def __init__(self, accountType):
self.accountType = accountType
self.transactions = []

def deposit(self, amount):
if (amount <= 0):
raise ValueError("amount must be greater than zero")
else:
self.transactions.append(Transaction(amount))
def deposit(self, amount, tDte=D.date.today()):
if (amount <= 0): raise ValueError("amount must be greater than zero")
else: self.transactions.append(Transaction(amount, tDte, DEP_WITH))

def withdraw(self, amount, tDte=D.date.today()):
if (amount <= 0): raise ValueError("amount must be greater than zero")
else: self.transactions.append(Transaction(-amount, tDte, DEP_WITH))

def withdraw(self, amount):
if (amount <= 0):
raise ValueError("amount must be greater than zero")
else:
self.transactions.append(Transaction(-amount))
def transfer(self, toAcct, amount, tDte=D.date.today()):
if (amount <= 0): raise ValueError("amount must be greater than zero")
else:
self.transactions.append(Transaction(-amount, tDte, TRANSFER))
toAcct.transactions.append(Transaction(+amount, tDte, TRANSFER))

def interestEarned(self):
amount = self.sumTransactions()
if self.accountType == SAVINGS:
if (amount <= 1000):
return amount * 0.001
else:
return 1 + (amount - 1000) * 0.002
if self.accountType == MAXI_SAVINGS:
if (amount <= 1000):
return amount * 0.02
elif (amount <= 2000):
return 20 + (amount - 1000) * 0.05
else:
return 70 + (amount - 2000) * 0.1
else:
return amount * 0.001
if (amount <= 1000): return amount * 0.001
else: return 1 + (amount - 1000) * 0.002
elif self.accountType == MAXI_SAVINGS:
if (self.withdrawnInLast10()): return amount * 0.001
else: return amount * 0.05

if (amount <= 1000): return amount * 0.02
elif (amount <= 2000): return 20 + (amount - 1000) * 0.05
else: return 70 + (amount - 2000) * 0.1
elif self.accountType == CHECKING: return amount * 0.001
else: raise ValueError("Unknown Acct Type")

def N_interestEarned(self):
if len(self.transactions) == 0: return 0
sum_intEarned = 0
sum_amt = self.transactions[0].amount
last_transaction_date = self.transactions[0].transactionDate
last_withdrawl_date = D.date(1970,1,1)
for t in self.transactions[1:]:
nDays = (t.transactionDate-last_transaction_date).days
sum_amt += t.amount
lowr_maxi = (t.transactionDate - last_withdrawl_date).days <= 10
annual_rate = self.calc_interestRate(sum_amt, lowr_maxi)
sum_intEarned += compound_interest(sum_amt, annual_rate, 365, nDays/365)
if t.amount < 0: last_withdrawl_date = t.transactionDate
return sum_intEarned

def calc_interestRate(self, amount, low_maxi):
if self.accountType == SAVINGS:
if (amount <= 1000): return 0.001
else: return (1 + (amount - 1000) * 0.002) / amount
elif self.accountType == MAXI_SAVINGS:
if (low_maxi): return 0.001
else: return 0.05
elif self.accountType == CHECKING: return 0.001
else: raise ValueError("Unknown Acct Type")

def sumTransactions(self, checkAllTransactions=True):
return sum([t.amount for t in self.transactions])
return sum([t.amount for t in self.transactions])

def withdrawnInLast10(self):
today = D.date.today()
for t in self.transactions:
if (((today-t.transactionDate).days <= 10) and (t.amount < 0) ): return 1
return 0
9 changes: 8 additions & 1 deletion abcbank/bank.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,17 @@ def totalInterestPaid(self):
for c in self.customers:
total += c.totalInterestEarned()
return total

def N_totalInterestPaid(self):
total = 0
for c in self.customers:
total += c.N_totalInterestEarned()
return total

def getFirstCustomer(self):
try:
self.customers = None
return self.customers[0].name
except Exception as e:
print(e)
return "Error"
return "Error"
28 changes: 15 additions & 13 deletions abcbank/customer.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from account import CHECKING, SAVINGS, MAXI_SAVINGS
import os, sys

from abcbank.account import CHECKING, SAVINGS, MAXI_SAVINGS

class Customer:
def __init__(self, name):
Expand All @@ -16,6 +17,9 @@ def numAccs(self):
def totalInterestEarned(self):
return sum([a.interestEarned() for a in self.accounts])

def N_totalInterestEarned(self):
return sum([a.N_interestEarned() for a in self.accounts])

# This method gets a statement
def getStatement(self):
# JIRA-123 Change by Joe Bloggs 29/7/1988 start
Expand All @@ -30,25 +34,23 @@ def getStatement(self):

def statementForAccount(self, account):
accountType = "\n\n\n"
if account.accountType == CHECKING:
accountType = "\n\nChecking Account\n"
if account.accountType == SAVINGS:
accountType = "\n\nSavings Account\n"
if account.accountType == MAXI_SAVINGS:
accountType = "\n\nMaxi Savings Account\n"
if account.accountType == CHECKING: accountType = "\n\nChecking Account\n"
if account.accountType == SAVINGS: accountType = "\n\nSavings Account\n"
if account.accountType == MAXI_SAVINGS: accountType = "\n\nMaxi Savings Account\n"
transactionSummary = [self.withdrawalOrDepositText(t) + " " + _toDollars(abs(t.amount))
for t in account.transactions]
transactionSummary = " " + "\n ".join(transactionSummary) + "\n"
totalSummary = "Total " + _toDollars(sum([t.amount for t in account.transactions]))
return accountType + transactionSummary + totalSummary

def withdrawalOrDepositText(self, transaction):
if transaction.amount < 0:
return "withdrawal"
elif transaction.amount > 0:
return "deposit"
else:
return "N/A"
if transaction.tType == 1:
retStr = "Transfer "
print('#####in here')
else: retStr = ""
if transaction.amount < 0: return retStr+"withdrawal"
elif transaction.amount > 0: return retStr+"deposit"
else: return "N/A"


def _toDollars(number):
Expand Down
3 changes: 1 addition & 2 deletions abcbank/date_provider.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from datetime import datetime


class DateProvider:
@staticmethod
def now():
return datetime.now()
return datetime.now()
8 changes: 4 additions & 4 deletions abcbank/transaction.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from datetime import datetime

import datetime as D

class Transaction:
def __init__(self, amount):
def __init__(self, amount, tDate=D.date.today(), tType=0):
self.amount = amount
self.transactionDate = datetime.now()
self.transactionDate = tDate
self.tType = tType
53 changes: 43 additions & 10 deletions tests/bank_tests.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import os, sys
import datetime as D

from nose.tools import assert_equals

from account import Account, CHECKING, MAXI_SAVINGS, SAVINGS
from bank import Bank
from customer import Customer
from abcbank.account import Account, CHECKING, MAXI_SAVINGS, SAVINGS
from abcbank.bank import Bank
from abcbank.customer import Customer


def test_customer_summary():
Expand All @@ -24,15 +27,45 @@ def test_checking_account():

def test_savings_account():
bank = Bank()
checkingAccount = Account(SAVINGS)
bank.addCustomer(Customer("Bill").openAccount(checkingAccount))
checkingAccount.deposit(1500.0)
savingsAccount = Account(SAVINGS)
bank.addCustomer(Customer("Bill").openAccount(savingsAccount))
savingsAccount.deposit(1500.0)
assert_equals(bank.totalInterestPaid(), 2.0)


def test_maxi_savings_account():
bank = Bank()
checkingAccount = Account(MAXI_SAVINGS)
bank.addCustomer(Customer("Bill").openAccount(checkingAccount))
checkingAccount.deposit(3000.0)
assert_equals(bank.totalInterestPaid(), 170.0)
maxiAccount = Account(MAXI_SAVINGS)
bank.addCustomer(Customer("Bill").openAccount(maxiAccount))
maxiAccount.deposit(3000.0)
print(bank.totalInterestPaid())
assert_equals(bank.totalInterestPaid(), 150.0)

def test_MaxiAcct_last10():
bank = Bank()
maxiAccount = Account(MAXI_SAVINGS)
savingsAccount = Account(SAVINGS)
bank.addCustomer(Customer("Magnus").openAccount(maxiAccount).openAccount(savingsAccount))
maxiAccount.deposit(100.0, D.date(2016,1,10))
maxiAccount.deposit(100.0, D.date(2016,1,10))
maxiAccount.withdraw(10.0, D.date(2016,8,20))
print(bank.totalInterestPaid())
assert_equals(bank.totalInterestPaid(), .19)

def test_N_interestDaily():
bank = Bank()
maxiAccount = Account(MAXI_SAVINGS)
savingsAccount = Account(SAVINGS)
bank.addCustomer(Customer("Magnus").openAccount(maxiAccount).openAccount(savingsAccount))
maxiAccount.deposit(100.0, D.date(2016,1,10))
maxiAccount.deposit(100.0, D.date(2016,2,10))
maxiAccount.withdraw(10.0, D.date(2016,8,20))
print(bank.N_totalInterestPaid())

if 1: # __name__ == '__main__':
test_customer_summary()
test_checking_account()
test_savings_account()
test_maxi_savings_account()
test_MaxiAcct_last10()
test_N_interestDaily()
27 changes: 21 additions & 6 deletions tests/customer_tests.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import os, sys
import datetime as D

from nose.tools import assert_equals, nottest

from account import Account, CHECKING, SAVINGS
from customer import Customer
from abcbank.account import Account, CHECKING, SAVINGS
from abcbank.customer import Customer


def test_statement():
Expand All @@ -17,20 +20,32 @@ def test_statement():
"\n\nSavings Account\n deposit $4000.00\n withdrawal $200.00\nTotal $3800.00" +
"\n\nTotal In All Accounts $3900.00")


def test_oneAccount():
oscar = Customer("Oscar").openAccount(Account(SAVINGS))
assert_equals(oscar.numAccs(), 1)


def test_twoAccounts():
oscar = Customer("Oscar").openAccount(Account(SAVINGS))
oscar.openAccount(Account(CHECKING))
assert_equals(oscar.numAccs(), 2)


@nottest
def test_threeAccounts():
oscar = Customer("Oscar").openAccount(Account(SAVINGS))
oscar.openAccount(Account(CHECKING))
assert_equals(oscar.numAccs(), 3)
assert_equals(oscar.numAccs(), 3)

def test_Transf_Statement():
checkingAccount = Account(CHECKING)
savingsAccount = Account(SAVINGS)
henry = Customer("Henry").openAccount(checkingAccount).openAccount(savingsAccount)
checkingAccount.deposit(100.0)
savingsAccount.deposit(4000.0)
savingsAccount.withdraw(200.0)
savingsAccount.transfer(checkingAccount, 50)
print(henry.getStatement())

test_oneAccount()
test_twoAccounts()
test_statement()
test_Transf_Statement()
9 changes: 6 additions & 3 deletions tests/transaction_tests.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from nose.tools import assert_is_instance
import os, sys

from transaction import Transaction
from nose.tools import assert_is_instance

from abcbank.transaction import Transaction

def test_type():
t = Transaction(5)
assert_is_instance(t, Transaction, "correct type")
assert_is_instance(t, Transaction, "correct type")

test_type()