Search code examples
pythonlisttruthtable

Truth table list


My goal is to make a truth table in python and here's my code:

from re import findall

string = "xyz"

def getChars(str):
    listChars = findall(r"\w", str)

    return listChars


def createCharsTruthTable(lst):
    n = 2 ** len(lst)

    boolList = [[True for x in range(n)] for j in range(len(lst))]

    num_of_T = n / 2

    for i in range(len(boolList)):
        for j in range(len(boolList[i])):
            if j >= num_of_T:
               boolList[i][j] = False

        num_of_T /= 2

    return boolList

createCharsTruthTable(getChars(string))

the problem is that the output is...

[[True, True, True, True, False, False, False, False], [True, True, False, False, False, False, False, False], [True, False, False, False, False, False, False, False]]

The first list got it right. My only problem is the succeeding lists, where in the second list is...

[True, True, False, False, False, False, False, False]

and my question is how do i turn this into...

[True, True, False, False, True, True, False, False]

Solution

  • Assuming you just want to create a "truth table" with 1/2 True values in the first line, 2x 1/4 True in the second line, and so on, such that the columns in that table would be the input for a truth function with that number of parameters. You can not just use any j as the cutoff from when to put False into the table, as the pattern is periodic. Instead, you could try dividing the current j by a power of 2 and testing whether it's even or odd:

    cols = 3
    rows = 2**cols
    boolList = [[True for x in range(rows)] for j in range(cols)]
    
    for i in range(cols):
        for j in range(rows):
            if (j // (2**(cols-1-i))) % 2 == 1:
               boolList[i][j] = False
    

    Result for boolList:

    [[True, True, True, True, False, False, False, False],
     [True, True, False, False, True, True, False, False],
     [True, False, True, False, True, False, True, False]]
    

    A better way might be to use itertools.product instead:

    >>> import itertools
    >>> list(itertools.product([True, False], repeat=3))                        
    [(True, True, True),
     (True, True, False),
     (True, False, True),
     (True, False, False),
     (False, True, True),
     (False, True, False),
     (False, False, True),
     (False, False, False)]
    

    (Note that rows and columns are inversed here, but it might even make more sense this way.)