zwei Datumsangaben vergleichen
Der Cache ist zwar ein Speicher, aber halt nicht der Speicher. Wenn du mehrere CPU-Kerne hast, hast du auch mehrere getrennte L1- und L2-Caches, die jeweils komplett unabhängig voneinander sind. Und wenn du auf die gleichen Werte aus zwei verschiedenen Kernen zugreifst, hast du am Ende in jedem Cache eine eigene Kopie. Zusätzlich zu der Kopie im RAM.
Das Programm weiß davon aber nichts, und die CPU kümmert sich vollständig alleine darum, dass alles passt. Meistens. Und wenn die Daten gerade nicht im Cache sind, führt die CPU einfach weiter die nächsten Instruktionen aus, die nach dem Lesezugriff im Programm kommen.
Und wenn da ein bedingter Sprung vorkommt, führt die CPU einfach einen der beiden Fälle aus, bevor die Bedingung überhaupt ausgewertet ist. Bei normalen Programmen rät eine CPU heutzutage in >95% der Fälle richtig. Und wenn sie nicht richtig liegt, macht sie einfach alles wieder rückgängig und fängt von vorne an.
Muss man alles wissen, um `datetime.datetime` richtig benutzen zu können.
Das Programm weiß davon aber nichts, und die CPU kümmert sich vollständig alleine darum, dass alles passt. Meistens. Und wenn die Daten gerade nicht im Cache sind, führt die CPU einfach weiter die nächsten Instruktionen aus, die nach dem Lesezugriff im Programm kommen.
Und wenn da ein bedingter Sprung vorkommt, führt die CPU einfach einen der beiden Fälle aus, bevor die Bedingung überhaupt ausgewertet ist. Bei normalen Programmen rät eine CPU heutzutage in >95% der Fälle richtig. Und wenn sie nicht richtig liegt, macht sie einfach alles wieder rückgängig und fängt von vorne an.
Muss man alles wissen, um `datetime.datetime` richtig benutzen zu können.
- __blackjack__
- User
- Beiträge: 13572
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Wobei die >95% richtig raten bei Verzweigungsvorhersagen nicht unbedingt daran liegt, dass die CPU gut im raten wäre, sondern auch weil die Leute die Compiler schreiben, wissen wie die CPU ”rät” und nach Möglichkeit Maschinencode erzeugen der die CPU richtig ”raten” lässt.
„Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.“ — Brian W. Kernighan
-
- User
- Beiträge: 982
- Registriert: Sonntag 19. September 2021, 09:40
Na ganz einfach: Ich bin zu blöd für diese komplexen neuen Möglichkeiten - mit einer Kommazahl kann ich umgehen!
Jetzt hänge ich schon wieder fest:
In meinem Rechentrainer melden sich ziemlich viele Nutzer doppelt, dreifach an oder auch noch öfter. Ich habe keine Ahnung, ob ihnen ihr Anmeldename nicht gefällt oder sie nach der Anmeldung sofort wieder ihr Passwort vergessen oder sie sich nur gerne irgendwo registrieren. Diese Anmeldungen sind nicht so leicht zu finden und ich hattte jetzt die Idee, wenigsten bei den Anmeldungen im letzten Schulhalbjahr schon mal diejenigen zu löschen, die sich nur einmal angemeldet haben und auch keine Anufgaben gerechnet haben. Dazu wollte ich nur einfach überprüfen, ob der letzte Login mit dem Datum der Registriereung identisch ist. Ich habe es geschafft, zu überprüfen ob der Tag (im Monat) der selbe ist aber nicht das Datum. (Bei "meinem" Starbasic war das halt einfach der ganzahlige Anteil - das hatte ich verstanden.)
Also:
Code: Alles auswählen
def loeschen(req):
auswahl = Profil.objects.filter(user__date_joined__lt=date(2023,8,1))
for a in auswahl:
if (a.user.date_joined.day ) == ((a.user.last_login.day )):
print(a)
return HttpResponse("fertig!")
von welchem Typ sind denn `date_joined` und `last_login`,welche Attribute hat/haben der Typ/die Typen?
___________________________________________________________________________________________________
https://www.python-kurs.eu/index.php
https://learnxinyminutes.com/docs/python/ https://learnxinyminutes.com/docs/de-de/python-de/
https://quickref.me/python | https://docs.python-guide.org/
- __blackjack__
- User
- Beiträge: 13572
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Pitwheazle: Im Grunde ist da doch eigentlich nichts anders als bei StarBASIC. Wenn Du dort zwei „serial“ Zahlen hast die Tage repräsentieren kannst Du die einfach Vergleichen. Sollte einer oder beide der Werte auch Zeitanteile enthaltenm musst Du davon vorher den Tagesanteil isolieren, mit einer Funktion. Wenn Du in Python zwei `Date`-Objekte hast, kannst Du die einfach vergleichen. Sollte einer oder beide der Werte auch Zeitanteile haben, musst Du davon vorher den Tagesanteil isolieren, mit einer Methode. Grundsätzlich das gleiche vorgehen.
„Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.“ — Brian W. Kernighan
-
- User
- Beiträge: 982
- Registriert: Sonntag 19. September 2021, 09:40
... das sind die datetime Werte aus der django.contrib.auth
... das ist mir sogar (ausnahmsweise) klar - nur bei StarBasic kann ich das, bei Django nicht. Welche Methode isoliert das Datum (ohne Zeit)?__blackjack__ hat geschrieben: ↑Donnerstag 21. September 2023, 15:44 ... Sollte einer oder beide der Werte auch Zeitanteile enthaltenm musst Du davon vorher den Tagesanteil isolieren, mit einer Funktion. Wenn Du in Python zwei `Date`-Objekte hast, kannst Du die einfach vergleichen. Sollte einer oder beide der Werte auch Zeitanteile haben, musst Du davon vorher den Tagesanteil isolieren, mit einer Methode. Grundsätzlich das gleiche vorgehen.
- noisefloor
- User
- Beiträge: 3942
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
Wenn du mal eine alternative, stark beispiellastige Doku als Alternative zur Python-Doku lesen möchtest: https://pymotw.com/3/datetime/index.htm ... e-datetime
Gruß, noisefloor
dateime-Objekte haben eine date() Methode. datetime und date-Objekte haben Attribute für day, month und year:Welche Methode isoliert das Datum (ohne Zeit)
Code: Alles auswählen
>>> from datetime import datetime
>>> some_time = datetime.now()
>>> some_time.date()
datetime.date(2023, 9, 21)
>>> some_time.date().day
21
>>> some_time.date().month
9
>>> some_time.date().year
2023
>>> some_time.year
2023
>>> some_time.month
9
>>> some_time.day
21
>>>
Gruß, noisefloor
-
- User
- Beiträge: 982
- Registriert: Sonntag 19. September 2021, 09:40
Danke. Ich fürchte, ich habe einfach grundsätzliche Probleme im Verständnis des objektorientierten Programmieren. Obwohl ich viele Anleitungen gelesen habe und auch weiß, das man Auto-modelle rot und blau färben kann und in Lkws umwandeln kann, es fällt es mir einfach schwer dies auf meine Probleme anzuwenden. ... und ich glaube, auch die Sprache der Django Dokumentation überfordert mich und Anleitungen wie die, von dir verlinkte, hilft mir weiter. Und auch w3shool oder delftstack haben mir eher weitergeholfen oder natürlich stackoverflow.
- noisefloor
- User
- Beiträge: 3942
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
die ganze Python Module of the Week Seite ist schon ziemlich gut. Weil das halt viel (bzw.fast alles) aus der Standardbibliothek erklärt wird, viel mit Beispielen. PMOTW gab's früher übrigens auch mal als Buch.
Die Django Doku ist auch schon ziemlich gut - nur geht die halt davon aus, dass man ein bisschen was kennt. Z.B. was ein datetime Objekt ist.
Gruß, noisefloor
die ganze Python Module of the Week Seite ist schon ziemlich gut. Weil das halt viel (bzw.fast alles) aus der Standardbibliothek erklärt wird, viel mit Beispielen. PMOTW gab's früher übrigens auch mal als Buch.
Die Django Doku ist auch schon ziemlich gut - nur geht die halt davon aus, dass man ein bisschen was kennt. Z.B. was ein datetime Objekt ist.
Gruß, noisefloor
-
- User
- Beiträge: 982
- Registriert: Sonntag 19. September 2021, 09:40
Vielleicht erklärt das mein Problem mithilfe der Django Doku zu lernen was ein datetime Objekt istnoisefloor hat geschrieben: ↑Donnerstag 21. September 2023, 17:46 Die Django Doku ist auch schon ziemlich gut - nur geht die halt davon aus, dass man ein bisschen was kennt. Z.B. was ein datetime Objekt ist.
-
- User
- Beiträge: 982
- Registriert: Sonntag 19. September 2021, 09:40
Bevor ich hier noch ein neues Posting aufmache, hänge ich die Frage doch hier gleich an:
Ich habe ja geschrieben, dass ich auf der Suche nach ungenutzten Accounts bin. Dabei habe ich fetsgestellt, dass es zwei Accounts gibt, die nicht mit einem Profil vernüpft sind. Die habe ich so gefunden:
... das ist sicher nicht elegant. Mein "Profil" ist so verknüpft:
... wie finde ich offiziell die Accounts, die keine Verknüfung haben?
Ich habe ja geschrieben, dass ich auf der Suche nach ungenutzten Accounts bin. Dabei habe ich fetsgestellt, dass es zwei Accounts gibt, die nicht mit einem Profil vernüpft sind. Die habe ich so gefunden:
Code: Alles auswählen
def fake(req):
auswahl = User.objects.filter(date_joined__lt=date(2023,8,1))
for a in auswahl:
try:
print(a.profil)
except:
print(" kein Profil: ", a)
return HttpResponse("fertig!")
Code: Alles auswählen
class Profil(models.Model):
user = models.OneToOneField(User, related_name='profil', on_delete=models.CASCADE )
-
- User
- Beiträge: 982
- Registriert: Sonntag 19. September 2021, 09:40
Und auch hier finde ich den Fehler nicht:
Ich habe geschrieben, dass ich alle Accounts aus dem letzten Halbjahr löschen will, bei denen die Registrierung und der letzte Login am gleichen Tag erfolgte und die keine Aufgaben (im "Protokoll") gemacht haben.
Jedesmal wenn ich den Code:
ausführe, bekomme ich neue User gemeldet die gelöscht wurden. Was habe ich denn da wieder übersehen? Die "id"s werden doch nicht neu vergeben?
Ich habe geschrieben, dass ich alle Accounts aus dem letzten Halbjahr löschen will, bei denen die Registrierung und der letzte Login am gleichen Tag erfolgte und die keine Aufgaben (im "Protokoll") gemacht haben.
Jedesmal wenn ich den Code:
Code: Alles auswählen
def loeschen(req):
auswahl = Profil.objects.filter(user__date_joined__lt=date(2023,8,1))
for a in auswahl:
if (a.user.date_joined.date() ) == ((a.user.last_login.date() )):
aufgaben = Protokoll.objects.filter(user_id = a.user.id).count()
if aufgaben == 0:
print( a, ": ", aufgaben)
account = User.objects.get(id=a.user.id)
print(account, " gelöscht")
account.delete()
return HttpResponse("fertig!")
-
- User
- Beiträge: 982
- Registriert: Sonntag 19. September 2021, 09:40
Ich lerne ja dank eurer unermüdlichen Hilfe immer wieder (ein Bisschen) dazu - vielleicht bekomme ich das mit dem Filter ja auch mal hin (ohne rumprobieren zu müssen).
Das funktioniert:
aber das nicht:
Das funktioniert:
Code: Alles auswählen
auswahl = User.objects.filter(date_joined__lt=date(2023,8,1))
for a in auswahl:
if (a.date_joined.date() ) == ((a.last_login.date() )):
Code: Alles auswählen
auswahl = User.objects.filter(date_joined__lt=date(2023,8,1), date_joined.date() = last_login.date())
Ja nee, das kann auch nicht funktionieren.
Ich hatte bereits an anderer Stetlle einmal erklärt, dass das eine Python Code ist und das andere wird vom ORM in eine SQL-Query gewandelt.
Ich hoffe, du hast die Namen vernünftig vergeben und "date_joined" ist ein date. Dann brauchst du da gar nicht wandeln. Wenn es eine DatetTimeField ist, dann ist deine Namensgebung kaputt.
Was hast du denn in der Dokumentation zu Djangos Querysets gefunden? Welche Lookups gibt es denn für Felder, die dir eventuell weiterhelfen können?
Ich hatte bereits an anderer Stetlle einmal erklärt, dass das eine Python Code ist und das andere wird vom ORM in eine SQL-Query gewandelt.
Ich hoffe, du hast die Namen vernünftig vergeben und "date_joined" ist ein date. Dann brauchst du da gar nicht wandeln. Wenn es eine DatetTimeField ist, dann ist deine Namensgebung kaputt.
Was hast du denn in der Dokumentation zu Djangos Querysets gefunden? Welche Lookups gibt es denn für Felder, die dir eventuell weiterhelfen können?
-
- User
- Beiträge: 982
- Registriert: Sonntag 19. September 2021, 09:40
Das "last_login" wird genauso wie "date_joined", wie schon beschrieben, von django.contrib.auth zur Verfügung gestellt und ich dachte, das seien beides datetime Objekt und
funktioniert auch aber
nicht. Ich bekomme die Fehlermeldung
... außerdem wollte ich ja nicht die Daten von date_joined und last_login inklusive Uhrzeit vergleichen sondern nur den Tag.
Code: Alles auswählen
]auswahl = User.objects.filter(last_login__lt=date(2023,8,1)
Code: Alles auswählen
auswahl = User.objects.filter(date_joined__lt=date(2023,8,1), date_joined = last_login)
Code: Alles auswählen
name 'last_login' is not defined
Wie gesagt, die Antwort liegt immer in der Dokumentation. Schau dir mal die Field lookups an. Darauf habe ich ja in meinem letzten Post schon hingewiesen. Es ist wichtig, sich mit dem ORM und den Queries in Django zu beschäftigen.
Und um auf Felder im selben Datensatz zu verlinken benötigst du F() Expressions.
Und um auf Felder im selben Datensatz zu verlinken benötigst du F() Expressions.
- __blackjack__
- User
- Beiträge: 13572
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Pitwheazle: Das die beiden folgenden Varianten…
…nicht funktionieren hat aber auch erst einmal überhaupt nichts mit Django zu tun. Das sollte also eigentlich nicht überraschen, sondern klar sein. Spätestens nach der Fehlermeldung und kurz überlegen sollte man sich darüber nicht wundern.
Django verändert nichts an der Python-Syntax, die gilt natürlich für jede Bibliothek die man verwendet. Da Python keine Referenzen als Datentyp kennt, kann man einem Rückgabewert, beziehungsweise noch allgemeiner einem Ausdruck nichts zuweisen. Auch in Django-Code geht das nicht. Bei Aufrufen mit Schlüsselwortargumenten muss vor dem ``=`` immer ein Name stehen. Daran kann Django nichts ändern.
Und was nach dem ``=`` steht muss natürlich ein Ausdruck sein, dessen Bestandteile die nicht literale sind, vorher irgendwo definiert worden sind. Wenn man `last_login` übergibt, muss Python das *vor* dem eigentlichen Aufruf durch einen konkreten Wert ersetzen können, wie bei jedem anderen Aufruf auch. Auch daran kann eine Bibliothek nichts ändern.
Code: Alles auswählen
auswahl = User.objects.filter(date_joined__lt=date(2023,8,1), date_joined.date() = last_login.date())
auswahl = User.objects.filter(date_joined__lt=date(2023,8,1), date_joined = last_login)
Django verändert nichts an der Python-Syntax, die gilt natürlich für jede Bibliothek die man verwendet. Da Python keine Referenzen als Datentyp kennt, kann man einem Rückgabewert, beziehungsweise noch allgemeiner einem Ausdruck nichts zuweisen. Auch in Django-Code geht das nicht. Bei Aufrufen mit Schlüsselwortargumenten muss vor dem ``=`` immer ein Name stehen. Daran kann Django nichts ändern.
Und was nach dem ``=`` steht muss natürlich ein Ausdruck sein, dessen Bestandteile die nicht literale sind, vorher irgendwo definiert worden sind. Wenn man `last_login` übergibt, muss Python das *vor* dem eigentlichen Aufruf durch einen konkreten Wert ersetzen können, wie bei jedem anderen Aufruf auch. Auch daran kann eine Bibliothek nichts ändern.
„Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.“ — Brian W. Kernighan
-
- User
- Beiträge: 982
- Registriert: Sonntag 19. September 2021, 09:40
Das habe ich mir angeschaut und (glaube ich) auch verstanden. Hätte das denn einen Vorteil zu meinem Code:sparrow hat geschrieben: ↑Sonntag 24. September 2023, 19:47 Und um auf Felder im selben Datensatz zu verlinken benötigst du F() Expressions.
Code: Alles auswählen
auswahl = User.objects.filter(date_joined__lt=date(2023,8,1))
for a in auswahl:
if (a.date_joined.date() ) == ((a.last_login.date() ))
... und das habe ich auch verstanden. ... wenn ich jetzt auch wieder nicht genau weiß was ein "literal" ist - das ist ein Zeichen oder eine Zahl, richtig?. Auch wenn es nicht so aussieht, ich lerne doch immer wieder ein Bisschen dazu .... ich vergesse halt immer wieder mal was.__blackjack__ hat geschrieben: ↑Montag 25. September 2023, 09:10 Bei Aufrufen mit Schlüsselwortargumenten muss vor dem ``=`` immer ein Name stehen. Daran kann Django nichts ändern.
Und was nach dem ``=`` steht muss natürlich ein Ausdruck sein, dessen Bestandteile die nicht literale sind, vorher irgendwo definiert worden sind.
Wenn ihr mir das erklärt verstehe ich das - mit der Dokumentation bin ich meistens überfordert.
Bei der Gelegenheit. Das mit dem einfachen und dem doppelten Unterstrich in den Filtern muss ich auch immer wieder ausprobieren. Könnt ihr das auch nochmal für einen Dummie erklären? Der doppelte Unterstich greift, soweit ich das verstanden habe, auf eine andere Tabelle zu.
- __blackjack__
- User
- Beiträge: 13572
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Literale sind feste Werte von einem bestimmten Typ für die es eine Notation/Syntax gibt. Also beispielsweise Zeichenketten und Zahlen. Das haben die meisten Programmiersprachen. Python bietet beispielsweise auch Syntax um beispielsweise Tupel, Listen, Wörterbücher, und Mengen direkt als Wert in den Quelltext zu schreiben. So etwas haben nicht alle Programmiersprachen.
Weiss nicht wie das bei StarBASIC ist, aber beim CBM BASIC auf meinem C64 müsste man ein Array mit Werten auch durch Code füllen, wie bei den meisten klassischen BASIC-Dialekten:
oder mit DATA-Zeilen und einer Schleife:
In FreeBASIC gibt's zwar keine Array-Literale aber immerhin Syntax für „initializers“, wo man beim deklarieren des Arrays die Werte angeben kann:
Doppelte Unterstriche bei den Filtern sind die Trennstellen zwischen Attributen und ggf. am Ende einem Operator oder eine Funktion die alle in den Namen gequetscht werden. Ist halt der Hack den man in der Python-Syntax machen kann, weil die Methode am Ende diesen Schlüssel als Zeichenkette bekommt und die auseinandernehmen und interpretieren kann wie sie will. Was das am Ende bedeutet ist ja nicht Teil der Python-Syntax, sondern was auch immer der Code der diese Argumente verarbeitet, daraus macht.
Code: Alles auswählen
# Liste als literal:
values = [42, 23, 4711]
# Hätte man das nicht, müsste man das mit Code ausdrücken:
values = list()
values.append(42)
values.append(23)
values.append(4711)
Code: Alles auswählen
10 DIM A(2):A(0)=42:A(1)=23:A(2)=4711
Code: Alles auswählen
10 DIM A(2):FOR I=0 TO 2:READ A(I):NEXT
20 DATA 42,23,4711
Code: Alles auswählen
Dim values(2) As Integer = {42, 23, 4711}
„Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.“ — Brian W. Kernighan
@Pitwheazle: Es geht schon darum den Tag zu vergleichen. Bzw explizit das Datum. Und wenn du dir die Lookups angeschaut hast, hast du __date gefunden um mit dem Datum in einem DateTimeField zu arbeiten.
Ob das einen Unterschied macht? Klar.
Stell dir vor, du hast eine Datenbank mit 1000 Datensätzen und möchtest alle löschen, die einen bestimmten Wert haben.
Was du gerade tust: Du holst dir alle Datensätze, prüfst in Programm die Bedingung und löscht dann wahrscheinlich jeden einzelnen Datensatz einzeln.
Was man eigentlich tut: Der Datenbank sagen, dass man alle Datensätze löschen möchte, die einer bestimmten Bedingung entsprechen und die Datenbank dann ihren Job machen lassen.
Ob das einen Unterschied macht? Klar.
Stell dir vor, du hast eine Datenbank mit 1000 Datensätzen und möchtest alle löschen, die einen bestimmten Wert haben.
Was du gerade tust: Du holst dir alle Datensätze, prüfst in Programm die Bedingung und löscht dann wahrscheinlich jeden einzelnen Datensatz einzeln.
Was man eigentlich tut: Der Datenbank sagen, dass man alle Datensätze löschen möchte, die einer bestimmten Bedingung entsprechen und die Datenbank dann ihren Job machen lassen.