einfache While-Schleife

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
AlohaBanane
Beiträge: 8
Registriert: So 16. Okt 2011, 08:42

einfache While-Schleife

Beitrag von AlohaBanane »

Hallo zusammen,

soll für die Uni ein Programm schreiben, dass wie folgt aussieht:

Eine Maschine kostet 120.000€. Man kann pro Monat 3.000€ zurückzahlen. Die Bank nimmt von diesen 3.000€ einen Jahresprozentsatz von 7%, sprich pro Monat 7% von 1/12 der 3.000€. Nach wie vielen Monaten macht man letztendlich Gewinn mit der Maschine?

Habe das Programm geschrieben und es funktioniert auch alles (hat mich echt gewundert :roll: ). Nun stellt sich die Frage, ob das überhaupt stimmt, was ich gerechnet habe, bzw. die Ausgabe der Monate stimmt. Würde mich echt freuen, wenn ihr da Mal einen Blick drüber werfen könntet.

Code: Alles auswählen

var
       k      : single;   {Kapital}
       zpm : single;   {Zurück zu zahlender Betrag pro Monat}
       z      : single;   {Verlangte Bankzinsen}
       t      : single;   {Tilgungsbetrag pro Monat}
       m     : single;   {Monate}
 
begin
 
    writeln ('Wie viel Kapital haben Sie sich von der Bank geliehen?');
    readln  (k);
    writeln ('Wie viel Geld koennen Sie pro Monat zurueckzahlen?');
    readln  (zpm);
    writeln ('Wie hoch sind die von der Bank angesetzten Zinsen?');
    writeln ('(Bsp: fuer 7% bitte nur die Zahl 7 eingeben)');
    readln  (z);
 
          while k > 0 do
          begin
             t     := zpm-(((k/12)/100)*z);
             k    := k-t;
             m   := m+1;
          end;
 
    writeln  ('Nach' ,m, 'Monaten haben Sie ihr Kapital ganz zurueckgezahlt');
    readln;
 
end.
Zuletzt geändert von Lori am Mi 16. Nov 2011, 22:27, insgesamt 1-mal geändert.
Grund: Highlighter

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: einfache While-Schleife

Beitrag von MAC »

Hallo.

Also ich finde das Programm ist eigentlich richtig (im Kopf durchgegangen...)
Was gibt es denn für einfache Eingaben aus ?
z.b
Du leihst 1000 € kannst 500 € zurückzahlen und musst 10% zinsen zahlen ?

3 Verbesserungen fallen mir im moment noch ein:
1. Die Variable m ist nicht initialisiert (bedeutet, es wird m = m + 1 aufgerufen, vorher ist aber noch gar nicht klar welchen anfangswert m hat).
Meistens ist der Anfangswert 0, muss aber nicht.
Würdest du vor begin der while schleife ein

Code: Alles auswählen

m := 0;
einfügen wärst du auf der sicheren seite.
2. EIne ausgabe wäre nicht schlecht wieviel Euro man den noch am letzten Monat übrig hat.
Dazu muss man nur die Zahl -1*k ausgeben. Mit

Code: Alles auswählen

InttoStr(-1*k)  {evt FloattoStr(-1*k), ka genau was bei single kommen muss}
kann man die zahl in einen Text umwandeln um sie dann auszugenen (Es kann sein das es auch so geht ich kenn mich mit konsolenanwendungen nicht aus, nur mit der gui...)
3. Es sollte ne wahnung geben, wenn der Zinssatz so gros ist , das das monatliche Einkommen ganz aufgebraucht wird, würde man den Kredit nicht abarbeiten können (wenn größer würde man in die "Schuldenfall" tappen).
ein

Code: Alles auswählen

if t < 0 then writeln ('Warnung...');
sollte in der While schleife platziert sein.
Darauf hin müsste man die schleife mit

Code: Alles auswählen

break;
abbrechen, da sie sonnst unendlich lange arbeiten würde...

Ach ja, schön das du den Quellcode grün gefärbt hast, es geht aber noch einfacher: Einfach makieren und im Editor im "Highlighter" auf "Freepascal/Lazarus" umstellen

Code: Alles auswählen

Signatur := nil;

AlohaBanane
Beiträge: 8
Registriert: So 16. Okt 2011, 08:42

Re: einfache While-Schleife

Beitrag von AlohaBanane »

Hey! Danke für deine Tipps! Jetzt klappt alles. Das mit dem if, then, else klappt nun auch hervorragend :wink:

Er gibt mir (für meine jetzige Aufgabe) aus, dass ich nach 46 Monaten alles zurückbezahlt hätte. Muss nur noch en letzten Tilgungsbetrag einbringen, dann ist es perfekt.

Code: Alles auswählen

var
       k   : single; {Kapital}
       zpm : single; {Zurück zu zahlender Betrag pro Monat}
       z   : single; {Verlangte Bankzinsen}
       t   : single; {Tilgungsbetrag pro Monat}
       m   : single; {Monate}
 
begin
 
    writeln ('Wie viel Kapital haben Sie sich von der Bank geliehen?');
    readln  (k);
    writeln ('Wie viel Geld koennen Sie pro Monat zurueckzahlen?');
    readln  (zpm);
    writeln ('Wie hoch sind die von der Bank angesetzten Zinsen?');
    writeln ('(Bsp: fuer 7% bitte nur die Zahl 7 eingeben)');
    readln  (z);
 
    m:=0;
 
    while k > 0 do
 
    begin
       t := zpm-(((k/12)/100)*z);
       k := k-t;
 
       if t < 0 then
 
          begin
          writeln ('Warnung! Sie tappen in die Schuldenfalle!!');
          readln;
          break;
          end
 
       else
 
           begin
           m := m+1;
           end
 
    end;
 
    writeln  ('Nach' ,m, 'Monaten haben Sie ihr Kapital ganz zurueckgezahlt');
    readln;
 
end.

Bauer321
Beiträge: 465
Registriert: Sa 21. Aug 2010, 21:30
OS, Lazarus, FPC: Windows 7 Ultimate (L 1.2.2 FPC 2.6.4 32-bit)
CPU-Target: 64-Bit
Wohnort: nahe Bremen
Kontaktdaten:

Re: einfache While-Schleife

Beitrag von Bauer321 »

ich habe das ganze mal eben getestet. du solltest die ausgabe am ende evtl noch formatieren, da das ganze so ein wenig verwirrend ist (finde ich)

"Eine Maschine kostet 120.000€. Man kann pro Monat 3.000€ zurückzahlen. Die Bank nimmt von diesen 3.000€ einen Jahresprozentsatz von 7%, sprich pro Monat 7% von 1/12 der 3.000€. Nach wie vielen Monaten macht man letztendlich Gewinn mit der Maschine?"
Macht das Programm nicht was anderes? Du schreibst hier das die Zinsen von den 3000 und nicht von den 120000€ genommen werden. Nur ein Tippfehler? Wenn nicht musst du das im Programm auch so machen.
Momentan nimmst du ja z Prozenz vom gesamten Kapital(ist eigentlich auch üblich) (t := zpm-(((k/12)/100)*z);)
www.mcpatcher.net | www.hoeper.me

AlohaBanane
Beiträge: 8
Registriert: So 16. Okt 2011, 08:42

Re: einfache While-Schleife

Beitrag von AlohaBanane »

War nur ein Tippfehler. Meine natürlich 7% von 1/12 des aktuellen Kredites. Wie bekomme ich denn die Ausgabe am Ende gerundet? Einfach mit round? wie müsste ich dass dann hinschreiben?

Jochen
Beiträge: 35
Registriert: So 30. Nov 2008, 23:35

Re: einfache While-Schleife

Beitrag von Jochen »

Code: Alles auswählen

uses
  math, // für intpower()
  ...
 
var
  digits:integer;
  ...
 
begin
  ...
  {Ausgabe runden}
  digits := 3; // Anzahl Nachkommastellen NKS
  m := round(m * intpower(10, digits)) / intpower(10, digits); // Zahl:=Runden(Zahl*10^NKS)*10^NKS
  Write(m: 8 + digits: digits); // Variable: Anzahl Gesamtstellen: Anzahl Nachkommastellen
  readln;
 
end.
http://lazarus-ccr.sourceforge.net/docs ... round.html
http://lazarus-ccr.sourceforge.net/docs ... power.html
http://lazarus-ccr.sourceforge.net/docs ... write.html

Da es bei solchen "kleinen" Programmen nicht so sehr auf den Speicherbedarf ankommt, würde ich aus dem Typ Single einen größeren machen. Sonst kommt man bei hohen Beträgen schnell an die Grenze. Der Typ Currency würde sich anbieten. :wink:
http://lazarus-ccr.sourceforge.net/fpcd ... 300003.1.2

Code: Alles auswählen

InttoStr(-1*k)  {evt FloattoStr(-1*k), ka genau was bei single kommen muss}
Natürlich FloatToStr(), da Single ein Fließkomma-Typ ist.

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: einfache While-Schleife

Beitrag von MAC »

Ich wusste echt nicht genau was single für ein tp ist :D ich arbeite eigt immer nur mit real :D

mit
k := round(k); wird k gerundet und das ergebnis der Runde Funktion in k gespeichert...
mit einen einfachen trick kannst du auf 1 nachkommastelle runden:
k := round(k*10)/10; da jetzt der wert k*10 gerundet wird und der gerundete wert durch 10 gerechnet wird... (Joachims funktion ist ähnlich , wobei es dort möglich ist die anzahl der stellen einfach zu variieren... )

Code: Alles auswählen

Signatur := nil;

AlohaBanane
Beiträge: 8
Registriert: So 16. Okt 2011, 08:42

Re: einfache While-Schleife

Beitrag von AlohaBanane »

Super. Alles wunderbar. Nur noch eine kleine Sache: Ich möchte das Erbenis (also die im Beispiel erwähnten 46 Monate) auch gerne in Jahren ausgeben, also z.B. i = m/12. Nun ist aber das Problem, dass wenn ich dieses Ergebnis auch runden möchte (diesmal aber auf 2 nachkommastellen) mir das Programm dann auch die 46 Monate mit 2 Nachkommastellen ausgibt, also 46.00. Ist ja auch klar, denn ich kann ja schlecht zwei Mal den selben Befehl mit unterschiedlichen Anweisungen angeben, also einmal

Code: Alles auswählen

digits := 0;
für 46 Monate und

Code: Alles auswählen

digits := 2;
für die Jahre. Pascal übernimmt einfach den letzteren Befehl für beide Ausgaben. Wie kann ich das noch ändern?

Vielen Dank für eure Mithilfe. Ihr erleichtert mir echt den Einstig ins Programmieren :D

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: einfache While-Schleife

Beitrag von MAC »

Doch das kannst du :)
es wär am besten wenn du mal den gesammten quellcode in dem das Runden und so gemacht wird nochmal schreibst, bzw wie du meinst...
Pascal geht die Anweisungen nach der reihe durch: heist wird digits erst 0 gesetzt, dann 2 gesetzt und dann abgefragt ist es 2.
Du kannst es aber auch 0 setzen, einmal abfragen(1.Abfrage), dann 2 setzten und nochmal abfragen (2te Abfrage).

Code: Alles auswählen

//Pseudocode
digits := 0;
//Round
//ausgabe 1
digits := 2;
//Round;
// Ausgabe 2

Code: Alles auswählen

Signatur := nil;

AlohaBanane
Beiträge: 8
Registriert: So 16. Okt 2011, 08:42

Re: einfache While-Schleife

Beitrag von AlohaBanane »

Und wieder kann ich mich nur bedanken. Nun gehts noch ein bisschen an die Optik (oder je nachdem, wie "schön" man ein cmd Feld gestalten kann). Schriftfarbe kann ich schon wechseln. Aber kann man auch die Maße des cmd Feldes festlegen, sodass das Programm auch genau hineinpasst und nicht noch die Hälfte unnötig schwarz ist? Oder müsste man dann eine eigene Schaltfläche zusammenbasteln mit Buttons und so weiter?

Kann auch nach erfolgreicher Gestaltung das Prog hier rein kopieren, wenn ihr das Mal ausprobieren wollt...

Jochen
Beiträge: 35
Registriert: So 30. Nov 2008, 23:35

Re: einfache While-Schleife

Beitrag von Jochen »

es wär am besten wenn du mal den gesammten quellcode in dem das Runden und so gemacht wird nochmal schreibst, ...
?
Ist ja auch klar, denn ich kann ja schlecht zwei Mal den selben Befehl mit unterschiedlichen Anweisungen angeben, ...
Natürlich kannst du das. Pack das Runden in eine Funktion, die du dann mit verschiedenen Werten aufrufen kannst.
Runden brauchst du die Monate eigentlich nicht, nur formatieren. m beginnt bei 0 und wird immer 1 hochgezählt.
Bei der Warnung mit der Schuldenfalle würde ich das ganze Programm beenden, sonst kommt noch die Ausgabe am Ende.

Zum Verschönern: die Unit Crt gibt ein paar Sachen her. Binde sie unter uses ein. Auf die Schnelle (unter Linux) hab ich das hier hin bekommen:

Code: Alles auswählen

begin
  Window(5,5,75,20); // erzeugt einen Bereich im Fenster
  TextBackground(Blue); // Farbe Hintergrund
  TextColor(Yellow); // Farbe Text
  ClrScr; // Bereich löschen
{... Programm}
Morgen versuche ich mal wie es unter Windows aussieht.

Jochen
Beiträge: 35
Registriert: So 30. Nov 2008, 23:35

Re: einfache While-Schleife

Beitrag von Jochen »

ach ja, Crt hat noch mehr. Oft sieht man ja, dass am Ende eines Programms steht: "press any key to exit ...", oder so. Leider klappt das mit readln() nicht. Aber hiermit:

Code: Alles auswählen

WriteLn();
Write('Beliebige Taste zum Beenden ... ');
repeat
until KeyPressed; // leere Schleife bis eine Taste gedrückt wurde
while KeyPressed do // leert den Puffer der Tastatur
begin ReadKey end;

Antworten