Coming from a Java background into Python and working my way through CodingBat (Python > Warmup-1 > pos_neg) the following confused me greatly:
>>> True ^ False
True
>>> 1<0 ^ -1<0
False
I appreciate the following:
>>> (1<0) ^ (-1<0)
True
But what is python interpreting 1<0 ^ -1<0 as to return false?
^ has higher precedence than <.
Thus, what is being evaluated is actually 1 < -1 < 0, where 0 ^ -1 = -1
And thus you rightly get False, since the inequality clearly does not hold.
You almost never have to remember the precedence table. Just neatly use parenthesis.
You might want to check this out as well, which discusses an identical situation.
0 ^ -1 equals -1. 1 < -1 < 0 is False since 1 is greater than -1. Python chains relational operators naturally, hence 1 < -1 < 0 is equivalent to (1 < -1) and (-1 < 0).
Related
I want the step by step explanation of the following code:
print(1 | 0 ^ 1 & ~0)
I tried with the output bit (output with first and second bit) and got the answer as 0. The tilde function got me hooked up for some time I found it a bit hard. The answer is 1.
First you must understand what each operator does
| - Bitwise OR: Returns True (1) if either of its operands is 1. e.g.
1 | 0 == True
& - Bitwise AND: Returns True if both of its operands are 1. e.g.
0 & 1 == False
^ - Bitwise XOR: Returns True if only one of its operands is 1. e.g.
0 ^ 1 == True
~ - Bitwise NOT: Flips the bit of its operand.
edit: As noted by Daniel Martin, In Python specifically, it flips all of the bits of an arbitrary integer. The formula would be ~x == -x - 1 e.g.
~0 == -1
Then you must understand the order of bitwise operations
In order of precedence:
~ -> & -> ^ -> |
Solving the expression in that order
1 | 0 ^ 1 & ~0 == 1 | 0 ^ 1 & -1 - ~ is applied first
1 | 0 ^ 1 & -1 == 1 | 0 ^ 1 - & is applied second
1 | 0 ^ 1 == 1 | 1 - ^ is applied third
1 | 1 == 1 - | is applied last
Okay, first let's put some parentheses in that code to show how the order of operations applies in python:
print(1 | 0 ^ 1 & ~0)
becomes
print(1 | (0 ^ (1 & (~0))))
Okay, all good.
Now then, first we'll go through what ~0 means, then we'll consider what 1 & (~0) is, then 0 ^ (1 & (~0)), then 1 | (0 ^ (1 & (~0))).
Because these are all bitwise operations, I'm going to flip back and forth between decimal and binary without warning. I hope you've had a basic introduction to what binary is.
So, first ~0. In languages with integer types that have a specific width, (e.g. in C or C++) ~0 would mean "a value that in binary is all 1 bits, as wide as the type", since ~ means "flip all the bits" and 0 is represented with all bits 0. But since python's integers don't have a specific width that would mean "a value that in binary is an infinite sequence of 1 bits", and so we have to fall back on what it says in the documentation:
The unary ~ (invert) operator yields the bitwise inversion of its integer argument. The bitwise inversion of x is defined as -(x+1). It only applies to integral numbers or to custom objects that override the __invert__() special method.
So ~0 is -1.
Now, what's 1 & (-1) ? Well, in binary 1 is just 1, and -1 is all 1 bits, as large as you might want. So the bitwise & of those two values is just 1, since for bitwise & the output has a 1 bit only where both inputs have a 1 bit.
Now, 0 ^ (1). Well, we know what 0 looks like in binary, and we know what 1 looks like in binary (they look just like decimal), and with ^ the output has a 1 bit only where the output and input differ. So 0 ^ 1 is just 1.
Now 1 | (1). This is just 1, by the definition of |.
In a way, python makes reasoning this out harder than it would be in C or many other languages by not having a fixed size for its integers, so when dealing with ~0 you have to briefly imagine that there's this infinite string of 1s that you're dealing with, but it isn't that bad.
print 1>0 == (-1)<0 # => False
print (1>0) == ((-1)<0) # => True
First line prints False.
Second line prints True
The problem is if according to the order comparison operators are above equality operators.
Shouldn't both lines print True? (Or at least the same thing..)
https://www.codecademy.com/en/forum_questions/512cd091ffeb9e603b005713
Both equality and the greater than and less than operators have the same precedence in Python. But you're seeing something odd because of how an expression with multiple comparison operators in a row gets evaluated. Rather than comparing the results of previous calculations using its rules of precedence, Python chains them together with and (repeating the middle subexpressions).
The expression 1 > 0 == -1 < 0 is equivalent to (1 > 0) and (0 == -1) and (-1 < 0) (except that each of the repeated subexpressions, like -1 only gets evaluated once, which might matter if it was a function call with side effects rather than an integer literal). Since the middle subexpression is False, the whole thing is False.
In the second version, the parentheses prevent the comparison chaining from happening, so it just evaluates the inequalities independently and then compares True == True which is True.
When I execute in python following code
print(0<5<2)
It gives False as output
but same thing in C++
std::cout<<(0<5<2);
returns True
Why this contradiction?
In Python, 0 < 5 < 2 is equivalent to 0 < 5 and 5 < 2.
In C++, it is equivalent to static_cast<int>(0 < 5) < 2.
The Python shorthand is originally inspired by mathematics, but has been so generalized that you can write really strange stuff, like
>>> 1 < 5 in [2,3,4]
False
>>> 1 < 5 in [2,3,5]
True
and confuse all your friends.
Because they are different language that has different syntax and work differently.
In the case of c++, the statement is evaluated from left to right.
0<5 == true
true < 2, this will trigger an implicit conversion from true to 1
1 < 2 == true, which is the end result
Python has different rules for how the language works.
I don't know them, but clearly they lead to different result in this case.
All comparison operations in Python have the same priority, which is lower than that of any arithmetic, shifting or bitwise operation. Thus "==" and "<" have the same priority, why would the first expression in the following evaluate to True, different from the 2nd expression?
>>> -1 < 0 == False
True
>>> (-1 < 0) == False
False
I would expect both be evaluated to False. Why is it not the case?
Python has a really nice feature - chained comparison, like in math expressions, so
-1 < 0 == False
is actually a syntactic sugar for
-1 < 0 and 0 == False
under the hood.
I thought I read somewhere that python (3.x at least) is smart enough to handle this:
x = 1.01
if 1 < x < 0:
print('out of range!')
However it is not working for me.
I know I can use this instead:
if ((x > 1) | (x < 0)):
print('out of range!')
... but is it possible to fix the version above?
It works well, it is your expression that is always False; try this one instead:
x = .99
if 1 > x > 0:
print('out of range!')
Python chained comparisons work like mathematical notation. In math, "0 < x < 1" means that x is greater than 0 and less than one, and "1 < x < 0" means that x is greater than 1 and less than 0.
And. Not or. Both conditions need to hold.
If you want an "or" , you can write one yourself. It's or in Python, not |; | is bitwise OR.
if x > 1 or x < 0:
whatever()
Alternatively, you can write your expression in terms of "and":
if not (0 <= x <= 1):
whatever()
You can do it in one compound expression, as you've already noted, and others have commented. You cannot do it in an expression with an implied conjunction (and / or), as you're trying to do with 1 < x < 0. Your expression requires an or conjunction, but Python's implied operation in this case is and.
Therefore, to get what you want, you have to reverse your conditional branches and apply deMorgan's laws:
if not(0 <= x <= 1):
print('out of range!')
Now you have the implied and operation, and you get the control flow you wanted.