Jump to content

Kryvich

Members
  • Content Count

    439
  • Joined

  • Last visited

  • Days Won

    8

Posts posted by Kryvich


  1. Something went wrong with system functions Int and Frac in Delphi 12, Win32 platform.

     

    At runtime, the result of the expression Frac(1.9) can be either 0.9 (as expected) or 0 or 0.89. I couldn't determine what affects this.

     

    Interestingly, in the Evaluate/Modify window, the expressions Frac(1.9) and Int(1.9) always return -NAN, whatever that means.

     

    FracEvaluate.thumb.jpg.f9862e72c41b5d80f62289a4a5dd60dc.jpg

     

    Has anyone encountered these issues?

     

    As a temporary workaround, I used x-Trunc(x) instead of Frac(x).


  2. 1 hour ago, David Heffernan said:

    I know how to code a solution. And I'd use a proper parser to do it. But I'm looking for a tool. 

    Definitely. But time is money. If Copilot can do it for you - why not?

    1 hour ago, David Heffernan said:

    Doesn't look like it handles code laid out over multiple lines. 

    for Line in Lines do   -->  Line := Lines.Text;


  3. Copilot.

    Quote

    Write a console utility in Delphi that will scan the specified folder with subfolders, open files with the PAS extension, and select all strings starting with "Format(" and ending with "])". Among the strings found, you need to select those that contain the "+" character before the "," character, and save these strings in the text file "format.log".

    The result:

    program FormatStringExtractor;
    
    uses
      SysUtils, Classes;
    
    function ContainsPlusBeforeComma(const S: string): Boolean;
    var
      PlusPos, CommaPos: Integer;
    begin
      PlusPos := Pos('+', S);
      CommaPos := Pos(',', S);
      Result := (PlusPos > 0) and (CommaPos > PlusPos);
    end;
    
    procedure ProcessFile(const FileName: string; LogFile: TStrings);
    var
      Lines: TStringList;
      Line, SubStr: string;
      StartPos, EndPos: Integer;
    begin
      Lines := TStringList.Create;
      try
        Lines.LoadFromFile(FileName);
        for Line in Lines do
        begin
          StartPos := Pos('Format(', Line);
          while StartPos > 0 do
          begin
            EndPos := PosEx('])', Line, StartPos);
            if EndPos > 0 then
            begin
              SubStr := Copy(Line, StartPos, EndPos - StartPos + 2);
              if ContainsPlusBeforeComma(SubStr) then
                LogFile.Add(SubStr);
              // Move the start position forward to find the next occurrence
              StartPos := PosEx('Format(', Line, EndPos + 2);
            end
            else
              Break;
          end;
        end;
      finally
        Lines.Free;
      end;
    end;
    
    procedure ProcessFolder(const Folder: string; LogFile: TStrings);
    var
      SearchRec: TSearchRec;
      FullPath: string;
    begin
      if FindFirst(Folder + '\*.*', faAnyFile, SearchRec) = 0 then
      begin
        repeat
          FullPath := Folder + '\' + SearchRec.Name;
          if (SearchRec.Attr and faDirectory) = faDirectory then
          begin
            if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
              ProcessFolder(FullPath, LogFile);
          end
          else if ExtractFileExt(SearchRec.Name).ToLower = '.pas' then
          begin
            ProcessFile(FullPath, LogFile);
          end;
        until FindNext(SearchRec) <> 0;
        FindClose(SearchRec);
      end;
    end;
    
    var
      Folder: string;
      LogFile: TStringList;
    begin
      Write('Enter folder path to scan: ');
      ReadLn(Folder);
    
      LogFile := TStringList.Create;
      try
        ProcessFolder(Folder, LogFile);
        LogFile.SaveToFile('format.log');
        WriteLn('Strings saved to format.log');
      finally
        LogFile.Free;
      end;
    end.

     


  4. Quote

    we have a C++ library statically linked to a Delphi application on Windows

    Can you please elaborate this? Maybe a short article on this topic.

     

    P.S. I've noticed that there have been several interesting Delphi projects from Brazilian developers lately. Skia for Delphi, D2Bridge Framework are the most notable.

    • Like 4

  5. 16 hours ago, David Heffernan said:

    I went from XE7 to 11.something and only upgraded to get high DPI support which was worth it. Not sure what would get me excited from here. 

     

    Probably would be copilot like goodness in the IDE. 

    Multiline strings '''...''' were a very nice addition to the language. Still waiting for constructions like

    • case string1 of 'aaa':...
    • DoubleValue := Variant1 if not VarIsNull(Variant1) else 0.0;

     


  6. There are three things you can watch forever: fire, water, and code improving.

     

    procedure TLinkMemo.CNCommand(var Message: TWMCommand);
    begin
      inherited;
      case Message.NotifyCode of
        EN_VSCROLL: SyncLink(True);
        EN_HSCROLL: SyncLink(False);
      end;
    end;
    
    procedure TLinkMemo.SyncLink(Vertical: Boolean);
    const
      BAR_FLAGS: array[Boolean] of Integer = (SB_HORZ, SB_VERT);
      MSGS: array[Boolean] of Cardinal = (WM_HSCROLL, WM_VSCROLL);
    var
      scrollInfo: TScrollInfo;
    begin
      if LinkedMemo = nil then
        Exit;
      var savedLink := LinkedMemo.LinkedMemo;
      try
        LinkedMemo.LinkedMemo := nil;
        scrollInfo.cbSize := SizeOf(scrollInfo);
        scrollInfo.fMask  := SIF_POS;
        if GetScrollInfo(Handle, BAR_FLAGS[Vertical], scrollInfo) then
          LinkedMemo.Perform(MSGS[Vertical], MAKEWPARAM(SB_THUMBPOSITION,
            scrollInfo.nPos), 0);
      finally
        LinkedMemo.LinkedMemo := savedLink;
      end;
    end;
    
    procedure TLinkMemo.WMHScroll(var Message: TMessage);
    begin
      inherited;
      SyncLink(False);
    end;
    
    procedure TLinkMemo.WMVScroll(var Message: TMessage);
    begin
      inherited;
      SyncLink(True);
    end;

     


  7. Quote

    ...very old languages are sneaking into the TIOBE index top 20.

    • 1. Python -- First appeared 20 February 1991; 34 years ago
    • 2. C++ -- First appeared    1985; 40 years ago
    • 3. Java -- First appeared    May 23, 1995; 29 years ago
    • 4. С -- First appeared    1972; 53 years ago
    • ...
    • 10. Delphi -- Initial release    1995

    Attention! Dinosaurs have won prizes!

    • Like 3

  8. @limelect How do you scroll horizontally?

    I know some programs allow this by holding the shift key down while you operate the scroll wheel. But in our case it doesn't work.

    I can scroll horizontally by dragging the bottom slider on the scroll bar, or by moving the cursor to the end of the line with the keys.


  9. OK, my take.

     

    unit Unit1;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
      System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
      Vcl.StdCtrls;
    
    type
      TLinkMemo = class(TMemo)
      private
        FLinkedMemo: TLinkMemo;
        procedure SyncLink;
      protected
        procedure WndProc(var Message: TMessage); override;
      public
        property LinkedMemo: TLinkMemo read FLinkedMemo write FLinkedMemo;
      end;
    
      TMemo = class(TLinkMemo);
    
      TForm1 = class(TForm)
        Memo1: TMemo;
        Memo2: TMemo;
        procedure FormCreate(Sender: TObject);
      private
      public
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure TLinkMemo.WndProc(var Message: TMessage);
    begin
      inherited;
      if (LinkedMemo = nil)
        or not LinkedMemo.HandleAllocated
      then
        Exit;
      case Message.Msg of
        WM_HSCROLL, WM_VSCROLL, WM_KEYDOWN, WM_MOUSEFIRST..WM_MOUSELAST: SyncLink;
      end;
    end;
    
    procedure TLinkMemo.SyncLink;
    
      procedure UpdateScrollBar(BarFlag: Integer; Msg: Cardinal);
      var
        scrollInfo: TScrollInfo;
      begin
        scrollInfo.cbSize := SizeOf(scrollInfo);
        scrollInfo.fMask  := SIF_POS;
        if GetScrollInfo(Handle, BarFlag, scrollInfo) then
          LinkedMemo.Perform(Msg, MAKEWPARAM(SB_THUMBPOSITION, scrollInfo.nPos), 0);
      end;
    
    var
      savedLink: TLinkMemo;
    begin
      savedLink := LinkedMemo.LinkedMemo;
      try
        LinkedMemo.LinkedMemo := nil;
        UpdateScrollBar(SB_HORZ, WM_HSCROLL);
        UpdateScrollBar(SB_VERT, WM_VSCROLL);
      finally
        LinkedMemo.LinkedMemo := savedLink;
      end;
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      Memo1.LinkedMemo := Memo2;
      Memo2.LinkedMemo := Memo1;
    end;
    
    end.

     

    • Thanks 1

  10. @limelect I guess you've over-engineered it a bit. @Uwe Raabe gave a great variant, it just needs a bit of tweaking.

     

    unit Unit1;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
      System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
      Vcl.StdCtrls;
    
    type
      TLinkMemo = class(TMemo)
      private
        FLinkedMemo: TLinkMemo;
        procedure WMVScroll(var Message: TMessage); message WM_VSCROLL;
        procedure WMHScroll(var Message: TMessage); message WM_HSCROLL;
        procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;
        procedure SyncLink;
      public
        property LinkedMemo: TLinkMemo read FLinkedMemo write FLinkedMemo;
      end;
    
      TMemo = class(TLinkMemo);
    
      TForm1 = class(TForm)
        Memo1: TMemo;
        Memo2: TMemo;
        procedure FormCreate(Sender: TObject);
      private
      public
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure TLinkMemo.SyncLink;
    var
      savedLink: TLinkMemo;
      myLine, linkLine: Integer;
    begin
      if LinkedMemo = nil then
        Exit;
      savedLink := LinkedMemo.LinkedMemo;
      try
        LinkedMemo.LinkedMemo := nil;
        LinkedMemo.CaretPos := CaretPos;
        LinkedMemo.Perform(EM_SCROLLCARET, 0, 0);
        myLine := Perform(EM_GETFIRSTVISIBLELINE, 0, 0);
        linkLine := LinkedMemo.Perform(EM_GETFIRSTVISIBLELINE, 0, 0);
        if myLine <> linkLine then
          LinkedMemo.Perform(EM_LINESCROLL, 0, myLine - linkLine);
      finally
        LinkedMemo.LinkedMemo := savedLink;
      end;
    end;
    
    procedure TLinkMemo.CNCommand(var Message: TWMCommand);
    begin
      inherited;
      if (Message.NotifyCode = EN_VSCROLL)
        or (Message.NotifyCode = EN_HSCROLL)
      then
        SyncLink;
    end;
    
    procedure TLinkMemo.WMVScroll(var Message: TMessage);
    begin
      inherited;
      SyncLink;
    end;
    
    procedure TLinkMemo.WMHScroll(var Message: TMessage);
    begin
      inherited;
      SyncLink;
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      Memo1.LinkedMemo := Memo2;
      Memo2.LinkedMemo := Memo1;
    end;
    
    end.

     


  11. @Uwe Raabe I hope the original author (notme) of the snippet has already done this. I've posted it here as a curious fact for those interested (like me). I haven't encountered any internal compiler errors in Delphi in recent years.

     

    Although, perhaps this bug has already been fixed in 12.2. (I have 12.1 CE).


  12. Never seen such error in Delphi 12, until today:

    [dcc32 Fatal Error] CompilerError.dpr(17): F2084 Internal Error: GPFC0000094-152D5B90(15290000)-0

    100% repeatability.

    program CompilerError;
    
    {$pointermath on}
    
    type
      PRec = ^TRec;
      TRec = record
      end;
      PArr = ^Arr;
      Arr = array [0..0] of TRec;
    
    var
      P: Pointer;
    
    begin
      P:=@PArr(P)[0];
      P:=@PRec(P)[0];
    end.

    (C) notme

     


  13. @Anders Melander Of course, I wrote about specifying short identifiers like Integer, PByteArray without a namespace inside a code section.

     

    Is there anyone here who writes System.Integer, Data.Win.ADODB.TADOQuery etc. in your code? And why?

     

    And the second question: if you don't do this for identifiers in your code, then why do it in the uses clause for system unit names?


  14. 1 hour ago, Anders Melander said:

    Huh? How do they do that?

    Can you give an example?

    I mean, you don't have to remember which system unit declares which type. You just write IntegerPByteArray instead of System.IntegerSystem.Sysutils.PByteArray and that's it!

     

    It makes sense to specify a namespace for System/RTL identifiers only in case of ambiguity.


  15. 19 hours ago, David Heffernan said:

    This code would be much better if each check of file header was done with same same code, against a signature declared either in a constant, or maybe in a file that was linked as a resource. This would make the code much cleaner, without so much repetition, and would allow you to extend it very easily. 

    Get paid by the number of lines? (Just kidding)


  16. Embarcadero can sometimes move system types and functions from one RTL unit to another. Should we care in which specific RTL module a particular system type is declared? The Unit Scope Names setting helps abstract away implementation details.


  17. If you have experience with CAI NEURAL API, you can help me.

    I need to create and train a neural network in Delphi like in TensorFlow, using the linear regression method::

    import tensorflow as tf
    from tensorflow.keras.models import Sequential
    from tensorflow.keras.layers import Dense
    
    # Model Definition
    model = Sequential()
    model.add(Dense(64, input_dim=14, activation='relu'))  # Input layer + first hidden layer
    model.add(Dense(128, activation='relu'))               # Second hidden layer
    model.add(Dense(64, activation='relu'))                # Third Hidden Layer
    model.add(Dense(46, activation='linear'))              # Output layer
    
    # Compiling the model
    model.compile(optimizer='adam', loss='mean_squared_error')
    
    # Train the model ( X_train and y_train - training data)
    model.fit(X_train, y_train, epochs=50, batch_size=10, validation_split=0.2)
    
    # Prediction for a new order
    predicted_materials = model.predict(new_order)
    print(predicted_materials)

    I created a CAI NEURAL API model, prepared training data, and started training.

      NN := TNNet.Create();
      NFit := TNeuralFit.Create();
      CreateWorkMatPairLists(80{%}, 10{%}, 10{%}, TrainingPairs, ValidationPairs, TestPairs);
      NN.AddLayer([
        TNNetInput.Create(WORKS_COUNT),
        TNNetFullConnectReLU.Create(64),
        TNNetFullConnectReLU.Create(128),
        TNNetFullConnectReLU.Create(64),
        TNNetFullConnectLinear.Create(MATERIALS_COUNT)
      ]);
    
      NFit.InitialLearningRate := 0.001;
      NFit.LearningRateDecay := 0.01;
      NFit.L2Decay := 0.00001;
      NFit.Fit(NN, TrainingPairs, ValidationPairs, TestPairs, {batchsize=}10, {epochs=}50);

    But I don't know how to set up the optimizer correctly (TensorFlow uses Adam). 

    And how to set the loss function - mean squared error.

    Does the CAI NEURAL API have such functionality, or do I need to write it myself?

×