File: gformat.py

package info (click to toggle)
python-pyshortcuts 1.9.5-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,632 kB
  • sloc: python: 1,097; makefile: 42
file content (96 lines) | stat: -rw-r--r-- 2,459 bytes parent folder | download
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