Funktionsaufruf verschachtelter 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
[-_-']
User
Beiträge: 2
Registriert: Sonntag 18. Januar 2015, 14:43

Hallo vielmals,
ich würde mich freuen, wenn ihr mir bei einem Problem mit ineinander verschachtelten Funktionen helfen könntet.

Zunächst einmal definiere ich eine Funktion g2 mit 5 Argumenten (Geradengleichung in 2-Punktform).
Anschließend benutze ich diese "allgemeine" Funktion, um konkrete Geradengleichungen, z.B.: y1 zu erstellen. Diese kann ich anschließend mit x Werten füttern und z.B. über scipy.optimize.fsolve() Schnittpunkte zwischen zwei Geraden bestimmen.

Nun zu meinem Problem:
Ich möchte y1 in einer Funktion fneu(y1) aufrufen und würde gerne die 4 Werte auslesen die ich beim Erzeugen von y1 and g2 übergeben habe.

Kann mir jemand vielleicht einen Tipp geben, wie ich mit dem Modul inspect an die gewünschten Informationen herankomme?

Vielen Dank schon mal im Vorraus!

Code: Alles auswählen

g2= lambda x1,y1,x2,y2,x: (y2-y1)/(x2-x1) * (x-x1) + y1 # Geradengleichung in 2-Punktform
y1 = lambda x:g2(2,9,4,9,x)

PS: Mir ist klar das es viele andere Lösungen gibt, z.B.: die Geradengleichung ein Tupel bestehend aus Gleichung und Werten ausgeben zu lassen
y1 = lambda x:(g2(2,9,4,9,x),2,9,4,9)
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@[-_-']: für diesen Fall gibt es functools.partial, das hat dann ein args-Argument:

Code: Alles auswählen

y1 = partial(g2, 2,9,4,9)
print y1.args
BlackJack

@[-_-']: Könntest Du das Problem eventuell auch mit ``def`` (``lambda`` macht hier keinen Sinn) und *eindeutigen* Namen und *einfacher*. Bei `y1` ist mir jetzt beispielsweise nicht klar wo Du das Argument von `g2()` meinst und wo die Funktion `y1` und was von beidem wo bei ``fneu(y1)`` verwendet werden soll. ``inspect`` verwenden zu wollen klingt IMHO nach verdächtig viel Magie.
[-_-']
User
Beiträge: 2
Registriert: Sonntag 18. Januar 2015, 14:43

Sirius3 hat geschrieben:@[-_-']: für diesen Fall gibt es functools.partial, das hat dann ein args-Argument:

Code: Alles auswählen

y1 = partial(g2, 2,9,4,9)
print y1.args

Vielen Dank Sirius3, genau das was ich gebraucht habe!
Wen es interessiert hier der Unsinn den ich damit verbrochen habe:
Ich will aktuell Strahlengänge an/durch optische Elemente zeichnen.
Dazu will ich beispielsweilse die Reflektion einer Geraden an einer anderen Geraden zeichnen und das wollte ich realisieren, in dem ich beim Aufruf der Spiegelgeradenberechnung die Argumente der beiden zu übergebenden Funktionen auslese.

Code: Alles auswählen

import numpy as np
import matplotlib.pyplot as plt
from functools import partial
from scipy.optimize import fsolve

# Geradengleichung in Zweipunktform
g2 = lambda x1,y1,x2,y2,x: ((y2-y1)/(x2-x1) * (x-x1) + y1 )

# Schnittpunktbestimmung
SP = lambda f1,f2: fsolve(lambda x: f1(x)[0]-f2(x)[0],0)

# Spiegelgeradenbestimmung
def SG(f1,sp):
    m = lambda f: (f.args[3]-f.args[1])/(f.args[2]-f.args[0])
    b = lambda m,f: -f.args[0]*m+f.args[1]
    orth = lambda x: -x/m(sp) +f1.args[1]+ f1.args[0]/m(sp)
    x1 = SP(sp,orth)
    y1 = orth(x1)
    x2 = 2*x1-f1.args[0]
    y2 = 2*y1-f1.args[1]
    x3 = SP(f1,sp)
    y3 = m(sp)*x3+b(m(sp),sp)
    x4 = 2*x3-x2 
    y4 = 2*y3-y2
    return x4,y4

fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111)
ax.grid()
ax.set_xticks(np.arange(0,21,1))
ax.set_yticks(np.arange(0,21,1))
ax.axis([-3,20,-3,20])

# Prisma plotten
xprim=[6,10,9,6]
yprim=[6,6,10,6]
ax.plot(xprim,yprim)

# Eingangsstrahl definieren
ye = partial(g2,2,9,4,9)

# Prismakante (seitens Eingangsstrahl) definieren
ype = partial(g2,xprim[0],yprim[0],xprim[2],yprim[2])

# Eingangsstrahl bis zum Prisma
ax.plot([2,SP(ype,ye)],[ye(2),ye(SP(ype,ye))])

# Am Prisma reflektierter Strahl
ax.plot([SP(ype,ye),SG(ye,ype)[0]],[ye(SP(ype,ye)),SG(ye,ype)[1]])

plt.show()
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@[-_-']: hier macht es allerdings solangsam Sinn, Klassen einzuführen. Denn außer planen Spiegeln will man ja in optischen Systemen auch gekrümmte Spiegel und Linsen haben. Dann braucht es auch keine Magie, Argumente von Funktionen herauszufinden, sondern man kann die Schnittpunktberechnung einfach einer Methode des optischen Elements übergeben.
Antworten