diff --git a/abcbank/account.py b/abcbank/account.py index e010009..cb3ebce 100644 --- a/abcbank/account.py +++ b/abcbank/account.py @@ -1,4 +1,5 @@ from abcbank.transaction import Transaction +from abcbank.date_provider import DateProvider CHECKING = 0 SAVINGS = 1 @@ -10,9 +11,18 @@ def __init__(self, accountType): self.accountType = accountType self.transactions = [] + def __hash__(self): + return self.accountType + + def __cmp__(self): + return object.__cmp__(self) + + def __eq__(self, rhs): + return self.accountType == rhs.accountType + def deposit(self, amount): if (amount <= 0): - raise ValueError("amount must be greater than zero") + print("amount must be greater than zero") else: self.transactions.append(Transaction(amount)) @@ -22,22 +32,42 @@ def withdraw(self, amount): else: self.transactions.append(Transaction(-amount)) + def getSavingsAccountLT1000(self, amount): + return amount * 0.001 * DateProvider.getTotalDaysPassedRatio() + + def getSavingsAccountGT1000(self, amount): + return self.getSavingsAccountLT1000(1000) + \ + (amount - 1000) * 0.002 * DateProvider.getTotalDaysPassedRatio() + def interestEarned(self): amount = self.sumTransactions() if self.accountType == SAVINGS: if (amount <= 1000): - return amount * 0.001 + return self.getSavingsAccountLT1000(amount) else: - return 1 + (amount - 1000) * 0.002 + return self.getSavingsAccountGT1000(amount) + 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 + if not self.checkTransactionInLastTenDays(): + return amount * 0.005 * DateProvider.getTotalDaysPassedRatio() + else: return amount * 0.001 * DateProvider.getTotalDaysPassedRatio() else: - return amount * 0.001 + return amount * 0.001 * DateProvider.getTotalDaysPassedRatio() - def sumTransactions(self, checkAllTransactions=True): - return sum([t.amount for t in self.transactions]) \ No newline at end of file + def sumTransactions(self): + return sum([t.amount for t in self.transactions]) + + def checkTransactionInLastTenDays(self): + for t in self.transactions: + if t.transactionDate >= DateProvider.tenDaysAgo(): + return True + return False + + def transfer(self, toAccount, amount): + if self == toAccount: + raise ValueError("transfer between same accounts are invalid") + if self.sumTransactions() < amount: + raise ValueError("amount in "+ self.accountType +"< 0") + else: + self.withdraw(amount) + toAccount.deposit(amount) \ No newline at end of file diff --git a/abcbank/bank.py b/abcbank/bank.py index 44711fe..6349e39 100644 --- a/abcbank/bank.py +++ b/abcbank/bank.py @@ -1,25 +1,32 @@ class Bank: def __init__(self): - self.customers = [] + self.customers = set() def addCustomer(self, customer): - self.customers.append(customer) + if customer not in self.customers: + self.customers.add(customer) + else: + print("Customer with name "+customer.name+" already present") + def customerSummary(self): summary = "Customer Summary" for customer in self.customers: summary = 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 - return self.customers[0].name + customerList = list(self.customers) + return customerList[0].name except Exception as e: print(e) return "Error" \ No newline at end of file diff --git a/abcbank/customer.py b/abcbank/customer.py index 7cfd62a..076804a 100644 --- a/abcbank/customer.py +++ b/abcbank/customer.py @@ -1,14 +1,25 @@ -from account import CHECKING, SAVINGS, MAXI_SAVINGS - +from abcbank.account import CHECKING, SAVINGS, MAXI_SAVINGS class Customer: def __init__(self, name): self.name = name - self.accounts = [] + self.accounts = set() + + def __hash__(self): + return abs(hash(self.name)) % (10 ** 8) + + def __cmp__(self): + return object.__cmp__(self) + + def __eq__(self, rhs): + return self.name == rhs.name def openAccount(self, account): - self.accounts.append(account) - return self + if account not in self.accounts: + self.accounts.add(account) + return self + else: + raise ValueError("account of given type already exists for customer") def numAccs(self): return len(self.accounts) diff --git a/abcbank/date_provider.py b/abcbank/date_provider.py index 33b64eb..40e31b1 100644 --- a/abcbank/date_provider.py +++ b/abcbank/date_provider.py @@ -1,7 +1,18 @@ -from datetime import datetime +from datetime import datetime, timedelta class DateProvider: @staticmethod def now(): - return datetime.now() \ No newline at end of file + return datetime.now() + + @staticmethod + def tenDaysAgo(): + return datetime.now() - timedelta(days=10) + + @staticmethod + def getTotalDaysPassedRatio(): + now = datetime.now() + start_year = datetime(now.year, 1, 1, 0, 0, 0) + days_passed = (datetime.now() - start_year).days + return float(days_passed)/float(365.0) \ No newline at end of file diff --git a/abcbank/transaction.py b/abcbank/transaction.py index 8e5b5ad..9ce4213 100644 --- a/abcbank/transaction.py +++ b/abcbank/transaction.py @@ -1,7 +1,7 @@ -from datetime import datetime +from abcbank.date_provider import DateProvider class Transaction: def __init__(self, amount): self.amount = amount - self.transactionDate = datetime.now() \ No newline at end of file + self.transactionDate = DateProvider.now() \ No newline at end of file diff --git a/tests/account_tests.py b/tests/account_tests.py new file mode 100644 index 0000000..22bf3a3 --- /dev/null +++ b/tests/account_tests.py @@ -0,0 +1,58 @@ +from nose.tools import assert_equals + +from abcbank.account import Account, CHECKING, MAXI_SAVINGS, SAVINGS +from abcbank.bank import Bank +from abcbank.customer import Customer +from abcbank.date_provider import DateProvider +from datetime import datetime + +def check_transfer_account(): + checkingAccount = Account(CHECKING) + savingsAccount = Account(SAVINGS) + henry = Customer("Henry").openAccount(checkingAccount).openAccount(savingsAccount) + checkingAccount.deposit(100.0) + savingsAccount.deposit(4000.0) + savingsAccount.transfer(checkingAccount, 100) + henry.getStatement() + assert_equals(henry.getStatement(), 'Statement for Henry\n\n' + 'Checking Account\n deposit $100.00\n ' + ' deposit $100.00\nTotal $200.00\n\nSavings Account\n ' + ' deposit $4000.00\n withdrawal $100.00\nT' + 'otal $3900.00\n\nTotal In All Accounts $4100.00') + +def test_checking_account(): + bank = Bank() + checkingAccount = Account(CHECKING) + bill = Customer("Bill").openAccount(checkingAccount) + bank.addCustomer(bill) + checkingAccount.deposit(100.0) + assert_equals(checkingAccount.interestEarned(), 0.1 * DateProvider.getTotalDaysPassedRatio()) + +def test_savings_account(): + bank = Bank() + savingsAccount = Account(SAVINGS) + bank.addCustomer(Customer("Bill").openAccount(savingsAccount)) + savingsAccount.deposit(1500.0) + assert_equals(savingsAccount.interestEarned(), savingsAccount.getSavingsAccountGT1000(1500) ) + + +def test_check_transaction_in_last_10_days(): + bank = Bank() + maxiSavingsAccount = Account(MAXI_SAVINGS) + bank.addCustomer(Customer("Bill").openAccount(maxiSavingsAccount)) + maxiSavingsAccount.deposit(3000.0) + assert_equals(maxiSavingsAccount.transactions[0].amount, 3000) + assert_equals(maxiSavingsAccount.transactions[0].transactionDate.year, DateProvider.now().year) + assert_equals(maxiSavingsAccount.transactions[0].transactionDate.month, DateProvider.now().month) + assert_equals(maxiSavingsAccount.transactions[0].transactionDate.day, DateProvider.now().day) + assert_equals(maxiSavingsAccount.transactions[0].transactionDate >= DateProvider.tenDaysAgo(), True) + assert_equals(maxiSavingsAccount.checkTransactionInLastTenDays(), True) + + +def test_maxi_savings_account(): + bank = Bank() + maxiSavingsAccount = Account(MAXI_SAVINGS) + bank.addCustomer(Customer("Bill").openAccount(maxiSavingsAccount)) + maxiSavingsAccount.deposit(3000.0) + assert_equals(maxiSavingsAccount.checkTransactionInLastTenDays(), True) + assert_equals(3000 * 0.001 * DateProvider.getTotalDaysPassedRatio(), maxiSavingsAccount.interestEarned()) \ No newline at end of file diff --git a/tests/bank_tests.py b/tests/bank_tests.py index 6de98db..6d3f864 100644 --- a/tests/bank_tests.py +++ b/tests/bank_tests.py @@ -1,8 +1,9 @@ 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 +from abcbank.date_provider import DateProvider def test_customer_summary(): @@ -13,26 +14,35 @@ def test_customer_summary(): "Customer Summary\n - John (1 account)") +def test_unique_customer_added(): + bank = Bank() + john1 = Customer("John") + bank.addCustomer(john1) + bank.addCustomer(john1) + assert_equals(bank.customerSummary(), + "Customer Summary\n - John (0 accounts)") + + + def test_checking_account(): bank = Bank() checkingAccount = Account(CHECKING) bill = Customer("Bill").openAccount(checkingAccount) bank.addCustomer(bill) checkingAccount.deposit(100.0) - assert_equals(bank.totalInterestPaid(), 0.1) - + assert_equals(bank.totalInterestPaid(), 0.1 * DateProvider.getTotalDaysPassedRatio()) def test_savings_account(): bank = Bank() - checkingAccount = Account(SAVINGS) - bank.addCustomer(Customer("Bill").openAccount(checkingAccount)) - checkingAccount.deposit(1500.0) - assert_equals(bank.totalInterestPaid(), 2.0) + savingsAccount = Account(SAVINGS) + bank.addCustomer(Customer("Bill").openAccount(savingsAccount)) + savingsAccount.deposit(1500.0) + assert_equals(bank.totalInterestPaid(), savingsAccount.interestEarned()) 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) \ No newline at end of file + maxiSavingsAccount = Account(MAXI_SAVINGS) + bank.addCustomer(Customer("Bill").openAccount(maxiSavingsAccount)) + maxiSavingsAccount.deposit(3000.0) + assert_equals(bank.totalInterestPaid(), maxiSavingsAccount.interestEarned()) \ No newline at end of file diff --git a/tests/customer_tests.py b/tests/customer_tests.py index 0211a4f..65acfcc 100644 --- a/tests/customer_tests.py +++ b/tests/customer_tests.py @@ -1,7 +1,7 @@ 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(): diff --git a/tests/transaction_tests.py b/tests/transaction_tests.py index 62caa8a..e44b0c0 100644 --- a/tests/transaction_tests.py +++ b/tests/transaction_tests.py @@ -1,6 +1,6 @@ from nose.tools import assert_is_instance -from transaction import Transaction +from abcbank.transaction import Transaction def test_type():