9

I am attempting to create a program that when run will ask for the boolean expression, the variables and then create a truth table for whatever is entered. I need to use a class and this is what I have so far. I am not sure where to go from here.

from itertools import product

class Boolean(object):

       def __init__(self, statement, vars):
           self.exp = statement
           self.vars = vars

       def __call__(self, statement, vars):

def main():
   expression = raw_input('Give an expression:')
   vars = raw_input('Give names of variables:')
   variables = vars.split(' ')
   b = Boolean(expression, variables)

if __name__ == "__main__":
   main()
DNA
  • 42,007
  • 12
  • 107
  • 146
say786
  • 91
  • 1
  • 1
  • 2
  • share with us what might the input / output would look like – taesu Apr 09 '15 at 20:55
  • I don't really understand what you are asking... moreover, I highly doubt you *need* to use a class, except if this is some homework and that's a requirement for the exercise. A function is probably enough. – Bakuriu Apr 09 '15 at 20:55
  • why are you importing `itertools`? – Daniel Apr 09 '15 at 20:56
  • I am required to use a class for this exercise. – say786 Apr 09 '15 at 21:08
  • The output for this would be asking for an expression, asking for the variables and then outputting a truth table – say786 Apr 09 '15 at 21:09

4 Answers4

14

I have a library that does exactly what you want! Check out the github repo or find it here on pypi.

The readme describes how everything works, but here's a quick example:

from truths import Truths
print Truths(['a', 'b', 'x', 'd'], ['(a and b)', 'a and b or x', 'a and (b or x) or d'])
+---+---+---+---+-----------+--------------+---------------------+
| a | b | x | d | (a and b) | a and b or x | a and (b or x) or d |
+---+---+---+---+-----------+--------------+---------------------+
| 0 | 0 | 0 | 0 |     0     |      0       |          0          |
| 0 | 0 | 0 | 1 |     0     |      0       |          1          |
| 0 | 0 | 1 | 0 |     0     |      1       |          0          |
| 0 | 0 | 1 | 1 |     0     |      1       |          1          |
| 0 | 1 | 0 | 0 |     0     |      0       |          0          |
| 0 | 1 | 0 | 1 |     0     |      0       |          1          |
| 0 | 1 | 1 | 0 |     0     |      1       |          0          |
| 0 | 1 | 1 | 1 |     0     |      1       |          1          |
| 1 | 0 | 0 | 0 |     0     |      0       |          0          |
| 1 | 0 | 0 | 1 |     0     |      0       |          1          |
| 1 | 0 | 1 | 0 |     0     |      1       |          1          |
| 1 | 0 | 1 | 1 |     0     |      1       |          1          |
| 1 | 1 | 0 | 0 |     1     |      1       |          1          |
| 1 | 1 | 0 | 1 |     1     |      1       |          1          |
| 1 | 1 | 1 | 0 |     1     |      1       |          1          |
| 1 | 1 | 1 | 1 |     1     |      1       |          1          |
+---+---+---+---+-----------+--------------+---------------------+

Hope this helps!

penchant
  • 2,263
  • 3
  • 14
  • 20
9

You could simply define any boolean function right in python.

consider the following example:

def f(w,x,y,z):
    return (x and y) and (w or z)

I've wrote a snippet that takes any function f, and returns its truth table:

import pandas as pd
from itertools import product

def truth_table(f):
    values = [list(x) + [f(*x)] for x in product([False,True], repeat=f.func_code.co_argcount)]
    return pd.DataFrame(values,columns=(list(f.func_code.co_varnames) + [f.func_name]))

Using this will yield (in a nicely formatted html if you're using IPython Notebook):

truth_table(f)

    w       x       y       z       f
0   False   False   False   False   False
1   False   False   False   True    False
2   False   False   True    False   False
3   False   False   True    True    False
4   False   True    False   False   False
5   False   True    False   True    False
6   False   True    True    False   False
7   False   True    True    True    True
8   True    False   False   False   False
9   True    False   False   True    False
10  True    False   True    False   False
11  True    False   True    True    False
12  True    True    False   False   False
13  True    True    False   True    False
14  True    True    True    False   True
15  True    True    True    True    True

Cheers.

OmerBA
  • 792
  • 8
  • 13
  • 2
    With Python 3 you need to use `__name__` and `__code__` instead of `func_name` and `func_code` respectively – Duncan WP May 31 '17 at 18:54
3

You probably want to do something like this:

from itertools import product
for p in product((True, False), repeat=len(variables)):
    # Map variable in variables to value in p
    # Apply boolean operators to variables that now have values
    # add result of each application to column in truth table
    pass

But the inside of the for loop is the hardest part, so good luck.

This is an example of what you would be iterating over in the case of three variables:

>>> list(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)]
Shashank
  • 13,713
  • 5
  • 37
  • 63
  • Would that be placed below what I have currently – say786 Apr 09 '15 at 21:11
  • What about building the truth table? And do I need to define product anywhere? – say786 Apr 09 '15 at 21:19
  • The `import` statement defines `product`. The truth table can be just about anything but I'd recommend using a dictionary where the keys are strings (expressions) and the values are bools. – Shashank Apr 09 '15 at 21:24
  • Thanks. I was trying to figure out how to create a truth table that knows to use the function that's the input. – say786 Apr 09 '15 at 21:39
0

If you don't mind providing the number of variables of the function (I think it is possible to get but I don't know how at this moment). I have the following:

from itertools import product
B = {0,1}
varNames= ["r","s","t","u","v","w","x","y","z"]

def booltable(f,n):
    vars = varNames[-n:]
    header = vars + ["f"]
    table = [*reversed([*map(lambda input: [*input,f(*input)], product(B,repeat=len(vars)))])]
    return [header] + table

If you want to have your 1's at the top (like I do), just reverse the answer.

return [*reversed([*map(lambda input: [*input,f(*input)],product(B,repeat=len(vars)))])]

Here is an example of how to use it, functions are defined using bitwise operations.

  • x | y - bitwise or of x and y
  • x ^ y - bitwise exclusive or of x and y
  • x & y - bitwise and of x and y
  • ~x - the bits of x inverted
# Example function
def aBooleanFunction(x,y,z):
    return (x | y) ^ ~(x ^ z) % 2
    
# Run
display(booltable(aBooleanFunction,3))

The output is:

[['x', 'y', 'z', 'f'],
 [1, 1, 1, 0],
 [1, 1, 0, 1],
 [1, 0, 1, 0],
 [1, 0, 0, 1],
 [0, 1, 1, 1],
 [0, 1, 0, 0],
 [0, 0, 1, 0],
 [0, 0, 0, 1]]

You can then parse this to a table in whatever format you want using, for example, tabulate.