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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ A dummy application for a bank; should provide various functions of a retail ban

* A customer can transfer between their accounts
* Change **Maxi-Savings accounts** to have an interest rate of 5% assuming no withdrawals in the past 10 days otherwise 0.1%
* Interest rates should accrue daily (incl. weekends), rates above are per-annum
* Interest rates should accrue daily (incl. weekends), rates above are per-annum
84 changes: 56 additions & 28 deletions abcbank/account.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,71 @@
from abcbank.transaction import Transaction

CHECKING = 0
SAVINGS = 1
MAXI_SAVINGS = 2

from datetime import datetime, timedelta

class Account:
def __init__(self, accountType):
self.accountType = accountType
self.dateOpened = datetime.now()
self.transactions = []
self.balance = 0
self.account_age_in_days = (datetime.now() - self.dateOpened).days


def deposit(self, amount):
if (amount <= 0):
raise ValueError("amount must be greater than zero")
else:
self.transactions.append(Transaction(amount))
if not amount > 0:
raise ValueError("Must enter an amount greater than zero")
new_transaction = Transaction(amount,'deposit')
self.balance += amount
self.transactions.append(new_transaction)

def withdraw(self, amount):
if (amount <= 0):
raise ValueError("amount must be greater than zero")
if not amount > 0:
raise ValueError("Must enter an amount greater than zero")
if not self.balance >= amount:
raise ValueError("Insufficient Funds")
else:
self.transactions.append(Transaction(-amount))
new_transaction = Transaction(amount,'withdrawal')
self.balance -= amount
self.transactions.append(new_transaction)

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

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

def dailyInterestRate(self):
default_interest = self.balance * 0.001 / 356
if self.accountType == 'CHECKING':
interest = (default_interest)

elif self.accountType == 'SAVINGS':
if self.balance <= 1000:
interest = default_interest
else:
return 70 + (amount - 2000) * 0.1
interest = (1 + (self.balance - 1000) * 0.002) / 356

elif self.accountType == 'MAXI_SAVINGS':
for t in self.transactions:
if t.action == "withdrawal" and (datetime.now() - t.transactionDate).days < 10:
interest = default_interest
else:
interest = self.balance * 0.05 / 356
return interest

def interestEarnedDaily(self):
interest = 0
if self.account_age_in_days == 0:
pass
else:
return amount * 0.001
for day in range(1,self.account_age_in_days):
interest += self.dailyInterestRate()
return interest

def accrueInterest(self):
if self.account_age_in_days>0:
for day in range(self.account_age_in_days-1):
self.balance += self.accruedDailyInterest() * self.interestEarnedDaily()
return self.balance





def sumTransactions(self, checkAllTransactions=True):
return sum([t.amount for t in self.transactions])
20 changes: 13 additions & 7 deletions abcbank/bank.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
from abcbank.customer import Customer

class Bank:
def __init__(self):
self.customers = []

def addCustomer(self, customer):
self.customers.append(customer)
def addCustomer(self, customer_name):
new_customer = Customer(customer_name)
self.customers.append(new_customer)
return new_customer

def customerSummary(self):
summary = "Customer Summary"
for customer in self.customers:
summary = summary + "\n - " + customer.name + " (" + self._format(customer.numAccs(), "account") + ")"
summary += "\n - " + customer.name + " (" + self._format(customer.numAccs(), "account") + ")"
return summary

def _format(self, number, word):
return str(number) + " " + (word if (number == 1) else word + "s")

def totalInterestPaid(self):
total = 0
for c in self.customers:
total += c.totalInterestEarned()
return total

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


class Customer:
def __init__(self, name):
self.name = name
self.accounts = []

def openAccount(self, account):
self.accounts.append(account)
return self

def openAccount(self, account_type):
is_valid = ['CHECKING','SAVINGS','MAXI_SAVINGS']
if account_type in is_valid:
new_account = Account(account_type)
self.accounts.append(new_account)
return new_account
else:
raise ValueError("Invalid Account Type")

def numAccs(self):
return len(self.accounts)

def totalInterestEarned(self):
return sum([a.interestEarned() for a in self.accounts])
return sum([a.interestEarnedDaily() for a in self.accounts])

def totalAssets(self):
return "Total Assets: " + _toDollars(sum([a.balance for a in self.accounts]))

# This method gets a statement
def getStatement(self):
Expand All @@ -25,31 +33,27 @@ def getStatement(self):
statement = "Statement for %s" % self.name
for account in self.accounts:
statement = statement + self.statementForAccount(account)
statement = statement + "\n\nTotal In All Accounts " + _toDollars(totalAcrossAllAccounts)
statement += "\n\nTotal In All Accounts " + _toDollars(totalAcrossAllAccounts)
return statement

def statementForAccount(self, account):
accountType = "\n\n\n"
if account.accountType == CHECKING:
if account.accountType == 'CHECKING':
accountType = "\n\nChecking Account\n"
if account.accountType == SAVINGS:
if account.accountType == 'SAVINGS':
accountType = "\n\nSavings Account\n"
if account.accountType == MAXI_SAVINGS:
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 = [t.action + " " + _toDollars(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"

def makeTransfer(self,amount,account_to,account_from):
deposit_to = account_to.deposit(amount)
withdraw_from = account_from.withdraw(amount)
return self.getStatement()

def _toDollars(number):
return "${:1.2f}".format(number)

6 changes: 4 additions & 2 deletions abcbank/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@


class Transaction:
def __init__(self, amount):
def __init__(self,amount,action):
self.amount = amount
self.transactionDate = datetime.now()
self.transactionDate = datetime.now()
self.action = action

52 changes: 52 additions & 0 deletions bank_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from nose.tools import assert_equals
from abcbank.account import Account
from abcbank.bank import Bank
from abcbank.customer import Customer
from abcbank.transaction import Transaction


def test_customer_summary():
bank = Bank()
john = bank.addCustomer('John')
john_new_checking = john.openAccount('CHECKING')
assert_equals(bank.customerSummary(),"Customer Summary\n - John (1 account)")

def test_checking_account():
bank = Bank()
bill = bank.addCustomer("Bill")
bill_new_checking = bill.openAccount('CHECKING')
bill_new_checking.deposit(100.00)
bill_new_checking.account_age_in_days = 20
assert_equals(round(bank.totalInterestPaid(),3), .005)

def test_savings_account():
bank = Bank()
bill = bank.addCustomer("Bill")
bill_new_maxi = bill.openAccount('MAXI_SAVINGS')
bill_new_maxi.deposit(1500.0)
bill_new_maxi.account_age_in_days = 10
assert_equals(round(bill_new_maxi.interestEarnedDaily(),2),1.9)

def test_maxi_savings_account():
bank = Bank()
bill = bank.addCustomer("Bill")
bill_new_maxi = bill.openAccount('MAXI_SAVINGS')
bill_new_maxi.deposit(3000.0)

def test_transfer():
bank = Bank()
bill = bank.addCustomer("Bill")
bill_savings = bill.openAccount('SAVINGS')
bill_checking = bill.openAccount('CHECKING')
bill_savings.deposit(200.0)
bill_checking.deposit(100.0)
bill.makeTransfer(50.0,bill_savings,bill_checking)
assert_equals(bill_checking.balance,50.0)
assert_equals(bill_savings.balance,250.0)

if __name__ == '__main__':
test_customer_summary()
test_checking_account()
test_savings_account()
test_maxi_savings_account()
test_transfer()
49 changes: 49 additions & 0 deletions customer_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from nose.tools import assert_equals, nottest
from abcbank.bank import Bank
from abcbank.account import Account
from abcbank.customer import Customer
from abcbank.transaction import Transaction


def test_statement():
bank = Bank()
henry = bank.addCustomer("Henry")
henry_checking=henry.openAccount('CHECKING')
henry_savings = henry.openAccount('SAVINGS')
henry_checkings.deposit(100.0)
henry_savings.deposit(4000.0)
henry_savings.withdraw(200.0)
assert_equals(henry.getStatement(),
"Statement for Henry" +
"\n\nChecking Account\n deposit $100.00\nTotal $100.00" +
"\n\nSavings Account\n deposit $4000.00\n withdrawal $200.00\nTotal $3800.00" +
"\n\nTotal In All Accounts $3900.00")


def test_oneAccount():
bank = Bank()
oscar = bank.addCustomer("Oscar")
oscar_savings = oscar.openAccount('SAVINGS')
assert_equals(oscar.numAccs(), 1)

def test_twoAccounts():
bank = Bank()
oscar = bank.addCustomer("Oscar")
oscar_savings = oscar.openAccount('SAVINGS')
oscar_checking = oscar.openAccount('CHECKING')
assert_equals(oscar.numAccs(), 2)

@nottest
def test_threeAccounts():
bank = Bank()
oscar = bank.addCustomer("Oscar")
oscar_savings = oscar.openAccount('SAVINGS')
oscar_checking = oscar.openAccount('CHECKING')
oscar_checking = oscar.openAccount('MAXI_SAVINGS')
assert_equals(oscar.numAccs(), 3)

if __name__ == '__main__':
test_oneAccount()
test_twoAccounts()
test_threeAccounts()

Empty file removed tests/__init__.py
Empty file.
38 changes: 0 additions & 38 deletions tests/bank_tests.py

This file was deleted.

Loading