Pinterest Stumbleupon Whatsapp
Ads by Google

When you start to read more and more about software development, you frequently come across the phrase “clean code”. In its purest form, this is code that’s easy for other people to read. It’s expressive and beautiful, and you can easily discern its intent simply by looking at it.

Writing clean code is easier said than done.

Whether you’re an Arduino Getting Started With Arduino: A Beginner's Guide Getting Started With Arduino: A Beginner's Guide Arduino is an open-source electronics prototyping platform based on flexible, easy-to use hardware and software. It's intended for artists, designers, hobbyists, and anyone interested in creating interactive objects or environments. Read More tinkerer, or you’re building Raspberry Pi Raspberry Pi: The Unofficial Tutorial Raspberry Pi: The Unofficial Tutorial Whether you're a current Pi owner who wants to learn more or a potential owner of this credit-card size device, this isn't a guide you want to miss. Read More applications with Python, or you’re even a web developer, there are some useful tips to follow that’ll make your code easier to read by others. Here’s what you need to know.

Be Consistent

Perhaps the first, and most obvious tip, is to be consistent in what you do. A good example of this is following the same patterns when naming functions The Absolute Basics Of Programming For Beginners (Part 2) The Absolute Basics Of Programming For Beginners (Part 2) In part 2 of our absolute beginners guide to programming, I'll be covering the basics of functions, return values, loops and conditionals. Make sure you’ve read part 1 before tackling this, where I explained the... Read More and variables The Basics Of Computer Programming 101 - Variables And DataTypes The Basics Of Computer Programming 101 - Variables And DataTypes Having introduced and talked a little about Object Oriented Programming before and where its namesake comes from, I thought it's time we go through the absolute basics of programming in a non-language specific way. This... Read More . You should pick a naming convention, and stick with it.

So, what naming convention should you use?

Well, if you’re writing Python for Raspberry Pi, the answer is clear. The PEP-8 standard (the barometer for good, clean Python code) says that variable names should be in lowercase, with each word separated by an underscore. For example: gpio_input and moisture_sensor_reading.

Ads by Google

cleancode-arduino

The Arduino style guide implicitly states you should write your variables in what’s known as Camel Case. Here, words aren’t separated by anything, but the first letter of each word is capitalized, except for the first word. For example: buttonPressed and temperatureReading.

There are, of course, other styles of variable naming. The above is simply that is recommended by the official style guides. But whatever you choose, make sure you stick by it, and use the same naming convention throughout your program.

Write Meaningful Comments

Comments are a great way of explaining what your program does. You can state what each function does and each variable represents in your own words. This makes it easy for a third-party to read your code, but also makes your code easier to maintain, as you ultimately understand it better.

But if you don’t write your comments in a way that’s obvious, and expressive, then you might not as well bother.

When writing comments, you should try and explain the why of the code, in addition to the how. Try and make the intent abundantly clear, and say something about the code that it can’t say itself. So, rather than:

// update reading

Consider writing:

// Update the number of times the laser beam has been broken, before tweeting it out

Make sure you write in full, grammatically correct sentences. In addition, the PEP-8 standard for Python says you should always write your comments and variables in English. This makes it easier for others to collaborate with you, should you decide to release your code as open source, as English is pretty much the lingua franca of software development.

The Arduino style guide goes even further, and says you must comment every code block, every for loop, and every variable declaration.

Personally, I think that’s a bit extreme. If you’re writing verbose, expressive variable names, then your code is already self documenting. That said, don’t hesitate to add comments where you think they’re needed. Use your own good judgement.

Simplify Your Code

When you’re learning to develop for the first time How To Learn Programming Without All The Stress How To Learn Programming Without All The Stress Maybe you've decided to pursue programming, whether for a career or just as a hobby. Great! But maybe you're starting to feel overwhelmed. Not so great. Here's help to ease your journey. Read More , you’re often filled with an immense rush of enthusiasm. You read everything you can about your chosen language, framework, or platform. You start encountering concepts you never knew before, and you’re all too eager to use them in your own code.

Things like ternary operators, which allow you to condense the logic of an “if statement” such as this one:


int x = 5;
if ( x < 10) {
 y = 1;
{ else {
 y = 0;
}

Into a single line, like this:

int x = 5; 
int y = (x < 10) ? 1 : 0;
printf("%i\n", y);

Ternary operators are certainly cool, and I encourage you to read up on them. But when you’re writing code that’s easy for others to read, they’re best avoided. That’s just one example, though.

The Arduino style guide also encourages you to avoid pointers, #define statements, and data types other than the standard: boolean, char, byte, int, unsigned int, long, unsigned long, float, double, string, array and void. You should avoid data types like uint8_t, as these are less commonly used, not explained in the documentation, and not terribly terse.

Indent, and Take Advantage of Whitespace

When it comes to writing clean code, Python users are at an advantage, as the standard Python interpreter mandates that all code must be sensibly structured and indented. If you don’t indent after each function and class declaration, and conditional statement, your program simply won’t run.

cleancode-python

On Arduino, there’s nothing stopping you from writing unstructured, compacted code. This, ultimately, is hard to read and hard to maintain.

But there’s nothing stopping you from structuring your code better, either.

First, establish how much you’re going to indent by. You should use the tab key judiciously, as each text editor treats the ASCII code for tab differently, and if you’re sharing your code with someone else, there’s a chance they can inadvertently introduce inconsistencies into your indentation. These inconsistencies can break your program, particularly if you’re using a whitespace-sensitive language like CoffeeScript CoffeeScript Is JavaScript Without The Headaches CoffeeScript Is JavaScript Without The Headaches I've never really liked writing JavaScript all that much. From the day I wrote my first line using it, I've always resented that whatever I write in it always ends up looking like a Jackson... Read More or Python. This article from OpenSourceHacker explains in more detail why the tab key should be avoided.

cleancode-tab

I tend to use four spaces for each indent, but the overall number is up to you. Just so long as you’re consistent.

You can configure your IDE and text editor to treat each tab as a set number of spaces, however, allowing you to use the tab key without the risk of introducing problems. If you use Sublime Text 2, check out their official documentation. If you use Vim, just edit your .vimrc file with these lines. The Arduino editor automatically does this for you, and inserts two spaces whenever you press tab.

Then, you simply need to know where to indent your code. As a good rule of thumb, you should always indent after each function declaration, and after each if, else, for, while, switch, and case statement.

Many editors come with the ability to indent whole blocks of code at once. If you use Sublime Text 2, you can set up a hotkey or keystroke combination. Otherwise, you can use the default combination, which (on OS X) is Cmd+[.  In the Arduino editor, you can fix your file’s indentation automatically by pressing Ctrl+T on Windows and Linux, and Cmd+T on OS X.

It entirely depends on your editor, so read the manual!

Don’t Repeat Yourself

One of the most important mantras of good software development is don’t repeat yourself, which is often shortened to DRY.

Writing DRY code is incredibly important, as it ensures that the logic of your program is consistent, allows you to make a change in once place and have it reflected globally, and you spend less time writing the same thing again and again.

The best way to stay DRY is with a liberal and generous use of functions – encapsulating a repeated task with a block of code you can call again and again – and ensuring that each one is distinct and well written.

cleancode-dry

A good function is short; the PEP-8 guide says little about function length, but Clean Code: A Handbook of Agile Software Craftsmanship by Bob Martin (highly recommended) says that “functions should hardly ever be 20 lines long”. Preferably, they’d be even shorter than that.

Functions should also do exactly one thing. Need a function that does two things? Write two functions.

These tips make it easy to follow the flow of a program, and to ultimately debug it if need be. There’s also an added benefit for Arduino users, who are tightly constrained by storage limitations, as redundancies are removed. This results in smaller programs.

Be Explicit

Another important mantra of software development is “explicit is better than implicit”. It means that your code should pretty much shout what it’s doing at the first glance. The Arduino style guide says that thing like this should be avoided:

if(buttonPressed){ 
 doSomething();
}

Rather, you should make it obvious what’s happening. Instead, write something like this:

if (buttonPressed == True){ 
 doSomething(); 
}

Go Out And Code (Well)

Writing clean code is surprisingly simple. You merely have to be consistent in everything you do, avoid redundancies, and be explicit. Remember, clean code is merely code that’s readable.

There’s a lot of great reading material on this subject. A great starting point is Arduino tutorial and API style guides, followed by the PEP-8 standard if you’re building Python apps for the Raspberry Pi. If you’re using another language (like Javascript on the Tessel board Building The Internet of Things, With Tessel: The Node.js Development Board Building The Internet of Things, With Tessel: The Node.js Development Board Tessel is a new breed of development board that runs entirely on Node.js, and after a successful Kickstarter, they’ve now the reached the point of being available to everyone. Read More ), check Google for an official style guide.

If you’re looking for a more academic reading on the subject, check out Clean Code: A Handbook of Agile Software Craftsmanship by Bob Martin. I mentioned it earlier in this article, and it comes highly recommended. Although it uses Java to illustrate concepts, many of the ideas can be passed on to other languages, like Python and C for Arduino.

There’s also some brilliant blog posts online that illustrate how to write good, descriptive, clean code. I recommend you check out “Clean, high quality code: a guide on how to become a better programmer” by Arash Arabi writing for butterfly.com.au, and “The Fundamentals of Writing Clean Code” by Chris Reynolds, writing for webdevstudios.com.

Although not explicitly related to clean code, it’s also helpful to learn what functions and libraries are best avoided in your language of choice. For example, if you’re learning PHP, you should avoid the “mysql” libraries, and if you’re building physical products with Arduino, you should never use the Delay function Arduino Delay Function, and Why You Shouldn't Use it Arduino Delay Function, and Why You Shouldn't Use it While delay() is handy for basic demonstrations of how Arduino works, you really shouldn't be using it in the real world. Here's why, and what you should use instead. Read More .

Remember, code that’s easier to read is easier to maintain. Plus, should you ever get stuck with something, it’s easier for someone to read it and help you.

Do you have any tips for writing clean code? Did I miss anything? Tell me! Leave me a comment below, and let me know.

Photo Credits: Dry Bed (Premasagar), Little TAB Key (Kai Hendry), 2015 (Wikilogia)

  1. Christopher HasARightToPrivacy
    September 10, 2015 at 6:16 am

    One way to write better-looking code for Arduino might be to ditch the Arduino IDE and pick up something else a little more modern. An article reviewing the various environment choices might be fun.

  2. Martin Green
    September 9, 2015 at 4:15 am

    Ok. I think I figured out why the last part of the code example for boolean value assignment got stripped from both my previous posts. It looks like the "less than" and "greater than" symbols are being interpreted as an HTML tag. I will try using LT for the less than symbol and GTE for greater than or equal. Just tack this on to the end of my previous post, substituting LT and GTE where needed:

    "If the two assignments from the original block are reversed like this…

    if ( myVar1 LT 10 ) {
    myVar2 = False;
    } else {
    myVar2 = True;
    }

    … then you can either just negate the result of the expression, like this…

    myVar2 = ! ( myVar1 LT 10 )

    ... or you can use inverse logic to rewrite the expression...

    myVar2 = ( myVar1 GTE 10 )
    "

  3. Martin Green
    September 9, 2015 at 4:03 am

    I noticed after posting that this site strips leading spaces from lines, making it impossible to indent code properly. Rest assured the code was pretty before posting it. ;-)

    Also, for some reason the editor stripped out a little from the middle of my previous comment when it was posted. The section about assigning a boolean value to a variable depending on the result of a comparison should have looked this this...

    Here is one that I see all the time with inexperienced programmers…

    if ( myVar1 < 10 ) {
    myVar2 = True;
    } else {
    myVar2 = False;
    }

    Never, never, never, never code it this way (I see this all the time too from junior developers). You already have a True/False expression in the argument to "if()"so just use it directly:

    myVar2 = ( myVar1 < 10 )

    You don't actually need the parenthesis but I like to use them to make it more clear what is being done here. If the two assignments from the original block are reversed like this…

    if ( myVar1 < 10 ) {
    myVar2 = False;
    } else {
    myVar2 = True;
    }

    … then you can either just negate the result of the expression, like this…

    myVar2 = ! ( myVar1 = 10 )

    • Mihir Patkar
      September 9, 2015 at 8:03 am

      Hey Martin, please use pastebin in the future for all your code

    • Matthew Hughes
      September 9, 2015 at 9:05 am

      Hi Martin,

      Again, I think you're confusing inexperience (I'm not inexperienced, btw) with personal style. You're confusing terseness with readability, as though they're the same thing. A huge chunk of my piece was me making the point that they aren't.

      Cheers!

  4. Martin Green
    September 9, 2015 at 3:52 am

    Wow, where to begin? I've been a professional contract programmer for nearly thirty years, and wrote software testing code in my role as a hardware engineer (radar, marine navigation equipment such as satnav, Loran C, etc) for another decade before that. While the article makes some useful and valid points it is DEAD WRONG about others.

    First, ternary operators actually SIMPLIFY code, and unless they are abused, generally make it not only more concise, but considerably more readable too. The example given in the article fails to point out the most important attribute of ternary operators... that they are an "expression", not a "block". As such, they can be plugged into your code anywhere you might otherwise use a single value such as a variable, thereby saving valuable storage space on the stack or heap. The two bits of sample code from the article are not equivalent, and the ternary version isn't optimized. Consider these instead:

    int x = 5;
    if ( x < 10 ) {
    y = 1;
    } else {
    y = 0;
    }
    printf( "%i\n", y );

    vs.

    int x = 5;
    printf( "%i\n", ( x < 10 ) ? 1 : 0 );

    It is ludicrous to suggest that the latter is inferior to the former, or that the latter is somehow difficult to read or understand.

    Next, the argument for "being explicit" completely misses the point. The problem is not that the code is missing the "== True", but that the variable is badly named (something that an earlier argument advises against). Rather than cluttering up your code with superfluous comparison operators than any good compiler is going to optimize out anyway, make the content of the variable more obvious...

    if( buttonIsCurrentlyPressed ) {
    doSomething();
    }

    ... or ...

    if( buttonWasPressed ) {
    doSomething();
    }

    I have spent many years mentoring junior programmers, and getting them to stop unnecessarily comparing to True or False is one of the first lessons.

    Finally, here is one that I see all the time with inexperienced programmers...

    if ( myVar1 < 10 ) {
    myVar2 = True;
    } else {
    myVar2 = False;
    }

    Never, never, never, never code it this way (I see this all the time too from junior developers). You already have a True/False expression in the argument to "if()"so just use it directly:

    myVar2 = ( myVar1 < 10 )

    You don't actually need the parenthesis but I like to use them to make it more clear what is being done here. If the two assignments from the original block are reversed like this...

    if ( myVar1 < 10 ) {
    myVar2 = False;
    } else {
    myVar2 = True;
    }

    ... then you can either just negate the result of the expression, like this...

    myVar2 = ! ( myVar1 = 10 )

    One more little tip... learn to use whitespace to improve readability. This...

    myVar = myFunc( ( 2 * myValue ) +1, myArray[ 5 ] )

    ... is considerably more "clean" than...

    myVar = myFunc((2*myValue)+1,myArray[5])

    One "more, more"... although the article alludes to this concept by suggesting that functions not exceed a certain number of lines, the more useful rule is that functions fit entirely on a single screen in your editor without scrolling. As soon as you are forced to scroll to read parts of the function the brain will lose the overall picture of the structure of what it does. You may need to break the function down into subfunctions several times to get each one onto a single screen, but it pays off in spades understanding the procedural flow later.

    ... Ok, last one... promise. Another technique new programmers often overapply once they learn it is recursion. Although it can greatly simplify some procedural problems conceptually, recursion often introduces enough extra overhead to negatively impact performance. Google recursion and factorials for more information. Even though factorials are commonly used in sample code to teach recursion, it is actually DRAMATICALLY faster and more efficient to calculate factorials with "for loops" instead"

    • Matthew Hughes
      September 9, 2015 at 9:02 am

      Hey Martin,

      I appreciate your comments.

      You make some interesting points in your three questions, but I just feel like I've got to remind you that we're not talking about flashy ways to accomplish tasks, or ways to optimize code. We're talking about readability. The ability to glance through code, and simply understand it.

      You make some really interesting points but I worry we're both singing from a slightly different hymn book.

      Regards,
      Matt

    • Christopher HasARightToPrivacy
      September 10, 2015 at 6:13 am

      I like your points and I appreciate opinionated people but...

      "It is ludicrous to suggest that [..] latter is somehow difficult to read or understand."

      I don't think the suggestion is ludicrous and I think you're being a little rigid here. I hate ternary operators and don't use them because they make the code look like garbage to me.

      I also never "simplify" code on my first draft. I tend to make it somewhat "verbose" on purpose. Then, when the code has proven effective, I make another pass, optimize and simplify.

      Anyway, my point is that your way isn't always the best for everybody else.

  5. Brian Wisti
    September 8, 2015 at 7:41 pm

    I think this does a fine job setting the tone for things to remember when you start digging into code. Only quibble is that the clarified comment example is a more detailed "what" rather than a "why." But that's harder to show in a comment apart from its code. I wouldn't complain about coming across a comment like that.

    Mostly this article just reminds me that I've been wanting to dig into Arduino & Raspberry Pi.