truth table: Binary Operations I¶
requirements¶
how to make a python test driven development environment with truth_table
as the name of the project
There are 16 binary operations, they all take 2 inputs, each of the inputs can be True or False, which gives four cases
test_contradiction¶
red: make it fail¶
I add a new TestCase to test_truth_table.py
def test_logical_negation_aka_not(self):
...
class TestBinaryOperations(unittest.TestCase):
def test_contradiction(self):
self.assertFalse(src.truth_table.contradiction(True, True))
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
def logical_negation(argument):
return not argument
def contradiction(argument):
return not argument
the terminal shows TypeError
TypeError: contradiction() takes 1 positional argument but 2 were given
I change the signature to make it take 2 inputs
def contradiction(p, q):
return not p
the test passes
refactor: make it better¶
I add the second case
def test_contradiction(self): self.assertFalse(src.truth_table.contradiction(True, True)) self.assertFalse(src.truth_table.contradiction(True, False))
the test is still green.
I add the next case
def test_contradiction(self): self.assertFalse(src.truth_table.contradiction(True, True)) self.assertFalse(src.truth_table.contradiction(True, False)) self.assertFalse(src.truth_table.contradiction(False, True))
the terminal shows AssertionError
AssertionError: True is not false
all three cases of the test expect False. I change the return statement
def contradiction(p, q): return False
the test is green again
I add the fourth case
def test_contradiction(self): self.assertFalse(src.truth_table.contradiction(True, True)) self.assertFalse(src.truth_table.contradiction(True, False)) self.assertFalse(src.truth_table.contradiction(False, True)) self.assertFalse(src.truth_table.contradiction(False, False))
another case that expects False, the test is still green! contradiction always returns False
test_logical_conjunction¶
red: make it fail¶
I add the next test
def test_contradiction(self):
...
def test_logical_conjunction(self):
self.assertTrue(src.truth_table.logical_conjunction(True, True))
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
def contradiction(p, q):
return False
def logical_conjunction(p, q):
return True
the test passes
refactor: make it better¶
I add the next case
def test_logical_conjunction(self): self.assertTrue(src.truth_table.logical_conjunction(True, True)) self.assertFalse(src.truth_table.logical_conjunction(True, False))
the terminal shows AssertionError
AssertionError: True is not false
when I add a return statement for False
def logical_conjunction(p, q): return False return True
the terminal shows AssertionError
AssertionError: False is not true
for the line that was passing before.
logical_conjunction
has to choose whether to return False or True based on the inputs. I can make it do that with if statementsdef logical_conjunction(p, q): if p == True: if q == False: return False return True
the test passes. The function returns False when
p
is True andq
is False, otherwise it returns True by defaultI add the next case
def test_logical_conjunction(self): self.assertTrue(src.truth_table.logical_conjunction(True, True)) self.assertFalse(src.truth_table.logical_conjunction(True, False)) self.assertFalse(src.truth_table.logical_conjunction(False, True))
and get AssertionError
AssertionError: True is not false
I add another if statement
def logical_conjunction(p, q): if p == False: if q == True: return False if p == True: if q == False: return False return True
the test passes
I add the last case
def test_logical_conjunction(self): self.assertTrue(src.truth_table.logical_conjunction(True, True)) self.assertFalse(src.truth_table.logical_conjunction(True, False)) self.assertFalse(src.truth_table.logical_conjunction(False, True)) self.assertFalse(src.truth_table.logical_conjunction(False, False))
the terminal shows AssertionError
AssertionError: True is not false
I add an if statement for it
def logical_conjunction(p, q): if p == False: if q == False: return False if q == True: return False if p == True: if q == False: return False return True
the terminal shows green
I add an if statement for the first case to make it clearer
def logical_conjunction(p, q): if p == False: if q == False: return False if q == True: return False if p == True: if q == False: return False if q == True: return True
There are only 2 results for this operation, in the first case the function returns True and in the other 3 cases it returns False. I rewrite the if statement for the case where the result is True then use an else clause for the other cases
def logical_conjunction(p, q): if p == True and q == True: return True else: return False if p == False: if q == False: return False if q == True: return False if p == True: if q == False: return False if q == True: return True
the test is still green. I remove the other if statements then change the first statement with bool
def logical_conjunction(p, q): if bool(p) and bool(q): # if p == True and q == True: return True else: return False
still green.
bool(x)
checks ifx
is True. I remove the commented line and rewrite the first line to make it simplerdef logical_conjunction(p, q): if p and q: # if bool(p) and bool(q): return True else: return False
the test is still green, Python tests if
p
andq
are True in the background, I remove the commented linePython has ternary operators or conditional expressions which allow me to write the if statements as one line
def logical_conjunction(p, q): return True if p and q else False if p and q: return True else: return False
the terminal shows green, I remove the other if statements and rewrite the return statement in an even simpler way thanks to Python’s truth value testing
def logical_conjunction(p, q): return p and q return True if p and q else False
still green! I remove the second return statement
def logical_conjunction(p, q): return p and q
test_project_second¶
red: make it fail¶
I add another test
def test_logical_conjunction(self):
...
def test_project_second(self):
self.assertTrue(src.truth_table.project_second(True, True))
the terminal shows AttributeError
AttributeError: module 'src.truth_table' has no attribute 'project_second'
green: make it pass¶
When I add a function definition for it
def logical_conjunction(p, q):
return p and q
def project_second(p, q):
return True
the test passes
refactor: make it better¶
I add the second case
def test_project_second(self): self.assertTrue(src.truth_table.project_second(True, True)) self.assertFalse(src.truth_table.project_second(True, False))
the terminal shows AssertionError
AssertionError: True is not false
I add an if statement
def project_second(p, q): if p == True: if q == False: return False return True
the test passes
I add the next case
def test_project_second(self): self.assertTrue(src.truth_table.project_second(True, True)) self.assertFalse(src.truth_table.project_second(True, False)) self.assertTrue(src.truth_table.project_second(False, True))
the test is still green
I add the last case
def test_project_second(self): self.assertTrue(src.truth_table.project_second(True, True)) self.assertFalse(src.truth_table.project_second(True, False)) self.assertTrue(src.truth_table.project_second(False, True)) self.assertFalse(src.truth_table.project_second(False, False))
and the terminal shows AssertionError
AssertionError: True is not false
I add another if statement
def project_second(p, q): if p == False: if q == False: return False if p == True: if q == False: return False return True
the test passes
This function returns True when
q
is True and returns False whenq
is False. I add a new statement to show thisdef project_second(p, q): return q if p == False: if q == False: return False if p == True: if q == False: return False return True
the test is still green, I remove the other statements
def project_second(p, q): return q
test_converse_non_implication¶
red: make it fail¶
I add another test
def test_project_second(self):
...
def test_converse_non_implication(self):
self.assertFalse(src.truth_table.converse_non_implication(True, True))
the terminal shows AttributeError
AttributeError: module 'src.truth_table' has no attribute 'converse_non_implication'
green: make it pass¶
I add the function
def project_second(p, q):
return q
def converse_non_implication(p, q):
return False
the test passes
refactor: make it better¶
I add another case
def test_converse_non_implication(self): self.assertFalse(src.truth_table.converse_non_implication(True, True)) self.assertFalse(src.truth_table.converse_non_implication(True, False))
the test is still green
I add the third case
def test_converse_non_implication(self): self.assertFalse(src.truth_table.converse_non_implication(True, True)) self.assertFalse(src.truth_table.converse_non_implication(True, False)) self.assertTrue(src.truth_table.converse_non_implication(False, True))
the terminal shows AssertionError
AssertionError: False is not true
I add an if statement
def converse_non_implication(p, q): if p == False: if q == True: return True return False
the test is green again
I add the next case
def test_converse_non_implication(self): self.assertFalse(src.truth_table.converse_non_implication(True, True)) self.assertFalse(src.truth_table.converse_non_implication(True, False)) self.assertTrue(src.truth_table.converse_non_implication(False, True)) self.assertFalse(src.truth_table.converse_non_implication(False, False))
the terminal still shows green
I can put the two if statements together with
and
def converse_non_implication(p, q): if p == False and q == True: # if p == False: # if q == True: return True return False
the terminal still shows green. I remove the other statements and rewrite the first line with logical negation and bool
def converse_non_implication(p, q): if not p == True and bool(q): # if p == False and q == True: return True else: return False
still green. I remove the comment and rewrite the line again
def converse_non_implication(p, q): if not bool(p) and q: # if not p == True and bool(q): return True else: return False
the test is still green. I remove the commented line and make the line simpler
def converse_non_implication(p, q): if not p and q: # if not bool(p) and q: return True else: return False
the test is still green. I use a conditional expression
def converse_non_implication(p, q): return True if not p and q else False if not p and q: return True else: return False
still green. I use the simpler return statement
def converse_non_implication(p, q): return not p and q return True if not p and q else False
all tests are still passing. I remove the second return statement
def converse_non_implication(p, q): return not p and q
review¶
Binary Operations take 2 inputs which could be True or False, if we name the first input p
and the second q
, the tests show that
Converse NonImplication returns
not p and q
Project Second always returns
q
Logical Conjunction returns
p and q
Contradiction always returns False, it does not care about the inputs
do you want to test more binary operations?