Using WorkCycles While Writing Code

Tools

Planning

You might keep tasks in project management software. If you do, grab a task/ticket. Then, on some kind of paper:

  1. Write down the goal you're trying to accomplish in the context of the task.
  2. Start reading the code you intend to modify and write how you intend to modify it.
  3. Try to think of these modifications in terms of the smallest possible git commits.
  4. When you finish planning, you should have a TODO list of code refactorings and additions.

Small Experiments

Whenever planning reveals that I need to use libraries or language features that I haven't mastered, I create a single file experiment to test my understanding of what the finished code should look like. This keeps the working branch for my repository code clean and ensures that I understand how to use the language/library to do what I'm trying to do. When I complete the experiment, I save it for future reference, and then return to my application code with the ability to focus less on how the programming language works and more on what needs to change in my application code. Divided attention is the enemy.

Write Tests as You Go

Writing tests, and ideally using TDD, will help you to get into a flow state and maintain it. Having a test will make it easier to specify concrete goals for WorkCycles.

Take Notes as You Go

Do this on whatever you're using for paper. When I'm debugging, I keep a list of precise hypotheses as to the cause of the bug and I check them off the list as I go. Doing this prevents me from forgetting what I've tried, which is sometimes easy to do with very nasty bugs. The precision of the hypothesis is very important. The more general the hypothesis, the easier it is to inadequately test it.

Filling Out WorkCycles Fields

Starting with the Prepare Phase

What am I trying to accomplish?

Baseline: refactor the private members of the FileScan class to use smart pointers

Stretch: Start putting smart pointers in TokenTree::find()

Why is this important and valuable? It improves the stability and memory management of my application.
How will I know this is complete? When my tests go green.
Potential distractions, procrastination? How am I going to deal with them? Need to rehydrate. Fill my water bottle during Cycle breaks.
Is this concrete / measurable or subjective / ambiguous? Concrete, because I've got tests to confirm that I've solved the problem.
Anything else noteworthy? Remember to git commit small and git commit often.

Moving on to the Work Phase

What am I trying to accomplish this cycle? In FileScan.cpp, dereference a row from relation_.
How will I get started? Line 41 FileScan.cpp, try using get() on the pointer.
Any hazards? How will I counter them? My wife might be waking up and wandering into the office. I will give her a hug, tell her I love her, and then return to my work.
Energy

High (I'm alert and thinking quickly)

Medium (I'm alert enough to think clearly)

Low (I'm sleepy and foggy)

Morale

High (Come at me bro)

Medium (I can likely do this)

Low (There's a tiny lump in my throat, where the crying lives)

Completed Cycle's target?

Yes (Nailed it.)

Half (Almost nailed it, maybe I will rescope.)

No (It nailed me. Must... rescope.)

Did you complete your session's targets?

Yes (All tests are green and all items on my paper plan are crossed out.)

Half (Based on what I've crossed off from my plan, I made significant headway.)

No (A low fraction of items on my plan could be checked off.)

How did this compare to my normal work output? I usually write something like: "Favorably", "Usual" or "Not so hot".
Did I get bogged down? Where? I got bogged down remembering the C++ syntax for writing a template in utilities.h line 40. Good thing I took notes on that syntax for a quick lookup next time.
What went well? How can I replicate this in the future? I kept my commits small, I checked-in frequently with my goals, and I spent a lot of time with all of my tests running green.
Any other takeaways? Lessons to share with others? Stay hydrated, and remember to move around and breathe.

Rescoping

One key to efficient rescoping is providing a good answer to "Why is this important and valuable?" In the past, I answered this question in the context of my life -- like, why is this task personally meaningful? That's an important question, but better addressed elsewhere.

In the example above, I answered the why-question like this "It improves the stability and memory management of my application." The reason I answered the question this way is that it enables me to focus on why I assigned myself these particular tasks in my paper plan. (I could have assigned myself some other tasks.) Answer the why-question at the right level of abstraction and you'll now have a tool to efficiently assign yourself different tasks when you need to rescope.

For example, if I discover that the work I'm doing is trivially easy and I blow through it, I can choose another task in the vein of improving memory management.

If I've misunderstood how to address memory management, focusing on refactoring the wrong class, I still know that the overarching goal is to improve memory management. I can rescope laterally, so to speak, refactoring a different class to accomplish the same goal.

If I discover that the refactoring is a way bigger undertaking than I expected, I can rescope vertically, drilling down to focus on refactoring something smaller (a function or even a variable) in the FileScan class.

Debriefing

Write down the day's date, where your work ended, and what you intend to work on when you resume work. Note specific lines of code you want to address. Then, walk away. Just walk away.

Additional Tips.

Master your tools. Fighting your text editor or constantly having to look up frequently used commandline options will interrupt your flow. Build systems for retrieving snippets and code samples that will enable you to focus on the code you're trying to write and modify.

v1.0