top of page
  • Writer's pictureRahul R

Writing readable, simple and modular code with Clean Code

Clean code is a concept in software engineering that focuses on writing code that is easy to read, understand, and maintain. The goal of clean code is to make software development more efficient and effective by reducing the complexity and improving the quality of the code.

Clean code principles emphasize the importance of readability, simplicity, and modularity in code. It is based on the idea that code is written for humans to read, not just computers to execute. Therefore, code should be easy to understand, follow consistent style, and use clear and descriptive naming conventions.

Some key principles of clean code include:

  1. Write code that is easy to read and understand.

  2. Use descriptive and meaningful names for variables, functions, and classes.

  3. Write small functions and methods that do one thing and do it well.

  4. Keep functions and methods short, ideally no more than 20 lines of code.

  5. Use consistent formatting and style throughout the codebase.

  6. Write code that is easy to test.

  7. Refactor code regularly to improve its quality and maintainability.

By following these principles, developers can create software that is easier to maintain, less prone to bugs, and more likely to meet the needs of the end-users.


1. Write code that is easy to read and understand

def calculate_area(radius):
    """
    Calculates the area of a circle given its radius.
    """
    pi = 3.14159
    area = pi * (radius ** 2)
    return area

In this code, the function calculate_area is clearly named and has a docstring that describes what it does. The variable pi is given a clear name and its value is defined at the top of the function for easy modification if needed. The calculation is performed in a readable manner, and the resulting value is returned with a clear name.

By using clear and descriptive names for variables, functions, and comments, the code is easy to read and understand, making it easier to maintain and modify in the future.


2. Use descriptive and meaningful names for variables, functions, and classes.


An example of using descriptive and meaningful names for variables, functions, and classes in Python :

# Example 1: Descriptive variable names

# Bad example
x = 10
y = 5
z = x + y
print(z)

# Good example
num_students = 10
num_teachers = 5
total_people = num_students + num_teachers
print(total_people)

# Example 2: Descriptive function names

# Bad example
def func1(a, b):
    return a + b

result = func1(2, 3)
print(result)

# Good example
def calculate_total(a, b):
    return a + b

total = calculate_total(2, 3)
print(total)

# Example 3: Descriptive class names

# Bad example
class MyClass1:
    pass

# Good example
class Customer:
    pass

In the examples above, the variables, functions, and classes have been given names that clearly and accurately describe what they represent or do. This makes the code easier to read, understand, and maintain.


3. Write small functions and methods that do one thing and do it well.


An example of a function that does multiple things and a refactored version that follows the "do one thing and do it well" principle:


# Function that does multiple things
def process_data(data):
    if len(data) < 5:
        print("Data is too short")
    else:
        data = data.strip()
        data = data.upper()
        data = data.replace(" ", "-")
        return data

# Refactored function that does one thing
def preprocess_data(data):
    data = data.strip()
    data = data.upper()
    return data

def replace_spaces_with_dashes(data):
    return data.replace(" ", "-")

def process_data(data):
    if len(data) < 5:
        print("Data is too short")
    else:
        data = preprocess_data(data)
        data = replace_spaces_with_dashes(data)
        return data

In the first version of the function process_data, it checks the length of the data, strips whitespace, makes the string uppercase, and replaces spaces with dashes. This function is doing multiple things, which makes it harder to read and understand.


In the refactored version, the function has been split into three smaller functions that each do one thing well: preprocess_data, replace_spaces_with_dashes, and process_data. preprocess_data only strips whitespace and makes the string uppercase, while replace_spaces_with_dashes only replaces spaces with dashes. process_data now calls these two functions to do its work, resulting in a cleaner and more readable code.


4. Keep functions and methods short, ideally no more than 20 lines of code.


An example of a function that follows this clean code principle:

def calculate_average(numbers):
    """
    Calculate the average of a list of numbers.

    Args:
        numbers (list of float): The numbers to calculate the average of.

    Returns:
        float: The average of the numbers.

    """
    if not numbers:
        return 0.0
    
    total = sum(numbers)
    average = total / len(numbers)

    return average

This function takes in a list of numbers and calculates their average. It has a clear and descriptive name, calculate_average, and a docstring that explains its purpose and usage. The function is also short and concise, with only 6 lines of code.


5. Use consistent formatting and style throughout the codebase.


Consistent formatting and style make the code easier to read and maintain. Here's an example of clean code that follows consistent formatting and style:

def calculate_sum(a: int, b: int) -> int:
    """Calculates the sum of two integers"""
    result = a + b
    return result

def main():
    x = 5
    y = 10
    sum = calculate_sum(x, y)
    print(f"The sum of {x} and {y} is {sum}")

if __name__ == "__main__":
    main()

In this example, the code follows the PEP 8 style guide, which is a widely accepted standard for Python code formatting. The functions are short and do one thing well, with descriptive names that make their purpose clear. The variable names are also descriptive, and the code uses type hints to make the function signatures clear.


6. Write code that is easy to test.


Here's an example of how to write code that is easy to test:

class Calculator:
    def add(self, x, y):
        return x + y

    def subtract(self, x, y):
        return x - y

    def multiply(self, x, y):
        return x * y

    def divide(self, x, y):
        if y == 0:
            raise ValueError("Cannot divide by zero!")
        return x / y

In this example, we have a class called Calculator that contains four methods: add, subtract, multiply, and divide. Each method does one thing and does it well, making it easy to test. We can write unit tests for each method to ensure that it is functioning as expected.

Additionally, we have added a check in the divide method to raise a ValueError if the second argument is zero. This ensures that the code will fail fast and explicitly, rather than silently producing incorrect results.


7. Refactor code regularly to improve its quality and maintainability.


Here's an example of refactoring code to improve its quality and maintainability:


Original code:

def calculate_area(radius):
    area = 3.14 * radius * radius
    return area

def calculate_volume(radius, height):
    volume = calculate_area(radius) * height
    return volume

Refactored code:

import math

def calculate_circle_area(radius):
    return math.pi * radius ** 2

def calculate_cylinder_volume(radius, height):
    circle_area = calculate_circle_area(radius)
    volume = circle_area * height
    return volume

In the refactored code:

  • The function calculate_area has been renamed to calculate_circle_area to be more descriptive of what it actually does.

  • The constant 3.14 has been replaced with math.pi for more accurate calculations.

  • The ** operator has been used to calculate the square of the radius instead of using * twice.

  • The function calculate_volume has been renamed to calculate_cylinder_volume to be more descriptive of what it actually does.

  • The function now calls the calculate_circle_area function to calculate the circle area, making it easier to test and reducing code duplication.



16 views0 comments

Recent Posts

See All

How to setup reverse proxy on apache2

To set up a reverse proxy to a local installation using Apache2, you need to configure the Apache Virtual Hosts to forward requests to your local server. Here's a step-by-step guide: Enable Proxy Modu

Comments

Couldn’t Load Comments
It looks like there was a technical problem. Try reconnecting or refreshing the page.
bottom of page