Clean Code

What is it, and how to write it?

Ishaan Sunita Pandita
6 min readFeb 20, 2022

Have a look at the following piece of code. If you want, copy and paste it here to ensure that it runs properly!

#include<iostream>
int
main()
{
int num = 100;//Initialise numstd::cout<<"Number is:"<<num<<std::endl<<"We are going to conduct a small test on this number. Let's check the output!\n"<<std::endl;
std::cout<<(num>100?(num%10==0)?num/10:num+(10-num%10):-num)<<"\n";
if(num>100){
if(num%10 == 0){std::cout<<"It is in the first category";}
else std::cout<<"It is in the second category";}
else
{
std::cout<<"It is in the third category";
}
return 0;
}

If you tried it, you know that it runs perfectly, but were you able to really understand what this code does or how?

If you did, that’s great! You’ve got an excellent sense of how code works and even remarkable perceptive skills; in fact, you’re talented enough to be qualified as better than the majority of code readers out there!

But, if you were not comfortable reading this piece of code, I completely understand why; because at first glance, I can’t understand it either!

This is exactly what this article discusses in detail, so let us understand where this perfectly executable code falters enough to be called Unclean Code; and what we can do to clean it!

Photo by Cookie the Pom on Unsplash

What went wrong & How to correct it?

To understand clean code, we first need to understand what is it that makes code dirty. Let us elaborate on the previous example:

Too crammed to understand!

Look at this section of code:

...
std::cout<<"Number is:"<<num<<std::endl<<"We are going to conduct a small test on this number. Let's check the output!\n"<<std::endl;
std::cout<<(num>100?(num%10==0)?num/10:num+(10-num%10):-num)<<"\n";
...

Crammed code is difficult to even read, let alone comprehend. Apart from this, it can also be difficult to locate errors in such code!

How can we make this code better? Well, separate unique elements of the logic by spacing them out appropriately. Something like this is much easier to understand:

...
std::cout<<"Number: "<<num<<std::endl;
std::cout<<"We are going to conduct a small test on this number. Let's check the output!\n"<<std::endl;int result = num > 100 ?
num%10 == 0 ?
num/10 : num+10 - num%10 : -num;
std::cout<<result<<"\n";
...

One may agree that while this is better, there is a lot of room for improvement. Let us discuss what more can be improved.

Too many empty spaces!

While spacing out pieces of logic is smart, over-spacing can actually be confusing too! Have a look at this section:

#include<iostream>
int
main()
{int num = 100; // Initialise num
...

There is no need to keep this much space between intand main() and before initialising num either. Let us correct that:

#include<iostream>
int main()
{
int num = 100; // Initialising num
...

This is much better. We even incorporated proper spacing for the crammed comment, while removing extra spaces in other parts of code. Great going!

Improper indentation!

While this code is in C++, where indentation plays not more than an aesthetic role, languages like Python will raise an error if the indentation is not correct. Let us see where we went wrong:

...
if num>100{
if(num%10 == 0){std::cout<<"It is in the first category";}
else std::cout<<"It is in the second category";}
else
{
std::cout<<"It is in the third category";
}
...

It is difficult to understand where a block starts or end in this code. Figuring out brackets is a big task here, so let us make it a little easier by formatting it in a clearer manner!

...
if(num > 100)
{
if(num%10 == 0)
std::cout<<"It is in the first category";
else
std::cout<<"It is in the second category";
}
else
std::cout<<"It is in the third category";
...

Nice! Now we can visually differentiate the start and end of blocks!

Inconsistent Syntax Patterns!

Let us observe this piece of code from one of our previous corrections:

...
std::cout<<"Number: "<<num<<std::endl;
std::cout<<"We are going to conduct a small test on this number. Let's check the output!\n"<<std::endl;int result = num > 100 ?
num%10 == 0 ?
num/10 : num+10 - num%10 : -num;
std::cout<<result<<"\n";
...

Well, the keen observer may notice that there are 2 types of line endings we have used here: std::endl and '\n' the new line character. Though there is nothing wrong with doing this, sometimes while reading code, one tends to ‘expect’ a pattern. If we start with '\n' , readers might expect the rest of the strings to end with a '\n' as well. Or vice-versa!

...
std::cout<<"Number: "
<<num
<<std::endl;
std::cout<<"We are going to conduct a small test on this number. Let's check the output!\n"
<<std::endl;
int result = num > 100 ?
num%10 == 0 ?
num/10 : num+10 - num%10 : -num;
std::cout<<result
<<std::endl;
...

Here, we have consistently used std::endl to end our lines, and also emphasized each unique output element in the std::cout stream by spacing them adequately!

Code is not DRY!

Over the course of reading the article, you may have noticed that we have repeatedly typed std:: before calling functions like cout or endl, which lie within its scope.

Although this is considered a good practice while writing code with a large number of external dependencies, this small function does not require any namespace other than std !

Let us ease our work by specifying this in our particular case and abide by the Don’t Repeat Yourself principle:

#include<iostream>
using namespace std;
int main()
{
int num = 100;
cout<<"Number: "
<<num
<<endl
<<"We are going to conduct a small test on this number. Let's check the output!"
<<endl<<endl;
int result = num > 100 ?
num%10 == 0 ?
num/10 : num+10 - num%10 : -num;
cout<<result
<<endl;
if(num > 100)
{
if(num%10 == 0)
cout<<"It is in the first category";
else
cout<<"It is in the second category";
}
else
cout<<"It is in the third category";
return 0;
}

That’s it!

Beautiful! This is beginning to look like an aesthetic and readable piece of code! In fact, this encompasses most of the basics of writing clean code.

If your code looks like the example above, give yourself a pat on the back, you’re doing great!

Brownie Points ?!

Now, one could go ahead and safely say that our work here is done; however, there are a few things left to do that will give us some brownie points as well!

Let me enlist some here:

  1. Using comments where needed
  2. Giving variables names that indicate their purpose
  3. Using functions to keep your code organised, and sometimes, to keep your main() function clean!
  4. Using common naming conventions, like camelCase or snake_case or PascalCase where required

Let us see these incorporated into our code:

#include<iostream>
using namespace std;
int checkNumber(int n)
{
// Returns the value to be displayed for the number 'n'
int result = n > 100 ?
n%10 == 0 ?
n/10 : n+10 - n%10 : -n;
return result;
}
void printCategory(int n)
{
// Classifies the number 'n' based on its value
if(n > 100)
{
if(n%10 == 0)
cout<<"It is in the first category"<<endl;
else
cout<<"It is in the second category"<<endl;
}
else
cout<<"It is in the third category"<<endl;
}
int main()
{
int num1 = 100, num2 = 110, num3 = 109;
cout<<"Numbers:"
<<num1<<'\t'<<num2<<'\t'<<num3
<<endl
<<"We are going to conduct a small test on these numbers. Let's check the output!"
<<endl<<endl;
cout<<checkNumber(num1)
<<endl;
printCategory(num1);

cout<<checkNumber(num2)
<<endl;
printCategory(num2);

cout<<checkNumber(num3)
<<endl;
printCategory(num3);
return 0;
}

Now this is what I call a work of art! This absolute masterpiece of code is divided into functions, which can be used in any combination required, any number of times, and for different inputs! A 3-dimensional victory, if I may call it so.

Summary Time!

We learnt the following properties of Clean Code:

  1. Appropriate spacing
  2. Appropriate indentation
  3. Consistent syntax pattern
  4. Using proper naming conventions
  5. Writing comments to explain the code, only where they are needed!
  6. The DRY Principle — Don’t Repeat Yourself
  7. Divide code into functions for re-usability

Once all items on this checklist are marked complete, you can sit back and relax, because any programmer in this world will be able to read and understand your code without having to strain their brain!

Thank you for reading!

If you liked this article, feel free to follow me on Medium, here, to read more like this one

If you’d like to get in touch, find me on my socials, here!

Have a look at some of my other stories as well:

--

--

Ishaan Sunita Pandita

Living life and becoming better than who I was yesterday. Oh, and also learning magic so I can turn data into money.