Traffic Light


I use the truth table to build a Traffic Light that changes color based on a timer, if the inputs are

  • what color is the light now?

  • is the timer done?

Here is the truth table for the traffic light

current light

timer done

show

RED

yes

GREEN

RED

no

RED

YELLOW

yes

RED

YELLOW

no

YELLOW

GREEN

yes

YELLOW

GREEN

no

GREEN

preview

Here are the tests I have at the end of this chapter

  1import src.traffic_light
  2import unittest
  3
  4
  5RED, YELLOW, GREEN = 'RED', 'YELLOW', 'GREEN'
  6NO_WALK = 'NO WALK'
  7WALK = (RED, 'WALK')
  8YELLOW_NO_WALK = (YELLOW, NO_WALK)
  9GREEN_NO_WALK = (GREEN, NO_WALK)
 10
 11
 12class TestTrafficLight(unittest.TestCase):
 13
 14    def test_traffic_light_when_red_w_walk_button(self):
 15        self.assertEqual(
 16            src.traffic_light.show(
 17                timer_done=True,
 18                walk_button=True,
 19            ),
 20            WALK
 21        )
 22
 23        self.assertEqual(
 24            src.traffic_light.show(
 25                timer_done=True,
 26                walk_button=False
 27            ),
 28            GREEN_NO_WALK
 29        )
 30
 31        self.assertEqual(
 32            src.traffic_light.show(
 33                timer_done=False,
 34                walk_button=True,
 35            ),
 36            WALK
 37        )
 38
 39        self.assertEqual(
 40            src.traffic_light.show(
 41                timer_done=False,
 42                walk_button=False,
 43            ),
 44            WALK
 45        )
 46
 47    def test_traffic_light_when_yellow_w_walk_button(self):
 48        self.assertEqual(
 49            src.traffic_light.show(
 50                current_light=YELLOW,
 51                timer_done=True,
 52                walk_button=True,
 53            ),
 54            WALK
 55        )
 56
 57        self.assertEqual(
 58            src.traffic_light.show(
 59                current_light=YELLOW,
 60                timer_done=True,
 61                walk_button=False,
 62            ),
 63            WALK
 64        )
 65
 66        self.assertEqual(
 67            src.traffic_light.show(
 68                current_light=YELLOW,
 69                timer_done=False,
 70                walk_button=True,
 71            ),
 72            YELLOW_NO_WALK
 73        )
 74
 75        self.assertEqual(
 76            src.traffic_light.show(
 77                current_light=YELLOW,
 78                timer_done=False,
 79                walk_button=False,
 80            ),
 81            YELLOW_NO_WALK
 82        )
 83
 84    def test_traffic_light_when_green_w_walk_button(self):
 85        self.assertEqual(
 86            src.traffic_light.show(
 87                current_light=GREEN,
 88                timer_done=True,
 89                walk_button=True,
 90            ),
 91            YELLOW_NO_WALK
 92        )
 93
 94        self.assertEqual(
 95            src.traffic_light.show(
 96                current_light=GREEN,
 97                timer_done=True,
 98                walk_button=False,
 99            ),
100            YELLOW_NO_WALK
101        )
102
103        self.assertEqual(
104            src.traffic_light.show(
105                current_light=GREEN,
106                timer_done=False,
107                walk_button=True,
108            ),
109            GREEN_NO_WALK
110        )
111
112        self.assertEqual(
113            src.traffic_light.show(
114                current_light=GREEN,
115                timer_done=False,
116                walk_button=False,
117            ),
118            GREEN_NO_WALK
119        )
120
121
122# Exceptions seen
123# AssertionError
124# NameError
125# AttributeError
126# TypeError
127# SyntaxError

requirements


start the project

  • I name this project traffic_light

  • I open a terminal

  • I make a directory for the project

    mkdir traffic_light
    

    the terminal goes back to the command line

  • I change directory to the project

    cd traffic_light
    

    the terminal shows I am in the traffic_light folder

    .../pumping_python/traffic_light
    
  • I make a directory for the source code

    mkdir src
    

    the terminal goes back to the command line

  • I make a Python file to hold the source code in the src directory

    touch src/traffic_light.py
    
    New-Item src/traffic_light.py
    

    the terminal goes back to the command line

  • I make a directory for the tests

    mkdir tests
    

    the terminal goes back to the command line

  • I make the tests directory a Python package

    Danger

    use 2 underscores (__) before and after init for __init__.py not _init_.py

    touch tests/__init__.py
    
    New-Item tests/__init__.py
    

    the terminal goes back to the command line

  • I make a Python file for the tests in the tests directory

    touch tests/test_traffic_light.py
    
    New-Item tests/test_traffic_light.py
    

    the terminal goes back to the command line

  • I open test_traffic_light.py in 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_traffic_light.py
    

    Visual Studio Code opens test_traffic_light.py in the editor

  • I add the first failing test to test_traffic_light.py

    1import unittest
    2
    3
    4class TestTrafficLight(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.txt
    

    the terminal goes back to the command line

  • I add pytest-watcher to the file

    echo "pytest-watcher" >> requirements.txt
    

    the terminal goes back to the command line

  • I setup the project with uv

    uv init
    

    the terminal shows

    Initialized project `traffic-light-controller`
    

    then goes back to the command line

  • I remove main.py from the project because I do not use it

    rm main.py
    

    the terminal goes back to the command line

  • I install the Python packages that I wrote in the requirements file

    uv add --requirement requirements.txt
    

    the terminal shows it installed the Python packages

  • I use pytest-watcher to run the tests automatically

    uv run pytest-watcher . --now
    

    the terminal shows

    ================================ FAILURES ================================
    ____________________ TestTrafficLight.test_failure _______________________
    
    self = <tests.test_traffic_light.TestTrafficLight testMethod=test_failure>
    
        def test_failure(self):
    >       self.assertFalse(True)
    E       AssertionError: True is not false
    
    tests/test_traffic_light.py:7: AssertionError
    ======================== short test summary info =========================
    FAILED tests/test_traffic_light.py::TestTrafficLight::test_failure - AssertionError: True is not false
    =========================== 1 failed in X.YZs ============================
    
  • I add AssertionError to the list of Exceptions seen in test_traffic_light.py

     4class TestTrafficLight(unittest.TestCase):
     5
     6    def test_failure(self):
     7        self.assertFalse(True)
     8
     9
    10# Exceptions seen
    11# AssertionError
    
  • then I change True to False in the assertion

    7        self.assertFalse(False)
    

    the test passes


test_traffic_light_when_red


RED: make it fail


I change test_failure to test_traffic_light_when_red

 4class TestTrafficLight(unittest.TestCase):
 5
 6    def test_traffic_light_when_red(self):(self):
 7        my_expectation = 'GREEN'
 8        reality = src.traffic_light.show(
 9            current_light='RED',
10            timer_done=True,
11        )
12        self.assertEqual(reality, my_expectation)
13
14
15  # Exceptions seen
16  # AssertionError

the terminal 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# NameError
    
  • I add an import statement at the top of the file

    1import src.traffic_light
    2import unittest
    

    the terminal shows AttributeError

    AttributeError: module 'src.traffic_light' has no attribute 'show'
    
  • I add AttributeError to the list of Exceptions seen

    16# Exceptions seen
    17# AssertionError
    18# NameError
    19# AttributeError
    
  • I open traffic_light.py from the src folder in the editor

  • I add a function to traffic_light.py

    1def show():
    2    return None
    

    the terminal shows TypeError

    TypeError: show() got an unexpected keyword argument 'current_light'
    
  • I add TypeError to the list of Exceptions seen in test_traffic_light.py

    16# Exceptions seen
    17# AssertionError
    18# NameError
    19# AttributeError
    20# TypeError
    
  • I add the keyword argument to the function in traffic_light.py

    1def show(current_light):
    2    return None
    

    the terminal shows TypeError

    TypeError: show() got an unexpected keyword argument 'timer_done'
    
  • I add timer_done to the function signature

    1def show(current_light, timer_done):
    2    return None
    

    the terminal shows AssertionError

    AssertionError: None != 'GREEN'
    
  • I change the return statement to give the test what it expects

    1def show(current_light, timer_done):
    2    return 'GREEN'
    

    the test passes


REFACTOR: make it better


  • I add another assertion for when the current light is RED and the timer has not expired, in test_traffic_light.py

     7    def test_traffic_light_when_red(self):
     8        my_expectation = 'GREEN'
     9        reality = src.traffic_light.show(
    10            current_light='RED',
    11            timer_done=True,
    12        )
    13        self.assertEqual(reality, my_expectation)
    14
    15        my_expectation = 'RED'
    16        reality = src.traffic_light.show(
    17            current_light='RED',
    18            timer_done=False,
    19        )
    20        self.assertEqual(reality, my_expectation)
    21
    22
    23# Exceptions seen
    

    the terminal shows AssertionError

    AssertionError: 'GREEN' != 'RED'
    
  • I add an if statement to traffic_light.py

    1def show(current_light, timer_done):
    2    if not timer_done:
    3        return 'RED'
    4    return 'GREEN'
    

    the test passes


test_traffic_light_when_yellow


RED: make it fail


I add another test for when the traffic light is red, to test_traffic_light.py

 7    def test_traffic_light_when_red(self):
 8        my_expectation = 'GREEN'
 9        reality = src.traffic_light.show(
10            current_light='RED',
11            timer_done=True,
12        )
13        self.assertEqual(reality, my_expectation)
14
15        my_expectation = 'RED'
16        reality = src.traffic_light.show(
17            current_light='RED',
18            timer_done=False,
19        )
20        self.assertEqual(reality, my_expectation)
21
22    def test_traffic_light_when_yellow(self):
23        my_expectation = 'RED'
24        reality = src.traffic_light.show(
25            current_light='YELLOW',
26            timer_done=True,
27        )
28        self.assertEqual(reality, my_expectation)
29
30
31# Exceptions seen

the terminal shows AssertionError

AssertionError: 'GREEN' != 'RED'

GREEN: make it pass


I add an if statement to traffic_light.py

1def show(current_light, timer_done):
2    if current_light == 'YELLOW':
3        if timer_done:
4            return 'RED'
5    if not timer_done:
6        return 'RED'
7    return 'GREEN'

the test passes


REFACTOR: make it better


  • I add another assertion to test_traffic_light.py

    22    def test_traffic_light_when_yellow(self):
    23        my_expectation = 'RED'
    24        reality = src.traffic_light.show(
    25            current_light='YELLOW',
    26            timer_done=True,
    27        )
    28        self.assertEqual(reality, my_expectation)
    29
    30        my_expectation = 'YELLOW'
    31        reality = src.traffic_light.show(
    32            current_light='YELLOW',
    33            timer_done=False,
    34        )
    35        self.assertEqual(reality, my_expectation)
    36
    37
    38# Exceptions seen
    

    the terminal shows AssertionError

    AssertionError: 'RED' != 'YELLOW'
    
  • I add an if statement to traffic_light.py

    1def show(current_light, timer_done):
    2    if current_light == 'YELLOW':
    3        if timer_done:
    4            return 'RED'
    5        else:
    6            return 'YELLOW'
    7    if not timer_done:
    8        return 'RED'
    9    return 'GREEN'
    

    the test passes


test_traffic_light_when_green


RED: make it fail


I add a test for when the traffic light is green, to test_traffic_light.py

22    def test_traffic_light_when_yellow(self):
23        my_expectation = 'RED'
24        reality = src.traffic_light.show(
25            current_light='YELLOW',
26            timer_done=True,
27        )
28        self.assertEqual(reality, my_expectation)
29
30        my_expectation = 'YELLOW'
31        reality = src.traffic_light.show(
32            current_light='YELLOW',
33            timer_done=False,
34        )
35        self.assertEqual(reality, my_expectation)
36
37    def test_traffic_light_when_green(self):
38        my_expectation = 'YELLOW'
39        reality = src.traffic_light.show(
40            current_light='GREEN',
41            timer_done=True,
42        )
43        self.assertEqual(reality, my_expectation)
44
45
46# Exceptions seen

the terminal shows AssertionError

AssertionError: 'GREEN' != 'YELLOW'

GREEN: make it pass


I add an if statement to traffic_light.py

 1def show(current_light, timer_done):
 2    if current_light == 'GREEN':
 3        if timer_done:
 4            return 'YELLOW'
 5    if current_light == 'YELLOW':
 6        if timer_done:
 7            return 'RED'
 8        else:
 9            return 'YELLOW'
10    if not timer_done:
11        return 'RED'
12    return 'GREEN'

the test passes


REFACTOR: make it better


  • I add an assertion to test_traffic_light.py

    37    def test_traffic_light_when_green(self):
    38        my_expectation = 'YELLOW'
    39        reality = src.traffic_light.show(
    40            current_light='GREEN',
    41            timer_done=True,
    42        )
    43        self.assertEqual(reality, my_expectation)
    44
    45        my_expectation = 'GREEN'
    46        reality = src.traffic_light.show(
    47            current_light='GREEN',
    48            timer_done=False,
    49        )
    50        self.assertEqual(reality, my_expectation)
    51
    52
    53# Exceptions seen
    

    the terminal shows AssertionError

    AssertionError: 'RED' != 'YELLOW'
    
  • I add an if statement to traffic_light.py

     1def show(current_light, timer_done):
     2    if current_light == 'GREEN':
     3        if timer_done:
     4            return 'YELLOW'
     5        else:
     6            return 'GREEN'
     7    if current_light == 'YELLOW':
     8        if timer_done:
     9            return 'RED'
    10        else:
    11            return 'YELLOW'
    12    if not timer_done:
    13        return 'RED'
    14    return 'GREEN'
    

    the test passes

  • I add variables for the colors to remove repetition

     1def show(current_light, timer_done):
     2    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     3
     4    if current_light == 'GREEN':
     5        if timer_done:
     6            return 'YELLOW'
     7        else:
     8            return 'GREEN'
     9    if current_light == 'YELLOW':
    10        if timer_done:
    11            return 'RED'
    12        else:
    13            return 'YELLOW'
    14    if not timer_done:
    15        return 'RED'
    16    return 'GREEN'
    
  • I use the new variables

     1def show(current_light, timer_done):
     2    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     3
     4    # if current_light == 'GREEN':
     5    if current_light == green:
     6        if timer_done:
     7            # return 'YELLOW'
     8            return yellow
     9        else:
    10            # return 'GREEN'
    11            return green
    12    # if current_light == 'YELLOW':
    13    if current_light == yellow:
    14        if timer_done:
    15            # return 'RED'
    16            return red
    17        else:
    18            # return 'YELLOW'
    19            return yellow
    20    if not timer_done:
    21        # return 'RED'
    22        return red
    23    # return 'GREEN'
    24    return green
    

    the test is still green

  • I remove the commented lines

     1def show(current_light, timer_done):
     2    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     3
     4    if current_light == green:
     5        if timer_done:
     6            return yellow
     7        else:
     8            return green
     9    if current_light == yellow:
    10        if timer_done:
    11            return red
    12        else:
    13            return yellow
    14    if not timer_done:
    15        return red
    16    return green
    
  • I add a new if statement for it the timer because it controls the traffic lights

     1def show(current_light, timer_done):
     2    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     3
     4    if timer_done:
     5        if current_light == green:
     6            return yellow
     7        if current_light == yellow:
     8            return red
     9        if current_light == red:
    10            return green
    11    if current_light == green:
    12        if timer_done:
    13            return yellow
    14        else:
    15            return green
    16    if current_light == yellow:
    17        if timer_done:
    18            return red
    19        else:
    20            return yellow
    21    if not timer_done:
    22        return red
    23    return green
    

    the test is still green

  • I add an else clause

     1def show(current_light, timer_done):
     2    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     3
     4    if timer_done:
     5        if current_light == green:
     6            return yellow
     7        if current_light == yellow:
     8            return red
     9        if current_light == red:
    10            return green
    11    else:
    12        return current_light
    13
    14    if current_light == green:
    15        if timer_done:
    16            return yellow
    17        else:
    18            return green
    19    if current_light == yellow:
    20        if timer_done:
    21            return red
    22        else:
    23            return yellow
    24    if not timer_done:
    25        return red
    26    return green
    

    still green

  • I remove the other if statements

     1def show(current_light, timer_done):
     2    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     3
     4    if timer_done:
     5        if current_light == green:
     6            return yellow
     7        if current_light == yellow:
     8            return red
     9        if current_light == red:
    10            return green
    11    else:
    12        return current_light
    

    green

  • I add a variable for the next light

     1def show(current_light, timer_done):
     2    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     3    next_light = red
     4
     5    if timer_done:
     6        if current_light == green:
     7            return yellow
     8        if current_light == yellow:
     9            return red
    10        if current_light == red:
    11            return green
    12    else:
    13        return current_light
    
  • I use the new variable in each condition

     1def show(current_light, timer_done):
     2    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     3    next_light = red
     4
     5    if timer_done:
     6        if current_light == green:
     7            next_light = yellow
     8            return yellow
     9        if current_light == yellow:
    10            next_light = red
    11            return red
    12        if current_light == red:
    13            next_light = green
    14            return green
    15    else:
    16        next_light = current_light
    17        return current_light
    

    the test is still green

  • I add a return statement for the variable

     1def show(current_light, timer_done):
     2    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     3    next_light = red
     4
     5    if timer_done:
     6        if current_light == green:
     7            next_light = yellow
     8            return yellow
     9        if current_light == yellow:
    10            next_light = red
    11            return red
    12        if current_light == red:
    13            next_light = green
    14            return green
    15    else:
    16        next_light = current_light
    17        return current_light
    18
    19    return next_light
    
  • I remove the other return statements

     1def show(current_light, timer_done):
     2    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     3    next_light = red
     4
     5    if timer_done:
     6        if current_light == green:
     7            next_light = yellow
     8        if current_light == yellow:
     9            next_light = red
    10        if current_light == red:
    11            next_light = green
    12    else:
    13        next_light = current_light
    14
    15    return next_light
    

    still green

  • I remove the if statement for when the light is 'YELLOW' because I no longer need it

     1def show(current_light, timer_done):
     2    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     3    next_light = red
     4
     5    if timer_done:
     6        if current_light == green:
     7            next_light = yellow
     8        if current_light == red:
     9            next_light = green
    10    else:
    11        next_light = current_light
    12
    13    return next_light
    

    the test is still green


test_traffic_light_when_red_w_walk_button


I want to add a button for people to push when they want to cross the street, the inputs for the traffic light will now be

  • what color is the light now?

  • is the timer done?

  • did the person push the walk button?

and the truth table when the traffic light is RED is

current light

timer done

walk button

show

RED

yes

yes

RED

RED

yes

no

GREEN

RED

no

yes

RED

RED

no

no

RED


RED: make it fail


I add walk_button to the call to src.traffic_light.show in the first assertion of test_traffic_light_when_red in test_traffic_light.py

 7    def test_traffic_light_when_red(self):
 8        my_expectation = 'GREEN'
 9        reality = src.traffic_light.show(
10            current_light='RED',
11            timer_done=True,
12            walk_button=True,
13        )
14        self.assertEqual(reality, my_expectation)
15
16        my_expectation = 'RED'
17        reality = src.traffic_light.show(
18            current_light='RED',
19            timer_done=False,
20        )
21        self.assertEqual(reality, my_expectation)
22
23    def test_traffic_light_when_yellow(self):

the terminal shows TypeError

TypeError: show() got an unexpected keyword argument 'walk_button'

GREEN: make it pass


  • I add a keyword argument in traffic_light.py

    1def show(current_light, timer_done, walk_button):
    

    the terminal shows 3 failures with TypeError

    FAILED ...test_traffic_light_when_green - TypeError: show() missing 1 required positional arg...
    FAILED ...test_traffic_light_when_red - TypeError: show() missing 1 required positional arg...
    FAILED ...test_traffic_light_when_yellow - TypeError: show() missing 1 required positional arg...
    
  • I add a default value for the new keyword argument

    1def show(
    2        current_light, timer_done,
    3        walk_button=False,
    4    ):
    

    the test passes


REFACTOR: make it better


  • I change the expectation for when the light is RED, the timer is done and the walk button is pushed

     7    def test_traffic_light_when_red(self):
     8        my_expectation = 'RED'
     9        reality = src.traffic_light.show(
    10            current_light='RED',
    11            timer_done=True,
    12            walk_button=True,
    13        )
    14        self.assertEqual(reality, my_expectation)
    

    the terminal shows AssertionError

    AssertionError: 'GREEN' != 'RED'
    
  • I add an if statement with an else clause to traffic_light.py

     1def show(
     2        current_light, timer_done,
     3        walk_button=False,
     4    ):
     5    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     6    next_light = red
     7
     8    if timer_done:
     9        if current_light == green:
    10            next_light = yellow
    11        if current_light == red:
    12            if walk_button:
    13                next_light = red
    14            else:
    15                next_light = green
    16    else:
    17        next_light = current_light
    18
    19    return next_light
    

    the test passes

  • I add an assertion for when the light is RED, the timer is done and the walk button has not been pushed, to test_traffic_light_when_red in test_traffic_light.py

     7    def test_traffic_light_when_red(self):
     8        my_expectation = 'RED'
     9        reality = src.traffic_light.show(
    10            current_light='RED',
    11            timer_done=True,
    12            walk_button=True,
    13        )
    14        self.assertEqual(reality, my_expectation)
    15
    16        my_expectation = 'GREEN'
    17        reality = src.traffic_light.show(
    18            current_light='RED',
    19            timer_done=True,
    20            walk_button=False
    21        )
    22        self.assertEqual(reality, my_expectation)
    23
    24        my_expectation = 'RED'
    25        reality = src.traffic_light.show(
    26            current_light='RED',
    27            timer_done=False,
    28            walk_button=False,
    29        )
    30        self.assertEqual(reality, my_expectation)
    31
    32    def test_traffic_light_when_yellow(self):
    

    the test is still green

  • I change the expectation to make sure the test works

    16        my_expectation = 'BOOM'
    

    the terminal shows AssertionError

    AssertionError: 'GREEN' != 'BOOM'
    
  • I change the expectation back

    16        my_expectation = 'GREEN'
    17        reality = src.traffic_light.show(
    18            current_light='RED',
    19            timer_done=True,
    20            walk_button=False
    21        )
    22        self.assertEqual(reality, my_expectation)
    

    the test is green again

  • I add an assertion for when the light is RED, the timer is done and the walk button is pressed

     7    def test_traffic_light_when_red(self):
     8        my_expectation = 'RED'
     9        reality = src.traffic_light.show(
    10            current_light='RED',
    11            timer_done=True,
    12            walk_button=True,
    13        )
    14        self.assertEqual(reality, my_expectation)
    15
    16        my_expectation = 'GREEN'
    17        reality = src.traffic_light.show(
    18            current_light='RED',
    19            timer_done=True,
    20            walk_button=False
    21        )
    22        self.assertEqual(reality, my_expectation)
    23
    24        my_expectation = 'RED'
    25        reality = src.traffic_light.show(
    26            current_light='RED',
    27            timer_done=False,
    28            walk_button=True,
    29        )
    30        self.assertEqual(reality, my_expectation)
    31
    32        my_expectation = 'RED'
    33        reality = src.traffic_light.show(
    34            current_light='RED',
    35            timer_done=False,
    36            walk_button=False,
    37        )
    38        self.assertEqual(reality, my_expectation)
    39
    40    def test_traffic_light_when_yellow(self):
    

    the test is still green

  • I add a variable for 'RED'

     7    def test_traffic_light_when_red(self):
     8        red = 'RED'
     9
    10        my_expectation = 'RED'
    
  • I use the variable to remove repetition

    still green

  • I remove the commented lines

     7    def test_traffic_light_when_red(self):
     8        red = 'RED'
     9
    10        reality = src.traffic_light.show(
    11            current_light=red,
    12            timer_done=True,
    13            walk_button=True,
    14        )
    15        self.assertEqual(reality, red)
    16
    17        my_expectation = 'GREEN'
    18        reality = src.traffic_light.show(
    19            current_light=red,
    20            timer_done=True,
    21            walk_button=False
    22        )
    23        self.assertEqual(reality, my_expectation)
    24
    25        reality = src.traffic_light.show(
    26            current_light=red,
    27            timer_done=False,
    28            walk_button=True,
    29        )
    30        self.assertEqual(reality, red)
    31
    32        reality = src.traffic_light.show(
    33            current_light=red,
    34            timer_done=False,
    35            walk_button=False,
    36        )
    37        self.assertEqual(reality, red)
    
  • I add a default value for the current_light keyword argument in traffic_light.py

    1def show(
    2        current_light='RED', timer_done,
    3        walk_button=False,
    4    ):
    

    the terminal shows SyntaxError

    SyntaxError: parameter without a default follows parameter with a default
    

    I cannot put a parameter that does NOT have a default value after a parameter that has a default value

  • I add SyntaxError to the list of Exceptions seen in test_traffic_light.py

    70# Exceptions seen
    71# AssertionError
    72# NameError
    73# AttributeError
    74# TypeError
    75# SyntaxError
    
  • I add a default value for timer_done in traffic_light.py

    1def show(
    2    current_light='RED', timer_done=False,
    3    walk_button=False,
    4):
    

    the test is green again

  • I change the name of test_traffic_light_when_red to test_traffic_light_when_red_w_walk_button in test_traffic_light.py

    5class TestTrafficLight(unittest.TestCase):
    6
    7    def test_traffic_light_when_red_w_walk_button(self):
    8        red = 'RED'
    
  • I remove the current_light parameter from the call to src.traffic_light.show in test_traffic_light_when_red_w_walk_button in test_traffic_light.py

     7    def test_traffic_light_when_red_w_walk_button(self):
     8        red = 'RED'
     9
    10        reality = src.traffic_light.show(
    11            timer_done=True,
    12            walk_button=True,
    13        )
    14        self.assertEqual(reality, red)
    15
    16        my_expectation = 'GREEN'
    17        reality = src.traffic_light.show(
    18            timer_done=True,
    19            walk_button=False
    20        )
    21        self.assertEqual(reality, my_expectation)
    22
    23        reality = src.traffic_light.show(
    24            timer_done=False,
    25            walk_button=True,
    26        )
    27        self.assertEqual(reality, red)
    28
    29        reality = src.traffic_light.show(
    30            timer_done=False,
    31            walk_button=False,
    32        )
    33        self.assertEqual(reality, red)
    34
    35    def test_traffic_light_when_yellow(self):
    

    the test is still green


test_traffic_light_when_yellow_w_walk_button

The truth table when the traffic light is YELLOW with the push button is

current light

timer done

walk button

show

YELLOW

yes

yes

RED

YELLOW

yes

no

RED

YELLOW

no

yes

YELLOW

YELLOW

no

no

YELLOW

  • I add walk_button to the call to src.traffic_light.show in the first assertion of test_traffic_light_when_yellow in test_traffic_light.py

    35      def test_traffic_light_when_yellow(self):
    36          my_expectation = 'RED'
    37          reality = src.traffic_light.show(
    38              current_light='YELLOW',
    39              timer_done=True,
    40              walk_button=True,
    41          )
    42          self.assertEqual(reality, my_expectation)
    43
    44          my_expectation = 'YELLOW'
    45          reality = src.traffic_light.show(
    46              current_light='YELLOW',
    47              timer_done=False,
    48          )
    49          self.assertEqual(reality, my_expectation)
    50
    51      def test_traffic_light_when_green(self):
    

    the test is still green

  • I add an assertion for when the light is YELLOW, the timer is done and the walk button is NOT pushed

    35    def test_traffic_light_when_yellow(self):
    36        my_expectation = 'RED'
    37        reality = src.traffic_light.show(
    38            current_light='YELLOW',
    39            timer_done=True,
    40            walk_button=True,
    41        )
    42        self.assertEqual(reality, my_expectation)
    43
    44        my_expectation = 'RED'
    45        reality = src.traffic_light.show(
    46            current_light='YELLOW',
    47            timer_done=True,
    48            walk_button=False,
    49        )
    50        self.assertEqual(reality, my_expectation)
    51
    52        my_expectation = 'YELLOW'
    53        reality = src.traffic_light.show(
    54            current_light='YELLOW',
    55            timer_done=False,
    56        )
    57        self.assertEqual(reality, my_expectation)
    58
    59    def test_traffic_light_when_green(self):
    

    still green

  • I add walk_button to the third assertion for when the light is YELLOW, the timer is NOT done and the walk button is pushed

    52        my_expectation = 'YELLOW'
    53        reality = src.traffic_light.show(
    54            current_light='YELLOW',
    55            timer_done=False,
    56            walk_button=True,
    57        )
    58        self.assertEqual(reality, my_expectation)
    

    green

  • I add an assertion for when the light is YELLOW, the timer is NOT done and the walk button is NOT pushed

    52        my_expectation = 'YELLOW'
    53        reality = src.traffic_light.show(
    54            current_light='YELLOW',
    55            timer_done=False,
    56            walk_button=True,
    57        )
    58        self.assertEqual(reality, my_expectation)
    59
    60        my_expectation = 'YELLOW'
    61        reality = src.traffic_light.show(
    62            current_light='YELLOW',
    63            timer_done=False,
    64            walk_button=False,
    65        )
    66        self.assertEqual(reality, my_expectation)
    67
    68    def test_traffic_light_when_green(self):
    

    still green

  • I change the name of the test from test_traffic_light_when_yellow to test_traffic_light_when_yellow_w_walk_button

    29        reality = src.traffic_light.show(
    30            timer_done=False,
    31            walk_button=False,
    32        )
    33        self.assertEqual(reality, red)
    34
    35    def test_traffic_light_when_yellow_w_walk_button(self):
    36        my_expectation = 'RED'
    37        reality = src.traffic_light.show(
    38            current_light='YELLOW',
    39            timer_done=True,
    40            walk_button=True,
    41        )
    42        self.assertEqual(reality, my_expectation)
    
  • I add a variable for YELLOW

    35    def test_traffic_light_when_yellow_w_walk_button(self):
    36        yellow = 'YELLOW'
    37
    38        my_expectation = 'RED'
    
  • I use the new variable to remove repetition

    35    def test_traffic_light_when_yellow_w_walk_button(self):
    36        yellow = 'YELLOW'
    37
    38        my_expectation = 'RED'
    39        reality = src.traffic_light.show(
    40            # current_light='YELLOW',
    41            current_light=yellow,
    42            timer_done=True,
    43            walk_button=True,
    44        )
    45        self.assertEqual(reality, my_expectation)
    46
    47        my_expectation = 'RED'
    48        reality = src.traffic_light.show(
    49            # current_light='YELLOW',
    50            current_light=yellow,
    51            timer_done=True,
    52            walk_button=False,
    53        )
    54        self.assertEqual(reality, my_expectation)
    55
    56        # my_expectation = 'YELLOW'
    57        reality = src.traffic_light.show(
    58            # current_light='YELLOW',
    59            current_light=yellow,
    60            timer_done=False,
    61            walk_button=True,
    62        )
    63        # self.assertEqual(reality, my_expectation)
    64        self.assertEqual(reality, yellow)
    65
    66        # my_expectation = 'YELLOW'
    67        reality = src.traffic_light.show(
    68            # current_light='YELLOW',
    69            current_light=yellow,
    70            timer_done=False,
    71            walk_button=False,
    72        )
    73        # self.assertEqual(reality, my_expectation)
    74        self.assertEqual(reality, yellow)
    75
    76    def test_traffic_light_when_green(self):
    

    the test is still green

  • I add a variable for RED

    35    def test_traffic_light_when_yellow_w_walk_button(self):
    36        red, yellow = 'RED', 'YELLOW'
    
  • I use the new variable to remove repetition

    35    def test_traffic_light_when_yellow_w_walk_button(self):
    36        red, yellow = 'RED', 'YELLOW'
    37
    38        # my_expectation = 'RED'
    39        reality = src.traffic_light.show(
    40            # current_light='YELLOW',
    41            current_light=yellow,
    42            timer_done=True,
    43            walk_button=True,
    44        )
    45        # self.assertEqual(reality, my_expectation)
    46        self.assertEqual(reality, red)
    47
    48        # my_expectation = 'RED'
    49        reality = src.traffic_light.show(
    50            # current_light='YELLOW',
    51            current_light=yellow,
    52            timer_done=True,
    53            walk_button=False,
    54        )
    55        # self.assertEqual(reality, my_expectation)
    56        self.assertEqual(reality, red)
    57
    58        # my_expectation = 'YELLOW'
    59        reality = src.traffic_light.show(
    60            # current_light='YELLOW',
    61            current_light=yellow,
    62            timer_done=False,
    63            walk_button=True,
    64        )
    65        # self.assertEqual(reality, my_expectation)
    66        self.assertEqual(reality, yellow)
    67
    68        # my_expectation = 'YELLOW'
    69        reality = src.traffic_light.show(
    70            # current_light='YELLOW',
    71            current_light=yellow,
    72            timer_done=False,
    73            walk_button=False,
    74        )
    75        # self.assertEqual(reality, my_expectation)
    76        self.assertEqual(reality, yellow)
    77
    78    def test_traffic_light_when_green(self):
    

    still green

  • I remove the comments

    35    def test_traffic_light_when_yellow_w_walk_button(self):
    36        red, yellow = 'RED', 'YELLOW'
    37
    38        reality = src.traffic_light.show(
    39            current_light=yellow,
    40            timer_done=True,
    41            walk_button=True,
    42        )
    43        self.assertEqual(reality, red)
    44
    45        reality = src.traffic_light.show(
    46            current_light=yellow,
    47            timer_done=True,
    48            walk_button=False,
    49        )
    50        self.assertEqual(reality, red)
    51
    52        reality = src.traffic_light.show(
    53            current_light=yellow,
    54            timer_done=False,
    55            walk_button=True,
    56        )
    57        self.assertEqual(reality, yellow)
    58
    59        reality = src.traffic_light.show(
    60            current_light=yellow,
    61            timer_done=False,
    62            walk_button=False,
    63        )
    64        self.assertEqual(reality, yellow)
    65
    66    def test_traffic_light_when_green(self):
    
  • I make global variables for the colors at the top of the file

    1import src.traffic_light
    2import unittest
    3
    4
    5RED, YELLOW = 'RED', 'YELLOW'
    6
    7
    8class TestTrafficLight(unittest.TestCase):
    
  • I use the RED global variable in test_traffic_light_when_red_w_walk_button

    10    def test_traffic_light_when_red_w_walk_button(self):
    11        # red = 'RED'
    12
    13        reality = src.traffic_light.show(
    14            timer_done=True,
    15            walk_button=True,
    16        )
    17        # self.assertEqual(reality, red)
    18        self.assertEqual(reality, RED)
    19
    20        my_expectation = 'GREEN'
    21        reality = src.traffic_light.show(
    22            timer_done=True,
    23            walk_button=False
    24        )
    25        self.assertEqual(reality, my_expectation)
    26
    27        reality = src.traffic_light.show(
    28            timer_done=False,
    29            walk_button=True,
    30        )
    31        # self.assertEqual(reality, red)
    32        self.assertEqual(reality, RED)
    33
    34        reality = src.traffic_light.show(
    35            timer_done=False,
    36            walk_button=False,
    37        )
    38        # self.assertEqual(reality, red)
    39        self.assertEqual(reality, RED)
    40
    41    def test_traffic_light_when_yellow_w_walk_button(self)
    

    the test is still green

  • I remove the commented lines

     1import src.traffic_light
     2import unittest
     3
     4
     5RED, YELLOW = 'RED', 'YELLOW'
     6
     7
     8class TestTrafficLight(unittest.TestCase):
     9
    10    def test_traffic_light_when_red_w_walk_button(self):
    11        reality = src.traffic_light.show(
    12            timer_done=True,
    13            walk_button=True,
    14        )
    15        self.assertEqual(reality, RED)
    16
    17        my_expectation = 'GREEN'
    18        reality = src.traffic_light.show(
    19            timer_done=True,
    20            walk_button=False
    21        )
    22        self.assertEqual(reality, my_expectation)
    23
    24        reality = src.traffic_light.show(
    25            timer_done=False,
    26            walk_button=True,
    27        )
    28        self.assertEqual(reality, RED)
    29
    30        reality = src.traffic_light.show(
    31            timer_done=False,
    32            walk_button=False,
    33        )
    34        self.assertEqual(reality, RED)
    35
    36    def test_traffic_light_when_yellow_w_walk_button(self)
    
  • I use the RED global variable in test_traffic_light_when_yellow_w_walk_button

    36    def test_traffic_light_when_yellow_w_walk_button(self):
    37        red, yellow = 'RED', 'YELLOW'
    38
    39        reality = src.traffic_light.show(
    40            current_light=yellow,
    41            timer_done=True,
    42            walk_button=True,
    43        )
    44        # self.assertEqual(reality, red)
    45        self.assertEqual(reality, RED)
    46
    47        reality = src.traffic_light.show(
    48            current_light=yellow,
    49            timer_done=True,
    50            walk_button=False,
    51        )
    52        # self.assertEqual(reality, red)
    53        self.assertEqual(reality, RED)
    

    still green

  • I use the YELLOW global variable in test_traffic_light_when_yellow_w_walk_button

    36  def test_traffic_light_when_yellow_w_walk_button(self):
    37      # red, yellow = 'RED', 'YELLOW'
    38
    39      reality = src.traffic_light.show(
    40          # current_light=yellow,
    41          current_light=YELLOW,
    42          timer_done=True,
    43          walk_button=True,
    44      )
    45      # self.assertEqual(reality, red)
    46      self.assertEqual(reality, RED)
    47
    48      reality = src.traffic_light.show(
    49          # current_light=yellow,
    50          current_light=YELLOW,
    51          timer_done=True,
    52          walk_button=False,
    53      )
    54      # self.assertEqual(reality, red)
    55      self.assertEqual(reality, RED)
    56
    57      reality = src.traffic_light.show(
    58          # current_light=yellow,
    59          current_light=YELLOW,
    60          timer_done=False,
    61          walk_button=True,
    62      )
    63      # self.assertEqual(reality, yellow)
    64      self.assertEqual(reality, YELLOW)
    65
    66      reality = src.traffic_light.show(
    67          # current_light=yellow,
    68          current_light=YELLOW,
    69          timer_done=False,
    70          walk_button=False,
    71      )
    72      # self.assertEqual(reality, yellow)
    73      self.assertEqual(reality, YELLOW)
    

    green

  • I remove the comments

    36    def test_traffic_light_when_yellow_w_walk_button(self):
    37        reality = src.traffic_light.show(
    38            current_light=YELLOW,
    39            timer_done=True,
    40            walk_button=True,
    41        )
    42        self.assertEqual(reality, RED)
    43
    44        reality = src.traffic_light.show(
    45            current_light=YELLOW,
    46            timer_done=True,
    47            walk_button=False,
    48        )
    49        self.assertEqual(reality, RED)
    50
    51        reality = src.traffic_light.show(
    52            current_light=YELLOW,
    53            timer_done=False,
    54            walk_button=True,
    55        )
    56        self.assertEqual(reality, YELLOW)
    57
    58        reality = src.traffic_light.show(
    59            current_light=YELLOW,
    60            timer_done=False,
    61            walk_button=False,
    62        )
    63        self.assertEqual(reality, YELLOW)
    64
    65    def test_traffic_light_when_green(self):
    

test_traffic_light_when_green_w_walk_button

The truth table when the traffic light is GREEN with the push button is

current light

timer done

walk button

show

GREEN

yes

yes

YELLOW

GREEN

yes

no

YELLOW

GREEN

no

yes

GREEN

GREEN

no

no

GREEN

  • I add walk_button to the call to src.traffic_light.show in the first assertion of test_traffic_light_when_green in test_traffic_light.py

    65    def test_traffic_light_when_green(self):
    66        my_expectation = 'YELLOW'
    67        reality = src.traffic_light.show(
    68            current_light='GREEN',
    69            timer_done=True,
    70            walk_button=True,
    71        )
    72        self.assertEqual(reality, my_expectation)
    73
    74        my_expectation = 'GREEN'
    75        reality = src.traffic_light.show(
    76            current_light='GREEN',
    77            timer_done=False,
    78        )
    79        self.assertEqual(reality, my_expectation)
    80
    81
    82# Exceptions seen
    

    the test is still green

  • I add an assertion for when the light is GREEN, the timer is done and the walk button is NOT pushed

    65    def test_traffic_light_when_green(self):
    66        my_expectation = 'YELLOW'
    67        reality = src.traffic_light.show(
    68            current_light='GREEN',
    69            timer_done=True,
    70            walk_button=True,
    71        )
    72        self.assertEqual(reality, my_expectation)
    73
    74        my_expectation = 'YELLOW'
    75        reality = src.traffic_light.show(
    76            current_light='GREEN',
    77            timer_done=True,
    78            walk_button=False,
    79        )
    80        self.assertEqual(reality, my_expectation)
    81
    82        my_expectation = 'GREEN'
    83        reality = src.traffic_light.show(
    84            current_light='GREEN',
    85            timer_done=False,
    86        )
    87        self.assertEqual(reality, my_expectation)
    

    still green

  • I add walk_button to the third assertion for when the light is GREEN, the timer is NOT done and the walk button is pushed

    82        my_expectation = 'GREEN'
    83        reality = src.traffic_light.show(
    84            current_light='GREEN',
    85            timer_done=False,
    86            walk_button=True,
    87        )
    88        self.assertEqual(reality, my_expectation)
    

    green

  • I add an assertion for when the light is GREEN, the timer is NOT done and the walk button is NOT pushed

    82        my_expectation = 'GREEN'
    83        reality = src.traffic_light.show(
    84            current_light='GREEN',
    85            timer_done=False,
    86            walk_button=True,
    87        )
    88        self.assertEqual(reality, my_expectation)
    89
    90        my_expectation = 'GREEN'
    91        reality = src.traffic_light.show(
    92            current_light='GREEN',
    93            timer_done=False,
    94            walk_button=False,
    95        )
    96        self.assertEqual(reality, my_expectation)
    97
    98
    99# Exceptions seen
    

    still green

  • I add a global variable for GREEN

    1import src.traffic_light
    2import unittest
    3
    4
    5RED, YELLOW, GREEN = 'RED', 'YELLOW', 'GREEN'
    6
    7
    8class TestTrafficLight(unittest.TestCase):
    
  • I use the GREEN global variable in test_traffic_light_when_red_w_walk_button

    17        # my_expectation = 'GREEN'
    18        reality = src.traffic_light.show(
    19            timer_done=True,
    20            walk_button=False
    21        )
    22        # self.assertEqual(reality, my_expectation)
    23        self.assertEqual(reality, GREEN)
    

    the test is still green

  • I remove the commented lines

    10    def test_traffic_light_when_red_w_walk_button(self):
    11        reality = src.traffic_light.show(
    12            timer_done=True,
    13            walk_button=True,
    14        )
    15        self.assertEqual(reality, RED)
    16
    17        reality = src.traffic_light.show(
    18            timer_done=True,
    19            walk_button=False
    20        )
    21        self.assertEqual(reality, GREEN)
    22
    23        reality = src.traffic_light.show(
    24            timer_done=False,
    25            walk_button=True,
    26        )
    27        self.assertEqual(reality, RED)
    28
    29        reality = src.traffic_light.show(
    30            timer_done=False,
    31            walk_button=False,
    32        )
    33        self.assertEqual(reality, RED)
    34
    35    def test_traffic_light_when_yellow_w_walk_button
    
  • I change the name of test_traffic_light_when_green to test_traffic_light_when_green_w_walk_button

  • I use the GREEN global variable in test_traffic_light_when_green_w_walk_button

     64    def test_traffic_light_when_green_w_walk_button(self):
     65        my_expectation = 'YELLOW'
     66        reality = src.traffic_light.show(
     67            # current_light='GREEN',
     68            current_light=GREEN,
     69            timer_done=True,
     70            walk_button=True,
     71        )
     72        self.assertEqual(reality, my_expectation)
     73
     74        my_expectation = 'YELLOW'
     75        reality = src.traffic_light.show(
     76            # current_light='GREEN',
     77            current_light=GREEN,
     78            timer_done=True,
     79            walk_button=False,
     80        )
     81        self.assertEqual(reality, my_expectation)
     82
     83        # my_expectation = 'GREEN'
     84        reality = src.traffic_light.show(
     85            # current_light='GREEN',
     86            current_light=GREEN,
     87            timer_done=False,
     88            walk_button=True,
     89        )
     90        # self.assertEqual(reality, my_expectation)
     91        self.assertEqual(reality, GREEN)
     92
     93        # my_expectation = 'GREEN'
     94        reality = src.traffic_light.show(
     95            # current_light='GREEN',
     96            current_light=GREEN,
     97            timer_done=False,
     98            walk_button=False,
     99        )
    100        # self.assertEqual(reality, my_expectation)
    101        self.assertEqual(reality, GREEN)
    

    still green

  • I use the YELLOW global variable

    64    def test_traffic_light_when_green_w_walk_button(self):
    65        # my_expectation = 'YELLOW'
    66        reality = src.traffic_light.show(
    67            # current_light='GREEN',
    68            current_light=GREEN,
    69            timer_done=True,
    70            walk_button=True,
    71        )
    72        # self.assertEqual(reality, my_expectation)
    73        self.assertEqual(reality, YELLOW)
    74
    75        # my_expectation = 'YELLOW'
    76        reality = src.traffic_light.show(
    77            # current_light='GREEN',
    78            current_light=GREEN,
    79            timer_done=True,
    80            walk_button=False,
    81        )
    82        # self.assertEqual(reality, my_expectation)
    83        self.assertEqual(reality, YELLOW)
    

    green

  • I remove the comments

    64    def test_traffic_light_when_green_w_walk_button(self):
    65        reality = src.traffic_light.show(
    66            current_light=GREEN,
    67            timer_done=True,
    68            walk_button=True,
    69        )
    70        self.assertEqual(reality, YELLOW)
    71
    72        reality = src.traffic_light.show(
    73            current_light=GREEN,
    74            timer_done=True,
    75            walk_button=False,
    76        )
    77        self.assertEqual(reality, YELLOW)
    78
    79        reality = src.traffic_light.show(
    80            current_light=GREEN,
    81            timer_done=False,
    82            walk_button=True,
    83        )
    84        self.assertEqual(reality, GREEN)
    85
    86        reality = src.traffic_light.show(
    87            current_light=GREEN,
    88            timer_done=False,
    89            walk_button=False,
    90        )
    91        self.assertEqual(reality, GREEN)
    

REFACTOR: make it better

  • I can remove the reality variable since it is only used once for each assertion in test_traffic_light_when_red_w_walk_button

    10    def test_traffic_light_when_red_w_walk_button(self):
    11        reality = src.traffic_light.show(
    12            timer_done=True,
    13            walk_button=True,
    14        )
    15        # self.assertEqual(reality, RED)
    16        self.assertEqual(
    17            src.traffic_light.show(
    18                timer_done=True,
    19                walk_button=True,
    20            ),
    21            RED
    22        )
    23
    24        reality = src.traffic_light.show(
    25            timer_done=True,
    26            walk_button=False
    27        )
    28        # self.assertEqual(reality, GREEN)
    29        self.assertEqual(
    30            src.traffic_light.show(
    31                timer_done=True,
    32                walk_button=False
    33            ),
    34            GREEN
    35        )
    36
    37        reality = src.traffic_light.show(
    38            timer_done=False,
    39            walk_button=True,
    40        )
    41        # self.assertEqual(reality, RED)
    42        self.assertEqual(
    43            src.traffic_light.show(
    44                timer_done=False,
    45                walk_button=True,
    46            ),
    47            RED
    48        )
    49
    50        reality = src.traffic_light.show(
    51            timer_done=False,
    52            walk_button=False,
    53        )
    54        # self.assertEqual(reality, RED)
    55        self.assertEqual(
    56            src.traffic_light.show(
    57                timer_done=False,
    58                walk_button=False,
    59            ),
    60            RED
    61        )
    
  • I remove the reality variable and the comments from test_traffic_light_when_red_w_walk_button

    10    def test_traffic_light_when_red_w_walk_button(self):
    11        self.assertEqual(
    12            src.traffic_light.show(
    13                timer_done=True,
    14                walk_button=True,
    15            ),
    16            RED
    17        )
    18
    19        self.assertEqual(
    20            src.traffic_light.show(
    21                timer_done=True,
    22                walk_button=False
    23            ),
    24            GREEN
    25        )
    26
    27        self.assertEqual(
    28            src.traffic_light.show(
    29                timer_done=False,
    30                walk_button=True,
    31            ),
    32            RED
    33        )
    34
    35        self.assertEqual(
    36            src.traffic_light.show(
    37                timer_done=False,
    38                walk_button=False,
    39            ),
    40            RED
    41        )
    42
    43    def test_traffic_light_when_yellow_w_walk_button(self):
    
  • I do the same thing in test_traffic_light_when_yellow_w_walk_button

     43    def test_traffic_light_when_yellow_w_walk_button(self):
     44        reality = src.traffic_light.show(
     45            current_light=YELLOW,
     46            timer_done=True,
     47            walk_button=True,
     48        )
     49        # self.assertEqual(reality, RED)
     50        self.assertEqual(
     51            src.traffic_light.show(
     52                current_light=YELLOW,
     53                timer_done=True,
     54                walk_button=True,
     55            ),
     56            RED
     57        )
     58
     59        reality = src.traffic_light.show(
     60            current_light=YELLOW,
     61            timer_done=True,
     62            walk_button=False,
     63        )
     64        # self.assertEqual(reality, RED)
     65        self.assertEqual(
     66            src.traffic_light.show(
     67                current_light=YELLOW,
     68                timer_done=True,
     69                walk_button=False,
     70            ),
     71            RED
     72        )
     73
     74        reality = src.traffic_light.show(
     75            current_light=YELLOW,
     76            timer_done=False,
     77            walk_button=True,
     78        )
     79        # self.assertEqual(reality, YELLOW)
     80        self.assertEqual(
     81            src.traffic_light.show(
     82                current_light=YELLOW,
     83                timer_done=False,
     84                walk_button=True,
     85            ),
     86            YELLOW
     87        )
     88
     89        reality = src.traffic_light.show(
     90            current_light=YELLOW,
     91            timer_done=False,
     92            walk_button=False,
     93        )
     94        # self.assertEqual(reality, YELLOW)
     95        self.assertEqual(
     96            src.traffic_light.show(
     97                current_light=YELLOW,
     98                timer_done=False,
     99                walk_button=False,
    100            ),
    101            YELLOW
    102        )
    
  • I remove the reality variable and comments from test_traffic_light_when_yellow_w_walk_button

    43    def test_traffic_light_when_yellow_w_walk_button(self):
    44        self.assertEqual(
    45            src.traffic_light.show(
    46                current_light=YELLOW,
    47                timer_done=True,
    48                walk_button=True,
    49            ),
    50            RED
    51        )
    52
    53        self.assertEqual(
    54            src.traffic_light.show(
    55                current_light=YELLOW,
    56                timer_done=True,
    57                walk_button=False,
    58            ),
    59            RED
    60        )
    61
    62        self.assertEqual(
    63            src.traffic_light.show(
    64                current_light=YELLOW,
    65                timer_done=False,
    66                walk_button=True,
    67            ),
    68            YELLOW
    69        )
    70
    71        self.assertEqual(
    72            src.traffic_light.show(
    73                current_light=YELLOW,
    74                timer_done=False,
    75                walk_button=False,
    76            ),
    77            YELLOW
    78        )
    79
    80    def test_traffic_light_when_green_w_walk_button
    
  • I can also do it with test_traffic_light_when_green_w_walk_button

     80    def test_traffic_light_when_green_w_walk_button(self):
     81        reality = src.traffic_light.show(
     82            current_light=GREEN,
     83            timer_done=True,
     84            walk_button=True,
     85        )
     86        # self.assertEqual(reality, YELLOW)
     87        self.assertEqual(
     88            src.traffic_light.show(
     89                current_light=GREEN,
     90                timer_done=True,
     91                walk_button=True,
     92            ),
     93            YELLOW
     94        )
     95
     96        reality = src.traffic_light.show(
     97            current_light=GREEN,
     98            timer_done=True,
     99            walk_button=False,
    100        )
    101        # self.assertEqual(reality, YELLOW)
    102        self.assertEqual(
    103            src.traffic_light.show(
    104                current_light=GREEN,
    105                timer_done=True,
    106                walk_button=False,
    107            ),
    108            YELLOW
    109        )
    110
    111        reality = src.traffic_light.show(
    112            current_light=GREEN,
    113            timer_done=False,
    114            walk_button=True,
    115        )
    116        # self.assertEqual(reality, GREEN)
    117        self.assertEqual(
    118            src.traffic_light.show(
    119                current_light=GREEN,
    120                timer_done=False,
    121                walk_button=True,
    122            ),
    123            GREEN
    124        )
    125
    126        reality = src.traffic_light.show(
    127            current_light=GREEN,
    128            timer_done=False,
    129            walk_button=False,
    130        )
    131        # self.assertEqual(reality, GREEN)
    132        self.assertEqual(
    133            src.traffic_light.show(
    134                current_light=GREEN,
    135                timer_done=False,
    136                walk_button=False,
    137            ),
    138            GREEN
    139        )
    
  • I remove the reality variable and comments from test_traffic_light_when_green_w_walk_button

     1    def test_traffic_light_when_green_w_walk_button(self):
     2        self.assertEqual(
     3            src.traffic_light.show(
     4                current_light=GREEN,
     5                timer_done=True,
     6                walk_button=True,
     7            ),
     8            YELLOW
     9        )
    10
    11        self.assertEqual(
    12            src.traffic_light.show(
    13                current_light=GREEN,
    14                timer_done=True,
    15                walk_button=False,
    16            ),
    17            YELLOW
    18        )
    19
    20        self.assertEqual(
    21            src.traffic_light.show(
    22                current_light=GREEN,
    23                timer_done=False,
    24                walk_button=True,
    25            ),
    26            GREEN
    27        )
    28
    29        self.assertEqual(
    30            src.traffic_light.show(
    31                current_light=GREEN,
    32                timer_done=False,
    33                walk_button=False,
    34            ),
    35            GREEN
    36        )
    37
    38
    39# Exceptions seen
    

    all the tests are still green


test_traffic_light_w_walk_sign

I want the traffic light to show WALK or NO WALK when a person can walk. This means the truth table for the Traffic Light is

current light

timer done

walk button

show

RED

yes

yes

RED + WALK

RED

yes

no

GREEN + NO WALK

RED

no

yes

RED + WALK

RED

no

no

RED + WALK

YELLOW

yes

yes

RED + WALK

YELLOW

yes

no

RED + WALK

YELLOW

no

yes

YELLOW + NO WALK

YELLOW

no

no

YELLOW + NO WALK

GREEN

yes

yes

YELLOW + NO WALK

GREEN

yes

no

YELLOW + NO WALK

GREEN

no

yes

GREEN + NO WALK

GREEN

no

no

GREEN + NO WALK

this shows that the Traffic Light only shows WALK when the light is RED


RED: make it fail


I change the expectation of the first assertion in test_traffic_light_when_red_w_walk_button

10      def test_traffic_light_when_red_w_walk_button(self):
11          self.assertEqual(
12              src.traffic_light.show(
13                  timer_done=True,
14                  walk_button=True,
15              ),
16              (RED, 'WALK')
17          )

the terminal shows AssertionError

AssertionError: 'RED' != ('RED', 'WALK')

GREEN: make it pass


  • I change the return statement in the show function in traffic_light.py

     1def show(
     2        current_light='RED', timer_done=False,
     3        walk_button=False,
     4    ):
     5    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     6    next_light = red
     7
     8    if timer_done:
     9        if current_light == green:
    10            next_light = yellow
    11        if current_light == red:
    12            if walk_button:
    13                next_light = red
    14            else:
    15                next_light = green
    16    else:
    17        next_light = current_light
    18
    19    return next_light, 'WALK'
    

    the terminal shows AssertionError

    FAILED ...test_traffic_light_when_green_w_walk_button - AssertionError: ('YELLOW', 'WALK') != 'YELLOW'
    FAILED ...test_traffic_light_when_red_w_walk_button - AssertionError: ('GREEN', 'WALK') != 'GREEN'
    FAILED ...test_traffic_light_when_yellow_w_walk_button - AssertionError: ('RED', 'WALK') != 'RED'
    

    my solution broke all the tests

  • I remove WALK from the return statement

    19    return next_light
    

    the terminal shows AssertionError

    AssertionError: 'RED' != ('RED', 'WALK')
    
  • I make a copy of the show function and paste it below, then change the name to show_walk, this way I keep what works while I try a new solution

     1def show(
     2        current_light='RED', timer_done=False,
     3        walk_button=False,
     4    ):
     5    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     6    next_light = red
     7
     8    if timer_done:
     9        if current_light == green:
    10            next_light = yellow
    11        if current_light == red:
    12            if walk_button:
    13                next_light = red
    14            else:
    15                next_light = green
    16    else:
    17        next_light = current_light
    18
    19    return next_light
    20
    21
    22def show_walk(
    23        current_light='RED', timer_done=False,
    24        walk_button=False,
    25    ):
    26    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
    27    next_light = red
    28
    29    if timer_done:
    30        if current_light == green:
    31            next_light = yellow
    32        if current_light == red:
    33            if walk_button:
    34                next_light = red
    35            else:
    36                next_light = green
    37    else:
    38        next_light = current_light
    39
    40    return next_light
    
  • I change the call to the show function in test_traffic_light_when_red_w_walk_button in test_traffic_light.py

    10    def test_traffic_light_when_red_w_walk_button(self):
    11        self.assertEqual(
    12            # src.traffic_light.show(
    13            src.traffic_light.show_walk(
    14                timer_done=True,
    15                walk_button=True,
    16            ),
    17            (RED, 'WALK')
    18        )
    

    the terminal still shows AssertionError

  • I change the return statement of the show_walk function in traffic_light.py

    22def show_walk(
    23        current_light='RED', timer_done=False,
    24        walk_button=False,
    25    ):
    26    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
    27    next_light = red
    28
    29    if timer_done:
    30        if current_light == green:
    31            next_light = yellow
    32        if current_light == red:
    33            if walk_button:
    34                next_light = red
    35            else:
    36                next_light = green
    37    else:
    38        next_light = current_light
    39
    40    return next_light, 'WALK'
    

    the test passes


REFACTOR: make it better


  • I change the expectation of the second assertion in test_traffic_light_when_red_w_walk_button in test_traffic_light.py

    10    def test_traffic_light_when_red_w_walk_button(self):
    11        self.assertEqual(
    12            # src.traffic_light.show(
    13            src.traffic_light.show_walk(
    14                timer_done=True,
    15                walk_button=True,
    16            ),
    17            (RED, 'WALK')
    18        )
    19
    20        self.assertEqual(
    21            src.traffic_light.show(
    22                timer_done=True,
    23                walk_button=False
    24            ),
    25            (GREEN, 'NO WALK')
    26        )
    

    the terminal shows AssertionError

    AssertionError: 'GREEN' != ('GREEN', 'NO WALK')
    
  • I change the call in the assertion from show to show_walk

    10    def test_traffic_light_when_red_w_walk_button(self):
    11        self.assertEqual(
    12            # src.traffic_light.show(
    13            src.traffic_light.show_walk(
    14                timer_done=True,
    15                walk_button=True,
    16            ),
    17            (RED, 'WALK')
    18        )
    19
    20        self.assertEqual(
    21            # src.traffic_light.show(
    22            src.traffic_light.show_walk(
    23                timer_done=True,
    24                walk_button=False
    25            ),
    26            (GREEN, 'NO WALK')
    27        )
    

    the terminal shows AssertionError

    AssertionError: Tuples differ: ('GREEN', 'WALK') != ('GREEN', 'NO WALK')
    
  • I add a walk variable to the show_walk function in traffic_light.py

    22def show_walk(
    23        current_light='RED', timer_done=False,
    24        walk_button=False,
    25    ):
    26    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
    27    next_light = red
    28    walk = 'NO WALK'
    29
    30    if timer_done:
    
  • I use the walk variable in the if statement for when the light is RED

    30    if timer_done:
    31        if current_light == green:
    32            next_light = yellow
    33        if current_light == red:
    34            if walk_button:
    35                next_light, walk = red, 'WALK'
    36            else:
    37                next_light = green
    38    else:
    39        next_light = current_light
    
  • I use the walk variable in the return statement

    22def show_walk(
    23        current_light='RED', timer_done=False,
    24        walk_button=False,
    25    ):
    26    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
    27    next_light = red
    28    walk = 'NO WALK'
    29
    30    if timer_done:
    31        if current_light == green:
    32            next_light = yellow
    33        if current_light == red:
    34            if walk_button:
    35                next_light, walk = red, 'WALK'
    36            else:
    37                next_light = green
    38    else:
    39        next_light = current_light
    40
    41    return next_light, walk
    

    the test passes

  • I change the third assertion in test_traffic_light_when_red_w_walk_button in traffic_light.py

    10    def test_traffic_light_when_red_w_walk_button(self):
    11        self.assertEqual(
    12            # src.traffic_light.show(
    13            src.traffic_light.show_walk(
    14                timer_done=True,
    15                walk_button=True,
    16            ),
    17            (RED, 'WALK')
    18        )
    19
    20        self.assertEqual(
    21            # src.traffic_light.show(
    22            src.traffic_light.show_walk(
    23                timer_done=True,
    24                walk_button=False
    25            ),
    26            (GREEN, 'NO WALK')
    27        )
    28
    29        self.assertEqual(
    30            # src.traffic_light.show(
    31            src.traffic_light.show_walk(
    32                timer_done=False,
    33                walk_button=True,
    34            ),
    35            (RED, 'WALK')
    36        )
    

    the terminal shows AssertionError

    AssertionError: Tuples differ: ('RED', 'NO WALK') != ('RED', 'WALK')
    
  • I add an if statement for it to the else clause in the show_walk function in traffic_light.py

    22def show_walk(
    23        current_light='RED', timer_done=False,
    24        walk_button=False,
    25    ):
    26    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
    27    next_light = red
    28    walk = 'NO WALK'
    29
    30    if timer_done:
    31        if current_light == green:
    32            next_light = yellow
    33        if current_light == red:
    34            if walk_button:
    35                next_light, walk = red, 'WALK'
    36            else:
    37                next_light = green
    38    else:
    39        next_light = current_light
    40        if current_light == red:
    41            walk = 'WALK'
    42
    43    return next_light, walk
    

    the test passes

  • I change the last assertion in test_traffic_light_when_red_w_walk_button in test_traffic_light.py

    10    def test_traffic_light_when_red_w_walk_button(self):
    11        self.assertEqual(
    12            # src.traffic_light.show(
    13            src.traffic_light.show_walk(
    14                timer_done=True,
    15                walk_button=True,
    16            ),
    17            (RED, 'WALK')
    18        )
    19
    20        self.assertEqual(
    21            # src.traffic_light.show(
    22            src.traffic_light.show_walk(
    23                timer_done=True,
    24                walk_button=False
    25            ),
    26            (GREEN, 'NO WALK')
    27        )
    28
    29        self.assertEqual(
    30            # src.traffic_light.show(
    31            src.traffic_light.show_walk(
    32                timer_done=False,
    33                walk_button=True,
    34            ),
    35            (RED, 'WALK')
    36        )
    37
    38        self.assertEqual(
    39            # src.traffic_light.show(
    40            src.traffic_light.show_walk(
    41                timer_done=False,
    42                walk_button=False,
    43            ),
    44            (RED, 'WALK')
    45        )
    46
    47    def test_traffic_light_when_yellow_w_walk_button(self):
    

    the test is still green


  • I change the first assertion in test_traffic_light_when_yellow_w_walk_button

    47    def test_traffic_light_when_yellow_w_walk_button(self):
    48        self.assertEqual(
    49            # src.traffic_light.show(
    50            src.traffic_light.show_walk(
    51                current_light=YELLOW,
    52                timer_done=True,
    53                walk_button=True,
    54            ),
    55            (RED, 'WALK')
    56        )
    

    the terminal shows AssertionError

    AssertionError: Tuples differ: ('RED', 'NO WALK') != ('RED', 'WALK')
    
  • I add an if statement to the show_walk function in traffic_light.py

    22def show_walk(
    23        current_light='RED', timer_done=False,
    24        walk_button=False,
    25    ):
    26    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
    27    next_light = red
    28    walk = 'NO WALK'
    29
    30    if timer_done:
    31        if current_light == green:
    32            next_light = yellow
    33        if current_light == red:
    34            if walk_button:
    35                next_light, walk = red, 'WALK'
    36            else:
    37                next_light = green
    38    else:
    39        next_light = current_light
    40        if current_light == red:
    41            walk = 'WALK'
    42
    43    if next_light == red:
    44        walk = 'WALK'
    45
    46    return next_light, walk
    

    the test passes. I forgot that from the truth table of the Traffic Light, it only shows WALK when the light is RED

  • I comment out the last two statements I added

    22def show_walk(
    23        current_light='RED', timer_done=False,
    24        walk_button=False,
    25    ):
    26    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
    27    next_light = red
    28    walk = 'NO WALK'
    29
    30    if timer_done:
    31        if current_light == green:
    32            next_light = yellow
    33        if current_light == red:
    34            if walk_button:
    35                # next_light, walk = red, 'WALK'
    36                next_light = red
    37            else:
    38                next_light = green
    39    else:
    40        next_light = current_light
    41        # if current_light == red:
    42        #     walk = 'WALK'
    43
    44    if next_light == red:
    45        walk = 'WALK'
    46
    47    return next_light, walk
    

    the test is still green

  • I remove the commented lines

    22def show_walk(
    23        current_light='RED', timer_done=False,
    24        walk_button=False,
    25    ):
    26    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
    27    next_light = red
    28    walk = 'NO WALK'
    29
    30    if timer_done:
    31        if current_light == green:
    32            next_light = yellow
    33        if current_light == red:
    34            if walk_button:
    35                next_light = red
    36            else:
    37                next_light = green
    38    else:
    39        next_light = current_light
    40
    41    if next_light == red:
    42        walk = 'WALK'
    43
    44    return next_light, walk
    

    still green

  • I change the second assertion in test_traffic_light_when_yellow_w_walk_button in test_traffic_light.py

    47    def test_traffic_light_when_yellow_w_walk_button(self):
    48        self.assertEqual(
    49            # src.traffic_light.show(
    50            src.traffic_light.show_walk(
    51                current_light=YELLOW,
    52                timer_done=True,
    53                walk_button=True,
    54            ),
    55            (RED, 'WALK')
    56        )
    57
    58        self.assertEqual(
    59            # src.traffic_light.show(
    60            src.traffic_light.show_walk(
    61                current_light=YELLOW,
    62                timer_done=True,
    63                walk_button=False,
    64            ),
    65            (RED, 'WALK')
    66        )
    

    the test is still green

  • I change the third assertion

    47    def test_traffic_light_when_yellow_w_walk_button(self):
    48        self.assertEqual(
    49            # src.traffic_light.show(
    50            src.traffic_light.show_walk(
    51                current_light=YELLOW,
    52                timer_done=True,
    53                walk_button=True,
    54            ),
    55            (RED, 'WALK')
    56        )
    57
    58        self.assertEqual(
    59            # src.traffic_light.show(
    60            src.traffic_light.show_walk(
    61                current_light=YELLOW,
    62                timer_done=True,
    63                walk_button=False,
    64            ),
    65            (RED, 'WALK')
    66        )
    67
    68        self.assertEqual(
    69            # src.traffic_light.show(
    70            src.traffic_light.show_walk(
    71                current_light=YELLOW,
    72                timer_done=False,
    73                walk_button=True,
    74            ),
    75            (YELLOW, 'NO WALK')
    76        )
    

    still green

  • I change the last assertion

    47    def test_traffic_light_when_yellow_w_walk_button(self):
    48        self.assertEqual(
    49            # src.traffic_light.show(
    50            src.traffic_light.show_walk(
    51                current_light=YELLOW,
    52                timer_done=True,
    53                walk_button=True,
    54            ),
    55            (RED, 'WALK')
    56        )
    57
    58        self.assertEqual(
    59            # src.traffic_light.show(
    60            src.traffic_light.show_walk(
    61                current_light=YELLOW,
    62                timer_done=True,
    63                walk_button=False,
    64            ),
    65            (RED, 'WALK')
    66        )
    67
    68        self.assertEqual(
    69            # src.traffic_light.show(
    70            src.traffic_light.show_walk(
    71                current_light=YELLOW,
    72                timer_done=False,
    73                walk_button=True,
    74            ),
    75            (YELLOW, 'NO WALK')
    76        )
    77
    78        self.assertEqual(
    79            # src.traffic_light.show(
    80            src.traffic_light.show_walk(
    81                current_light=YELLOW,
    82                timer_done=False,
    83                walk_button=False,
    84            ),
    85            (YELLOW, 'NO WALK')
    86        )
    

    the test is still green

  • I have used NO WALK and WALK enough times, that I add global variables for them

     1import src.traffic_light
     2import unittest
     3
     4
     5RED, YELLOW, GREEN = 'RED', 'YELLOW', 'GREEN'
     6WALK = (RED, 'WALK')
     7NO_WALK = 'NO WALK'
     8
     9
    10class TestTrafficLight(unittest.TestCase):
    
  • I use the new variables in test_traffic_light_when_red_w_walk_button

    12    def test_traffic_light_when_red_w_walk_button(self):
    13        self.assertEqual(
    14            # src.traffic_light.show(
    15            src.traffic_light.show_walk(
    16                timer_done=True,
    17                walk_button=True,
    18            ),
    19            # (RED, 'WALK')
    20            WALK
    21        )
    22
    23        self.assertEqual(
    24            # src.traffic_light.show(
    25            src.traffic_light.show_walk(
    26                timer_done=True,
    27                walk_button=False
    28            ),
    29            # (GREEN, 'NO WALK')
    30            (GREEN, NO_WALK)
    31        )
    32
    33        self.assertEqual(
    34            # src.traffic_light.show(
    35            src.traffic_light.show_walk(
    36                timer_done=False,
    37                walk_button=True,
    38            ),
    39            # (RED, 'WALK')
    40            WALK
    41        )
    42
    43        self.assertEqual(
    44            # src.traffic_light.show(
    45            src.traffic_light.show_walk(
    46                timer_done=False,
    47                walk_button=False,
    48            ),
    49            # (RED, 'WALK')
    50            WALK
    51        )
    

    still green

  • I use them in test_traffic_light_when_yellow_w_walk_button

    53def test_traffic_light_when_yellow_w_walk_button(self):
    54    self.assertEqual(
    55        # src.traffic_light.show(
    56        src.traffic_light.show_walk(
    57            current_light=YELLOW,
    58            timer_done=True,
    59            walk_button=True,
    60        ),
    61        # (RED, 'WALK')
    62        WALK
    63    )
    64
    65    self.assertEqual(
    66        # src.traffic_light.show(
    67        src.traffic_light.show_walk(
    68            current_light=YELLOW,
    69            timer_done=True,
    70            walk_button=False,
    71        ),
    72        # (RED, 'WALK')
    73        WALK
    74    )
    75
    76    self.assertEqual(
    77        # src.traffic_light.show(
    78        src.traffic_light.show_walk(
    79            current_light=YELLOW,
    80            timer_done=False,
    81            walk_button=True,
    82        ),
    83        # (YELLOW, 'NO WALK')
    84        (YELLOW, NO_WALK)
    85    )
    86
    87    self.assertEqual(
    88        # src.traffic_light.show(
    89        src.traffic_light.show_walk(
    90            current_light=YELLOW,
    91            timer_done=False,
    92            walk_button=False,
    93        ),
    94        # (YELLOW, 'NO WALK')
    95        (YELLOW, NO_WALK)
    96    )
    

  • I change the first assertion in test_traffic_light_when_green_w_walk_button

     98    def test_traffic_light_when_green_w_walk_button(self):
     99        self.assertEqual(
    100            # src.traffic_light.show(
    101            src.traffic_light.show_walk(
    102                current_light=GREEN,
    103                timer_done=True,
    104                walk_button=True,
    105            ),
    106            (YELLOW, NO_WALK)
    107        )
    

    the test is still green

  • I change the second assertion

     98    def test_traffic_light_when_green_w_walk_button(self):
     99        self.assertEqual(
    100            # src.traffic_light.show(
    101            src.traffic_light.show_walk(
    102                current_light=GREEN,
    103                timer_done=True,
    104                walk_button=True,
    105            ),
    106            (YELLOW, NO_WALK)
    107        )
    108
    109        self.assertEqual(
    110            # src.traffic_light.show(
    111            src.traffic_light.show_walk(
    112                current_light=GREEN,
    113                timer_done=True,
    114                walk_button=False,
    115            ),
    116            (YELLOW, NO_WALK)
    117        )
    

    still green

  • I change the third assertion

     98    def test_traffic_light_when_green_w_walk_button(self):
     99        self.assertEqual(
    100            # src.traffic_light.show(
    101            src.traffic_light.show_walk(
    102                current_light=GREEN,
    103                timer_done=True,
    104                walk_button=True,
    105            ),
    106            (YELLOW, NO_WALK)
    107        )
    108
    109        self.assertEqual(
    110            # src.traffic_light.show(
    111            src.traffic_light.show_walk(
    112                current_light=GREEN,
    113                timer_done=True,
    114                walk_button=False,
    115            ),
    116            (YELLOW, NO_WALK)
    117        )
    118
    119        self.assertEqual(
    120            # src.traffic_light.show(
    121            src.traffic_light.show_walk(
    122                current_light=GREEN,
    123                timer_done=False,
    124                walk_button=True,
    125            ),
    126            (GREEN, NO_WALK)
    127        )
    
  • I change the last assertion

     98    def test_traffic_light_when_green_w_walk_button(self):
     99        self.assertEqual(
    100            # src.traffic_light.show(
    101            src.traffic_light.show_walk(
    102                current_light=GREEN,
    103                timer_done=True,
    104                walk_button=True,
    105            ),
    106            (YELLOW, NO_WALK)
    107        )
    108
    109        self.assertEqual(
    110            # src.traffic_light.show(
    111            src.traffic_light.show_walk(
    112                current_light=GREEN,
    113                timer_done=True,
    114                walk_button=False,
    115            ),
    116            (YELLOW, NO_WALK)
    117        )
    118
    119        self.assertEqual(
    120            # src.traffic_light.show(
    121            src.traffic_light.show_walk(
    122                current_light=GREEN,
    123                timer_done=False,
    124                walk_button=True,
    125            ),
    126            (GREEN, NO_WALK)
    127        )
    128
    129        self.assertEqual(
    130            # src.traffic_light.show(
    131            src.traffic_light.show_walk(
    132                current_light=GREEN,
    133                timer_done=False,
    134                walk_button=False,
    135            ),
    136            (GREEN, NO_WALK)
    137        )
    

    still green


  • I remove the show function from traffic_light.py since it is no longer used

     1def show_walk(
     2        current_light='RED', timer_done=False,
     3        walk_button=False,
     4    ):
     5    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     6    next_light = red
     7    walk = 'NO WALK'
     8
     9    if timer_done:
    10        if current_light == green:
    11            next_light = yellow
    12        if current_light == red:
    13            if walk_button:
    14                next_light = red
    15            else:
    16                next_light = green
    17    else:
    18        next_light = current_light
    19
    20    if next_light == red:
    21        walk = 'WALK'
    22
    23    return next_light, walk
    
  • Since my new solution works, I right click on the name show_walk and select Rename Symbol (Visual Studio Code) to change the name to show and all tests are still green

    1def show(
    2        current_light='RED', timer_done=False,
    3        walk_button=False,
    4    ):
    

### REFACTOR show

  • I add 2 global variables to test_traffic_light.py

     1import src.traffic_light
     2import unittest
     3
     4
     5RED, YELLOW, GREEN = 'RED', 'YELLOW', 'GREEN'
     6NO_WALK = 'NO WALK'
     7WALK = (RED, 'WALK')
     8YELLOW_NO_WALK = (YELLOW, NO_WALK)
     9GREEN_NO_WALK = (GREEN, NO_WALK)
    10
    11
    12class TestTrafficLight(unittest.TestCase):
    
  • I use GREEN_NO_WALK for (GREEN, NO_WALK) in the second assertion of test_traffic_light_when_red_w_walk_button

    the test is still green

  • I remove the commented lines

    14    def test_traffic_light_when_red_w_walk_button(self):
    15        self.assertEqual(
    16            src.traffic_light.show(
    17                timer_done=True,
    18                walk_button=True,
    19            ),
    20            WALK
    21        )
    22
    23        self.assertEqual(
    24            src.traffic_light.show(
    25                timer_done=True,
    26                walk_button=False
    27            ),
    28            GREEN_NO_WALK
    29        )
    30
    31        self.assertEqual(
    32            src.traffic_light.show(
    33                timer_done=False,
    34                walk_button=True,
    35            ),
    36            WALK
    37        )
    38
    39        self.assertEqual(
    40            src.traffic_light.show(
    41                timer_done=False,
    42                walk_button=False,
    43            ),
    44            WALK
    45        )
    46
    47    def test_traffic_light_when_yellow_w_walk_button(self):
    
  • I use YELLOW_NO_WALK for (YELLOW, NO_WALK) in test_traffic_light_when_yellow_w_walk_button

    47    def test_traffic_light_when_yellow_w_walk_button(self):
    48        self.assertEqual(
    49            # src.traffic_light.show(
    50            src.traffic_light.show(
    51                current_light=YELLOW,
    52                timer_done=True,
    53                walk_button=True,
    54            ),
    55            # (RED, 'WALK')
    56            WALK
    57        )
    58
    59        self.assertEqual(
    60            # src.traffic_light.show(
    61            src.traffic_light.show(
    62                current_light=YELLOW,
    63                timer_done=True,
    64                walk_button=False,
    65            ),
    66            # (RED, 'WALK')
    67            WALK
    68        )
    69
    70        self.assertEqual(
    71            # src.traffic_light.show(
    72            src.traffic_light.show(
    73                current_light=YELLOW,
    74                timer_done=False,
    75                walk_button=True,
    76            ),
    77            # (YELLOW, 'NO WALK')
    78            # (YELLOW, NO_WALK)
    79            YELLOW_NO_WALK
    80        )
    81
    82        self.assertEqual(
    83            # src.traffic_light.show(
    84            src.traffic_light.show(
    85                current_light=YELLOW,
    86                timer_done=False,
    87                walk_button=False,
    88            ),
    89            # (YELLOW, 'NO WALK')
    90            # (YELLOW, NO_WALK)
    91            YELLOW_NO_WALK
    92        )
    

    still green

  • I remove the commented lines from test_traffic_light_when_yellow_w_walk_button

    47    def test_traffic_light_when_yellow_w_walk_button(self):
    48        self.assertEqual(
    49            src.traffic_light.show(
    50                current_light=YELLOW,
    51                timer_done=True,
    52                walk_button=True,
    53            ),
    54            WALK
    55        )
    56
    57        self.assertEqual(
    58            src.traffic_light.show(
    59                current_light=YELLOW,
    60                timer_done=True,
    61                walk_button=False,
    62            ),
    63            WALK
    64        )
    65
    66        self.assertEqual(
    67            src.traffic_light.show(
    68                current_light=YELLOW,
    69                timer_done=False,
    70                walk_button=True,
    71            ),
    72            YELLOW_NO_WALK
    73        )
    74
    75        self.assertEqual(
    76            src.traffic_light.show(
    77                current_light=YELLOW,
    78                timer_done=False,
    79                walk_button=False,
    80            ),
    81            YELLOW_NO_WALK
    82        )
    83
    84    def test_traffic_light_when_green_w_walk_button(self):
    
  • I use YELLOW_NO_WALK for (YELLOW, NO_WALK) in test_traffic_light_when_green_w_walk_button

     84    def test_traffic_light_when_green_w_walk_button(self):
     85        self.assertEqual(
     86            # src.traffic_light.show(
     87            src.traffic_light.show(
     88                current_light=GREEN,
     89                timer_done=True,
     90                walk_button=True,
     91            ),
     92            # (YELLOW, NO_WALK)
     93            YELLOW_NO_WALK
     94        )
     95
     96        self.assertEqual(
     97            # src.traffic_light.show(
     98            src.traffic_light.show(
     99                current_light=GREEN,
    100                timer_done=True,
    101                walk_button=False,
    102            ),
    103            # (YELLOW, NO_WALK)
    104            YELLOW_NO_WALK
    105        )
    

    green

  • I use GREEN_NO_WALK for (GREEN, NO_WALK)

     84    def test_traffic_light_when_green_w_walk_button(self):
     85        self.assertEqual(
     86            # src.traffic_light.show(
     87            src.traffic_light.show(
     88                current_light=GREEN,
     89                timer_done=True,
     90                walk_button=True,
     91            ),
     92            # (YELLOW, NO_WALK)
     93            YELLOW_NO_WALK
     94        )
     95
     96        self.assertEqual(
     97            # src.traffic_light.show(
     98            src.traffic_light.show(
     99                current_light=GREEN,
    100                timer_done=True,
    101                walk_button=False,
    102            ),
    103            # (YELLOW, NO_WALK)
    104            YELLOW_NO_WALK
    105        )
    106
    107        self.assertEqual(
    108            # src.traffic_light.show(
    109            src.traffic_light.show(
    110                current_light=GREEN,
    111                timer_done=False,
    112                walk_button=True,
    113            ),
    114            # (GREEN, NO_WALK)
    115            GREEN_NO_WALK
    116        )
    117
    118        self.assertEqual(
    119            # src.traffic_light.show(
    120            src.traffic_light.show(
    121                current_light=GREEN,
    122                timer_done=False,
    123                walk_button=False,
    124            ),
    125            # (GREEN, NO_WALK)
    126            GREEN_NO_WALK
    127        )
    128
    129
    130# Exceptions seen
    

    still green

  • I remove the commented lines

     84    def test_traffic_light_when_green_w_walk_button(self):
     85        self.assertEqual(
     86            src.traffic_light.show(
     87                current_light=GREEN,
     88                timer_done=True,
     89                walk_button=True,
     90            ),
     91            YELLOW_NO_WALK
     92        )
     93
     94        self.assertEqual(
     95            src.traffic_light.show(
     96                current_light=GREEN,
     97                timer_done=True,
     98                walk_button=False,
     99            ),
    100            YELLOW_NO_WALK
    101        )
    102
    103        self.assertEqual(
    104            src.traffic_light.show(
    105                current_light=GREEN,
    106                timer_done=False,
    107                walk_button=True,
    108            ),
    109            GREEN_NO_WALK
    110        )
    111
    112        self.assertEqual(
    113            src.traffic_light.show(
    114                current_light=GREEN,
    115                timer_done=False,
    116                walk_button=False,
    117            ),
    118            GREEN_NO_WALK
    119        )
    120
    121
    122# Exceptions seen
    123# AssertionError
    124# NameError
    125# AttributeError
    126# TypeError
    127# SyntaxError
    

  • I add a conditional expression at the top of the show function with an if statement for when the timer is NOT done

     1def show(
     2        current_light='RED', timer_done=False,
     3        walk_button=False,
     4    ):
     5    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     6    next_light = red
     7    walk = 'NO WALK'
     8
     9    if not timer_done:
    10        return current_light, (
    11            'WALK'
    12            if current_light == red
    13            else 'NO WALK'
    14        )
    15
    16    if timer_done:
    

    green

  • I add an if statement for when the light is GREEN

     1def show(
     2        current_light='RED', timer_done=False,
     3        walk_button=False,
     4    ):
     5    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     6    next_light = red
     7    walk = 'NO WALK'
     8
     9    if not timer_done:
    10        return current_light, (
    11            'WALK'
    12            if current_light == red
    13            else 'NO WALK'
    14        )
    15
    16    if current_light == green:
    17        return yellow, 'NO WALK'
    18
    19    if timer_done:
    

    still green

  • I add an if statement for when the light is RED

     1def show(
     2        current_light='RED', timer_done=False,
     3        walk_button=False,
     4    ):
     5    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     6    next_light = red
     7    walk = 'NO WALK'
     8
     9    if not timer_done:
    10        return current_light, (
    11            'WALK'
    12            if current_light == red
    13            else 'NO WALK'
    14        )
    15
    16    if current_light == green:
    17        return yellow, 'NO WALK'
    18    if current_light == red:
    19        return (
    20            (red, 'WALK')
    21            if walk_button
    22            else (green, 'NO WALK')
    23        )
    24
    25    if timer_done:
    

    the test is still green

  • I add a return statement for the default case which covers when the light is YELLOW

     1def show(
     2        current_light='RED', timer_done=False,
     3        walk_button=False,
     4    ):
     5    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     6    next_light = red
     7    walk = 'NO WALK'
     8
     9    if not timer_done:
    10        return current_light, (
    11            'WALK'
    12            if current_light == red
    13            else 'NO WALK'
    14        )
    15
    16    if current_light == green:
    17        return yellow, 'NO WALK'
    18    if current_light == red:
    19        return (
    20            (red, 'WALK')
    21            if walk_button
    22            else (green, 'NO WALK')
    23        )
    24
    25    return (red, 'WALK')
    26
    27    if timer_done:
    28        if current_light == green:
    29            next_light = yellow
    30        if current_light == red:
    31            if walk_button:
    32                next_light = red
    33            else:
    34                next_light = green
    35    else:
    36        next_light = current_light
    37
    38    if next_light == red:
    39        walk = 'WALK'
    40
    41    return next_light, walk
    

    still green

  • I remove the other statements

     1def show(
     2        current_light='RED', timer_done=False,
     3        walk_button=False,
     4    ):
     5    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     6    next_light = red
     7    walk = 'NO WALK'
     8
     9    if not timer_done:
    10        return current_light, (
    11            'WALK'
    12            if current_light == red
    13            else 'NO WALK'
    14        )
    15
    16    if current_light == green:
    17        return yellow, 'NO WALK'
    18    if current_light == red:
    19        return (
    20            (red, 'WALK')
    21            if walk_button
    22            else (green, 'NO WALK')
    23        )
    24
    25    return (red, 'WALK')
    
  • I change the value of the walk variable

    1def show(
    2        current_light='RED', timer_done=False,
    3        walk_button=False,
    4    ):
    5    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
    6    next_light = red
    7    walk = 'WALK'
    8
    9    if not timer_done:
    
  • I use it to remove repetition in the statements

     1def show(
     2        current_light='RED', timer_done=False,
     3        walk_button=False,
     4    ):
     5    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     6    next_light = red
     7    walk = 'WALK'
     8
     9    if not timer_done:
    10        return current_light, (
    11            # 'WALK'
    12            walk
    13            if current_light == red
    14            else 'NO WALK'
    15        )
    16
    17    if current_light == green:
    18        return yellow, 'NO WALK'
    19    if current_light == red:
    20        return (
    21            # (red, 'WALK')
    22            (red, walk)
    23            if walk_button
    24            else (green, 'NO WALK')
    25        )
    26
    27    # return (red, 'WALK')
    28    return (red, walk)
    

    green

  • I change the next_light variable to no_walk

    1def show(
    2        current_light='RED', timer_done=False,
    3        walk_button=False,
    4    ):
    5    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
    6    no_walk = 'NO WALK'
    7    walk = 'WALK'
    8
    9    if not timer_done:
    
  • I use it to remove repetition

     1def show(
     2        current_light='RED', timer_done=False,
     3        walk_button=False,
     4    ):
     5    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     6    no_walk = 'NO WALK'
     7    walk = 'WALK'
     8
     9    if not timer_done:
    10        return current_light, (
    11            # 'WALK'
    12            walk
    13            if current_light == red
    14            # else 'NO WALK'
    15            else no_walk
    16        )
    17
    18    if current_light == green:
    19        # return yellow, 'NO WALK'
    20        return yellow, no_walk
    21    if current_light == red:
    22        return (
    23            # (red, 'WALK')
    24            (red, walk)
    25            if walk_button
    26            # else (green, 'NO WALK')
    27            else (green, no_walk)
    28        )
    29
    30    # return (red, 'WALK')
    31    return (red, walk)
    

    still green

  • I remove the commented lines

     1def show(
     2        current_light='RED', timer_done=False,
     3        walk_button=False,
     4    ):
     5    red, yellow, green = 'RED', 'YELLOW', 'GREEN'
     6    no_walk = 'NO WALK'
     7    walk = 'WALK'
     8
     9    if not timer_done:
    10        return current_light, (
    11            walk
    12            if current_light == red
    13            else no_walk
    14        )
    15
    16    if current_light == green:
    17        return yellow, no_walk
    18    if current_light == red:
    19        return (
    20            (red, walk)
    21            if walk_button
    22            else (green, no_walk)
    23        )
    24
    25    return (red, walk)
    

review

I ran tests for a Traffic Light that has a timer and a button for people to push when they want to walk. If the inputs are

  • what color is the light now?

  • is the timer done?

  • did the person push the walk button?

then this is the truth table for the Traffic Light

current light

timer done

walk button

show

RED

yes

yes

RED + WALK

RED

yes

no

GREEN + NO WALK

RED

no

yes

RED + WALK

RED

no

no

RED + WALK

YELLOW

yes

yes

RED + WALK

YELLOW

yes

no

RED + WALK

YELLOW

no

yes

YELLOW + NO WALK

YELLOW

no

no

YELLOW + NO WALK

GREEN

yes

yes

YELLOW + NO WALK

GREEN

yes

no

YELLOW + NO WALK

GREEN

no

yes

GREEN + NO WALK

GREEN

no

no

GREEN + NO WALK


code from the chapter

Do you want to see all the CODE I typed in this chapter?


what is next?

you now know

Would you like to test making a calculator?


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