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.

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.

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.

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.

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

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 CoffeeScriptCoffeeScript Is JavaScript Without The HeadachesCoffeeScript Is JavaScript Without The HeadachesI'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.

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.

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.

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.

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.

Anonymous

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 )
"

Anonymous

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!

Anonymous

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:

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

Anonymous

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.

Anonymous

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.

Matthew Hughes is a software developer and writer from Liverpool, England. He is seldom found without a cup of strong black coffee in his hand and absolutely adores his Macbook Pro and his camera. You can read his blog at http://www.matthewhughes.co.uk and follow him on twitter at @matthewhughes.