Problem mit einer Schleife

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.
firstfacility
User
Beiträge: 28
Registriert: Samstag 20. Dezember 2014, 09:26

Es stellt sich gerade ein Problem beim lesen der Streaming-Datei. Auf der Shell mit cat Streaming-Datei bekomme ich zuverlässig zB:

Code: Alles auswählen

artist=James Blunt
title=One Of The Brightest Stars
album=All The Lost Souls
artwork=cover-ccdc4ae7dbfbe2e188d009db095c1db4.jpg
genre=Rock
comment=
Wenn ich nun aber mit meinem Script :

Code: Alles auswählen

try:
   while True:
      f = open( sys.path[0] + "/now_playing", "r" )
      line1 = f.readline()
      line2 = f.readline()
      line3 = f.readline()
      line4 = f.readline()
      sleep (1)
      f.close()
      inter = line1[7:]
      titel = line2[6:]
      alb = line3[6:]
      cover = line4[8:]
      cover = cover.rstrip('\n')
      fout = open( sys.path[0] + "/command", "w" )
      fout.write(cover)
      fout.close()
      print (cover)
bekomme ich ab und zu eine zerstückelte Ausgabe wie zb:

Code: Alles auswählen

genre=Rock
comment=

=
=
=
=
Wie könnte ich das ändern ?
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Ich würde mich da Stück für Stück dran tasten.
Dateien öffnet man mit "with", damit man sich nicht selbst um das Schließen kümmern muss.

ungetestet:

Code: Alles auswählen

with open(os.path.join(sys.path[0], "now_playing")) as input_file:
    for line in input_file:
        print line
Die Ausgabe müsste identisch mit der von cat sein.

Außerdem möchtest du keine Variablen durchnummerieren sondern stattdessen einen Liste nehmen, oder eine geeignete Datenstruktur für die zu erwartenden Daten. In deinem Fall könnte sich ein dict aufdrängen.

Du musst die Zeilen auch nicht per Hand zerlegen. Dafür gibt es split. Dem kann man auch die Anzahl der maximalen Teile mitgeben, um zu verhindern, dass es zu Fehlinterpretationen kommt, wenn nach dem Trennzeichen noch einmal das Trennzeichen auftaucht:

Code: Alles auswählen

>>> "schluessel=wert".split("=")
['schluessel', 'wert']
>>> "schluessel=wert=irgendwas".split("=", 1)
['schluessel', 'wert=irgendwas']


Die Sache mit dem Warten vor dem Schließen der Datei verstehe ich nicht.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

sparrow hat geschrieben:Die Sache mit dem Warten vor dem Schließen der Datei verstehe ich nicht.
So wie ich das sehe, ändert sich der Inhalt der Datei, sobald ein neuer Titel gespielt wird. Eleganter wäre es natürlich zu testen, ob die Datei seit dem letzten Lesevorgang geändert wurde, bevor sie neu eingelesen wird.
firstfacility
User
Beiträge: 28
Registriert: Samstag 20. Dezember 2014, 09:26

Die Streaming Datei verhält sich nicht wie zB ein Logfile dh die neuen Daten werden nicht nacheinander geschrieben sondern die Datei wird immer wieder neu geschrieben. Ich werde jetzt mal den Vorschlag von sparrow versuchen, das liest sich logisch was er schreibt.
BlackJack

Man könnte dann auch die Datei in einem Rutsch einlesen und dann erst im Speicher in Zeilen zerlegen um die Gefahr zu verringern eine noch nicht vollständig geschriebene neue Datei zu lesen falls der Schreiber die Datei nicht atomar durch eine neue Version ersetzt.

Die Zerlegung an festen Indexwerten pro Zeile sieht mir auf jeden Fall viel zu wackelig aus, da würde ich auch eher allgemein Schlüssel/Wert-Paare parsen und in einem Wörterbuch ablegen. Und das dann in einer Funktion erledigen.

``sys.path[0]`` ist auch ziemlich eigenartig. Was da geneu steht ist von mehreren Faktoren abhängig die man nicht wirklich 100%ig unter Kontrolle hat. Es sei denn man hat dort vorher selber einen Pfad eingefügt, aber dann hat man den ja auch irgendwie anders zur Verfügung als ausgerechnen die erste Position der Pfade für Modulimporte zu verwenden. Pfadteile sollte man mit `os.path.join()` zusammensetzen.
firstfacility
User
Beiträge: 28
Registriert: Samstag 20. Dezember 2014, 09:26

ist das fricklig.....

Code: Alles auswählen

with open(os.path.join(sys.path[0], "now_playing")) as f:
    for line in f:
       print (line)
       line1 = f.readline()
       print (line1)
       "lines=f".split("=")
       ['lines', 'f']
       "lines=f=artwork".split("=", 1)
       ['lines', 'f=artwork']
       print (lines)

Also bis "print (line)" läuft es gut, ich habe zwar erst kurz getestet aber der ouput ist :

Code: Alles auswählen

artist=Söhne Mannheims

title=Ich Lern Was über Dich

album=Barrikaden Von Eden

artwork=cover-f68b4e460389fa247afc80e24495ac47.jpg

genre=Pop
Was natürlich nicht läuft ist line.split . Die Ausgabe die ich brauche wäre Zeile 1-3 alles ab = und ohne \n. Und die Zeilen muss ich danach einzeln verarbeiten. Also split ab = macht schon Sinn, aber danach sollten die Zeilen geteilt werden ........ nun da verlassen sie mich wenn mir jemand dafür einen Tipp geben könnte.
@BlackJack
sys.path[0] hat bisher funktioniert, du hast aber recht mit absoluten Pfaden zu arbeiten ist sicher stressfreier. Als nächstes werde ich mich damit beschäftigen.
BlackJack

@firstfacility: Das ist sicher nicht der Output denn das dürfte an einem `NameError` wegen der letzten Zeile scheitern da `lines` hier nirgends definiert ist.

Die Beispiele plus Ergebnisse aus der interaktiven Python-Shell-Sitzung von sparrow in die Schleife hinein zu kopieren ist auch reichlich sinnlos. Was hast Du Dir dabei gedacht? Ausserdem solltest Du Dich entscheiden ob Du über die Zeilen iterieren oder die `readline()`-Funktion verwenden willst. Das so zu kombinieren ist unsinnig.
firstfacility
User
Beiträge: 28
Registriert: Samstag 20. Dezember 2014, 09:26

ja ich weiß als Anfänger darf ich auch Fehler machen .....sorry. Also mein Code schaut nun so aus:

Code: Alles auswählen

with open(os.path.join(sys.path[0], "now_playing")) as f:
    for line in f:
       line=line.strip()
       wert=line.split("=")
       ['wert', 'line']
       for werts in wert:
          print (werts)
Die Ausgabe kommt dann so:

Code: Alles auswählen

artist
Söhne Mannheims
title
Hier Kommen Die Söhne
album
Barrikaden Von Eden
artwork
cover-f68b4e460389fa247afc80e24495ac47.jpg
genre
Pop
comment
Wenn ich nun einzelne Zeilen brauche kann ich mir die aus der Ausgabe holen ?
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@firstfacility: Natürlich darf man als Anfänger Fehler machen. Dies ist unvermeidlich und völlig normal. Im übrigen macht man auch später noch Fehler, wenngleich auch andere. Aber man sollte stets begründen können, warum der von einem selbst geschrieben Code eben so geschrieben wurde. Also beginne einfach einmal Zeile für Zeile zu überlegen, was Du da machst, was der Code bewirken soll und warum Du davon ausgehst, dass es funktioniert; denn sonst hättest Du es ja nicht geschrieben ... sondern geraten.
Antworten