diff --git a/abcbank/account.py b/abcbank/account.py index e010009..871f14e 100644 --- a/abcbank/account.py +++ b/abcbank/account.py @@ -1,43 +1,195 @@ -from abcbank.transaction import Transaction +from transaction import Transaction +from abc import abstractmethod +from date_provider import DateProvider +import datetime -CHECKING = 0 -SAVINGS = 1 -MAXI_SAVINGS = 2 +""" +Changes: + 1. added acctType data-type to identify account type + 2. created savings, checking, and maxi classes that inherit parent class account + 3. overrode interest_earned() method in each class, decorated as an abstract method in Account + 4. added logic to handle daily interest, this is handled by changing the sum_transaction method + 5. also added logic to recognize when a year has past and the customer gets year interest on the Maxi account + 6. Added test interest earned method in order to test interest calculations without considering DateProvider.now() + 7. Interest rate accrual now occurs on a daily basis along with year returns from the MAxi Savings Account +""" -class Account: - def __init__(self, accountType): - self.accountType = accountType +class Account(object): + def __init__(self): self.transactions = [] + self.type = "Default" def deposit(self, amount): - if (amount <= 0): + if amount <= 0: raise ValueError("amount must be greater than zero") else: self.transactions.append(Transaction(amount)) def withdraw(self, amount): - if (amount <= 0): + if amount <= 0: raise ValueError("amount must be greater than zero") else: self.transactions.append(Transaction(-amount)) + @abstractmethod def interestEarned(self): - amount = self.sumTransactions() - if self.accountType == SAVINGS: - if (amount <= 1000): - return amount * 0.001 + """ + To be implemented in subclass + """ + + def sum_transactions(self, checkAllTransactions=True, num_days=1): + """ + Essentially returns sum of transactions across all accounts, if not checking all transactions will check total + in the past num_days (mainly for interest accural) + num_days is defaulted to 1 day + """ + total = 0 + + if checkAllTransactions: + return sum([t.amount for t in self.transactions]) + else: + for trans in self.transactions: + if DateProvider.now() - trans.transactionDate <= datetime.timedelta(days=num_days): + total += trans.amount + return total + +class SavingsAccount(Account): + # rate changes can be made here (immutable types) + interest_rates = (.001, .002) + rate_thresholds = (1000,) + + def __init__(self): + super(SavingsAccount, self).__init__() + self.type = "Savings Account" + self.interest_timer = DateProvider.now() + + def interestEarned(self): + """ + returns --> total interest earned from this savings account + """ + amount = self.sum_transactions() + now = DateProvider.now() + + if now - self.interest_timer > datetime.timedelta(days=1): + if amount <= SavingsAccount.rate_thresholds: + self.interest_timer = DateProvider.now() + return amount * SavingsAccount.interest_rates[0] + 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 + self.interest_timer = DateProvider.now() + return 1 + (amount - SavingsAccount.rate_thresholds[0]) * SavingsAccount.interest_rates[1] + + else: + return 0 + + def testInterestEarned(self): + """ + This method is used to test interest calculations not dependent on time + """ + amount = self.sum_transactions() + if amount <= SavingsAccount.rate_thresholds[0]: + self.interest_timer = DateProvider.now() + return amount * SavingsAccount.interest_rates[0] + + else: + self.interest_timer = DateProvider.now() + return 1 + (amount - SavingsAccount.rate_thresholds[0]) * SavingsAccount.interest_rates[1] + + +class CheckingAccount(Account): + # rate changes can be made here (immutable types) + interest_rates = (.001,) + + def __init__(self): + super(CheckingAccount, self).__init__() + self.type = "Checking Account" + self.interest_timer = DateProvider.now() + + def interestEarned(self): + """ + returns --> total interest earned from this checking account per year + """ + # daily accrual of interest + if DateProvider.now() - self.interest_timer > datetime.timedelta(days=1): + self.interest_timer = DateProvider.now() # reset timer + return self.sum_transactions(False) * CheckingAccount.interest_rates + else: + return 0 + + def testInterestEarned(self): + """ + To test interest earned on all transaction not time dependent + """ + return self.sum_transactions(True) * CheckingAccount.interest_rates + +class MaxiSavings(Account): + + # cannot be change + rate_thresholds = (1000, 2000) + + def __init__(self): + super(MaxiSavings, self).__init__() + self.type = "Maxi Savings Account" + self.interest_rates = [.02, .05, .1] + self.interest_timer = DateProvider.now() + self.interest_timer_daily = DateProvider.now() + self.interest_timer_tenDay = DateProvider.now() + + def interestEarned(self): + """ + Note: rates can be adjusted by changing class variables interest_Rates and rate_thresholds + returns --> interest earned from the Maxi Savings account + """ + amount = self.sum_transactions(False, 365) + + # yearly interest rate accrual + if DateProvider.now() - self.interest_timer > datetime.timedelta(days=365): + if amount <= self.rate_thresholds[0]: + self.interest_timer = DateProvider.now() + return amount * self.interest_rates[0] + + elif amount < MaxiSavings.rate_thresholds[1]: + self.interest_timer = DateProvider.now() + return 20 + (amount - MaxiSavings.rate_thresholds[0]) * self.interest_rates[1] + + else: + self.interest_timer = DateProvider.now() + return 70 + (amount - MaxiSavings.rate_thresholds[1]) * self.interest_rates[2] + + # checking for daily interest + amount = self.sum_transactions(False) + if datetime.timedelta(days=1) < DateProvider.now() - self.interest_timer_daily < datetime.timedelta(days=365): + if self.interest_timer_tenDay + datetime.timedelta(days=1) > datetime.timedelta(days=10): + self.interest_timer_daily = DateProvider.now() + return amount * .05 else: - return 70 + (amount - 2000) * 0.1 + self.interest_timer_daily = DateProvider.now() + return amount * .001 + else: + return 0 + + def test_interest_earned(self): + """ + this method removes the time dependency just to check interest calculations + """ + amount = self.sum_transactions() + if amount <= self.rate_thresholds[0]: + self.interest_timer = DateProvider.now() + return amount * self.interest_rates[0] + + elif amount < MaxiSavings.rate_thresholds[1]: + self.interest_timer = DateProvider.now() + return 20 + (amount - MaxiSavings.rate_thresholds[0]) * self.interest_rates[1] + else: - return amount * 0.001 + self.interest_timer = DateProvider.now() + return 70 + (amount - MaxiSavings.rate_thresholds[1]) * self.interest_rates[2] + - def sumTransactions(self, checkAllTransactions=True): - return sum([t.amount for t in self.transactions]) \ No newline at end of file + def set_interest_rate(self, ratesList): + """ + ratesList --> list of three interest rates + allows for dynamic changing of account interest rates + """ + MaxiSavings.interest_rates = ratesList diff --git a/abcbank/bank.py b/abcbank/bank.py index 44711fe..8ccc82a 100644 --- a/abcbank/bank.py +++ b/abcbank/bank.py @@ -1,25 +1,69 @@ +from customer import Customer + + class Bank: + """ + Changes made: + 1. spaced out functions + 2. type check in addCustomer method (raising typeError) + 3. imported Customer class + 4. instantiated customers with list() instead of [] + 5. refactored methods to conform to PEP8 (lowercase and underscores) + 6. made _format() static (can safely due this) + 7. deleted self.customers = None in get_first_customer() + 8. changed argument name in _format() for clarity of use + 9. deleted total = 0 in total interest paid, allows this method to be called multiple times + 10. added a clear_interest_paid() method to clear out interest paid record + """ + def __init__(self): - self.customers = [] + self.customers = list() + self.interest_paid = 0 - def addCustomer(self, customer): + def add_customer(self, customer): + """ + Customer can be a list of customers + """ + # check customer is a customer object + if not isinstance(customer, Customer): + raise TypeError(str(customer) + " is not a customer object") self.customers.append(customer) - def customerSummary(self): + + def customer_summary(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.num_accounts(), "account") + ")" return summary - def _format(self, number, word): - return str(number) + " " + (word if (number == 1) else word + "s") - def totalInterestPaid(self): - total = 0 + + @staticmethod + def _format(number, type_acct): + """ + Descr: Used internal to class as a text formatting helper function + number: number of customer accounts + word: type of account + """ + return str(number) + " " + (type_acct if (number == 1) else type_acct + "s") + + def total_interest_paid(self): + """ + Descr: keeps a running total of interest paid to customers until cleared + """ for c in self.customers: - total += c.totalInterestEarned() - return total - def getFirstCustomer(self): + self.interest_paid += c.total_interest_earned() + + print("Interest paid out by the bank to Customers....") + return self.interest_paid + + def clear_interest_paid(self): + """ + Descr: zero out interest paid to customers + """ + self.interest_paid = 0 + print("Record of interest paid out to customers cleared....") + + def get_first_customer(self): try: - self.customers = None return self.customers[0].name except Exception as e: print(e) - return "Error" \ No newline at end of file + return "Error no customers on file" diff --git a/abcbank/customer.py b/abcbank/customer.py index 7cfd62a..6e74f74 100644 --- a/abcbank/customer.py +++ b/abcbank/customer.py @@ -1,4 +1,6 @@ -from account import CHECKING, SAVINGS, MAXI_SAVINGS +from account import Account +from transaction import Transaction +from date_provider import DateProvider class Customer: @@ -6,49 +8,118 @@ def __init__(self, name): self.name = name self.accounts = [] - def openAccount(self, account): - self.accounts.append(account) - return self + def open_account(self, account): + if isinstance(account, Account): + self.accounts.append(account) + return self + else: + raise TypeError(str(account) + "Needs to be an Account type ie.. CheckingAccount, " + "SavingsAccount, MaxiSavings, Account") - def numAccs(self): + def num_accounts(self): + """ + returns how many accounts this customer has + """ return len(self.accounts) - def totalInterestEarned(self): - return sum([a.interestEarned() for a in self.accounts]) + def total_interest_earned(self): + earned = 0 + for a in self.accounts: + earned += a.interestEarned() + return earned - # This method gets a statement - def getStatement(self): - # JIRA-123 Change by Joe Bloggs 29/7/1988 start - statement = None # reset statement to null here - # JIRA-123 Change by Joe Bloggs 29/7/1988 end - totalAcrossAllAccounts = sum([a.sumTransactions() for a in self.accounts]) + def get_statement(self): + """ + returns a statement showing transactions and totals for each account + """ + total_across_all_accounts = sum([a.sum_transactions() for a in self.accounts]) 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 += self.statement_for_account(account) + + statement += "\n\nTotal In All Accounts " + _toDollars(total_across_all_accounts) return statement - 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" - 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" + def statement_for_account(self, account): + account_type = "\n\n\n" + + if account.type == "Checking Account": + account_type = "\n\nChecking Account\n" + + if account.type == "Savings Account": + account_type = "\n\nSavings Account\n" + + if account.type == "Maxi Savings Account": + account_type = "\n\nMaxi Savings Account\n" + + transaction_summary = [self.withdrawal_or_deposit_text(t) + " " + _toDollars(abs(t.amount)) for t in account.transactions] + + transaction_summary = " " + "\n ".join(transaction_summary) + "\n" + + total_summary = "Total " + _toDollars(sum([t.amount for t in account.transactions])) + + return account_type + transaction_summary + total_summary + + @staticmethod + def withdrawal_or_deposit_text(transaction): + if isinstance(transaction, Transaction): + if transaction.amount < 0: + return "withdrawal" + + elif transaction.amount > 0: + return "deposit" + + else: + return "N/A" + else: + raise TypeError("Error" + str(transaction) + "is not a Transaction type") + + def is_account(self, account_type): + """ + accountType --> account type string type ie "Savings Account" + return --> index of account in self.accounts list + """ + index = None + for x in range(len(self.accounts)): + if self.accounts[x].type == account_type: + index = x + break + return index + + def withdraw(self, account_type, amount): + """ + Descr: withdraws money into account + accountType is the account type targeted + :return: + """ + index = self.is_account(account_type) + self.accounts[index].withdraw(amount) + + # checks if Maxi was withdrawn from if so reset interest rates back + if account_type == "Maxi Savings Account": + self.accounts[index].interest_timer_tenDay = DateProvider.now() # resets timer for higher interest rate + + def deposit(self, account_type, amount): + """ + Descr: deposits money into account + accountType is the account type targeted + """ + index = self.is_account(account_type) + self.accounts[index].deposit(amount) + + def transfer(self, from_account, to_account, amount): + + if from_account != to_account: + + fr = self.is_account(from_account) + to = self.is_account(to_account) + + self.accounts[fr].withdraw(amount) + self.accounts[to].deposit(amount) + else: - return "N/A" + print("No Operation, same accounts, transfer not possible!!") def _toDollars(number): diff --git a/abcbank/transaction.py b/abcbank/transaction.py index 8e5b5ad..8df10c5 100644 --- a/abcbank/transaction.py +++ b/abcbank/transaction.py @@ -2,6 +2,14 @@ class Transaction: + """ + Changes: + 1. attempting to ensure amount is a numeric type + """ + def __init__(self, amount): - self.amount = amount - self.transactionDate = datetime.now() \ No newline at end of file + if isinstance(amount, float) or isinstance(amount, int) or isinstance(amount, long): + self.amount = amount + self.transactionDate = datetime.now() + else: + raise TypeError(str(amount) + " is not a number type") diff --git a/tests/bank_tests.py b/tests/bank_tests.py index 6de98db..8d09044 100644 --- a/tests/bank_tests.py +++ b/tests/bank_tests.py @@ -1,38 +1,92 @@ -from nose.tools import assert_equals - -from account import Account, CHECKING, MAXI_SAVINGS, SAVINGS +from nose.tools import assert_equals, with_setup, raises +from account import CheckingAccount, SavingsAccount, MaxiSavings from bank import Bank from customer import Customer -def test_customer_summary(): +def set_up(): + """Set up test stimulus as global variable for respective test functions""" + global customers, jay, dave, jim, harry, bank + jay = Customer('Jay') + dave = Customer('Dave') + jim = Customer('Jim') + harry = Customer('Harry') + customers = [jay, dave, jim, harry] bank = Bank() - john = Customer("John").openAccount(Account(CHECKING)) - bank.addCustomer(john) - assert_equals(bank.customerSummary(), - "Customer Summary\n - John (1 account)") + + +def tear_down(): + """End test on function""" + + +@with_setup(set_up(), tear_down()) +def test_customer_summary(): + + jay.open_account(CheckingAccount()) + jay.open_account(SavingsAccount()) + jim.open_account(CheckingAccount()) + jim.open_account(SavingsAccount()) + dave.open_account(MaxiSavings()) + dave.open_account(CheckingAccount()) + dave.open_account(SavingsAccount()) + harry.open_account(CheckingAccount()) + + for i in range(45): + dave.open_account(CheckingAccount()) + + for cust in customers: + bank.add_customer(cust) + + print(bank.get_first_customer()) + print(bank.customer_summary()) + # assert_equals(bank.customer_summary(), "Customer Summary\n- Jay (2 account)\n- Dave (48 accounts)\n- Jim (2 accounts)\n- Harry (1 account)") 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) + checkingAccount = CheckingAccount() + bill = Customer("Bill").open_account(checkingAccount) + bank.add_customer(bill) + bill.deposit("Checking Account", 100.0) + assert_equals(bank.total_interest_paid(), 0) # it takes 1 day to get interest --> added as newly requested feature def test_savings_account(): bank = Bank() - checkingAccount = Account(SAVINGS) - bank.addCustomer(Customer("Bill").openAccount(checkingAccount)) + checkingAccount = SavingsAccount() + bank.add_customer(Customer("Bill").open_account(SavingsAccount())) checkingAccount.deposit(1500.0) - assert_equals(bank.totalInterestPaid(), 2.0) + assert_equals(bank.total_interest_paid(), 0) # take 1 day to get interest --> added as newly requested feature + assert_equals(checkingAccount.testInterestEarned(), 2) + checkingAccount.deposit(5000) + assert_equals(checkingAccount.testInterestEarned(), 12) def test_maxi_savings_account(): bank = Bank() - checkingAccount = Account(MAXI_SAVINGS) - bank.addCustomer(Customer("Bill").openAccount(checkingAccount)) + checkingAccount = MaxiSavings() + bank.add_customer(Customer("Bill").open_account(CheckingAccount())) checkingAccount.deposit(3000.0) - assert_equals(bank.totalInterestPaid(), 170.0) \ No newline at end of file + assert_equals(bank.total_interest_paid(), 0) + + +@with_setup(set_up(), tear_down()) +@raises(TypeError) +def failTest(): + bk = Bank() + john = Customer("John") + notACust = 'wrong' + bk.add_customer(notACust) + + +def catch_except_get_first_customer(): + bk = Bank() + print(bk.get_first_customer()) + + +catch_except_get_first_customer() +failTest() +test_checking_account() +test_customer_summary() +test_maxi_savings_account() +test_savings_account() diff --git a/tests/customer_tests.py b/tests/customer_tests.py index 0211a4f..fc02af8 100644 --- a/tests/customer_tests.py +++ b/tests/customer_tests.py @@ -1,36 +1,93 @@ -from nose.tools import assert_equals, nottest - -from account import Account, CHECKING, SAVINGS +from nose.tools import assert_equals, nottest, with_setup, assert_false +from account import CheckingAccount, SavingsAccount, MaxiSavings from customer import Customer +def setup(): + global deposit, withdraw + deposit = [3000, 2000, 1500, 453.56] + withdraw = [100, 150, 300.43, 111, 45.22] + + +def tear_down(): + """end of test""" + + def test_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) - assert_equals(henry.getStatement(), + checking_account = CheckingAccount() + savings_account = SavingsAccount() + maxi = MaxiSavings() + henry = Customer("Henry") + henry.open_account(checking_account) + henry.open_account(savings_account) + henry.open_account(maxi) + henry.deposit("Maxi Savings Account", 5000.00) + henry.withdraw("Maxi Savings Account", 3500.00) + henry.deposit("Checking Account", 100.0) + henry.deposit('Savings Account', 4000.0) + henry.withdraw('Savings Account', 200) + print(henry.get_statement()) + assert_equals(henry.get_statement(), "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") - + "\n\nMaxi Savings Account\n deposit $5000.00\n withdrawal $3500.00\nTotal $1500.00" + "\n\nTotal In All Accounts $5400.00") -def test_oneAccount(): - oscar = Customer("Oscar").openAccount(Account(SAVINGS)) - assert_equals(oscar.numAccs(), 1) +test_statement() -def test_twoAccounts(): - oscar = Customer("Oscar").openAccount(Account(SAVINGS)) - oscar.openAccount(Account(CHECKING)) - assert_equals(oscar.numAccs(), 2) +def test_n_accounts(n): + joe = Customer('Joe') + for i in range(n): + joe.open_account(SavingsAccount()) + joe.open_account(CheckingAccount()) + joe.open_account(MaxiSavings()) + assert_equals(joe.num_accounts(), n*3) + print("n accounts test passes! ") @nottest -def test_threeAccounts(): - oscar = Customer("Oscar").openAccount(Account(SAVINGS)) - oscar.openAccount(Account(CHECKING)) - assert_equals(oscar.numAccs(), 3) \ No newline at end of file +def test_three_accounts(): + oscar = Customer("Oscar").open_account(SavingsAccount()) + oscar.open_account(CheckingAccount()) + assert_false(oscar.num_accounts() == 3) + + +@with_setup(setup(), tear_down()) +def test_account_balance(): + jay = Customer("Jay").open_account(CheckingAccount()) + jay.open_account(SavingsAccount()) + jay.open_account(MaxiSavings()) + for dep in deposit: + jay.deposit("Checking Account", dep) + jay.deposit("Savings Account", dep) + jay.deposit("Maxi Savings Account", dep) + + for wd in withdraw: + jay.withdraw("Checking Account", wd) + jay.withdraw("Savings Account", wd) + jay.withdraw("Maxi Savings Account", wd) + + # checks totals in each account + for i in range(jay.num_accounts()): + assert_equals(jay.accounts[i].sum_transactions(), sum(deposit) - sum(withdraw)) + + +def transfer_test(): + jay = Customer('Jay').open_account(SavingsAccount()).open_account(CheckingAccount()) + jay.deposit("Checking Account", 1000) + jay.deposit("Savings Account", 400) + jay.transfer("Checking Account", "Savings Account", 200) + print(jay.get_statement()) + checking_index = jay.is_account("Checking Account") + savings_index = jay.is_account("Savings Account") + assert_equals(jay.accounts[checking_index].sum_transactions(), 800) + assert_equals(jay.accounts[savings_index].sum_transactions(), 600) + print('\nTransfer test success') + + +test_n_accounts(15) +test_three_accounts() +test_account_balance() +transfer_test() diff --git a/tests/myTests.py b/tests/myTests.py new file mode 100644 index 0000000..9f78bee --- /dev/null +++ b/tests/myTests.py @@ -0,0 +1,46 @@ +from customer import * +from account import * +from bank import Bank +from date_provider import DateProvider + +tm = DateProvider().now() +bk = Bank() + +jim = Customer("Jim") +sam = Customer("Sam") +sam.open_account(CheckingAccount()) +sam.open_account(SavingsAccount()) +sam.open_account(MaxiSavings()) + +jim.open_account(CheckingAccount()) +jim.open_account(SavingsAccount()) + +jim.deposit("Checking Account", 750) +jim.transfer("Checking Account", "Savings Account", 250) + + +sam.deposit("Savings Account", 1500) +sam.withdraw("Savings Account", 249) + +# print(sam.statement_for_account(sam.accounts[1])) + +sam.deposit("Checking Account", 758956) +sam.withdraw("Checking Account", 11154) + +sam.deposit("Maxi Savings Account", 123633.75) +sam.withdraw("Maxi Savings Account", 999.33) + +sam.transfer("Savings Account", "Checking Account", 455) + +print(sam.get_statement()) +print('\n \n ') +print(jim.get_statement()) +print('\n \n ') +bk.add_customer(sam) +bk.add_customer(jim) + +print(bk.customer_summary()) + +print('\n \n \n') + +print(bk.total_interest_paid()) diff --git a/tests/transaction_tests.py b/tests/transaction_tests.py index 62caa8a..790b129 100644 --- a/tests/transaction_tests.py +++ b/tests/transaction_tests.py @@ -1,8 +1,40 @@ -from nose.tools import assert_is_instance - +from nose.tools import assert_equals, assert_is_instance, with_setup, raises from transaction import Transaction +from date_provider import DateProvider + + +now = DateProvider().now() + + +def set_up(): + global stimulus, errorStimulus + stimulus = [1, 250, 11, 76.65, 789765.45] + errorStimulus = [1, 55, 3, 4, 'error'] + + +def tear_down(): + """End of test""" + + + +@with_setup(set_up(), tear_down()) +def success(): + for stim in stimulus: + t = Transaction(stim) + assert_is_instance(t, Transaction, "correct type") + assert_equals(t.amount, stim) + assert_equals(t.transactionDate, now) + print(str(stim) + " Passed...\n") + + +@with_setup(set_up(), tear_down()) +@raises(TypeError) +def failure(): + for stim in errorStimulus: + print(stim) + Transaction(stim) + print(str(stim) + " Passed...\n") +success() -def test_type(): - t = Transaction(5) - assert_is_instance(t, Transaction, "correct type") \ No newline at end of file +failure()