Anfängerfrage zu Zeitintervallen

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.
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Hallo,

Ich will ein Programm schrieben, das mir alle 5Minuten das aktuelle Datum in eine Textdatei schreibt.

Code: Alles auswählen

import time
inp=open('log.txt','a')         #log.txt öffnen
inp.write(time.strftime('%d.%m.%Y %H:%M:%S'))     #datum einfügen
inp.close()                    #dokument closen
Jetzt muss ich da eine Schleife drumsetzten.
Das kriege ich denke ich hin, aber wie mache ich das mit "alle 5 Minuten"

Hoffe jmd weis was ich meine. Hab durch google nichts gefunden, bsw. wusste nicht wirklich wie ich danach suchen soll.

Gruss


EDIT:
Habe etwas rumgeschaut, und habe jetzt vllt eine idee:

Code: Alles auswählen

import time
while (abbruchbedingung zb leertaste drücken):
time.sleep(300)        #5minuten
inp=open('log.txt','a')         #log.txt öffnen
inp.write(time.strftime('%d.%m.%Y %H:%M:%S'))     #datum einfügen
inp.close()                    #dokument closen
Würde das Funktionieren?

(wie gesagt bin Anfänger in sachen Programmieren.... :lol:
rafael
User
Beiträge: 189
Registriert: Mittwoch 26. Juli 2006, 16:13

Das würde gehen, soweit ich das sehe.

Ich würde es aber so machen

Code: Alles auswählen

import time

inp=open('log.txt','a')         # Besser nicht immer in ner Schleife öffnen ;)
while abbruchbedingung zb leertaste drücken: # Da brauch man keine Klammer
    time.sleep(300)        #5minuten
    inp.flush() # So kann man die Datei auch speichern, ohne sie immer wieder neu zu öffnen
    inp.write(time.strftime('%d.%m.%Y %H:%M:%S'))     #datum einfügen
inp.close()  
BlackJack

Das `flush()` sollte man *nach* dem `write()` machen, damit das gerade geschriebene auch wirklich sofort rausgeschrieben wird.
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Also bisher sieht es so aus:

Code: Alles auswählen

import time
while : #habt ihr nen voschlag für hier hin?
    time.sleep(3)        #5minuten
    inp.write(time.strftime('%d.%m.%Y %H:%M:%S'))#datum einfügen
    inp.write('\n')
    inp.flush()
inp.close() 
Aber wie bekomme ich hin das die Schleife bis zu einem besimtmten Tastendruck weiter arbeitet?
Im moment druckt sie nur immer weiter die Daten aus, das Funktioniert, aber beendet wird sie ja nicht.

Durch ne break anweisung?


Gruss
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Du kannst dein Script auch mit "STRG + C" abbrechen ;). Zu deinem Schreibverfahren ... ich würde das Handle auf die Datei nicht unbedingt die gesamte Zeit über offen halten, sondern immer zum gewünschten Zeitpunkt öffnen, schreiben und dann wieder sauber schließen.

Code: Alles auswählen

import sys
import time

def schleifen(warten):
    while True:
        time.sleep(warten)
        zeitstempel = time.strftime('%d.%m.%Y %H:%M:%S')
        try:
            inp = open('log.txt','a')
            try:
                inp.write(zeitstempel + '\n')
            finally:
                inp.close()
        except (IOError, OSError), error:
            print "FEHLER: Konnte Zeitstempel '%s' nicht schreiben: %s" % (zeitstempel, error)
            sys.exit(2)

def main():
    try:
        schleifen(300) # Schleifenmethode aufrufen, mit 300 Sekunden Wartezeit
    except KeyboardInterrupt:
        print "-- Abbruch durch Benutzer --"
 
if __name__ == '__main__':
    main()
EDIT:
- Bugs in Codesnippet ausgemerzt und getestet
Zuletzt geändert von Masaru am Mittwoch 7. März 2007, 23:49, insgesamt 2-mal geändert.
rafael
User
Beiträge: 189
Registriert: Mittwoch 26. Juli 2006, 16:13

BlackJack hat geschrieben:Das `flush()` sollte man *nach* dem `write()` machen, damit das gerade geschriebene auch wirklich sofort rausgeschrieben wird.
Ups, hab ich in die falsche Zeile geschrieben. :oops:
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Zu Masaru:
Wenn ich dein Script ausführe, hängt sich mein Rechner auf und ich darf neustarten...O.o^^
Aber muss nähere Infos zu meinem Problem geben, denn zu dieser finally Option und so kommt er garnicht, denn ich benötige das Programm zum feststellen in welchem Zeitraum mein PC heruntergefahren wird.
Näheres: Ich gehe morgens in die Schule und hab meinen Rechner laufen, bin am downloaden. Komme mittags heim und der Rechner ist aus, Steckerleiste ebenfalls.
Und keiner will zugeben das er es war. Ist mir schon öfters passiert, deswegen will ich feststellen wer um diese Zeit in frage käme..
Dann schaue ich einfahc auf den letzten eintrag und schon weis ich wielange er gelaufen ist.

Gruss
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Sephiroth hat geschrieben:Zu Masaru:
Wenn ich dein Script ausführe, hängt sich mein Rechner auf und ich darf neustarten...O.o^^
Da waren auch ein paar Fehler noch drinnen, die ich mal korrigiert und bei mir getestet habe. Sollte bei dir auch funktionieren ;).
Sephiroth hat geschrieben:... zu dieser finally Option und so kommt er garnicht ...
Keine Sorge, bei meinem Codebeispiel wird Dein Problem nicht übergangen. Das "finally" meint, dass nach dem Öffnen und Schreiben des Zeitstempels in Zeile 9 und 11, egal ob ein Fehler passiert oder nicht, diese Datei auch wieder geschlossen wird.
Dadurch, dass dieser Vorgang innerhalb der while-Schleife liegt wird der Log-Eintrag und das öffnen der Datei immer nur dann gemacht, wenn es nötig ist.

Das permanente "offen" halten des Dateihandles bringt Dir nämlich keinen Vorteil. Wenn jemand den Rechner runterfährt, bekommt Dein Script es werder mit einem offenen Dateihandle noch mit einem wiederholten Öffnen, Schreiben, Lesen Modell hin ;).

Was für Dich vielleicht noch zusätzlich viel Interessanter wäre, ist mitzuloggen wenn sich ein Benutzer an deinem System anmeldet (Windows/KDE/etc.-Login).

Dies könntest Du mit einem Script lösen welches z.B. Windows über ein Batch aus dem Autostart Ordner gestartet wird, und Zeit, sowie aktuellen Benutzer loggt.

Ich würde in Deinem Falle den Personen in meinem häuslichen Umfeld eigene Accunts mit Passwörtern in meinem System anlegen, womit man genau bestimmen könnte wer sich wann eingeloggt hat.

Ein solches Script könnte z.B. sein:

Code: Alles auswählen

import datetime
import getpass
import sys

def log_systemstart():
    zeitstempel = datetime.datetime.now().strftime("%d.%m.%Y %H:%M:%S")
    benutzer = getpass.getuser()
    try:
        inp = open('systemstart.log', 'a')
        try:
            inp.write("[%s] Benutzer '%s' hat System gestartet" % (zeitstempel, benutzer))
        finally:
            inp.close()
    except (OSError, IOError), error:
        print "FEHLER: konnte logeintrag nicht schreiben: %s" % error
        sys.exit(2) 

if __name__ == '__main__':
    log_systemstart()
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Danke an Masaru, aber ich wollte das Programm möglichst einfach halten. Und ehrlich gesagt versteh ich große Teile deines Codes nicht..^^ also bleib ich vorerst mal bei meiner Ursprungsvariante:

Code: Alles auswählen

import time
inp=open('log.txt','a')
while True: #habt ihr nen voschlag für hier hin?
    time.sleep(3)        #5minuten
    inp.write(time.strftime('%d.%m.%Y %H:%M:%S'))#datum einfügen
    inp.write('\n')
    inp.flush()
inp.close()
Aber wie bekomme ich noch ne Abbruchbedingung Leertastendruck.
Also die While Schleife soll solange ausgeführt werden bis die leertaste gedrückt wird.

Oder allgemein:Wie kann man überhaupt auf Tastendrücke eingehen mit python?

Gruss
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Unter Einbindung/Verwendung einer Bibliothek, welche Tastendruck (oder auch eben das Fehlen eines solchen) innerhalb einer Console abfragen kann wie z.B. WConiounter Windows, cursesunter Unix, etc.

Eine solche Programmierung würde aber weit aus komplexer werden, als das was ich bisher gepostet hatte ;).

Mein Vorschlag weiterhin wäre, brich das Script mittels der Tastenkombination "STRG + C" ab, beende das Consolen/Shell-Fenster oder kick den Prozess ... oder hat es einen bestimmten Grund, warum Du unbedingt mit "Leertaste" das Script abbrechen möchtest?
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Hab mir den Quellcode nochmal angeschaut... hatte einen Fehler, oben... (Time war falsch geschrieben) und...

Außerdem finde ich es sinnvoller, wenn in der Datei immernur die neueste Uhrzeit drinne steht, über einige Stunden kann die Logdatei schon recht groß werden, oder oO?... Und er sollte erst am Ende warten, damit man gleich ein Ergebnis sieht...

(Das im 2ten Absatz sind nur persönliche Vorschläge, wie ich es sinnvoller find. Wenn du das anhängen besser findest, einfach nur bei "inp = open('log.txt','w')" das w zu einem a, für append... und wenn du noch fragen zu den Befehlen hast, in den Docs steht alles. Bspw. für try, except, finally: http://docs.python.org/ref/try.html)

Code: Alles auswählen

# -*- coding: cp1252 -*-
import sys 
import time 

def schleifen(warten): 
    while True: # <--- Dauerschleife bis Strg + C...
        zeitstempel = time.strftime('%d.%m.%Y %H:%M:%S') 
        try: 
            inp = open('log.txt','w') 
            try: 
                inp.write(zeitstempel + '\n') # Datum + Zeilenumbruch einfügen 
                # inp.flush() # da jedesmal 'close' obsolet 
            finally: 
                inp.close()
                print zeitstempel
                time.sleep(warten) 
        except (IOError, OSError), error: 
            print "FEHLER: Konnte Zeitstempel '%s' nicht schreiben: %s" % (zeitstempel, error) 
            sys.exit(2) 

def main(): 
    try: 
        schleifen(5) # Schleifenmethode aufrufen, mit 5 Sekunden Wartezeit 
    except KeyboardInterrupt: #wenn Strg+C gedrückt wird, passiert das...
        print "-- Abbruch durch Benutzer --"
  
if __name__ == '__main__': 
    main()
Edit: Arg, bin ich langsam oO'''
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Bin jetzt wieder auf dies hier zurückgekommen:

Code: Alles auswählen

# -*- coding: cp1252 -*-
import time

inp=open('log.txt','a')         #log.txt öffnen
while True:
    time.sleep(5)
    inp.write(time.strftime('%d.%m.%Y %H:%M:%S'))     #datum einfügen
    inp.write('\n')
    inp.flush() 
Es macht aus was ich will. Nur mit dem Beenden ist das sone sache..
Erstmal hat es eine ungewöhnlich hohe CPU Auslastung..31%

Und wenn ich den shell mit dem x schließe, hängt sich mein pc auf und ich muss neustarten..egal was ich ausprobieren, kriege es nicht richtig beendet.
Aber in die Textdatei schreibt es trotzdem.
Es würde also so auch funktionieren, aber wäre schon nicht schlecht wenn man es auch beenden könnte...


PS:Blackvivi, hast du zufällig einen gp2x?
Wie klein die Welt doch ist :D


Gruss
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Kannst Du vielleicht ein paar mehr Infos posten?
- Betriebssystem
- Python Interpreter Version
- Arbeitsspeicher und CPU Taktung
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

OS:WinXP Professionel
Python Version 2.4 (da ich pygame benutzten will und es das nicht für die 2.5er gibt)
512MB Ram
~1,3GHz (Athlon XP 2000+)

Edit:Ausgeführt hab ich das Script in IDLE
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Meine Empfehlung .. starte dein Script (und ähnliche wie Du jetzt entworfen hast) immer aus einer Eingabeaufforderung, Shell, etc. herraus.

Bsp.:

Code: Alles auswählen

c:\pyscripte> python logsystemstart.py
(Wichtig hierbei ist, dass der Pfad des Python-Interpreters 'python.exe' in Den Umgebungsvariablen von Windows gesetzt ist .. wenn Dies nicht der Fall ist würdest Du es recht schnell mitbekommen)

Dort sollten dann u.a. auch Fehler angezeigt werden und Du kannst das Script mit "STRG + C" (oder auch STRG+Pause für ProzessKick) unter Windows beenden.

Die Fehleranalyse ist zudem recht simple und man kann mit "print" schön Informationen oder Positionen wo das Script gerade ist anzeigen, ohne dass Du Dich in einen "Debugger" einarbeiten müsstest.
Zuletzt geändert von Masaru am Donnerstag 8. März 2007, 01:38, insgesamt 1-mal geändert.
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Meine Empfehlung .. starte dein Scripte (wenn es sich um Consolen-Scripte handelt) immer aus einer Eingabeaufforderung, Shell, etc. herraus.

Dort sollten dann u.a. auch Fehler angezeigt werden und Du kannst das Script mit "STRG + C" (oder auch STRG+Pause für ProzessKick) unter Windows beenden.
Gibt es dafür ein tut?
Unter Linux weiß ich es, aber windows ist mir in manchen sachen nciht so vertraut....


Gruss
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

In welchem Ordner ist dein Skript?...

Start --> Ausführen --> "CMD" eingeben --> dort in den Ordner wechseln...

Wenn es beispielsweise auf dem Desktop ist, brauchst du nur "CD Desktop" einzugeben, wenn es auf "D:" ist, brauchst du nur "D:" einzugeben....

Und dann dort einfach den Namen des Skripts eingeben, musst nichtmal umbedingt "python" davor eingeben.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sephiroth hat geschrieben:Gibt es dafür ein tut?
Ja, in den [wiki]FAQ#WieStarteIchSkripte[/wiki].
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Sephiroth
User
Beiträge: 28
Registriert: Freitag 3. November 2006, 00:12

Danke an: Leonidas; BlackVivi; Masaru und den rest.. :D
Läuft alles prima!!!!

Thread kann daher closed wenn das ein mod sieht.

Zusammenfassend für leute die ein ähnliches Problem haben/hatten wie ich:

Code: Alles auswählen

import time
weiter = True
inp=open('log.txt','a')
while weiter: 
    time.sleep(3)        
    inp.write(time.strftime('%d.%m.%Y %H:%M:%S'))
    inp.write('\n')
    inp.flush()
Das hier funktioniert wunderbar, und mit strg+c abbrechen.


Gruss
BlackJack

Noch ein paar Anmerkungen: `weiter` wird nicht wirklich gebraucht, da kann man gleich ``while True:`` schreiben.

Der Name für das Dateiobjekt ist ein wenig irreführend ─ ich muss bei `inp` jedenfalls an eine Abkürzung für *Input* denken.

Das Zeilenendezeichen kann man auch gleich in die Formatierungszeichenkette von `time.strftime()` einbauen.
Antworten