Two simple methods to refactor deeply nested code

If you need more than 3 levels of indentation, you’re screwed!

Shuhan Mirza
5 min readJan 5, 2023
Gif by dkobayahi

“If you need more than 3 levels of indentation, you’re screwed anyway, and should fix your program.” You can find this line in the official linux kernel coding style by Linus Torvalds.

Dealing with deeply nested code is like trying to unravel an infinite set of Matryoshka Dolls — it’s a never-ending task. As software engineers, it’s our responsibility to write code that’s easily readable by our teammates. But sometimes, we come across code that’s so deeply nested, it feels like a monster that needs to be defeated. That’s when it’s time to roll up our sleeves and slay the demon of deep nesting by refactoring the code. Trust me, your peers will thank you for making their lives easier.

How? I will discuss two techniques for refactoring deeply nested code;

  1. Extraction
  2. Inversion

Extraction

Visual representation of code block extraction (Image licensed to author)

Deeply nested code can often be a sign that a block of code is violating the Single Responsibility principle from SOLID — it’s doing too many things, and it’s tough to understand what’s going on. In these cases, it can be helpful to extract code blocks and turn them into their own functions. This will not only make your code more organized and readable, but it will also make it easier to reuse and maintain in the long run.

Let’s see an example of extraction:

#FIXME: extract the process of finding sum
def compute(x: int, y: int) -> int:
if x > y:
sum = 0
for num in range(y, x + 1):
sum += num
return sum
else:
return 0
def process(x: int, y: int) -> int:
sum = 0
for num in range(y, x + 1):
sum += num
return sum


def compute(x: int, y: int) -> int:
if x > y:
return process(x, y) #extracted function
else:
return 0

Inversion

Visual representation of code block inversion (Image licensed to author)

When we’re coding, it’s easy to get caught up in the “happy path” mentality — we focus on the successful outcome and structure our logic accordingly. But this can lead to deeply nested code blocks that are tough to read and understand. That’s where the Guard Clause Pattern (aka the Bouncer Pattern) comes in.

By flipping the progression of our logic and looking for cases where we can return early, we can make our code more readable and maintainable. In other words, we’re bouncing out any cases that don’t meet our success criteria and keeping the party (aka our code) moving along smoothly.

Let’s see an example of code inversion:

#FIXME: invert and add a guard clause
def compute(x: int, y: int) -> int:
if x > y:
sum = 0
for num in range(y, x + 1):
sum += num
return sum
else:
return 0
def compute(x: int, y: int) -> int:
if x <= y: #guard clause
return 0

sum = 0
for num in range(y, x + 1):
sum += num
return sum

Now let’s see what happens if we do both the extraction and inversion,

def process(x: int, y: int) -> int:
sum = 0
for num in range(y, x + 1):
sum += num
return sum


def compute(x: int, y: int) -> int:
if x <= y:
return 0

return process(x, y)

Doesn’t it look better? The refactoring process has improved the code’s readability and reduced cyclomatic complexity.

Another Example

Let’s see another example of deep-nested code and refactor it using above mentioned procedures. I choose UVa-10070 for illustrating the example, which is a fairly easy problem from UVa Online Judge.

Problem

10070 Leap Year or Not Leap Year and …

The ancient race of Gulamatu is very advanced in their year calculation scheme. They understand what leap year is (A year that is divisible by 4 and not divisible by 100 with the exception that years that are divisible by 400 are also leap year.) and they have also similar festival years. One is the Huluculu festival (happens on years divisible by 15) and the Bulukulu festival (Happens on years divisible by 55 provided that is also a leap year). Given an year you will have to state what properties these years have. If the year is not leap year nor festival year, then print the line ‘This is an ordinary year.’ The order of printing (if present) the properties is: leap year → huluculu → bulukulu.

Sample Input

2000
3600
4515
2001

Sample Output

This is leap year.

This is leap year.
This is huluculu festival year.

This is huluculu festival year.

This is an ordinary year.

Solution #1 [ deep-nested code ]

import sys

if __name__ == "__main__":

first_input = True

for line in sys.stdin:
if not first_input: #FIXME
print()
else:
first_input = False

input_year = int(line)

is_leap_year = False
is_huluculu_year = False
is_bulukulu_year = False

if input_year % 4 == 0: #FIXME
if input_year % 100 == 0:
if input_year % 400 == 0:
is_leap_year = True

if input_year % 55 == 0: #FIXME
is_bulukulu_year = True
else:
is_leap_year = True

if input_year % 55 == 0: #FIXME
is_bulukulu_year = True

if input_year % 15 == 0: #FIXME
is_huluculu_year = True

if is_leap_year:
print("This is leap year.")
if is_huluculu_year:
print("This is huluculu festival year.")
if is_bulukulu_year:
print("This is bulukulu festival year.")

if not is_leap_year and not is_huluculu_year and not is_bulukulu_year:
print("This is an ordinary year.")

The above code has been written dangerously deep-nested deliberately.

Solution #2 [ Refactored ]

import sys

FLAG_FIRST_INPUT = True


def print_blank_line_if_not_first_input():
global FLAG_FIRST_INPUT

if FLAG_FIRST_INPUT:
FLAG_FIRST_INPUT = False
return

print()


def check_leap_year(year: int) -> bool:
if year % 400 == 0:
return True
if year % 100 == 0:
return False
if year % 4 == 0:
return True

return False


def check_huluculu_year(year: int) -> bool:
if year % 15 == 0:
return True

return False


def check_bulukulu_year(is_leap_year: bool, year: int) -> bool:
if is_leap_year and year % 55 == 0:
return True

return False


def process_input(year: int):
is_leap_year = check_leap_year(year)
is_huluculu_year = check_huluculu_year(year)
is_bulukulu_year = check_bulukulu_year(is_leap_year, year)

if is_leap_year:
print("This is leap year.")
if is_huluculu_year:
print("This is huluculu festival year.")
if is_bulukulu_year:
print("This is bulukulu festival year.")

if not is_leap_year and not is_huluculu_year and not is_bulukulu_year:
print("This is an ordinary year.")


if __name__ == "__main__":

for line in sys.stdin:
print_blank_line_if_not_first_input()
process_input(int(line))

I refactored solution#1 by code extracting and code inversion. If you think solution#2 can be written in a more readable way, please feel free to comment.

Want to Connect?
If you have any feedback, please ping me on my

LinkedIn: https://linkedin.com/in/shuhanmirza/

--

--