<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Bitstring
Bitstring is a pure Python module designed to help make the creation and analysis of binary data as simple and natural as possible. The documentation is really good and this page limits itself to some quick examples.
Step1:  Basics
There are four basic classes for representing binary data
Step2:  Converting to a different format
Step3:  Lengths, slicing and joining
Step4:  Non-byte aligned binary data
This only works for some data types!
Step5:  Packing and unpacking
Packing and unpacking is particularly useful for creating "compound" binary data.
Step6:  Finding and replacing
Step7:  Bit-operations
<ASSISTANT_TASK:>
Python Code:
import bitstring
Explanation: Bitstring
Bitstring is a pure Python module designed to help make the creation and analysis of binary data as simple and natural as possible. The documentation is really good and this page limits itself to some quick examples.
End of explanation
from_hex = bitstring.BitArray('0x0001b3')
from_bin = bitstring.BitArray('0b001100')
from_oct = bitstring.BitArray('0o34100')
from_int = bitstring.BitArray(uint=45, length=8)
from_int_bigendian = bitstring.BitArray(intbe=-32768, length=16)
from_float = bitstring.BitArray(float=10.3, length=32)                     # floats must be 32 or 64 bits long
from_float_littleendian = bitstring.BitArray(floatle=-273.15, length=64)   # floats must be 32 or 64 bits long
from_raw = bitstring.BitArray(bytes=b'\x00\x01\x02\xff', length=28)
from_bool = bitstring.BitArray(True)
from_hex, from_bin, from_oct, from_int, from_int_bigendian, from_float, from_float_littleendian, from_raw, from_bool
Explanation: Basics
There are four basic classes for representing binary data: Bits, BitArray, ConsBitStream and BitStream. Each has advantages and disadvantages but for most applications BitArray will be a good choice.
End of explanation
from_int.bin, from_int.bytes, from_int.uint, from_int.int, from_int.hex, from_float_littleendian.floatbe
Explanation: Converting to a different format
End of explanation
len(from_bool), len(from_float)
from_int[-4:].bin, from_int[:4].int
from_hex + from_int
Explanation: Lengths, slicing and joining
End of explanation
seven_bits = bitstring.BitArray(int=32, length=7)
len(seven_bits), seven_bits.bin
seven_bits.tobytes()     # tobytes() ensures padding to byte-alignment
Explanation: Non-byte aligned binary data
This only works for some data types!
End of explanation
packed = bitstring.pack('bool, int:7, floatbe:32', True, -32, -273.15)
len(packed), packed.bin, packed.bytes
packed.unpack('bool, int:7, floatbe:32')
Explanation: Packing and unpacking
Packing and unpacking is particularly useful for creating "compound" binary data.
End of explanation
list(packed.find('0b0000')), list(packed.findall('0b0000'))
packed.replace('0b0000', '0b1111')
packed.bin
packed.startswith('0b111'), packed.endswith('0b111')
Explanation: Finding and replacing
End of explanation
a = bitstring.BitArray('0b00001111')
b = bitstring.BitArray('0b01010101')
(a).bin, (~a).bin, (a<<2).bin, (a>>2).bin, (a*2).bin, (a&b).bin, (a|b).bin, (a^b).bin
Explanation: Bit-operations
End of explanation
<END_TASK>