Elevator

I want to make an Elevator Controller that will MOVE to a floor when I push a button for the floor.

preview

These are the tests I have at the end of the chapter

elevator/tests/test_elevator.py
 1import src.elevator
 2import unittest
 3
 4
 5class TestElevator(unittest.TestCase):
 6
 7    def test_emergency_w_above_weight_doors_closed_number_pushed(self):
 8        self.assertFalse(
 9            src.elevator.controller(
10                number_pushed=True,
11                doors_closed=True,
12                above_weight=True,
13                emergency=True,
14            )
15        )
16        self.assertFalse(
17            src.elevator.controller(
18                number_pushed=True,
19                doors_closed=True,
20                above_weight=True,
21                emergency=False,
22            )
23        )
elevator/tests/test_elevator.py
25    def test_emergency_w_below_weight_doors_closed_number_pushed(self):
26        self.assertFalse(
27            src.elevator.controller(
28                number_pushed=True,
29                doors_closed=True,
30                above_weight=False,
31                emergency=True,
32            )
33        )
34        self.assertTrue(
35            src.elevator.controller(
36                number_pushed=True,
37                doors_closed=True,
38                above_weight=False,
39                emergency=False,
40            )
41        )
elevator/tests/test_elevator.py
43    def test_emergency_w_above_weight_doors_open_number_pushed(self):
44        self.assertFalse(
45            src.elevator.controller(
46                number_pushed=True,
47                doors_closed=False,
48                above_weight=True,
49                emergency=True,
50            )
51        )
52        self.assertFalse(
53            src.elevator.controller(
54                number_pushed=True,
55                doors_closed=False,
56                above_weight=True,
57                emergency=False,
58            )
59        )
elevator/tests/test_elevator.py
61    def test_emergency_w_below_weight_doors_open_number_pushed(self):
62        self.assertFalse(
63            src.elevator.controller(
64                number_pushed=True,
65                doors_closed=False,
66                above_weight=False,
67                emergency=True,
68            )
69        )
70        self.assertFalse(
71            src.elevator.controller(
72                number_pushed=True,
73                doors_closed=False,
74                above_weight=False,
75                emergency=False,
76            )
77        )
elevator/tests/test_elevator.py
79    def test_emergency_w_above_weight_doors_closed_number_not_pushed(self):
80        self.assertFalse(
81            src.elevator.controller(
82                number_pushed=False,
83                doors_closed=True,
84                above_weight=True,
85                emergency=True,
86            )
87        )
88        self.assertFalse(
89            src.elevator.controller(
90                number_pushed=False,
91                doors_closed=True,
92                above_weight=True,
93                emergency=False,
94            )
95        )
elevator/tests/test_elevator.py
 97    def test_emergency_w_below_weight_doors_closed_number_not_pushed(self):
 98        self.assertFalse(
 99            src.elevator.controller(
100                number_pushed=False,
101                doors_closed=True,
102                above_weight=False,
103                emergency=True,
104            )
105        )
106        self.assertFalse(
107            src.elevator.controller(
108                number_pushed=False,
109                doors_closed=True,
110                above_weight=False,
111                emergency=False,
112            )
113        )
elevator/tests/test_elevator.py
115    def test_emergency_w_above_weight_doors_open_number_not_pushed(self):
116        self.assertFalse(
117            src.elevator.controller(
118                number_pushed=False,
119                doors_closed=False,
120                above_weight=True,
121                emergency=True,
122            )
123        )
124        self.assertFalse(
125            src.elevator.controller(
126                number_pushed=False,
127                doors_closed=False,
128                above_weight=True,
129                emergency=False,
130            )
131        )
elevator/tests/test_elevator.py
133    def test_emergency_w_below_weight_doors_open_number_not_pushed(self):
134        self.assertFalse(
135            src.elevator.controller(
136                number_pushed=False,
137                doors_closed=False,
138                above_weight=False,
139                emergency=True,
140            )
141        )
142        self.assertFalse(
143            src.elevator.controller(
144                number_pushed=False,
145                doors_closed=False,
146                above_weight=False,
147                emergency=False,
148            )
149        )
150
151
152# Exceptions seen
153# AssertionError
154# NameError
155# AttributeError
156# TypeError
157# SyntaxError

start the project

  • I open a terminal

    • I open makePythonTdd.sh

    • I open makePythonTdd.ps1

    • I change the name of the project to elevator in makePythonTdd.sh

       1#!/bin/bash
       2uv init elevator
       3cd elevator
       4mkdir src
       5mv main.py src/elevator.py
       6mkdir tests
       7touch tests/__init__.py
       8
       9echo "import unittest
      10
      11
      12class TestElevator(unittest.TestCase):
      13
      14    def test_failure(self):
      15        self.assertFalse(True)
      16
      17
      18# Exceptions seen
      19# AssertionError
      20" > tests/test_elevator.py
      21
      22echo "pytest" > requirements.txt
      23echo "pytest-watcher" >> requirements.txt
      24uv add --requirement requirements.txt
      25uv run pytest-watcher . --now
      
    • I run makePythonTdd.sh in the terminal to make the elevator project

      ./makePythonTdd.sh
      
    • I change the name of the project to elevator in makePythonTdd.ps1

       1uv init elevator
       2cd elevator
       3mkdir src
       4Move-Item "main.py" "src/elevator.py"
       5mkdir tests
       6New-Item tests/__init__.py
       7
       8"import unittest
       9
      10
      11class TestElevator(unittest.TestCase):
      12
      13    def test_failure(self):
      14        self.assertFalse(True)
      15
      16
      17# Exceptions seen
      18# AssertionError
      19" | Out-File "tests/test_elevator.py" -Encoding UTF8
      20
      21"pytest" | Out-File requirements.txt -Encoding UTF8
      22"pytest-watcher" >> requirements.txt
      23uv add --requirement requirements.txt
      24uv run pytest-watcher . --now
      
    • I run makePythonTdd.ps1 in the terminal to make the elevator project

      .\makePythonTdd.ps1
      

    the terminal is my friend, and shows AssertionError

    ======================== FAILURES =========================
    ______________ TestElevator.test_failure __________________
    
    self = <tests.test_elevator.TestElevator testMethod=test_failure>
    
        def test_failure(self):
    >       self.assertFalse(True)
    E       AssertionError: True is not false
    
    tests/test_elevator.py:7: AssertionError
    ================ short test summary info ==================
    FAILED tests/test_elevator.py::TestElevator::test_failure - AssertionError: True is not false
    ==================== 1 failed in X.YZs ====================
    
  • I hold ctrl (Windows/Linux) or option/command (MacOS) on the keyboard and use the mouse to click on tests/test_elevator.py:7 to open it

  • I change assertFalse to assertTrue in test_elevator.py

     4class TestElevator(unittest.TestCase):
     5
     6    def test_failure(self):
     7        # self.assertFalse(True)
     8        self.assertTrue(True)
     9
    10
    11# Exceptions seen
    

    the test passes.

  • I open a new terminal then change directory to elevator

    cd elevator
    
  • I add the new files and folder to git for tracking

    git add .
    
  • I add a git commit message

    git commit -am 'setup project'
    

I want the Elevator to MOVE only when the button for a floor is pushed. I get this truth table

floor button

output

pushed

True

NOT pushed

False

Where True means the Elevator will MOVE up or down to the floor number that is pushed, and False means it does NOT MOVE.


test_number_pushed

RED: make it fail


  • I go back to the terminal where the tests are running

  • I change test_failure to test_number_pushed with an assertion for if the button for a floor is pushed

    floor button

    output

    pushed

    True

     4class TestElevator(unittest.TestCase):
     5
     6    def test_number_pushed(self):
     7        self.assertTrue(
     8            src.elevator.controller(
     9                number_pushed=True,
    10            )
    11        )
    12
    13
    14# Exceptions seen
    15# AssertionError
    

    the terminal is my friend, and shows NameError

    NameError: name 'src' is not defined
    

    because I do not have a definition for src in this file.

  • I add NameError to the list of Exceptions seen

    14# Exceptions seen
    15# AssertionError
    16# NameError
    

GREEN: make it pass


  • I add an import statement at the top of the file

    1import src.elevator
    2import unittest
    3
    4
    5class TestElevator(unittest.TestCase):
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.elevator'
                    has no attribute 'elevator'
    

    because elevator.py in the src folder does not have anything named controller in it.

  • I add AttributeError to the list of Exceptions seen

    15# Exceptions seen
    16# AssertionError
    17# NameError
    18# AttributeError
    
  • I open elevator.py from the src folder

  • I delete all the text in the file then add a function named controller to elevator.py

    1def controller():
    2    return None
    

    the terminal is my friend, and shows TypeError

    TypeError: elevator() got
               an unexpected keyword argument 'number_pushed'
    

    because the test called the controller function with a name (number_pushed) that is not in the parentheses of its definition.

  • I add TypeError to the list of Exceptions seen, in test_elevator.py

    15# Exceptions seen
    16# AssertionError
    17# NameError
    18# AttributeError
    19# TypeError
    
  • I add number_pushed to the function signature

    1def controller(number_pushed):
    2    return None
    

    the terminal is my friend, and shows AssertionError

    AssertionError: None is not true
    

    the controller function returned None and the assertion expects True

  • I change the return statement to give the test what it wants

    1def controller(number_pushed):
    2    return True
    

    the test passes. The controller function always returns True, it does not care about the inputs. Is this Tautology?

    elevator(number_pushed=True ) -> True
    
  • I add a git commit message in the other terminal

    git commit -am 'add test_number_pushed'
    

test_number_not_pushed

RED: make it fail


  • I go back to the terminal where the tests are running

  • I add a test with an assertion for if the button for a floor is NOT pushed

    floor button

    output

    NOT pushed

    False

     7    def test_number_pushed(self):
     8        self.assertTrue(
     9            src.elevator.controller(
    10                number_pushed=True,
    11            )
    12        )
    13
    14    def test_number_not_pushed(self):
    15        self.assertFalse(
    16            src.elevator.controller(
    17                number_pushed=False,
    18            )
    19        )
    20
    21
    22# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: True is not false
    

    because the controller function always returns True and this assertion expects False.


GREEN: make it pass


  • I make the function return its input

    1def controller(number_pushed):
    2    return number_pushed
    

    the test passes.

    elevator(number_pushed=True ) -> True
    elevator(number_pushed=False) -> False
    
  • I add a git commit message in the other terminal

    git commit -am 'add test_number_not_pushed'
    

I want the Elevator to MOVE only when the button for a floor is pushed AND the doors are closed. I do not want anything or anyone falling out of the Elevator while it is MOVING. The inputs to the Elevator Controller will then be

  • was the number for a floor pushed?

  • are the doors closed?

Which gives me this truth table

floor button

doors

output

pushed

closed

True

pushed

open

False

NOT pushed

closed

False

NOT pushed

open

False


test_doors_closed_number_pushed

RED: make it fail


  • I go back to the terminal where the tests are running

  • I add doors_closed with a value to the call to the controller function from test_number_pushed for if the button for a floor is pushed AND the Elevator doors are closed

    floor button

    doors

    output

    pushed

    closed

    True

     7    def test_number_pushed(self):
     8        self.assertTrue(
     9            src.elevator.controller(
    10                number_pushed=True,
    11                doors_closed=True,
    12            )
    13        )
    14
    15    def test_number_not_pushed(self):
    
    TypeError: elevator() got
               an unexpected keyword argument 'doors_closed'
    

    because the test called the controller function with a name (doors_closed) that is not in the parentheses of its definition.


GREEN: make it pass


  • I add doors_closed to the function in elevator.py

    1def controller(number_pushed, doors_closed):
    2    return number_pushed
    

    the terminal is my friend, and shows TypeError

    TypeError: elevator() missing
               1 required positional argument: 'doors_closed'
    

    because the assertion in test_number_not_pushed calls the controller function with one argument (number_pushed) and I just changed the function to make it take two required arguments (number_pushed and doors_closed). I have to make doors_closed a choice.

  • I add a default value for doors_closed to make it a choice

    1def controller(number_pushed, doors_closed=False):
    2    return number_pushed
    

    the test passes.

    elevator(number_pushed=True , doors_closed=True ) -> True
    

REFACTOR: make it better


  • I change the name of test_number_pushed to test_doors_closed_number_pushed

     5class TestElevator(unittest.TestCase):
     6
     7    def test_doors_closed_number_pushed(self):
     8        self.assertTrue(
     9            src.elevator.controller(
    10                number_pushed=True,
    11                doors_closed=True,
    12            )
    13        )
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_doors_closed_number_pushed'
    

test_doors_open_number_pushed

RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add a test named test_doors_open_number_pushed with an assertion for if the button for a floor is pushed AND the Elevator doors are open

    floor button

    doors

    output

    pushed

    open

    False

     7    def test_doors_closed_number_pushed(self):
     8        self.assertTrue(
     9            src.elevator.controller(
    10                number_pushed=True,
    11                doors_closed=True,
    12            )
    13        )
    14
    15    def test_doors_open_number_pushed(self):
    16        self.assertFalse(
    17            src.elevator.controller(
    18                number_pushed=True,
    19                doors_closed=False,
    20            )
    21        )
    22
    23    def test_number_not_pushed(self):
    

    the terminal is my friend, and shows AssertionError

    AssertionError: True is not false
    

    because the controller function returns the value of the number_pushed parameter.


GREEN: make it pass


I add an if statement to the controller function in elevator.py

1def controller(number_pushed, doors_closed=False):
2    if not doors_closed:
3        return False
4    return number_pushed

the test passes.

elevator(number_pushed=True , doors_closed=True ) -> True
elevator(number_pushed=True , doors_closed=False) -> False

REFACTOR: make it better


  • I want the Elevator to only check if the doors are closed if the button for a floor is pushed. I change the if statement

    1def controller(number_pushed, doors_closed=False):
    2    # if not doors_closed:
    3    if not number_pushed:
    4        return False
    5    # return number_pushed
    6    return doors_closed
    

    the test is still green.

  • I remove the commented lines

    1def controller(number_pushed, doors_closed=False):
    2    if not number_pushed:
    3        return False
    4    return doors_closed
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_doors_open_number_pushed'
    

If the button for a floor is pushed, the Elevator only MOVES when the doors are closed.


test_doors_closed_number_not_pushed

  • I go back to the terminal where the tests are running

  • I add doors_closed with a value to the call to the controller function from test_number_not_pushed for if the button for a floor is NOT pushed AND the Elevator doors are closed

    floor button

    doors

    output

    NOT pushed

    closed

    False

    23    def test_number_not_pushed(self):
    24        self.assertFalse(
    25            src.elevator.controller(
    26                number_pushed=False,
    27                doors_closed=True,
    28            )
    29        )
    30
    31
    32# Exceptions seen
    

    the test is still green.

    elevator(number_pushed=True , doors_closed=True ) -> True
    elevator(number_pushed=True , doors_closed=False) -> False
    elevator(number_pushed=False, doors_closed=True ) -> False
    
  • I change the name of test_number_not_pushed to test_doors_closed_number_not_pushed

    15    def test_doors_open_number_pushed(self):
    16        self.assertFalse(
    17            src.elevator.controller(
    18                number_pushed=True,
    19                doors_closed=False,
    20            )
    21        )
    22
    23    def test_doors_closed_number_not_pushed(self):
    24        self.assertFalse(
    25            src.elevator.controller(
    26                number_pushed=False,
    27                doors_closed=True,
    28            )
    29        )
    30
    31
    32# Exceptions seen
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_doors_closed_number_not_pushed'
    

test_doors_open_number_not_pushed

RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add test_doors_open_number_not_pushed with an assertion for if the button for a floor is NOT pushed AND the Elevator doors are open, in test_elevator.py

    floor button

    doors

    output

    NOT pushed

    open

    False

    23    def test_doors_closed_number_not_pushed(self):
    24        self.assertFalse(
    25            src.elevator.controller(
    26                number_pushed=False,
    27                doors_closed=True,
    28            )
    29        )
    30
    31    def test_doors_open_number_not_pushed(self):
    32        self.assertTrue(
    33            src.elevator.controller(
    34                number_pushed=False,
    35                doors_closed=False,
    36            )
    37        )
    38
    39
    40# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    

GREEN: make it pass


  • I change assertTrue to assertFalse in test_doors_open_number_not_pushed

    31    def test_doors_open_number_not_pushed(self):
    32        self.assertFalse(
    33            src.elevator.controller(
    34                number_pushed=False,
    35                doors_closed=False,
    36            )
    37        )
    38
    39
    40# Exceptions seen
    

    the test passes.

    elevator(number_pushed=True , doors_closed=True ) -> True
    elevator(number_pushed=True , doors_closed=False) -> False
    elevator(number_pushed=False, doors_closed=True ) -> False
    elevator(number_pushed=False, doors_closed=False) -> False
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_doors_open_number_not_pushed'
    

When the controller function is called, it checks if the button for a floor is NOT pushed

  • If the button for a floor is NOT pushed it returns False

    elevator(number_pushed=False, doors_closed=False) -> False
    └── def controller(number_pushed, doors_closed=False):
        └── if not number_pushed:
            └── return False
            return doors_closed
    
    elevator(number_pushed=False, doors_closed=True ) -> False
    └── def controller(number_pushed, doors_closed=False):
        └── if not number_pushed:
            └── return False
            return doors_closed
    
  • If the button for a floor is pushed it returns the value of doors_closed

    • if the button for a floor is pushed AND the Elevator doors are open, it returns False

      elevator(number_pushed=False, doors_closed=True ) -> False
      └── def controller(number_pushed, doors_closed=False):
          ├── if not number_pushed:
                return False
          └── return doors_closed
              return False
      
    • if the button for a floor is pushed AND the Elevator doors are closed, it returns True

      elevator(number_pushed=True , doors_closed=True ) -> True
      └── def controller(number_pushed, doors_closed=False):
          ├── if not number_pushed:
                return False
          └── return doors_closed
              return True
      

So far, the truth table for the Elevator is

floor button

doors

output

pushed

closed

True

pushed

open

False

NOT pushed

closed

False

NOT pushed

open

False

I want to add a failsafe to the Elevator Controller so it will NOT MOVE if the total weight of the Elevator when occupied is above a certain number, the inputs to the Controller will then be

  • was the number for a floor pushed?

  • are the doors closed?

  • is the Elevator above the weight limit?

Which gives me this truth table

floor button

doors

weight limit

output

pushed

closed

above

False

pushed

closed

below

True

pushed

open

above

False

pushed

open

below

False

floor button

doors

weight limit

output

NOT pushed

closed

above

False

NOT pushed

closed

below

False

NOT pushed

open

above

False

NOT pushed

open

below

False


test_above_weight_doors_open_number_not_pushed

RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add above_weight to the call to src.elevator.controller from test_doors_open_number_not_pushed for if the button for a floor is NOT pushed AND the Elevator doors are open AND the Elevator is above the weight limit

    floor button

    doors

    weight limit

    output

    NOT pushed

    open

    above

    False

    31    def test_doors_open_number_not_pushed(self):
    32        self.assertFalse(
    33            src.elevator.controller(
    34                number_pushed=False,
    35                doors_closed=False,
    36                above_weight=True,
    37            )
    38        )
    39
    40
    41# Exceptions seen
    

    the terminal is my friend, and shows TypeError

    TypeError: elevator() got
               an unexpected keyword argument 'above_weight'
    

    because the test called the controller function with a name (above_weight) that is not in the parentheses of its definition.


GREEN: make it pass


  • I add above_weight to the function signature in elevator.py

    1def controller(
    2        number_pushed, doors_closed=False,
    3        above_weight,
    4    ):
    5    if not number_pushed:
    6        return False
    7    return doors_closed
    

    the terminal is my friend, and shows SyntaxError

    SyntaxError: parameter without a default follows
                 parameter with a default
    

    because parameters without default values must come before parameters with default values.

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

    41# Exceptions seen
    42# AssertionError
    43# NameError
    44# AttributeError
    45# TypeError
    46# SyntaxError
    
  • I add a default value to make above_weight a choice, in elevator.py

    1def controller(
    2    number_pushed, doors_closed=False,
    3    above_weight=False,
    4):
    

    the test passes.

    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=True
    ) -> False
    

REFACTOR: make it better


  • I change the name of the test from test_doors_open_number_not_pushed to test_above_weight_doors_open_number_not_pushed, in test_elevator.py

    23    def test_doors_closed_number_not_pushed(self):
    24        self.assertFalse(
    25            src.elevator.controller(
    26                number_pushed=False,
    27                doors_closed=True,
    28            )
    29        )
    30
    31    def test_above_weight_doors_open_number_not_pushed(self):
    32        self.assertFalse(
    33            src.elevator.controller(
    34                number_pushed=False,
    35                doors_closed=False,
    36                above_weight=True,
    37            )
    38        )
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_above_weight_doors_open_number_not_pushed'
    

test_below_weight_doors_open_number_not_pushed

RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add a test with an assertion for if the button for a floor is NOT pushed AND the Elevator doors are open AND the Elevator is below the weight limit

    floor button

    doors

    weight limit

    output

    NOT pushed

    closed

    below

    False

    31    def test_above_weight_doors_open_number_not_pushed(self):
    32        self.assertFalse(
    33            src.elevator.controller(
    34                number_pushed=False,
    35                doors_closed=False,
    36                above_weight=True,
    37            )
    38        )
    39
    40    def test_below_weight_doors_open_number_not_pushed(self):
    41        self.assertTrue(
    42            src.elevator.controller(
    43                number_pushed=False,
    44                doors_closed=False,
    45                above_weight=False,
    46            )
    47        )
    48
    49
    50# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    

    because the controller function returned False and this assertion expects True.


GREEN: make it pass


  • I change assertTrue to assertFalse in test_below_weight_doors_open_number_not_pushed

    40    def test_below_weight_doors_open_number_not_pushed(self):
    41        self.assertFalse(
    42            src.elevator.controller(
    43                number_pushed=False,
    44                doors_closed=False,
    45                above_weight=False,
    46            )
    47        )
    48
    49
    50# Exceptions seen
    

    the test passes.

    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=True
    ) -> False
    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=False
    ) -> False
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_below_weight_doors_open_number_not_pushed'
    

test_above_weight_doors_closed_number_not_pushed

RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add a value for the above_weight parameter to the call to src.elevator.controller from test_doors_closed_number_not_pushed for if the button for a floor is NOT pushed AND the Elevator doors are closed AND the Elevator is above the weight limit

    floor button

    doors

    weight limit

    output

    NOT pushed

    closed

    above

    False

    23    def test_doors_closed_number_not_pushed(self):
    24        self.assertFalse(
    25            src.elevator.controller(
    26                number_pushed=False,
    27                doors_closed=True,
    28                above_weight=True,
    29            )
    30        )
    31
    32    def test_above_weight_doors_open_number_not_pushed(self):
    

    the test is still green.

    elevator(
        number_pushed=False, doors_closed=True,
        above_weight=True
    ) -> False
    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=True
    ) -> False
    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=False
    ) -> False
    
  • I change the name of the test from test_doors_closed_number_not_pushed to test_above_weight_doors_closed_number_not_pushed, in test_elevator.py

    15    def test_doors_open_number_pushed(self):
    16        self.assertFalse(
    17            src.elevator.controller(
    18                number_pushed=True,
    19                doors_closed=False,
    20            )
    21        )
    22
    23    def test_above_weight_doors_closed_number_not_pushed(self):
    24        self.assertFalse(
    25            src.elevator.controller(
    26                number_pushed=False,
    27                doors_closed=True,
    28                above_weight=True,
    29            )
    30        )
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_above_weight_doors_closed_number_not_pushed'
    

test_below_weight_doors_closed_number_not_pushed

RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add a test with an assertion for if the button for a floor is NOT pushed AND the Elevator doors are closed AND the Elevator is below the weight limit

    floor button

    doors

    weight limit

    output

    NOT pushed

    closed

    below

    False

    23    def test_above_weight_doors_closed_number_not_pushed(self):
    24        self.assertFalse(
    25            src.elevator.controller(
    26                number_pushed=False,
    27                doors_closed=True,
    28                above_weight=True,
    29            )
    30        )
    31
    32    def test_below_weight_doors_closed_number_not_pushed(self):
    33        self.assertTrue(
    34            src.elevator.controller(
    35                number_pushed=False,
    36                doors_closed=True,
    37                above_weight=False,
    38            )
    39        )
    40
    41    def test_above_weight_doors_open_number_not_pushed(self):
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    

GREEN: make it pass


  • I change assertTrue to assertFalse in test_below_weight_doors_closed_number_not_pushed

    32    def test_below_weight_doors_closed_number_not_pushed(self):
    33        self.assertFalse(
    34            src.elevator.controller(
    35                number_pushed=False,
    36                doors_closed=True,
    37                above_weight=False,
    38            )
    39        )
    40
    41    def test_above_weight_doors_open_number_not_pushed(self):
    

    the test passes.

    elevator(
        number_pushed=False, doors_closed=True,
        above_weight=True
    ) -> False
    elevator(
        number_pushed=False, doors_closed=True,
        above_weight=False
    ) -> False
    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=True
    ) -> False
    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=False
    ) -> False
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_below_weight_doors_closed_number_not_pushed'
    

test_above_weight_doors_open_number_pushed

RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add a value for the above_weight parameter to the call to src.elevator.controller from test_doors_open_number_pushed for if the button for a floor is pushed AND the Elevator doors are open AND the Elevator is above the weight limit

    floor button

    doors

    weight limit

    output

    pushed

    open

    above

    False

    15    def test_doors_open_number_pushed(self):
    16        self.assertFalse(
    17            src.elevator.controller(
    18                number_pushed=True,
    19                doors_closed=False,
    20                above_weight=True,
    21            )
    22        )
    23
    24    def test_above_weight_doors_closed_number_not_pushed(self):
    

    the test is still green.

    elevator(
        number_pushed=True, doors_closed=False,
        above_weight=True
    ) -> False
    
  • I change the name of the test from test_doors_open_number_pushed to test_above_weight_doors_open_number_pushed, in test_elevator.py

     7    def test_doors_closed_number_pushed(self):
     8        self.assertTrue(
     9            src.elevator.controller(
    10                number_pushed=True,
    11                doors_closed=True,
    12            )
    13        )
    14
    15    def test_above_weight_doors_open_number_pushed(self):
    16        self.assertFalse(
    17            src.elevator.controller(
    18                number_pushed=True,
    19                doors_closed=False,
    20                above_weight=True,
    21            )
    22        )
    23
    24    def test_above_weight_doors_closed_number_not_pushed(self):
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_above_weight_doors_open_number_pushed'
    

test_below_weight_doors_open_number_pushed

RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add a test with an assertion for if the button for a floor is pushed AND the Elevator doors are open AND the Elevator is below the weight limit

    floor button

    doors

    weight limit

    output

    pushed

    open

    below

    False

    15    def test_above_weight_doors_open_number_pushed(self):
    16        self.assertFalse(
    17            src.elevator.controller(
    18                number_pushed=True,
    19                doors_closed=False,
    20                above_weight=True,
    21            )
    22        )
    23
    24    def test_below_weight_doors_open_number_pushed(self):
    25        self.assertTrue(
    26            src.elevator.controller(
    27                number_pushed=True,
    28                doors_closed=False,
    29                above_weight=False,
    30            )
    31        )
    32
    33    def test_above_weight_doors_closed_number_not_pushed(self):
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    

    because the controller function returns False and this assertion expects True.


GREEN: make it pass


  • I change assertTrue to assertFalse in test_below_weight_doors_open_number_pushed

    24    def test_below_weight_doors_open_number_pushed(self):
    25        self.assertFalse(
    26            src.elevator.controller(
    27                number_pushed=True,
    28                doors_closed=False,
    29                above_weight=False,
    30            )
    31        )
    32
    33    def test_above_weight_doors_closed_number_not_pushed(self):
    

    the test passes.

    elevator(
        number_pushed=True, doors_closed=False,
        above_weight=True
    ) -> False
    elevator(
        number_pushed=True, doors_closed=False,
        above_weight=False
    ) -> False
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_below_weight_doors_open_number_pushed'
    

test_above_weight_doors_closed_number_pushed

RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add a value for the above_weight parameter to the call to src.elevator.controller from test_doors_closed_number_pushed for if the button for a floor is pushed AND the Elevator doors are closed AND the Elevator is above the weight limit

    floor button

    doors

    weight limit

    output

    pushed

    closed

    above

    False

     7    def test_doors_closed_number_pushed(self):
     8        self.assertTrue(
     9            src.elevator.controller(
    10                number_pushed=True,
    11                doors_closed=True,
    12                above_weight=True,
    13            )
    14        )
    15
    16    def test_above_weight_doors_open_number_pushed(self):
    

    the test is still green.

  • I change assertTrue to assertFalse in test_doors_closed_number_pushed

     7    def test_doors_closed_number_pushed(self):
     8        self.assertFalse(
     9            src.elevator.controller(
    10                number_pushed=True,
    11                doors_closed=True,
    12                above_weight=True,
    13            )
    14        )
    15
    16    def test_above_weight_doors_open_number_pushed(self):
    

    the terminal is my friend, and shows AssertionError

    AssertionError: True is not false
    
  • I add an if statement for above_weight in elevator.py

    1def controller(
    2        number_pushed, doors_closed=False,
    3        above_weight=False,
    4    ):
    5    if not number_pushed:
    6        return False
    7    if above_weight:
    8        return False
    9    return doors_closed
    

    the test passes.

    elevator(
        number_pushed=True, doors_closed=True,
        above_weight=True
    ) -> False
    elevator(
        number_pushed=True, doors_closed=False,
        above_weight=True
    ) -> False
    elevator(
        number_pushed=True, doors_closed=False,
        above_weight=False
    ) -> False
    

REFACTOR: make it better


  • I change the name of the test from test_doors_closed_number_pushed to test_above_weight_doors_closed_number_pushed, in test_elevator.py

     5class TestElevator(unittest.TestCase):
     6
     7    def test_above_weight_doors_closed_number_pushed(self):
     8        self.assertFalse(
     9            src.elevator.controller(
    10                number_pushed=True,
    11                doors_closed=True,
    12                above_weight=True,
    13            )
    14        )
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_above_weight_doors_closed_number_pushed'
    

test_below_weight_doors_closed_number_pushed

RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add a test with an assertion for if the button for a floor is pushed AND the Elevator doors are closed the Elevator is below the weight limit

    floor button

    doors

    weight limit

    output

    pushed

    closed

    below

    True

     7    def test_above_weight_doors_closed_number_pushed(self):
     8        self.assertFalse(
     9            src.elevator.controller(
    10                number_pushed=True,
    11                doors_closed=True,
    12                above_weight=True,
    13            )
    14        )
    15
    16    def test_below_weight_doors_closed_number_pushed(self):
    17        self.assertFalse(
    18            src.elevator.controller(
    19                number_pushed=True,
    20                doors_closed=True,
    21                above_weight=False,
    22            )
    23        )
    24
    25    def test_above_weight_doors_open_number_pushed(self):
    

    the terminal is my friend, and shows AssertionError

    AssertionError: True is not false
    

    because the controller function returns True and this assertion expects False.


GREEN: make it pass


  • I change assertFalse to assertTrue in test_below_weight_doors_closed_number_pushed

    16    def test_below_weight_doors_closed_number_pushed(self):
    17        self.assertTrue(
    18            src.elevator.controller(
    19                number_pushed=True,
    20                doors_closed=True,
    21                above_weight=False,
    22            )
    23        )
    24
    25    def test_above_weight_doors_open_number_pushed(self):
    

    the test passes.

    elevator(
        number_pushed=True, doors_closed=True,
        above_weight=True
    ) -> False
    elevator(
        number_pushed=True, doors_closed=True,
        above_weight=False
    ) -> True
    elevator(
        number_pushed=True, doors_closed=False,
        above_weight=True
    ) -> False
    elevator(
        number_pushed=True, doors_closed=False,
        above_weight=False
    ) -> False
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_below_weight_doors_closed_number_pushed'
    

When the controller function is called, it checks if the button for a floor is NOT pushed

  • If the button for a floor is NOT pushed it returns False

    elevator(
        number_pushed=False, doors_closed=True,
        above_weight=True
    ) -> False
    └── def controller(
                number_pushed, doors_closed=False,
                above_weight=False,
            ):
            └── if not number_pushed:
                └── return False
                if above_weight:
                    return False
                return doors_closed
    
    elevator(
        number_pushed=False, doors_closed=True,
        above_weight=False
    ) -> False
    └── def controller(
                number_pushed, doors_closed=False,
                above_weight=False,
            ):
            └── if not number_pushed:
                └── return False
                if above_weight:
                    return False
                return doors_closed
    
    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=True
    ) -> False
    └── def controller(
                number_pushed, doors_closed=False,
                above_weight=False,
            ):
            └── if not number_pushed:
                └── return False
                if above_weight:
                    return False
                return doors_closed
    
    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=False
    ) -> False
    └── def controller(
                number_pushed, doors_closed=False,
                above_weight=False,
            ):
            └── if not number_pushed:
                └── return False
                if above_weight:
                    return False
                return doors_closed
    
  • If the button for a floor is pushed it checks if the total weight of the Elevator is above the weight limit

    • if the total weight of the Elevator is above the weight limit, it returns False

      elevator(
          number_pushed=True, doors_closed=True,
          above_weight=True
      ) -> False
      └── def controller(
                  number_pushed, doors_closed=False,
                  above_weight=False,
              ):
              ├── if not number_pushed:
                     return False
              └── if above_weight:
                  └── return False
                  return doors_closed
      
      elevator(
          number_pushed=True, doors_closed=False,
          above_weight=True
      ) -> False
      └── def controller(
                  number_pushed, doors_closed=False,
                  above_weight=False,
              ):
              ├── if not number_pushed:
                     return False
              └── if above_weight:
                  └── return False
                  return doors_closed
      
    • if the total weight of the Elevator is below the weight limit, it returns the value of doors_closed

      • if the button for a floor is pushed AND the total weight of the Elevator is below the weight limit AND the Elevator doors are open, it returns False

        elevator(
            number_pushed=True, doors_closed=False,
            above_weight=False
        ) -> False
        └── def controller(
                    number_pushed, doors_closed=False,
                    above_weight=False,
                ):
                ├── if not number_pushed:
                       return False
                ├── if above_weight:
                       return False
                └── return doors_closed
                    return False
        
      • if the button for a floor is pushed AND the total weight of the Elevator is below the weight limit AND the Elevator doors are closed, it returns True

        elevator(
            number_pushed=True, doors_closed=True,
            above_weight=False
        ) -> True
        └── def controller(
                    number_pushed, doors_closed=False,
                    above_weight=False,
                ):
                ├── if not number_pushed:
                       return False
                ├── if above_weight:
                       return False
                └── return doors_closed
                    return True
        

The truth table for the Elevator is

floor button

doors

weight limit

output

pushed

closed

above

False

pushed

closed

below

True

pushed

open

above

False

pushed

open

below

False

floor button

doors

weight limit

output

NOT pushed

closed

above

False

NOT pushed

closed

below

False

NOT pushed

open

above

False

NOT pushed

open

below

False

I want to make sure the Elevator can be stopped with a button in an emergency. The inputs to the Controller will then be

  • was the number for a floor pushed?

  • are the doors closed?

  • is the Elevator above the weight limit?

  • was the emergency button pushed?


test_emergency_w_above_weight_doors_closed_number_pushed

The truth table for when the button for a floor is pushed AND the Elevator doors are closed AND the Elevator is above the weight limit, is

floor button

doors

weight limit

emergency button

output

pushed

closed

above

pushed

False

pushed

closed

above

NOT pushed

False


RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add emergency to the call to src.elevator.controller from the assertion of test_above_weight_doors_closed_number_pushed for if the button for a floor is pushed AND the Elevator doors are closed AND the Elevator is above the weight limit AND the emergency button is pushed

    floor button

    doors

    weight limit

    emergency button

    output

    pushed

    closed

    above

    pushed

    False

    10    def test_above_weight_doors_closed_number_pushed(self):
    11        self.assertFalse(
    12            src.elevator.controller(
    13                number_pushed=True,
    14                doors_closed=True,
    15                above_weight=True,
    16                emergency=True,
    17            )
    18        )
    19
    20    def test_below_weight_doors_closed_number_pushed(self):
    

    the terminal shows TypeError

    TypeError: elevator() got
               an unexpected keyword argument 'emergency'
    

    because the test called the controller function with a name (emergency) that is not in the parentheses of its definition.


GREEN: make it pass



REFACTOR: make it better


  • I add an assertion to test_above_weight_doors_closed_number_pushed for if the button for a floor is pushed AND the Elevator doors are closed AND the Elevator is above the weight limit AND the emergency button is NOT pushed

    floor button

    doors

    weight limit

    emergency button

    output

    pushed

    closed

    above

    NOT pushed

    False

     7    def test_above_weight_doors_closed_number_pushed(self):
     8        self.assertFalse(
     9            src.elevator.controller(
    10                number_pushed=True,
    11                doors_closed=True,
    12                above_weight=True,
    13                emergency=True,
    14            )
    15        )
    16        self.assertTrue(
    17            src.elevator.controller(
    18                number_pushed=True,
    19                doors_closed=True,
    20                above_weight=True,
    21                emergency=False,
    22            )
    23        )
    24
    25    def test_below_weight_doors_closed_number_pushed(self):
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    

    because the function returns False and this assertion expects True.

  • I change assertTrue to assertFalse in test_above_weight_doors_closed_number_pushed

     7      def test_above_weight_doors_closed_number_pushed(self):
     8          self.assertFalse(
     9              src.elevator.controller(
    10                  number_pushed=True,
    11                  doors_closed=True,
    12                  above_weight=True,
    13                  emergency=True,
    14              )
    15          )
    16          self.assertFalse(
    17              src.elevator.controller(
    18                  number_pushed=True,
    19                  doors_closed=True,
    20                  above_weight=True,
    21                  emergency=False,
    22              )
    23          )
    24
    25      def test_below_weight_doors_closed_number_pushed(self):
    

    the test passes.

    elevator(
        number_pushed=True, doors_closed=True,
        above_weight=True, emergency=True,
    ) -> False
    elevator(
        number_pushed=True, doors_closed=True,
        above_weight=True, emergency=False,
    ) -> False
    
  • I change the name of the test from test_above_weight_doors_closed_number_pushed to test_emergency_w_above_weight_doors_closed_number_pushed

     7class TestElevator(unittest.TestCase):
     8
     9    def test_emergency_w_above_weight_doors_closed_number_pushed(self):
    10        self.assertFalse(
    11            src.elevator.controller(
    12                number_pushed=True,
    13                doors_closed=True,
    14                above_weight=True,
    15                emergency=True,
    16            )
    17        )
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_emergency_w_above_weight_doors_closed_number_pushed'
    

test_emergency_w_below_weight_doors_closed_number_pushed

The truth table for when the button for a floor is pushed AND the Elevator doors are closed AND the Elevator is below the weight limit, is

floor button

doors

weight limit

emergency button

output

pushed

closed

below

pushed

False

pushed

closed

below

NOT pushed

True


RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add a value for the emergency parameter to the call to src.elevator.controller from the assertion of test_below_weight_doors_closed_number_pushed for if the button for a floor is pushed AND the Elevator doors are closed AND the Elevator is below the weight limit AND the emergency button is pushed

    floor button

    doors

    weight limit

    emergency button

    output

    pushed

    closed

    below

    pushed

    False

    25    def test_below_weight_doors_closed_number_pushed(self):
    26        self.assertTrue(
    27            src.elevator.controller(
    28                number_pushed=True,
    29                doors_closed=True,
    30                above_weight=False,
    31                emergency=True,
    32            )
    33        )
    34
    35    def test_above_weight_doors_open_number_pushed(self):
    

    the test is still green.

  • I change assertTrue to assertFalse in test_below_weight_doors_closed_number_pushed

    25    def test_below_weight_doors_closed_number_pushed(self):
    26        self.assertFalse(
    27            src.elevator.controller(
    28                number_pushed=True,
    29                doors_closed=True,
    30                above_weight=False,
    31                emergency=True,
    32            )
    33        )
    34
    35    def test_above_weight_doors_open_number_pushed(self):
    

    the terminal is my friend, and shows AssertionError

    AssertionError: True is not false
    

GREEN: make it pass


  • I add an if statement for the emergency parameter to the function definition in elevator.py

     1def controller(
     2        number_pushed, doors_closed=False,
     3        above_weight=False, emergency=False,
     4    ):
     5    if not number_pushed:
     6        return False
     7    if above_weight:
     8        return False
     9    if emergency:
    10        return False
    11    return doors_closed
    

    the test passes.

    elevator(
        number_pushed=True, doors_closed=True,
        above_weight=True, emergency=True,
    ) -> False
    elevator(
        number_pushed=True, doors_closed=True,
        above_weight=True, emergency=False,
    ) -> False
    elevator(
        number_pushed=True, doors_closed=True,
        above_weight=False, emergency=True,
    ) -> False
    

REFACTOR: make it better


  • I want the function to check if the Elevator doors are closed before it checks if the emergency button is pushed

     1def controller(
     2        number_pushed, doors_closed=False,
     3        above_weight=False, emergency=False,
     4    ):
     5    if not number_pushed:
     6        return False
     7    if above_weight:
     8        return False
     9    # if emergency:
    10    if not doors_closed:
    11        return False
    12    # return doors_closed
    13    if emergency:
    14        return False
    15    return True
    
  • I remove the commented lines from test_below_weight_doors_closed_number_pushed

     1def controller(
     2        number_pushed, doors_closed=False,
     3        above_weight=False, emergency=False,
     4    ):
     5    if not number_pushed:
     6        return False
     7    if above_weight:
     8        return False
     9    if not doors_closed:
    10        return False
    11    if emergency:
    12        return False
    13    return True
    
  • I add an assertion to test_below_weight_doors_closed_number_pushed for if the button for a floor is pushed AND the Elevator doors are closed AND the Elevator is below the weight limit AND the emergency button is NOT pushed

    floor button

    doors

    weight limit

    emergency button

    output

    pushed

    closed

    below

    NOT pushed

    True

    25    def test_below_weight_doors_closed_number_pushed(self):
    26        self.assertFalse(
    27            src.elevator.controller(
    28                number_pushed=True,
    29                doors_closed=True,
    30                above_weight=False,
    31                emergency=True,
    32            )
    33        )
    34        self.assertFalse(
    35            src.elevator.controller(
    36                number_pushed=True,
    37                doors_closed=True,
    38                above_weight=False,
    39                emergency=False,
    40            )
    41        )
    42
    43    def test_above_weight_doors_open_number_pushed(self):
    

    the terminal is my friend, and shows AssertionError

    AssertionError: True is not false
    

    because the function returns True and this assertion expects False.

  • I change assertFalse to assertTrue in test_below_weight_doors_closed_number_pushed

    25    def test_below_weight_doors_closed_number_pushed(self):
    26        self.assertFalse(
    27            src.elevator.controller(
    28                number_pushed=True,
    29                doors_closed=True,
    30                above_weight=False,
    31                emergency=True,
    32            )
    33        )
    34        self.assertTrue(
    35            src.elevator.controller(
    36                number_pushed=True,
    37                doors_closed=True,
    38                above_weight=False,
    39                emergency=False,
    40            )
    41        )
    42
    43    def test_above_weight_doors_open_number_pushed(self):
    

    the test passes.

    elevator(
        number_pushed=True, doors_closed=True,
        above_weight=True, emergency=True,
    ) -> False
    elevator(
        number_pushed=True, doors_closed=True,
        above_weight=True, emergency=False,
    ) -> False
    elevator(
        number_pushed=True, doors_closed=True,
        above_weight=False, emergency=True,
    ) -> False
    elevator(
        number_pushed=True, doors_closed=True,
        above_weight=False, emergency=False,
    ) -> True
    
  • I change the name of the test from test_below_weight_doors_closed_number_pushed to test_emergency_w_below_weight_doors_closed_number_pushed

    16        self.assertFalse(
    17            src.elevator.controller(
    18                number_pushed=True,
    19                doors_closed=True,
    20                above_weight=True,
    21                emergency=False,
    22            )
    23        )
    24
    25    def test_emergency_w_below_weight_doors_closed_number_pushed(self):
    26        self.assertFalse(
    27            src.elevator.controller(
    28                number_pushed=True,
    29                doors_closed=True,
    30                above_weight=False,
    31                emergency=True,
    32            )
    33        )
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_emergency_w_below_weight_doors_closed_number_pushed'
    

test_emergency_w_above_weight_doors_open_number_pushed

The truth table for when the button for a floor is pushed AND the Elevator doors are open AND the Elevator is above the weight limit, is

floor button

doors

weight limit

emergency button

output

pushed

open

above

pushed

False

pushed

open

above

NOT pushed

False


RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add a value for the emergency parameter to the call to src.elevator.controller from the assertion of test_above_weight_doors_open_number_pushed for if the button for a floor is pushed AND the Elevator doors are open AND the Elevator is above the weight limit AND the emergency button is pushed

    floor button

    doors

    weight limit

    emergency button

    output

    pushed

    open

    above

    pushed

    False

    43    def test_above_weight_doors_open_number_pushed(self):
    44        self.assertFalse(
    45            src.elevator.controller(
    46                number_pushed=True,
    47                doors_closed=False,
    48                above_weight=True,
    49                emergency=True,
    50            )
    51        )
    52
    53    def test_below_weight_doors_open_number_pushed(self):
    

    the test is still green.

    elevator(
        number_pushed=True, doors_closed=False,
        above_weight=True, emergency=True,
    ) -> False
    
  • I add an assertion to test_above_weight_doors_open_number_pushed for if the button for a floor is pushed AND the Elevator doors are open AND the Elevator is above the weight limit AND the emergency button is NOT pushed

    floor button

    doors

    weight limit

    emergency button

    output

    pushed

    open

    above

    NOT pushed

    False

    43    def test_above_weight_doors_open_number_pushed(self):
    44        self.assertFalse(
    45            src.elevator.controller(
    46                number_pushed=True,
    47                doors_closed=False,
    48                above_weight=True,
    49                emergency=True,
    50            )
    51        )
    52        self.assertTrue(
    53            src.elevator.controller(
    54                number_pushed=True,
    55                doors_closed=False,
    56                above_weight=True,
    57                emergency=False,
    58            )
    59        )
    60
    61    def test_below_weight_doors_open_number_pushed(self):
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    

GREEN: make it pass


I change assertTrue to assertFalse in test_above_weight_doors_open_number_pushed

43    def test_above_weight_doors_open_number_pushed(self):
44        self.assertFalse(
45            src.elevator.controller(
46                number_pushed=True,
47                doors_closed=False,
48                above_weight=True,
49                emergency=True,
50            )
51        )
52        self.assertFalse(
53            src.elevator.controller(
54                number_pushed=True,
55                doors_closed=False,
56                above_weight=True,
57                emergency=False,
58            )
59        )
60
61    def test_below_weight_doors_open_number_pushed(self):

the test passes.

elevator(
    number_pushed=True, doors_closed=False,
    above_weight=True, emergency=True,
) -> False
elevator(
    number_pushed=True, doors_closed=False,
    above_weight=True, emergency=False,
) -> False

REFACTOR: make it better


  • I change the name of the test from test_above_weight_doors_open_number_pushed to test_emergency_w_above_weight_doors_open_number_pushed

    34        self.assertTrue(
    35            src.elevator.controller(
    36                number_pushed=True,
    37                doors_closed=True,
    38                above_weight=False,
    39                emergency=False,
    40            )
    41        )
    42
    43    def test_emergency_w_above_weight_doors_open_number_pushed(self):
    44        self.assertFalse(
    45            src.elevator.controller(
    46                number_pushed=True,
    47                doors_closed=False,
    48                above_weight=True,
    49                emergency=True,
    50            )
    51        )
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_emergency_w_above_weight_doors_open_number_pushed'
    

test_emergency_w_below_weight_doors_open_number_pushed

The truth table for when the button for a floor is pushed AND the Elevator doors are open AND the Elevator is below the weight limit, is

floor button

doors

weight limit

emergency button

output

pushed

open

below

pushed

False

pushed

open

below

NOT pushed

False


RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add a value for the emergency parameter to the call to src.elevator.controller from the assertion of test_below_weight_doors_open_number_pushed for if the button for a floor is pushed AND the Elevator doors are open AND the Elevator is below the weight limit AND the emergency button is pushed

    floor button

    doors

    weight limit

    emergency button

    output

    pushed

    open

    below

    pushed

    False

    61    def test_below_weight_doors_open_number_pushed(self):
    62        self.assertFalse(
    63            src.elevator.controller(
    64                number_pushed=True,
    65                doors_closed=False,
    66                above_weight=False,
    67                emergency=True,
    68            )
    69        )
    70
    71    def test_above_weight_doors_closed_number_not_pushed(self):
    

    the test is still green.

    elevator(
        number_pushed=True, doors_closed=False,
        above_weight=True, emergency=True,
    ) -> False
    elevator(
        number_pushed=True, doors_closed=False,
        above_weight=True, emergency=False,
    ) -> False
    elevator(
        number_pushed=True, doors_closed=False,
        above_weight=False, emergency=True,
    ) -> False
    
  • I add an assertion to test_below_weight_doors_open_number_pushed for if the button for a floor is pushed AND the Elevator doors are open AND the Elevator is below the weight limit AND the emergency button is NOT pushed

    floor button

    doors

    weight limit

    emergency button

    output

    pushed

    open

    below

    NOT pushed

    False

    61    def test_below_weight_doors_open_number_pushed(self):
    62        self.assertFalse(
    63            src.elevator.controller(
    64                number_pushed=True,
    65                doors_closed=False,
    66                above_weight=False,
    67                emergency=True,
    68            )
    69        )
    70        self.assertTrue(
    71            src.elevator.controller(
    72                number_pushed=True,
    73                doors_closed=False,
    74                above_weight=False,
    75                emergency=False,
    76            )
    77        )
    78
    79    def test_above_weight_doors_closed_number_not_pushed(self):
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    

GREEN: make it pass


I change assertTrue to assertFalse in test_below_weight_doors_open_number_pushed

61    def test_below_weight_doors_open_number_pushed(self):
62        self.assertFalse(
63            src.elevator.controller(
64                number_pushed=True,
65                doors_closed=False,
66                above_weight=False,
67                emergency=True,
68            )
69        )
70        self.assertFalse(
71            src.elevator.controller(
72                number_pushed=True,
73                doors_closed=False,
74                above_weight=False,
75                emergency=False,
76            )
77        )
78
79    def test_above_weight_doors_closed_number_not_pushed(self):

the test passes.

elevator(
    number_pushed=True, doors_closed=False,
    above_weight=True, emergency=True,
) -> False
elevator(
    number_pushed=True, doors_closed=False,
    above_weight=True, emergency=False,
) -> False
elevator(
    number_pushed=True, doors_closed=False,
    above_weight=False, emergency=True,
) -> False
elevator(
    number_pushed=True, doors_closed=False,
    above_weight=False, emergency=False,
) -> False

REFACTOR: make it better


  • I change the name of the test from test_below_weight_doors_open_number_pushed to test_emergency_w_below_weight_doors_open_number_pushed

    52        self.assertFalse(
    53            src.elevator.controller(
    54                number_pushed=True,
    55                doors_closed=False,
    56                above_weight=True,
    57                emergency=False,
    58            )
    59        )
    60
    61    def test_emergency_w_below_weight_doors_open_number_pushed(self):
    62        self.assertFalse(
    63            src.elevator.controller(
    64                number_pushed=True,
    65                doors_closed=False,
    66                above_weight=False,
    67                emergency=True,
    68            )
    69        )
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_emergency_w_below_weight_doors_open_number_pushed'
    

test_emergency_w_above_weight_doors_closed_number_not_pushed

The truth table for when the button for a floor is NOT pushed AND the Elevator doors are closed AND the Elevator is above the weight limit, is

floor button

doors

weight limit

emergency button

output

NOT pushed

closed

above

pushed

False

NOT pushed

closed

above

NOT pushed

False


RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add a value for the emergency parameter to the call to src.elevator.controller from the assertion of test_above_weight_doors_closed_number_not_pushed for if the button for a floor is NOT pushed AND the Elevator doors are closed AND the Elevator is above the weight limit AND the emergency button is pushed

    floor button

    doors

    weight limit

    emergency button

    output

    NOT pushed

    closed

    above

    pushed

    False

    79    def test_above_weight_doors_closed_number_not_pushed(self):
    80        self.assertFalse(
    81            src.elevator.controller(
    82                number_pushed=False,
    83                doors_closed=True,
    84                above_weight=True,
    85                emergency=True,
    86            )
    87        )
    88
    89    def test_below_weight_doors_closed_number_not_pushed(self):
    

    the test is still green.

    elevator(
        number_pushed=False, doors_closed=True,
        above_weight=True, emergency=True,
    ) -> False
    
  • I add an assertion to test_above_weight_doors_closed_number_not_pushed for if the button for a floor is NOT pushed AND the Elevator doors are closed AND the Elevator is above the weight limit AND the emergency button is NOT pushed

    floor button

    doors

    weight limit

    emergency button

    output

    NOT pushed

    closed

    above

    NOT pushed

    False

    79    def test_above_weight_doors_closed_number_not_pushed(self):
    80        self.assertFalse(
    81            src.elevator.controller(
    82                number_pushed=False,
    83                doors_closed=True,
    84                above_weight=True,
    85                emergency=True,
    86            )
    87        )
    88        self.assertTrue(
    89            src.elevator.controller(
    90                number_pushed=False,
    91                doors_closed=True,
    92                above_weight=True,
    93                emergency=False,
    94            )
    95        )
    96
    97    def test_below_weight_doors_closed_number_not_pushed(self):
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    

GREEN: make it pass


I change assertTrue to assertFalse in test_above_weight_doors_closed_number_not_pushed

79    def test_above_weight_doors_closed_number_not_pushed(self):
80        self.assertFalse(
81            src.elevator.controller(
82                number_pushed=False,
83                doors_closed=True,
84                above_weight=True,
85                emergency=True,
86            )
87        )
88        self.assertFalse(
89            src.elevator.controller(
90                number_pushed=False,
91                doors_closed=True,
92                above_weight=True,
93                emergency=False,
94            )
95        )
96
97    def test_below_weight_doors_closed_number_not_pushed(self):

the test passes.

elevator(
    number_pushed=False, doors_closed=True,
    above_weight=True, emergency=True,
) -> False
elevator(
    number_pushed=False, doors_closed=True,
    above_weight=True, emergency=False,
) -> False

REFACTOR: make it better


  • I change the name of the test from test_above_weight_doors_closed_number_not_pushed to test_emergency_w_above_weight_doors_closed_number_not_pushed

    70        self.assertFalse(
    71            src.elevator.controller(
    72                number_pushed=True,
    73                doors_closed=False,
    74                above_weight=False,
    75                emergency=False,
    76            )
    77        )
    78
    79    def test_emergency_w_above_weight_doors_closed_number_not_pushed(self):
    80        self.assertFalse(
    81            src.elevator.controller(
    82                number_pushed=False,
    83                doors_closed=True,
    84                above_weight=True,
    85                emergency=True,
    86            )
    87        )
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_emergency_w_above_weight_doors_closed_number_not_pushed'
    

test_emergency_w_below_weight_doors_closed_number_not_pushed

The truth table for when the button for a floor is NOT pushed AND the Elevator doors are closed AND the Elevator is below the weight limit, is

floor button

doors

weight limit

emergency button

output

NOT pushed

closed

below

pushed

False

NOT pushed

closed

below

NOT pushed

False


RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add a value for the emergency parameter to the call to src.elevator.controller from the assertion of test_below_weight_doors_closed_number_not_pushed for if the button for a floor is NOT pushed AND the Elevator doors are closed AND the Elevator is below the weight limit AND the emergency button is pushed

    floor button

    doors

    weight limit

    emergency button

    output

    NOT pushed

    closed

    below

    pushed

    False

     97    def test_below_weight_doors_closed_number_not_pushed(self):
     98        self.assertFalse(
     99            src.elevator.controller(
    100                number_pushed=False,
    101                doors_closed=True,
    102                above_weight=False,
    103                emergency=True,
    104            )
    105        )
    106
    107    def test_above_weight_doors_open_number_not_pushed(self):
    

    the test is still green.

    elevator(
        number_pushed=False, doors_closed=True,
        above_weight=True, emergency=True,
    ) -> False
    elevator(
        number_pushed=False, doors_closed=True,
        above_weight=True, emergency=False,
    ) -> False
    elevator(
        number_pushed=False, doors_closed=True,
        above_weight=False, emergency=True,
    ) -> False
    
  • I add an assertion to test_below_weight_doors_closed_number_not_pushed for if the button for a floor is NOT pushed AND the Elevator doors are closed AND the Elevator is below the weight limit AND the emergency button is NOT pushed

    floor button

    doors

    weight limit

    emergency button

    output

    NOT pushed

    closed

    below

    NOT pushed

    False

     97    def test_below_weight_doors_closed_number_not_pushed(self):
     98        self.assertFalse(
     99            src.elevator.controller(
    100                number_pushed=False,
    101                doors_closed=True,
    102                above_weight=False,
    103                emergency=True,
    104            )
    105        )
    106        self.assertTrue(
    107            src.elevator.controller(
    108                number_pushed=False,
    109                doors_closed=True,
    110                above_weight=False,
    111                emergency=False,
    112            )
    113        )
    114
    115    def test_above_weight_doors_open_number_not_pushed(self):
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    

GREEN: make it pass


I change assertTrue to assertFalse in test_below_weight_doors_closed_number_not_pushed

 97    def test_below_weight_doors_closed_number_not_pushed(self):
 98        self.assertFalse(
 99            src.elevator.controller(
100                number_pushed=False,
101                doors_closed=True,
102                above_weight=False,
103                emergency=True,
104            )
105        )
106        self.assertFalse(
107            src.elevator.controller(
108                number_pushed=False,
109                doors_closed=True,
110                above_weight=False,
111                emergency=False,
112            )
113        )
114
115    def test_above_weight_doors_open_number_not_pushed(self):

the test passes.

elevator(
    number_pushed=False, doors_closed=True,
    above_weight=True, emergency=True,
) -> False
elevator(
    number_pushed=False, doors_closed=True,
    above_weight=True, emergency=False,
) -> False
elevator(
    number_pushed=False, doors_closed=True,
    above_weight=False, emergency=True,
) -> False
elevator(
    number_pushed=False, doors_closed=True,
    above_weight=False, emergency=False,
) -> False

REFACTOR: make it better


  • I change the name of the test from test_below_weight_doors_closed_number_not_pushed to test_emergency_w_below_weight_doors_closed_number_not_pushed

     88        self.assertFalse(
     89            src.elevator.controller(
     90                number_pushed=False,
     91                doors_closed=True,
     92                above_weight=True,
     93                emergency=False,
     94            )
     95        )
     96
     97    def test_emergency_w_below_weight_doors_closed_number_not_pushed(self):
     98        self.assertFalse(
     99            src.elevator.controller(
    100                number_pushed=False,
    101                doors_closed=True,
    102                above_weight=False,
    103                emergency=True,
    104            )
    105        )
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_emergency_w_below_weight_doors_closed_number_not_pushed'
    

test_emergency_w_above_weight_doors_open_number_not_pushed

The truth table for when the button for a floor is NOT pushed AND the Elevator doors are open AND the Elevator is above the weight limit, is

floor button

doors

weight limit

emergency button

output

NOT pushed

open

above

pushed

False

NOT pushed

open

above

NOT pushed

False


RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add a value for the emergency parameter to the call to src.elevator.controller from the assertion of test_above_weight_doors_open_number_not_pushed for if the button for a floor is NOT pushed AND the Elevator doors are open AND the Elevator is above the weight limit AND the emergency button is pushed

    floor button

    doors

    weight limit

    emergency button

    output

    NOT pushed

    open

    above

    pushed

    False

    115    def test_above_weight_doors_open_number_not_pushed(self):
    116        self.assertFalse(
    117            src.elevator.controller(
    118                number_pushed=False,
    119                doors_closed=False,
    120                above_weight=True,
    121                emergency=True,
    122            )
    123        )
    124
    125    def test_below_weight_doors_open_number_not_pushed(self):
    

    the test is still green.

    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=True, emergency=True,
    ) -> False
    
  • I add an assertion to test_above_weight_doors_open_number_not_pushed for if the button for a floor is NOT pushed AND the Elevator doors are open AND the Elevator is above the weight limit AND the emergency button is NOT pushed

    floor button

    doors

    weight limit

    emergency button

    output

    NOT pushed

    open

    above

    NOT pushed

    False

    115    def test_above_weight_doors_open_number_not_pushed(self):
    116        self.assertFalse(
    117            src.elevator.controller(
    118                number_pushed=False,
    119                doors_closed=False,
    120                above_weight=True,
    121                emergency=True,
    122            )
    123        )
    124        self.assertTrue(
    125            src.elevator.controller(
    126                number_pushed=False,
    127                doors_closed=False,
    128                above_weight=True,
    129                emergency=False,
    130            )
    131        )
    132
    133    def test_below_weight_doors_open_number_not_pushed(self):
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    

GREEN: make it pass


I change assertTrue to assertFalse in test_above_weight_doors_open_number_not_pushed

115    def test_above_weight_doors_open_number_not_pushed(self):
116        self.assertFalse(
117            src.elevator.controller(
118                number_pushed=False,
119                doors_closed=False,
120                above_weight=True,
121                emergency=True,
122            )
123        )
124        self.assertFalse(
125            src.elevator.controller(
126                number_pushed=False,
127                doors_closed=False,
128                above_weight=True,
129                emergency=False,
130            )
131        )
132
133    def test_below_weight_doors_open_number_not_pushed(self):

the test passes.

elevator(
    number_pushed=False, doors_closed=False,
    above_weight=True, emergency=True,
) -> False
elevator(
    number_pushed=False, doors_closed=False,
    above_weight=True, emergency=False,
) -> False

REFACTOR: make it better


  • I change the name of the test from test_above_weight_doors_open_number_not_pushed to test_emergency_w_above_weight_doors_open_number_not_pushed

    106        self.assertFalse(
    107            src.elevator.controller(
    108                number_pushed=False,
    109                doors_closed=True,
    110                above_weight=False,
    111                emergency=False,
    112            )
    113        )
    114
    115    def test_emergency_w_above_weight_doors_open_number_not_pushed(self):
    116        self.assertFalse(
    117            src.elevator.controller(
    118                number_pushed=False,
    119                doors_closed=False,
    120                above_weight=True,
    121                emergency=True,
    122            )
    123        )
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_emergency_w_above_weight_doors_open_number_not_pushed'
    

test_emergency_w_below_weight_doors_open_number_not_pushed

The truth table for when the button for a floor is NOT pushed AND the Elevator doors are open AND the Elevator is below the weight limit, is

floor button

doors

weight limit

emergency button

output

NOT pushed

open

below

pushed

False

NOT pushed

open

below

NOT pushed

False


RED: make it fail


  • I go back to the terminal where the tests are running.

  • I add a value for the emergency parameter to the call to the controller function from the assertion of test_below_weight_doors_open_number_not_pushed for if the button for a floor is NOT pushed AND the Elevator doors are open AND the Elevator is below the weight limit AND the emergency button is pushed

    floor button

    doors

    weight limit

    emergency button

    output

    NOT pushed

    open

    below

    pushed

    False

    133    def test_below_weight_doors_open_number_not_pushed(self):
    134        self.assertFalse(
    135            src.elevator.controller(
    136                number_pushed=False,
    137                doors_closed=False,
    138                above_weight=False,
    139                emergency=True,
    140            )
    141        )
    142
    143
    144# Exceptions seen
    145# AssertionError
    146# NameError
    147# AttributeError
    148# TypeError
    149# SyntaxError
    

    the test is still green.

    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=True, emergency=True,
    ) -> False
    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=True, emergency=False,
    ) -> False
    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=False, emergency=True,
    ) -> False
    
  • I add an assertion to test_below_weight_doors_open_number_not_pushed for if the button for a floor is NOT pushed AND the Elevator doors are open AND the Elevator is below the weight limit AND the emergency button is NOT pushed

    floor button

    doors

    weight limit

    emergency button

    output

    NOT pushed

    open

    below

    NOT pushed

    False

    133    def test_below_weight_doors_open_number_not_pushed(self):
    134        self.assertFalse(
    135            src.elevator.controller(
    136                number_pushed=False,
    137                doors_closed=False,
    138                above_weight=False,
    139                emergency=True,
    140            )
    141        )
    142        self.assertTrue(
    143            src.elevator.controller(
    144                number_pushed=False,
    145                doors_closed=False,
    146                above_weight=False,
    147                emergency=False,
    148            )
    149        )
    150
    151
    152# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    

    because the controller function returned False and this assertion expects True.


GREEN: make it pass


I change assertTrue to assertFalse in test_below_weight_doors_open_number_not_pushed

133    def test_below_weight_doors_open_number_not_pushed(self):
134        self.assertFalse(
135            src.elevator.controller(
136                number_pushed=False,
137                doors_closed=False,
138                above_weight=False,
139                emergency=True,
140            )
141        )
142        self.assertFalse(
143            src.elevator.controller(
144                number_pushed=False,
145                doors_closed=False,
146                above_weight=False,
147                emergency=False,
148            )
149        )
150
151
152# Exceptions seen

the test passes.

elevator(
    number_pushed=False, doors_closed=False,
    above_weight=True, emergency=True,
) -> False
elevator(
    number_pushed=False, doors_closed=False,
    above_weight=True, emergency=False,
) -> False
elevator(
    number_pushed=False, doors_closed=False,
    above_weight=False, emergency=True,
) -> False
elevator(
    number_pushed=False, doors_closed=False,
    above_weight=False, emergency=False,
) -> False

REFACTOR: make it better


  • I change the name of the test from test_below_weight_doors_open_number_not_pushed to test_emergency_w_below_weight_doors_open_number_not_pushed

    124        self.assertFalse(
    125            src.elevator.controller(
    126                number_pushed=False,
    127                doors_closed=False,
    128                above_weight=True,
    129                emergency=False,
    130            )
    131        )
    132
    133    def test_emergency_w_below_weight_doors_open_number_not_pushed(self):
    134        self.assertFalse(
    135            src.elevator.controller(
    136                number_pushed=False,
    137                doors_closed=False,
    138                above_weight=False,
    139                emergency=True,
    140            )
    141        )
    142        self.assertFalse(
    143            src.elevator.controller(
    144                number_pushed=False,
    145                doors_closed=False,
    146                above_weight=False,
    147                emergency=False,
    148            )
    149        )
    
  • I add a git commit message in the other terminal

    git commit -am \
    'add test_emergency_w_below_weight_doors_open_number_not_pushed'
    

When the controller function is called, it checks if the button for a floor is NOT pushed

  • If the button for a floor is NOT pushed it returns False

    elevator(
        number_pushed=False, doors_closed=True,
        above_weight=True, emergency=True,
    ) -> False
    └── def controller(
                number_pushed, doors_closed=False,
                above_weight=False, emergency=False,
            ):
            └── if not number_pushed:
                └── return False
                if above_weight:
                    return False
                if not doors_closed:
                    return False
                if emergency:
                    return False
                return True
    
    elevator(
        number_pushed=False, doors_closed=True,
        above_weight=True, emergency=False,
    ) -> False
    └── def controller(
                number_pushed, doors_closed=False,
                above_weight=False, emergency=False,
            ):
            └── if not number_pushed:
                └── return False
                if above_weight:
                    return False
                if not doors_closed:
                    return False
                if emergency:
                    return False
                return True
    
    elevator(
        number_pushed=False, doors_closed=True,
        above_weight=False, emergency=True,
    ) -> False
    └── def controller(
                number_pushed, doors_closed=False,
                above_weight=False, emergency=False,
            ):
            └── if not number_pushed:
                └── return False
                if above_weight:
                    return False
                if not doors_closed:
                    return False
                if emergency:
                    return False
                return True
    
    elevator(
        number_pushed=False, doors_closed=True,
        above_weight=False, emergency=False,
    ) -> False
    └── def controller(
                number_pushed, doors_closed=False,
                above_weight=False, emergency=False,
            ):
            └── if not number_pushed:
                └── return False
                if above_weight:
                    return False
                if not doors_closed:
                    return False
                if emergency:
                    return False
                return True
    
    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=True, emergency=True,
    ) -> False
    └── def controller(
                number_pushed, doors_closed=False,
                above_weight=False, emergency=False,
            ):
            └── if not number_pushed:
                └── return False
                if above_weight:
                    return False
                if not doors_closed:
                    return False
                if emergency:
                    return False
                return True
    
    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=True, emergency=False,
    ) -> False
    └── def controller(
                number_pushed, doors_closed=False,
                above_weight=False, emergency=False,
            ):
            └── if not number_pushed:
                └── return False
                if above_weight:
                    return False
                if not doors_closed:
                    return False
                if emergency:
                    return False
                return True
    
    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=False, emergency=True,
    ) -> False
    └── def controller(
                number_pushed, doors_closed=False,
                above_weight=False, emergency=False,
            ):
            └── if not number_pushed:
                └── return False
                if above_weight:
                    return False
                if not doors_closed:
                    return False
                if emergency:
                    return False
                return True
    
    elevator(
        number_pushed=False, doors_closed=False,
        above_weight=False, emergency=False,
    ) -> False
    └── def controller(
                number_pushed, doors_closed=False,
                above_weight=False, emergency=False,
            ):
            └── if not number_pushed:
                └── return False
                if above_weight:
                    return False
                if not doors_closed:
                    return False
                if emergency:
                    return False
                return True
    
  • If the button for a floor is pushed it checks if the total weight of the Elevator is above the weight limit

    • if the total weight of the Elevator is above the weight limit, it returns False

      elevator(
          number_pushed=True, doors_closed=False,
          above_weight=True, emergency=True,
      ) -> False
      └── def controller(
                  number_pushed, doors_closed=False,
                  above_weight=False, emergency=False,
              ):
              ├── if not number_pushed:
                     return False
              └── if above_weight:
                  └── return False
                  if not doors_closed:
                      return False
                  if emergency:
                      return False
                  return True
      
      elevator(
          number_pushed=True, doors_closed=False,
          above_weight=True, emergency=False,
      ) -> False
      └── def controller(
                  number_pushed, doors_closed=False,
                  above_weight=False, emergency=False,
              ):
              ├── if not number_pushed:
                     return False
              └── if above_weight:
                  └── return False
                  if not doors_closed:
                      return False
                  if emergency:
                      return False
                  return True
      
      elevator(
          number_pushed=True, doors_closed=True,
          above_weight=True, emergency=True,
      ) -> False
      └── def controller(
                  number_pushed, doors_closed=False,
                  above_weight=False, emergency=False,
              ):
              ├── if not number_pushed:
                     return False
              └── if above_weight:
                  └── return False
                  if not doors_closed:
                      return False
                  if emergency:
                      return False
                  return True
      
      elevator(
          number_pushed=True, doors_closed=True,
          above_weight=True, emergency=False,
      ) -> False
      └── def controller(
                  number_pushed, doors_closed=False,
                  above_weight=False, emergency=False,
              ):
              ├── if not number_pushed:
                     return False
              └── if above_weight:
                  └── return False
                  if not doors_closed:
                      return False
                  if emergency:
                      return False
              return True
      
    • if the total weight of the Elevator is below the weight limit, it checks if the Elevator doors are closed

      • if the Elevator doors are open, it returns False

        elevator(
            number_pushed=True, doors_closed=False,
            above_weight=False, emergency=True,
        ) -> False
        └── def controller(
                    number_pushed, doors_closed=False,
                    above_weight=False, emergency=False,
                ):
                ├── if not number_pushed:
                       return False
                ├── if above_weight:
                       return False
                └── if not doors_closed:
                    └── return False
                    if emergency:
                        return False
                    return True
        
        elevator(
            number_pushed=True, doors_closed=False,
            above_weight=False, emergency=False,
        ) -> False
        └── def controller(
                    number_pushed, doors_closed=False,
                    above_weight=False, emergency=False,
                ):
                ├── if not number_pushed:
                       return False
                ├── if above_weight:
                       return False
                └── if not doors_closed:
                    └── return False
                    if emergency:
                        return False
                    return True
        
      • if the Elevator doors are closed, it checks if the emergency button is pushed

        • if the emergency button is pushed, it returns False

          elevator(
              number_pushed=True, doors_closed=True,
              above_weight=False, emergency=True,
          ) -> False
          └── def controller(
                      number_pushed, doors_closed=False,
                      above_weight=False, emergency=False,
                  ):
                  ├── if not number_pushed:
                         return False
                  ├── if above_weight:
                         return False
                  ├── if not doors_closed:
                         return False
                  └── if emergency:
                      └── return False
                      return True
          
        • the button for a floor is pushed AND the doors are closed AND the Elevator is NOT above the weight limit, and the emergency button is NOT pushed, it returns True

          elevator(
              number_pushed=True, doors_closed=True,
              above_weight=False, emergency=False,
          ) -> True
          └── def controller(
                      number_pushed, doors_closed=False,
                      above_weight=False, emergency=False,
                  ):
                  ├── if not number_pushed:
                         return False
                  ├── if above_weight:
                         return False
                  ├── if not doors_closed:
                         return False
                  ├── if emergency:
                         return False
                  └── return True
          

refactor controller

  • All the if statements in the controller function return False which means I can use Logical Disjunction (OR) to put them together

     1def controller(
     2        number_pushed, doors_closed=False,
     3        above_weight=False, emergency=False,
     4    ):
     5    if (
     6        not number_pushed
     7        or above_weight
     8        or not doors_closed
     9        or emergency
    10    ):
    11        return False
    12    return True
    

    the tests are still green and this is a long statement.

  • I put the two statements that have not together

     5    if (
     6        not number_pushed
     7        or not doors_closed
     8        or above_weight
     9        or emergency
    10    ):
    11        return False
    12    return True
    

    still green.

  • I “factor” out the nots

    1    if (
    2        # not number_pushed
    3        # or not doors_closed
    4        not (number_pushed and doors_closed)
    5        or above_weight
    6        or emergency
    7    ):
    8        return False
    9    return True
    

    green.

  • I remove the commented lines

     1def controller(
     2        number_pushed, doors_closed=False,
     3        above_weight=False, emergency=False,
     4    ):
     5    if (
     6        not (number_pushed and doors_closed)
     7        or above_weight
     8        or emergency
     9    ):
    10        return False
    11    return True
    

    Which do you like better? One if statement to bind them all or many simple statements?

  • I add a git commit message in the other terminal

    git commit -am 'refactor controller'
    

close the project

  • I close test_elevator.py and elevator.py

  • I click in the terminal where the tests are running

  • I use q on the keyboard to leave the tests. The terminal shows

    .../pumping_python
    

    I am back in the pumping_python directory.


review

I ran tests for an Elevator Controller with these inputs:

  • was the number for a floor pushed?

  • are the doors closed?

  • is it above the weight limit?

  • was the emergency button pushed?

The inputs gave me this truth table

floor button

doors

weight limit

emergency button

output

pushed

closed

above

pushed

False

pushed

closed

above

NOT pushed

False

pushed

closed

below

pushed

False

pushed

closed

below

NOT pushed

True

floor button

doors

weight limit

emergency button

output

pushed

open

above

pushed

False

pushed

open

above

NOT pushed

False

pushed

open

below

pushed

False

pushed

open

below

NOT pushed

False

floor button

doors

weight limit

emergency button

output

NOT pushed

closed

above

pushed

False

NOT pushed

closed

above

NOT pushed

False

NOT pushed

closed

below

pushed

False

NOT pushed

closed

below

NOT pushed

False

floor button

doors

weight limit

emergency button

output

NOT pushed

open

above

pushed

False

NOT pushed

open

above

NOT pushed

False

NOT pushed

open

below

pushed

False

NOT pushed

open

below

NOT pushed

False

The only time this elevator moves up or down is when the button for a floor is pushed AND the doors are closed AND the Elevator is NOT above the weight limit, and the emergency button is NOT pushed.


code from the chapter

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


what is next?

Would you like to test making a Microwave?


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.