1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
"""fixed length formatting of floats"""
from math import log10
def getfloat_attr(obj, attr, length=11):
"""Format an attribute of an object for printing."""
val = getattr(obj, attr, None)
if val is None:
return 'unknown'
if isinstance(val, int):
return f'{val}'
if isinstance(val, float):
return gformat(val, length=length).strip()
return repr(val)
def gformat(val, length=11):
"""Format a number with '%g'-like format.
Except that:
a) the length of the output string will be of the requested length.
b) positive numbers will have a leading blank.
c) the precision will be as high as possible.
d) trailing zeros will not be trimmed.
The precision will typically be ``length-7``.
Parameters
----------
val : float
Value to be formatted.
length : int, optional
Length of output string (default is 11).
Returns
-------
str
String of specified length.
Notes
------
Positive values will have leading blank.
"""
if val is None or isinstance(val, bool):
return f'{repr(val):>{length}s}'
try:
expon = int(log10(abs(val)))
except (OverflowError, ValueError):
expon = 0
length = max(length, 7)
form = 'e'
prec = length - 7
ab_expon = abs(expon)
if ab_expon > 99:
prec -= 1
elif ((expon >= 0 and expon < (prec+4))
or (expon <= -1 and -expon < (prec-2))
or (expon <= -1 and prec < 5 and abs(expon)<3 )):
form = 'f'
prec += 4
if expon > 0:
prec -= expon
def fmt(val, length, prec, form):
"format "
prec = max(prec, 0)
out = f'{val:{length}.{prec}{form}}'
if form == 'e' and 'e+0' in out or 'e-0' in out:
out = f'{val:{length+1}.{prec+1}{form}}'.replace('e-0', 'e-').replace('e+0', 'e+')
return out
prec += 1
out = '_'*(length+2)
while len(out) > length:
prec -= 1
out = fmt(val, length, prec, form)
if '_' in out:
out = fmt(val, length, prec, form)
while len(out) < length:
prec += 1
out = fmt(val, length, prec, form)
return out
def fcompact(val):
"""format a float value, removing extra trailing zeros"""
val = f'{val:.6f}'
while val.endswith('0'):
val = val[:-1]
if val.endswith('.'):
val = val + '0'
return val
|