Seite 1 von 1

Datum vergleichen

Verfasst: Sonntag 11. September 2022, 17:26
von Tippex
Hallo zusammen,
über eine Datei bekomme ich folgende Befehle:


.......
wsheiz/11.9.2022/17:30/20:20
wsheiz/14.9.2022/19:30/21:20
........

Erster Teil ist ein Ident (wsheiz)
Zweiter Teil ist ein Einschaltdatum
Dritter Teil ist die Einschaltuhrzeit
Vierter Teil ist die Ausschaltuhrzeit

Jetzt möchte ich ermitteln ob die aktuelle Datum/Uhrzeit in oder außerhalb dieser Zeiträume liegt:

Mein Programm:

Code: Alles auswählen

while True:
    fi_out2 = open("Dateit2","r")
    for line in fi_out2:
        li=(line.split("/"))
        
        antag = (li[1].split("."))
        an_t = antag[0]
        an_m = antag[1]
        an_j = antag[2]
    
        anzeit = (li[2].split(":"))
        an_st = anzeit[0]
        an_min = anzeit[1]
       
        auszeit = (li[3].split(":"))
        aus_st = auszeit[0]
        aus_min = auszeit[1]
        
        anzeitges = time.struct_time((an_j,an_m,an_t,an_st,an_min,0,0,0,0))
        print(anzeitges)
        auszeitges = time.struct_time((an_j,an_m,an_t,aus_st,aus_min,0,0,0,0))
        print(auszeitges)
        
        akttime = time.localtime()
        print(akttime)
        
        if akttime > anzeitges and akttime < auszeitges:   [b]Fehler:  TypeError: '>' not supported between instances of 'int' and 'str' ...[/b]
           print ("innerhalb")
        else:
           print ("außerhalb")
    # 
fi_out2.close()
Wo habe ich da einen Fehler gemacht? Das mit den Datumsformaten fällt mir generell (noch) schwer.

Vielen Danke

Re: Datum vergleichen

Verfasst: Sonntag 11. September 2022, 17:34
von __blackjack__
@Tippex: Die Meldung ist doch recht deutlich: man kann keine ganzen Zahlen und Zeichenketten auf grösser oder kleiner vergleichen. Du packst da Zeichenketten in eine Struktur und versuchst die dann mit einer Struktur zu vergleichen wo das System sinnvoller- und korrekterweise Zahlen liefert.

Man würde hier aber auch eher mit dem `datetime`-Modul arbeiten.

Du solltest auch bessere Namen verwenden. Keine kryptischen Abkürzungen sondern Namen die dem Leser verraten was der Wert dahinter bedeutet.

Re: Datum vergleichen

Verfasst: Sonntag 11. September 2022, 17:48
von Sirius3
Der Fehler sagt doch genau, wo das Problem liegt, Du wandelst Deine String-Zahlen nicht in int um.

Du öffnest ständig Dateien, die Du nicht wieder schließt. Deshalb sollte man immer das with-Statement benutzen. `fi_out2` ist ein ziemlich schlechter Variablenname für eine Datei, die man zum Lesen, also (input) benutzt. Was soll das `fi´ denn bedeuten? Benutze keine kryptischen Abkürzungen, wie `fi` oder `li`. Was soll denn die 2? Nummern an Variablennamen sagen nichts aus, sollten also nicht benutzt werden. `anzeitges`, `an_st`?

Was bedeuten die Klammern um die split-Ausdrücke?
Zum Verarbeiten von Datum gibt es das datetime-Modul, das man hier auch benutzen sollte.

Code: Alles auswählen

current_date = datetime.datetime.now()
with open("Dateit2", "r") as lines:
    for line in lines:
        _, date, start, stop = line.split('/')
        date = datetime.datetime.strptime(date, '%d.%m.%Y').date()
        start = datetime.datetime.strptime(start, '%H:%M').time()
        stop = datetime.datetime.strptime(stop, '%H:%M').time()
        start = datetime.datetime.combine(date, start)
        stop = datetime.datetime.combine(date, stop)
        if start <= current_date < stop:
           print ("innerhalb")
        else:
           print ("außerhalb")

Re: Datum vergleichen

Verfasst: Sonntag 11. September 2022, 18:01
von __blackjack__
Bezüglich `an_st`: ich möchte lösen: "g", diese Namen machen `angst`. 🤡

Re: Datum vergleichen

Verfasst: Sonntag 11. September 2022, 19:54
von Tippex
Hallo,
komme eigentlich von C++. li_xyz ist z.B. eine lokale Variable des Typs integer... lb lf ls ... global int wäre gi_xyz ....

Python noch am lernen und kann bis heute noch nicht begreifen warum man eine Variable nicht definieren muss. Ein Schreibfehler und man hat eine neue Variable. Aber ansonsten ist Python eine sehr produktive leicht zu lernende Sprache.

an_st soll bedeuten: Anschaltung in Stunde :D

Programm läuft leider nicht

Traceback (most recent call last):
File "./test.py", line 12, in <module>
stop = datetime.datetime.strptime(stop, '%H:%M').time()
File "/usr/lib/python3.7/_strptime.py", line 577, in _strptime_datetime
tt, fraction, gmtoff_fraction = _strptime(data_string, format)
File "/usr/lib/python3.7/_strptime.py", line 362, in _strptime
data_string[found.end():])
ValueError: unconverted data remains:

Re: Datum vergleichen

Verfasst: Sonntag 11. September 2022, 20:05
von Tippex
programmiere auf dem Raspberry unter Linux mit Thonny

Re: Datum vergleichen

Verfasst: Sonntag 11. September 2022, 20:09
von Sirius3
Der neue Fehler kommt daher, dass Zeilen mit einem Zeileendezeichen enden, kann man z.B. per `line.strip().split('/')` lösen.
Auch in C++ sollte man keine kryptischen Abkürzungen benutzen und auch dort führt ein Schreibfehler zu einem Programmfehler. Typen haben nichts im Variablennamen verloren, und da man nur mit lokalen Variablen arbeitet, müßten alle mit l anfangen, was diesen Buchstaben überflüssig macht.

Re: Datum vergleichen

Verfasst: Sonntag 11. September 2022, 20:22
von Tippex
Hi,
super, dass war der Fehler. Jetzt muss ich noch ins Python-Buch schauen damit ich die Programmzeilen auch alle verstehe.
Gerne würde ich mich dazu nochmals melden falls was nicht klar wird.

Vielen Dank für die Unterstützung!

Re: Datum vergleichen

Verfasst: Sonntag 11. September 2022, 22:02
von __blackjack__
@Tippex: Dabei ist das mit den nicht deklarierten Variablen nur halb so schlimm wie es sein könnte, denn das ist ja nur bei Zuweisungen von Werten ein Problem. Falls man sich beim Verwenden eines Namens vertippt, gibt es zumindest einen `NameError` zur Laufzeit. Es gibt Programmiersprachen da würde nicht einmal das passieren, sondern einfach eine neue Variable mit einem Defaultwert entstehen. War bei meiner ersten Programmiersprache so: BASIC auf dem C64. 🤓

Re: Datum vergleichen

Verfasst: Sonntag 25. September 2022, 20:43
von Tippex
Hallo,
bin jetzt am weiter programmieren und hänge jetzt an der Fehlermeldung

list_mail[x][0] = date
NameError: name 'list_mail' is not defined


Warum zum Teufel soll ich den Listennamen vorher definieren?
Da ich die Dateizeilen von hinten lesen möchte, habe ich mir überlegt, alle Zeilen in eine Liste zu scheiben und dann diese von hinten her zu lesen.

Könnte mir da jemand einen Hinweis geben? Das wäre super!
Bitte jetzt keine andere Lösung vorschlagen wie ich die Datei von hinten lesen kann - weis dass es da auch andere Möglichkeit gibt - würde gerne so weiter machen mit einem Array/Liste.

Danke

Code: Alles auswählen

  
#!/usr/bin/python3

import sys
import subprocess #bash starten
import time, datetime, copy


x=0
with open("gmxout2", "r") as lines:
    for line in lines:
        _, date, start, stop = line.strip().split('/')
        date = datetime.datetime.strptime(date, '%d.%m.%Y').date()
        start = datetime.datetime.strptime(start, '%H:%M').time()
        stop = datetime.datetime.strptime(stop, '%H:%M').time()
        start = datetime.datetime.combine(date, start)
        stop = datetime.datetime.combine(date, stop)
        #breakpoint()
        print(date)

# Daten in Liste schreiben
        list_mail[x][0] = date
        list_mail[x][1] = start
        list_mail[x][2] = stop
        x=x+1

current_date = datetime.datetime.now()
#x+1 = Anzahl Mails

#Liste rückwärtslesen und auf Gleichheit mit heute prüfen
y = copy.deepcopy(x)
while y >= 0:
    print(list_mail[y])
    y=y-1
.......

Re: Datum vergleichen

Verfasst: Sonntag 25. September 2022, 20:56
von Dennis89
Hallo,

woher zum Teufel soll der Python-Interpreter wissen was 'list_mail' sein soll, wenn du das nicht definierst?

Grüße
Dennis

Re: Datum vergleichen

Verfasst: Sonntag 25. September 2022, 21:01
von __blackjack__
@Tippex: Auch hier sagt die Fehlermeldung recht deutlich was das Problem ist. `list_mail` ist nicht definiert. Werte fangen nicht einfach so an zu existieren weil man das gerade für praktisch halten würde, und Python schaut auch nicht den Namen an und rät was das denn überhaupt für ein Typ sein soll der da auf magische Weise verwendet werden soll.

Wahrscheinlich möchtest Du irgendwo vorher mal eine leere Liste anlegen. Und auch da kann man dann nicht auf irgenwelche nicht existierenden Indizes zugreifen. Das `x` ist hier auch unsinnig. Häng die Werte einfach an die Liste an, da braucht man keinen Index für.

Und beim Indexzugriff auf das Listenelement dann das gleiche Problem. Statt da mit magischen, festen 0 - 2 Werten zu arbeiten, erstelle ein Objekt mit den drei Werten, beispielsweise eine Liste oder ein Tupel und hänge dieses Objekt an die Liste an. `date` da mit rein zu stecken ist redundant. Man würde entweder *das* weg lassen, oder `start` und `stop` als `time`-Objekte belassen.

Grunddatentypen haben in Namen nichts zu suchen. Man ändert den Typ während der Programmentwicklung ab und zu mal, und dann hat man entweder falsche, irreführende Namen, oder muss alle betroffenen Namen im Programm anpassen. Das wäre dann also eher `mails`.

Man sollte an einen Namen im gleichen Namensraum auch keine Werte verschiedenen (Duck-)Typs binden. `start` und `stop` sollten hier nur an Zeiten oder nur an komplette Zeitpunkte gebunden werden. Man muss hier auch nicht jedes Zwischenergebnis an einen Namen binden.

`deepcopy()` auf einen `int`-Wert anzuwenden ist sinnlos weil ganze Zahlen unveränderlich sind. Überhaupt ist `deepcopy()` ein Warnzeichen, dass da was falsch läuft. Das braucht man nur *sehr* selten.

Ähnliches gilt für Indexwerte. Die braucht man auch nur selten. Wenn Du in umgekehrter Reihenfolge über eine Sequenz iterieren möchtest, verwende einfach die `reversed()`-Funktion.

Re: Datum vergleichen

Verfasst: Sonntag 25. September 2022, 21:04
von sparrow
Ich finde es übrigens sehr witzig, dass __blackjack__ darauf hinweist, wann ein NameError ausgelöst wird und Tippex das einen Post später leider nicht mehr weiß.

Re: Datum vergleichen

Verfasst: Dienstag 27. September 2022, 16:46
von bb1898
sparrow hat geschrieben: Sonntag 25. September 2022, 21:04 Ich finde es übrigens sehr witzig, dass __blackjack__ darauf hinweist, wann ein NameError ausgelöst wird und Tippex das einen Post später leider nicht mehr weiß.
Ich glaube, da fehlte eher die Überlegung, dass "list_mail[x][0] = date" nicht einfach eine Zuweisung an einen neuen Namen ist, sondern erst mal die Verwendung des Namens "list_mail", der noch nicht definiert ist. Denn ohne die Indexzugriffe würde es ja gehen:

Code: Alles auswählen

list_mail = [None, [date]]
wenn ich mal ganz frech x = 1 voraussetze. Dass die Konstruktion unsinnig ist, steht auf einem anderen Blatt.

Re: Datum vergleichen

Verfasst: Dienstag 27. September 2022, 18:32
von __blackjack__
@bb1898: Das sollte jemandem der von C++ kommt, aber schon irgendwie klar sein, und auch mit genug wissen über Datentypen, dass nicht klar ist welchen Typ `list_mail` dann hätte, wenn so etwas funktionieren sollte.