Abfrage-Frage

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
mechanicalStore
User
Beiträge: 177
Registriert: Dienstag 29. Dezember 2009, 00:09

Wenn start und ende vorhanden sind, will ich prüfen, ob search dazwischen liegt, wenn ende fehlt, will ich schauen ob search > start ist. Lässt sich das rgendwie noch vereinfachen/zusmmenfassen? Wenn ende = None ist, kann ich das ja nicht in der gleichen Abfrage verwenden.

Code: Alles auswählen

from datetime import datetime


def main():
    
    start_date: datetime = datetime(year = 2022, month = 5, day = 10)
    
    # end_date: datetime = datetime(year = 2024, month = 7, day = 15)
    end_date: datetime = None
    
    search_date: datetime = datetime(year = 2023, month = 11, day = 20)
    
    search(start_date, end_date, search_date)
    

def search(start_date, end_date, search_date):

    check: bool = False
    if not end_date:
        if start_date <= search_date:
            check = True
    else:
        if start_date <= search_date < end_date:
            check = True

    print('foo') if check else print('bar')


if __name__ == '__main__':
    main()
Benutzeravatar
sparrow
User
Beiträge: 4535
Registriert: Freitag 17. April 2009, 10:28

Die Beschreibung deines Problems passt nicht zum Code.
Wenn start und ende vorhanden sind, will ich prüfen, ob search dazwischen liegt

Code: Alles auswählen

if start_date <= search_date < end_date:
Die Parameter von "search" würde ich in der Reihenfolge ändern, so dass "end_date" nicht unbedingt gesetzt werden muss (und None als default hat). Der Wert wird ggf. durch einen Maximalwert ersetzt.

Ungetestet:

Code: Alles auswählen

import datetime
from datetime import datetime as DateTime

MAX_DATETIME = DateTime(year=datetime.MAXYEAR, month=12, day=31)

def main():
    start_date = DateTime(year = 2022, month = 5, day = 10) 
    end_date = DateTime(year = 2024, month = 7, day = 15)
    search_date = DateTime(year = 2023, month = 11, day = 20)
    is_date_between(search_date, start_date, end_date)
    

def is_date_between(search_date, start_date, end_date=None):
    end_date = MAX_DATETIME if end_date is None else end_date
    return start_date <= search_date < end_date

if __name__ == "__main__":
    main()
Benutzeravatar
pillmuncher
User
Beiträge: 1530
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Oder so:

Code: Alles auswählen

from datetime import datetime


def main():
    start_date: datetime = datetime.fromisoformat("2022-05-10")
    end_date: datetime = datetime.fromisoformat("2023-07-15")
    search_date: datetime = datetime.fromisoformat("2024-11-20")

    if is_between(start_date=start_date, search_date=search_date, end_date=end_date):
        print("foo")
    else:
        print("bar")
    if is_between(start_date=start_date, search_date=search_date):
        print("foo")
    else:
        print("bar")


def is_between(*, start_date, end_date=None, search_date):
    return start_date < search_date <= (search_date if end_date is None else end_date)


if __name__ == "__main__":
    main()
Du hattest geschrieben, dass du auf search > start testst, im code steht aber logisch search >= start. Ich habe das deswegen dahingehend geändert, sodass start_date aus- und end_date eingeschlossen sind in der Suche. Es ist auch meistens besser, wenn Funktionen kein IO haben, wie etwa print(). Dann kann man die Logik einfach testen, ohne dass man sich mit den ganzen print Ausgaben herumärgern muss. Siehe dazu: https://www.youtube.com/watch?v=DJtef410XaM
In specifications, Murphy's Law supersedes Ohm's.
mechanicalStore
User
Beiträge: 177
Registriert: Dienstag 29. Dezember 2009, 00:09

Habe mich etwas falsch ausgedrückt. Es ist in dem Fall wie ein „rechts offenes Intervall“, also start_date ist immer inkludiert, end_date exkludiert. Aus dem Grund wird der Code von pillmuncher, so toll er auch ist, nicht laufen, da search_date < search_date nicht die Bedingung erfüllt.
Übrigens die print Aufrufe dienten nur der Demonstration (um ein lauffähiges Beispiel zu generieren), der eigentliche Code hat das so natürlich nicht.
Danke für die Antworten, ist auf jeden Fall (durch sparrow‘s) Code jetzt kompakter, das was ich wollte.

Gruß
Sirius3
User
Beiträge: 18257
Registriert: Sonntag 21. Oktober 2012, 17:20

@mechanicalStore: Typannotationen sollten irgendjemandem einen Mehrwert bieten, bei Deinen ist schon allein durch die Zuweisung klar, dass es sich um `datetime` handelt, man kann die also weglassen.
Ein Flag wie `check` braucht man im Normalfall nicht, weil man die Prüfung auch einfach als Funktion schreiben könnte, was den Code nochmals lesbarer macht.
Der Tenary-Operator `a if b else c` ist ein Ausdruck, das heißt, man sollte irgendwas mit dem Ergebnis machen, bei Deinem Ausdruck mit `print` machst Du aber mit dem Rückgabewert nichts. Das sollte man also als normales if schreiben, oder `foo` if check else `bar`.

Die einfachste Lösung wäre `and` und `or`:

Code: Alles auswählen

from datetime import datetime

def search(search_date, start_date, end_date=None):
    check = start_date <= search_date and (end_date is None or search_date < end_date)
    print("foo" if check else "bar")

def main():
     start_date = datetime(year=2022, month=5, day=10)
    # end_date = datetime(year=2024, month=7, day=15)
    search_date = datetime(year=2023, month=11, day=20)
    search(search_date, start_date)

if __name__ == '__main__':
    main()
mechanicalStore
User
Beiträge: 177
Registriert: Dienstag 29. Dezember 2009, 00:09

@Sirius3: Genau da wäre ich mir nicht sicher, ob das immer funktioniert:

Code: Alles auswählen

... (end_date is None or search_date < end_date)
Wenn der "or" Teil als erstes interpretiert würde, gäbe es doch eine Exception beim Vergleich. Warum ist es so sicher, dass nach

Code: Alles auswählen

end_date is None
der "or" Teil überhaupt gar nicht mehr geprüft wird?
Sirius3
User
Beiträge: 18257
Registriert: Sonntag 21. Oktober 2012, 17:20

Weil das die Funktionsweise von `or` ist: Werte den ersten Ausdruck aus, falls das Ergebnis wahr ist, ist das das Ergebnis des gesamten Ausdrucks, und der zweite Teil wird nicht ausgeführt. Nur falls der erste Teil unwahr ist, wird das Ergebnis des zweiten Teils zurückgeliefert.
Antworten