Aller Anfang ist schwer. Auch mit Python.
Als C++ hardwarenaher Programmierer tue ich mich mit Python schwer.
Komplexes kann verbüffend kompakt geschrieben werden, aber ich bin an klar definierten Variablentypen gewöhnt und hier komme ich mit dem Durcheinander nicht klar.
Erschwerend kommt dazu, dass die Handbücher fast ausschließlich objektorientiertes Fachjargon nutzen, so dass selbst einfache Anleitungen kaum zu vestehen sind.
Konkret:
Wie wandle ich eine Float-Variable in einem Byte? Wie umgekehrt?
Das gleiche mit einem uint32? oder ein int32?
Wie lasse ich eine Float-Variable in einem Ascii String formatiert umwandeln?
Gibt es sowas, wie die sprintf() Methode?
Wo kann ich dafür eine Anleitung finden (deutsch ,englisch, französisch, aber keine mit jedes 2 Wort als Fachkauderwelsch)
Gibt es das?
Danke
Variablentyp umwandeln.
Schau dir hierfür mal das struct-Modul an.RIN67630 hat geschrieben:Wie wandle ich eine Float-Variable in einem Byte? Wie umgekehrt?
Das gleiche mit einem uint32? oder ein int32?
Auch Python beherrscht String Formatting. Zum einen via str.format(), zum anderen mit dem %-Operator. Wobei letzteres deutlich näher an der C-typischen Syntax ist. Eine ganz gute Einführung, die beide Arten (d.h. pythonisch und klassisch) beschreibt, findest du hier.RIN67630 hat geschrieben:Wie lasse ich eine Float-Variable in einem Ascii String formatiert umwandeln?
Gibt es sowas, wie die sprintf() Methode?
[quote="snafu"]
Schau dir hierfür mal das struct-Modul an.
Getan. Ausprobiert. Kein Erfog:
ich kann in dB das schreiben was ich will aus pack() kommt immer das gleiches heraus.
Es muss doch nicht so kompliziert und unituitiv sein, sowas einfaches, wie ein Float, das >0 und <255 ist, als Byte zu konvertieren!
im Arduino Compiler schreibe ich:
x = byte(dB); //fertig!
Hier bin ich seit Stunden am Suchen...
Schau dir hierfür mal das struct-Modul an.
Getan. Ausprobiert. Kein Erfog:
Code: Alles auswählen
>>> dB = 45.3
>>> print dB
45.3
>>> dB = dB // 1
>>> print dB
45.0
>>> from struct import *
>>> pack ('c',dB)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: char format require string of length 1
Es muss doch nicht so kompliziert und unituitiv sein, sowas einfaches, wie ein Float, das >0 und <255 ist, als Byte zu konvertieren!
im Arduino Compiler schreibe ich:
x = byte(dB); //fertig!
Hier bin ich seit Stunden am Suchen...
So ich bin das Problem ausgewichen.
Die Ursprungsformel hatte wegen eine Multiplikation mit 0.1 das Ergebnis ins Königreich der Floats katapultiert.
Ich habe die Multiplikation * 0.1 durch eine Division / 10 ersetzt. Jetzt kommt ein Integer heraus...
Mei ist das gewöhnungsbedürftig!
Nur habe ich ein Integer, aber noch kein Byte.
Das ist das nächstes Problem. Mit der socket Library muss ich ein Byte (nicht 2) an einem Socket senden.
Wenn ich jetzt s.send(dB) durchführe, schickt er eifrig zwei Bytes heraus!
Hat jemand eine Idée?
Die Ursprungsformel hatte wegen eine Multiplikation mit 0.1 das Ergebnis ins Königreich der Floats katapultiert.
Ich habe die Multiplikation * 0.1 durch eine Division / 10 ersetzt. Jetzt kommt ein Integer heraus...
Mei ist das gewöhnungsbedürftig!
Nur habe ich ein Integer, aber noch kein Byte.
Das ist das nächstes Problem. Mit der socket Library muss ich ein Byte (nicht 2) an einem Socket senden.
Wenn ich jetzt s.send(dB) durchführe, schickt er eifrig zwei Bytes heraus!
Hat jemand eine Idée?
Das Verhalten ist bei C++ dasselbe.RIN67630 hat geschrieben:Die Ursprungsformel hatte wegen eine Multiplikation mit 0.1 das Ergebnis ins Königreich der Floats katapultiert.
Ich habe die Multiplikation * 0.1 durch eine Division / 10 ersetzt. Jetzt kommt ein Integer heraus...
Mei ist das gewöhnungsbedürftig!
Die Lösung dafür wurde schon oben genannt.RIN67630 hat geschrieben:Nur habe ich ein Integer, aber noch kein Byte.
Das Leben ist wie ein Tennisball.
Python verfolgt eben ein anderes Konzept. Da denkt man in Zahlen und nicht in Shorts, Bytes und Longs. Das ist an den Schnittstellen zur "C-Welt" manchmal etwas frickelig, wobei es oft Bibliotheken gibt, die einem die Umwandlungen abnehmen. Man müsste die nur benutzen.RIN67630 hat geschrieben:Es muss doch nicht so kompliziert und unituitiv sein, sowas einfaches, wie ein Float, das >0 und <255 ist, als Byte zu konvertieren!
im Arduino Compiler schreibe ich:
x = byte(dB); //fertig!
Hier bin ich seit Stunden am Suchen...
Und dafür, dass du so vernarrt in Typen bist, stellst du dich im Umgang mit dem pack()-Aufruf nicht allzu geschickt an...
- noisefloor
- User
- Beiträge: 3876
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
@RIN67630: dein Grundproblem ist, dass du _denkst_, du müsstest in Python alles so machen wie in C++. Das ist falsch (also so gut wie immer, wenn du von Sprache A auf B wechselst). Wenn du ideomatisches Python schreiben willst, musst du den Ideomen von Python folgen und die von C++ vergessen.
Gruß, noisefloor
@RIN67630: dein Grundproblem ist, dass du _denkst_, du müsstest in Python alles so machen wie in C++. Das ist falsch (also so gut wie immer, wenn du von Sprache A auf B wechselst). Wenn du ideomatisches Python schreiben willst, musst du den Ideomen von Python folgen und die von C++ vergessen.
Gruß, noisefloor
Ich gebe gern zu, dass ich immer noch nicht verstanden habe, wie man damit einen Byte erzeugt.snafu hat geschrieben: Und dafür, dass du so vernarrt in Typen bist, stellst du dich im Umgang mit dem pack()-Aufruf nicht allzu geschickt an...
Nein, ich bin nicht im "Byte" Typ vernarrt, ich muss* der Gegenstelle (auf der ich leider keinen Einfluss habe) exakt einen Byte liefern.
Vielleicht gibt es eine andere Abhilfe im Socket-Modul? Ich bin am Suchen...
* das ist übrigens die Definition des schlechten Streßes: etwas zu müssen und es nicht zu können.
Verzeiht mir bitte, wenn ich etwas gereizt bin.
- noisefloor
- User
- Beiträge: 3876
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
Integer haben in Python auch eine `to_bytes`Methode, mit der du einen Integer-Wert in Bytes umwandeln kannst. Doku.
Gruß, noisefloor
Integer haben in Python auch eine `to_bytes`Methode, mit der du einen Integer-Wert in Bytes umwandeln kannst. Doku.
Gruß, noisefloor
Danke" Das klingt gut: gleich ausprobiert:noisefloor hat geschrieben:Hallo,
Integer haben in Python auch eine `to_bytes`Methode, mit der du einen Integer-Wert in Bytes umwandeln kannst. Doku.
Code: Alles auswählen
>>> (250).to_bytes(1, byteorder='big')
Traceback (most recent call last): File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'to_bytes'
Also erstmals die neue Version für Raspberry Pi kompilieren?
Vielleicht gibt es ein Grund, warum sie nicht in den Raspbian Repos ist?
Du solltest das installieren können. Einen technischen Grund warum das nicht laufen sollte gibt es obendrauf auch nicht.
Was an
nun aber so irre kompliziert sein soll erschließt sich mir nicht :K
Was an
Code: Alles auswählen
>>> import struct
>>> struct.pack("b", 127)
b'\x7f'
- noisefloor
- User
- Beiträge: 3876
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
Python 3 ist auch unter Raspbian Teil der Grundinstallation. Falls wider erwarten nicht:
Du musst - wie bei den allermeisten anderen Linux-Distros auch - Python 3 über `python3` aufrufen. `python` startet immer Python 2.
Falls du nicht einen sehr guten Grund hast, Python 2 heutzutage noch zu nutzen, solltest du sowie so mit Python 3 arbeiten.
Gruß, noisefloor
Python 3 ist auch unter Raspbian Teil der Grundinstallation. Falls wider erwarten nicht:
Code: Alles auswählen
sudo apt install python3
Falls du nicht einen sehr guten Grund hast, Python 2 heutzutage noch zu nutzen, solltest du sowie so mit Python 3 arbeiten.
Gruß, noisefloor
Der Grund ist, dass die Umstellung von Python 2 auf 3 über mehrere Jahre voran geht und immer noch andauert, weil manche Programme nicht 100% kompatibel sind.RIN67630 hat geschrieben:Vielleicht gibt es ein Grund, warum sie nicht in den Raspbian Repos ist?
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
[Stirnklopf] läuft auch OoB!noisefloor hat geschrieben: Du musst - wie bei den allermeisten anderen Linux-Distros auch - Python 3 über `python3` aufrufen. `python` startet immer Python 2.
Manchmal fehlt einem nur der entscheidender Hinweis!
Danke.
P.S. struct.pack("B",20) habe ich jetzt auch verstanden.
#"B", nicht "b", wenn man unsigned Byte möchte
Es kommt ein Byte heraus. Dargestellt wird aber immer ASCII, sofern es darstellbar ist.
Aber zum Weiterleiten an Socket, ist die Python-Darstellung irrelevant.
Ah, okay. Dich hatte verwirrt, dass da keine Zahl steht, sondern ein Zeichen. Das ist quasi die Art von Darstellung, die man bei einem Binärformat auch in der jeweiligen Datei hätte, wenn man sie in einem Editor öffnet. Dein Socket lauscht aber eh nur auf die "Morsezeichen" (Bits). Was man daraus macht, ist abhängig vom Kontext.RIN67630 hat geschrieben:Es kommt ein Byte heraus. Dargestellt wird aber immer ASCII, sofern es darstellbar ist.
Aber zum Weiterleiten an Socket, ist die Python-Darstellung irrelevant.
Übrigens, nicht nur!snafu hat geschrieben:Dich hatte verwirrt, dass da keine Zahl steht, sondern ein Zeichen.
Den ersten Versuch machte ich, Deiner Empfehlung nach, als die Eingangsvariable noch ein Float war. Das ging grundsätzlich schief.