BEST PRACTICES

MolSSI best practices provides a starting point to get into software development operations to ensure that your code is reliable and reproducible while decreasing long-term maintenance requirements, increasing long-term viability, and allow others to work on your code base to assist your own efforts. Before starting into MolSSI best practice one must first think about the user base of a given project whether this is a project only used by yourself, within a small group, or a large community project. If your project is small and personal you may want to consider each topic in detail before implementing while for large community projects each topic is quite crucial.

MolSSI’s best practices center around the following pillars:

Version Control

Version control keeps a complete history of your work on a given project. It facilitates collaboration on projects where everyone can work freely on an part of the project without overriding others’ changes. You can move between past versions and rollback when needed, nothing is lost. Also, you can review the history of your project through commit messages that describe each added change and see what exactly has changed in the contents. You can see who made the changes and when it happened.

This is greatly beneficial whether you are working independently or within a team.

Novice Tutorials:

Intermediate:


Testing and Code Coverage

Software should be tested regularly throughout the development cycle to insure correct operation. Thorough testing is typically an afterthought, but for larger projects it can be essential for ensuring changes in some parts of the code do not negatively affect other parts.

Two main types of testing are strongly encouraged

  • Regression tests – given a known input, does the software correctly and consistently return the correct values?
  • Unit tests – Similar to general testing, except testing is done on much smaller units (such as single functions or classes). This is helpful for catching errors in uncommonly-used parts of the code which may be skipped in general testing. Unit tests can be added as new features are added, resulting in better code coverage.

Recommended:

Tutorials:


Continuous Integration

Continuous integration (CI) automatically runs builds your codes and run your tests on a variety of different platforms. Typically this may be run when new code is committed or before merging experimental code into the main repository. CI useful for catching bugs before they reach your end users, and for testing on platforms that are not available to every developer.

Most CI software and services have webhooks for integration github.

Examples of CI Software/Services:

Examples of projects using CI:


Code Style

Code style is important so that new developers can quickly read and understand new code. While code style is typically quite personal, languages often have at least a few dominant coding styles which are familiar to most programmers in that language. Automatic formatting can enforce a particular coding style, and are often configurable for each project.

Example of a coding style guides:


Documentation

Documentation must be provided to allow for use, development, and maintenance of the code. Documentation is often overlooked by developers since it is tedious and boring, however good documentation is an extremely good habit to develop.

The documentation typically involves several components:

  • Build requirements and dependencies (if applicable)
  • How to compile/build/test/install
  • How to use the software (through the API or through inputs)
  • Some examples

Another aspect of documentation is code documentation. This is very important for further development and maintenance, including by yourself in the future. This typically includes documenting various internal files, functions, and classes; what pieces of code do; and most importantly, the reasoning behind some decisions as to why some code was written a particular way.

Documentation should be kept up to date with changes in the code, which is not an easy task for large, fast-moving codebases. However, slightly out-of-date documentation is generally preferable to no documentation.

It is recommended that the examples provided within the documentation are compiled and/or run regularly (if possible, as part of the testing of the software) to ensure that it does not become neglected and out-of-date, confusing users.

Popular documentation packages:

Examples of good documentation:

  • Pybind11 – A C++/Python binding module
  • Arb – Arbitrary precision math library
  • Eigen – C++ Matrix math library

Build Systems

Generally, at least part of a lot of software must be compiled. Doing this in a clean (and possibly cross-platform) way is not trivial.

However, having a somewhat standard build system makes uptake by new users and developers much easier and makes it more likely that the code will be maintained in the future. Therefore, use of common build systems is encouraged. For most compiled C/C++/Fortran code encountered in computational chemistry, CMake is recommended.


Best Practices in Software Design

Software quality depends on many factors such as: Functionality, usability, performance, reliability, portability, interoperability, scalability, and reusability (see full description here).

There are many aspects that contribute to a good design and to the quality of your software. An important one is to follow the best practices and give thoughts to the design of your software. Lucky, many experienced programmers have developed best practices over a substantial period of time. Those best practices can help inexperienced developers to learn software design easily and quickly.

SOLID:

The first things you can learn that will immediately improve the quality of software is to follow the  the SOLID Principles of Software Design. Following those 5 principles will results in a more understandable, flexible and maintainable code.  You can read more here:

Design Patterns:

Design Patterns are well-thought-of, reusable solutions to common recurring problems that developer face during software development. They are considered a common terminology between experience developers. Design Patterns are general and can be applied to any programming language. It’s also highly encouraged to use Object Oriented Programming (correctly) in large-scale projects. The following are some reference to get you started.

Object Oriented Programming (OOP):

It’s also highly encouraged to use Object Oriented Programming (correctly) in large-scale projects.


External Resources