@JETMAN: Da fehlen ein Importe damit der Code funktioniert. Ich vermute mal `Matrix` soll aus `sympy` kommen? Und `identity()` aus `numpy`?
In der Funktion wird bei `eval()` ein `T` verwendet was nirgends definiert ist. `eval()` ist sowieso eine blöde Idee. Insbesondere wenn man sowieso schon `sympy` hat und sich damit dynamisch einen Ausdruck aufbauen kann. Da `poly` sowieso nicht verwendet wird in Deinem Test, habe ich das jetzt erst einmal einfach rausgeworfen.
Um Gleichheitszeichen in Argumentlisten werden normalerweise keine Leerzeichen gesetzt.
Man kann auf der linken Seite einer Zuweisung tatsächlich eine Liste mit Namen schreiben, das macht aber niemand. Da steht normalerweise ein Tupel und meistens auch ohne irgendwelche Klammern, solange das nicht auf mehr als eine Zeile aufgeteilt werden muss.
Namen werden klein_mit_unterstrichen geschrieben, ausser Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase). Kryptische Abkürzungen sind doof. Das soll man lesen und verstehen können ohne das man Rätselraten muss. `li_len`? Klingt nach einem asiatischen Namen.
Der Name ist aber sowieso unnötig, genau wie das `i`, denn man kann auch direkt über die Elemente von `JCells` iterieren, ohne den Umweg über einen Index.
Der Wert von `z` muss nicht an einen Namen gebunden werden, denn an der einzigen Stelle wo das ausser beim ``if`` noch verwendet wird, hat es *immer* den Wert `True`, sonst wäre der Programmablauf ja nicht in den ``if``-Zweig gegangen.
``list(jc.keys())[0]`` liefert einen beliebigen Schlüssel aus `jc` – ist das gewollt? Was ist mit den anderen Schlüsseln? Das sieht mir extrem nach einem Programmierfehler aus.
Anstelle der ganzen `get()`-Aufrufe würde man einen Index/Schlüsselzugriff machen, denn es ist ja bei jedem der Zugriffe garantiert dass es den Schlüssel gibt, womit `get()` keinen Sinn macht.
Zumindest im innersten ``if`` kann man die umschliessende Schleife abbrechen, denn eine weitere Abarbeitung kann am Zustand/Ergebnis nichts mehr ändern.
Vor der zweiten Schleife in der Funktion macht es keinen Sinn `tm` an einen Wert zu binden, der dann nirgends verwendet wird.
Die Schleife kann auch gleich über `ews.items()` gehen, denn man braucht im Schleifenkörper grundsätzlich Schlüssel *und* Wert.
Das wiederholte ”erweitern” einer Zeichenkette mit ``+`` ist ineffizient. Man sammelt deshalb die Teilzeichenketten in einer Liste und setzt sie dann am Ende mit der `str.join()`-Methode zusammen. Hier kann man als Trennzeichen dann die Multiplikation wählen. Das macht den Code auch einfacher, weil man am Anfang nicht mehr den Sonderfall hat bei dem Kein ' * ' hinzugefügt werden muss.
`var` ist bereits eine Zeichenkette. Da macht es keinen Sinn noch einmal `str()` mit aufzurufen. Überhaupt ist das Zusammenstückeln von Zeichenketten und Werten mit ``+`` und `str()` nicht wirklich Python sondern eher BASIC. In Python gibt es dafür Zeichenkettenformatierung.
Code: Alles auswählen
def minipoly(matrix, var='T'):
_, jordan_cells = matrix.jordan_cells()
ews = dict()
for cell in jordan_cells:
eigenvals = cell.eigenvals()
gefunden = False
m = list(eigenvals.keys())[0]
for k in ews:
if k == m:
gefunden = True
if ews[k] < eigenvals[k]:
ews.update(eigenvals)
print(True, k, ews[k], eigenvals[k])
break
if not gefunden:
ews.update(eigenvals)
poly_pur = list()
for k, value in ews.items():
if k == 0:
tm = ''
else:
tm = '{}{}'.format('-' if k > 0 else '+', abs(k))
poly_pur.append('({}{}*Id)**{}'.format(var, tm, value))
return ' * '.join(poly_pur)
Aber wie gesagt möchte man eher nicht evil `eval()` verwenden, insbesondere wenn man in der letzten Schleife stattdessen eine Sympy-Objekt erstellen kann (`add` und `sub` aus dem `operator`-Modul):
Code: Alles auswählen
T, Id = symbols('T Id')
terms = list()
for k, value in ews.items():
terms.append((add if k < 0 else sub)(T, k * Id)**value)
return Mul(*terms)