truth table: Binary Operations part 1
The last chapter covered 2 types of operations. Nullary Operations which do not take input, and Unary Operations which take 1 input.
There are also Binary Operations, these take 2 inputs. Each of the inputs in this exercise will be True or False which means there are 4 possible ways the inputs can be sent to an operation
preview
These combinations give 16 binary operations each of which returns True or False based on the inputs it receives. Here are the 16 operations that are covered in these chapters and what they return
Material Implication returns
Logical Equality returns
first_input == second_inputTrue when
first_inputandsecond_inputare equal
Logical NOR returns
Negate Second returns
Converse Implication returns
Project First returns
Material NonImplication returns
Exclusive Disjunction returns
first_input != second_inputTrue when
first_inputandsecond_inputare NOT equal
Logical Disjunction returns
Logical NAND returns
Negate First returns
Converse NonImplication returns
Project Second returns
Logical Conjunction returns
Contradiction always returns False
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_contradiction
RED: make it fail
I add a new TestCase to test_truth_table.py
1import unittest
2import src.truth_table
3
4
5class TestNullaryOperations(unittest.TestCase):
6
7 def test_logical_true(self):
8 self.assertTrue(src.truth_table.logical_true())
9
10 def test_logical_false(self):
11 self.assertFalse(src.truth_table.logical_false())
12
13
14class TestUnaryOperations(unittest.TestCase):
15
16 def test_logical_identity(self):
17 self.assertTrue(src.truth_table.logical_identity(True))
18 self.assertFalse(src.truth_table.logical_identity(False))
19
20 def test_logical_negation_aka_not(self):
21 self.assertFalse(src.truth_table.logical_negation(True))
22 self.assertTrue(src.truth_table.logical_negation(False))
23
24
25class TestBinaryOperations(unittest.TestCase):
26
27 def test_contradiction(self):
28 self.assertFalse(src.truth_table.contradiction(True, True))
29
30
31# Exceptions seen
the terminal shows AttributeError
AttributeError: module 'src.truth_table' has no attribute 'contradiction'
GREEN: make it pass
I add a function definition to truth_table.py
13def logical_negation(the_input):
14 return not the_input
15
16
17def contradiction(the_input):
18 return not the_input
TypeError: contradiction() takes 1 positional argument but 2 were given
The definition only takes one input, but the test sent two. I add second_input as the second name in parentheses then change argument to first_input for the first input given when the function is called by the test
Tip
In Visual Studio Code I can change all the places that a name is in the file, by using
17def contradiction(first_input, second_input):
18 return not first_input
the test passes. When contradiction gets True as its first input and True as its second input, it returns the opposite of the first input, that means it returns not True which is False
REFACTOR: make it better
I add the second case to
test_contradictionintest_truth_table.py, this is when the first input is True and the second input is False27 def test_contradiction(self): 28 self.assertFalse(src.truth_table.contradiction(True, True)) 29 self.assertFalse(src.truth_table.contradiction(True, False))the test is still green.
contradictionreturns False in the two cases where the first input is TrueI add the third case, which is when the first input is False and the second input is True
27 def test_contradiction(self): 28 self.assertFalse(src.truth_table.contradiction(True, True)) 29 self.assertFalse(src.truth_table.contradiction(True, False)) 30 self.assertFalse(src.truth_table.contradiction(False, True))the terminal shows AssertionError
AssertionError: True is not falseso far all three cases of the test expect False, which means
contradictionshould return False whenI change the return statement in the
contradictionfunction intruth_table.pyto return the expectation17def contradiction(first_input, second_input): 18 return Falsethe test passes
I add the fourth case to
test_contradictionintest_truth_table.py, this is when the two inputs are False27 def test_contradiction(self): 28 self.assertFalse(src.truth_table.contradiction(True, True)) 29 self.assertFalse(src.truth_table.contradiction(True, False)) 30 self.assertFalse(src.truth_table.contradiction(False, True)) 31 self.assertFalse(src.truth_table.contradiction(False, False)) 32 33 34# Exceptions seenthe test is still green!
Contradiction always returns False it does not matter what inputs it gets
test_logical_conjunction
RED: make it fail
I add a test for logical_conjunction in test_truth_table.py with the first case where the two inputs are True
31 self.assertFalse(src.truth_table.contradiction(False, False))
32
33 def test_logical_conjunction(self):
34 self.assertTrue(src.truth_table.logical_conjunction(True, True))
35
36
37# Exceptions seen
the terminal shows AttributeError
AttributeError: module 'src.truth_table' has no attribute 'logical_conjunction'. Did you mean: 'logical_negation'?
GREEN: make it pass
I add the function in truth_table.py
17def contradiction(first_input, second_input):
18 return False
19
20
21def logical_conjunction(first_input, second_input):
22 return True
the test . logical_conjunction returns True when the first and second input are both True
REFACTOR: make it better
I add the next case - when the first input is True and the second input is False, to
test_logical_conjunctionintest_truth_table.py33 def test_logical_conjunction(self): 34 self.assertTrue(src.truth_table.logical_conjunction(True, True)) 35 self.assertFalse(src.truth_table.logical_conjunction(True, False))the terminal shows AssertionError
AssertionError: True is not falseI make the
logical_conjunctionfunction intruth_table.pyreturn False21def logical_conjunction(first_input, second_input): 22 return False 23 return Truethe terminal shows AssertionError
AssertionError: False is not trueThe line that was passing before is now failing
logical_conjunction has to make a choice. It should return
I can make it do that with if statements
if statements
An if statement is a way for a program to do something based on something else. I can use them to make a function choose between 2 things, there are written as
if something:
do this
I add if statements to the
logical_conjunctionfunction intruth_table.py21def logical_conjunction(first_input, second_input): 22 if first_input == True: 23 if second_input == False: 24 return False 25 return Truethe test passes.
logical_conjunctionreturnsI add the case where the first input is False and the second input is True to
test_logical_conjunctionintest_truth_table.py33 def test_logical_conjunction(self): 34 self.assertTrue(src.truth_table.logical_conjunction(True, True)) 35 self.assertFalse(src.truth_table.logical_conjunction(True, False)) 36 self.assertFalse(src.truth_table.logical_conjunction(False, True))the terminal shows AssertionError
AssertionError: True is not falseI add another if statement for this case to
logical_conjunctionintruth_table.py21def logical_conjunction(first_input, second_input): 22 if first_input == False: 23 if second_input == True: 24 return False 25 if first_input == True: 26 if second_input == False: 27 return False 28 return Truethe test passes.
logical_conjunctionreturnsI add the last case, which is when the two inputs are False, to
test_logical_conjunctionintest_truth_table.py33 def test_logical_conjunction(self): 34 self.assertTrue(src.truth_table.logical_conjunction(True, True)) 35 self.assertFalse(src.truth_table.logical_conjunction(True, False)) 36 self.assertFalse(src.truth_table.logical_conjunction(False, True)) 37 self.assertFalse(src.truth_table.logical_conjunction(False, False)) 38 39 40# Exceptions seenthe terminal shows AssertionError
AssertionError: True is not falseI add if statements for the new case to
logical_conjunctionintruth_table.py21def logical_conjunction(first_input, second_input): 22 if first_input == False: 23 if second_input == False: 24 return False 25 if first_input == False: 26 if second_input == True: 27 return False 28 if first_input == True: 29 if second_input == False: 30 return False 31 return Truethe test passes.
logical_conjunctionreturnsI have the same if statement twice -
if first_input == Falsefor the 3rd and 4th cases where the first input is False21def logical_conjunction(first_input, second_input): 22 if first_input == False: 23 if second_input == False: 24 return False 25 if first_input == False: 26 if second_input == True: 27 return False 28 if first_input == True: 29 if second_input == False: 30 return False 31 return TrueI remove the second one
21def logical_conjunction(first_input, second_input): 22 if first_input == False: 23 if second_input == False: 24 return False 25 if second_input == True: 26 return False 27 if first_input == True: 28 if second_input == False: 29 return False 30 return Truethe test is still green
I add an if statement for the first case, where the first and second inputs are both True
21def logical_conjunction(first_input, second_input): 22 if first_input == False: 23 if second_input == False: 24 return False 25 if second_input == True: 26 return False 27 if first_input == True: 28 if second_input == False: 29 return False 30 if second_input == True: 31 return Truethe terminal still shows green
there are only 2 results for this operation, in the first case the function returns True. In the other 3 cases it returns False.
21def logical_conjunction(first_input, second_input): 22 if first_input == False: 23 if second_input == False: 24 return False 25 if second_input == True: 26 return False 27 if first_input == True: 28 if second_input == False: 29 return False 30 if second_input == True: 31 return TrueTip
I can put two if statements together when one is under the other. For example
if something: if something_else:can also be written as
if something and something_else:I put the two if statements for the one case where the result is True together and use an else clause for the other cases where the first and second inputs are not both True
21def logical_conjunction(first_input, second_input): 22 if first_input == True and second_input == True: 23 return True 24 else: 25 return False 26 if first_input == False: 27 if second_input == False: 28 return False 29 if second_input == True: 30 return False 31 if first_input == True: 32 if second_input == False: 33 return False 34 if second_input == True: 35 return Truethe test is still green
I remove the other if statements then use bool in the first if statement
21def logical_conjunction(first_input, second_input): 22 if bool(first_input) and bool(second_input): 23 # if first_input == True and second_input == True: 24 return True 25 else: 26 return Falsestill green. bool checks if the thing in parentheses is True in the background
I remove the commented line then change the first line to make it simpler
21def logical_conjunction(first_input, second_input): 22 if first_input and second_input: 23 # if bool(first_input) and bool(second_input): 24 return True 25 else: 26 return Falsethe test is still green
Tip
these if statements are the same
if something == True:if bool(something): == True``if bool(something):
if something:
Python checks if
somethingis True in the background when I typeif something:I remove the commented line
conditional expressions
Python has ternary operators or conditional expressions which allow me to write the if statement and the else clause as one line
21def logical_conjunction(first_input, second_input): 22 return True if first_input and second_input else False 23 if first_input and second_input: 24 return True 25 else: 26 return Falsethe terminal shows green
I remove the other if statements then change the return statement to a simpler form
21def logical_conjunction(first_input, second_input): 22 return first_input and second_input 23 return True if first_input and second_input else Falsestill green!
I remove the second return statement
21def logical_conjunction(first_input, second_input): 22 return first_input and second_input
Logical Conjunction also known as and, returns
Tip
All of the statements below give the same result
this checks if
somethingis Trueif something == True: return True else: return Falsethis uses bool to get the boolean of
somethingthen checks if the result is Trueif bool(something) == True: return True else: return Falsethis checks if
bool(something)is True in the backgroundif bool(something): return True else: return Falsethis checks if
somethingis True in the backgroundif something: return True else: return Falsethis returns True if
somethingis Truereturn True if something else Falsethis also returns True after checking if
somethingis True in the backgroundreturn something
the last one works because Python tests if something is True in the background same as it does when I type if something:
test_project_second
RED: make it fail
I add a test for another Binary Operation in test_truth_table.py
37 self.assertFalse(src.truth_table.logical_conjunction(False, False))
38
39 def test_project_second(self):
40 self.assertTrue(src.truth_table.project_second(True, True))
41
42
43# Exceptions seen
the terminal shows AttributeError
AttributeError: module 'src.truth_table' has no attribute 'project_second'
GREEN: make it pass
I add a definition for the function in truth_table.py
21def logical_conjunction(first_input, second_input):
22 return first_input and second_input
23
24
25def project_second(first_input, second_input):
26 return True
the test passes. When the first input is True and the second input is False, this function returns True
REFACTOR: make it better
I add the second case - where the first input is True and the second input False, to
test_project_secondintest_truth_table.py39 def test_project_second(self): 40 self.assertTrue(src.truth_table.project_second(True, True)) 41 self.assertFalse(src.truth_table.project_second(True, False))the terminal shows AssertionError
AssertionError: True is not falseI add an if statement for the case to
project_secondintruth_table.py25def project_second(first_input, second_input): 26 if first_input == True: 27 if second_input == False: 28 return False 29 return Truethe test
I add the next case, which is when the first input is False and the second input is True to
test_project_secondintest_truth_table.py39 def test_project_second(self): 40 self.assertTrue(src.truth_table.project_second(True, True)) 41 self.assertFalse(src.truth_table.project_second(True, False)) 42 self.assertTrue(src.truth_table.project_second(False, True))the test is still green
I add the last case - when the two inputs are False
39 def test_project_second(self): 40 self.assertTrue(src.truth_table.project_second(True, True)) 41 self.assertFalse(src.truth_table.project_second(True, False)) 42 self.assertTrue(src.truth_table.project_second(False, True)) 43 self.assertFalse(src.truth_table.project_second(False, False)) 44 45 46# Exceptions seenthe terminal shows AssertionError
AssertionError: True is not falseI add an if statement for this case to
project_secondintruth_table.py25def project_second(first_input, second_input): 26 if first_input == False: 27 if second_input == False: 28 return False 29 if first_input == True: 30 if second_input == False: 31 return False 32 return Truethe test passes
project_secondreturnsIt returns the same value as the second input. I add a new return statement to show this
25def project_second(first_input, second_input): 26 return second_input 27 if first_input == False: 28 if second_input == False: 29 return False 30 if first_input == True: 31 if second_input == False: 32 return False 33 return Truethe test is still green
I remove the other statements
25def project_second(first_input, second_input): 26 return second_input
Project Second returns the second input, it always returns
test_converse_non_implication
RED: make it fail
I add a test for converse_non_implication in test_truth_table.py
43 self.assertFalse(src.truth_table.project_second(False, False))
44
45 def test_converse_non_implication(self):
46 self.assertFalse(src.truth_table.converse_non_implication(True, True))
47
48
49# Exceptions seen
the terminal shows AttributeError
AttributeError: module 'src.truth_table' has no attribute 'converse_non_implication'
GREEN: make it pass
I add the function to truth_table.py
25def project_second(first_input, second_input):
26 return second_input
27
28
29def converse_non_implication(first_input, second_input):
30 return False
the test passes. converse_non_implication returns False when the first input is True and the second input is False
REFACTOR: make it better
I add the next case to
test_converse_non_implicationintest_truth_table.py, when the first input is True and the second input is False45 def test_converse_non_implication(self): 46 self.assertFalse(src.truth_table.converse_non_implication(True, True)) 47 self.assertFalse(src.truth_table.converse_non_implication(True, False))the test is still green, because it expects False in both cases
I add the third case - where the first input is False and the second input is True
45 def test_converse_non_implication(self): 46 self.assertFalse(src.truth_table.converse_non_implication(True, True)) 47 self.assertFalse(src.truth_table.converse_non_implication(True, False)) 48 self.assertTrue(src.truth_table.converse_non_implication(False, True))the terminal shows AssertionError
AssertionError: False is not trueI add an if statement to
converse_non_implicationintruth_table.py29def converse_non_implication(first_input, second_input): 30 if first_input == False: 31 if second_input == True: 32 return True 33 return Falsethe test passes. The
converse_non_implicationfunction returnsI add the next case - when the first and second inputs are both False, to
test_converse_non_implicationintest_truth_table.py45 def test_converse_non_implication(self): 46 self.assertFalse(src.truth_table.converse_non_implication(True, True)) 47 self.assertFalse(src.truth_table.converse_non_implication(True, False)) 48 self.assertTrue(src.truth_table.converse_non_implication(False, True)) 49 self.assertFalse(src.truth_table.converse_non_implication(False, False)) 50 51 52# Exceptions seenthe test is still passing
I use
andakalogical_conjunctionto put the two if statements together inconverse_non_implicationintruth_table.py29def converse_non_implication(first_input, second_input): 30 if first_input == False and second_input == True: 31 # if first_input == False: 32 # if second_input == True: 33 return True 34 return Falsethe terminal still shows green
I remove the commented lines then change the first line with logical negation and bool
29def converse_non_implication(first_input, second_input): 30 if not first_input == True and bool(second_input): 31 # if first_input == False and second_input == True: 32 return True 33 return Falsestill green
I add an else clause
29def converse_non_implication(first_input, second_input): 30 if not first_input == True and bool(second_input): 31 # if first_input == False and second_input == True: 32 return True 33 else: 34 return Falsethe test is still green
I remove the comment and use bool with the first part of the if statement to make it simpler
29def converse_non_implication(first_input, second_input): 30 if not bool(first_input) and second_input: 31 # if not first_input == True and bool(second_input): 32 return True 33 else: 34 return Falsethe test is still green
I remove the commented line and make the if statement simpler
29def converse_non_implication(first_input, second_input): 30 if not first_input and second_input: 31 # if not bool(first_input) and second_input: 32 return True 33 else: 34 return Falsethe terminal still shows green
I use a conditional expression
29def converse_non_implication(first_input, second_input): 30 return True if not first_input and second_input else False 31 if not first_input and second_input: 32 return True 33 else: 34 return Falsestill green
I remove the if statements then use the simpler return statement
29def converse_non_implication(first_input, second_input): 30 return not first_input and second_input 31 return True if not first_input and second_input else Falseall tests are still passing
I remove the second return statement
29def converse_non_implication(first_input, second_input): 30 return not first_input and second_input
Converse NonImplication always returns
not first_input and second_inputthe Logical Conjunction of the Negation of the first input and the second input
True only when the first input is False and the second input is True
review
Binary Operations take 2 inputs, each input can be True or False, if the first input is named first_input and the second input is named second_input, the tests show that
-
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 Conjunction is “and”
Logical Negation is “not”
All the logic statements or conditions have been written with some or all of the above 2.
code from the chapter
Do you want to see all the CODE I typed for the Truth Table?
what is next?
Would you like to test more binary operations?