Thodoris Kouleris
Software Engineer
Three (3) rules for readable code
1. Avoid Deeply Nested Code
It’s common, especially among newer developers, to try to handle one case inside another and then handle yet another case within that, and so on.
Example:
if condition1:
if condition2:
if condition3:
# Do something
In this scenario, anyone trying to read the code will struggle significantly. Every time they encounter an if, they need to remember where they are and why. This makes the code harder to read and more difficult to understand.
A Better Approach:
if not condition1:
return
if not condition2:
return
if not condition3:
return
# Do something
To make the above code more readable, we created a helper function and utilized the early return technique. If data is missing, we return. If the user is inactive, we return. If the user’s profile doesn’t exist, we return. This way, the code becomes more readable and easier for the reader to follow without overloading their memory.
2. Extract Variable Checks into Functions
In many cases, variable checks can make code harder to read, requiring you to keep track of what each variable does. A simple way to make your code read like plain text is to extract variable checks into functions. For example:
Before:
if data.users.length > 0:
# Do something
After:
def has_users(data):
return len(data.users) > 0
if has_users(data):
# Do something
In the above block, we created the has_users function. This allows the reader to interpret the code as “if the data has users” rather than deciphering what data.users.length means.
3. Avoid Code Duplication
In programming, it’s important not to write the same code repeatedly. This can simplify future changes to the code. For example, what if you needed to change the text from "User is active and" to "Client is available and"? While this might only appear in two lines in a small example, in a real-world application, such a string might be duplicated across 10 or 20 places. You’d need to find and modify the string in all of those instances. Instead, you can use a function to handle this centrally.
Example:
def log_user_status(user):
print(f"{user.name} is active and {user.status}")
By using this function, you only need to update the logic in one place if changes are required.
Final Code with All Three Improvements:
def has_users(data):
return len(data.users) > 0
def log_user_status(user):
print(f"{user.name} is active and {user.status}")
def process_data(data):
if not data:
return
if not data.is_active:
return
if not has_users(data):
return
for user in data.users:
log_user_status(user)
Why These Rules Are Important
These three rules are crucial for writing readable code and making future changes easier. Even code we wrote today might be hard to remember after three years when modifications are required. If we don’t structure the code to be navigable and readable, we will spend more time developing new features or fixing bugs.