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

Hallo,

Ich bin letztens auf Python zugestoßen und hab mir direkt ein Buch bestellt, was mir einen guten Einstieg in Python gebracht hat.
Aber back to topic:

Ich wollte dann ein Programm just4fun schreiben, das an Tamagotchi anlehnt (Tamapython). Ich habe danach im Internet gesucht und sozusagen ein Template mit tkinter dann genommen, das man erweitern kann.

Im Template gibt es nur Hunger und Days. Ich habe jedoch Health eingefügt, das immer -10 gehen sollte, wenn Hunger < 15 ist.
Jedoch geht jetzt mein Hunger in den Minusbereich und Health bleibt still, egal was passiert.

Hier der Code:

Code: Alles auswählen

#--------------------------------
#Tamapython Version 0.1
#--------------------------------

import tkinter

pressreturn = True


#tamapython
hunger = 100
health = 100
day = 0

#---------------------------------

def gameStart(event):
    global pressreturn

    if pressreturn == False:
        pass

    else:
        startLabel.config(text="")
        updateHunger()
        updateHealth()
        updateDay()
        updateDisplay()


        pressreturn == False

#-------------------------------------------
def updateDisplay():
    global health
    global hunger
    global day

    if health <= 50:
        catPic.config(image = hungryphoto)
    else:
        catPic.config(image = normalphoto)

        hungerLabel.config(text="Hunger: " + str(hunger))

        dayLabel.config(text="day: " + str(day))

        healthLabel.config(text="Health: " + str(health))

        catPic.after(100, updateDisplay)
#------------------------------------------------------
def updateHunger():
    global hunger

    hunger -=1

    if isAlive():
        hungerLabel.after(500, updateHunger)

def updateDay():
    global day

    day += 1

    if isAlive():
        dayLabel.after(5000, updateDay)
#-------------------------------------------------
def updateHealth():
    global hunger
    global health

    if hunger <= 15:
        health -= 10
#-------------------------
def feed():
    global hunger

    if hunger <= 95:
        hunger += 15
    else:
        hunger -=15
#-------------------------------
def isAlive():
    global hunger
    global health

    if health <= 0:
        startLabel.config(text="Game over")
        return False
    else:
        return True

#---------------------------------------


root = tkinter.Tk()
root.title("Tamapython v01")
root.geometry("1280x720")

startLabel = tkinter.Label(root, text="Press Enter to start", font=('Helvetica', 26))
startLabel.pack()

hungerLabel = tkinter.Label(root, text="Hunger: " + str(hunger), font=('Helvetica', 26))
hungerLabel.pack()

healthLabel = tkinter.Label(root, text="Health: " + str(health), font=('Helvetica', 26))
healthLabel.pack()

dayLabel = tkinter.Label(root, text="Day: " + str(day), font=('Helvetica', 26))
dayLabel.pack()

hungryphoto = tkinter.PhotoImage(file="hungry.gif")
normalphoto = tkinter.PhotoImage(file="normal.gif")

catPic = tkinter.Label(root, image=normalphoto)
catPic.pack()

btnFeed = tkinter.Button(root, text="Feed", command=feed)
btnFeed.pack()

root.bind('<Return>', gameStart)

root.mainloop()
Ich hoffe ich bin in der richtigen Kategorie und ich hoffe, ich kann das Problem bald lösen.
Ich bedanke mich für jede Antwort :)
Zuletzt geändert von Anonymous am Montag 10. April 2017, 21:17, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@andr0meda55: Vergiss bitte das es ``global`` gibt. Lern am besten erst einmal die Grundlagen. Funktionen. Keine globalen Variablen. Dann objektorientierte Programmierung (OOP) vor GUIs, denn für GUI-Programmierung kommt man um OOP nicht wirklich drum herum.
andr0meda55
User
Beiträge: 17
Registriert: Montag 10. April 2017, 20:48

BlackJack hat geschrieben:@andr0meda55: Vergiss bitte das es ``global`` gibt. Lern am besten erst einmal die Grundlagen. Funktionen. Keine globalen Variablen. Dann objektorientierte Programmierung (OOP) vor GUIs, denn für GUI-Programmierung kommt man um OOP nicht wirklich drum herum.
Die Grundlagen habe ich schon gelernt, bei Funktionen bin ich dran und danach denke ich lerne ich OOP und dann erstmal tkinter. Danke für den Hinweis.
Denkt ihr bzw du, ob das Buch "Python 3, Das umfassende Handbuch" von Johannes Ernesti und Peter Kaiser gut ist? Das besitze ich nämlich.
Vielleicht könnt ihr mir ja andere Sachen zum lernen von Python empfehlen.. :D
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Fruehere Versionen dieses Buches sind hier oefter mal zerrissen worden. Empfohlen wird "Learn Python the hard way" von Zed Shaw.
Benutzeravatar
pixewakb
User
Beiträge: 1409
Registriert: Sonntag 24. April 2011, 19:43

Wenn Du Dir tkinter anschaust, dann würde ich damit nur kleinere Sachen versuchen. Ich mag PyQt, damit geht es sehr viel schneller und einfacher. Nur als Tipp.
andr0meda55
User
Beiträge: 17
Registriert: Montag 10. April 2017, 20:48

Okay, ich lerne die ganzen Sachen und dann versuch ich es mal in PyQt statt tkinter. Ich find auch z.B die tkinter Buttons nicht schön, oder gibts da bei PyQt/tkinter irgendwie ne Verschönerungs-Methode?
Benutzeravatar
/me
User
Beiträge: 3554
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

__deets__ hat geschrieben:Empfohlen wird "Learn Python the hard way" von Zed Shaw.
Das finde ich nicht unbedingt toll, aber die Geschmäcker sind halt verschieden. Für die Hardcore "Python 2 forever"-Fraktion mag LPTHW vielleicht in größeren Teilen durchaus geeignet sein.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich hab' Python gelernt, bevor es beide Buecher gab. Gelernt habe ich also von keinem. Herr Shaw ist glaube euphemistisch beschrieben ein "meinungsstarker" Typ. Und das scheint natuerlich auch bei einer Frage wie Python 2 vs 3 durch.

Aber ich kenne diverse Leute, die damit gute Erfahrungen gemacht haben.
andr0meda55
User
Beiträge: 17
Registriert: Montag 10. April 2017, 20:48

Sorry wenn ich jetzt das Thema wieder hoch hole, aber:
Ich habs jetzt mal als Konsolenanwendung versucht und objekt orientiert (wobei ich mir da nicht sicher bin, ob das jetzt OOP ist)
Es funktioniert eigentlich alles super... eigentlich.
Das Problem ist hierbei: Hunger aktualisiert sich nicht. Mehr müsste ich eigentlich m.M.n nicht sagen.
Könnt ihr mir hierbei helfen?

Code: Alles auswählen

tamapython = {
'name':'NAME',
# 'age': 0,
'hunger': 100 ,
'photo': '(づ。◕‿‿◕。)づ',
'playstart': True
}
# ------------------------------------------------------- #
print(tamapython['photo'])
print("Hallo! Das ist absofort dein Haustier! Behandle es gut!")
print("Es heißt: " + tamapython['name'])
# ------------------------------------------------------- #
def feed(tamapython):
    if tamapython['hunger'] <= 50:
        tamapython['hunger'] += 10
    else:
        print("Hat kein Hunger")
# ------------------------------------------------------- #
def updateHunger(tamapython):
    if tamapython['playstart'] == True:
        tamapython['hunger'] -= 20
        print(tamapython['hunger'])
        updateHunger(500, updateHunger)
        print(tamapython['hunger'])
# ------------------------------------------------------- #

print(tamapython)
feed(tamapython)

TrayserCassa
User
Beiträge: 97
Registriert: Donnerstag 2. Mai 2013, 19:11

Hallo und willkommen im Forum

Also OOP heißt, dass du ein Object (In deinem Fall das Tamapython) als Object wiederspiegelst.
Das heißt:

Eigenschaften wie Name, Leben, etc lagerst du nicht global in einem Dictionary sondern baust dir eine Klasse. Deine Klasse hat Funktionen / Methoden die diese werte beeinflussen können. In deinem Fall beeinflusst deine Methode feed und updateHunger das Dictionary, was schon mal nicht falsch ist, allerdings nicht der OOP Ansatz.

Außerdem solltest du nicht auf globaler Ebene schreiben. Wo du dein Tama Dictionary deklarierst. Dafür benutzt du das

if __name__ == '__main__':
main()

Diese Bedingung ist immer True, wenn du dein script von der Konsole startest :)

Ich hab dir das Gerüst kurz aufgebaut.. Vollende es :)

Code: Alles auswählen


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

    def feed(self):
        pass

    def updateHunger(self):
        pass


def main():
    new_tama = Tamapython()

    print(new_tama.photo)

    new_tama.feed()


if __name__ == '__main__':
    main()


Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@andr0meda55: wie merkst Du denn, dass sich Hunger nicht ändert? Bisher rufst Du nur »feed« auf und weil der Hunger größer als 50 ist, passiert nichts, außer der Ausgabe "Hat keinen Hunger", wobei das seltsam ist, ein großer Hungerwert heißt kein Hunger???
andr0meda55
User
Beiträge: 17
Registriert: Montag 10. April 2017, 20:48

Sirius3 hat geschrieben:@andr0meda55: wie merkst Du denn, dass sich Hunger nicht ändert? Bisher rufst Du nur »feed« auf und weil der Hunger größer als 50 ist, passiert nichts, außer der Ausgabe "Hat keinen Hunger", wobei das seltsam ist, ein großer Hungerwert heißt kein Hunger???
Andersrum. :D

@TrayserCassa
Ist das so richtig?

Code: Alles auswählen

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

    def feed(self):
        if self.hunger <= 50:
            self.hunger += 20
        else:
            print(self.name + " hat keinen Hunger!")

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


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)
    # new_tama.updateHunger()
    new_tama.feed()
    print(new_tama.hunger)



if __name__ == '__main__':
    main()
Habe jedenfalls ein Error wenn ich new_tama.updateHunger() "einspielen" lasse.
Ohne das new_tama.updateHunger() klappt es, aber nur einmal.

Der Error lautet:
Traceback (most recent call last):
(づ。◕‿‿◕。)づ
File "C:/Users/Andr0meda55/PycharmProjects/tamapython/tamapython.py", line 32, in <module>
Hey! Das ist dein neues Haustier! Behandle es gut!
main()
Ach übrigens... es heißt: name
File "C:/Users/Andr0meda55/PycharmProjects/tamapython/tamapython.py", line 25, in main
80
new_tama.updateHunger()
File "C:/Users/Andr0meda55/PycharmProjects/tamapython/tamapython.py", line 16, in updateHunger
self.updateHunger(500, self.updateHunger)
TypeError: updateHunger() takes 1 positional argument but 3 were given
Was mach ich falsch? Wie pack ich updateHunger() in ein Loop, so das ich das Programm schließen MUSS?
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

Was soll denn in Zeile 23 mit "updateHunger(500, updateHunger)" erreicht werden? Im neuesten Versuch wäre das Zeile 16.
BlackJack

@andr0meda55: Was hast Du Dir bei dem Aufruf denn gedacht? Die Methode hat ja ganz offensichtlich keine Parameter für die 500 und die Methode selbst. Was in der Methode selbst auch keine Information sein sollte die man ihr übergeben sollte, denn wenn man die schreibt kennt man die Methode ja.

Wenn Du das in einer Schleife aufrufen möchtest, dann musst Du genau das machen: Eine Schleife schreiben in der das aufgerufen wird.

Du solltest Benutzerinteraktion, also Ein- und Ausgaben von der Programmlogik trennen. So ein Tamapython-Objekt sollte also keine `print()`-Ausgaben machen. Sonst kann man nicht unabhängig von der Logik die Benutzerschnittstelle ändern, oder die Logik testen, ohne das auch gleich die Benutzerinteraktion mit verwendet wird.

Wenn man die Informationen über das Tamapython für den Benutzer aufbereiten möchte, währe eine `is_hungry()`-Methode praktisch um von aussen fragen zu können ob das Tamapython hungrig ist, ohne wissen zu müssen wie der Zustand in den Objekten repräsentiert wird.
andr0meda55
User
Beiträge: 17
Registriert: Montag 10. April 2017, 20:48

Zizibee hat geschrieben:Was soll denn in Zeile 23 mit "updateHunger(500, updateHunger)" erreicht werden? Im neuesten Versuch wäre das Zeile 16.
Er soll in 500ms immer updateHunger abrufen.
BlackJack

@andr0meda55: Aber warum sollte das passieren, statt das die `updateHunger()`-Methode mit den Argumenten 500 und der Methode selbst aufgerufen wird? Das sagst Du Python soll passieren. Also macht Python das auch. Oder versucht es zumindest.

Merke: Programmiersprachen machen machen das was Du sagst, und zwar *genau* das, und nicht auf magische Weise das was Du eigentlich meinst. :-)
andr0meda55
User
Beiträge: 17
Registriert: Montag 10. April 2017, 20:48

Okay, jetzt hast du mich aber überfordert :D
Soll ich jetzt eine isHungry Methode machen? Und was soll die tun? Wie soll die checken das das Tamapython hungrig ist? mit einer if-Abfrage?
BlackJack

@andr0meda55: Wenn Du ausserhalb der Klasse ausgeben möchtest ob das Tamapython hungrig ist oder nicht, dann musst Du das ja vorher prüfen. Und nach Möglichkeit ohne von aussen wissen zu müssen wie man das prüft. Also braucht man da eine Methode für die einem verrät ob das Tamapython hungrig ist oder nicht. Ja oder Nein wird normalerweise als `True` und `False` kodiert, also müsste eine `is_hungry()`-Methode `True` liefern wenn das Tamapython hungrig ist, und `False` wenn nicht. Methoden die `is_*()` oder `has_*()` heissen, geben in der Regel einen Wahrheitswert als Ergebnis zurück.

Ein ``if`` braucht man *in* der Methode nicht, nur einen Ausdruck der entsprechend zu `True` oder `False` ausgewertet wird. Das ``if`` steht eher beim Aufrufer der Methode wenn der Entscheiden muss ob er etwas ausgibt oder nicht.

Übrigens `is_hungry()` und nicht `isHungry()`. `updateHunger()` sollte auch `update_hunger()` heissen. Schau Dir bei Gelegenheit mal den Style Guide for Python Code an.
andr0meda55
User
Beiträge: 17
Registriert: Montag 10. April 2017, 20:48

Also ich habe es mir jetzt so mal vorgestellt (grob geschrieben):

Code: Alles auswählen

class Tamapython(object):
    def __init__(self):
        self.name = 'name'
        self.hunger = 100
        self.photo = '(づ。◕‿‿◕。)づ'
        self.is_hungry = False
# ------------------------------------------------- #
    def feed(self):
        if self.hunger <= 50:
            self.hunger += 20
        else:
            print(self.name + " hat keinen Hunger!")
# ------------------------------------------------- #
    def update_hunger(self):
        while self.hunger == 100:
            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 == True:
        new_tama.feed()
    print(new_tama.hunger)
# ------------------------------------------------- #
if __name__ == '__main__':
    main()
# ------------------------------------------------- #

def is_hungry(self):
    if self.hunger <= 50:
        self.is_hungry == True
        
Ist das jetzt so korrekt? :D
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

andr0meda55 hat geschrieben:Ist das jetzt so korrekt?
Leider nein. Mal abgesehen von den Kommentarstrichen, die eher stören, was hast Du Dir bei den Zeilen 32 bis 34 gedacht? Versuche einmal zu erklären, was dort passiert und warum.
Antworten