Various ways to add leading zeros to a number, for instance a wind direction, using Python. Available as a Jupyter Notebook
First some definitions. The wind direction is measured in degrees clockwise from north and represents the direction the wind is blowing from. For instance an easterly wind, i.e. wind blowing from the east has a direction of 90 degrees. Let's generate 16 wind directions from 0 (north) to 337.5 (north by northwest).
interval = 22.5 # degrees assert 360 % interval < 0.001 n = int(360/interval) directions = [interval * x for x in range(n)] print(directions)
[0.0, 22.5, 45.0, 67.5, ... 337.5]
No doubt the most pythonic way to add leading zeros to a bare string, the built-in str.zfill()
method is designed to do just that.
for dir_ in directions: print(str(int(dir_)).zfill(3), str(dir_).zfill(5))
000 000.0 022 022.5 045 045.0 067 067.5 090 090.0 112 112.5 135 135.0 157 157.5 180 180.0 202 202.5 225 225.0 247 247.5 270 270.0 292 292.5 315 315.0 337 337.5
We can immediately see our first quirk: the integer representation truncates decimal values rather than rounding up (as I learned to do at school) or rounding towards the nearest even number (as the Python round() funtion would do).
Very fast and arguably even more readable for people with a good understanding of basic python syntax but no desire to read the docs or explore the obscure corners of the language. Add the maximum possible number of leading zeros and then slice the desired number of digits.
for direction in directions: print(('00'+str(int(direction)))[-3:], ('00'+str(direction))[-5:])
000 000.0 022 022.5 045 045.0 067 067.5 090 090.0 112 112.5 135 135.0 157 157.5 180 180.0 202 202.5 225 225.0 247 247.5 270 270.0 292 292.5 315 315.0 337 337.5
As part of a longer string this allows the number to be inserted with leading zeros. Compatible with all current versions of Python.
for direction in directions: print('Int: {:03d} | Float: {:05.1f}'. format( int(direction), direction) )
Int: 000 | Float: 000.0 Int: 022 | Float: 022.5 Int: 045 | Float: 045.0 Int: 067 | Float: 067.5 Int: 090 | Float: 090.0 Int: 112 | Float: 112.5 Int: 135 | Float: 135.0 Int: 157 | Float: 157.5 Int: 180 | Float: 180.0 Int: 202 | Float: 202.5 Int: 225 | Float: 225.0 Int: 247 | Float: 247.5 Int: 270 | Float: 270.0 Int: 292 | Float: 292.5 Int: 315 | Float: 315.0 Int: 337 | Float: 337.5
From Python 3.6 this is even terser.
for dir_ in directions: print(f'Int: {int(dir_):03d} | Float: {dir_:05.1f}')
Int: 000 | Float: 000.0 Int: 022 | Float: 022.5 Int: 045 | Float: 045.0 Int: 067 | Float: 067.5 Int: 090 | Float: 090.0 Int: 112 | Float: 112.5 Int: 135 | Float: 135.0 Int: 157 | Float: 157.5 Int: 180 | Float: 180.0 Int: 202 | Float: 202.5 Int: 225 | Float: 225.0 Int: 247 | Float: 247.5 Int: 270 | Float: 270.0 Int: 292 | Float: 292.5 Int: 315 | Float: 315.0 Int: 337 | Float: 337.5
By overloading the built-in __str__()
method for the class we can create our own custom string representation of the value.
class WindRecord(int): def __init__(self, direction): self.direction = direction def __str__(self): return f'Wind direction: {self.direction:05.1f} °' for direction in directions: d = WindRecord(direction) print(d)
Wind direction: 000.0 ° Wind direction: 022.5 ° Wind direction: 045.0 ° Wind direction: 067.5 ° Wind direction: 090.0 ° Wind direction: 112.5 ° Wind direction: 135.0 ° Wind direction: 157.5 ° Wind direction: 180.0 ° Wind direction: 202.5 ° Wind direction: 225.0 ° Wind direction: 247.5 ° Wind direction: 270.0 ° Wind direction: 292.5 ° Wind direction: 315.0 ° Wind direction: 337.5 °
Thanks to @clement for comments