AI Skill Report Card
Manipulating Binary Sequences
Quick Start14 / 15
Python# Three binary sequence types b = b"hello" # bytes: immutable ba = bytearray(b"hello") # bytearray: mutable mv = memoryview(ba) # memoryview: zero-copy view over a buffer # Common conversions bytes([104, 105]) # b'hi' (from ints 0-255) bytes("hi", "utf-8") # b'hi' (from str, encoding required) "hi".encode("utf-8") # b'hi' (preferred str->bytes) b"hi".decode("utf-8") # 'hi' (preferred bytes->str) bytearray(5) # bytearray(b'\x00\x00\x00\x00\x00')
Recommendation▾
Add an example showing error handling for UnicodeDecodeError or malformed binary input to reinforce the pitfalls section
Workflow13 / 15
Progress:
- Identify which type is needed: immutable data (
bytes), mutable buffer (bytearray), or zero-copy view (memoryview) - Construct from the right source (int, iterable of ints, str+encoding, or existing buffer)
- Perform required operations (slicing, concatenation, searching, formatting)
- Convert back to str/list if needed, being explicit about encoding
- Use
memoryviewwhen avoiding copies matters (large buffers, C extensions, file/socket I/O)
Choosing a type
bytes: fixed binary data, dictionary keys, hashable payloads, protocol constants.bytearray: building up binary data incrementally (e.g., parsing, buffering socket reads).memoryview: slicing/reading large buffers without copying; interop witharray,numpy, C buffer protocol.
Construction
Pythonbytes(10) # 10 zero bytes bytes(range(65, 70)) # b'ABCDE' bytearray(b"abc") # mutable copy bytes.fromhex("48656c6c6f") # b'Hello' b"Hello".hex() # '48656c6c6f'
Mutating bytearray
Pythonba = bytearray(b"hello") ba[0] = ord('H') # bytearray(b'Hello') ba.extend(b" world") ba += b"!" del ba[0]
memoryview essentials
Pythondata = bytearray(b"0123456789") mv = memoryview(data) mv[2:5] # <memory> slice, no copy bytes(mv[2:5]) # b'234' materialize when needed mv[0:3] = b"abc" # write-through to underlying buffer mv.tobytes() mv.cast('I') # reinterpret format (e.g., as unsigned ints)
Common operations (shared by bytes/bytearray)
Pythonb"hello world".split(b" ") # [b'hello', b'world'] b"hello".startswith(b"he") # True b"a,b,c".split(b",") b"%s is %d" % (b"x", 5) # printf-style formatting (bytes % since 3.5) b" hi ".strip() b"abc".find(b"b") # 1 b"".join([b"a", b"b"]) # b'ab'
Recommendation▾
Include a struct module example for more complex binary packing/unpacking scenarios
Examples16 / 20
Example 1:
Input: Convert a list of integers [72, 101, 108, 108, 111] to a bytes object and back.
Output:
Pythondata = bytes([72, 101, 108, 108, 111]) # b'Hello' list(data) # [72, 101, 108, 108, 111] data.decode("ascii") # 'Hello'
Example 2: Input: Read a large file in chunks and process without copying. Output:
Pythonwith open("big.bin", "rb") as f: buf = bytearray(f.read()) mv = memoryview(buf) chunk = mv[1024:2048] # no copy, view into buf process(chunk) # functions accepting buffer protocol work directly
Example 3: Input: Build a binary message incrementally then freeze it. Output:
Pythonmsg = bytearray() msg += b"\x01" # header byte msg += len(payload).to_bytes(2, "big") msg += payload frozen = bytes(msg) # immutable for sending/hashing
Recommendation▾
Show a 'bad outcome' example (e.g., O(n²) bytes concatenation) alongside the good pattern for contrast
Best Practices
- Always specify encoding explicitly (
"utf-8") — never rely on defaults across platforms. - Use
bytes.fromhex/.hex()for human-readable binary debugging. - Prefer
int.to_bytes(length, byteorder)andint.from_bytes(...)for fixed-width integer packing instead of manual bit math. - Use
memoryviewto avoid copies when slicing large binary buffers repeatedly. - Use
bytearrayas an accumulator instead of repeatedbytesconcatenation (which is O(n²)). - Compare binary data with
==/in, not by decoding to str first.
Common Pitfalls
- Don't mix
strandbytesin operations (b"a" + "b"raisesTypeError) — always encode/decode explicitly. - Don't forget
bytesis immutable;+=onbytescreates a new object each time (usebytearrayfor loops). - Don't assume
memoryviewslices are independent copies — mutating the original buffer affects the view and vice versa. - Don't call
.decode()without handling potentialUnicodeDecodeErroron untrusted input. - Remember
bytes(int)creates a zero-filled buffer of that length, not a bytes representation of the number — use.to_bytes()for that.