TL;DR
You can do this by calculating the size of the unit part, whether it is negative or not, and then round up the number according to the previous numbers.
def num_to_7_char(num):
if num == 0:
return "0.00000"
int_part = int(log10(abs(num))) + 1
minus_part = int(num < 0)
round_to = max(6 - int_part - minus_part, 0)
return "{num:.{round_to}f}".format(num=num, round_to=round_to)
Code working on Repl.it
Explanation
If the number is zero, returns 0.00000
because a logarithm of 0 cannot be calculated.
To calculate the unit part of the number I use the method math.log10
to know how many houses the number has, calculating how many times I have to multiply the number 10
to reach the desired number. Ex.:
from math import log10
print(log10(1)) # 0
print(log10(10)) # 1
print(log10(100)) # 2
I use the method abs to take the module of a number, because to calculate a logarithm the number must be greater than 0.
Utilise int to convert the result to an integer and sum 1
so that the calculation corresponds to the number of unit digits of the number.
To calculate the space that will be occupied by the character -
(minus sign) I do a simple conversion from Boolean to integer, where True
will become 1
and False
will become 0
.
The variable round_to
stores the amount we want in the decimal places, as this will depend on how many characters will be left of the point.
The calculation of the rounding is done by decreasing the whole part and the part of the signal of the desired total. In this case the total desired is 6, because it is necessary to consider that the point will occupy a character.
The max is being used so that the case of round_to
be negative, it sets minimum limit to zero. Ex.:
max(1, 0) # 1
max(0, 0) # 0
max(-1, 0) # 0
In the end it is used string formatting using the method str.format
to round up and limit the number.
The site Pyformat has good examples to understand how it works.
Note that this model does not work properly in some cases for obvious reasons certain numbers are not possible to be represented in 7 characters without specifying some other rules, for example:
- Number greater than
9_999_999
: because it would take at least 8 characters to represent them.
- 6-digit integers: The algorithm uses the rule to convert a
int
for float
and fill the remaining characters with zeros to the right, but if an integer has only 6 digits it is not possible to represent it because only one point could be added, without being able to add zeros.
What if the result requires more than 7 characters, such as 10,000,000? Is it impossible to obtain such a value in the operations done? And as questioned in the questions, the point and the negative sign should count within this limit of 7? Because you specify seven numeric characters, but in the example you only put 5, because there is the point and minus sign.
– Woss