Erste Versuche mit Python

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
AdrianA
User
Beiträge: 4
Registriert: Sonntag 5. September 2010, 20:50

Hallo.
Ich hab soeben nach einem Python Forum gesucht, damit ich eventuell Hilfe bei einem Programm bekomme!
Vor kurzem habe ich Python erst in der Schule kennengelernt und starte jetzt erste Versuche, um ein wenig zu üben.
Ich dachte mir also, schreib ich mal ein kleines Programm, was den BMI ausrechnet.
Hier der Text:

Code: Alles auswählen

# Eingabe
print 'Körpergewicht: '
Körpergewicht = input()
print
print 'Körpergröße in m: '
Körpergröße = input()
print
print 'Geschlecht (männlich oder weiblich): '
Geschlecht = raw_input()


# Verarbeitung

BMI = Körpergewicht/(Körpergröße*Körpergröße)

# Ausgabe

print 'Dein BMI entspricht:'
print BMI

if BMI < 20 and Geschlecht == männlich:
    print 'Du hast Untergewicht! Iss, Iss, Iss! :D'

elif BMI == 20-25 and Geschlecht == männlich:
    print 'Du hast Normalgewicht! Alles in bester Ordnung :)'

elif BMI == 25-30 and Geschlecht == männlich:
    print 'Du hast Übergewicht! Owei, sieh zu, dass du abnimmst! :/ '

elif BMI == 30-40 and Geschlecht == männlich:
    print 'Du hast Adipositas! Das bedeutet starkes Übergewicht! Geh zum Arzt! '

elif BMI > 40 and Geschlecht == männlich:
    print 'Du hast massive Adipositas! Es sieht schlecht aus! Geh dringend zum Arzt! :/ '

elif BMI < 19 and Geschlecht == weiblich:
    print 'Du hast Untergewicht! Iss, Iss, Iss! :D'
    
elif BMI == 19-24 and Geschlecht == weiblich:
    print 'Du hast Normalgewicht! Alles in bester Ordnung :)'

elif BMI == 24-30 and Geschlecht == weiblich:
    print 'Du hast Übergewicht! Owei, sieh zu, dass du abnimmst! :/ '

elif BMI == 30-40 and Geschlecht == weiblich:
    print 'Du hast Adipositas! Das bedeutet starkes Übergewicht" Geh zum Arzt! '

elif BMI > 40 and Geschlecht == weiblich:
    print 'Du hast massive Adipositas! Es sieht schlecht aus! Geh dringend zum Arzt! :/ '


Ich hab wirklich noch kaum Ahnung von Python, also wäre schön, wenn mir jemand helfen könnte...
Das Problem ist nämlich, sobald ich die Änderungen speicher und "Run Module" anklicke, funktioniert noch alles ganz gut.
Doch wenn ich Körpergewicht, Körpergröße und Geschlecht eingebe, wirft das Programm nur folgendes aus:

Code: Alles auswählen

Python 2.6 (r26:66721, Oct  2 2008, 11:35:03) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.

    ****************************************************************
    Personal firewall software may warn about the connection IDLE
    makes to its subprocess using this computer's internal loopback
    interface.  This connection is not visible on any external
    interface and no data is sent to or received from the Internet.
    ****************************************************************
    
IDLE 2.6      
>>> ================================ RESTART ================================
>>> 
Körpergewicht: 
65

Körpergröße in m: 
1.78

Geschlecht (männlich oder weiblich): 
männlich
Dein BMI entspricht:
20.515086479
>>> 
Eigentlich sollte danach ja noch was kommen, was man an meinem Code erkennt^^
Also.. Hilfe wäre sehr nett :)
Ich arbeite mit Python 2.6, wie man am Code erkennt.

Dankesehr :)
Adrian
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

AdrianA hat geschrieben:Eigentlich sollte danach ja noch was kommen, was man an meinem Code erkennt^^
Das stimmt: Ein Traceback wegen eines `NameError`, da`männlich` nie definiert wurde. Das `20-25` wird uebrigens zu `5` ausgewertet. Du vermischst Namen, Strings und Zahlen. Nicht gut.

Code: Alles auswählen

BMI == 25-30
sollte so aussehen:

Code: Alles auswählen

25 <= BMI <= 30
`raw_input` nimmt als Argument uebrigens einen String als Prompt entgegen, du brauchst keine `print` vorschalten.
AdrianA
User
Beiträge: 4
Registriert: Sonntag 5. September 2010, 20:50

Danke erstmal!
Stimmt, das mit dem:
25 <= BMI <= 30

da hätt ich selbst drauf kommen können^^

Wie "definiere" ich denn das männlich, bzw das weiblich?.

danke
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

AdrianA hat geschrieben:Wie "definiere" ich denn das männlich, bzw das weiblich?.
Nein du hast mich missverstanden, du willst in den Vergleichen u"männlich", "weiblich" nutzen, also Strings, keine Namen.

Natuerlich kannst du

Code: Alles auswählen

männlich = u"männlich"
nutzen und so `männlich` definieren ... aber that way lies madness.

Du solltest dich zum anfang aber besser auf ASCII begrenzen, also einfaches Alphabet ohne Umlaute und dergleichen, das verkompliziert den Einstieg nur Unnoetig (`str` vs `unicode`, Encodings, ...).
AdrianA
User
Beiträge: 4
Registriert: Sonntag 5. September 2010, 20:50

OK, so siehts jetzt aus, und es funktioniert :)
Kann ich mir es eventuell noch leichter machen, oder passt das so?:)

Dankesehr für die Hilfe!

Code: Alles auswählen

# Eingabe
print 'Koerpergewicht: '
Koerpergewicht = input()
print
print 'Koerpergroeße in m: '
Koerpergroeße = input()
print
print 'Geschlecht (maennlich oder weiblich): '
Geschlecht = raw_input()


# Verarbeitung

BMI = Koerpergewicht/(Koerpergroeße*Koerpergroeße)
maennlich = 'maennlich'
weiblich = 'weiblich'

# Ausgabe

print 'Dein BMI entspricht:'
print BMI

if BMI < 20 and Geschlecht == str(maennlich):
    print 'Du hast Untergewicht! Iss, Iss, Iss! :D'

elif 20 <= BMI <= 25 and Geschlecht == str(maennlich):
    print 'Du hast Normalgewicht! Alles in bester Ordnung :)'

elif 25 <= BMI <= 30 and Geschlecht == str(maennlich):
    print 'Du hast Uebergewicht! Owei, sieh zu, dass du abnimmst! :/ '

elif 30 <= BMI <= 40 and Geschlecht == str(maennlich):
    print 'Du hast Adipositas! Das bedeutet starkes Uebergewicht! Geh zum Arzt! '

elif BMI > 40 and Geschlecht == str(maennlich):
    print 'Du hast massive Adipositas! Es sieht schlecht aus! Geh dringend zum Arzt! :/ '

elif BMI < 19 and Geschlecht == str(weiblich):
    print 'Du hast Untergewicht! Iss, Iss, Iss! :D'
    
elif 19 <= BMI <= 24 and Geschlecht == str(maennlich):
    print 'Du hast Normalgewicht! Alles in bester Ordnung :)'

elif 24 <= BMI <= 30 and Geschlecht == str(weiblich):
    print 'Du hast Uebergewicht! Owei, sieh zu, dass du abnimmst! :/ '

elif 30 <= BMI <= 40 and Geschlecht == str(weiblich):
    print 'Du hast Adipositas! Das bedeutet starkes Uebergewicht" Geh zum Arzt! '

elif BMI > 40 and Geschlecht == str(weiblich):
    print 'Du hast massive Adipositas! Es sieht schlecht aus! Geh dringend zum Arzt! :/ '

derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Ähm, maennlich und weiblich sind doch schon Strings?! Warum dann zusätzlich nochmal str(…) darauf anwenden?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

cofi hat geschrieben:Natuerlich kannst du

Code: Alles auswählen

männlich = u"männlich"
nutzen und so `männlich` definieren ... aber that way lies madness.
Ich meinte:

Code: Alles auswählen

if BMI < 20 and Geschlecht == "maennlich":
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Desweiteren: Vergiss (vorerst), dass es 'input' gibt und verwende stattdessen 'raw_input'. Die Gründe kann man hier alle paar Tage nachlesen.

'raw_input' liefert zwar eine Zeichenkette zurück, mit welcher nicht direkt weitergerechnet werden kann, es existieren jedoch "Umwandlungsfunktionen":

Code: Alles auswählen

# Ganzzahlen (Integer):
groesse = int(raw_input(u'Ihre Größe bitte.'))
# Fließkommazahlen (float):
foo = float(raw_input(u'Ihre Fließkommazahl.'))
Grüße ...
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Py-Prog
User
Beiträge: 673
Registriert: Dienstag 16. Februar 2010, 17:52
Wohnort: G:\ermany

@ AdrianA wieso nicht so:

Code: Alles auswählen

Körpergewicht=input('Körpergewicht: ')
wenn du es untereinander haben willst dann lasses wies ist.


:lol: :wink:
Technik ist: wenn alles funktioniert und keiner weiß warum.
Wer Rechtschreibfehler findet darf sie behalten.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Diese ganzen if...elif-Kaskaden sind ja furchtbar. Ich würde mir mal zuerst eine geeignete Datenstruktur überlegen.

Du hast anscheinend unabhängig vom Geschlecht die selben Meldungen, die nach Auswertung erscheinen sollen. Die könnte man schon mal in ein Tupel packen:

Code: Alles auswählen

messages = (
    u'Du hast Untergewicht! Iss, Iss, Iss! :D',
    u'Du hast Normalgewicht! Alles in bester Ordnung :)',
   ...
)
Will man darauf zugreifen benötigt man nur noch den Index:

Code: Alles auswählen

print messages[1]
Dann zu den Fallunterscheidungen. Nehmen wir mal vereinfachender Weise an, es gäbe immer eine definierte obere und untere Schranke. Damit müßte man immer prüfen, ob der BMI-Wert in einer Schranke liegt und zwar solange, bis die passende Schranke gefunden wurde.

Nun stellt sich noch die Frage, wieso Du immer "<=" verwendest. Damit wäre die Zuordnung auf den Intervallgrenzen undefiniert. Also solltest Du eine eindeutige Ordnung definieren, z.B. "<=" bei der unteren und "<" bei der oberen Schranke.

Idee: Man merkt sich die Schranken in einem Tupel:

Code: Alles auswählen

BMI_DEF = (20, 25, 30, 35, 40)
Dieses Tupel kann man nun durchlaufen, zu Beginn den ersten Wert als obere Schranke nehmen, danach in jedem Durchlauf das alte Element als untere und das aktuelle als obere Schranke und ganz am Schluss das letzte Element als untere Schranke annehmen.
Um nicht immer mit krummen Index-Zugriffen zu arbeiten, erzeugen wir uns daraus einfach für jeden Durchlauf ein passendes Tupel, bestehend aus (min, max)-Werten.

Dazu gibt es im itertools-Modul izip_longest und chain:

Code: Alles auswählen

In [6]: bmi_def = BMI_DEF

In [7]: list(izip_longest(chain((None, ), bmi_def), bmi_def))
Out[7]: [(None, 20), (20, 25), (25, 30), (30, 35), (35, 40), (40, None)]
Mit diesen Tupeln können wir nun mit einem if-Statement testen, ob ein gegebener bmi-Wert in einem Intervall liegt:

Code: Alles auswählen

    for index, constraints in enumerate(izip_longest(chain((None, ), bmi_def), bmi_def)):
        min_, max_ = constraints
        if min_ <= bmi and bmi < max_:
            return index
Durch das enumerate erzeugen wir uns einen index, der uns das Intervall angibt, in dem unserer bmi liegt. Damit kann man dann die Nachrichten gezielt ausgeben (s.o.).

Eigentlich müssen wir uns nun nur noch die "Grenzfälle" angucken. Also den 1. Durchlauf und den letzten, wo wir je einmal ein "None" statt eines Integers bekommen.

Schauen wir zunächst auf den Test aufs Minmum bei einem angenommenen bmi von 10:

Code: Alles auswählen

min_ <= bmi 
führt zu:

Code: Alles auswählen

In [8]: None < 10
Out[8]: True
Aha. Diesen Fall brauchen wir nicht extra behandeln.

Wie siehts mit dem Schluss aus, wo wir ein Tupel der Art (40, None).

Code: Alles auswählen

bmi < max_
bei einem bmi von 41 führt zu

Code: Alles auswählen

In [9]: 41 < None
Out[9]: False
Das klappt so nicht; wir müssen einen Ausweg für das letzte Intervall finden.

Idee: Sollte der max-Wert None sein, ersetzen wir ihn durch einen hinreichend großen Integeer Wert.

Code: Alles auswählen

        if not max_:
            max_ = bmi+1
Nun muss man eigentlich nur noch alles zusammenpacken:
http://www.python-forum.de/pastebin.php ... &mode=view

Die Anpassung des Datentypen für die Geschlechter-Unterscheidung überlasse ich mal dem OP ;-) Tipp: Ich würde ein Dictionary nehmen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
AdrianA
User
Beiträge: 4
Registriert: Sonntag 5. September 2010, 20:50

Wow, danke für die Mühe!
Ich werd mir später nochmal in Ruhe Gedanken über alles machen, jetzt beim ersten Mal durchlesen versteh ich nur Bahnhof :P

Trotzdem vielen, vielen Dank.

;)
Antworten