Datum vergleichen

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
Tippex
User
Beiträge: 7
Registriert: Donnerstag 14. Juni 2018, 15:07

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
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

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")
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Bezüglich `an_st`: ich möchte lösen: "g", diese Namen machen `angst`. 🤡
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Tippex
User
Beiträge: 7
Registriert: Donnerstag 14. Juni 2018, 15:07

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:
Tippex
User
Beiträge: 7
Registriert: Donnerstag 14. Juni 2018, 15:07

programmiere auf dem Raspberry unter Linux mit Thonny
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

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.
Tippex
User
Beiträge: 7
Registriert: Donnerstag 14. Juni 2018, 15:07

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!
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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. 🤓
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Tippex
User
Beiträge: 7
Registriert: Donnerstag 14. Juni 2018, 15:07

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
.......
Benutzeravatar
Dennis89
User
Beiträge: 1153
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

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

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

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ß.
bb1898
User
Beiträge: 200
Registriert: Mittwoch 12. Juli 2006, 14:28

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.
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten