2016-07-06 8 views
0

Meine App ermöglicht es dem Benutzer, einfache Python-Ausdrücke anzugeben, die als Funktionen einer bestimmten Variablen verwendet werden. Zum Beispiel könnte der Benutzer schreiben 'x**2 + 2*x + 4' und meine App würde das in eine Funktion von x, äquivalent zu lambda x: x**2 + 2*x + 4 zu analysieren. Ich weiß schon, wie dies zu tun mit:Wie analysiert man Python-Funktionen aus Strings mit einem beliebigen Variablennamen?

def _f(expression, template): 
    code = parser.expr(expression).compile() 
    return template(code) 

def function_x(expression): 
    return _f(expression, lambda code: lambda x: eval(code)) 

jedoch, dass nur eine Funktion Parser für x macht. Wenn ich eine andere Variable Arbeit machen wollen, würde ich mehr Parser definieren, wie:

def function_xy(expression): 
    return _f(expression, lambda code: lambda x, y: eval(code)) 

def function_n(expression): 
    return _f(expression, lambda code: lambda n: eval(code)) 

def function_A(expression): 
    return _f(expression, lambda code: lambda A: eval(code)) 

Gibt es eine bessere Art und Weise Benutzerfunktionen von jede vorgegebene Variable zu analysieren? Das heißt, ich kann ein bestimmtes Eingabefeld in der UI vordefinieren, um Funktionen von u zu akzeptieren, während ein anderes Eingabefeld zum Akzeptieren von Funktionen von v und so weiter vordefiniert wird. Nur der Buchstabe u würde im ersten Eingabefeld funktionieren, während nur der Buchstabe v im zweiten Eingabefeld funktionieren würde.

Bitte beachten Sie, dass die Variablennamen selbst vordefiniert sind; Der Benutzer wählt nicht aus, welche Buchstaben er verwenden möchte.

+1

Ist das nur für Spaß/Bildung? Weil sympy ziemlich mächtig ist –

+0

Ich erstelle ein parametrisches Funktionsplotter-Modul für meine [Satz-App] (https://github.com/kelvin13/Knockout), [Bild] (http://www.pasteall.org/pic/ show.php? id = 104850). Einige andere Teile der App verwenden ebenfalls das gleiche Benutzerfunktions-Framework, aber die Menge der möglichen variablen Buchstaben ist ziemlich klein, so dass der Ansatz, den ich oben hatte, gut funktioniert hat. Ich weiß, dass SymPy solche Sachen gut machen kann, aber SymPy fühlt sich an wie ein furchtbar großer Hammer, den ich benutzen kann, wenn ich nur ein paar extra variable Namen brauche. –

Antwort

1

Verwenden Sie das lambdify module from Sympy, full docs here

Das Paket hat mehrere Möglichkeiten, dieses Problem zu adressieren, da es voll symbolisches Rechnen auf einem leistungsfähigen Ebene unterstützen (zB 1, 2, 3)

Zum Beispiel

Je nachdem, wie Sie das Paket verwenden möchten, können Sie es auf einer Core-Ebene für einen modularen Entwurf oder Sub in Ausdrücken bei th anwenden Der letzte Moment. Der ursprüngliche Link zeigt, wie man von sympy zu generischen Python-Lambda-Funktionen in einer Weise konvertiert

Sie sparen sich viel Zeit diese Route. Zum Beispiel, Sie sind "working" Code stürzt ab, wenn ich "sin(x)" eingeben, wo sympy es mit Leichtigkeit behandelt. Das war die erste, die ich ausprobiert habe - symbolische Berechnung ist wirklich schwierig. IMO, das Extra-Paket ist die großen Kopfschmerzen und Stunden auf dem Weg des Debuggens wert

+0

Um String-Parsing zu erhalten, würde ich das gesamte SymPy-Modul benötigen? Ich versuche, mehr externe Bibliotheken zu vermeiden, wenn sie nicht unbedingt benötigt werden. –

+0

Ja, würden Sie, zumindest ohne schmerzhafte Entwirrung der Bibliothek. Sie werden sowieso große Teile davon wieder umsetzen, warum nicht schon die sorgfältige und fachkundige Arbeit machen? Gibt es einen besonderen Grund, nicht mehr Bibliotheken einzubeziehen? Lizenzprobleme? –

+0

Wenn Sie die symbolitische Analyse erweitern, wird es nur noch schwieriger. Warum nicht die Expertenlösung von Grund auf verwenden? –