Blog Datasheets Home About me Clients My work Services Contact

G2Labs Grzegorz Grzęda

Avoiding code smells and anti-patterns in C and Python programming

July 21, 2023

As developers, we strive to write clean, efficient, and maintainable code. However, as projects grow in size and complexity, it’s easy for code to start exhibiting “code smells” and anti-patterns. In this blog post, we’ll explore some common code smells and anti-patterns in both C and Python programming, and discuss strategies for avoiding them.

Code Smells in C

Duplicated Code

Duplicated code, also known as “Don’t Repeat Yourself” (DRY) violation, occurs when the same or very similar code appears in multiple places within a codebase. This can make maintenance difficult and increases the likelihood of introducing bugs.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// Duplicated Code Example
void processInputA(int value) {
    // logic to process input A
}

void processInputB(int value) {
    // logic to process input B
}

void processInputC(int value) {
    // logic to process input C
}

// Duplicated logic in each function

To avoid duplicated code, we can refactor the common logic into a separate function and call it from the other functions.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// Refactored Duplicated Code
void processInput(int value, int inputType) {
    if (inputType == A) {
        // logic to process input A
    } else if (inputType == B) {
        // logic to process input B
    } else if (inputType == C) {
        // logic to process input C
    }
}

Long Functions

Long functions are difficult to understand, maintain, and test. They are often a sign that a function is doing too much, violating the Single Responsibility Principle.

1
2
3
4
// Long Function Example
void processData(int a, int b, int c, int d, int e, int f, int g) {
    // long and complex logic here
}

To address long functions, we can break them down into smaller, more focused functions that each handle a specific task.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// Refactored Long Function
void processData(int a, int b, int c, int d, int e, int f, int g) {
    processA(a);
    processB(b);
    processC(c);
    processD(d);
    processE(e);
    processF(f);
    processG(g);
}

Anti-patterns in Python

Magic Numbers

Magic numbers are literal values that appear without explanation, making code difficult to read and maintain.

1
2
3
# Magic Numbers Example
def calculate_area(radius):
    return 3.14 * radius**2

Instead of using magic numbers, we should define constants with descriptive names.

1
2
3
4
# Refactored Magic Numbers
PI = 3.14
def calculate_area(radius):
    return PI * radius**2

Nested Control Structures

Nested control structures, such as deeply nested if-else statements and loops, can make code hard to read and understand.

1
2
3
4
5
6
7
8
# Nested Control Structures Example
if condition1:
    if condition2:
        # do something
    else:
        # do something else
else:
    # do something different

To avoid nested control structures, we can use early returns and guard clauses to simplify the logic.

1
2
3
4
5
6
7
# Refactored Nested Control Structures
def calculate_discount(price, customer_type):
    if customer_type == "loyal":
        return price * 0.2
    if customer_type == "new":
        return price * 0.1
    return 0

Conclusion

Code smells and anti-patterns can make code harder to read, maintain, and extend. By being mindful of these issues and applying refactoring techniques, we can improve the quality of our code and make it more maintainable and robust. With the examples and strategies discussed in this post, I hope you can identify and address code smells and anti-patterns in your C and Python code. Happy coding!


➡️ Handling MQTT Message Queuing for C and Python Programmers


⬅️ Implementing MQTT Communication in C and Python Applications: A Step-by-Step Guide


Go back to Posts.