truth table: Binary Operations part 3
requirements
how to get back to the automated tests
If your tests stopped after the previous chapter, heres’s how to get back to the tests
Make sure you are in the
pumping_pythonfolder with pwd in the terminalpwdif the terminal shows anything other than
.../pumping_pythonyou need to change directory to the
pumping_pythonfolderOnce in the
pumping_pythondirectory, change directory to the projectcd truth_tablethe terminal shows
.../pumping_python/truth_tableactivate the Virtual Environment
source .venv/bin/activateon Windows without Windows Subsystem for Linux use
.venv/scripts/activate.ps1instead ofsource .venv/bin/activate.venv/scripts/activate.ps1when the Virtual Environment is activated, the terminal shows
(.venv) .../pumping_python/truth_tablerun the tests
pytest-watch
test_exclusive_disjunction
RED: make it fail
I add a new test to test_truth_table.py
73 self.assertFalse(src.truth_table.logical_disjunction(False, False))
74
75 def test_exclusive_disjunction(self):
76 self.assertFalse(src.truth_table.exclusive_disjunction(True, True))
77
78
79# Exceptions seen
the terminal shows AttributeError
AttributeError: module 'src.truth_table' has no attribute 'exclusive_disjunction'
GREEN: make it pass
I add the function for exclusive_disjunction in truth_table.py
45def logical_disjunction(first_input, second_input):
46 return first_input or second_input
47
48
49def exclusive_disjunction(first_input, second_input):
50 return False
the test passes. exclusive_disjunction returns False when the two inputs are True
REFACTOR: make it better
I add the next case to
test_exclusive_disjunctionintest_truth_table.py75 def test_exclusive_disjunction(self): 76 self.assertFalse(src.truth_table.exclusive_disjunction(True, True)) 77 self.assertTrue(src.truth_table.exclusive_disjunction(True, False))the terminal shows AssertionError
AssertionError: False is not trueI add if statements to
exclusive_disjunctionintruth_table.py49def exclusive_disjunction(first_input, second_input): 50 if first_input == True: 51 if second_input == False: 52 return True 53 return Falsethe test passes
I change the two if statements to one if statement
49def exclusive_disjunction(first_input, second_input): 50 if first_input == True and second_input == False: 51 # if first_input == True: 52 # if second_input == False: 53 return True 54 return Falsestill green
I remove the commented line and move the return statement to the left
49def exclusive_disjunction(first_input, second_input): 50 if first_input == True and second_input == False: 51 return True 52 return Falsethe terminal still shows green.
exclusive_disjunctionreturnsI add the third case to
test_exclusive_disjunctionintest_truth_table.py75 def test_exclusive_disjunction(self): 76 self.assertFalse(src.truth_table.exclusive_disjunction(True, True)) 77 self.assertTrue(src.truth_table.exclusive_disjunction(True, False)) 78 self.assertTrue(src.truth_table.exclusive_disjunction(False, True))the terminal shows AssertionError
AssertionError: False is not trueI add if statements to
exclusive_disjunctionintruth_table.py49def exclusive_disjunction(first_input, second_input): 50 if first_input == False: 51 if second_input == True: 52 return True 53 if first_input == True and second_input == False: 54 return True 55 return Falsethe test passes
I change the new statements to one if statement
49def exclusive_disjunction(first_input, second_input): 50 if first_input == False and second_input == True: 51 # if first_input == False: 52 # if second_input == True: 53 return True 54 if first_input == True and second_input == False: 55 return True 56 return Falsestill green
I remove the comments and move the return statement to the left
49def exclusive_disjunction(first_input, second_input): 50 if first_input == False and second_input == True: 51 return True 52 if first_input == True and second_input == False: 53 return True 54 return Falsethe terminal still shows green.
exclusive_disjunctionreturnsI add the last case to
test_exclusive_disjunctionintest_truth_table.py75 def test_exclusive_disjunction(self): 76 self.assertFalse(src.truth_table.exclusive_disjunction(True, True)) 77 self.assertTrue(src.truth_table.exclusive_disjunction(True, False)) 78 self.assertTrue(src.truth_table.exclusive_disjunction(False, True)) 79 self.assertFalse(src.truth_table.exclusive_disjunction(False, False)) 80 81 82# Exceptions seenthe test is still green.
exclusive_disjunctionreturnsI write the if statements in terms of True
49def exclusive_disjunction(first_input, second_input): 50 if not first_input == True and second_input == True: 51 # if first_input == False and second_input == True: 52 return True 53 if first_input == True and not second_input == True: 54 # if first_input == True and second_input == False: 55 return True 56 return Falseis green the color of money?
I remove the commented lines and make the statements simpler with bool
49def exclusive_disjunction(first_input, second_input): 50 if not bool(first_input) and bool(second_input): 51 # if not first_input == True and second_input == True: 52 return True 53 if bool(first_input) and not bool(second_input): 54 # if first_input == True and not second_input == True: 55 return True 56 return Falsestill green
I remove the commented lines and make the if statements simpler
49def exclusive_disjunction(first_input, second_input): 50 if not first_input and second_input: 51 # if not bool(first_input) and bool(second_input): 52 return True 53 if first_input and not second_input: 54 # if bool(first_input) and not bool(second_input): 55 return True 56 return Falsethe test is still passing
Tip
I can put two if statements together with Logical Disjunction (or) when they are at the same indentation level and return the same thing. For example
if something: return this if something_else: return thiscan also be written as
if something or something_else: return thisI use Logical Disjunction to put the two if statements that return True together
49def exclusive_disjunction(first_input, second_input): 50 if (not first_input and second_input) or (first_input and not second_input): 51 return True 52 # if not first_input and second_input: 53 # return True 54 # if first_input and not second_input: 55 # return True 56 return Falsethe test is still green
I remove the commented lines
49def exclusive_disjunction(first_input, second_input): 50 if (not first_input and second_input) or (first_input and not second_input): 51 return True 52 return Falsethe test is still passing
I use a conditional expression
49def exclusive_disjunction(first_input, second_input): 50 return True if (not first_input and second_input) or (first_input and not second_input) else False 51 if (not first_input and second_input) or (first_input and not second_input): 52 return True 53 return Falsewhy is the grass greener on the other side?
I remove the other statements and make the ternary operator simpler
49def exclusive_disjunction(first_input, second_input): 50 return (not first_input and second_input) or (first_input and not second_input) 51 return True if (not first_input and second_input) or (first_input and not second_input) else Falsethe terminal still shows green
I remove the second return statement
49def exclusive_disjunction(first_input, second_input): 50 return (not first_input and second_input) or (first_input and not second_input)still green
exclusive_disjunctionreturns False whenfirst_inputandsecond_inputare the same and returns True when they are NOT. I add an if statement to show this with the equality symbol (2 equal signs together =+=)49def exclusive_disjunction(first_input, second_input): 50 if first_input == second_input: 51 return False 52 else: 53 return True 54 return (not first_input and second_input) or (first_input and not second_input)the terminal still shows green
I change the new if statement to a simple return statement
49def exclusive_disjunction(first_input, second_input): 50 return not (first_input == second_input) 51 # if first_input == second_input: 52 # return False 53 # else: 54 # return True 55 return (not first_input and second_input) or (first_input and not second_input)the test is still green
I remove the commented lines, then use an even simpler return statement with the NOT equal symbol (exclamation mark and equal symbol !+=)
49def exclusive_disjunction(first_input, second_input): 50 return first_input != second_input 51 return not (first_input == second_input) 52 return (not first_input and second_input) or (first_input and not second_input)
Exclusive Disjunction returns
True when the two inputs are NOT equal
False when the two inputs are equal
first_input != second_input- which reads as first input is NOT equal to second inputnot (first_input == second_input)- which reads as the Logical Negation of the Logical Equality of the first input and the second input(not first_input and second_input) or (first_input and not second_input)which is the Logical Disjunction of the Logical Conjunction of the Logical Negation of the first input and the second input, and the Logical Conjunction of first input and the Logical Negation of the second input. Wow! That’s a lot
all of the above statements mean the same thing. Would “Logical Inequality” be a better name for Exclusive Disjunction?
Exclusive Disjunction is also known as Exclusive OR or XOR which is used in many different fields
test_material_non_implication
RED: make it fail
I add another test to test_truth_table.py
79 self.assertFalse(src.truth_table.exclusive_disjunction(False, False))
80
81 def test_material_non_implication(self):
82 self.assertFalse(src.truth_table.material_non_implication(True, True))
83
84
85# Exceptions seen
the terminal shows AttributeError
AttributeError: module 'src.truth_table' has no attribute 'material_non_implication'. Did you mean: 'converse_non_implication'?
GREEN: make it pass
I add a function for material_non_implication in truth_table.py
49def exclusive_disjunction(first_input, second_input):
50 return first_input != second_input
51 return not first_input == second_input
52 return (not first_input and second_input) or (first_input and not second_input)
53
54
55def material_non_implication(first_input, second_input):
56 return False
the test passes. material_non_implication returns False when the two inputs are True
REFACTOR: make it better
I add another case to
test_material_non_implicationintest_truth_table.py81 def test_material_non_implication(self): 82 self.assertFalse(src.truth_table.material_non_implication(True, True)) 83 self.assertTrue(src.truth_table.material_non_implication(True, False))the terminal shows AssertionError
AssertionError: False is not trueI add an if statement to
material_non_implicationintruth_table.py55def material_non_implication(first_input, second_input): 56 if first_input == True: 57 if second_input == False: 58 return True 59 return Falsethe test passes
I change the two if statements to one
55def material_non_implication(first_input, second_input): 56 if first_input == True and second_input ==False: 57 # if first_input == True: 58 # if second_input == False: 59 return True 60 return Falsethe test is still green
I remove the commented lines and move the new return statement to the left
55def material_non_implication(first_input, second_input): 56 if first_input == True and second_input ==False: 57 return True 58 return Falsethe test is still green.
material_non_implicationreturnsI add the next case in
test_truth_table.py81 def test_material_non_implication(self): 82 self.assertFalse(src.truth_table.material_non_implication(True, True)) 83 self.assertTrue(src.truth_table.material_non_implication(True, False)) 84 self.assertFalse(src.truth_table.material_non_implication(False, True))the test is still green.
material_non_implicationreturnsI add the fourth case
81 def test_material_non_implication(self): 82 self.assertFalse(src.truth_table.material_non_implication(True, True)) 83 self.assertTrue(src.truth_table.material_non_implication(True, False)) 84 self.assertFalse(src.truth_table.material_non_implication(False, True)) 85 self.assertFalse(src.truth_table.material_non_implication(False, False)) 86 87 88# Exceptions seenthe terminal still shows green.
material_non_implicationreturnsthere is only one case where
material_non_implicationreturns True. I write the if statement in terms of True intruth_table.py55def material_non_implication(first_input, second_input): 56 if first_input == True and not second_input == True: 57 # if first_input == True and second_input ==False: 58 return True 59 return Falsethe test is still passing
I remove the commented line and change the if statement with bool
55def material_non_implication(first_input, second_input): 56 if bool(first_input) and not bool(second_input): 57 # if first_input == True and not second_input == True: 58 return True 59 return Falsegreen is a primary color
I remove the commented line and write a simpler if statement
55def material_non_implication(first_input, second_input): 56 if first_input and not second_input: 57 # if bool(first_input) and not bool(second_input): 58 return True 59 return Falsethe test is still green
I remove the commented lines then add a conditional expression
55def material_non_implication(first_input, second_input): 56 return first_input and not second_input 57 if first_input and not second_input: 58 return True 59 return Falsethe test is still green
I remove the other statements
55def material_non_implication(first_input, second_input): 56 return first_input and not second_input
Material NonImplication returns
first_input and not second_inputwhich is the Logical Conjunction of the first input and the Logical Negation of the second inputTrue only when the first input is True and the second input is False
it is the opposite or Logical Negation of Material or Logical Implication which returns False only when the first input is True and the second input is False
test_project_first
RED: make it fail
I add a new test in test_truth_table.py
85 self.assertFalse(src.truth_table.material_non_implication(False, False))
86
87 def test_project_first(self):
88 self.assertTrue(src.truth_table.project_first(True, True))
89
90
91# Exceptions seen
the terminal shows AttributeError
AttributeError: module 'src.truth_table' has no attribute 'project_first'
GREEN: make it pass
I add a function definition for project_first in truth_table.py
55def material_non_implication(first_input, second_input):
56 return first_input and not second_input
57
58
59def project_first(first_input, second_input):
60 return True
the test passes. project_first returns True when the two inputs are True
REFACTOR: make it better
I add the second case to
test_project_firstintest_truth_table.py87 def test_project_first(self): 88 self.assertTrue(src.truth_table.project_first(True, True)) 89 self.assertTrue(src.truth_table.project_first(True, False))the test is still green.
project_firstreturnson to the next case
87 def test_project_first(self): 88 self.assertTrue(src.truth_table.project_first(True, True)) 89 self.assertTrue(src.truth_table.project_first(True, False)) 90 self.assertFalse(src.truth_table.project_first(False, True))the terminal shows AssertionError
AssertionError: True is not falseI add if statements for this case to
project_firstintruth_table.py59def project_first(first_input, second_input): 60 if first_input == False: 61 if second_input == True: 62 return False 63 return Truethe test passes.
project_firstreturnsI change the if statements to one if statement
59def project_first(first_input, second_input): 60 if first_input == False and second_input == True: 61 # if first_input == False: 62 # if second_input == True: 63 return False 64 return Truethe terminal still shows green
I remove the commented line and move the return statement to the left
59def project_first(first_input, second_input): 60 if first_input == False and second_input == True: 61 return False 62 return Truethe test is still green
I add the last case to
test_project_firstintest_truth_table.py87 def test_project_first(self): 88 self.assertTrue(src.truth_table.project_first(True, True)) 89 self.assertTrue(src.truth_table.project_first(True, False)) 90 self.assertFalse(src.truth_table.project_first(False, True)) 91 self.assertFalse(src.truth_table.project_first(False, False)) 92 93 94# Exceptions seenthe terminal shows AssertionError
AssertionError: True is not falseI add if statements to
project_firstintruth_table.py59def project_first(first_input, second_input): 60 if first_input == False: 61 if second_input == False: 62 return False 63 if first_input == False and second_input == True: 64 return False 65 return Truethe test passes
I change the if statements to one if statement
59def project_first(first_input, second_input): 60 if first_input == False and second_input == False: 61 # if first_input == False: 62 # if second_input == False: 63 return False 64 if first_input == False and second_input == True: 65 return False 66 return Truethe test is still green
I remove the commented lines, and move the return statement to the left
59def project_first(first_input, second_input): 60 if first_input == False and second_input == False: 61 return False 62 if first_input == False and second_input == True: 63 return False 64 return Truethe test is still green.
project_firstreturnsI add a return statement to show that this function returns the same value as
first_inputin every case59def project_first(first_input, second_input): 60 return first_input 61 if first_input == False and second_input == False: 62 return False 63 if first_input == False and second_input == True: 64 return False 65 return Truethe terminal still shows green
I remove the other statements
59def project_first(first_input, second_input): 60 return first_input
Project First returns the first input, it always returns
it is like Project Second which always returns the second input
test_converse_implication
RED: make it fail
I add a new test to test_truth_table.py
91 self.assertFalse(src.truth_table.project_first(False, False))
92
93 def test_converse_implication(self):
94 self.assertTrue(src.truth_table.converse_implication(True, True))
95
96
97# Exceptions seen
the terminal shows AttributeError
AttributeError: module 'src.truth_table' has no attribute 'converse_implication'. Did you mean: 'converse_non_implication'?
GREEN: make it pass
I add a function definition for converse_implication in truth_table.py
59def project_first(first_input, second_input):
60 return first_input
61
62
63def converse_implication(first_input, second_input):
64 return True
the test passes. converse_implication returns True when first_input and second_input are both True
REFACTOR: make it better
I add the second case to
test_converse_implicationintest_truth_table.py93 def test_converse_implication(self): 94 self.assertTrue(src.truth_table.converse_implication(True, True)) 95 self.assertTrue(src.truth_table.converse_implication(True, False))the test is still green.
converse_implicationreturnstime for the next case
93 def test_converse_implication(self): 94 self.assertTrue(src.truth_table.converse_implication(True, True)) 95 self.assertTrue(src.truth_table.converse_implication(True, False)) 96 self.assertFalse(src.truth_table.converse_implication(False, True))the terminal shows AssertionError
AssertionError: True is not falseI add if statements to
converse_implicationintruth_table.py63def converse_implication(first_input, second_input): 64 if first_input == False: 65 if second_input == True: 66 return False 67 return Truethe test passes
I change the two if statements to one if statement
63def converse_implication(first_input, second_input): 64 if first_input == False and second_input == True: 65 # if first_input == False: 66 # if second_input == True: 67 return False 68 return Truethe test is still green
I remove the commented lines and move the return statement to the left
63def converse_implication(first_input, second_input): 64 if first_input == False and second_input == True: 65 return False 66 return Truestill green.
converse_implicationreturnsI add the last case to
test_converse_implicationintest_truth_table.py93 def test_converse_implication(self): 94 self.assertTrue(src.truth_table.converse_implication(True, True)) 95 self.assertTrue(src.truth_table.converse_implication(True, False)) 96 self.assertFalse(src.truth_table.converse_implication(False, True)) 97 self.assertTrue(src.truth_table.converse_implication(False, False)) 98 99 100# Exceptions seenthe terminal still shows green.
converse_implicationreturnsI change the if statement in terms of True in
truth_table.py63def converse_implication(first_input, second_input): 64 if not first_input == True and second_input == True: 65 # if first_input == False and second_input == True: 66 return False 67 return Truethe test is still green
I remove the commented line and use bool
63def converse_implication(first_input, second_input): 64 if not bool(first_input) and bool(second_input): 65 # if not first_input == True and second_input == True: 66 return False 67 return Truedo you like green eggs and ham?
I remove the commented line and make the if statement simpler
63def converse_implication(first_input, second_input): 64 if not first_input and second_input: 65 # if not bool(first_input) and bool(second_input): 66 return False 67 return Truethe terminal still shows green
I add the opposite of the if statement for the second return statement
63def converse_implication(first_input, second_input): 64 if not first_input and second_input: 65 return False 66 if not (not first_input and second_input): 67 return Truethe test is still passing
I move the new if statement to the top
63def converse_implication(first_input, second_input): 64 if not (not first_input and second_input): 65 return True 66 if not first_input and second_input: 67 return Falsegreen
I add a conditional expression
63def converse_implication(first_input, second_input): 64 return True if not (not first_input and second_input) else False 65 if not (not first_input and second_input): 66 return True 67 if not first_input and second_input: 68 return Falsethe test is still green
I remove the other if statements and write a simpler conditional expression
63def converse_implication(first_input, second_input): 64 return not (not first_input and second_input) 65 return True if not (not first_input and second_input) else Falsethe terminal still shows green
I remove the commented lines and “multiply not” by the symbols in the parentheses
63def converse_implication(first_input, second_input): 64 return (not not first_input) (not and) (not second_input) 65 return not (not first_input and second_input)the terminal shows SyntaxError
SyntaxError: invalid syntaxI change “not and” to “or” to be correct
63def converse_implication(first_input, second_input): 64 return (not not first_input) or (not second_input) 65 return not (not first_input and second_input)back to green
I remove the other return statement then remove “not not” since it cancels out - the negation of a negation is the original thing
63def converse_implication(first_input, second_input): 64 return first_input or not second_input 65 return (not not first_input) or (not second_input)the tests is still green
I remove the other return statement
63def converse_implication(first_input, second_input): 64 return first_input or not second_input
Converse Implication returns
first_input or not second_inputFalse only when
first_inputis False andsecond_inputis Truethe Logical Disjunction of the first input and the Logical Negation of the second input
It is the opposite of Converse NonImplication which always returns not first_input and second_input or True only when first_input is False and second_input is True
review
Binary Operations take 2 inputs, each input can be True or False, if we name the first input first_input and the second one second_input, the tests show that
-
returns
first_input or not second_inputreturns False when
first_inputis False andsecond_inputis Trueis the opposite or Logical Negation of Converse NonImplication which only returns True when
first_inputis False andsecond_inputis True
-
returns
first_inputis the opposite or Logical Negation of Negate First which only returns True when
first_inputis False
-
returns
first_input and not second_inputreturns True when
first_inputis False andsecond_inputis Trueis the opposite or Logical Negation of Material or Logical Implication which only returns False when
first_inputis True andsecond_inputis False
-
returns
first_input != second_inputreturns True when
first_inputandsecond_inputare NOT equalis the opposite or Logical Negation of Logical Equality which only returns True when the two inputs are equal
-
returns
first_input or second_inputreturns False when
first_inputandsecond_inputare both Falseis the opposite or Logical Negation of Logical NOR which only returns True when the two inputs are False
-
always returns True
is the opposite or Logical Negation of Contradiction which always returns False
-
returns
not (first_input and second_input)returns False when
first_inputandsecond_inputare both Trueis the opposite or Logical Negation (not) of Logical Conjunction (and) which only returns True when the two inputs are True
-
returns
not first_inputis the opposite or Logical Negation of Project First which only returns True when
first_inputis True
-
returns
not first_input and second_inputreturns True when
first_inputis False andsecond_inputis Trueis the opposite or Logical Negation of Converse Implication which only returns False when
first_inputis False andsecond_inputis True
-
returns
second_inputis the opposite or Logical Negation of Negate Second which only returns True when
second_inputis False
Logical Conjunction returns
returns
first_input and second_inputis the opposite or Logical Negation of Logical NAND which only returns False when the two inputs are True
and
Logical Disjunction is “or”
Logical Conjunction is “and”
Logical Negation is “not”
All the logic statements or conditions have been written with some or all of the above 3.
code from the chapter
Do you want to see all the CODE I typed for the Truth Table?