AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi statt x-fache „if then else“-Abfragen eine intelligentere Lösung gesucht
Thema durchsuchen
Ansicht
Themen-Optionen

statt x-fache „if then else“-Abfragen eine intelligentere Lösung gesucht

Ein Thema von juergen · begonnen am 29. Mai 2013 · letzter Beitrag vom 2. Jun 2013
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.174 Beiträge
 
Delphi 11 Alexandria
 
#11

AW: statt x-fache „if then else“-Abfragen eine intelligentere Lösung gesucht

  Alt 30. Mai 2013, 18:37
@stahli,
danke für deinen Hinweis.
Das kenne ich, mein Problem ist der sich x-facch wiederholdende *fast* gleiche Code in jeder einzelnen If-Klausel. Eine If Klausel hat ca. 300 Zeilen.....
Deswegen mein Ansporn das diese 300 Zeilen nur noch einmal aufgerufen werden und der Dateiname anhand der Userauswahl vorher zusammengestellt wird und dann in dieser einen Procedure genutzt werden kann ohne If-Klauseln für die jeweilige Userauswahl.

@Sir Rufo,
Erst einmal vielen Dank für die aufklärenden Worte im Post #9!
Da lag ich ja fast..... ähhh nein ganz daneben mit meiner Annahme auf die Variable bezogen. Aber wer nicht fragt...

Auch für dein Beispeil ohne Generics vielen Dank! Im Moment baue ich noch einiges anderes um. Sobald ich dann ans Aufräumen für das hier besprochene Thema gehe, werde ich mir dein Code ganz genau Schritt für Schritt anschauen. Ich vermute, dass sich mir dabei noch ein paar Fragen stellen werden.

Bis hierhin tausend Dank und noch einen schönen Feiertag (zumindest in NRW)!

Gruß
Jürgen
Jürgen
  Mit Zitat antworten Zitat
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.174 Beiträge
 
Delphi 11 Alexandria
 
#12

AW: statt x-fache „if then else“-Abfragen eine intelligentere Lösung gesucht

  Alt 31. Mai 2013, 00:38
@Sir Rufo,

habe jetzt deine Variante mit kleineren Anpassungen erfolgreich umgesetzt.
Läuft super und ich habe einiges gelernt!

Nochmals Danke!
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#13

AW: statt x-fache „if then else“-Abfragen eine intelligentere Lösung gesucht

  Alt 31. Mai 2013, 03:31
Läuft super und ich habe einiges gelernt!
Ein weiterer jetzt möglicher Schritt wäre das Erstellen eines Builders aus einer Zeichenkette.

Dazu müsstest du einen einfachen Parser schreiben, der für jede "Variable" (zB. %TITLE%) den passenden Part erstellt und zu einem Builder hinzufügt.
Dabei wäre es günstig, einen neuen Part für konstante Teile des Dateinamens zu implementieren (zB. "-miep-" in "%INTERPRET%-miep-%TITLE%"). Der gibt immer den gleichen String zurück.
Damit könnte der Anwender den Pfad dann frei konfigurieren

Ich möchte dem Anwender keine RegEx-Ausdrücke oder dergleichen anbieten, es soll eben EINFACH und durch Lieschen Müller bedien bar sein.
Es ist als erfahrener Anwender immer schön, wenn man zusätzlich zu sinnvollen Voreinstellungen an solchen Sachen schrauben kann.


Abgesehen davon könnte man auch eine grafische Oberfläche zum einfachen Zusammensetzen eines Builders anbieten.
Intellekt ist das Verstehen von Wissen. Verstehen ist der wahre Pfad zu Einsicht. Einsicht ist der Schlüssel zu allem.

Geändert von BUG (31. Mai 2013 um 03:37 Uhr)
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#14

AW: statt x-fache „if then else“-Abfragen eine intelligentere Lösung gesucht

  Alt 31. Mai 2013, 08:25
Dazu müsstest du einen einfachen Parser schreiben, der für jede "Variable" (zB. %TITLE%) den passenden Part erstellt und zu einem Builder hinzufügt.
Der 'Parser' sieht dann z.B. so aus:
Delphi-Quellcode:
Filename := Replace (Filename,'%TITLE%',MyMusic.Title,[rfReplaceAll]);
Filename := Replace (Filename,'%INTERPRET%',MyMusic.Interpret,[rfReplaceAll]);
Filename := Replace (Filename,'%DATE%',DateToStr(Date),[rfReplaceAll]);
...
Allerdings ist das kein Parser, sondern etwas viel einfacheres: Ein String-Austausch-O-Mat.

Diese Vorgehensweise halte ich persönlich für die flexibelste, weil jederzeit Variablen (bzw. eigentlich ja Platzhalter) hinzugefügt werden können.

Eine fortlaufende Numerierung? Nennen wir sie '%NUMBER%'
Delphi-Quellcode:
Filename := Replace (Filename,'%NUMBER%',IntToStr(Number),[rfReplaceAll]);
Inc(Number);
Das gleiche, nur hier soll die Nummer nur erhöht werden, wenn der Platzhalter existiert.
Delphi-Quellcode:
if Pos ('%NUMBER%', Filename)>0 then
begin
  Filename := Replace (Filename,'%NUMBER%',IntToStr(Number),[rfReplaceAll]);
  inc(Number);
end;
Usw.

Du kannst das dann auch auf die Spitze treiben, indem Du einen Skriptinterpreter einbindest. Dann kann der Anwender seine eigenen Namensregeln festlegen. Braucht zwar kaum einer, aber Spaß macht es trotzdem.
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#15

AW: statt x-fache „if then else“-Abfragen eine intelligentere Lösung gesucht

  Alt 1. Jun 2013, 11:16
Allerdings ist das kein Parser, sondern etwas viel einfacheres: Ein String-Austausch-O-Mat.
Das ist allerdings auch nicht das, was ich vorgeschlagen habe
Ich habe das Erstellen eines Builder-Objekts aus dem String vorgeschlagen.
Intellekt ist das Verstehen von Wissen. Verstehen ist der wahre Pfad zu Einsicht. Einsicht ist der Schlüssel zu allem.
  Mit Zitat antworten Zitat
Benutzerbild von juergen
juergen

Registriert seit: 10. Jan 2005
Ort: Bönen
1.174 Beiträge
 
Delphi 11 Alexandria
 
#16

AW: statt x-fache „if then else“-Abfragen eine intelligentere Lösung gesucht

  Alt 1. Jun 2013, 19:19
@BUG,

so wie ich dich verstanden habe schlägst du vor mit reservierten Wörtern zu arbeiten (z.B. "miep").
Das ist jetzt schon ziemlich einfach in dem aufgezeigten FileNameBuilder von Sir Rufo umsetzbar.
Dazu würde ich einfach einen neuen TFileNamePart erstellen und entsprechend anwenden.
Oder habe ich dich jetzt falsch verstanden?
Jürgen
Indes sie forschten, röntgten, filmten, funkten, entstand von selbst die köstlichste Erfindung: der Umweg als die kürzeste Verbindung zwischen zwei Punkten. (Erich Kästner)
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#17

AW: statt x-fache „if then else“-Abfragen eine intelligentere Lösung gesucht

  Alt 2. Jun 2013, 13:36
Dazu würde ich einfach einen neuen TFileNamePart erstellen und entsprechend anwenden.
Ich hatte mir so etwas vorgestellt:
Delphi-Quellcode:
unit FilenameBuilder;

interface

uses
  Classes,
  Generics.Collections,
  SysUtils;

// ...

  TFilenamePartFactory = class
  private
    FParts : TDictionary<string, IFilenamePart>;
  public
    constructor Create;
    destructor Destroy; override;

    function GetPart( const AKey : string ) : IFilenamePart;
    // >>
    function GetConstantPart( const AString : string ) : IFilenamePart;
   // <<
  end;

// ...

implementation

// ...

  TConstantPart = class( TFilenamePart )
  public
    contructor create(AString: String);
  protected
    function Build( const AData : TMP3Meta ) : string; override;
  private
    constantString: string;
  end;

// ...

function TFilenameBuilder.GetFilename( const AData : TMP3Meta ) : string;
var
  LBuilder : TStringBuilder;
  LIdx : Integer;
begin
  LBuilder := TStringBuilder.Create;
  try
    for LIdx := 0 to FParts.Count - 1 do
      begin
        // "-" entfernt
        LBuilder.Append( FParts[LIdx].Build( AData ) );
      end;

    Result := LBuilder.ToString;

  finally
    LBuilder.Free;
  end;
end;

// ...

{ TConstantPart }

constructor TConstantPart.create(AString: string)
begin
  constantString := AString;
end;

function TConstantPart.Build( const AData : TMP3Meta ) : string;
begin
  Result := constantString;
end;

{ TFilenamePartFactory }

// ...

function TFilenamePartFactory.GetConstantPart( const AString : string ) : IFilenamePart;
begin
  Result := TConstantPart.create(AString);
end;

end.
Dann könnte man wie folgt für den Builder eine Factory schreiben:
Delphi-Quellcode:
type TFilenameBuilderFactory = class
  public
    constructor create(AFactory: TFilenamePartFactory; ownsFactory: boolean = true);
    destructor destroy; override;
    
    (** Returns a *new* object, caller handles destruction. *)
    function createBuilder(AString : string): TFilenameBuilder;

  private
    FFactory: TFilenamePartFactory;
    FOwnsFactory: boolean;
    // non-constant state
    FInVariable: boolean;
    FBuffer: string; // invariant: length(FBuffer) = 0
    FBuilder: TFilenameBuilder; // invariant: FBuilder = nil
    // methods
    procedure flushBuffer;
  end;

constructor TFilenameBuilderFactory.create(AFactory: TFilenamePartFactory; ownsFactory: boolean);
begin
  FFactory = AFactory;
  FOwnsFactory = ownsFactory;
  setLength(buffer, 0);
  FBuilder = nil;
end;

destructor TFilenameBuilderFactory.destroy
begin
  if FOwnsFactory then FFactory.free();
end;

procedure TFilenameBuilderFactory.flushBuffer;
var
  tempPart: IFilenamePart;
begin
  if (length(FBuffer) > 0) then
  begin
    if inVariable
      then tempPart := AFactory.GetPart(FBuffer) // not sure what TDirectory.getItem does when key does not exist!!!
      else tempPart := AFactory.GetConstantPart(FBuffer);
    ABuilder.add(tempPart);
  end;
  setLength(FBuffer, 0);
end;

function TFilenameBuilderFactory.createBuilder(AString : string): TFilenameBuilder;
var
  position: integer;
begin
  FBuilder = TFilenameBuilder.create();
  inVariable = false;
  for position := 1 to length(string) do
  begin
    if (AString[position] = '%') then
    begin
      flushBuffer();
      inVariable = not inVariable;
    end else begin
      FBuffer := FBuffer + AString[position];
    end;
  end;
  flushBuffer();
  result = FBuilder;
  FBuilder = nil;
end;
Dar Parser lässt noch viel Raum für Verbesserung, sollte aber als zur Verdeutlichung taugen.


Achtung:
Ich habe lange kein Delphi mehr benutzt, sind also wahrscheinlich Fehler drin.
Anmerkung zur Code-Qualität sind natürlich erwünscht
Intellekt ist das Verstehen von Wissen. Verstehen ist der wahre Pfad zu Einsicht. Einsicht ist der Schlüssel zu allem.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:03 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