Numbers (Thousand Separators, Currencies)

Juggling different number formats can be intimidating - but thanks to the power of Jinja, nothing is impossible:

If you are using a Flow to, for example, dynamically generate invoices (see our Hubspot, Clockify & Google Docs Flow on the marketplace), then you might have run into the issues of properly formatting your numbers. Well, fear no more, for the solution is nigh. Just keep on reading.

String Formatting in Python

String formatting in python is extremely powerful and advanced. In fact, it is so complex, it has its own mini-language.

If something feels unclear at any point in this article, or you want to dive even deeper into the topic, you can find the entire documentation for strings in Python here. Good luck.

But, because I like you, I will do my best to save you the detour. So let's get into the juicy details.

The three different Methods of String Formatting

There are three different ways of formatting strings in python - the old one, the new one, and the newest one!

The old-style formatting uses % placeholders for formatting text:

"John Wayne has %d living parents." % 0

Will yield the string "John Wayne has 0 living parents" (poor guy).

The new-style formatting uses {}-brackets for formatting:

"However, John Wayne has {0} friendly Butler, {1}.".format( 1, "Alfred")

This yields the string "However, John Wayne has 1 friendly Butler, Alfred."

The newest style of formatting with string literals, called f-strings, uses curly brackets as well, but there's no need to use .format function anymore:

character = "Bateman"
strength = 1000

f"{character}: I can do {strength} now."

Yields us "Bateman: I can do 1000 now."

As you can see, we can use curly brackets in combination with indices to specify which argument of the .format function should go where in the string. This is especially convenient when inserting a large number of arguments into a string as you won't have to count the previous occurrences of %-signs to know where your argument will end up.

In our Flow Builder, either way will work fine, however, %-replacement can be used with | format , while the {} notation will only work with the Python built-in .format function, so keep that in mind. However, as you will soon see, using the {} notation is more powerful.

Using Python String Formatting for pretty Numbers

If we want to print a float number as a currency somewhere, we will want to make sure that we always print the number with two decimal precision. As you might have already encountered, simply trying to print a float will lead to the shortest float possible, e.g. "18.5", when we really want it to print "18.50".

But here comes the magic: using string formatting, we can tell the tool to always print two decimals!

"%.2f" | format(ourfloat)# or"{:.2f}".format(ourfloat)

will both yield us a number with two decimals precision printed, no matter if the decimals are zero. Note the inclusion of a colon in our new-style formatting, which basically replaces the percentage sign when you want to use the Format Specification Mini-Language.

What am I looking at?

As specified in the relevant Python documentation, the number after the dot (in this case 2) specifies the precision. Want more decimals? Simply increase the number!

The last character inside the brackets specifies the notation of the number to be pasted in (f for fixed point, e for scientific notation, % for percent, just to name a few.

If we want to include thousand separators in our number, we can extend the code, but it will only work using new-style formatting:

"{:,.2f}".format(1500.9)

This code will yield "1,500.90", which is finally what we want to represent currencies. We can even immediately format our string to include a currency sign, e.g.:

"${:,.2f}".format(1500.9)

As only the content of the brackets is replaced, this will yield "$1,500.90".

Printing German Number Notation

Ah yes, the Germans need to use a different way to represent numbers, of course. Maybe your country does too, and you want to switch the thousand separators and the decimal point. We have to get a bit hacky here, but don't worry! It's easy once you see it.

{{ "{:,.2f}".format(price) | replace(",", "X") | replace(".", ",") | replace("X", '"") }}

Woah woah woah, what's going on here?

Well, we are just chaining three different replace functions to get executed once the formatting function is done. So what exactly are we doing here?

  1. The format function gets called and returns our number with American formatting. Current string: 1,500.90, Germans unhappy

  2. If we were to immediately switch the commas for dots, we would be unable to replace the dots with commas, as we would have commas everywhere. So instead we need to use a placeholder (X). Current string: 1X500.90

  3. Now we can switch the dot with a comma. Current string: 1X500,90

  4. Finally, we can replace the X(s) with our dot(s). Final Status: 1.500,90, Germans happy.

That's it! Correctly formatted numbers everywhere, yay!

Once again, if you want to dive deeper into the countless possibilities of string formatting in Python, check out the official documentation for the Python String Library here.

Happy automating!

Last updated