Schleifendurchläufe zählen & Variable neu setzen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Bindl
User
Beiträge: 70
Registriert: Donnerstag 27. Oktober 2016, 11:48

Hi zusammen,

ich soll folgendes Programm schreiben:
Schreiben Sie ein Programm, das die Anzahl der Jahre berechnet, die benötigt werden,
um bei einem Startkapital von 1.000€ und einem Zinssatz von 4,5% einen Endbetrag von
10.000€ zu erreichen.

Ich dachte mir folgendes:
Eine while Schleife die so oft durchlaufen wird bis i >= 10000 ist.

Code: Alles auswählen

i = 0

while i <= 10000:
     i = 1000 * 1.045
         if i >= 10000:
             print() # Hier sollten dann die Schleifendurchläufe ausgegeben werden
         else:
             continue # Nur müssten die 1000 ja nun durch das neue i ersetzt werden
Wie kann ich Schelifendurchläufe zählen und wie kann ich hier die 1000 durch das neue i ersetzen ?


Danke schonmal für die Hilfe
BlackJack

@Bindl: Der Name `i` ist schlecht gewählt. Wenn das ein Betrag sein soll, dann nenne es doch einfach `betrag` und nicht `i`. Und wenn das bei 1000 anfangen soll, dann fang auch bei 1000 an und nicht bei 0.

Die 1000 durch `i` ersetzen geht ganz einfach: Ersetz die 1000 durch `i`. Also die 1 und die drei Nullen weg und stattdessen an der Stelle ein i.

Das ``if``/``else``-Konstrukt ist zu tief eingerückt.

Der ``else``-Zweig mit dem ``continue`` macht keinen Sinn wenn danach nichts mehr kommt was übersprungen werden soll wenn die ``if``-Bedingung nicht zutrifft.

Und auch das ``if`` macht dort keinen Sinn. Diese Bedingung ist, wenn sonst alles richtig ist, ja automatisch *nach* der Schleife (fast) erfüllt, denn die wird ja verlassen wenn i > 10000 gilt.

Zum Zählen: Das musst Du halt einfach *machen*. Also einen Zähler vor der Schleife mit 0 initialisieren und in der Schleife dann diesen Wert jeweils um eins erhöhen, dann hast Du nach der Schleife die Anzahl wie oft sie durchlaufen wurde.
Bindl
User
Beiträge: 70
Registriert: Donnerstag 27. Oktober 2016, 11:48

Hi,

ich glaube die Lösung gefunden zu haben.
Zumindest ergibt es das richtige Ergebnis.

Code: Alles auswählen

startwert = 1000
summe = startwert
zaehler = 0

while summe <= 10000:
    summe = summe * 1.045
    zaehler += 1

print("Anzahl: {}".format(zaehler))

Ich sehe gerade, das ich mir den startwert hätte schenken können und einfach die summe = 1000 hätte setzen können.
Naja, ich bin ja noch Anfänger.
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

@Bindl: in der Aufgabe steht, dass 10000€ erreicht werden sollen, nicht "überschritten".
BlackJack

Wobei ich die Aufgabe ohne Schleife lösen würde. Man kann das ja auch direkt ausrechnen:

Code: Alles auswählen

from math import ceil, log

startkapital = 1000
zielbetrag = 10000
zinssatz = 4.5
jahre = int(ceil(log(zielbetrag / startkapital, 1 + zinssatz / 100)))
print('Anzahl Jahre: ', jahre)
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Bindl hat geschrieben:

Code: Alles auswählen

while summe <= 10000:
    summe = summe * 1.045
    zaehler += 1
Die Multiplikation von summe kannst du übrigens mit der gleichen Kurzschreibweise durchführen wie die Addition bei zaehler.

Code: Alles auswählen

while summe <= 10000:
    summe *= 1.045
    zaehler += 1
BlackJack

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.

Code: Alles auswählen

In [1]: import sympy

In [2]: sympy.init_printing()
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.

Code: Alles auswählen

In [3]: from sympy import Eq, Function, rsolve, solve
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.
Antworten