Seite 1 von 1

MPD status (Anfänger Fragen)

Verfasst: Sonntag 4. Oktober 2009, 10:39
von Sleepy Floyd
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...

Verfasst: Sonntag 4. Oktober 2009, 10:44
von cofi
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.

Verfasst: Sonntag 4. Oktober 2009, 12:33
von 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.

Verfasst: Sonntag 4. Oktober 2009, 13:32
von Dav1d
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

Verfasst: Montag 5. Oktober 2009, 16:10
von Sleepy Floyd
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.

:?

Verfasst: Montag 5. Oktober 2009, 16:14
von Dav1d
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

Verfasst: Montag 5. Oktober 2009, 16:29
von Sleepy Floyd
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)

Verfasst: Montag 5. Oktober 2009, 16:39
von Dav1d
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()

Verfasst: Montag 5. Oktober 2009, 17:27
von Sleepy Floyd
Diese try...finally Sachen hab ich grundsätzlich noch nicht wirklich kapiert. Werd mir die Kapitel nochmal anschauen...

Verfasst: Montag 5. Oktober 2009, 17:28
von Hyperion
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!

Verfasst: Montag 5. Oktober 2009, 23:20
von sma
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.

Verfasst: Dienstag 6. Oktober 2009, 09:32
von mkesper
Bei Python 2.5 würde ich das with-Statement importieren:

Code: Alles auswählen

from __future__ import with_statement

Verfasst: Dienstag 6. Oktober 2009, 15:28
von Dav1d
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?

Verfasst: Mittwoch 7. Oktober 2009, 10:00
von Hyperion
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 :-(

Verfasst: Mittwoch 7. Oktober 2009, 19:20
von 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