Hallo Leute,
ich bin auf der Suche nach jemanden der mir den im Anhang beiliegenden Code "übersetzen" könnte.
Biete 15€ per Paypal.
Damit meine ich Stichpunkthaltig was passiert in Zeile xy, was macht dieser Operator etc.
z.B rechts daneben am Rand
Es geht hierbei um eine Iterationsmethode mit dem Trapez und dem Simpsonverfahren.
Diese sollen am Ende gegenübergestellt werden und das Konvergenzverhalten soll dokumentiert werden.
Ziel ist es das der Leser neben den Quellcode eine Übersetzung daneben liegen hat, bei der er nachvollziehen kann was dort genau geschieht und programmiert wird!
Die Screenshots hab ich in einen Dropbox Ordner gepackt
https://1drv.ms/u/s!Av3mnwAi2mF0kyJnAFmR65sThvoU?e=ePGOvP
https://1drv.ms/u/s!Av3mnwAi2mF0kyJnAFm ... U?e=ePGOvP
Vielen Dank
Suche Quellcode Übersetzung
- __blackjack__
- User
- Beiträge: 13113
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@rectosh99: Wenn Du Quelltext zeigen möchtest, dann bitte als Text hier in einem Beitrag, nicht als Bilder vom Editor bei einem externen Cloud-Hoster.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
@__blackjack__
Verzeihung!
import numpy as np
import pylab as pl
#--------------------------------------------
def fu(x):
#--------------------------------------------
#return np.exp(-x**2)
return np.sin(x)/(x+1)+0.2
#return 2*x**2-x+1 # hier liefert Sipson den korr Wert!!
#--------------------------------------------
def IntTrapez(a, b, n):
#--------------------------------------------
sr = []
X = []
Y = []
X.append(a)
Y.append(fu(a))
dx = (b-a)/n
s = (fu(a) + fu(b))/2
xi=a
for i in range(2,n+1,1):
xi += dx
s += fu(xi)
cs = " Trapez: i=%2d x=%6.2f f(x)=%6.2f summe=%8.5f" % (i, xi, fu(xi), s*dx)
X.append(xi)
Y.append(fu(xi))
sr.append(cs)
s *= dx
X.append(b)
Y.append(fu(b))
return (s, sr, X, Y)
#--------------------------------------------
def IntSimpson(a, b, n):
#--------------------------------------------
sr = []
if (n % 2 != 0):
sr.append("Simpson: n muss gerade sein.")
return (0, sr)
dx = (b - a) / n
s = fu(a) + fu(b)
xi = a
for i in range(1,n,1):
xi = xi + dx
if (i % 2 == 0 ):
s += 2 * fu(xi)
else:
s += 4 * fu(xi)
cs = " Simpson: i=%2d x=%6.2f f(x)=%6.2f summe=%8.5f" % (i, xi, fu(xi), s*dx/3)
sr.append(cs)
return (s*dx/3 , sr)
#--------------------------------------------
def IntGauss3(a, b):
#--------------------------------------------
sr = []
xsi =[-0.774596669241483, 0, 0.774596669241483]
alpha =[0.555555555555556, 0.888888888888889, 0.555555555555556]
s = 0
for i in range(0,3,1):
xi = (a + b) / 2 + xsi * (b - a) / 2
Wi = alpha * (b - a) / 2
s += Wi * fu(xi)
cs = " Gauss3: i=%2d xi=%6.4f Wi=%6.4f f(xi)= %6.2f summe=%8.5f" % (i, xi, Wi, fu(xi), s)
sr.append(cs)
return (s, sr)
#--------------------------------------------
def SubsequCallToAllMethods(a,b,n):
#--------------------------------------------
# unsere Ergebnisse:
(sTr,srT,Xi,Yi) = IntTrapez(a, b, n)
(sSi,srS) = IntSimpson(a, b, n)
(sGs,srG) = IntGauss3(a, b)
print("Trapez =", sTr)
for c in srT :
print(c)
print("Simpson =", sSi)
for c in srS :
print(c)
print("Gauss3 =", sGs)
for c in srG :
print(c)
# Plot:
X = np.linspace(a,b,100)
Y = fu(X)
ax=pl.gca()
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
clabel =("f(x)")
pl.plot( X, Y, 'b', label=clabel)
clabel =("Trapez = %8.6f") % (sTr)
pl.plot( Xi, Yi, 'g', label=clabel)
#pl.scatter(X, Y)
pl.xlabel("x")
pl.ylabel("f(x)")
pl.legend ()
pl.show()
#--------------------------------------------
def Konvergenztester(a,b):
#--------------------------------------------
results_n1 =[]
results_n2 =[]
results_Trapez = []
results_Simpson = []
err_Trapez = []
err_Simpson = []
quitAtRoudOffErrPerc = 0.005
(errp1, errp2) = (1e100,1e100)
happy = False
iTest1, iTest2 = 0,0
for n in range(4,1000,2):
(intTrapez,srT,Xi,Yi) = IntTrapez(a, b, n)
(intSimpson,srS) = IntSimpson(a, b, n)
if(len(results_Trapez) > 0 and len(results_Simpson) > 0):
errp1 = abs((results_Trapez[-1] - intTrapez)/intTrapez) * 100
errp2 = abs((results_Simpson[-1] - intSimpson)/intSimpson) * 100
if(errp1 > quitAtRoudOffErrPerc or len(results_n1) == 0):
iTest1 += 1
results_n1.append(n)
err_Trapez.append(errp1)
if(errp2 > quitAtRoudOffErrPerc or len(results_n2) == 0):
iTest2 += 1
results_n2.append(n)
err_Simpson.append(errp2)
results_Trapez.append(intTrapez)
results_Simpson.append(intSimpson)
if(errp1 <= quitAtRoudOffErrPerc and errp2 <= quitAtRoudOffErrPerc):
happy = True
break
if(not happy):
print("Keine Konvergenz nach", n , "Schritten")
clabel = "Trapezregel %s intervals, err=%6.2f %% after %d steps" % (results_n1[-1],err_Trapez[-1],iTest1)
pl.plot( results_n1, err_Trapez, 'b', label="%s" % clabel)
clabel = "Simpson %s intervals, err=%6.2f %% after %d steps" % (results_n2[-1],err_Simpson[-1],iTest2)
pl.plot( results_n2, err_Simpson, 'g', label="%s" % clabel)
pl.xlabel(r'$intervals$')
pl.ylabel(r'$est. err. [\%] $')
pl.legend ()
pl.show()
#--------------------------------------------
def main():
#--------------------------------------------
# Eingabe:
inpStr = input("Integrationsformeln\nGib a= b= n= (mit , getrennt)")
nSeps = inpStr.count(',')
if (nSeps != 2):
print("error: you have to define a,b,n separated by exactly two commas such as 0,1,10")
return False
(a,b,n) = inpStr.split(",")
if (a.isnumeric() == False or b.isnumeric() == False or n.isnumeric() == False):
print("error: a,b,n have to be numbers")
return False
(a,b,n) = [float(a), float(b), int(n)]
print("a=",a,"b=",b,"n=",n)
SubsequCallToAllMethods(a,b,n)
Konvergenztester(a,b)
#input("...press any key to continue")
#--------------------------------------------
#--------------------------------------------
if __name__ == "__main__":
main()
Verzeihung!
import numpy as np
import pylab as pl
#--------------------------------------------
def fu(x):
#--------------------------------------------
#return np.exp(-x**2)
return np.sin(x)/(x+1)+0.2
#return 2*x**2-x+1 # hier liefert Sipson den korr Wert!!
#--------------------------------------------
def IntTrapez(a, b, n):
#--------------------------------------------
sr = []
X = []
Y = []
X.append(a)
Y.append(fu(a))
dx = (b-a)/n
s = (fu(a) + fu(b))/2
xi=a
for i in range(2,n+1,1):
xi += dx
s += fu(xi)
cs = " Trapez: i=%2d x=%6.2f f(x)=%6.2f summe=%8.5f" % (i, xi, fu(xi), s*dx)
X.append(xi)
Y.append(fu(xi))
sr.append(cs)
s *= dx
X.append(b)
Y.append(fu(b))
return (s, sr, X, Y)
#--------------------------------------------
def IntSimpson(a, b, n):
#--------------------------------------------
sr = []
if (n % 2 != 0):
sr.append("Simpson: n muss gerade sein.")
return (0, sr)
dx = (b - a) / n
s = fu(a) + fu(b)
xi = a
for i in range(1,n,1):
xi = xi + dx
if (i % 2 == 0 ):
s += 2 * fu(xi)
else:
s += 4 * fu(xi)
cs = " Simpson: i=%2d x=%6.2f f(x)=%6.2f summe=%8.5f" % (i, xi, fu(xi), s*dx/3)
sr.append(cs)
return (s*dx/3 , sr)
#--------------------------------------------
def IntGauss3(a, b):
#--------------------------------------------
sr = []
xsi =[-0.774596669241483, 0, 0.774596669241483]
alpha =[0.555555555555556, 0.888888888888889, 0.555555555555556]
s = 0
for i in range(0,3,1):
xi = (a + b) / 2 + xsi * (b - a) / 2
Wi = alpha * (b - a) / 2
s += Wi * fu(xi)
cs = " Gauss3: i=%2d xi=%6.4f Wi=%6.4f f(xi)= %6.2f summe=%8.5f" % (i, xi, Wi, fu(xi), s)
sr.append(cs)
return (s, sr)
#--------------------------------------------
def SubsequCallToAllMethods(a,b,n):
#--------------------------------------------
# unsere Ergebnisse:
(sTr,srT,Xi,Yi) = IntTrapez(a, b, n)
(sSi,srS) = IntSimpson(a, b, n)
(sGs,srG) = IntGauss3(a, b)
print("Trapez =", sTr)
for c in srT :
print(c)
print("Simpson =", sSi)
for c in srS :
print(c)
print("Gauss3 =", sGs)
for c in srG :
print(c)
# Plot:
X = np.linspace(a,b,100)
Y = fu(X)
ax=pl.gca()
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
clabel =("f(x)")
pl.plot( X, Y, 'b', label=clabel)
clabel =("Trapez = %8.6f") % (sTr)
pl.plot( Xi, Yi, 'g', label=clabel)
#pl.scatter(X, Y)
pl.xlabel("x")
pl.ylabel("f(x)")
pl.legend ()
pl.show()
#--------------------------------------------
def Konvergenztester(a,b):
#--------------------------------------------
results_n1 =[]
results_n2 =[]
results_Trapez = []
results_Simpson = []
err_Trapez = []
err_Simpson = []
quitAtRoudOffErrPerc = 0.005
(errp1, errp2) = (1e100,1e100)
happy = False
iTest1, iTest2 = 0,0
for n in range(4,1000,2):
(intTrapez,srT,Xi,Yi) = IntTrapez(a, b, n)
(intSimpson,srS) = IntSimpson(a, b, n)
if(len(results_Trapez) > 0 and len(results_Simpson) > 0):
errp1 = abs((results_Trapez[-1] - intTrapez)/intTrapez) * 100
errp2 = abs((results_Simpson[-1] - intSimpson)/intSimpson) * 100
if(errp1 > quitAtRoudOffErrPerc or len(results_n1) == 0):
iTest1 += 1
results_n1.append(n)
err_Trapez.append(errp1)
if(errp2 > quitAtRoudOffErrPerc or len(results_n2) == 0):
iTest2 += 1
results_n2.append(n)
err_Simpson.append(errp2)
results_Trapez.append(intTrapez)
results_Simpson.append(intSimpson)
if(errp1 <= quitAtRoudOffErrPerc and errp2 <= quitAtRoudOffErrPerc):
happy = True
break
if(not happy):
print("Keine Konvergenz nach", n , "Schritten")
clabel = "Trapezregel %s intervals, err=%6.2f %% after %d steps" % (results_n1[-1],err_Trapez[-1],iTest1)
pl.plot( results_n1, err_Trapez, 'b', label="%s" % clabel)
clabel = "Simpson %s intervals, err=%6.2f %% after %d steps" % (results_n2[-1],err_Simpson[-1],iTest2)
pl.plot( results_n2, err_Simpson, 'g', label="%s" % clabel)
pl.xlabel(r'$intervals$')
pl.ylabel(r'$est. err. [\%] $')
pl.legend ()
pl.show()
#--------------------------------------------
def main():
#--------------------------------------------
# Eingabe:
inpStr = input("Integrationsformeln\nGib a= b= n= (mit , getrennt)")
nSeps = inpStr.count(',')
if (nSeps != 2):
print("error: you have to define a,b,n separated by exactly two commas such as 0,1,10")
return False
(a,b,n) = inpStr.split(",")
if (a.isnumeric() == False or b.isnumeric() == False or n.isnumeric() == False):
print("error: a,b,n have to be numbers")
return False
(a,b,n) = [float(a), float(b), int(n)]
print("a=",a,"b=",b,"n=",n)
SubsequCallToAllMethods(a,b,n)
Konvergenztester(a,b)
#input("...press any key to continue")
#--------------------------------------------
#--------------------------------------------
if __name__ == "__main__":
main()
Kurz noch zum Hintergrund: Ich bin Bauingenieur, tätig in der Tragwerksplanung.
Zu meiner Studiumszeit haben wir ausschließlich VBA Programmierung behandelt.
Das Verständnis für die verschiedenen Integrationsmethoden habe ich noch:
Ich soll meinen Cousin etwas helfen, oben genannten Quellcode besser zu verstehen.
Programmieren darf/soll er dann andere Aufhaben selber!
Gruß
Zu meiner Studiumszeit haben wir ausschließlich VBA Programmierung behandelt.
Das Verständnis für die verschiedenen Integrationsmethoden habe ich noch:
Ich soll meinen Cousin etwas helfen, oben genannten Quellcode besser zu verstehen.
Programmieren darf/soll er dann andere Aufhaben selber!
Gruß
Ich verstehe da einiges nicht. Allein das Programmierungsprinzip ist mir völlig fremd.
Ich suche jemand der mir hilft, falls ja super, falls nicht dann nicht.
Irgendwelche Beiträge in denen ich meine schlechten Programmierkenntnisse erklären muss, möchte ich gerne abweisen.
Gruß
Ich suche jemand der mir hilft, falls ja super, falls nicht dann nicht.
Irgendwelche Beiträge in denen ich meine schlechten Programmierkenntnisse erklären muss, möchte ich gerne abweisen.
Gruß
-
- User
- Beiträge: 491
- Registriert: Mittwoch 13. November 2019, 08:38
Das ist wenig konkret. Ohne konkrete Frage kann man auch nicht richtig helfen; außer ebenso pauschal zu antworten: das "Programmierungsprinzip" ist hier erklärt https://docs.python.org/3/tutorial/index.html.
"ich bin auf der Suche nach jemanden der mir den im Anhang beiliegenden Code "übersetzen" könnte."
"Damit meine ich Stichpunkthaltig was passiert in Zeile xy, was macht dieser Operator etc.
z.B rechts daneben am Rand"
Ich bin auf der Suche nach jemanden der Profi in dieser tollen Sache ist und für ihn ein leichtes Spiel ist. Natürlich könnte ich mir selbst alles erarbeiten, aber das ist hier nicht mein Gesuch in diesem Beitrag.
Wenn ich über eine Zeitunganzeige eine Reinigungskraft suche, bringen mir Anrufer die mir erzählen in welchem Supermarkt es das günstigste und beste Putzmittel gibt herzlich wenig.
Trotzdem Danke.
Wie vorhin gesagt, wenn sich jemand findet super, wenn nicht dann nicht!
Gruß
"Damit meine ich Stichpunkthaltig was passiert in Zeile xy, was macht dieser Operator etc.
z.B rechts daneben am Rand"
Ich bin auf der Suche nach jemanden der Profi in dieser tollen Sache ist und für ihn ein leichtes Spiel ist. Natürlich könnte ich mir selbst alles erarbeiten, aber das ist hier nicht mein Gesuch in diesem Beitrag.
Wenn ich über eine Zeitunganzeige eine Reinigungskraft suche, bringen mir Anrufer die mir erzählen in welchem Supermarkt es das günstigste und beste Putzmittel gibt herzlich wenig.
Trotzdem Danke.
Wie vorhin gesagt, wenn sich jemand findet super, wenn nicht dann nicht!
Gruß
-
- User
- Beiträge: 491
- Registriert: Mittwoch 13. November 2019, 08:38
Wenn ich über eine Zeitungsanzeige eine Reinigungskraft suchte, beschriebe ich die Aufgaben aber auch detaillierter als "Es muss geputzt werden.". Wenn du nicht konkreter werden willst, sondern pauschal alles kommentiert haben möchtest, bin ich raus. Viel Erfolg.
- __blackjack__
- User
- Beiträge: 13113
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@rectosh99: Wenn man den Quelltext in Code-Tags setzt im Beitrag, dann bleiben die Einrückungen erhalten, die bei Python ja wichtiger Bestandteil der Syntax sind:
Was meinst Di mit „Programmierungsprinzip“? Ich sehe da Funktionen mit prozeduralem Code als Inhalt, also nichts was sich jetzt wesentlich von Basic/VBA unterscheiden würde. Du hast da sogar ein bisschen Glück, dass da scheinbar nichts verwendet wird, was zu weit von VBA abweicht. Die Funktion hätte man beispielsweise als Argument übergeben können/sollen, statt da eine hart kodierte `fu()`-Funktion in den verschiedenen Integrationsvarianten aufzurufen. Funktionen sind in Python nämlich auch Werte.
Wo genau liegen denn die Verständnisprobleme? Was sind die Fragen die nach dem Durcharbeiten vom Grundlagentutorial in der Python-Dokumentation nicht geklärt sind? Was verstehst Du konkret nicht? Weicht irgendwo ein (Zwischen)Ergebnis von dem ab was Du erwartest? Was hättest Du da erwartet und was bekommst Du?
Hilfreich wäre vielleicht wenn Du das Programm etwas überarbeitest. Ich habe jetzt raus was die *Werte* von `sr` und `cs` bedeuten, aber nicht wirklich was die *Namen* bedeuten. Wenn man da sinnvolle Namen verwendet, wird es schon verständlicher. Im allgemeinden sollte man keine kryptischen Abkürzungen in Namen verwenden, und schon gar keine Namen die nur daraus bestehen. Denn der Zweck von Namen ist ja dem Leser die Bedeutung der Werte dahinter zu vermitteln.
Ich würde übrigens sagen, dass das Programm fehlerhaft ist, denn die Schrittweite ``dx = (b-a)/n`` berechnen und dann in jedem Schritt `dx` aufaddieren ist bei Gleitkommazahlen eine schlechte Idee, denn die sind nicht exakt und bei jeder Addition kann es dadurch ungenauer werden. An einer Stelle beim Plotten wird ja bereits `numpy.linspace()` verwendet. Insgesamt würde es vielleicht Sinn machen wenn man `numpy` mehr verwenden würde in dem Programm.
Das scheint auch nicht von einem Python-Programmierer zu sein. Es wird sich an einige Konventionen aus dem Style Guide for Python Code nicht gehalten. Zum Beispiel das Namen klein_mit_unterstrichen geschrieben werden, und was Leerzeichen- und Zeilensetzung angeht um die Lesbarkeit zu erhöhen. Dann gibt es unnötige Klammern um Bedingungen bei ``if`` & Co und den Defaultwert 1 für die Schrittweite bei `range()` gibt man auch nicht an. ”Linien”-Kommentare sind auch unüblich.
Man muss auch nicht jedes kleine Zwischenergebnis an einen Namen binden. Insbesondere wenn der Name dann auch noch kryptisch ist, macht dass das lesen/verstehen eher schwerer als einfacher.
Bei der `main()` machen die ``return False`` keinen Sinn, weil es nirgends ein ``return True`` gibt. Die Funktion gibt also entweder `False` oder `None` zurück.
Man vergleicht auch nicht mit literalen Wahrheitswerten. Da kommt ja nur wieder ein Wahrheitswert bei heraus. Also hätte man auch gleich den Wert nehmen können mit dem man vergleicht, beziehungsweise dessen negation. Also statt:
Diese Tests sind aber ein bisschen ”unpythonisch”. Man würde einfach die Umwandlung machen und auf den `ValueError` reagieren der dabei ausgelöst werden kann. Da Zuweisung an mehrere Namen auch mit einem `ValueError` fehl schlägt, wenn die Anzahl der Werte nicht passt, kann man das gleich mit berücksichtigen.
Den ``%``-Operator für Zeichenkettenformatierung benutzt man eigentlich schon lange nicht mehr ohne einen guten Grund. Dafür gibt es f-Zeichenkettenliterale.
Bei `konvergenztester()` sind viele schlechte Namen, die man besser sprechender wählen würde.
`iTest1` und `iTest2` sind überflüssig, weil das die Längen der dazugehörigen Listen sind, die man einfach mit `len()` abfragen kann.
Das ganze in einem ersten Überarbeitungsschritt (ungetestet) etwas „pythonischer“ und lesbarer:
Code: Alles auswählen
import numpy as np
import pylab as pl
#--------------------------------------------
def fu(x):
#--------------------------------------------
#return np.exp(-x**2)
return np.sin(x)/(x+1)+0.2
#return 2*x**2-x+1 # hier liefert Sipson den korr Wert!!
#--------------------------------------------
def IntTrapez(a, b, n):
#--------------------------------------------
sr = []
X = []
Y = []
X.append(a)
Y.append(fu(a))
dx = (b-a)/n
s = (fu(a) + fu(b))/2
xi=a
for i in range(2,n+1,1):
xi += dx
s += fu(xi)
cs = " Trapez: i=%2d x=%6.2f f(x)=%6.2f summe=%8.5f" % (i, xi, fu(xi), s*dx)
X.append(xi)
Y.append(fu(xi))
sr.append(cs)
s *= dx
X.append(b)
Y.append(fu(b))
return (s, sr, X, Y)
#--------------------------------------------
def IntSimpson(a, b, n):
#--------------------------------------------
sr = []
if (n % 2 != 0):
sr.append("Simpson: n muss gerade sein.")
return (0, sr)
dx = (b - a) / n
s = fu(a) + fu(b)
xi = a
for i in range(1,n,1):
xi = xi + dx
if (i % 2 == 0 ):
s += 2 * fu(xi)
else:
s += 4 * fu(xi)
cs = " Simpson: i=%2d x=%6.2f f(x)=%6.2f summe=%8.5f" % (i, xi, fu(xi), s*dx/3)
sr.append(cs)
return (s*dx/3 , sr)
#--------------------------------------------
def IntGauss3(a, b):
#--------------------------------------------
sr = []
xsi =[-0.774596669241483, 0, 0.774596669241483]
alpha =[0.555555555555556, 0.888888888888889, 0.555555555555556]
s = 0
for i in range(0,3,1):
xi = (a + b) / 2 + xsi[i] * (b - a) / 2
Wi = alpha[i] * (b - a) / 2
s += Wi * fu(xi)
cs = " Gauss3: i=%2d xi=%6.4f Wi=%6.4f f(xi)= %6.2f summe=%8.5f" % (i, xi, Wi, fu(xi), s)
sr.append(cs)
return (s, sr)
#--------------------------------------------
def SubsequCallToAllMethods(a,b,n):
#--------------------------------------------
# unsere Ergebnisse:
(sTr,srT,Xi,Yi) = IntTrapez(a, b, n)
(sSi,srS) = IntSimpson(a, b, n)
(sGs,srG) = IntGauss3(a, b)
print("Trapez =", sTr)
for c in srT :
print(c)
print("Simpson =", sSi)
for c in srS :
print(c)
print("Gauss3 =", sGs)
for c in srG :
print(c)
# Plot:
X = np.linspace(a,b,100)
Y = fu(X)
ax=pl.gca()
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
clabel =("f(x)")
pl.plot( X, Y, 'b', label=clabel)
clabel =("Trapez = %8.6f") % (sTr)
pl.plot( Xi, Yi, 'g', label=clabel)
#pl.scatter(X, Y)
pl.xlabel("x")
pl.ylabel("f(x)")
pl.legend ()
pl.show()
#--------------------------------------------
def Konvergenztester(a,b):
#--------------------------------------------
results_n1 =[]
results_n2 =[]
results_Trapez = []
results_Simpson = []
err_Trapez = []
err_Simpson = []
quitAtRoudOffErrPerc = 0.005
(errp1, errp2) = (1e100,1e100)
happy = False
iTest1, iTest2 = 0,0
for n in range(4,1000,2):
(intTrapez,srT,Xi,Yi) = IntTrapez(a, b, n)
(intSimpson,srS) = IntSimpson(a, b, n)
if(len(results_Trapez) > 0 and len(results_Simpson) > 0):
errp1 = abs((results_Trapez[-1] - intTrapez)/intTrapez) * 100
errp2 = abs((results_Simpson[-1] - intSimpson)/intSimpson) * 100
if(errp1 > quitAtRoudOffErrPerc or len(results_n1) == 0):
iTest1 += 1
results_n1.append(n)
err_Trapez.append(errp1)
if(errp2 > quitAtRoudOffErrPerc or len(results_n2) == 0):
iTest2 += 1
results_n2.append(n)
err_Simpson.append(errp2)
results_Trapez.append(intTrapez)
results_Simpson.append(intSimpson)
if(errp1 <= quitAtRoudOffErrPerc and errp2 <= quitAtRoudOffErrPerc):
happy = True
break
if(not happy):
print("Keine Konvergenz nach", n , "Schritten")
clabel = "Trapezregel %s intervals, err=%6.2f %% after %d steps" % (results_n1[-1],err_Trapez[-1],iTest1)
pl.plot( results_n1, err_Trapez, 'b', label="%s" % clabel)
clabel = "Simpson %s intervals, err=%6.2f %% after %d steps" % (results_n2[-1],err_Simpson[-1],iTest2)
pl.plot( results_n2, err_Simpson, 'g', label="%s" % clabel)
pl.xlabel(r'$intervals$')
pl.ylabel(r'$est. err. [\%] $')
pl.legend ()
pl.show()
#--------------------------------------------
def main():
#--------------------------------------------
# Eingabe:
inpStr = input("Integrationsformeln\nGib a= b= n= (mit , getrennt)")
nSeps = inpStr.count(',')
if (nSeps != 2):
print("error: you have to define a,b,n separated by exactly two commas such as 0,1,10")
return False
(a,b,n) = inpStr.split(",")
if (a.isnumeric() == False or b.isnumeric() == False or n.isnumeric() == False):
print("error: a,b,n have to be numbers")
return False
(a,b,n) = [float(a), float(b), int(n)]
print("a=",a,"b=",b,"n=",n)
SubsequCallToAllMethods(a,b,n)
Konvergenztester(a,b)
#input("...press any key to continue")
#--------------------------------------------
#--------------------------------------------
if __name__ == "__main__":
main()
Wo genau liegen denn die Verständnisprobleme? Was sind die Fragen die nach dem Durcharbeiten vom Grundlagentutorial in der Python-Dokumentation nicht geklärt sind? Was verstehst Du konkret nicht? Weicht irgendwo ein (Zwischen)Ergebnis von dem ab was Du erwartest? Was hättest Du da erwartet und was bekommst Du?
Hilfreich wäre vielleicht wenn Du das Programm etwas überarbeitest. Ich habe jetzt raus was die *Werte* von `sr` und `cs` bedeuten, aber nicht wirklich was die *Namen* bedeuten. Wenn man da sinnvolle Namen verwendet, wird es schon verständlicher. Im allgemeinden sollte man keine kryptischen Abkürzungen in Namen verwenden, und schon gar keine Namen die nur daraus bestehen. Denn der Zweck von Namen ist ja dem Leser die Bedeutung der Werte dahinter zu vermitteln.
Ich würde übrigens sagen, dass das Programm fehlerhaft ist, denn die Schrittweite ``dx = (b-a)/n`` berechnen und dann in jedem Schritt `dx` aufaddieren ist bei Gleitkommazahlen eine schlechte Idee, denn die sind nicht exakt und bei jeder Addition kann es dadurch ungenauer werden. An einer Stelle beim Plotten wird ja bereits `numpy.linspace()` verwendet. Insgesamt würde es vielleicht Sinn machen wenn man `numpy` mehr verwenden würde in dem Programm.
Das scheint auch nicht von einem Python-Programmierer zu sein. Es wird sich an einige Konventionen aus dem Style Guide for Python Code nicht gehalten. Zum Beispiel das Namen klein_mit_unterstrichen geschrieben werden, und was Leerzeichen- und Zeilensetzung angeht um die Lesbarkeit zu erhöhen. Dann gibt es unnötige Klammern um Bedingungen bei ``if`` & Co und den Defaultwert 1 für die Schrittweite bei `range()` gibt man auch nicht an. ”Linien”-Kommentare sind auch unüblich.
Man muss auch nicht jedes kleine Zwischenergebnis an einen Namen binden. Insbesondere wenn der Name dann auch noch kryptisch ist, macht dass das lesen/verstehen eher schwerer als einfacher.
Bei der `main()` machen die ``return False`` keinen Sinn, weil es nirgends ein ``return True`` gibt. Die Funktion gibt also entweder `False` oder `None` zurück.
Man vergleicht auch nicht mit literalen Wahrheitswerten. Da kommt ja nur wieder ein Wahrheitswert bei heraus. Also hätte man auch gleich den Wert nehmen können mit dem man vergleicht, beziehungsweise dessen negation. Also statt:
Code: Alles auswählen
if (
a.isnumeric() == False
or b.isnumeric() == False
or n.isnumeric() == False
):
print("error: a,b,n have to be numbers")
# besser
if not a.isnumeric() or not b.isnumeric() or not n.isnumeric():
print("error: a,b,n have to be numbers")
# beziehungsweise
if not (a.isnumeric() and b.isnumeric() and n.isnumeric()):
print("error: a,b,n have to be numbers")
Den ``%``-Operator für Zeichenkettenformatierung benutzt man eigentlich schon lange nicht mehr ohne einen guten Grund. Dafür gibt es f-Zeichenkettenliterale.
Bei `konvergenztester()` sind viele schlechte Namen, die man besser sprechender wählen würde.
`iTest1` und `iTest2` sind überflüssig, weil das die Längen der dazugehörigen Listen sind, die man einfach mit `len()` abfragen kann.
Das ganze in einem ersten Überarbeitungsschritt (ungetestet) etwas „pythonischer“ und lesbarer:
Code: Alles auswählen
#!/usr/bin/env python3
import numpy as np
import pylab as pl
def funktion(x):
# return np.exp(-x ** 2)
return np.sin(x) / (x + 1) + 0.2
# return 2 * x ** 2 - x + 1 # hier liefert Simpson den korrekten Wert!
def trapez_integration(a, b, n):
summe = (funktion(a) + funktion(b)) / 2
texte = []
xs = [a]
ys = [funktion(a)]
x_i = a
d_x = (b - a) / n
for i in range(2, n + 1):
x_i += d_x
summe += funktion(x_i)
xs.append(x_i)
ys.append(funktion(x_i))
texte.append(
f"Trapez: i={i:2d} x={x_i:6.2f} f(x)={funktion(x_i):6.2f}"
f" summe={summe * d_x:8.5f}"
)
xs.append(b)
ys.append(funktion(b))
return (summe * d_x, texte, xs, ys)
def simpson_integration(a, b, n):
if n % 2 != 0:
return (0, ["Simpson: n muss gerade sein."])
summe = funktion(a) + funktion(b)
texte = []
x_i = a
d_x = (b - a) / n
for i in range(1, n):
x_i += d_x
summe += (2 if i % 2 == 0 else 4) * funktion(x_i)
texte.append(
f"Simpson: i={i:2d} x={x_i:6.2f} f(x)={funktion(x_i):6.2f}"
f" summe={summe * d_x / 3:8.5f}"
)
return (summe * d_x / 3, texte)
def gauss3_integration(a, b):
xsis = [-0.774596669241483, 0, 0.774596669241483]
alphas = [0.555555555555556, 0.888888888888889, 0.555555555555556]
summe = 0
texte = []
for i, (xsi, alpha) in enumerate(zip(xsis, alphas)):
x_i = (a + b) / 2 + xsi * (b - a) / 2
w_i = alpha * (b - a) / 2
summe += w_i * funktion(x_i)
texte.append(
f"Gauss3: i={i:2d} xi={x_i:6.4f} Wi={w_i:6.4f}"
f" f(xi)={funktion(x_i):6.2f} summe={summe:8.5f}"
)
return (summe, texte)
def subsequent_call_to_all_methods(a, b, n):
trapez_summe, trapez_texte, trapez_xs, trapez_ys = trapez_integration(
a, b, n
)
simpson_summe, simpson_texte = simpson_integration(a, b, n)
gauss_summe, gauss_texte = gauss3_integration(a, b)
for methoden_name, summe, texte in [
("Trapez", trapez_summe, trapez_texte),
("Simpson", simpson_summe, simpson_texte),
("Gauss3", gauss_summe, gauss_texte),
]:
print(methoden_name, "=", summe)
for text in texte:
print(" ", text)
ax = pl.gca()
ax.xaxis.set_ticks_position("bottom")
ax.spines["bottom"].set_position(("data", 0))
xs = np.linspace(a, b, 100)
pl.plot(xs, funktion(xs), "b", label="f(x)")
pl.plot(trapez_xs, trapez_ys, "g", label=f"Trapez = {trapez_summe:8.6f}")
pl.xlabel("x")
pl.ylabel("f(x)")
pl.legend()
pl.show()
def konvergenztester(a, b):
max_allowed_error = 0.005
trapez_ns = []
trapez_results = []
trapez_errors = []
simpson_ns = []
simpson_results = []
simpson_errors = []
trapez_error = simpson_error = np.Infinity
for n in range(4, 1000, 2):
trapez_summe, _, _, _ = trapez_integration(a, b, n)
simpson_summe, _ = simpson_integration(a, b, n)
if trapez_results and simpson_results:
trapez_error = (
abs((trapez_results[-1] - trapez_summe) / trapez_summe) * 100
)
simpson_error = (
abs((simpson_results[-1] - simpson_summe) / simpson_summe)
* 100
)
if trapez_error > max_allowed_error or not trapez_ns:
trapez_ns.append(n)
trapez_errors.append(trapez_error)
if simpson_error > max_allowed_error or not simpson_ns:
simpson_ns.append(n)
simpson_errors.append(simpson_error)
trapez_results.append(trapez_summe)
simpson_results.append(simpson_summe)
if (
trapez_error <= max_allowed_error
and simpson_error <= max_allowed_error
):
break
else:
print("Keine Konvergenz nach", n, "Schritten")
for methoden_name, ns, errors, colour in [
("Trapezregel", trapez_ns, trapez_errors, "b"),
("Simpson", simpson_ns, simpson_errors, "g"),
]:
pl.plot(
ns,
errors,
colour,
label=(
f"{methoden_name} {ns[-1]} intervals,"
f" err={errors[-1]:6.2f} % after {len(ns)} steps"
),
)
pl.xlabel(R"$intervals$")
pl.ylabel(R"$est. err. [\%] $")
pl.legend()
pl.show()
def main():
input_text = input(
"Integrationsformeln\n" "Gib a= b= n= (mit , getrennt)"
)
try:
a, b, n = map(int, input_text.split())
except ValueError:
print(
"error: a,b,n must be numbers and separatet by exactly two commas."
)
else:
print("a=", a, "b=", b, "n=", n)
subsequent_call_to_all_methods(a, b, n)
konvergenztester(a, b)
if __name__ == "__main__":
main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
@__blackjack__
Für deine verbesserung bedanke mich sehr! Wäre nicht nötig gewesen... Aber ganz großes Engagement! Danke!
Offiziell ist dieser Quellcode die Lösung eines Dozenten. Ich habe mich etwas in Phyton eingelesen und versuche es meinem Cousin einigermaßen verständlich zu erklären.
Gruß
Für deine verbesserung bedanke mich sehr! Wäre nicht nötig gewesen... Aber ganz großes Engagement! Danke!
Offiziell ist dieser Quellcode die Lösung eines Dozenten. Ich habe mich etwas in Phyton eingelesen und versuche es meinem Cousin einigermaßen verständlich zu erklären.
Gruß
- __blackjack__
- User
- Beiträge: 13113
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@rectosh99: Ich dachte es ist vielleicht leichter verständlich wenn bessere Namen verwendet werden und ein paar unnütze Sachen einfach wegfallen.
Kannst Du Dir das mit Deinem Cousin nicht gemeinsam erarbeiten? Die Grundlagen muss *er* ja schliesslich drauf haben, also was ein Operator bedeutet, was eine Liste an Operationen erlaubt und so weiter. Wobei das IMHO auch nicht wirklich „rocket science“ ist, denn so wirklich exotisches wird da ja gar nicht verwendet. Und Python selbst ist von der Syntax her ja auch relativ leichtgewichtig und das meiste auch ohne tiefergehende Kenntnisse verständlich.
Bei den Operatoren haben die meisten die normale mathematische Bedeutung. Aus der Reihe fallen ``**`` für Potenz, also ``x ** 3`` ist x³. Und ``%`` wenn man das nicht von Sprachen aus der C-Familie kennt: Modulo. Wäre in VBA ``MOD`` soweit ich weiss. War es jedenfalls in älteren Microsoft-BASIC-Dialekten.
Ansonsten hat die Dokumentation einen Index wo man nach Operatoren und Funktions- und Methodennamen schauen kann.
`trapez_results` und `simpson_results` könnte man auch noch vereinfachen, denn das müssten gar keine Listen sein, weil da immer nur auf das letzte Element zugegriffen wird. Alles davor interessiert nicht.
Dass das wiederholte aufaddieren von einem Gleitkommadeltawert von einem Dozenten kommt, ist IMHO ein bisschen beängstigend. Dozenten sollten doch wissen, dass man das nicht macht.
Last but not least: Man kann in Python, wie in den guten alten BASIC-Implementierungen, auch einfach eine interaktive Python-Shell starten und einfach mal sachen ”live” ausprobieren um sie Sprache oder Bibliotheken zu erforschen. Entweder einfach python als Programm in einer Konsole aufrufen, oder eine Shell mit mehr Funktionalität wie IPython in der Konsole oder per JupyterLab im Browser verwenden.
Kannst Du Dir das mit Deinem Cousin nicht gemeinsam erarbeiten? Die Grundlagen muss *er* ja schliesslich drauf haben, also was ein Operator bedeutet, was eine Liste an Operationen erlaubt und so weiter. Wobei das IMHO auch nicht wirklich „rocket science“ ist, denn so wirklich exotisches wird da ja gar nicht verwendet. Und Python selbst ist von der Syntax her ja auch relativ leichtgewichtig und das meiste auch ohne tiefergehende Kenntnisse verständlich.
Bei den Operatoren haben die meisten die normale mathematische Bedeutung. Aus der Reihe fallen ``**`` für Potenz, also ``x ** 3`` ist x³. Und ``%`` wenn man das nicht von Sprachen aus der C-Familie kennt: Modulo. Wäre in VBA ``MOD`` soweit ich weiss. War es jedenfalls in älteren Microsoft-BASIC-Dialekten.
Ansonsten hat die Dokumentation einen Index wo man nach Operatoren und Funktions- und Methodennamen schauen kann.
`trapez_results` und `simpson_results` könnte man auch noch vereinfachen, denn das müssten gar keine Listen sein, weil da immer nur auf das letzte Element zugegriffen wird. Alles davor interessiert nicht.
Dass das wiederholte aufaddieren von einem Gleitkommadeltawert von einem Dozenten kommt, ist IMHO ein bisschen beängstigend. Dozenten sollten doch wissen, dass man das nicht macht.
Last but not least: Man kann in Python, wie in den guten alten BASIC-Implementierungen, auch einfach eine interaktive Python-Shell starten und einfach mal sachen ”live” ausprobieren um sie Sprache oder Bibliotheken zu erforschen. Entweder einfach python als Programm in einer Konsole aufrufen, oder eine Shell mit mehr Funktionalität wie IPython in der Konsole oder per JupyterLab im Browser verwenden.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Idealerweise würde man ja bei der Trapez-Methode nicht jeden Funktionswert dreimal berechnen, sondern alles einmal vorberechnen. Die Summe ist etwas daneben, weil nicht wirklich Trapeze aufaddiert werden.
Bei der Simpson-Interation gilt im Wesentlichen das selbe:
Code: Alles auswählen
def trapez_integration(a, b, n):
xs = np.linspace(a, b, n + 1)
ys = funktion(xs)
d_x = xs[1] - xs[0]
texte = []
summe = ys[0] / 2
for i, (x_i, y_i) in enumerate(zip(xs[1:-1], ys[1:-1]), 2):
summe += y_i
texte.append(
f"Trapez: i={i:2d} x={x_i:6.2f} f(x)={y_i:6.2f}"
f" summe={summe * d_x:8.5f}"
)
summe += ys[-1] / 2
return (summe * d_x, texte, xs, ys)
Code: Alles auswählen
def simpson_integration(a, b, n):
if n % 2 != 0:
return (0, ["Simpson: n muss gerade sein."])
xs = np.linspace(a, b, n + 1)
ys = funktion(xs)
# factors are 1 4 2 4 ... 4 2 4 1
factors = np.arange(n + 1) % 2 * 2 + 2
factors[[0,-1]] = 1
factors = factors / 3
summe = 0
d_x = xs[1] - xs[0]
texte = []
for i, (factor, x_i, y_i) in enumerate(zip(factors, xs, ys), 1):
summe += factor * y_i
texte.append(
f"Simpson: i={i:2d} x={x_i:6.2f} f(x)={y_i:6.2f}"
f" summe={summe * d_x:8.5f}"
)
return (summe * d_x, texte)