Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Variablen doppelt (float und str) verwalten? (https://www.delphipraxis.net/210027-variablen-doppelt-float-und-str-verwalten.html)

cltom 18. Feb 2022 10:45

Delphi-Version: XE2

Variablen doppelt (float und str) verwalten?
 
Hallo,

eine Stil- oder Effizienz-Frage und eigentlich ein klassisches Thema. Man hat einen Haufen Variablen in einer Klasse, vorwiegend double, integer, einige wenige Strings (hier nicht relevant). Für das User-Interface, die Ausgabe, etc. braucht man eine String-Version der Variablen. Also FloatToStr/F. Dazu noch eine Umwandlung von SI in die passende Einheit (die Variablen liegen alle in SI vor, das UI stellt dem User passende Einheiten zur Verfügung).

Im Grunde braucht es also sinngemäß so etwas:

Delphi-Quellcode:
  edt_Value.Text := FloatToStrF(RoundTo(ConvertFromSI(SomeClass.Value, SomeClass.TargetUnit), -2);
Alles gut soweit.

Nun braucht man den oben erzeugten String (konvertiert und gerundet) an anderer Stelle nochmals, etwa in einem StringGrid.

So, jetzt stellt sich die Frage:

a) den gleichen Befehl von oben im Grunde rüberkopieren
b) den String einmal erstellen und als weitere Variable in der Klasse mitführen
c) eine eigene Klasse nur mit den Strings erzeugen
d) den String von dort kopieren, wo er schon erzeugt ist
e) für jede Variable eine eigene Funktion bauen, die sie als String zurückgibt.
f) die Königslösung: eine generelle Funktion bauen, die eine beliebige Variable als String zurückgibt

a) hat den augenscheinlichen Nachteil, dass Code vervielfacht wird. Da die Konvertierung von Einheiten über einen Datenbank-Zugriff geht, wird das auch etwas Performance kosten, weil mehrere hundert Zugriffe für alle Umrechnungsfaktoren aus der DB gelesen werden, und das dann eben zwei- oder mehrfach.
b) hat den (ebenso offensichtlichen) Nachteil, dass jede Variable zweifach erzeugt wird, einmal der Originalwert (double, integer), einmal seine nach SI konvertierte, gerundete string-Fassung und die Klasse recht aufgeblasen wird.
c) räumt den letzteren Nachteil auf und hat damit den Vorteil, dass ich das Objekt mit den Originaldaten übergeben kann.
d) funktioniert nicht, da nicht alle Variablen gleichzeit im UI verfügbar sind.
e) machbar, erscheint mir aber auch nicht beliebig elegant.
f) wär ideal, bloß wie? Der Funktion müsste man eine beliebige Variable übergeben können. Vielleicht übersehe ich was, aber ich seh nicht, wie das gehen sollte.

Habt ihr andere Idee? Danke im Voraus!

Der schöne Günther 18. Feb 2022 10:55

AW: Variablen doppelt (float und str) verwalten?
 
Vielleicht ist es für mich noch zu früh am Morgen, aber bei uns bin ich hiermit eigentlich glücklich geworden:

Für Einheiten eigenen Typ definieren, wie z.B.
Delphi-Quellcode:
type
  /// <summary>Luftdruck in <b>kPa</b></summary>
  TAirPressure = Single;

  /// <summary>Temperatur in °C</summary>
  TTemperature = Single;
Wenn man das dann irgendwo auf dem Bildschirm oder anzeigt gibt es einen
Delphi-Quellcode:
IUnitFormatter
mit z.B
Delphi-Quellcode:
IUnitFormatter = interface
  function format(
    const airPressure: TAirPressure;
    const digits: Byte = 0
  ): String; overload;
  function format(
    const temperature: TTemperature;
    const digits: Byte = 1
  ): String; overload;
end;
Dann beschränkt sich das Anzeigen in Edit-Feldern, Grids usw. meist auf ein simples:
Delphi-Quellcode:
Text := myFormatter.format(myTemperature);
Ist der Benutzer dann z.B. so verrückt dass er statt °C lieber diese komischen Ami-Einheiten (°F und so) haben will, wird zur Laufzeit einfach der Formatter ausgetauscht der dann als Ergebnis nicht "40,1 °C" sondern "60.4 °F" ausgibt.

peterbelow 18. Feb 2022 11:00

AW: Variablen doppelt (float und str) verwalten?
 
Bau eine Converter-Klasse die alle Umwandlungsfaktoren einmal aus der Datenbank lädt und eine Formattierungsfunktion nach deinem Bedarf anbietet. Der Funktion übergibst Du Wert, Zieleinheit, Zahl Nachkommastellen.

cltom 18. Feb 2022 11:13

AW: Variablen doppelt (float und str) verwalten?
 
Guten Morgen! :-D und danke!

Zitat:

Für Einheiten eigenen Typ definieren, wie z.B.
wie immer, wenn man fragt, man lernt immer was dazu! Die Idee hatte ich nicht. Wäre ein gehöriger Umbau, hat aber Charme, weil damit das leidige Thema auch addressiert ist, dass ich ja bei jedem Wert erst mal rausfinden muss, welcher Typ Einheit das ist (Länge, Masse, Geschwindigkeit, etc.). Man hat es dann in der Variablendeklaration mit dabei. Elegant und wohl auch leichter lesbar. Muss mal überlegen, welche Implikationen das noch mitbringt, etwa wenn die Werte aus der SQL gelesen werden. Ich geh davon aus, dass sowas wie FieldByName('Temperature').AsFloat immer noch klappt, weil der Typ TTemperatur ja auf double beruht. Ich kann es ja mal im kleinen Versuchen und sehen, ob das irgendwo dann klemmt.

Danke!

cltom 18. Feb 2022 11:21

AW: Variablen doppelt (float und str) verwalten?
 
Zitat:

Zitat von peterbelow (Beitrag 1502458)
Bau eine Converter-Klasse die alle Umwandlungsfaktoren einmal aus der Datenbank lädt und eine Formattierungsfunktion nach deinem Bedarf anbietet. Der Funktion übergibst Du Wert, Zieleinheit, Zahl Nachkommastellen.

Die Konvertierungsfaktoren einmal alle zu lesen, ergibt tatsächlich viel Sinn. Ich hab noch nichts optimiert, aber zig hundert mal die (oft gleichen) Faktoren rauszulesen, liegt mir schon länger im Magen. Bisher erzeuge ich mir zig mal eine Instanz der Konvertierungsklasse, lese die benötigten Faktoren raus, konvertiere und geb das Objekt wieder frei. Könnte man sehen, wie viel Zeit das spart, wenn ich die Faktoren nur einmal rauslese (bevor alle Werte konvertiert werden).

Ansonsten hab ich genau so eine Klasse schon, die diversen Konversionen von und nach SI liefert. Aber ja, aktuell liefert sie wieder einen (double) Wert zurück. Stimmt aber, im Grunde kann man die Klasse etwas erweitern, sodass sie auch Strings liefert.

Danke Dir!

himitsu 18. Feb 2022 12:17

AW: Variablen doppelt (float und str) verwalten?
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1502457)
Für Einheiten eigenen Typ definieren, wie z.B.
Delphi-Quellcode:
type
  /// <summary>Luftdruck in <b>kPa</b></summary>
  TAirPressure = Single;

  /// <summary>Temperatur in °C</summary>
  TTemperature = Single;

Ja, einen "Typ", keinen Alias, denn sonst ist es für den Compiler das Selbe und nicht nur das Gleiche. :zwinker:


Delphi-Quellcode:
type
  /// <summary>Luftdruck in <b>kPa</b></summary>
  TAirPressure = type Single;

  /// <summary>Temperatur in °C</summary>
  TTemperature = type Single;

Der schöne Günther 18. Feb 2022 12:24

AW: Variablen doppelt (float und str) verwalten?
 
Zitat:

Zitat von cltom (Beitrag 1502460)
Ich geh davon aus, dass sowas wie FieldByName('Temperature').AsFloat immer noch klappt, weil der Typ TTemperatur ja auf double beruht.

Richtig.

himitsus Tipp mit dem "eigener Typ" statt Alias hatte ich ganz vergessen, und das öffnet noch eine weitere Tür:

Du kannst noch einen "record helper" für einen Typ wie z.B. eine Winkelposition
Delphi-Quellcode:
type TAngularPosition = type Single
definieren, und dann noch mit Methoden ausstatten und Operator-Überladungen ausstatten. Sodass wenn man z.B. einen Winkel 190° und 180° addiert dass nicht 370 sondern 10 rauskommt.

Aber nur falls einem langweilig ist 😉

cltom 18. Feb 2022 14:50

AW: Variablen doppelt (float und str) verwalten?
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1502467)
Zitat:

Zitat von cltom (Beitrag 1502460)
Ich geh davon aus, dass sowas wie FieldByName('Temperature').AsFloat immer noch klappt, weil der Typ TTemperatur ja auf double beruht.

Richtig.

himitsus Tipp mit dem "eigener Typ" statt Alias hatte ich ganz vergessen, und das öffnet noch eine weitere Tür:

Du kannst noch einen "record helper" für einen Typ wie z.B. eine Winkelposition
Delphi-Quellcode:
type TAngularPosition = type Single
definieren, und dann noch mit Methoden ausstatten und Operator-Überladungen ausstatten. Sodass wenn man z.B. einen Winkel 190° und 180° addiert dass nicht 370 sondern 10 rauskommt.

Aber nur falls einem langweilig ist 😉

ok, sehr schön, muss ich mal ausprobieren! werde mal mit beiden Varianten ins Rennen gehen zum Lernen und sehen, wie es dann klappt. Danke Euch!!

freimatz 21. Feb 2022 07:07

AW: Variablen doppelt (float und str) verwalten?
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1502467)
Du kannst noch einen "record helper" für einen Typ wie z.B. eine Winkelposition
Delphi-Quellcode:
type TAngularPosition = type Single
definieren, und dann noch mit Methoden ausstatten und Operator-Überladungen ausstatten. Sodass wenn man z.B. einen Winkel 190° und 180° addiert dass nicht 370 sondern 10 rauskommt.

Vorsicht - das kann auch mal in die Hose gehen. Bei uns gibt es einen Fall bei dem 370° bedeutet dass sich das Ding einmal ganz rum (360°) und noch 10° dazu um die Achse dreht.
Und dann gibt es bei uns noch Winkel die von -180° bis +180° gehen und welche von 0° bis 360° - und bei manchen kann der Anwender noch einstellen welche der beiden Varianten er will. :-D


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:59 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