Bildung der Standardform einer Polynomfunktion

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
ixfighter
User
Beiträge: 1
Registriert: Dienstag 12. Februar 2019, 12:20

Hallo Community,
ich habe es schon kräfteringend versucht, aber finde für mein Problem einfach keine Lösung.

Ich möchte dass der mir der Benutzer über die input Funktion den Grad des Polynoms als int. sagt
und ich dann daraus erstmal die Standardforme bastle, um später mit symypy weiterrechnen zu können.
(Beispiel Grad:3 --> a*x**3 + b*x**2 + c*x**1 + d)

Bislang habe ich es schon geschafft Listen der benötigten Parameter zu erstellen, aber jetzt weiß ich nicht wie man diese Listen zu dieser gewünschten Standardform zusammenfügt.
Mein Quelltext bislang:
a,b,c,d,e,f,g,h,i,j,k,l = symbols('a,b,c,d,e,f,g,h,i,j,k,l')
m,n,o,p,q,r,s,t,u,v,w,x,y,z = symbols('m,n,o,p,q,r,s,t,u,v,w,x,y,z')


Exponenten = []
Buchstaben = []
X = []


Alphabet = [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z]

Grad = int(input("Hallo,\n"
"dieses Programm berechnet Ihnen Nullstellen, Extrempunkte,\n"
"sowie Wendepunkte einer von ihnen gewählten\n"
"Polynomfunktion.\n"
"Als erstes geben Sie bitte den höchsten Exponenten ihrer\n"
"Polynomfunktion (Grad der Funktion) an: "))

Grad = Grad +1
while Grad > 1:
Grad = Grad -1
Exponenten.append(Grad)

for E in range(0,len(Exponenten)+1,1):
Buchstaben.append(Alphabet[E])

for E in Exponenten:
X.append(x)

print(Buchstaben)
print(X)
print(Exponenten)
Vielleicht gibt es auch eine viel primitivere Lösung, bin für jede Hilfe. Dankeschön :-)
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Polynome kann man z.B. so erzeugen:

Code: Alles auswählen

>>> sympy.polys.Poly.from_list([7,6,5], sympy.Symbol('x'))
Poly(7*x**2 + 6*x + 5, x, domain='ZZ')
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ixfighter: Anmerkungen zum Quelltext:

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausgenommen Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).

Variablen sollte man dort definieren wo sie gebraucht werden und nicht alle zusammen irgendwo am Anfang. Das macht den Code unübersichtlicher und schwerer wartbar, weil man dann eventuell erst suchen muss um zu sehen wie etwas definiert wurde. Zudem ist es umständlicher Codeabschnitte in eigene Funktionen auszulagern wenn man sich den Code dazu zusammen suchen muss. Das ist zudem oft der Grund warum nach Codeänderungen unbenutze Variablen im Code bleiben, weil man nicht daran denkt auch die Definition weiter oben im Code zu löschen. Zum Beispiel wenn man eine Schleife in eine „list comprehension“ ändert, und irgendwo im Code dann eine unsinnige Zuweisung einer leeren Liste stehen bleibt.

Die Schleife für `exponenten` lässt sich als Einzeiler mit `range()`, `reversed()`, und `list()` schreiben:

Code: Alles auswählen

    exponenten = []
    while grad > 1:
        grad = grad - 1
        exponenten.append(grad) 

    # ->

    exponenten = list(reversed(range(1, grad)))
Die ganzen Einzelbuchstaben von `a` bis `z` mehrfach von Hand in den Quelltext zu schreiben ist mühsam und fehleranfällig. Man kann das bei `symbols()` auch viel einfacher schreiben und im Code braucht man weder die einzelnen Namen, noch das ”umpacken” von einem Tupel in eine Liste. Damit wird auch `alphabet` zu einem Einzeiler:

Code: Alles auswählen

    (
        a, b, c, d, e, f, g, h, i, j, k, l, m,
        n, o, p, q, r, s, t, u, v, w, x, y, z
    ) = symbols('a b c d e f g h i j k l m n o p q r s t u v w x y z')
    alphabet = [
        a, b, c, d, e, f, g, h, i, j, k, l, m,
        n, o, p, q, r, s, t, u, v, w, x, y, z
    ]
    
    # ->
    
    alphabet = symbols('a:z')
Allerdings ist da ja `x` enthalten und das möchtest Du ja als Variable des Polynoms verwenden und nicht als Variable für Faktoren. Also sollte man das aus dem `alphabet` heraus lassen:

Code: Alles auswählen

    alphabet = symbols('a:w y:z')
Bei `range()` ist der Anfang 0 und die Schrittweite 1 die Voreinstellung. Das braucht man nicht anzugeben.

`e` ist kein guter Name für eine ganze Zahl als Laufindex. Einbuchstabige Namen an sich sind in der Regel schon keine gute Idee ausserhalb *sehr* begrenzter Sichtbarkeitsbereiche („comprehensions“, ``lambda``-Ausdrücke, …). Ganze Zahlen aus Laufindex bilden da eine Ausnahme, allerdings sind die Namen da dann traditionell `i`, `j`, und `k`, wie in der Mathematik.

Aber auch die Schleife für `buchstaben` lässt sich in einer Zeile ausdrücken:

Code: Alles auswählen

    buchstaben = []
    for i in range(len(exponenten) + 1):
        buchstaben.append(alphabet[i])
    
    # ->
    
    buchstaben = alphabet[:len(exponenten) + 1]
`buchstaben` ist kein so wirklich passender Name. Treffender wäre vielleicht `faktoren`.

Was `X` sein oder werden soll habe ich nicht verstanden. Da versuchst Du ein nicht vorhandenes `x` mehrfach in eine Liste `X` zu stecken‽ An der Stelle würde das Programm mit einem `NameError` abbrechen weil es `x` nicht gibt.

Wenn man den Code jetzt mit der Antwort von Sirius3 kombiniert, fehlt noch das erstellen eines `Poly`-Objekts:

Code: Alles auswählen

    exponenten = list(reversed(range(1, grad)))
    alphabet = symbols('a:w y:z')
    faktoren = alphabet[:len(exponenten) + 1]
    polynom = Poly.from_list(faktoren, Symbol('x'))
    print(faktoren)
    print(exponenten)
    print(polynom)
Allerdings sieht man hier nun, das `exponenten` gar nicht tatsächlich benötigt wird, weil davon eigentlich nur die Länge verwendet wird, und die hängt von `grad` ab. Also bleibt insgesamt das hier übrig:

Code: Alles auswählen

#!/usr/bin/env python3
from sympy import Poly, Symbol, symbols


def main():
    variables = symbols('a:w y:z')
    grad = int(
        input(
            'Hallo,\n'
            'dieses Programm berechnet Ihnen Nullstellen, Extrempunkte,\n'
            'sowie Wendepunkte einer von ihnen gewählten\n'
            'Polynomfunktion.\n'
            'Als erstes geben Sie bitte den höchsten Exponenten ihrer\n'
            'Polynomfunktion (Grad der Funktion) an: '
        )
    )
    if grad > len(variables):
        raise ValueError(
            f'Grad ({grad}) grösser als Menge der Variablen ({len(variables)})'
        )
    
    polynom = Poly.from_list(variables[:grad], Symbol('x'))
    print(polynom)


if __name__ == '__main__':
    main()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten