Traffic Light: tests and solutions
makePythonTdd TrafficLight
The code in makePythonTdd.sh from Traffic Light
1#!/bin/bash 2uv init traffic_light 3cd traffic_light 4mkdir tests 5touch tests/__init__.py 6 7echo "import unittest 8 9 10class TestTrafficLight(unittest.TestCase): 11 12 def test_failure(self): 13 self.assertFalse(True) 14 15 16# Exceptions seen 17# AssertionError 18" > tests/test_traffic_light.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 Traffic Light
1uv init traffic_light 2cd traffic_light 3mkdir tests 4New-Item tests/__init__.py 5 6"import unittest 7 8 9class TestTrafficLight(unittest.TestCase): 10 11 def test_failure(self): 12 self.assertFalse(True) 13 14 15# Exceptions seen 16# AssertionError 17" | Out-File "tests/test_traffic_light.py" -Encoding UTF8 18 19"pytest" | Out-File requirements.txt -Encoding UTF8 20"pytest-watcher" >> requirements.txt 21uv add --requirement requirements.txt 22uv run pytest-watcher . --now
Traffic Light: tests
The code in traffic_light/tests/test_traffic_light.py from Traffic Light
1import src.traffic_light
2import unittest
3
4
5GREEN, YELLOW, RED = 'GREEN', 'YELLOW', 'RED'
6
7
8class TestTrafficLight(unittest.TestCase):
9
10 def test_parallel_green_cross_red_timer_not_done(self):
11 self.assertEqual(
12 src.traffic_light.control(
13 red_phase='cross',
14 current_parallel=GREEN,
15 current_cross=RED,
16 timer_done=False,
17 ),
18 (GREEN, RED)
19 )
20
21 def test_parallel_green_cross_red_timer_done(self):
22 self.assertEqual(
23 src.traffic_light.control(
24 red_phase='cross',
25 current_parallel=GREEN,
26 current_cross=RED,
27 timer_done=True,
28 ),
29 (YELLOW, RED)
30 )
32 def test_parallel_yellow_cross_red_timer_not_done(self):
33 self.assertEqual(
34 src.traffic_light.control(
35 red_phase='cross',
36 current_parallel=YELLOW,
37 current_cross=RED,
38 timer_done=False,
39 ),
40 (YELLOW, RED)
41 )
42
43 def test_parallel_yellow_cross_red_timer_done(self):
44 self.assertEqual(
45 src.traffic_light.control(
46 red_phase='cross',
47 current_parallel=YELLOW,
48 current_cross=RED,
49 timer_done=True,
50 ),
51 (RED, RED)
52 )
54 def test_parallel_red_cross_red_timer_not_done(self):
55 self.assertEqual(
56 src.traffic_light.control(
57 red_phase='cross',
58 current_parallel=RED,
59 current_cross=RED,
60 timer_done=False,
61 ),
62 (RED, RED)
63 )
64
65 def test_parallel_red_cross_red_timer_done(self):
66 self.assertEqual(
67 src.traffic_light.control(
68 red_phase='cross',
69 current_parallel=RED,
70 current_cross=RED,
71 timer_done=True,
72 ),
73 (RED, GREEN)
74 )
76 def test_cross_green_parallel_red_timer_not_done(self):
77 self.assertEqual(
78 src.traffic_light.control(
79 red_phase='parallel',
80 current_parallel=RED,
81 current_cross=GREEN,
82 timer_done=False,
83 ),
84 (RED, GREEN)
85 )
86
87 def test_cross_green_parallel_red_timer_done(self):
88 self.assertEqual(
89 src.traffic_light.control(
90 red_phase='parallel',
91 current_parallel=RED,
92 current_cross=GREEN,
93 timer_done=True,
94 ),
95 (RED, YELLOW)
96 )
98 def test_cross_yellow_parallel_red_timer_not_done(self):
99 self.assertEqual(
100 src.traffic_light.control(
101 red_phase='parallel',
102 current_parallel=RED,
103 current_cross=YELLOW,
104 timer_done=False,
105 ),
106 (RED, YELLOW)
107 )
108
109 def test_cross_yellow_parallel_red_timer_done(self):
110 self.assertEqual(
111 src.traffic_light.control(
112 red_phase='parallel',
113 current_parallel=RED,
114 current_cross=YELLOW,
115 timer_done=True,
116 ),
117 (RED, RED)
118 )
120 def test_cross_red_parallel_red_timer_not_done(self):
121 self.assertEqual(
122 src.traffic_light.control(
123 red_phase='parallel',
124 current_parallel=RED,
125 current_cross=RED,
126 timer_done=False,
127 ),
128 (RED, RED)
129 )
130
131 def test_cross_red_parallel_red_timer_done(self):
132 self.assertEqual(
133 src.traffic_light.control(
134 red_phase='parallel',
135 current_parallel=RED,
136 current_cross=RED,
137 timer_done=True,
138 ),
139 (GREEN, RED)
140 )
142 def test_failsafe(self):
143 self.assertEqual(
144 src.traffic_light.control(
145 red_phase='BOOM',
146 current_parallel='BAP',
147 current_cross=RED,
148 timer_done=False,
149 ),
150 (RED, RED)
151 )
152 self.assertEqual(
153 src.traffic_light.control(
154 red_phase='BOOM',
155 current_parallel=RED,
156 current_cross='POW',
157 timer_done=False,
158 ),
159 (RED, RED)
160 )
161 self.assertEqual(
162 src.traffic_light.control(
163 red_phase='BOOM',
164 current_parallel=GREEN,
165 current_cross=GREEN,
166 timer_done=False,
167 ),
168 (RED, RED)
169 )
170 self.assertEqual(
171 src.traffic_light.control(
172 red_phase='BOOM',
173 current_parallel=GREEN,
174 current_cross=YELLOW,
175 timer_done=False,
176 ),
177 (RED, RED)
178 )
179 self.assertEqual(
180 src.traffic_light.control(
181 red_phase='BOOM',
182 current_parallel=YELLOW,
183 current_cross=GREEN,
184 timer_done=False,
185 ),
186 (RED, RED)
187 )
188 self.assertEqual(
189 src.traffic_light.control(
190 red_phase='BOOM',
191 current_parallel=YELLOW,
192 current_cross=YELLOW,
193 timer_done=False,
194 ),
195 (RED, RED)
196 )
197
198
199# Exceptions seen
200# AssertionError
201# NameError
202# AttributeError
203# TypeError
Traffic Light: solution
The code in traffic_light/src/traffic_light/__init__.py from Traffic Light
1RED, YELLOW, GREEN = 'RED', 'YELLOW', 'GREEN'
2
3
4def is_not_safe(parallel, cross):
5 return (
6 (parallel == cross != RED)
7 or (parallel == GREEN and cross == YELLOW)
8 or (parallel == YELLOW and cross == GREEN)
9 )
10
11
12def is_not_light(light):
13 return not (
14 light == GREEN or light == YELLOW or light == RED
15 )
16
17
18def triggers_failsafe(parallel, cross):
19 return (
20 is_not_light(parallel) or is_not_light(cross)
21 or is_not_safe(parallel, cross)
22 )
23
24
25def next_light(red_phase, parallel, cross):
26 if red_phase == 'cross':
27 if parallel == GREEN:
28 return YELLOW, RED
29 if parallel == RED:
30 return RED, GREEN
31 if red_phase == 'parallel':
32 if cross == GREEN:
33 return RED, YELLOW
34 if cross == RED:
35 return GREEN, RED
36 return RED, RED
37
38
39def control(
40 timer_done, red_phase='parallel',
41 current_parallel=RED, current_cross=RED,
42 ):
43 if triggers_failsafe(current_parallel, current_cross):
44 return RED, RED
45
46 if not timer_done:
47 return current_parallel, current_cross
48
49 if timer_done:
50 return next_light(
51 red_phase, current_parallel, current_cross
52 )
53
54 return RED, RED