Hunger geht in Minus, Health bleibt gleich?!

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.
andr0meda55
User
Beiträge: 17
Registriert: Montag 10. April 2017, 20:48

wenn Hunger <= 50 geht, soll is_hungry auf True schalten.
Und ich habe vor, das wenn is_hungry auf True ist, das er feed aufrufen soll, was jedoch noch nicht wirklich angepasst ist.
Diese Kommentarstriche habe ich dazu gemacht, damit ich mein Code lesbarer machen kann, aber wenn sie stören, kann ich sie auch wieder weg machen :D
BlackJack

@andr0meda55: `is_hungry` wird aber nirgends geändert. Ausserdem ist das ein Datenattribut und nicht wie vorgeschlagen eine Methode. Man sollte keine redundanten Daten speichern. Wenn die Bedingung für `is_hungry` ist das `hunger` kleiner 50 ist, dann sollte man das prüfen und nicht parallel noch einen Wert überall verwalten müssen wo `hunger` geändert werden könnte.

Ups, ich sehen gerade erst die ”Methode” `is_hungry()`. Woher soll Python denn wissen das die zur `Tamapython`-Klasse gehört? Das musst Du schon *in* die Klasse schreiben. Und dann darf die Methode nicht `is_hungry` heissen, oder das Datenattribut darf nicht so heissen. Ein Attribut kann immer nur an *einen* Wert gebunden werden. Wie soll denn sonst bei ``new_tama.is_hungry`` entschieden werden ob da nun der Wahrheitswert oder die Methode gemeint ist?

Aber wie gesagt, es sollte sowieso nur die Methode geben. Und wie auch schon gesagt, solche Testmethoden geben einen Wert zurück und verändern nicht den Zustand des Objekts. Das ist *sehr* unerwartet.

Wahrheitswerte vergleicht man übrigens nicht mit literalen Wahrheitswerten. Bei dem Vergleich kommt ja nur wieder ein Wahrheitswert heraus, aber den hatte man vorher ja schon, das macht also keinen Sinn. Statt ``if condition == True:`` schreibt man einfach nur ``if condition:``. Und falls man das Gegenteil prüfen möchte, gibt es die Negation mit ``not``: ``if not condition:``.

Die Methode würde so aussehen:

Code: Alles auswählen

    def is_hungry(self):
        return self.hunger <= 50
Und die Abfrage dann:

Code: Alles auswählen

    if new_tama.is_hungry():
        new_tama.feed()
andr0meda55
User
Beiträge: 17
Registriert: Montag 10. April 2017, 20:48

Traceback (most recent call last):
File "C:/Users/andr0meda55/PycharmProjects/tamapython/tamapython.py", line 38, in <module>
main()

Error: File "C:/Users/andr0meda55/PycharmProjects/tamapython/tamapython.py", line 29, in main
if new_tama.is_hungry():
TypeError: 'bool' object is not callable

Hier der Code von main():

Code: Alles auswählen

def main():
    new_tama = Tamapython()
    print(new_tama.photo)
    print("Hey! Das ist dein neues Haustier! Behandle es gut!")
    print("Ach übrigens... es heißt: " + new_tama.name)
    if new_tama.is_hungry():
        new_tama.feed()
    else:
        print(new_tama.name + " hat kein Hunger!")
    print(new_tama.hunger)
/EDIT:
Habe das () bei if new_tama.is_hungry: entfernt und jetzt gehts.
Jedoch fällt mir jetzt auf, das ich nicht das erreiche, was ich will.
Sobald ich das Programm starte, sollte es so aussehen:
(づ。◕‿‿◕。)づ
Hey! Das ist dein neues Haustier! Behandle es gut!
Ach übrigens... es heißt: name
name hat kein Hunger!
100
80
60
40
60
name hat kein Hunger!

und das halt in der Dauerschleife.
BlackJack

@andr0meda55: Natürlich kann man ein `bool` nicht aufrufen, das sollte ja aber auch gar kein `bool`-Wert sondern eine Methode sein.

Die Ausgabe passt nicht wirklich zur gezeigten `main()`, es sei denn in der `feed()`-Methode steht eine Schleife und die Ausgabe mit dem Hunger wird noch mal irgend wo anders gemacht.
andr0meda55
User
Beiträge: 17
Registriert: Montag 10. April 2017, 20:48

Woah, jetzt, sobald ich das Programm starte, geht es innerhalb Millisekunden in den Millionen Bereich, im Minus wohlbemerkt und meine CPU hat so einiges am arbeiten :shock:

Code: Alles auswählen

class Tamapython(object):
    def __init__(self):
        self.name = 'name'
        self.hunger = 100
        self.photo = '(づ。◕‿‿◕。)づ'
        self.is_hungry = False
        self.is_alive = True

        def is_hungry(self):
            return self.hunger <= 50

        def is_alive(self):
            return self.hunger <= 1


    # ------------------------------------------------- #
    def feed(self):
        while self.is_hungry == True:
            self.hunger += 20



    # ------------------------------------------------- #
    def updateHunger(self):
        while self.is_alive == True:
            self.hunger -= 20
            print(self.hunger)




def main():
    new_tama = Tamapython()
    print(new_tama.photo)
    print("Hey! Das ist dein neues Haustier! Behandle es gut!")
    print("Ach übrigens... es heißt: " + new_tama.name)
    if new_tama.is_hungry:
        new_tama.feed()
    else:
        print(new_tama.name + " hat kein Hunger!")
    print(new_tama.hunger)
    new_tama.updateHunger()


if __name__ == '__main__':
    main()


Hier ein kleiner Ausschnitt der Konsole:
Programm startet

-18040180
-18040200
-18040220
-18040240
-18040260
-18040280
-18040300
-18040320
-18040340
-18040360
...and it goes on :D
bb1898
User
Beiträge: 199
Registriert: Mittwoch 12. Juli 2006, 14:28

BlackJack hat geschrieben:@andr0meda55: Natürlich kann man ein `bool` nicht aufrufen, das sollte ja aber auch gar kein `bool`-Wert sondern eine Methode sein.

Die Ausgabe passt nicht wirklich zur gezeigten `main()`, es sei denn in der `feed()`-Methode steht eine Schleife und die Ausgabe mit dem Hunger wird noch mal irgend wo anders gemacht.
Es ist ja auch die _gewünschte_ Ausgabe und nicht die, die wirklich kommt (wie die jetzt aussieht, steht nicht im Beitrag).
bb1898
User
Beiträge: 199
Registriert: Mittwoch 12. Juli 2006, 14:28

andr0meda55 hat geschrieben:Woah, jetzt, sobald ich das Programm starte, geht es innerhalb Millisekunden in den Millionen Bereich, im Minus wohlbemerkt und meine CPU hat so einiges am arbeiten :shock:

Code: Alles auswählen

class Tamapython(object):
    def __init__(self):
        self.name = 'name'
        self.hunger = 100
        self.photo = '(づ。◕‿‿◕。)づ'
        self.is_hungry = False
        self.is_alive = True

        def is_hungry(self):
            return self.hunger <= 50

        def is_alive(self):
            return self.hunger <= 1


    # ------------------------------------------------- #
    def feed(self):
        while self.is_hungry == True:
            self.hunger += 20



    # ------------------------------------------------- #
    def updateHunger(self):
        while self.is_alive == True:
            self.hunger -= 20
            print(self.hunger)




def main():
    new_tama = Tamapython()
    print(new_tama.photo)
    print("Hey! Das ist dein neues Haustier! Behandle es gut!")
    print("Ach übrigens... es heißt: " + new_tama.name)
    if new_tama.is_hungry:
        new_tama.feed()
    else:
        print(new_tama.name + " hat kein Hunger!")
    print(new_tama.hunger)
    new_tama.updateHunger()


if __name__ == '__main__':
    main()


Hier ein kleiner Ausschnitt der Konsole:
Programm startet

-18040180
-18040200
-18040220
-18040240
-18040260
-18040280
-18040300
-18040320
-18040340
-18040360
...and it goes on :D
Kein Wunder. Du hast immer noch gleich benannte Methoden und Datenattribute, jetzt sogar zwei davon (is_hungry und is_alive). Die Methoden hast Du in Deine __init__-Methode hineingeschachtelt, ich weiß nicht, ob das Deine Absicht war oder nicht (wohl eher nicht). Du rufst sie jedenfalls nicht auf, sondern fragst das Datenattribut is_hungry in einer Endlosschleife ab, ohne dass es je geändert würde. Und die sinnlosen Vergleiche "== True" sind auch noch immer da.

Wenn Du die beiden Datenattribute ersatzlos streichst, statt dessen die entsprechenden Methoden herausrückst und damit zu eigenständigen Methoden der Klasse machst, und im Hauptprogramm die Methode is_hungry aufrufst, dann sollte eigentlich passieren, was Du Dir vorstellst.

Dass das Tierchen hungrig wird, wenn sein Hunger-Wert _unter_ eine vorgegebene Grenze fällt, ist zwar seltsam, dem Computer aber gleichgültig.
andr0meda55
User
Beiträge: 17
Registriert: Montag 10. April 2017, 20:48

Und inwiefern soll ich jetzt == True ersetzen?
z.B zu:

Code: Alles auswählen

 def updateHunger(self):
        while self.is_alive:
            self.hunger -= 20
            print(self.hunger)
?
BlackJack

@andr0meda55: Die ``while``-Schleifen gehören nicht in die Methoden und die gezeigte ist ziemlich offensichtlich einen Endlosschleife weil sich die Werte für die Bedingung niemals ändern. Falls ``self.is_alive`` an einen Wahrheitswert gebunden ist, dann sehe ich da innerhalb der Schleife keinen Code der das jemals ändert, und falls ``self.is_alive`` eine Methode ist, dann ist die als Wahrheitswert betrachtet immer ”wahr”. Es macht aber keinen Sinn eine Methode als Wahrheitswert zu betrachten. Die sollte man *aufrufen* und damit ihren *Rückgabewert* als Bedingung verwenden. Dann macht das schon eher Sinn.
andr0meda55
User
Beiträge: 17
Registriert: Montag 10. April 2017, 20:48

Ich hab jetzt noch ein bisschen getüftelt..
Jetzt wenn ich das Programm starte, funktioniert es so:
(づ。◕‿‿◕。)づ
Traceback (most recent call last):
Hey! Das ist dein neues Haustier! Behandle es gut!
Ach übrigens... es heißt: name
File "C:/Users/andr0meda55/PycharmProjects/tamapython/tamapython.py", line 46, in <module>
80
80
main()
File "C:/Users/andr0meda55/PycharmProjects/tamapython/tamapython.py", line 41, in main
new_tama.is_hungry()
AttributeError: 'Tamapython' object has no attribute 'is_hungry'

Process finished with exit code 1
Der Code:

Code: Alles auswählen

class Tamapython(object):
    def __init__(self):
        self.name = 'name'
        self.hunger = 100
        self.photo = '(づ。◕‿‿◕。)づ'
        self.is_alive = True

        def is_hungry(self):
            return self.hunger <= 50

        def is_alive(self):
            return self.hunger <= 0



    # ------------------------------------------------- #
    def feed(self):
        while self.is_hungry == True:
            self.hunger += 20



    # ------------------------------------------------- #
    def updateHunger(self):
            self.hunger -= 20
            print(self.hunger)




def main():
    new_tama = Tamapython()
    print(new_tama.photo)
    print("Hey! Das ist dein neues Haustier! Behandle es gut!")
    print("Ach übrigens... es heißt: " + new_tama.name)
    if new_tama.is_alive:
        new_tama.updateHunger()
    else:
        print(new_tama.name + " hat kein Hunger!")
    print(new_tama.hunger)
    new_tama.is_hungry()
    new_tama.updateHunger()


if __name__ == '__main__':
    main()



//EDIT: Habe jetzt den Attribut "is_hungry = False" zur Klasse hinzugefügt und jetzt gehts etwa so:
(づ。◕‿‿◕。)づ
Hey! Das ist dein neues Haustier! Behandle es gut!
Ach übrigens... es heißt: name
80
80
60
Process finished with exit code 0
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@andr0meda55: das wird auch nichts werden, solange Dir die Grundlagen der Objektorientierten Programmierung wie Attribute und Methoden als auch auch das behandeln von Objekten in einem boolschen Kontext nicht vertraut sind.

Hast Du denn irgendein Buch, an dem Du Dich orientieren kannst? Falls nein, so gehört unter den deutschsprachigen Büchern die Einführung von Michael Weigend zu den besseren Publikationen. Und auch der Crashkurs von Eric Matthes ist besser als das Cover vermuten lässt. Ein gutes Buch macht übrigens Spaß :)
andr0meda55
User
Beiträge: 17
Registriert: Montag 10. April 2017, 20:48

Ich besitze das Buch "Python 3 - Das umfassende Handbuch" von Johannes Ernesti, Peter Kaiser.
Soll ich zuerst Attribute, Methode oder die Objektorienterte Programmierung lesen, um es effektiv zu erlernen?
Ich denke ich werde mir bald die beiden Bücher holen. Sehen vielversprechend aus! :D
Mal so ne Frage nebenbei: Wie ist eigentlich die Lernkurve von Python?
Was meint ihr, benötige ich viel Zeit um wenig Zeug zu lernen oder andersrum?
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@andr0meda55: Die Python Lernkurve ist anfangs flach, d.h. Du kannst schnell zu ersten Erfolgserlebnissen kommen. Das ist gerade für Anfänger schön. Aber Python kann auch recht komplex werden, wenn Du in die Tiefen des objektorientieren Entwurfs der Sprache hinabsteigst. Dann wird die Lernkurve ggf. etwas steiler. Aber es lohnt sich; Python bleibt später auch für Fortgeschrittene schön :D
andr0meda55
User
Beiträge: 17
Registriert: Montag 10. April 2017, 20:48

Okay. Kennt jemand übrigens eine gute IDE im Gegensatz zu Pycharm? PyCharm lässt meine CPU wie sonst noch was arbeiten im Idle und meine Lüfter haben auch bald kein bock mehr drauf, die ganze Zeit so schnell zu laufen :D
BlackJack

@andr0meda55: PyCharm sollte eigentlich ganz gut sein. Und wenn man nichts tut auch nicht viel CPU-Zeit verbrauchen. Ausser wenn am Anfang, beim ersten Start alle installierten Bibliotheken statisch analysiert werden. Das kann eine Weile brauchen. Müsste unten in der Statusleiste stehen wenn so ein Vorgang läuft. Die Ergebnisse werden aber gecachet, das heisst wenn das einmal abgeschlossen ist, sollte auch der Prozessor nicht mehr viel zu tun haben wenn man nichts macht.

Viele Leute sind auch ohne IDE ganz glücklich. Ich verwende Sublime Text (kostet Geld), dann gibt's noch die üblichen verdächtigen: Emacs und Vim. Und hunderte anderer Editoren. Frag 5 Leute und Du bekommst 10 Meinungen was der beste Editor ist. :-) Da muss man letztlich selbst ausprobieren was einem so liegt und was nicht.
andr0meda55
User
Beiträge: 17
Registriert: Montag 10. April 2017, 20:48

Ich denke ich bleib bei PyCharm. Hauptsache meine CPU brennt nicht ab. :D
Ich werde übrigens heute Tamapython versuchen neu zu schreiben, ohne irgendwelche Abfragen in einer Methode etc.
Habt ihr Tipps wie man den Code lesbarer machen kann für andere und sich selber?
Antworten