I'm just going to assume that your bisect()
function is a method of the class you mentioned and that it looks similar to this:
def bisect()
while self.word_wrap() == False:
pass
As far as the word_wrap()
method is concered, I would propose to break it up into smaller methods because small methods are:
1. Easier to Test
Imagine writing a unit test for your word_wrap()
method. You'll need to test whether:
- the text is split into lines correctly
- the lines are split into words correctly
- the line length check does indeed work for every kind of input (say, a line with no words on it)
- the height calculation works as expected
- the returned font object has the correct properties and values
Writing a unit test for the latter bullet point certainly isn't an issue. However, the rest of the method is opaque to any caller (including unit tests), meaning it can not be (unit) tested thoroughly. Breaking all these bullet points up into their own distinct methods will allow you to test them.
2. Easier to Read
Some or even all of the tasks performed need their own variables, their own logic and their own comments, all of which have to be scanned and "organized" by a reader.
2.a. Easier to Understand
From my experience, more than 3 or 4 variables in one function will lead to the reader having to look them up again when reading the rest of the method, regardless of how simple the variables were in the first place. I'm not saying you should never use more than 3 or 4 variables in one method, but I would advise to try and avoid it.
Having multiple methods allows the reader to ignore all the variables that are required to get a smaller task done and instead see the smaller tasks as a method that returns a result, not more, not less. This 'frees' up brainpower that would otherwise be used to remember what a certain variable did and whether it will still be used somewhere else in a function.
... the span of absolute judgment and the span of immediate memory
impose severe limitations on the amount of information that we are able
to receive, process, and remember. By organizing the stimulus input
simultaneously into several dimensions and successively into a sequence
of chunks, we manage to break (or at least stretch) this informational
bottleneck.
http://psychclassics.yorku.ca/Miller/
2.b. Easier to Debug
A bug that can be easily understood is also much easier to debug, simply because it is easy to define what exactly isn't working.
It's the same thing that distinguishes a good bug report ("Firefox freezes when opening SVG file on Win10; logs attached") from a bad one ("Firefox crashes when opening file") or a good SO question ("JS: Uncaught Exception: can not call method foo of bar") from a bad one ("my web site dont works, please fix").
2.c. Easier to Re-Use
Sometime in the future you might have to solve a problem similar to the one you're solving now, for example if you need to fit text into an arbitrary geometric shape instead of just an image (or rectangle, really).
A lot of the smaller tasks, such as splitting the text into lines and words, measuring word size and fitting words into a shape will have to be used again to implement the new feature. Instead of having to refactor these smaller tasks out of one method then, why not split them up into their own methods now?
Finally, imagine how much of this answer you would have already forgotten if it was written without any formatting or bullet points.