(Logisches) Problem mit Liste

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
D.Seybold
User
Beiträge: 4
Registriert: Montag 25. Januar 2016, 11:49

Guten Morgen,

ich (Python-Neuling) habe eine serielle Verbindung zwischen dem RaPi und einem Empfänger für Temperatur-Messwerte. Zu diesem Empfänger gibt es mehrere Sender die ich mit einem Befehl abfragen kann. Ich bekomme anschließend Daten in folgenden Format zurück:

$N,0000004\r$A,1,137293289,20.00,10.00,00030,Sender 29 , 11:21:38,25.01.2016\r$A,1,........

$N sagt aus, wieviele Sender mit dem Empfänger gepollt sind. Daraufhin kommen alle Sender mit ihrer Konfiguration beginnend mit einem $A. \r ist immer das Ende des Datensatzes.

Ich möchte diese Daten auswerten, jedoch habe ich gerade (knoble schon seit einiger Zeit) ein Problem bei dem Aufbröseln der einzelnen Senderdaten.

Gibt es eine Performante Lösung um die Senderdaten ($A), die alle in einem String hängen herauszuziehen und in ein Mehrdimensionales Array (o.ä.) zu speichern?

Andere Daten die von den Sendern kommen werden in folgendem Format gespeichert (hier Messdaten):

Liste der ankommenden Daten: ["$D", "000035", "0", "22.10", "47.06", "Sender 68 "]
Liste mit Bezeichnern (zum anlegen eines Dic): ["request", "id", "status", "temp", "feuchte", "name"]

Daraus erzeuge ich anschließend ein Dic. Möchte ich das nun aber mit meinen Konfigurationsdaten der Sender machen muss ich irgendwie zuerst die $A-Datensätze herausfiltern und anschließend diese wieder auseinandernehmen um sie in eine Liste zu schreiben damit ich mein Dic erstellen kann.

Kennt da jemand eine gute Lösung?

MfG :D
BlackJack

@D.Seybold: Ich würde als erstes dafür sorgen das das „carriage return“ (CR) das als '\r' repräsentiert wird als Zeilenende angesehen wird. In der Dokumention von PySerial steht dazu etwas mit `io.TextIOWrapper`.

Dann bekommst Du die einzelnen Datensätze als Zeilen geliefert und kannst einfach mit der `startswith()`-Methode auf Zeichenketten prüfen ob die Zeile mit '$A' anfängt.
D.Seybold
User
Beiträge: 4
Registriert: Montag 25. Januar 2016, 11:49

Danke für den Tipp. Hat mir weitergeholfen und kann nun schön meine Dics erstellen. Muss ich halt meine anderen Auswertungen anpassen da durch diese Methode noch weitere Sachen entfallen, die ich davor per Hand abgeschnitten hab (z.B. b'......' bei serial.readline()). :D

MfG
BlackJack

@D.Seybold: Was meinst Du mit b'…' abschneiden? Du hast da hoffentlich nicht die Zeichenkettenrepräsentation von `bytes`-Objekten mit Zeichenkettenoperationen bearbeitet‽
D.Seybold
User
Beiträge: 4
Registriert: Montag 25. Januar 2016, 11:49

Nunja, zuvor hatte ich folgenden Code:

Code: Alles auswählen

data = str(ser.readline())
if data.startswith("b'") == True:
     data = data[2:]
     data = data[:data.rfind("'")]
if len(data) > 0:
     .......
Dadurch hab ich die ankommenden Bytes zu einem String konvertiert und konnte anschließend mit dem String weiterarbeiten.

Mein jetziger Code:

Code: Alles auswählen

data = str(sio.readline())
if len(data) > 0:
     ........
BlackJack

@D.Seybold: Der `str()`-Aufruf ist in beiden Fällen falsch. Im ersten Fall wirklich gruselig, man will nicht wirklich auf der Zeichenkettenrepräsentation von Datentypen operieren statt die Operationen zu verwenden die der Datentyp selbst zur Verfügung stellt, und im zweiten Fall bekommst Du bereits eine (Unicode)Zeichenkette von dem `readline()`-Aufruf und da ist der `str()`-Aufruf einfach nur überflüssig.

Um aus Bytes eine Zeichenkette zu machen muss man sie mit der `decode()`-Methode dekodieren.

Ein expliziter Vergleich mit literalen Wahrheitswerten ist unnötig, da kommt ja nur wieder ein Wahrheitswert heraus denn man vor dem Vergleich auch schon hatte. Also nur ``if data.startswith(something):``.
D.Seybold
User
Beiträge: 4
Registriert: Montag 25. Januar 2016, 11:49

OK, das der str() in meinem jetzigen Code überflüssig ist hab ich auch vor ca. 2 Minuten herausgefunden :roll:

Danke für die decode()-Methode. Ich dachte die str()-Methode konvertiert zu einem String :idea:

Explizite Vergleiche sind zwar überflüssig, hab ich mir aber angewöhnt, da es in vielen Sprachen einfacher zu lesen ist (zumindest meine Meinung) ;)
BlackJack

@D.Seybold: Was ist denn da besser zu lesen? Das würde nur zutreffen wenn der Name nicht gut ist, was ich bei `startswith()` jetzt nicht nachvollziehen könnte, denn „wenn diese Zeichenkette mit dieser Zeichenketten beginnt“ finde ich nicht unverständlicher als „wenn es wahr ist das diese Zeichenkette mit dieser Zeichenketten beginnt“. Zumal man bei Python eine Sprache hat in der verschiedene Werte einen ”Wahrheitsgehalt” haben und das auch von manchen Programmierern/APIs ausgenutzt wird, so dass eine Funktion zwar einen ”wahren” oder ”unwahren” Wert zurückgeben kann, der aber nicht zwingend `True` oder `False` sein muss.

In dem Zusammenhang ist auch das ``if len(data) > 0:`` nicht üblich und würde einfach als ``if data:`` geschrieben, weil leere Sequenzen ”unwahr” sind und alle anderen ”wahr”.
Antworten