truth table: Binary Operations 2


requirements

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(True, True)
 52        )
 53        self.assertFalse(
 54            src.truth_table.converse_non_implication(True, False)
 55        )
 56        self.assertTrue(
 57            src.truth_table.converse_non_implication(False, True)
 58        )
 59        self.assertFalse(
 60            src.truth_table.converse_non_implication(False, False)
 61        )
 62
 63    def test_negate_first(self):
 64        self.assertFalse(src.truth_table.negate_first(True, True))
 65        self.assertFalse(src.truth_table.negate_first(True, False))
 66        self.assertTrue(src.truth_table.negate_first(False, True))
 67        self.assertTrue(src.truth_table.negate_first(False, False))
 68
 69    def test_logical_nand(self):
 70        self.assertFalse(src.truth_table.logical_nand(True, True))
 71        self.assertTrue(src.truth_table.logical_nand(True, False))
 72        self.assertTrue(src.truth_table.logical_nand(False, True))
 73        self.assertTrue(src.truth_table.logical_nand(False, False))
 74
 75    def test_tautology(self):
 76        self.assertTrue(src.truth_table.tautology(True, True))
 77        self.assertTrue(src.truth_table.tautology(True, False))
 78        self.assertTrue(src.truth_table.tautology(False, True))
 79        self.assertTrue(src.truth_table.tautology(False, False))
 80
 81    def test_logical_disjunction(self):
 82        self.assertTrue(
 83            src.truth_table.logical_disjunction(True, True)
 84        )
 85        self.assertTrue(
 86            src.truth_table.logical_disjunction(True, False)
 87        )
 88        self.assertTrue(
 89            src.truth_table.logical_disjunction(False, True)
 90        )
 91        self.assertFalse(
 92            src.truth_table.logical_disjunction(False, False)
 93        )
 94
 95
 96# Exceptions seen
 97# AttributeError
 98# TypeError
 99# AssertionError
100# SyntaxError

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 8 items
    
    tests/test_binary.py ....                                     [ 50%]
    tests/test_nullary_unary.py ....                              [100%]
    
    ======================== 8 passed in G.HIs =========================
    
  • I hold ctrl (Windows) or option (MacOS) on the keyboard, then click on tests/test_binary.py with the mouse to open it in the editor


test_negate_first


RED: make it fail


I add a new test for negate_first in test_binary.py

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

the terminal is my friend, and shows AttributeError

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

there is no definition for negate_first in truth_table.py


GREEN: make it pass


I use the Explorer to open truth_table.py from the src folder in the editor

  • I add the function in truth_table.py

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

    the test passes.

negate_first returns False, if the first input is True and the second input is True

first input

second input

return

True

True

False


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_binary.py

    63    def test_negate_first(self):
    64        self.assertFalse(src.truth_table.negate_first(True, True))
    65        self.assertFalse(src.truth_table.negate_first(True, False))
    

    the test is still green. negate_first returns

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

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

    • False, if the first input is True

    first input

    second input

    return

    True

    True

    False

    True

    False

    False

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

    63    def test_negate_first(self):
    64        self.assertFalse(src.truth_table.negate_first(True, True))
    65        self.assertFalse(src.truth_table.negate_first(True, False))
    66        self.assertTrue(src.truth_table.negate_first(False, True))
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    
  • I add if statements for this case to negate_first in truth_table.py

    34def negate_first(first_input, second_input):
    35    if first_input == False:
    36        if second_input == True:
    37            return True
    38    return False
    

    the test passes. negate_first returns

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

    • False, if the first input is True

    first input

    second input

    return

    True

    True

    False

    True

    False

    False

    False

    True

    True

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

    63    def test_negate_first(self):
    64        self.assertFalse(src.truth_table.negate_first(True, True))
    65        self.assertFalse(src.truth_table.negate_first(True, False))
    66        self.assertTrue(src.truth_table.negate_first(False, True))
    67        self.assertTrue(src.truth_table.negate_first(False, False))
    68
    69
    70# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    
  • I add an if statement for it in truth_table.py

    34def negate_first(first_input, second_input):
    35    if first_input == False:
    36        if second_input == False:
    37            return True
    38        if second_input == True:
    39            return True
    40    return False
    

    the test passes. negate_first returns

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

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

    • True, if the first input is False

    • False, if the first input is True

    oh! It returns the logical negation of the first input

  • I add a return statement

    34def negate_first(first_input, second_input):
    35    return not first_input
    36    if first_input == False:
    37        if second_input == False:
    38            return True
    39        if second_input == True:
    40            return True
    41    return False
    

    the test is still green

  • I remove the other statements

    34def negate_first(first_input, second_input):
    35    return not first_input
    

    still green, no need for if statements here.

Negate First always returns

  • not first_input

  • True, if the first input is False

  • False, if the first input is True

  • the opposite (Logical Negation) of the first input in all cases, it does not care about the second input

first input

second input

return

True

True

False

True

False

False

False

True

True

False

False

True


examples of Negate First


  • approval to do something, if the inputs are

    • is risky?

    • has a reason?

    is risky?

    has reason?

    approved

    yes

    yes

    no

    yes

    no

    no

    no

    yes

    yes

    no

    no

    yes

  • going for a walk, if the inputs are

    • is it raining?

    • do I feel like walking?

    is raining?

    feel like walking?

    should walk

    yes

    yes

    no

    yes

    no

    no

    no

    yes

    yes

    no

    no

    yes

  • smoke detector battery test, if the inputs are

    • is the battery dead?

    • is there smoke?

    battery dead?

    is there smoke?

    beep

    yes

    yes

    beep

    yes

    no

    beep

    no

    yes

    no beep

    no

    no

    no beep

  • can the system be used while it is being updated, if the inputs are

    • is update running?

    • what kind of user?

    update running?

    what kind of user?

    system can be used

    yes

    admin

    no

    yes

    guest

    no

    no

    admin

    yes

    no

    guest

    yes

  • bad referee call, if the inputs are

    • is home team?

    • is bad play?

    is home team?

    is bad play?

    good call

    yes

    no

    no

    yes

    yes

    no

    no

    no

    yes

    no

    yes

    yes


test_logical_nand


RED: make it fail


I add a new test to test_binary.py

63    def test_negate_first(self):
64        self.assertFalse(src.truth_table.negate_first(True, True))
65        self.assertFalse(src.truth_table.negate_first(True, False))
66        self.assertTrue(src.truth_table.negate_first(False, True))
67        self.assertTrue(src.truth_table.negate_first(False, False))
68
69    def test_logical_nand(self):
70        self.assertFalse(src.truth_table.logical_nand(True, True))
71
72
73# Exceptions seen

the terminal is my friend, and shows AttributeError

AttributeError: module 'src.truth_table' has no attribute 'logical_nand'. Did you mean: 'logical_false'?

there is no definition for logical_nand in truth_table.py


GREEN: make it pass


I add the function to truth_table.py

34def negate_first(first_input, second_input):
35    return not first_input
36
37
38def logical_nand(first_input, second_input):
39    return False

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

first input

second input

return

True

True

False


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, in test_binary.py

    69    def test_logical_nand(self):
    70        self.assertFalse(src.truth_table.logical_nand(True, True))
    71        self.assertTrue(src.truth_table.logical_nand(True, False))
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    
  • I add if statements to logical_nand in truth_table.py

    38def logical_nand(first_input, second_input):
    39    if first_input == True:
    40        if second_input == False:
    41            return True
    42    return False
    

    the test passes. logical_nand returns

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

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

    • the logical negation of the second input so far

    first input

    second input

    return

    True

    True

    False

    True

    False

    True

  • I add another case, where the first input is False and the second input is True, to test_logical_nand in test_binary.py

    69    def test_logical_nand(self):
    70        self.assertFalse(src.truth_table.logical_nand(True, True))
    71        self.assertTrue(src.truth_table.logical_nand(True, False))
    72        self.assertTrue(src.truth_table.logical_nand(False, True))
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    
  • I add if statements to logical_nand in truth_table.py

    38def logical_nand(first_input, second_input):
    39    if first_input == False:
    40        if second_input == True:
    41            return True
    42    if first_input == True:
    43        if second_input == False:
    44            return True
    45    return False
    

    the test passes. logical_nand returns

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

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

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

    first input

    second input

    return

    True

    True

    False

    True

    False

    True

    False

    True

    True

  • 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_nand in test_binary.py

    69    def test_logical_nand(self):
    70        self.assertFalse(src.truth_table.logical_nand(True, True))
    71        self.assertTrue(src.truth_table.logical_nand(True, False))
    72        self.assertTrue(src.truth_table.logical_nand(False, True))
    73        self.assertTrue(src.truth_table.logical_nand(False, False))
    74
    75
    76# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    
  • I add an if statement to logical_nand in truth_table.py

    38def logical_nand(first_input, second_input):
    39    if first_input == False:
    40        if second_input == False:
    41            return True
    42        if second_input == True:
    43            return True
    44    if first_input == True:
    45        if second_input == False:
    46            return True
    47    return False
    

    the test passes. logical_nand returns

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

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

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

    • False, if the first input is True and the second input is True - this is the only case where it returns False

  • I add an if statement for the one case where it returns False with an else clause for the other 3 cases

    38def logical_nand(first_input, second_input):
    39    if first_input == True:
    40        if second_input == True:
    41            return False
    42    else:
    43        return True
    44    if first_input == False:
    45        if second_input == False:
    46            return True
    47        if second_input == True:
    48            return True
    49    if first_input == True:
    50        if second_input == False:
    51            return True
    52    return False
    

    the test is still green

  • I remove the other statements and put the two if statements together

    38def logical_nand(first_input, second_input):
    39    # if first_input == True:
    40    #     if second_input == True:
    41    if first_input == True and second_input == True:
    42            return False
    43    else:
    44        return True
    

    still green

  • I remove the comments and use bool

    38def logical_nand(first_input, second_input):
    39    # if first_input == True and second_input == True:
    40    if bool(first_input) == True and bool(second_input) == True:
    41            return False
    42    else:
    43        return True
    

    green

  • I remove the commented line and == True

    38def logical_nand(first_input, second_input):
    39    # if bool(first_input) == True and bool(second_input) == True:
    40    if bool(first_input) and bool(second_input):
    41            return False
    42    else:
    43        return True
    

    still green

  • I remove bool

    38def logical_nand(first_input, second_input):
    39    # if bool(first_input) and bool(second_input):
    40    if first_input and second_input:
    41            return False
    42    else:
    43        return True
    

    the test is still green

  • I want to use one return statement (a conditional expression) for everything, which means I need an if statement that returns True. I use logical negation (not) to change the else clause to the opposite of the if statement

    38def logical_nand(first_input, second_input):
    39    if first_input and second_input:
    40            return False
    41    # else:
    42    if not (first_input and second_input):
    43        return True
    

    still green

  • I move the new if statement to the top

    38def logical_nand(first_input, second_input):
    39    if not (first_input and second_input):
    40        return True
    41    if first_input and second_input:
    42            return False
    

    green

  • I change the second if statement to an else clause

    38def logical_nand(first_input, second_input):
    39    if not (first_input and second_input):
    40        return True
    41    # if first_input and second_input:
    42    else:
    43            return False
    

    green, green, green again 🎶

  • I add a conditional expression

    38def logical_nand(first_input, second_input):
    39    return True if not (first_input and second_input) else False
    40    if not (first_input and second_input):
    41        return True
    42    else:
    43            return False
    

    still green

  • I remove the if statement and use the simpler form of the ternary operator

    38def logical_nand(first_input, second_input):
    39    return not (first_input and second_input)
    40    return True if not (first_input and second_input) else False
    

    the test is still green

  • I remove the second return statement

    38def logical_nand(first_input, second_input):
    39    return not (first_input and second_input)
    

    this is the opposite (Logical Negation) of logical_conjunction

  • I add a return statement to make sure

    38def logical_nand(first_input, second_input):
    39    return not logical_conjunction(first_input, second_input)
    40    return not (first_input and second_input)
    

    green all the way

Logical NAND

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

  • returns not (first_input and second_input) which is the opposite (Logical Negation) of the Logical Conjunction of the first input and the second input, many words

  • is the opposite of Logical Conjunction which only returns True, if the first input is True and second input is True or returns first_input and second_input

  • is the not of the and of the first input and second input, confusing?

  • is not and

first input

second input

return

True

True

False

True

False

True

False

True

True

False

False

True


examples of Logical NAND


  • can the website be reached, if the inputs are

    • is main server down?

    • is backup server down?

    is main down?

    is backup down?

    can reach website?

    yes

    yes

    no

    yes

    no

    yes

    no

    yes

    yes

    no

    no

    yes

  • safety with household cleaning products, if the inputs are

    • is bleach?

    • is soap?

    is bleach?

    is soap?

    is safe?

    yes

    yes

    no

    yes

    no

    yes

    no

    yes

    yes

    no

    no

    yes

  • fridge alarm, if the inputs are

    • door open?

    • temperature rose?

    door open?

    temperature rose?

    alarm

    yes

    yes

    yes

    yes

    no

    no

    no

    yes

    no

    no

    no

    no

  • deny a transaction, if the inputs are

    • amount is larger than normal?

    • the recipient is new?

    large amount?

    new recipient?

    approve/deny

    yes

    yes

    deny

    yes

    no

    approve

    no

    yes

    approve

    no

    no

    approve

  • show content, if the inputs are

    • is user younger than 18?

    • is the content flagged as adult?

    less than 18?

    adult content?

    block/show

    yes

    yes

    block

    yes

    no

    show

    no

    yes

    show

    no

    no

    show

  • stop 2 processes from writing to the same place, if the inputs are

    • is process A writing?

    • is process B writing?

    process A write?

    process B write?

    stop/allow

    yes

    yes

    stop

    yes

    no

    allow

    no

    yes

    allow

    no

    no

    allow


Note

When there is only one if statement that returns False with an else clause

if something:
    return False
else:
    return True

I can use its logical negation (not) to return True

if not something:
    return True
else:
    return False

I can write it with a ternary operator (conditional expression)

return True if not (something) else False

which can be made simpler as

return not (something)

this means

  • if something: return False is the same as return not (something), just like

  • if something: return True is the same as return something


test_tautology


RED: make it fail


I add a test for the next Binary Operation in test_binary.py

69    def test_logical_nand(self):
70        self.assertFalse(src.truth_table.logical_nand(True, True))
71        self.assertTrue(src.truth_table.logical_nand(True, False))
72        self.assertTrue(src.truth_table.logical_nand(False, True))
73        self.assertTrue(src.truth_table.logical_nand(False, False))
74
75    def test_tautology(self):
76        self.assertTrue(src.truth_table.tautology(True, True))
77
78
79# Exceptions seen

the terminal is my friend, and shows AttributeError

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

truth_table.py does not have tautology in it


GREEN: make it pass


I add the function to truth_table.py

38def logical_nand(first_input, second_input):
39    return not logical_conjunction(first_input, second_input)
40    return not (first_input and second_input)
41
42
43def tautology(first_input, second_input):
44    return True

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

first input

second input

return

True

True

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_tautology in test_binary.py

    75    def test_tautology(self):
    76        self.assertTrue(src.truth_table.tautology(True, True))
    77        self.assertTrue(src.truth_table.tautology(True, False))
    

    the test is still green. tautology returns

    • True, 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

    • True, if the first input is True

    first input

    second input

    return

    True

    True

    True

    True

    False

    True

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

    75    def test_tautology(self):
    76        self.assertTrue(src.truth_table.tautology(True, True))
    77        self.assertTrue(src.truth_table.tautology(True, False))
    78        self.assertTrue(src.truth_table.tautology(False, True))
    

    the test is still green. tautology returns True

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

    • if the first input is True

    first input

    second input

    return

    True

    True

    True

    True

    False

    True

    False

    True

    True

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

    75    def test_tautology(self):
    76        self.assertTrue(src.truth_table.tautology(True, True))
    77        self.assertTrue(src.truth_table.tautology(True, False))
    78        self.assertTrue(src.truth_table.tautology(False, True))
    79        self.assertTrue(src.truth_table.tautology(False, False))
    80
    81
    82# Exceptions seen
    

    still green, there is only one result for this operation.

Tautology always returns True, it does not care about the inputs. It is the opposite of contradiction which always returns False

first input

second input

return

True

True

True

True

False

True

False

True

True

False

False

True


examples of Tautology


  • work, if the inputs are

    • do I have work?

    • do I feel like working?

    have work?

    feel like work?

    work?

    yes

    yes

    work

    yes

    no

    work

    no

    yes

    work

    no

    no

    work

  • the customer is always right, if the inputs are

    • did customer complain?

    • is customer new?

    complain?

    new?

    is customer king?

    yes

    yes

    yes

    yes

    no

    yes

    no

    yes

    yes

    no

    no

    yes

  • the sun is real, if the inputs are

    • am I awake?

    • is it bright or dark outside?

    awake?

    bright/dark?

    is sun real?

    yes

    bright

    yes

    yes

    dark

    yes

    no

    bright

    yes

    no

    dark

    yes

  • I can get better, if the inputs are

    • am I good?

    • have I done this before?

    good?

    done before?

    can get better?

    yes

    yes

    yes

    yes

    no

    yes

    no

    yes

    yes

    no

    no

    yes

  • a noun is the name of a person, place or thing, if the inputs are

    • is a person?

    • is a place or a thing?

    person?

    place/thing?

    noun is a name

    yes

    place

    yes

    yes

    thing

    yes

    no

    place

    yes

    no

    thing

    yes

  • unconditional love, if the inputs are

    • has the person been good?

    • does the person deserve love?

    been good?

    deserving?

    love?

    yes

    place

    love

    yes

    thing

    love

    no

    place

    love

    no

    thing

    love


test_logical_disjunction


RED: make it fail


I add another test to test_binary.py

75    def test_tautology(self):
76        self.assertTrue(src.truth_table.tautology(True, True))
77        self.assertTrue(src.truth_table.tautology(True, False))
78        self.assertTrue(src.truth_table.tautology(False, True))
79        self.assertTrue(src.truth_table.tautology(False, False))
80
81    def test_logical_disjunction(self):
82        self.assertTrue(
83            src.truth_table.logical_disjunction(True, True)
84        )
85
86
87# Exceptions seen

the terminal is my friend, and shows AttributeError

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

there is no logical_disjunction in truth_table.py in the src folder, yet


GREEN: make it pass


I add the function to truth_table.py

41def tautology(first_input, second_input):
42    return True
43
44
45def logical_disjunction(first_input, second_input):
46    return True

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

first input

second input

return

True

True

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_disjunction in test_binary.py

    81    def test_logical_disjunction(self):
    82        self.assertTrue(
    83            src.truth_table.logical_disjunction(True, True)
    84        )
    85        self.assertTrue(
    86            src.truth_table.logical_disjunction(True, False)
    87        )
    

    the test is still green. logical_disjunction returns

    • True, 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

    • True, if the first input is True

    so far this is the same as Tautology

    first input

    second input

    return

    True

    True

    True

    True

    False

    True

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

    81    def test_logical_disjunction(self):
    82        self.assertTrue(
    83            src.truth_table.logical_disjunction(True, True)
    84        )
    85        self.assertTrue(
    86            src.truth_table.logical_disjunction(True, False)
    87        )
    88        self.assertTrue(
    89            src.truth_table.logical_disjunction(False, True)
    90        )
    

    the test is still green. logical_disjunction still looks like Tautology, it returns

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

    • True, if the first input is True

    first input

    second input

    return

    True

    True

    True

    True

    False

    True

    False

    True

    True

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

    81    def test_logical_disjunction(self):
    82        self.assertTrue(
    83            src.truth_table.logical_disjunction(True, True)
    84        )
    85        self.assertTrue(
    86            src.truth_table.logical_disjunction(True, False)
    87        )
    88        self.assertTrue(
    89            src.truth_table.logical_disjunction(False, True)
    90        )
    91        self.assertFalse(
    92            src.truth_table.logical_disjunction(False, False)
    93        )
    94
    95
    96# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: True is not false
    
  • I add if statements for the new case to logical_disjunction in truth_table.py

    47def logical_disjunction(first_input, second_input):
    48    if first_input == False:
    49        if second_input == False:
    50            return False
    51    return True
    

    the test passes. logical_disjunction returns

    • False, if the first input is False and the second input is False - this is the only case where it returns False

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

    • True, if the first input is True

  • I change the two if statements to one if statement with Logical Conjunction (AND)

    47def logical_disjunction(first_input, second_input):
    48    # if first_input == False:
    49    #     if second_input == False:
    50    if first_input == False and second_input == False:
    51            return False
    52    return True
    

    the test is still green

  • I use not to write the statements with True

    47def logical_disjunction(first_input, second_input):
    48    # if first_input == False and second_input == False:
    49    if (not first_input == True) and (not second_input == True):
    50            return False
    51    return True
    

    still green

  • I use the bool built-in function

    47def logical_disjunction(first_input, second_input):
    48    # if (not first_input == True) and (not second_input == True):
    49    if (
    50        (not bool(first_input) == True)
    51        and
    52        (not bool(second_input) == True)
    53    ):
    54            return False
    55    return True
    

    green

  • I remove == True

    47def logical_disjunction(first_input, second_input):
    48    # if (
    49    #     (not bool(first_input) == True)
    50    #     and
    51    #     (not bool(second_input) == True)
    52    # ):
    53    if (not bool(first_input)) and (not bool(second_input)):
    54            return False
    55    return True
    

    still green

  • I use a simpler if statement

    47def logical_disjunction(first_input, second_input):
    48    # if (not bool(first_input)) and (not bool(second_input)):
    49    if (not first_input) and (not second_input):
    50            return False
    51    return True
    

    how many green bottles standing on a wall?

  • I add a second if statement for the opposite (logical negation) of the statement I have, like I did with Logical NAND

    47def logical_disjunction(first_input, second_input):
    48    if (not first_input) and (not second_input):
    49            return False
    50    if not ((not first_input) and (not second_input)):
    51        return True
    

    the test is still green, that is a lot of nots

  • I move the new if statement to the top

    47def logical_disjunction(first_input, second_input):
    48    if not ((not first_input) and (not second_input)):
    49        return True
    50    if (not first_input) and (not second_input):
    51            return False
    

    still green

  • I change the second if statement to an else clause

    47def logical_disjunction(first_input, second_input):
    48    if not ((not first_input) and (not second_input)):
    49        return True
    50    # if (not first_input) and (not second_input):
    51    else:
    52            return False
    

    green

  • I add a conditional expression

    47def logical_disjunction(first_input, second_input):
    48    return True if not (
    49        (not first_input) and (not second_input)
    50    ) else False
    51    if not ((not first_input) and (not second_input)):
    52        return True
    53    else:
    54            return False
    

    green again 🎶

  • I make the return statement simpler

    47def logical_disjunction(first_input, second_input):
    48    return not ((not first_input) and (not second_input))
    49    return True if not (
    50        (not first_input) and (not second_input)
    51    ) else False
    

    the test is still green. A reminder that I can return the Logical Negation (not) of an if statement that returns False like I did with Logical NAND

    Note

    return not ((not first_input) and (not second_input)) returns the opposite (Logical Negation) of the Logical Conjunction of the Logical Negation of first_input, and the Logical Negation of second_input. This means that in the 4 cases

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

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

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

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

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

    first

    second

    not first

    not second

    ((not first) and (not second))

    not ((not first) and (not second))

    True

    True

    False

    False

    False

    True

    True

    False

    False

    True

    False

    True

    False

    True

    True

    False

    False

    True

    False

    False

    True

    True

    True

    False

  • not” appears 3 times in this statement, I want to change that. I “multiply” it by each thing inside the parentheses to try to make the statement simpler

    47def logical_disjunction(first_input, second_input):
    48    return (not not first_input) (not and) (not not second_input)
    49    return not ((not first_input) and (not second_input))
    

    the terminal is my friend, and shows SyntaxError

    SyntaxError: invalid syntax
    
  • I add SyntaxError to the list of Exceptions seen in test_binary.py

     97# Exceptions seen
     98# AttributeError
     99# TypeError
    100# AssertionError
    101# SyntaxError
    
  • I fix the failing line by changing “not and” to “or” in truth_table.py

    47def logical_disjunction(first_input, second_input):
    48    return (not not first_input) or (not not second_input)
    49    return not ((not first_input) and (not second_input))
    

    the test passes

  • I remove not not from the return statement because it cancels out

    47def logical_disjunction(first_input, second_input):
    48    return first_input or second_input
    49    return (not not first_input) or (not not second_input)
    

    the test is still green. Do two nots make a right?

  • I remove the second return statement

    47def logical_disjunction(first_input, second_input):
    48    return first_input or second_input
    

    green everywhere

Logical Disjunction also known as “or” returns

  • first_input or second_input

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

first input

second input

return

True

True

True

True

False

True

False

True

True

False

False

False


examples of Logical Disjunction


  • system works, if the inputs are

    • is main system running?

    • is backup system running?

    is main running?

    is backup running?

    is system working?

    yes

    yes

    yes

    yes

    no

    yes

    no

    yes

    yes

    no

    no

    no

  • emergency room triage, if the inputs are

    • is it life threatening?

    • is patient a child?

    life threat?

    child?

    treat immediately

    yes

    yes

    yes

    yes

    no

    yes

    no

    yes

    yes

    no

    no

    no

  • automatic door that opens, if the inputs are

    • has keycard?

    • entered code?

    has keycard?

    entered code?

    open door

    yes

    yes

    yes

    yes

    no

    yes

    no

    yes

    yes

    no

    no

    no

  • give discount if the person is already a customer or has a coupon, if the inputs are

    • is already a customer?

    • has coupon code?

    already customer

    has coupon

    give discount

    yes

    yes

    yes

    yes

    no

    yes

    no

    yes

    yes

    no

    no

    no

  • elevator moves, if the inputs are

    • did I push the button?

    • did someone else push the button?

    I pushed

    someone else pushed

    elevator moves

    yes

    yes

    yes

    yes

    no

    yes

    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

  • Logical Disjunction

    first input

    second input

    return

    True

    True

    True

    True

    False

    True

    False

    True

    True

    False

    False

    False

  • Tautology

    first input

    second input

    return

    True

    True

    True

    True

    False

    True

    False

    True

    True

    False

    False

    True

  • Logical NAND

    first input

    second input

    return

    True

    True

    False

    True

    False

    True

    False

    True

    True

    False

    False

    True

  • Negate First

    first input

    second input

    return

    True

    True

    False

    True

    False

    False

    False

    True

    True

    False

    False

    True

  • Converse NonImplication

    • 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

    first input

    second input

    return

    True

    True

    False

    True

    False

    False

    False

    True

    True

    False

    False

    False

  • Project Second

    first input

    second input

    return

    True

    True

    True

    True

    False

    False

    False

    True

    True

    False

    False

    False

  • Logical Conjunction returns

    • 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

    first input

    second input

    return

    True

    True

    True

    True

    False

    False

    False

    True

    False

    False

    False

    False

  • Contradiction

    first input

    second input

    return

    True

    True

    False

    True

    False

    False

    False

    True

    False

    False

    False

    False

and

All the logic statements or conditions have been written with some or all of these 3.

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

not first

False

False

True

True

negate_first

not (first and second)

False

True

True

True

logical_nand

True

True

True

True

True

tautology

first or second

True

True

True

False

logical_disjunction


code from the chapter

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


what is next?

Would you like test even more binary operations?


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