Seite 1 von 1

Ineinander verschachtelte Funktionen

Verfasst: Mittwoch 14. November 2007, 09:37
von Hakan78
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]

Verfasst: Mittwoch 14. November 2007, 09:42
von 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.

Verfasst: Mittwoch 14. November 2007, 09:50
von Hakan78
Jo hab ich gemacht bin eben nur ausversehen zu früh auf Absende Button gekommen.

Verfasst: Mittwoch 14. November 2007, 10:22
von 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.

Verfasst: Mittwoch 14. November 2007, 10:23
von Rebecca
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.

Verfasst: Mittwoch 14. November 2007, 11:01
von Hakan78
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]

Verfasst: Mittwoch 14. November 2007, 11:20
von Rebecca
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.

Verfasst: Mittwoch 14. November 2007, 11:29
von Rebecca
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),...]

Verfasst: Mittwoch 14. November 2007, 13:31
von Leonidas
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.

Verfasst: Mittwoch 14. November 2007, 19:42
von Hakan78
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.