Deliberate Practice and Coding

Deliberate practice applied to coding offers some unique opportunities. Unlike other skills, like learning to play the cello (to pick one that I have some experience with), you can go very far without a personal mentor. The feedback from the computer is about as objective as it gets. It will let you know exactly how good your code is.

This also helps remove the emotional component – positive and negative – that can sometimes impede progress with an in-person mentor. This doesn’t remove all emotion, however. Just about everyone who’s worked in a professional coding shop has witnessed the rare occurrence of a coder cursing at or even physically attacking their computer because their code isn’t working as expected. Those are surreal moments when an avalanche of cognitive biases and unconscious behavior become visible to all but the coder. That’s a topic for for a different post. Suffice it to say, learning how to control your emotions, channel frustration, and ignite curiosity is part of what distinguishes good coders from great coders.

Which gets met to finding quality feedback. While I’ve made a good living writing mountains of proprietary code for various business and corporations, I earned my coding chops by working on or authoring open source projects. This was the best source I found for getting feedback on my code. It also taught me another important lesson: Do not attach your identity to the code you write. Like any noob, I had a lot of pride in my early code that was pretty much untested outside my little work environment. In the open source world, the feedback was often swift and harsh. Or, at least is was when my identity was attached to it. Learning to separate work product from identity revealed just how much emotional spin I was putting on what was in hindsight reasonable feedback. I have concerns that the current climate in the coding world is opting for soft feedback and good feelings over legitimate and reasonable feedback. This, too, is for another post.

It’s worth giving some thought about the the pros and cons of working with an actual person for mentorship. Along with good instruction, a single mentor will pass along their own limitations and biases. Not necessarily a bad thing, just something to be aware of. So multiple mentors are better than just one, which starts to move down the path of actively participating in open source projects. By “actively” I mean not just contributing code, but studying the code (and it’s history) of existing successful projects. There are usually many ways to solve a problem with software. Work to understand why one approach is better than another. Insights like this are best gained, in my experience, by studying good code.

Somewhat related, if you are working from a book or a training program, actually type in the examples – character by character. Don’t cheat yourself by copy-pasting code examples. This is the muscle memory component to coding that you will find when learning other more physical skills (like playing the cello.) If you really want to experience the gnarly edge, ditch the IDE and code with at text editor. I still do all my coding in vim and this keyboard.

Another approach to deliberate practice is the idea of coding “katas.” This never clicked with me. I attribute this to having studied martial arts for 25 years, most of that time at the black belt level. Mapping the human psycho/physical world and the purpose of katas in the dojo to the machine world is too much of a mis-match. Much is lost in the translation, in my experience. The katas in the dojo, regardless the art form, translated easily to other styles and practices. The coding “katas” are more tightly coupled to the coding language in which they are written. In my view, it’s yet another example of swiping a cool sounding word and concept and force-fitting it to another domain. A software version of cargo cults – expecting form to create function. “Black belt” or “Ninja” coder are other force-fits. Yet again, something for another post.

But those are my limitations. Your experience will no doubt be different. As learning exercises and proficiency tracks, many of the coding “katas” look to be very good.

(For related thoughts on how building your own tools can deepen your understanding of a skill, see “Tools for Practice.” The examples in the article combine software development and cello practice.)

 

Image by Robert Pastryk from Pixabay

Expert 2.0

A common characteristic among exceptionally creative and innovative people is that they read outside their central field of expertise. Many of the solutions they find have their origins in the answers other people have found to problems in unrelated fields. Breakthrough ideas can happen when you adopt practices that are common in other fields. This is a foundational heuristic to open software development. Raymond (1999) observes:

Given a large enough beta-tester and co-developer base, almost every problem will be characterized quickly and the fix obvious to someone. Or, less formally, “Given enough eyeballs, all bugs are shallow.” I dub this “Linus’s Law.” (P. 41)

So named for Linus Torvalds, best known as the founder of the Linux operating system. In the case of the Linux operating system, no one developer can can have absolute expert knowledge of every line of code and how it interacts (or not) with every other line of code. But collectively a large pool of contributing developers can have absolute expert knowledge of the system. The odds are good that one of these contributors has the expertise to identify an issue in cases where all the other contributors may not understand that particular part of the system well enough to recognize it as the source of the agony.

This idea easily scales to include knowledge domains beyond software development. That is, solutions being found by people working outside the problem space or by people working within the problem space in possession of expertise and interests outside the problem space.

Imagine, around 1440, a gentleman from Verona named Luigi D’vino who makes fine wines for a living. And imagine a gentleman from Munich named Hans Münze who punches out coins for a living. Then imagine a guy who is familiar with the agricultural screw presses used by winemakers, has experience with blacksmithing, and knowledge of coin related metallurgy. Imagine this third gentleman figures out a way to combine these elements to invent “movable type.” This last guy actually existed in the form of Johannes Gutenberg.

 

Assuming D’vino and Münze were each experts in their problem space, they very likely found incremental innovations to their respective crafts. But Guttenberg’s interests ranged farther and as a consequence was able to envision an innovation that was truly revolutionary.

But if you, specifically, wish to make these types of connections and innovations, there has to be a there there for the “magic” to happen. Quality “thinking outside the box” doesn’t happen without a lot of prior preparation. You will need to know something about what’s outside the box. And note, there aren’t any limitations on what this “what” may be. The only requirement is that it has to be outside the current problem space. Even so, any such knowledge doesn’t guarantee that it will be useful. It only enhances the possibility for innovative thinking.

There is more that can be done to tune and develop innovative thinking skills. What Bock suggests touches on several fundamental principles to transfer of learning, the “magic” of innovative thinking, as defined by Haskell (2001, pp. 45-46).

  • Learners need to acquire a large primary knowledge base or high level of expertise in the area that transfer is required.
  • Some level of knowledge base in subjects outside the primary area is necessary for significant transfer.
  • An understanding of the history of the transfer area(s) is vital.

To summarize, in your field of interest you must be an expert of both technique and history (lest your “innovation” turn out to be just another re-invented wheel), and you must have a sufficiently deep knowledge base in the associated area of interested from which elements will be derived that contribute to the innovation.

References

Haskell, R. E. (2001). Transfer of learning: Cognition, instruction, and reasoning. San Diego, CA: Academic Press.

Raymond, E. S. (1999) The cathedral and the bazaar: Musings on Linux and open source by an accidental revolutionary. Sebastopol, CA: O’Reilly & Associates, Inc.

 

Image by István Kis from Pixabay

System Dynamics and Causal Loop Diagrams 101

Reading causal loop diagrams can be a little counter-intuitive. It will be important to understand how to read them in order to understanding the dynamic quality of the models that will appear in subsequent posts. The interactions between the various elements and the effects of those interactions on stocks and flows are typically represented by a solid black arrow (Figure 1.)

Figure 1

“A” has an interaction with “B” and that interaction is in the direction of “A” to “B.” But what’s the effect of “A’s” interaction with “B?” To display this effect, a green open head arrow or a red closed head arrow is used to describe the type of interaction between the two elements.

Figure 2
Figure 3

A green open-head arrow (Figure 2) is a direct relationship. A red closed-head arrow (Figure 3) is an inverse relationship.

To help understand these relationships, consider the analogy of being in the driver’s seat of a car. Imagine the car has a constant speed of 40 miles per hour. The car has been designed to go this speed with your feet off the peddles. (Not a particularly safe design feature, I’ll grant. But this is a thought experiment. So ride along with me for a little while. I promise we won’t crash.) Now, when you increase (↑) pressure on the gas peddle the car’s speed increases (↑). If you then decrease (↓) pressure on the gas peddle the car’s speed decreases (↓) until it returns to the original 40 MPH. That’s the direct relationship illustrated between “A” and “B” in Figure 2. As “A” increases, so does “B.” Increase pressure on the gas peddle and the speed of the car increases. As “A” decreases, so does “B.” Decrease pressure on the gas peddle and the car speed decreases until it slows down the the original 40 MPH. More of “A” results in more of “B” (↑↑) while less of “A” results in less of  “B.” (↓↓)

Now for the brake. If you increase (↑) pressure on the brake peddle the car’s speed decreases (↓) – it slows down to something less than 40 miles per hour. Increase the pressure on the brake enough and the car will stop. However, if you decrease (↓) pressure on the brake the car’s speed begins to increase (↑). If you remove all pressure on the brake peddle, the car returns to the constant 40 mile per hour speed. That’s the inverse relationship illustrated between “A” and “B” in Figure 3. As “A” increases, “B” goes the opposite way and decreases. Increase pressure on the brake peddle and the speed of the car decreases. As “A” decreases, “B” goes the opposite way and increases. Decrease pressure on the brake and the speed of the car increases until it is once again moving at 40 MPH. More of “A” results in of less of “B” (↑↓) while less of “A” results in more of  “B.” (↓↑)

For an example of these relationships in action, let’s look at the dynamics behind two cosmic quandaries: Which came first, the chicken or the egg and why do chickens cross the road?

No matter which came first, eggs come from chickens and chickens come from eggs. If the number of eggs increase, the number of chickens will increase. If the number of eggs decrease, the number of chickens will decrease (Figure 4.)

Figure 4

If the number of chickens increase, the number of eggs will increase. If the number of chickens decrease, the number of eggs will decrease (Figure 5.)

Figure 5

These are direct relationships as described for Figure 2. Taken together, the causal loop diagram is shown in Figure 6.

Figure 6

If times are good, there are more and more eggs leading to more and more chickens and Chicken World starts to get a bit crowded. In search of a better life, some of the chickens decide to cross the road (now you know why they cross the road!) Another direct relationship in the system (Figure 7.)

Figure 7

However, life is so good on the other side of the road that chickens never cross back over to where they started. An increase in the number road crossings result in a decrease in the number of chickens. (Figure 8.) This is an inverse relationship as described for Figure 3.

Figure 8

Connecting all the pieces, the very simple causal loop diagram describing Chicken World is shown in Figure 9.

Figure 9

This simple example illustrates how systems stay balanced. If there are too many eggs, leading to too many chickens, more chickens cross the road until the population is restored to a sustainable level. If too many chickens cross the road, the number of chickens decrease and therefore so do the number of eggs which means there are fewer chickens crossing road. Once again, the population is eventually restored to a sustainable level.

That’s all the system dynamics you’ll need to read the causal loop diagrams presented in subsequent posts.