Learning Clean Code: Before Getting Code Shamed

Learning Clean Code: Before Getting Code Shamed

Hi Everyone, this is my first article here in Hashnode! And I don't know why I started off with this certain topic. So here it goes -

What is Clean Code?

It is quite a self-explanatory term. From what I learned, the manner in which we follow conventions of keeping our code as clean as possible. Although not simply in terms of algorithmic or system complexity, it is certainly simple and easy in terms of implementation.

Clean code is a coding pattern that is simple to read, analyze, and modify by other programmers. It's simple to write code that only the machine understands or we understand for the time being, but this is inefficient in the long term. We will hardly understand our own code after some days if we don't follow such convention.

“Code is read more than it is written.” ― Daniel Roy Greenfeld

Benefits of Following Clean Code Conventions

  • Clean code
  • Quality of code
  • Readability of code
  • Makes code maintenance easier

giphy.gif

Who will teach us Clean Code Conventions?

A straightforward answer would've been 'Just Google it!', which actually is true! Hehe! But from the way I saw it, it's Self-realization Bro! So there was this time when I was searching for a code from my last term, and the moment I started reading those lines I was like - 'Wait! What is this lo? lo lo? final lo? double lo??'... And that's just the name of functions I used. Yeah! I real dreadful coding pattern indeed!!

I didn't even know back then if there were any conventions so I didn't bother learning! But I was connected to many dev communities and meme pages! Yeah, I learned it from memes.

code_quality.png

I am pretty sure this is somewhat of code shaming or something like that!

And now it was up to Google and Youtube to save me and my code from getting code shamed. I particularly found this conf-talk very interesting and resourceful.

So with that on the line, I'll just list down some conventions for anyone reading this to skim through if they like it:

1. Magic Numbers

A magic number is an arbitrary number in the code that has no context or meaning. Because it makes code difficult to comprehend and maintain, this is considered an anti-pattern. The way code conveys intent is one of the most significant parts of code quality. Because of this obscure intent of magic numbers, they should be avoided.

// Bad practice
for i in range(1,10)
  // do something

// Good practice
numberOfChocolates = 10
for chocolate in numberOfChocolates
    // do something

2. Deep Nested Loops Should Be Avoided

Sometimes we use nested loops that are difficult to understand. Too deep branch nesting is one of the most common mistakes that many newbie programmers make. If a newbie JavaScript programmer writes the multi-layer branch nesting, then there might be multiple curly braces, layer after layer: if { if { if { ... }}}, which is commonly known as "Nested If Statement Hell."

However, Python uses indentation instead of {}, so too deep nested branches will produce more serious consequences than in other languages. For example, too many levels of indentations can easily make the code exceed the limit of words per line specified in PEP8. Let's take a look at the following code:

def buy_fruit(nerd, store):
    """Go to the fruit store to buy apples.

    - First, check if the store is open.
    - If there are apples, buy 1
    - If the money is not enough, go home to take more money.
    """
    if store.is_open():
        if store.has_stocks("apple"):
            if nerd.can_afford(store.price("apple", amount=1)):
                nerd.buy(store, "apple", amount=1)
                return
            else:
                nerd.go_home_and_get_money()
                return buy_fruit(nerd, store)
        else:
            raise MadAtNoFruit("no apple in store!")
    else:
        raise MadAtNoFruit("store is closed!")

The biggest problem with the above code is that it follows the original conditional branching directly, resulting in just a dozen lines of code containing three nested branches.

Such kind of code has poor readability and maintainability. However, we can use a very simple trick "End the function in advance" to optimize the code:

def buy_fruit(nerd, store):
    if not store.is_open():
        raise MadAtNoFruit("store is closed!")

    if not store.has_stocks("apple"):
        raise MadAtNoFruit("no apple in store!")

    if nerd.can_afford(store.price("apple", amount=1)):
        nerd.buy(store, "apple", amount=1)
        return
    else:
        nerd.go_home_and_get_money()
        return buy_fruit(nerd, store)

"End the function in advance" means using a statement such as return or raise to terminate the function in the branch ahead of time. For example, in the new buy_fruit function, when the branch condition is not met, we simply throw an exception and end the code branch. Such kind of code has no nested branches, so it's more straightforward and easier to read.

3. Our Comments Should be Self-Explanatory

Explain Uh Huh.gif

This one is one kind of personal attack on a particular individual. Well, we do believe comments make it easier for people to comprehend later, and they also make it easier for other programmers to collaborate on the same project. But according to coding conventions, if you see comments in your code, it means your code isn't self-explanatory.

“While comments are neither inherently good or bad, they are frequently used as a crutch. You should always write your code as if comments didn’t exist. This forces you to write your code in the simplest, plainest, most self-documenting way you can humanly come up with.” — Jeff Atwood

4. Avoiding Large Functions

When a function or a class is very large, it is recommended that it be divided into multiples. This will make our code more readable, maintainable, and reusable.

Let's say we need to multiply and divide two numbers. We can implement this with one function. However, it is a great idea to divide them in half. Thus, individual functions can be reused across the program if they exist.

5. Avoiding Repetitive Code

similarfaces.jpg

A code block that appears more than once in your code is referred to as repetitive code. In such cases, it's better to turn our code into a function.

6. Variable Naming

To put it straightforward a variable should:

  • Have a meaningful name
  • Preference of being Descriptive Over being Concise
  • Using Consistent Verbs per Concept
  • Avoiding One-Letter Variable Names

I'll end with this final quote from the book 'Clean Code: A Handbook of Agile Software Craftsmanship', Authored by, Robert C. Martin, where he mentioned:

“Indeed, the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code. ...[Therefore,] making it easy to read makes it easier to write.”

bugs.gif

References:

  1. tutorialdocs.com/article/python-conditional..
  2. medium.com/s/story/reflections-on-clean-cod..
  3. youtube.com/watch?v=RMN_bkZ1KM0