In Bit Manipulation Part 1, we looked at how numbers are represented in binary form. That background understanding is necessary for us to look at bitwise operators, which are operators (just like `+`, or `` for numbers) which look directly at the binary digits (or bits) of a number.
In Python, the bitwise operators are:
Operator  Syntax  Summary  Example 

left shift  x << y 
x with bits shifted to the left by y places. Same as x * 2^y 
3 << 2 = 12
Binary representation of 3 is `0b11`. Shifting these bits to the left by 2 places is `0b1100`, which is 12.

right shift  x >> y 
x with bits shifted to the right by y places. Same as x / 2^y 
24 >> 3 = 3
Binary representation of 24 is `0b11000`. Shifting these bits to the right by 3 places is `0b00011`, which is 3.

bitwise AND  x & y  each bit of the output is 1 if the bit in both x AND y are 1, otherwise 0 
21 & 12 = 4
Binary representation of 21 is `0b10101` and 12 is `0b01100`. The output where the bit is 1 only if the bit in both 21 AND 12 are 1 is `0b00100`, which is 4.

bitwise OR  x  y  each bit of the output is 1 if the bit in either x OR y are 1 (including both), otherwise 0 
3  5 = 7
Binary representation of 3 is `0b011` and 5 is `0b101`. The output where the bit is 1 if the bit in either 3 OR 5 are 1 is `0b111`, which is 7.

bitwise EXCLUSIVE OR  x ^ y  each bit of the output is 1 if EXACTLY 1 is 1, otherwise 0 
3 ^ 5 = 6
Binary representation of 3 is `0b011` and 5 is `0b101`. The output where the bit is 1 if EXACTLY 1 bit in 3 OR 5 are 1 is `0b110`, which is 6.

bitwise NOT (or complement)  ~x 
switch each 1 for 0 and vice version. Same as x  1 
~2 = 3
Binary representation of 2 is `0b10`. The output where each bit is switched is is `11111101`, which is 3.
Note!  the `bin()` function in Python returns binary strings, not the binary bits (ie `11111101`), which is the two's complement representation.

In Part 3 of this series we'll look at how we can use these operators in some common scenarios.