Generate Truth Tables with some variables already set in python - python

My requirement is to generate the truth tables for n variables, for which i can use itertables. However, in this requirement I have some variables already set to True/False
For eg sample input is [True, False, Undefined, True, Undefined]
What I want to generate is
[True, False, True, True, True]
[True, False, True, True, False]
[True, False, False, True, True]
[True, False, False, True, False]
Is there any easy way to do this?

Sure; we simply need to construct a list with all the options we're choosing from for each element. For example:
>>> from itertools import product
>>> vv = [True, False, None, True, None]
>>> choose_from = [[True, False] if x is None else [x] for x in vv]
>>> pp = product(*choose_from)
>>> for p in pp:
... print(p)
...
(True, False, True, True, True)
(True, False, True, True, False)
(True, False, False, True, True)
(True, False, False, True, False)

Create a list of lists like this:
possible = [[True],[False],[True,False],[True],[True,False]]
Then use itertools.product:
for table in itertools.product(*possible):
....

Related

is there a more efficient way to make a grid for bool values

I am trying to make a grid to store bool variables kinda like mine sweeper and i would like to find a better way
So far i have a very inefficient way of just declaring like 15 lists with the values set to false like this
A = [False, False, False, False, False, False, False, False, False, False]
Is there a more efficient way to do this
You can efficiently create a list of the same value with:
A = [False]*15
However, more code is required to extend this into a grid. Instead, you could use NumPy to create a grid of False (True) values by using np.zeros (np.ones). For example, a 3x4 grid of False values can be created with:
grid = np.zeros((3, 4), dtype=bool)
>> [[False False False False]
>> [False False False False]
>> [False False False False]]
You might want to use a 2D array for that:
array = [
[False, False, False, False, False, False, False, False, False, False],
[False, False, False, False, False, False, False, False, False, False],
...
]
This can also be created using a list comp:
array = [[False] * 15 for _ in range(15)]

'None' type error when importing function

I am trying to import the answer of a function. The function is this:
def flo(rate,length, interval, threshold):
data = [] #to create an empty list
new = [rate[i:i+ length] for i in range(0, len( rate)-len( rate) % length , length)]
for i in range(len(new )):
data.append('True')
print(data)
return
flo( rate,length, interval, threshold)
where I got the output:
[False]
[False, False]
[False, False, True]
[False, False, True, True]
[False, False, True, True, True]
[False, False, True, True, True, False]
[False, False, True, True, True, False, True]
[False, False, True, True, True, False, True, True]
[False, False, True, True, True, False, True, True, False]
Now I want to import this answer into another function. So I did:
import flow_rate as flow
z = flow.flow_rate ( rate, length, interval, threshold)
print(z)
But my output is:
None
Am I doing something wrong?
You simply put a return statement. There is not variable after return, so None is getting returned. It is as good as the returnstatement is not present in the function.
So you need to return the data:
return data

Getting True values in a boolean list from indices - python

How do I compute the inverse of what is described here: Getting indices of True values in a boolean list ?
That above link always comes up when I try searching for "how to obtain the true values in a boolean list from integer indices," but it gives me the indices from the true values in a boolean list, which is the inverse of what I want...
For example, from:
t = [4, 5, 7]
count = 16
I want to obtain:
[False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]
The values are all 0 indexed, as expected with Python.
I'm guessing that my question is a duplicate, but it's so annoying to not be able to find what I'm looking for every time I try to remember how to do this operation, I decided to ask a new question so my Google search will hopefully bring up this post next time.
You can use a list comprehension. I recommend you turn t into a set for O(1) lookup:
t_set = set(t)
res = [i in t_set for i in range(count)]
Use a list comprehension with conditions:
print([True if i in t else False for i in range(count)])
Shorter:
print([i in t else False for i in range(count)])
How about this:
In [6]: holderplace =[False for i in range(count)]
In [7]: for i in t:
...: holderplace[i-1]=True
...:
In [8]: holderplace
Out[8]:
[False,
False,
False,
True,
True,
False,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False]
In [9]:
You could also try using map():
list(map(lambda x: x in t, range(count)))
# [False, False, False, False, True, True, False, True, False, False, False, False, False, False, False, False]
It might also be worth converting t to a set, since lookup is O(1) instead of O(N).
You could also use __contains__():
list(map(t.__contains__, range(count)))

Python 2d array boolean reduction

I've got a 2D array comprised of boolean values (True,False). I'd like to consolidate the array to a 1D based on a logical function of the contents.
e.g.
Input:
[[True, True, False],
[False, False, False],
[True, True, True]]
Output (logical AND):
[False,
False,
True]
How would this be done without a loop ?
You can use Python's built-in all method with a list-comprehension:
[all(x) for x in my_list]
If that's still too loopy for you, combine it with map:
map(all, my_list)
Note that map doesn't return a list in Python 3. If you want a list as your result, you can call list(map(all, my_list)) instead.
You can do this without NumPy too. Here is one solution using list comprehension. Explanation: It will loop over sub-lists and even if one of the items in each sub-list is False, it outputs False else True.
inp = [[True, True, False],[False, False, False],[True, True, True]]
out = [False if False in i else True for i in inp]
print (out)
# [False, False, True]
Alternative (less verbose) as suggested by Jean below:
out = [False not in i for i in inp]
I'm assuming you want to apply logical ANDs to the rows. You can apply numpy.all.
>>> import numpy as np
>>> a = np.array([[True, True, False], [False, False, False], [True, True, True]])
>>> a
array([[ True, True, False],
[False, False, False],
[ True, True, True]])
>>>
>>> np.all(a, axis=1)
array([False, False, True])
For a solution without numpy, you can use operator.and_ and functools.reduce.
>>> from operator import and_
>>> from functools import reduce
>>>
>>> lst = [[True, True, False], [False, False, False], [True, True, True]]
>>> [reduce(and_, sub) for sub in lst]
[False, False, True]
edit: actually, reduce is a bit redundant in this particular case.
>>> [all(sub) for sub in lst]
[False, False, True]
does the job just as well.
You can do this with numpy with the numpy.all function:
>>> import numpy as np
>>> arr = np.array([[True, True, False],
... [False, False, False],
... [True, True, True]]
... )
>>> np.all(arr, axis=1)
array([False, False, True])
Here thus the i-th element is True if all elements of the i-th row are True, and False otherwise. Note that the list should be rectangular (all sublists should contain the same number of booleans).
In "pure" Python, you can use the all function as well, like:
>>> data = [[True, True, False], [False, False, False], [True, True, True]]
>>> list(map(all, data))
[False, False, True]
This approach will work as well if the "matrix" is not rectangular. Note that for an empty sublist, this will return True, since all elements in an empty sublist are True.
You can also do this with map and reduce:
from functools import reduce
l = [[True, True, False],
[False, False, False],
[True, True, True]]
final = list(map(lambda x: reduce(lambda a, b: a and b, x), l))
print(final)
# [False, False, True]
The benefit here is that you can change the reduce function to something else (say, an OR or something more adventurous).

How to apply a logical operator to all elements in a python list

I have a list of booleans in python. I want to AND (or OR or NOT) them and get the result. The following code works but is not very pythonic.
def apply_and(alist):
if len(alist) > 1:
return alist[0] and apply_and(alist[1:])
else:
return alist[0]
Any suggestions on how to make it more pythonic appreciated.
Logical and across all elements in a_list:
all(a_list)
Logical or across all elements in a_list:
any(a_list)
If you feel creative, you can also do:
import operator
def my_all(a_list):
return reduce(operator.and_, a_list, True)
def my_any(a_list):
return reduce(operator.or_, a_list, False)
keep in mind that those aren't evaluated in short circuit, whilst the built-ins are ;-)
another funny way:
def my_all_v2(a_list):
return len(filter(None,a_list)) == len(a_list)
def my_any_v2(a_list):
return len(filter(None,a_list)) > 0
and yet another:
def my_all_v3(a_list):
for i in a_list:
if not i:
return False
return True
def my_any_v3(a_list):
for i in a_list:
if i:
return True
return False
and we could go on all day, but yes, the pythonic way is to use all and any :-)
By the way, Python has not tail recursion elimination, so don't try to translate LISP code directly ;-)
ANDing and ORing is easy:
>>> some_list = [True] * 100
# OR
>>> any(some_list)
True
#AND
>>> all(some_list)
True
>>> some_list[0] = False
>>> any(some_list)
True
>>> all(some_list)
False
NOTing is also fairly easy:
>>> [not x for x in some_list]
[True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
Of course, how you would use those results might require some interesting applications of DeMorgan's theorem.
Reduce can do this:
reduce(lambda a,b: a and b, alist, True)
As fortran mentioned, all is the most succinct way to do it. But reduce answers the more general question "How to apply a logical operator to all elements in a python list?"
The idiom for such operations is to use the reduce function (global in Python 2.X, in module functools in Python 3.X) with an appropriate binary operator either taken from the operator module or coded explicitly. In your case, it's operator.and_
reduce(operator.and_, [True, True, False])
Here's another solution:
def my_and(a_list):
return not (False in a_list)
def my_or(a_list):
return True in a_list
ANDing all elements will return True if all elements are True, hence no False in a list.
ORing is similar, but it should return True if at least one True value is present in a list.
As the other answers show, there are multiple ways to accomplish this task. Here's another solution that uses functions from the standard library:
from functools import partial
apply_and = all
apply_or = any
apply_not = partial(map, lambda x: not x)
if __name__ == "__main__":
ls = [True, True, False, True, False, True]
print "Original: ", ls
print "and: ", apply_and(ls)
print "or: ", apply_or(ls)
print "not: ", apply_not(ls)

Categories

Resources