Recently I was solving one of the very basic problems on conditionals from Hackerrank.
The problem was:
If n is odd, print Weird
If n is even and in the inclusive range of 2 to 5 print Not Weird
If n is even and in the inclusive range of 6 to 20 print Weird
If n is even and greater than 20, print Not Weird
So i wrote the following code
if(n % 2 == 0 & n >=6 & n <= 20 ):
print("Weird")
elif(n % 2 == 0 & n <= 2 & n >= 5):
print("Not Weird")
elif( n % 2 != 0):
print("Weird")
else:
print("Not Weird")
It didn't work at first. I figured out that i had to use "and" instead of "&".
But, I am not convinced why did this happen..
for n = 12, all 3 conditions of the first if condition are true. so true & true & true should also be true, right?
this photo shows the code snippet with some print messages
I am very intrigued to know the reason behind this behaviour, please guide! (may be something very minor but please don't mind :) )
Every time you have this kind of doubts, you can use the dis
module, in your case I make a lambda function to evaluate the process:
func = lambda x: x % 2 == 0 & x >= 6 & x <= 20
this gives us the follow disassmbled code:
0 LOAD_FAST 0 (x)
2 LOAD_CONST 1 (2)
4 BINARY_MODULO
6 LOAD_CONST 2 (0)
8 LOAD_FAST 0 (x)
10 BINARY_AND
12 DUP_TOP
14 ROT_THREE
16 COMPARE_OP 2 (==)
18 JUMP_IF_FALSE_OR_POP 40
20 LOAD_CONST 3 (6)
22 LOAD_FAST 0 (x)
24 BINARY_AND
26 DUP_TOP
28 ROT_THREE
30 COMPARE_OP 5 (>=)
32 JUMP_IF_FALSE_OR_POP 40
34 LOAD_CONST 4 (20)
36 COMPARE_OP 1 (<=)
38 RETURN_VALUE
>> 40 ROT_TWO
42 POP_TOP
44 RETURN_VALUE
explained is just:
x
value2
valuemodulo
comparison between 2
and x
, the answer is 0
when you use 12
as the param value.0
valuex
valueand
comparison between 0
and x
, naturally, a bitwise operation between any value (eg: b'1100'
) and b'0000'
will return 0
.==
operator. This means as other answers said (x % 2) == (0 & x)
at this time, with x
being 12
, the translated operation is 0 == 0
(True).==
result check if is False (in that case, jump to row 40
of bytecode) else, remove the result (POP) from TOS (Top of stack)6
valuex
valueand
comparison, this time between 6
(b'0110'
) and 12
(x
= b'1100'
) with a result of 4
(b'0100'
)>=
operator with the last stored value (0 >= 4
as said in other answers).0 >= 4
is then, evaluated in the next instruction, False
causes than the code skip directly to the instruction 40
(Return False) without even test the last case.Of course, this is the bytecode explanation of how python works, the short answer is the 0 & n >= 6 & n
thing, with this in mind, we can assume than every number different from 0, will return False to this evaluation, because a bitwise operation between b'0110'
will always be greater than 0.
Bitwise operators are evaluated before Boolean operators.
https://docs.python.org/3.8/library/dis.html Dis module reference.