Nur mal so spasseshalber zum Nachvollziehen wie man mit Hilfe von Python und der Bibliothek `sympy` (und IPython als interaktive Python-Shell (was aber auch mit anderen gehen würde)) von der Schleifenlösung auf das direkte Ausrechnen kommen kann.
Zuerst importieren wir `sympy` und rufen eine Funktion auf, welche die Ausgabe etwas hübscher macht, in dem auch in der Konsole die Formeln die wir mit `sympy` erstellen und manipulieren nicht wie Quelltext, sondern mehr wie die normale mathematische Notation ausgegeben werden.
Die Lösung mit der ``while``-Schleife ist ja eigentlich eine rekursive Formel iterativ ausgerechnet. Der Betrag für ein Jahr, im Programm `summe`, wird aus dem vorherigen Betrag berechnet, also der Betrag für das n-te Jahr aus dem Betrag für das Jahr n-1.
Also importieren wir aus `sympy` ein paar Sachen, die wir brauchen um das symbolisch ausdrücken und auflösen zu können.
Nun können wir die Objekte erstellen die für die Funktion und die symbolischen Variablen stehen. Die Funktion nennen wir `a` und wir brauchen noch eine Variable für den Startkapital `a_0`, die Zinsrate `i`, das Jahr `n`, und den Zielbetrag `t`.
Code: Alles auswählen
In [4]: a = Function('a')
In [5]: a_0, i, n, t = sympy.symbols('a_0 i n t')
Mit diesen Symbolen können wir nun ein Objekt erstellen, welches die Gleichung für rekursiv definierte Folge repräsentiert, die von der ``while``-Schleife ausgerechnet wird.
Code: Alles auswählen
In [6]: Eq(a(n), a(n-1) * (i+1))
Out[6]: a(n) = (i + 1)⋅a(n - 1)
Im nächsten Schritt fragen wir `sympy` nach geschlossenen Formeln mit der zusätzlichen Voraussetzung, dass der Startwert `a_0` für `a(n)` existiert:
Code: Alles auswählen
In [7]: rsolve(Eq(a(n), a(n-1) * (i + 1)), a(n), [a_0])
Out[7]:
n
a₀⋅(i + 1)
Damit kann man jetzt ohne Schleife den Betrag für das Jahr `n` bei Startkapital `a₀` und Zinsrate `i` ausrechnen. Was uns noch nicht von einer Schleife wegbringen würde, weil man auch mit dieser Formel natürlich die Jahre durchprobieren müsste bis man den Zielbetrag erreicht hat. Aber man kann damit eine weitere Gleichung aufstellen in der man diese Formel mit dem Zielbetrag gleichsetzt.
Code: Alles auswählen
In [8]: Eq(t, rsolve(Eq(a(n), a(n-1) * (i + 1)), a(n), [a_0]))
Out[8]:
n
t = a₀⋅(i + 1)
Und diese Gleichung kann man nun nach `n` auflösen um eine Formel zu erhalten die einem das Jahr ausrechnet in dem der Zielbetrag erreicht ist.
Code: Alles auswählen
In [9]: solve(Eq(t, rsolve(Eq(a(n), a(n-1) * (i + 1)), a(n), [a_0])), n)
Out[9]:
⎡ ⎛t ⎞ ⎤
⎢ log⎜──⎟ ⎥
⎢ ⎝a₀⎠ ⎥
⎢──────────⎥
⎣log(i + 1)⎦
Die eckigen Klammern bedeuten, dass das Ergebnis eine Liste ist, weil bei manchen Auflösungen für andere Gleichungen auch mehr als ein Ergebnis kommen kann.
Damit der Ausdruck für die Eingabe nicht noch länger wird, binden wir das eine Ergebnis mal an den Namen `f`.
Code: Alles auswählen
In [10]: f = solve(Eq(t, rsolve(Eq(a(n), a(n-1) * (i + 1)), a(n), [a_0])), n)[0]
In [11]: f
Out[11]:
⎛t ⎞
log⎜──⎟
⎝a₀⎠
──────────
log(i + 1)
Nun haben wir eine Formel die alle unsere bekannten Werte enthält (Zielbetrag `t`, Startkapital `a₀`, und Zinsrate `i`) und die den gesuchten Wert `n`, das Jahr ausrechnet. Also ersetzen wir die Variablen mal durch die Werte aus der Aufgabe.
Code: Alles auswählen
In [12]: f.evalf(subs={a_0: 1000, t: 10000, i: 0.045})
Out[12]: 52.3114043892928
Da nach einem ganzen Jahr gefragt wurde, muss die Aufrundungsfunktion noch in die Formel eingebaut werden um das gleiche Ergebnis wie bei der ``while``-Schleife zu bekommen.
Code: Alles auswählen
In [13]: sympy.ceiling(f)
Out[13]:
⎡ ⎛t ⎞ ⎤
⎢ log⎜──⎟ ⎥
⎢ ⎝a₀⎠ ⎥
⎢──────────⎥
⎢log(i + 1)⎥
In [14]: sympy.ceiling(f).evalf(subs={a_0: 1000, t: 10000, i: 0.045})
Out[14]: 53.00
Jetzt muss man nur noch wissen, dass `log a / log b` (`log` = der natürliche Logarithmus) äquivalent zum Logarithmus von `a` zur Basis `b` ist, dann landet man bei der Lösung die ich weiter oben als Python-Programm ohne Schleife gepostet habe.