Good practise in Python Part 2: Usability & Style#

In this notebook we will discuss some examples of good practise from the point of view of code usability. Here we are thinking about ways to make our code user friendly, this can be for team members collaborating on a project together, external users picking up your code to use for their own project or simply your future-self when you return to some of your own code after some time has passed. If our code is dense, difficult to read and understand then it will end up underused and you may have to spend additional time explaining what you have done. At worst it will cause bugs or mistakes when a third-party comes along to modify or use it without being able to understand what has been implemented, or why. It is often said that code is read far more often than it is written.

As in the first good practise notebook, it is impossible to cover all of the ways code can optmised for usability. Moreover usability is a more subjective topic; what is most usable depends on many things, including the experience and expertise of the user. There is also sometimes a balance to be struck between usability and code efficiency. For example it might be viewed as more user friendly to program Simpson’s rule for integration using a loop as the sequence of operations becomes a little more visible, however as we saw in Good practise part 1 this comes at a computational cost.

Here we will simply attempt to give some general rules of thumb to help you create readable codes and introduce you to some further reading about conventions and style. Arguably the most important aspect of keeping code usable is consistency, we should choose a particular convention and stick to it.

For instance when we introduced variables and functions we touched upon naming conventions, keeping your names succinct but descriptive helps readers follow the program stucture. Even within this one topic there is a lot of discussion, see here.

Different existing projects will have their own conventions and Python itself has certain style conventions. These have been formalised (to some extent) in the “PEP8” Python style guide.

This style guide gives some suggestions for naming conventions within Python but also some useful pointers for consistent and readable layout of the code. For instance it is suggested that a white space is left either side of an assignment = e.g.

some_variable = 10

which you will have noticed being done throughout the notebooks for this module. Of course this is not essential, the code will still work without the space, but this consistency helps the reader to recognise common code quickly and easily.

Comments#

Code comments are also an important element of programming style and usability. We should always be leaving helpful comments within code cells, i.e. not only a verbose description of your project in a notebook mardown cell, but also short succinct comments regarding the code implementation should appear adjacent to the code itself. As you will have seen we can leave comments using the # symbol, both inline, e.g.

another_variable = 11 # this is a different variable to some_variable

or in a block, e.g.

# --------------------------------
# This cell creates one variable
# --------------------------------

yet_another_variable = 12

Clearly the example above is overkill, we don’t need to occupy this much space for a simple comment, but it demonstrates how comments can be used to enhance the formatting of the code and help the reader follow what is going on.

As you can see, there is a balance to be struck with our comments; too many and we obscure the code itself, too few and the reader has no guidance on the code implementation. A good rule of thumb is never to write a code cell without any comments at all. Another helpful exercise is to try to picture yourself reading the code back in 6 months time; what hints would help you follow what you have done?

Relax, but not too much!#

As with the naming convention article, please don’t get too hung up on all of the conventions desribed in the style guide, we will not penalise infractions of these conventions (and it is likley we do not follow them all to the letter ourselves!) but this is designed to help you create better looking code. What we will penalise is dense code with a lot of inconsistency, no comments and which we find difficult to read and understand!

A few more examples#

Here are a few more examples where usability is a consideration.

When we introduced Python modules and their namespaces we warned against importing as * e.g.

import numpy as *

This creates a readability issue as we cannot tell where functions in our current namespace have originated.

We discussed in Good practise part 1 the WET-vs-DRY principle from the point of view of efficiency, but it also has a readability justification too. The better we compartmentalise our code in functions and modules the easier it is to read the hierarchy of operations. If your primary interest is in the overall structure of the program then you aren’t necessarily interested in the inner-workings of each function and seeing the order of the individual function calls will give you enough of an idea of what is happening where. On the other hand if you are seeking to change one particular part of a program, having that piece separated into a function makes it easier to concentrate on its operation without scrolling through lines and lines of the main code.

Version control#

When working on large projects, perhaps collaborating with other developers, or even just in maintaining your own set of codes, it is quite common for people to use version control software. Such software provides a simple way to save versions of your code as you go, allows you to roll back when you need to, and gives you an easy way to share and collaborate on code.

You may have come across ‘Git’ or ‘GitHub’ while searching for computational resources online, Git is perhaps the most widely used form of version control and GitHub is a service to host and distribute your code repository (other software and platforms are available).

We do not expect you to use version control in your studies for this module, however it is quite common place in industry and academic research, and you may see it if you take a 4000 level computing module, so it is useful to know about. You may come across it, or wish to make use of it, later in your career.


We leave you with…

import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!