String aus toml zu einer tuple mit bitmap wandeln

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
Dennis89
User
Beiträge: 1562
Registriert: Freitag 11. Dezember 2020, 15:13

Guten Abend und schon wieder benötige ich etwas Unterstützung.

Es geht letztendlich um die Ansteuerung eines Displays. Das Display bietet die Möglichkeit an 8 Symbole anzulegen. Ein Symbol besteht aus einem 8x5 bitmap.
Das ist die Doku dazu

Nun ist ein Python-Code, in dem erst mal 8 Smybole mit diesem Umfang niedergeschrieben werden, ziemlich doof zu lesen und die Scrollerei nervt.

Deswegen und weil es in dem Projekt noch weitere Einstellmöglichkeiten gibt, wurde eine toml-Datei angelegt.

Wenn ich jetzt zum Beispiel ein Symbole erstellen will, dann übergebe ich diese Tuple:

Code: Alles auswählen

(0b00100,0b01010,0b01010,0b01010,0b01010,0b10001,0b11111,0b01110)
Also das Ziel ist es, den String aus der toml-Datei in dieses Format/Datentyp zu wandeln.

Die toml-Datei hat dann diesen Inhalt:

Code: Alles auswählen

[Symbole]
thermometer = '0b00100,0b01010,0b01010,0b01010,0b01010,0b10001,0b11111,0b01110'
Da habe ich erst mal eventuell ein Verständnisproblem mit den Datentypen. In der Doku steht 'bitmap' , aber:

Code: Alles auswählen

print(type(0b00100))
<class 'int'>
und das 'b' sagt mir ja, das es sich um eine Binärzahl handelt.

Wenn ich jetzt die toml-Datei auslese, erhalte ich einen String, diesen in Binär umgewandelt gibt mir aber zu wenig Zeichen aus.

Code: Alles auswählen

print(bin(int('0b00100', 2)))
0b100
Die Zahl ist die gleiche, aber das Display erwartet hier 5 Zeichen und bekommt nur 3.
Die Methode, die ich kenne um die Nullen aufzufüllen, liefert aber wieder einen String:

Code: Alles auswählen

print(format(int('0b00100', 2), '#08b'))
0b000100
print(type(format(int('0b00100', 2), '#08b')))
<class 'str'>
Also erst mal, ist 'bitmap' ein Datentyp, den ich verwenden muss? Wenn ich danach google komme ich auf das Modul 'binascii'. Dadurch erhalte ich aber Byte-Objekte.
Das ist mal wieder nicht mein Projekt und ich habe das Display auch nicht um es testen zu können.

Mit 'binascii' habe ich das so gelöst:

Code: Alles auswählen

#!/usr/bin/python3
import toml
import binascii

config_conf = """
[Symbole]
thermometer = '0b00100,0b01010,0b01010,0b01010,0b01010,0b10001,0b11111,0b01110'
"""
config = toml.loads(config_conf)


test = tuple(
    binascii.a2b_qp(config["Symbole"]["thermometer"].split(",")[index])
    for index in range(len(config["Symbole"]["thermometer"].split(",")))
)
print(test)
print(type(test[0]))
Kann mir jemand sagen, ob dass der richtige Weg war und ich die Byte-Objekte so übergeben kann oder suche ich hier wirkich was ganz anderes?

Vielen Dank und Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Das erwartet nicht 4 Zeichen, das erwartet eine Ganzzahl, die sich aus 4 Bits ergibt.
In der Dokumentation ist auch ein Tool verlinkt, mit dem man das prima ausprobieren kann.

0b00100, was das mittlere Feld umschalten würde, ist nichts anderes als eine andere binäre Notation für eine 4. Und die fehlenden führenden Nullen machen daraus keine andere Zahl.

Code: Alles auswählen

>>> 0b00100
4
>>> 0b100
4
TOML kennt übrigens Listen. Die Elemente jetzt zwangsläufig in einen langen String zu packen ist also unnötig.
Und die Frage ist, ob man da tatsächlich die Notation als Binärzahl verwendet oder nicht gleich Integers schreibt. Die Notation als Binärzahl macht für mich nur sinn, wenn man sie so formatiiert untereinander schreibt, dass man das Muster anhand der Zeichen erkennen kann.
Zuletzt geändert von sparrow am Freitag 22. April 2022, 22:47, insgesamt 1-mal geändert.
Benutzeravatar
Dennis89
User
Beiträge: 1562
Registriert: Freitag 11. Dezember 2020, 15:13

Danke für deine Antwort.

Du meintest 5 Bit? Wegen " 8x5 bitmap".

Dass "0b00100" auch als "4" dargestellt werden kann ist mir klar. Was mir nicht klar ist/war bzw. auf was ich durch deinen Post gerade erst gekommen bin, heißt dass, das ich einfach Zahlen übergeben kann, die in Binärschreibweise 5 Bit nicht überschreiten?
Also wäre

Code: Alles auswählen

0b11111
31
meine größte Zahl und ich könnte einfach folgendes machen:

Code: Alles auswählen

config_conf = """
[Symbole]
thermometer = '0b00100,0b01010,0b01010,0b01010,0b01010,0b10001,0b11111,0b01110'
"""
config = toml.loads(config_conf)


test = tuple(
    int(config["Symbole"]["thermometer"].split(",")[index], 2)
    for index in range(len(config["Symbole"]["thermometer"].split(",")))
)
?

Grüße
Dennis

Edit: Das wurde so in toml geschrieben, da ich davon ausgegangen bin, das Display braucht das genau so. Aber wenn du mir mit diesem Post zustimmst, bzw. ich das richtig verstanden habe, dann kann man das natürlich ändern.
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Ja, aber TOML kann Listen.

Code: Alles auswählen

config_conf = """
[Symbole]
thermometer = ["0b00100", "0b01010", "0b01010", "0b01010", "0b01010", "0b10001", "0b11111", "0b01110"]
"""
config = toml.loads(config_conf)

test = [int(bitmap_row, 2) for bitmap_row in config["Symbole"]["thermometer"]]

Edit:

Oder als Integers:

Code: Alles auswählen

config_conf = """
[Symbole]
thermometer = [4, 10, 10, 10, 10, 17, 31, 14]
"""
config = toml.loads(config_conf)

test = config["Symbole"]["thermometer"]


Edit Edit:

Unabhängig von der dem Problem aber zu deinem Code:
In Python ist es zumeist ein Anti-Pattern über einen Index zu iterieren. Hier sogar doppelt schwierig, weil du das tust und dann sogar für jedes Element noch einmal die Zeichenkette splittest.
Zuletzt geändert von sparrow am Freitag 22. April 2022, 23:04, insgesamt 1-mal geändert.
Benutzeravatar
Dennis89
User
Beiträge: 1562
Registriert: Freitag 11. Dezember 2020, 15:13

Vielen Dank!

Den Hinweis mit der Liste habe ich erst bei meinem edit gesehen. Da stand der Beispielcode schon. Wird aber auf für den richtigen Code auf jeden Fall geändert 👍🏼

Danke nochmals für die schnelle Hilfe.

Grüße und gute Nacht
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Mir fallen hinterher immer noch Dinge ein, und ich will Doppelposts vermeiden :)
Benutzeravatar
Dennis89
User
Beiträge: 1562
Registriert: Freitag 11. Dezember 2020, 15:13

Guten Morgen,

den Edit Edit habe ich gerade erst gesehen. Ich hatte wirklich Schwierigkeiten die Werte aus der Datei richtig auszulesen und dabei ist das entstanden und hatte mich dann nur noch auf die Datentypen fokusiert. (Eigentlich weis ich das mit dem Anti-Pattern)
Wenn die toml-Datei richtig/besser aufgebaut ist, wie von dir gezeigt, dann ist das wesentlich einfacher.

Bin für jeden Edit dankbar :D

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Antworten