Automatic Teller Machine
I want to make an Automatic Teller Machine that shows different outputs, if the inputs are
is the PIN correct?
is the requested amount smaller or bigger than what is in the account?
then this is the truth table I get
PIN |
balance |
withdrawal |
|---|---|---|
right PIN |
enough |
CASH |
right PIN |
NOT enough |
DENIED |
wrong PIN |
yes |
DENIED |
wrong PIN |
NOT enough |
DENIED |
preview
These are the tests I have at the end of the chapter
1import src.atm
2import unittest
3
4
5class TestATM(unittest.TestCase):
6
7 def test_atm_withdrawal(self):
8 my_expectation = 'CASH'
9 self.assertEqual(
10 src.atm.withdraw(
11 card_has_expired=False,
12 pin_is_correct=True,
13 balance_is_enough=True,
14 above_daily_limit=False,
15 ),
16 my_expectation
17 )
18
19 my_expectation = 'DENIED'
20
21 self.assertEqual(
22 src.atm.withdraw(
23 card_has_expired=True,
24 pin_is_correct=True,
25 balance_is_enough=True,
26 above_daily_limit=True,
27 ),
28 my_expectation
29 )
30
31 self.assertEqual(
32 src.atm.withdraw(
33 card_has_expired=True,
34 pin_is_correct=True,
35 balance_is_enough=True,
36 above_daily_limit=False,
37 ),
38 my_expectation
39 )
40
41 self.assertEqual(
42 src.atm.withdraw(
43 card_has_expired=True,
44 pin_is_correct=True,
45 balance_is_enough=False,
46 above_daily_limit=True,
47 ),
48 my_expectation
49 )
50
51 self.assertEqual(
52 src.atm.withdraw(
53 card_has_expired=True,
54 pin_is_correct=True,
55 balance_is_enough=False,
56 above_daily_limit=False,
57 ),
58 my_expectation
59 )
60
61 self.assertEqual(
62 src.atm.withdraw(
63 card_has_expired=True,
64 pin_is_correct=False,
65 balance_is_enough=True,
66 above_daily_limit=True,
67 ),
68 my_expectation
69 )
70
71 self.assertEqual(
72 src.atm.withdraw(
73 card_has_expired=True,
74 pin_is_correct=False,
75 balance_is_enough=True,
76 above_daily_limit=False,
77 ),
78 my_expectation
79 )
80
81 self.assertEqual(
82 src.atm.withdraw(
83 card_has_expired=True,
84 pin_is_correct=False,
85 balance_is_enough=False,
86 above_daily_limit=True,
87 ),
88 my_expectation
89 )
90
91 self.assertEqual(
92 src.atm.withdraw(
93 card_has_expired=True,
94 pin_is_correct=False,
95 balance_is_enough=False,
96 above_daily_limit=False
97 ),
98 my_expectation
99 )
100
101 self.assertEqual(
102 src.atm.withdraw(
103 card_has_expired=False,
104 pin_is_correct=True,
105 balance_is_enough=True,
106 above_daily_limit=True,
107 ),
108 my_expectation
109 )
110
111 self.assertEqual(
112 src.atm.withdraw(
113 card_has_expired=False,
114 pin_is_correct=True,
115 balance_is_enough=False,
116 above_daily_limit=True,
117 ),
118 my_expectation
119 )
120
121 self.assertEqual(
122 src.atm.withdraw(
123 card_has_expired=False,
124 pin_is_correct=True,
125 balance_is_enough=False,
126 above_daily_limit=False,
127 ),
128 my_expectation
129 )
130
131 self.assertEqual(
132 src.atm.withdraw(
133 card_has_expired=False,
134 pin_is_correct=False,
135 balance_is_enough=True,
136 above_daily_limit=True,
137 ),
138 my_expectation
139 )
140
141 self.assertEqual(
142 src.atm.withdraw(
143 card_has_expired=False,
144 pin_is_correct=False,
145 balance_is_enough=True,
146 above_daily_limit=False,
147 ),
148 my_expectation
149 )
150
151 self.assertEqual(
152 src.atm.withdraw(
153 card_has_expired=False,
154 pin_is_correct=False,
155 balance_is_enough=False,
156 above_daily_limit=True,
157 ),
158 my_expectation
159 )
160
161 self.assertEqual(
162 src.atm.withdraw(
163 card_has_expired=False,
164 pin_is_correct=False,
165 balance_is_enough=False,
166 above_daily_limit=False,
167 ),
168 my_expectation
169 )
170
171
172# Exceptions seen
173# AssertionError
174# NameError
175# AttributeError
176# TypeError
requirements
start the project
I name this project
atmI open a terminal
I make a directory for the project
mkdir atmthe terminal goes back to the command line
I change directory to the project
cd atmthe terminal is my friend, and shows I am in the
atmfolder.../pumping_python/atmI make a directory for the source code
mkdir srcthe terminal goes back to the command line
I make a Python file to hold the source code in the
srcdirectorytouch src/atm.pyNew-Item src/atm.pythe terminal goes back to the command line
I make a directory for the tests
mkdir teststhe terminal goes back to the command line
I make the
testsdirectory a Python packageDanger
use 2 underscores (__) before and after
initfor__init__.pynot_init_.pytouch tests/__init__.pyNew-Item tests/__init__.pythe terminal goes back to the command line
I make a Python file for the tests in the
testsdirectorytouch tests/test_atm.pyNew-Item tests/test_atm.pythe terminal goes back to the command line
I open
test_atm.pyin the editor of the Integrated Development Environment (IDE)Tip
I can open a file from the terminal in the Integrated Development Environment (IDE) with the name of the program and the name of the file. That means if I type this in the terminal
code tests/test_atm.pyVisual Studio Code opens
test_atm.pyin the editorI add the first failing test to
test_atm.py1import unittest 2 3 4class TestATM(unittest.TestCase): 5 6 def test_failure(self): 7 self.assertFalse(True)I make a requirements file for the Python packages I need, in the terminal
echo "pytest" > requirements.txtthe terminal goes back to the command line
I add pytest-watcher to the file
echo "pytest-watcher" >> requirements.txtthe terminal goes back to the command line
I set up the project with uv
uv initthe terminal shows
Initialized project `atm`then goes back to the command line
I remove
main.pyfrom the project because I do not use itrm main.pythe terminal goes back to the command line
I install the Python packages that I wrote in the requirements file
uv add --requirement requirements.txtthe terminal shows that it installed the Python packages
I use pytest-watcher to run the tests automatically
uv run pytest-watcher . --nowthe terminal is my friend, and shows
================================ FAILURES ================================ _________________________ TestATM.test_failure ___________________________ self = <tests.test_atm.TestATM testMethod=test_failure> def test_failure(self): > self.assertFalse(True) E AssertionError: True is not false tests/test_atm.py:7: AssertionError ======================== short test summary info ========================= FAILED tests/test_atm.py::TestATM::test_failure - AssertionError: True is not false =========================== 1 failed in X.YZs ============================I add AssertionError to the list of Exceptions seen in
test_atm.py4class TestATM(unittest.TestCase): 5 6 def test_failure(self): 7 self.assertFalse(True) 8 9 10# Exceptions seen 11# AssertionErrorthen I change True to False in the assertion
7 self.assertFalse(False)the test passes
test_atm_withdrawal
RED: make it fail
I change test_failure to test_atm_withdrawal, then add an assertion for when the right PIN is entered and there is enough money in the account
PIN |
balance |
withdrawal |
|---|---|---|
right PIN |
enough |
CASH |
4class TestATM(unittest.TestCase):
5
6 def test_atm_withdrawal(self):
7 my_expectation = 'CASH'
8 reality = src.atm.withdraw(
9 pin_is_correct=True,
10 balance_is_enough=True,
11 )
12 self.assertEqual(reality, my_expectation)
13
14
15# Exceptions seen
16# AssertionError
the terminal is my friend, and shows NameError
NameError: name 'src' is not defined
GREEN: make it pass
I add NameError to the list of Exceptions seen
15# Exceptions seen 16# AssertionError 17# NameErrorI add an import statement at the top of the file
1import src.atm 2import unittest 3 4 5class TestATM(unittest.TestCase):the terminal is my friend, and shows AttributeError
AttributeError: module 'src.atm' has no attribute 'withdraw'I add AttributeError to the list of Exceptions seen
16# Exceptions seen 17# AssertionError 18# NameError 19# AttributeErrorI add a function to
atm.py1def withdraw(): 2 return Nonethe terminal is my friend, and shows TypeError
TypeError: withdraw() got an unexpected keyword argument 'pin_is_correct'I add TypeError to the list of Exceptions seen in
test_atm.py16# Exceptions seen 17# AssertionError 18# NameError 19# AttributeError 20# TypeErrorI add the keyword argument to the function in
atm.py1def withdraw(pin_is_correct): 2 return Nonethe terminal is my friend, and shows TypeError
TypeError: withdraw() got an unexpected keyword argument 'balance_is_enough'I add
balance_is_enoughto the function signature1def withdraw(pin_is_correct, balance_is_enough): 2 return Nonethe terminal is my friend, and shows AssertionError
AssertionError: None != 'CASH'I change the return statement to give the test what it expects
1def withdraw(pin_is_correct, balance_is_enough): 2 return 'CASH'the test passes. The
withdrawfunction always returns CASH, it does not care about the inputs. Is this Tautology?
REFACTOR: make it better
I add an assertion for when the right PIN is entered AND there is NOT enough money in the account
PIN
balance
withdrawal
right PIN
enough
CASH
right PIN
NOT enough
DENIED
7 def test_atm_withdrawal(self): 8 my_expectation = 'CASH' 9 reality = src.atm.withdraw( 10 pin_is_correct=True, 11 balance_is_enough=True, 12 ) 13 self.assertEqual(reality, my_expectation) 14 15 my_expectation = 'DENIED' 16 reality = src.atm.withdraw( 17 pin_is_correct=True, 18 balance_is_enough=False, 19 ) 20 self.assertEqual(reality, my_expectation) 21 22 23# Exceptions seenthe terminal is my friend, and shows AssertionError
AssertionError: 'CASH' != 'DENIED'I add an if statement to
atm.py1def withdraw(pin_is_correct, balance_is_enough): 2 if pin_is_correct and not balance_is_enough: 3 return 'DENIED' 4 return 'CASH'the test passes
I add an assertion for when the wrong PIN is entered and there is enough money in the account, to
test_atm_withdrawalintest_atm.pyPIN
balance
withdrawal
right PIN
enough
CASH
right PIN
NOT enough
DENIED
wrong PIN
yes
DENIED
the terminal is my friend, and shows AssertionError
AssertionError: 'CASH' != 'DENIED'I add an if statement for this case to
atm.py1def withdraw(pin_is_correct, balance_is_enough): 2 if not pin_is_correct and balance_is_enough: 3 return 'DENIED' 4 if pin_is_correct and not balance_is_enough: 5 return 'DENIED' 6 return 'CASH'the test passes
I add an assertion for the last case - when the wrong PIN is entered and there is NOT enough money left in the account, in
test_atm.pyPIN
balance
withdrawal
right PIN
enough
CASH
right PIN
NOT enough
DENIED
wrong PIN
yes
DENIED
wrong PIN
NOT enough
DENIED
7 def test_atm_withdrawal(self): 8 my_expectation = 'CASH' 9 reality = src.atm.withdraw( 10 pin_is_correct=True, 11 balance_is_enough=True, 12 ) 13 self.assertEqual(reality, my_expectation) 14 15 my_expectation = 'DENIED' 16 reality = src.atm.withdraw( 17 pin_is_correct=True, 18 balance_is_enough=False, 19 ) 20 self.assertEqual(reality, my_expectation) 21 22 my_expectation = 'DENIED' 23 reality = src.atm.withdraw( 24 pin_is_correct=False, 25 balance_is_enough=True, 26 ) 27 self.assertEqual(reality, my_expectation) 28 29 my_expectation = 'DENIED' 30 reality = src.atm.withdraw( 31 pin_is_correct=False, 32 balance_is_enough=False, 33 ) 34 self.assertEqual(reality, my_expectation) 35 36 37# Exceptions seenthe terminal is my friend, and shows AssertionError
AssertionError: 'CASH' != 'DENIED'I add an if statement to
atm.pyfor the last case1def withdraw(pin_is_correct, balance_is_enough): 2 if not pin_is_correct and not balance_is_enough: 3 return 'DENIED' 4 if not pin_is_correct and balance_is_enough: 5 return 'DENIED' 6 if pin_is_correct and not balance_is_enough: 7 return 'DENIED' 8 return 'CASH'the test passes
3 of the cases return
'DENIED'and only one case returns'CASH'. I add an if statement with an else clause for the one case1def withdraw(pin_is_correct, balance_is_enough): 2 if pin_is_correct and balance_is_enough: 3 return 'CASH' 4 else: 5 return 'DENIED' 6 if not pin_is_correct and not balance_is_enough: 7 return 'DENIED' 8 if not pin_is_correct and balance_is_enough: 9 return 'DENIED' 10 if pin_is_correct and not balance_is_enough: 11 return 'DENIED' 12 return 'CASH'the test is still green
I remove the other if statements
1def withdraw(pin_is_correct, balance_is_enough): 2 if pin_is_correct and balance_is_enough: 3 return 'CASH' 4 else: 5 return 'DENIED'still green
I do not need to make the
my_expectationvariable 3 times intest_atm.pysince it is the same value every time. I remove the repetition fromtest_atm.py7 def test_atm_withdrawal(self): 8 my_expectation = 'CASH' 9 reality = src.atm.withdraw( 10 pin_is_correct=True, 11 balance_is_enough=True, 12 ) 13 self.assertEqual(reality, my_expectation) 14 15 my_expectation = 'DENIED' 16 17 reality = src.atm.withdraw( 18 pin_is_correct=True, 19 balance_is_enough=False, 20 ) 21 self.assertEqual(reality, my_expectation) 22 23 reality = src.atm.withdraw( 24 pin_is_correct=False, 25 balance_is_enough=True, 26 ) 27 self.assertEqual(reality, my_expectation) 28 29 reality = src.atm.withdraw( 30 pin_is_correct=False, 31 balance_is_enough=False, 32 ) 33 self.assertEqual(reality, my_expectation) 34 35 36# Exceptions seengreen
test_atm_withdrawal_w_daily_limit
So far, the truth table for the Automatic Teller Machine is
PIN |
balance |
withdrawal |
|---|---|---|
right PIN |
enough |
CASH |
right PIN |
NOT enough |
DENIED |
wrong PIN |
yes |
DENIED |
wrong PIN |
NOT enough |
DENIED |
I want to add a condition for a daily limit on how much can be withdrawn from the account.The inputs for the ATM will then be
is the PIN correct?
is the requested amount smaller or bigger than what is in the account?
will this put the account above or below the daily limit for withdrawals?
the truth table for the ATM will now be
PIN |
balance |
daily limit |
withdrawal |
|---|---|---|---|
right PIN |
enough |
above limit |
DENIED |
right PIN |
enough |
below limit |
CASH |
right PIN |
NOT enough |
above limit |
DENIED |
right PIN |
NOT enough |
below limit |
DENIED |
wrong PIN |
enough |
above limit |
DENIED |
wrong PIN |
enough |
below limit |
DENIED |
wrong PIN |
NOT enough |
above limit |
DENIED |
wrong PIN |
NOT enough |
below limit |
DENIED |
RED: make it fail
I add an assertion for the first case where the right PIN is entered, the account balance is enough and the account is above limit for daily withdrawals, to test_atm_withdrawal in test_atm.py
PIN |
balance |
daily limit |
withdrawal |
|---|---|---|---|
right PIN |
enough |
above limit |
DENIED |
7 def test_atm_withdrawal(self):
8 my_expectation = 'DENIED'
9 reality = src.atm.withdraw(
10 pin_is_correct=True,
11 balance_is_enough=True,
12 above_daily_limit=True,
13 )
14 self.assertEqual(reality, my_expectation)
15
16 my_expectation = 'CASH'
17 reality = src.atm.withdraw(
18 pin_is_correct=True,
19 balance_is_enough=True,
20 )
21 self.assertEqual(reality, my_expectation)
the terminal is my friend, and shows TypeError
TypeError: withdraw() got an unexpected keyword argument 'above_daily_limit'
GREEN: make it pass
I add
above_daily_limitto the function inatm.py1def withdraw( 2 pin_is_correct, balance_is_enough, 3 above_daily_limit, 4 ): 5 if pin_is_correct and balance_is_enough:the terminal is my friend, and shows AssertionError
AssertionError: 'CASH' != 'DENIED'I add an if statement
5 if pin_is_correct and balance_is_enough: 6 if above_daily_limit: 7 return 'DENIED' 8 return 'CASH' 9 else: 10 return 'DENIED'the terminal is my friend, and shows TypeError
TypeError: withdraw() missing 1 required positional argument: 'above_daily_limit'I add a default value for
above_daily_limitto make it a choice1def withdraw( 2 pin_is_correct, balance_is_enough, 3 above_daily_limit=False, 4 ): 5 if pin_is_correct and balance_is_enough: 6 if above_daily_limit: 7 return 'DENIED' 8 return 'CASH' 9 else: 10 return 'DENIED'the test passes.
REFACTOR: make it better
I do not need to add anything to the second assertion in
test_atm_withdrawalbecause the default value for theabove_daily_limitparameter of thewithdrawfunction is FalsePIN
balance
daily limit
withdrawal
right PIN
enough
above limit
DENIED
right PIN
enough
below limit
CASH
this means
reality = src.atm.withdraw( pin_is_correct=True, balance_is_enough=True, )is the same as
reality = src.atm.withdraw( pin_is_correct=True, balance_is_enough=True, above_daily_limit=False, )I add an assertion for the case where the right PIN is entered, the account balance is NOT enough and the account is above limit for daily withdrawals, in
test_atm.pyPIN
balance
daily limit
withdrawal
right PIN
enough
above limit
DENIED
right PIN
enough
below limit
CASH
right PIN
NOT enough
above limit
DENIED
7 def test_atm_withdrawal(self): 8 my_expectation = 'DENIED' 9 reality = src.atm.withdraw( 10 pin_is_correct=True, 11 balance_is_enough=True, 12 above_daily_limit=True, 13 ) 14 self.assertEqual(reality, my_expectation) 15 16 my_expectation = 'CASH' 17 reality = src.atm.withdraw( 18 pin_is_correct=True, 19 balance_is_enough=True, 20 ) 21 self.assertEqual(reality, my_expectation) 22 23 my_expectation = 'DENIED' 24 25 reality = src.atm.withdraw( 26 pin_is_correct=True, 27 balance_is_enough=False, 28 above_daily_limit=True, 29 ) 30 self.assertEqual(reality, my_expectation) 31 32 reality = src.atm.withdraw( 33 pin_is_correct=True, 34 balance_is_enough=False, 35 ) 36 self.assertEqual(reality, my_expectation)the test is still green
I do not need to add anything to the fourth assertion for when the right PIN is entered, the balance is NOT enough and the account is below limit for daily withdrawals, because the default value for the
above_daily_limitparameter of thewithdrawfunction is FalsePIN
balance
daily limit
withdrawal
right PIN
enough
above limit
DENIED
right PIN
enough
below limit
CASH
right PIN
NOT enough
above limit
DENIED
right PIN
NOT enough
below limit
DENIED
this means
reality = src.atm.withdraw( pin_is_correct=True, balance_is_enough=False, )is the same as
reality = src.atm.withdraw( pin_is_correct=True, balance_is_enough=False, above_daily_limit=False, )I add
above_daily_limitto the fifth assertion for the case where the wrong PIN is entered, the account balance is enough and the account is above limit for daily withdrawalsPIN
balance
daily limit
withdrawal
wrong PIN
enough
above limit
DENIED
7 def test_atm_withdrawal(self): 8 my_expectation = 'DENIED' 9 reality = src.atm.withdraw( 10 pin_is_correct=True, 11 balance_is_enough=True, 12 above_daily_limit=True, 13 ) 14 self.assertEqual(reality, my_expectation) 15 16 my_expectation = 'CASH' 17 reality = src.atm.withdraw( 18 pin_is_correct=True, 19 balance_is_enough=True, 20 ) 21 self.assertEqual(reality, my_expectation) 22 23 my_expectation = 'DENIED' 24 25 reality = src.atm.withdraw( 26 pin_is_correct=True, 27 balance_is_enough=False, 28 above_daily_limit=True, 29 ) 30 self.assertEqual(reality, my_expectation) 31 32 reality = src.atm.withdraw( 33 pin_is_correct=True, 34 balance_is_enough=False, 35 ) 36 self.assertEqual(reality, my_expectation) 37 38 reality = src.atm.withdraw( 39 pin_is_correct=False, 40 balance_is_enough=True, 41 above_daily_limit=True, 42 ) 43 self.assertEqual(reality, my_expectation) 44 45 reality = src.atm.withdraw( 46 pin_is_correct=False, 47 balance_is_enough=False, 48 ) 49 self.assertEqual(reality, my_expectation) 50 51 52# Exceptions seenstill green
I do not need to add anything to the sixth assertion for when the wrong PIN is entered, the balance is NOT enough and the account is below limit for daily withdrawals, because the default value for the
above_daily_limitparameter of thewithdrawfunction is FalsePIN
balance
daily limit
withdrawal
wrong PIN
enough
above limit
DENIED
wrong PIN
enough
below limit
DENIED
this means
reality = src.atm.withdraw( pin_is_correct=False, balance_is_enough=False, )is the same as
reality = src.atm.withdraw( pin_is_correct=False, balance_is_enough=False, above_daily_limit=False, )I add an assertion for the when the wrong PIN is entered, the balance is NOT enough and the account is above limit for daily withdrawals
PIN
balance
daily limit
withdrawal
wrong PIN
enough
above limit
DENIED
wrong PIN
enough
below limit
DENIED
wrong PIN
NOT enough
above limit
DENIED
38 reality = src.atm.withdraw( 39 pin_is_correct=False, 40 balance_is_enough=True, 41 above_daily_limit=True, 42 ) 43 self.assertEqual(reality, my_expectation) 44 45 reality = src.atm.withdraw( 46 pin_is_correct=False, 47 balance_is_enough=False, 48 ) 49 self.assertEqual(reality, my_expectation) 50 51 reality = src.atm.withdraw( 52 pin_is_correct=False, 53 balance_is_enough=False, 54 above_daily_limit=True 55 ) 56 self.assertEqual(reality, my_expectation) 57 58 59# Exceptions seengreen
I add an assertion for when the wrong PIN is entered, the balance is NOT enough and the account is below limit for daily withdrawals
PIN
balance
daily limit
withdrawal
wrong PIN
enough
above limit
DENIED
wrong PIN
enough
below limit
DENIED
wrong PIN
NOT enough
above limit
DENIED
wrong PIN
NOT enough
below limit
DENIED
51 reality = src.atm.withdraw( 52 pin_is_correct=False, 53 balance_is_enough=False, 54 above_daily_limit=True 55 ) 56 self.assertEqual(reality, my_expectation) 57 58 reality = src.atm.withdraw( 59 pin_is_correct=False, 60 balance_is_enough=False, 61 ) 62 self.assertEqual(reality, my_expectation) 63 64 65# Exceptions seenstill green
I move the assertion for the one case where the ATM gives cash, to the top and remove the second
my_expectationvariable7 def test_atm_withdrawal(self): 8 my_expectation = 'CASH' 9 reality = src.atm.withdraw( 10 pin_is_correct=True, 11 balance_is_enough=True, 12 ) 13 self.assertEqual(reality, my_expectation) 14 15 my_expectation = 'DENIED' 16 17 reality = src.atm.withdraw( 18 pin_is_correct=True, 19 balance_is_enough=True, 20 above_daily_limit=True, 21 ) 22 self.assertEqual(reality, my_expectation) 23 24 reality = src.atm.withdraw( 25 pin_is_correct=True, 26 balance_is_enough=False, 27 above_daily_limit=True, 28 ) 29 self.assertEqual(reality, my_expectation) 30 31 reality = src.atm.withdraw( 32 pin_is_correct=True, 33 balance_is_enough=False, 34 ) 35 self.assertEqual(reality, my_expectation) 36 37 reality = src.atm.withdraw( 38 pin_is_correct=False, 39 balance_is_enough=True, 40 above_daily_limit=True, 41 ) 42 self.assertEqual(reality, my_expectation) 43 44 reality = src.atm.withdraw( 45 pin_is_correct=False, 46 balance_is_enough=False, 47 ) 48 self.assertEqual(reality, my_expectation) 49 50 reality = src.atm.withdraw( 51 pin_is_correct=False, 52 balance_is_enough=False, 53 above_daily_limit=True 54 ) 55 self.assertEqual(reality, my_expectation) 56 57 reality = src.atm.withdraw( 58 pin_is_correct=False, 59 balance_is_enough=False, 60 ) 61 self.assertEqual(reality, my_expectation) 62 63 64# Exceptions seenThere is only one case where the
withdrawfunction returns'CASH'. I add if statements for the other cases toatm.py1def withdraw( 2 pin_is_correct, balance_is_enough, 3 above_daily_limit=False, 4 ): 5 denial = 'DENIED' 6 7 if not pin_is_correct: 8 return denial 9 if not balance_is_enough: 10 return denial 11 if above_daily_limit: 12 return denial 13 14 if pin_is_correct and balance_is_enough: 15 if above_daily_limit: 16 return 'DENIED' 17 return 'CASH' 18 else: 19 return 'DENIED'the test is still green.
The ATM
denies a withdrawal if the wrong PIN is entered because you cannot enter the system
denies a withdrawal if the account balance is NOT enough. This only happens if the right PIN is entered.
denies a withdrawal if the account is above limit for the daily withdrawal limit. This only happens if the account balance is enough.
I add a return statement for the one case where the withdrawal is allowed
1def withdraw( 2 pin_is_correct, balance_is_enough, 3 above_daily_limit=False, 4 ): 5 denial = 'DENIED' 6 7 if not pin_is_correct: 8 return denial 9 if not balance_is_enough: 10 return denial 11 if above_daily_limit: 12 return denial 13 return 'CASH' 14 15 if pin_is_correct and balance_is_enough: 16 if above_daily_limit: 17 return 'DENIED' 18 return 'CASH' 19 else: 20 return 'DENIED'still green.
The ATM
denies a withdrawal if the wrong PIN is entered because you cannot enter the system
denies a withdrawal if the account balance is NOT enough. This only happens if the right PIN is entered.
denies a withdrawal if the account is above limit for the daily withdrawal limit. This only happens if the account balance is enough.
approves a withdrawal only if the right PIN is entered and the balance is enough and the account is below limit for daily withdrawals
I remove the other statements
1def withdraw( 2 pin_is_correct, balance_is_enough, 3 above_daily_limit=False, 4 ): 5 denial = 'DENIED' 6 7 if not pin_is_correct: 8 return denial 9 if not balance_is_enough: 10 return denial 11 if above_daily_limit: 12 return denial 13 return 'CASH'
test_atm_withdrawal_w_expired_bank_card
The truth table for the Automatic Teller Machine is now
PIN |
balance |
daily limit |
withdrawal |
|---|---|---|---|
right PIN |
enough |
above limit |
DENIED |
right PIN |
enough |
below limit |
CASH |
right PIN |
NOT enough |
above limit |
DENIED |
right PIN |
NOT enough |
below limit |
DENIED |
wrong PIN |
enough |
above limit |
DENIED |
wrong PIN |
enough |
below limit |
DENIED |
wrong PIN |
NOT enough |
above limit |
DENIED |
wrong PIN |
NOT enough |
below limit |
DENIED |
I want to add a condition for when the bank card is expired.The inputs for the ATM will then be
has the card expired?
is the PIN correct?
is the requested amount smaller or bigger than what is in the account?
will this put the account above or below the daily limit for withdrawals?
the truth table for the ATM will now be
card expired |
PIN |
balance |
daily limit |
withdrawal |
|---|---|---|---|---|
expired |
right PIN |
enough |
above limit |
DENIED |
expired |
right PIN |
enough |
below limit |
DENIED |
expired |
right PIN |
NOT enough |
above limit |
DENIED |
expired |
right PIN |
NOT enough |
below limit |
DENIED |
expired |
wrong PIN |
enough |
above limit |
DENIED |
expired |
wrong PIN |
enough |
below limit |
DENIED |
expired |
wrong PIN |
NOT enough |
above limit |
DENIED |
expired |
wrong PIN |
NOT enough |
below limit |
DENIED |
NOT expired |
right PIN |
enough |
above limit |
DENIED |
NOT expired |
right PIN |
enough |
below limit |
CASH |
NOT expired |
right PIN |
NOT enough |
above limit |
DENIED |
NOT expired |
right PIN |
NOT enough |
below limit |
DENIED |
NOT expired |
wrong PIN |
enough |
above limit |
DENIED |
NOT expired |
wrong PIN |
enough |
below limit |
DENIED |
NOT expired |
wrong PIN |
NOT enough |
above limit |
DENIED |
NOT expired |
wrong PIN |
NOT enough |
below limit |
DENIED |
RED: make it fail
I add a value for the card_expired parameter to the call to the withdraw function for the case where the card has expired, the right PIN is entered, the account balance is enough and the account is above limit for daily withdrawals, in test_atm_withdrawal in test_atm.py
card expired |
PIN |
balance |
daily limit |
withdrawal |
|---|---|---|---|---|
expired |
right PIN |
enough |
above limit |
DENIED |
7 def test_atm_withdrawal(self):
8 my_expectation = 'CASH'
9 reality = src.atm.withdraw(
10 pin_is_correct=True,
11 balance_is_enough=True,
12 )
13 self.assertEqual(reality, my_expectation)
14
15 my_expectation = 'DENIED'
16
17 reality = src.atm.withdraw(
18 card_has_expired=True,
19 pin_is_correct=True,
20 balance_is_enough=True,
21 above_daily_limit=True,
22 )
23 self.assertEqual(reality, my_expectation)
the terminal is my friend, and shows TypeError
TypeError: withdraw() got an unexpected keyword argument 'card_has_expired'
GREEN: make it pass
I add
card_has_expiredto the function signature inatm.py1def withdraw( 2 pin_is_correct, balance_is_enough, 3 above_daily_limit=False, card_has_expired, 4 ):the terminal is my friend, and shows SyntaxError
SyntaxError: parameter without a default follows parameter with a defaultI add a default value for
card_has_expired1def withdraw( 2 pin_is_correct, balance_is_enough, 3 above_daily_limit=False, card_has_expired=False, 4 ):the test passes
REFACTOR: make it better
I add an assertion for when the card has expired, the right PIN is entered, the account balance is enough and the account is below limit for daily withdrawals, to
test_atm_withdrawalintest_atm.pycard expired
PIN
balance
daily limit
withdrawal
expired
right PIN
enough
above limit
DENIED
expired
right PIN
enough
below limit
DENIED
7 def test_atm_withdrawal(self): 8 my_expectation = 'CASH' 9 reality = src.atm.withdraw( 10 pin_is_correct=True, 11 balance_is_enough=True, 12 ) 13 self.assertEqual(reality, my_expectation) 14 15 my_expectation = 'DENIED' 16 17 reality = src.atm.withdraw( 18 card_has_expired=True, 19 pin_is_correct=True, 20 balance_is_enough=True, 21 above_daily_limit=True, 22 ) 23 self.assertEqual(reality, my_expectation) 24 25 reality = src.atm.withdraw( 26 card_has_expired=True, 27 pin_is_correct=True, 28 balance_is_enough=True, 29 above_daily_limit=False, 30 ) 31 self.assertEqual(reality, my_expectation)the terminal is my friend, and shows AssertionError
AssertionError: 'CASH' != 'DENIED'I add an if statement to the
withdrawfunction inatm.py1def withdraw( 2 pin_is_correct, balance_is_enough, 3 above_daily_limit=False, card_has_expired=False, 4 ): 5 denial = 'DENIED' 6 7 if card_has_expired: 8 return denial 9 if not pin_is_correct: 10 return denial 11 if not balance_is_enough: 12 return denial 13 if above_daily_limit: 14 return denial 15 return 'CASH'the test passes. the ATM
denies a withdrawal if the card has expired, it will NOT check the PIN.
denies a withdrawal if the wrong PIN is entered because you cannot enter the system.
denies a withdrawal if the account balance is NOT enough. This only happens if the right PIN is entered.
denies a withdrawal if the account is above limit for the daily withdrawal limit. This only happens if the account balance is enough.
approves a withdrawal only if the card has NOT expired, the right PIN is entered, the balance is enough and the account is below limit for daily withdrawals
I add
card_has_expiredto the fourth assertion, which is for when the card has expired, the right PIN is entered, the balance is NOT enough and the account is above limit for daily withdrawalscard expired
PIN
balance
daily limit
withdrawal
expired
right PIN
enough
above limit
DENIED
expired
right PIN
enough
below limit
DENIED
expired
right PIN
NOT enough
above limit
DENIED
7 def test_atm_withdrawal(self): 8 my_expectation = 'CASH' 9 reality = src.atm.withdraw( 10 pin_is_correct=True, 11 balance_is_enough=True, 12 ) 13 self.assertEqual(reality, my_expectation) 14 15 my_expectation = 'DENIED' 16 17 reality = src.atm.withdraw( 18 card_has_expired=True, 19 pin_is_correct=True, 20 balance_is_enough=True, 21 above_daily_limit=True, 22 ) 23 self.assertEqual(reality, my_expectation) 24 25 reality = src.atm.withdraw( 26 card_has_expired=True, 27 pin_is_correct=True, 28 balance_is_enough=True, 29 above_daily_limit=False, 30 ) 31 self.assertEqual(reality, my_expectation) 32 33 reality = src.atm.withdraw( 34 card_has_expired=True, 35 pin_is_correct=True, 36 balance_is_enough=False, 37 above_daily_limit=True, 38 ) 39 self.assertEqual(reality, my_expectation)the test is still green
I add
card_has_expiredto the fifth assertion, I also addabove_daily_limitto be clearer. This is for the case where the card has expired, the right PIN is entered, the balance is NOT enough and the account is below limit for daily withdrawalscard expired
PIN
balance
daily limit
withdrawal
expired
right PIN
enough
above limit
DENIED
expired
right PIN
enough
below limit
DENIED
expired
right PIN
NOT enough
above limit
DENIED
expired
right PIN
NOT enough
below limit
DENIED
33 reality = src.atm.withdraw( 34 card_has_expired=True, 35 pin_is_correct=True, 36 balance_is_enough=False, 37 above_daily_limit=True, 38 ) 39 self.assertEqual(reality, my_expectation) 40 41 reality = src.atm.withdraw( 42 card_has_expired=True, 43 pin_is_correct=True, 44 balance_is_enough=False, 45 above_daily_limit=False, 46 ) 47 self.assertEqual(reality, my_expectation) 48 49 reality = src.atm.withdraw( 50 pin_is_correct=False, 51 balance_is_enough=True, 52 above_daily_limit=True, 53 ) 54 self.assertEqual(reality, my_expectation)still green
I add
card_has_expiredto the next assertion, for the case where the card has expired, the wrong PIN is entered, the balance is enough and the account is above limit for daily withdrawalscard expired
PIN
balance
daily limit
withdrawal
expired
wrong PIN
enough
above limit
DENIED
41 reality = src.atm.withdraw( 42 card_has_expired=True, 43 pin_is_correct=True, 44 balance_is_enough=False, 45 above_daily_limit=False, 46 ) 47 self.assertEqual(reality, my_expectation) 48 49 reality = src.atm.withdraw( 50 card_has_expired=True, 51 pin_is_correct=False, 52 balance_is_enough=True, 53 above_daily_limit=True, 54 ) 55 self.assertEqual(reality, my_expectation) 56 57 reality = src.atm.withdraw( 58 pin_is_correct=False, 59 balance_is_enough=False, 60 ) 61 self.assertEqual(reality, my_expectation)green
I add an assertion for the case where the card has expired, the wrong PIN is entered, the balance is enough and the account is below limit for daily withdrawals
card expired
PIN
balance
daily limit
withdrawal
expired
wrong PIN
enough
above limit
DENIED
expired
wrong PIN
enough
below limit
DENIED
41 reality = src.atm.withdraw( 42 card_has_expired=True, 43 pin_is_correct=False, 44 balance_is_enough=True, 45 above_daily_limit=True, 46 ) 47 self.assertEqual(reality, my_expectation) 48 49 reality = src.atm.withdraw( 50 card_has_expired=True, 51 pin_is_correct=False, 52 balance_is_enough=True, 53 above_daily_limit=False, 54 ) 55 self.assertEqual(reality, my_expectation) 56 57 reality = src.atm.withdraw( 58 pin_is_correct=False, 59 balance_is_enough=False, 60 ) 61 self.assertEqual(reality, my_expectation)still green
I add
card_has_expiredandabove_daily_limitto the next assertion, which is for when the card has expired, the wrong PIN is entered, the balance is NOT enough and the account is above limit for daily withdrawalscard expired
PIN
balance
daily limit
withdrawal
expired
wrong PIN
enough
above limit
DENIED
expired
wrong PIN
enough
below limit
DENIED
expired
wrong PIN
NOT enough
above limit
DENIED
57 reality = src.atm.withdraw( 58 card_has_expired=True, 59 pin_is_correct=False, 60 balance_is_enough=True, 61 above_daily_limit=False, 62 ) 63 self.assertEqual(reality, my_expectation) 64 65 reality = src.atm.withdraw( 66 card_has_expired=True, 67 pin_is_correct=False, 68 balance_is_enough=False, 69 above_daily_limit=True 70 ) 71 self.assertEqual(reality, my_expectation) 72 73 reality = src.atm.withdraw( 74 pin_is_correct=False, 75 balance_is_enough=False, 76 above_daily_limit=True 77 ) 78 self.assertEqual(reality, my_expectation)the test is still green
I change the next assertion to be for when the card has expired, the wrong PIN is entered, the balance is NOT enough and the account is below limit for daily withdrawals
card expired
PIN
balance
daily limit
withdrawal
expired
wrong PIN
enough
above limit
DENIED
expired
wrong PIN
enough
below limit
DENIED
expired
wrong PIN
NOT enough
above limit
DENIED
expired
wrong PIN
NOT enough
below limit
DENIED
49 reality = src.atm.withdraw( 50 card_has_expired=True, 51 pin_is_correct=False, 52 balance_is_enough=True, 53 above_daily_limit=True, 54 ) 55 self.assertEqual(reality, my_expectation) 56 57 reality = src.atm.withdraw( 58 card_has_expired=True, 59 pin_is_correct=False, 60 balance_is_enough=True, 61 above_daily_limit=False, 62 ) 63 self.assertEqual(reality, my_expectation) 64 65 reality = src.atm.withdraw( 66 card_has_expired=True, 67 pin_is_correct=False, 68 balance_is_enough=False, 69 above_daily_limit=True, 70 ) 71 self.assertEqual(reality, my_expectation) 72 73 reality = src.atm.withdraw( 74 card_has_expired=True, 75 pin_is_correct=False, 76 balance_is_enough=False, 77 above_daily_limit=False 78 ) 79 self.assertEqual(reality, my_expectation) 80 81 reality = src.atm.withdraw( 82 pin_is_correct=False, 83 balance_is_enough=False, 84 ) 85 self.assertEqual(reality, my_expectation)still green
I change the last assertion to be for when the card has NOT expired, the right PIN is entered, the balance is enough and the account is above limit for daily withdrawals
card expired
PIN
balance
daily limit
withdrawal
NOT expired
right PIN
enough
above limit
DENIED
73 reality = src.atm.withdraw( 74 card_has_expired=True, 75 pin_is_correct=False, 76 balance_is_enough=False, 77 above_daily_limit=False 78 ) 79 self.assertEqual(reality, my_expectation) 80 81 reality = src.atm.withdraw( 82 card_has_expired=False, 83 pin_is_correct=True, 84 balance_is_enough=True, 85 above_daily_limit=True, 86 ) 87 self.assertEqual(reality, my_expectation) 88 89 90# Exceptionsgreen
I go back to the first assertion to add the
card_has_expiredandabove_daily_limitparameters. This is the one case where the ATM gives cash - when the card has NOT expired, the right PIN is entered, the balance is enough and the account is below limit for daily withdrawalscard expired
PIN
balance
daily limit
withdrawal
NOT expired
right PIN
enough
above limit
DENIED
NOT expired
right PIN
enough
below limit
CASH
7 def test_atm_withdrawal(self): 8 my_expectation = 'CASH' 9 reality = src.atm.withdraw( 10 card_has_expired=False, 11 pin_is_correct=True, 12 balance_is_enough=True, 13 above_daily_limit=False, 14 ) 15 self.assertEqual(reality, my_expectation)still green
I add an assertion for the case where the card has NOT expired, the right PIN is entered, the balance is NOT enough and the account is above limit for daily withdrawals
card expired
PIN
balance
daily limit
withdrawal
NOT expired
right PIN
enough
above limit
DENIED
NOT expired
right PIN
enough
below limit
CASH
NOT expired
right PIN
NOT enough
above limit
DENIED
75 reality = src.atm.withdraw( 76 card_has_expired=True, 77 pin_is_correct=False, 78 balance_is_enough=False, 79 above_daily_limit=False 80 ) 81 self.assertEqual(reality, my_expectation) 82 83 reality = src.atm.withdraw( 84 card_has_expired=False, 85 pin_is_correct=True, 86 balance_is_enough=True, 87 above_daily_limit=True, 88 ) 89 self.assertEqual(reality, my_expectation) 90 91 reality = src.atm.withdraw( 92 card_has_expired=False, 93 pin_is_correct=True, 94 balance_is_enough=False, 95 above_daily_limit=True, 96 ) 97 self.assertEqual(reality, my_expectation) 98 99 100# Exceptions seenthe test is still green
I add an assertion for when the card has NOT expired, the right PIN is entered, the balance is NOT enough and the account is below limit for daily withdrawals
card expired
PIN
balance
daily limit
withdrawal
NOT expired
right PIN
enough
above limit
DENIED
NOT expired
right PIN
enough
below limit
CASH
NOT expired
right PIN
NOT enough
above limit
DENIED
NOT expired
right PIN
NOT enough
below limit
DENIED
83 reality = src.atm.withdraw( 84 card_has_expired=False, 85 pin_is_correct=True, 86 balance_is_enough=True, 87 above_daily_limit=True, 88 ) 89 self.assertEqual(reality, my_expectation) 90 91 reality = src.atm.withdraw( 92 card_has_expired=False, 93 pin_is_correct=True, 94 balance_is_enough=False, 95 above_daily_limit=True, 96 ) 97 self.assertEqual(reality, my_expectation) 98 99 reality = src.atm.withdraw( 100 card_has_expired=False, 101 pin_is_correct=True, 102 balance_is_enough=False, 103 above_daily_limit=False, 104 ) 105 self.assertEqual(reality, my_expectation) 106 107 108# Exceptions seenstill green
I add an assertion for when the card has NOT expired, the wrong PIN is entered, the balance is enough and the account is above limit for daily withdrawals
card expired
PIN
balance
daily limit
withdrawal
NOT expired
wrong PIN
enough
above limit
DENIED
99 reality = src.atm.withdraw( 100 card_has_expired=False, 101 pin_is_correct=True, 102 balance_is_enough=False, 103 above_daily_limit=False, 104 ) 105 self.assertEqual(reality, my_expectation) 106 107 reality = src.atm.withdraw( 108 card_has_expired=False, 109 pin_is_correct=False, 110 balance_is_enough=True, 111 above_daily_limit=True, 112 ) 113 self.assertEqual(reality, my_expectation) 114 115 116# Exceptions seengreen
I add the next assertion, where the card has NOT expired, the wrong PIN is entered, the balance is enough and the account is below limit for daily withdrawals
card expired
PIN
balance
daily limit
withdrawal
NOT expired
wrong PIN
enough
above limit
DENIED
NOT expired
wrong PIN
enough
below limit
DENIED
107 reality = src.atm.withdraw( 108 card_has_expired=False, 109 pin_is_correct=False, 110 balance_is_enough=True, 111 above_daily_limit=True, 112 ) 113 self.assertEqual(reality, my_expectation) 114 115 reality = src.atm.withdraw( 116 card_has_expired=False, 117 pin_is_correct=False, 118 balance_is_enough=True, 119 above_daily_limit=False, 120 ) 121 self.assertEqual(reality, my_expectation) 122 123 124# Exceptions seenstill green
I add an assertion for when the card has NOT expired, the wrong PIN is entered, the balance is NOT enough and the account is above limit for daily withdrawals
card expired
PIN
balance
daily limit
withdrawal
NOT expired
wrong PIN
enough
above limit
DENIED
NOT expired
wrong PIN
enough
below limit
DENIED
NOT expired
wrong PIN
NOT enough
above limit
DENIED
107 reality = src.atm.withdraw( 108 card_has_expired=False, 109 pin_is_correct=False, 110 balance_is_enough=True, 111 above_daily_limit=True, 112 ) 113 self.assertEqual(reality, my_expectation) 114 115 reality = src.atm.withdraw( 116 card_has_expired=False, 117 pin_is_correct=False, 118 balance_is_enough=True, 119 above_daily_limit=False, 120 ) 121 self.assertEqual(reality, my_expectation) 122 123 reality = src.atm.withdraw( 124 card_has_expired=False, 125 pin_is_correct=False, 126 balance_is_enough=False, 127 above_daily_limit=True, 128 ) 129 self.assertEqual(reality, my_expectation) 130 131 132# Exceptions seenthe test is still green
I add an assertion for when the card has NOT expired, the wrong PIN is entered, the balance is NOT enough and the account is below limit for daily withdrawals
card expired
PIN
balance
daily limit
withdrawal
NOT expired
wrong PIN
enough
above limit
DENIED
NOT expired
wrong PIN
enough
below limit
DENIED
NOT expired
wrong PIN
NOT enough
above limit
DENIED
NOT expired
wrong PIN
NOT enough
below limit
DENIED
107 reality = src.atm.withdraw( 108 card_has_expired=False, 109 pin_is_correct=False, 110 balance_is_enough=True, 111 above_daily_limit=True, 112 ) 113 self.assertEqual(reality, my_expectation) 114 115 reality = src.atm.withdraw( 116 card_has_expired=False, 117 pin_is_correct=False, 118 balance_is_enough=True, 119 above_daily_limit=False, 120 ) 121 self.assertEqual(reality, my_expectation) 122 123 reality = src.atm.withdraw( 124 card_has_expired=False, 125 pin_is_correct=False, 126 balance_is_enough=False, 127 above_daily_limit=True, 128 ) 129 self.assertEqual(reality, my_expectation) 130 131 reality = src.atm.withdraw( 132 card_has_expired=False, 133 pin_is_correct=False, 134 balance_is_enough=False, 135 above_daily_limit=False, 136 ) 137 self.assertEqual(reality, my_expectation) 138 139 140# Exceptions seenstill green
I remove the
realityvariables because I do not need them, I can call theshowfunction directlydef test_atm_withdrawal(self): my_expectation = 'CASH' self.assertEqual( src.atm.withdraw( card_has_expired=False, pin_is_correct=True, balance_is_enough=True, above_daily_limit=False, ), my_expectation ) my_expectation = 'DENIED' self.assertEqual( src.atm.withdraw( card_has_expired=True, pin_is_correct=True, balance_is_enough=True, above_daily_limit=True, ), my_expectation ) self.assertEqual( src.atm.withdraw( card_has_expired=True, pin_is_correct=True, balance_is_enough=True, above_daily_limit=False, ), my_expectation ) self.assertEqual( src.atm.withdraw( card_has_expired=True, pin_is_correct=True, balance_is_enough=False, above_daily_limit=True, ), my_expectation ) self.assertEqual( src.atm.withdraw( card_has_expired=True, pin_is_correct=True, balance_is_enough=False, above_daily_limit=False, ), my_expectation ) self.assertEqual( src.atm.withdraw( card_has_expired=True, pin_is_correct=False, balance_is_enough=True, above_daily_limit=True, ), my_expectation ) self.assertEqual( src.atm.withdraw( card_has_expired=True, pin_is_correct=False, balance_is_enough=True, above_daily_limit=False, ), my_expectation ) self.assertEqual( src.atm.withdraw( card_has_expired=True, pin_is_correct=False, balance_is_enough=False, above_daily_limit=True, ), my_expectation ) self.assertEqual( src.atm.withdraw( card_has_expired=True, pin_is_correct=False, balance_is_enough=False, above_daily_limit=False ), my_expectation ) self.assertEqual( src.atm.withdraw( card_has_expired=False, pin_is_correct=True, balance_is_enough=True, above_daily_limit=True, ), my_expectation ) self.assertEqual( src.atm.withdraw( card_has_expired=False, pin_is_correct=True, balance_is_enough=False, above_daily_limit=True, ), my_expectation ) self.assertEqual( src.atm.withdraw( card_has_expired=False, pin_is_correct=True, balance_is_enough=False, above_daily_limit=False, ), my_expectation ) self.assertEqual( src.atm.withdraw( card_has_expired=False, pin_is_correct=False, balance_is_enough=True, above_daily_limit=True, ), my_expectation ) self.assertEqual( src.atm.withdraw( card_has_expired=False, pin_is_correct=False, balance_is_enough=True, above_daily_limit=False, ), my_expectation ) self.assertEqual( src.atm.withdraw( card_has_expired=False, pin_is_correct=False, balance_is_enough=False, above_daily_limit=True, ), my_expectation ) self.assertEqual( src.atm.withdraw( card_has_expired=False, pin_is_correct=False, balance_is_enough=False, above_daily_limit=False, ), my_expectation ) # Exceptions seen
close the project
I close
test_atm.pyandatm.pyin the editorI click in the terminal, then use q on the keyboard to leave the tests. The terminal goes back to the command line
I change directory to the parent of
atmcd ..the terminal is my friend, and shows
.../pumping_pythonI am back in the
pumping_pythondirectory
review
I ran tests for an Automatic Teller Machine with the following inputs:
has the card expired?
is the PIN correct?
is the requested amount smaller or bigger than what is in the account?
will this put the account above or below the daily limit for withdrawals?
the inputs gave me this truth table
card expired |
PIN |
balance |
daily limit |
withdrawal |
|---|---|---|---|---|
expired |
right PIN |
enough |
above limit |
DENIED |
expired |
right PIN |
enough |
below limit |
DENIED |
expired |
right PIN |
NOT enough |
above limit |
DENIED |
expired |
right PIN |
NOT enough |
below limit |
DENIED |
expired |
wrong PIN |
enough |
above limit |
DENIED |
expired |
wrong PIN |
enough |
below limit |
DENIED |
expired |
wrong PIN |
NOT enough |
above limit |
DENIED |
expired |
wrong PIN |
NOT enough |
below limit |
DENIED |
card expired |
PIN |
balance |
daily limit |
withdrawal |
|---|---|---|---|---|
NOT expired |
right PIN |
enough |
above limit |
DENIED |
NOT expired |
right PIN |
enough |
below limit |
CASH |
NOT expired |
right PIN |
NOT enough |
above limit |
DENIED |
NOT expired |
right PIN |
NOT enough |
below limit |
DENIED |
NOT expired |
wrong PIN |
enough |
above limit |
DENIED |
NOT expired |
wrong PIN |
enough |
below limit |
DENIED |
NOT expired |
wrong PIN |
NOT enough |
above limit |
DENIED |
NOT expired |
wrong PIN |
NOT enough |
below limit |
DENIED |
What if I want the ATM to give a different message with each denial, so that the user knows why the withdrawal failed? The truth table could then be
card expired |
PIN |
balance |
daily limit |
withdrawal |
|---|---|---|---|---|
expired |
right PIN |
enough |
above limit |
DENIED: Card Expired |
expired |
right PIN |
enough |
below limit |
DENIED: Card Expired |
expired |
right PIN |
NOT enough |
above limit |
DENIED: Card Expired |
expired |
right PIN |
NOT enough |
below limit |
DENIED: Card Expired |
expired |
wrong PIN |
enough |
above limit |
DENIED: Card Expired |
expired |
wrong PIN |
enough |
below limit |
DENIED: Card Expired |
expired |
wrong PIN |
NOT enough |
above limit |
DENIED: Card Expired |
expired |
wrong PIN |
NOT enough |
below limit |
DENIED: Card Expired |
card expired |
PIN |
balance |
daily limit |
withdrawal |
|---|---|---|---|---|
NOT expired |
right PIN |
enough |
above limit |
DENIED: You have exceeded the daily withdrawal Limit |
NOT expired |
right PIN |
enough |
below limit |
CASH |
NOT expired |
right PIN |
NOT enough |
above limit |
DENIED: There is not enough money in the account to complete the withdrawal |
NOT expired |
right PIN |
NOT enough |
below limit |
DENIED: There is not enough money in the account to complete the withdrawal |
NOT expired |
wrong PIN |
enough |
above limit |
Error: You entered the wrong PIN. Try again |
NOT expired |
wrong PIN |
enough |
below limit |
Error: You entered the wrong PIN. Try again |
NOT expired |
wrong PIN |
NOT enough |
above limit |
Error: You entered the wrong PIN. Try again |
NOT expired |
wrong PIN |
NOT enough |
below limit |
Error: You entered the wrong PIN. Try again |
code from the chapter
what is next?
you now know
rate pumping python
If this has been a 7 star experience for you, please CLICK HERE to leave a 5 star review of pumping python. It helps other people get into the book too