Summary

In my last article, I talked about how I had to bend or break my own rules last week. This week, I talk about finding a process that works for yourself.

Introduction

It was a grueling week at work and at home. Nothing specific, just a lot of small stuff that had to be done and I just felt like I was hitting walls getting it done. But amidst that turmoil, I found comfort in being able to get deep into the occasional bit of work. Even if it was only for a half hour here and there, losing my mind in my own work for a while helped me relax. And that relaxing helped me get through the week.

So, this week, I decided to talk about what I have found that helps me get into that mindset, in the hope of helping others with their own journey.

Finding Your Own Groove

Due to a lot of things happening in my personal life and professional life in the past week, I did not get a lot done on the PyMarkdown project. As I have mentioned before, I need to take of my entire life, not just focus on the one project. And it is not like I did not get any work done this past week. It was just the quantity of work done was a lot lower than I hoped for. And while before that might have bothered me at one point in my life, I now realize the fallacy of focusing too much of my life on one thing.

Two thing that helped me accomplish the little work that I did this week was understanding myself and having a good groove to my coding. I will probably do multiple articles in the future on understanding myself, but this week I want to focus on finding that groove. And while I do listen to music while coding, that is not the groove I am talking about. Groove itself is an interesting word. According to Merriam-Webster, there are six separate definitions attributed to the word. The two definitions that I think are most applicable are:

top form

and

the middle of the strike zone in baseball where a pitch is most easily hit

To me, both definitions indicate a place where something is more easily accomplished. When I work, be it professionally or personally, that is the mindset I aim for: keeping my efficiency maxed out.

That is what a groove is about for me. Finding a groove is being able to get into that mindset where I can be as efficient as possible on the task that I am doing. Maybe it is mowing the lawn with headphones on, maybe it is loading the dishwasher with no music on, but some tasks just work better when you get an environment set up that helps you get the job done in what seems like no time. It helps me get the task done, and sometimes it also makes the time taken to perform the task seem like nothing at all.

And for software development, I really have two different grooves.

My Debugging Groove

I believe I have a solid groove for my debugging. As I have mentioned in previous articles, I prefer logging to interactive debuggers as I feel that I can see the entire picture more clearly that way. I will often turn on debug logging and execute the test I am debugging to print out a very verbose log of what happened. I typically do so with a specific area of the Markdown translation that needs addressing, so I quickly try and get to that area of the output. From there, I make sure that the logs show the relevant states that I need to see and go from there.

It might seem boring, but it is what my debugging grove is all about. I start with an okay-ish picture of what I think is going on. My goal is to improve the resolution of that picture to the point where I can spot the problem. Sometimes it is obvious and sometimes it takes a couple of hours, but it seldom fails for me. That process is so ingrained into my tasks that I can easily get into a groove with me, my music, and one terminal output window laid on top of one VSCode window with source code. I get to a place where I do not think about what I am doing, I just think and do.

For me, that is what works: having the data in front of me to help fill in the gaps of the picture that I have in my head. If I had to put some descriptions to the style of debugging, I would probably use words like fluid and dense. I like a lot of organized information and the ability to move as freely as possible through the data. That balance of information just allows me to properly visualize the specific debug tasks that I am undertaking.

Or as Jimmy Fallon might say: “That’s My Jam!”

My Coding Groove

Once I follow that path and I get to a probable reason that my code is not working the way I want it to, that is where my coding groove comes in. Knowing I was drafting this article on Sunday, I saved some “groove code” that I wrote on Saturday:

xyz = False
if container_depth == len(parser_state.token_stack) - 1 and position_marker.index_number == -1:
    xx = -1
    for i in range(1, len(parser_state.token_stack)):
        POGGER.debug("$>stack:$:", i, parser_state.token_stack[i])
        POGGER.debug("$>token:$:", i, parser_state.token_stack[i].matching_markdown_token)
        if parser_state.token_stack[i].matching_markdown_token.is_block_quote_start:
            y = parser_state.token_stack[i].matching_markdown_token.leading_spaces.split("\n")
            xx = len(y[-1])
        elif parser_state.token_stack[i].matching_markdown_token.is_list_start:
            xx = -1
    delta = len(extracted_whitespace) - xx
    POGGER.debug("len(ws)=$", len(extracted_whitespace))
    POGGER.debug("len(containers)=$", xx)
    xyz = xx != -1 and delta >= 4
    if xyz:
        container_level_tokens = [] 
        abc = True

Just for the record, the first sample that I pasted in this article was about four times the size of the above text, but I trimmed it for readability. I was okay in trimming it down because the patterns in the removed code were just repeated patterns from the above code.

And yes, I totally admit the code is ugly. It does not describe what it is doing, it is not nicely organized, and contains a certain amount of cut-and-paste code. But for me, looking at that code when I am in my own groove, it makes total sense to me. With the current context being the task that I am working on, I focus on what changes I need to make to the code to bring it closer to the desired end goal.

Would I ever check in code like this? Nope. But in terms of allowing me to stay in my groove and focus on the problem at hand, it works wonders for me. I do care about code quality and readable code. But none of that really matters until I can get the code working properly. Pretty code that is wonderfully organized just does not matter if it does not work as intended. Therefore, my coding process temporarily cuts that requirement out of the picture to allow me to be more efficient.

If I had to try and related it to a process that most people would recognize, I would associate my process with writing an essay the way I was taught in high school. The debugging phase in the last section is doing the research for the essay. The “groove code” above is me writing out a preface, a body, and a conclusion, keeping things loose until I find a combination of paragraphs that echo the research and connect properly. Once that is done, the rest is just window dressing to make things look good, which is what the next section is about.

After The Groove Is Over

Besides sounding like a great name for a rock song, that process does leave me with cleanup to do once I solve the problem. I do not want to take away the importance of this section by calling it “cleanup” or anything like that. While the hard part is coming up with a working solution, it can also be difficult to express that solution in a way that I will understand when I look at it again two weeks from now. I need to remove the code that is related into its own function, give the function a good name, give the variables a good name, and make sure that I will not look at it later and go “what was I thinking?”

As an example, the first step in cleaning up that code was to move most of it to its own function, __handle_trailing_indent_with_block_quote:

    if (
        container_depth >= len(parser_state.token_stack) - 1
        and position_marker.index_number == -1
    ):
        (
            have_pre_processed_indent,
            container_level_tokens,
            skip_containers_before_leaf_blocks,
            used_indent,
        ) = ContainerBlockProcessor.__handle_trailing_indent_with_block_quote(
            parser_state, extracted_whitespace
        )

Looking at the __handle_pre_processed_indent function that held the earlier version of the code, it was obvious that the new code should have its own function. However, when I was fixing the code, it was also obvious that keeping everything in one place made the most sense. But now that I went from a fixing stage to a quality stage, the priorities shifted. Now it was more about making sure that the change that I made was readable and maintainable.

To that extent, I took some more time to provide each of the variables with a more descriptive name of what it was doing:

    @staticmethod
    def __handle_trailing_indent_with_block_quote(parser_state, extracted_whitespace):
        used_indent = -1
        for stack_index in range(1, len(parser_state.token_stack)):
            POGGER.debug(
                "$>stack:$:", stack_index, parser_state.token_stack[stack_index]
            )
            POGGER.debug(
                "$>token:$:",
                stack_index,
                parser_state.token_stack[stack_index].matching_markdown_token,
            )
            if parser_state.token_stack[
                stack_index
            ].matching_markdown_token.is_block_quote_start:
                split_spaces = parser_state.token_stack[
                    stack_index
                ].matching_markdown_token.leading_spaces.split("\n")
                used_indent = len(split_spaces[-1])
            else:
                assert parser_state.token_stack[
                    stack_index
                ].matching_markdown_token.is_list_start
                used_indent = parser_state.token_stack[
                    stack_index
                ].matching_markdown_token.indent_level
        delta = len(extracted_whitespace) - used_indent
        POGGER.debug("len(ws)=$", len(extracted_whitespace))
        POGGER.debug("len(containers)=$", used_indent)
        have_pre_processed_indent = used_indent != -1 and delta >= 4
        return have_pre_processed_indent, [], have_pre_processed_indent, used_indent

The variable xx became used_indent, the variable i became stack_token and so forth. I also ran my standard tools black, flake8, and pylint on the code to make sure I was not missing anything.

Doing this step any earlier in the change process would have just slowed me down. But with the changes finished and the “groove context” vanishing from my mind, it was the right time to capture that information and reorganize. Capture that context in the naming of the objects as best as I can, and make it look neat.

As a friend of mine once said:

Leave it cleaner that you found it for the next developer. Because remember, that next developer will probably be you.

What Does This Mean For Readers?

As I have said in other articles about process, this is the process that works for me and make me produce the best work. There really is not guide that says, “if your name is Jack, then this is the way you developer software”. I have found that I get little bit of insights from here and there, with more experimentation than success. But even little insights and experiments, whether the outcome is positive or negative, helps me tune my process that much more.

So, for any readers that are looking to improve their process, while I would like to give each reader their own guide to developing at their most efficient: it is up to you. Read articles and see if something that another developer describes in their process speaks to you. Look at other aspects of your life and see if you can transplant things that work in those aspects into your development process.

And please, if nothing else, experiment. Experiment knowing that you can learn from an experiment failing as well as from an experiment succeeding. There is no right answer that works for everyone. Just a patchwork worth of process that is tuned to how you work.

What Was My Experience So Far?

Lots of external stuff, but I am glad I took the time to describe how I work through a change problem. Finding that set of processes that work for me took years, and even then, I tweak and change them as I grow and learn. Regardless, it is good to share and perhaps helps others.

What is Next?

I am making progress on the last batch of scenario tests that were added, but it is slow process. Hoping to get further on that this week. Stay tuned!

Like this post? Share on: TwitterFacebookEmail

Comments

So what do you think? Did I miss something? Is any part unclear? Leave your comments below.


Reading Time

~9 min read

Published

Markdown Linter Beta Bugs

Category

Software Quality

Tags

Stay in Touch