Berechnung Lagrange-Polynom mit geg. x-und y-Werten (2023)

Und was ist Deine bisherige Leistung außer den Aufgabentext einzuscannen?
Wir können hier gerne bei konkreten Fragen helfen, aber wir reagieren allergisch, wenn uns nur die Hausaufgaben hingeklatscht werden.

Zum Code an sich läßt sich sagen, dass Dein Lehrer dringend Python lernen sollte. Ein Module my_func_lib zu nennen ist aus mehreren Gründen schlecht. Dass es sich bei einem Modul um eine "Lib" handelt, ist offensichtlich, das in den Namen zu schreiben unsinnig, das Präfix my_ trägt nicht zum Verständnis bei, kann also auch weg, bleibt `func` was so generisch ist, dass es auch weg kann. Module sollten wie alles andere auch, nach dem benannt sein, was es enthält. Im Supermarkt steht ja auf der Packung auch Cornflakes oder Schokolade drauf, und nicht überall nur "Essen".

Datentypen sollten nicht in Variablen vorkommen, x_list ist also nur x und die Typannotation ist zwischen zu einschränkend und komplett falsch. Es wird numpy eingebunden, also liegt zumindest die Vermutung nahe, dass x auch ein numpy-Array sein könnte. `plot_me` plottet hoffentlich nicht mich, sondern ein Polynom, so dass der Name `plot_polynom` aussagekräftiger wäre.

Methoden mit _ sind nicht öffentlich, sollten also nicht außerhalb der Klasse direkt aufgerufen werden.

Klassen werden nach Konvention großgeschrieben, also `Polynom`, das ist hilfreich, weil es sich von der Schreibweise von der konkreten Polynom-Instanz, die man dann `polynom` (statt p) nennen könnte, unterscheidet.

Ein Polynom bekommt als Argument ein poly(nom)? Das ist so, wie wenn auf der Zutatenliste eines Kuchens "Kuchen" steht. Völlige unsinnig. Richtig wäre coefficients.
Die __repr__-Methode sollte einen String zurückgeben, der erkennen läßt, dass es sich um eine Polynom-Instanz handelt, hier wird aber die Repräsentation einer Liste zurückgegeben, damit läßt sich eine Liste in der Ausgabe nicht von einem Polynom unterscheiden. Die Funktion ist also falsch. Magische Funktionen (__str__) ruft man nicht direkt auf.
Bei den nächsten Methoden (eval, __add__, __mul__) fehlen plötzlich die Typannotationen, wenn schon Annotationen dann richtig (siehe oben) und vollständig.
Auch für Dich wäre es wichtig zu wissen, ob `eval´ nun nur für ein einzelnes x, eine Liste mit x-Werten oder einem numpy-Array funktionieren sollte.

Bei __mul__ werden wieder schlechte Variablennamen benutzt, warum gx und gy?
Über Indizes iteriert man nicht, wenn man es vermeiden kann. Es ist unsinnig, eine Leere Liste zu definieren und die in jedem Schleifendurchgang zu kopieren, statt einfach immer wieder eine neue leere Liste zu erzeugen.

Die isinstance-Prüfung auf int und float ist viel zu einschränkend, es gibt noch etliche weitere Klassen, die sich wie Zahlen verhalten.

In _cut wird sehr umständlich der kleinste Index != 0 ermittelt. Da das ja eher die Ausnahme ist, sollte man nicht alle Koeffizienten durchgehen müssen. Funktionen, die den internen Zustand ändern, sollten sich nicht selbst als Rückgabewert haben, das verwirrt nur, weil der Anwender denkt, er bekäme ein neues Objekt.
`_round` rundet nicht wirklich, und wenn man die Funktion schon so nennt, sollte man sie auch benutzen. continue sollte man vermeiden. Und hier stimmt zusätzlich noch die Typannotation des Rückgabewerts mit dem Rückgabewert überein.

Code: Alles auswählen

import matplotlib.pyplot as pltimport numpy as npfrom polynom import lagrange_polynom_interpolation, Polynomdef plot_polynom(x, y, polynom): # MUSS NOCH GESCHRIEBEN WERDEN! fig = plt.figure() plt.plot(x, y, "x") plt.plot(x_poly, y_poly, ":") plt.savefig("pic.png", dpi=fig.dpi) plt.show()def main(): # Beispiel um ein Polynom zu erstellen: pol = polynom([1,2]) x = [1, 2, 3] y = [3, 6, 0] polynom = lagrange_polynom_interpolation(x, y) print(polynom) polynom.make_numbers_nice(tol=1e-12) print(polynom) print(f"An der Stelle x = 2 ist der Wert des Polynoms p(x) = {p.eval(2)}") plot_polynom(x, y, polynom)if __name__ == "__main__": main()

Code: Alles auswählen

import numpy as npfrom itertools import countclass Polynom: """Eine Klasse um eine Polynom darzustellen und die Addition und Multiplikation mit anderen Polynomen oder Zahlen zu definieren. Polynome werden dabei als Liste mit absteigenden Grad gespeichert. Bsp.: x^2 -3x +2 <=> [1, -3, 2] 4x +5 <=> [4, 5] Polynome können nur Addiert und Multipliziert werden. Die Subtraktion und Division ist noch nicht Definiert. """ def __init__(self, coefficients): self._coefficients = coefficients def __repr__(self) -> str: """Damit die Klasse eine Vernüpgtige Darstellung hat, wenn ein Element dieser Klasse geprinted ( print(polynom([1,2])) ) wird. Wir nutzen die Darstellung der Listen in Python und benutzen den String der in dieser Klasse definiert ist. Returns: str: Den String der in der Klasse "List" definiert ist. """ return f"Polynom({self._coefficients!r})" def eval(self, x) -> float: # MUSS NOCH GESCHRIEBEN WERDEN! raise NotImplementedError def __add__(self, other): # MUSS NOCH GESCHRIEBEN WERDEN! raise NotImplementedError def __iadd__(self, other): """Wird benötigt um "+=" zu ermöglichen. Verweist am Ende auf die unter __add__ definierte Addition.""" return self + other def __mul__(self, other): """Funktion die definiert, was passiert wenn zwei Polynome multipliziert werden. Durch diese Funktionen kann der "*" benutzt werden um Polynome zu multiplizieren. Ein Polynom kann mit einem anderen Polynom oder einer anderen Zahl multipliziert werden. Bsp.: [1,2]*[1,3] = [1,5,6] 3 * [1,2] = [3,6] Args: other (polynom | float): Das was mit dem Polynom multipliziert werden soll Raises: TypeError: Wenn weder ein Float noch ein Polynom zur Multiplikation verwendet werden sollen, wird ein Fehler produziert. Returns: polynom: Ein neues Polynom """ if isinstance(other, polynom): grad = self.grad result = type(self)([0]) for i, c in enumerate(self._coefficients)): values = [c * d for d in other._coefficients] values.extend([0] * (grad - i)) result += type(self)(values) return result if isinstance(other, (int, float)): scaled_coefficients = [other * c for c in self._coefficients] return type(self)(scaled_coefficients) raise TypeError def __imul__(self, other): """Wird gebraucht um "*=" zu umzuschreiben. Verweist am Ende auf die definition der Multiplikation. Args: other (polynom | float): Das was mit dem Polynom multipliziert werden soll Returns: polynom: Ein neues Polynom """ return self * other def __eq__(self, other) -> bool: """Funktion die Benötigt wird um Gleichheit zwischen Polynomen zu bestimmen. Also das auf die Frage [1,2] == [1,2] mit True oder False geantwortet werden kann. Args: other (polynom): Anderes Polynom Returns: bool: Gibt zurück ob die beiden Polynome gleich sind (True) oder nicht (False). """ return self._coefficients == other._coefficients def _cut(self): """Bei der Addition kann es sein, dass sich führende Terme kürzen. Das Polynom kann mit dieser Funktion gekürzt werden. Bsp.: [1,2] + [-1, 4] = [0,6] In diesem Beispiel würde [0,6] das Polynom nach der Addition sein, mit self._cut() wird [0,6] zu [6]. Returns: polynom: gekürztes Polynom """ idx = 0 while self._coefficients[idx] == 0: idx += 1 self._coefficients = self._coefficients[idx:] def make_numbers_nice(self, tol: float = 1e-14): """Zahlen wie 0.00000000000002 und 1.999999999 sollen zu 0 bzw. 2 gerundet werden. Args: tol (float, optional): Einstellung für die Toleranz. Defaults to 1e-14. Returns: polynom: Neues Polynom bei dem die Zahle nahe 0 auf 0 gesetzt wurden. """ new_coefficients = [] for coefficient in self._coefficients: rounded_coefficient = round(c) if abs(rounded_coefficient - coefficient) <= tol: new_coefficients.append(rounded_coefficient) else: new_coefficients.append(coefficient) self._coefficients = new_coefficients self._cut() def full(self, variable: str = "x") -> str: """Für den Fall das jmd die Datstellung als Polynom präfeiert, der kann mit self.full eine Darstellung der Art: 2x**2 + 3x**1 - 4x**0 Das "x" kann dabei als optionale Variable übergeben werden. Wenn man f(y) haben will, sollte man self.full("y") eingeben. Args: variable (str, optional): Wer eine andere Variable als x möchte. Defaults to "x". Returns: str: String der via print ausgegeben werden kanns """ result = [] for power, coefficient in zip(count(self.grad, -1), self._coefficients): if not result: result.append(f"{coefficient:.4f}{variable}^{power}") else: sign = "+" if coefficient >= 0 else "-" result.append(f"{sign} {abs(coefficient):.4f}{variable}^{power}") return " ".join(result) @property def grad(self) -> int: """Gibt den Grad vom Polynom zurück. Dieser ist um ein kleiner als die Länge der gespeicherten Liste. Returns: int: Grad des Polynoms """ return len(self._poly) - 1def lagrange_polynom_interpolation( x: list[int | float], y: list[int | float]) -> polynom: # MUSS NOCH GESCHRIEBEN WERDEN! raise NotImplementedError()
Top Articles
Latest Posts
Article information

Author: Jamar Nader

Last Updated: 12/06/2023

Views: 6476

Rating: 4.4 / 5 (55 voted)

Reviews: 86% of readers found this page helpful

Author information

Name: Jamar Nader

Birthday: 1995-02-28

Address: Apt. 536 6162 Reichel Greens, Port Zackaryside, CT 22682-9804

Phone: +9958384818317

Job: IT Representative

Hobby: Scrapbooking, Hiking, Hunting, Kite flying, Blacksmithing, Video gaming, Foraging

Introduction: My name is Jamar Nader, I am a fine, shiny, colorful, bright, nice, perfect, curious person who loves writing and wants to share my knowledge and understanding with you.