...will evaluate as True if coin is equal to the bitwise OR of 25, 10 and 5 - i.e. 31. In other word, it's equivalent to coin == 31. That's because the bitwise OR has precedence over the == operator. See operator precedence in Python.
If I replace the ‘|’ with ‘or’ the code runs just fine.
It probably doesn't. If you replace | with or, you have the statement coin == 25 or 10 or 5 which is always True in the if statement because it's evaluated as (coin == 25) or (not 0) or (not 0) in an if statement.
Thanks. I think I understand why I wouldn't want to use it in this case. But what is an example of where I can use it? This makes me think I should avoid using bitwise operators with integers and keep it to strings only, but I know that's not true from what I've learned.
Aside from operations on bitfields, a bitwise operator can be useful in several "non bits" cases. For instance:
value & 1 evaluates to 1 if value is odd (and will evaluate to True in an if statement) value >> 1 divides value by 2 (integer division)
But usually bitwise operators are for when you want to manipulate bits in values. For instance:
value | 5 returns value with bits 1 and 3 set to True value & 0xffff returns the 16 least-significant bits in value (usually you do this to make sure it will fit in 2 bytes in memory for example) value & (0xffff ^ 5) returns the lower 16 bits of value with bits 1 and 3 set to False
They're quite simple. Just convert the values to binary and apply the applicable truth tables. Just remember operator precedence when you use them, and in doubt, don't trust your luck and apply parentheses generously 🙂
python in general tends toward readability over performance optimisation… you’re right they’re an advanced concept, and i’d say if you ever use bitwise operators in python they should be wrapped in some descriptive and very minimal function: treat it like a black box, because the next person that comes along likely won’t understand what’s happening without a pretty good description
a bit field is just not a descriptive data structure, so manipulate it directly as little as possible
i’d also say that most peoples use of bitwise operators is when unpacking external data formats (network traffic, operating system primitives, files formats, etc) and they’re usually wrapped in data structures that make those things more pythonic
unless you know you need bitwise operators, you probably don’t need bitwise operators
When you're working with the binary representation of numbers.
In your code you had three numbers 25, 10 and 5. If we write those number in binary we get:
25: 0b00011001
10: 0b00001010
5: 0b00000101
(The 0b at the start is just a way of saying "this is binary")
When you do a bitwise-or, it's a bit like adding up but you don't bother with carrying anything. So let's do 25 | 10, starting at the right-hand end going bit by bit (bitwise):
0 | 1 = 1
1 | 0 = 1
0 | 0 = 0
1 | 1 = 1
1 | 0 = 1
0 | 0 = 0 for all the rest
So the result is 0b00011011 which is 27.
So now you're asking "when would I ever need to do such a thing?" and the flippant answer is "you'll know when you need it".
You're looking for more though, I know. Basically computers often put multiple bits of data into bitstreams (long sequences of bits). Think networking and file storage. Constructing these bitstreams is done with bitwise operators like |, &, ^, << and >>. Together they form a different type of maths to what you're used to.
These operators work in a very similar way to how +, -, * and / work. They take two numbers and return a third. If we rewrite your code using operators you're more familiar with...
if coin == 25 | 10 | 5: # if coin == 31
...
if coin == 25 + 10 + 5: # if coin == 40
...
...you can see it's obviously wrong because you're doing one comparison with the result of the operation (addition or bitwise-or), not three comparisons.
Thank you for the thorough explanation. It makes sense to me why I had the error that I did. I'll keep this in mind next time when I consider using a bitwise operator.