7.2 Coding conventions
Contents
7.2 Coding conventions#
Estimated time for this notebook: 10 minutes
One code, many layouts:#
Consider the following fragment of python:
import species
def AddToReaction(name, reaction):
reaction.append(species.Species(name))
this could also have been written:
from species import Species
def add_to_reaction(a_name, a_reaction):
l_species = Species(a_name)
a_reaction.append(l_species)
So many choices#
Layout
Naming
Syntax choices
Layout#
reaction = {
"reactants": ["H", "H", "O"],
"products": ["H2O"]
}
reaction2 = {
"reactants":
[
"H",
"H",
"O"
],
"products": [
"H2O"
]
}
Layout choices#
Brace style
Line length
Indentation
Whitespace/Tabs
Inconsistency will produce a mess in your code! Some choices will make your code harder to read, whereas others may affect the code. For example, if you copy/paste code with tabs in a place that’s using spaces, they may appear OK in your screen but it will fail when running it.
Naming Conventions#
Camel case is used in the following example, where class name is in UpperCamel, functions in lowerCamel and underscore_separation for variables names:
class ClassName:
def methodName(self, variable_name):
self.instance_variable = variable_name
This example uses underscore_separation
for all the names:
class class_name:
def method_name(self, a_variable):
self.m_instance_variable = a_variable
The usual Python convention (see PEP8) is UpperCamel for class names, and underscore_separation for function and variable names:
class ClassName:
def method_name(self, variable_name):
self.instance_variable = variable_name
However, particular projects may have their own conventions (and you will even find Python standard libraries that don’t follow these conventions).
Newlines#
Newlines make code easier to read
Newlines make less code fit on a screen
Use newlines to describe your code’s rhythm.
Syntax Choices#
The following two snippets do the same, but the second is separated into more steps, making it more readable.
big = True
fast = False
color = "brown"
cheap = True
if color == "red" and fast or big and cheap:
print("Vrroom!")
Vrroom!
exciting = color == "red" and fast
practical = big and cheap
if exciting or practical:
print("Vrroom!")
Vrroom!
We create extra variables as an intermediate step. Don’t worry about the performance now, the compiler will do the right thing.
What about operator precedence? Being explicit helps to remind yourself what you are doing.
Explicit operator precedence
Compound expressions
Package import choices
Type Annotations#
Python is dynamically typed, which means if a variable x
is an integer:
x = 32
it is valid in Python to make it into a string or any other type later:
x = "bananas"
This is not the case in a statically typed language, like C++ or Java. Having this flexibility in Python can be convenient but it can also lead to unexpected, and potentially difficult to diagnose, mistakes if variables in your code have different types to what was expected.
For example, consider the following function:
def repeat(x, y, times=2):
return (x + y) * times
repeat("dog", "woof")
'dogwoofdogwoof'
It looks like a function that repeats its inputs a number of times, but what if the inputs are numbers?
repeat(2, 3, times=3)
15
Ah, that’s not what we wanted (we were hoping for 232323).
To help us remember how the function is supposed to be used, we can add type annotations (or type “hints”):
def repeat(x: str, y: str, times: int = 3) -> str:
return (x + y) * times
The syntax variable_name: type
indicates the type each parameter should have (x
and y
are strings, and times
is an integer), and the arrow syntax in function_name(...) -> type
indicates the type of data the function returns (a string for the repeat
function above).
Note that type annotating your code will not change it’s behaviour (Python does not enforce variables to be their annotated types):
repeat(2, 3, times=3)
15
But they form a kind of documentation to help us understand how the function should be used, and there are tools that can use them to diagnose issues in your code (see the “Linters” section).
In this case we could do this to get what we expected originally:
int(repeat("2", "3", times=3))
232323
See the Python documentation for more details on type annotations and the typing
library.
Coding Conventions#
You should try to have an agreed policy for your team for these matters.
If your language or project has a standard policy, use that. For example:
Python: PEP8
Julia: Official style guide