Seite 1 von 1

dec to bin optimierung?

Verfasst: Montag 25. Februar 2008, 10:53
von cyp++
Hallo Community,

in Rahmen eines Steganographie Projekts, muss ich Farben - welche in dezimaler Form vorhanden sind - in binär umwandeln. Dafür habe ich mir eine Funktion geschrieben, die allerdings auf eine andere (selbstgeschriebene) Funktion zugreift, ob das so pythonic und optimal ist wage ich zu bezweifeln, also stelle ich mal meinen Code hier rein und bitte um Hilfe meinen Code zu o ptimieren und pythonisieren :D

Code: Alles auswählen

def zeroise_bin(numbr):
    tmp = ''
    tmp = tmp.join(numbr*['0'])
    return tmp

def dec_to_bin(value):
    tmp = ''
    bin = []
    while (value!=0):
        if value%2==0:
            value /= 2
            bin += '0'
        if value%2==1:
            value /= 2
            bin += '1'

    places = zeroise_bin(8-len(bin))
    tmp = places + tmp.join(bin)

    return tmp

print dec_to_bin(ord('A'))

Hautsächlich geht es mir um das Nullen auffüllen, damit ich auf 8 Bits komme, da ich alle benötige.

MfG

Verfasst: Montag 25. Februar 2008, 11:20
von BlackJack
Meine übliche Bemerkung: Das heisst `int_to_bin()` weil die Funktion ganze Zahlen erwartet und keine "Dezimalzahlen".

`number` mit `numbr` ab zu kürzen ist ja wohl'n Scherz. Wobei diese überaus komplizierte Funktion scheinbar nichts anderes macht als ``'0' * number``. Das muss man nun wirklich nicht in eine Funktion auslagern.

In beiden Funktionen ist die Zeile ``tmp = ''`` überlüssig.

In beiden ``if``-Zweigen wird ``value`` durch zwei geteilt, dass heisst das kann man aus der Schleife heraus ziehen und muss es nur einmal hin schreiben.

Wenn auf eine ``if``-Abfrage eine zweite folgt, die genau das Gegenteil der ersten behandelt, kann man sich den Test sparen und einfach ein ``else`` nehmen.

Allerdings kannst Du Dir auch mal anschauen was jeweils beim Test heraus kommt und was darauf hin an `bin` angehängt wird. Da braucht man gar keine ``if``-Abfrage für.

Für's auffüllen mit 0en gibt's auf Zeichenketten die `zfill()`-Methode.

Ausserdem sollte man vor dem Optimieren erst einmal dafür sorgen, dass die Funktion korrekt ist! Teste Deine mal, da kommen falsche Ergebnisse heraus.

Code: Alles auswählen

def int2bin(value):
    result = list()
    while value:
        result.append(str(value & 1))
        value >>= 1
    result.reverse()
    return ''.join(result).zfill(8)

Verfasst: Montag 25. Februar 2008, 11:28
von cyp++
Meine übliche Bemerkung: Das heisst `int_to_bin()` weil die Funktion ganze Zahlen erwartet und keine "Dezimalzahlen".
Hatte ich zuerst auch stehen, aber dann dachte ich mir es wären dezimalzahlen. Aber okay, nun weiß ich bescheid.

`number` mit `numbr` ab zu kürzen ist ja wohl'n Scherz. Wobei diese überaus komplizierte Funktion scheinbar nichts anderes macht als ``'0' * number``. Das muss man nun wirklich nicht in eine Funktion auslagern.
Stimmt, die Abkürzung ist echt lächerlich ;-) Und zu der Auslagerung in eine Funktion: Ich dachte es sähe übersichtlicher aus!

Ausserdem sollte man vor dem Optimieren erst einmal dafür sorgen, dass die Funktion korrekt ist! Teste Deine mal, da kommen falsche Ergebnisse heraus.
Da stimmt ich nicht mit dir überein! Bei mir kommt das richtige Ergebnis raus! z.b. 15 -> 00001111

Verfasst: Montag 25. Februar 2008, 11:35
von Zap
cyp++ hat geschrieben:Da stimmt ich nicht mit dir überein! Bei mir kommt das richtige Ergebnis raus! z.b. 15 -> 00001111
Da hast du nen glücklichen Treffer gelandet.
Schau mal hier:

Code: Alles auswählen

In [14]: dec_to_bin(2)
Out[14]: '00000001'

In [15]: dec_to_bin(4)
Out[15]: '00000001'

Verfasst: Mittwoch 27. Februar 2008, 16:44
von cyp++

Code: Alles auswählen

while value:
        result.append(str(value & 1))
        value >>= 1
Das verstehe ich noch nicht so ganz. Value & 1? value >>= 1?

Ich bitte um Erklärung.

Verfasst: Mittwoch 27. Februar 2008, 16:50
von audax
Binäroperatoren, Bitschubserei.

>> ist der Operator für Shift

Verfasst: Mittwoch 27. Februar 2008, 17:27
von numerix
BlackJack hat geschrieben:Meine übliche Bemerkung: Das heisst `int_to_bin()` weil die Funktion ganze Zahlen erwartet und keine "Dezimalzahlen".
Das sehe ich anders.
Was hier umgewandelt wird sind natürliche Zahlen im Dezimalsystem in entsprechende Dualzahlen. Die Menge der ganzen Zahlen umfasst auch negative Zahlen, um die geht es ja nicht. Da es hier um Umwandlungen zwischen Zahlensystemen geht, ist dec oder dez m.E. genau richtig, weil es die Basis benennt - ebenso wie bin.

Verfasst: Mittwoch 27. Februar 2008, 17:35
von Leonidas
pütone hat geschrieben:Das sehe ich anders.
Was hier umgewandelt wird sind natürliche Zahlen im Dezimalsystem in entsprechende Dualzahlen.
Nein, da werden Ganzzahlen in Dualzahlen konvertiert. Du kannst der Funktion auch Oktalzahlen oder Hexadezimalzahlen geben, die werden alle vom Python-Interpreter identisch behandelt, weil sie alle Integer sind.

Verfasst: Mittwoch 27. Februar 2008, 17:38
von audax
Aber man kann eben auch Oktalzahlen oder Hexazahlen umwandeln.

Verfasst: Mittwoch 27. Februar 2008, 17:44
von EyDu
pütone hat geschrieben:Was hier umgewandelt wird sind natürliche Zahlen im Dezimalsystem in entsprechende Dualzahlen. Die Menge der ganzen Zahlen umfasst auch negative Zahlen, um die geht es ja nicht. Da es hier um Umwandlungen zwischen Zahlensystemen geht, ist dec oder dez m.E. genau richtig, weil es die Basis benennt - ebenso wie bin.
Der Unterschied ist, dass du einen Wert in die Funktion hineingibst und eine Repräsentation dieses Wertes in einem bestimmten Format (dual, ternär, dezimal, ...) zurückbekommst.

Das Eingabeformat, typischerweise dezimal, ist dabei vollkommen uninteressant.

Verfasst: Mittwoch 27. Februar 2008, 18:50
von numerix
Ich bin von dem ausgegangen, was das Ausgangsprogramm leisten soll.
Da geht es um dezimale Farbwerte, die in Dualzahlen umgewandelt werden. Und in diesem Zusammenhang ist dez oder dec m.E. die bessere Wahl für die Bezeichnung, weil es das beschreibt, was die Funktion IN DIESEM PROGRAMM macht: nämliche Dezimalzahlen in Binär-/Dualzahlen umzuwandeln.

Verfasst: Mittwoch 27. Februar 2008, 19:07
von BlackJack
Die Funktion wandelt Zahlen in Binärdarstellung um. Das die vorher mal irgendwann in Dezimaldarstellung vorhanden waren spielt keine Rolle. Eine Funktion `dec_to_int()` sollte, wenn der Name passen soll, auch Zahlen in Dezimaldarstellung entgegennehmen, also Objekte vom Typ `str` oder `unicode` und keine `int` oder `long`. Tut diese Funktion aber nicht.

Verfasst: Mittwoch 27. Februar 2008, 19:38
von cyp++
audax hat geschrieben:Binäroperatoren, Bitschubserei.

>> ist der Operator für Shift
Okay, den Operator hab ich jetzt verstanden!

Doch was ist mit

Code: Alles auswählen

value & 1
?

Verfasst: Mittwoch 27. Februar 2008, 19:44
von audax
Ein binäres 'und'

1001 & 1 -> 1
1001 & 10 -> 0
1111 & 1100 -> 1100

http://docs.python.org/ref/binary.html