Human readable number formatting

jepler at unpythonic.net jepler at unpythonic.net
Wed Sep 28 02:09:28 CEST 2005


Compared to your program, I think the key to mine is to divide by "limit"
before taking the log.  In this way, things below the "limit" go to the next lower integer.

I think that instead of having 'step' and 'base', there should be a single
value which would be 1000 or 1024.

import math

def MakeFormat(prefixes, step, limit, base):
    def Format(n, suffix='B', places=2):
        if abs(n) < limit:
            if n == int(n):
                return "%s %s" % (n, suffix)
            else:
                return "%.1f %s" % (n, suffix)
        magnitude = math.log(abs(n) / limit, base) / step
        magnitude = min(int(magnitude)+1, len(prefixes)-1)

        return '%.1f %s%s' % (
                    float(n) / base ** (magnitude * step),
                    prefixes[magnitude], suffix)
    return Format

DecimalFormat = MakeFormat(
    prefixes = ['', 'k', 'M', 'G', 'T'],
    step = 3,
    limit = 100,
    base = 10)


BinaryFormat = MakeFormat(
    prefixes = ['', 'ki', 'Mi', 'Gi', 'Ti'],
    step = 10,
    limit = 100,
    base = 2)

values = [0, 1, 23.5, 100, 1000/3, 500, 1000000, 12.345e9]
print [DecimalFormat(v) for v in values]
print [BinaryFormat(v) for v in values]
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-list/attachments/20050927/9835b49a/attachment.pgp>


More information about the Python-list mailing list