Python string.format() percentage without rounding Python string.format() percentage without rounding python python

Python string.format() percentage without rounding


If you want to round down always (instead of rounding to the nearest precision), then do so, explicitly, with the math.floor() function:

from math import floordef floored_percentage(val, digits):    val *= 10 ** (digits + 2)    return '{1:.{0}f}%'.format(digits, floor(val) / 10 ** digits)print floored_percentage(0.995, 1)

Demo:

>>> from math import floor>>> def floored_percentage(val, digits):...     val *= 10 ** (digits + 2)...     return '{1:.{0}f}%'.format(digits, floor(val) / 10 ** digits)... >>> floored_percentage(0.995, 1)'99.5%'>>> floored_percentage(0.995, 2)'99.50%'>>> floored_percentage(0.99987, 2)'99.98%'


Something like this:

def my_format(num, x):     return str(num*100)[:4 + (x-1)] + '%'>>> my_format(.9995, 1)'99.9%'>>> my_format(.9995, 2)'99.95%'>>> my_format(.9999, 1)'99.9%'>>> my_format(0.99987, 2)'99.98%'


With Python 3.6+, you can use formatted string literals, also known as f-strings. These are more efficient than str.format. In addition, you can use more efficient floor division instead of math.floor. In my opinion, the syntax is also more readable.

Both methods are included below for comparison.

from math import floorfrom random import randomdef floored_percentage(val, digits):    val *= 10 ** (digits + 2)    return '{1:.{0}f}%'.format(digits, floor(val) / 10 ** digits)def floored_percentage_jpp(val, digits):    val *= 10 ** (digits + 2)    return f'{val // digits / 10 ** digits:.{digits}f}%'values = [random() for _ in range(10000)]%timeit [floored_percentage(x, 1) for x in values]      # 35.7 ms per loop%timeit [floored_percentage_jpp(x, 1) for x in values]  # 28.1 ms per loop