Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Denkansätze (Algorithmik? richtiges Vorgehen?) (https://www.delphipraxis.net/126833-denkansaetze-algorithmik-richtiges-vorgehen.html)

julchen 3. Jan 2009 06:52


Denkansätze (Algorithmik? richtiges Vorgehen?)
 
Hallo,

habe dieses Thema Nächstes Datum errechnen gelesen und habe mir dazu ein paar Gedanken gemacht. Da ich häufig (leider) auch "irgendwelchen Unsinn" verzapfe wie
Delphi-Quellcode:
StrToDate(DateToStr(Now))
- ich nehme das jetzt mal als Beispiel-Code, weil dieses Konstrukt am häufigsten "Angesprochen" wurde - würde ich gerne von den "Profis" wissen, wie man solche "Denkfehler" vermeiden kann? Vielleicht könnt Ihr eine Lösung posten und vielleicht einmal - für Anfänger und halb- bis wenigwissende wie mich - erklären, wie die vorgehensweise wäre, um so etwas zu lösen.
Ihr könnt auch ein anderes Beispiel nehmen, wenn es pädagogisch wertvoller ist - die Gedanken sind frei!!!
Mich interessiert besonders, wie ich Programmierwissen richtig anwende und wie ich "denken" muss, um ein Problem zu lösen.
Ich hoffe, Ihr versteht, worauf ich hinaus möchte :gruebel:

An die Mods:
Sollte hier etwas konstruktives bei heraus kommen, wäre es vielleicht gut, das Thema in eine andere Rubrik hinzuschieben, wo es dauerhaft erhalten bleibt. Das überlasse ich Eurem ermessen.

Mit vielen Grüssen
julchen

[edit=Phoenix]Titel mal etwas verbessert und das ganze nach Programmieren allgemein geschoben. Mfg, Phoenix[/edit]

mkinzler 3. Jan 2009 07:24

Re: Denkansätze
 
Am Besten im Trockenen überlegen, wie man das Problem am Besten lösen kann ( z.B. auf einem Blatt Papier). Dort kann man auch einen Algorithmus auf richtige Funktion Testen ( Schreibtischtest)

DeddyH 3. Jan 2009 10:20

Re: Denkansätze
 
Genau, geeignete Mittel wären der Programmablaufplan (PAP) oder das Struktogramm.

Phoenix 3. Jan 2009 11:46

Re: Denkansätze (Algorithmik? richtiges Vorgehen?)
 
Zitat:

Zitat von julchen
Da ich häufig (leider) auch "irgendwelchen Unsinn" verzapfe wie
Delphi-Quellcode:
StrToDate(DateToStr(Now))
- ich nehme das jetzt mal als Beispiel-Code, weil dieses Konstrukt am häufigsten "Angesprochen" wurde - würde ich gerne von den "Profis" wissen, wie man solche "Denkfehler" vermeiden kann?

Okay, das ist ein grober Schnitzer.
Wer einen Datumswert in einen String konvertiert, nur um genau diesen String dann wieder in einen Datumswert zu konvertieren, der ist irgendwie merkbefreit. Natürlich funktioniert das. Nur ist 'StrToDate(DateToStr(now))' halt gleich 'now', und das kann man auch gleich hinschreiben.

Genauso der ganze Quatsch wie mit
Delphi-Quellcode:
if boolscherAusdruck = true then
oder fast noch schlimmer
Delphi-Quellcode:
if boolscherAusdruck then
  irgendwas := true
else
  irgendwas := false;
Was man ganz einfach mit
Delphi-Quellcode:
irgendwas := boolscherAusdruck;
machen kann.

Man sollte bei jedem Code den man schreibt hinterher nochmal einen guten Meter bis zwei nach hinten gehen, sich das in seiner Gesamtheit angucken und bei jedem Ausdruck fragen: Macht das wirklich Sinn? Ist das wirklich notwendig?

Oder noch besser: Solche Ausdrücke (seien es Konvertierungen, Vergleichsoperationen etc.) mal im Kopf (oder auf Papier) vollständig auswerten. Wenn man drüber nachdenkt was man macht, dann erkennt man solche unnötigen Operationen ziemlich schnell und kann sie vereinfacht darstellen. Das macht den Code übersichtlicher und damit später leichter Wartbar.

SirTwist 3. Jan 2009 13:20

Re: Denkansätze (Algorithmik? richtiges Vorgehen?)
 
Wenn ich vor einem Problem hocke und nicht weiter weiß, hilft es mir oftmals, jemand anders (der auch programmieren kann) das Problem zu erklären. Es passiert mir dann regelmäßig, dass ich am Ende der Problembeschreibung auch die Lösung weiß. Man bedankt sich dann höflich fürs zuhören, schmunzelt über das WTF-Gesicht des anderen und geht weiterprogrammieren.

Ich denke das liegt daran, dass ich mir Mühe gebe, dem anderen das Problem möglichst verständlich zu erklären. Das dürfte ähnlich zu dem "mal ein paar Meter zurückgehen" sein, was Phoenix vorgeschlagen hat.

Gruß,
SirTwist

mkinzler 3. Jan 2009 18:21

Re: Denkansätze (Algorithmik? richtiges Vorgehen?)
 
Das war ja auch mein Ansatz. Eine Lösung unabhängig vom Computer um zuerst einen allgemeinen Lösungsnsatz zu entwickeln.

kalmi01 3. Jan 2009 19:01

Re: Denkansätze (Algorithmik? richtiges Vorgehen?)
 
Zitat:

Zitat von Phoenix
Wer einen Datumswert in einen String konvertiert, nur um genau diesen String dann wieder in einen Datumswert zu konvertieren, der ist irgendwie merkbefreit. Natürlich funktioniert das. Nur ist 'StrToDate(DateToStr(now))' halt gleich 'now', und das kann man auch gleich hinschreiben.

Na ja, so ganz korrekt ist das nicht immer. Manchmal gibt auch Unsinniges einen Sinn.

In einer anderen Programmierumgebung verwende ich manchmal ein ähnliches Konstrukt: FloatToInt(IntToFloat(Zahl))
Auf den ersten Blick reichlich dämlich, ABER bei der Konvertierung IntToFloat werden Buchstaben/Zeichen ausgefiltert. Ich erhalte also IMMER mindesten 0 (null) als Rückgabe. Null führt bei der Berechnung zwar nicht zu einem Sinnvollen Ergebnis, verhindert aber den Absturz.
Was in einer Programmierumgebung, in der es kein try except-Konstrukt gibt, schon Sinn macht.

mkinzler 3. Jan 2009 19:03

Re: Denkansätze (Algorithmik? richtiges Vorgehen?)
 
Now ist aber definitv ein korrekter DateTime-Wert

kalmi01 3. Jan 2009 19:05

Re: Denkansätze (Algorithmik? richtiges Vorgehen?)
 
stimmt, aber dieser Vor-Zurück-Konvertiererei ist in diesem Thread doch nur ein Beispiel für (angeblich) unsinnigen Code.

fkerber 3. Jan 2009 19:07

Re: Denkansätze (Algorithmik? richtiges Vorgehen?)
 
Hi!

Zitat:

Zitat von SirTwist
Wenn ich vor einem Problem hocke und nicht weiter weiß, hilft es mir oftmals, jemand anders (der auch programmieren kann) das Problem zu erklären.

Ich ziehe hier meist sogar jemanden vor, der eben gerade nicht programmieren kann, da es manchmal die dämlichsten Sachen sind, die man übersieht und die ein anderer Programmierer dann auch mit "äh, das war ja wohl klar" abtut. Ein "Laie" fragt da schonmal eher nach...


Ciao, Frederic

lincore 3. Jan 2009 20:39

Re: Denkansätze (Algorithmik? richtiges Vorgehen?)
 
Zitat:

Zitat von julchen
Hallo,
Mich interessiert besonders, wie ich Programmierwissen richtig anwende und wie ich "denken" muss, um ein Problem zu lösen.
Ich hoffe, Ihr versteht, worauf ich hinaus möchte :gruebel:

Moin Julchen,

ich spare mir die Tools und praktischen Hinweise, die bereits so zahlreich erwähnt worden sind und komme gleich zum Kern meiner Aussage:
Was das vielgepriesene logische Denken anbelangt, entwickelt sich das glaube ich mit der Zeit von selbst. Ich habe mit neun Jahren angefangen, einem Second-Hand Spectrum ZX-81 (mit 16K RAM! :) meine Spielewünsche mit Basic einzubleuen (und das immer wieder, weil ich nicht begriffen hatte, wie man diesen dämlichen Kassettenrecorder benutzt um die Programme zu speichern und zu laden). Seitdem habe ich mich mit dem Programmieren als Hobby beschäftigt, und auch wenn ich diese gewisse "professionelle Barriere" nie durchbrochen habe, glaube ich, dass mir allein das langjährige Tun geholfen hat, besser logisch zu denken und Fehler zu vermeiden. Bestimmt lacht mich jetzt jeder Taschenrechner aus, aber für meine Zwecke reicht es. Die Welt der Computer ist nunmal eine gänzlich andere als die Unsere, in die man sich erst einmal einleben muss; Da sollte man keine Wunder erwarten oder zu verdächtig wohlklingenden Pillen greifen.

Und so peinlich dir besagte Quellcodezeile auch sein mag: sie ist völlig harmlos, wird wahrscheinlich sogar wegoptimiert.
Kleines Plus: Du wirst diesen Fehler nie wieder machen :)
[Edit: Wenns denn deiner gewesen wäre]

Schönes Wochenende,
lincore

julchen 4. Jan 2009 12:45

Re: Denkansätze (Algorithmik? richtiges Vorgehen?)
 
Hallo,

erst einmal DANKE für die Antworten.

Ich habe irgendwie nicht das Gefühl, hinter das "Geheimnis" der Programmierung zu kommen,
wie ich meine Ideen und Vorstellungen in praktischen Code umsetzen kann.
Das liest sich jetzt blöd - und ist es auch.
Aber ich kann´s auch nicht besser beschreiben.
Wahrscheinlich bin ich einfach nur zu blöd, den ganzen Scheiss zu kapieren.

Viele Grüsse

mkinzler 4. Jan 2009 12:50

Re: Denkansätze (Algorithmik? richtiges Vorgehen?)
 
Das glaube ich nicht. :zwinker:
Man muss nur versuchen, das Problem zu zerlegen und nicht zu kompliziert zu denken

kalmi01 4. Jan 2009 16:10

Re: Denkansätze (Algorithmik? richtiges Vorgehen?)
 
Zitat:

Zitat von Julchen
Wahrscheinlich bin ich einfach nur zu blöd, den ganzen Scheiss zu kapieren.

Mit blöd hat das absolut garnichts zu tun.
Manche können malen, Andere können musizieren und wieder Anderen macht es Spass wehrlose Nullen und Einsen in der Gegend rum zu schubsen.
Das schöne daran ist, das sich diese Talente und Interessen im Laufe der Jahre verschieben können.
Wenn mir vor 2 Jahren jemand gesagt hätte, das ich mal freiwillig eine sauschwere Fremdsprache nur so aus Spass am Lernen, lernen würde, dem hätte ich einen Vogel gezeigt.
Vielleicht platzt bei Dir ja auch irgendwann mal der Knoten und wenn nicht, auch egal, wenn man das was man tuen muss, so gut tut, wie man kann.

lincore 4. Jan 2009 17:19

Re: Denkansätze (Algorithmik? richtiges Vorgehen?)
 
Hm,

also wenn es ein Geheimnis gibt, dann kenne ich es nicht. Es ist bestimmt so, dass es manchen Menschen leichter fällt zu abstrahieren und "logisch zu denken". Aber das heißt noch lange nicht, dass der Rest nicht programmieren könnte. Dann wäre dieses Forum so leer wie ein dreckiges Bierglas in einer stürmischen Herbstnacht.

Fehler kommen nunmal vor; davon weiß ich ein Lied zu singen. Wenn ich zum Beispiel den Beat eines Songs mit einem leichten Kopfnicken akzentuiere und dabei eine Funktion schreibe, die auf ein Array von Zeigern zugreift oder etwas ähnlich Gefährliches tut, kann ich mich jetzt schon darauf einstellen, dass ich erst einmal eine Exception um die Ohren gehauen bekomme wenn ich es wage, das Programm auszuführen. Mit ständiger Übung und verbesserter Konzentration verschwinden die meisten Fehler wie von selbst (und machen Platz für neue).

Zudem sollte man sich bemühen, die Grundlagen lückenlos zu kennen, um voraussagen zu können, wie sich ein bestimmter Code verhalten wird. Bestes Beispiel hierfür ist der beliebte "Fence Post Error": Wer nicht weiß, dass das erste Element eines Arrays den Index 0 hat, wird beim Zugriff auf letzte Element eine hübsche Überraschung erleben - und nicht wissen wieso.

Um einen Aspekt der Programmiersprache zu begreifen, sich mit einer unbekannten Komponente anzufreunden oder einen Algorhythmus auszuprobieren, ist es außerdem eine gute Idee, eine kleine (Konsolen-)Anwendung ohne zusätzlichen Schnick-Schnack zu schreiben. So stellt man sicher, dass man alles verstanden hat und die Syntax beherrscht. Das ist gerade zu Beginn eines neuen Projektes ratsam, weil man damit einen Überblick über den Aufwand und die Machbarkeit erhält.

Falls Delphi deine erste Berühurung mit der "Kunst" des Programmierens ist, wäre es übrigens bestimmt keine schlechte Idee, ein gutes Buch zu lesen (Auflistung von Amazon), das nicht nur Delphi selbst, sondern auch allgemeinere Aspekte von Computern und Programmiersprachen beschreibt. Wie bereits geschrieben kannst Du den elenden Zustand des "Im Trüben fischens" nur verlassen, indem Du verstehst was Du tust und was der Computer tut. Wissenslücken können sich mit etwas Pech jahrelang verstecken und immer wieder zu Kopfschütteln und Resignation führen.

Nun zum Thema "Wie muss ich denken, um ein Problem zu lösen?"
In diesem Thread hat jemand geschrieben, man solle Aufgaben in Teilaufgaben zerlegen. Das ist die ganze Magie. Man zerlegt etwas so lange in Teilaufgaben, bis jede dieser Aufgaben mit einer Zeile Code dargestellt werden kann. Zudem muss man sich klar machen, wie man diesen Code strukturieren möchte. Mehrfach wiederverwendeter Code gehört zum Beispiel in eine Funktion/Prozedur, weil mehrfach vorhandener Code auch mehr Aufwand und Fehleranfälligkeit mit sich bringt. Für Klassen wiederum ist es wichtig, die innere Funktionsweise zu verbergen und dem Klienten nur eine möglichst universell einsetzbare Schnittstelle zur Verfügung zu stellen.

Wenn ich eine Funktion schreiben möchte, die einiges Nachdenken erfordert, öffne ich gerne mal eine Textdatei und schreibe den Namen der Funktion und was sie tun soll. Dann überlege ich mir, was dafür getan werden muss und schreibe das nieder. Zuletzt zerlege ich die Teilaufgaben in Pseudocode, der (fast) 1:1 in Delphi umsetzbar ist.

Beispiel:
Code:
function TGenericArray<T>.insert
(Methode der Klasse TGenericArray<T>)

Aufgabe:
Mit der Methode insert kann ein zweites TGenericArray<T> in self eingefügt werden. <index> beschreibt hierbei die erste Position im Array, ab der das zweite Array eingefügt wird. Die Parameter <from> und <til> begrenzen die einzufügenden Elemente des zweiten Arrays

Ablauf:
- Auf Zulässigkeit der Parameter prüfen
- Benötigte Plätze im Array bestimmen und in Variable <space> zwischenspeichern
- Methode rearrange mit <space> und <index> aufrufen, um den benötigten Platz zu schaffen (die folgenden Elemente nach hinten schieben)
- Durchlaufe alle einzufügenden Elemente des zweiten Arrays und füge sie in dieses Array(self) ein.

Globale Variablen/Konstanten:
TGL_TOP_OF_LIST    =    -255;

Lokale Variablen:
space (integer) speichert Zahl der benötigten freien Plätze
i (integer) Schleifenzähler

Parameter:
einzufügendes TGenericArray<T>,
<index> ab dem Einzufügen ist,
<from>, <til> geben den Bereich des zweiten Arrays an, der eingefügt werden soll

Pseudocode:
- Falls <from> oder <til> = TOP_OF_LIST dann setze <from> bzw. <til> gleich self.count() - 1
- Falls (<from> oder <til>) größer sind als self.count() - 1 oder kleiner sind als 0 dann
    - Verlasse die Funktion mit dem Ergebnis false
- Setze <space> gleich <til> - <from> + 1
- rufe rearrange(<index>, <space>, insertion = true) auf
- von [i] bis [i] + <space> - 1 tue dies:
    - dieses Array[i] is gleich zweites Array[from + i - index]
Und hier das Ergebnis:
Delphi-Quellcode:
// inserts a portion of another TGenericArray at <index>. The range of the
// included TGenericArray is determined by the <from> and <til> parameters.
// Returns true when successful.
function TGenericArray<T>.insert(list: TGenericArray<T>; index: integer = TGL_TOP_OF_LIST;
  from: integer = 0; til: integer = TGL_TOP_OF_LIST): boolean;
var
  i: Integer;
  space: integer;
begin
  if from = TGL_TOP_OF_LIST then from := list.high();
  if til = TGL_TOP_OF_LIST then til := list.high();
  if (from < 0) or (from > list.high()) or (til < 0) or (til > list.high()) or (til < from) then      
  begin
    result := false;
    exit();
  end;
  space := til - from + 1;
  auxRearrange(index, true, space);
  for i := index to index + space - 1 do
    mArray[i] := list.data[from + i - index];
end;
Es ist immer gut, solche Dinge aus der Abstraktion zu locken, in die Wirklichkeit zu bannen und damit (be)greifbar zu machen. Wäre ich nicht so unsäglich faul, würde ich mich für solche Aufgaben bestimmt an den Schreibtisch setzen und eine Mindmap machen. Sowas hilft dabei, den Kopf wieder zu entwirren und Ziele und Hürden klar aufzustellen.

Als Letztes möchte ich dir raten, so viel Code zu lesen wie Du kannst. Davon kannst Du eine Menge lernen. Versuche den Code zu verstehen, was tut er? Was macht diese Funktion? Warum ist die Klasse so aufgebaut? Um an guten Quellcode zu gelangen, bietet sich nicht nur das OpenSource-Forum hier bei dp an, auch Google-Code ist eine gute Quelle - wenn man weiß wonach man sucht.

Ich hoffe mein Geschwafel war in irgend einer Weise hilfreich. Viel Erfolg mit Delphi etc.,
lincore

PS: Statt nach dem Stein der Weisen zu suchen wäre es vielleicht besser, an tatsächlichen Problemen zu wachsen. Gib dafür am besten ein Beispiel mit Code zum Besten, sofern vorhanden. Daran sollte sich manches besser erläutern lassen.

julchen 6. Jan 2009 09:08

Re: Denkansätze (Algorithmik? richtiges Vorgehen?)
 
Danke für Deinen Text :-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:39 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz