A terminal UI prints each message inside its own ASCII box, with the boxes stacked vertically. Implement
format_boxes(sentences: list[str], max_width: int | None = None) -> list[str]
returning the output lines. Every sentence is a non-empty string of printable ASCII characters (spaces included).
Width. Every box is equally wide: its inner width W equals the longest sentence's length. If max_width is given (>= 1), W = min(longest, max_width).
Lines.
- A border line is
"+" + "-" * (W + 2) + "+". - A text line is
"| " + text + " " * (W - len(text)) + " |"(text left-aligned, padded on the right toW). - Output: a border, then the text lines of sentence 1, a border, the text lines of sentence 2, a border, and so on, ending with a border. Neighbouring boxes share the border between them. No sentences means no lines at all.
Wrapping. A sentence of length <= W is one text line, exactly as given (its spaces are kept). A longer sentence (only possible with max_width) is wrapped:
- Split it into words at spaces; runs of spaces separate words and are otherwise dropped.
- Cut any word longer than
Winto pieces ofWcharacters (the last piece may be shorter); each piece counts as a word. - Fill lines greedily: put words on the current line separated by one space while the line stays
<= Wlong; otherwise start a new line with that word.
If a long sentence has no words at all (it is only spaces), it becomes one empty text line.
format_boxes(["Hello there", "Hi"])
# ["+-------------+",
# "| Hello there |",
# "+-------------+",
# "| Hi |",
# "+-------------+"]
format_boxes(["the quick brown fox", "ok"], max_width=9)
# ["+-----------+",
# "| the quick |",
# "| brown fox |",
# "+-----------+",
# "| ok |",
# "+-----------+"]
format_boxes(["abcdefghij xy"], max_width=4)
# ["+------+",
# "| abcd |",
# "| efgh |",
# "| ij |", ("ij xy" would be 5 > 4)
# "| xy |",
# "+------+"]
Show hint
Compute W first, then build a list of text lines per sentence (one line, or the wrapped lines) and join them with borders. When wrapping, keep the current line as a list of words plus its length, so adding a word costs 1 + len(word).