Coding standards

Guide to coding standards for Q-CTRL projects


Standards for coding style MUST be obtained from the following hierarchy in the order specified:

  1. Third-party
  2. Language
  3. First-party

Third-party

“Third-party” refers to the third-party software you are using and the corresponding Third-party coding standards. For example, if you are using Django, you MUST use the Django coding style. If any of the following conditions hold then you MUST move to Language:

  1. You are not using third-party software
  2. The third-party software does not specify a coding standard
  3. The coding standard does not specify a rule (for example how to name variables)

Language

“Language” refers to the language you are using and the corresponding language coding standards. For example, if you are using Python, you MUST use the PEP 8 – Style Guide for Python Code. If any of the following conditions hold then you MUST move to First-party:

  1. The language does not specify a coding standard
  2. The coding standard does not specify a rule (for example how to name variables)

First-party

“First-party” refers to the Q-CTRL coding standards. The Q-CTRL coding standards exist to specify standards that are not defined in the coding standards of the third-party software or language you are using.

Third-party coding standards

Third-partyStyleDocstringsTestingLinting
DjangoDjango coding stylenumpydoc[++]pytestPylint
ReactAirbnb React/JSX Style GuideJSDocJest and React Testing LibraryESLint and eslint-config-airbnb

Language coding standards

LanguageStyleDocstringsTestingLinting
GoEffective GoGodocgo testGolint
GraphQLGraphQL RulesCommonMark[++]N/Agraphql-schema-linter
HTMLPrettierN/AHTMLProoferN/A
JavaScriptAirbnb JavaScript Style Guide() {JSDocJestESLint and eslint-config-airbnb
MarkdownPrettierN/AN/AMarkdownlint
PythonPEP 8numpydoc[++]pytest, mypyPylint, Black, isort
TypeScriptN/ATSDocJestESLint and eslint-config-airbnb-typescript

Q-CTRL coding standards

Variable naming

Unless prescribed otherwise by the framework or language (as described above), use the following rules when naming variables:

  • Spell variable names out in full using American English spelling (for example optimized_pulse or optimizedPulse and NOT op).
  • For variable names that are more than three words, use an acronym (for example cpmg and NOT carr_purcell_meiboom_gill or carrPurcellMeiboomGill).
  • For variable names that describe how many of an object there are, use <object>_count or <object>Count (for example pulse_count or pulseCount and NOT number_of_pulses, numberOfPulses, pulses_count, or pulsesCount).
  • Capitalize only the first letter of acronyms in camelCase or PascalCase names (for example QctrlApiException or tensorPwc and NOT QCTRLAPIException or tensorPWC).

Docstrings

GraphQL

The CommonMark specification is unopinionated and/or inconsistent in a small number of cases. We therefore adopt the following additional standards.

  • Inline math MUST start with `$ and end with $`:
`$E=mc^2$`
  • Block math MUST have the language set to math:
 ```math
 E=mc^2
 ```
  • Footnote referencing MUST use the following syntax:
This is my sentence with a footnote[^1].

[^1]: My reference.

numpydoc

The numpydoc standard is unopinionated and/or inconsistent in a small number of cases. We therefore adopt the following additional standards.

  • Place the leading and final triple quotes of each docstring on their own lines, with no blank lines separating them from the contents, as follows:
    """
    <contents>
    """
    
  • Use single backticks when referring to a module, function, class, method, parameter, variable, or attribute thereof; otherwise use double backticks (for example `np.array`, `int`, `parameter_1`, `CustomClass.attribute`, `CustomClass.method`, ``value_1*value_2``, ``function().result``, or ``List[int]``).
  • numpydoc’s style for parameter types is too simple for some complex types, in particular involving lists or tuples; we use Python (3.9) syntax to represent them. Moreover, if there are requirements on the dtype or shape of a parameter, we include that information in parentheses. Below are a few examples of how we represent some types.
    hamiltonian : Pwc or SparsePwc
    noise_operators : list[np.ndarray or Tensor or Stf], optional
    lindblad_terms : list[tuple[float, np.ndarray or sp.sparse.spmatrix]]
    tensor : Tensor(scalar, real)
    sample_times : np.ndarray(1D, real), optional