booleans part 2

I added a new if statement to the only_takes_numbers function in the calculator program because when I tested it with different data types, True and False passed the condition, and made the test fail.

This means that they are also integers or floats even though they are booleans. I want to find out if booleans are integers or floats


open the project

  • I change directory to the booleans folder

    cd booleans
    

    the terminal shows I am in the booleans folder

    .../pumping_python/booleans
    
  • I activate the virtual environment

    source .venv/bin/activate
    

    Attention

    on Windows without Windows Subsystem for Linux use .venv/bin/activate.ps1 NOT source .venv/bin/activate

    .venv/scripts/activate.ps1
    

    the terminal shows

    (.venv) .../pumping_python/booleans
    
  • I use pytest-watch to run the tests

    pytest-watch
    

    the terminal shows

    rootdir: .../pumping_python/booleans
    collected 2 items
    
    tests/test_booleans.py ..                                        [100%]
    
    ============================ 2 passed in X.YZs =============================
    
  • I hold ctrl on the keyboard and click on tests/test_booleans.py to open it in the editor


is a boolean an integer or a float?

RED: make it fail

I add a new assertion to the test_what_is_false method

6    def test_what_is_false(self):
7        self.assertIsInstance(False, bool)
8        self.assertNotIsInstance(False, int)
9        self.assertFalse(False)

the terminal shows AssertionError

AssertionError: False is an instance of <class 'int'>

in Python, False is a boolean and an integer

GREEN: make it pass

I change assertNotIsInstance to assertIsInstance

7        self.assertIsInstance(False, bool)
8        self.assertIsInstance(False, int)
9        self.assertFalse(False)

the test passes

REFACTOR: make it better

  • I add a note

    50# False is False
    51# False is not true
    52# False is a boolean
    53# False is an integer
    54
    55
    56# Exceptions Encountered
    57# AssertionError
    
  • I add another assertion to see if False is a float

     7        self.assertIsInstance(False, bool)
     8        self.assertIsInstance(False, int)
     9        self.assertIsInstance(False, float)
    10        self.assertFalse(False)
    

    the terminal shows AssertionError

    AssertionError: False is not an instance of <class 'float'>
    

    False is not a float

  • I change assertIsInstance to assertNotIsInstance

     8        self.assertIsInstance(False, int)
     9        self.assertNotIsInstance(False, float)
    10        self.assertFalse(False)
    

    the test passes

  • I add a note

    53# False is a boolean
    54# False is an integer
    55# False is not a float
    56
    57
    58# Exceptions Encountered
    59# AssertionError
    
  • I add an assertion to the test_what_is_true method to test if True is also an integer

    20    def test_what_is_true(self):
    21        self.assertIsInstance(True, bool)
    22        self.assertNotIsInstance(True, int)
    23        self.assertTrue(True)
    

    the terminal shows AssertionError

    AssertionError: True is an instance of <class 'int'>
    

    in Python, True is a boolean and an integer

  • I change assertNotIsInstance to assertIsInstance

    21        self.assertIsInstance(True, bool)
    22        self.assertIsInstance(True, int)
    23        self.assertTrue(True)
    

    the test passes

  • I add a note

    44# True is a boolean
    45# True is an integer
    46# the empty dictionary is false
    47# the empty set is false
    
  • I add another assertion to test if True is a float

    20    def test_what_is_true(self):
    21        self.assertIsInstance(True, bool)
    22        self.assertIsInstance(True, int)
    23        self.assertIsInstance(True, float)
    24        self.assertTrue(True)
    

    the terminal shows AssertionError

    AssertionError: True is not an instance of <class 'float'>
    

    True is not a float

  • I change the assert method

    22        self.assertIsInstance(True, int)
    23        self.assertNotIsInstance(True, float)
    24        self.assertTrue(True)
    

    the test passes

  • I add a note

    45# True is a boolean
    46# True is an integer
    47# True is not a float
    48# the empty dictionary is false
    

    This explains why my test with different data types failed. True and False are integers and the if statement in the only_takes_numbers function only allowed integers and floats.

    The add function returned numbers in the calculation with True and False because they are integers. I want to know what their values are

  • I can use an iterable with the assertIsInstance method, the same way I do with the isinstance function in the only_takes_numbers Function definitions in the calculator

    20    def test_what_is_true(self):
    21        self.assertIsInstance(True, bool)
    22        self.assertIsInstance(True, int)
    23        self.assertIsInstance(True, (bool, int))
    24        self.assertNotIsInstance(True, float)
    

    the test is still green

  • I remove the first two assertions

    20    def test_what_is_true(self):
    21        self.assertIsInstance(True, (bool, int))
    22        self.assertNotIsInstance(True, float)
    23        self.assertTrue(True)
    

    still green

  • I do the same thing in the test_what_is_false function

     6    def test_what_is_false(self):
     7        self.assertIsInstance(False, bool)
     8        self.assertIsInstance(False, int)
     9        self.assertIsInstance(False, (bool, int))
    10        self.assertNotIsInstance(False, float)
    

    the tests are still passing

  • I remove the first two assertions in the test

    6    def test_what_is_false(self):
    7        self.assertIsInstance(False, (bool, int))
    8        self.assertNotIsInstance(False, float)
    9        self.assertFalse(False)
    

    still green

  • I can use a for loop for the assertions that test what is False

     6    def test_what_is_false(self):
     7        self.assertIsInstance(False, (bool, int))
     8        self.assertNotIsInstance(False, float)
     9        # self.assertFalse(False)
    10        # self.assertFalse(None)
    11        # self.assertFalse(0)
    12        # self.assertFalse(0.0)
    13        # self.assertFalse(str())
    14        # self.assertFalse(tuple())
    15        # self.assertFalse(list())
    16        # self.assertFalse(set())
    17        # self.assertFalse(dict())
    18        for false_item in (
    19            False,
    20            None,
    21            0, 0.0,
    22            str(),
    23            tuple(),
    24            list(),
    25            set(),
    26            dict(),
    27        ):
    28            with self.subTest(i=false_item):
    29                self.assertFalse(false_item)
    

    the test is still green

  • I remove the commented lines

     6    def test_what_is_false(self):
     7        self.assertIsInstance(False, (bool, int))
     8        self.assertNotIsInstance(False, float)
     9        for false_item in (
    10            False,
    11            None,
    12            0, 0.0,
    13            str(),
    14            tuple(),
    15            list(),
    16            set(),
    17            dict(),
    18        ):
    19            with self.subTest(i=false_item):
    20                self.assertFalse(false_item)
    

    still green

  • I add True to make sure the test works

    17            dict(),
    18            True,
    19        ):
    20            with self.subTest(i=item):
    21                self.assertFalse(item)
    

    the terminal shows AssertionError

    SUBFAILED(i=True) tests/test_booleans.py::TestBooleans::test_what_is_false - AssertionError: True is not false
    
  • I remove the failing line and the test is green again

  • I add a for loop for all the assertions that test what is True

    22    def test_what_is_true(self):
    23        self.assertIsInstance(True, (bool, int))
    24        self.assertNotIsInstance(True, float)
    25        # self.assertTrue(True)
    26        # self.assertTrue(-1)
    27        # self.assertTrue(1)
    28        # self.assertTrue(-0.1)
    29        # self.assertTrue(0.1)
    30        # self.assertTrue('text')
    31        # self.assertTrue((1, 2, 3, 'n'))
    32        # self.assertTrue([1, 2, 3, 'n'])
    33        # self.assertTrue({1, 2, 3, 'n'})
    34        # self.assertTrue({'key': 'value'})
    35        for true_item in (
    36            True,
    37            -1, 1,
    38            -0.1, 0.1,
    39            'text',
    40            (1, 2, 3, 'n'),
    41            [1, 2, 3, 'n'],
    42            {1, 2, 3, 'n'},
    43            {'key': 'value'},
    44        ):
    45            with self.subTest(i=true_item):
    46                self.assertTrue(true_item)
    

    the terminal still shows green

  • I remove the commented lines

    22    def test_what_is_true(self):
    23        self.assertIsInstance(True, (bool, int))
    24        self.assertNotIsInstance(True, float)
    25        for true_item in (
    26            True,
    27            -1, 1,
    28            -0.1, 0.1,
    29            'text',
    30            (1, 2, 3, 'n'),
    31            [1, 2, 3, 'n'],
    32            {1, 2, 3, 'n'},
    33            {'key': 'value'},
    34        ):
    35            with self.subTest(i=true_item):
    36                self.assertTrue(true_item)
    

    still green

  • I add False to make sure the test still works as expected

    33            {'key': 'value'},
    34            False,
    35        ):
    36            with self.subTest(i=item):
    37                self.assertTrue(item)
    

    the terminal shows AssertionError

    SUBFAILED(i=False) tests/test_booleans.py::TestBooleans::test_what_is_true - AssertionError: False is not true
    
  • I remove the line I just added and the test is green again


test_the_value_of_false

RED: make it fail

I add a new test to find out the value of False

33        self.assertTrue({'key': 'value'})
34
35    def test_the_value_of_false(self):
36        self.assertEqual(False+1, None)
37
38
39# NOTES

the terminal shows AssertionError

AssertionError: 1 != None

False is 0

GREEN: make it pass

I change the expectation to match

36        self.assertEqual(False+1, 1)

the test passes

REFACTOR: make it better

  • I add another assertion

    36        self.assertEqual(False+1, 1)
    37        self.assertEqual(False-1, 1)
    

    the terminal shows AssertionError

    AssertionError: -1 != 1
    

    False is 0

  • I change the expectation

    37        self.assertEqual(False-1, -1)
    

    the test passes

  • I add another assertion

    37        self.assertEqual(False-1, -1)
    38        self.assertEqual(False*1, -1)
    

    the terminal shows AssertionError

    AssertionError: 0 != -1
    

    False is 0

  • I change the expectation

    38        self.assertEqual(False*1, 0)
    

    the test passes

  • what happens if I divide a number by False?

    38        self.assertEqual(False*1, 0)
    39        1 / False
    40
    41
    42# NOTES
    

    the terminal shows ZeroDivisionError because False is 0

  • I add assertRaises

    35    def test_the_value_of_false(self):
    36        self.assertEqual(False+1, 1)
    37        self.assertEqual(False-1, -1)
    38        self.assertEqual(False*1, 0)
    39        with self.assertRaises(ZeroDivisionError):
    40            1 / False
    

    the test passes

  • I add a note

    60# 0 is false
    61# None is false
    62# False is False
    63# False is not true
    64# False is a boolean
    65# False is an integer
    66# False is not a float
    67# False is 0
    

time to test the value of True


test_the_value_of_true

RED: make it fail

I add a new test to find out the value of True

39        with self.assertRaises(ZeroDivisionError):
40            1 / False
41
42    def test_the_value_of_true(self):
43        self.assertEqual(True+1, 1)
44
45
46# NOTES

the terminal shows AssertionError

AssertionError: 2 != 1

True is 1

GREEN: make it pass

I change the expectation

43        self.assertEqual(True+1, 2)

the test passes

REFACTOR: make it better

  • I add another assertion

    43        self.assertEqual(True+1, 2)
    44        self.assertEqual(True-1, 2)
    

    the terminal shows AssertionError

    AssertionError: 0 != 2
    

    True is 1

  • I change the expectation

    44        self.assertEqual(True-1, 0)
    

    the test passes

  • I add an assertion

    44        self.assertEqual(True-1, 0)
    45        self.assertEqual(True*1, 0)
    

    the terminal shows AssertionError

    AssertionError: 1 != 0
    

    True is 1

  • I change the expectation

    45        self.assertEqual(True*1, 1)
    

    the test passes

  • I add an assertion for division

    45        self.assertEqual(True*1, 1)
    46        self.assertEqual(True/2, 1)
    

    the terminal shows AssertionError

    AssertionError: 0.5 != 1
    

    True is 1

  • I change the assertion

    46        self.assertEqual(True/1, 1)
    

    the test passes

  • I add a note

    59# True is an integer
    60# True is not a float
    61# True is 1
    62# the empty dictionary is false
    

close the project

  • I close test_booleans.py in the editor

  • I click in the terminal and exit the tests with ctrl+c on the keyboard, the terminal shows

    (.venv) .../pumping_python/booleans
    
  • I deactivate the virtual environment

    deactivate
    

    the terminal goes back to the command line, (.venv) is no longer on the left side

    .../pumping_python/booleans
    
  • I change directory to the parent of booleans

    cd ..
    

    the terminal shows

    .../pumping_python
    

    I am back in the pumping_python directory


review

I added assertions that show booleans are also integers and NOT floats then added the following tests


code from the chapter

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


what is next?

you know

Would you like to test dictionaries?


rate pumping python

If this has been a 7 star experience for you, please leave a 5 star review. It helps other people get into the book too