Hallo zusammen,
für die Uni steht bei mir diesen Semester eine Einführung in Python an. Aufgrund der Corona-Situation ist allerdings der komplette Kurs in Eigenregie online zu erledigen. Das klappt soweit auch ganz gut mit den bereitgestellten Unterlagen, allerdings hänge ich jetzt seit Stunden an einer Aufgabe und befürchte, ich sehe den Wald vor lauter Bäumen einfach nicht. Nachfragen beim Dozenten sind auch schwierig, deswegen hoffe ich darauf, dass ihr mir vielleicht auf den Sprung helfen mögt, denn im Internet habe ich auch nichts gefunden, was mir weiterhilft.
Es geht darum, eine Klasse zu schreiben, die ein Polynom beschreibt. Zusätzlich soll es Methoden geben, die dieses Polynom an einer Stelle x auswerten und eine weitere, die die Ableitung bildet. Die Ableitung soll dabei ebenfalls wieder ein Polynom sein. Die Auswertung an Stelle x funktioniert. Problematisch ist die Ableitung, also die untere Methode. Offenbar funktioniert die Funktion an sich schon (zumindest gibt sie die richtigen Koeffizienten aus). Wenn ich allerdings dann versuche, die erhaltene Ableitung an einer Stelle x auszuwerten (müsste ja gehen, wenn sie ebenfalls ein Polynom ist), bekomme ich folgenden Fehler: "can't multiply sequence by non-int of type 'float'"
Daran verzweifle ich seit Stunden. Hat jemand einen Tipp für mich?
class Polynom:
"""Erstellen der Polynome mit Koeffizienten koeff, Eingabe in der Form ko_1*x**n, ko_2*x**(n-1), ..."""
def __init__(self, *koeff):
"""Speichern der eingegebenen Parameter als Liste"""
self.koeff = list(koeff)
def eval(self, x):
"""Auswertung des Polynoms an der Stelle x, Rueckgabewert y"""
y = 0
for i in range(len(self.koeff)):
y+=(self.koeff*x**(len(self.koeff)-i-1))
return(y)
def derivative(self):
"""Bilden einer Ableitung"""
diff = []
for i in range(len(self.koeff)-1):
diff.append((len(self.koeff)-(i+1))*self.koeff)
print(diff)
deriv = Polynom(diff)
return(deriv)
Erstellen einer Polynomklasse / Methode f. Ableitung
Code: Alles auswählen
y = 0
for i in range(len(self.koeff)):
y+=(self.koeff*x**(len(self.koeff)-i-1))
Code: Alles auswählen
y = 0
for i in range(len(self.koeff)):
y+=(self.koeff[i]*x**(len(self.koeff)-i-1))
Code: Alles auswählen
y = 0
for i,koeff in enumerate(self.koeff):
y+=(koeff*x**(len(self.koeff)-i-1))
Das ist ein "For Each" Loop über eine Liste. Gucke dir dazu gerne mal etwas an.
Ansonsten macht es natürlich Sinn den Grad der Funktion als Variable auszudrücken und den Code wie folgt zu formulieren:
Code: Alles auswählen
y = 0
deg = len(self.koeff)
for i,koeff in enumerate(self.koeff):
y+=(koeff*x**(deg-i-1))
Und wenn du richtig gut bist, gucke dir gerne mal die List Komprehentions in Python an:
Code: Alles auswählen
y = 0
deg = len(self.koeff)
value_list = [koeff*x**(deg-i-1) for i,x in self.koeff]
for value in value_list:
y += value
Code: Alles auswählen
deg = len(self.koeff)
y = sum([koeff*x**(deg-i-1) for i,x in self.koeff])
- __blackjack__
- User
- Beiträge: 14012
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Mitch_92: Zu einer Fehlerbeschreibung gehört auch der Code der den behaupteten Fehler auslöst. Ich bekomme den nämlich nicht. Dafür einen anderen.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
@Freumel: der Index war schon richtig, nur das [ i ] wird ohne Code-Tags als Kursiv interpretiert.
Richtig Cool ist es, Polynome mit Hilfe des Horner-Schemas zu berechnen, dazu werden die Koeffizienten ja schon in der richtigen Reihenfolge übergeben, nämlich beginnend mit dem der größten Potenz. Bitte benutze keine Abkürzungen, wenn Du Koeffizienten meinst, dann schreib die auch aus, oder besser gleich auf Englisch, da ja alles andere auch englisch ist.
`return` ist keine Funktion, also gehören da auch keine unnötigen Klammern hin.
Bei solchen Klassen wird oft __call__ überschrieben, dann verhält sich eine Instanz wie eine Funktion und kann aufgerufen werden.
@Mitch_92: hast Du mal das was Du bei Polynom als Argumente übergibst mit dem verglichen, was beim Erzeugen innerhalb von `derivate` verwendet wird? Einfach mal in __init__ coefficients per print ausgeben und schauen, was der Unterschied ist.
Richtig Cool ist es, Polynome mit Hilfe des Horner-Schemas zu berechnen, dazu werden die Koeffizienten ja schon in der richtigen Reihenfolge übergeben, nämlich beginnend mit dem der größten Potenz. Bitte benutze keine Abkürzungen, wenn Du Koeffizienten meinst, dann schreib die auch aus, oder besser gleich auf Englisch, da ja alles andere auch englisch ist.
`return` ist keine Funktion, also gehören da auch keine unnötigen Klammern hin.
Code: Alles auswählen
class Polynom:
"""Erstellen der Polynome mit Koeffizienten koeff, Eingabe in der Form ko_1*x**n, ko_2*x**(n-1), ..."""
def __init__(self, *coefficients):
"""Speichern der eingegebenen Parameter als Liste"""
self.coefficients = coefficients
def eval(self, x):
"""Auswertung des Polynoms an der Stelle x, Rueckgabewert y"""
y = 0
for coefficient in coefficients
y = y * x + coefficient
return y
__call__ == eval
def derivative(self):
"""Bilden einer Ableitung"""
new_coefficients = []
for power, coefficient in reversed(enumerate(reversed(self.coefficients[:-1]), 1)):
new_coefficients .append(power * coefficient)
return Polynom(new_coefficients)
@Mitch_92: hast Du mal das was Du bei Polynom als Argumente übergibst mit dem verglichen, was beim Erzeugen innerhalb von `derivate` verwendet wird? Einfach mal in __init__ coefficients per print ausgeben und schauen, was der Unterschied ist.
- __blackjack__
- User
- Beiträge: 14012
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Mitch_92: Anmerkungen zum Code: Mit beliebigen Positionsargumenten sollte man sparsam umgehen. Statt die Koeffizienten als einzelne Argumente an die `Polynom.__init__()` zu übergeben sollte man da schon eine Liste (oder generell etwas iterierbares) als *ein* Argument übergeben. Genau dieser magische Kram ist nämlich Dein Problem, denn da brauchst Du dann auch beim Aufruf die Magie.
Namen sollten nicht kryptisch abgekürzt werden. Wenn man `koeffizienten` meint, sollte man nicht nur `koeff` schreiben. Und man sollte sich für Deutsch oder Englisch entscheiden und kein Denglisch.
Das die eingegebenen Parameter als Liste gespeichert werden ist ein Implementierugsdetail, das hat nichts im Docstring zu suchen. Ebensowenig das beim Auswerten der lokale Name `y` lautet.
``for i in range(len(sequence)):`` ist ein „anti pattern“ in Python. Man kann in Python *direkt* über die Elemente von Sequenztypen wie Listen iterieren. Falls man *zusätzlich* einen laufenden Wert braucht, gibt es die `enumerate()`-Funktion.
In diesem Falle wäre `exponent` auch ein passendere Name für `i`.
Ungetestet:
Namen sollten nicht kryptisch abgekürzt werden. Wenn man `koeffizienten` meint, sollte man nicht nur `koeff` schreiben. Und man sollte sich für Deutsch oder Englisch entscheiden und kein Denglisch.
Das die eingegebenen Parameter als Liste gespeichert werden ist ein Implementierugsdetail, das hat nichts im Docstring zu suchen. Ebensowenig das beim Auswerten der lokale Name `y` lautet.
``for i in range(len(sequence)):`` ist ein „anti pattern“ in Python. Man kann in Python *direkt* über die Elemente von Sequenztypen wie Listen iterieren. Falls man *zusätzlich* einen laufenden Wert braucht, gibt es die `enumerate()`-Funktion.
In diesem Falle wäre `exponent` auch ein passendere Name für `i`.
Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
class Polynom:
"""
Erstellen der Polynome mit Koeffizienten coefficients, in der Form
ko_1*x**n, ko_2*x**(n-1), ...
"""
def __init__(self, coefficients):
self.coefficients = list(coefficients)
def __repr__(self):
return f"{self.__class__.__name__}({self.coefficients!r})"
def __call__(self, x):
"""
Wertet Polynom an Stelle `x` aus.
"""
return sum(
coefficient * x ** exponent
for exponent, coefficient in enumerate(reversed(self.coefficients))
)
def derivative(self):
"""
Bildet die Ableitung.
"""
return Polynom(
[
coefficient * exponent
for coefficient, exponent in zip(
self.coefficients[:-1],
reversed(range(len(self.coefficients))),
)
]
)
def main():
polynom = Polynom([5, 8, 7, 5, 3, 9])
print(polynom)
print(polynom.derivative())
print(polynom(23))
print(polynom.derivative()(42))
if __name__ == "__main__":
main()
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Wow, das ging ja mal schnell!
Mein Ursprungsproblem scheint wohl tatsächlich eher am Aufruf zu liegen, denn meine oben vorgestellte Lösung wurde vom Dozenten inzwischen als richtig bewertet...
Dennoch werde ich natürlich mal schauen, dass ich das ganze mit Hilfe eurer Antworten noch besser und schöner gestalten kann.
Danke euch vielmals, für mich als absoluten Anfänger (nicht nur in Python, sondern allgemein im Programmieren) ist sowas echt Gold wert =)
Mein Ursprungsproblem scheint wohl tatsächlich eher am Aufruf zu liegen, denn meine oben vorgestellte Lösung wurde vom Dozenten inzwischen als richtig bewertet...
Dennoch werde ich natürlich mal schauen, dass ich das ganze mit Hilfe eurer Antworten noch besser und schöner gestalten kann.
Danke euch vielmals, für mich als absoluten Anfänger (nicht nur in Python, sondern allgemein im Programmieren) ist sowas echt Gold wert =)