prize18-2 Exercise 3: Truncate to a Byte Limit Without Breaking a Character ============================================================================= Idea: a continuation byte always looks like 10xxxxxx, so the byte at the cut position tells you whether you are mid-character. If data[limit] is a continuation byte, the character containing it started earlier, so step back until data[end] is a lead byte or ASCII. You never step back more than three bytes. ex3.py: def safe_truncate(data, limit): if len(data) <= limit: return data end = limit while end > 0 and data[end] & 0xC0 == 0x80: end -= 1 return data[:end] data = "caf\u00e9 \u20ac \U0001F600!".encode("utf-8") print(len(data)) for limit in range(4, 9): cut = safe_truncate(data, limit) print(limit, len(cut), cut.decode("utf-8")) naive = data[:8] print(naive.decode("utf-8", errors="replace")) Real output (Python 3.14): 15 4 3 caf 5 5 café 6 6 café 7 6 café 8 6 café café � Limits 7 and 8 both fall inside the 3-byte euro sign (bytes 6-8), so the safe version keeps only 6 bytes. The naive slice data[:8] ends mid-character and decodes to a replacement character. (Trailing space in the lines for limits 6-8 is the real space character.)