truth table: Binary Operations 4
requirements
preview
These are the tests I have at the end of the chapter
1import src.truth_table
2import unittest
3
4
5CASE_1 = True, True
6CASE_2 = True, False
7CASE_3 = False, True
8CASE_4 = False, False
9
10
11class TestBinaryOperations(unittest.TestCase):
12
13 def test_contradiction(self):
14 contradiction = src.truth_table.contradiction
15 self.assertFalse(contradiction(*CASE_1))
16 self.assertFalse(contradiction(*CASE_2))
17 self.assertFalse(contradiction(*CASE_3))
18 self.assertFalse(contradiction(*CASE_4))
19
20 def test_logical_conjunction(self):
21 logical_conjunction = (
22 src.truth_table.logical_conjunction
23 )
24 self.assertTrue(logical_conjunction(*CASE_1))
25 self.assertFalse(logical_conjunction(*CASE_2))
26 self.assertFalse(logical_conjunction(*CASE_3))
27 self.assertFalse(logical_conjunction(*CASE_4))
29 def test_project_second(self):
30 project_second = src.truth_table.project_second
31 self.assertTrue(project_second(*CASE_1))
32 self.assertFalse(project_second(*CASE_2))
33 self.assertTrue(project_second(*CASE_3))
34 self.assertFalse(project_second(*CASE_4))
35
36 def test_converse_non_implication(self):
37 converse_non_implication = (
38 src.truth_table.converse_non_implication
39 )
40 self.assertFalse(converse_non_implication(*CASE_1))
41 self.assertFalse(converse_non_implication(*CASE_2))
42 self.assertTrue(converse_non_implication(*CASE_3))
43 self.assertFalse(converse_non_implication(*CASE_4))
45 def test_negate_first(self):
46 negate_first = src.truth_table.negate_first
47 self.assertFalse(negate_first(*CASE_1))
48 self.assertFalse(negate_first(*CASE_2))
49 self.assertTrue(negate_first(*CASE_3))
50 self.assertTrue(negate_first(*CASE_4))
51
52 def test_logical_nand(self):
53 nand = src.truth_table.logical_nand
54 self.assertFalse(nand(*CASE_1))
55 self.assertTrue(nand(*CASE_2))
56 self.assertTrue(nand(*CASE_3))
57 self.assertTrue(nand(*CASE_4))
59 def test_tautology(self):
60 tautology = src.truth_table.tautology
61 self.assertTrue(tautology(*CASE_1))
62 self.assertTrue(tautology(*CASE_2))
63 self.assertTrue(tautology(*CASE_3))
64 self.assertTrue(tautology(*CASE_4))
65
66 def test_logical_disjunction(self):
67 logical_disjunction = (
68 src.truth_table.logical_disjunction
69 )
70 self.assertTrue(logical_disjunction(*CASE_1))
71 self.assertTrue(logical_disjunction(*CASE_2))
72 self.assertTrue(logical_disjunction(*CASE_3))
73 self.assertFalse(logical_disjunction(*CASE_4))
75 def test_exclusive_disjunction(self):
76 xor = src.truth_table.exclusive_disjunction
77 self.assertFalse(xor(*CASE_1))
78 self.assertTrue(xor(*CASE_2))
79 self.assertTrue(xor(*CASE_3))
80 self.assertFalse(xor(*CASE_4))
81
82 def test_material_non_implication(self):
83 material_non_implication = (
84 src.truth_table.material_non_implication
85 )
86 self.assertFalse(material_non_implication(*CASE_1))
87 self.assertTrue(material_non_implication(*CASE_2))
88 self.assertFalse(material_non_implication(*CASE_3))
89 self.assertFalse(material_non_implication(*CASE_4))
91 def test_project_first(self):
92 project_first = src.truth_table.project_first
93 self.assertTrue(project_first(*CASE_1))
94 self.assertTrue(project_first(*CASE_2))
95 self.assertFalse(project_first(*CASE_3))
96 self.assertFalse(project_first(*CASE_4))
97
98 def test_converse_implication(self):
99 converse_implication = (
100 src.truth_table.converse_implication
101 )
102 self.assertTrue(converse_implication(*CASE_1))
103 self.assertTrue(converse_implication(*CASE_2))
104 self.assertFalse(converse_implication(*CASE_3))
105 self.assertTrue(converse_implication(*CASE_4))
107 def test_negate_second(self):
108 negate_second = src.truth_table.negate_second
109 self.assertFalse(negate_second(*CASE_1))
110 self.assertTrue(negate_second(*CASE_2))
111 self.assertFalse(negate_second(*CASE_3))
112 self.assertTrue(negate_second(*CASE_4))
113
114 def test_logical_nor(self):
115 logical_nor = src.truth_table.logical_nor
116 self.assertFalse(logical_nor(*CASE_1))
117 self.assertFalse(logical_nor(*CASE_2))
118 self.assertFalse(logical_nor(*CASE_3))
119 self.assertTrue(logical_nor(*CASE_4))
121 def test_logical_equality(self):
122 logical_equality = (
123 src.truth_table.logical_equality
124 )
125 self.assertTrue(logical_equality(*CASE_1))
126 self.assertFalse(logical_equality(*CASE_2))
127 self.assertFalse(logical_equality(*CASE_3))
128 self.assertTrue(logical_equality(*CASE_4))
129
130 def test_material_implication(self):
131 material_implication = (
132 src.truth_table.material_implication
133 )
134 self.assertTrue(material_implication(*CASE_1))
135 self.assertFalse(material_implication(*CASE_2))
136 self.assertTrue(material_implication(*CASE_3))
137 self.assertTrue(material_implication(*CASE_4))
138
139
140# Exceptions seen
141# AttributeError
142# TypeError
143# AssertionError
144# SyntaxError
open the project
Make sure you are in the
pumping_pythonfolder with pwd in the terminalpwdif the terminal does not show
.../pumping_pythonchange directory to the
pumping_pythonfolderOnce in
pumping_python, change directory to the projectcd truth_tablethe terminal shows
.../pumping_python/truth_tableI run the tests with pytest-watcher
uv run pytest-watcher . --nowthe terminal is my friend, and shows
rootdir: .../pumping_python/truth_table configfile: pyproject.toml collected 16 items tests/test_binary.py ............ [ 75%] tests/test_nullary_unary.py .... [100%] ================== 16 passed in G.HIs ===================I hold ctrl (Windows) or option (MacOS) on the keyboard, then click on
tests/test_binary.pywith the mouse to open itOver the past 3 chapters I tested
contradiction which always returns False
logical_conjunction aka and which returns
first_input and second_inputproject_second which always returns
second_inputconverse_non_implication which returns
not first_input and second_inputnegate_first which always returns
not first_inputlogical_nand which returns
not (first_input and second_input)tautology which always returns True
logical_disjunction which returns
first_input or second_inputexclusive_disjunction which returns
((not first_input and second_input) or (first_input and not second_input))material_non_implication which returns
first_input and not second_inputproject_first which always returns
first_inputconverse_implication which returns
first_input or not second_input
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 if the first input is True and the second input is True, to test_binary.py
first input |
second input |
return |
|---|---|---|
True |
True |
False |
99 self.assertTrue(converse_implication(False, False))
100
101 def test_negate_second(self):
102 negate_second = src.truth_table.negate_second
103 self.assertFalse(negate_second(True, True))
104
105
106# 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 open
truth_table/__init__.pyfrom thesrcfolderI add a function definition for negate_second to
truth_table.py92def converse_implication(first_input, second_input): 93 return logical_disjunction( 94 first_input, 95 logical_negation(second_input) 96 ) 97 return first_input or not second_input 98 99 100def negate_second(first_input, second_input): 101 return Falsethe test passes. negate_second returns False, if the first input is True and the second input is True.
negate_second(True , True ) -> False
REFACTOR: make it better
I add an assertion for the next case, which is if the first input is True and the second input is False, to test_negate_second in
test_binary.pyfirst input
second input
return
True
False
True
101 def test_negate_second(self): 102 negate_second = src.truth_table.negate_second 103 self.assertFalse(negate_second(True, True)) 104 self.assertTrue(negate_second(True, False)) 105 106 107# Exceptions seenthe terminal is my friend, and shows AssertionError
AssertionError: False is not truebecause the negate_second function returns False and the assertion expects True.
I add an if statement to negate_second in
truth_table.py100def negate_second(first_input, second_input): 101 if second_input == False: 102 return True 103 return Falsethe test passes because when negate_second is called, Python checks
if second_input == False:if
second_inputis NOT equal to False, it runsreturn Falsenegate_second(True , True ) -> False └── def negate_second(first_input, second_input): ├── first_input == True ├── second_input == True ├── if second_input == False: │ return True └── return Falseif
second_inputis equal to False, it runsreturn Truenegate_second(True , False) -> True └── def negate_second(first_input, second_input): ├── first_input == True ├── second_input == False └── if second_input == False: └── return True return False
negate_second(True , False) -> True negate_second(True , True ) -> FalseI add an assertion for the third case, which is if the first input is False and the second input is True, to test_negate_second in
test_binary.pyfirst input
second input
return
False
True
False
101 def test_negate_second(self): 102 negate_second = src.truth_table.negate_second 103 self.assertFalse(negate_second(True, True)) 104 self.assertTrue(negate_second(True, False)) 105 self.assertFalse(negate_second(False, True)) 106 107 108# Exceptions seenthe test is still green. negate_second returns the logical negation of the second input in all 3 cases.
negate_second(False, True ) -> False negate_second(True , False) -> True negate_second(True , True ) -> FalseI add an assertion for the last case, which is if the first input is False and the second input is False
first input
second input
return
False
False
True
101 def test_negate_second(self): 102 negate_second = src.truth_table.negate_second 103 self.assertFalse(negate_second(True, True)) 104 self.assertTrue(negate_second(True, False)) 105 self.assertFalse(negate_second(False, True)) 106 self.assertTrue(negate_second(False, False)) 107 108 109# Exceptions seenthe test is still green.
negate_second(False, False) -> True negate_second(False, True ) -> False negate_second(True , False) -> True negate_second(True , True ) -> FalseI add the bool built-in function to the negate_second function in
truth_table.py100def negate_second(first_input, second_input): 101 # if second_input == False: 102 if bool(second_input) == False: 103 return True 104 return Falsestill green.
I use Logical Negation (NOT) to write the statement in terms of True
100def negate_second(first_input, second_input): 101 # if second_input == False: 102 # if bool(second_input) == False: 103 if not bool(second_input) == True: 104 return True 105 return Falsegreen.
I remove
== True100def negate_second(first_input, second_input): 101 # if second_input == False: 102 # if bool(second_input) == False: 103 # if not bool(second_input) == True: 104 if not bool(second_input): 105 return True 106 return Falsestill green.
I remove bool
100def negate_second(first_input, second_input): 101 # if second_input == False: 102 # if bool(second_input) == False: 103 # if not bool(second_input) == True: 104 # if not bool(second_input): 105 if not second_input: 106 return True 107 return Falsethe test is still green, because Python checks if
second_inputis equal to False whenif second_input == False:runs. I assume the following substitutionsif the value of
somethingis Falsesomething = False if something == False if bool(something) == False if bool(False ) == False # use the value if False == False # bool(False) returns False if True == True # write in terms of True if True # remove '== True' if not False # not False == True if not something # use the name for the valueif the value of
somethingis Truesomething = True if something == False if bool(something) == False if bool(True ) == False # use the value if True == False # bool(True) returns True if False == True # write in terms of True if not True == True # write in terms of True if not True # remove '== True' if not something # use the name for the value
if bool(something) == Falseis the same asif not bool(something) == Trueis the same asif not bool(something)is the same asif not something.I add a conditional expression
100def negate_second(first_input, second_input): 101 # if second_input == False: 102 # if bool(second_input) == False: 103 # if not bool(second_input) == True: 104 # if not bool(second_input): 105 # if not second_input: 106 # return True 107 # return False 108 return True if not second_input else Falsestill green.
if not second_input vs return True return True vs if not second_input return False vs else FalseI remove
True ifandelse Falseto make the statement simpler100def negate_second(first_input, second_input): 101 # if second_input == False: 102 # if bool(second_input) == False: 103 # if not bool(second_input) == True: 104 # if not bool(second_input): 105 # if not second_input: 106 # return True 107 # return False 108 # return True if not second_input else False 109 return not second_inputI remove the comments
100def negate_second(first_input, second_input): 101 return not second_inputI add a git commit message in the other terminal
git commit -am 'add negate_second'
Negate Second always returns
not second_inputthe Logical Negation of the second input
It is the Logical Negation (NOT) of Project Second which always returns the second input. It always negates 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 if the first input is True and the second input is True, to
test_binary.pyfirst input
second input
return
True
True
False
104 self.assertTrue(negate_second(False, False)) 105 106 def test_logical_nor(self): 107 logical_nor = src.truth_table.logical_nor 108 self.assertFalse(logical_nor(True, True)) 109 110 111# Exceptions seenthe terminal is my friend, and shows AttributeError
AttributeError: module 'src.truth_table' has no attribute 'logical_nor'. Did you mean: 'logical_nand'?truth_table.pydoes not have any definition for logical_nor.
GREEN: make it pass
I add logical_nor to truth_table.py
100def negate_second(first_input, second_input):
101 return not second_input
102
103
104def logical_nor(first_input, second_input):
105 return False
the test passes. logical_nor returns False, if the first input is True and the second input is True.
logical_nor(True , True ) -> False
REFACTOR: make it better
I add an assertion for the second case, which is if the first input is True and the second input is False, to test_logical_nor in
test_binary.pyfirst input
second input
return
True
False
False
100 def test_logical_nor(self): 101 logical_nor = src.truth_table.logical_nor 102 self.assertFalse(logical_nor(True, True)) 103 self.assertFalse(logical_nor(True, False)) 104 105 106# Exceptions seenthe 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
logical_nor(True , False) -> False logical_nor(True , True ) -> FalseI add an assertion for the next case, which is if the first input is False and the second input is True
first input
second input
return
False
True
False
100 def test_logical_nor(self): 101 logical_nor = src.truth_table.logical_nor 102 self.assertFalse(logical_nor(True, True)) 103 self.assertFalse(logical_nor(True, False)) 104 self.assertFalse(logical_nor(False, True)) 105 106 107# Exceptions seenthe 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
logical_nor(False, True ) -> False logical_nor(True , False) -> False logical_nor(True , True ) -> FalseI add an assertion for the last case, which is if the first input is False and the second input is False
first input
second input
return
False
False
True
100 def test_logical_nor(self): 101 logical_nor = src.truth_table.logical_nor 102 self.assertFalse(logical_nor(True, True)) 103 self.assertFalse(logical_nor(True, False)) 104 self.assertFalse(logical_nor(False, True)) 105 self.assertTrue(logical_nor(False, False)) 106 107 108# Exceptions seenthe terminal is my friend, and shows AssertionError
AssertionError: False is not truebecause the logical_nor function returns False and the assertion expects True.
I add if statements for this case to logical_nor in
truth_table.py104def logical_nor(first_input, second_input): 105 if first_input == False: 106 if second_input == False: 107 return True 108 return Falsethe test passes.
logical_nor(False, False) -> True logical_nor(False, True ) -> False logical_nor(True , False) -> False logical_nor(True , True ) -> Falsebecause Python checks if
first_inputis equal to False when the logical_nor function is called. Whenif first_input == False:runs,if
first_inputis NOT equal to False, it leaves the if statement to run the rest of the function -return Falselogical_nor(True , True ) -> False └── def logical_nor(first_input, second_input): ├── first_input == True ├── second_input == True ├── if first_input == False: │ if second_input == False: │ return True └── return Falselogical_nor(True , False) -> False └── def logical_nor(first_input, second_input): ├── first_input == True ├── second_input == False ├── if first_input == False: │ if second_input == False: │ return True └── return Falseif
first_inputis equal to False, it checks ifsecond_inputis equal to Falseif
second_inputis NOT equal to False, it leaves theif first_input == False:then runsreturn Falselogical_nor(False, True ) -> False └── def logical_nor(first_input, second_input): ├── first_input == False ├── second_input == True ├── if first_input == False: │ if second_input == False: │ return True └── return Falseif
second_inputis equal to False, it runsreturn Truelogical_nor(False, False) -> True └── def logical_nor(first_input, second_input): ├── first_input == False ├── second_input == False └── if first_input == False: └── if second_input == False: └── return True return False
it only checks
second_inputiffirst_inputis equal to False.
I add the bool built-in function
104def logical_nor(first_input, second_input): 105 # if first_input == False: 106 if bool(first_input) == False: 107 # if second_input == False: 108 if bool(second_input) == False: 109 return True 110 return Falsethe test is still green.
I use Logical Negation (NOT) to write the if statements in terms of True
104def logical_nor(first_input, second_input): 105 # if first_input == False: 106 # if bool(first_input) == False: 107 if not bool(first_input) == True: 108 # if second_input == False: 109 # if bool(second_input) == False: 110 if not bool(second_input) == True: 111 return True 112 return Falsestill green.
I remove
== True104def logical_nor(first_input, second_input): 105 # if first_input == False: 106 # if bool(first_input) == False: 107 # if not bool(first_input) == True: 108 if not bool(first_input): 109 # if second_input == False: 110 # if bool(second_input) == False: 111 # if not bool(second_input) == True: 112 if not bool(second_input): 113 return True 114 return Falsegreen.
I remove bool
104def logical_nor(first_input, second_input): 105 # if first_input == False: 106 # if bool(first_input) == False: 107 # if not bool(first_input) == True: 108 # if not bool(first_input): 109 if not first_input: 110 # if second_input == False: 111 # if bool(second_input) == False: 112 # if not bool(second_input) == True: 113 # if not bool(second_input): 114 if not second_input: 115 return True 116 return Falsestill green, because I can assume the following substitutions for when
if something == False:runsif the value of
somethingis Falsesomething = False if something == False if bool(something) == False if bool(False ) == False # use the value if False == False # bool(False) returns False if True == True # write in terms of True if True # remove '== True' if not False # not False == True if not something # use the name for the valueif the value of
somethingis Truesomething = True if something == False if bool(something) == False if bool(True ) == False # use the value if True == False # bool(True) returns True if False == True # write in terms of True if not True == True # write in terms of True if not True # remove '== True' if not something # use the name for the value
if bool(something) == Falseis the same asif not bool(something) == Trueis the same asif not bool(something)is the same asif not something.I use Logical Conjunction (AND) to put the two if statements together
104def logical_nor(first_input, second_input): 105 # if first_input == False: 106 # if bool(first_input) == False: 107 # if not bool(first_input) == True: 108 # if not bool(first_input): 109 # if not first_input: 110 # if second_input == False: 111 # if bool(second_input) == False: 112 # if not bool(second_input) == True: 113 # if not bool(second_input): 114 # if not second_input: 115 if not first_input and not second_input: 116 return True 117 return Falsestill 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
104def logical_nor(first_input, second_input): 105 # if first_input == False: 106 # if bool(first_input) == False: 107 # if not bool(first_input) == True: 108 # if not bool(first_input): 109 # if not first_input: 110 # if second_input == False: 111 # if bool(second_input) == False: 112 # if not bool(second_input) == True: 113 # if not bool(second_input): 114 # if not second_input: 115 # if not first_input and not second_input: 116 # return True 117 # return False 118 return ( 119 True if 120 not first_input and not second_input 121 else False 122 )the test is still green.
I remove
True ifandelse False104def logical_nor(first_input, second_input): 105 # if first_input == False: 106 # if bool(first_input) == False: 107 # if not bool(first_input) == True: 108 # if not bool(first_input): 109 # if not first_input: 110 # if second_input == False: 111 # if bool(second_input) == False: 112 # if not bool(second_input) == True: 113 # if not bool(second_input): 114 # if not second_input: 115 # if not first_input and not second_input: 116 # return True 117 # return False 118 return ( 119 # True if 120 not first_input and not second_input 121 # else False 122 )still green.
I write the statement in terms of not because it happens 2 times
118 return ( 119 # True if 120 # not first_input and not second_input 121 (not first_input) 122 (not or) 123 (not second_input) 124 # else False 125 )the terminal is my friend, and shows SyntaxError
SyntaxError: invalid syntaxI “factor” out the nots
118 return ( 119 # True if 120 # not first_input and not second_input 121 # (not first_input) 122 # (not or) 123 # (not second_input) 124 not (first_input or second_input) 125 # else False 126 )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 inputlogical_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, True)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, False)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, True)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, False)
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
114 # if not first_input and not second_input: 115 # return True 116 # return False 117 return logical_negation( 118 logical_disjunction( 119 first_input, second_input 120 ) 121 ) 122 return ( 123 # True if 124 # not first_input and not second_input 125 # (not first_input) 126 # (not or) 127 # (not second_input) 128 not (first_input or second_input) 129 # else False 130 )still green.
logical_nor(False, False) -> True └── not logical_disjunction(False, False) -> True logical_nor(False, True ) -> False └── not logical_disjunction(False, True ) -> False logical_nor(True , False) -> False └── not logical_disjunction(True , False) -> False logical_nor(True , True ) -> False └── not logical_disjunction(True , True ) -> FalseI remove the comments
104def logical_nor(first_input, second_input): 105 return logical_negation( 106 logical_disjunction( 107 first_input, second_input 108 ) 109 ) 110 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.
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 if the first input is True and the second input is True to
test_binary.pyfirst input
second input
return
True
True
True
113 self.assertTrue(logical_nor(False, False)) 114 115 def test_logical_equality(self): 116 logical_equality = ( 117 src.truth_table.logical_equality 118 ) 119 self.assertTrue(logical_equality(True, True)) 120 121 122# Exceptions seenthe 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 definition for logical_equality in truth_table.py
104def logical_nor(first_input, second_input):
105 return logical_negation(
106 logical_disjunction(
107 first_input, second_input
108 )
109 )
110 return not (first_input or second_input)
111
112
113def logical_equality(first_input, second_input):
114 return True
the test passes. logical_equality returns True, if the first input is True and the second input is True.
logical_equality(True , True ) -> True
REFACTOR: make it better
I add an assertion for the next case, which is if the first input is True and the second input is False, to test_logical_equality in
test_binary.pyfirst input
second input
return
True
False
False
115 def test_logical_equality(self): 116 logical_equality = ( 117 src.truth_table.logical_equality 118 ) 119 self.assertTrue(logical_equality(True, True)) 120 self.assertFalse(logical_equality(True, False)) 121 122 123# Exceptions seenthe terminal is my friend, and shows AssertionError
AssertionError: True is not falsebecause the logical_equality function returns True and the assertion expects False.
I add an if statement to logical_equality in
truth_table.py113def logical_equality(first_input, second_input): 114 if second_input == False: 115 return False 116 return Truethe test passes because when logical_equality is called, it runs
if second_input == False:if
second_inputis NOT equal to False, it leaves the if statement then runsreturn True.if
second_inputis equal to False, it runsreturn False.
logical_equality(True , False) -> False logical_equality(True , True ) -> TrueI add an assertion for the next case, which is if the first input is False and the second input is True, to test_logical_equality in
test_binary.pyfirst input
second input
return
False
True
False
115 def test_logical_equality(self): 116 logical_equality = ( 117 src.truth_table.logical_equality 118 ) 119 self.assertTrue(logical_equality(True, True)) 120 self.assertFalse(logical_equality(True, False)) 121 self.assertFalse(logical_equality(False, True)) 122 123 124# Exceptions seenthe terminal is my friend, and shows AssertionError
AssertionError: True is not falsebecause when logical_equality is called, Python runs
if second_input == False:if
second_inputis equal to False, it runsreturn Falseif
second_inputis NOT equal to False, it leaves the if statement then runsreturn True.second_inputis 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.py113def logical_equality(first_input, second_input): 114 if first_input == False: 115 return False 116 if second_input == False: 117 return False 118 return Truethe test passes because when logical_equality is called, Python runs
if first_input == False:if
first_inputis NOT equal to False, it runs the next if statement -if second_input == False:if
second_inputis NOT equal to False, it leaves the if statement then runsreturn Truethen leaves the function since the return statement is the last thing to run in a function.if
second_inputis equal to False, it runsreturn Falsethen leaves the function since the return statement is the last thing to run in a function.
if
first_inputis equal to False, it runsreturn Falsethen leaves the function since the return statement is the last thing to run in a function.
logical_equality(False, True ) -> False logical_equality(True , False) -> False logical_equality(True , True ) -> TrueI add an assertion for the last case, which is if the first input is False and the second input is False, to test_logical_equality in
test_binary.pyfirst input
second input
return
False
False
True
115 def test_logical_equality(self): 116 logical_equality = ( 117 src.truth_table.logical_equality 118 ) 119 self.assertTrue(logical_equality(True, True)) 120 self.assertFalse(logical_equality(True, False)) 121 self.assertFalse(logical_equality(False, True)) 122 self.assertTrue(logical_equality(False, False)) 123 124 125# Exceptions seenthe terminal is my friend, and shows AssertionError
AssertionError: False is not truebecause when logical_equality is called, Python runs
if first_input == False:if
first_inputis equal to False, it runsreturn False.if
first_inputis NOT equal to False, it runs the next if statement -if second_input == False:.if
second_inputis NOT equal to False, it leaves the if statement then runsreturn True.if
second_inputis equal to False, it runsreturn False.second_inputis 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.py113def logical_equality(first_input, second_input): 114 if first_input == False: 115 if second_input == False: 116 return True 117 return False 118 if second_input == False: 119 return False 120 return Truethe test passes.
logical_equality(False, False) -> True logical_equality(False, True ) -> False logical_equality(True , False) -> False logical_equality(True , True ) -> TruePython checks
if first_input == False:when logical_equality is calledif
first_inputis NOT equal to False, it runs the next if statement -if second_input == False:if
second_inputis NOT equal to False, it leaves the if statement then runsreturn Truelogical_equality(True , True ) -> True └── def logical_equality(first_input, second_input): ├── first_input == True ├── second_input == True ├── if first_input == False: │ if second_input == False: │ return True │ return False ├── if second_input == False: │ return False └── return Trueif
second_inputis equal to False, it runsreturn Falselogical_equality(True , False) -> False └── def logical_equality(first_input, second_input): ├── first_input == True ├── second_input == False ├── if first_input == False: │ if second_input == False: │ return True │ return False └── if second_input == False: └── return False return True
if
first_inputis equal to False, it runsif second_input == False:if
second_inputis NOT equal to False, it leaves the if statement then runs the next line -return Falselogical_equality(False, True ) -> False └── def logical_equality(first_input, second_input): ├── first_input == False ├── second_input == True └── if first_input == False: ├── if second_input == False: │ return True └── return False if second_input == False: return False return Trueif
second_inputis equal to False, it runsreturn Truelogical_equality(False, False) -> True └── def logical_equality(first_input, second_input): ├── first_input == False ├── second_input == False └── if first_input == False: └── if second_input == False: └── return True return False if second_input == False: return False return True
I add the bool built-in function
113def logical_equality(first_input, second_input): 114 # if first_input == False: 115 if bool(first_input) == False: 116 # if second_input == False: 117 if bool(second_input) == False: 118 return True 119 return False 120 # if second_input == False: 121 if bool(second_input) == False: 122 return False 123 return Truethe test is still green.
I use Logical Negation (NOT) to write the statements in terms of True
113def logical_equality(first_input, second_input): 114 # if first_input == False: 115 # if bool(first_input) == False: 116 if not bool(first_input) == True: 117 # if second_input == False: 118 # if bool(second_input) == False: 119 if not bool(second_input) == True: 120 return True 121 return False 122 # if second_input == False: 123 # if bool(second_input) == False: 124 if not bool(second_input) == True: 125 return False 126 returnstill green.
I remove
== True113def logical_equality(first_input, second_input): 114 # if first_input == False: 115 # if bool(first_input) == False: 116 # if not bool(first_input) == True: 117 if not bool(first_input): 118 # if second_input == False: 119 # if bool(second_input) == False: 120 # if not bool(second_input) == True: 121 if not bool(second_input): 122 return True 123 return False 124 # if second_input == False: 125 # if bool(second_input) == False: 126 # if not bool(second_input) == True: 127 if not bool(second_input): 128 return False 129 return Truegreen.
I remove bool
113def logical_equality(first_input, second_input): 114 # if first_input == False: 115 # if bool(first_input) == False: 116 # if not bool(first_input) == True: 117 # if not bool(first_input): 118 if not first_input: 119 # if second_input == False: 120 # if bool(second_input) == False: 121 # if not bool(second_input) == True: 122 # if not bool(second_input): 123 if not second_input: 124 return True 125 return False 126 # if second_input == False: 127 # if bool(second_input) == False: 128 # if not bool(second_input) == True: 129 # if not bool(second_input): 130 if not second_input: 131 return False 132 return Truestill green because I can assume the following substitutions for when
if something == False:runsif the value of
somethingis Falsesomething = False if something == False if bool(something) == False if bool(False ) == False # use the value if False == False # bool(False) returns False if True == True # write in terms of True if True # remove '== True' if not False # not False == True if not something # use the name for the valueif the value of
somethingis Truesomething = True if something == False if bool(something) == False if bool(True ) == False # use the value if True == False # bool(True) returns True if False == True # write in terms of True if not True == True # write in terms of True if not True # remove '== True' if not something # use the name for the value
if bool(something) == Falseis the same asif not bool(something) == Trueis the same asif not bool(something)is the same asif not something.I use Logical Conjunction (AND) to make two of the cases clearer
113def logical_equality(first_input, second_input): 114 # if first_input == False: 115 # if bool(first_input) == False: 116 # if not bool(first_input) == True: 117 # if not bool(first_input): 118 # if not first_input: 119 # if second_input == False: 120 # if bool(second_input) == False: 121 # if not bool(second_input) == True: 122 # if not bool(second_input): 123 # if not second_input: 124 if not first_input and not second_input: 125 return True 126 if not first_input and second_input: 127 return False 128 # if second_input == False: 129 # if bool(second_input) == False: 130 # if not bool(second_input) == True: 131 # if not bool(second_input): 132 if not second_input: 133 return False 134 return Truethe 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
124 if not first_input and not second_input: 125 return True 126 if not first_input and second_input: 127 return False 128 # if second_input == False: 129 # if bool(second_input) == False: 130 # if not bool(second_input) == True: 131 # if not bool(second_input): 132 # if not second_input: 133 if first_input and not second_input: 134 return False 135 if first_input and second_input: 136 return Truestill green.
I put the if statements that return the same thing together
113def logical_equality(first_input, second_input): 114 # if first_input == False: 115 # if bool(first_input) == False: 116 # if not bool(first_input) == True: 117 # if not bool(first_input): 118 # if not first_input: 119 # if second_input == False: 120 # if bool(second_input) == False: 121 # if not bool(second_input) == True: 122 # if not bool(second_input): 123 # if not second_input: 124 # if second_input == False: 125 # if bool(second_input) == False: 126 # if not bool(second_input) == True: 127 # if not bool(second_input): 128 # if not second_input: 129 if not first_input and second_input: 130 return False 131 if first_input and not second_input: 132 return False 133 if first_input and second_input: 134 return True 135 if not first_input and not second_input: 136 return TrueI use Logical Disjunction (OR) to put the two if statements that return True together
129 # if not first_input and second_input: 130 # return False 131 # if first_input and not second_input: 132 # return False 133 # if first_input and second_input: 134 # return True 135 # if not first_input and not second_input: 136 # return True 137 if ( 138 (first_input and second_input) 139 or 140 (not first_input and not second_input) 141 ): 142 return True 143 else: 144 return Falsegreen, because I can put two if statements together if they both return the same thing and are at the same indentation level
if something: return this if something_else: return thiscan also be written as
if something or something_else: return thisI add a conditional expression
137 # if ( 138 # (first_input and second_input) 139 # or 140 # (not first_input and not second_input) 141 # ): 142 # return True 143 # else: 144 # return False 145 return True if ( 146 (first_input and second_input) 147 or 148 (not first_input and not second_input) 149 ) else Falsestill green.
I remove
True ifandelse False145 # return True if ( 146 return ( 147 (first_input and second_input) 148 or 149 (not first_input and not second_input) 150 # ) else False 151 )the test is still green.
I write the second part of the statement in terms of not because it happens twice
145 # return True if ( 146 return ( 147 (first_input and second_input) 148 or 149 # (not first_input and not second_input) 150 ( 151 (not first_input) 152 (not or) 153 (not second_input) 154 ) 155 # ) else False 156 )the terminal is my friend, and shows SyntaxError
SyntaxError: invalid syntaxI “factor” out the nots
100 # return True if ( 101 return ( 102 (first_input and second_input) 103 or 104 # (not first_input and not second_input) 105 # ( 106 # (not first_input) 107 # (not or) 108 # (not second_input) 109 # ) 110 not (first_input or second_input) 111 # ) else False 112 )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 inputreturn logical_disjunction( logical_conjunction(first_input, second_input), logical_nor(first_input, second_input) )because
logical_disjunction returns
first_input or second_inputlogical_conjunction returns
first_input and second_inputlogical_nor returns
not (first_input or second_input)
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
145 # return True if ( 146 return logical_disjunction( 147 logical_conjunction(first_input, second_input), 148 logical_nor(first_input, second_input) 149 ) 150 return ( 151 (first_input and second_input) 152 or 153 # (not first_input and not second_input) 154 # ( 155 # (not first_input) 156 # (not or) 157 # (not second_input) 158 # ) 159 not (first_input or second_input) 160 # ) else False 161 )still green.
logical_equality returns True, if the first input and second input are equal, which means I can write a much simpler return statement thanks to the equality (
==) symbol (2 equal signs together =+= on the keyboard)145 # return True if ( 146 return first_input == second_input 147 return logical_disjunction( 148 logical_conjunction(first_input, second_input), 149 logical_nor(first_input, second_input) 150 ) 151 return ( 152 (first_input and second_input) 153 or 154 # (not first_input and not second_input) 155 # ( 156 # (not first_input) 157 # (not or) 158 # (not second_input) 159 # ) 160 not (first_input or second_input) 161 # ) else False 162 )the test is still green.
I remove the commented lines
113def logical_equality(first_input, second_input): 114 return first_input == second_input 115 return logical_disjunction( 116 logical_conjunction(first_input, second_input), 117 logical_nor(first_input, second_input) 118 ) 119 return ( 120 (first_input and second_input) 121 or 122 not (first_input or second_input) 123 )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'
returns
first_input == second_input.returns True when the first input is equal to the second input.
returns 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. Oh brother!
is the opposite of Exclusive Disjunction which returns True, only if the first input and second input are NOT equal.
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 if the first input is True and the second input is True, to
test_binary.pyfirst input
second input
return
True
True
True
122 self.assertTrue(logical_equality(False, False)) 123 124 def test_material_implication(self): 125 material_implication = ( 126 src.truth_table.material_implication 127 ) 128 self.assertTrue(material_implication(True, True)) 129 130 131# Exceptions seenthe terminal is my friend, and shows AttributeError
AttributeError: module 'src.truth_table' has no attribute 'material_implication'. Did you mean: 'material_non_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
122 return (
123 (first_input and second_input)
124 or
125 not (first_input or second_input)
126 )
127
128
129def material_implication(first_input, second_input):
130 return True
the test passes. material_implication returns True, if the first input is True and the second input is True.
material_implication(True , True ) -> True
REFACTOR: make it better
I add an assertion to test_material_implication for the next case, which is if the first input is True and the second input is False, in
test_binary.pyfirst input
second input
return
True
False
False
124 def test_material_implication(self): 125 material_implication = ( 126 src.truth_table.material_implication 127 ) 128 self.assertTrue(material_implication(True, True)) 129 self.assertFalse(material_implication(True, False)) 130 131 132# Exceptions seenthe terminal is my friend, and shows AssertionError
AssertionError: True is not falsebecause the function returns True and the assertion expects False.
I add an if statement to material_implication in
truth_table.py126def material_implication(first_input, second_input): 127 if second_input == False: 128 return False 129 return Truethe test passes because when material_implication is called, it runs
if second_input == False:if
second_inputis NOT equal to False, it runsreturn Trueif
second_inputis equal to False, it runsreturn False
material_implication(True , False) -> False material_implication(True , True ) -> TrueI add an assertion to test_material_implication for the next case, which is if the first input is False and the second input is True in
test_binary.pyfirst input
second input
return
False
True
True
124 def test_material_implication(self): 125 material_implication = ( 126 src.truth_table.material_implication 127 ) 128 self.assertTrue(material_implication(True, True)) 129 self.assertFalse(material_implication(True, False)) 130 self.assertTrue(material_implication(False, True)) 131 132 133# Exceptions seenthe 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.
material_implication(False, True ) -> True material_implication(True , False) -> False material_implication(True , True ) -> TrueI add an assertion for the fourth case, which is if the first input is False and the second input is False
first input
second input
return
False
False
True
124 def test_material_implication(self): 125 material_implication = ( 126 src.truth_table.material_implication 127 ) 128 self.assertTrue(material_implication(True, True)) 129 self.assertFalse(material_implication(True, False)) 130 self.assertTrue(material_implication(False, True)) 131 self.assertTrue(material_implication(False, False)) 132 133 134# Exceptions seenthe terminal is my friend, and shows AssertionError
AssertionError: False is not truebecause when material_implication gets called, it runs
if second_input == False:if
second_inputis NOT equal to False, it runsreturn True.if
second_inputis equal to False, it runsreturn False.second_inputis 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.py126def material_implication(first_input, second_input): 127 if first_input == True: 128 if second_input == False: 129 return False 130 return Truethe test passes.
material_implication(False, False) -> True material_implication(False, True ) -> True material_implication(True , False) -> False material_implication(True , True ) -> TruePython checks
if first_input == True:when material_implication is calledif
first_inputis NOT equal to True, it leaves the if statement to run the rest of the function -return Truematerial_implication(False, False) -> True └── def material_implication(first_input, second_input): ├── first_input == False ├── second_input == False ├── if first_input == True: │ if second_input == False: │ return False └── return Truematerial_implication(False, True ) -> True └── def material_implication(first_input, second_input): ├── first_input == False ├── second_input == True ├── if first_input == True: │ if second_input == False: │ return False └── return Trueif
first_inputis equal to True, it checks ifsecond_inputis equal to Falseif
second_inputis NOT equal to False, it leavesif first_input == True:to run the rest of the function -return Truematerial_implication(True , True ) -> True └── def material_implication(first_input, second_input): ├── first_input == True ├── second_input == True └── if first_input == True: ┌───┴── if second_input == False: │ return False └── return Trueif
second_inputis equal to False it runsreturn Falsematerial_implication(True , False) -> False └── def material_implication(first_input, second_input): ├── first_input == True ├── second_input == False └── if first_input == True: └── if second_input == False: └── return False return True
it only checks the second input if the first input is True.
I use the bool built-in function
126def material_implication(first_input, second_input): 127 # if first_input == True: 128 if bool(first_input) == True: 129 # if second_input == False: 130 if bool(second_input) == False: 131 return False 132 return Truethe test is still green.
I use Logical Negation (NOT) to write the second if statement in terms of True
126def material_implication(first_input, second_input): 127 # if first_input == True: 128 if bool(first_input) == True: 129 # if second_input == False: 130 # if bool(second_input) == False: 131 if not bool(second_input) == True: 132 return False 133 return Truestill green.
I remove
== True126def material_implication(first_input, second_input): 127 # if first_input == True: 128 # if bool(first_input) == True: 129 if bool(first_input): 130 # if second_input == False: 131 # if bool(second_input) == False: 132 # if not bool(second_input) == True: 133 if not bool(second_input): 134 return False 135 return Truegreen.
I remove bool
126def material_implication(first_input, second_input): 127 # if first_input == True: 128 # if bool(first_input) == True: 129 # if bool(first_input): 130 if first_input: 131 # if second_input == False: 132 # if bool(second_input) == False: 133 # if not bool(second_input) == True: 134 # if not bool(second_input): 135 if not second_input: 136 return False 137 return Truestill green, because
when
if something == False:runs, Python checks ifsomethingis equal to False. I can assume the following substitutionsif the value of
somethingis Falsesomething = False if something == False if bool(something) == False if bool(False ) == False # use the value if False == False # bool(False) returns False if True == True # write in terms of True if True # remove '== True' if not False # not False == True if not something # use the name for the valueif the value of
somethingis Truesomething = True if something == False if bool(something) == False if bool(True ) == False # use the value if True == False # bool(True) returns True if False == True # write in terms of True if not True == True # write in terms of True if not True # remove '== True' if not something # use the name for the value
when
if something == True:runs, Python checks if(something)is equal to True. I can assume the following substitutionsif the value of
somethingis Falsesomething = False if something == True if bool(something) == True if bool(False ) == True # use the value if False == True # bool(False) returns False if not True == True # write in terms of True if not True # remove '== True' if False # not True == False if something # use the name for the valueif the value of
somethingis Truesomething = True if something == True if bool(something) == True if bool(True ) == True # use the value if True == True # bool(True) returns True if True # remove '== True' if something # use the name for the value
if bool(something) == Falseis the same asif not bool(something) == Trueis the same asif not bool(something)is the same asif not something.if bool(something) == Trueis the same asif bool(something)is the same asif something.
I use Logical Conjunction (AND) to put the two if statements together
126def material_implication(first_input, second_input): 127 # if first_input == True: 128 # if bool(first_input) == True: 129 # if bool(first_input): 130 # if first_input: 131 # if second_input == False: 132 # if bool(second_input) == False: 133 # if not bool(second_input) == True: 134 # if not bool(second_input): 135 # if not second_input: 136 if first_input and not second_input: 137 return False 138 return Truethe 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
136 if first_input and not second_input: 137 return False 138 else: 139 return Truestill green.
I change the else clause to the Logical Negation (NOT) of the if statement
136 if first_input and not second_input: 137 return False 138 # else: 139 if not (first_input and not second_input): 140 return Truegreen.
I add a conditional expression
136 # if first_input and not second_input: 137 # return False 138 # else: 139 # if not (first_input and not second_input): 140 # return 141 return ( 142 True if 143 not (first_input and not second_input) 144 else False 145 )still green.
I remove
True ifandelse Falseto make it simpler136 # if first_input and not second_input: 137 # return False 138 # else: 139 # if not (first_input and not second_input): 140 # return 141 return ( 142 # True if 143 not (first_input and not second_input) 144 # else False 145 )the test is still green.
I “multiply” not by the symbols in parentheses
136 # if first_input and not second_input: 137 # return False 138 # else: 139 # if not (first_input and not second_input): 140 # return 141 return ( 142 # True if 143 # not (first_input and not second_input) 144 (not first_input) 145 (not and) 146 (not not second_input) 147 # else False 148 )the terminal is my friend, and shows SyntaxError
SyntaxError: invalid syntaxI change
not andto or136 # if first_input and not second_input: 137 # return False 138 # else: 139 # if not (first_input and not second_input): 140 # return 141 return ( 142 # True if 143 # not (first_input and not second_input) 144 (not first_input) 145 # (not and) 146 or 147 (not not second_input) 148 # else False 149 )the test is green again.
I remove
not notbecause they cancel out136 # if first_input and not second_input: 137 # return False 138 # else: 139 # if not (first_input and not second_input): 140 # return 141 return ( 142 # True if 143 # not (first_input and not second_input) 144 (not first_input) 145 # (not and) 146 or 147 # (not not second_input) 148 second_input 149 # else False 150 )the test is still green, because two nots make a “right”?
material_implication returns
not first_input or second_inputnot first_inputis the Logical Negation (NOT) offirst_inputif 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_inputis the Logical Disjunction (OR) of the Logical Negation (NOT) of the first input, and the second inputlogical_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
136 # if first_input and not second_input: 137 # return False 138 # else: 139 # if not (first_input and not second_input): 140 # return 141 return logical_disjunction( 142 logical_negation(first_input), 143 second_input 144 ) 145 return ( 146 # True if 147 # not (first_input and not second_input) 148 (not first_input) 149 # (not and) 150 or 151 # (not not second_input) 152 second_input 153 # else False 154 )still green.
material_implication(False, False) -> True └── logical_disjunction(True , False) -> True material_implication(False, True ) -> True └── logical_disjunction(True , True ) -> True material_implication(True , False) -> False └── logical_disjunction(False, False) -> False material_implication(True , True ) -> True └── logical_disjunction(False, True ) -> TrueI remove the comments
126def material_implication(first_input, second_input): 127 return logical_disjunction( 128 logical_negation(first_input), 129 second_input 130 ) 131 return not first_input or second_inputI 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 the other terminal
git commit -am 'add material_implication'
Material Implication also known as Logical Implication returns
not first_input or second_input.the Logical Disjunction of the Logical Negation of the first input, and the second input.
False only if the first input is True and the second input is False.
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
extract global variables
I go back to the terminal where the tests are running.
I add variables for the four test cases that are repeated in every test, in
test_binary.py1import src.truth_table 2import unittest 3 4 5CASE_1 = True, True 6CASE_2 = True, False 7CASE_3 = False, True 8CASE_4 = False, False 9 10 11class TestBinaryOperations(unittest.TestCase): 12 13 def test_contradiction(self):I use the variables with a single starred expression to remove repetition of
True, True,True, False,False, TrueandFalse, Falsefrom test_contradiction13 def test_contradiction(self): 14 contradiction = src.truth_table.contradiction 15 # self.assertFalse(contradiction(True, True)) 16 self.assertFalse(contradiction(*CASE_1)) 17 # self.assertFalse(contradiction(True, True)) 18 self.assertFalse(contradiction(*CASE_2)) 19 # self.assertFalse(contradiction(False, True)) 20 self.assertFalse(contradiction(*CASE_3)) 21 # self.assertFalse(contradiction(False, False)) 22 self.assertFalse(contradiction(*CASE_4)) 23 24 def test_logical_conjunction(self):the test is still green.
I remove the commented lines from test_logical_conjunction
13 def test_contradiction(self): 14 contradiction = src.truth_table.contradiction 15 self.assertFalse(contradiction(*CASE_1)) 16 self.assertFalse(contradiction(*CASE_2)) 17 self.assertFalse(contradiction(*CASE_3)) 18 self.assertFalse(contradiction(*CASE_4)) 19 20 def test_logical_conjunction(self):I use the variables with a single starred expression to remove repetition of
True, True,True, False,False, TrueandFalse, Falsefrom test_logical_conjunction20 def test_logical_conjunction(self): 21 logical_conjunction = ( 22 src.truth_table.logical_conjunction 23 ) 24 self.assertTrue(logical_conjunction(*CASE_1)) 25 self.assertFalse(logical_conjunction(*CASE_2)) 26 self.assertFalse(logical_conjunction(*CASE_3)) 27 self.assertFalse(logical_conjunction(*CASE_4)) 28 29 def test_project_second(self):still green.
I use the variables with a single starred expression to remove repetition of
True, True,True, False,False, TrueandFalse, Falsefrom test_project_second29 def test_project_second(self): 30 project_second = src.truth_table.project_second 31 self.assertTrue(project_second(*CASE_1)) 32 self.assertFalse(project_second(*CASE_2)) 33 self.assertTrue(project_second(*CASE_3)) 34 self.assertFalse(project_second(*CASE_4)) 35 36 def test_converse_non_implication(self):green.
I use the variables with a single starred expression to remove repetition of
True, True,True, False,False, TrueandFalse, Falsefrom test_converse_non_implication36 def test_converse_non_implication(self): 37 converse_non_implication = ( 38 src.truth_table.converse_non_implication 39 ) 40 self.assertFalse(converse_non_implication(*CASE_1)) 41 self.assertFalse(converse_non_implication(*CASE_2)) 42 self.assertTrue(converse_non_implication(*CASE_3)) 43 self.assertFalse(converse_non_implication(*CASE_4)) 44 45 def test_negate_first(self):still green.
I use the variables with a single starred expression to remove repetition of
True, True,True, False,False, TrueandFalse, Falsefrom test_negate_first45 def test_negate_first(self): 46 negate_first = src.truth_table.negate_first 47 self.assertFalse(negate_first(*CASE_1)) 48 self.assertFalse(negate_first(*CASE_2)) 49 self.assertTrue(negate_first(*CASE_3)) 50 self.assertTrue(negate_first(*CASE_4)) 51 52 def test_logical_nand(self):the test is still green.
I use the variables with a single starred expression to remove repetition of
True, True,True, False,False, TrueandFalse, Falsefrom test_logical_nand52 def test_logical_nand(self): 53 nand = src.truth_table.logical_nand 54 self.assertFalse(nand(*CASE_1)) 55 self.assertTrue(nand(*CASE_2)) 56 self.assertTrue(nand(*CASE_3)) 57 self.assertTrue(nand(*CASE_4)) 58 59 def test_tautology(self):still green.
I use the variables with a single starred expression to remove repetition of
True, True,True, False,False, TrueandFalse, Falsefrom test_tautology59 def test_tautology(self): 60 tautology = src.truth_table.tautology 61 self.assertTrue(tautology(*CASE_1)) 62 self.assertTrue(tautology(*CASE_2)) 63 self.assertTrue(tautology(*CASE_3)) 64 self.assertTrue(tautology(*CASE_4)) 65 66 def test_logical_disjunction(self):green.
I use the variables with a single starred expression to remove repetition of
True, True,True, False,False, TrueandFalse, Falsefrom test_logical_disjunction66 def test_logical_disjunction(self): 67 logical_disjunction = ( 68 src.truth_table.logical_disjunction 69 ) 70 self.assertTrue(logical_disjunction(*CASE_1)) 71 self.assertTrue(logical_disjunction(*CASE_2)) 72 self.assertTrue(logical_disjunction(*CASE_3)) 73 self.assertFalse(logical_disjunction(*CASE_4)) 74 75 def test_exclusive_disjunction(self):still green.
I use the variables with a single starred expression to remove repetition of
True, True,True, False,False, TrueandFalse, Falsefrom test_exclusive_disjunction75 def test_exclusive_disjunction(self): 76 xor = src.truth_table.exclusive_disjunction 77 self.assertFalse(xor(*CASE_1)) 78 self.assertTrue(xor(*CASE_2)) 79 self.assertTrue(xor(*CASE_3)) 80 self.assertFalse(xor(*CASE_4)) 81 82 def test_material_non_implication(self):the test is still green.
I use the variables with a single starred expression to remove repetition of
True, True,True, False,False, TrueandFalse, Falsefrom test_material_non_implication82 def test_material_non_implication(self): 83 material_non_implication = ( 84 src.truth_table.material_non_implication 85 ) 86 self.assertFalse(material_non_implication(*CASE_1)) 87 self.assertTrue(material_non_implication(*CASE_2)) 88 self.assertFalse(material_non_implication(*CASE_3)) 89 self.assertFalse(material_non_implication(*CASE_4)) 90 91 def test_project_first(self):still green.
I use the variables with a single starred expression to remove repetition of
True, True,True, False,False, TrueandFalse, Falsefrom test_project_first91 def test_project_first(self): 92 project_first = src.truth_table.project_first 93 self.assertTrue(project_first(*CASE_1)) 94 self.assertTrue(project_first(*CASE_2)) 95 self.assertFalse(project_first(*CASE_3)) 96 self.assertFalse(project_first(*CASE_4)) 97 98 def test_converse_implication(self):green.
I use the variables with a single starred expression to remove repetition of
True, True,True, False,False, TrueandFalse, Falsefrom test_converse_implication98 def test_converse_implication(self): 99 converse_implication = ( 100 src.truth_table.converse_implication 101 ) 102 self.assertTrue(converse_implication(*CASE_1)) 103 self.assertTrue(converse_implication(*CASE_2)) 104 self.assertFalse(converse_implication(*CASE_3)) 105 self.assertTrue(converse_implication(*CASE_4)) 106 107 def test_negate_second(self):still green.
I use the variables with a single starred expression to remove repetition of
True, True,True, False,False, TrueandFalse, Falsefrom test_negate_second107 def test_negate_second(self): 108 negate_second = src.truth_table.negate_second 109 self.assertFalse(negate_second(*CASE_1)) 110 self.assertTrue(negate_second(*CASE_2)) 111 self.assertFalse(negate_second(*CASE_3)) 112 self.assertTrue(negate_second(*CASE_4)) 113 114 def test_logical_nor(self):the test is still green.
I use the variables with a single starred expression to remove repetition of
True, True,True, False,False, TrueandFalse, Falsefrom test_logical_nor114 def test_logical_nor(self): 115 logical_nor = src.truth_table.logical_nor 116 self.assertFalse(logical_nor(*CASE_1)) 117 self.assertFalse(logical_nor(*CASE_2)) 118 self.assertFalse(logical_nor(*CASE_3)) 119 self.assertTrue(logical_nor(*CASE_4)) 120 121 def test_logical_equality(self):still green.
I use the variables with a single starred expression to remove repetition of
True, True,True, False,False, TrueandFalse, Falsefrom test_logical_equality121 def test_logical_equality(self): 122 logical_equality = ( 123 src.truth_table.logical_equality 124 ) 125 self.assertTrue(logical_equality(*CASE_1)) 126 self.assertFalse(logical_equality(*CASE_2)) 127 self.assertFalse(logical_equality(*CASE_3)) 128 self.assertTrue(logical_equality(*CASE_4)) 129 130 def test_material_implication(self):green.
I use the variables with a single starred expression to remove repetition of
True, True,True, False,False, TrueandFalse, Falsefrom test_material_implication130 def test_material_implication(self): 131 material_implication = ( 132 src.truth_table.material_implication 133 ) 134 self.assertTrue(material_implication(*CASE_1)) 135 self.assertFalse(material_implication(*CASE_2)) 136 self.assertTrue(material_implication(*CASE_3)) 137 self.assertTrue(material_implication(*CASE_4)) 138 139 140# Exceptions seen 141# AttributeError 142# TypeError 143# AssertionError 144# SyntaxErrorstill green.
I add a git commit message in the other terminal
git commit -am 'extract variables for cases'
close the project
I close
test_binary.pyandtruth_table.pyI 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_tablecd ..the terminal shows
.../pumping_pythonI am back in the
pumping_pythondirectory.
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
-
returns
not first_input or second_inputreturns False only if
first_inputis True andsecond_inputis Falseis the Logical Negation (NOT) of Material Non-Implication which returns True only if
first_inputis True andsecond_inputis False
first input
second input
return
True
True
True
True
False
False
False
True
True
False
False
True
-
returns
first_input == second_inputreturns True only if
first_inputandsecond_inputare equalis the Logical Negation (NOT) of Exclusive Disjunction (Exclusive OR) which returns True only if
first_inputandsecond_inputare NOT equal
first input
second input
return
True
True
True
True
False
False
False
True
False
False
False
True
-
returns
not (first_input or second_input)returns True only if
first_inputis False andsecond_inputis Falseis the Logical Negation (NOT) of Logical Disjunction which returns False only if
first_inputis False andsecond_inputis False
first input
second input
return
True
True
False
True
False
False
False
True
False
False
False
True
-
always returns
not second_inputreturns True only if
second_inputis Falseis the Logical Negation (NOT) of Project Second which returns True only if
second_inputis True
first input
second input
return
True
True
False
True
False
True
False
True
False
False
False
True
-
returns
first_input or not second_inputreturns False if
first_inputis False andsecond_inputis Trueis the Logical Negation (NOT) of Converse Non-Implication which returns True only if
first_inputis False andsecond_inputis True
first input
second input
return
True
True
True
True
False
True
False
True
False
False
False
True
-
always returns
first_inputreturns True only if
first_inputis Trueis the Logical Negation (NOT) of Negate First which returns True only if
first_inputis False
first input
second input
return
True
True
True
True
False
True
False
True
False
False
False
False
-
returns
first_input and not second_inputreturns True only if
first_inputis True andsecond_inputis Falseis the Logical Negation (NOT) of Material/Logical Implication which returns False only if
first_inputis True andsecond_inputis False
first input
second input
return
True
True
False
True
False
True
False
True
False
False
False
False
-
returns
first_input != second_inputreturns True only if
first_inputandsecond_inputare NOT equalis the Logical Negation (NOT) of Logical Equality which returns True only if
first_inputandsecond_inputare equal
first input
second input
return
True
True
False
True
False
True
False
True
True
False
False
False
-
returns
first_input or second_inputreturns False only if
first_inputis False andsecond_inputis Falseis the Logical Negation (NOT) of Logical NOR which returns True only if
first_inputis False andsecond_inputis False
first input
second input
return
True
True
True
True
False
True
False
True
True
False
False
False
-
always returns True
never returns False
is the Logical Negation (NOT) of contradiction which always returns False
first input
second input
return
True
True
True
True
False
True
False
True
True
False
False
True
-
returns
not (first_input and second_input)returns False only if
first_inputis True andsecond_inputis Trueis the Logical Negation (NOT) of Logical Conjunction (AND) which returns True only if
first_inputis True andsecond_inputis True
first input
second input
return
True
True
False
True
False
True
False
True
True
False
False
True
-
always returns
not first_inputreturns True only if
first_inputis Falseis the Logical Negation (NOT) of Project First which returns True only if
first_inputis True
first input
second input
return
True
True
False
True
False
False
False
True
True
False
False
True
-
returns
not first_input and second_inputreturns True only if
first_inputis False andsecond_inputis Trueis the Logical Negation (NOT) of Converse Implication which returns False if
first_inputis False andsecond_inputis True
first input
second input
return
True
True
False
True
False
False
False
True
True
False
False
False
-
always returns
second_inputreturns True only if
second_inputis Trueis the Logical Negation (NOT) of Negate Second which returns True only if
second_inputis False
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_inputreturns True only if
first_inputis True andsecond_inputis Trueis the Logical Negation (NOT) of Logical NAND which returns False only if
first_inputis True andsecond_inputis True
first input
second input
return
True
True
True
True
False
False
False
True
False
False
False
False
-
always returns False
never returns True
is the Logical Negation (NOT) of Tautology which always returns True
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 |
name of operation |
|---|---|---|---|---|---|
False |
False |
False |
False |
False |
|
first and second |
True |
False |
False |
False |
|
second |
True |
False |
True |
False |
|
(not first) and second |
False |
False |
True |
False |
|
not first |
False |
False |
True |
True |
|
not (first and second) |
False |
True |
True |
True |
|
True |
True |
True |
True |
True |
|
first or second |
True |
True |
True |
False |
|
(not (first and second)) and (first or second) |
False |
True |
True |
False |
|
first and (not second) |
False |
True |
False |
False |
|
first |
True |
True |
False |
False |
|
first or (not second) |
True |
True |
False |
True |
|
not second |
False |
True |
False |
True |
|
not (first or second) |
False |
False |
False |
True |
|
(not first or second) and (first or not second) |
True |
False |
False |
True |
|
(not first) or second |
True |
False |
True |
True |
code from the chapter
Do you want to see all the CODE I typed for the Truth Table?
what is next?
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.