Car
I want to make a Car that can be turned on with the push of a button, if the inputs are
is the key close to the starter?
was the start button pressed?
this is the truth table I get for the Car Starter
key |
start |
output |
|---|---|---|
close |
pressed |
ON |
close |
NOT pressed |
OFF |
far |
pressed |
OFF |
far |
NOT pressed |
OFF |
preview
These are the tests I have at the end of the chapter
1import src.car
2import unittest
3
4
5OFF = 'OFF'
6
7
8class TestCar(unittest.TestCase):
9
10 def test_key_close_brake_pressed_w_gear(self):
11 self.assertEqual(
12 src.car.starter(
13 key_is_close=True,
14 brake_is_pressed=True,
15 start_is_pushed=True,
16 in_park=True,
17 ),
18 'ON'
19 )
20
21 self.assertEqual(
22 src.car.starter(
23 key_is_close=True,
24 brake_is_pressed=True,
25 start_is_pushed=True,
26 in_park=False,
27 ),
28 OFF
29 )
30
31 self.assertEqual(
32 src.car.starter(
33 key_is_close=True,
34 brake_is_pressed=True,
35 start_is_pushed=False,
36 in_park=True,
37 ),
38 OFF
39 )
40
41 self.assertEqual(
42 src.car.starter(
43 key_is_close=True,
44 brake_is_pressed=True,
45 start_is_pushed=False,
46 in_park=False,
47 ),
48 OFF
49 )
50
51 def test_key_close_brake_not_pressed_w_gear(self):
52 self.assertEqual(
53 src.car.starter(
54 key_is_close=True,
55 brake_is_pressed=False,
56 start_is_pushed=True,
57 in_park=True,
58 ),
59 OFF
60 )
61
62 self.assertEqual(
63 src.car.starter(
64 key_is_close=True,
65 brake_is_pressed=False,
66 start_is_pushed=True,
67 in_park=False,
68 ),
69 OFF
70 )
71
72 self.assertEqual(
73 src.car.starter(
74 key_is_close=True,
75 brake_is_pressed=False,
76 start_is_pushed=False,
77 in_park=True,
78 ),
79 OFF
80 )
81
82 self.assertEqual(
83 src.car.starter(
84 key_is_close=True,
85 brake_is_pressed=False,
86 start_is_pushed=False,
87 in_park=False,
88 ),
89 OFF
90 )
91
92 def test_key_far_brake_pressed_w_gear(self):
93 self.assertEqual(
94 src.car.starter(
95 key_is_close=False,
96 brake_is_pressed=True,
97 start_is_pushed=True,
98 in_park=True,
99 ),
100 OFF
101 )
102
103 self.assertEqual(
104 src.car.starter(
105 key_is_close=False,
106 brake_is_pressed=True,
107 start_is_pushed=True,
108 in_park=False,
109 ),
110 OFF
111 )
112
113 self.assertEqual(
114 src.car.starter(
115 key_is_close=False,
116 brake_is_pressed=True,
117 start_is_pushed=False,
118 in_park=True,
119 ),
120 OFF
121 )
122
123 self.assertEqual(
124 src.car.starter(
125 key_is_close=False,
126 brake_is_pressed=True,
127 start_is_pushed=False,
128 in_park=False,
129 ),
130 OFF
131 )
132
133 def test_key_far_brake_not_pressed_w_gear(self):
134 self.assertEqual(
135 src.car.starter(
136 key_is_close=False,
137 brake_is_pressed=False,
138 start_is_pushed=True,
139 in_park=True,
140 ),
141 OFF
142 )
143
144 self.assertEqual(
145 src.car.starter(
146 key_is_close=False,
147 brake_is_pressed=False,
148 start_is_pushed=True,
149 in_park=False,
150 ),
151 OFF
152 )
153
154 self.assertEqual(
155 src.car.starter(
156 key_is_close=False,
157 brake_is_pressed=False,
158 start_is_pushed=False,
159 in_park=True,
160 ),
161 OFF
162 )
163
164 self.assertEqual(
165 src.car.starter(
166 key_is_close=False,
167 brake_is_pressed=False,
168 start_is_pushed=False,
169 in_park=False,
170 ),
171 OFF
172 )
173
174
175# Exceptions seen
176# AssertionError
177# NameError
178# AttributeError
179# TypeError
180# SyntaxError
requirements
start the project
I name this project
carI open a terminal
I use uv to make a directory for the project
uv init carthe terminal shows
Initialized project `car` at `.../pumping_python/car`then goes back to the command line
I change directory to the project
cd carthe terminal shows I am in the
carfolder.../pumping_python/carI remove
main.pyfrom the project because I do not use itrm main.pythe terminal goes back to the command line
I 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/car.pyNew-Item src/car.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_car.pyNew-Item tests/test_car.pythe terminal goes back to the command line
I open
test_car.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_car.pyVisual Studio Code opens
test_car.pyin the editorI add the first failing test to
test_car.py1import unittest 2 3 4class TestCar(unittest.TestCase): 5 6 def test_failure(self): 7 self.assertFalse(True)I go back to the terminal to make a requirements file for the Python packages I need
echo "pytest" > requirements.txtthe terminal goes back to the command line
I add pytest-watcher to the requirements file
echo "pytest-watcher" >> requirements.txtthe 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 tree to look at the structure of the project
treethe terminal shows
. ├── README.md ├── pyproject.toml ├── requirements.txt ├── src │ └── car.py ├── tests │ ├── __init__.py │ └── test_car.py └── uv.lockif you do not see
uv.lockin your tree, do not worry, run the tests nextI use pytest-watcher to run the tests automatically
uv run pytest-watcher . --nowthe terminal is my friend, and shows AssertionError
======================== FAILURES ======================== _________________ TestCar.test_failure ___________________ self = <tests.test_car.TestCar testMethod=test_failure> def test_failure(self): > self.assertFalse(True) E AssertionError: True is not false tests/test_car.py:7: AssertionError ================ short test summary info ================= FAILED tests/test_car.py::TestCar::test_failure - AssertionError: True is not false =================== 1 failed in X.YZs ====================if the terminal does not show the same error, then check
if your
tests/__init__.pyhave 2 underscores (__) before and afterinitfor__init__.pynot_init_.pyif you ran
echo "pytest-watcher" >> requirements.txt, to addpytest-watcherto the requirements file
fix those errors then try to run
uv run pytest-watcher . --nowagainI add AssertionError to the list of Exceptions seen in
test_car.py4class TestCar(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_key_close
The truth table for when the key is close to the starter is
key |
start |
output |
|---|---|---|
close |
pressed |
ON |
close |
NOT pressed |
OFF |
RED: make it fail
I change test_failure to test_key_close, then add an assertion for when the key is close and the start button is pressed
key |
start |
output |
|---|---|---|
close |
pressed |
ON |
4class TestCar(unittest.TestCase):
5
6 def test_key_close(self):
7 my_expectation = 'ON'
8 reality = src.car.starter(
9 key_is_close=True,
10 start_is_pressed=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
because I do not have a definition for src in this file
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.car 2import unittest 3 4 5class TestCar(unittest.TestCase):the terminal is my friend, and shows AttributeError
AttributeError: module 'src.car' has no attribute 'starter'because
car.pyin thesrcfolder does not have anything namedstarterin itIf you get ModuleNotFoundError
ModuleNotFoundError: No module named 'src'check if you have
__init__.pyin thetestsfolder with underscores (__) before and afterinitfor__init__.pynot_init_.pyI add AttributeError to the list of Exceptions seen
16# Exceptions seen 17# AssertionError 18# NameError 19# AttributeErrorI add a function named
startertocar.py1def starter(): 2 return Nonethe terminal is my friend, and shows TypeError
TypeError: starter() got an unexpected keyword argument 'key_is_close'because the test called the
starterfunction with 2 keyword arguments (key_is_closeandstart_is_pressed) and this definition only allows calls with 0 argumentsI add TypeError to the list of Exceptions seen in
test_car.py16# Exceptions seen 17# AssertionError 18# NameError 19# AttributeError 20# TypeErrorI add the keyword argument to the function in
car.py1def starter(key_is_close): 2 return Nonethe terminal is my friend, and shows TypeError
TypeError: starter() got an unexpected keyword argument 'start_is_pressed'because the test called the
starterfunction with 2 keyword arguments (key_is_closeandstart_is_pressed) and this definition only allows calls with 1 inputI add
start_is_pressedto the function signature1def starter(key_is_close, start_is_pressed): 2 return Nonethe terminal is my friend, and shows AssertionError
AssertionError: None != 'ON'the
starterfunction returned None and the test expects ‘ON’I change the return statement to give the test what it wants
1def starter(key_is_close, start_is_pressed): 2 return 'ON'the test passes. The
starterfunction always returns ON, it does not care about the inputs. Is this Tautology?
REFACTOR: make it better
I add an assertion for when the key is close and the start button is NOT pressed, in
test_car.pykey
start
output
close
pressed
ON
close
NOT pressed
OFF
7 def test_key_close(self): 8 my_expectation = 'ON' 9 reality = src.car.starter( 10 key_is_close=True, 11 start_is_pressed=True, 12 ) 13 self.assertEqual(reality, my_expectation) 14 15 my_expectation = 'OFF' 16 reality = src.car.starter( 17 key_is_close=True, 18 start_is_pressed=False, 19 ) 20 self.assertEqual(reality, my_expectation) 21 22 23# Exceptions seenthe terminal is my friend, and shows AssertionError
AssertionError: 'ON' != 'OFF'because the
starterfunction returns ‘ON’ and the test expects ‘OFF’I add an if statement to the
starterfunction incar.py1def starter(key_is_close, start_is_pressed): 2 if start_is_pressed == False: 3 return 'OFF' 4 5 return 'ON'the test passes
I use Logical Negation (NOT) to write it in terms of True
1def starter(key_is_close, start_is_pressed): 2 # if start_is_pressed == False: 3 if not start_is_pressed == True: 4 return 'OFF' 5 6 return 'ON'the test is still green
I remove
== True1def starter(key_is_close, start_is_pressed): 2 # if start_is_pressed == False: 3 # if not start_is_pressed == True: 4 if not start_is_pressed: 5 return 'OFF' 6 7 return 'ON'still green, because
if something == Falseis the same asif not something == Trueis the same asif not somethingI remove the commented lines
1def starter(key_is_close, start_is_pressed): 2 if not start_is_pressed: 3 return 'OFF' 4 5 return 'ON'this is what happens when the
starterfunction is calledit returns ‘OFF’ if the start button is NOT pressed
it returns ‘ON’ if the above condition is not met
test_key_far
The truth table for when the key is far from the starter is
key |
start |
output |
|---|---|---|
far |
pressed |
OFF |
far |
NOT pressed |
OFF |
RED: make it fail
I add a test with an assertion for when the key is far from the starter and the start button is pressed, in test_car.py
key |
start |
output |
|---|---|---|
far |
pressed |
OFF |
15 my_expectation = 'OFF'
16 reality = src.car.starter(
17 key_is_close=True,
18 start_is_pressed=False,
19 )
20 self.assertEqual(reality, my_expectation)
21
22 def test_key_far(self):
23 my_expectation = 'OFF'
24 reality = src.car.starter(
25 key_is_close=False,
26 start_is_pressed=True,
27 )
28 self.assertEqual(reality, my_expectation)
29
30
31 # Exceptions seen
the terminal is my friend, and shows AssertionError
AssertionError: 'ON' != 'OFF'
because the starter function returns ‘ON’ and the test expects ‘OFF’
GREEN: make it pass
I add an if statement to car.py
1def starter(key_is_close, start_is_pressed):
2 if key_is_close == False:
3 return 'OFF'
4
5 if not start_is_pressed:
6 return 'OFF'
7
8 return 'ON'
the test passes
REFACTOR: make it better
I use Logical Negation (NOT) to write the new if statement in terms of True
1def starter(key_is_close, start_is_pressed): 2 # if key_is_close == False: 3 if not key_is_close == True: 4 return 'OFF' 5 6 if not start_is_pressed: 7 return 'OFF' 8 9 return 'ON'the test is still green
I remove
== True1def starter(key_is_close, start_is_pressed): 2 # if key_is_close == False: 3 # if not key_is_close == True: 4 if not key_is_close: 5 return 'OFF' 6 7 if not start_is_pressed: 8 return 'OFF' 9 10 return 'ON'still green, because
if something == Falseis the same asif not something == Trueis the same asif not somethingI use Logical Disjunction (OR) to put the two if statements together because they both return the same thing (
'OFF')1def starter(key_is_close, start_is_pressed): 2 # if key_is_close == False: 3 # if not key_is_close == True: 4 # if not key_is_close: 5 # return 'OFF' 6 7 # if not start_is_pressed: 8 if not key_is_close or not start_is_pressed: 9 return 'OFF' 10 11 return 'ON'the test is still green
I rewrite the statement in terms of Logical Negation (NOT) because it happens two times
1def starter(key_is_close, start_is_pressed): 2 # if key_is_close == False: 3 # if not key_is_close == True: 4 # if not key_is_close: 5 # return 'OFF' 6 # if not start_is_pressed: 7 # if not key_is_close or not start_is_pressed: 8 if ( 9 (not key_is_close) 10 (not and) 11 (not start_is_pressed) 12 ): 13 return 'OFF' 14 15 return 'ON'the terminal is my friend, and shows SyntaxError
SyntaxError: invalid syntaxI add SyntaxError to the list of Exceptions seen in
test_car.py31# Exceptions seen 32# AssertionError 33# NameError 34# AttributeError 35# TypeError 36# SyntaxErrorI “factor” out the nots in the
starterfunction incar.py1def starter(key_is_close, start_is_pressed): 2 # if key_is_close == False: 3 # if not key_is_close == True: 4 # if not key_is_close: 5 # return 'OFF' 6 # if not start_is_pressed: 7 # if not key_is_close or not start_is_pressed: 8 # if ( 9 # (not key_is_close) 10 # (not and) 11 # (not start_is_pressed) 12 # ): 13 if not (key_is_close and start_is_pressed): 14 return 'OFF' 15 16 return 'ON'the test is green again
I remove the commented lines
1def starter(key_is_close, start_is_pressed): 2 if not (key_is_close and start_is_pressed): 3 return 'OFF' 4 5 return 'ON'this is what happens when the
starterfunction is calledit returns ‘OFF’ if the key is far from the starter OR the start button is NOT pressed
it returns ‘ON’ if the above conditions are not met
is this Logical Conjunction?
I add an assertion for when the key is far from the starter and the start button is NOT pressed to test_key_far in
test_car.pykey
start
output
far
pressed
OFF
far
NOT pressed
OFF
22 def test_key_far(self): 23 my_expectation = 'OFF' 24 reality = src.car.starter( 25 key_is_close=False, 26 start_is_pressed=True, 27 ) 28 self.assertEqual(reality, my_expectation) 29 30 reality = src.car.starter( 31 key_is_close=False, 32 start_is_pressed=False, 33 ) 34 self.assertEqual(reality, my_expectation) 35 36 37# Exceptions seenthe test is still green
I make a global variable to remove repetition from the tests
1import src.car 2import unittest 3 4 5OFF = 'OFF' 6 7 8class TestCar(unittest.TestCase):this way all the tests can use the same global variable and I do not have to make one for each test
I use the new global variable to remove
'OFF'from test_key_close10 def test_key_close(self): 11 my_expectation = 'ON' 12 reality = src.car.starter( 13 key_is_close=True, 14 start_is_pressed=True, 15 ) 16 self.assertEqual(reality, my_expectation) 17 18 # my_expectation = 'OFF' 19 reality = src.car.starter( 20 key_is_close=True, 21 start_is_pressed=False, 22 ) 23 # self.assertEqual(reality, my_expectation) 24 self.assertEqual(reality, OFF)still green
I remove the commented lines
10 def test_key_close(self): 11 my_expectation = 'ON' 12 reality = src.car.starter( 13 key_is_close=True, 14 start_is_pressed=True, 15 ) 16 self.assertEqual(reality, my_expectation) 17 18 reality = src.car.starter( 19 key_is_close=True, 20 start_is_pressed=False, 21 ) 22 self.assertEqual(reality, OFF) 23 24 def test_key_far(self):I use the new global variable to remove
'OFF'from test_key_far24 def test_key_far(self): 25 # my_expectation = 'OFF' 26 reality = src.car.starter( 27 key_is_close=False, 28 start_is_pressed=True, 29 ) 30 # self.assertEqual(reality, my_expectation) 31 self.assertEqual(reality, OFF) 32 33 reality = src.car.starter( 34 key_is_close=False, 35 start_is_pressed=False, 36 ) 37 # self.assertEqual(reality, my_expectation) 38 self.assertEqual(reality, OFF) 39 40 41# Exceptions seengreen
I remove the commented lines
24 def test_key_far(self): 25 reality = src.car.starter( 26 key_is_close=False, 27 start_is_pressed=True, 28 ) 29 self.assertEqual(reality, OFF) 30 31 reality = src.car.starter( 32 key_is_close=False, 33 start_is_pressed=False, 34 ) 35 self.assertEqual(reality, OFF) 36 37 38# Exceptions seen
test_key_close_brake_pressed
So far, the truth table for the car starter is
key |
start |
output |
|---|---|---|
close |
pressed |
ON |
close |
NOT pressed |
OFF |
far |
pressed |
OFF |
far |
NOT pressed |
OFF |
I want the car to start only when the brake pedal is pressed, the inputs for the car will then be
is the key close to the starter?
is the brake being pressed?
was the start button pressed?
and the truth table for when the key is close and the brake is being pressed, is:
key |
brake |
start |
output |
|---|---|---|---|
close |
pressed |
pressed |
ON |
close |
pressed |
NOT pressed |
OFF |
RED: make it fail
I add a value for brake_is_pressed to the first assertion in test_key_close, for when the key is close, the brake is being pressed and the start button is pressed
key |
brake |
start |
output |
|---|---|---|---|
close |
pressed |
pressed |
ON |
7 def test_key_close(self):
8 my_expectation = 'ON'
9 reality = src.car.starter(
10 key_is_close=True,
11 brake_is_pressed=True,
12 start_is_pressed=True,
13 )
14 self.assertEqual(reality, my_expectation)
the terminal is my friend, and shows TypeError
TypeError: starter() got an unexpected keyword argument 'brake_is_pressed'. Did you mean 'start_is_pressed'?
because the test called the starter function with 3 keyword arguments (key_is_close, brake_is_pressed and start_is_pressed) and the function only allows calls with 2 arguments (key_is_close and start_is_pressed)
GREEN: make it pass
I add
brake_is_pressedto the function signature incar.py1def starter( 2 key_is_close, start_is_pressed, 3 brake_is_pressed, 4 ): 5 if not (key_is_close and start_is_pressed): 6 return 'OFF' 7 8 return 'ON'the terminal is my friend, and shows TypeError
FAILED ...test_key_close - TypeError: starter() missing 1 required positional argument: 'brake_is_pressed' FAILED ...test_key_far - TypeError: starter() missing 1 required positional argument: 'brake_is_pressed'because the tests call the
starterfunction with 2 arguments (key_is_closeandstart_is_pressed) and I just changed the function signature to make it take 3 required arguments (key_is_close,start_is_pressedandbrake_is_pressed). I have to makebrake_is_presseda choice.I add a default value to make
brake_is_presseda choice1def starter( 2 key_is_close, start_is_pressed, 3 brake_is_pressed=False, 4 ):the test passes because
src.car.starter( key_is_close=True, start_is_pressed=False, )is now the same as
src.car.starter( key_is_close=True, start_is_pressed=False, brake_is_pressed=False, )a function uses the default value for a parameter when it is called without a value for the parameter.
REFACTOR: make it better
I add a value for
brake_is_pressedto the next assertion for when the key is close, the brake is being pressed and the start button is NOT pressedkey
brake
start
output
close
pressed
pressed
ON
close
pressed
NOT pressed
OFF
7 def test_key_close(self): 8 my_expectation = 'ON' 9 reality = src.car.starter( 10 key_is_close=True, 11 brake_is_pressed=True, 12 start_is_pressed=True, 13 ) 14 self.assertEqual(reality, my_expectation) 15 16 reality = src.car.starter( 17 key_is_close=True, 18 brake_is_pressed=True, 19 start_is_pressed=False, 20 ) 21 self.assertEqual(reality, OFF) 22 23 def test_key_far(self):the test is still green
I change the name of the test from test_key_close to test_key_close_brake_pressed
5class TestCar(unittest.TestCase): 6 7 def test_key_close_brake_pressed(self): 8 my_expectation = 'OFF'
test_key_close_brake_not_pressed
The truth table for when the key is close and the brake is NOT pressed is
key |
brake |
start |
output |
|---|---|---|---|
close |
NOT pressed |
pressed |
OFF |
close |
NOT pressed |
NOT pressed |
OFF |
I add a new test with an assertion for when the key is close, the brake is NOT pressed and the start button is pressed
key
brake
start
output
close
NOT pressed
pressed
OFF
19 reality = src.car.starter( 20 key_is_close=True, 21 brake_is_pressed=True, 22 start_is_pressed=False, 23 ) 24 self.assertEqual(reality, OFF) 25 26 def test_key_close_brake_not_pressed(self): 27 reality = src.car.starter( 28 key_is_close=True, 29 brake_is_pressed=False, 30 start_is_pressed=True, 31 ) 32 self.assertEqual(reality, OFF) 33 34 def test_key_far(self):the terminal is my friend, and shows AssertionError
AssertionError: 'ON' != 'OFF'because the
starterfunction returned ‘ON’ and the test expects ‘OFF’I add an if statement to the
starterfunction incar.py1def starter( 2 key_is_close, start_is_pressed, 3 brake_is_pressed=False, 4 ): 5 if brake_is_pressed == False: 6 return 'OFF' 7 8 if not (key_is_close and start_is_pressed): 9 return 'OFF' 10 11 return 'ON'the test passes
I use Logical Negation (NOT) to write the new if statement in terms of True
1def starter( 2 key_is_close, start_is_pressed, 3 brake_is_pressed=False, 4 ): 5 # if brake_is_pressed == False: 6 if not brake_is_pressed == True: 7 return 'OFF' 8 9 if not (key_is_close and start_is_pressed): 10 return 'OFF' 11 12 return 'ON'the test is still green
I remove
== True1def starter( 2 key_is_close, start_is_pressed, 3 brake_is_pressed=False, 4 ): 5 # if brake_is_pressed == False: 6 # if not brake_is_pressed == True: 7 if not brake_is_pressed: 8 return 'OFF' 9 10 if not (key_is_close and start_is_pressed): 11 return 'OFF' 12 13 return 'ON'still green, because
if something == Falseis the same asif not something == Trueis the same asif not somethingI use Logical Disjunction to put the two if statements together because they return the same thing
1def starter( 2 key_is_close, start_is_pressed, 3 brake_is_pressed=False, 4 ): 5 # if brake_is_pressed == False: 6 # if not brake_is_pressed == True: 7 # if not brake_is_pressed: 8 # return 'OFF' 9 10 # if not (key_is_close and start_is_pressed): 11 if ( 12 not (key_is_close and start_is_pressed) 13 or 14 not brake_is_pressed 15 ): 16 return 'OFF' 17 18 return 'ON'green
I write the statement in terms of NOT
1def starter( 2 key_is_close, start_is_pressed, 3 brake_is_pressed=False, 4 ): 5 # if brake_is_pressed == False: 6 # if not brake_is_pressed == True: 7 # if not brake_is_pressed: 8 # return 'OFF' 9 10 # if not (key_is_close and start_is_pressed): 11 # if ( 12 # not (key_is_close and start_is_pressed) 13 # or 14 # not brake_is_pressed 15 # ): 16 if ( 17 (not (key_is_close and start_is_pressed)) 18 (not and) 19 (not brake_is_pressed) 20 ): 21 return 'OFF' 22 23 return 'ON'the terminal is my friend, and shows SyntaxError
SyntaxError: invalid syntaxI “factor” out the nots
1def starter( 2 key_is_close, start_is_pressed, 3 brake_is_pressed=False, 4 ): 5 # if brake_is_pressed == False: 6 # if not brake_is_pressed == True: 7 # if not brake_is_pressed: 8 # return 'OFF' 9 10 # if not (key_is_close and start_is_pressed): 11 # if ( 12 # not (key_is_close and start_is_pressed) 13 # or 14 # not brake_is_pressed 15 # ): 16 # if ( 17 # (not (key_is_close and start_is_pressed)) 18 # (not and) 19 # (not brake_is_pressed) 20 # ): 21 if not ( 22 (key_is_close and start_is_pressed) 23 and 24 (brake_is_pressed) 25 ): 26 return 'OFF' 27 28 return 'ON'the test is green again
I remove the commented lines
1def starter( 2 key_is_close, start_is_pressed, 3 brake_is_pressed=False, 4 ): 5 if not ( 6 key_is_close 7 and start_is_pressed 8 and brake_is_pressed 9 ): 10 return 'OFF' 11 12 return 'ON'this is what happens when the
starterfunction is calledit returns ‘OFF’ if the key is far from the starter OR the start button is NOT pressed OR the brake is NOT pressed
it returns ‘ON’ if none of the conditions are met
I add an assertion for when the key is close, the brake is NOT pressed and the start button is NOT pressed, in test_key_close_brake_not_pressed in
test_car.pykey
brake
start
output
close
NOT pressed
pressed
OFF
close
NOT pressed
NOT pressed
OFF
26 def test_key_close_brake_not_pressed(self): 27 reality = src.car.starter( 28 key_is_close=True, 29 brake_is_pressed=False, 30 start_is_pressed=True, 31 ) 32 self.assertEqual(reality, OFF) 33 34 reality = src.car.starter( 35 key_is_close=True, 36 brake_is_pressed=False, 37 start_is_pressed=False, 38 ) 39 self.assertEqual(reality, OFF) 40 41 def test_key_far(self):the test is still green
test_key_far_brake_pressed
The truth table for when the key is far from the starter and the brake is being pressed, is:
key |
brake |
start |
output |
|---|---|---|---|
far |
pressed |
pressed |
OFF |
far |
pressed |
NOT pressed |
OFF |
I add a value for the
brake_is_pressedparameter to the first assertion in test_key_close for the case where the key is far from the starter, the brake is being pressed and the start button is pressedkey
brake
start
output
far
pressed
pressed
OFF
34 reality = src.car.starter( 35 key_is_close=True, 36 brake_is_pressed=False, 37 start_is_pressed=False, 38 ) 39 self.assertEqual(reality, OFF) 40 41 def test_key_far(self): 42 reality = src.car.starter( 43 key_is_close=False, 44 brake_is_pressed=True, 45 start_is_pressed=True, 46 ) 47 self.assertEqual(reality, OFF)the test is still green
I add a value for
brake_is_pressedto the next assertion, for when the key is far from the starter, the brake is being pressed and the start button is NOT pressedkey
brake
start
output
far
pressed
pressed
OFF
far
pressed
NOT pressed
OFF
40 def test_key_far(self): 41 reality = src.car.starter( 42 key_is_close=False, 43 brake_is_pressed=True, 44 start_is_pressed=True, 45 ) 46 self.assertEqual(reality, OFF) 47 48 reality = src.car.starter( 49 key_is_close=False, 50 brake_is_pressed=True, 51 start_is_pressed=False, 52 ) 53 self.assertEqual(reality, OFF) 54 55 56# Exceptions seenstill green
I change the name of the test from test_key_far to test_key_far_brake_pressed
34 reality = src.car.starter( 35 key_is_close=True, 36 brake_is_pressed=False, 37 start_is_pressed=False, 38 ) 39 self.assertEqual(reality, OFF) 40 41 def test_key_far_brake_pressed(self): 42 reality = src.car.starter( 43 key_is_close=False, 44 brake_is_pressed=True, 45 start_is_pressed=True, 46 ) 47 self.assertEqual(reality, OFF)
test_key_far_brake_not_pressed
The truth table for when the key is far from the starter and the brake is NOT pressed is
key |
brake |
start |
output |
|---|---|---|---|
far |
NOT pressed |
pressed |
OFF |
far |
NOT pressed |
NOT pressed |
OFF |
I add a new test with an assertion for when the key is far from the starter, the brake is NOT pressed and the start button is pressed
key
brake
start
output
far
NOT pressed
pressed
OFF
48 reality = src.car.starter( 49 key_is_close=False, 50 brake_is_pressed=True, 51 start_is_pressed=False, 52 ) 53 self.assertEqual(reality, OFF) 54 55 def test_key_far_brake_not_pressed(self): 56 reality = src.car.starter( 57 key_is_close=False, 58 brake_is_pressed=False, 59 start_is_pressed=True, 60 ) 61 self.assertEqual(reality, OFF) 62 63 64# Exceptions seengreen
I add an assertion for when the key is far from the starter, the brake is NOT pressed and the start button is NOT pressed
key
brake
start
output
far
NOT pressed
pressed
OFF
far
NOT pressed
NOT pressed
OFF
56 def test_key_far_brake_not_pressed(self): 57 reality = src.car.starter( 58 key_is_close=False, 59 brake_is_pressed=False, 60 start_is_pressed=True, 61 ) 62 self.assertEqual(reality, OFF) 63 64 reality = src.car.starter( 65 key_is_close=False, 66 brake_is_pressed=False, 67 start_is_pressed=False, 68 ) 69 self.assertEqual(reality, OFF) 70 71 72# Exceptions seenstill green
I call the
starterfunction directly in test_key_far_brake_not_pressed, I do not need therealityvariable because it is only used once in each assertion56 def test_key_far_brake_not_pressed(self): 57 reality = src.car.starter( 58 key_is_close=False, 59 brake_is_pressed=False, 60 start_is_pressed=True, 61 ) 62 # self.assertEqual(reality, OFF) 63 self.assertEqual( 64 src.car.starter( 65 key_is_close=False, 66 brake_is_pressed=False, 67 start_is_pressed=True, 68 ), 69 OFF 70 ) 71 72 reality = src.car.starter( 73 key_is_close=False, 74 brake_is_pressed=False, 75 start_is_pressed=False, 76 ) 77 # self.assertEqual(reality, OFF) 78 self.assertEqual( 79 src.car.starter( 80 key_is_close=False, 81 brake_is_pressed=False, 82 start_is_pressed=False, 83 ), 84 OFF 85 )the test is still green
I remove the commented lines and
realityvariables56 def test_key_far_brake_not_pressed(self): 57 self.assertEqual( 58 src.car.starter( 59 key_is_close=False, 60 brake_is_pressed=False, 61 start_is_pressed=True, 62 ), 63 OFF 64 ) 65 66 self.assertEqual( 67 src.car.starter( 68 key_is_close=False, 69 brake_is_pressed=False, 70 start_is_pressed=False, 71 ), 72 OFF 73 ) 74 75 76# Exceptions seenI do the same thing in test_key_far_brake_pressed
41 def test_key_far_brake_pressed(self): 42 reality = src.car.starter( 43 key_is_close=False, 44 brake_is_pressed=True, 45 start_is_pressed=True, 46 ) 47 # self.assertEqual(reality, OFF) 48 self.assertEqual( 49 src.car.starter( 50 key_is_close=False, 51 brake_is_pressed=True, 52 start_is_pressed=True, 53 ), 54 OFF 55 ) 56 57 reality = src.car.starter( 58 key_is_close=False, 59 brake_is_pressed=True, 60 start_is_pressed=False, 61 ) 62 # self.assertEqual(reality, OFF) 63 self.assertEqual( 64 src.car.starter( 65 key_is_close=False, 66 brake_is_pressed=True, 67 start_is_pressed=False, 68 ), 69 OFF 70 ) 71 72 def test_key_far_brake_not_pressed(self):still green
I remove the commented lines and
realityvariables from test_key_far_brake_pressed41 def test_key_far_brake_pressed(self): 42 self.assertEqual( 43 src.car.starter( 44 key_is_close=False, 45 brake_is_pressed=True, 46 start_is_pressed=True, 47 ), 48 OFF 49 ) 50 51 self.assertEqual( 52 src.car.starter( 53 key_is_close=False, 54 brake_is_pressed=True, 55 start_is_pressed=False, 56 ), 57 OFF 58 ) 59 60 def test_key_far_brake_not_pressed(self):on to test_key_close_brake_not_pressed
26 def test_key_close_brake_not_pressed(self): 27 reality = src.car.starter( 28 key_is_close=True, 29 brake_is_pressed=False, 30 start_is_pressed=True, 31 ) 32 # self.assertEqual(reality, OFF) 33 self.assertEqual( 34 src.car.starter( 35 key_is_close=True, 36 brake_is_pressed=False, 37 start_is_pressed=True, 38 ), 39 OFF 40 ) 41 42 reality = src.car.starter( 43 key_is_close=True, 44 brake_is_pressed=False, 45 start_is_pressed=False, 46 ) 47 # self.assertEqual(reality, OFF) 48 self.assertEqual( 49 src.car.starter( 50 key_is_close=True, 51 brake_is_pressed=False, 52 start_is_pressed=False, 53 ), 54 OFF 55 ) 56 57 def test_key_far_brake_pressed(self):green
I remove the commented lines and
realityvariables from test_key_close_brake_not_pressed26 def test_key_close_brake_not_pressed(self): 27 self.assertEqual( 28 src.car.starter( 29 key_is_close=True, 30 brake_is_pressed=False, 31 start_is_pressed=True, 32 ), 33 OFF 34 ) 35 36 self.assertEqual( 37 src.car.starter( 38 key_is_close=True, 39 brake_is_pressed=False, 40 start_is_pressed=False, 41 ), 42 OFF 43 ) 44 45 def test_key_far_brake_pressed(self):I call the
starterfunction directly in test_key_close_brake_pressed10 def test_key_close_brake_pressed(self): 11 my_expectation = 'ON' 12 reality = src.car.starter( 13 key_is_close=True, 14 brake_is_pressed=True, 15 start_is_pressed=True, 16 ) 17 # self.assertEqual(reality, my_expectation) 18 self.assertEqual( 19 src.car.starter( 20 key_is_close=True, 21 brake_is_pressed=True, 22 start_is_pressed=True, 23 ), 24 'ON' 25 ) 26 27 reality = src.car.starter( 28 key_is_close=True, 29 brake_is_pressed=True, 30 start_is_pressed=False, 31 ) 32 # self.assertEqual(reality, OFF) 33 self.assertEqual( 34 src.car.starter( 35 key_is_close=True, 36 brake_is_pressed=True, 37 start_is_pressed=False, 38 ), 39 OFF 40 ) 41 42 def test_key_close_brake_not_pressed(self):still green
I remove the commented lines and unused variables from test_key_close_brake_pressed
10 def test_key_close_brake_pressed(self): 11 self.assertEqual( 12 src.car.starter( 13 key_is_close=True, 14 brake_is_pressed=True, 15 start_is_pressed=True, 16 ), 17 'ON' 18 ) 19 20 self.assertEqual( 21 src.car.starter( 22 key_is_close=True, 23 brake_is_pressed=True, 24 start_is_pressed=False, 25 ), 26 OFF 27 ) 28 29 def test_key_close_brake_not_pressed(self):
test_key_close_brake_pressed_w_gear
the truth table for the car starter is
key |
brake |
start |
output |
|---|---|---|---|
close |
pressed |
pressed |
ON |
close |
pressed |
NOT pressed |
OFF |
close |
NOT pressed |
pressed |
OFF |
close |
NOT pressed |
NOT pressed |
OFF |
key |
brake |
start |
output |
|---|---|---|---|
far |
pressed |
pressed |
OFF |
far |
pressed |
NOT pressed |
OFF |
far |
NOT pressed |
pressed |
OFF |
far |
NOT pressed |
NOT pressed |
OFF |
I want to make sure the car is in park before it can start, so it does not immediately move when it is turned on (that would be a problem). The inputs will then be
is the key close to the starter?
is the brake being pressed?
was the start button pressed?
is the gear in park?
and the truth table for when the key is close and the brake is being pressed, is:
key |
brake |
start |
gear |
output |
|---|---|---|---|---|
close |
pressed |
pressed |
in park |
ON |
close |
pressed |
pressed |
NOT in park |
OFF |
close |
pressed |
NOT pressed |
in park |
OFF |
close |
pressed |
NOT pressed |
NOT in park |
OFF |
RED: make it fail
I add a value for in_park to the assertion for the case where the key is close, the brake is being pressed, the start button is pressed and the car gear is in park, to test_key_close_brake_pressed
key |
brake |
start |
gear |
output |
|---|---|---|---|---|
close |
pressed |
pressed |
in park |
ON |
10 def test_key_close_brake_pressed(self):
11 self.assertEqual(
12 src.car.starter(
13 key_is_close=True,
14 brake_is_pressed=True,
15 start_is_pressed=True,
16 in_park=True,
17 ),
18 'ON'
19 )
the terminal shows TypeError
TypeError: starter() got an unexpected keyword argument 'in_park'
because the test called the starter function with 4 keyword arguments (key_is_close, brake_is_pressed, start_is_pressed and in_park) and the definition only allows calls with 2 required arguments (key_is_close and start_is_pressed) and 1 optional argument (brake_is_pressed)
GREEN: make it pass
I add
in_parkto thestarterfunction signature incar.py1def starter( 2 key_is_close, start_is_pressed, 3 brake_is_pressed=False, in_park, 4 ): 5 if not ( 6 key_is_close 7 and start_is_pressed 8 and brake_is_pressed 9 ): 10 return 'OFF' 11 12 return 'ON'the terminal is my friend, and shows SyntaxError
SyntaxError: parameter without a default follows parameter with a defaultbecause parameters without default values must come before parameters with default values
I add a default value for the
in_parkparameter in the function signature to make it a choice1def starter( 2 key_is_close, start_is_pressed, 3 brake_is_pressed=False, in_park=False, 4):the test passes
REFACTOR: make it better
I add an assertion for when the key is close, the brake is being pressed, the start button is pressed and the car gear is NOT in park
key
brake
start
gear
output
close
pressed
pressed
in park
ON
close
pressed
pressed
NOT in park
OFF
10 def test_key_close_brake_pressed(self): 11 self.assertEqual( 12 src.car.starter( 13 key_is_close=True, 14 brake_is_pressed=True, 15 start_is_pressed=True, 16 in_park=True, 17 ), 18 'ON' 19 ) 20 21 self.assertEqual( 22 src.car.starter( 23 key_is_close=True, 24 brake_is_pressed=True, 25 start_is_pressed=True, 26 in_park=False, 27 ), 28 OFF 29 ) 30 31 self.assertEqual( 32 src.car.starter( 33 key_is_close=True, 34 brake_is_pressed=True, 35 start_is_pressed=False, 36 ), 37 OFF 38 )the terminal is my friend, and shows AssertionError
AssertionError: 'ON' != 'OFF'because the
starterfunction returns ‘ON’ and the test expects ‘OFF’I add an if statement to the
starterfunction incar.py1def starter( 2 key_is_close, start_is_pressed, 3 brake_is_pressed=False, in_park=False, 4 ): 5 if in_park == False: 6 return 'OFF' 7 8 if not ( 9 key_is_close 10 and start_is_pressed 11 and brake_is_pressed 12 ): 13 return 'OFF' 14 15 return 'ON'the test passes
I use Logical Negation (NOT) to write it in terms of True
5 # if in_park == False: 6 if not in_park == True: 7 return 'OFF'the test is still green
I remove
== True5 # if in_park == False: 6 # if not in_park == True: 7 if not in_park: 8 return 'OFF'still green, because
if something == Falseis the same asif not something == Trueis the same asif not somethingI use Logical Disjunction (OR) to put the two if statements together because they both return ‘OFF’
1def starter( 2 key_is_close, start_is_pressed, 3 brake_is_pressed=False, in_park=False, 4 ): 5 # if in_park == False: 6 # if not in_park == True: 7 # if not in_park: 8 # return 'OFF' 9 10 # if not ( 11 # key_is_close 12 # and start_is_pressed 13 # and brake_is_pressed 14 # ): 15 if ( 16 not ( 17 key_is_close 18 and start_is_pressed 19 and brake_is_pressed 20 ) or not in_park 21 ): 22 return 'OFF' 23 24 return 'ON'that is one long confusing statement
I write the new if statement in terms of not
10 # if not ( 11 # key_is_close 12 # and start_is_pressed 13 # and brake_is_pressed 14 # ): 15 # if ( 16 # not ( 17 # key_is_close 18 # and start_is_pressed 19 # and brake_is_pressed 20 # ) or not in_park 21 # ): 22 if ( 23 (not ( 24 key_is_close 25 and start_is_pressed 26 and brake_is_pressed 27 )) 28 (not and) 29 (not in_park) 30 ): 31 return 'OFF' 32 33 return 'ON'the terminal is my friend, and shows SyntaxError
SyntaxError: invalid syntaxI factor out the nots
10 # if not ( 11 # key_is_close 12 # and start_is_pressed 13 # and brake_is_pressed 14 # ): 15 # if ( 16 # not ( 17 # key_is_close 18 # and start_is_pressed 19 # and brake_is_pressed 20 # ) or not in_park 21 # ): 22 # if ( 23 # (not ( 24 # key_is_close 25 # and start_is_pressed 26 # and brake_is_pressed 27 # )) 28 # (not and) 29 # (not in_park) 30 # ): 31 if not ( 32 ( 33 key_is_close 34 and start_is_pressed 35 and brake_is_pressed 36 ) 37 and 38 in_park 39 ): 40 return 'OFF' 41 42 return 'ON'the test is green again
I remove the commented lines
1def starter( 2 key_is_close, start_is_pressed, 3 brake_is_pressed=False, in_park=False, 4 ): 5 if not ( 6 key_is_close 7 and start_is_pressed 8 and brake_is_pressed 9 and in_park 10 ): 11 return 'OFF' 12 13 return 'ON'this is what happens when the
starterfunction is calledit returns ‘OFF’ if the key is far from the starter OR the start button is NOT pressed OR the brake is NOT pressed OR the car gear is NOT in park
it returns ‘ON’ if none of the conditions are met
I add a value for the
in_parkparameter in the next assertion for when the key is close, the brake is being pressed, the start button is NOT pressed and the car gear is in park, in test_key_close_brake_pressed intest_car.pykey
brake
start
gear
output
close
pressed
pressed
in park
ON
close
pressed
pressed
NOT in park
OFF
close
pressed
NOT pressed
in park
OFF
10 def test_key_close_brake_pressed(self): 11 self.assertEqual( 12 src.car.starter( 13 key_is_close=True, 14 brake_is_pressed=True, 15 start_is_pressed=True, 16 in_park=True, 17 ), 18 'ON' 19 ) 20 21 self.assertEqual( 22 src.car.starter( 23 key_is_close=True, 24 brake_is_pressed=True, 25 start_is_pressed=True, 26 in_park=False, 27 ), 28 OFF 29 ) 30 31 self.assertEqual( 32 src.car.starter( 33 key_is_close=True, 34 brake_is_pressed=True, 35 start_is_pressed=False, 36 in_park=True, 37 ), 38 OFF 39 ) 40 41 def test_key_close_brake_not_pressed(self):still green
I add an assertion for when the key is close, the brake is being pressed, the start button is NOT pressed and the car gear is NOT in park
key
brake
start
gear
output
close
pressed
pressed
in park
ON
close
pressed
pressed
NOT in park
OFF
close
pressed
NOT pressed
in park
OFF
close
pressed
NOT pressed
NOT in park
OFF
10 def test_key_close_brake_pressed(self): 11 self.assertEqual( 12 src.car.starter( 13 key_is_close=True, 14 brake_is_pressed=True, 15 start_is_pressed=True, 16 in_park=True, 17 ), 18 'ON' 19 ) 20 21 self.assertEqual( 22 src.car.starter( 23 key_is_close=True, 24 brake_is_pressed=True, 25 start_is_pressed=True, 26 in_park=False, 27 ), 28 OFF 29 ) 30 31 self.assertEqual( 32 src.car.starter( 33 key_is_close=True, 34 brake_is_pressed=True, 35 start_is_pressed=False, 36 in_park=True, 37 ), 38 OFF 39 ) 40 41 self.assertEqual( 42 src.car.starter( 43 key_is_close=True, 44 brake_is_pressed=True, 45 start_is_pressed=False, 46 in_park=False, 47 ), 48 OFF 49 ) 50 51 def test_key_close_brake_not_pressed(self):green
I change the name of the test from test_key_close_brake_pressed to test_key_close_brake_pressed_w_gear
8class TestCar(unittest.TestCase): 9 10 def test_key_close_brake_pressed_w_gear(self): 11 self.assertEqual( 12 src.car.starter( 13 key_is_close=True, 14 brake_is_pressed=True, 15 start_is_pressed=True, 16 in_park=True, 17 ), 18 'ON' 19 )
test_key_close_brake_not_pressed_w_gear
The truth table for when the key is close and the brake is NOT pressed is
key |
brake |
start |
gear |
output |
|---|---|---|---|---|
close |
NOT pressed |
pressed |
in park |
OFF |
close |
NOT pressed |
pressed |
NOT in park |
OFF |
close |
NOT pressed |
NOT pressed |
in park |
OFF |
close |
NOT pressed |
NOT pressed |
NOT in park |
OFF |
I add a value for the
in_parkparameter to the first assertion in test_key_close_brake_not_pressed for when the key is close, the brake is NOT pressed, the start button is pressed and the car gear is in parkkey
brake
start
gear
output
close
NOT pressed
pressed
in park
OFF
51 def test_key_close_brake_not_pressed(self): 52 self.assertEqual( 53 src.car.starter( 54 key_is_close=True, 55 brake_is_pressed=False, 56 start_is_pressed=True, 57 in_park=True, 58 ), 59 OFF 60 )still green
I add an assertion for when the key is close, the brake is NOT pressed, the start button is pressed and the car gear is NOT in park
key
brake
start
gear
output
close
NOT pressed
pressed
in park
OFF
close
NOT pressed
pressed
NOT in park
OFF
51 def test_key_close_brake_not_pressed(self): 52 self.assertEqual( 53 src.car.starter( 54 key_is_close=True, 55 brake_is_pressed=False, 56 start_is_pressed=True, 57 in_park=True, 58 ), 59 OFF 60 ) 61 62 self.assertEqual( 63 src.car.starter( 64 key_is_close=True, 65 brake_is_pressed=False, 66 start_is_pressed=True, 67 in_park=False, 68 ), 69 OFF 70 ) 71 72 self.assertEqual( 73 src.car.starter( 74 key_is_close=True, 75 brake_is_pressed=False, 76 start_is_pressed=False, 77 ), 78 OFF 79 ) 80 81 def test_key_far_brake_pressed(self):the test is still green
I add a value for
in_parkto the next assertion, for when the key is close, the brake is NOT pressed, the start button is NOT pressed and the car gear is in parkkey
brake
start
gear
output
close
NOT pressed
pressed
in park
OFF
close
NOT pressed
pressed
NOT in park
OFF
close
NOT pressed
NOT pressed
in park
OFF
51 def test_key_close_brake_not_pressed(self): 52 self.assertEqual( 53 src.car.starter( 54 key_is_close=True, 55 brake_is_pressed=False, 56 start_is_pressed=True, 57 in_park=True, 58 ), 59 OFF 60 ) 61 62 self.assertEqual( 63 src.car.starter( 64 key_is_close=True, 65 brake_is_pressed=False, 66 start_is_pressed=True, 67 in_park=False, 68 ), 69 OFF 70 ) 71 72 self.assertEqual( 73 src.car.starter( 74 key_is_close=True, 75 brake_is_pressed=False, 76 start_is_pressed=False, 77 in_park=True, 78 ), 79 OFF 80 ) 81 82 def test_key_far_brake_pressed(self):still green
I add an assertion for when the key is close, the brake is NOT pressed, the start button is NOT pressed and the car gear is NOT in park
key
brake
start
gear
output
close
NOT pressed
pressed
in park
OFF
close
NOT pressed
pressed
NOT in park
OFF
close
NOT pressed
NOT pressed
in park
OFF
close
NOT pressed
NOT pressed
NOT in park
OFF
51 def test_key_close_brake_not_pressed(self): 52 self.assertEqual( 53 src.car.starter( 54 key_is_close=True, 55 brake_is_pressed=False, 56 start_is_pressed=True, 57 in_park=True, 58 ), 59 OFF 60 ) 61 62 self.assertEqual( 63 src.car.starter( 64 key_is_close=True, 65 brake_is_pressed=False, 66 start_is_pressed=True, 67 in_park=False, 68 ), 69 OFF 70 ) 71 72 self.assertEqual( 73 src.car.starter( 74 key_is_close=True, 75 brake_is_pressed=False, 76 start_is_pressed=False, 77 in_park=True, 78 ), 79 OFF 80 ) 81 82 self.assertEqual( 83 src.car.starter( 84 key_is_close=True, 85 brake_is_pressed=False, 86 start_is_pressed=False, 87 in_park=False, 88 ), 89 OFF 90 ) 91 92 def test_key_far_brake_pressed(self):green
I change the name of the test from test_key_close_brake_not_pressed to test_key_close_brake_not_pressed_w_gear
41 self.assertEqual( 42 src.car.starter( 43 key_is_close=True, 44 brake_is_pressed=True, 45 start_is_pressed=False, 46 in_park=False, 47 ), 48 OFF 49 ) 50 51 def test_key_close_brake_not_pressed_w_gear(self): 52 self.assertEqual( 53 src.car.starter( 54 key_is_close=True, 55 brake_is_pressed=False, 56 start_is_pressed=True, 57 in_park=True, 58 ), 59 OFF 60 )
test_key_far_brake_pressed_w_gear
The truth table for when the key is far from the starter and the brake is being pressed is
key |
brake |
start |
gear |
output |
|---|---|---|---|---|
far |
pressed |
pressed |
in park |
OFF |
far |
pressed |
pressed |
NOT in park |
OFF |
far |
pressed |
NOT pressed |
in park |
OFF |
far |
pressed |
NOT pressed |
NOT in park |
OFF |
I add a value for the
in_parkparameter in the first assertion of test_key_far_brake_pressed, for when the key is far from the starter, the brake is being pressed, the start button is pressed, and the car gear is in parkkey
brake
start
gear
output
far
pressed
pressed
in park
OFF
92 def test_key_far_brake_pressed(self): 93 self.assertEqual( 94 src.car.starter( 95 key_is_close=False, 96 brake_is_pressed=True, 97 start_is_pressed=True, 98 in_park=True, 99 ), 100 OFF 101 )still green
I add an assertion for when the key is far from the starter, the brake is being pressed, the start button is pressed and the car gear is NOT in park
key
brake
start
gear
output
far
pressed
pressed
in park
OFF
far
pressed
pressed
NOT in park
OFF
92 def test_key_far_brake_pressed(self): 93 self.assertEqual( 94 src.car.starter( 95 key_is_close=False, 96 brake_is_pressed=True, 97 start_is_pressed=True, 98 in_park=True, 99 ), 100 OFF 101 ) 102 103 self.assertEqual( 104 src.car.starter( 105 key_is_close=False, 106 brake_is_pressed=True, 107 start_is_pressed=True, 108 in_park=False, 109 ), 110 OFF 111 ) 112 113 self.assertEqual( 114 src.car.starter( 115 key_is_close=False, 116 brake_is_pressed=True, 117 start_is_pressed=False, 118 ), 119 OFF 120 ) 121 122 def test_key_far_brake_not_pressed(self):still green
I add a value for the
in_parkparameter to the next assertion for when the key is far from the starter, the brake is being pressed, the start button is NOT pressed, and the car gear is in parkkey
brake
start
gear
output
far
pressed
pressed
in park
OFF
far
pressed
pressed
NOT in park
OFF
far
pressed
NOT pressed
in park
OFF
92 def test_key_far_brake_pressed(self): 93 self.assertEqual( 94 src.car.starter( 95 key_is_close=False, 96 brake_is_pressed=True, 97 start_is_pressed=True, 98 in_park=True, 99 ), 100 OFF 101 ) 102 103 self.assertEqual( 104 src.car.starter( 105 key_is_close=False, 106 brake_is_pressed=True, 107 start_is_pressed=True, 108 in_park=False, 109 ), 110 OFF 111 ) 112 113 self.assertEqual( 114 src.car.starter( 115 key_is_close=False, 116 brake_is_pressed=True, 117 start_is_pressed=False, 118 in_park=True, 119 ), 120 OFF 121 ) 122 123 def test_key_far_brake_not_pressed(self):the test is still green
I add an assertion for when the key is far from the starter, the brake is being pressed, the start button is NOT pressed, and the car gear is NOT in park
key
brake
start
gear
output
far
pressed
pressed
in park
OFF
far
pressed
pressed
NOT in park
OFF
far
pressed
NOT pressed
in park
OFF
far
pressed
NOT pressed
NOT in park
OFF
92 def test_key_far_brake_pressed(self): 93 self.assertEqual( 94 src.car.starter( 95 key_is_close=False, 96 brake_is_pressed=True, 97 start_is_pressed=True, 98 in_park=True, 99 ), 100 OFF 101 ) 102 103 self.assertEqual( 104 src.car.starter( 105 key_is_close=False, 106 brake_is_pressed=True, 107 start_is_pressed=True, 108 in_park=False, 109 ), 110 OFF 111 ) 112 113 self.assertEqual( 114 src.car.starter( 115 key_is_close=False, 116 brake_is_pressed=True, 117 start_is_pressed=False, 118 in_park=True, 119 ), 120 OFF 121 ) 122 123 self.assertEqual( 124 src.car.starter( 125 key_is_close=False, 126 brake_is_pressed=True, 127 start_is_pressed=False, 128 in_park=False, 129 ), 130 OFF 131 ) 132 133 def test_key_far_brake_not_pressed(self):still green
I change the name of the test from test_key_far_brake_pressed to test_key_far_brake_pressed_w_gear
82 self.assertEqual( 83 src.car.starter( 84 key_is_close=True, 85 brake_is_pressed=False, 86 start_is_pressed=False, 87 in_park=False, 88 ), 89 OFF 90 ) 91 92 def test_key_far_brake_pressed_w_gear(self): 93 self.assertEqual( 94 src.car.starter( 95 key_is_close=False, 96 brake_is_pressed=True, 97 start_is_pressed=True, 98 in_park=True, 99 ), 100 OFF 101 )
test_key_far_brake_not_pressed_w_gear
The truth table for when the key is far from the starter and the brake is NOT pressed is
key |
brake |
start |
gear |
output |
|---|---|---|---|---|
far |
NOT pressed |
pressed |
in park |
OFF |
far |
NOT pressed |
pressed |
NOT in park |
OFF |
far |
NOT pressed |
NOT pressed |
in park |
OFF |
far |
NOT pressed |
NOT pressed |
NOT in park |
OFF |
I add a value for the
in_parkparameter to the first assertion in test_key_far_brake_not_pressed, for when the key is far from the starter, the brake is NOT pressed, the start button is pressed, and the car gear is in parkkey
brake
start
gear
output
far
NOT pressed
pressed
in park
OFF
133 def test_key_far_brake_not_pressed(self): 134 self.assertEqual( 135 src.car.starter( 136 key_is_close=False, 137 brake_is_pressed=False, 138 start_is_pressed=True, 139 in_park=True, 140 ), 141 OFF 142 )the test is still green
I add an assertion for when the key is far from the starter, the brake is NOT pressed, the start button is pressed, and the car gear is NOT in park
key
brake
start
gear
output
far
NOT pressed
pressed
in park
OFF
far
NOT pressed
pressed
NOT in park
OFF
133 def test_key_far_brake_not_pressed(self): 134 self.assertEqual( 135 src.car.starter( 136 key_is_close=False, 137 brake_is_pressed=False, 138 start_is_pressed=True, 139 in_park=True, 140 ), 141 OFF 142 ) 143 144 self.assertEqual( 145 src.car.starter( 146 key_is_close=False, 147 brake_is_pressed=False, 148 start_is_pressed=True, 149 in_park=False, 150 ), 151 OFF 152 ) 153 154 self.assertEqual( 155 src.car.starter( 156 key_is_close=False, 157 brake_is_pressed=False, 158 start_is_pressed=False, 159 ), 160 OFF 161 ) 162 163 164# Exceptions seenstill green
I add a value for the
in_parkparameter to the next assertion, for when the key is far from the starter, the brake is NOT pressed, the start button is NOT pressed, and the car gear is in parkkey
brake
start
gear
output
far
NOT pressed
pressed
in park
OFF
far
NOT pressed
pressed
NOT in park
OFF
far
NOT pressed
NOT pressed
in park
OFF
133 def test_key_far_brake_not_pressed(self): 134 self.assertEqual( 135 src.car.starter( 136 key_is_close=False, 137 brake_is_pressed=False, 138 start_is_pressed=True, 139 in_park=True, 140 ), 141 OFF 142 ) 143 144 self.assertEqual( 145 src.car.starter( 146 key_is_close=False, 147 brake_is_pressed=False, 148 start_is_pressed=True, 149 in_park=False, 150 ), 151 OFF 152 ) 153 154 self.assertEqual( 155 src.car.starter( 156 key_is_close=False, 157 brake_is_pressed=False, 158 start_is_pressed=False, 159 in_park=True, 160 ), 161 OFF 162 )green
I add an assertion for when the key is far from the starter, the brake is NOT pressed, the start button is NOT pressed, and the car gear is NOT in park
key
brake
start
gear
output
far
NOT pressed
pressed
in park
OFF
far
NOT pressed
pressed
NOT in park
OFF
far
NOT pressed
NOT pressed
in park
OFF
far
NOT pressed
NOT pressed
NOT in park
OFF
133 def test_key_far_brake_not_pressed(self): 134 self.assertEqual( 135 src.car.starter( 136 key_is_close=False, 137 brake_is_pressed=False, 138 start_is_pressed=True, 139 in_park=True, 140 ), 141 OFF 142 ) 143 144 self.assertEqual( 145 src.car.starter( 146 key_is_close=False, 147 brake_is_pressed=False, 148 start_is_pressed=True, 149 in_park=False, 150 ), 151 OFF 152 ) 153 154 self.assertEqual( 155 src.car.starter( 156 key_is_close=False, 157 brake_is_pressed=False, 158 start_is_pressed=False, 159 in_park=True, 160 ), 161 OFF 162 ) 163 164 self.assertEqual( 165 src.car.starter( 166 key_is_close=False, 167 brake_is_pressed=False, 168 start_is_pressed=False, 169 in_park=False, 170 ), 171 OFF 172 ) 173 174 175# Exceptions seenall the tests are still green
I change the name of the test from test_key_far_brake_not_pressed to test_key_far_brake_not_pressed_w_gear
123 self.assertEqual( 124 src.car.starter( 125 key_is_close=False, 126 brake_is_pressed=True, 127 start_is_pressed=False, 128 in_park=False, 129 ), 130 OFF 131 ) 132 133 def test_key_far_brake_not_pressed_w_gear(self): 134 self.assertEqual( 135 src.car.starter( 136 key_is_close=False, 137 brake_is_pressed=False, 138 start_is_pressed=True, 139 in_park=True, 140 ), 141 OFF 142 )
close the project
review
I ran tests for a car with these inputs:
is the key close to the starter?
is the brake being pressed?
was the start button pressed?
is the car in park?
the inputs gave me this truth table
key |
brake |
start |
gear |
output |
|---|---|---|---|---|
close |
pressed |
pressed |
in park |
ON |
close |
pressed |
pressed |
NOT in park |
OFF |
close |
pressed |
NOT pressed |
in park |
OFF |
close |
pressed |
NOT pressed |
NOT in park |
OFF |
key |
brake |
start |
gear |
output |
|---|---|---|---|---|
close |
NOT pressed |
pressed |
in park |
OFF |
close |
NOT pressed |
pressed |
NOT in park |
OFF |
close |
NOT pressed |
NOT pressed |
in park |
OFF |
close |
NOT pressed |
NOT pressed |
NOT in park |
OFF |
key |
brake |
start |
gear |
output |
|---|---|---|---|---|
far |
pressed |
pressed |
in park |
OFF |
far |
pressed |
pressed |
NOT in park |
OFF |
far |
pressed |
NOT pressed |
in park |
OFF |
far |
pressed |
NOT pressed |
NOT in park |
OFF |
key |
brake |
start |
gear |
output |
|---|---|---|---|---|
far |
NOT pressed |
pressed |
in park |
OFF |
far |
NOT pressed |
pressed |
NOT in park |
OFF |
far |
NOT pressed |
NOT pressed |
in park |
OFF |
far |
NOT pressed |
NOT pressed |
NOT in park |
OFF |
the only time I can start this car is when the key is close to the starter, the brake is being pressed, the start button is pressed and the car gear is in park.
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