Ineinander verschachtelte Funktionen

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
Hakan78
User
Beiträge: 9
Registriert: Mittwoch 14. November 2007, 00:05

Hallo
Ich bin neu bei Python und muss daher eine Anfängerfrage stellen, auf die ich leider nach über 2 Stunden suchen im Netz keine Antwort gefunden habe.
Ich möchte eine Funktion innerhalb einer anderen aufrufen und bekomme immer eine Fehlermeldung dabei. Das ganze soll sieht so aus

Code: Alles auswählen

def funktion1(param)
     doSomething
def funktion2()
      do Somethin
      funktion1(3)
oder in richtigem code

Code: Alles auswählen

    def abstand(x1,x2,y1,y2):
        s = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))
        return s


    def beschleunigung(y1,y2,s):
        a = 9.81*(y1-y2)/s
        return a

    def zeit(v,a,s,y1,y2):
        if y2 == y1:
            t=s/v
        else:
            t=-v/a+((sqrt(v*v+2*a*s))/a)
        return t

    def geschwindigkeit(v,a,t):
        vneu = v +a*t
        return vneu

    def fitness(xArray,yArray):
        zeit = 0
        for i in range(len(xArray)-1):
              s = abstand(xArray[i],xArray[i+1],yArray[i],yArray[i+1])
              print s
wobei fitness und abstand grade die Funktionen sind um die es geht.
Fehlermeldung ist dann Folgende:

Code: Alles auswählen

Traceback (most recent call last):
  File "/home/general/Uni/Eaza/rutsche.py", line 1, in <module>
    class rutsche(object):
  File "/home/general/Uni/Eaza/rutsche.py", line 44, in rutsche
    fitness(xArray,yArray)
  File "/home/general/Uni/Eaza/rutsche.py", line 39, in fitness
    s = abstand(xArray[i],xArray[i+1],yArray[i],yArray[i+1])
NameError: global name 'abstand' is not defined

Kann mir wer helfen? Des weiteren wenn ich die Funktion abstand weiter unten, also nach fitness erst implementiere, kennt python die nicht. Gibts da so ne Möglichkeit wi in C++ den Methodenkopf am Anfang einer Klasse zu implementieren und die eigentliche Funktion erst später?
Einen netten Gruß
Jan[/code]
Zuletzt geändert von Hakan78 am Mittwoch 14. November 2007, 09:49, insgesamt 3-mal geändert.
BlackJack

Zeig doch mal was Du hast und was für einen Fehler Du bekommst. Möglichst den genauen Wortlaut per copy'n'paste.

Funktionsaufruf ist einfach der Name der Funktion gefolgt von Klammern die die Argumente enthalten, die die aufgerufene Funktion erwartet.
Hakan78
User
Beiträge: 9
Registriert: Mittwoch 14. November 2007, 00:05

Jo hab ich gemacht bin eben nur ausversehen zu früh auf Absende Button gekommen.
BlackJack

Also dass hier funktioniert problemlos:

Code: Alles auswählen

def main():
    def abstand():
        print 'abstand'
    
    def fitness():
        abstand()

    fitness()
Zeig uns doch mal ein minimales, "lauffähiges" Beispiel, das die Fehlermeldung auslöst. Das was Du da gezeigt hast sieht so auf den ersten Blick jedenfalls korrekt aus.

Was mich am Traceback ein wenig verwirrt: Sind die Funktionen etwa alle in einer Klasse definiert!?

Zur zweiten Frage: In Python gibt's bis auf die Ausnahme ``global`` keine Deklarationen. ``def``-Anweisungen sind ausführbar und müssen halt ausgeführt werden bevor man auf das Funktionsobjekt über den Namen zugreifen kann.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Wenn ich deinen Code so, wie er ist, laufen lasse, muss ich erstens die Einrueckung aendern (jeweils die ersten vier Leerzeichen entfernen), dann sqrt importieren, dann laeuft es fehlerfrei, allerdings ohne das was passiert. Dann habe ich zum Schluss noch einen Aufruf von Fitness angehaengt, und es laeuft immer noch fehlerfrei.

Dein Fehler sollte auch nicht auftreten. Es ist auch egal, wenn du die Funktion abstand nach der Funktion fitness definierst. Denn wenn du am Ende des Programmes erst die Funktion fitness aufrufst, sind ja alle Funktionen schon definiert.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Hakan78
User
Beiträge: 9
Registriert: Mittwoch 14. November 2007, 00:05

Hääte ich vieleicht schon gle4ich machen sollen aber nun mal die gesamte Klasse( Dann erledigt sich das auch mit dem Einrücken.)

Code: Alles auswählen

import math

class rutsche(object):
    stuetzpunkte = 19
    yArray = []
    xArray = []
    hoehe = 20
    breite = 40
    yArray.append(hoehe)
    xArray.append(0)
    for i in range(stuetzpunkte):
        aktuellehoehe = hoehe - hoehe/stuetzpunkte*(i+1)
        yArray.append(aktuellehoehe)
        aktuellebreite = 0 +  (breite/stuetzpunkte)*(i+1)
        xArray.append(aktuellebreite)
    xArray.append(breite)    
    yArray.append(0)
    print yArray
    print xArray

    
    def abstand(x1,x2,y1,y2):
        s = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))
        return s


    def beschleunigung(y1,y2,s):
        a = 9.81*(y1-y2)/s
        return a

    def zeit(v,a,s,y1,y2):
        if y2 == y1:
            t=s/v
        else:
            t=-v/a+((sqrt(v*v+2*a*s))/a)
        return t

    def geschwindigkeit(v,a,t):
        vneu = v +a*t
        return vneu

    def fitness(self,xArray,yArray):
        zeit = 0
        for i in range(len(xArray)-1):
              s = self.abstand(xArray[i],xArray[i+1],yArray[i],yArray[i+1])
              print s


neueRutsche = rutsche()
die Letzte Zeile ist nur ein Versuch gewesen[/code]
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Nimm es mir nicht uebel, aber von Objektorientierter Programmierung hast du keine Ahnung. Vielleicht solltest du erstmal ein einfuehrendes Tutorial lesen?

Erstmal die ganzen Definitionen in Zeile 5ff: Du machst da Klassenvariablen draus, wo Objektvariablen besser geeignet waeren. Du solltst das Ganze in eine __init__-Methode verpacken.

Dann bekommen Objektmethoden immer das Objekt selbst als ersten Parameter uebergeben, den man ueblicherweise self nennt. Bei der fitness-Methode hast du das ja richtig gemacht, bei den restlichen Methoden nicht. Du duerftest da ein paar Fehlermeldungen wegen falscher Parameteranzahl erhalten.

sqrt musst du via math.sqrt aufrufen

Dann z.b. die fitness-Methode: Sinn von OOP ist ja, dass die Daten ( in diesem Fall xArray und yArray) im Objekt vorliegen und man sie nicht nochmal extra via Parameter uebergeben werden muessen! Du kannst sie dir ueber self.xArray etc holen.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Nochwas: Die Abstansmethode ist total allgemein und auch fuer andere Dinge anwendbar. Die wuerde ich aus der Klasse rausziehen. Mann sie auch leicht fuer Punkte beliebiger Dimension erweitern...

Ausserdem wuerde ich die Daten der Stuetzpunkte nicht in zwei verschiedenen Listen speichern, sondern in einer Liste von (x, y)-Tupeln, z.B.:

Code: Alles auswählen

stuetzpunkte = [(1, 2), (3, 4),...]
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Das kann auch schon deswegen nicht Funktionieren, da Klassenmethoden automatisch einen ersten Parameter, die Instanz mitbekommen, die üblicherweise an `self`gebunden wird. Das tust du fast nirgendwo.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Hakan78
User
Beiträge: 9
Registriert: Mittwoch 14. November 2007, 00:05

Danke erstmal für die Antworten, werde mich damit wieter beschäftigen. Hab das ganze ein wenig umgeschrieben, die Klasse wegepackt und druch ne main methode ersetzt und so läuft es nu erstmal.
Antworten