Zeilenabstand Programmausgabe DOS-Shell

Für Fragen von Einsteigern und Programmieranfängern...
Neuling
Beiträge: 33
Registriert: Do 30. Dez 2021, 01:08
OS, Lazarus, FPC: Windows 10 (L 2.2.0 FPC 3.2.2)
CPU-Target: 64Bit

Zeilenabstand Programmausgabe DOS-Shell

Beitrag von Neuling »

Hallo,

ich habe vor einer Woche angefangen zu programmieren. Dementsprechend mäßig sind meine Kenntnisse. Ich habe ein kleines ( ca. 600 Zeilen ) Programm erstellt, in dem ich mit Prozeduren, Funktionen und Variablen spiele. Die Ausgabe der Rechnungen läuft über die DOS-Shell, außerdem werden die Werte optional in eine Datei geschrieben. Bei der Ausgabe auf dem Bildschirm soll der Zeilenabstand konstant sein. Das funktioniert aber nur, wenn der Wert der Variable "speichern" "true" ist. Um lange Erklärungen zu vermeiden habe ich den Quellcode als Anhang meines Post mitgeliefert. Das Programm ist bei Ausführung selbsterklärend. Das Problem zeigt sich, wenn man die Option speichern überspringt, im zweiten Durchlauf speichert und dann beim dritten Durchlauf wieder auf speichern verzichtet. Ich würde mich freuen, wenn jemand eine Erklärung für dieses - für mich nicht nachvollziehbare - Verhalten des Programmes zu bieten hätte.
Dateianhänge
Collatz_Muell.pas
(15.6 KiB) 37-mal heruntergeladen
Collatz_Muell.lpi
(1.58 KiB) 29-mal heruntergeladen
Ich nehme jede berechtigte Kritik an. Es sei denn, diese fällt von oben herab vor meine Füße.
Programmieren macht Spaß.

Neuling
Beiträge: 33
Registriert: Do 30. Dez 2021, 01:08
OS, Lazarus, FPC: Windows 10 (L 2.2.0 FPC 3.2.2)
CPU-Target: 64Bit

Re: Zeilenabstand Programmausgabe DOS-Shell

Beitrag von Neuling »

Ich vergaß, mich für eventuelle Antworten zu bedanken. Was ich hiermit ausdrücklich mache.
Ich nehme jede berechtigte Kritik an. Es sei denn, diese fällt von oben herab vor meine Füße.
Programmieren macht Spaß.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 5069
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: Zeilenabstand Programmausgabe DOS-Shell

Beitrag von af0815 »

Ich verstehe die Frage nicht wirklich. Was soll der Zeilenabstand gleich sein ?

In Lazarus kann man ein Programm debuggen.

https://www.youtube.com/watch?v=LZ90IBa9_8M
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Neuling
Beiträge: 33
Registriert: Do 30. Dez 2021, 01:08
OS, Lazarus, FPC: Windows 10 (L 2.2.0 FPC 3.2.2)
CPU-Target: 64Bit

Re: Zeilenabstand Programmausgabe DOS-Shell

Beitrag von Neuling »

Danke für die Antwort. Ich werde mir das Video morgen anschauen. Aber der Debugger läuft doch automatisch, wenn man das Programm kompiliert und startet.
Ich nehme jede berechtigte Kritik an. Es sei denn, diese fällt von oben herab vor meine Füße.
Programmieren macht Spaß.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 5069
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: Zeilenabstand Programmausgabe DOS-Shell

Beitrag von af0815 »

Ja, mit dem Debugger kann man das Programm Schritt für Schritt ausführen und sich auch den Inhalt von Variablen ansehen. Weiter kann man Breakpoints setzen, dort wird das Programm angehalten und man auch die Variablen kontrollieren. Damit kann man feststellen warum sein Programm nicht so reagiert wie man will.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Neuling
Beiträge: 33
Registriert: Do 30. Dez 2021, 01:08
OS, Lazarus, FPC: Windows 10 (L 2.2.0 FPC 3.2.2)
CPU-Target: 64Bit

Re: Zeilenabstand Programmausgabe DOS-Shell

Beitrag von Neuling »

Danke. Das habe ich aber schon gemacht, indem ich die Variablen jeweils in die Shell ausgelesen habe. Aber mit dem Debugger ist das sicher einfacher. Ich habe mir ein zweibändiges Lehrbuch über Lazarus/Free Pascal bestellt. Damit ich mich nicht wieder Stundenlang mit einem Problem herumschlagen muss. Von den ca. 80 Stunden, die ich mich bisher mit Programmierung beschäftigt habe, musste ich ca, 10 für dieses Problem aufwenden. Ich werde heute noch einmal nach einer Lösung suchen. Vielleicht hat ja jemand aus eigener Erfahrung eine Erklärung für dieses merkwürdige Verhalten zu bieten. Guten Rutsch.
Ich nehme jede berechtigte Kritik an. Es sei denn, diese fällt von oben herab vor meine Füße.
Programmieren macht Spaß.

Benutzeravatar
h-elsner
Beiträge: 180
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint18.3, Win10, Lazarus 2.0.12, FPC3.2.0
CPU-Target: 64Bit
Wohnort: Illertissen
Kontaktdaten:

Re: Zeilenabstand Programmausgabe DOS-Shell

Beitrag von h-elsner »

Das Problem mit dem Zeilenabstand verstehe ich nicht und kann ich auch nicht nachstellen. Wird denn nicht der Zeilenabstand vom Terminalprogramm selbst bestimmt? Oder geht es vielleicht um zufällige Leerzeilen? Keine Ahnung, ich sehe wie gesagt da nichts auffälliges.
Mir stört beim Testen allerdings die umständliche Bedienung auf. Muss es denn wirklich ein Terminalprogramm sein?

Mir ist aber ein Problem aufgefallen. Der automatisch generierte Dateiname aus der Zahl, hat manchmal Leerzeichen vor der Nummer. Das kann man in Windows nicht mehr umbenennen. Das geht nur in Linux.
In dem Zusammenhang ist mir aufgefallen, dass einige Variablen gar nicht initalisiert sind, d.h. sie können zufällige Werte haben. Beim Speichern zum Beispiel der Pfad, was die Leerzeichen im Dateinamen erklären könnte. Wenn ich mit Variablen arbeite, sollten die immer einen definierten Wert haben.

Gruß HE

Neuling
Beiträge: 33
Registriert: Do 30. Dez 2021, 01:08
OS, Lazarus, FPC: Windows 10 (L 2.2.0 FPC 3.2.2)
CPU-Target: 64Bit

Re: Zeilenabstand Programmausgabe DOS-Shell

Beitrag von Neuling »

Danke für die Antwort. Ich werde in Zukunft darauf achten alle Variablen zu initialisieren. Auch werde ich den Lernprozess systematischer gestalten. Und meine Ideen nicht einfach so umsetzen. Einen guten Rutsch wünsche ich.

Neuling
Ich nehme jede berechtigte Kritik an. Es sei denn, diese fällt von oben herab vor meine Füße.
Programmieren macht Spaß.

Benutzeravatar
h-elsner
Beiträge: 180
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint18.3, Win10, Lazarus 2.0.12, FPC3.2.0
CPU-Target: 64Bit
Wohnort: Illertissen
Kontaktdaten:

Re: Zeilenabstand Programmausgabe DOS-Shell

Beitrag von h-elsner »

Warum sollte man Ideen nicht einfach umsetzen. Der Lerneffekt ist riesig. Ich habe auch keine Ahnung, frue mich aber, dass wieder etwas geht. Ist nich alles elegant und ich lerne hier immer was. Meine Frau lacht schon über mich, wenn ich jedesmal, wenn ich im Forum etwas lese, meine Programme umschreibe.
Meist ist xyz_wp der Auslöser für die "Mehrarbeit".

Ich habe mir mal dein Programm näher angeschaut, weil ich das interessant finde. Hatte vorher noch nie etwas von Hern Collatz gehört. Deshalb verstehe ich auch nicht alles, was du da machst. Ein paar Dinge sind mir aber doch aufgefallen.

- die globale Variable 'prim', wofür ist die? Du verwendest sie nur einmal, könntest aber auch dor den Rückgabewert der Funktion IstPrim verwenden. Das hast du ja sonst auch gemacht.
- du hast Proceduren, wo du die zu testende Zahl übergibst. OK. Aber warum mixt du dann die die Variable 'zuTesten' rein? Dies ist meiner Meinung nach fehleranfällig und unübersichtlich. Einmal übergeben und dann konsequent nutzen ist deutlich besser. Beispiel: Zeile 89.
- du rufst eine Funktion auf und verwendest das Ergebnis nicht. Zu welchem Zweck. Dann ruft du die Funktion noch einzweites Mal auf und benutzt das Ergebnis. Der erste Aufruf ist damit komplett sinnlos, oder verstehe ich da etwas falsch? Beispiel Zeilen 278/279. Kommt aber öfters vor und geht massiv auf die Laufzeit.
- Das Konstrukt "write(textDatei,'',i,'');" verstehe ich nicht. Wozu sind die '' ? Ich benutze write/writeln ganz selten, vielleicht braucht man das, aber für mich sieht das so aus, als ob das Weglassen keinen Unterschied machen würde?

Aus Spaß und weil ich dein Programm irgendwie cool finde, habe ich mal eine GUI drumherum gebaut. Vielleicht kannst du mal testen, ob das funktioniert, speziell "procedure CollatzAllgemein(n: integer);" Das ist nämlich etwas, wo ich die Mathematik nicht verstehe. Da muss ich mich erst noch einlesen.
Macht das überhaupt Sinn, was ich da als Oberfläche für die Eingabe gemacht habe?
Collatz1.zip
(4.44 KiB) 23-mal heruntergeladen
Gruß HE

Neuling
Beiträge: 33
Registriert: Do 30. Dez 2021, 01:08
OS, Lazarus, FPC: Windows 10 (L 2.2.0 FPC 3.2.2)
CPU-Target: 64Bit

Re: Zeilenabstand Programmausgabe DOS-Shell

Beitrag von Neuling »

Danke für die Antwort. Die zusätzlichen Variablen habe ich eingeführt um - wenn ich eine andere Zahl testen will, das Ergebnis der ersten später noch brauche - ein wiederholtes ausführen der Funktion zu vermeiden. Das Programm ist zudem noch lange nicht fertig.

Letztendlich geht es um Collatz Folgen. Nehme eine natürliche Zahl. Ist diese gerade, dann teile durch 2. Ist die Zahl ungerade, dann rechne 3*n+1. Es wird vermutet, dass jede nat. Zahl letztendlich zu der Schleife 4,2,1,4,2,1,4... führt.

Die Prozedur CollatzAllg dient nur dazu herauszufinden, für welche Zahlen a, b die Folge in eine Schleife hineinführt.
Also : N2 = N1/2 wenn N gerade,

N2 = a*N1+b wenn N1 ungerade.

Dazu habe ich zwei Prozeduren geschrieben, die bis zu 26 aufeinanderfolgende Berechnungsergebnisse dahingehend untersucht, ob sich eine Zahl wiederholt. WerteSchieben und Werte Vergleichen. Das hieße nämlich, das die Rechnung in eine Schleife "eingelaufen" ist. Dann wird die Berechnung abgebrochen. Meine Lösung ist nicht sehr elegant, müsste man z. B. eine große Zahl an Rechenergebnissen vergleichen, dann würde viel Zeit für die Implementierung draufgehen. Deshalb werde ich nach einer Lösung mit Strings suchen. Ich bin, wie gesagt, noch blutiger Anfänger.

Den Quellcode habe ich angehängt. Danke für die GUI, damit fange ich auch bald an. Ich werde mir das ganze am Wochenende anschauen. Wenn ich die Basics verstanden habe.
Dateianhänge
Collatz_Hurra_1_Int64.pas
(21.51 KiB) 29-mal heruntergeladen
Collatz_Hurra_1_Int64.lpi
(2 KiB) 28-mal heruntergeladen
Ich nehme jede berechtigte Kritik an. Es sei denn, diese fällt von oben herab vor meine Füße.
Programmieren macht Spaß.

Benutzeravatar
h-elsner
Beiträge: 180
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint18.3, Win10, Lazarus 2.0.12, FPC3.2.0
CPU-Target: 64Bit
Wohnort: Illertissen
Kontaktdaten:

Re: Zeilenabstand Programmausgabe DOS-Shell

Beitrag von h-elsner »

Wenn du nichts dagegen hast, würde ich gerne an deinem Projekt "dranbleiben".

Hier meine Anmerkungen:
- Globale Variablen nur da benutzen, wo es unbeding notwendig ist. prim, quad usw. sind es definitiv nicht. Du ruft die function dort wo du es benutzt einmal auf und merkst dir das Ergebnis in der jeweiligen procedure oder funktion mittels einer lokalen Variable. Der Grund ist, dass globale Variablen immer ein Gefahr für Programmfehler ist.
- die Variablen a1..z1 würde ich durch eine array of int64 ersetzen und möglichst auch als lokale Variable wo du es benutzt. Erweiterungen sind dann ganz einfach möglich.

Sich mit Arrays zu beschäftigen ist erst einmal schwierig, aber wenn man es macht, hat man riesige Vorteile bei allen möglichen Berechnungen. In deinem Falle würde ich mir sogar eine eigene Variable "erschaffen" hinter der sich das Array verbirgt, weil man dann diese Variable an Prozeduren und Funktionen übergeben kann. Nach dem ich das richtig begriffen hatte, finde ich das sehr elegant und nützlich. Sofort klar war mir das allerdings auch nicht, das hat eine Weile gedauert.

Gruß HE

Benutzeravatar
h-elsner
Beiträge: 180
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint18.3, Win10, Lazarus 2.0.12, FPC3.2.0
CPU-Target: 64Bit
Wohnort: Illertissen
Kontaktdaten:

Re: Zeilenabstand Programmausgabe DOS-Shell

Beitrag von h-elsner »

Ungetestet würde das dann etwa so aussehen:

Code: Alles auswählen


const
  AnzahlErg=20;  {Anzahl Ergebnisse, hier kann man einfach ändern, wieviele Ergebbnisse man vergleichen will}

type
  TCollatz = array [0..AnzahlErg] of int64;    {Ein Variablentyp für eine Reihe von Ergebnissen}

procedure WerteSchieben(var w: TCollatz);   {Hier muss das Array var sein, denn wir verändern es in der Procedure}
{w[0] ist x, w[1] ist a1, w[2] ist b1 .. w[AnzahlErg] wäre z1 bzw das letzte Glied in der Folge}
var
  i: integer;

begin
  for i:=AnzahlErg downto 1 do
    w[i]:=w[i-1];
end;

function WerteVergleich(const w: TCollatz): boolean;   {Hier ändert sich nichts am Array}
{w[1] ist a1, w[2] ist b1 .. w[AnzahlErg] wäre z1 bzw das letzte Glied in der Folge}
var
  i: integer;

begin
  result:=false;
  for i:=1 to AnzahlErg-1 do
    if (w[1]>0) and
       (w[i+1]>0) and
       (w[1]=w[i+1]) then
      result:=true;
end;
Verständnisfrage: Können auch negative Werte auftreten oder sind das alles natürliche Zahle >=0 ?
Wenn ja könnten wir den Zahlenraum erweitern, wenn wir als Variablen "QWord" nehmen. Obwohl, bei so großen Zahlen fliegt uns das laufzeitmäßg um die Ohren.

Gruß HE
Zuletzt geändert von h-elsner am Sa 8. Jan 2022, 11:04, insgesamt 3-mal geändert.

wp_xyz
Beiträge: 4241
Registriert: Fr 8. Apr 2011, 09:01

Re: Zeilenabstand Programmausgabe DOS-Shell

Beitrag von wp_xyz »

h-elsner hat geschrieben:
Mi 5. Jan 2022, 10:09

Code: Alles auswählen

const
  AnzahlErg=20;  {Anzahl Ergebnisse, hier kann man einfach ändern, wieviele Ergebbnisse man vergleichen will}

type
  TCollatz = array [0..AnzahlErg] of int64;    {Ein Variablentyp für eine Reihe von Ergebnissen}
  
Wenn ich den Bezeichner "AnzahlErg" wörtlich nehme und die Array-Elemente wie normal ab 0 indiziert sind, hat das letzte Element den Index AnzahlErg-1. Dein Array läuft aber bis AnzahlErg.

Außerdem ist in dem Code-Beispiel der erste Index 1. Warum deklarierst du das Array dann als von 0 beginnend?

Weiterhin läuft die Schleife bis AnzahlErg. In dem Code wird aber auch auf das Element mit dem Index i+1 zugegriffen, wenn die Schleife am Ende ist, also auf das Element AnzahlErg+1.

Diese winzigen Unterschiede können die Quelle von vielen Problemen sein!

Benutzeravatar
h-elsner
Beiträge: 180
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint18.3, Win10, Lazarus 2.0.12, FPC3.2.0
CPU-Target: 64Bit
Wohnort: Illertissen
Kontaktdaten:

Re: Zeilenabstand Programmausgabe DOS-Shell

Beitrag von h-elsner »

Ja, das stimmt. Beim Vergleich muss es for i:=1 to AnzahlErg-1 do ... heißen. w[0] ist im Prinzip der Überlauf beim Linksschieben des Arrays und wird bei ihm nach der Variable x geschoben. Verglichen werden im Originalprogramm die Integervariablen b1..z1 mit a1. Ich habe versucht, das 1:1 umzusetzen, aber statt x einzelne Variable zu nehmen, ein Array anzulegen, einfach um zu demonstrieren, dass der Quelltext schöner aussieht und einfacher zu warten ist.

Ich habe das oben korrigiert und noch ein paar Tippfehler entfernt.

Gruß HE

Neuling
Beiträge: 33
Registriert: Do 30. Dez 2021, 01:08
OS, Lazarus, FPC: Windows 10 (L 2.2.0 FPC 3.2.2)
CPU-Target: 64Bit

Re: Zeilenabstand Programmausgabe DOS-Shell

Beitrag von Neuling »

Hallo,
selbstverständlich können Sie " dranbleiben. Da ich in wenigen Tagen eine Umschulung zum Fachinformatiker beginne ist mir jeder Input recht. Das mit den Variablen habe ich inzwischen verstanden. Irgendwann in der nächsten Zeit werde ich das Programm dahingehend ändern. Die beiden Prozeduren WerteSchieben und WerteVergleich habe ich durch eine Funktion WerteVergleich ersetzt. Dabei werden alle Rechenergebnisse in einen String geschrieben und und das jeweils aktuelle Berechnungsergebnis mit den Werten im String verglichen.

Mit Arrays werde ich mich in den nächsten Tagen beschäftigen. Danke für den Hinweis.

Momentan versuche ich, eine Langzahlarithmetik zu bauen. Da die Berechnungsergebnisse der Prozedur CollatzAllgemein mitunter schnell groß werden. Das ist eine gute Übung in Punkto Strings.

Das verbesserte (aber noch lange nicht fertige) Programm im Anhang. Über eine Rückmeldung würde ich mich freuen. Auch im Anhang die Funktion LangzahlAddition. Nicht sehr elegant, aber hoffentlich allgemein funktional.

Gruß
Neuling
Dateianhänge
Collatz_eleganter_1_2.pas
(22.76 KiB) 26-mal heruntergeladen
Langzahlarithmetik_Addition_unelegant_test_3.pas
(2.75 KiB) 24-mal heruntergeladen
Ich nehme jede berechtigte Kritik an. Es sei denn, diese fällt von oben herab vor meine Füße.
Programmieren macht Spaß.

Antworten