Context
I am receiving numbers as strings in Python 3 and want to transmit them as strings in order to preserve accuracy so that the upstream server can convert the numbers-as-strings to decimal.Decimal
without loss of accuracy.
[Admins: I have repeatedly searched Stack Overflow and other resources can cannot find anyone asking or answering this specific question.]
Question
How do I use str.format
to provide the given floating point format (below)? Showing that it's impossible is an acceptable answer.
Succinctly put, the format is just to provide at least one decimal place at all times even if that is just a trailing zero, but never to perform any rounding.
I suppose there may be a Formatter class solution, which would be acceptable if available, but a str.format
solution is preferred.
I would be interested in knowing if f-strings can achieve this as well. Using f-strings is not preferred as an answer in this context, but it would be interesting to know if f-strings can provide this format (without just packing the demonstrated expression inside the f-string for execution: that's just moving the required code into a secondary evaluation environment).
Required Format
To distinguish the numbers from int
the format must suffix ".0"
to whole numbers only if they are presented without any decimal places, but preserve exactly any decimal places that are presented, even if that includes trailing zeroes.
There is an alternative solution under consideration which is to strip all trailing decimal places that are zeroes but leave one and only one trailing decimal zero for whole numbers (and of course preserve all non-zero decimal places without rounding).
Incoming strings can be expected to be valid int
or Decimal
. The special case of receiving a whole number with just the decimal point and no decimal places is invalid and will not occur (no need to handle "42."
). The empty string (""
) will not occur.
It's not acceptable just to configure to a large number of decimal places ("{:.28f}".format(1)
).
Demonstration
AFAIK this should be the required behaviour. Looking for this behaviour using format
:
for number in ("42", "4200", "42.0000", "42.34", "42.3400", "42.3456"): string = "." in number and number or number +".0" print(number, "=>", string)
42 => 42.04200 => 4200.0042.0000 => 42.000042.34 => 42.3442.3400 => 42.340042.3456 => 42.3456
Alternative
This alternative behaviour is also acceptable.
for number in ("42", "4200", "42.0000", "42.34", "42.3400", "42.3456"): string = ( number.rstrip("0")[-1] == "." and number.rstrip("0") +"0" or "." not in number and number +".0" or number.rstrip("0") ) print(number, "=>", string)
42 => 42.04200 => 4200.042.0000 => 42.042.34 => 42.3442.3400 => 42.3442.3456 => 42.3456