Forum: PC-Programmierung PYTHON Zahl aus string ermitteln


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von dev (Gast)


Lesenswert?

Hallo,

der in python implementierte UDP Server erhät ein Frame das so aussieht: 
FRAME:50

Nun möchte ich nur die Zahl in ienem Integer speichern. Wie kann ich 
dies in python realisieren? Wie unten gezeigt habe ich mal die Funktion 
findall eingesetzt.
Allerdings erhalte ich einen Vector mit mehrern Werden. Darin ist die 
Zahl 50 abgelegt. Wie kann ich nur die Zahl erhausziehen?
1
 data, address = serverSocket.recvfrom(1024)
2
3
 length = len(data)
4
5
 header_frame = data.decode('utf-8')
6
 zahl = re.findall('([0-9]*)', header_frame)

von B. W. (yesitsme)


Lesenswert?

1
>>> data = "FRAME:50"
2
>>> s = data.split(":")
3
>>> v = int(s[1])
4
>>> print(v)
5
50

Wobei was steht da noch in den Daten drin?

von Stefan B. (stefan_b278)


Lesenswert?

frame='FRAME:50'
print(frame)
a = frame.split(':')
print(a)
try:
    print(a[1])
except IndexError:
    print('keinen Doppelpunkt gefunden')

try:
    nummer = int(a[1])
except (IndexError, ValueError):
    print('keine Zahl gefunden')
else:
    print ('Nummer: ', nummer)

: Bearbeitet durch User
von dev (Gast)


Lesenswert?

Das steht drin:
1
['', '', '', '', '', '', '', '50', '']

von B. W. (yesitsme)


Lesenswert?

dev schrieb:
> Das steht drin:
>
>
1
> ['', '', '', '', '', '', '', '50', '']
2
>

Das könnte daran liegen, das * Null bis X mal matched.
Versuch mal +


https://docs.python.org/3/library/re.html#regular-expression-syntax

von Norbert (Gast)


Lesenswert?

1
#!/usr/bin/python3
2
import re
3
4
data = '49FRAME:50 51'
5
zahlen = re.findall('([0-9]+)', data)
6
for zahl in zahlen:
7
    print(int(zahl))
49
50
51

von dev (Gast)


Lesenswert?

Danke funktioniert allerdings muss ich das ganze in einer while Schleife 
ausführen. Das mit dem print ist dann ein Problem. Wie kann ich die 
gefunden Zahl in eine Variable ablegen?

von Norbert (Gast)


Lesenswert?

dev schrieb:
> Wie kann ich die
> gefunden Zahl in eine Variable ablegen?

Wenn das eine ernst gemeinte Frage ist, dann solltest du nicht an einem 
UDP-Server arbeiten sondern ein Python Grundlagenbuch lesen.

von imonbln (Gast)


Lesenswert?

dev schrieb:
> Das mit dem print ist dann ein Problem. Wie kann ich die
> gefunden Zahl in eine Variable ablegen?

Wie wäre es mit
1
import re
2
data ="49FRAME:50 51"
3
zahlen = [int(x) for x in re.findall(r"\d+", data)]

Dann sind alle Zahlen als Integer in einer List.
Aber mal grundsätzlich wie sinnvoll ist es einfach alle Zahlen zu 
konvertieren und dann hoffen das da, was Gutes bei rauskommt? Wie sieht 
denn ein echter kompletter Frame aus? Vielleicht ist es sinnvoll eine 
Art Parser zu schreiben, welchen den Frame versteht und dann nur die 
Werte welche man wirklich braucht als integer zu parsen.

von dev (Gast)


Lesenswert?

Das erste Frame beinhaltet die Anzahl der zu übertragenen Frames. Am 
Ende also nach dem letzten Frame soll ein Ack gesendet werden.

von B. W. (yesitsme)


Lesenswert?

Du denkst daran, das UDP dir keine Meldung gibt, wenn Packete verloren 
gehen.

Was versuchst du da eigendlich?

von dev (Gast)


Lesenswert?

Ja das ist mir bewusst.

von Mario M. (thelonging)


Lesenswert?

B. W. schrieb:
> Was versuchst du da eigendlich?

Klingt als ob er TFTP neu erfinden will.

von dev (Gast)


Lesenswert?

Größer Datenmengen sammeln. 1000 Frames mit jeweils 350 bytes.

von dev (Gast)


Lesenswert?

Was ich leider nicht tun kann ist, nach jedem ankommenden Frame ein 
Acknowledge Frame zu senden aufgrund von Verzögerungen durch das 
Mobilfunknetz.

von Andi (Gast)


Lesenswert?

dev schrieb:
> Was ich leider nicht tun kann ist, nach jedem ankommenden Frame ein
> Acknowledge Frame zu senden aufgrund von Verzögerungen durch das
> Mobilfunknetz.

Deswegen verwendet man dafür auch besser TCP, das kann damit umgehen.

von Ein T. (ein_typ)


Lesenswert?

dev schrieb:
> Danke funktioniert allerdings muss ich das ganze in einer while Schleife
> ausführen. Das mit dem print ist dann ein Problem. Wie kann ich die
> gefunden Zahl in eine Variable ablegen?

Lieber TO, ich weiß ja: Du hast JETZT ein Problem und möchtest es JETZT 
lösen, und zwar bitte so schnell wie möglich. Das verstehe ich, aber 
trotzdem ist Dein Ansatz leider nicht sonderlich zielführend -- denn am 
Ende möchtest Du mit den gewonnenen Daten ja irgendetwas machen -- und 
wie soll das gehen, solange Du keine Ahnung von Deinem Werkzeug hast?

Meine ebenso wohlwollende wie dringende Empfehlung ist daher, erstmal 
einen Schritt von Deinem Problem zurückzutreten, und ein Python-Tutorial 
durchzuarbeiten. Davon habe ich unten zwei verlinkt: das erste [1] ist 
der Goldstandard von den Machern der Sprache selbst, das zweite [2] ist 
eine deutsche Übersetzung einer älteren Version des vorherigen 
Tutorials, wenn Dein Englisch vielleicht nicht so gut ist, und wenn Dir 
beide nicht gefallen, haben die Entwickler von Python noch einige 
Empfehlungen für weitere gute Tutorials unter [3].

Was Dein eigentliches Problem angeht, Deine Frames zu parsen, gibt es 
dazu viele mögliche Ansätze. Ein üblicher Ansatz wären die hier im 
Thread bislang gezeigten, also: mit str.split(), re.findall() oder einer 
List Comprehension, ein wesentlich weiter gehender Ansatz wäre hingegen, 
einen Parsergenerator wie Lark [4], PyPEG [5] oder Parsimonius [6] zu 
benutzen. Ein paar allgemeine, grundsätzliche Anmerkungen hinsichtlich 
solcher Parserwerkzeuge findest Du bei Mario Tomasetti.

Herzlich willkommen im Python-Universum, viel Spaß, Erfolg und Glück! 
;-)


[1] https://docs.python.org/3/tutorial/
[2] https://py-tutorial-de.readthedocs.io/de/python-3.3/
[3] https://wiki.python.org/moin/BeginnersGuide
[4] https://lark-parser.readthedocs.io/en/latest/
[5] https://fdik.org/pyPEG/
[6] https://github.com/erikrose/parsimonious
[7] https://tomassetti.me/parsing-in-python/

von Thorben (Gast)


Lesenswert?

Du brauchst auch kein Ack frame senden, sondern musst Dir ein Protokol 
ausdenken, ob nun auf UDP o. TCP.

1. Magic Key
2. Sequenznummer (UDP) o. Datalength (TCP)
3. Payload z.b. als Json string
4. CRC
5. Endframe (bei TCP)

Magickey damit du weisst das es von deinem Client kommt
Mit der Sequenzenummer kannst du feststellen, ob ein Frame verloren 
gegangen ist
Bei TCP musst du die länge mitgeben, weil der Frame aufgteilt wird
Payload Json (lässt sich einfach parsen)
CRC Zur Sicherheit
Endframe damit du beim TCP weisst dass das ganze Frame kam

Schau Dir mal Mqtt an, dafür gibt es fertige Libs und Broker.

von dev (Gast)


Lesenswert?

Hallo Thorben,

vielen Dank für deinen hilfreichen Beitrag.

Ich würde UDP bevorzugen. Allerdings ist mir nicht ganz klar, woher der 
Sender weiß das auch alle Frames angekommen sind oder auch nicht? Der 
Empfänger müsste doch dann am Ende ein ACK Frame an den Sender 
versenden.

von MaWin (Gast)


Lesenswert?

B. W. schrieb:
> Packete

Was ist das?

von Sebastian (Gast)


Lesenswert?

dev schrieb:
> Ich würde UDP bevorzugen. Allerdings ist mir nicht ganz klar, woher der
> Sender weiß das auch alle Frames angekommen sind oder auch nicht? Der
> Empfänger müsste doch dann am Ende ein ACK Frame an den Sender
> versenden.

Bei UDP weiss der Sender nicht ob ein Paket angekommen ist, und der 
Empfänger weiss nicht ob eins verloren gegangen ist. Du bist anscheinend 
gerade dabei ein Protokoll zu entwerfen das diese Zusicherungen oberhalb 
von UDP nachrüstet. Das ist aber recht anspruchsvoll. Zum Beispiel kann 
auch dein ACK-Paket verloren gehen ...

LG, Sebastian

von B. W. (yesitsme)


Angehängte Dateien:

Lesenswert?

MaWin schrieb:
> B. W. schrieb:
>> Packete
>
> Was ist das?

Meist Boxen aus Paappe in die man Dinge reinlegen kann um diese dann von 
einem Transportunternehmen von A nach B transportieren zu lassen. Wie 
ich finde eine sehr gute bildliche Beschreibung wie UDP funktioniert.

von Mario M. (thelonging)


Lesenswert?

Diese Packete sind nicht von Paappe!

von MaWin (Gast)


Lesenswert?

B. W. schrieb:
> Meist Boxen aus Paappe in die man Dinge reinlegen kann um diese dann von
> einem Transportunternehmen von A nach B transportieren zu lassen.

Ah. Das muss die neue Rechtschreibung sein.

von B. W. (yesitsme)


Lesenswert?

Mario M. schrieb:
> Diese Packete sind nicht von Paappe!

Stimmt... Bei UDP wirst du es am Ende eher mit Elektronendifferenzen zu 
tun haben. Da ist nix mit Pappe. Es sei denn du hast IPoAC in deiner 
Transportstrecke.

von dev (Gast)


Lesenswert?

Ja ein Transportprotokoll müsste ich implementieren. Aber da bin ich 
raus.

von Thorben (Gast)


Lesenswert?

>Ich würde UDP bevorzugen.

Und mit welcher Begründung?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.