truth table: Binary Operations 4


requirements

Binary Operations 3


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        contradiction = src.truth_table.contradiction
  9        self.assertFalse(contradiction(True, True))
 10        self.assertFalse(contradiction(True, False))
 11        self.assertFalse(contradiction(False, True))
 12        self.assertFalse(contradiction(False, False))
 13
 14    def test_logical_conjunction(self):
 15        logical_conjunction = (
 16            src.truth_table.logical_conjunction
 17        )
 18        self.assertTrue(
 19            logical_conjunction(True, True)
 20        )
 21        self.assertFalse(
 22            logical_conjunction(True, False)
 23        )
 24        self.assertFalse(
 25            logical_conjunction(False, True)
 26        )
 27        self.assertFalse(
 28            logical_conjunction(False, False)
 29        )
 30
 31    def test_project_second(self):
 32        project_second = src.truth_table.project_second
 33        self.assertTrue(project_second(True, True))
 34        self.assertFalse(project_second(True, False))
 35        self.assertTrue(project_second(False, True))
 36        self.assertFalse(project_second(False, False))
 37
 38    def test_converse_non_implication(self):
 39        converse_non_implication = (
 40            src.truth_table.converse_non_implication
 41        )
 42        self.assertFalse(
 43            converse_non_implication(True, True)
 44        )
 45        self.assertFalse(
 46            converse_non_implication(True, False)
 47        )
 48        self.assertTrue(
 49            converse_non_implication(False, True)
 50        )
 51        self.assertFalse(
 52            converse_non_implication(False, False)
 53        )
 54
 55    def test_negate_first(self):
 56        negate_first = src.truth_table.negate_first
 57        self.assertFalse(negate_first(True, True))
 58        self.assertFalse(negate_first(True, False))
 59        self.assertTrue(negate_first(False, True))
 60        self.assertTrue(negate_first(False, False))
 61
 62    def test_logical_nand(self):
 63        logical_nand = src.truth_table.logical_nand
 64        self.assertFalse(logical_nand(True, True))
 65        self.assertTrue(logical_nand(True, False))
 66        self.assertTrue(logical_nand(False, True))
 67        self.assertTrue(logical_nand(False, False))
 68
 69    def test_tautology(self):
 70        tautology = src.truth_table.tautology
 71        self.assertTrue(tautology(True, True))
 72        self.assertTrue(tautology(True, False))
 73        self.assertTrue(tautology(False, True))
 74        self.assertTrue(tautology(False, False))
 75
 76    def test_logical_disjunction(self):
 77        logical_disjunction = (
 78            src.truth_table.logical_disjunction
 79        )
 80        self.assertTrue(logical_disjunction(True, True))
 81        self.assertTrue(logical_disjunction(True, False))
 82        self.assertTrue(logical_disjunction(False, True))
 83        self.assertFalse(logical_disjunction(False, False))
 84
 85    def test_exclusive_disjunction(self):
 86        exclusive_disjunction = (
 87            src.truth_table.exclusive_disjunction
 88        )
 89        self.assertFalse(exclusive_disjunction(True, True))
 90        self.assertTrue(exclusive_disjunction(True, False))
 91        self.assertTrue(exclusive_disjunction(False, True))
 92        self.assertFalse(exclusive_disjunction(False, False))
 93
 94    def test_material_non_implication(self):
 95        material_non_implication = (
 96            src.truth_table.material_non_implication
 97        )
 98        self.assertFalse(
 99            material_non_implication(True, True)
100        )
101        self.assertTrue(
102            material_non_implication(True, False)
103        )
104        self.assertFalse(
105            material_non_implication(False, True)
106        )
107        self.assertFalse(
108            material_non_implication(False, False)
109        )
110
111    def test_project_first(self):
112        project_first = src.truth_table.project_first
113        self.assertTrue(project_first(True, True))
114        self.assertTrue(project_first(True, False))
115        self.assertFalse(project_first(False, True))
116        self.assertFalse(project_first(False, False))
117
118    def test_converse_implication(self):
119        converse_implication = (
120            src.truth_table.converse_implication
121        )
122        self.assertTrue(
123            converse_implication(True, True)
124        )
125        self.assertTrue(
126            converse_implication(True, False)
127        )
128        self.assertFalse(
129            converse_implication(False, True)
130        )
131        self.assertTrue(
132            converse_implication(False, False)
133        )
134
135    def test_negate_second(self):
136        negate_second = src.truth_table.negate_second
137        self.assertFalse(negate_second(True, True))
138        self.assertTrue(negate_second(True, False))
139        self.assertFalse(negate_second(False, True))
140        self.assertTrue(negate_second(False, False))
141
142    def test_logical_nor(self):
143        logical_nor = src.truth_table.logical_nor
144        self.assertFalse(logical_nor(True, True))
145        self.assertFalse(logical_nor(True, False))
146        self.assertFalse(logical_nor(False, True))
147        self.assertTrue(logical_nor(False, False))
148
149    def test_logical_equality(self):
150        logical_equality = (
151            src.truth_table.logical_equality
152        )
153        self.assertTrue(logical_equality(True, True))
154        self.assertFalse(logical_equality(True, False))
155        self.assertFalse(logical_equality(False, True))
156        self.assertTrue(logical_equality(False, False))
157
158    def test_material_implication(self):
159        material_implication = (
160            src.truth_table.material_implication
161        )
162        self.assertTrue(
163            material_implication(True, True)
164        )
165        self.assertFalse(
166            material_implication(True, False)
167        )
168        self.assertTrue(
169            material_implication(False, True)
170        )
171        self.assertTrue(
172            material_implication(False, False)
173        )
174
175
176# Exceptions seen
177# AttributeError
178# TypeError
179# AssertionError
180# SyntaxError

continue the project


test_negate_second

The truth table for negate_second is

first input

second input

return

True

True

False

True

False

True

False

True

False

False

False

True


RED: make it fail


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

first input

second input

return

True

True

False

118    def test_converse_implication(self):
119        converse_implication = (
120            src.truth_table.converse_implication
121        )
122        self.assertTrue(
123            converse_implication(True, True)
124        )
125        self.assertTrue(
126            converse_implication(True, False)
127        )
128        self.assertFalse(
129            converse_implication(False, True)
130        )
131        self.assertTrue(
132            converse_implication(False, False)
133        )
134
135    def test_negate_second(self):
136        negate_second = src.truth_table.negate_second
137        self.assertFalse(negate_second(True, True))
138
139
140# Exceptions seen

the terminal is my friend, and shows AttributeError

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

I do not have a definition for negate_second in truth_table.py


GREEN: make it pass


I add a function for negate_second to truth_table.py

 94def converse_implication(first_input, second_input):
 95    return logical_disjunction(
 96        first_input,
 97        logical_negation(second_input)
 98    )
 99    return first_input or not second_input
100
101
102def negate_second(first_input, second_input):
103    return False

the test passes. negate_second 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_negate_second in test_truth_table.py

    first input

    second input

    return

    True

    False

    True

    135    def test_negate_second(self):
    136        negate_second = src.truth_table.negate_second
    137        self.assertFalse(negate_second(True, True))
    138        self.assertTrue(negate_second(True, False))
    139
    140
    141# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    

    because the negate_second function returns False and the assertion expects True.

  • I add an if statement to negate_second in truth_table.py

    102def negate_second(first_input, second_input):
    103    if second_input == False:
    104        return True
    105    return False
    

    the test passes because when negate_second is called, it runs if second_input == False:

    • if second_input is NOT equal to False, it runs return False

    • if second_input is equal to False, it runs return 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_negate_second in test_truth_table.py

    first input

    second input

    return

    False

    True

    False

    135    def test_negate_second(self):
    136        negate_second = src.truth_table.negate_second
    137        self.assertFalse(negate_second(True, True))
    138        self.assertTrue(negate_second(True, False))
    139        self.assertFalse(negate_second(False, True))
    140
    141
    142# Exceptions seen
    

    the test is still green. negate_second returns the logical negation of the second input in all 3 cases.

  • 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

    True

    135    def test_negate_second(self):
    136        negate_second = src.truth_table.negate_second
    137        self.assertFalse(negate_second(True, True))
    138        self.assertTrue(negate_second(True, False))
    139        self.assertFalse(negate_second(False, True))
    140        self.assertTrue(negate_second(False, False))
    141
    142
    143# Exceptions seen
    

    the test is still green.

  • I add the bool built-in function to the negate_second function in truth_table.py

    102def negate_second(first_input, second_input):
    103    # if second_input == False:
    104    if bool(second_input) == False:
    105        return True
    106    return False
    

    still green.

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

    102def negate_second(first_input, second_input):
    103    # if second_input == False:
    104    # if bool(second_input) == False:
    105    if bool(not second_input) == True:
    106        return True
    107    return False
    

    green.

  • I remove == True

    102def negate_second(first_input, second_input):
    103    # if second_input == False:
    104    # if bool(second_input) == False:
    105    # if bool(not second_input) == True:
    106    if bool(not second_input):
    107        return True
    108    return False
    

    still green.

  • I remove bool

    102def negate_second(first_input, second_input):
    103    # if second_input == False:
    104    # if bool(second_input) == False:
    105    # if bool(not second_input) == True:
    106    # if bool(not second_input):
    107    if not second_input:
    108        return True
    109    return False
    

    the test is still green, because when if second_input == False: runs, Python checks if second_input is equal to False. I can assume the following substitutions

    • if the value of something is False

      if something           == False
      if bool(something    ) == False
      if bool(False        ) == False
      if False               == False
      if True                == True  # use equality
      if True                         # remove '== True'
      if not False                    # change to terms of False
      if not something
      
    • if the value of something is True

      if something           == False
      if bool(something    ) == False
      if bool(True         ) == False
      if True                == False
      if False               == True  # use equality
      if False                        # remove '== True'
      if not True                     # change to terms of True
      if not something
      

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

  • I add a conditional expression

    102def negate_second(first_input, second_input):
    103    # if second_input == False:
    104    # if bool(second_input) == False:
    105    # if bool(not second_input) == True:
    106    # if bool(not second_input):
    107    # if not second_input:
    108    #     return True
    109    # return False
    110    return True if not second_input else False
    

    still green.

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

    102def negate_second(first_input, second_input):
    103    # if second_input == False:
    104    # if bool(second_input) == False:
    105    # if bool(not second_input) == True:
    106    # if bool(not second_input):
    107    # if not second_input:
    108    #     return True
    109    # return False
    110    # return True if not second_input else False
    111    return not second_input
    
  • I remove the comments

    102def negate_second(first_input, second_input):
    103    return not second_input
    
  • I add a git commit message in another terminal

    git commit -am 'add negate_second'
    

Negate Second always returns

It is the Logical Negation (NOT) of Project Second which always returns the second input


examples of Negate Second


  • returning a defective product, if the inputs are

    • do I have the original receipt?

    • does the product work?

    receipt?

    product works?

    return?

    yes

    yes

    no

    yes

    no

    yes

    no

    yes

    no

    no

    no

    yes

  • I do not pick up calls from numbers that are not in my contact list, if the inputs are

    • am I busy?

    • is the number saved in my phone?

    busy?

    number saved?

    send to voicemail?

    yes

    yes

    no

    yes

    no

    yes

    no

    yes

    no

    no

    no

    yes


test_logical_nor

The truth table for logical_nor is

first input

second input

return

True

True

False

True

False

False

False

True

False

False

False

True


RED: make it fail


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

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

    first input

    second input

    return

    True

    True

    False

    135    def test_negate_second(self):
    136        negate_second = src.truth_table.negate_second
    137        self.assertFalse(negate_second(True, True))
    138        self.assertTrue(negate_second(True, False))
    139        self.assertFalse(negate_second(False, True))
    140        self.assertTrue(negate_second(False, False))
    141
    142    def test_logical_nor(self):
    143        logical_nor = src.truth_table.logical_nor
    144        self.assertFalse(logical_nor(True, True))
    145
    146
    147# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

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

    truth_table.py does not have any definition for logical_nor.


GREEN: make it pass


I add the function to truth_table.py

102def negate_second(first_input, second_input):
103    return not second_input
104
105
106def logical_nor(first_input, second_input):
107    return False

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


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_logical_nor in test_truth_table.py

    first input

    second input

    return

    True

    False

    False

    147    def test_logical_nor(self):
    148        logical_nor = src.truth_table.logical_nor
    149        self.assertFalse(logical_nor(True, True))
    150        self.assertFalse(logical_nor(True, False))
    151
    152
    153# Exceptions seen
    

    the test is still green. logical_nor 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

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

    first input

    second input

    return

    False

    True

    False

    147    def test_logical_nor(self):
    148        logical_nor = src.truth_table.logical_nor
    149        self.assertFalse(logical_nor(True, True))
    150        self.assertFalse(logical_nor(True, False))
    151        self.assertFalse(logical_nor(False, True))
    152
    153
    154# Exceptions seen
    

    the test is still green. logical_nor returns

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

    • False, if the first input is True

  • 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

    True

    147    def test_logical_nor(self):
    148        logical_nor = src.truth_table.logical_nor
    149        self.assertFalse(logical_nor(True, True))
    150        self.assertFalse(logical_nor(True, False))
    151        self.assertFalse(logical_nor(False, True))
    152        self.assertTrue(logical_nor(False, False))
    153
    154
    155# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    

    because the logical_nor function returns False and the assertion expects True.

  • I add if statements for this case to logical_nor in truth_table.py

    106def logical_nor(first_input, second_input):
    107    if first_input == False:
    108        if second_input == False:
    109            return True
    110    return False
    

    the test passes.

  • I add the bool built-in function

    106def logical_nor(first_input, second_input):
    107    # if first_input == False:
    108    if bool(first_input) == False:
    109        # if second_input == False:
    110        if bool(second_input) == False:
    111            return True
    112    return False
    

    the test still green.

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

    106def logical_nor(first_input, second_input):
    107    # if first_input == False:
    108    # if bool(first_input) == False:
    109    if bool(not first_input) == True:
    110        # if second_input == False:
    111        # if bool(second_input) == False:
    112        if bool(not second_input) == True:
    113            return True
    114    return False
    

    still green.

  • I remove == True

    106def logical_nor(first_input, second_input):
    107    # if first_input == False:
    108    # if bool(first_input) == False:
    109    # if bool(not first_input) == True:
    110    if bool(not first_input):
    111        # if second_input == False:
    112        # if bool(second_input) == False:
    113        # if bool(not second_input) == True:
    114        if bool(not second_input):
    115            return True
    116    return False
    

    green.

  • I remove bool

    106def logical_nor(first_input, second_input):
    107    # if first_input == False:
    108    # if bool(first_input) == False:
    109    # if bool(not first_input) == True:
    110    # if bool(not first_input):
    111    if not first_input:
    112        # if second_input == False:
    113        # if bool(second_input) == False:
    114        # if bool(not second_input) == True:
    115        # if bool(not second_input):
    116        if not second_input:
    117            return True
    118    return False
    

    still green, because I can assume the following substitutions for when if something == False: runs

    • if the value of something is False

      if something           == False
      if bool(something    ) == False
      if bool(False        ) == False
      if False               == False
      if True                == True  # use equality
      if True                         # remove '== True'
      if not False                    # change to terms of False
      if not something
      
    • if the value of something is True

      if something           == False
      if bool(something    ) == False
      if bool(True         ) == False
      if True                == False
      if False               == True  # use equality
      if False                        # remove '== True'
      if not True                     # change to terms of True
      if not something
      

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

  • I use Logical Conjunction (AND) to put the two if statements together

     94def logical_nor(first_input, second_input):
     95    # if first_input == False:
     96    # if bool(first_input) == False:
     97    # if bool(not first_input) == True:
     98    # if bool(not first_input):
     99    # if not first_input:
    100        # if second_input == False:
    101        # if bool(second_input) == False:
    102        # if bool(not second_input) == True:
    103        # if bool(not second_input):
    104        # if not second_input:
    105    if not first_input and not second_input:
    106            return True
    107    return False
    

    still green, because I can put two if statements together when one is indented under the other

    if something:
        if something_else:
    

    can also be written as

    if something and something_else:
    
  • I add a conditional expression

    106def logical_nor(first_input, second_input):
    107    # if first_input == False:
    108    # if bool(first_input) == False:
    109    # if bool(not first_input) == True:
    110    # if bool(not first_input):
    111    # if not first_input:
    112        # if second_input == False:
    113        # if bool(second_input) == False:
    114        # if bool(not second_input) == True:
    115        # if bool(not second_input):
    116        # if not second_input:
    117    # if not first_input and not second_input:
    118    #         return True
    119    # return False
    120    return (
    121        True if
    122        not first_input and not second_input
    123        else False
    124    )
    

    the test is still green.

  • I remove True if and else False

    106def logical_nor(first_input, second_input):
    107    # if first_input == False:
    108    # if bool(first_input) == False:
    109    # if bool(not first_input) == True:
    110    # if bool(not first_input):
    111    # if not first_input:
    112        # if second_input == False:
    113        # if bool(second_input) == False:
    114        # if bool(not second_input) == True:
    115        # if bool(not second_input):
    116        # if not second_input:
    117    # if not first_input and not second_input:
    118    #         return True
    119    # return False
    120    return (
    121        # True if
    122        not first_input and not second_input
    123        # else False
    124    )
    

    still green.

  • I write the statement in terms of not because it happens 2 times

    120    return (
    121        # True if
    122        # not first_input and not second_input
    123        (not first_input)
    124        (not or)
    125        (not second_input)
    126        # else False
    127    )
    

    the terminal is my friend, and shows SyntaxError

    SyntaxError: invalid syntax
    

    because I cannot negate or this way

  • I “factor” out the nots

    120    return (
    121        # True if
    122        # not first_input and not second_input
    123        # (not first_input)
    124        # (not or)
    125        # (not second_input)
    126        not (first_input or second_input)
    127        # else False
    128    )
    

    the test is green again.

  • logical_nor returns not (first_input or second_input) which is the Logical Negation (NOT) of the Logical Disjunction (OR) of the first input and the second input

    logical_negation(
        logical_disjunction(
            first_input, second_input
        )
    )
    

    this means that in the four cases

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

      not (first_input or second_input)
      not (True        or True        )
      not (True                       )
      False # not logical_disjunction(True, False)
      
    • if the first input is True and the second input is False, logical_nor returns

      not (first_input or second_input)
      not (True        or False       )
      not (True                       )
      False # not logical_disjunction(True, True)
      
    • if the first input is False and the second input is True, logical_nor returns

      not (first_input or second_input)
      not (False       or True        )
      not (True                       )
      False # not logical_disjunction(False, False)
      
    • if the first input is False and the second input is False, logical_nor returns

      not (first_input or second_input)
      not (False       or False       )
      not (False                      )
      True  # not logical_disjunction(False, True)
      

    first

    second

    first or second

    not (first or second)

    True

    True

    True

    False

    True

    False

    True

    False

    False

    True

    True

    False

    False

    False

    False

    True

    I add a return statement to show this

    106def logical_nor(first_input, second_input):
    107    # if first_input == False:
    108    # if bool(first_input) == False:
    109    # if bool(not first_input) == True:
    110    # if bool(not first_input):
    111    # if not first_input:
    112        # if second_input == False:
    113        # if bool(second_input) == False:
    114        # if bool(not second_input) == True:
    115        # if bool(not second_input):
    116        # if not second_input:
    117    # if not first_input and not second_input:
    118    #         return True
    119    # return False
    120    return logical_negation(
    121        logical_disjunction(
    122            first_input, second_input
    123        )
    124    )
    125    return (
    126        # True if
    127        # not first_input and not second_input
    128        # (not first_input)
    129        # (not or)
    130        # (not second_input)
    131        not (first_input or second_input)
    132        # else False
    133    )
    

    still green.

  • I remove the comments

    106def logical_nor(first_input, second_input):
    107    return logical_negation(
    108        logical_disjunction(
    109            first_input, second_input
    110        )
    111    )
    112    return not (first_input or second_input)
    
  • I add a git commit message in the other terminal

    git commit -am 'add logical_nor'
    

    I can use either of these `return statements`_. The first return statement is the only one that runs in this case, because the return statement is the last thing to run in a function.

Logical NOR returns

  • not (first_input or second_input)

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

  • the Logical Negation of the Logical Disjunction (OR) of the first input and second input

  • not or of the first input and second input


examples of Logical Nor


  • fitness discipline, if the inputs are

    • did I eat cake?

    • did I skip the workout?

    eat cake

    skip workout

    disciplined

    yes

    yes

    no

    yes

    no

    no

    no

    yes

    no

    no

    no

    yes

  • a late fee, if the inputs are

    • did I make the payment?

    • am I within the grace period?

    made payment

    grace period

    late fee charged

    yes

    yes

    no

    yes

    no

    no

    no

    yes

    no

    no

    no

    yes


test_logical_equality

The truth table for logical_equality is

first input

second input

return

True

True

True

True

False

False

False

True

False

False

False

True


RED: make it fail


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

  • I add a test for Logical Equality with an assertion for when the first input is True and the second input is True to test_truth_table.py

    first input

    second input

    return

    True

    True

    True

    135    def test_logical_nor(self):
    136        logical_nor = src.truth_table.logical_nor
    137        self.assertFalse(logical_nor(True, True))
    138        self.assertFalse(logical_nor(True, False))
    139        self.assertFalse(logical_nor(False, True))
    140        self.assertTrue(logical_nor(False, False))
    141
    142    def test_logical_equality(self):
    143        logical_equality = (
    144            src.truth_table.logical_equality
    145        )
    146        self.assertTrue(logical_equality(True, True))
    147
    148
    149# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

    AttributeError: module 'src.truth_table'
                    has no attribute 'logical_equality'.
                    Did you mean: 'logical_identity'?
    

    because there is no definition for logical_equality in truth_table.py


GREEN: make it pass


I add a function for it in truth_table.py

106def logical_nor(first_input, second_input):
107    return logical_negation(
108        logical_disjunction(
109            first_input, second_input
110        )
111    )
112    return not (first_input or second_input)
113
114
115def logical_equality(first_input, second_input):
116    return True

the test passes. logical_equality 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_equality in test_truth_table.py

    first input

    second input

    return

    True

    False

    False

    149    def test_logical_equality(self):
    150        logical_equality = (
    151            src.truth_table.logical_equality
    152        )
    153        self.assertTrue(logical_equality(True, True))
    154        self.assertFalse(logical_equality(True, False))
    155
    156
    157# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: True is not false
    

    because the logical_equality function returns True and the assertion expects False.

  • I add an if statement to logical_equality in truth_table.py

    115def logical_equality(first_input, second_input):
    116    if second_input == False:
    117        return False
    118    return True
    

    the test passes because when logical_equality is called, it runs if second_input == False:

    • if second_input is NOT equal to False, it leaves the if statement then runs return True

    • if second_input is equal to False, it runs return False

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

    first input

    second input

    return

    False

    True

    False

    149    def test_logical_equality(self):
    150        logical_equality = (
    151            src.truth_table.logical_equality
    152        )
    153        self.assertTrue(logical_equality(True, True))
    154        self.assertFalse(logical_equality(True, False))
    155        self.assertFalse(logical_equality(False, True))
    156
    157
    158# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: True is not false
    

    because when logical_equality is called, it runs if second_input == False:

    • if second_input is equal to False, it runs return False

    • if second_input is NOT equal to False, it leaves the if statement then runs return True

    • second_input is True in this case, which raises AssertionError since the assertion expects False and the function returns True

  • I add another if statement to the logical_equality function in truth_table.py

    115def logical_equality(first_input, second_input):
    116    if first_input == False:
    117        return False
    118    if second_input == False:
    119        return False
    120    return True
    

    the test passes because when logical_equality is called, it runs if first_input == False:

  • 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_equality in test_truth_table.py

    first input

    second input

    return

    False

    False

    True

    149    def test_logical_equality(self):
    150        logical_equality = (
    151            src.truth_table.logical_equality
    152        )
    153        self.assertTrue(logical_equality(True, True))
    154        self.assertFalse(logical_equality(True, False))
    155        self.assertFalse(logical_equality(False, True))
    156        self.assertTrue(logical_equality(False, False))
    157
    158
    159# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    

    because when logical_equality is called, it runs if first_input == False:

    • if first_input is equal to False, it runs return False

    • if first_input is NOT equal to False, it runs the next if statement - if second_input == False:

      • if second_input is NOT equal to False, it leaves the if statement then runs return True

      • if second_input is equal to False, it runs return False

      • second_input is False in this case, which raises AssertionError since the assertion expects True and the function returns False

  • I add an if statement to the logical_equality function in truth_table.py

    115def logical_equality(first_input, second_input):
    116    if first_input == False:
    117        if second_input == False:
    118            return True
    119        return False
    120    if second_input == False:
    121        return False
    122    return True
    

    the test passes because when logical_equality is called, it runs if first_input == False:

    • if first_input is NOT equal to False, it runs the next if statement - if second_input == False:

      • if second_input is NOT equal to False, it leaves the if statement then runs return True

      • if second_input is equal to False, it runs return False

    • if first_input is equal to False, it runs if second_input == False:

      • if second_input is NOT equal to False, it leaves the if statement then runs the next line - return False

      • if second_input is equal to False, it runs return True

  • I add the bool built-in function

    115def logical_equality(first_input, second_input):
    116    # if first_input == False:
    117    if bool(first_input) == False:
    118        # if second_input == False:
    119        if bool(second_input) == False:
    120            return True
    121        return False
    122    # if second_input == False:
    123    if bool(second_input) == False:
    124        return False
    125    return True
    

    the test is still green.

  • I use Logical Negation (NOT) to write the statements in terms of True

    115def logical_equality(first_input, second_input):
    116    # if first_input == False:
    117    # if bool(first_input) == False:
    118    if bool(not first_input) == True:
    119        # if second_input == False:
    120        # if bool(second_input) == False:
    121        if bool(not second_input) == True:
    122            return True
    123        return False
    124    # if second_input == False:
    125    # if bool(second_input) == False:
    126    if bool(not second_input) == True:
    127        return False
    128    return
    

    still green.

  • I remove == True

    115def logical_equality(first_input, second_input):
    116    # if first_input == False:
    117    # if bool(first_input) == False:
    118    # if bool(not first_input) == True:
    119    if bool(not first_input):
    120        # if second_input == False:
    121        # if bool(second_input) == False:
    122        # if bool(not second_input) == True:
    123        if bool(not second_input):
    124            return True
    125        return False
    126    # if second_input == False:
    127    # if bool(second_input) == False:
    128    # if bool(not second_input) == True:
    129    if bool(not second_input):
    130        return False
    131    return True
    

    green.

  • I remove bool

    115def logical_equality(first_input, second_input):
    116    # if first_input == False:
    117    # if bool(first_input) == False:
    118    # if bool(not first_input) == True:
    119    # if bool(not first_input):
    120    if not first_input:
    121        # if second_input == False:
    122        # if bool(second_input) == False:
    123        # if bool(not second_input) == True:
    124        # if bool(not second_input):
    125        if not second_input:
    126            return True
    127        return False
    128    # if second_input == False:
    129    # if bool(second_input) == False:
    130    # if bool(not second_input) == True:
    131    # if bool(not second_input):
    132    if not second_input:
    133        return False
    134    return True
    

    still green because I can assume the following substitutions for when if something == False: runs

    • if the value of something is False

      if something           == False
      if bool(something    ) == False
      if bool(False        ) == False
      if False               == False
      if True                == True  # use equality
      if True                         # remove '== True'
      if not False                    # change to terms of False
      if not something
      
    • if the value of something is True

      if something           == False
      if bool(something    ) == False
      if bool(True         ) == False
      if True                == False
      if False               == True  # use equality
      if False                        # remove '== True'
      if not True                     # change to terms of True
      if not something
      

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

  • I use Logical Conjunction (AND) to make two of the cases clearer

    115def logical_equality(first_input, second_input):
    116    # if first_input == False:
    117    # if bool(first_input) == False:
    118    # if bool(not first_input) == True:
    119    # if bool(not first_input):
    120    # if not first_input:
    121        # if second_input == False:
    122        # if bool(second_input) == False:
    123        # if bool(not second_input) == True:
    124        # if bool(not second_input):
    125        # if not second_input:
    126    if not first_input and not second_input:
    127        return True
    128    if not first_input and second_input:
    129        return False
    130    # if second_input == False:
    131    # if bool(second_input) == False:
    132    # if bool(not second_input) == True:
    133    # if bool(not second_input):
    134    if not second_input:
    135        return False
    136    return True
    

    the test is still green, because I can put two if statements together when one is indented under the other

    if something:
        if something_else:
    

    can also be written as

    if something and something_else:
    
  • I do the same thing for the other two cases

    126    if not first_input and not second_input:
    127        return True
    128    if not first_input and second_input:
    129        return False
    130    # if second_input == False:
    131    # if bool(second_input) == False:
    132    # if bool(not second_input) == True:
    133    # if bool(not second_input):
    134    # if not second_input:
    135    if first_input and not second_input:
    136        return False
    137    if first_input and second_input:
    138        return True
    

    still green.

  • I put the if statements that return the same thing together

    115def logical_equality(first_input, second_input):
    116    # if first_input == False:
    117    # if bool(first_input) == False:
    118    # if bool(not first_input) == True:
    119    # if bool(not first_input):
    120    # if not first_input:
    121        # if second_input == False:
    122        # if bool(second_input) == False:
    123        # if bool(not second_input) == True:
    124        # if bool(not second_input):
    125        # if not second_input:
    126    # if second_input == False:
    127    # if bool(second_input) == False:
    128    # if bool(not second_input) == True:
    129    # if bool(not second_input):
    130    # if not second_input:
    131    if not first_input and second_input:
    132        return False
    133    if first_input and not second_input:
    134        return False
    135    if first_input and second_input:
    136        return True
    137    if not first_input and not second_input:
    138        return True
    
  • I use Logical Disjunction (OR) to put the two if statements that return True together

    131    # if not first_input and second_input:
    132    #     return False
    133    # if first_input and not second_input:
    134    #     return False
    135    # if first_input and second_input:
    136    #     return True
    137    # if not first_input and not second_input:
    138    #     return True
    139    if (
    140        (first_input and second_input)
    141        or
    142        (not first_input and not second_input)
    143    ):
    144        return True
    145    else:
    146        return False
    

    green, because I can put two if statements together when they both return the same thing and are at the same indentation level

    if something:
        return this
    if something_else:
        return this
    

    can also be written as

    if something or something_else:
        return this
    
  • I add a conditional expression

    131    # if not first_input and second_input:
    132    #     return False
    133    # if first_input and not second_input:
    134    #     return False
    135    # if first_input and second_input:
    136    #     return True
    137    # if not first_input and not second_input:
    138    #     return True
    139    # if (
    140    #     (first_input and second_input)
    141    #     or
    142    #     (not first_input and not second_input)
    143    # ):
    144    #     return True
    145    # else:
    146    #     return False
    147    return True if (
    148        (first_input and second_input)
    149        or
    150        (not first_input and not second_input)
    151    ) else False
    

    still green.

  • I remove True if and else False

    147    # return True if (
    148    return (
    149        (first_input and second_input)
    150        or
    151        (not first_input and not second_input)
    152    # ) else False
    153    )
    

    the test is still green.

  • I write the second part of the statement in terms of not because it happens twice

    147    # return True if (
    148    return (
    149        (first_input and second_input)
    150        or
    151        # (not first_input and not second_input)
    152        (
    153            (not first_input)
    154            (not or)
    155            (not second_input)
    156        )
    157    # ) else False
    158    )
    

    the terminal is my friend, and shows SyntaxError

    SyntaxError: invalid syntax
    

    because I cannot negate or this way

  • I “factor” out the nots

    147    # return True if (
    148    return (
    149        (first_input and second_input)
    150        or
    151        # (not first_input and not second_input)
    152        # (
    153        #     (not first_input)
    154        #     (not or)
    155        #     (not second_input)
    156        # )
    157        not (first_input or second_input)
    158    # ) else False
    159    )
    

    the test is green again.

  • Logical Equality returns ((first_input and second_input) or not (first_input or second_input)), which can be thought of as the Logical Disjunction (OR) of the Logical Conjunction (AND) of the first input and second input, and the Logical Negation(NOT) of the Logical Disjunction (OR) of the first input and second input also known as the Logical NOR of the first input and second input

    return logical_disjunction(
        logical_conjunction(first_input, second_input),
        logical_nor(first_input, second_input)
    )
    

    because

    logical_disjunction(first_input, second_input)
    
    first_input              == (first_input and second_input)
    logical_conjunction      == (first_input and second_input)
    
    second_input             == not (first_input or second_input)
    logical_nor              == not (first_input or second_input)
    

    or

    return logical_disjunction(
        logical_conjunction(first_input, second_input),
        logical_negation(
            logical_disjunction(first_input, second_input)
        )
    )
    

    This means that in the four cases

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

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

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

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

      (first and second) or (not (first or second))
      (False and False ) or (not (False or False ))
       False             or (not  False           )
       False             or  True
       True              # logical_disjunction(False, True)
      

    first

    second

    first and second

    first or second

    not (first or second)

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

    True

    True

    True

    False

    True

    True

    True

    False

    False

    True

    True

    False

    False

    True

    False

    False

    False

    False

    False

    False

    False

    True

    True

    True

    I add a return statement to show this

    147    # return True if (
    148    return logical_disjunction(
    149        logical_conjunction(first_input, second_input),
    150        logical_nor(first_input, second_input)
    151    )
    152    return (
    153        (first_input and second_input)
    154        or
    155        # (not first_input and not second_input)
    156        # (
    157        #     (not first_input)
    158        #     (not or)
    159        #     (not second_input)
    160        # )
    161        not (first_input or second_input)
    162    # ) else False
    163    )
    

    still green.

  • logical_equality returns True, if the first input and second input are the equal, which means I can write a much simpler return statement thanks to the equality (==) symbol (2 equal signs together =+= on the keyboard)

    115def logical_equality(first_input, second_input):
    116    # if first_input == False:
    117    # if bool(first_input) == False:
    118    # if bool(not first_input) == True:
    119    # if bool(not first_input):
    120    # if not first_input:
    121        # if second_input == False:
    122        # if bool(second_input) == False:
    123        # if bool(not second_input) == True:
    124        # if bool(not second_input):
    125        # if not second_input:
    126    # if second_input == False:
    127    # if bool(second_input) == False:
    128    # if bool(not second_input) == True:
    129    # if bool(not second_input):
    130    # if not second_input:
    131    # if not first_input and second_input:
    132    #     return False
    133    # if first_input and not second_input:
    134    #     return False
    135    # if first_input and second_input:
    136    #     return True
    137    # if not first_input and not second_input:
    138    #     return True
    139    # if (
    140    #     (first_input and second_input)
    141    #     or
    142    #     (not first_input and not second_input)
    143    # ):
    144    #     return True
    145    # else:
    146    #     return False
    147    # return True if (
    148    return first_input == second_input
    149    return logical_disjunction(
    150        logical_conjunction(first_input, second_input),
    151        logical_nor(first_input, second_input)
    152    )
    153    return (
    154        (first_input and second_input)
    155        or
    156        # (not first_input and not second_input)
    157        # (
    158        #     (not first_input)
    159        #     (not or)
    160        #     (not second_input)
    161        # )
    162        not (first_input or second_input)
    163    # ) else False
    164    )
    

    the test is still green.

  • I remove the commented lines

    115def logical_equality(first_input, second_input):
    116    return first_input == second_input
    117    return logical_disjunction(
    118        logical_conjunction(first_input, second_input),
    119        logical_nor(first_input, second_input)
    120    )
    121    return (
    122        (first_input and second_input)
    123        or
    124        not (first_input or second_input)
    125    )
    

    I can use any of these `return statements`_. The first return statement is the only one that runs in this case, because the return statement is the last thing to run in a function.

  • I add a git commit message in the other terminal

    git commit -am 'add logical_equality'
    

Logical Equality


examples of Logical Equality


  • my expectation matches reality, if the inputs are

    • reality

    • expectation

    reality

    my expectation

    expectation matches reality

    yes

    yes

    yes

    yes

    no

    no

    no

    yes

    no

    no

    no

    yes

  • a market is balanced, if the inputs are

    • supply

    • demand

    supply

    demand

    balance

    high

    high

    yes

    high

    low

    no

    low

    high

    no

    low

    low

    yes

  • we are in agreement, if the inputs are

    • what did I say?

    • what did you say?

    I said

    You said

    agreement

    yes

    yes

    yes

    yes

    no

    no

    no

    yes

    no

    no

    no

    yes


test_material_implication

The truth table for material_implication is

first input

second input

return

True

True

True

True

False

False

False

True

True

False

False

True


RED: make it fail


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

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

    first input

    second input

    return

    True

    True

    True

    149    def test_logical_equality(self):
    150        logical_equality = (
    151            src.truth_table.logical_equality
    152        )
    153        self.assertTrue(logical_equality(True, True))
    154        self.assertFalse(logical_equality(True, False))
    155        self.assertFalse(logical_equality(False, True))
    156        self.assertTrue(logical_equality(False, False))
    157
    158    def test_material_implication(self):
    159        material_implication = (
    160            src.truth_table.material_implication
    161        )
    162        self.assertTrue(
    163            material_implication(True, True)
    164        )
    165
    166
    167# Exceptions seen
    

    the terminal is my friend, and shows AttributeError

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

    because there is no definition for material_implication in truth_table.py


GREEN: make it pass


I add a function for material_implication to truth_table.py

115def logical_equality(first_input, second_input):
116    return first_input == second_input
117    return logical_disjunction(
118        logical_conjunction(first_input, second_input),
119        logical_nor(first_input, second_input)
120    )
121    return (
122        (first_input and second_input)
123        or
124        not (first_input or second_input)
125    )
126
127
128def material_implication(first_input, second_input):
129    return True

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


REFACTOR: make it better


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

    first input

    second input

    return

    True

    False

    False

    158    def test_material_implication(self):
    159        material_implication = (
    160            src.truth_table.material_implication
    161        )
    162        self.assertTrue(
    163            material_implication(True, True)
    164        )
    165        self.assertFalse(
    166            material_implication(True, False)
    167        )
    168
    169
    170# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: True is not false
    

    because the function returns True and the assertion expects False.

  • I add an if statement to material_implication in truth_table.py

    128def material_implication(first_input, second_input):
    129    if second_input == False:
    130        return False
    131    return True
    

    the test passes because when material_implication is called, it runs if second_input == False:

    • if second_input is NOT equal to False, it runs return True

    • if second_input is equal to False, it runs return False

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

    first input

    second input

    return

    False

    True

    True

    158    def test_material_implication(self):
    159        material_implication = (
    160            src.truth_table.material_implication
    161        )
    162        self.assertTrue(
    163            material_implication(True, True)
    164        )
    165        self.assertFalse(
    166            material_implication(True, False)
    167        )
    168        self.assertTrue(
    169            material_implication(False, True)
    170        )
    171
    172
    173# Exceptions seen
    

    the test is still green. material_implication returns

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

    • the second input in these three cases

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

    first input

    second input

    return

    False

    False

    True

    158    def test_material_implication(self):
    159        material_implication = (
    160            src.truth_table.material_implication
    161        )
    162        self.assertTrue(
    163            material_implication(True, True)
    164        )
    165        self.assertFalse(
    166            material_implication(True, False)
    167        )
    168        self.assertTrue(
    169            material_implication(False, True)
    170        )
    171        self.assertTrue(
    172            material_implication(False, False)
    173        )
    174
    175
    176# Exceptions seen
    

    the terminal is my friend, and shows AssertionError

    AssertionError: False is not true
    

    because when material_implication gets called, it runs if second_input == False:

    • if second_input is NOT equal to False, it runs return True

    • if second_input is equal to False, it runs return False

    • second_input is False in this case, which causes AssertionError since the assertion expects True and the function returns False

  • I add an if statement to the material_implication function for the one case where it returns False, in truth_table.py

    128def material_implication(first_input, second_input):
    129    if first_input == True:
    130        if second_input == False:
    131            return False
    132    return True
    

    the test passes.

  • I use the bool built-in function

    128def material_implication(first_input, second_input):
    129    # if first_input == True:
    130    if bool(first_input) == True:
    131        # if second_input == False:
    132        if bool(second_input) == False:
    133            return False
    134    return True
    

    the test is still green.

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

    128def material_implication(first_input, second_input):
    129    # if first_input == True:
    130    if bool(first_input) == True:
    131        # if second_input == False:
    132        # if bool(second_input) == False:
    133        if bool(not second_input) == True:
    134            return False
    135    return True
    

    still green.

  • I remove == True

    128def material_implication(first_input, second_input):
    129    # if first_input == True:
    130    # if bool(first_input) == True:
    131    if bool(first_input):
    132        # if second_input == False:
    133        # if bool(second_input) == False:
    134        # if bool(not second_input) == True:
    135        if bool(not second_input):
    136            return False
    137    return True
    

    green.

  • I remove bool

    128def material_implication(first_input, second_input):
    129    # if first_input == True:
    130    # if bool(first_input) == True:
    131    # if bool(first_input):
    132    if first_input:
    133        # if second_input == False:
    134        # if bool(second_input) == False:
    135        # if bool(not second_input) == True:
    136        # if bool(not second_input):
    137        if not second_input:
    138            return False
    139    return True
    

    still green, because

    • when if something == False: runs, Python checks if something is equal to False. I can assume the following substitutions

      • if the value of something is False

        if something           == False
        if bool(something    ) == False
        if bool(False        ) == False
        if False               == False
        if True                == True  # use equality
        if True                         # remove '== True'
        if not False                    # change to terms of False
        if not something
        
      • if the value of something is True

        if something           == False
        if bool(something    ) == False
        if bool(True         ) == False
        if True                == False
        if False               == True  # use equality
        if False                        # remove '== True'
        if not True                     # change to terms of True
        if not something
        
    • when if something == True: runs, Python checks if (something) is equal to True. I can assume the following substitutions

      • if the value of something is False

        if something           == True
        if bool(something    ) == True
        if bool(False        ) == True
        if False               == True
        if not True            == True  # change to terms of True
        if not True                     # remove '==True'
        if False
        if something
        
      • if the value of something is True

        if something           == True
        if bool(something    ) == True
        if bool(True         ) == True
        if True                == True  # remove '==True'
        if True
        if something
        
    • if bool(something) == False is the same as if bool(not something) == True is the same as if bool(not 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 Logical Conjunction (AND) to put the two if statements together

    128def material_implication(first_input, second_input):
    129    # if first_input == True:
    130    # if bool(first_input) == True:
    131    # if bool(first_input):
    132    # if first_input:
    133        # if second_input == False:
    134        # if bool(second_input) == False:
    135        # if bool(not second_input) == True:
    136        # if bool(not second_input):
    137        # if not second_input:
    138    if first_input and not second_input:
    139            return False
    140    return True
    

    the test is still green, because I can put two if statements together when one is indented under the other

    if something:
        if something_else:
    

    can also be written as

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

    128def material_implication(first_input, second_input):
    129    # if first_input == True:
    130    # if bool(first_input) == True:
    131    # if bool(first_input):
    132    # if first_input:
    133        # if second_input == False:
    134        # if bool(second_input) == False:
    135        # if bool(not second_input) == True:
    136        # if bool(not second_input):
    137        # if not second_input:
    138    if first_input and not second_input:
    139        return False
    140    else:
    141        return True
    

    still green.

  • I change the else clause to the Logical Negation (NOT) of the if statement

    138    if first_input and not second_input:
    139        return False
    140    # else:
    141    if not (first_input and not second_input):
    142        return True
    

    green.

  • I add a conditional expression

    138    # if first_input and not second_input:
    139    #     return False
    140    # else:
    141    # if not (first_input and not second_input):
    142    #     return
    143    return (
    144        True if
    145        not (first_input and not second_input)
    146        else False
    147    )
    

    still green.

  • I remove True if and else False to make it simpler

    138    # if first_input and not second_input:
    139    #     return False
    140    # else:
    141    # if not (first_input and not second_input):
    142    #     return
    143    return (
    144        # True if
    145        not (first_input and not second_input)
    146        # else False
    147    )
    

    the test is still green.

  • I “multiply” not by the symbols in parentheses

    138    # if first_input and not second_input:
    139    #     return False
    140    # else:
    141    # if not (first_input and not second_input):
    142    #     return
    143    return (
    144        # True if
    145        # not (first_input and not second_input)
    146        (not first_input)
    147        (not and)
    148        (not not second_input)
    149        # else False
    150    )
    

    the terminal is my friend, and shows SyntaxError

    SyntaxError: invalid syntax
    

    because I cannot negate and this way.

  • I change not and to or

    138    # if first_input and not second_input:
    139    #     return False
    140    # else:
    141    # if not (first_input and not second_input):
    142    #     return
    143    return (
    144        # True if
    145        # not (first_input and not second_input)
    146        (not first_input)
    147        # (not and)
    148        or
    149        (not not second_input)
    150        # else False
    151    )
    

    the test is green again.

  • I remove not not because they cancel out

    138    # if first_input and not second_input:
    139    #     return False
    140    # else:
    141    # if not (first_input and not second_input):
    142    #     return
    143    return (
    144        # True if
    145        # not (first_input and not second_input)
    146        (not first_input)
    147        # (not and)
    148        or
    149        # (not not second_input)
    150        second_input
    151        # else False
    152    )
    

    the test is still green, because two nots make a “right”?

  • material_implication returns not first_input or second_input

    • not first_input is the Logical Negation (NOT) of first_input

      • if the first input is True, this part of the statement is False

      • if the first input is False, this part of the statement is True

    • not first_input or second_input is the Logical Disjunction (OR) of the Logical Negation (NOT) of the first input, and the second input

      logical_disjunction(
          logical_negation(first_input),
          second_input
      )
      

    this means that in the four cases

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

      not first_input or second_input
      not True        or True
      False           or True
      True            # logical_disjunction(False, True)
      
    • if the first input is True and the second input is False, material_implication returns

      not first_input or second_input
      not True        or False
      False           or False
      False           # logical_disjunction(False, False)
      
    • if the first input is False and the second input is True, material_implication returns

      not first_input or second_input
      not False       or True
      True            or True
      True            # logical_disjunction(True, True)
      
    • if the first input is False and the second input is False, material_implication returns

      not first_input or second_input
      not False       or False
      True            or False
      True            # logical_disjunction(True, False)
      

    first

    not first

    second

    (not first or second)

    True

    False

    True

    True

    True

    False

    False

    False

    False

    True

    True

    True

    False

    True

    False

    True

    I add a return statement to show this

    128def material_implication(first_input, second_input):
    129    # if first_input == True:
    130    # if bool(first_input) == True:
    131    # if bool(first_input):
    132    # if first_input:
    133        # if second_input == False:
    134        # if bool(second_input) == False:
    135        # if bool(not second_input) == True:
    136        # if bool(not second_input):
    137        # if not second_input:
    138    # if first_input and not second_input:
    139    #     return False
    140    # else:
    141    # if not (first_input and not second_input):
    142    #     return
    143    return logical_disjunction(
    144        logical_negation(first_input),
    145        second_input
    146    )
    147    return (
    148        # True if
    149        # not (first_input and not second_input)
    150        (not first_input)
    151        # (not and)
    152        or
    153        # (not not second_input)
    154        second_input
    155        # else False
    156    )
    

    still green.

  • I remove the comments

    128def material_implication(first_input, second_input):
    129    return logical_disjunction(
    130        logical_negation(first_input),
    131        second_input
    132    )
    133    return not first_input or second_input
    

    I can use either of these `return statements`_. The first return statement is the only one that runs in this case, because the return statement is the last thing to run in a function.

  • I add a git commit message in another terminal

    git commit -am 'add material_implication'
    

Material Implication also known as Logical Implication returns

it is the Logical Negation (NOT) of Material Non-Implication which returns True only if the first input is True and the second input is False.


examples of Material Implication


  • does the fire alarm work, if the inputs are

    • is there a fire?

    • is the alarm ringing?

    fire?

    alarm?

    alarm works

    yes

    yes

    yes

    yes

    no

    no

    no

    yes

    yes (false positive)

    no

    no

    yes


close the project

  • I close test_truth_table.py and truth_table.py

  • I click in the terminal where the tests are running

  • I 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 two inputs, each input can be True or False. If I name the first input first_input and the second input second_input, the tests show that

  • Material/Logical Implication

    • returns not first_input or second_input

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

    • is the Logical Negation (NOT) of Material Non-Implication which returns True only if first_input is True and second_input is False

    first input

    second input

    return

    True

    True

    True

    True

    False

    False

    False

    True

    True

    False

    False

    True

  • Logical Equality

    first input

    second input

    return

    True

    True

    True

    True

    False

    False

    False

    True

    False

    False

    False

    True

  • Logical NOR

    • returns not (first_input or second_input)

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

    • is the Logical Negation (NOT) of Logical Disjunction which returns False only if first_input is False and second_input is False

    first input

    second input

    return

    True

    True

    False

    True

    False

    False

    False

    True

    False

    False

    False

    True

  • Negate Second

    first input

    second input

    return

    True

    True

    False

    True

    False

    True

    False

    True

    False

    False

    False

    True

  • Converse Implication

    • returns first_input or not second_input

    • returns False if first_input is False and second_input is True

    • is the Logical Negation (NOT) of Converse Non-Implication which returns True only if first_input is False and second_input is True

    first input

    second input

    return

    True

    True

    True

    True

    False

    True

    False

    True

    False

    False

    False

    True

  • Project First

    first input

    second input

    return

    True

    True

    True

    True

    False

    True

    False

    True

    False

    False

    False

    False

  • Material Non-Implication

    first input

    second input

    return

    True

    True

    False

    True

    False

    True

    False

    True

    False

    False

    False

    False

  • Exclusive Disjunction

    • returns first_input != second_input

    • returns True only if first_input and second_input are NOT equal

    • is the Logical Negation (NOT) of Logical Equality which returns True only if first_input and second_input are equal

    first input

    second input

    return

    True

    True

    False

    True

    False

    True

    False

    True

    True

    False

    False

    False

  • Logical Disjunction

    • returns first_input or second_input

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

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

    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

    • returns not (first_input and second_input)

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

    • is the Logical Negation (NOT) of Logical Conjunction (AND) which returns True only if first_input is True and second_input is True

    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 Non-Implication

    • returns not first_input and second_input

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

    • is the Logical Negation (NOT) 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 Logical Negation (NOT) 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

The binary operations can be written with some combination of AND, NOT and OR.

return

True, True

True, False

False, True

False, False

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

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

False

True

True

False

exclusive_disjunction

first and (not second)

False

True

False

False

material_non_implication

first

True

True

False

False

project_first

first or (not second)

True

True

False

True

converse_implication

not second

False

True

False

True

negate_second

not (first or second)

False

False

False

True

logical_nor

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

True

False

False

True

logical_equality

(not first) or second

True

False

True

True

material_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 see more examples of the truth table?


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.