Probleme bei einer ''if'' Abfrage.

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.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Samstag 29. Juli 2006, 14:27

ChrissiG hat geschrieben: Gäbe es an dieser Lösung auch etwas anders zu machen? Wenn ja was?
Das "== True" raus, und dann passt es. Vergiss aber nicht hinterher einen Integer draus zu machen.

@thelittlebug: "-".isdigit() ist False.
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Samstag 29. Juli 2006, 15:34

Was passiert wenn ich -856 eingebe?
LoL... ;) ich ahbe erst gerätselt ;) Aber birkenfeld hats gut gesagt ;9 Das Lässt er net durch... da di da dup ;)

Und stimmt ;) Das ''== True'' ist ja im Prinziep doppelt gemoppelt ;)

Aber am Anfang bei der Entwicklung ansich besser zu lesen... Ist das schlechter Programmierstil oder ist das einfach nur unschön? In welche Kategorie gehört das? :D

MfG ChrissiG


##EDIT##

Ich habe mein Script nun wieder etwas erweitert. Und zwar wird nun dem Alter entsprechen ein BMI-Wert angegeben, welcher nicht über/unterschritten werden sollte.

Das ganze habe ich wiefolgt gelößt und wollte mal eure Meinung dazu hören:

Die Prüfung ob das Alter angegeben ist oder nicht sieht wiefolgt aus:

Code: Alles auswählen

# Auf Alter hinweisen
if alter.isdigit():
    print 'Sie haben das Alter angegeben, die Auswertung wird gleich folgen'
    alter = int(alter) #alter zum Rechnen umwandeln
else:
    alter = raw_input('Bitte geben Sie Ihr Alter an. Es wird benötigt!: ')
    if alter.isdigit() == True:
        print 'Sie haben Ihr Alter angegeben, Danke. Die Auswertung folgt.'
        alter = int(alter) #alter zum Rechnen umwandeln
    else:
        alter = 'nein'
        print 'Sie muessen Ihren BMI-Wert selbst vergleichen!'
Ich bin mir nicht sicher ob es hierdran schon liegt aber später taucht ein Fehler auf. Darüber später dann mehr.

Die Ausgabe habe ich wiefolgt gestaltet:

Code: Alles auswählen

# Auswertung 
print
print 'Sie haben einen BMI von %.2f' % bmi
print 'gerundet müssten Sie einen BMI-Wert von %.f haben' % bmi
print
if alter < 24:
    print 'Ihr BMI-Wert sollte Ihrem Alter entsprechend zwischen 19 und 24 liegen.'
elif alter < 34 and alter > 24:
    print 'Ihr BMI-Wert sollte Ihrem Alter entsprechend zwischen 20 und 25 liegen.'
elif alter < 44 and alter > 34:
    print 'Ihr BMI-Wert sollte Ihrem Alter entsprechend zwischen 21 und 26 liegen.'
elif alter < 54 and alter > 44:
    print 'Ihr BMI-Wert sollte Ihrem Alter entsprechend zwischen 22 und 27 liegen.'
elif alter < 64 and alter > 54:
    print 'Ihr BMI-Wert sollte Ihrem Alter entsprechend zwischen 23 und 28 liegen.'
elif alter > 64:
    print 'Wenn Sie älter als 64 Jahre sind sollte Ihr BMI-Wert eine Groesse von 29 nicht ueberschreiten!'
else:
    print 'Sie haben Ihr Alter nicht angegeben. Daher müssen Sie selbst Ihren Wert mit der folgenden Tabelle vergleichen.'

if alter == 'nein':
    print
    print 'Zum Vergleich. So sind die BMI Normalwerte dem Alter nach geordnet:'
    print '19-24 Jahre    19-24'  # 1
    print '25-34 Jahre    20-25'  # 2 
    print '35-44 Jahre    21-26'  # 3
Usw... (möchte nicht so viel Posten!)

Dannach kommt halt nur noch Ausgabe und eine ''Return'' Abfrage zum Beenden.

So und nun zu meinem Fehler. Wenn ich das Alter nicht angebe bzw. ein ''nein'' reinschreibe kommt nicht der Spruch, dass ich mein Alter nicht angegeben habe, sondern das ich älter als 64 Jahre bin. Hier ein Beispiel:
Geben Sie Ihr Körpergewicht in Kg an: 90
Geben Sie Ihre Körpergröße in Meter an: 1,89
Geben Sie bitte Ihr Alter an: nein
Bitte geben Sie Ihr Alter an. Es wird benötigt!: nein
Sie muessen Ihren BMI-Wert selbst vergleichen!

Sie haben einen BMI von 25.20
gerundet müssten Sie einen BMI-Wert von 25 haben

Wenn Sie älter als 64 Jahre sind sollte Ihr BMI-Wert eine Groesse von 29 nicht ueberschreiten!

Zum Vergleich. So sind die BMI Normalwerte dem Alter nach geordnet:
19-24 Jahre 19-24
Beim ersten Mal weißt er richtig darauf hin, das die Person selber vergleichen muss. Beim 2. Mal fehlt dieser Spruch, obwohl eingebaut (siehe oben bei Ausgabe)

Das ist im Moment das einzige Problem vor dem ich noch stehe.

Woran liegt das? Und wie kann ich das beheben? Könnt Ihr mir das bitte sagen? ;)

Und weitere Verbesserungsforschläge sind natürlich immer willkommen :D


MfG ChrissiG
BlackJack

Samstag 29. Juli 2006, 18:32

ChrissiG hat geschrieben:Und stimmt ;) Das ''== True'' ist ja im Prinziep doppelt gemoppelt ;)

Aber am Anfang bei der Entwicklung ansich besser zu lesen... Ist das schlechter Programmierstil oder ist das einfach nur unschön?


In Python würde ich sagen schlechter Stil weil nicht nur `True` und `False` als Wahrheitswerte dienen können, sondern jedes Objekt. Und ein Objekt das als Wahrheitswert "falsch" ist ergibt beim Vergleich mit `False` wieder `False` und nicht `True`.
Das ganze habe ich wiefolgt gelößt und wollte mal eure Meinung dazu hören:

Die Prüfung ob das Alter angegeben ist oder nicht sieht wiefolgt aus:

Code: Alles auswählen

# Auf Alter hinweisen
if alter.isdigit():
    print 'Sie haben das Alter angegeben, die Auswertung wird gleich folgen'
    alter = int(alter) #alter zum Rechnen umwandeln
else:
    alter = raw_input('Bitte geben Sie Ihr Alter an. Es wird benötigt!: ')
    if alter.isdigit() == True:
        print 'Sie haben Ihr Alter angegeben, Danke. Die Auswertung folgt.'
        alter = int(alter) #alter zum Rechnen umwandeln
    else:
        alter = 'nein'
        print 'Sie muessen Ihren BMI-Wert selbst vergleichen!'
Ich bin mir nicht sicher ob es hierdran schon liegt aber später taucht ein Fehler auf. Darüber später dann mehr.
Ich würde das vereinfachen und nur einmal Fragen. Und nicht mit `isdigit()` sondern ruhig mit der Ausnahme arbeiten.

Und auch wenn es in Python möglich ist, sollte man einem Namen in einem Kontext immer nur Objekte eines Typs zuweisen, oder zumindest solche die sich entsprechend Verhalten. Also das `alter` mal Zahl und mal Zeichenkette ist, ist etwas ungünstig. Eine Ausnahme von dieser Empfehlung ist `None`, was als Platzhalter für "undefiniert" genommen werden kann.

Code: Alles auswählen

try:
    alter = float(raw_input('Bitte geben Sie ihr Alter in Jahren an: '))
except ValueError:
    print 'Sie haben kein Alter angegeben.  Bitte benutzen sie die Tabelle...'
    alter = None
Die Ausgabe habe ich wiefolgt gestaltet:

Code: Alles auswählen

# Auswertung 
print
print 'Sie haben einen BMI von %.2f' % bmi
print 'gerundet müssten Sie einen BMI-Wert von %.f haben' % bmi
print
if alter < 24:
    print 'Ihr BMI-Wert sollte Ihrem Alter entsprechend zwischen 19 und 24 liegen.'
elif alter < 34 and alter > 24:
    print 'Ihr BMI-Wert sollte Ihrem Alter entsprechend zwischen 20 und 25 liegen.'
elif alter < 44 and alter > 34:
    print 'Ihr BMI-Wert sollte Ihrem Alter entsprechend zwischen 21 und 26 liegen.'
elif alter < 54 and alter > 44:
    print 'Ihr BMI-Wert sollte Ihrem Alter entsprechend zwischen 22 und 27 liegen.'
elif alter < 64 and alter > 54:
    print 'Ihr BMI-Wert sollte Ihrem Alter entsprechend zwischen 23 und 28 liegen.'
elif alter > 64:
    print 'Wenn Sie älter als 64 Jahre sind sollte Ihr BMI-Wert eine Groesse von 29 nicht ueberschreiten!'
else:
    print 'Sie haben Ihr Alter nicht angegeben. Daher müssen Sie selbst Ihren Wert mit der folgenden Tabelle vergleichen.'

if alter == 'nein':
    print
    print 'Zum Vergleich. So sind die BMI Normalwerte dem Alter nach geordnet:'
    print '19-24 Jahre    19-24'  # 1
    print '25-34 Jahre    20-25'  # 2 
    print '35-44 Jahre    21-26'  # 3
So und nun zu meinem Fehler. Wenn ich das Alter nicht angebe bzw. ein ''nein'' reinschreibe kommt nicht der Spruch, dass ich mein Alter nicht angegeben habe, sondern das ich älter als 64 Jahre bin.
Das ist ein Problem wenn man Objekte unterschiedlichen Typs miteinander vergleicht. So ein Vergleich, auch auf kleiner und grösser funktioniert in Python immer, nur ist das Ergebnis willkürlich aber konstant (zumindest in einer Interpretierersitzung). Mehr Garantien werden nicht gemacht.

Wenn man also eine beliebige Zahl mit einer beliebigen Zeichenkette vergleicht, dann ist die Zahl immer kleiner als die Zeichenkette. Oder umgekehrt. Und genau solche Vergleiche machst Du, wenn `alter` an 'nein' gebunden ist:

Code: Alles auswählen

In [150]: 'viking' > 42
Out[150]: True
Am besten prüft man am Anfang ob das Alter überhaupt angegeben wurde und geht dann entsprechend bei `if` oder `else` weiter.

Ein weiterer Verbesserungsvorschlag: Nicht so viel Quelltext wiederholen. Lieber die sich nicht wiederholenden Teile in eine entsprechende Datenstruktur herausziehen. Zum Beispiel könntest Du Dir eine Tabelle (Liste von Listen) von zwei Alterswerten (Unter-, Obergrenze) und dem minimalen BMI generieren und die dann für die Ausgaben heranziehen. Ungefähr so:

Code: Alles auswählen

def create_bmi_table():
    result = list()
    for i in xrange(6):
        result.append([14 + i * 10, 24 + i * 10, 19 + i])
    result[0][0] = 0
    result[-1][1] = sys.maxint
    return result

bmi_table = create_bmi_table()

for untergrenze, obergrenze, bmi_untergrenze in bmi_table:
    if untergrenze < alter < obergrenze:
        print ('Ihr BMI-Wert sollte Ihrem Alter entsprechend zwischen'
               ' %d und %d liegen.' % (bmi_untergrenze, bmi_untergrenze + 5))
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Samstag 29. Juli 2006, 20:38

Sehr gute Hinweise von dir. Ich Danke dir.

Leider kann ich nicht ganz alles einbauen.

Dazu gehört unter anderem diese Tabelle die du als letztes Angesprochen hast.
Den rest habe ich bereits eingebaut.

Aber in 12 Tagen melde ich mich nochmal ;) Mit dem "vollständigen Programm" Und werde wiedermal eure Meinung abfragen :D

Und ich finde das muss mal gesagt werden. Wie viel Arbeit Ihr euch macht hier um leuten wir z.B. mir zu helfen... das verdient Lob! Großes Lob! Habt Dank!

Also dann bis in 12 Tagen ;)

cYa und by by!

MfG ChrissiG
Antworten