Bioinformatics is a multidisciplinary field where people come from heterogeneous backgrounds. Some bioinformaticians are hardcore biologists, others have extensive formation in mathematics or computer science. This diversity is very important for the field because it encourages efficient solutions crafted by groups of domain experts. It also makes it easier to transpose solutions from other fields (e.g. statistics, physics or machine learning) to unanswered questions in biology. On the other hand, it is hard for a small bioinformatics team to achieve the perfect solution in terms of software quality, biological soundness and mathematical elegance. In the current state of affairs, it seems like the quality of the written software is the biggest victim of the high level of specialization and expertise needed to contribute interesting solutions to biological problems.

My goal here is not to further criticize the quality of the published code, but to illustrate some simple steps that could help the community create more robust software that is more likely to be useful, bug free and widely used. The tips exposed in this post also aim to make it easier to collaborate on projects. If bioinformaticians follow coding guidelines and good software development practices, it will be easier for third parties to read, understand and appreciate the published code and contribute features or identify bugs.

The guidelines that will be discussed here are the following:

As I work mostly in the Python programming language, this post will give explicit examples using this language, but the concepts are meant to be language agnostic.

1. Source control

This is probably one of the most important things. We have incredible tools to track changes in the code, add features without breaking everything and manage collaborations. The most famous one right now is certainly git . Git is a revision control system written by Linux Torvalds. It allows users to track the evolution of a project by using commits which represent sets of changes in a project tree. Commits are associated with short descriptive messages that can be tracked to explain what changed (and the associated motivations and consequences).

Github is basically a website that puts a very nice interface over git and provides users with a remote server that can be used to centralize code across contributors. Github is free for open source projects which contributed to it’s popularity in the Open Source ecosystem. It also provides cool things like free web hosting for project pages, issue tracking capabilities and good tutorials. Github also integrates really well with services like Read the Docs, a dynamic documentation hosting platform, and Travis CI, a continuous integration service. Github user’s pages also make for very good portfolios because they show both your own projects and open source collaborations which are often viewed positively by employers.

If you are not familiar with Git and Github, I would highly recommend diving into it. They are, at this point in time, crucial for the open source community and can help putting your project on the map and showcase your skills. I think that using git during development can really make it easier to avoid major problems as you can easily see what you have changed and go back in time if needed. It is also a good system to organize releases of your program and to keep a clean production branch and a messier development version (branches are like two divergent copies of a project that can eventually be merged back together).

After publication, the use of Github can be very beneficial as your users will have access to the most recent version of your program. It will also make it easier for them to fix bugs or to add features by forking (copying) your code and then asking you to integrate their changes to your project. This is a lot more interesting and dynamic that having a .zip file in the supplemental material.

2. Coding conventions

In the industry, a lot of companies enforce strict coding guidelines that define how you should name your variables, how many spaces you should use for indentation, etc. This can seem tedious, but it has the advantage of improving readability. It also makes sure that code from collaborative projects is homogeneous which is important for readability and maintainability.

In bioinformatics, people from different backgrounds and varying degrees of experience in software development are asked to find solutions to complex problems and to implement the resulting algorithms as fast as possible. This results in working solutions (usually), but the quality of the written software is often a victim of this process. Another problem is that after publication, newer projects are prioritized and support is often sparse or completely dropped for previous software. Of course, this is not the case for solutions emerging from “big” bioinformatics lab that have the human, financial and technical resources needed to offer good support. Nonetheless, for most laboratories, this is a very real problem that needs to be addressed.

One realistic solution to this problem is to adhere to known and widely adopted development guidelines in terms of coding style. This will make it easier to provide support by making sure the code is clean. Using such conventions also makes it easier to dig in the code of the recently graduated Ph.D. student that is now unreachable. It homogenizes the writing style across lab members, or even, on a larger scale, across developers.

As an example, PEP8 is an official style guide for Python code. Its description is concise and precise and it takes only a few hours to learn it. It was built to improve readability and is widely adopted in the Python community.

It is very easy to verify the pep8ness of your code by installing the pep8 program ( pip install pep8 ) and using it from the terminal: pep8 my_cool_script.py . The tool will then proceed to yell at you until you fix all the inconsistencies. This is a great way to verify compliance and makes it really easy to adopt the style guide.

This example was from Python (because yay Python!), but style guides exist for a lot of different languages. You can check out Google’s style guides to find a guide on your favorite language. At my lab, we use pep8 for Python and try to follow the Google style guide for other languages.

3. Use automatic code documentation systems

Another common problem is bioinformatics is documentation versioning. We all know the feeling of finally finding the command line argument we’ve been looking for and noticing that it doesn’t work since version 2.π.18 rc2. This often happens because the online docs weren’t changed when the new version was rolled out. For the expert user, this usually means going back to the source to find the relevant bit of code. Alternatively, in my experience, people scream, hit their keyboard and use a different tool.

To solve this problem, one can simply make sure that the documentation follows the code by writing it directly in the source files. Tools like sphinx will parse all of your code, extract the documentation and nicely format it in a large variety of formats. As stated earlier, services like Read the Docs can then be used to host the documentation and to update it on new pushes or releases. Using this approach will make it easier to find the current documentation. Users will even be able to easily generate their new, up-to-date, custom version if they want to.

Tools like sphinx also have nice features like automatic search boxes, internal references in your documentation and nice syntax highlighting. The screenshot below shows an example of Sphinx documentation written by my colleague.

Figure 1. Example of Sphinx documentation for the pyGenClean project (written by my colleague Louis-Philippe)

I also want to point out that the quality of the documentation was highlighted by the reviewers, suggesting that it was not done in vain.

4. Write tests

I used to think I was a pretty good programmer. Then, I started writing test and realized that my prior on my own error rate was way off. I can now only hope that I am prudent enough in my testing practices to balance out the fact that any piece of software I write is likely to have bugs. What I mean to say is that writing tests is important (I know you have heard this before…). Unfortunately, the only way to actually realize this is by writing tests. So, if you usually don’t write tests, I dare you do take a random project you have written in the past and to write a test suite. If you get to a decent coverage and all your tests pass flawlessly, you can skip to the next section as you are officially a Programming God™.

In other words, you never know how much you need tests before you write tests, so go ahead and try it if you have never done it. Concretely, I would recommend checking out the built-in unittest module if you are a Python programmer. You should also consider using a service like Travis to test new versions of your code on selected environments as soon as they are pushed to Github. Travis will allow you to add a small badge that tells your users if your build is passing or failing. It will also yell at you by email if you break something.

If you want to learn more about testing, I would recommend checking out Ned Betchelder’s PyCon 2014 talk.

5. (Really) learn your programming language

Programming languages often have little quirks that make them so endearing. Examples of this include boilerplate code such as the if __name__ == "__main__": statement in Python that have very specific uses that might be obscure to newcomers. Taking time to learn about these ubiquitous axioms is necessary, because it will result in a gain of productivity in the long run.

Most importantly, programmers need to use the tools that have been developed to fill gaps that are not covered by the standard library. Examples of this include using numpy, pandas, scipy and matplotlib if you are doing scientific stuff in Python. Thinking in numpy arrays or pandas DataFrame sometimes feels like it’s a completely different language, but the gain in computational performance and ease of development is certainly worth learning some (sometimes weird) syntax. I am by no means an R expert, but I think that a lot of my frustration with the language is caused by my lack of knowledge of tools like dplyr which apparently greatly simplify data manipulation.

My point is that reading about the “meta” of a new language and the solutions that people have been developing is as important as learning the basic syntax of the language. It will help avoid reinventing the wheel by leveraging great communities of strong programmers that have previously shared your needs and concerns.

6. Comply to language paradigms

Most programming languages are built on philosophic ideas and concepts that their creator and community believe in. Sometimes, the manifestation of these ideas is subtle, but it other cases it has been made very clear and explicit. As an example of this, when you type import this in a Python interpreter, you get the following:

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!

These seemingly religious guidelines are example of core ideas and guidelines that are often adopted and accepted in the Python community. I believe that most of them will result in better code, or at least spark discussions that will result in informed decisions about software design.

7. Submit your package to an index

Bioinformatics software is often hard to install and poorly maintained. A good example of this is a .zip file containing some source code and a makefile with absolute paths attached to the publication. Unfortunately, distributing software like this makes it hard to fix bugs and distribute bug fixes. People often get stuck with the flawed 1.0.0 version and end up seeking an alternative tool.

A very simple solution to this problem is to never package the source code in a static media like a journal publication. As proposed earlier, a first step is to use services like Github to manage the source code. A link to the repository can be added to the publication and up to date installation instructions can be provided on the associated web page. This solves most of the issues, but the user still has to do some work that can be avoided.

Submitting the package to an index prior to publishing makes it really easy to install the software with a single command. Python provides the pypi index and R provides CRAN where you can upload your package and allow users to install it via simple commands that resemble the package manager install commands Linux users are familiar with (e.g. apt-get install ). Package repositories also keep track of metadata like author and license information as well as software version. I think that journals should even make uploading packages to public repositories mandatory before publication. This would be a concrete solution to some of the most important criticisms of bioinformatics software.

For instructions on how to package your software using Python, see the Python Packaging User Guide. It’s also useful to look how other project do their packaging. For this, you can visit your favorite project’s Github page.

Conclusion

Finally, I think that the quality of bioinformatics software will increase in the future because of all the great services that make errors harder and harder. The bioinformatics community is constantly growing and attracting very smart and engaging people and I am convinced that the good faith of bioinformaticians will help eliminate bad development practices. I hope that the few suggestions exposed in this post will help in the fight against bugs.

#social #stuff

Comments

Please enable JavaScript to view the comments powered by Disqus.