In 1999, the Mars Client Orbiter crashed putting a melancholic end to a $125-million project. The crash happened because two teams responsible for designing two software subsystems of the spacecraft used different units of measurement.

Although a silly bug, it's not immediately clear how to avoid it in a Python program. Let's stick to the unit of measurement problem but in a lower stake situation. Assume you want to calculate someone's Body Mass Index (BMI).

The BMI formula is given by

$$BMI = \frac{weight}{height^2}$$

where weight and height are measured in kilograms and meters respectively.

```
def calculate_bmi(weight: float, height: float) -> float:
return weight / height**2
```

I am Brazilian and would probably not misuse `calculate_bmi`

, since I am used to the metric system. If I were born in the USA, however, I might have wanted to pass `weight`

in pounds and `height`

in feet.

```
# Me
calculate_bmi(82.4, 1.83) # > 24.605094210039116
# American me
calculate_bmi(181.7, 6.00) # > 5.047222222222222
```

One way to avoid this kind of bug is to use mypy with `typing.NewType`

.

```
# bmi.py
from typing import NewType
Kg = NewType('Kg', float)
Meter = NewType('Meter', float)
def calculate_bmi(weight: Kg, height: Meter) -> float:
return weight / height**2
print(calculate_bmi(82.4, 1.83))
```

`bmi.py`

doesn't type-check. Notice I have changed the function annotation but I am still calling it with two floats (`82.4`

, `1.83`

). Mypy – rightfully so – yells at me.

```
$ mypy bmi.py
Argument 1 to "calculate_bmi" has incompatible type "float"; expected "Kg"
Argument 2 to "calculate_bmi" has incompatible type "float"; expected "Meter"
```

To make mypy happy, you need to wrap the numbers in the newly created types `Kg`

and `Meter`

.

```
calculate_bmi(Kg(82.4), Meter(1.83))
```

This style of code is not very pythonic, but it does have its place. Specially,
when the same type (`float`

) can represent two different things (pounds and
kilos). At the very least, you get the correct value of your Body Mass
Index by requiring the caller of `calculate_bmi`

to explicitly declare the unit
of measurement of `height`

and `weight`

. In more critical scenarios, you might end up savingsaved NASA a couple million dollars.