2014-01-12 20 views
6

Ich möchte String-Gleichungen (die gleich 0 sind) analysieren und dann lösen, indem ich ein Wörterbuch von Variablen verwende, auf die ich Zugriff habe.Verwenden von SymPy zum generischen Parsen und Lösen von Gleichungen

Zum Beispiel:

s = '(x/z)-y' 
eq = parse(s) 
eq.solve({'x': 10, 'y': 5}) 
print(eq) 
>>> {'z': 2} 

Nun hatte ich geschrieben Code, der vor einem Monat so etwas wie dies tat, aber ich kann einfach nicht finden. Ich erinnere mich jedoch, dass ich SymPy und seine sympify-Funktion zusammen mit seiner Solve-Funktion verwendet habe. Ich habe die Dokumentation zu diesen Funktionen überprüft, aber ich konnte mir nicht vorstellen, wie ich sie dazu bringe, so zu arbeiten, wie ich es möchte.

Und eine zusätzliche Frage: Wäre es möglich, die Variablen irgendwie zu wickeln, so dass ich etwas mehr als nur einen Buchstaben für sie verwenden könnte? Beispiel: Anstatt nur 'x' ich haben könnte '{myvar-42}'

EDIT:

Okay, ich schließlich gelang es, einige Code schreiben, der tat, was ich wollte:

eq = sympify('(x/y)-z', locals={'x': 10, 'z': 5}) 
solution = solve(eq, dict=True) 
print(solution) 
>>> [{'z': 2}] 

Aber meine "Extra" -Frage bleibt bestehen.

+0

' 'myvar-42'' - nur parse die Zeichenfolge. – aIKid

+0

@alKid Wie? Wenn ich sympify für eine Zeichenfolge verwende, die Klammern enthält, gibt es mir Fehler (weil es denkt, dass es ein Wörterbuch oder etwas ist). Ich habe jedoch eine Lösung gefunden: Ich könnte eine Regex-Ersetzung von allen {*} vornehmen und sie durch Buchstaben ersetzen. Nachdem die Lösung abgeschlossen ist, kann ich sie einfach mit einem von mir erstellten Wörterbuch zurückstellen. – fgblomqvist

Antwort

5

Wie Sie festgestellt haben, wandelt sympify Zeichenfolgen in SymPy-Ausdrücke um.

Um Ihre andere Frage zu beantworten, können Symbolnamen alles sein, aber sympify analysiert nur gültige Python-IDs zu Symbolnamen. Aber Sie können tun

>>> Symbol('{myvar-42}') + 1 
{myvar-42} + 1 

Und beachten Sie, dass gültige Python Idenfifiers müssen nicht einzelne Buchstaben sein. Sie können eine beliebige Kombination aus Buchstaben, Zahlen und Unterstrichen sein, die nicht mit einer Zahl beginnt, wie x_2 oder abc123.

Wenn Sie noch brauchen, um String-Parsing tun will aber nicht gültigen Python Bezeichner als Symbolnamen, wahrscheinlich der sauberste Weg wäre normal Namen zu verwenden und ersetzen sie für andere, die in, wie

>>> expr = sympify('x + 1') 
>>> expr.subs(Symbol('x'), Symbol('{myvar-42}') 
{myvar-42} + 1 

Schließlich die Symbole mit Buchstaben zu ersetzen, können Sie die locals Argument verwenden, um sympify, wie Sie getan haben, oder, wenn Sie sie später ersetzen möchten, verwenden Sie subs:

>>> x, y, z = symbols('x y z') 
>>> expr = sympify('x/z - y') 
>>> expr.subs({x: 10, y: 5}) 
10/z - 5 
+0

Das war genau das, was ich gesucht habe, danke! – fgblomqvist

+0

Wie funktioniert das mit Auto_symbol? – denfromufa

+0

Ich glaube, es fängt NameErrors und wiederholt den Ausdruck mit den undefinierten Namen definiert als Symbole. – asmeurer

Verwandte Themen