byteformat - Was ist schöner

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Ihr kennt bestimmt alle das Problem 100000000 Bytes ist nicht aussagekräftig, wie wäre es mit 95.37 Megabytes ;)

Gut, das Problem ist einfach zu Lösen. Ich habe jedoch zwei Lösungen und kann mich nicht wirklich für eine entscheiden. Deshalb und vor allem aus Neugierde möchte ich von euch wissen welches ist der schönste weg ;)

Meine zwei Versionen:

o(n) - ~ 4.5 usec/durchlauf

Code: Alles auswählen

def byteformat(n, units=('', 'kilo', 'mega', 'giga', 'terra')):
    i = 0    
    while n >= 1024.0 and i < len(units):
        n /= 1024.0
        i += 1
    return "%.2f %sbytes" % (n, units[i])
O(1) - ~7 usec/durchlauf

Code: Alles auswählen

def byteformatlog(n, units=('', 'kilo', 'mega', 'giga', 'terra')):
    i = int(math.log(n, 1024))
    if i >= len(units): i = len(units) - 1
    n /= 1024.0**i 
    return "%.2f %sbytes" % (n, units[i])
Die Benötigte Zeit wurde mit timeit und 102'400'000 als Argument gemessen.

Was meint ihr dazu? Hat jemand eine hübschere Lösung?
BlackJack

Bei der ersten Lösung sind `i` und die "komplizierte" Abbruchbedingung der ``while``-Schleife, Dinge die ich beseitigen würde (ungetestet):

Code: Alles auswählen

from __future__ import division

def byteformat(n, units=('', 'kilo', 'mega', 'giga', 'terra')):
    for unit in units:
        if n < 1024:
            break
        n /= 1024
    return '%.2f %sbytes' % (n, unit)
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Nett :)
Hab die anderen beiden auch noch so umgeschrieben dass sie "from __future__ import division" verwenden.

Zeiten:
byteformat: 4.5 -> gleich
byteformaglog: 6.6 -> schneller!
byteformatfor (blackjack): 3.5 -> am schnellsten (:
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Übrigens stimmen die Präfixe nicht. Wenn du 1024 als Basis verwendest, musst du "kibi", "mibi" etc. voranstellen.

</nitpick>
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

birkenfeld hat geschrieben:Übrigens stimmen die Präfixe nicht. Wenn du 1024 als Basis verwendest, musst du "kibi", "mibi" etc. voranstellen.

</nitpick>
Kibibyte tönt einfach nicht gut. Ich könnts natürlich noch kilo binary bytes, kib oder einfach KB nennen... :roll: Aber du hast schon recht, das sollte ich noch überdenken :)
lunar

Wie wäre es mit dieser Lösung? Die ist aus einer Python-Implementierung von "du", die ich mal irgendwo im Netz gefunden habe, und auf meiner Platte abgelegt habe (also nicht von mir selbst geschrieben, wenn jemand die Quelle weiß, bitte sagen).
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

lunar hat geschrieben:Wie wäre es mit dieser Lösung? Die ist aus einer Python-Implementierung von "du", die ich mal irgendwo im Netz gefunden habe, und auf meiner Platte abgelegt habe (also nicht von mir selbst geschrieben, wenn jemand die Quelle weiß, bitte sagen).
Hm ich weis ja nicht... Da gefällt mir die Lösung von Blackjack oder meine mit log besser. :)

http://code.djangoproject.com/browser/d ... rs.py#L503
Hier sieht man noch wies in Django gelöst ist. Finde ich aber auch nicht schön. Dafür vermutlich schnell.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Kann man da nicht was mit Bitshifting machen?

Was diese Kibi-/Mibi-/Kiwi-/Hiwi-Benennungssache angeht, die kommt in meinen Augen reichlich spät und hört sich echt doof an ;)
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Y0Gi hat geschrieben:Kann man da nicht was mit Bitshifting machen?

Was diese Kibi-/Mibi-/Kiwi-/Hiwi-Benennungssache angeht, die kommt in meinen Augen reichlich spät und hört sich echt doof an ;)
floats shiften kommt nicht gut (:
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

BlackJack hat geschrieben:

Code: Alles auswählen

from __future__ import division

def byteformat(n, units=('', 'kilo', 'mega', 'giga', 'terra')):
    for unit in units:
        if n < 1024:
            break
        n /= 1024
    return '%.2f %sbytes' % (n, unit)
Die Lösung hat ein Problem:

Code: Alles auswählen

In [2]: lib.byteformat(1024**4)
Out[2]: '1.00 TiB'

In [3]: lib.byteformat(1024**5)
Out[3]: '1.00 TiB'

In [4]: lib.byteformat(1024**6)
Out[4]: '1024.00 TiB'
Es wird auch durch 1024 Dividiert wenn keine nächste Einheit vorhanden ist. :?

Das Problem würde sich zwar für die nächsten 100 Jahre verbergen lassen in dem units bis yota erweitert wird. Aber hübsch ist es dennoch nicht.
BlackJack

Okay, dann spendieren wir für die ganz grossen Platten/Dateien noch eine Multiplikation:

Code: Alles auswählen

def byteformat(n, units=('', 'kilo', 'mega', 'giga', 'terra')):
    for unit in units:
        if n < 1024:
            break
        n /= 1024
    else:
        n *= 1024
    return '%.2f %sbytes' % (n, unit)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Die Einheit ist aber dennoch eher noch Terabyte und nicht Terrabyte.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Leonidas hat geschrieben:Die Einheit ist aber dennoch eher noch Terabyte und nicht Terrabyte.
Habe es gesehen zur Kenntnis genommen und gefixt. ;)

Verwende nun KiB/MiB/... :)
Antworten