Generate Truth Table but leave some variables undefined in python - python

input:
vv = [True, False, None, True, None]
Is there a way to generate truth table by replacing undefined one boolean at a time
So the ouptut would be
[True, False, True, True, None]
[True, False, False, True, None]
[True, False, None, True, False]
[True, False, None, True, True]

Assuming that Undefined can be None, for example, you could do as follows:
l = [True, False, None, True, None]
# first get indices of None/Undefined elements in the input list
indexes = [i for i,v in enumerate(l) if v is None]
# for each index, generate new list using True and False
# as substitutes.
for idx in indexes:
for sub in [True, False]:
new_l = l[:]
new_l[idx] = sub
print(new_l)
This gives:
[True, False, True, True, None]
[True, False, False, True, None]
[True, False, None, True, True]
[True, False, None, True, False]

Related

How to get index of numpy multidimensional array in reverse order?

For example I have this np.array:
[[True, True, False, False]
[True, False, True, False]
[False, True, False, True]
[False, False, True, True]]
I want to get the the first index that is True in each row but counting from the back of the row. So expected output is a (4,) array corresponding to each row:
[1, # First index that is True is at index 1
2, # First index that is True is at index 2
3, # First index that is True is at index 3
3] # First index that is True is at index 3
a = np.array(
[[True, True, False, False],
[True, False, True, False],
[False, True, False, True],
[False, False, True, True]]
)
idx = a.shape[1] - 1 - np.argmax(a[:,::-1], axis=1)
np.argmax() will find the index of the highest value (for each row with axis=1). Since True is equivalent to 1 and False to 0, it'll record the index of the first True value. Simply reverse the rows so you find the "last" one and then substract this from the row length to account for the fact that you're counting backwards.
you can use python to reversea row and find an element: row.reverse() and row.find(True). in numpy you can use numpy.flip(row) to reverse a row and numpy.where(row == True) to find an element in a row.
import numpy as np
x = np.array([[True, True, False, False],
[True, False, True, False],
[False, True, False, True],
[False, False, True, True]])
result = []
for row in x:
row = np.flip(row)
index = np.where(row == True)
result.append(index[0][0])
print(result)

How to generate these lists of True and False?

I am looping through a list of 3 items, something like:
for i in range(3):
and trying to produce the following lists on each respective iteration:
[True, True, False, False, False, False]
[False, False, True, True, False, False]
[False, False, False, False, True, True]
What would be a good way in python to do this?
Here's one way:
>>> for i in range(3):
... print([(x // 2) == i for x in range(6)])
...
[True, True, False, False, False, False]
[False, False, True, True, False, False]
[False, False, False, False, True, True]
Try like this:
k = 0
for i in range(3):
# Other tasks
myList = [False for x in range(4)]
myList[k:k] = [True,True]
print(myList)
k += 2
L = [False, False, False, False, True, True]
for _ in range(3):
L = L[-2:] + L[:4]
print(L)

Python, The fastest way to find numbers indexes in np. array

The fastest way to find numbers indexes in np. array in Python is?
Suppose we have a list of numbers from 0 to 20, and we want to know the indexes of digits 2 and 5
The canonical way would be to use numpy's where method:
a = np.array(range(20))
np.where((a == 2) | (a == 5))
Note that in order to combine the two terms (a == 2) and (a == 5) we need the bitwise or operator |. The reason is that both (a == 2) and (a == 5) return a numpy array of dtype('bool'):
>>> a == 2
array([False, False, True, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False])
>>> (a == 5)
array([False, False, False, False, False, True, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False])
>>> (a == 2) | (a==5)
array([False, False, True, False, False, True, False, False, False,
False, False, False, False, False, False, False, False, False,
False, False])

Choose random elements from specific elements of an array

I have a 1D (numpy) array with boolean values. for example:
x = [True, True, False, False, False, True, False, True, True, True, False, True, True, False]
The array contains 8 True values. I would like to keep, for example, exactly 3 (must be less than 8 in this case) as True values randomly from the 8 that exist. In other words I would like to randomly set 5 of those 8 True values as False.
A possible result can be:
x = [True, True, False, False, False, False, False, False, False, False, False, False, True, False]
How to implement it?
One approach would be -
# Get the indices of True values
idx = np.flatnonzero(x)
# Get unique indices of length 3 less than the number of indices and
# set those in x as False
x[np.random.choice(idx, len(idx)-3, replace=0)] = 0
Sample run -
# Input array
In [79]: x
Out[79]:
array([ True, True, False, False, False, True, False, True, True,
True, False, True, True, False], dtype=bool)
# Get indices
In [80]: idx = np.flatnonzero(x)
# Set 3 minus number of True indices as False
In [81]: x[np.random.choice(idx, len(idx)-3, replace=0)] = 0
# Verify output to have exactly three True values
In [82]: x
Out[82]:
array([ True, False, False, False, False, False, False, True, False,
False, False, True, False, False], dtype=bool)
Build an array with the number of desired True and False, then just shuffle it
import random
def buildRandomArray(size, numberOfTrues):
res = [False]*(size-numberOfTrues) + [True]*numberOfTrues
random.shuffle(res)
return res
Live example

Python boolean operations on lists - inconsistent results

Suppose I have two lists:
>>> y
[False, False, True, False, True, False, False, True, False, True, False, False]
>>> z
[False, True, True, True, True, True, False, False, False, False, False, True]
Then I do the following:
>>> y or z
[False, False, True, False, True, False, False, True, False, True, False, False]
>>> z or y
[False, True, True, True, True, True, False, False, False, False, False, True]
Shouldn't the correct answer be as shown below?
[False, True, True, True, True, True, False, True, False, True, False, True]
I also get incorrect answers with and:
>>> y and z
[False, True, True, True, True, True, False, False, False, False, False, True]
>>> z and y
[False, False, True, False, True, False, False, True, False, True, False, False]
I tested 1s and 0s with odd results:
>>> y=[0,0,0,0,0]
>>> z=[1,1,1,1,1]
>>> y or z
[0, 0, 0, 0, 0]
>>> z or y
[1, 1, 1, 1, 1]
>>> y and z
[1, 1, 1, 1, 1]
>>> z and y
[0, 0, 0, 0, 0]
What am I doing incorrectly?
y or z doesn't behave how you think it does, on the individual elements. Instead, it evaluates the 'truthiness' of the first argument (y). Since y is a non-empty list, it evaluates to true. The overall statement then evaluates to y.
Similarly, z or y first looks to see if z is truthy (which it is, because it's a non empty list). Thus the statement evaluates to z without ever looking at y or the elements within it.
Here are some clearer examples:
>>> [1,2,3,4] or [5,6,7,8]
[1, 2, 3, 4]
>>> ['this','is','a','list'] or ['and','here','is','another']
['this', 'is', 'a', 'list']
An empty list evaluates as 'false-y', so in this care, the right hand list is the value of the statement:
>>> [] or ['and','here','is','another']
['and', 'here', 'is', 'another']
Swapping the order of the lists shows that the first one to evaluate as true will be the result:
>>> ['and','here','is','another'] or ['this','is','a','list']
['and', 'here', 'is', 'another']
To achieve what you want, you could do a list comprehension like
[
y_item or z_item
for y_item, z_item
in zip(y, z)
]
The correct approach for or operation:
[a or b for a, b in zip(y, z)]
The correct approach for and operation:
[a and b for a, b in zip(y, z)]
None, False, 0, '', (), [], {} and few more (mentioned here -> Truth Value Testing) are considered False.
here's some example:
[] is False, [False] is True since its not empty, check using
bool([False])
>>> [] and [False]
[]
>>> bool([] and [False])
False
[] is False, [False] is True, hence Here True
>>> [] or [False]
[False]
>>> bool([] or [False])
True

Categories

Resources