Introduction
The impetus for this post is that I noticed that my approach to writing production software applications was to write code in some kind of sandbox that was outside the repository that I intended to check in.
Goal
My goal was to first prove that I could accomplish the task I needed to do and verify it was correct with no regards as to the code aesthetics or how easy it would be to modify it. The primary purpose was to get something to work. However, it was always with the attitude that the initial code version was in no way shape or manner the final releasable product.
Prototype
I was trying to solve a problem that I discussed in a blog post. I was not totally familiar how within Python:
- I was supposed to launch an external process and capture the output.
- After capturing the output I needed to parse it
- And produce something that was consumable by the OS X diskutil unmount command.
The idea was that the utility would unmount a set of problematic volumes (aka, some pesky time machine volumes).
Source Code Version 1
In my typical fashion, I authored the code delineated in the following figure that met the requirements I just specified.
As I was writing this I noticed that the variables:
output
-
tmLines
, and -
timeMachineVolumes
all declared that they were a list of strings. If ever there was a chance for bugs that is a classic way to introduce them.
Additionally, I am not a big fan of reams and reams of unfettered code. In my opinion, that is unmaintainable. The original code gives hints that it can be refactored. We can deduce this because before each block of code there is a comment that describes its functionality.
The Better Way
The first step was to create specific types for the various transformations. This is really just syntactic sugar but serves to make code more readable and less error prone when refactoring. The following figure shows the transformation.
Next, I needed to re-arrange the code as methods in a class. The following figure shows how I rearranged the original code to make it more understandable for future versions of me.
The results of this refactoring resulted in three methods
⢠_runExternalMountCommand
⢠_extractTimeMachineLines
⢠_extractTimeMachineVolumes
These three methods are called sequentially from the .execute driver method.
Summary
What you should learn is first make your code work correctly. Next, remember that either a future you or someone who did not author the original code will at some point have to update and/or fix it. Thus, construct your code so that it is understandable to humans. Leave explicit hints as to the function of the source code. I would go as far as to say to write code that reads as English and is self documenting. Some people refer to this as literate programming.
I published the original version here
Top comments (0)