読者です 読者をやめる 読者になる 読者になる

整数をSI接頭辞で簡易表現(Firendly Number, by checkio)

Python

Friendly number :: py.CheckiO - game for python coders

基数、桁精度、接頭辞、接尾辞。すべてデフォルト引数があるがオプショナルに指定できる。

提出に何度も落ちて都度失敗した入力をかわす、という感じで継ぎ足した。ひどいコードになった。最初のうちはdecimal使わずに文字列をガチャガチャいじって(スライスやsplitなど)で騙し騙しやっていが、入力10**24でもう無理、という気分になり結局decimalを使う運びとなった。このくらいのコード書くのにも1時間強かかったのでちょっと辛いですね…

from decimal import Decimal

def friendly_number(number, base=1000, decimals=0, suffix='',
                    powers=['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']):
    n = number
    r = str(n) + powers[0]
    i = 0
    if abs(n) < base:
        if decimals == 0:
            return r + suffix
        return str(n) + '.' + decimals * '0' + suffix
    while True:
        if abs(n) < base or i == len(powers)-1:
            break
        i += 1
        n = Decimal(n) / Decimal(base)
        if decimals:
            d = str(round(n, decimals))
        else:
            d = str(int(n))
        r = d + powers[i]

    r += suffix
    return r

if __name__ == '__main__':
    assert friendly_number(102) == '102', '102'
    assert friendly_number(10240) == '10k', '10k'
    assert friendly_number(12341234, decimals=1) == '12.3M', '12.3M'
    assert friendly_number(12461, decimals=1) == '12.5k', '12.5k'
    assert friendly_number(1024000000, base=1024, suffix='iB') == '976MiB', '976MiB'
    assert friendly_number(12000000, decimals=3) == "12.000M"
    assert friendly_number(102, decimals=2) == '102.00'
    assert friendly_number(-150, base=100, powers=["","d","D"]) == '-1d'
    print(friendly_number(255000000000, powers=["","k","M"]))
    assert friendly_number(0, decimals=3, suffix="th") == "0.000th"
    friendly_number(10**24)