Schleifenabbruch - Problem

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
Dexter1997
User
Beiträge: 92
Registriert: Sonntag 2. Dezember 2012, 21:13

In Zeile 39 wird dem Computer befohlen, daß die Attributs-schleife beendet wird, wenn die Variable Eingabe den Wert "z2 oder "Z" enthält. Macht er aber nicht, was hab ich falsch gemacht?

Code: Alles auswählen

import random, time

def Ausgabe_einfach(ausgabe, wartezeit):
    print ausgabe + "\n"
    time.sleep(wartezeit)

Stufe = 1
Erfahrung = 0
Erfahrung_b = 100

Lernpunkte = 1
Gold = 30

Intelligenz = 1
Geisteskraft = 10
Konzentration = 1

while True:
    if Erfahrung >= Erfahrung_b:
        pass
    
    print "[1] Charackter"
    print "[2] Attribute"
    print "[3] Rechnen"
    Eingabe = raw_input("Zahl eingeben: ")
    print

    if Eingabe == "1":
        print "Stufe      : " + str(Stufe)
        print "Erfahrung  : " + str(Erfahrung) + "/" + str(Erfahrung_b)
        print "____________________"
        print "Intelligenz   : " + str(Intelligenz)
        print "Geisteskraft  : " + str(Geisteskraft)
        print "Konzentration : " + str(Konzentration)
        print
        time.sleep(4)

    elif Eingabe == "2":
        while Eingabe != "z" or Eingabe != "Z":
            print "Lernpunkte: " + str(Lernpunkte) + "   Gold: " + str(Gold)
            print "[1] Intelligenz:    " + str(Intelligenz) + "    Verbessern: 1 LP oder " + str(Intelligenz * 30) + " Gold"
            print "[2] Geisteskraft:  " + str(Geisteskraft) + "    Verbessern: 1 LP oder " + str((Geisteskraft - 9) * 30) + " Gold"
            print "[3] Konzentration:  " + str(Konzentration) + "    Verbessern: 1 LP oder " + str(Konzentration * 30) + " Gold"
            Eingabe = raw_input("Zahl eingeben (z = Zurueck): ")
            print

            if Eingabe == "1" and Lernpunkte >= 1:
                Ausgabe_einfach("Intelligenz erhoeht! (- 1 LP)", 1.2)
                Lernpunkte -= 1
                Intelligenz += 1

            elif Eingabe == "1" and Lernpunkte == 0 and Gold >= Intelligenz * 30 and Intelligenz != 4:
                Ausgabe_einfach("Intelligenz_erhoeht! (- " + str(Intelligenz * 30) + " Gold)", 1.2)
                Gold -= Intelligenz * 30
                Intelligenz += 1

            elif Eingabe == "1" and Lernpunkte == 0 and Gold < Intelligenz * 30:
                Ausgabe_einfach("Du hast keinen Lernpunkt und nicht genug Gold!", 1.4)

            elif Eingabe == "1" and Intelligenz == 4: Ausgabe_einfach("Noch intelligenter kannst du nicht sein!", 1.4)

            elif Eingabe == "2" and Lernpunkte >= 1:
                Ausgabe_einfach("Geisteskraft erhoeht! (- 1 LP)", 1.2)
                Lernpunkte -= 1
                Geisteskraft += 1

            elif Eingabe == "2" and Lernpunkte == 0 and Gold >= (Geisteskraft - 9) * 30:
                Ausgabe_einfach("Geisteskraft erhoeht! (- " + str((Geisteskraft - 9) * 30) + " Gold)", 1.2)
                Gold -= (Geisteskraft - 9) * 30
                Geisteskraft += 1

            elif Eingabe == "2" and Lernpunkte == 0 and Gold < (Geisteskraft - 9) * 30:
                Ausgabe_einfach("Du hast keinen Lernpunkt und nicht genug Gold!", 1.4)

            elif Eingabe == "3" and Lernpunkte >= 1:
                Ausgabe_einfach("Konzentration erhoeht! (- 1 LP)", 1.2)
                Lernpunkte -= 1
                Konzentration += 1

            elif Eingabe == "3" and Lernpunkte == 0 and Gold >= Konzentration * 30:
                Ausgabe_einfach("Konzentration erhoeht!(- " + str(Konzentration * 30) + " Gold)", 1.4)
                Gold -= Konzentration * 30
                Konzentration += 1

            elif Eingabe == "3" and Lernpunkte == 0 and Gold < Konzentration * 30:
                Ausgabe_einfach("Du hast keinen Lernpunkt und nicht genug Gold!", 1.2)
            
    elif Eingabe == "3":
        pass

    else: print "Eingabe ungueltig"

Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

and?
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

@Dexter1997: Benutze doch »"...".format« für die Ausgaben, das wird gleich viel übersichtlicher.
Und wenn es schon so viele »if«s sein müssen, dann schachtle sie doch wenigstens so, dass Du »else« benutzen kannst, statt nochmal das Negative aller vorhergebenden Bedingungen schreiben mußt.
Dexter1997
User
Beiträge: 92
Registriert: Sonntag 2. Dezember 2012, 21:13

Vielen dank für eure antworten und netten hinweise!!!
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Der (wenn auch knappe) Hinweis von darktrym ist der richtige. Überlege Dir noch einmal ganz genau, wann die Schleifenbedingung wahr ist und wann falsch.

Spoiler 1: Sie ist immer wahr.

Spoiler 2: "z" ist ungleich "Z", "Z" ist ungleich "z"

Darüber hinaus solltest Du dringenst anfangen, Deinen Code zu strukturieren.

Kleine Aufgabe: Strukturiere den Code derart, dass keine Funktion länger als 8 Zeilen ist. Code auf Modulebene ist tabu (Ausnahme: Konstanten).

Beispiele findest Du hier im Forum zu Hauf (Bsp. main-Idiom).
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Hatten wir im Übrigen schon einmal. Ich finde den Code auch grässlich, deshalb die kurze Antwort.
Und beim nächsten Mal verwendest du diesen Code, bevor ich nochmal meine Augen schädigen bekomm'.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import random
import time

 
def Ausgabe_einfach(ausgabe, wartezeit):
    '''verzögerte Bildschirmausgabe'''
    print "%s\n" % ausgabe
    time.sleep(wartezeit)
 
Stufe = 1
Erfahrung = 0
Erfahrung_b = 100
 
Lernpunkte = 1
Gold = 30
 
Intelligenz = 1
Geisteskraft = 10
Konzentration = 1
 
while True:
    if Erfahrung >= Erfahrung_b:
        pass
   
    print "[1] Charackter"
    print "[2] Attribute"
    print "[3] Rechnen"
    Eingabe = raw_input("Zahl eingeben: ")
    print
 
    if Eingabe == "1":
        print "Stufe      : %d" % Stufe
        print "Erfahrung  : %d/%d" % (Erfahrung, Erfahrung_b)
        print "____________________"
        print "Intelligenz   : %d" % Intelligenz
        print "Geisteskraft  : %d" % Geisteskraft
        print "Konzentration : %d" % Konzentration
        print
        time.sleep(4)
 
    elif Eingabe == "2":
        while Eingabe.upper() != "Z":
            print "Lernpunkte: %d   Gold: %d" % (Lernpunkte, Gold)
            print "[1] Intelligenz:    %d    Verbessern: 1 LP oder %d Gold" % (Intelligenz, Intelligenz * 30)
            print "[2] Geisteskraft:  %d    Verbessern: 1 LP oder %d Gold" % (Geisteskraft, (Geisteskraft - 9) * 30)
            print "[3] Konzentration:  %d    Verbessern: 1 LP oder %d Gold" % (Konzentration, Konzentration * 30)
            Eingabe = raw_input("Zahl eingeben (z = Zurueck): ")
            print
 
            if Eingabe == "1" and Lernpunkte >= 1:
                Ausgabe_einfach("Intelligenz erhoeht! (- 1 LP)", 1.2)
                Lernpunkte -= 1
                Intelligenz += 1
 
            elif Eingabe == "1" and Lernpunkte == 0 and Gold >= Intelligenz * 30 and Intelligenz != 4:
                Ausgabe_einfach("Intelligenz_erhoeht! (- %d Gold)" % Intelligenz * 30, 1.2)
                Gold -= Intelligenz * 30
                Intelligenz += 1
 
            elif Eingabe == "1" and Lernpunkte == 0 and Gold < Intelligenz * 30:
                Ausgabe_einfach("Du hast keinen Lernpunkt und nicht genug Gold!", 1.4)
 
            elif Eingabe == "1" and Intelligenz == 4: Ausgabe_einfach("Noch intelligenter kannst du nicht sein!", 1.4)
 
            elif Eingabe == "2" and Lernpunkte >= 1:
                Ausgabe_einfach("Geisteskraft erhoeht! (- 1 LP)", 1.2)
                Lernpunkte -= 1
                Geisteskraft += 1
 
            elif Eingabe == "2" and Lernpunkte == 0:
                if Gold >= (Geisteskraft - 9) * 30:
                    Ausgabe_einfach("Geisteskraft erhoeht! (- %d Gold)" % (Geisteskraft - 9) * 30, 1.2)
                    Gold -= (Geisteskraft - 9) * 30
                    Geisteskraft += 1
                else:
                    Ausgabe_einfach("Du hast keinen Lernpunkt und nicht genug Gold!", 1.4)
 
            elif Eingabe == "3" and Lernpunkte >= 1:
                Ausgabe_einfach("Konzentration erhoeht! (- 1 LP)", 1.2)
                Lernpunkte -= 1
                Konzentration += 1
 
            elif Eingabe == "3" and Lernpunkte == 0:
                if Gold >= Konzentration * 30:
                    Ausgabe_einfach("Konzentration erhoeht!(- %d Gold)" % Konzentration * 30, 1.4)
                    Gold -= Konzentration * 30
                    Konzentration += 1
                else:
                    Ausgabe_einfach("Du hast keinen Lernpunkt und nicht genug Gold!", 1.2)
           
    elif Eingabe == "3":
        pass
 
    else: print "Eingabe ungueltig"
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@Dexter1997: `random` wird importiert, aber gar nicht verwendet.

Die Namen entsprechen nicht alle dem Style Guide for Python Code. Funktionsnamen sollten eine Tätigkeit beschreiben.

Das Hauptprogramm auf Modulebene sollte in einer Funktion verschwinden.

`Stufe`, `Erfahrung`, und `Erfahrung_b` werden definiert und nur zur Ausgabe verwendet, aber niemals geändert. Man sollte nicht zu viel „Variables” im Programm haben was überhaupt gar nicht wirklich verwendet wird. `Erfahrung_b` ist ausserdem ein schlechter Name denn dieses `_b` hat keine verständliche Bedeutung.

An der Stelle wo Du das Problem mit dem 'z' hast würde ich das nicht als Bedingung der ``while``-Schleife verwenden, sondern eine Endlosschleife schreiben die abgebrochen wird *nachdem* der Benutzer die `eingabe` getätigt hat. Im Moment bist Du davon abhängig was *vor* der Schleife an `eingabe` gebunden ist, und vertraust darauf dass es nicht 'z' ist. Ist es in diesem Fall natürlich auch nicht, aber wenn man ausserhalb der Schleife daran mal etwas ändert muss man diesen Sonderfall immer beachten.

Diese ganzen ``if``-Bedingungen sind nicht wirklich konsistent. An einer Stelle wird geprüft ob die Intelligenz 4 ist und dem Benutzer gesagt er kann nicht intelligenter als das werden, während man über andere Zweige an dieser Beschränkung vorbeikommen kann.

Wenn man sich die drei Hauptmenüpunkte anschaut, dann sieht man auch sehr viele gemeinsamkeiten. Bis auf dass es bei der Intelligenz eine Obergrenze gibt, wird im Grunde bei allen das gleiche gemacht. Es unterscheidet sich nur durch die Berechnung den Preises. Hier sollte man die Eigenschaften in einer Datenstruktur zusammenfassen und dann eine Funktion schreiben, welche die Preisberechnung und die Eigenschaften als Argument übergeben bekommt, und dann die Eigenschaften entsprechend ändert. Die Preisberechnung für jede Eigenschaft sollte auch nur *einmal* im Quelltext stehen und nicht jeweils viermal. Im Grunde ist das schon ein Fall für objektorientierte Programmierung.

Für *eine* Funktion ist das Hauptprogramm auch viel zu lang und zu tief verschachtelt. Aber das wurde ja schon erwähnt.

(Ungetestet)

Code: Alles auswählen

#!/usr/bin/env python
import time
 
ERFAHRUNG_MAX = 100


def mit_pause_ausgeben(ausgabe, wartezeit):
    print ausgabe, '\n'
    time.sleep(wartezeit)


def main():
    stufe = 1
    erfahrung = 0
     
    lernpunkte = 1
    gold = 30
     
    intelligenz = 1
    geisteskraft = 10
    konzentration = 1
     
    while True:
        if erfahrung >= ERFAHRUNG_MAX:
            pass
       
        print '[1] Charackter'
        print '[2] Attribute'
        print '[3] Rechnen'
        eingabe = raw_input('Zahl eingeben: ')
        print
     
        if eingabe == '1':
            print 'Stufe      : {}'.format(stufe)
            print 'Erfahrung  : {}/{}'.format(erfahrung, ERFAHRUNG_MAX)
            print '_' * 20
            print 'Intelligenz   : {}'.format(intelligenz)
            print 'Geisteskraft  : {}'.format(geisteskraft)
            print 'Konzentration : {}'.format(konzentration)
            print
            time.sleep(4)
     
        elif eingabe == '2':
            while True:
                print 'Lernpunkte: {}   Gold: {}'.format(lernpunkte, gold)
                print (
                    '[1] Intelligenz:    {}    Verbessern: 1 LP oder {} Gold'
                        .format(intelligenz, intelligenz * 30)
                )
                print (
                    '[2] Geisteskraft:  {}    Verbessern: 1 LP oder {} Gold'
                        .format(geisteskraft, (geisteskraft - 9) * 30)
                )
                print (
                    '[3] Konzentration:  {}    Verbessern: 1 LP oder {} Gold'
                        .format(konzentration, konzentration * 30)
                )
                eingabe = raw_input('Zahl eingeben (z = Zurueck): ')
                print
                if eingabe.lower() == 'z':
                    break

                elif eingabe == '1':
                    if intelligenz == 4:
                        mit_pause_ausgeben(
                            'Noch intelligenter kannst du nicht sein!', 1.4
                        )
                    elif lernpunkte >= 1:
                        mit_pause_ausgeben('Intelligenz erhoeht! (- 1 LP)', 1.2)
                        lernpunkte -= 1
                        intelligenz += 1
                    else:
                        if gold >= intelligenz * 30:
                            mit_pause_ausgeben(
                                'Intelligenz_erhoeht! (- {} Gold)'.format(
                                    intelligenz * 30
                                ),
                                1.2
                            )
                            gold -= intelligenz * 30
                            intelligenz += 1
                        else:
                            mit_pause_ausgeben(
                                'Du hast keinen Lernpunkt und nicht genug Gold!',
                                1.4
                            )
     
                elif eingabe == '2':
                    if lernpunkte >= 1:
                        mit_pause_ausgeben(
                            'Geisteskraft erhoeht! (- 1 LP)', 1.2
                        )
                        lernpunkte -= 1
                        geisteskraft += 1
                    else:
                        if gold >= (geisteskraft - 9) * 30:
                            mit_pause_ausgeben(
                                'Geisteskraft erhoeht! (- {} Gold)'.format(
                                    (geisteskraft - 9) * 30
                                ),
                                1.2
                            )
                            gold -= (geisteskraft - 9) * 30
                            geisteskraft += 1
                        else:
                            mit_pause_ausgeben(
                                'Du hast keinen Lernpunkt und nicht genug Gold!',
                                1.4
                            )
             
                elif eingabe == '3':
                    if lernpunkte >= 1:
                        mit_pause_ausgeben(
                            'Konzentration erhoeht! (- 1 LP)', 1.2
                        )
                        lernpunkte -= 1
                        konzentration += 1
                    else:
                        if gold >= konzentration * 30:
                            mit_pause_ausgeben(
                                'Konzentration erhoeht!(- {} Gold)'.format(
                                    konzentration * 30
                                ),
                                1.4
                            )
                            gold -= konzentration * 30
                            konzentration += 1
                        else:
                            mit_pause_ausgeben(
                                'Du hast keinen Lernpunkt und nicht genug Gold!',
                                1.2
                            )
                   
        elif eingabe == '3':
            pass
     
        else:
            print 'Eingabe ungueltig'


if __name__ == '__main__':
    main()
Antworten