Automated Teller Machine: tests and solutions


makePythonTdd ATM

The code in makePythonTdd.sh from Automated Teller Machine

 1#!/bin/bash
 2uv init atm
 3cd atm
 4mkdir tests
 5touch tests/__init__.py
 6
 7echo "import unittest
 8
 9
10class TestATM(unittest.TestCase):
11
12    def test_failure(self):
13        self.assertFalse(True)
14
15
16# Exceptions seen
17# AssertionError
18" > tests/test_atm.py
19
20echo "pytest" > requirements.txt
21echo "pytest-watcher" >> requirements.txt
22uv add --requirement requirements.txt
23uv run pytest-watcher . --now

The code in makePythonTdd.ps1 from Automated Teller Machine

 1uv init atm
 2cd atm
 3New-Item "src/atm.py"
 4mkdir tests
 5New-Item tests/__init__.py
 6
 7"import unittest
 8
 9
10class TestATM(unittest.TestCase):
11
12    def test_failure(self):
13        self.assertFalse(True)
14
15
16# Exceptions seen
17# AssertionError
18" | Out-File "tests/test_atm.py" -Encoding UTF8
19
20"pytest" | Out-File requirements.txt -Encoding UTF8
21"pytest-watcher" >> requirements.txt
22uv add --requirement requirements.txt
23uv run pytest-watcher . --now

Automated Teller Machine: tests

The code in atm/tests/test_atm.py from Automated Teller Machine

atm/tests/test_atm.py
 1import src.atm
 2import unittest
 3
 4
 5DENIED = 'DENIED'
 6
 7
 8class TestATM(unittest.TestCase):
 9
10    def test_card_w_below_limit_right_pin_enough_cash(self):
11        self.assertEqual(
12            src.atm.withdraw(
13                right_pin=True,
14                enough_cash=True,
15                above_daily_limit=False,
16                card_expired=False,
17            ),
18            'CASH'
19        )
20        self.assertEqual(
21            src.atm.withdraw(
22                right_pin=True,
23                enough_cash=True,
24                above_daily_limit=False,
25                card_expired=True,
26            ),
27            DENIED
28        )
atm/tests/test_atm.py
30    def test_card_w_above_limit_right_pin_enough_cash(self):
31        self.assertEqual(
32            src.atm.withdraw(
33                right_pin=True,
34                enough_cash=True,
35                above_daily_limit=True,
36                card_expired=True,
37            ),
38            DENIED
39        )
40        self.assertEqual(
41            src.atm.withdraw(
42                right_pin=True,
43                enough_cash=True,
44                above_daily_limit=True,
45                card_expired=False,
46            ),
47            DENIED
48        )
atm/tests/test_atm.py
50    def test_card_w_above_limit_right_pin_not_enough_cash(self):
51        self.assertEqual(
52            src.atm.withdraw(
53                right_pin=True,
54                enough_cash=False,
55                above_daily_limit=True,
56                card_expired=True,
57            ),
58            DENIED
59        )
60        self.assertEqual(
61            src.atm.withdraw(
62                right_pin=True,
63                enough_cash=False,
64                above_daily_limit=True,
65                card_expired=False,
66            ),
67            DENIED
68        )
atm/tests/test_atm.py
70    def test_card_w_below_limit_right_pin_not_enough_cash(self):
71        self.assertEqual(
72            src.atm.withdraw(
73                right_pin=True,
74                enough_cash=False,
75                above_daily_limit=False,
76                card_expired=True,
77            ),
78            DENIED
79        )
80        self.assertEqual(
81            src.atm.withdraw(
82                right_pin=True,
83                enough_cash=False,
84                above_daily_limit=False,
85                card_expired=False,
86            ),
87            DENIED
88        )
atm/tests/test_atm.py
 90    def test_card_w_above_limit_wrong_pin_enough_cash(self):
 91        self.assertEqual(
 92            src.atm.withdraw(
 93                right_pin=False,
 94                enough_cash=True,
 95                above_daily_limit=True,
 96                card_expired=True,
 97            ),
 98            DENIED
 99        )
100        self.assertEqual(
101            src.atm.withdraw(
102                right_pin=False,
103                enough_cash=True,
104                above_daily_limit=True,
105                card_expired=False,
106            ),
107            DENIED
108        )
atm/tests/test_atm.py
110    def test_card_w_below_limit_wrong_pin_enough_cash(self):
111        self.assertEqual(
112            src.atm.withdraw(
113                right_pin=False,
114                enough_cash=True,
115                above_daily_limit=False,
116                card_expired=True,
117            ),
118            DENIED
119        )
120        self.assertEqual(
121            src.atm.withdraw(
122                right_pin=False,
123                enough_cash=True,
124                above_daily_limit=False,
125                card_expired=False,
126            ),
127            DENIED
128        )
atm/tests/test_atm.py
130    def test_card_w_above_limit_wrong_pin_not_enough_cash(self):
131        self.assertEqual(
132            src.atm.withdraw(
133                right_pin=False,
134                enough_cash=False,
135                above_daily_limit=True,
136                card_expired=True,
137            ),
138            DENIED
139        )
140        self.assertEqual(
141            src.atm.withdraw(
142                right_pin=False,
143                enough_cash=False,
144                above_daily_limit=True,
145                card_expired=False,
146            ),
147            DENIED
148        )
atm/tests/test_atm.py
150    def test_card_w_below_limit_wrong_pin_not_enough_cash(self):
151        self.assertEqual(
152            src.atm.withdraw(
153                right_pin=False,
154                enough_cash=False,
155                above_daily_limit=False,
156                card_expired=True,
157            ),
158            DENIED
159        )
160        self.assertEqual(
161            src.atm.withdraw(
162                right_pin=False,
163                enough_cash=False,
164                above_daily_limit=False,
165                card_expired=False,
166            ),
167            DENIED
168        )
169
170
171# Exceptions seen
172# AssertionError
173# NameError
174# AttributeError
175# TypeError
176# SyntaxError

Automated Teller Machine: solution

The code in atm/src/atm.py from Automated Teller Machine

atm/src/atm.py
 1def withdraw(
 2        right_pin, enough_cash,
 3        above_daily_limit=False, card_expired=False,
 4    ):
 5    denied = 'DENIED'
 6    if card_expired:
 7        return denied
 8    if above_daily_limit:
 9        return denied
10    if not right_pin:
11        return denied
12    if not enough_cash:
13        return denied
14    return 'CASH'