...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
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.
|| is the logical OR in most languages I know of, but I'm pretty sure python only has the or keyword, no shorthand.
Bitwise OR applies the logic to the individual bits in the underlying data. Think about how you would add two large numbers by hand. Write one number above the other and add at each position. Bitwise or is like that, except you OR the two bits in each position instead of adding them.
In your example (you can do an OR with n inputs, the result is 1 if any input is 1):
11001 25 01010 10 00101 5 ----- OR 11111 31
So your code is actually being interpreted as if coin == 31:
I did come across that link but didn't quite understand it. If looking only at 25 | 10, does the code not run as expected because 25 is 5 digits long and 10 is 4 digits long? Is that what's meant by "two equivalent length bit designs"?
If an int is only x bytes long, but y bytes are needed for an action, it's just padded with 0's to the left. So 0b110 = 0b0110 = 0b00000110. Usually you will use either 8, 16, 32 or 64 digits/bits (char, short, int and long respectively, and 1, 2, 4 and 8 bytes long, 1 byte = 8 bits. So you'll usually align it with bytes.) However, for calculating like this removing trailing zeroes can make it more tidy, and sometimes 4 or 2 bits are used too. And bools technically only use 1 bit.
I don't have the answer, but if you are looking to do something like that you could simply do : if coin in (25, 10, 5):
Or use a list but I think using a tuple is better as your values are fixed.
You want the keyword "or" rather than the bitwise operator. Alternatively, use "if coin in {25, 10, 5}". The curly braces denote a set, which is implemented as a hash table, so the lookup will be fast even when the number of choices is large.
Looking thru the mundane file (not Linux access control list) permissions. All those flags are crammed into st_mode. In st_mode, on/off bit at 2^8 is that on?
I'm just now sure when it is appropriate to use '|'. If bitwise operators can only be used with integers (and not floats), what's an example where I can use it.
one small gripe i have is that the repr¹ doesn't handle aliases (ie items with more than one bit set) that well , but tbh its not an easy problem
example to illustrate the problem :
class Foo(enum.Flag):
A = auto()
B = auto()
C = auto()
# no D
AB = 0b0011
CD = 0b1100
print(Foo.AB | Foo.C) # <Foo.A|B|C: 7> NOT <Foo.AB|C: 7>
print(Foo.CD | Foo.A) # <Foo.A|C|CD: 13> NOT <Foo.A|CD: 7>
its a minor thing but it annoys me a bit
[1]: the _name_ member , which is used by __repr__ , of an enum member is actually generated either when the individual enum class is created or when the value is first needed by _missing_ . also the docs call these names surrounded by single underscores "sunder" names