Exercise 3 solution import struct NAME = struct.Struct("<8sH") def pack_record(name, value): return NAME.pack(name.encode("ascii"), value) def unpack_record(raw): name, value = NAME.unpack_from(raw) return name.rstrip(b"\x00").decode("ascii"), value blob = pack_record("temp", 215) print(blob.hex(" ")) # 74 65 6d 70 00 00 00 00 d7 00 print(unpack_record(blob)) # ('temp', 215) print(unpack_record(pack_record("exactly8", 1))) # ('exactly8', 1) print(pack_record("toolongname", 2).hex(" ")) # 74 6f 6f 6c 6f 6e 67 6e 02 00 print(unpack_record(pack_record("toolongname", 2))) # ('toolongn', 2) try: unpack_record(blob[:5]) except struct.error as e: print("struct.error:", e) # struct.error: unpack_from requires a buffer of at least 10 bytes for unpacking 10 bytes at offset 0 (actual buffer size is 5) (Run as written; the output matched the comments. The wording of the final error message may differ between Python versions (check).) Explanation: the "s" code always produces exactly the stated number of bytes. A short name is padded with zero bytes on pack, so rstrip(b"\x00") removes the padding on unpack. A name that is too long is silently cut to 8 bytes with no error, so a careful writer checks the length first. A buffer that is too short raises struct.error, which is the signal that the file is truncated or the offset is wrong.