[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

I want understand how this word wrap program playing on input

On Fri, Apr 5, 2019 at 5:34 AM Arup Rakshit <ar at> wrote:
>         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)
> My questions are:
> 1. why  `line_length` is set to `current_line_length` initially?
> 2. In the if clause why `current_line_length` is set back to 0 every time the condition is true.
> 3. Also why that `if` test is required there.

I'll start with questions 2 and 3, then wheel back to #1.

The 'current_line_length' variable is a classic running counter. It
counts something until it hits a limit, then gets reset. Imagine
emulating a vending machine - you add up the coins inserted until it
reaches the value of the product, then dispense the product and reset
the "money inserted" counter to zero. In this case, the word wrapping
is done by saying "will this word fit? If not, go to a new line" for
every word.

So, to come back to question 1: The counter is initially full, rather
than empty, to force the creation of a new line at the start of the
loop. The very first word seen (since a "word" is guaranteed to have
at least one character in it - text.split() makes sure of that) will
be shown up as "nope, won't fit", so the list of lists gets its first
value added to it. As an alternative, it could have been written like

lines_of_words = [ [] ] # one initial line
current_line_length = 0 # the initial line is empty

Depending on the algorithm, sometimes it's easiest to force something
to happen on the first iteration, and sometimes it's easiest to force
it to happen at the end. (And sometimes both.) You'll see tricks like
this in a lot of places.

Hope that helps! :)