Kurze Frage zum def Befehl

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
Shaldy
User
Beiträge: 123
Registriert: Sonntag 2. März 2008, 22:49

Also, ich bin noch ziemlich neu auf dem Gebiet und hab eine Frage.

Code: Alles auswählen

def start():
    print "Wilkommen zu meinem kleinen Rechenprogramm."
    print "Bis jetzt können sie hier die Werte einer Parabel und ihre nächsten"
    print "Zinssätze errechnen."
    print
    print "Um bestimmte Werte für eine Parabel auszurechnen, drücken sie die 1."
    print "Um Zinssätze für die nächsten Jahre auszurechnen, drücken sie die 2."
    print
    eingabe = input("Ihre Eingabe: ")
    if eingabe == 1:
        parabel()
    if eingabe == 2:
        zinsrechnung()
start()

#>>>--------------------------------------------------------------------<<<

def parabel():
    #Eingabe    
    print "Hier berechnen wir eine Parabel der Funktion f(x)->x²"
    x_start = input("Geben sie den x-Wert als Startwert ein: ")
    x_ende = input("Geben sie den x-Wert als Endwert ein: ")
    schritte = input ("In welchem Schritt soll gerechnet werden? ")

    #Verarbeitung
    while x_start <= x_ende:
        rechnung = x_start
        rechnung = rechnung**2
        
        #Ausgabe
        if x_start >= 0:
            print "X-Wert:"+str(x_start)+",     Y-Wert:",rechnung
        if x_start < 0:
            print "X-Wert:"+str(x_start)+",    Y-Wert:",rechnung
        x_start+=schritte
    print
    start()
parabel()

#>>>--------------------------------------------------------------------<<<

def zinsrechnung():
    #Eingabe
    laufzeit = input("Für wie viele Jahre rechnen? ")
    kapital = input("Startkapital eingeben: ")
    zinssatz = input ("Zinssatz in Prozent angeben")
    jahr = 1

    #Verarbeitung
    while jahr <= laufzeit:
        anhang = (kapital*zinssatz)/100.0
        kapital_neu = kapital + anhang
        print "Jahr:",jahr
        print "Kapital:",kapital,"€ +",anhang,"€ =",kapital_neu
        print
        laufzeit+=1
    print
    start()
zinsrechnung()
start()
Angenommen ich schreibe einen Code in einen dieser Def...() Befehle. Wenn ich dann irgendwann den Namen dieses Befehls mit den Klammern dahinter wiedergebe springt der Code doch bis dorthin und wiederholt dieses Stück Code oder lieg ich da falsch? Bei mir kommt nämlich folgende Fehlermeldung:

Code: Alles auswählen

IDLE 1.2.1      ==== No Subprocess ====
>>> 
Wilkommen zu meinem kleinen Rechenprogramm.
Bis jetzt können sie hier die Werte einer Parabel und ihre nächsten
Zinssätze errechnen.

Um bestimmte Werte für eine Parabel auszurechnen, drücken sie die 1.
Um Zinssätze für die nächsten Jahre auszurechnen, drücken sie die 2.

Ihre Eingabe: 1
Traceback (most recent call last):
  File "C:\Python25\Scripte\Rechnen.py", line 14, in <module>
    start()
  File "C:\Python25\Scripte\Rechnen.py", line 11, in start
    parabel()
NameError: global name 'parabel' is not defined
Dies ist keine Signatur!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hallo Shaldy, willkommen im Forum,

Das liegt daran, dass ``parabel()`` zu der Zeit wo du es aufrufst noch nicht definiert ist, weil du es erst später definierst. Also kannst du es entweder früher definieren oder diesen ``if __name__ == '__main__':\n main()``-Trick verwenden.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Shaldy
User
Beiträge: 123
Registriert: Sonntag 2. März 2008, 22:49

Ähm, und wie funktioiniert dieser Trick? ^^"
Dies ist keine Signatur!
BlackJack

Ich würde es nicht als "Trick" bezeichnen. Es ist ganz normaler Python-Code.

Du solltest generell die Ablaufsteuerung überdenken. Funktionsaufrufe sind keine Sprungbefehle so wie Du sie missbrauchst. Deine Funktionen kehren nicht zurück wenn Du am Ende immer eine andere Funktion aufrufst. Sämtliche lokalen Variablen von jedem Aufruf bleiben so das ganze Programm über erhalten. Ausserdem gibt es bei CPython eine künstliche Begrenzung wie oft man Funktionsaufrufe verschachteln kann.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Shaldy hat geschrieben:Ähm, und wie funktioiniert dieser Trick? ^^"
Du benennst ``start()`` in ``main()`` um, wirst das modulglobale ``start()`` los und kopierst den von mir geposteten Code ganz ans ende der Datei. Oder du benutzt die Forumssuche und schaust wie so etwas eben aussieht.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Ähm, und wie funktioiniert dieser Trick? ^^"
Wie man an deinem Quelltext sehen kann, befindest du dich noch in einem sehr frühen Stadium des Programmierens. Da - und eigentlich überhaupt - ist es sicher besser, wenn man ein Programm nicht dadurch zum Laufen bekommt, dass man irgendeinen "Trick" anwendet - der, worauf ja schon hingewiesen wurde, natürlich objektiv kein "Trick" ist, aber subjektiv für dich z.Zt. vermutlich schon -, sondern - und auch darauf wurde schon hingewiesen - ein Programm dem eigenen aktuellen Kenntnisstand gemäß so aufbaut, dass es fehlerfrei läuft.

Konkreter Vorschlag:
Die Funktion start() ganz weglassen und zum "Hauptprogramm" machen - ganz nach unten. Die Aufrufe von parabel() und zinsrechnung() in eine Schleife packen, die so lange zirkuliert, bis der Anwender - z.B. durch die Eingabe von 0 - das Programm beendet.

Und: Die meisten Bezeichner sind für meinen Geschmack gut gelungen, bis auf "rechnung" und "anhang". Daran solltest du noch ein bisschen feilen.
BlackJack

Ich plädiere, gerade bei Anfängern, gegen "Hauptprogramm auf Modulebene" und für das ``if __name__ == '__main__'``-Idiom. Denn gerade Anfängern kann es viel an Erkenntnisgewinn bringen, wenn sie ihr Programm als Modul importieren können und ihre Funktionen einzeln testen können, um heraus zu finden, wie sie sich bei verschiedenen Eingaben verhalten.

@Shaldy: Noch ein paar Anmerkungen zum Quelltext:

Bei der Ausgabe in `parabel()` solltest Du mit ``%`` die Werte in eine Zeichenkette formatieren, dann brauchst Du das ``if``/``else`` nicht. Details: http://docs.python.org/lib/typesseq-strings.html

Die ``while``-Schleife in `zinsrechnung()` sollte man durch eine ``for``-Schleife ersetzen. Und auch hier wäre die Formatierung per ``%`` wieder nützlich, um zum Beispiel die Anzahl der angezeigten Nachkommastellen auf zwei zu beschränken.
Shaldy
User
Beiträge: 123
Registriert: Sonntag 2. März 2008, 22:49

naja, ich bin noch nicht sehr weit mit python, hab sozusagen erst grade damit angefangen. Was in meinem Code steht ist alles was ich bis jetzt hinkriege. Hab den Code jetzt folgendermaßen umgeschrieben. So funktioniert er:

Code: Alles auswählen

def begruessung():
    print "Wilkommen zu meinem kleinen Rechenprogramm."
    print "Bis jetzt können sie hier die Werte einer Parabel und ihre nächsten"
    print "Zinssätze errechnen."
    print
    print "Um bestimmte Werte für eine Parabel auszurechnen, drücken sie die 1."
    print "Um Zinssätze für die nächsten Jahre auszurechnen, drücken sie die 2."
    print "Um das Programm zu beenden, drücken sie die 3"
    print
    start()

#-----------------------------------------------------------------------<<<

def start():
    eingabe = input("Ihre Eingabe: ")
    if eingabe == 1:
        parabel()
    if eingabe == 2:
        zinsrechnung()
    if eingabe == 3:
        print "Auf wiedersehen!"
        exit

#>>>--------------------------------------------------------------------<<<

def parabel():
    #Eingabe    
    print "Hier berechnen wir eine Parabel der Funktion f(x)->x²"
    x_start = input("Geben sie den x-Wert als Startwert ein: ")
    x_ende = input("Geben sie den x-Wert als Endwert ein: ")
    schritte = input ("In welchem Schritt soll gerechnet werden? ")

    #Verarbeitung
    while x_start <= x_ende:
        rechnung = x_start
        rechnung = rechnung**2
        
        #Ausgabe
        if x_start >= 0:
            print "X-Wert:"+str(x_start)+",     Y-Wert:",rechnung
        if x_start < 0:
            print "X-Wert:"+str(x_start)+",    Y-Wert:",rechnung
        x_start+=schritte
    print
    start()

#>>>--------------------------------------------------------------------<<<

def zinsrechnung():
    #Eingabe
    laufzeit = input("Für wie viele Jahre rechnen? ")
    kapital = input("Startkapital eingeben: ")
    zinssatz = input ("Zinssatz in Prozent angeben: ")
    jahr = 1

    #Verarbeitung
    while jahr <= laufzeit:
        anhang = (kapital*zinssatz)/100.0
        kapital_neu = kapital + anhang

        #Ausgabe
        print "Jahr:",jahr
        print "Kapital:",kapital,"€ +",anhang,"€ =",kapital_neu
        kapital = kapital_neu
        jahr+=1
    print
    start()
def ende():
    exit

begruessung()
Dies ist keine Signatur!
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Hallo Shaldy,

das ist kein wirklicher Fortschritt, was du da präsentierst.
Die gleichen "schrägen Sachen" sind nur in andere Häppchen eingeteilt.

Du hast doch in diesem Thread konkrete Tipps bekommen,
wie man daraus einen anständigeren Quelltext machen könnte,
setzt sie aber nicht um, sondern zeigst uns mehr oder weniger das Gleiche noch mal.

Was ist also dein Anliegen?
Shaldy
User
Beiträge: 123
Registriert: Sonntag 2. März 2008, 22:49

Ich habe ganz oben gesagt, daß ich dauernd eine Fehlermeldung bekomme, wenn ich das Programm starte.
Das ist mit dem "neuen" Text behoben.
Ich fange in Informatik gerade erst mit Python an, was ich euch gezeigt habe war zwar keine Hausaufgabe, aber mehr als das kann ich im Moment noch nicht.
Ich wollte lediglich wissen wie ich die Fehlermeldung wegbekomme und das ist jetzt geschafft.

Danke =)
Dies ist keine Signatur!
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Informatik-Studium?
Antworten