__le__

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
xocy
User
Beiträge: 10
Registriert: Freitag 28. Oktober 2022, 13:04

hallo,
ich weiss ich muss den vergleich mit __le__ einbauen. ich finde dazu leider nichts hilfreiches nur vergleiche fuer attribute. wonach muesste ich ausschau halten.

lg

Code: Alles auswählen

class Cookies:
    def __init__(self, max):
        self.max = max
        self.n= 1

    def count(self):
        if self.n <= self.max:
            print(f"Ich essse keks nummer {self.n}. yummy yummy")
            self.n += 1
            return self.n
        else:
            print("ich platze gleich :O nein nein")

test = Cookies(100)

if test.count() <= Cookies(100):
    print(test.count())
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

Was soll den das Ergebnis eines solchen Vergleichs sein? Das ist irgendwie ein Äpfel mit Birnen Vergleichen, oder hier Count mit Cookies: macht keinen Sinn.

Der Name `count` ist etwas verwirrend, weil da nichts gezählt wird, sondern ein Zähler verändert wird. Eine Funktion sollte entweder in keinem Fall einen Returnwert haben, oder immer. Bei Dir ist im if-Block ein return im else-Block aber nicht. Das ist mit Sicherheit ein Programmfehler.
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

was ist denn der Sinn des ganzen? Die Instanz einer Klasse mit einem Wert in irgendeiner Form zu vergleichen zu wollen ist erst mal ungewöhnlich. Außerdem liefert count() bei dir einen Integer oder None. Damit lässt sich ein Größenvergleich schlecht implementieren.
Gruß, noisefloor
xocy
User
Beiträge: 10
Registriert: Freitag 28. Oktober 2022, 13:04

hallo,
es sollten solange kekse gefuttert werden bis 100 erreicht waeren. rueckblickend betrachtet sieht das ganze doch recht wirr aus.

lg
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

und warum implementierst du die Abfrage "100 Kekse gefuttert" nicht in die Klasse selbst? Warum willst du nur den externen Vergleich?

Gruß, noisefloor
__deets__
User
Beiträge: 14523
Registriert: Mittwoch 14. Oktober 2015, 14:29

Also ich wuerde das so angehen:

Code: Alles auswählen

class Magen:
    def __init__(self):
        self._kekse = 0
    def __le__(...) # deine Aufgabe
    
    def keks_essen(self):
        self._kekse += 1

magen = Magen()
while magen < 100:
    magen.keks_essen()
imonbln
User
Beiträge: 149
Registriert: Freitag 3. Dezember 2021, 17:07

__deets__ hat geschrieben: Donnerstag 1. Dezember 2022, 10:58

Code: Alles auswählen

while magen < 100:
    magen.keks_essen()
Ein kleiner Typo __le__ ist less_equal du vergleichst aber hier __lt__, da wird sich der Interpreter beschweren, dass er nicht zwischen Magen und Int ein "<" machen kann.
Benutzeravatar
__blackjack__
User
Beiträge: 13071
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Also ich finde es ja auch komisch einen Magen mit einer Zahl zu vergleichen. Das liest sich doch auch total schräg. Was sollen denn die konkreten Randbedingungen sein? Warum tut es nicht eine einfache Schleife?

Code: Alles auswählen

for keks_nummer in range(1, 101):
    print(f"Ich esse 🍪 Nummer {keks_nummer}. Yummy yummy.")
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
__deets__
User
Beiträge: 14523
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich denke hier gehts um die Möglichkeit, Vergleichssemantik für eigene Typen zu verstehen. Natürlich ist das etwas konstruiert.
Benutzeravatar
__blackjack__
User
Beiträge: 13071
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Dass das irgendwie einen Lerneffekt haben soll war mir schon klar, aber es ist halt ein wirklich schlechtes Beispiel. Und so ähnlich wie es beim lernen von Klassen auch dazugehört wann man keine Klasse schreibt, sollte man hier IMHO deutlich sagen, dass man das so nicht macht.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
xocy
User
Beiträge: 10
Registriert: Freitag 28. Oktober 2022, 13:04

ja mir ist auf dem weg zum einkaufen eingefallen, das es vermutlich besser so zu verstehen ist.

Code: Alles auswählen

class Cookies:
    def __init__(self, max):
        self.max = max
        self.n= 1

    def __iter__(self):
        return self

    def __next__(self):
        if self.n <= self.max:
            res = self.n
            self.n += 1
            return res
        else:
            raise StopIteration

    def __le__(self):
        return self



test = Cookies(100)

while test <= Cookies:
    print(next(test))
else:
    print("ich werde dick :O")
edit: ein einfaches return self hat das problem geloest danke trotzdem


lg
__deets__
User
Beiträge: 14523
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist Quatsch-Code. test <= Cookies ist falsch, und liefert

Code: Alles auswählen

Traceback (most recent call last):
  File "/tmp/test.py", line 24, in <module>
    while test <= Cookies:
TypeError: Cookies.__le__() takes 1 positional argument but 2 were given
Und self zurueckzugeben ist auch Unfug, denn das ist immer wahr (ohne weiter Massnahmen, und die waeren auch nicht angezeigt).
Benutzeravatar
__blackjack__
User
Beiträge: 13071
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@xocy: Nimm einfach wie gezeigt eine ``for``-Schleife und `range()` oder überlege Dir ein wenigstens ansatzweise sinnvolles Beispiel. Sonst lernt man nicht wie man es richtig macht.

Was an sich schon mal nicht sinnvoll ist, oder nur in wirklich seltenen Fällen, ist der Vergleich von so unterschiedlichen Typen mittels ``<`` & Co. Wo man dann übrigens eigentlich auch wirklich alle Operatoren haben möchte, denn wenn ``a <= b`` funktioniert, erwartet der Leser das auch ``<``, ``>``, ``>=``, ``==``, und ``!=`` konsistent dazu funktionieren. Und wenn man ``==`` implementiert, sollte man auch `__hash__()` implementieren, um den nächsten unliebsamen Überraschungen entgegen treten zu können. Und wenn einem das für den Anfang alles noch zu kompliziert ist: Einfach erst einmal anderes lernen. Das man die Vergleichsoperatoren überladen will, kommt gar nicht so oft vor. Wenn dann in der Regel auch nur bei Werttypen und nicht bei Objekten mit veränderlichem Zustand. Und wenn Objekte mit veränderlichem Zustand, dann sind die relativen Vergleichsoperatoren in der Regel nur auf einer unveränderlichen Untermenge des Zustands definiert. Also so wirklich gar nicht was *hier* versucht wird. Wenn das wirklich mal Sinn macht, dann kann man sich damit einmal auseinandersetzen — und dann das `attrs`-Package verwenden um (auch) solche Klassen zu schreiben, so dass man sich damit nie wieder beschäftigen muss. 🙂
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
__blackjack__
User
Beiträge: 13071
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Um das mit den Keksen mal sinnvoller zu modellieren:

Code: Alles auswählen

#!/usr/bin/env python3
from itertools import count


class CookieEater:
    def __init__(self, capacity):
        self.capacity = capacity
        self.cookie_count = 0

    def is_full(self):
        return self.cookie_count >= self.capacity

    def eat_cookie(self):
        if self.is_full():
            raise ValueError("already full")
        self.cookie_count += 1


def main():
    me = CookieEater(10)
    for cookie_number in count(1):
        if me.is_full():
            print("Ich platze gleich :O")
            break

        print(f"Ich esse Keks Nummer {cookie_number}. Yummy yummy.")
        me.eat_cookie()


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
xocy
User
Beiträge: 10
Registriert: Freitag 28. Oktober 2022, 13:04

ich wollte es anders mal probieren als mit for und range. ich sehe schon dafuer fehlt mir noch etwas wissen. ich werde mir einfach was neues suchen und dort weiter lernen danke.

lg
Antworten