Seite 1 von 1

Vergleichen für Arme

Verfasst: Sonntag 1. Mai 2016, 18:13
von Sophus
Hallo Leute,

ich bin gerade dabei Versionen miteinander zu vergleichen. Durch einen Zufall bin ich auf parse_version vom Modul pkg_resources. Nun bin ich ein wenig verwirrt. Vor diesem Hintergrund habe ich für mich etwas kleines gebastelt. Bisher bin ich so verfahren, dass ich zwei Variablen miteinander verglichen habe - dies entspricht hier im Quelltext der compare_parser()-Funktion. Wie ich schon schrieb, bin ich auf das Modul pkg_resources gestoßen. Dazu habe ich dann die Funktion compare_parser gebastelt. Um zu testen, ob beide die "Wahrheit" sagen, habe ich dazu einen Generator gebastelt, und in das Wörterbuch einige Versionen geschrieben. Zur Simulation ist hier der Schlüssel (Key) die derzeitige Programmversion und der Wert (Value) ist sozusagen die Aktualisierungs-Version auf einem Server. Und nun werden die Versionen in meinem Skript miteinander verglichen. In meinem Fall sagen beide Varianten die Wahrheit.

Deswegen wollte ich mich an euch wenden und fragen, ob es vollkommen ausreicht, wenn man die Variablen so vergleicht wie in der compare_versions oder ob man eher die compare_parser()-übernehmen sollte? Gibt es Grenzen und Tücken?

Hinweis: Die Print-Anweisungen ignorieren wir mal getrost. Sie sind für mich, um selbst zu vergleichen.

Code: Alles auswählen

from pkg_resources import parse_version

def dict_version_generator():

    dict_versions = {"1.5.4": "1.5.4.5",
                     "1.5.5": "1.5.4",
                     "1.6.4": "1.8.4"}
    
    for k, v  in dict_versions.iteritems():
        yield k, v
    
def compare_parser(v1, v2):
    print "\nv1", v1
    print "v2", v2
    
    return parse_version(v1) < parse_version(v2)

def compare_versions(v1, v2):
    print "\nv1", v1
    print "v2", v2
    if unicode(v1) == unicode(v2):
        return False
    if unicode(v1) < unicode(v2):
        return True

if __name__ == "__main__":
    for ke, val in dict_version_generator():       
        print "compare_versions",  compare_versions(ke, val)
        print "compare_parser", compare_parser(ke, val)

Re: Vergleichen für Arme

Verfasst: Sonntag 1. Mai 2016, 18:30
von Sirius3
@Sophus: dict.iteritems liefert schon einen Iterator.

Code: Alles auswählen

def dict_version_generator():
    dict_versions = {"1.5.4": "1.5.4.5",
                     "1.5.5": "1.5.4",
                     "1.6.4": "1.8.4"}
    return dict_versions.iteritems()
Wenn Du schon einen funktionierenden Parser für Versionsstrings hast, warum willst Du dann eine kaputte Variante verwenden?

Re: Vergleichen für Arme

Verfasst: Sonntag 1. Mai 2016, 18:51
von BlackJack
@Sophus: Es gibt die üblichen Grenzen und Tücken wenn man Zeichenketten mit Ziffernfolgen sortiert/vergleicht. Es sind halt keine Zahlen und darum wird lexikographisch und nicht nach Zahlwert sortiert. Ausserdem deckt `parse_version()` noch etwas mehr als Zahlen/Ziffernfolgen ab. Einfach mal das in der Dokumentation der Funktion erwähnte PEP440 durcharbeiten.

Re: Vergleichen für Arme

Verfasst: Sonntag 1. Mai 2016, 19:37
von Sophus
@Sirius3: Was genau meinst du mit kaputter Variante? Was ist kaputt?

@BlackJack: Ich frage nur deshalb, weil parse_version() etwas langsamer ist als meine "billigere" Variante.

Ich möchte am Ende des Tages ja auch nur zwei Versionen miteinander vergleichen - also keine große Sache. Aber da ich mir nicht sicher bin, ob meine Variante ausreicht, wende ich mich eben an euch.

Re: Vergleichen für Arme

Verfasst: Sonntag 1. Mai 2016, 20:15
von Sirius3
@Sophus: ich denke, das sollte Deine Frage beantworten:

Code: Alles auswählen

>>> '2.10.3' < '2.9.7'
True

Re: Vergleichen für Arme

Verfasst: Sonntag 1. Mai 2016, 20:19
von Sophus
@Sirius3: Ich habe mal die beiden Versionsnummern in mein Wörterbuch übernommen. Du hast Recht. Das Ergebnis ist falsch. Danke dir.

Re: Vergleichen für Arme

Verfasst: Sonntag 1. Mai 2016, 22:23
von DasIch
Wie von BlackJack schon erwähnt beschreibt PEP 440 genau wie Versionen aussehen sollen und wie sie sortiert werden. Der Abschnitt zum sortieren, was dass einzige für dich relevant ist, ist auch sehr kurz. Lies den einfach.