How to write clean code?

Ramesh Adhikari
4 min readDec 14, 2022

--

Introduction

How to write code that could be readable, reusable, and refactor-able is a very challenging and interesting part of software development. Clean code is code that other developers can easily read, understand, and add to. Anyone can write code that a computer can understand, but only a good programmer can write code that humans can understand.

Importance of clean code

  • Create easily maintainable & extensible code
  • Easy to debug & refactor
  • Eventually, you will write unbreakable code
  • Writing clean code might cost you time in the first place, but you will end up spending less time on maintenance.

Following are some guidelines for writing clean code:

Variables

Use meaningful and pronounceable variable names

Bad:

ymdstr = datetime.date.today()

Good:

current_date = datetime.date.today()

Use the same vocabulary for the same type of variable

Bad:

get_user_info()
get_user_data()
get_user_record()

Good:

get_user()

Use searchable names

It’s important that the code we do write is readable and searchable.

Bad:

# What the heck is 86400 for?
time.sleep(86400)

Good:

# Declare them in the global namespace for the module.
SECONDS_IN_A_DAY = 60 * 60 * 24
time.sleep(SECONDS_IN_A_DAY)

Don’t add unneeded context

If your class/object name tells you something, don’t repeat that in your variable name.

Bad:

class Student:
student_name: str
student_address: str
student_phone: str

Good:

class Student:
name: str
address: str
phone: str

Functions

Limiting the number of function parameters is incredibly important because it makes testing your function easier. Having more than three leads to a combinatorial explosion where you have to test tons of different cases with each separate argument.

Zero arguments are the ideal case. One or two arguments are ok, and three should be avoided. Anything more than that should be consolidated. Usually, if you have more than two arguments, then your function is trying to do too much. In cases where it’s not, most of the time, a higher-level object will suffice as an argument.

Bad:

def create_menu(title, body, button_text, cancellable):

Good:

class Menu:
def __init__(self, config: dict):
title = config["title"]
body = config["body"]
# ...

menu = Menu(
{
"title": "My Menu",
"body": "Something about my menu",
"button_text": "OK",
"cancellable": False
}
)

Functions should do one thing

Bad:

def email_clients(clients: List[Client]):
"""Filter active clients and send them an email.
"""
for client in clients:
if client.active:
email(client)

Good:

def get_active_clients(clients: List[Client]) -> List[Client]:
"""Filter active clients.
"""
return [client for client in clients if client.active]
def email_clients(clients: List[Client, ...]) -> None:
"""Send an email to a given list of clients.
"""
for client in clients:
email(client)

Don’t repeat yourself (DRY)

Do your absolute best to avoid duplicate code. Duplicate code is bad because it means that there’s more than one place to alter something if you need to change some logic.

We want to calculate the BMI of five subjects. Here is how we could do it in Python:

Body Mass Index is a simple calculation using a person’s height and weight. The formula is BMI = kg/m2, where kg is a person’s weight in kilograms and m2 is their height in meters squared. A BMI of 25.0 or more is overweight, while the healthy range is 18.5 to 24.9.

# Subject data = [weight_kg, height_m]
subject1 = [80, 1.62]
subject2 = [69, 1.53]
subject3 = [80, 1.66]
subject4 = [80, 1.79]
subject5 = [72, 1.60]
bmi_subject1 = int(subject1[0] / subject1[1]**2)
print("bmi {} = {}".format('subject1', bmi_subject1))
bmi_subject2 = int(subject2[0] / subject2[1]**2)
print("bmi {} = {}".format('subject2', bmi_subject2))
bmi_subject3 = int(subject3[0] / subject3[1]**2)
print("bmi {} = {}".format('subject3', bmi_subject3))
bmi_subject4 = int(subject4[0] / subject4[1]**2)
print("bmi {} = {}".format('subject4', bmi_subject4))
bmi_subject5 = int(subject5[0] / subject5[1]**2)
print("bmi {} = {}".format('subject5', bmi_subject5))

The code produces the expected output:

bmi subject1 = 30
bmi subject2 = 29
bmi subject3 = 29
bmi subject4 = 24
bmi subject5 = 28

While the above code works, it requires a lot of typing, retyping, and cut-and-pasting.

It is a good idea to adhere to the DRY principle when writing computer code: don’t repeat yourself. If we cut and paste code to reuse it in various places, we may at some point realize our code contains an error and have to fix the error in all the places we pasted and used our code. Often times we forget to fix one of the pasted pieces of code, and we will be confused why our code does not work. Just imagine if we made a mistake in our BMI formula, we would have to fix our mistake five times in the above code.

final improvement

The above code works well. However, we had to copy-and-paste the call to our function for each subject and remember to change the subject number.

The final version of our code is below. We now use a list of lists to hold our subjects’ data. Each internal list holds the data for a subject, and we have added the subject number along with their weight and height. Our code now uses a for loop to call our bmi_calc() function for each subject.

def bmi_calc(sub_num, weight_kg, height_m):
"""Calculate BMI from weight in kg and height in meters"""
bmi = int(weight_kg / height_m**2)
subject = 'subject' + str(sub_num)
print("bmi {} = {}".format(subject, bmi))
# Subject data = [weight_kg, height_m]
subjects =[[1, 80, 1.62], # subject1
[2, 69, 1.53], # subject2
[3, 80, 1.66], # subject3
[4, 80, 1.79], # subject4
[5, 72, 1.60]] # subject5
for sub in subjects:
bmi_calc(sub[0], sub[1], sub[2])

--

--