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 floor

def 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 floor
from random import random

def 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