MPD status (Anfänger Fragen)

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
Sleepy Floyd
User
Beiträge: 5
Registriert: Sonntag 4. Oktober 2009, 10:08

Hallo zusammen...

ich bin gerade dabei, die ersten Schritte mit Python zu machen. Hab keinerlei Informatik Hintergrund und auch kein besonderes Anliegen, alles nur aus Neugier und Interesse.

Wie dem auch sei, bin nach einigen Tutorials mit dem Buch "Beginning Python - From Novice to Professional" von Magnus Hetland recht glücklich geworden. Als erstes "Projekt" hatte ich mir vorgenommen, ein kleines Script zu schreiben, das sich zu meinem MPD Server verbindet und den Status in eine Textdatei schreibt.

Sieht bisher so aus:

Code: Alles auswählen

import mpd
import time

def main():
	client = mpd.MPDClient()
	client.connect('192.168.1.2','6600')


	song = client.currentsong()
	artist = song['artist'] 
	title = song['title']
	album = song['album']

	zeit = time.asctime()

	line = str(zeit) + ': ' + title + ' by ' + artist + ' from the album ' + album  


	f = open('/home/sleepy/test' , 'w')
	f.writelines(line)
	f.close

if __name__ == '__main__':
    main()
Wahrscheinlich ästhetisch nicht sehr schön, aber wenigstens funktioniert es für einen ersten Hack.

In der Datei test steht dann folgende Ausgabe:
Sun Oct 4 11:30:41 2009: La Mouche by Cassius from the album 1999

Nun meine Frage:
Ist es möglich, dass bei jedem Liedwechsel (so lange das Script läuft) eine neue Zeile mit den aktuellen Infos geschrieben wird, dass also ein richtiges Log entsteht?
Mein erster Gedanke war, irgendwie mit einer IF Schleife alle paar Sekunden den Status zu überprüfen und dann bei einer Veränderung eine neue Zeile zu schreiben.
Kommt mir aber irgendwie nicht sonderlich elegant vor...

Jemand ne Idee, wie man das lösen könnte? Is wahrscheinlich ziemlich trivial, mir geht allerdings diese ganze Programmierer-Denke noch vollkommen ab...
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

http://if-schleife.de/

Ansonsten suchst du wahrscheinlich `while` und `time.sleep`. Evtl findest du in der mpd Dokumentation noch etwas, mit dem man das besser loesen kann.
BlackJack

@Sleepy Floyd: `time.asctime()` gibt schon eine Zeichenkette zurück, da braucht man nicht noch einmal `str()` für aufrufen. Die Zeile kann man etwas kürzer mit dem ``%``-Operator zusammensetzen:

Code: Alles auswählen

    line = '%s: %s by %s from the album %s\n' % (zeit, title, artist, album)
Die Datei solltest Du mit dem Modus 'a' wie "append" öffnen, damit die Zeilen angehängt werden und nicht jedesmal der alte Dateiinhalt verworfen wird und immer nur eine Zeile in der Datei steht.

Die `writelines()`-Methode erwartet ein "iterable" von Zeichenketten. Eine Zeichenkette ist das grundsätzlich ja auch, aber so schreibst Du jedes Zeichen einzeln mit dem Aufruf. Die `write()`-Methode schreibt dagegen die ganze Zeichenkette in einem Rutsch.

Und dann solltest Du die `close()`-Methode auch *aufrufen*, also mit Klammern. Sonst hat das keinen Effekt.
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Du kannst zum sekündlichen prüfen, oder welche zeitspanne auch immer time.sleep(1) # 1 Sekunde, verwenden in einer while-Schleife, so etwa:

Code: Alles auswählen

import mpd
import time

def main():
    ...

if __name__ == '__main__':
    while True:
         main()
         time.sleep(1) # 1 = eine Sekunde
the more they change the more they stay the same
Sleepy Floyd
User
Beiträge: 5
Registriert: Sonntag 4. Oktober 2009, 10:08

cofi: Tja, wie man sieht geht mir auch die richtige Lingo ab...

Black Jack: Das mit den Variablen in der Ausgabezeile finde ich persönlich in diesem Fall nicht so schön. In der Literatur, die ich bisher gelesen habe, wird das auch alles so gemacht und ich seh definitiv ein, dass es bei komplexeren Ausgaben einfacher ist, die Werte zu sammeln und dann per %s einzufügen. Meine simple Zeile (und auch die meisten trivialen Beispiele) find ich so irgendwie lesbarer... vielleicht auch nur 'ne Geschmacksverwirrung meinerseits.

David: Danke schonmal so weit...


Ich mach mir ja nicht so sonderlich viel Gedanken um das Problem hier, deshalb wollte ich meine Frage erstmal in kleinere Schritte unterteilen.

Das Script soll beim ausführen einfach nur schauen, ob sich seit dem letzten Aufruf irgendwas verändert hat... wenn ja, dann die Zeile schreiben, wenn nicht, dann halt nix tun.

also:

Code: Alles auswählen

[...]
	line = zeit + ': "' + title + '" by "' + artist + '" from the album "' + album + '"\n'

	f = open('/home/sleepy/test' , 'r+a')
	testline = f.readlines()[-1]
	if testline == line:
		pass 
	else:
		f.write(line)
		f.close()
Funktioniert soweit...

Allerdings wieder die etwas penetrante Frage, ob man es besser machen kann.
Jedes mal die Datei zu öffnen und die letzte Zeile auszulesen erscheint mir als unpraktisch, besonders falls es wirklich noch soweit kommt, dass ich es irgendwie implementiere, dass alle paar Sekunden der Status überprüft wird und nicht nur, wenn ich das Script per Hand starte.

:?
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

ganz einfach: datei geöffnet lassen

und die If-Abfrage ist so schöner:

Code: Alles auswählen

    if not testline == line:
        f.write(line)
        f.close()
mfg

PS: vielleicht nützt dir das etwas: http://docs.python.org/library/threadin ... ding.Timer
the more they change the more they stay the same
Sleepy Floyd
User
Beiträge: 5
Registriert: Sonntag 4. Oktober 2009, 10:08

hm... tja... und ich dachte schon, dass mit meiner IF-Abfrage wär schon elegant . :wink:

Wie geht das mit dem Datei offen lassen genau? In dem Buch, das ich in meinem ersten Post angesprochen hatte, stand, dass es eigentlich ziemlich unnötig ist, Dateien zu schließen, da Python unbenutzte Datei eh nach ein paar Sekunden zu macht.
Hilft mir das also weiter, wenn ich das f.close() weg lass oder meinst du was anderes?


Ach ja, danke für irgendwelche Links, aber macht euch da nicht zu viel Arbeit mit'm raussuchen. Ich bin hier weniger an Dokumentation zu irgendwelchen Modulen interessiert (wobei ne schöne Einführung in die Standard-Library nicht schlecht wär) sondern eher an Kleinigkeiten wie der Sache mit der IF-pass-Else Ding grad. Babysteps halt 8)
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Eine Datei sollte auf jeden Fall geschlossen werden!

allerdings könnte man das in einem try ... finally block machen http://docs.python.org/reference/compou ... -statement

mit 'offen lassen' meine ich halt die Datei nicht schliesen per f.close()

so in etwa

Code: Alles auswählen

import mpd
import time

def main(file_object):
    client = mpd.MPDClient()
    client.connect('192.168.1.2','6600')


    song = client.currentsong()
    artist = song['artist']
    title = song['title']
    album = song['album']

    zeit = time.asctime()

    line = str(zeit) + ': ' + title + ' by ' + artist + ' from the album ' + album 


    file_object.write(line)
 
if __name__ == '__main__':
    f = open('/home/sleepy/test' , 'a')
    try:
        while True:
            main(f)
            time.sleep(1)
    finally:
        f.close()
the more they change the more they stay the same
Sleepy Floyd
User
Beiträge: 5
Registriert: Sonntag 4. Oktober 2009, 10:08

Diese try...finally Sachen hab ich grundsätzlich noch nicht wirklich kapiert. Werd mir die Kapitel nochmal anschauen...
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Sleepy Floyd hat geschrieben:Diese try...finally Sachen hab ich grundsätzlich noch nicht wirklich kapiert. Werd mir die Kapitel nochmal anschauen...
Dav1d aber auch nicht ;-)

Den Code von ihm vergiss mal ganz schnell wieder!
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Der Hinweis Dateien möglichst immer explizit zu schließen und das try-finally von Dav1d sind korrekt - Problem ist höchstens, dass die while-Schleife nicht bzw. nur mit ^C beendet wird. Ab Python 2.6 würde ich aber with benutzen und nicht mehr try-finally.
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Bei Python 2.5 würde ich das with-Statement importieren:

Code: Alles auswählen

from __future__ import with_statement
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Hyperion hat geschrieben:
Sleepy Floyd hat geschrieben:Diese try...finally Sachen hab ich grundsätzlich noch nicht wirklich kapiert. Werd mir die Kapitel nochmal anschauen...
Dav1d aber auch nicht ;-)

Den Code von ihm vergiss mal ganz schnell wieder!
ich dachte schon, kannst dus pls erklären was ich falsch gemacht hab?
the more they change the more they stay the same
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Dav1d hat geschrieben:ich dachte schon, kannst dus pls erklären was ich falsch gemacht hab?
Nee, sorry. Ich hatte übersehen, dass das Öffnen ja gar nicht der entscheidene Aspekt war und bin daher über das fehlende except gestoplert. Ich hätte den Code und das Problem besser lesen müssen - war also mein Fehler ;-)

Tja, ich sollte die Finger vom Python Forum lassen, solange ich michim Moment fast täglich mit Java rumschlagen muss und deswegen genervt bin :-(
BlackJack

@Hyperion: Also ich finde es toll nach einem Tag hässlichem Java-Quelltext in die kuschelige, heile Welt des Python-Forums entfliehen zu können. :-D
Antworten