I was working on what seemed an easy exercise but I ran into a problem with a the "and" orperator. I think I understand quite well how it works:
print("0 and 0 : ", (0 and 0))
print("0 and 1 : ", (0 and 1))
print("1 and 0 : ", (1 and 0))
print("1 and 1 : ", (1 and 1))
print((0 and 1) == (1 and 0))
That gives me the expected results :
0 and 0 : 0
0 and 1 : 0
1 and 0 : 0
1 and 1 : 1
True
BUT when I run this code:
A = '00111000111000111000111000'
B = '00001110001110001110001110'
for i in range(len(A)):
s1s2 = (A[i] and B[i])
s2s1 = (B[i] and A[i])
print(f"s1={A[i]}, s2={B[i]}, s1 and s2 = {s1s2} ; s2 and s1 = {s2s1} :", (s1s2) == (s2s1))
I end up with non-sense results in my console using Python3.9 on VSCode(and I tried online too):
s1=1, s2=0, s1 and s2 = 0 ; s2 and s1 = 1 : False
s1=0, s2=1, s1 and s2 = 1 ; s2 and s1 = 0 : False
The same problem goes with "or".
A = '00111000111000111000111000'
B = '00001110001110001110001110'
for i in range(len(A)):
s1s2 = (A[i] or B[i])
s2s1 = (B[i] or A[i])
print(f"s1={A[i]}, s2={B[i]} || s1 or s2 = {s1s2} ; s2 or s1 = {s2s1} || s1s2 == s2s1 : ", (s1s2) == (s2s1))
That returns non-sense things :
s1=1, s2=0 || s1 or s2 = 1 ; s2 or s1 = 0 || s1s2 == s2s1 : False
s1=0, s2=1 || s1 or s2 = 0 ; s2 or s1 = 1 || s1s2 == s2s1 : False
I've tried to transform the string A and B into lists before running the loop but it gave me the same results. Do you have any idea about what's going on here? What I am missing or doing wrong ?
Let's take a slightly different case:
0 and None -> 0
None and 0 -> None
'1' and '0' -> '0'
'0' and '1' -> '1'
Why? Well in the first two cases, both 0
(an integer) and None
are falsy, so the first one is returned. In the second two cases, you have non-empty strings, both of which are truthy, so the second one is returned.
There are a couple of ways to fix the second result to be there same as integer comparison. The simplest way is to convert each bit to integer on demand:
A = '00111000111000111000111000'
B = '00001110001110001110001110'
for a, b in zip(A, B):
a = int(a)
b = int(b)
s1s2 = (a and b)
s2s1 = (b and a)
print(f"s1={a}, s2={b}, s1 and s2 = {s1s2} ; s2 and s1 = {s2s1} :", (s1s2) == (s2s1))
Another way is to work with integers directly and use bit-twiddling. This requires you to set the number of bits explicitly, since something like int(A).bit_length()
will discard any leading zeroes:
N = 26
A = 0b00111000111000111000111000
B = 0b00001110001110001110001110
for i in range(N - 1, -1, -1):
a = (A & (1 << i)) >> i
b = (B & (1 << i)) >> i
s1s2 = (a and b)
s2s1 = (b and a)
print(f"s1={a}, s2={b}, s1 and s2 = {s1s2} ; s2 and s1 = {s2s1} :", (s1s2) == (s2s1))
You can omit >> i
in both cases since it does not affect the truth value of the bit selected by (X & (1 << i))
. Also, 1 << i == 2**i
.