I want understand how this word wrap program playing on input

David Raymond David.Raymond at tomtom.com
Thu Apr 4 15:48:58 EDT 2019


> Yep, spotted that too! :-) BTW, your fix also a bug: the last word on a
> line won't be followed by a space (off-by-one). The easiest fix for that
> is to add 1 to line_length initially, another little trick.

> Or, equivalently, to reset current_line_length to -1, which is an elegant hack.

I'm actually going to stand my ground on this one. The incrementing of the line length happens _after_ you've added that word to the line, and the check for length is checking against the length of the new word. So adding the 1 for "the space at the end" won't come into effect until the next word, where you're asking "if I add this new word..." at which point you'll want to have included that space.


So copy and paste wrap to wrap2 and make your changes to wrap2, then run something like this, playing with the line length to check. The pipes show the last allowed position of a character.



def wrap(text, line_length):
    """Wrap a string to a specified line length
    Original Version"""
    words = text.split()
    lines_of_words = []
    current_line_length = line_length

    for word in words:
        if current_line_length + len(word) > line_length:
            lines_of_words.append([]) # new line
            current_line_length = 0
        lines_of_words[-1].append(word)
        current_line_length += len(word)

    lines = [' '.join(line_of_words) for line_of_words in lines_of_words]
    return '\n'.join(lines)

def wrap2(text, line_length):
    """Wrap a string to a specified line length
    Altered Version"""
    words = text.split()
    lines_of_words = []
    current_line_length = line_length

    for word in words:
        if current_line_length + len(word) > line_length:
            lines_of_words.append([]) # new line
            current_line_length = 0
        lines_of_words[-1].append(word)
        current_line_length += len(word) + 1

    lines = [' '.join(line_of_words) for line_of_words in lines_of_words]
    return '\n'.join(lines)

foo = "a b antidisestablishmentarianism c d e f g h i j k l m n o p queue are ess tee you vee doubleyou ecks why zee"

for wrapWidth in range(12, 19):
    print(f"Width = {wrapWidth:d}")
    showWidth = " " * (wrapWidth - 1) + "|"
    print(showWidth)
    print(wrap(foo, wrapWidth))
    print(showWidth)
    print(wrap2(foo, wrapWidth))
    print(showWidth)
    print("\n")


More information about the Python-list mailing list