truth table: Binary Operations 1


preview

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

 1import src.truth_table
 2import unittest
 3
 4
 5class TestBinaryOperations(unittest.TestCase):
 6
 7    def test_contradiction(self):
 8        self.assertFalse(
 9            src.truth_table.contradiction(True, True)
10        )
11        self.assertFalse(
12            src.truth_table.contradiction(True, False)
13        )
14        self.assertFalse(
15            src.truth_table.contradiction(False, True)
16        )
17        self.assertFalse(
18            src.truth_table.contradiction(False, False)
19        )
20
21    def test_logical_conjunction(self):
22        self.assertTrue(
23            src.truth_table.logical_conjunction(True, True)
24        )
25        self.assertFalse(
26            src.truth_table.logical_conjunction(True, False)
27        )
28        self.assertFalse(
29            src.truth_table.logical_conjunction(False, True)
30        )
31        self.assertFalse(
32            src.truth_table.logical_conjunction(False, False)
33        )
34
35    def test_project_second(self):
36        self.assertTrue(
37            src.truth_table.project_second(True, True)
38        )
39        self.assertFalse(
40            src.truth_table.project_second(True, False)
41        )
42        self.assertTrue(
43            src.truth_table.project_second(False, True)
44        )
45        self.assertFalse(
46            src.truth_table.project_second(False, False)
47        )
48
49    def test_converse_non_implication(self):
50        self.assertFalse(
51            src.truth_table.converse_non_implication(
52                True, True
53            )
54        )
55        self.assertFalse(
56            src.truth_table.converse_non_implication(
57                True, False
58            )
59        )
60        self.assertTrue(
61            src.truth_table.converse_non_implication(
62                False, True
63            )
64        )
65        self.assertFalse(
66            src.truth_table.converse_non_implication(
67                False, False
68            )
69        )
70
71
72# Exceptions seen
73# AttributeError
74# TypeError
75# AssertionError

requirements

truth table: Nullary and Unary Operations

continue the project

  • Make sure you are in the pumping_python folder with pwd in the terminal

    pwd
    

    if the terminal does not show

    .../pumping_python
    

    change directory to the pumping_python folder

  • Once in pumping_python, change directory to the project

    cd truth_table
    

    the terminal shows

    .../pumping_python/truth_table
    
  • I run the tests with pytest-watcher

    uv run pytest-watcher . --now
    
  • the terminal is my friend, and shows

    rootdir: .../pumping_python/truth_table
    configfile: pyproject.toml
    collected 4 items
    
    tests/test_nullary_unary.py ....                              [100%]
    
    ======================== 4 passed in G.HIs =========================
    

test_contradiction

The truth table for contradiction is

first input

second input

return

True

True

False

True

False

False

False

True

False

False

False

False


RED: make it fail


  • I open the Explorer to make a new file in the tests folder

  • I right click the tests folder then select New File and name the new file test_binary.py

  • I add a new test for contradiction with an assertion for when the first input is True and the second input is True in test_binary.py

    first input

    second input

    return

    True

    True

    False

     1import src.truth_table
     2import unittest
     3
     4
     5class TestBinaryOperations(unittest.TestCase):
     6
     7    def test_contradiction(self):
     8        self.assertFalse(
     9            src.truth_table.contradiction(True, True)
    10        )
    11
    12
    13# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.truth_table' has no attribute 'contradiction'
    

    because I have not defined contradiction in truth_table.py

  • I add AttributeError to the list of Exceptions seen

    13# Exceptions seen
    14# AttributeError
    

GREEN: make it pass


  • I open truth_table.py in the editor

  • I add the function to truth_table.py

    13def logical_negation(the_input):
    14    return not the_input
    15
    16
    17def contradiction():
    18    return None
    

    the terminal is my friend, and shows TypeError

    TypeError: contradiction() takes 0 positional arguments but 2 were given
    

    because the test called the contradiction function with 2 arguments and this definition only takes calls with 0 arguments

  • I add TypeError to the list of Exceptions seen

    13# Exceptions seen
    14# AttributeError
    15# TypeError
    
  • I add first_input as the name of the first argument. to the function signature for contradiction in truth_table.py

    17def contradiction(first_input):
    18    return None
    

    the terminal is my friend, and shows TypeError

    TypeError: contradiction() takes 1 positional argument but 2 were given
    

    because the test called the contradiction function with 2 arguments and I just changed the definition to only allow calls with 1 argument

  • I add second_input as the name of the second input in parentheses

    17def contradiction(first_input, second_input):
    18    return None
    

    the test passes because None is False and the test expects False


REFACTOR: make it better


  • I change the return statement to make it clearer

    17def contradiction(first_input, second_input):
    18    return False
    

    the test is still green. contradiction function returns False, if the first input is True and the second input is True

  • I add an assertion for the second case, which is when the first input is True and the second input is False, to test_binary.py

    first input

    second input

    return

    True

    False

    False

     7    def test_contradiction(self):
     8        self.assertFalse(
     9            src.truth_table.contradiction(True, True)
    10        )
    11        self.assertFalse(
    12            src.truth_table.contradiction(True, False)
    13        )
    14
    15
    16# Exceptions seen
    

    the test is still green. contradiction returns False

    • if the first input is True and the second input is False

    • if the first input is True and the second input is True

  • I add an assertion for the third case, which is when the first input is False and the second input is True

    first input

    second input

    return

    False

    True

    False

     7    def test_contradiction(self):
     8        self.assertFalse(
     9            src.truth_table.contradiction(True, True)
    10        )
    11        self.assertFalse(
    12            src.truth_table.contradiction(True, False)
    13        )
    14        self.assertFalse(
    15            src.truth_table.contradiction(False, True)
    16        )
    17
    18
    19# Exceptions seen
    

    the test is still green. contradiction returns False

    • if the first input is False and the second input is True

    • if the first input is True and the second input is False

    • if the first input is True and the second input is True

  • I add an assertion for the fourth case, which is when the first input is False and the second input is False

     7    def test_contradiction(self):
     8        self.assertFalse(
     9            src.truth_table.contradiction(True, True)
    10        )
    11        self.assertFalse(
    12            src.truth_table.contradiction(True, False)
    13        )
    14        self.assertFalse(
    15            src.truth_table.contradiction(False, True)
    16        )
    17        self.assertFalse(
    18            src.truth_table.contradiction(False, False)
    19        )
    20
    21
    22# Exceptions seen
    

    the test is still green. contradiction returns False

    • if the first input is False and the second input is False

    • if the first input is False and the second input is True

    • if the first input is True and the second input is False

    • if the first input is True and the second input is True

contradiction always returns False, it does not care about the inputs


examples of Contradiction


  • A broken light switch, if the inputs are

    • is the switch on?

    • is there electricity?

    If the switch is broken, the inputs do not matter

    switch

    electricity

    bulb

    on

    on

    off

    on

    off

    off

    off

    on

    off

    off

    off

    off

  • A rule that does not allow watching TV, if the inputs are

    • is homework done?

    • is the room clean?

    homework done

    clean room

    can watch TV

    yes

    yes

    no

    yes

    no

    no

    no

    yes

    no

    no

    no

    no

  • A rule about loaning money to friends, if the inputs are

    • person can be trusted?

    • is a small amount?

    trusted person

    small amount

    loan money to friend

    yes

    yes

    no

    yes

    no

    no

    no

    yes

    no

    no

    no

    no

  • Do not disturb, if the inputs are

    • is the person in favorites list?

    • is it during allowed hours?

    favorites

    allowed hours

    allow to ring

    yes

    yes

    no

    yes

    no

    no

    no

    yes

    no

    no

    no

    no

  • Broken Multi Factor Authentication to log in, if the inputs are

    • did the user provide the right password?

    • did the user provide the right MFA code?

    right password

    right MFA code

    log in

    yes

    yes

    no

    yes

    no

    no

    no

    yes

    no

    no

    no

    no


test_logical_conjunction

The truth table for logical_conjunction is

first input

second input

return

True

True

True

True

False

False

False

True

False

False

False

False


RED: make it fail


I add a new test with an assertion for the first case, which is where the first input is True and the second input is True, in test_binary.py

first input

second input

return

True

True

True

 7    def test_contradiction(self):
 8        self.assertFalse(
 9            src.truth_table.contradiction(True, True)
10        )
11        self.assertFalse(
12            src.truth_table.contradiction(True, False)
13        )
14        self.assertFalse(
15            src.truth_table.contradiction(False, True)
16        )
17        self.assertFalse(
18            src.truth_table.contradiction(False, False)
19        )
20
21    def test_logical_conjunction(self):
22        self.assertTrue(
23            src.truth_table.logical_conjunction(True, True)
24        )
25
26
27# Exceptions seen

the terminal is my friend, and shows AttributeError

AttributeError: module 'src.truth_table' has no attribute 'logical_conjunction'. Did you mean: 'logical_negation'?

because there is nothing named logical_conjunction in truth_table.py


GREEN: make it pass


I add the function to truth_table.py

17def contradiction(first_input, second_input):
18    return False
19
20
21def logical_conjunction(first_input, second_input):
22    return True

the test passes. logical_conjunction returns True, if the first input is True and the second input is True


REFACTOR: make it better


  • I add an assertion for the next case, which is when the first input is True and the second input is False, to test_logical_conjunction in test_binary.py

    first input

    second input

    return

    True

    False

    False

    21    def test_logical_conjunction(self):
    22        self.assertTrue(
    23            src.truth_table.logical_conjunction(True, True)
    24        )
    25        self.assertFalse(
    26            src.truth_table.logical_conjunction(True, False)
    27        )
    28
    29
    30# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: True is not false
    

    because the function returns True and the test expects False

  • I add AssertionError to the list of Exceptions

    30# Exceptions seen
    31# AttributeError
    32# TypeError
    33# AssertionError
    
  • I make the logical_conjunction function in truth_table.py return False

    21def logical_conjunction(first_input, second_input):
    22    return False
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    

    because the function now returns False and the assertion before this one, expects True

    logical_conjunction has to make a choice. It should return

    • False, if the first input is True and the second input is False

    • True, if the first input is True and the second input is True

    • the second input in these 2 cases

  • I change the return statement of the logical_conjunction function in truth_table.py

    21def logical_conjunction(first_input, second_input):
    22    return second_input
    

    the test passes. logical_conjunction returns

    • False, if the second input is False

    • True, if the second input is True

  • I add an assertion for the third case, which is when the first input is False and the second input is True to test_logical_conjunction in test_binary.py

    first input

    second input

    return

    False

    True

    False

    21    def test_logical_conjunction(self):
    22        self.assertTrue(
    23            src.truth_table.logical_conjunction(True, True)
    24        )
    25        self.assertFalse(
    26            src.truth_table.logical_conjunction(True, False)
    27        )
    28        self.assertFalse(
    29            src.truth_table.logical_conjunction(False, True)
    30        )
    31
    32
    33# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: True is not false
    

    because my solution does not work for this case. The function returned True and the assertion expected False. The logical_conjunction function has to make a choice, it should return

    • False, if the first input is False and the second input is True

    • False, if the first input is True and the second input is False

    • True, if the first input is True and the second input is True

    I can use if statements to make it choose what to do based on the conditions


if statements

An if statement is a way for a program to choose what to do based on something else. I can use if statements to make a function choose between 2 things. They are written this way in Python

if something:
    then do this
  • I add an if statement for when the first input is False to the logical_conjunction function in truth_table.py

    21def logical_conjunction(first_input, second_input):
    22    if first_input == False:
    23        return False
    24    return second_input
    

    the test passes. logical_conjunction returns

    • False, if the first input is False

    • the second input if the above condition is NOT met

    Note

  • I add an assertion for the last case, which is when the first input is False and the second input is False, to test_logical_conjunction in test_binary.py

    first input

    second input

    return

    False

    False

    False

    21    def test_logical_conjunction(self):
    22        self.assertTrue(
    23            src.truth_table.logical_conjunction(True, True)
    24        )
    25        self.assertFalse(
    26            src.truth_table.logical_conjunction(True, False)
    27        )
    28        self.assertFalse(
    29            src.truth_table.logical_conjunction(False, True)
    30        )
    31        self.assertFalse(
    32            src.truth_table.logical_conjunction(False, False)
    33        )
    34
    35
    36# Exceptions seen
    

    the test is still green

  • There is only one case where logical_conjunction returns True, I add an if statement for it in truth_table.py

    21def logical_conjunction(first_input, second_input):
    22    # if first_input == False:
    23    #     return False
    24    # return second_input
    25    if first_input == True:
    26        if second_input == True:
    27            return True
    

    the test is still green, because the function returns

  • I add a return statement to make it clearer

    21def logical_conjunction(first_input, second_input):
    22    # if first_input == False:
    23    #     return False
    24    # return second_input
    25    if first_input == True:
    26        if second_input == True:
    27            return True
    28    return None
    

    still green, because None is False

  • I change None to False in the return statement, to make it clearer

    21def logical_conjunction(first_input, second_input):
    22    # if first_input == False:
    23    #     return False
    24    # return second_input
    25    if first_input == True:
    26        if second_input == True:
    27            return True
    28    # return None
    29    return False
    

    green

  • I add bool to the if statements

    21def logical_conjunction(first_input, second_input):
    22    # if first_input == False:
    23    #     return False
    24    # return second_input
    25    # if first_input == True:
    26    if bool(first_input) == True:
    27        # if second_input == True:
    28        if bool(second_input) == True:
    29            return True
    30    # return None
    31    return False
    

    still green, because bool(anything) returns True or False for the thing in parentheses like the tests in the booleans chapter with the assertFalse and assertTrue methods

  • Since bool(True) is the same as True, bool(first_input) == True is the same thing as True == True when first_input is True, which is a repetition. I remove == True from the if statements

    21def logical_conjunction(first_input, second_input):
    22    # if first_input == False:
    23    #     return False
    24    # return second_input
    25    # if first_input == True:
    26    # if bool(first_input) == True:
    27    if bool(first_input):
    28        # if second_input == True:
    29        # if bool(second_input) == True:
    30        if bool(second_input):
    31            return True
    32    # return None
    33    return False
    

    the test is still green, because

    • if bool(something) checks if bool(something) returns True

    • if bool(something) == True is the same as if bool(something)

  • I can remove bool

    21def logical_conjunction(first_input, second_input):
    22    # if first_input == False:
    23    #     return False
    24    # return second_input
    25    # if first_input == True:
    26    # if bool(first_input) == True:
    27    # if bool(first_input):
    28    if first_input:
    29        # if second_input == True:
    30        # if bool(second_input) == True:
    31        # if bool(second_input):
    32        if second_input:
    33            return True
    34    # return None
    35    return False
    

    still green, because if bool(something) == True is the same as if bool(something) is the same as if something

    Tip

    • if something == True: checks if something is equal to True

    • these if statements check if the result of bool(something) is True, the same way the assertTrue method does

      • if bool(something) == True:

      • if bool(something):

      • if something:

    all the above if statements have the same result

  • I can use AND to put two if statements together when one is indented under the other. For example

    if something:
        if something_else:
    

    can also be written as

    if something and something_else:
    

    I use AND to put the two if statements together

    21def logical_conjunction(first_input, second_input):
    22    # if first_input == False:
    23    #     return False
    24    # return second_input
    25    # if first_input == True:
    26    # if bool(first_input) == True:
    27    # if bool(first_input):
    28    # if first_input:
    29        # if second_input == True:
    30        # if bool(second_input) == True:
    31        # if bool(second_input):
    32        # if second_input:
    33    if first_input and second_input:
    34            return True
    35    # return None
    36    return False
    

    green

  • I add an else clause to make it clearer

    22def logical_conjunction(first_input, second_input):
    23    # if first_input == False:
    24    #     return False
    25    # return second_input
    26    # if first_input == True:
    27    # if bool(first_input) == True:
    28    # if bool(first_input):
    29    # if first_input:
    30        # if second_input == True:
    31        # if bool(second_input) == True:
    32        # if bool(second_input):
    33        # if second_input:
    34    if first_input and second_input:
    35        return True
    36    # return None
    37    else:
    38        return False
    

    still green


conditional expressions

  • There is a way to write the if statement and else clause that currently take up 4 lines, with one line. It is called a ternary operator or conditional expression. I add one to the function

    21def logical_conjunction(first_input, second_input):
    22    return True if first_input and second_input else False
    23    # if first_input == False:
    24    #     return False
    25    # return second_input
    26    # if first_input == True:
    27    # if bool(first_input) == True:
    28    # if bool(first_input):
    29    # if first_input:
    30        # if second_input == True:
    31        # if bool(second_input) == True:
    32        # if bool(second_input):
    33        # if second_input:
    34    if first_input and second_input:
    35        return True
    36    # return None
    37    else:
    38        return False
    

    the test is still green, because this is the same statement in a different order

    • return True comes first instead of after the if statement

    • first_input and second_input come next, without the if

    • else comes after first_input and second_input

    • then False without the return comes after else

    this means that

    return True if something else False
    

    is a simpler way to write

    if something:
        return True
    else:
        return False
    
  • I can make the conditional expression even simpler, if I remove return True and else False

    21def logical_conjunction(first_input, second_input):
    22    return first_input and second_input
    23    return True if first_input and second_input else False
    24    # if first_input == False:
    25    #     return False
    26    # return second_input
    27    # if first_input == True:
    28    # if bool(first_input) == True:
    29    # if bool(first_input):
    30    # if first_input:
    31        # if second_input == True:
    32        # if bool(second_input) == True:
    33        # if bool(second_input):
    34        # if second_input:
    35    if first_input and second_input:
    36        return True
    37    # return None
    38    else:
    39        return False
    

    still green!

  • I remove the other statements because the return statement is the last thing to run in a function

    21def logical_conjunction(first_input, second_input):
    22    return first_input and second_input
    

logical_conjunction also known as and, always returns

  • first_input and second_input

  • True, if the first input is True and the second input is True


examples of Logical Conjunction


  • A person can vote, if the inputs are

    • is the person a citizen?

    • is the person old enough?

    is a citizen

    is old enough

    can vote

    yes

    yes

    yes

    yes

    no

    no

    no

    yes

    no

    no

    no

    no

  • Music player goes to the next song or pauses, if the inputs are

    • are headphones connected?

    • has the current song finished playing?

    headphones connected

    current song finished

    play next

    yes

    yes

    yes

    yes

    no

    no

    no

    yes

    no

    no

    no

    no

  • Baking a cake, if the inputs are

    • flour?

    • eggs?

    flour

    eggs

    can bake

    yes

    yes

    yes

    yes

    no

    no

    no

    yes

    no

    no

    no

    no

  • I am a programmer, if the inputs are

    • can read code?

    • can write code?

    read

    write

    is a programmer

    yes

    yes

    yes

    yes

    no

    no

    no

    yes

    no

    no

    no

    no

  • Multi Factor Authentication to log in, if the inputs are

    • did the user provide the right password?

    • did the user provide the MFA code?

    right password

    right MFA code

    log in

    yes

    yes

    yes

    yes

    no

    no

    no

    yes

    no

    no

    no

    no

    how did I get the right MFA code without the right password?

  • selling a product, if the inputs are

    • is there supply?

    • is there demand?

    supply

    demand

    can sell

    yes

    yes

    yes

    yes

    no

    no

    no

    yes

    no

    no

    no

    no


Note

All of the statements below have the same result

  • return True if something is equal to True

    if something == True:
        return True
    else:
        return False
    
  • return True if the result of bool(something) is equal to True

    if bool(something) == True:
        return True
    else:
        return False
    
  • return True if the result of bool(something) is True

    if bool(something):
        return True
    else:
        return False
    
  • return True if the result of bool(something) is True

    if something:
        return True
    else:
        return False
    
  • return True if the result of bool(something) is True

    return True if something else False
    
  • return True if the result of bool(something) is True

    return something
    

test_project_second

The truth table for project_second is

first input

second input

return

True

True

True

True

False

False

False

True

True

False

False

False


RED: make it fail


I add a test for project_second with an assertion for the case where the first input is True and the second input is True, to test_binary.py

first input

second input

return

True

True

True

21    def test_logical_conjunction(self):
22        self.assertTrue(
23            src.truth_table.logical_conjunction(True, True)
24        )
25        self.assertFalse(
26            src.truth_table.logical_conjunction(True, False)
27        )
28        self.assertFalse(
29            src.truth_table.logical_conjunction(False, True)
30        )
31        self.assertFalse(
32            src.truth_table.logical_conjunction(False, False)
33        )
34
35    def test_project_second(self):
36        self.assertTrue(
37            src.truth_table.project_second(True, True)
38        )
39
40
41# Exceptions seen

the terminal is my friend, and shows AttributeError

AttributeError: module 'src.truth_table' has no attribute 'project_second'

because I do not have a definition for the project_second function in truth_table.py


GREEN: make it pass


I add the function to truth_table.py

21def logical_conjunction(first_input, second_input):
22    return first_input and second_input
23
24
25def project_second(first_input, second_input):
26    return True

the test passes. project_second returns True, if the first input is True and the second input is True, just like logical_conjunction


REFACTOR: make it better


  • I add an assertion for the second case, which is when the first input is True and the second input is False, to test_project_second in test_binary.py

    first input

    second input

    return

    True

    False

    False

    35    def test_project_second(self):
    36        self.assertTrue(
    37            src.truth_table.project_second(True, True)
    38        )
    39        self.assertFalse(
    40            src.truth_table.project_second(True, False)
    41        )
    

    the terminal is my friend, and shows AssertionError

    AssertionError: True is not false
    

    because the function returns True and the test expects

    • False, if the first input is True and the second input is False

    • True, if the first input is True and the second input is True

    • the second input in both cases

  • I make project_second return second_input in truth_table.py

    25def project_second(first_input, second_input):
    26    return second_input
    

    the test passes. project_second function returns the second input

  • I add an assertion to test_project_second for the next case, which is when the first input is False and the second input is True, in test_binary.py

    35    def test_project_second(self):
    36        self.assertTrue(
    37            src.truth_table.project_second(True, True)
    38        )
    39        self.assertFalse(
    40            src.truth_table.project_second(True, False)
    41        )
    42        self.assertTrue(
    43            src.truth_table.project_second(False, True)
    44        )
    

    the test is still green

  • I add an assertion for the last case, which is when the first input is False and the second input is False

    first input

    second input

    return

    False

    False

    False

    35    def test_project_second(self):
    36        self.assertTrue(
    37            src.truth_table.project_second(True, True)
    38        )
    39        self.assertFalse(
    40            src.truth_table.project_second(True, False)
    41        )
    42        self.assertTrue(
    43            src.truth_table.project_second(False, True)
    44        )
    45        self.assertFalse(
    46            src.truth_table.project_second(False, False)
    47        )
    48
    49
    50# Exceptions seen
    

    still green.

project_second always returns the second input, it does not care about the first input


examples of Project Second


  • Binge watching TV, if the inputs are

    • should I sleep?

    • do I want to watch one more episode?

    sleep?

    do I want it?

    watch TV

    yes

    yes

    yes

    yes

    no

    no

    no

    yes

    yes

    no

    no

    no

  • dictatorship, if the inputs are

    • is voters’ choice?

    • is dictator’s choice?

    voters

    dictator

    outcome

    yes

    yes

    yes

    yes

    no

    no

    no

    yes

    yes

    no

    no

    no

  • being sick, if the inputs are

    • sick before?

    • sick now?

    before

    now

    sick

    healthy

    healthy

    healthy

    healthy

    sick

    sick

    sick

    healthy

    healthy

    sick

    sick

    sick

  • my expectation versus reality, if the inputs are

    • my expectation

    • reality

    expectation

    reality

    result

    True

    True

    True

    True

    False

    False

    False

    True

    True

    False

    False

    False


test_converse_non_implication

The truth table for converse_non_implication is

first input

second input

return

True

True

False

True

False

False

False

True

True

False

False

False


RED: make it fail


I add a test for converse_non_implication with an assertion for when the first input is True and the second input is True, to test_binary.py

first input

second input

return

True

True

False

35    def test_project_second(self):
36        self.assertTrue(
37            src.truth_table.project_second(True, True)
38        )
39        self.assertFalse(
40            src.truth_table.project_second(True, False)
41        )
42        self.assertTrue(
43            src.truth_table.project_second(False, True)
44        )
45        self.assertFalse(
46            src.truth_table.project_second(False, False)
47        )
48
49    def test_converse_non_implication(self):
50        self.assertFalse(
51            src.truth_table.converse_non_implication(
52                True, True
53            )
54        )
55
56
57# Exceptions seen

the terminal is my friend, and shows AttributeError

AttributeError: module 'src.truth_table' has no attribute 'converse_non_implication'

because there is no definition for converse_non_implication in truth_table.py in the src folder


GREEN: make it pass


I add the function to truth_table.py

25  def project_second(first_input, second_input):
26      return second_input
27
28
29  def converse_non_implication(first_input, second_input):
30      return False

the test passes. converse_non_implication returns False, if the first input is True and the second input is True


REFACTOR: make it better


  • I add an assertion for the next case, which is when the first input is True and the second input is False, to test_converse_non_implication in test_binary.py

    first input

    second input

    return

    True

    False

    False

    49    def test_converse_non_implication(self):
    50        self.assertFalse(
    51            src.truth_table.converse_non_implication(
    52                True, True
    53            )
    54        )
    55        self.assertFalse(
    56            src.truth_table.converse_non_implication(
    57                True, False
    58            )
    59        )
    60
    61
    62# Exceptions seen
    

    the test is still green. converse_non_implication returns False

    • if the first input is True and the second input is False

    • if the first input is True and the second input is True

  • I add an assertion for the third case, which is when the first input is False and the second input is True

    first input

    second input

    return

    False

    True

    True

    49    def test_converse_non_implication(self):
    50        self.assertFalse(
    51            src.truth_table.converse_non_implication(
    52                True, True
    53            )
    54        )
    55        self.assertFalse(
    56            src.truth_table.converse_non_implication(
    57                True, False
    58            )
    59        )
    60        self.assertTrue(
    61            src.truth_table.converse_non_implication(
    62                False, True
    63            )
    64        )
    65
    66
    67# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    
  • I add an if statement for this case to the converse_non_implication function in truth_table.py

    29def converse_non_implication(first_input, second_input):
    30    if first_input == False:
    31        return True
    32    return False
    

    the test passes. converse_non_implication returns

    • True if the first input is False

    • False if the above condition is not met

  • I add an assertion for the next case, which is when the first input is False and the second input is False, to test_converse_non_implication in test_binary.py

    first input

    second input

    return

    False

    False

    False

    49    def test_converse_non_implication(self):
    50        self.assertFalse(
    51            src.truth_table.converse_non_implication(
    52                True, True
    53            )
    54        )
    55        self.assertFalse(
    56            src.truth_table.converse_non_implication(
    57                True, False
    58            )
    59        )
    60        self.assertTrue(
    61            src.truth_table.converse_non_implication(
    62                False, True
    63            )
    64        )
    65        self.assertFalse(
    66            src.truth_table.converse_non_implication(
    67                False, False
    68            )
    69        )
    70
    71
    72# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: True is not false
    

    because the function returned True and the assertion expects False

  • I add an if statement for the one case that returns True, to the one in the converse_non_implication function in truth_table.py

    29def converse_non_implication(first_input, second_input):
    30    if first_input == False:
    31        if second_input == True:
    32            return True
    33    return False
    

    the test passes

  • I add bool

    29def converse_non_implication(first_input, second_input):
    30    # if first_input == False:
    31    if bool(first_input) == False:
    32        # if second_input == True:
    33        if bool(second_input) == True:
    34            return True
    35    return False
    

    the test is still green

  • I use Logical Negation (NOT) to write the first if statement in terms of True

    29def converse_non_implication(first_input, second_input):
    30    # if first_input == False:
    31    # if bool(first_input) == False:
    32    if not bool(first_input) == True:
    33        # if second_input == True:
    34        if bool(second_input) == True:
    35            return True
    36    return False
    

    still green, because if bool(something) == False is the same as if not bool(something) == True

  • I remove == True

    29def converse_non_implication(first_input, second_input):
    30    # if first_input == False:
    31    # if bool(first_input) == False:
    32    # if not bool(first_input) == True:
    33    if not bool(first_input):
    34        # if second_input == True:
    35        # if bool(second_input) == True:
    36        if bool(second_input):
    37            return True
    38    return False
    

    green, because

    • if not bool(something) == True is the same as if not bool(something)

    • if bool(something) == True is the same as if bool(something)

  • I remove bool

    29def converse_non_implication(first_input, second_input):
    30    # if first_input == False:
    31    # if bool(first_input) == False:
    32    # if not bool(first_input) == True:
    33    # if not bool(first_input):
    34    if not first_input:
    35        # if second_input == True:
    36        # if bool(second_input) == True:
    37        # if bool(second_input):
    38        if second_input:
    39            return True
    40    return False
    

    still green, because

    • if bool(something) == False is the same as if not bool(something) == True is the same as if not bool(something) is the same as if not something

    • if bool(something) == True is the same as if bool(something) is the same as if something

  • I use AND to put the two if statements together

    29def converse_non_implication(first_input, second_input):
    30    # if first_input == False:
    31    # if bool(first_input) == False:
    32    # if not bool(first_input) == True:
    33    # if not bool(first_input):
    34    # if not first_input:
    35        # if second_input == True:
    36        # if bool(second_input) == True:
    37        # if bool(second_input):
    38        # if second_input:
    39    if not first_input and second_input:
    40            return True
    41    return False
    

    the test is still green, because I can use AND to put two if statements together when one is indented under the other. For example

    if something:
        if something_else:
    

    can also be written as

    if something and something_else:
    
  • I add an else clause to be clearer

    29def converse_non_implication(first_input, second_input):
    30    # if first_input == False:
    31    # if bool(first_input) == False:
    32    # if not bool(first_input) == True:
    33    # if not bool(first_input):
    34    # if not first_input:
    35        # if second_input == True:
    36        # if bool(second_input) == True:
    37        # if bool(second_input):
    38        # if second_input:
    39    if not first_input and second_input:
    40        return True
    41    else:
    42        return False
    

    still green

  • I add a conditional expression

    29def converse_non_implication(first_input, second_input):
    30    return (
    31        True
    32        if not first_input and second_input
    33        else False
    34    )
    35    # if first_input == False:
    36    # if bool(first_input) == False:
    37    # if not bool(first_input) == True:
    38    # if not bool(first_input):
    39    # if not first_input:
    40        # if second_input == True:
    41        # if bool(second_input) == True:
    42        # if bool(second_input):
    43        # if second_input:
    44    if not first_input and second_input:
    45        return True
    46    else:
    47        return False
    

    green

  • I remove True if and else False to make the simpler return statement

    29def converse_non_implication(first_input, second_input):
    30    return not first_input and second_input
    31    return (
    32        True
    33        if not first_input and second_input
    34        else False
    35    )
    36    # if first_input == False:
    37    # if bool(first_input) == False:
    38    # if not bool(first_input) == True:
    39    # if not bool(first_input):
    40    # if not first_input:
    41        # if second_input == True:
    42        # if bool(second_input) == True:
    43        # if bool(second_input):
    44        # if second_input:
    45    if not first_input and second_input:
    46        return True
    47    else:
    48        return False
    

    still green

  • converse_non_implication returns not first_input and second_input

    this means that in the 4 cases

    • if the first input is True and the second input is True, converse_non_implication returns

      (not first) and second
      (not True ) and True
      False       and True  # logical_conjunction(False, True)
      False                 # logical_conjunction(False, True)
      
    • if the first input is True and the second input is False, converse_non_implication returns

      (not first) and second
      (not True ) and False
      False       and False # logical_conjunction(False, False)
      False                 # logical_conjunction(False, False)
      
    • if the first input is False and the second input is True, converse_non_implication returns

      (not first) and second
      (not False) and True
      True        and True  # logical_conjunction(True, True)
      True                  # logical_conjunction(True, True)
      
    • if the first input is False and the second input is False, converse_non_implication returns

      (not first) and second
      (not False) and False
      True        and False # logical_conjunction(True, False)
      False                 # logical_conjunction(True, False)
      

    first

    not first

    second

    (not first) and second

    True

    False

    True

    False

    True

    False

    False

    False

    False

    True

    True

    True

    False

    True

    False

    False

    I add a return statement to show this

    29def converse_non_implication(first_input, second_input):
    30    return logical_conjunction(
    31        not first_input,
    32        second_input
    33    )
    34    return not first_input and second_input
    35    return (
    36        True
    37        if not first_input and second_input
    38        else False
    39    )
    40    # if first_input == False:
    41    # if bool(first_input) == False:
    42    # if not bool(first_input) == True:
    43    # if not bool(first_input):
    44    # if not first_input:
    45        # if second_input == True:
    46        # if bool(second_input) == True:
    47        # if bool(second_input):
    48        # if second_input:
    49    if not first_input and second_input:
    50        return True
    51    else:
    52        return False
    

    the test is still green

  • I remove the other statements

    29def converse_non_implication(first_input, second_input):
    30    return logical_conjunction(
    31        not first_input,
    32        second_input
    33    )
    34    return not first_input and second_input
    

Converse NonImplication always returns

  • not first_input and second_input

  • the Logical Conjunction of the Negation of the first input, and the second input

  • True, if the first input is False and the second input is True


examples of Converse NonImplication


  • crossing the street, if the inputs are

    • light is green for cars?

    • light is green for walking?

    green for cars?

    green for walking?

    can I cross the street?

    yes

    yes

    no

    yes

    no

    no

    no

    yes

    yes

    no

    no

    no

  • raise prices, if the inputs are

    • is supply abundant or scarce?

    • is demand strong or weak?

    supply

    demand

    raise prices

    abundant

    strong

    no

    abundant

    weak

    no

    scarce

    strong

    yes

    scarce

    weak

    no

  • do a computer update, if the inputs are

    • is the computer in use?

    • is there an update available?

    computer in use

    update available

    do update

    yes

    yes

    no

    yes

    no

    no

    no

    yes

    yes

    no

    no

    no

  • should I reply to a message?, if the inputs are

    • is it a group message?

    • is it one on one from a close friend?

    group chat

    close friend

    reply

    yes

    yes

    no

    yes

    no

    no

    no

    yes

    yes

    no

    no

    no

  • only give a discount to a new customer with a coupon code, if the inputs are

    • is already a customer?

    • does customer have the coupon code?

    already customer

    has coupon

    give discount

    yes

    yes

    no

    yes

    no

    no

    no

    yes

    yes

    no

    no

    no

  • run the gas generator, if the inputs are

    • is the house receiving electricity from the grid?

    • is there fuel in the generator?

    grid

    fuel

    run generator

    yes

    yes

    no

    yes

    no

    no

    no

    yes

    yes

    no

    no

    no


close the project

  • I close test_binary.py and truth_table.py in the editor

  • I click in the terminal, then use q on the keyboard to leave the tests. The terminal goes back to the command line

  • I change directory to the parent of truth_table

    cd ..
    

    the terminal shows

    .../pumping_python
    

    I am back in the pumping_python directory


review

Binary Operations take 2 inputs, each input can be True or False, if the first input is named first_input and the second input is named second_input, the tests show that

  • Converse NonImplication

    first input

    second input

    return

    True

    True

    False

    True

    False

    False

    False

    True

    True

    False

    False

    False

    • returns not first_input and second_input

    • returns True only if first_input is False and second_input is True

    • is the opposite (Logical Negation) of Converse Implication which returns False if first_input is False and second_input is True

  • Project Second

    first input

    second input

    return

    True

    True

    True

    True

    False

    False

    False

    True

    True

    False

    False

    False

  • Logical Conjunction returns

    first input

    second input

    return

    True

    True

    True

    True

    False

    False

    False

    True

    False

    False

    False

    False

    • returns first_input and second_input

    • returns True only if first_input is True and second_input is True

    • is the opposite (Logical Negation) of Logical NAND which returns False only if first_input is True and second_input is True

  • Contradiction

    first input

    second input

    return

    True

    True

    False

    True

    False

    False

    False

    True

    False

    False

    False

    False

and

1 logic statement has been written with and, another was written both.

return

True, True

True, False

False, True

False, False

name of operation

False

False

False

False

False

contradiction

first and second

True

False

False

False

logical_conjunction

second

True

False

True

False

project_second

(not first) and second

False

False

True

False

converse_non_implication


code from the chapter

Do you want to see all the CODE I typed for the Truth Table?


what is next?

Would you like to write more tests with bool?


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