truth table: Binary Operations II


requirements

how to make a python test driven development environment with truth_table as the name of the project


test_negate_first

red: make it fail

I add a test for negate first to TestBinaryOperations in test_truth_table.py

def test_converse_non_implication(self):
    ...

def test_negate_first(self):
    self.assertFalse(src.truth_table.negate_first(True, True))

and the terminal shows AttributeError

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

green: make it pass

I add the function definition

def converse_non_implication(p, q):
    return not p and q


def negate_first(p, q):
    return False

the test passes

refactor: make it better

  • I add the second case

    def test_negate_first(self):
        self.assertFalse(src.truth_table.negate_first(True, True))
        self.assertFalse(src.truth_table.negate_first(True, False))
    

    the test is still green

  • I add the next case

    def test_negate_first(self):
        self.assertFalse(src.truth_table.negate_first(True, True))
        self.assertFalse(src.truth_table.negate_first(True, False))
        self.assertTrue(src.truth_table.negate_first(False, True))
    

    the terminal shows AssertionError

    AssertionError: False is not true
    

    I add an if statement

    def negate_first(p, q):
        if p == False and q == True:
            return True
        return False
    

    the test passes

  • I add the last case

    def test_negate_first(self):
        self.assertFalse(src.truth_table.negate_first(True, True))
        self.assertFalse(src.truth_table.negate_first(True, False))
        self.assertTrue(src.truth_table.negate_first(False, True))
        self.assertTrue(src.truth_table.negate_first(False, False))
    

    the terminal shows AssertionError

    AssertionError: False is not true
    

    I add an if statement for it

    def negate_first(p, q):
        if p == False and q == False:
            return True
        if p == False and q == True:
            return True
        return False
    

    the test is green again

  • The 2 cases where the function returns True are when p is False, I add a new if statement with an else clause

    def negate_first(p, q):
        if p == False:
            return True
        else:
            return False
        if p == False and q == False:
            return True
        if p == False and q == True:
            return True
        return False
    

    the test is still green. I remove the other statements and use bool

    def negate_first(p, q):
        if not bool(p):
        # if p == False:
            return True
        else:
            return False
    

    still green, I remove the commented line and simplify the if statement

    def negate_first(p, q):
        if not p:
        # if not bool(p):
            return True
        else:
            return False
    

    the test is still green. I add a ternary operator

    def negate_first(p, q):
        return True if not p else False
        if not p:
            return True
        else:
            return False
    

    I change it to the simpler form

    def negate_first(p, q):
        return not p
        return True if not p else False
    

    all the tests are still passing. I remove the second return statement

    def negate_first(p, q):
        return not p
    

test_logical_nand

red: make it fail

I add a new test

def test_negate_first(self):
    ...

def test_logical_nand(self):
    self.assertFalse(src.truth_table.logical_nand(True, True))

the terminal shows AttributeError

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

green: make it pass

I add a definition for the function

def negate_first(p, q):
    return not p


def logical_nand(p, q):
    return False

the terminal shows green again

refactor: make it better

  • I add the next case

    def test_logical_nand(self):
        self.assertFalse(src.truth_table.logical_nand(True, True))
        self.assertTrue(src.truth_table.logical_nand(True, False))
    

    the terminal shows AssertionError

    AssertionError: False is not true
    

    I add an if statement

    def logical_nand(p, q):
        if p == True and q == False:
            return True
        return False
    

    the test passes

  • I add another case

    def test_logical_nand(self):
        self.assertFalse(src.truth_table.logical_nand(True, True))
        self.assertTrue(src.truth_table.logical_nand(True, False))
        self.assertTrue(src.truth_table.logical_nand(False, True))
    

    the terminal shows AssertionError

    AssertionError: False is not true
    

    I add an if statement

    def logical_nand(p, q):
        if p == False and q == True:
            return True
        if p == True and q == False:
            return True
        return False
    

    green again

  • I add the last case

    def test_logical_nand(self):
        self.assertFalse(src.truth_table.logical_nand(True, True))
        self.assertTrue(src.truth_table.logical_nand(True, False))
        self.assertTrue(src.truth_table.logical_nand(False, True))
        self.assertTrue(src.truth_table.logical_nand(False, False))
    

    the terminal shows AssertionError

    AssertionError: False is not true
    

    I add another if statement

    def logical_nand(p, q):
        if p == False and q == False:
            return True
        if p == False and q == True:
            return True
        if p == True and q == False:
            return True
        return False
    

    the test is green again

  • I add an if statement for the one case that returns True with an else clause for the other 3 that return False

    def logical_nand(p, q):
        if p == True and q == True:
            return False
        else:
            return True
        if p == False and q == False:
            return True
        if p == False and q == True:
            return True
        if p == True and q == False:
            return True
        return False
    

    the test is still green. From Logical Conjunction I know I can change the first statement

    def logical_nand(p, q):
        if p and q:
        # if p == True and q == True:
            return False
        else:
            return True
    

    still green. I want to use a conditional expression, which means I have to use an if statement that returns True. I use logical negation to change the else clause with not

    def logical_nand(p, q):
        if p and q:
            return False
        if not (p and q):
        # else:
            return True
    

    the test is still green. I use the simple return statement

    def logical_nand(p, q):
        return not (p and q)
        if p and q:
            return False
        if not (p and q):
            return True
    

    still green, I remove the other statements.

    def logical_nand(p, q):
        return not (p and q)
    

    When the if statement returns False I can return its logical negation with not


test_tautology

red: make it fail

I add a test

def test_logical_nand(self):
    ...

def test_tautology(self):
    self.assertTrue(src.truth_table.tautology(True, True))

the terminal shows AttributeError

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

green: make it pass

I add a function definition

def logical_nand(p, q):
    return not (p and q)


def tautology(p, q):
    return True

the test passes

refactor: make it better

  • I add the next case

    def test_tautology(self):
        self.assertTrue(src.truth_table.tautology(True, True))
        self.assertTrue(src.truth_table.tautology(True, False))
    

    the terminal still shows green

  • I add another case

    def test_tautology(self):
        self.assertTrue(src.truth_table.tautology(True, True))
        self.assertTrue(src.truth_table.tautology(True, False))
        self.assertTrue(src.truth_table.tautology(False, True))
    

    the test is still green.

  • I add the last case

    def test_tautology(self):
        self.assertTrue(src.truth_table.tautology(True, True))
        self.assertTrue(src.truth_table.tautology(True, False))
        self.assertTrue(src.truth_table.tautology(False, True))
        self.assertTrue(src.truth_table.tautology(False, False))
    

    still green, there is only one result for this operation.


test_logical_disjunction

red: make it fail

I add another test

def test_logical_conjunction(self):
    ...

def test_logical_disjunction(self):
    self.assertTrue(src.truth_table.logical_disjunction(True, True))

the terminal shows AttributeError

AttributeError: module 'src.truth_table' has no attribute 'logical_disjunction'. Did you mean: 'logical_conjunction'?

green: make it pass

I add the function

def tautology(p, q):
    return True


def logical_disjunction(p, q):
    return True

the test passes

refactor: make it better

  • I add the next case

    def test_logical_disjunction(self):
        self.assertTrue(src.truth_table.logical_disjunction(True, True))
        self.assertTrue(src.truth_table.logical_disjunction(True, False))
    

    the terminal still shows green

  • I add the next case

    def test_logical_disjunction(self):
        self.assertTrue(src.truth_table.logical_disjunction(True, True))
        self.assertTrue(src.truth_table.logical_disjunction(True, False))
        self.assertTrue(src.truth_table.logical_disjunction(False, True))
    

    the test is still green

  • I add the fourth case

    def test_logical_disjunction(self):
        self.assertTrue(src.truth_table.logical_disjunction(True, True))
        self.assertTrue(src.truth_table.logical_disjunction(True, False))
        self.assertTrue(src.truth_table.logical_disjunction(False, True))
        self.assertFalse(src.truth_table.logical_disjunction(False, False))
    

    the terminal shows AssertionError

    AssertionError: True is not false
    

    I add an if statement

    def logical_disjunction(p, q):
        if p == False and q == False:
            return False
        return True
    

    the test passes

  • I can change the if statement

    def logical_disjunction(p, q):
        if not p and not q:
        # if p == False and q == False:
            return False
        return True
    

    the terminal still shows green

  • I use a simple return statement with not

    def logical_disjunction(p, q):
        return not (not p and not q):
        if not p and not q:
            return False
        return True
    

    the test is still green. not appears 3 times in this statement, I “multiply” it by each symbol in the parentheses to make the statement simpler

    def logical_disjunction(p, q):
        return not not p not and not not q:
        return not (not p and not q):
    

    the terminal shows SyntaxError

    SyntaxError: invalid syntax
    

    I add it to the list of Exceptions encountered

    # Exceptions Encountered
    # AssertionError
    # AttributeError
    # TypeError
    # SyntaxError
    

    then I fix the line, not and is or

    def logical_disjunction(p, q):
        return not not p or not not q:
        return not (not p and not q):
    

    the test passes. not not cancels out, so I remove them from the statement

    def logical_disjunction(p, q):
        return p or 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

do you want to test more binary operations?


truth table: tests and solutions