Jeden Tag um die gleiche zeit etwas in Datei schreiben

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
egon11
User
Beiträge: 354
Registriert: Mittwoch 14. Dezember 2016, 20:59

Hallo, ich möchte jeden Tag um die gleiche Zeit etwas in eine Datei schreiben.
Es läuft ein Script in einer Dauerschleife, aber das Script könnte auch ab und an mal neugestartet werden.
Jetzt habe ich folgenden Code:

Code: Alles auswählen

while True:
    z = 0
    zeit = datetime.now()
    with open("~/zeit.txt", "r+") as oeffnen:
        lesen = oeffnen.readlines()
  
    if not lesen:
        with open("~/zeit.txt", "w") as schreib:
            schreib.write(str(z) + "\n" + str (zeit))

    elif datetime.strptime(lesen[1],"%Y-%m-%d %H:%M:%S.%f" ) < (zeit - timedelta(hours=24)):
        with open("~/zeit.txt", "w") as schreib:
            schreib.write(str(z) + "\n" + str(zeit))
    else:
 
    time.sleep(1)
    z += 1
Aber so richtig bin ich noch nicht überzeugt bzw. zählt es 24h ab da, wo ich das erste mal in die Datei die Zeit geschrieben habe.

Wie könnte ich es noch ausbauen, um ab z.b. 6.00 Uhr jeden Tage etwas rein geschrieben wird. Wenn das Script unterbrochen wird und um 7 neu gestartet wird, soll es eben um 7 schreiben.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was hast du denn fuer ein System? Denn sowas macht man eigentlich mit den dafuer vorgesehenen Scheduler, also zB time units unter Linux, unter Windows der Taskplaner (https://learn.microsoft.com/de-de/windo ... cific-time), und ich vermute mal macOS launchd kann sowas auch. Oder deren Automations-Framework, Automator oder wie das heisst.
Sirius3
User
Beiträge: 17759
Registriert: Sonntag 21. Oktober 2012, 17:20

Der Filemodus r+ ist eigentlich für Text-Dateien nie sinnvoll.
Man stückelt keine Strings mit + zusammen, sondern nutzt Formatstrings.
`lesen` ist eher ein Name für eine Funktion, und nicht für Zeilen, die gelesen wurden. Ebenso `oeffnen` oder `schreib`.
~ wird nicht automatisch in das Home-Verzeichnis konvertiert, Du hast also in Deinem aktuellen Arbeitsverzeichnis ein Verzeichnis ~?
Stringliterale sollten nur einmal im Code vorkommen, vor allem wenn es sich um Dateinamen handelt. Dann definiert man den String einmal als Konstante am Anfange der Datei.
Wenn Du eine fixe Zeit haben willst, dann mußt Du halt die Zeit absolut angeben und nicht mit timedelta.
Der else-Block ist leer, das ist ein Syntaxfehler.
Die selbe Datei alle 1 Sekunde zu lesen, ist Resourcenverschwendung. Du kennst ja nach dem ersten Lesen den Inhalt.
`z` hat immer den Wert 0.
Zeilen in einer Datei enden immer mit einem Zeile-Ende-Zeichen.

Code: Alles auswählen

import time
from datetime import datetime
from pathlib import Path

ZEIT_FILENAME = Path.home() / "zeit.txt"

def main():
    try:
        counter, last_time = ZEIT_FILE.read_text().splitlines()
    except (IOError, ValueError):
        # something wrong with the file
        counter = last_time = None
    else:
        last_time = datetime.strptime(last_time, "%Y-%m-%d %H:%M:%S.%f")
    while True:
        now = datetime.now()
        signal_time = datetime(now.year, now.month, now.day, 6, 0, 0)
        if last_time is None or (last_time < signal_time and now >= signal_time):
            last_time = now
            ZEIT_FILENAME.write_text(f"0\n{last_time}\n")
        time.sleep(1)

if __name__ == "__main__":
    main()
egon11
User
Beiträge: 354
Registriert: Mittwoch 14. Dezember 2016, 20:59

Ok das klappt. Ich hatte nur nicht auf dem Schirm das man bei datetime auch die Argumente setzen kann wie man will (datetime(now.year, now.month, now.day, 6, 0, 0).

Was mir gerade nicht geläufig ist, der "counter" vor der Variable zähl wohl jedes mal hoch?
egon11
User
Beiträge: 354
Registriert: Mittwoch 14. Dezember 2016, 20:59

Ich habe mal noch 2 Fragen, könnte man den obigen Code nicht auch so abkürzen:

Code: Alles auswählen

try:
   last_time = datetime.strptime(FILENAME.read_text().splitlines()[1], "%Y-%m-%d %H:%M:%S.%f")
    
except (IOError, IndexError, ValueError):
        last_time = None
Und würde sich das gegenseitig behindern, wenn 2 Scripte auf eine Datei zugreifen (lesend oder schreibend)? Oder würde ein Prozess dann warten?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn due den Counter nicht willst, muss der schon vernünftig raus programmiert werden. Nicht durch weglassen und dann einfach immer noch annehmen, das gewünschte Datum wäre in der zweiten Zeile.

Zwei Prozesse über eine Datei zu synchronisieren erfordert mehr Arbeit. Da wartet niemand von alleine höflich auf den anderen, sondern da wird aufeinander rum getrampelt. Warum glaubst du das so mache zu müssen? Was soll da insgesamt passieren?
egon11
User
Beiträge: 354
Registriert: Mittwoch 14. Dezember 2016, 20:59

Wie meinst du das mit den counter rausprogrammieren?

Ich wollte 2 separate Scripte bauen, der eine der in die Datei schreibt und der andere, der der von der Datei liest, aber das ist das kleinste Problem.
Das kann ich auch gut in einen Script machen.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Warum willst du den Code von Sirius3 aendern? Offensichtlich doch um den counter loszuwerden, oder nicht? Denn der steht nicht mehr in der Zeile. Wenn du aber von zwei gespeicherten Informationen auf eine gehst, dann ist es doch falsch, mit [1] auf die *zweite* Zeile zuzugreifen. Wenn du nicht verstehst, was da passiert, dann ist es besser, den counter einfach nicht weiter zu benutzen, statt daran rumfrickeln zu wollen.

Wirklich erleuchtet, was das gesamtproblem angeht, bin ich nicht. Aber wenn du ohne diese Kruecke mit einer Datei auskommst (die noch einen ganzen Sack anderer Probleme hat), dann solltest du darauf verzichten, ja.
Benutzeravatar
__blackjack__
User
Beiträge: 13122
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wozu soll denn jeden Tag um die gleiche Zeit diese Zeit als Text in einer Datei geschrieben werden um dann von einem anderen Programm gelesen zu werden? Das andere Programm kann doch auch einfach die aktuelle Zeit ermitteln und damit feststellen ob ein bestimmter Zeitpunkt noch in der Zukunft oder schon in der Vergangenheit liegt‽ Welches tatsächliche Problem soll denn hier gelöst werden?

Zumal man für das hier besprochene Programm auch keinen dauerhaft laufenden Prozess schreiben würde, nicht mal Python benutzen würde, sondern einfach einen Eintrag in der crontab setzen würde:

Code: Alles auswählen

0 6 * * *  date +'%Y-%m-%d %T.%N' > /home/username/zeit.txt
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten