Seite 1 von 2
[Anfänger] Variable wird nciht mehr gebunden
Verfasst: Dienstag 26. Januar 2016, 21:53
von Chris79
Hallo,
ich habe in einem Kurs eine Aufgabe bekommen und muss diese nun Lösen.
Keien Angst ich möchte nciht die Lösung von euch wissen sondern habe ein anderes Problem
In der while schleife die erste "if"
dort möchte ich guess neu binden -> guess = round((low+high)/2,2)
leider behält aber guess die ganze zeit den initialen wert den ich am Anfang des scripts vergeben habe
Ich zermarter mir nun shcon den ganzen Tag den kopf und weiß nicht wo mein Fehler liegt.
Achtung vor Codeausführung: durch dieses nicht binden ist eine endloss schleife entstanden
Über eine Antwort würde ich mich sehr freuen
Chris
Code: Alles auswählen
balance = 10000
annualInterestRate = 8.0
low = round(balance/12,2)
high = round(balance*(1+(annualInterestRate/12)**12)/12,2)
guess = (low+high)/2
def rechnen(x,y,z): #x=balance, y=anualInterestRate, z=guess
i = 0
while i < 12:
i = i+1
x = (x - z) + ((x - z)*(y/12))
return x
while round(rechnen(balance,annualInterestRate,guess),2) != 0:
if round(rechnen(balance,annualInterestRate,guess),2) > 0:
low = guess
guess = round((low+high)/2,2)
print guess,'goesser'
if round(rechnen(balance,annualInterestRate,guess)) < 0:
high = guess
guess = round((low+high)/2,2)
print guess,'kleiner'
print 'guess:',guess
Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Dienstag 26. Januar 2016, 22:06
von Sirius3
@Chirs79: Du solltest mal Deine Startbedingungen überprüfen. Wann kann das Verfahren überhaupt funktionieren? Was bewirkt das Runden? Versuche die Funktion nur einmal und nicht dreimal pro Durchgang zu berechnen.
Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Dienstag 26. Januar 2016, 22:22
von BlackJack
@Chirs79: Statt einbuchstabiger Namen die in einem Kommentar durch jeweils ein Wort erklärt werden, hätte man besser gleich das jeweilige Wort genommen. Dann braucht man den Kommentar nicht. Was die Namensschreibweise angeht wäre ein Blick in den
Style Guide for Python Code angebracht.
Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Dienstag 26. Januar 2016, 22:37
von Chris79
erstmal vielen dank für eure schnellen Antworten.
Ich habe die Berechnung nun anstatt dreimal einmal in der while drinnen.
Auch habe ich versucht auf die schnelle etwas aus dem Style guide zu beachten ( die def ist nun hoffentlich ok)
Allerdings habe ich immer noch das gleich problem.
Er/Sie durchläuft andauernd die erste if und ändert denw ert von guess nicht
Code: Alles auswählen
balance = 10000
annualInterestRate = 8.0
low = balance/12
high = balance*(1+(annualInterestRate/12)**12)/12
guess = (low + high)/2
def rechnen(
balance,anualInterestRate,guess):
i = 0
while i < 12:
i = i+1
balance = (balance - guess) + ((balance - guess)*(anualInterestRate/12))
return balance
balance1 = round(rechnen(balance,annualInterestRate,guess),2)
while round(balance1,2) != 0.00:
balance1 = rechnen(balance,annualInterestRate,guess)
if balance1 > 0.00:
low = guess
guess = (low+high)/2
print guess,'goesser'
if balance1 < 0.00:
high = guess
guess = (low+high)/2
print guess,'kleiner'
print 'guess:',round(guess,2)
Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Dienstag 26. Januar 2016, 22:41
von Sirius3
@Chirs79: Du solltest mal Deine Startbedingungen überprüfen.
Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Dienstag 26. Januar 2016, 22:51
von Chris79
Sirius3 hat geschrieben:@Chirs79: Du solltest mal Deine Startbedingungen überprüfen.
Ist der Fehler darin so offensichtlich?
Wenn ja bin ich nach dem ganzen Tag davor sitzten wahrschenlich mit einem Tunnelblick gestraft.
Ich glaube dann sollte ich nach einer Nacht schlafen da ncohmla drauf schauen.
Ich kann aktuell nichts entdecken was mich irgendworan zweifeln lässt :K
Danke aber tortzdem. Vllt. geht mir morgen ja ein licht auf

Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Mittwoch 27. Januar 2016, 10:32
von Chris79
Ok, frische Kopf frische idee
So mittlerweile habe ich rausgefunden, dass die VariablenBindung funktioniert.
Nur leider wrd der die Variable balance in def rechnen nicht kleiner sondern größer und dies verursacht die Störung.
Nun bin ich wieder bei den
Startbedingungen angekommen und sehe bei der Berechnung von high den Fehler.
Ein anderes script welches die "Berechnung" ohne bisection durchführt liefert mir ein ergebnis für "guess" welche weit über high liegt.
Also muss in der Berechnungsformel mein Fehler liegen
Was mir bei der Entdeckung geholfen hat war das Script nicht einfach so laufen zu lassen sondern die while schleife auf eine gerineg anzahl (30) zu begrenzen und mir die wert ausgeben zu lassen.
Danke soweit schonmal an eure Hartnäckigkeit -> Prüfe die Startbedingungen

Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Mittwoch 27. Januar 2016, 11:03
von Sirius3
@Chirs79: ganz sinnvoll ist es, Bedingungen auch explizit im Programm zu schreiben, dafür gibt es "assert". In Deinem Fall also:
Code: Alles auswählen
assert rechnen(balance,annualInterestRate,high) > 0, "Funktionswert bei high zu klein %f" % rechnen(balance,annualInterestRate,high)
assert rechnen(balance,annualInterestRate,low) < 0, "Funktionswert bei low zu groß %f" % rechnen(balance,annualInterestRate,low)
Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Mittwoch 27. Januar 2016, 12:13
von Chris79
@Sirius3:
ähm ja danke. Da ich erst seit 2Wochen in der Mateire drinnen bin, kann ich dir bei dem Vorschlag nicht ganz folgen bzw verstehe ihn einfahc nicht
Ich habe es weiter angepasst aber irgendwie habe ich wohl noch einen denkfehler bei der if clause
epsilon habe ich eingefügt weil eine abweichung von ein paar cent ok sind
Code: Alles auswählen
balance = 320000
annualInterestRate = 0.2
epsilon = 0.01
low = balance/12.0
high = (balance*(1+annualInterestRate/12)**12)/12
guess = (low + high)/2
def rechnen(
balance,anualInterestRate,guess):
i = 0
while i < 12:
i = i+1
balance = (balance - guess) + ((balance - guess)*(anualInterestRate/12))
return balance
balance1 = rechnen(balance,annualInterestRate,guess)
i = 0
while abs(balance1 - guess) >= epsilon:
if balance1 > guess:
high = guess
else:
low = guess
guess = (low+high)/2
balance1 = rechnen(balance,annualInterestRate,guess)
print 'guess:',round(guess,2)
Falls es jemanden interessiert habe ich zu der Aufgabe auch Testcases bekommen:
Test Case 1:
balance = 320000
annualInterestRate = 0.2
Result Your Code Should Generate:
-------------------
Lowest Payment: 29157.09
Test Case 2:
balance = 999999
annualInterestRate = 0.18
Result Your Code Should Generate:
-------------------
Lowest Payment: 90325.03
Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Mittwoch 27. Januar 2016, 13:15
von Sirius3
@Chirs79: So viel zu folgen gibt es nicht; Du prüfst am Anfang, ob die Startwerte so sind, dass das Verfahren konvergiert. Statt i händisch zu zählen solltest Du eine for-Schleife benutzen
Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Mittwoch 27. Januar 2016, 14:38
von eckhard
Eine Frage zur Zeile 25:
rechnen wird immer mit dem sich nicht ändernden Wert balance gefüttert.
Dann wird rechnen auch immer den gleichen Wert liefern.
Sollte es vielleicht
heißen?
Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Mittwoch 27. Januar 2016, 15:16
von Chris79
eckhard hat geschrieben:Eine Frage zur Zeile 25:
rechnen wird immer mit dem sich nicht ändernden Wert balance gefüttert.
Dann wird rechnen auch immer den gleichen Wert liefern.
Sollte es vielleicht
heißen?
Hi,
das ist korrekt das der wert sich nicht ändert da sich guess ändert.
Balance ist fest vorgegeben sowie annualInterestRate
Es geht dabei um die Abzahlung einer Kreditkarte/dahrlehen etc.
Balance ist die Schuld am Tag 0. Nach einem Jahr soll alles abbezahlt sein.
Um dies unter berücksichtigung der Monatlichen Zinsen zu berechnen soll erstmal mit guees = (high+low)2 ein startwert als annahme erzeugt werden
Die Berechnung läuft dann 12mal durhc (1 JAhr) und hat im optimalfall am ende eine balance1 von 0
liegt der Wert über 0 (zu wenig abbezhalt) muss also mein low höher werden um ein neues mittel zu finden, bei balance1 < 0 also zuviel bezahlt muss mein high niedriger werden
Ich hoffe ich konnt so etwas Klarheit schaffen
Danke für das interesse

Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Freitag 29. Januar 2016, 10:39
von Chris79
So.
Erstmal vielen Dank für die Unterstützung.
Mittlerweile ist das Problem gelöst.
Was waren meine Fehler?:
1. bei der Startdefinition "high" fehlte vorne eine Klammer
2. bei der "Umformulierung der Funktion rechnen() von xyz zu sprechenden Namen ist mir ein Fehler unterlaufen
3. Währen der Fehlersuche vertauschte ich dann hin und wieder mal high und low in der if abfrage und veränderter die while Bedingung weil ich den Fehler dort vermutete
Kann ich das Thema irgendwie auf gelöst setzen?
Hier nun der Funktionierende Code:
Code: Alles auswählen
balance = 999999
annualInterestRate = 0.18
epsilon = 0.05
low = balance/12.0
high = (balance*(1+annualInterestRate/12)**12)/12
guess = (low + high)/2
def rechnen(x,y,z): #x=balance, y=anualInterestRate, z=guess
i = 0
while i < 12:
i = i+1
x = (x - z) + ((x - z)*(y/12))
return x
balance1 = rechnen(balance,annualInterestRate,guess)
while abs(balance1) >= epsilon:
if balance1 > 0.00:
low = guess
else:
high = guess
guess = (low+high)/2
balance1 = rechnen(balance,annualInterestRate,guess)
print 'Lowest Payment:',round(guess,2)
Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Freitag 29. Januar 2016, 14:33
von BlackJack
@Chirs79: Die Themen werden hier üblicherweise nicht als gelöst markiert.
Wenn man `high` nicht so kompliziert macht, dann kann man auch keinen Fehler machen. Ich hätte da einfach den Gesamtbetrag genommen, denn da sieht man sofort ohne lange über eine Formel nachdenken zu müssen, dass der Betrag grösser ist als der optimale Betrag pro Monat.
Code: Alles auswählen
#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
def calculate_one_year(balance, annual_interest_rate, monthly_payment):
for _ in xrange(12):
balance -= monthly_payment
balance *= 1 + annual_interest_rate / 12
return balance
def calculate_lowest_monthly_payment(balance, annual_interest_rate):
lower_limit = balance / 12
upper_limit = balance
monthly_payment = 0.01 # Just in case `balance` is very small.
while abs(lower_limit - upper_limit) >= 0.001:
monthly_payment = (lower_limit + upper_limit) / 2
if calculate_one_year(
balance, annual_interest_rate, monthly_payment
) > 0:
lower_limit = monthly_payment
else:
upper_limit = monthly_payment
return monthly_payment
def main():
for balance, annual_interest_rate in [(320000, 0.2), (999999, 0.18)]:
print(
'Lowest Payment: {0:.2f}'.format(
calculate_lowest_monthly_payment(balance, annual_interest_rate)
)
)
if __name__ == '__main__':
main()
Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Freitag 29. Januar 2016, 14:43
von Sirius3
@Chirs79: ein "gelöst" gibt es hier nicht, weil es immer noch etwas zu sagen gibt
z.B: auf oberster Ebene sollte nichts außer Konstanten und Definitionen stehen, die Variablennamen in rechnen sollten mehr Aussagekraft haben, statt sie in einem Kommentar erklären zu müssen. Statt while solltest Du eine for-Schleife verwenden. Durch Umwandeln in eine while-True-Schleife spart man sich kopierten Code. Statt explizit zu runden läßt man das die Stringformatierung machen:
Code: Alles auswählen
def rechnen(balance,anualInterestRate,guess):
for _ in range(12):
balance = (balance - guess) * (1 + anualInterestRate/12)
return balance
def main():
balance = 999999
annualInterestRate = 0.18
epsilon = 0.05
low = balance/12.0
high = (balance*(1+annualInterestRate/12)**12)/12
while True:
guess = (low + high) / 2
balance1 = rechnen(balance, annualInterestRate, guess)
if abs(balance1) < epsilon:
break
if balance1 > 0:
low = guess
else:
high = guess
print 'Lowest Payment: %.2f' % guess
if __name__ == '__main__':
main()
Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Freitag 29. Januar 2016, 16:35
von Chris79
Dann hole ich mal aus:
WOW
Meins sieht gewollt aus und deins gekonnt
Ich habe aber noch kleine Fragen dazu:
Der Underscore ist das eine Variable wie wenn ich i benutzen würde oder hat das noch ne andere Beudeutung?
Oder ist das einfach State of the art oder sozusagen dein persönlicher Favorit?
das versteh ich irgendiwe nicht so ganz. Klar ist das der "Startbefehl" aber das __name__ == ergibt sich mir nicht
Gruß Chris
P.S.: Ist es eigentlich Möglich den Usernamen im Forum zu ändern? Haben ne Wuchstaben Verbechselung drinne

Chirs79 -> Chris79 ?
Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Freitag 29. Januar 2016, 17:45
von DasIch
Chirs79 hat geschrieben:Der Underscore ist das eine Variable wie wenn ich i benutzen würde oder hat das noch ne andere Beudeutung?
Ja. Es ist nur eine reguläre Variable aber man benutzt _ per Konvention für Variablen die man anlegen muss aber nicht benutzt werden.
Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Freitag 29. Januar 2016, 18:06
von Chris79
DasIch hat geschrieben:Chirs79 hat geschrieben:Der Underscore ist das eine Variable wie wenn ich i benutzen würde oder hat das noch ne andere Beudeutung?
Ja. Es ist nur eine reguläre Variable aber man benutzt _ per Konvention für Variablen die man anlegen muss aber nicht benutzt werden.
Ok, danke, das habe ich verstanden

Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Sonntag 31. Januar 2016, 02:56
von Chris79
Chirs79 hat geschrieben:
das versteh ich irgendiwe nicht so ganz. Klar ist das der "Startbefehl" aber das __name__ == ergibt sich mir nicht
Gruß Chris
P.S.: Ist es eigentlich Möglich den Usernamen im Forum zu ändern? Haben ne Wuchstaben Verbechselung drinne

Chirs79 -> Chris79 ?
Kann mir bitte das nochmal jemand näher bringen?
Danke
Re: [Anfänger] Variable wird nciht mehr gebunden
Verfasst: Sonntag 31. Januar 2016, 04:34
von DasIch
__name__ ist eine Variable die vom Interpreter definiert wird und ist ein String mit dem Namen des Moduls. Wenn das Modul direkt ausgeführt wird anstatt importiert zu werden, ist der Name des Moduls __main__. Die if Konstruktion führt also main() nur aus wenn das Modul direkt ausgeführt wird und nicht wenn es importiert wird.