Code Signing

////////////////////////////////////////////////////////////////////////////

Code Signing Tutorial__________________

maXbox Starter 118 – Get a code signing certificate and sign the Executable.

“The Sign of the Southern Cross – signtime.

Code Source: 1033_signtool_simplebatch_solution_mX4Cert_second64.txt

If you have a code base of a 64-bit Windows executable you can sign this Exe. Code signing is the process of digitally signing executables and scripts to confirm the software author and guarantee that the code has not been altered or corrupted since it was signed for the first time.

{———————————————————————-}

{- -} {- Tool> signtool sign /f certs/tcertificate4.p12 /p belplan /t -}
{- http://timestamp.digicert.com m85covid6.png -}

{-Done Adding Additional Store -}

SignTool Error: This file format cannot be signed because it is not recognized. SignTool Error: An error occurred while attempting to sign: {- m85covid6.png -}

{———————————————————————-}

As you can see, you can’t sign a png or jpg file, just exe, jar, js and bat and a few others. The *.p12 contains both the private and the public key, and also information about the owner (name, email, location, address, etc. ) all being certified by a third party. With such certificate, a user can identify himself and authenticate himself to any organization trusting the third party.

You should be able to see the content of the p12 file with

openssl pkcs12 -info -in filename.p12

provided openssl is installed in your system.

The executable is organised in a project-, a manifest- and a resource unit. This article will be the default article after the implementation of the new Minimum Requirements for Code Signing on February 1, 2017.

pic1: tutor118_signobjectscreen_6.png

You can either sign files out of a working directory, or you can place them in your Windows SDK\bin folder.

Source Organisation Steps

  1. Open the Command Prompt: Windows 7: Start > Run > cmd, or for Windows 8-10, press the Windows Key, then type cmd and press enter.
  2. Navigate to the directory with signtool.exe.
  3. Use the following command to sign your file:
  4. signtool sign /a /tr http://timestamp.globalsign.com/tsa/r6advanced1 /td SHA256 /fd SHA256 c:/path/to/your/file.exe
  5. To verify the successful signature use the following commands: Authenticode: signtool verify /v /pa

Alternatively, you can batch that in a script:

Const TOOLPATH =

   'C:\maxbox\maxbox51\examples\signtool\';

   //'from C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\signtool.exe';

const CERTFILE =

'C:\maxbox\maxbox51\examples\signtool\certs\maxbox4exe.pfx';

writeln(GETDOSOutput('signtool.exe sign /f'

     +' certs/maxbox4exe.pfx /p '+PASSTOKENfromfile

     //+' /t http://timestamp.digicert.com '+TOSIGNFILE

     +' /tr http://timestamp.globalsign.com/tsa/r6advanced1
     /td SHA256 /fd SHA256 ' +TOSIGNFILE  ,TOOLPATH));//}

Enter your Token Password. If the signing is successful you will see a prompt informing you so for the signing process.

→ Done Adding Additional Store

  • /tr– Specify an RFC 3161 compliant trusted time stamp server.*Recommended*
  • /td SHA256– Must be called after “/tr”, this command specifies the TimeStamp digest Algorithm. *Recommended*
  • /ac– Specify an Additional Certificate.

Note: Timestamping your Code is extremely important and is highly recommended for every piece of code that you sign.
This timestamp will allow the file that you sign to remain valid long after the certificate itself has expired.

So for the verify of the sign get the latest revision of signtool with patches as from issues and it goes like this:

WinExec32(‘cmd /C signtool.exe verify /v /pa ‘+TOSIGNFILE+’ >

 signresult3445.txt’,1);

Verifying: PointInSpace5_64.exe

Signature Index: 0 (Primary Signature)

Hash of file (sha256):

139E1FBBEB8BA664CA08EB6B3B8CEFD1E59AC87A7A97B6DACE406FF489828BBB

Signing Certificate Chain:

Issued to: maXboxCertAuth

Issued by: maXboxCertAuth

Expires: Sun Jan 01 00:59:59 2040

SHA1 hash: 6F83207B500DCC0E32A719599CBC6BD7E6B2A04D

Issued to: maXbox4signer

Issued by: maXboxCertAuth

Expires: Sun Jan 01 00:59:59 2040

SHA1 hash: 6A89501B76D47C189A60BF1070BAA2FBFD38D7D7

Issued to: maXbox4exe

Issued by: maXbox4signer

Expires: Sun Jan 01 00:59:59 2040

SHA1 hash: F0EB0CA218C5707FAC78921F81092CECA12AD0E9

The signature is timestamped: Tue Jan 02 19:31:40 2024

Timestamp Verified by:

Issued to: GlobalSign

Issued by: GlobalSign

Expires: Sun Dec 10 01:00:00 2034

SHA1 hash: 8094640EB5A7A1CA119C1FDDD59F810263A7FBD1

Issued to: GlobalSign Timestamping CA – SHA384 – G4

Issued by: GlobalSign

Expires: Sun Dec 10 01:00:00 2034

SHA1 hash: F585500925786F88E721D235240A2452AE3D23F9

Issued to: Globalsign TSA for CodeSign1 – R6

Issued by: GlobalSign Timestamping CA – SHA384 – G4

Expires: Sun May 08 08:45:38 2033

SHA1 hash: CA3E8CFD7CFD329A99359A9A38F86185F0B01C4A

Successfully verified: PointInSpace5_64.exe

Number of files successfully Verified: 1

Number of warnings: 0  Number of errors: 0

The interesting point is to know where the certificate with the hash is stored in the executable itself. Validate a PE certificate. Is the signature valid or not. It should work when signature is embedded in PE executable and when the signature is in a security catalog.

For example the exe maXbox5.exe with the hash:

SHA-1: ddf3fa4e3ccb0835082c8d8bbd9ddd98a5b5c7b5

SHA-256: da34199785ae5371e2cf8a23a12b68295f7c968ba0c8a24f367baf0c5f091439

The embedded cert can be found at the end of an executable as a PE layer, we can visualize such a structure of a PE executable, look at the blue section called overlay at the very end:

Pic2: tutor118_maxbox5_visualized_samplesections.png

In Delphi or maXbox, I can include a folder’s source code by adding it to the project Search Path or define as an include file, or adding it to the Library Path. The Search Path applies for the UMatrix.pas only to the current project, while the Library Path applies to any project opened with the IDE.

From DetectItEasy

PE64   Linker: Turbo Linker (8.0) [GUI64,signed]   Compiler: Embarcadero Delphi (11.0 Alexandria) [Standard]   Sign tool: Windows Authenticode (2.0) [PKCS #7]

File size 59.92 MB (62832288 bytes)

Test of code signing overlay size

You can measure the overlay with a before and after analyze:

Size of Exe befor sign: 63,141,888 bytes

Size of Exe after sign: 63,149,728 bytes

makes a diff of 7840 bytes and this is what we see on virustotal:

Overlay

entropy 7.6731858253479

offset 63141888

chi2 5806.17

filetype unknown

md5 d2702c89702ab006afd750091060100c

size 7840

X509 Certificates

maXbox4signer

Globalsign TSA for CodeSign1 – R6

GlobalSign Timestamping CA – SHA384 – G4

GlobalSign

The Mystery of VirusTotal

Also please specify which certificate kind is the correct one. Most sites only mention “code signing” and talk about signing applications that are actually compiled by the user. This is actually the case for me. I got a last compile of this year 2023 for the multi-installer of Python4Delphi and as usual signed this with my code signing certificate as usual but VirusTotal showed 2 detections:

So what to do, checked the MSIL.Agent read something about misused code signing so I decided to test it without code signing and no flag this time, so it has to do with the signing process! (which is an extension of the underlaying Executable as overlay). I replaced the authenticode time stamp countersignature from digicert to globalsign an it worked with VirusTotal!:

 +' /tr http://timestamp.globalsign.com/tsa/r6advanced1 /td SHA256 /fd SHA256 ' +TOSIGNFILE  ,TOOLPATH));  //} 

Pic3&4: tutor118_VTotal_secondtest.png

When we compare the sign part of VirusTotal in Details we can see that SHA-256 orders additionally use the R1-R3 Cross Certificate – default March 31, 2014 & after. (The R1-R3 Cross Certificate will need to be installed on the signing computer but not specified as an additional certificate during the signing procedure):

The old timestamp one X509 Certificates from DigiCert and the new one from GlobalSign:

VirusTotal – File – da34199785ae5371e2cf8a23a12b68295f7c968ba0c8a24f367baf0c5f091439

Pic5: 8_mX5_64bitGUI2.png

Why we cannot use single “\u” to represent smiley within a string? Because when \u escape was designed, all unicode chars   could be represented by 2 bytes or 4 hexadecimal digits. So there are always 4 hexadecimal digits after \u in a java string literal.

 To represent a larger value of Unicode you need a larger hexadecimal number but that will   break existing java strings. So there java uses same approach as utf-16 representation.  As an example, the letter A is represented in unicode as U+0041 and in ansi as just 41. So converting that would be pretty simple, but you must find out how the unicode character is encoded. The most common are UTF-16 and UTF-8. UTF 16, is basically two bytes per character, but even that is an oversimplification, as a character may have more bytes. UTF-8 sounds as if it means 1 byte per character but can be 2 or 3. To further complicate matters, UTF-16  can be little endian or big endian. (U+0041 or U+4100).

Happy Coding

Conclusion:

To sign a Windows executable file, you will need a code signing certificate from a Certificate Authority (CA) like Verisign or a self signed certificate with OpenSSL or instantssl.com1. Once you have the certificate, you can use Microsoft’s SignTool to sign your app. You can download SignTool as part of the Windows SDK1.

You download it as part of the Windows SDK. Note that it’s also possible to install SignTool without installing the entire SDK.

How to install SignTool.exe for Windows 10 – Stack Overflow

Once installed you can use SignTool from the command line or a script.

Script: softwareschule.ch/examples/maxbox_starter115.txt

CC 6503 LS Models photo MK
Jouef CC 6511 & CC 6512
Jouef 21004 – Roco 21003 – Jouef Champagnole 21002 – Lima 21001
CC 21000 Parade 21001-21004 by Jouef

Something to model:
The locomotive was built at the same time as the largely identical CC 6500 (as the names reveal, one was a DC single-system locomotive, the other was a two-system locomotive with the five-digit series designation beginning with “2”). The “mathematically” resulting CC 14500 was not built; 6500 (DC) + 14500 (AC) = 21000 (DC+AC) is not possible here – this is in contrast to the successor and last generation Nez Casséz, the 15000 (AC) + 7200 (DC) = 22200 (DC+AC ), here “summed up” in the order in which they appeared.

There were only four CC 21000s; they were built for traffic from Paris to the southwest/Burgundy and, above all, towards Switzerland/Simplon/Italy. For years on this route they pulled the TEE Cisalpin, the Simplon Express, the Lombardie Express and perhaps occasionally the Luthetia (otherwise a task shared by the CC 6500 and two BB 25500s in double traction).
The locomotive was strong, fast and had enormous pulling power at slow speeds (424kN). The 21001 once drove at 281 km/h on a test train. Simply an elegant, powerful and powerful appearance – it’s a shame I never saw her live.
With the appearance of the TGV, the CC 21000 became superfluous and were converted into CC 6500 – then further south and used primarily in freight traffic (including on the Mont Cenis line). This was particularly visible visually due to the disappearing transformer.

TAB Mythique CC 6509 silver & 6544 beton
TAB Mythique CC 6544 beton & 6509 silver second shot
E 656 209

References:

Compiled Project:

https://github.com/maxkleiner/maXbox4/releases/download/V4.2.4.80/maxbox5.zip

Free Automated Malware Analysis Service – powered by Falcon Sandbox (hybrid-analysis.com)

Topic:

certificate – Signing a Windows EXE file – Stack Overflow

Preparation:

How to install SignTool.exe for Windows 10 – Stack Overflow


Doc and Tool: https://maxbox4.wordpress.com

PDF Version: http://www.softwareschule.ch/download/maxbox_starter118.pdf

Distance to sphere 3 is 6.40300 (vs. measured 6.40300)

Distance to sphere 4 is 3.46390 (vs. measured 3.46400)

//}

Max Kleiner 03/01/2024

Time goes by
Unfortunately, 2024 starts with sad news: on 1 January 2024, Niklaus Wirth passed away. Wirth was the creator and founder of Pascal (and several other programming languages) and received the Turing Award for his work in 1984. We will always remember him as one of the most important pioneers in developing programming languages, programming methodologies and software engineering.
By Tyomitch - Own work, Copyrighted free use, https://commons.wikimedia.org/w/index.php?curid=449735
For the new year 2024, we have very exciting developments in the planning. For Codolex, the Low Code tool for Delphi, we have some really useful new features planned for Q1. More on this in a news letter next month. On 19 January, I am organising a webinar together with Ian Barker from Embarcadero about Codolex and maXbox5.
In Memorian to Niklaus Wirth
Schweizer Electronic AG
Lematec CC 6540

The Mystery of IStream

For clarity and safety, the IStream object defined in the Delphi Visual Component Library (VCL) is a dynamic object that doesn’t have any methods, procedures, functions, events, listener etc… until these methods are defined in your code. The IStream Object will publish these methods correctly for external COM objects expecting an IStream interface.

For example you want to convert an OleVariant from an external COM to a memory stream, its kind of a mystery stream:

function getmemstreamfromIStream(avariant: variant): TMemorystream;
var instream: IStream; astream: TStream;
begin
  instream:= IUnknown(avariant) as IStream;
  astream:= TOleStream.Create(instream);
  result:= astream as TMemorystream;
end;

That will not work because its an invalid class typecast exception, the solution will be a method called CopyFrom():

function getMemStreamfromIStream2(avariant: variant): TMemorystream;
 var instream: IStream; ostream: TStream;
 begin
    instream:= IUnknown(avariant) as IStream;
    ostream:= TOleStream.Create(instream);
    result:= TMemorystream.Create;
    try
      result.CopyFrom(OStream, OStream.Size);
    finally
      OStream.Free;
    end;
 end;

TMemoryStream is a stream that stores its data in dynamic memory. Use TMemoryStream to store data in a dynamic memory buffer that is enhanced with file-like access capabilities. TMemoryStream provides the general I/O capabilities we use.

You could use most any TStream derived object within your own code implementation, including THandleStream or TFileStream. THandleStream provides access to the file handle variable that Windows API require for many core file read/write API calls.

That code works because of a new feature introduced in D2010, namely the ability to recover a reference to the object that implements an interface. Note though that if the IStream is implemented by something other than your Delphi code, then the cast will fail.

As another solution is the load of an IStream from an OLE response stream as unknown variant type to a well known TMemoryStream in order to save the response stream to a file (in our example a binary QR-code image file as a png graphic):

Const
  URLGoogleQRCODE='https://chart.apis.google.com/chart?chs=%dx%d&cht=qr&chld=%s&chl=%s';
  AFILENAME= 'mX5QRCode5.png';
  QDATA= 'https://maxbox4.wordpress.com/';

Type TQrImage_ErrCorrLevel=(L,M,Q,H);

Function QRCcodeOle(Wid,Hei:Word; C_Level,apath:string; const Data:string): string;
var
  httpReq,hr: Olevariant;  instream: IStream;
  jo: TJSON; strm :TMemoryStream; 
begin 
  httpReq:= CreateOleObject('WinHttp.WinHttpRequest.5.1');
  //jo:= TJSON.Create();
  hr:= httpReq.Open('GET',  
                       format(URLGoogleQRCODE,[Wid,Hei,C_Level,HTTPEncode(Data)]))            
  httpReq.setRequestheader('content-type','application/octet-stream'); 
  //httpReq.setRequestheader('Authorization','Bearer '+ CHATGPT_APIKEY2);
  if hr= S_OK then HttpReq.Send();
  strm:= TMemoryStream.create;
  If HttpReq.Status = 200 Then begin
    try
       strm:= getMemStreamfromIStream2(HttpReq.responsestream);
       //getmemStreamfromIStream2file(hrstream, apath);
       writeln('responsestream size: '+itoa(strm.size)); 
       strm.savetoFile(apath)
       openFile(apath);  
    except
       writeln('EHTTPex: '+ExceptiontoString(exceptiontype, exceptionparam));
    finally
       strm.free;
       httpreq:= unassigned; 
    end;  
  end;                
end;

//https://stackoverflow.com/questions/15441014/how-do-i-load-an-istream-into-a-tmemorystream

And the call of the function, but it doesn’t returns anything for the moment, cause we store the result direct in a file (better would be to get back a boolean of success or fail)://6. Call of the OLE WinHttp Class

//6. Call of the OLE WinHttp Class
writeln('back of OLE call: '+
  QRCcodeOle(150,150,'Q',ExePath+'\examples\'+AFILENAME, QDATA));
writeln('SHA1 '+Sha1(ExePath+'examples\'+AFILENAME));  //} 


writeln(‘back of OLE call: ‘+
QRCcodeOle(150,150,’Q’,ExePath+’\examples\’+AFILENAME, QDATA));
writeln(‘SHA1 ‘+Sha1(ExePath+’examples\’+AFILENAME)); //}

Another option is to write a TStream-derived class that accesses the IStream internally (similar to how the RTL’s TStreamAdapter class wraps a TStream so it can be passed around as an IStream).

Using the Google Chart Tools / Image Charts (aka Chart API) you can easily generate QR codes, this kind of images are a special type of two-dimensional barcodes. They are also known as hardlinks or physical world hyperlinks.

QDATA= ‘https://maxbox4.wordpress.com/’;

I was probably not aware of TOleStream at the time I wrote this answer. Looking at TOleStream now, I notice that it does not support 64-bit streams. This code does. Other than that, this code is almost identical to the code that TOleStream uses, with one only exception being that this code’s implementation of the Size property getter is more optimized than TOleStream‘s implementation is, and this code implements the Size property setter whereas TOleStream does not.

So we can combine the invoke call from HttpReq.responsestream to get a file in one function:

function getmemStreamfromIStream2File(avariant: variant; 
                                            apath: string): Tmemorystream;
 var instream: IStream; ostream: TStream;
 begin
    instream:= IUnknown(avariant) as IStream;
    ostream:= TOleStream.Create(instream);
    result:=  Tmemorystream.Create;
    try
      result.CopyFrom(OStream, OStream.Size);
      result.SaveToFile(apath)
    finally
      OStream.Free;
    end;
 end;

maXbox5 QRCode Tutorial
Get Images as Response Stream
Lima Helvetia – Erasmus

Conclusion: There are probably better ways, but I would create a TOleStream, which is designed as an IStream wrapper; then you can use the CopyFrom() method of your MemoryStream to load and save the data!

5 City Cycle: Geneva-Bern-Basel-Zürich-St. Gallen

St. Gallen

You can expect the journey from Bern Hbf to London by train to take around 10 hours 34 minutes. If you want to get there as quickly as possible, it can take as little as 7 hours 54 minutes on the fastest services. You’ll usually find around 19 trains per day running on this route, which spans 462 miles (744 km). You’ll have to make 2 changes along the way on your journey to London. Eurostar, TGV or Thalys are the main rail operators on this route, all of which offer modern trains with plenty of space for luggage and comfortable seating.

HLE 16 – 1601 Vitrain ref 2161

La 1601 “Freccia del Sole” est intéressante, car elle a fait l’objet d’essais sur le BLS avec la 1602. Pour cela, elle a reçu un 4e pantographe lui permettant de rouler en Suisse. Avec logo R.T. Suisse Railtour.
D’après Wikipédia:
La série 16 est une série de huit locomotives électriques polytension commandée en 1966 par la SNCB, afin de tracter les convois sur la ligne vers Cologne nouvellement électrifiée, trois ans après celle vers Paris. En mars 2010, elles furent définitivement mises hors service.

https://www.petits-trains-ho.fr/forum/vitrains/hle-16-1601-vitrain-ref-2161.html
64bit from 4Gewinnt 1994 to 2024 in maXbox5
function SumSquareDigitsPy(n: integer): integer;
{Sum the square integers in a number}
var st: string;
begin
  st:= inttostr(n)
  with TPythonEngine.Create(Nil) do begin
    pythonhome:= PYHOME64;
    try
      loaddll;
      result:= strtoint(EvalStr('sum(int(x)**2 for x in list(str('+st+')))')); 
    except
      raiseError;        
    finally       
      free;
    end;
  end;         
end;

Compare hybrid code in mX5
function SumSquaredDigits_(n: integer): integer;
{Sum the squares of the digits in a number}
var t: integer;
begin
Result:=0;
repeat
   begin
    t:=n mod 10; n:=n div 10;
    Result:=Result+t*t;
   end
until n<1;
end;

And the Pythonic way:

digstr:= '0123456789';
sumi:= 0;
for it:= 1 to length(digstr) do sumi:= 
                 sumi+round(pow(atoi(digstr[it]),2));
writeln(itoa(sumi));
>>> 285
Roco Tartaruga https://www.roco.cc/ren/products/72500-electric-locomotive-e444-fs.html
Unicode Support
Very Cold in Kiruna
Märklin, Roco, Lima
Locland3 SNCF 6520 – DB 1308 – SBB 11249
CC 21001 -21004 by Jouef
Tutorial Multicode SQL, RegEx, HTML and Python

Mime Base64Decode Stream

If it returns a random, base64-encoded image in JPEG format you have two options:

Accept (required) – header indicating the content type to accept in the result. Must be set to the following:image/jpg.

function GEO_to_text_API2_randimage(AURL, url_name, aApikey: string): string;
var httpq: THttpConnectionWinInet;
    rets, rets2: TMemoryStream;  
    heads: TStrings; iht: IHttpConnection; //losthost:THTTPConnectionLostEvent;
begin
  httpq:= THttpConnectionWinInet.Create(true); 
  rets:= TMemoryStream.create;
  heads:= TStringlist.create;     
  try 
    heads.add('X-Api-Key='+aAPIkey);
    heads.add('Accept=image/jpg');
    iht:= httpq.setHeaders(heads);
    httpq.Get(Format(AURL,[urlencode(url_name)]), rets);
    if httpq.getresponsecode=200 Then begin
       rets.Position:= 0;
       rets.savetofile((exepath+'randimage.jpg'));
       openfile(exepath+'randimage.jpg');

Or you encode (change) the raw get stream with the procedure ALMimeBase64decodeStream();

function GEO_to_text_API2_randimage(AURL, url_name, aApikey: string): string;
var httpq: THttpConnectionWinInet;
    rets, rets2: TMemoryStream;  
    heads: TStrings; iht: IHttpConnection; //losthost:THTTPConnectionLostEvent;
begin
  httpq:= THttpConnectionWinInet.Create(true); 
  rets:= TMemoryStream.create;
  rets2:= TMemoryStream.create;
  heads:= TStringlist.create;     
  try 
    heads.add('X-Api-Key='+aAPIkey);
    //heads.add('Accept=image/jpg');
    iht:= httpq.setHeaders(heads);
    httpq.Get(Format(AURL,[urlencode(url_name)]), rets);
    if httpq.getresponsecode=200 Then begin
       writeln('size of '+itoa(rets.size));
       rets.Position:= 0;
       ALMimeBase64decodeStream(rets, rets2)
       rets2.savetofile((exepath+'randimage.jpg'));
       openfile(exepath+'randimage.jpg');
    end else result:='Failed:'+itoa(Httpq.getresponsecode)+Httpq.GetResponseHeader('message');
  except  
    writeln('EWI_HTTP: '+ExceptiontoString(exceptiontype,exceptionparam));
  finally
    httpq:= Nil;
    heads.Free;
    rets.Free;
    rets2.Free;
  end;                  
end;                 //}

Base64 strings are normally padded with trailing “=” signs to make sure their length is a multiple of 4.

Some decoders will try to correct for the missing padding chars while others will not. See the StackOverflow question “Remove trailing “=” when base64 encoding

The Random Image API generates random images for all your placeholder and design needs. It supports custom sizes as well as custom image categories.

https://api-ninjas.com/api/randomimage

MemoryStream to String

StreamToString3(ms) and other inbuilts missing a tag so an explicit method works as workaround:

Function TryMemoryStreamToString(const MS: TMemoryStream; var s: string): Boolean;
   begin
     Result:= False; if(MS=Nil) then Exit;
     try
       SetLength(s, MS.Size - MS.Position);
       writeln('debug size: '+itoa(length(s)));
       MS.Read(s, Length(s));
       Result:= True;
     except
       Result:= False;
     end;
   end;

And the other way round:

Function TryStringToMemoryStream(const s: string; var MS: TMemoryStream):Boolean;
   begin
     Result:= False; if(MS=Nil) then Exit;
     try
       MS.Write(s, Length(s));
       Result:= True;
     except
       Result:= False;
     end;
   end; 

Trilateration Equation

////////////////////////////////////////////////////////////////////////////

Trilateration Equation ______________________________________________________________

maXbox Starter 115 – Get Target-point from 4 Sensors.

“Time behaves like space – timeless.

Source: 966_U_PointInSpace52_mX4Form2_64.pas & PointInSpace5_64.exe

Click to access maxbox_starter115.pdf

If you have a code base of 32-bit Windows Delphi applications that you want to convert to 64-bit Windows, you should first do a reorganisation of the sources for an overview. Today we deal with an old Borland library UMatrix.pas and a mathematical problem with of course a solution too.

{——————————————————————————}

{- -} {- Turbo Pascal Numerical Methods Toolbox ——————–}

{- Copyright (c) 1986, 87 by Borland International, Inc.————-}

{- This unit provides procedures for dealing with systems of linear -}

{- equations. ———————————————————–}

{——————————————————————————}

UMatrix.pas

Given the 3D coordinate locations of four sensors and their known distance from a target, calculate the location of the target.

Point From 4 Sensors (delphiforfun.org)

The source is organised in a project-, a form- and a calculation unit:

pic1: 115_d_radstudio_code.png

So its not always that easy to open your old 32-bit application in the IDE, add and activate the 64-bit Windows target platform, and compile your application as a 64-bit target Windows application. We must search also our old dependencies and check the compatibility with components.

Source Organisation

Unit UMatrix is the unit from the old Borland Turbo Pascal Numeric Toolbox which contains the Gaussian Elimination procedure used here among other matrix operations.

So we have sensors at known locations in 3D space. Each sensor can supply distance information to a target but knows nothing about the target’s direction. Alternatively, the sensors are Satellites and the target is a GPS receiver which reads very accurate time stamps transmitted by the satellites and calculates distances based on time offsets between its clock when a clock time message is received and satellites’ clock time when the message was sent (as contained in the message).
Given the sensor (X, Y, Z) coordinates and their distance-to-target values, we’ll use Gaussian Elimination to solve a set of linear equations describing the problem and derived as follows:

The distance Di to target at (Xt, Yt, Zt) for sensor “i” located at (Ai, Bi, Ci) is given by

Sqr(Di)=Sqr(Ai – Xt) + Sqr(Bi – Yt) + Sqr(Ci – -Zt)

after expanding:

Di2 = Ai2 – 2AiXt + Xt2 +Bi2 – 2BiYt +Yt2 +Ci2 – 2CiZt + Zt2

So for the reorganisation of the sources I have the latest revision with patches as from issues and it goes like this:

begin { procedure Gaussian_Elimination }
  Initial(Dimen, Coefficients, Constants, Solution, Error);
  if Dimen > 1 then begin
    UpperTriangular(Dimen, Coefficients, Constants, Error);
    if Error = 0 then
      BackwardsSub(Dimen, Coefficients, Constants, Solution);
  end;
end; { procedure Gaussian_Elimination }

Solving this system of quadratic equations can be tricky, but we can subtract the Sensor1 equation from each of the other 3 to obtain linear equations like the following example for Sensor2::

2(A1-A2)Xt + 2(B1-B2)Yt + 2(C1-C2)Zt = D22-A22-B22-C22-D12

The resulting 3 equations in 3 unknowns form a system of linear equations which are solved here using Gaussian Elimination to find the (Xt, Yt, Zt) target coordinates.
Note that the original problem requires 4 equations to resolve the 3 unknowns (the x, y, and z coordinates of the target). Two sensors can narrow target location down to a circle (the intersection of 2 spheres with target distances as radii), the 3rd sensor narrows the location down to two possible points, (the intersection of the circle with the 3rd sensor’s sphere circle).

The 4th sensor should resolve which of those two points is the target. Any error in specified locations or distances would either have no solution or require that some input values be adjusted. The techniques applied here result in reported distances being adjusted to produce a solution. Differences between input and calculated distances are listed as part of the solution. Lets have a look at the init routine Initial which is called in the main by Gaussian Elimination:

procedure Initial(Dimen : integer;

var Coefficients : TNmatrix;

var Constants : TNvector;

var Solution : TNvector; var Error : byte);

{———————————————————-}

{- Input: Dimen, Coefficients, Constants -}

{- Output: Solution, Error -}

{- This procedure test for errors in the value of Dimen. -}

{- This procedure also finds the solution for the -}

{- trivial case Dimen = 1. -}

{———————————————————-}

begin

Error:= 0;

if Dimen < 1 ten Error:= 1

else if Dimen = 1 then

if ABS(Coefficients[1, 1]) < TNNearlyZero then Error:= 2

else Solution[1]:= Constants[1] / Coefficients[1, 1];

end; { procedure Initial }

procedure Initial(Dimen        : integer;
              var Coefficients : TNmatrix;
              var Constants    : TNvector;
              var Solution     : TNvector;
              var Error        : byte);

{----------------------------------------------------------}
{- Input: Dimen, Coefficients, Constants                  -}
{- Output: Solution, Error                                -}
{-                                                        -}
{- This procedure test for errors in the value of Dimen.  -}
{- This procedure also finds the solution for the         -}
{- trivial case Dimen = 1.                                -}
{----------------------------------------------------------}

begin
  Error:= 0;
  if Dimen < 1 ten
    Error:= 1
  else
    if Dimen = 1 then
      if ABS(Coefficients[1, 1]) < TNNearlyZero then
        Error:= 2
      else
        Solution[1]:= Constants[1] / Coefficients[1, 1];
end; { procedure Initial }

P ic2: 115_GUIDesignandRuntime2023-12-02143419.png

The Solve button returns a position which may be at distances different from those in the original distance equations but do satisfy the distances relative to Sensor 1. That is part of what we sacrifice by eliminating one of the equations and converting quadratics to linear. A better solution in the ”GPS case might be to incorporate dummy 4th variable representing the distance error due to clock synchronization errors between the satellites and the GPS receiver. The multivariate Newton-Raphson algorithm is a possible way to solve by using 4 quadratic equations in 4 unknowns.

Pic3: 115_Designtime2023-12-02143302.png

In Delphi or maXbox, I can include a folder’s source code by adding it to the project Search Path or define as an include file, or adding it to the Library Path. The Search Path applies for the UMatrix.pas only to the current project, while the Library Path applies to any project opened with the IDE.

Version 5 Test Case

Version 5 posted today adds a second method for locating the target. Trilateration uses the locations of three sensors to exactly narrow the target location down to at most two possibilities. See this Wikipedia article for an excellent discussion and derivation of the Math involved. I translated a C code implementation to Delphi for testing.

Trilateration – Wikipedia

Trilateration

By solving the 4 combination using 3 of the 4 sensors and saving the two solutions from each case, it seems that we have good luck in identifying the single solution. It is much more robust to the Gaussian Elimination version, easily solving the case submitted by a user which led to the current investigation: Using notation (x, y, z, r) to represent the x, y, z, coordinates and r, the measured distance to the target.

A test case is defined by (0,0,0,10), (10,0,0,10), (0,10,0,10), and (10,10,0,10). Gaussian Elimination finds no solution or an incorrect solution if a small increment is added to the z coordinate of one of the sensors to remove the singularity. Trilateration correctly identifies the solution as (5, 5, 7.07) or (5, 5, -7.07) which is also valid:

Solution 1: 5.00 5.00 7.07

Distance to sphere 1 is 10.000 (radius 10.000)

Distance to sphere 2 is 10.000 (radius 10.000)

Distance to sphere 3 is 10.000 (radius 10.000)

Solution 2: 5.00 5.00 -7.07

Distance to sphere 1 is 10.000 (radius 10.000)

Distance to sphere 2 is 10.000 (radius 10.000)

Distance to sphere 3 is 10.000 (radius 10.000)

Solution 1: 5.00 5.00 7.07

Distance to sphere 1 is 10.000 (radius 10.000)

Distance to sphere 2 is 10.000 (radius 10.000)

Distance to sphere 4 is 10.000 (radius 10.000)

Solution 2: 5.00 5.00 -7.07

Distance to sphere 1 is 10.000 (radius 10.000)

Distance to sphere 2 is 10.000 (radius 10.000)

Distance to sphere 4 is 10.000 (radius 10.000)

Solution 1: 5.00 5.00 -7.07

Distance to sphere 1 is 10.000 (radius 10.000)

Distance to sphere 3 is 10.000 (radius 10.000)

Distance to sphere 4 is 10.000 (radius 10.000)

Solution 2: 5.00 5.00 7.07

Distance to sphere 1 is 10.000 (radius 10.000)

Distance to sphere 3 is 10.000 (radius 10.000)

Distance to sphere 4 is 10.000 (radius 10.000)

Solution 1: 5.00 5.00 -7.07

Distance to sphere 2 is 10.000 (radius 10.000)

Distance to sphere 3 is 10.000 (radius 10.000)

Distance to sphere 4 is 10.000 (radius 10.000)

Solution 2: 5.00 5.00 7.07

Distance to sphere 2 is 10.000 (radius 10.000)

Distance to sphere 3 is 10.000 (radius 10.000)

Distance to sphere 4 is 10.000 (radius 10.000)

Sum of coordinate differences:

Solution 1: 28.28427, Solution #2: 28.28427

Use Solution 2 set

Solution 2: 5.00 5.00 -7.07

Distance to sphere 1 is 10.00000 (vs. measured 10.00000)

Distance to sphere 2 is 10.00000 (vs. measured 10.00000)

Distance to sphere 3 is 10.00000 (vs. measured 10.00000)

Distance to sphere 4 is 10.00000 (vs. measured 10.00000)

As you can see in Pic2 there are 19 TEdit controls for user input; 4 for each of the 4 sensors plus 3 if the user wants to enter target values. The target values were convenient when debugging the code with sets of points with known solutions. In order to simplify the code, I defined an array, Sensors, of TSensorEdits records, each containing 4 TEdit references (object references are always pointers), plus the numeric version of the X, Y, Z, and R (distance) values represent by the edits for that specific sensor.
Perhaps as suggested we can just define references to avoid an assembler.

Geometrically, each of the 4 sensors and its target distance define a sphere upon which the target must lie, and that should be the common point of intersection of all 4 spheres.

Pic4: 115_GUIDesignandRuntime2023-12-02143419.png

This target coordinate technique above used to help with the understanding about what each distance represents and what the difference results of. Alternatively, the sensors are Satellites and the target is a GPS receiver which reads very accurate time stamps transmitted by the satellites and calculates distances based on time offsets between its clock and satellites’ clocks. About the topic:

How GPS Receivers Work – Trilateration vs Triangulation – GIS Geography

Another interesting topic is the Runge-Kutta technique for solving second order ordinary differential equations, like in a pendulum motion.

Pendulums, Simple and otherwsie (delphiforfun.org)

Pic6: 8_mX5_64bitGUI2.png

Conclusion:

Triangulation is process of measuring bearings and calculating distances (using the Sine Rule). Trilateration is the process of measuring distances and calculating bearings (using Cosine Rule).
Geometrically, each of the 4 sensors and its target distance define a sphere upon which the target must lie, and that should be the common point of intersection of all 4 sphere. 
64-bit isn’t a magic bullet. Other than that, you only need to change if you’ve already encountered one of the limits imposed by 32-bit or you want to develop plug-ins for 64-bit app or just be compatible with a 64-bit operation system.

Script: softwareschule.ch/examples/maxbox_starter115.txt

References:

Compiled Project:
https://github.com/maxkleiner/maXbox4/releases/download/V4.2.4.80/maxbox5.zip

Topic:
http://delphiforfun.org/Programs/Math_Topics/PointFrom4Sensors.htm

https://gis.stackexchange.com/questions/17344/differences-between-triangulation-and-trilateration

Preparation:
https://stackoverflow.com/questions/4051603/how-should-i-prepare-my-32-bit-delphi-programs-for-an-eventual-64-bit-compiler

Doc and Tool: https://maxbox4.wordpress.com

Appendix

Unit UMatrix

Procedure Determinant( Dimen : integer; Data : TNmatrix; var Det : Float;
var Error : byte)’);

Procedure Inverse2( Dimen : integer; Data : TNmatrix; var Inv : TNmatrix;
var Error : byte)’);

Procedure
Gaussian_Elimination(Dimen:integer;Coefficients:TNmatrix;Constants:TNvector;
var Solution:TNvector;var Error:byte);

Procedure Partial_Pivoting(Dimen:integer; Coefficients:TNmatrix;Constants:TNvector;
var Solution:TNvector;var Error:byte);

Procedure LU_Decompose(Dimen:integer;Coefficients:TNmatrix;
var Decomp:TNmatrix;var Permute:TNmatrix;var Error:byte);

Procedure LU_Solve(Dimen: integer;var Decomp TNmatrix;Constants:TNvector;
var Permute:TNmatrix;var Solution:TNvector;var Error:byte);

Procedure Gauss_Seidel( Dimen : integer; Coefficients : TNmatrix; Constants : TNvector;
Tol : Float; MaxIter : integer; var Solution : TNvector;
var Iter : integer; var Error : byte)’);
end;

CL.AddTypeS(‘TNvector’, ‘array[1..30] of Extended’);

//TNvector = array[1..TNArraySize] of Float;
CL.AddTypeS(‘TNmatrix’, ‘array[1..30] of TNvector’);
//TNmatrix = array[1..TNArraySize] of TNvector;
CL.AddConstantN(‘TNNearlyZero’,’Extended’).setExtended( 1E-07);
CL.AddConstantN(‘TNArraySize’,’LongInt’).SetInt( 30);

CL.AddDelphiFunction(‘Procedure Gaussian_Elimination( Dimen : integer; Coefficients : TNmatrix; Constants : TNvector; var Solution : TNvector; var Error : byte)’);
CL.AddDelphiFunction(‘Procedure Partial_Pivoting( Dimen : integer; Coefficients : TNmatrix; Constants : TNvector; var Solution : TNvector; var Error : byte)’);
CL.AddDelphiFunction(‘Procedure LU_Decompose( Dimen : integer; Coefficients : TNmatrix; var Decomp : TNmatrix; var Permute : TNmatrix; var Error : byte)’);
CL.AddDelphiFunction(‘Procedure LU_Solve2( Dimen : integer; var Decomp : TNmatrix; Constants : TNvector; var Permute : TNmatrix; var Solution : TNvector; var Error : byte)’);
CL.AddDelphiFunction(‘Procedure Gauss_Seidel( Dimen : integer; Coefficients : TNmatrix; Constants : TNvector; Tol : Float; MaxIter : integer; var Solution : TNvector; var Iter : integer; var Error : byte)’);
end;

Solution 1: 5.00 5.00 5.00

Distance to sphere 1 is 6.928 (radius 6.928)

Distance to sphere 2 is 6.403 (radius 6.403)

Distance to sphere 3 is 6.403 (radius 6.403)

Solution 2: 5.00 -3.00 5.00

Distance to sphere 1 is 6.928 (radius 6.928)

Distance to sphere 2 is 6.403 (radius 6.403)

Distance to sphere 3 is 6.403 (radius 6.403)

Sum of coordinate differences:

Solution 1: 1.75172, Solution #2: 24.05681

Using Solution 1 set

Solution 1: 5.00 5.00 5.00

Distance to sphere 1 is 6.92800 (vs. measured 6.92800)

Distance to sphere 2 is 6.40300 (vs. measured 6.40300)

Distance to sphere 3 is 6.40300 (vs. measured 6.40300)

Distance to sphere 4 is 3.46390 (vs. measured 3.46400)

//}

Max Kleiner 02/12/2023

CC 40104
Source: Historical Railway Images

https://en.wikipedia.org/wiki/Arbal%C3%A8te_(train)

Fleischmann N V 200 126
Minitrix 16692
Lematec SNCF BB 9274
Lima #309157 Blauer Enzian / Helvetia
TEE Collection

That code works because of a new feature introduced in D2010, namely the ability to recover a reference to the object that implements an interface. Note though that if the IStream is implemented by something other than your Delphi code, then the cast will fail.

function QRCcodeOle(Wid,Hei:Word; C_Level,apath:string; const Data:string): string;
var
  httpReq,hr: Olevariant;  instream: IStream;
  jo: TJSON; strm :TMemoryStream; 
begin  
  httpReq:= CreateOleObject('WinHttp.WinHttpRequest.5.1');
  //jo:= TJSON.Create();
  hr:= httpReq.Open('GET',  
                       format(URLGoogleQRCODE,[Wid,Hei,C_Level,HTTPEncode(Data)]))            
  httpReq.setRequestheader('content-type','application/octet-stream'); 
  //httpReq.setRequestheader('Authorization','Bearer '+ CHATGPT_APIKEY2);
  if hr= S_OK then HttpReq.Send();
  strm:= TMemoryStream.create;
  If HttpReq.Status = 200 Then begin
    try
       //https://stackoverflow.com/questions/4938601/getting-an-istream-from-an-olevariant
       strm:= getmemStreamfromIStream2(HttpReq.responsestream);
       //getmemStreamfromIStream2file(hrstream, apath);
       writeln('responsestream size: '+itoa(strm.size)); 
       strm.savetoFile(apath)
       openFile(apath);  
    except
       writeln('EHTTPex: '+ExceptiontoString(exceptiontype, exceptionparam));
    finally
       strm.free;
       httpreq:= unassigned; 
    end;  
  end;                
end;
//https://stackoverflow.com/questions/15441014/how-do-i-load-an-istream-into-a-tmemorystream
Build SimTool with Python
PyQtGraph

Good morning Max

Thank you for your transcription, I’d love to take a look at it.
I’ve read “1.1 Architecture Goals” for the moment.

My picture was simply a “brain dump” so that I could gain an overview and clarity.
I will not use this image in the report. This is just a work aid.

True, a legend is missing. This was freestyle with no reference to UML or Arc42. The meaning was:
Arrow colors
Green = Read data
Red = write data
Black = call (e.g. of a method)
rectangles
Blue = data
Green = methods

My intention – and how this image came to be – was based on one aspect of the “CQRS” pattern:
With prototyping, I first developed individual functionalities and inserted them (not at first, but then) into the “main” in an unstructured manner.
–> With the CQRS approach I wanted to create order, i.e. which methods do I use to write which data and when. And which methods read these. And where should this data be kept?

Through this approach I got to the point where I got a workable “result”, but skipped the previous design.
That was exactly the (weak) point where I had a hard time in the last two weeks.

The MVC is also mentioned in the Arc42 book (by Dr. Gernot Starke) for “systems with graphical user interfaces”.
He also formulated it in Chapter 7.6.3 “GUI-relevant architectural patterns” in such a way that in reality the frameworks used (in my case Qt) usually already dictate the architectural decision.
In my case this is actually the MVC. Or – if I understand correctly – Qt even simplifies the MVC into a model view (i.e. view and controller are combined in Qt), see https://doc.qt.io/qt-5/model-view-programming. html.

Thank you Max for your feedback! It’s a nudge in the right direction at the right time.
With this basis the MVC pattern is actually possible. the Model/View model from Qt, which is the right way for me to use the architecture and design for my work and to document it in the report.

My Qt GUI is the view and implements the display of the data interpreted by the backend.
At the same time, it accepts user input and fulfills the controller role.
My classes “Topology” and “DrawAlgorithm” represent the model in the backend.
I think this is the right approach.
Thank you very much for your help!

E good start to the week.

Greetings, Andy

Cannonball

Here’s an animated graphics program that builds on the bouncing ball program by adding some horizontal movement to the ball, drawing a primitive cannon that you can aim, a target that can be moved and an adjustable powder charge to give the initial push to the ball. Cannonball is also the project-name of the 64bit migration from maXbox4 to maXbox5.

Background and techniques

The rotate and translate routines developed in the Rotate A Square  program are used here to elevate the cannon.  The ball movement loop is similar to the Bouncing Ball program with the addition of a horizontal component.  Initial velocities in the X and Y direction are proportional to the cosine and sine of the elevation angle respectively.   I’ll defer further discussion of that for a Math Topic page.  (The text really  needs some illustrations that I haven’t developed yet.)  

http://www.softwareschule.ch/examples/cannonball.txt

The only other logic is to determine  whether the cannonball has hit the target.   “Collision detection” is a common (and complicated) problem in most animated graphics applications.  I haven’t studied up on it yet, so just did a “quick and dirty” implementation checking if the distance from the center of the cannonball is less than its radius from the left or top edges of the target after each move.  The problem is that, for low angles, the horizontal movement may take the ball from one side of the target to the other side in one loop increment, so we never know that we went right through it!    Oh well, I have to leave something for you readers to work on.

http://delphiforfun.org/Programs/cannon_balls.htm

Trajectories of three objects thrown at the same angle (70°). The black object does not experience any form of drag and moves along a parabola. The blue object experiences Stokes’ drag, and the green object Newtonian drag.

https://en.wikipedia.org/wiki/Ballistics

{************* TheoreticalCalc **********}
procedure TheroreticalCalc;
var
  root,T1, Vf:float;
  Vxf, Vyf:float;
  X1,Y1:float;
  TTop, Xtop,Ytop:float;
  Tlast, VyLast, Xlast:float;
  floor:float;
begin
  with {stats.}amemo1.lines do begin
    clear;
    add(format('Barrel Len %d, Angle %6.1f, Initial V %6.1f, gravity %6.1f',
                [barrellength,180*theta/pi,v1,g]));
    if g=0 then g:=0.001;            
    root:= v1*v1 - 2*g*sin(theta)*Barrellength;
    if root>=0 then begin
      T1:=(v1 - sqrt(root))/(g*sin(theta+0.001));
      Vf:= v1 - g*sin(theta)*T1;
      Vxf:=Vf*cos(theta);
      Vyf:=Vf*sin(theta);
      X1:=Barrellength*cos(theta);
      Y1:=Barrellength*sin(Theta);
      floor:=(origin.y+ballradius)-groundlevel;
      {out of barrel, Vx remains constant, Vy := Vyf- g*DeltaT}
      {Vy=0 then Vyf-g*Ttop=0 or Ttop=Vyf/g}
      Ttop:=Vyf/g;
      {x distance at top} Xtop:=Vxf*Ttop;
      {height at top = average y velocity+ time}   Ytop:=(Vyf + 0)/2*TTop;
      {Time to fall from ytop to groundlevel, descending part of projectiles path}
      //Vylast:=2*g*(Ytop+Y1-floor); {speed when ball hits ground}
      TLast:=sqrt(2*(Y1+YTop-floor)/g );
      Xlast:=Vxf*TLast;
      add(format('Time in barrel %6.1f seconds',[T1]));
      add(format('X distance at end of barrel %6.1f',[X1]));
      add(format('Y distance at end of barrel %6.1f',[Y1]));
      add(format('Time to top of freeflight arc %6.1f, %6.1f total',[Ttop,T1+Ttop]));
      add(format('X distance to top of freeflight arc %6.1f, %6.1f total',[Xtop,X1+Xtop]));
      add(format('Height above barrel to top of freeflight arc %6.1f, %6.1f total',
                                                                    [Ytop,Y1+Ytop]));
      add(format('Time to reach ground from max height %6.1f, %6.1f total',
                                                                    [TLast,T1+Ttop+TLast]));
      add(format('X distance from top of freeflight arc to end %6.1f, %6.1f total',
                                                                    [XLast,X1+Xtop+XLast]));
    end else add('Velocity too low, cannonball does not exit barrel');
  end;
end;


   procedure rotate(var p:Tpoint; a:float);
   {rotate a point to angle a from horizontal}
   var t:TPoint;
   begin
     t:=P;
     p.x:=trunc(t.x*cos(a)-t.y*sin(a));
     p.y:=trunc(t.x*sin(a)+t.y*cos(a));
   end;

   procedure translate(var p:TPoint; t:TPoint);
   {translate a point by t.x and t.y}
   Begin
     p.x:=p.x+t.x;
     p.y:=p.y+t.y;
   end;

As an improvement:

A series of concentric ellipses could be drawn on to draw a better looking target.  It should be a TTarget object derived from some graphic object so that it knows how to redraw itself, can be redrawn, etc.   
Same idea applies to the cannon – a better looking cannon object that knows how to redraw itself at any specified angle and position.
The program could be converted to a game by limiting the number of shots for a turn, keeping score, allowing multiple players, adding a level 2 with a slowly moving target, etc.   

Cannonball Report for BPM 112


Report Cannonball Simulation for #112

Today we make a detour into the world of ballistics, simulation & training.
One of my friends on Delphi for Fun gave me the idea to port the executable to a script for windows 11 as a preparation for the 64bitbox.

So ballistics is the study of the motion of projectiles, such as bullets, shells, and rockets, in our script we deal only with balls. It is a branch of mechanics that deals with the behavior of objects in motion. Ballistics can be divided into three main categories: internal ballistics, external ballistics, and terminal ballistics.
So I translated the Delphi program with a few improvements into that script: http://www.softwareschule.ch/examples/cannonball.txt

image1: 1_1234_cannonball4.png

set background map

Of course we can simulate a cannonball using a physics simulation software or in our case integrate that model with Pascal. This simulation allows you to blast a ball out of a cannon and challenge yourself to hit a moveable target. You can set parameters such as angle (elevation), initial speed (powder charge), and mass (gravity), and explore the vector representations.
Also an explainable statistic is part of the script, as summary or detailed (our standard case which hit the target):

Summary of study case

  • Barrel Len 87, Angle 45.0, Initial V 24.0, gravity 1.0
  • Time in barrel 3.8 seconds
  • X distance at end of barrel 61.5
  • Y distance at end of barrel 61.5
  • Time to top of freeflight arc 15.1, 18.9 total
  • X distance to top of freeflight arc 226.5, 288.1 total
  • Height above barrel to top of freeflight arc 113.3, 174.8 total
  • Time to reach ground from max height 18.7, 37.6 total

X distance from top of freeflight arc to end 281.4, 569.5 total

image2: 2_1234_cannonball4_studycase.png

The interesting thing is that this simulation shows how the motion of a projectile like a cannonball is fundamentally the same as the orbit of a celestial body like the moon!
The rotate and translate routines developed are used here to elevate the cannon. The ball movement loop is similar to a Bouncing Ball program with the addition of a horizontal component. Initial velocities in the X and Y direction are proportional to the cosine and sine of the elevation angle respectively.
The barrel is a bit tricky; We do assume that the cannonball inside the barrel is “rolling up a ramp” with the component of gravity acting parallel to the barrel being the force acting to reduce the velocity of the cannonball in both x and y directions, so we keep an eye on the distance function:

function distance(p1,p2:TPoint):float;
begin
result:= sqrt(sqr(p1.x-p2.x)+sqr(p1.y-p2.y));
end;

   function distance(p1,p2:TPoint):float;
   begin
     result:= sqrt(sqr(p1.x-p2.x)+sqr(p1.y-p2.y));
   end; 

Two functions, Rotate and Translate, do the rotation of points. Rotation about an origin point of (0,0) is rather straightforward as we can see from the code below:

procedure rotate(var p:Tpoint; a:float);
{rotate a point to angle a from horizontal}
var t:TPoint;
begin
t:=P;
p.x:=trunc(t.xcos(a)-t.ysin(a));
p.y:=trunc(t.xsin(a)+t.ycos(a));
end;

procedure translate(var p:TPoint; t:TPoint);
{translate a point by t.x and t.y}
Begin
p.x:=p.x+t.x;
p.y:=p.y+t.y;
end;

   procedure rotate(var p:Tpoint; a:float);
   {rotate a point to angle a from horizontal}
   var t:TPoint;
   begin
     t:=P;
     p.x:=trunc(t.x*cos(a)-t.y*sin(a));
     p.y:=trunc(t.x*sin(a)+t.y*cos(a));
   end;

   procedure translate(var p:TPoint; t:TPoint);
   {translate a point by t.x and t.y}
   Begin
     p.x:=p.x+t.x;
     p.y:=p.y+t.y;
   end;  

Once we have the point rotated to the desired angle relative to then origin, Translate() can move the point by adding the new x and y origin coordinates to the x and y values of the point of type TPoint.
The other logic is to determine whether the cannonball has hit the target, which is moveable by a trackbar. “Collision detection” is a common (and also complicated) problem in most animated graphics apps. The implementation is checking if the distance from the center of the cannonball is less than its radius from the left or top edges of the target after each move or hit. The problem is that, for low angles, a horizontal movement may take the ball from one side of the target to the other side in one loop increment, so we never know that we went right through it!

A funny thing is the storage of cannonballs; Spherical objects, such as cannonballs, can be stacked to form a pyramid with one cannonball at the top, sitting on top of a square composed of four cannonballs, sitting on top of a square composed of nine cannonballs, and so forth.

Win11 scriot

image3: 3_1234_cannonball4compiler1.png

In PyGame for example, collision detection is done using Rect objects. The Rect object offers various methods for detecting collisions between objects. Even the collision between a rectangular and circular object such as a paddle and a ball can be detected by a collision between two rectangular objects, the paddle and the bounding rectangle of the ball. Now we can summarize the theoretic results in a procedure of our statistic:

{* TheoreticalCalc **}
procedure TheroreticalCalc;
var
root,T1, Vf:float;
Vxf, Vyf:float;
X1,Y1:float;
TTop, Xtop,Ytop:float;
Tlast, VyLast, Xlast:float;
floor:float;
begin
with {stats.}amemo1.lines do begin
clear;
add(format('Barrel Len %d, Angle %6.1f, Initial V %6.1f, gravity %6.1f',
[barrellength,180theta/pi,v1,g])); if g=0 then g:=0.001; root:= v1v1 - 2gsin(theta)Barrellength; if root>=0 then begin T1:=(v1 - sqrt(root))/(gsin(theta+0.001));
Vf:= v1 - gsin(theta)T1;
Vxf:=Vfcos(theta); Vyf:=Vfsin(theta);
X1:=Barrellengthcos(theta); Y1:=Barrellengthsin(Theta);
floor:=(origin.y+ballradius)-groundlevel;
{out of barrel, Vx remains constant, Vy := Vyf- gDeltaT} {Vy=0 then Vyf-gTtop=0 or Ttop=Vyf/g}
Ttop:=Vyf/g;
{x distance at top} Xtop:=VxfTtop; {height at top = average y velocity+ time} Ytop:=(Vyf + 0)/2TTop;
{Time to fall from ytop to groundlevel, descending part of projectiles path}
{speed when ball hits ground}
TLast:=sqrt(2(Y1+YTop-floor)/g ); Xlast:=VxfTLast;
add(format('Time in barrel %6.1f seconds',[T1]));
add(format('X distance at end of barrel %6.1f',[X1]));
add(format('Y distance at end of barrel %6.1f',[Y1]));
add(format('Time to top of freeflight arc %6.1f, %6.1f total',[Ttop,T1+Ttop]));
add(format('X distance top of freeflight arc %6.1f, %6.1f total',[Xtop,X1+Xtop]));
add(format('Height above barrel to top of freeflight arc %6.1f, %6.1f total',
[Ytop,Y1+Ytop]));
add(format('Time to reach ground from max height %6.1f, %6.1f total',
[TLast,T1+Ttop+TLast]));
add(format('X distance from top of freeflight arc to end %6.1f, %6.1f total',
[XLast,X1+Xtop+XLast]));
end else add('Velocity too low, cannonball does not exit barrel');
end;
end;
main gui

The 64-bit version needs a small update of the

IntersectRect API function to detect intersections

cause it needs IntersectRect2 function to detect as bool:

http://www.softwareschule.ch/examples/cannonball2.txt

By the way I asked ChatGPT how can I program cannonball in Pascal and the answer:
To program a cannonball in Pascal, you can use the following steps:

  1. Define the initial position and velocity of the cannonball.
  2. Calculate the acceleration of the cannonball due to gravity.
  3. Update the velocity and position of the cannonball using the calculated acceleration.
  4. Repeat step 3 until the cannonball collides with an object or reaches a certain height.

In this example code snippet, CircleRectCollision() is a custom function that detects collision between a circle and a rectangle. You can modify this function to suit your needs; the main part of the script has only 4 procedures:

processmessagesOFF;
loadStatForm();
loadmainForm();
UpdateImage();

@main part

Links and References:

http://www.softwareschule.ch/examples/cannonball.txt

http://delphiforfun.org/Programs/bouncing_ball.htm

https://en.wikipedia.org/wiki/Ballistics

4 Different Apps of maXbox4

The scripts are 1247_Dispenser_mX4_Form12.pas, 1243_U_Cannonballs32.pas, 1241_pixabay_api_tester12.pas and 1234_NeuralNetwork2_XOR_test12.pas and 1234_NeuralNetwork2_XOR_sampleEU_EKON27.pas.

Pixabay RestClient

The road to 64-bit

If you have a code base of 32-bit Windows Delphi applications that you want to convert to 64-bit Windows, you should

  • Open your 32-bit application in the IDE, add and activate the 64-bit Windows target platform, and compile your application as a 64-bit Windows application. (For details, see Steps in Creating Multi-Device Applications.)
  • Review and handle the following issues (mostly related to pointer operations, NativeInt size, and Assembly code).
compare to 32 to 64

Winapi Issues

  • If you pass pointers to SendMessage/PostMessage/TControl.Perform, the wParam and lParam parameters should be type-casted to the WPARAM/LPARAM type and not to Integer/Longint.
    • Correct:SendMessage(hWnd, WM_SETTEXT, 0, LPARAM(@MyCharArray));
    • Wrong:SendMessage(hWnd, WM_SETTEXT, 0, Integer(@MyCharArray));
  • Replace SetWindowLong/GetWindowLog with SetWindowLongPtr/GetWindowLongPtr for GWLP_HINSTANCEGWLP_IDGWLP_USERDATAGWLP_HWNDPARENT and GWLP_WNDPROC as they return pointers and handles. Pointers that are passed to SetWindowLongPtr should be type-casted to LONG_PTR and not to Integer/Longint.
    • Correct:SetWindowLongPtr(hWnd, GWLP_WNDPROC, LONG_PTR(@MyWindowProc));
    • Wrong:SetWindowLong(hWnd, GWL_WNDPROC, Longint(@MyWindowProc));
  • Pointers that are assigned to the TMessage.Result field should use a type-cast to LRESULT instead of Integer/Longint.
    • Correct:Message.Result := LRESULT(Self);
    • Wrong:Message.Result := Integer(Self);
  • All TWM...-records for the windows message handlers must use the correct Windows types for the fields:Msg: UINT; wParam: WPARAM; lParam: LPARAM; Result: LRESULT)

https://docwiki.embarcadero.com/RADStudio/Sydney/en/Converting_32-bit_Delphi_Applications_to_64-bit_Windows

CC 21004
A warm welcome
Test on 4 Python Versions
In a Delphi XE7 64-bit VCL program, the unit Vcl.OleAutocannot be found:[dcc64 Fatal Error] Unit1.pas(33): F1026 File not found: 'Vcl.OleAuto.dcu'While it works without problems in a 32-bit program:uses  Vcl.OleAuto;...
FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); If the file does not have a BOM then you need to explicitly specify the encoding, e.g.LoadFromFile(FileName, TEncoding.UTF8);LoadFromFile(FileName, TEncoding.Unicode);//UTF-16 LELoadFromFile(FileName, TEncoding.BigEndianUnicode);//UTF-16 BE
Another step to 64-bit as the cannonball resource test

Runtime Library

  • Overloads. For functions that took PChar, there are now PAnsiChar and PWideChar versions so the appropriate function gets called.
  • AnsiXXX functions are a consideration:
    • SysUtils.AnsiXXXX functions, such as AnsiCompareStr:
      • Remain declared with string and float to UnicodeString.
      • Offer better backward compatibility (no need to change code).
    • The AnsiStrings unit’s AnsiXXXX functions offer the same capabilities as the SysUtils.AnsiXXXX functions, but work only for AnsiString. Also, the AnsiStrings.AnsiXXXX functions provide better performance for an AnsiString than SysUtils.AnsiXXXX functions, which work for both AnsiString and UnicodeString, because no implicit conversions are performed.
  • Write/Writeln and Read/Readln:
    • Continue to convert to/from ANSI/OEM code pages.
    • Console is mostly ANSI or OEM anyway.
    • Offer better compatibility with legacy applications.
    • TFDD (Text File Device Drivers):
      • TTextRec and TFileRec.
      • File names are WideChar, but as above, data is ANSI/OEM.
    • Use TEncoding and TStrings for Unicode file I/O.
  • PByte – declared with $POINTERMATH ON. This allows array indexing and pointer math like PAnsiChar.
  • String information functions:
  • RTL provides helper functions that enable users to do explicit conversions between code pages and element size conversions. If developers are using the Move function on a character array, they cannot make assumptions about the element size. Much of this problem can be mitigated by making sure all RValue references generate the proper calls to RTL to ensure proper element sizes.

Components and Classes

  • TStrings: Store UnicodeString internally (remains declared as string).
  • TWideStrings (may get deprecated) is unchanged. Uses WideString (BSTR) internally.
  • TStringStream
    • Has been rewritten –- defaults to the default ANSI encoding for internal storage.
    • Encoding can be overridden.
    • Consider using TStringBuilder instead of TStringStream to construct a string from bits and pieces.
  • TEncoding
    • Defaults to users’ active code page.
    • Supports UTF-8.
    • Supports UTF-16, big and little endian.
    • Byte Order Mark (BOM) support.
    • You can create descendent classes for user-specific encodings.
  • Component streaming (Text DFM files):
    • Are fully backward-compatible.
    • Stream as UTF-8 only if component type, property, or name contains non-ASCII-7 characters.
    • String property values are still streamed in “#” escaped format.
    • May allow values as UTF-8 as well (open issue).
    • Only change in binary format is potential for UTF-8 data for component name, properties, and type name.

Byte Order Mark

The Byte Order Mark (BOM) should be added to files to indicate their encoding:

  • UTF-8 uses EF BB BF.
  • UTF-16 Little Endian uses FF FE.
  • UTF-16 Big Endian uses FE FF.

Steps to Unicode-enable your applications

You need to perform these steps:

  1. Review char- and string-related functions.
  2. Rebuild the application.
  3. Review surrogate pairs.
  4. Review string payloads.

For more details, see Enabling Your Applications for Unicode

Most of the times you deal with pointers or assembler code like:

function StrToWord(const Value: String): Word;
begin
  Result:= Word(pointer(@Value[1])^);
end;

function WordToStr(const Value: Word): WordStr;
begin
  SetLength(Result, SizeOf(Value));
  Move(Value, Result[1], SizeOf(Value));
end;

Or you can switch from assembler to code:

{$define GEOMETRY_NO_ASM}

procedure DivMod(dividend : Integer; divisor: Word; var result, remainder : Word);
{$ifndef GEOMETRY_NO_ASM}
asm
   push  ebx
   mov   ebx, edx
   mov   edx, eax
   shr   edx, 16
   div   bx
   mov   ebx, remainder
   mov   [ecx], ax
   mov   [ebx], dx
   pop   ebx
{$else}
begin
   Result:=Dividend div Divisor;
   Remainder:=Dividend mod Divisor;
{$endif}
end;

One of the unsolved problem is to catch an AccessViolation instead of

CL.AddTypeS('TRuntimeError', '( reNone, reOutOfMemory, reInvalidPtr, reDivByZ'   +'ero, reRangeError, reIntOverflow, reInvalidOp, reZeroDivide, reOverflow, r'   +'eUnderflow, reInvalidCast, reAccessViolation, rePrivInstruction, reControl'   +'Break, reStackOverflow, reVarTypeCast, reVarInvalidOp, reVarDispatch, reVa'   +'rArrayCreate, reVarNotArray, reVarArrayBounds, reAssertionFailed, reExtern'   +'alException, reIntfCastError, reSafeCallError )');

The weird thing was in one of the previous alpha versions (see below) the catch of the AV was present but in the meantime the app stuck and exits:

Catch an AV

After debugging I realized it is a first chance exception which works as long the debugger is running with break or continue but without debugger the app disappears without forwarding the AV on the output like AV at address xyz read of address 000.

first chance exception
DSG Test

Top 10 Algorithms

What are the top 10 algorithms every software engineer should know by heart?

I wouldn’t say so much specific algorithms, as groups of algorithms.

  1. Greedy algorithms. If your problem can be solved with an algorithm that can make a decision now and at the end this decision will still be optimal, then you don’t need to look any further. Examples are Prim, Kruscal for Minimal Spanning Trees (MST) and the Fractional Knapsack problem.
  2. Divide and Conquer. Examples of this group are binary search and quicksort. Basically, you divide your problem into two distinct sub-problems, solve each one separately and at the end combine the solutions. Concerning complexity, you will probably get something recursive e.g. T(n) = 2T(n/2) + n, which you can solve using the Master theorem
  3. Graph and search algorithms. Other than the MST, Breadth First Search (BFS) and Depth First Search (DFS), Dijkstra and possibly A*. If you feel you want to go further in this, Bellman-Ford (for dense graphs), Branch and Bound, Iterative Deepening, Minimax, AB search.
  4. Flows. Basically, Ford-Fulkerson.
  5. Simulated Annealing. This is a very easy, very powerful randomized optimization algorithm. It gobbles NP-hard problems like Travelling Salesman Problem (TSP) for breakfast.
  6. Hashing. Properties of hashing, known hashing algorithms and how to use them to make a hashtable.
  7. Dynamic Programming. Examples are the Discrete Knapsack Problem and Longest Common Subsequence (LCS).
  8. Randomized Algorithms. Two great examples are given by Karger for the MST and Minimum Cut.
  9. Approximation Algorithms. There is a trade off sometimes between solution quality and time. Approximation algorithms can help with getting a not so good solution to a very hard problem at a good time.
  10. Linear Programming. Especially the simplex algorithm but also duality, rounding for integer programming etc.

RTL location for the 64bitbox

Variants in 'sys\Variants.pas',
VarUtils in 'sys\VarUtils.pas',
SysConst in 'sys\SysConst.pas',
SysUtils in 'sys\SysUtils.pas',
SyncObjs in 'common\SyncObjs.pas',
Types in 'sys\Types.pas',
VCLCom in 'common\VCLCom.pas',
ComConst in 'common\ComConst.pas',
ComObj in 'common\ComObj.pas',
ComObjWrapper in 'common\ComObjWrapper.pas',
RTLConsts in 'common\RTLConsts.pas',
Contnrs in 'common\Contnrs.pas',
ConvUtils in 'common\ConvUtils.pas',
DateUtils in 'common\DateUtils.pas',
IniFiles in 'common\IniFiles.pas',
Masks in 'common\Masks.pas',
Math in 'common\Math.pas',
Registry in 'common\Registry.pas',
StdConvs in 'common\StdConvs.pas',
StdVCL in 'common\StdVCL.pas',
StrUtils in 'common\StrUtils.pas',
TypInfo in 'common\TypInfo.pas',
VarConv in 'common\VarConv.pas',
VarCmplx in 'common\VarCmplx.pas',
Classes in 'common\Classes.pas',
MaskUtils in 'common\MaskUtils.pas',
HelpIntfs in 'common\HelpIntfs.pas',
ScktComp in 'common\ScktComp.pas',
AccCtrl in 'win\AccCtrl.pas',
AclAPI in 'win\AclAPI.pas',
ActiveX in 'win\ActiveX.pas',
ComSvcs in 'win\ComSvcs.pas',
ADOInt in 'win\ADOInt.pas',
AspTlb in 'win\AspTlb.pas',
COMAdmin in 'win\COMAdmin.pas',
CommCtrl in 'win\CommCtrl.pas',
CommDlg in 'win\CommDlg.pas',
Cpl in 'win\Cpl.pas',
DDEml in 'win\DDEml.pas',
Dlgs in 'win\Dlgs.pas',
DwmApi in 'win\DwmApi.pas',
FlatSB in 'win\FlatSB.pas',
ImageHlp in 'win\ImageHlp.pas',
Imm in 'win\Imm.pas',
Isapi in 'win\Isapi.pas',
Isapi2 in 'win\Isapi2.pas',
LZExpand in 'win\LZExpand.pas',
Mapi in 'win\Mapi.pas',
Messages in 'win\Messages.pas',
MMSystem in 'win\MMSystem.pas',
msxml in 'win\msxml.pas',
Mtx in 'win\Mtx.pas',
MultiMon in 'win\MultiMon.pas',
Nb30 in 'win\Nb30.pas',
Ns30Fix in 'win\Ns30Fix.pas',
Ns35Fix in 'win\Ns35Fix.pas',
Ns36Fix in 'win\Ns36Fix.pas',
Nsapi in 'win\Nsapi.pas',
ObjComAuto in 'common\ObjComAuto.pas',
ObjAuto in 'common\ObjAuto.pas',
OleDB in 'win\OleDB.pas',
OleDlg in 'win\OleDlg.pas',
OpenGL in 'win\OpenGL.pas',
oleacc in 'win\oleacc.pas',
Penwin in 'win\Penwin.pas',
PsAPI in 'win\PsAPI.pas',
RegStr in 'win\RegStr.pas',
RichEdit in 'win\RichEdit.pas',
ShellAPI in 'win\ShellAPI.pas',
SHFolder in 'win\SHFolder.pas',
ShlObj in 'win\ShlObj.pas',
ShLwApi in 'win\ShLwApi.pas',
StrHlpr in 'sys\StrHlpr.pas',
TlHelp32 in 'win\TlHelp32.pas',
UrlMon in 'win\UrlMon.pas',
UxTheme in 'win\UxTheme.pas',
VarHlpr in 'sys\VarHlpr.pas',
WideStrings in 'common\WideStrings.pas',
WideStrUtils in 'common\WideStrUtils.pas',
windows in 'win\windows.pas',
winInet in 'win\winInet.pas',
Winsafer in 'win\Winsafer.pas',
WinSock in 'win\WinSock.pas',
winSpool in 'win\winSpool.pas',
winSvc in 'win\winSvc.pas',
CorError in 'win\CorError.pas',
CorHdr in 'win\CorHdr.pas',
Cor in 'win\Cor.pas',
DXTypes in 'win\DXTypes.pas',
DXFile in 'win\DXFile.pas',
DxDiag in 'win\DxDiag.pas',
D3DX8 in 'win\D3DX8.pas',
D3DX9 in 'win\D3DX9.pas',
Direct3D in 'win\Direct3D.pas',
Direct3D8 in 'win\Direct3D8.pas',
DX7toDX8 in 'win\DX7toDX8.pas',
Direct3D9 in 'win\Direct3D9.pas',
DirectDraw in 'win\DirectDraw.pas',
DirectShow9 in 'win\DirectShow9.pas',
DirectInput in 'win\DirectInput.pas',
DirectSound in 'win\DirectSound.pas',
DirectPlay8 in 'win\DirectPlay8.pas',
DirectMusic in 'win\DirectMusic.pas',
WMF9 in 'win\WMF9.pas',
ZLibConst in 'common\ZLibConst.pas',
ZLib in 'common\ZLib.pas',
Character in 'common\Character.pas',
Generics.Defaults in 'common\Generics.Defaults.pas',
Generics.Collections in 'common\Generics.Collections.pas',
Rtti in 'common\Rtti.pas',
TimeSpan in 'common\TimeSpan.pas',
Diagnostics in 'common\Diagnostics.pas',
AnsiStrings in 'common\AnsiStrings.pas',
TpcShrd in 'win\TpcShrd.pas',
RtsCom in 'win\RtsCom.pas',
MsInkAut in 'win\MsInkAut.pas',
MsInkAut15 in 'win\MsInkAut15.pas',
Manipulations in 'win\Manipulations.pas',
IOUtils in 'common\IOUtils.pas',
D2D1 in 'win\D2D1.pas',
DxgiFormat in 'win\DxgiFormat.pas',
Wincodec in 'win\Wincodec.pas',
KnownFolders in 'win\KnownFolders.pas',
ObjectArray in 'win\ObjectArray.pas',
PropSys in 'win\PropSys.pas',
PropKey in 'win\PropKey.pas',
StructuredQuery in 'win\StructuredQuery.pas',
StructuredQueryCondition in 'win\StructuredQueryCondition.pas'; 
  • You can tell the debugger to ignore certain kinds of exceptions. Figure 3 shows Delphi’s language-exception options. Add an exception class to the list, and all exceptions of that type and of any descendant types will pass through to your program without Delphi interfering.
enter image description here
step to 64bit

In its default settings, the Delphi IDE notifies you whenever an exception occurs in your program, as in Figure 1. What’s important to realize is that at that point, none of your program’s exception-handling code has run yet. It’s all Delphi itself; its special status as a debugger allows it to get first notification of any exception in your program, even before your program knows about it.

enter image description here

Avoiding notification

If you do not want to be notified when an exception occurs, you have a few options.

  • You can use Delphi’s “advanced breakpoints” to disable exception handling around a region of code. To begin, set a breakpoint on the line of code where you want the IDE to ignore exceptions. Right-click on the breakpoint dot in the gutter and open the breakpoint-property dialog. In the advanced section are some check boxes. (See Figure 2.) Clear the “Break” box to prevent the debugger from interrupting your program at that line, and set the “Ignore subsequent exceptions” box. Afterward, set another breakpoint where you want the debugger to resume handling exceptions. Change its properties to handle subsequent exceptions.
catch the exception on

The odd thing is that I have wrapped my pascal call in a try except, which has handlers for AccessViolationExceptionCOMException and everything else, but when Delphi 10.4 intercepts the AccessViolationException, the debugger breaks on the method call (doc.OCR), and if I step through, it continues to the next line instead of entering the catch or except block.  So I decided to to catch the exception on the script runtime routine to get the most on my console from dynamic maXbox:

So for the reorganisation of the sources I have the latest revision with patches from issue #202 (commit 86a057c) but I am unable to compile the files at first (Core_D27) that are part of the PascalScript_Core_D27.dpk for that platform for Linux64, Win64 nor MacOS64.

Here’s some source output at first to show the internal exception handling for the 10.4 dccosx64 or dcc64 compiler (similar results exist for dcclinux64):

procedure TPSExec.ExceptionProc(proc, Position: Cardinal; Ex: TPSError; const s: tbtString; NewObject: TObject);
var
  d, l: Longint;
  pp: TPSExceptionHandler;   //debcnt: integer
begin
  ExProc := proc;
  ExPos := Position;
  ExEx := Ex;
  ExParam := s;
  inc(debcnt);
  if maxform1.GetStatDebugCheck then
     maxform1.memo2.lines.add('debug: '+inttostr(debcnt)+'-'+s+' '+inttostr(proc)+' err:'+inttostr(ord(ex)));     //fmain
   // halt(1);
   //pause;
   //ShowMessage('We do not get this far');
  if ExObject <> nil then
    ExObject.Free;
  ExObject := NewObject;
  //ShowMessage('We do not get this far: '+exparam);

  if Ex = eNoError then Exit;
  //maxform1.memo2.lines.add(s);
  // ShowMessage('We do not get this far');

  for d := FExceptionStack.Count -1 downto 0 do
  begin
    pp := FExceptionStack[d];
    if Cardinal(FStack.Count) > pp.StackSize then
    begin
      for l := Longint(FStack.count) -1 downto Longint(pp.StackSize) do
        FStack.Pop;
    end;

A 64-bit program has the following possible advantages over the same one compiled for 32-bit (x86):

  • More registers. 64-bit x86 chips have several more registers and this can, in theory (if the compiler takes advantage) result in faster code in some cases.
  • More memory. With a 32-bit program you were generally limited to either a 2GB address space or a 4GB address space in total, if you compiled with /LARGEADDRESSAWARE, which was about 3.5GB in practice due to Windows’ kernel/userspace split. A 64-bit process can address much more. This is only important if your app needs a lot of memory.
  • Ability to build plugins for 64-bit programs, like Explorer. Unless you’re using COM for a plugin, where data is marshalled, you can’t mix 32-bit and 64-bit code in the one process in Windows, such as a 64-bit EXE loading a 32-bit DLL. If you wanted to write an Explorer plugin, for example, you couldn’t have it work with the 64-bit version of Explorer with old versions of Delphi. You will be able to with the 64-bit version.
  • Delphi-specific: the compiler will use SSE/SSE2 instructions for floating point calculations, where the current 32-bit compiler only uses x87 FPU instructions (I think.) This should give a speed increase for floating-point math. You probably won’t even notice unless your app is highly FP-dependent (a game, perhaps, or a data processing application, that kind of thing.)

The answer to your question “will I benefit from having a 64 bits Delphi application?” is highly dependent on your specific application. In general, there is unlikely to be much benefit beyond, possibly, a small speed increase. Don’t rely on 64-bit to speed up a slow application though: you will still need to make algorithmic changes for large speed boosts. 64-bit isn’t a magic bullet. Other than that, you only need to change if you’ve already encountered one of the limits imposed by 32-bit – I suspect you haven’t, or you wouldn’t be asking the question.

If you decide to convert, you may find this thread very useful.

But one other thing: even if you don’t need to change, you might want to, especially if your app is a personal project. You might learn stuff, your code will be higher quality when you fix 32/64-bit issues, and a project like that can be fun. You’re a programmer, after all 🙂

println('message decrypt chaine: '+    RSADecrypt(RSAEncrypt(('123456'),'65537','536071'),'408473','536071')); 
>>> 123456

https://www.virustotal.com/gui/file/7eed102b255e4d61aefbea6c1826777a32f22257e4b993d33b9e4247f0855552/details

long unit- and compatability test
FPC and Lazarus is about 20 times faster, but why?

64-bit Report: http://www.softwareschule.ch/download/maxbox_starter113.pdf

Click to access maxbox_starter113.pdf

An Example to compare 32- and 64-bit: We have sensors at known locations in 3D space. Each sensor can supply distance information to a target but knows nothing about the target’s direction. Alternatively, the sensors are Satellites and the target is a GPS receiver which reads very accurate time stamps transmitted by the satellites and calculates distances based on time offsets between its clock when a clock time message is received and satellites’ clock time when the message was sent (as contained in the message).

http://delphiforfun.org/Programs/Math_Topics/PointFrom4Sensors.htm

There are 19 TEdit controls for user input; 4 for each of the 4 sensors plus 3 if the user wants to enter target values.  The target values were convenient when debugging the code with sets of points with known solutions.  In order to simplify the code, I defined an array, Sensors,  of  TSensorEdits records, each containing 4 TEdit pointers (object references are always pointers), plus the numeric version of the X, Y, Z, and R (distance)  values represent by the edits for that sensor.     

Unit UMatrix is the unit from the old Borland Turbo Pascal  Numeric Toolbox which contains the GuussianElimination procedure used here among other matrix operations.  

Load and Save buttons use Ini file types to save and reload problem cases.

Script Example at: https://sourceforge.net/projects/maxbox/files/Examples/13_General/966_U_PointInSpace52_mX4Form2_64.pas/download

The Road with Delphi 11.3 and Win 11

Since I use SynPdf.pas I have to include SynCommons.pas in my project. But it seems I’ve got more than I wanted. Sometimes when I debug in IDE and try to dig into some routine I get to Move procedure from SynCommons.pas instead of my proc where I want to come!

procedure Move(const Source; var Dest; Count: Integer);
asm // eax=source edx=dest ecx=count
         // original code by john o’harrow – included since delphi 2007
        cmp     ecx,32

what’s going on? And how to switch it off? I only need to export my reports to PDF! not logging or something else!

FastCode move and fillchar are included within SynCommons.pas.
You can get rid of it, by commenting the corresponding lines in the initialization block of this unit.
Under new versions of the framework, you have a conditional setting to disable it.

SynPDF was not tied to SynCommons.pas at the beginning, but a lot of duplicated code did appear between the two units.
Since SynCommons.pas is optimized for speed, and unit tested, we rather rely on it.
SmartLinking won’t make it big in your exe: logging and all the other won’t be part of it.

Do you mean I should comment these?
RedirectCode(GetAddressFromCall(@RecordCopyInvoke),@RecordCopy);
RedirectCode(GetAddressFromCall(@FillCharInvoke),@FillChar);
RedirectCode(GetAddressFromCall(@MoveInvoke),@Move);

Delphi 11.3 on Win 11

With Synedit changes were made of wordwrap and other language syntax , also security check of scripts are active:

Also we tested Python 3.11.0. Release Date: Oct. 24, 2022. This is the stable release of Python 3.11.0. Python 3.11.0 is the newest major release of the Python  programming language, and it contains many new features and optimizations.

Multi Python Tests
Const  PYHOME64 = 'C:\Users\user\AppData\Local\Programs\Python\Python311\'; 
  PYDLL64  = 'C:\Users\user\AppData\Local\Programs\Python\Python311\python311.dll';

eng.Execstr('import qrcode as pyqr'); 
     //eng.Execstr('import random as rand');  
      eng.Execstr(QRCODE);      
      eng.Execstr('Qrcode_Maker("https://maxbox4.wordpress.com/")');
      // eng.Execstr('Qrcode_Maker("https://www.medium.com/")');
      OpenDoc(exepath+'qrcodemx45.png');   //}

Some of the new major new features and changes in Python 3.11 are: General changes 1. PEP 657 — Include Fine-Grained Error Locations 

C:\maxbox\ipso\IBZ_Module1_4_2022\maxbox4Aarau\maxbox5\maxbox522\maxbox5>py -3.11 -m pip install qrcode
Collecting qrcode
Using cached qrcode-7.4.2-py3-none-any.whl (46 kB)
Collecting typing-extensions (from qrcode)
Obtaining dependency information for typing-extensions from https://files.pythonhosted.org/packages/24/21/7d397a4b7934ff4028987914ac1044d3b7d52712f30e2ac7a2ae5bc86dd0/typing_extensions-4.8.0-py3-none-any.whl.metadata
Downloading typing_extensions-4.8.0-py3-none-any.whl.metadata (3.0 kB)
Collecting pypng (from qrcode)
Using cached pypng-0.20220715.0-py3-none-any.whl (58 kB)
Collecting colorama (from qrcode)
Using cached colorama-0.4.6-py2.py3-none-any.whl (25 kB)
Using cached typing_extensions-4.8.0-py3-none-any.whl (31 kB)
Installing collected packages: pypng, typing-extensions, colorama, qrcode
Successfully installed colorama-0.4.6 pypng-0.20220715.0 qrcode-7.4.2 typing-extensions-4.8.0[notice] A new release of pip is available: 23.2.1 -> 23.3.1
[notice] To update, run: C:\Users\User\AppData\Local\Programs\Python\Python311\python.exe -m pip install –upgrade pip

C:\maxbox\ipso\IBZ_Module1_4_2022\maxbox4Aarau\maxbox5\maxbox522\maxbox5>

Py compare shell to script
pandas test text
Dev Environment Win11 with D11.3

64bit crypto box

LockBox3 is a Delphi library for cryptography.
It provides support for AES, DES, 3DES, Blowfish, Twofish, SHA, MD5, a variety of chaining modes, RSA digital signature and verific…

This is a source-only release of TurboPack LockBox3. It includes designtime and runtime packages for Delphi and C++Builder and supports VCL, FMX, Win32, Win64, macOS, iOS, and Android.

I not updated the complete libary

lBox 3

FastCode move and fillchar are included within SynCommons.pas.
You can get rid of it, by commenting the corresponding lines in the initialization block of this unit.
Under new versions of the framework, you have a conditional setting to disable it.

SynPDF was not tied to SynCommons.pas at the beginning, but a lot of duplicated code did appear between the two units. So a call to move and fillchar raises a AV.
Since SynCommons.pas is optimized for speed, and unit tested, we rather rely on it.
SmartLinking won’t make it big in your exe: logging and all the other won’t be part of it.

Updating

TurboPack LockBox3 is available via the GetIt Package Manager where you can quickly and easily install and uninstall it.

To manually install TurboPack LockBox3 into your IDE, take the following steps:

  1. Unzip the release files into a directory (e.g., d:\lockBox3).
  2. Start RAD Studio.
  3. Add the source directory (e.g. d:\lockBox3\run and all the subdirectories) to the IDE’s library path. For C++Builder, add the hpp subdirectory (e.g., d:\lockBox3\source\hpp\Win32\Release) to the IDE’s system include path.
  4. Open & install the designtime package specific to the IDE being used. The IDE should notify you the components have been installed.
Cryptobox included

debug the debugger

Bale 10th Floor
maXbox5 1176_APILayer_Demo64.txt Compiled done: 02/12/2023 19:27:52

debug size: 10146
{“lang”: “en”, “all_text”: “A\n\”SCHWEIZERHOF\nVICTORIA\n10000\nL\nU”, “annotations”: [“A”, “\””, “SCHWEIZERHOF”, “VICTORIA”, “10000”, “L”, “U”]}

mX5 executed: 02/12/2023 19:27:53 Runtime: 0:0:3.719 Memload: 80% use

How to chat with GPT

GPT stands for Generative Pre-trained Transformer. It is a deep learning model based on the Transformer architecture that has been pre-trained on a large corpus of text data. GPT is used for natural language processing tasks such as language modeling, text generation, and question answering.

ChatGPT is an AI-based chatbot developed by OpenAI that can be used in various ways across many industries.

First you need an account:

Playground with GPT

Second, you need to register an Open AI account,(Note: This is required). Then open website, Log in first. After the login is completed, it is still at the previous website

Then you can use a maXbox script to get access to the server:

maXbox GPT Script

Due to the limitation of OpenAI’s official server, the ChatGPT model cannot be used temporarily. So the plugin accesses the GPT3 model. It’s a relatively old model and not very smart. But it can be used normally.

Thats how the code look likes in maXbox or Python:

function TALHTTPClient2_AskChatGPT(feedstream:string;
                              aResponseHeader:TALHTTPResponseHeader2):string;
Var
  poststrm: TStream;
  JPostdata, aturl: string;
  jo: TJSON;
begin
  JPostData:= '{' +
    '"model": "text-davinci-003",'+
    '"prompt": "%s",'+
    '"max_tokens": 2048,'+
    '"temperature": 0.3'+
    '}';
    
  with TALWininetHttpClient2.create do begin
    atUrl:= 'https://api.openai.com/v1/completions';
    //RequestHeader.UserAgent:= UAGENT;
    RequestHeader.ContentType:= 'application/json';
    RequestHeader.Authorization:= 'Bearer '+ CHATGPT_APIKEY2;
    try
      poststrm:= TStringStream.create(format(JPostData,[feedstream]));
      jo:= TJSON.Create(); 
      jo.parse(Post3(atUrl, poststrm, [])) 
      result:=jo.values['choices'].asarray[0].asobject['text'].asstring;
    finally
      Free;
      postStrm.Free;
      jo.Free;
    end; 
  end; //with   
end; 

The ChatGPT API allows developers to integrate ChatGPT into their own applications, products, or services as a result of JSON. The API endpoint for making POST requests is api.openai.com/v1/chat/completions

One important thing is the temperature. Temperature is a hyperparameter used in some natural language processing models, including ChatGPT, to control the level of randomness or “creativity” in the generated text. Higher temperatures result in more diverse and unpredictable output. Conversely, lower temperatures result in more conservative and predictable output.

const genfunc = 
  'def generate_response(prompt):            '+LF+
  '   response = openai.Completion.create(   '+LF+
  '      engine="text-davinci-002",          '+LF+
  '      prompt=prompt,                      '+LF+
  '      max_tokens=60,                      '+LF+
  '      n=1,                                '+LF+
  '      stop=None,                          '+LF+
  '      temperature=0.5,                    '+LF+
  '     )                                    '+LF+
  '   return response.choices[0].text.strip()';

function Python32_AskChatGPT(feedstream: string): string;
begin
with TPythonEngine.Create(Nil) do begin                         
    pythonhome:= PYHOME;
    try                                                           
      loadDLL;                                                    
      execStr('import openai'); 
      //https://github.com/sknetwork-team/scikit-network/issues/498   
      execstr('openai.api_key = "sk-your-api-key"');             
      execStr(genfunc);
      //execStr('connection.request("GET","api.parse.com/echo")');
      println(evalStr('openai.version'));     
      println(evalStr('generate_response("What is the capital of France?")'));       
    except                                                        
      raiseError;                                                 
    finally 
      unloadDLL;                                                       
      free;                                                       
    end;                                                          
  end;
end;                     

You can sign up using your email address or Google/Microsoft account.

  1. After signing up, you will receive a verification email in your provided email address.
  2. You will also need to verify your account with a mobile number.
  3. Once you have verified your account, you can generate an API key.
  4. To generate an API key, log in to your OpenAI account and visit the API keys page.
  5. Click on your profile in the top-right corner and select “View API Key” to get your key. 
  6. Click on “Create new secret key” to generate a new key. The API key is used to authenticate requests made to the OpenAI API.
procedure PYdemo32;
var frm: TForm;  mem: TMemo;
begin
  with TPythonEngine.Create(Nil) do begin                        
   pythonhome:= 'C:\Users\breitsch\AppData\Local\Programs\Python\Python37-32\'; 
    try                                                          
      loadDLL;                                                    
      execStr('love="ILovemaXbox"');                 
      frm:= TForm.create(self);
      mem:= TMemo.Create(frm);
      mem.parent:= frm;
      mem.color:= clblack; 
      mem.font.name:= 'Courier';    //a fixed font size.
      mem.font.size:= 12;
      mem.font.color:= clred; 
      mem.Align:= alClient;  
      with frm do begin
        position:= poScreenCenter;
        caption:= 'PyHeart2';
        width:= 600; height:= 500;
        //canvas.brush.bitmap
        mem.text:=StringReplace(evalStr('"n".join(["".join([(love[(x-y)%len(love)] if((x*0.05)**2+(y*0.1)**2-1)**3-(x*0.05)**2*(y*0.1)**3<=0 else" ")for x in range(-30,30 )])for y in range(15,-15,-1)])'),'n',
              CRLF,[rfReplaceAll, rfIgnoreCase]); 
        Showmodal;
       end;  
    except                                                       
      raiseError;                                                 
    finally                                                      
      free; 
      frm.Free;                                                      
    end;                                                          
  end;
end;              

Conclusion

Natural Language Processing (NLP) has become increasingly popular over the years, and ChatGPT API is one of the most powerful tools to implement NLP. The API provides access to OpenAI’s GPT-3 language model, allowing you to generate natural language responses to any input text. In this blog, we will go through a step-by-step guide on how to use OpenAI’s ChatGPT API in Python and maXbox, along with code examples.

Example: writeln(‘answer6: ‘+TALHTTPClient2_AskChatGPT(‘Why is cold fusion not possible?’, nil));

answer6: Cold fusion is not possible because it is not supported by the laws of physics. Cold fusion would require a reaction to occur at room temperature, which is not possible according to the laws of thermodynamics. In addition, the amount of energy required to initiate a cold fusion reaction is far greater than what is available in the environment.

Limitations

While the world is certainly over the moon for the wonders of ChatGPT, there are certain limitations to what ChatGPT can and cannot do. It is certainly a breakthrough in AI, but the journey to “singularity” may only be in its initial phase. ChatGPT is far from creating human-like intelligence, let alone replacing it.

ChatGPT, Generative Pre-trained transformer, is based on Natural language processing (NLP) which has its own limitations. For example, language models cannot adequately process contextual words, phrases, homonyms, sarcasm, and ambiguity, to name a few. ChatGPT, likewise, performs poorly when inputs are ambiguous or beyond the language model’s processing capabilities.

ChatGPT cannot also process overly complex inputs, slang, or excessive abbreviations.

swisscognitive

The problem with false questions: writeln(‘answer6: ‘+TALHTTPClient2_AskChatGPT(‘Why is earth bigger than the sun?’, nil));

answer6: Earth is bigger than the sun because the sun is a star, and stars are much smaller than planets. The sun is about 1.3 million times larger than Earth in terms of volume, but Earth is much more massive than the sun. Earth has a mass of 5.972 x 10^24 kg, while the sun has a mass of 1.989 x 10^30 kg.

Test of Leakage

[maxkleiner/maXbox4] OpenAI API Key exposed on …

Hi there,

Your OpenAI API key was determined to have been leaked, which has triggered a key disable and this friendly notification email.

AIGuardian has detected the following OpenAI API Key exposed within your … account. Details – Secret type: OpenAI API Key
– Repository: maxkleiner/maXbox4 – Pushed date: April 3rd 2023, 14:18:45 UTC

TRestClient

A Delphi REST client API to consume REST services written in any programming language. The API it is designed to work with Delphi 7 or later. Newer versions takes advantage of Generics Methods.

function TRestResource3_AskChatGPT(askstream: string; 
                                 aResponseHeader:TRestResponseHandler):string;
var pstrm: TStream;
    JPostdat: string;
    jo: TJSON; arest: TRestResource;
begin
  JPostDat:= '{'+
    '"model": "text-davinci-003",'+
    '"prompt": "%s",'+
    '"max_tokens": 2048,'+
    '"temperature": 0.15}';

  with TRestClient.create(self) do begin
      arest:= Resource('https://api.openai.com/v1/completions');
      arest.ContentType('application/json');
      arest.Authorization('Bearer '+CHATGPT_APIKEY2);
      ConnectionType:= hctWinInet;
    try
      pstrm:= TStringStream.create(format(JPostDat,[askstream]));
      jo:= TJSON.Create(); 
      jo.parse(arest.Post(pstrm)); 
      writeln('responsecode: '+itoa(responsecode)+' verifycert: '+botostr(verifycert));
      result:= jo.values['choices'].asarray[0].asobject['text'].asstring;
    finally
      Free;
      jo.Free;
      pStrm.Free;        
    end; 
  end; //with   
end; 

//https://github.com/fabriciocolombo/delphi-rest-client-api/blob/master/src/RestClient.pas
PAC Diagram

API Types

procedure SIRegister_RestClient(CL: TPSPascalCompiler);
begin
 CL.AddConstantN('DEFAULT_COOKIE_VERSION','LongInt').SetInt( 1);
  CL.AddTypeS('TRestRequestMethod', '( METHOD_GET, METHOD_POST, METHOD_PUT, METHOD_'
   +'PATCH, METHOD_DELETE )');
  CL.AddTypeS('TRestResponseHandler', 'Procedure ( ResponseContent : TStream)');
  CL.AddClassN(CL.FindClass('TOBJECT'),'TRestResource');
  CL.AddTypeS('TCustomCreateConnection', 'Procedure ( Sender : TObject; AConnec'
   +'tionType : THttpConnectionType; out AConnection : IHttpConnection)');
  SIRegister_TJsonListAdapter(CL);
  CL.AddClassN(CL.FindClass('TOBJECT'),'TRestClient');
  CL.AddTypeS('TRestOnRequestEvent', 'Procedure ( ARestClient : TRestClient; AR'
   +'esource : TRestResource; AMethod : TRestRequestMethod)');
  CL.AddTypeS('TRestOnResponseEvent', 'Procedure ( ARestClient : TRestClient; R'
   +'esponseCode : Integer; const ResponseContent : string)');
  CL.AddTypeS('THTTPErrorEvent', 'Procedure ( ARestClient : TRestClient; AResou'
   +'rce : TRestResource; AMethod : TRestRequestMethod; AHTTPError : EHTTPError; var ARetryMode : THTTPRetryMode)');
  SIRegister_TRestClient(CL);
  SIRegister_TRestCookie(CL);
  SIRegister_TRestResource(CL);
  //SIRegister_TMultiPartFormAttachment(CL);
  //SIRegister_TMultiPartFormData(CL);
end;

Produce a formatted 12×12 multiplication table of the kind memorized by rote when in primary (or elementary) school.

program MultiplicationTables;
//https://rosettacode.org/wiki/Multiplication_tables

const
  MAX_COUNT = 12;
var
  lRow, lCol: Integer;
begin //@main
  maxform1.orangestyle1click(self);
  memo2.font.name:= 'courier';
  memo1.font.size:= 12;
  Write('  | ');
  for lRow := 1 to MAX_COUNT do
    Write(Format('%4d', [lRow]));
  Writeln('');
  Writeln('--+-' + StringOfChar('-', MAX_COUNT * 4));
  for lRow := 1 to MAX_COUNT do begin
    Write(Format('%2d', [lRow]));
    Write('| ');
    for lCol := 1 to MAX_COUNT do begin
      if lCol < lRow then
        Write('    ')
      else
        Write(Format('%4d', [lRow * lCol]));
    end;
    Writeln('');
  end;
end.

              _od#HMM6&*MMMH::-_
          _dHMMMR??MMM? ""| `"'-?Hb_
       .~HMMMMMMMMHMMM#M?        `*HMb.
     ./?HMMMMMMMMMMM"*"""           &MHb.
    /'|MMMMMMMMMMM'             -   `*MHM\
   /  |MMMMMMHHM''                   .MMMHb
  |   9HMMP   .Hq,                   TMMMMMH
 /     |MM\,H-""&&6\__               `MMMMMMb
|       `""HH#,       \             - MMMMMMM|
|           `HoodHMM###.              `9MMMMMH
|              .MMMMMMMM##\             `*"?HM
|         ..  ,HMMMMMMMMMMMo\.              |M
|             |MMMMMMMMMMMMMMMMHo           |M
|              ?MMMMMMMMMMMMMMMM*           |H
|.              `#MMMMMMMMMMMMM'           .M|
 \                `MMMMMMMMMMM*            |P
 `\                MMMMMMMMT"'            ,H
  `\              `MMMMMMH?              ./
    \.            |MMMH#"               ,/
     `\.          |MMP'               ./'
       `~\        `HM:.-    .       ,/'
          "-\_       '_\ .      _.-"
              "-\-#odMM\_,oo==-"
    
maXbox4 1203_multiplicationtable.txt Compiled done: 06/04/2023 20:51:38

| 1 2 3 4 5 6 7 8 9 10 11 12
–+————————————————-
1| 1 2 3 4 5 6 7 8 9 10 11 12
2| 4 6 8 10 12 14 16 18 20 22 24
3| 9 12 15 18 21 24 27 30 33 36
4| 16 20 24 28 32 36 40 44 48
5| 25 30 35 40 45 50 55 60
6| 36 42 48 54 60 66 72
7| 49 56 63 70 77 84
8| 64 72 80 88 96
9| 81 90 99 108
10| 100 110 120
11| 121 132
12| 144
mX4 executed: 06/04/2023 20:51:39 Runtime: 0:0:1.178 Memload: 49% use

Exception Handling

When you send an invalid sign like Produce a formatted 12 × 12 multiplication table of the kind memorized… you get:

Exception: Bad Request (400) - 'https://api.openai.com/v1/completions'. 

the invalid sign is the 12 × 12 which we fix with 12 x 12 as x not ×

with TRestClient you can resolve the event-handler with:

procedure TRestOnResponseEvent2(ARestClient: TRestClient; ResponseCode: Integer; 
              const ResponseContent: string);  
 begin
   writeln(objtostr(arestclient));
   writeln('on response '+responsecontent)
   writeln('on response '+itoa(responsecode));
   writeln('enabled compression '+botostr(arestclient.EnabledCompression));
 end;   

Then you get a more accurate error:

TRestClient@046E1E00
on response {
  "error": {
    "message": "Your request contained invalid JSON: 'utf-8' codec can't decode byte 0xd7 in position 65: invalid continuation byte",
    "type": "invalid_request_error",
    "param": null,
    "code": null
  }
}

on response 400
enabled compression TRUE
 aquest:= ' Produce a formatted  12 x 12 multiplication table of the kind memorized by rote when in primary (or elementary) school in Pascal. ';

writeln('Answer9: '+TRestClient3_AskChatGPT(aquest, Nil));

Answer9: 

program MultiplicationTable;

uses crt;

var
  i, j : Integer;

begin
  clrscr;
  writeln('  |  1  2  3  4  5  6  7  8  9 10 11 12');
  writeln('--+-----------------------------------');
  for i := 1 to 12 do
  begin
    write(i, ' |');
    for j := 1 to 12 do
    begin
      write(Format('%3d', [i * j]));
    end;
    writeln;
  end;
  readln;
end.

The HTTP headers Accepts-Encoding is usually a comparison algorithm of request header. All the HTTP client used to tell the server which encoding or encoding it supports. Then the server will respond in any of the supporting encoding formats. The server selects any one of the proposals, uses it and informs the client of its choice with the Content-Encoding response header.

function TRestClient3_AskChatGPT(askstream: string; 
                                  aResponseHeader:TRestResponseHandler):string;
var pstrm: TStream;
    JPostdat: string;
    jo: TJSON; arest: TRestResource; ahint: IHttpConnection2;
begin
  JPostDat:= '{'+
    '"model": "text-davinci-003",'+
    '"prompt": "%s",'+
    '"max_tokens": 2048,'+
    '"temperature": 0.15}';

  with TRestClient.create(self) do begin
      arest:= Resource('https://api.openai.com/v1/completions');
      arest.ContentType('application/json');
      arest.Authorization('Bearer '+CHATGPT_APIKEY2);
      ConnectionType:= hctWinInet;
    try
      pstrm:= TStringStream.create(format(JPostDat,[askstream]));
      jo:= TJSON.Create(); 
      OnafterRequest:= @TRestOnRequestEvent2;
      OnResponse:= @TRestOnResponseEvent2;
      jo.parse(arest.Post(pstrm)); 
      writeln('respcode: '+itoa(responsecode)+' verifycert: '+botostr(verifycert));
      writeln('responseheader: '+responseheader['Date']);
      writeln('content-encoding:'+responseheader['Content-Encoding']);
      result:= jo.values['choices'].asarray[0].asobject['text'].asstring;
      //OnResponse:= @TRestOnResponseEvent2;
      //OnafterRequest:= @TRestOnRequestEvent2;
    except
      onError:= @THTTPErrorEvent21;  
      OnConnectionLost:= @THTTPConnectionLostEvent2;
    finally
      //Function UnWrapConnection: IHttpConnection2');
      //ahint:= UnWrapConnection;
      Free;
      jo.Free;
      pStrm.Free;        
    end; 
  end; //with   
end; 

Syntax:

Accept-Encoding: gzip | compress | deflate | br| identity| *

Note: Multiple algorithm are also can be applicable.

The HTTP Location header is a response header that is used under 2 circumstances to ask a browser to redirect a URL (status code 3xx) or provide information about the location of a newly created resource (status code of 201). Its usage is often confused with another HTTP Header which is HTTP Content-Location header. The main difference between them is that Location gives the URL of the resource where the redirection of the page happens while HTTP Content-Location is used to indicate the URL of a transmitted resource.

https://www.geeksforgeeks.org/http-headers-location/?ref=rp

maXbox4 1202_chatgpt_API37tester.txt Compiled done: 07/04/2023 10:17:21

TRestClient@046E2228
on response {“id”:”cmpl-72bZZ7n4OfQco41zWqcO1TaBMeiG7″,”object”:”text_completion”,”created”:1680855441,”model”:”text-davinci-003″,”choices”:[{“text”:”\n\nprogram MultiplicationTable;\n\n{This program prints a 12×12 multiplication table}\n\nvar\n i, j : Integer;\n\nbegin\n Writeln(‘ | 1 2 3 4 5 6 7 8 9 10 11 12’);\n Writeln(‘–+———————————–‘);\n for i := 1 to 12 do\n begin\n Write(i, ‘ |’);\n for j := 1 to 12 do\n begin\n Write(Format(‘%3d’, [i * j]));\n end;\n Writeln;\n end;\nend.”,”index”:0,”logprobs”:null,”finish_reason”:”stop”}],”usage”:{“prompt_tokens”:29,”completion_tokens”:138,”total_tokens”:167}}

on response 200
enabled compression TRUE
content-encoding:
on request method 1
responsecode: 200 verifycert: TRUE
responseheader: Fri, 07 Apr 2023 08:17:25 GMT
content-encoding:
Answer9:

program MultiplicationTable;

{This program prints a 12×12 multiplication table}

var
i, j : Integer;

begin
Writeln(‘ | 1 2 3 4 5 6 7 8 9 10 11 12’);
Writeln(‘–+———————————–‘);
for i := 1 to 12 do
begin
Write(i, ‘ |’);
for j := 1 to 12 do
begin
Write(Format(‘%3d’, [i * j]));
end;
Writeln;
end;
end.
mX4 executed: 07/04/2023 10:17:25 Runtime: 0:0:4.658 Memload: 48% use

Version 32 with onResponse Exception Event

{$I .\OPENAIAPIKEY.INC}

procedure TRestOnResponseEvent2(ARestClient: TRestClient; ResponseCode:Integer; 
                                              const ResponseContent: string);  
 begin
   print('@addr:'+objtostr(arestclient));
   print('response cont: '+responsecontent)
   print('response code: '+itoa(responsecode));
   print('enabled compression '+botostr(arestclient.EnabledCompression));
   print('content-encoding:'+arestclient.responseheader['Content-Encoding']);
   print('verifycert: '+botostr(arestclient.verifycert));
 end;    


function TRestClient3_AskChatGPT(askstream: string; 
                                  aResponseHeader:TRestResponseHandler):string;
var JPostdat: string;
    jo: TJSON; rest: TRestResource;
begin
  JPostDat:= '{'+
    '"model": "text-davinci-003",'+
    '"prompt": "%s",'+
    '"max_tokens": 2048,'+
    '"temperature": 0.15}';

  with TRestClient.create(self) do begin
      rest:= Resource('https://api.openai.com/v1/completions');
      println('@addr:'+objtostr(rest))
      rest.ContentType('application/json');
      rest.Authorization('Bearer '+CHATGPT_APIKEY2);               
      ConnectionType:= hctWinInet;
      OnResponse:= @TRestOnResponseEvent2;
    try
      jo:= TJSON.Create(); 
      jo.parse(rest.Post(TStringStream.create(format(JPostDat,[askstream])))); 
      result:= jo.values['choices'].asarray[0].asobject['text'].asstring;
    finally
      Free;
      jo.Free;
    except  
      writeln('EWI_Exc:'+ExceptiontoString(exceptiontype,exceptionparam));
    end; 
  end; //with   
end; 

http://softwareschule.ch/examples/chatgpt32.txt

//'Q: Write a Pascal program to list all prime numbers up to a user-input upper number';

var i,j,upper_numb: integer;

upper_numb:= 20;

writeln('Prime numbers up to '+itoa(upper_numb)+' are:');
for i:= 2 to upper_numb do begin
  for j:= 2 to (i - 1) do begin
    if (i mod j = 0) then
      break;
  end;
  if (i = j) then
    writeln(itoa(i));
end;
polYgon Jazz im Breitsch
polYgon Jazz im Breitsch 2
chat with a rat

Test Bing Chat

What can I do with maXbox4 ?

maXbox4 is a script tool engine, compiler and source lib all in one exe to design and code your scripts in a shellbook1. It supports object scripting with Pascal syntax and has over 360000 functions and procedures1. You can use maXbox4 to learn programming, create applications, games, simulations, web services, and more2. You can also download maXbox4 from GitHub3 or Internet Archive4 and try it online on Replit2.

There are many examples of maXbox4 scripts available online. You can find some of them on the following sources:

A Medium blog post by maXbox that shows how to use Python code in maXbox4 scripts 1.
A list of all examples and tutorials included in the maXbox4 package 2.
A GitHub repository that contains the source code and documentation of maXbox4 ³.
A Replit page that allows you to run maXbox4 scripts online 4.
A SourceForge page that hosts some examples of maXbox4 scripts 5.
You can also create your own scripts using the Pascal syntax and the built-in functions and objects of maXbox4. You can use the editor, compiler, debugger, and code explorer features of maXbox4 to design and code your scripts in a shellbook.

Received message. There are many examples of maXbox4 scripts available online. You can find some of them on the following sources: – A Medium blog post by maXbox that shows how to use Python code in maXbox4 scripts. – A list of all examples and tutorials included in the maXbox4 package. – A GitHub repository that contains the source code and documentation of maXbox4. – A Replit page that allows you to run maXbox4 scripts online. – A SourceForge page that hosts some examples of maXbox4 scripts. You can also create your own scripts using the Pascal syntax and the built-in functions and objects of maXbox4. You can use the editor, compiler, debugger, and code explorer features of maXbox4 to design and code your scripts in a shellbook.
Learn more:

  1. maxbox4.wordpress.com
  2. softwareschule.ch
  3. github.com
  4. replit.com
  5. sourceforge.net
    +2 more

How do I use Python code in maXbox4 scripts?

To use Python code in maXbox4 scripts, you need to use the PythonEngine component that allows you to evaluate or execute Python code from Pascal. You also need to have a Python DLL that matches your system architecture and load it with the OpenDll method. You can install Python from the official website1 or use the DLL provided by maXbox42. You can also check for registered Python versions with the GetRegisteredPythonVersions function2. Once you have the PythonEngine and the DLL ready, you can use the EvalStr or ExecStr methods to run Python code from a string or a file. For example, you can write something like this in your maXbox4 script2:

with TPythonEngine.create(self) do begin
Dllpath:= ‘C:\Users\max\AppData\Local\Programs\Python\Python36-32\’;
Dllname:= ‘python37_32.dll’;
LoadDll;
writeln(pythonhome);
writeln(ExecModule);
pypara:= ‘https://en.wikipedia.org/wiki/WoW64&#8217;;
try
writeln(evalstr(‘import(“math”).sqrt(45)’));
writeln(evalstr(‘import(“hashlib”).sha1(b”https://en.wikipedia.org/wiki/WoW64&#8243;).hexdigest()’));
writeln(evalstr(‘import(“hashlib”).sha1(b”‘+pypara+'”).hexdigest().upper()’));
writeln(evalstr(‘import(“hashlib”).sha256(b”‘+pypara+'”).hexdigest().upper()’));
except
on E: Exception do
writeln(E.ClassName, ‘: ‘, E.Message);
end;
end;

This will run some Python code that imports math and hashlib modules and performs some calculations and hashing operations. You can also use other methods of the PythonEngine component to access Python objects, variables, functions, and modules. For more information, you can refer to the documentation of Python4Delphi3, which is the library that maXbox4 uses to integrate with Python.

Received message. To use Python code in maXbox4 scripts, you need to use the PythonEngine component that allows you to evaluate or execute Python code from Pascal. You also need to have a Python DLL that matches your system architecture and load it with the OpenDll method. You can install Python from the official website or use the DLL provided by maXbox4. You can also check for registered Python versions with the GetRegisteredPythonVersions function. Once you have the PythonEngine and the DLL ready, you can use the EvalStr or ExecStr methods to run Python code from a string or a file. For example, you can write something like this in your maXbox4 script:

pascal with TPythonEngine.create(self) do begin Dllpath:= 'C:\\Users\\max\\AppData\\Local\\Programs\\Python\\Python36-32\\'; Dllname:= 'python37_32.dll'; LoadDll; writeln(pythonhome); writeln(ExecModule); pypara:= 'https://en.wikipedia.org/wiki/WoW64'; try writeln(evalstr('__import__("math").sqrt(45)')); writeln(evalstr('__import__("hashlib").sha1(b"https://en.wikipedia.org/wiki/WoW64").hexdigest()')); writeln(evalstr('__import__("hashlib").sha1(b"'+pypara+'").hexdigest().upper()')); writeln(evalstr('__import__("hashlib").sha256(b"'+pypara+'").hexdigest().upper()')); except on E: Exception do writeln(E.ClassName, ': ', E.Message); end; end; This will run some Python code that imports math and hashlib modules and performs some calculations and hashing operations. You can also use other methods of the PythonEngine component to access Python objects, variables, functions, and modules. For more information, you can refer to the documentation of Python4Delphi, which is the library that maXbox4 uses to integrate with Python.
Learn more:

  1. softwareschule.ch
  2. maxbox4.wordpress.com
  3. github.com
  4. stackoverflow.com
  5. realpython.com
    +2 more

How do I use other languages or tools in maXbox4 scripts?

There are different ways to use other languages or tools in maXbox4 scripts, depending on what you want to achieve. Some of the possible methods are:

  • Using the ExecuteShell function to run external commands or programs from your maXbox4 script. For example, you can write something like this to run a Python script from your maXbox4 script¹:
println(getDosOutput('py examples\\httpheader1.py --url "https://www.ipso.ch/ibz"',exePath));
  • Using the TProcess component to create and control a child process from your maXbox4 script. For example, you can write something like this to run a Java program from your maXbox4 script²:
with TProcess.create(nil) do begin
  Executable:= 'java';
  Parameters.Add('-jar');
  Parameters.Add('examples\\HelloWorld.jar');
  Options:= Options + [poWaitOnExit];
  Execute;
end;
  • Using the TWebBrowser component to embed a web browser in your maXbox4 script and load web pages or web applications that use other languages or tools. For example, you can write something like this to load a Replit page that runs a JavaScript program from your maXbox4 script³:
with TWebBrowser.create(nil) do begin
  Parent:= form1;
  Align:= alClient;
  Navigate('https://replit.com/@maxbox/maXbox4-code-compiler-script-studio');
end;
  • Using the TPythonEngine component to evaluate or execute Python code from your maXbox4 script, as explained in the previous answer. You can also use other components that allow you to integrate with other languages or tools, such as TLuaEngine for Lua, TJSEngine for JavaScript, TRubyEngine for Ruby, etc. You can find some of these components on GitHub4 or SourceForge.

Source: Conversation with Bing, 14/05/2023
(1) maXbox4 4.7.6.10 11/08/2022 17:09:06 1. http://www.softwareschule.ch/download/maxbox_starter98.pdf.
(2) maxbox (max kleiner) – Replit. https://replit.com/@maxbox.
(3) GitHub – maxkleiner/maXbox4: code compiler script studio. https://github.com/maxkleiner/maXbox4.
(4) Releases · maxkleiner/maXbox4 · GitHub. https://github.com/maxkleiner/maXbox4/releases.

function XorEncode2(const Key, Source: AnsiString): AnsiString;
var  I: Integer;
     B: Byte;
begin
  Result:='';
  for I:= 1 to Length(Source) do begin
    if Length(Key) > 0 then
      B:= ord(Key[1+ ((I- 1) mod Length(Key))]) Xor ord(Source[I])
    else
      B:= ord(Source[I]);
    Result:= Result+ AnsiString(AnsiLowerCase(IntToHex(B,2)));
  end;
end;

function XorDecode2(const Key, Source: AnsiString): AnsiString;
var I: Integer;
    B: Byte;
begin
  Result:='';
  for I:= 0 to Length(Source) div 2- 1 do begin
    B:= StrToIntDef('$'+ string(Copy(Source,(I * 2)+ 1,2)),Ord(' '));
    if Length(Key) > 0 then
      B:= ord(Key[1+ (I mod Length(Key))]) Xor B;
    //Result:= Result + AnsiChar(B);
     Result:= Result+ chr(B);
  end;
end; 

writeln(XorEncode2('max123°','this is the box tox 5 hive®'));  
writeln(xordecode2('max123°',XorEncode('max123°','this is the box tox 5 hive®')));  

>>>
19091142125ac34d1510541251df15410c5e4a13854d091147579d
this is the box tox 5 hive®               

A key committee of lawmakers in the European Parliament have approved a first-of-its-kind artificial intelligence regulation — making it closer to becoming law.

What do the rules say?

The AI Act categorizes applications of AI into four levels of risk: unacceptable risk, high risk, limited risk and minimal or no risk.

Unacceptable risk applications are banned by default and cannot be deployed in the bloc.

They include:

  • AI systems using subliminal techniques, or manipulative or deceptive techniques to distort behavior
  • AI systems exploiting vulnerabilities of individuals or specific groups
  • Biometric categorization systems based on sensitive attributes or characteristics
  • AI systems used for social scoring or evaluating trustworthiness
  • AI systems used for risk assessments predicting criminal or administrative offenses
  • AI systems creating or expanding facial recognition databases through untargeted scraping
  • AI systems inferring emotions in law enforcement, border management, the workplace, and education

Several lawmakers had called for making the measures more expensive to ensure they cover ChatGPT.

the geometer
error: Microsoft Visual C++ 14.0 or greater is required. Get it with “Microsoft C++ Build Tools”: https://visualstudio.microsoft.com/visual-cpp-build-tools/

AGSI Data Storage API

////////////////////////////////////////////////////////////////////////////////

AGSI Data Storage Report

__________________________________________________________________

maXbox Starter 99 – Data representation of gas in storage as a timeline AGSI dataset.

There are many kinds of data scientists:

a) Those who dive in data are the best.

This data science tutorial explains the so called AGSI data storage and his visualisation of the time line. AGSI is the Aggregated Gas Storage Inventory and offers you the possibility to be kept up to date whenever a new service announcement or update from one of our data providers is posted on the website.

The Gas Infrastructure Europe (GIE) is also providing related data such as the Storage Map and Storage Investment Database at https://www.gie.eu/publications/maps/

The result of the data will be the chart below:

timeline

Pic: 1154_agsi_plot13.png

We use WinHttp.WinHttpRequest, JSONObjects and TEECharts library with loading and testing the plot. Also an API-key is needed, get the key first at: https://agsi.gie.eu/account

The data represents gas in storage at the end of the previous gas day. Data is updated every day at 19:30 CET and a second time at 23:00. Before we dive into code this is the main part of the script:

plotform:= getForm2(1400, 600, clsilver, 'Sciplot4maXbox');

plotform.icon.loadfromresourcename(hinstance,'ZHISTOGRAM');

HttpResponse:=

getEnergyStreamJSON2(URL_AGSIAPI2,'DE,2022-01-03,150',AGSI_APIKEY);

JSON2Plot(plotform, letGenerateJSON2(HttpResponse));

The main part generates a form, invokes the API and plots the data.

GIE is providing an API (Application Programming Interface) service on its AGSI and ALSI transparency publication platforms.

Using API access, consumer can bypass the AGSI and ALSI website and get hold of the data directly and continuously. It enables to extract, filter, aggregate the data and create any subset as required, without having to download each dataset separately from the website. The API export format is JSON. For example a subset of 150 days:

Pic: 1154_agsi_plot14.png

The published datasets are based on the EIC code mapping table provided to ACER. Storage data is aggregated by company, and country.

With the call I pass country, start-date and amount of days:

getEnergyStreamJSON2(URL_AGSIAPI2,'DE,2022-01-03,150',AGSI_APIKEY);

All available datasets can be downloaded also in Excel, CSV and JSON format. The data in this report shows an aggregated view – individual datasets by company and storage facility are also accessible.

Kali Linux

So lets start with the API call:

<!-- wp:paragraph -->
<p>HttpResponse:=</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>getEnergyStreamJSON2(URL_AGSIAPI2,'DE,2022-01-03,150',AGSI_APIKEY);</p>
<!-- /wp:paragraph -->

This command and script runs WinHttp.WinHttpRequest. When you fail you get a bunch of exceptions like the following:

Exception: WinHttp.WinHttpRequest: The data necessary to complete this operation is not yet available; or you missed a valid key:

AGSIPost: Failed at getting response:403{

"error": {

"code": 403,

"message": "The request is missing a valid API key.",

"status": "PERMISSION_DENIED"

}}

The funny thing is the JSON formatted exception. Be also carefully to expose your key as I get from Git: GitGuardian has detected the following Google API Key exposed within your GitHub account.

Next is the formatting of the get-call with a valid API-key request in the function energyStream()

function getEnergyStreamJSON2(AURL,feedstream,aApikey:string): string;

...

encodURL:= Format(AURL,[HTTPEncode(asp[0]),(asp[1]),asp[2]]);
writeln(encodurl) //debug
hr:= httpRq.Open('GET', encodURL, false);
httpRq.setRequestheader('user-agent',USERAGENTE);
httpRq.setRequestheader('x-key',aAPIkey);

...

And where is the fabulous content-type? As far as I understood there are only two places in a web-request where to set a content-type:

  1. The client sets a content type for the body he is sending to the server (e.g. for get and post).
  2. The server sets a content type for the response.

A sender that generates a message containing a payload body has to generate a Content-Type header field in that message unless the intended media type of the enclosed representation is unknown to the sender; otherwise we failed at getting response: 503503 – Service Unavailable.

  • (‘headers={“Content-Type”:”application/json”}’)
  • httpRq.setRequestheader(‘Content-Type’,application/json);

It means that the content-type HTTP header should be set only for PUT and POST requests. GET requests can have “Accept” headers, which say which types of content the client understands. The server can then use that to decide which content type to send back.

As an option you can also use TALWinInetHttpClient. It is a easy to use WinInet-based protocol and supports HTTPs. HTTP client component which allows to post and get any data from the Web via HTTP protocol.

function TALHTTPClient_Get(aUrl:AnsiString; feedstream,aApikey: 
                                                 string): string;

Var LHttpClient: TALWininetHttpClient; asp:TStringArray;

begin
 LHttpClient:= TALWininetHttpClient.create;
 asp:= splitStr(feedstream,',');
 LHttpClient.url:= Format(AURL,[HTTPEncode(asp[0]), 
                                           asp[1]),asp[2]]);

 LHttpClient.RequestMethod:= HTTPmt_Get; //HTTPrm_Post;
 LHttpClient.RequestHeader.UserAgent:=USERAGENTE;
 //LHttpClient.RequestHeader.CustomHeaders:=
 LHttpClient.RequestHeader.RawHeaderText:='x-key:'+aAPIkey;
try
 result:= LHttpClient.Get1(LHttpClient.url); //overload;
finally
 LHttpClient.Free;
end;
end;

Any missing or incomplete data is also be visible on AGSI. Next we step to the conversion of our JSON response for the plot with TJSONObject:

function letGenerateJSON2(HttpRqresponseText: string): TJSONArray;
var jo: TJSONObject;  
begin
  jo:= TJSONObject.Create4(HttpRqresponseText);
  try
    //writeln(jo.getstring('data'));
    writeln(itoa(jo.getjsonarray('data').getjsonobject(0).length))
    writeln(itoa(jo.getjsonarray('data').length))
    result:= jo.getjsonarray('data'); 
    //write out to check     
    for it:= 0 to result.length-1 do 
       writeln(result.getjsonobject(it).getstring('gasDayStart')+':'+
                      result.getjsonobject(it).getstring('injection')); 
  except
    writeln('EJson: '+ExceptiontoString(exceptiontype, exceptionparam));
  end;                         
end;       

function getEnergyStreamJSON2(AURL, feedstream, aApikey: string): string;
var encodURL: string;
    httpRq,hr: Olevariant;
    asp: TStringArray;
begin
  httpRq:= CreateOleObject('WinHttp.WinHttpRequest.5.1');
  // Opens HTTPs connection.  
  try 
    asp:= splitStr(feedstream,',');
    encodURL:= Format(AURL,[HTTPEncode(asp[0]),(asp[1]),asp[2]]);   
    writeln(encodurl)        
    hr:= httpRq.Open('GET', encodURL, false);
    httpRq.setRequestheader('user-agent',USERAGENTE);
    httpRq.setRequestheader('x-key',aAPIkey); 
    if hr= S_OK then HttpRq.Send();
    If HttpRq.Status = 200 Then
       result:= HttpRq.responseText
    Else result:= 'Failed getting response:'+itoa(HttpRq.Status)+HttpRq.responseText;
        //writeln('debug response: '+HttpReq.GetAllResponseHeaders); 
  except  
    writeln('Error: '+HttpRq.responseText);
    writeln('EHTTP: '+ExceptiontoString(exceptiontype, exceptionparam));       
  finally
    httprq:= unassigned;
  end;                  
end; 

Using API access, the audience can bypass the AGSI and ALSI website and get hold of the data directly and continuously.

And this JSON Array as above function returns, we pass to the next plot:

procedure JSON2Plot(form1: TForm; jar: TJSONArray);
var chart1: TChart;  
    cnt: integer; sumup,tmp2,tmp: double; gday: string;
begin
  form1.onclose:= @Form_CloseClick;
  chart1:= ChartInjector(form1); 
  sumup:=0; tmp2:=0; tmp:=0;
  try
   for cnt:= 0 to jar.length-1 do begin
     //writeln(locate.getjsonobject(it).getstring('gasDayStart')+':'+
     tmp:= jar.getjsonobject(jar.length-1-cnt).getdouble('injection'); 
     tmp2:= jar.getjsonobject(jar.length-1-cnt).getdouble('full'); 
     sumup:= sumup+tmp;
     gday:= jar.getjsonobject(jar.length-1-cnt).getstring('gasDayStart');
     chart1.Series[0].Addxy(cnt,tmp,gday,clgreen);
     chart1.Series[1].Addxy(cnt,tmp2,'',clred);
     chart1.Series[2].Addxy(cnt,jar.getjsonobject(jar.length-1-cnt).getdouble('withdrawal'),'',clyellow);
   end;
  except
    writeln('EPlot: '+ExceptiontoString(exceptiontype, exceptionparam));
  end;   
 PrintF('Landrange %d: Injection sum: %.2f', [jar.length-1, sumup]);
end; 

As we can see we have 4 series to plot (including timeline):

  1. Injection (Injection during gas day)
  2. Full (Storage / WGV (in%))
  3. Withdrawal (Withdrawal during gas day (2 digits accuracy)).
  4. GasDayStart (The start of the gas day reported)

The time series is a result of the gas day and a trend is available.

“Gas day” means the period from 5:00 to 5:00 UTC the following day for winter time and from 4:00 to 4:00 UTC the following day when daylight saving is applied. Gas day is to be interpreted as UTC+1 for CET or UTC+2 in summer time for CEST. (Definition: see CAM Network Code specific-cations).

API access is provided in a REST-like interface (Representational State Transfer) exposing database resources in a JSON format with content-type in the mentioned Response Header.

Pic: 1154_json_https__agsi.gie.eu.png

The code of the data science vision contains example usage, and runs under Python3, Delphi, Jupyter-Notebook, Lazarus and maXbox4. Note that the API service is made available to the public free of charge. ONLY the data as currently available on the platforms is made available.

Tip: To extract data direct from the system, you can click on one of these links in a browser (web traffic versus API traffic ;-)):

AGSI+ https://agsi.gie.eu/api?type=eu

Conclusion:

GIE is providing an API (Application Programming Interface) service on its AGSI and AGSI+ storage data. The API documentation is on progress and provides examples and guidance on how to use the service and is available after registration to get an API-key. Below zoom of the past half year:

half year

Pic: 1154_agsi_plot15.png

Script the Win API mixed with DLL- or procompiled Function:
function InternetReadFile(
           hfile: HINTERNET;
           lpbuffer: string;
           dwNumberOfBytesToRead: DWord;
           var lpdwNumberOfBytesRead: DWord): boolean;
   {BOOL InternetReadFile(
    [in]  HINTERNET hFile,
    [out] LPVOID    lpBuffer,
    [in]  DWORD     dwNumberOfBytesToRead,
    [out] LPDWORD   lpdwNumberOfBytesRead }
   external 'InternetReadFile@Wininet.dll stdcall';


function HttpGetDirect2(const Url: string): string;
var
  NetHandle: HINTERNET;
  UrlHandle: HINTERNET;
  Buffer: string; //array[0..1024] of Char;
  BytesRead: dWord;
begin
  Result:= '';
  NetHandle:= InternetOpen('maXbox4 agent',INTERNET_OPEN_TYPE_PRECONFIG,'nil','nil',0);
  writeln('debug '+itoa(nethandle));
  //if Assigned(NetHandle) then begin
  Setlength(Buffer, 1024)
  if NetHandle <> 0 then begin
    UrlHandle:= InternetOpenUrl(NetHandle, pchar(Url),'nil', 0,INTERNET_FLAG_RELOAD,0);
    writeln('debug '+itoa(urlhandle));
    if UrlHandle <> 0 then begin{ UrlHandle valid? Proceed with download }
      //FillChar(Buffer, SizeOf(Buffer), 0);
      buffer:= ' ';
      repeat
        Result:= Result + Buffer;
        buffer:= ' ';                      
        //InternetReadFile(UrlHandle, @Buffer,sizeof(buffer), BytesRead);
        InternetReadFile(UrlHandle, Buffer, length(buffer), BytesRead);
      until BytesRead = 0;    //}
      InternetCloseHandle(UrlHandle);
    end else
      { UrlHandle is not valid. Raise an exception. }
      xraise( Exception.CreateFmt('Cannot open URL %s',[Url]));
    InternetCloseHandle(NetHandle);
  end else
    { NetHandle is not valid. Raise an exception }
    xraise (Exception.Create('Unable to initialize Wininet'));
end;

The scripts and images can be found:

https://github.com/maxkleiner/agsi-data

Reference:

https://agsi.gie.eu/api

https://svn.code.sf.net/p/alcinoe/code/demos/ALWinInetHTTPClient/_source/Unit1.pas

https://docwiki.embarcadero.com/Libraries/Sydney/en/System.Net.HttpClient.THTTPClient.Post

Doc and Tool: https://maxbox4.wordpress.com

Script Ref: 1154_energy_api_agsi_plot14.txt

HttpResponse:= getEnergyStreamJSON2(URL_AGSIAPI2,’AT,2022-01-03,150′,AGSI_APIKEY);
  Appendix: shows an WinAPIDownload class from maXbox4 integration
TWinApiDownload = class(TObject)
  private
    fEventWorkStart : TEventWorkStart;
    fEventWork : TEventWork;
    fEventWorkEnd : TEventWorkEnd;
    fEventError : TEventError;
    fURL : string;
    fUserAgent : string;
    fStop : Boolean;
    fActive : Boolean;
    fCachingEnabled : Boolean;
    fProgressUpdateInterval : Cardinal;
    function GetIsActive : Boolean;
  public
    constructor Create;
    destructor Destroy; override;
    function CheckURL(aURL: string) : Integer;
    function Download(Stream : TStream) : Integer; overload;
    function Download(var res : string) : Integer; overload;
    function ErrorCodeToMessageString(aErrorCode : Integer) : string;
    procedure Stop;
    procedure Clear;
    property UserAgent : string read fUserAgent write fUserAgent;
    property URL : string read fURL write fURL;
    property DownloadActive : Boolean read GetIsActive;
    property CachingEnabled : Boolean read fCachingEnabled write fCachingEnabled;
    property UpdateInterval:Cardinal read fProgressUpdateInterval write fProgressUpdateInterval;
    property OnWorkStart : TEventWorkStart read fEventWorkStart write fEventWorkStart;
    property OnWork : TEventWork read fEventWork write fEventWork;
    property OnWorkEnd : TEventWorkEnd read fEventWorkEnd write fEventWorkEnd;
    property OnError : TEventError read fEventError write fEventError;
  end;  
  

Max Kleiner 10/10/2022

procedure TFormVisualLearningSaveScreenshot(filename: string);
begin
  try
    WriteLn(' Saving '+filename+'.');
    SaveHandleToBitmap(filename, FormVisualLearning.Handle);
  except
    // Nothing can be done if this fails.
  end;
end;
Kranzelbinder Poertschach 2015 August
On Train with Sister

— Falcon Sandbox Analysis Summary —

File Name: maXbox4.exe
Analysis State: SUCCESS
Threat Verdict: no specific threat
Threat Score: n/a/100
AV Detection Ratio: n/a
AV Family Name:
Time of analysis: 2022-12-12 14:10:55
File Size (bytes): 34014488
File Type: PE32 executable (GUI) Intel 80386, for MS Windows
Contacted Domains: none
Contacted Hosts: none
Environment: Windows 10 64 bit (ID: 160)

Version 4.7.6.20

CC Collection
CC 40107, 40110, 40103 and CC 6517, 6547
Stacked Chart with Series
procedure TForm1FormCreateTest(Sender: TObject);
var Chart1: TChart; bs: TBarSeries; form1: TForm;
begin
  form1:= TForm.create(self);
  form1.setbounds(10,10,600,400);
  form1.show;
  chart1:= TChart.create(form1) 
  chart1.parent:= form1;
  chart1.align:= alClient;
  Chart1.View3D:=false;
  bs:= TBarSeries.create(self);
  with Chart1.AddSeries(bs) {as TBarSeries} do begin
    Marks.Visible:=false;
    bs.MultiBar:= teembstacked; //teembSelfStack;
    FillSampleValues(10);
  end;
end;  

Showcase

A showcase was published to how he uses JSON objects from HTTP requests to visualize aggregated gas storage inventory data into graphs and charts.

Why A Data Scientist Chooses Delphi For Powerful Real World Visualizations

Embarcadero Tech Challenge

Iterate within a JSON Array

The API returns the number of days, hours, working days, working hours, wages, weekend days, and the list of public holidays of the requested date period and country. You can also add any number of working days or working hours to a given date. 50 countries and over 230 regional calendars are supported and we work hard to keep our database up to date by following government announcements regarding public holidays changes.

https://rapidapi.com/joursouvres-api/api/working-days/

 "public_holidays": {   
      "total": 10,
      "mondays": 4,
      "tuesdays": 0,
      "wednesdays": 0,
      "thursdays": 1,
      "fridays": 1,
      "saturdays": 1,
      "sundays": 3,
      "list":  [
         {     "date": "2022-01-01",
               "description" : "Jour de l'An"},
         {     "date": "2022-01-02",
               "description" : "Saint-Berchtold"},
         {     "date": "2022-04-15",
               "description" : "Vendredi Saint"},
         {     "date": "2022-04-18",
               "description" : "Lundi de Pâques"},
         {     "date": "2022-05-01",
               "description" : "Fête du Travail"},
         {     "date": "2022-05-26",
               "description" : "Jeudi de l'Ascension"},
         {     "date": "2022-06-06",
               "description" : "Lundi de la Pentecôte"},
         {     "date": "2022-08-01",
               "description" : "Fête Nationale suisse"},
         {     "date": "2022-12-25",
               "description" : "Noël"},
         {     "date": "2022-12-26",
               "description" : "Saint Etienne"}
        ]
    },

The point was to get the right iterator which counts the array without get access to the total value in combination of object and array:

 if httpq.getresponsecode=200 Then begin 
        
   arcnt:= jo.values['public_holidays'].asobject['list'].asarray.count;
   for it:= 0 to arcnt-1 do
     result:= result+ jo.values['public_holidays'].asobject['list'].asarray[it].asobject['description'].asstring+CRLF
       end else result:='Failed:'+
            itoa(Httpq.getresponsecode)+Httpq.GetResponseHeader('message'); 
   except 
      writeln('EWI_HTTP: '+ExceptiontoString(exceptiontype,exceptionparam));
   finally

writeln(‘public_holidays: ‘+CRLF+
utf8tostr(workdays_API2(‘AURL’, ‘aclient’,’2022-01-01′,’2022-12-31′,’CH’)));

const AURLS ='https://working-days.p.rapidapi.com/1.3/analyse?start_date=%s&end_date=%s'+'&country_code=%s';

public_holidays:
Jour de l’An
Saint-Berchtold
Vendredi Saint
Lundi de Pâques
Fête du Travail
Jeudi de l’Ascension
Lundi de la Pentecôte
Fête Nationale suisse
Noël
Saint Etienne

writeln(AskChatGPT(‘how to start a DCOM server?’)); Answer2:

  1. Open the Control Panel and select Administrative Tools.
  2. Select Component Services.
  3. Expand the Component Services node and select Computers.
  4. Right-click on My Computer and select Properties.
  5. Select the COM Security tab.
  6. Under Launch and Activation Permissions, select Edit Limits.
  7. Select Add and enter the user name or group name that will be allowed to start the DCOM server.
  8. Select OK and then select Apply.
  9. Select OK to close the Properties window.
  10. Right-click on My Computer and select Properties.
  11. Select the COM Security tab.
  12. Under Access Permissions, select Edit Limits.
  13. Select Add and enter the user name or group name that will be allowed to access the DCOM server.
  14. Select OK and then select Apply.
  15. Select OK to close the Properties window.
  16. Right-click on My Computer and select Manage.
  17. Expand the Services and Applications node and select Services.
  18. Right-click on the DCOM server and select Properties.
  19. Select the Log On tab.
  20. Select This Account and enter the user name and password of the user or group that will be allowed to start the DCOM server.
  21. Select OK to close the Properties window.
  22. Right-click on the DCOM server and select Start.
  23. The DCOM server should now be running.
Got a prize but still blocked
https://bextuychiev.github.io/tricking-data-science/book/statistics/concepts.html

Long Term Time Serie over Years

as per Date June 2024
Update 2025
https://sourceforge.net/projects/maxbox5/files/EKON29/1154_energy_api_agsi_plot14_64bit2025.txt/download

TensorFlow EKON 25

EKON 25 is the most traditional Delphi conference and offers a deep dive for the modern developer and architect aiming to transform technologies into valuable business solutions. We always focus on the big picture: Delphi innovations, Cross platforms, IoT, Data Bases, Frameworks, Tools, Delphi fundamentals, Web, maXbox and Cloud technologies, as well as professional insights.

First I got TensorFlow to running with Microsoft Visual C++ 2015-2022 Redistributable (x64) – 14.30.30704 first to install.

Then I needed ImageAI:

C:\Users\breitsch\AppData\Local\Programs\Python\Python38>python -m pip install imageai
Collecting imageai
Using cached imageai-2.1.6-py3-none-any.whl (160 kB)
Requirement already satisfied: matplotlib==3.3.2 in c:\users\breitsch\appdata\local\programs\python\python38\lib\site-packages (from imageai) (3.3.2)
Collecting opencv-python
Downloading opencv_python-4.5.4.58-cp38-cp38-win_amd64.whl (35.1 MB)
|¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦| 35.1 MB 6.4 MB/s
Collecting keras==2.4.3
Using cached Keras-2.4.3-py2.py3-none-any.whl (36 kB)
Collecting pillow==7.0.0
Downloading Pillow-7.0.0-cp38-cp38-win_amd64.whl (2.0 MB)
|¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦| 2.0 MB 1.6 MB/s
Collecting keras-resnet==0.2.0
Using cached keras-resnet-0.2.0.tar.gz (9.3 kB)
Collecting scipy==1.4.1
Downloading scipy-1.4.1-cp38-cp38-win_amd64.whl (31.0 MB)
|¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦| 31.0 MB 6.4 MB/s
Collecting numpy==1.19.3
Downloading numpy-1.19.3-cp38-cp38-win_amd64.whl (13.3 MB)
|¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦| 13.3 MB 6.8 MB/s
Requirement already satisfied: h5py==2.10.0 in c:\users\breitsch\appdata\local\programs\python\python38\lib\site-packages (from imageai) (2.10.0)
Requirement already satisfied: python-dateutil>=2.1 in c:\users\breitsch\appdata\local\programs\python\python38\lib\site-packages (from matplotlib==3.3.2->imageai) (2.8.1)
Requirement already satisfied: kiwisolver>=1.0.1 in c:\users\breitsch\appdata\local\programs\python\python38\lib\site-packages (from matplotlib==3.3.2->imageai) (1.2.0)
Requirement already satisfied: certifi>=2020.06.20 in c:\users\breitsch\appdata\local\programs\python\python38\lib\site-packages (from matplotlib==3.3.2->imageai) (2020.6.20)
Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.3 in c:\users\breitsch\appdata\local\programs\python\python38\lib\site-packages (from matplotlib==3.3.2->imageai) (2.4.7)
Requirement already satisfied: cycler>=0.10 in c:\users\breitsch\appdata\local\programs\python\python38\lib\site-packages (from matplotlib==3.3.2->imageai) (0.10.0)
Collecting pyyaml
Downloading PyYAML-6.0-cp38-cp38-win_amd64.whl (155 kB)
|¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦| 155 kB …
Requirement already satisfied: six in c:\users\breitsch\appdata\local\programs\python\python38\lib\site-packages (from h5py==2.10.0->imageai) (1.15.0)
Building wheels for collected packages: keras-resnet
Building wheel for keras-resnet (setup.py) … done
Created wheel for keras-resnet: filename=keras_resnet-0.2.0-py2.py3-none-any.whl size=20490 sha256=d2422d60d9cced0f8187ffaee05bfde5170fd975a30feab18548dc676ba07077
Stored in directory: c:\users\breitsch\appdata\local\pip\cache\wheels\be\90\98\9d455f04a7ca277366b36c660c89d171ff5abb7bdd8a8b8e75
Successfully built keras-resnet
Installing collected packages: numpy, opencv-python, scipy, pyyaml, keras, pillow, keras-resnet, imageai
Attempting uninstall: numpy
Found existing installation: numpy 1.18.5
Uninstalling numpy-1.18.5:
Successfully uninstalled numpy-1.18.5
Attempting uninstall: scipy
Found existing installation: scipy 1.5.2
Uninstalling scipy-1.5.2:
Successfully uninstalled scipy-1.5.2
Attempting uninstall: pillow
Found existing installation: Pillow 7.2.0
Uninstalling Pillow-7.2.0:
Successfully uninstalled Pillow-7.2.0
ERROR: After October 2020 you may experience errors when installing or updating packages. This is because pip will change the way that it resolves dependency conflicts.

We recommend you use –use-feature=2020-resolver to test your packages with the new resolver before it becomes the default.

Next step was to install TensorFlow:

tensorflow 2.3.1 requires numpy<1.19.0,>=1.16.0, but you’ll have numpy 1.19.3 which is incompatible.
Successfully installed imageai-2.1.6 keras-2.4.3 keras-resnet-0.2.0 numpy-1.19.3 opencv-python-4.5.4.58 pillow-7.0.0 pyyaml-6.0 scipy-1.4.1
WARNING: You are using pip version 20.2.3; however, version 21.3.1 is available.
You should consider upgrading via the ‘C:\Users\breitsch\AppData\Local\Programs\Python\Python38\python.exe -m pip install –upgrade pip’ command.

Technically, it’s not an error, it’s a warning. It’s mainly just verbose, so you can safely ignore it. To silence it, do this in the correct order. You will also need to restart your kernel for now.

import os
os.environ[‘TF_CPP_MIN_LOG_LEVEL’] = ‘3’

import tensorflow as tf

2021-10-30 10:50:47.532288: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library ‘cudart64_101.dll’; dlerror: cudart64_101.dll not found
2021-10-30 10:50:47.532312: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
2021-10-30 10:50:49.434662: W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library ‘nvcuda.dll’; dlerror: nvcuda.dll not found
2021-10-30 10:50:49.434691: W tensorflow/stream_executor/cuda/cuda_driver.cc:312] failed call to cuInit: UNKNOWN ERROR (303)
2021-10-30 10:50:49.439066: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:169] retrieving CUDA diagnostic information for host: BREITSCH-BOX
2021-10-30 10:50:49.439194: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:176] hostname: BREITSCH-BOX
2021-10-30 10:50:49.440299: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN)to use the following CPU instructions in performance-critical operations: AVX2
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2021-10-30 10:50:49.461185: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x1bba71e4320 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2021-10-30 10:50:49.461227: I tensorflow/compiler/xla/service/service.cc:176] StreamExecutor device (0): Host, Default Version
this first line fine

In the end we need a pretrained model. yolo-tiny.h5

Traceback (most recent call last):
File “C:\Program Files\Streaming\IBZ2021\Module2_3\992_oma_objectdetector21.py”, line 49, in detector.loadModel()
File “C:\Users\breitsch\AppData\Local\Programs\Python\Python38\lib\site-packages\imageai\Detection__init__.py”, line 195, in loadModel
model.load_weights(self.modelPath)
File “C:\Users\breitsch\AppData\Local\Programs\Python\Python38\lib\site-packages\tensorflow\python\keras\engine\training.py”, line 2204, in load_weights
with h5py.File(filepath, ‘r’) as f:
File “C:\Users\breitsch\AppData\Local\Programs\Python\Python38\lib\site-packages\h5py_hl\files.py”, line 406, in init
fid = make_fid(name, mode, userblock_size,
File “C:\Users\breitsch\AppData\Local\Programs\Python\Python38\lib\site-packages\h5py_hl\files.py”, line 173, in make_fid
fid = h5f.open(name, flags, fapl=fapl)
File “h5py_objects.pyx”, line 54, in h5py._objects.with_phil.wrapper
File “h5py_objects.pyx”, line 55, in h5py._objects.with_phil.wrapper
File “h5py\h5f.pyx”, line 88, in h5py.h5f.open
OSError: Unable to open file (unable to open file: name = ‘./crypt/models/yolo-tiny.h5’, errno = 2, error message = ‘No such file or directory’, flags = 0, o_flags = 0)

The Result:

C:\maXbox\works2021\maxbox4>pip3 install wget
Collecting wget
Downloading https://files.pythonhosted.org/packages/47/6a/62e288da7bcda82b935f
f0c6cfe542970f04e29c756b0e147251b2fb251f/wget-3.2.zip
Building wheels for collected packages: wget
Building wheel for wget (setup.py) … done
Stored in directory: C:\Users\Max\AppData\Local\pip\Cache\wheels\40\15\30\7d8f
7cea2902b4db79e3fea550d7d7b85ecb27ef992b618f3f
Successfully built wget
Installing collected packages: wget
Successfully installed wget-3.2
WARNING: You are using pip version 19.1, however version 21.3.1 is available.
You should consider upgrading via the ‘python -m pip install –upgrade pip’ comm
and.

no console attached..
2021-11-14 15:35:41.808611: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library ‘cudart64_110.dll’; dlerror: cudart64_110.dll not found
2021-11-14 15:35:41.808653: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
2021-11-14 15:35:47.777464: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library ‘cudart64_110.dll’; dlerror: cudart64_110.dll not found
2021-11-14 15:35:47.778953: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library ‘cublas64_11.dll’; dlerror: cublas64_11.dll not found
2021-11-14 15:35:47.780421: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library ‘cublasLt64_11.dll’; dlerror: cublasLt64_11.dll not found
2021-11-14 15:35:47.781861: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library ‘cufft64_10.dll’; dlerror: cufft64_10.dll not found
2021-11-14 15:35:47.783291: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library ‘curand64_10.dll’; dlerror: curand64_10.dll not found
2021-11-14 15:35:47.784715: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library ‘cusolver64_11.dll’; dlerror: cusolver64_11.dll not found
2021-11-14 15:35:47.786130: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library ‘cusparse64_11.dll’; dlerror: cusparse64_11.dll not found
2021-11-14 15:35:47.787515: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library ‘cudnn64_8.dll’; dlerror: cudnn64_8.dll not found
2021-11-14 15:35:47.787556: W tensorflow/core/common_runtime/gpu/gpu_device.cc:1850] Cannot dlopen some GPU libraries. Please make sure the missing libraries mentioned above are installed properly if you would like to use GPU. Follow the guide at https://www.tensorflow.org/install/gpu for how to download and setup the required libraries for your platform.
Skipping registering GPU devices…
2021-11-14 15:35:47.787860: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX AVX2
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
C:\maXbox\works2021\maxbox4\992_oma_objectdetector21.py:56: DeprecationWarning: ‘detectCustomObjectsFromImage()’ function has been deprecated and will be removed in future versions of ImageAI.
Kindly use ‘detectObjectsFromImage()’
minimum_percentage_probability=40.0)
WARNING: Logging before flag parsing goes to stderr.
W1114 15:35:48.381193 16336 ag_logging.py:146] AutoGraph could not transform .predict_function at 0x00000228002AA268> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, export AUTOGRAPH_VERBOSITY=10) and attach the full output.
Cause: ‘arguments’ object has no attribute ‘posonlyargs’
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
this first line fine
person : 55.95281720161438
person : 66.63782596588135
person : 46.17394208908081
person : 41.51414334774017
person : 64.7615909576416
person : 64.41770792007446

integrate image detector compute ends…

elapsedSeconds:= 14.6140739
no console attached..
mX4 executed: 14/11/2021 15:35:56 Runtime: 0:0:17.227 Memload: 44% use

TF ImageAI Classifier

Catapult Simulator (tension or torsion)

Here’s a “cup” type catapult simulator (no sling).   It simulates tensional or torsional  driving forces with user specified design parameters. 

We build the app with maXbox to test callbacks and RungeKutta:

URungeKutta4test.pas 
http://www.softwareschule.ch/examples/catapult.txt
http://delphiforfun.org/Programs/catapult.htm

Catapult Parameters

Pivot height above ground (so we can tell when the projectile hits the ground).
Beam Length
Distance from Pivot to projectile end of beam (negative values =  left of pivot)
Distance from Pivot to Force point  – may be negative, (left of pivot), or positive (right of pivot)
Mass of projectile
Force type (torsion or tension)
For Tension (spring) force Spring Fixed end point coordinates Spring Constant : Force per unit length of the driving spring.  Compression springs may be modeled by specifying a negative spring constant.i   
For Torsion force  Force value.
Mass of beam (On Advanced tab sheet)
Air frictional drag coefficient (On Advanced tab sheet)

Units Choices

Large Metric:  Length in Meters (m); Mass in kilograms (kg); Force in newtons (N).  One newton is the force required to accelerate one kilogram at one meter per second per second.
Small Metric: Length in  centimeters (cm), Mass in grams (g), Force in grams force (gf)      Note that 1 gram force is approximately equal to 1 centinewton.   (1 gram force  = 0.980665 centinewton =  0.00980665 newtons = approximate force of earth’s gravity on a 1 gram mass ).
Large English: Length in feet (ft), Mass in pounds (lb); Force in pounds-force (lbf).  One pound force = 4.44822 newtons =  approximate force of earth’s gravity on a 1 pound mass ). 
Small English: Length in inches (in); Mass in ounces (oz), Force in ounces force  (ozf). . One ounce force = 28.35 gf = 0.278 N = approximate force of earth’s gravity on a 1 ounce mass ).

In numerical analysis, the Runge-Kutta methods (English: / ˈ r ʊ ŋ ə ˈ k ʊ t ɑː / RUUNG-ə-KUUT-tah) are a family of implicit and explicit iterative methods, which include the well-known routine called the Euler Method, used in temporal discretization for the approximate solutions of ordinary differential equations.

mX4 driving force
Weltnet by Max 1995
Repl Teaching
EKON Locomotion 1204
The Box of Max
https://sourceforge.net/projects/maxbox/files/Examples/13_General/1116_U_ChallengingmathTeasers.pas/download
Into the beginning
Free Pascal Utils
Train on Colab
train ship

Image Classification with Lazarus

Another fascinating option is to run the entire system as runtime virtualization with the help of a Jupyter notebook running on Ubuntu in the cloud on Google Colab or Colab.research container.

1076_CAI_UVisualGAN2tester1.pas
Visualize DropOut Rate

Readable pdf version at:

https://www.academia.edu/53798878/maXbox_Starter87_Image_Classification_Lazarus

Lazarus is also being built in Colab and the deep learning network is compiled and trained too in a Jupiter notebook.

https://gitlab.ti.bfh.ch/knm4/python4delphi/-/blob/master/EKON24_SimpleImageClassificationCPU_2021.ipynb

The build of Free Pascal with Lazarus on a Ubuntu Linux is included, as can be seen under the following link:

https://github.com/maxkleiner/maXbox/blob/master/EKON24_SimpleImageClassificationCPU.ipynb

or an update with 64-bit

https://github.com/maxkleiner/python4delphi/blob/master/EKON24_SimpleImageClassificationCPU_2021.ipynb

bithit

Now the 16 Steps (extract):

https://colab.research.google.com/github/maxkleiner/python4delphi/blob/master/EKON24_SimpleImageClassificationCPU_2021.ipynb

!apt-get update

Ign:1 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64  InRelease
Get:2 https://cloud.r-project.org/bin/linux/ubuntu bionic-cran40/ InRelease [3,626 B]
Ign:3 https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64  InRelease
Hit:4 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64  Release
Hit:5 https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64  Release
Get:6 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
Get:7 https://cloud.r-project.org/bin/linux/ubuntu bionic-cran40/ Packages [67.4 kB]
Get:8 http://ppa.launchpad.net/c2d4u.team/c2d4u4.0+/ubuntu bionic InRelease [15.9 kB]
Hit:9 http://archive.ubuntu.com/ubuntu bionic InRelease
Get:11 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]
Hit:13 http://ppa.launchpad.net/cran/libgit2/ubuntu bionic InRelease
Get:14 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]
Hit:15 http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic InRelease
Get:16 http://security.ubuntu.com/ubuntu bionic-security/restricted amd64 Packages [581 kB]
Hit:17 http://ppa.launchpad.net/graphics-drivers/ppa/ubuntu bionic InRelease
Get:18 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages [1,428 kB]
Get:19 http://ppa.launchpad.net/c2d4u.team/c2d4u4.0+/ubuntu bionic/main Sources [1,802 kB]
Get:20 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages [2,335 kB]
Get:21 http://archive.ubuntu.com/ubuntu bionic-updates/universe amd64 Packages [2,202 kB]
Get:22 http://archive.ubuntu.com/ubuntu bionic-updates/restricted amd64 Packages [613 kB]
Get:23 http://ppa.launchpad.net/c2d4u.team/c2d4u4.0+/ubuntu bionic/main amd64 Packages [922 kB]
Get:24 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages [2,770 kB]
Fetched 13.0 MB in 4s (3,425 kB/s)
Reading package lists... Done

!apt-get install fpc fpc-source lazarus git subversion

Reading package lists... Done
Building dependency tree       
Reading state information... Done
git is already the newest version (1:2.17.1-1ubuntu0.9).

!git clone https://github.com/joaopauloschuler/neural-api.git

Cloning into 'neural-api'...
remote: Enumerating objects: 2372, done.
remote: Counting objects: 100% (494/494), done.
remote: Compressing objects: 100% (370/370), done.
remote: Total 2372 (delta 340), reused 236 (delta 124), pack-reused 1878
Receiving objects: 100% (2372/2372), 4.58 MiB | 10.38 MiB/s, done.
Resolving deltas: 100% (1585/1585), done.

!svn checkout https://svn.code.sf.net/p/lazarus-ccr/svn/components/multithreadprocs mtprocs

 mtprocs/examples
A    mtprocs/examples/parallelloop1.lpr
A    mtprocs/examples/parallelloop_nested1.lpi
A    mtprocs/examples/parallelloop_nested1.lpr
A    mtprocs/examples/recursivemtp1.lpr
A    mtprocs/examples/simplemtp1.lpr
A    mtprocs/examples/parallelloop1.lpi
A    mtprocs/examples/recursivemtp1.lpi
A    mtprocs/examples/simplemtp1.lpi
A    mtprocs/examples/testmtp1.lpi
A    mtprocs/examples/testmtp1.lpr
A    mtprocs/Readme.txt
A    mtprocs/mtprocs.pas
A    mtprocs/mtpcpu.pas
A    mtprocs/multithreadprocslaz.lpk
A    mtprocs/mtputils.pas
A    mtprocs/multithreadprocslaz.pas
Checked out revision 8093.

5. !lazbuild mtprocs/multithreadprocslaz.lpk

6. !ls -l neural-api/examples/SimpleImageClassifier/SimpleImageClassifier.lpi

-rw-r--r-- 1 root root 5694 Sep 23 08:37 neural-api/examples/SimpleImageClassifier/SimpleImageClassifier.lpi

7. !lazbuild neural-api/examples/SimpleImageClassifier/SimpleImageClassifier.lpi

Hint: (lazarus) [RunTool] /usr/bin/fpc "-iWTOTP"
Hint: (lazarus) [RunTool] /usr/bin/fpc "-va" "compilertest.pas"
TProject.DoLoadStateFile Statefile not found: /content/neural-api/bin/x86_64-linux/units/SimpleImageClassifier.compiled
Hint: (lazarus) [RunTool] /usr/bin/fpc "-iWTOTP" "-Px86_64" "-Tlinux"
Hint: (lazarus) [RunTool] /usr/bin/fpc "-va" "-Px86_64" "-Tlinux" "compilertest.pas"
Hint: (11031) End of reading config file /etc/fpc.cfg
Free Pascal Compiler version 3.0.4+dfsg-18ubuntu2 [2018/08/29] for x86_64
Copyright (c) 1993-2017 by Florian Klaempfl and others
(1002) Target OS: Linux for x86-64
(3104) Compiling SimpleImageClassifier.lpr
(3104) Compiling /content/neural-api/neural/neuralnetwork.pas
(3104) Compiling /content/neural-api/neural/neuralvolume.pas

8. ls -l neural-api/bin/x86_64-linux/bin/SimpleImageClassifier

-rwxr-xr-x 1 root root 1951024 Sep 23 08:43 neural-api/bin/x86_64-linux/bin/SimpleImageClassifier*

9. import os, import urllib.request

import os
import urllib.request
if not os.path.isfile('cifar-10-batches-bin/data_batch_1.bin'):
  print("Downloading CIFAR-10 Files")
  url = 'https://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz'
  urllib.request.urlretrieve(url, './file.tar')


Downloading CIFAR-10 Files
  1. ls -l
total 166080
-rw-r--r-- 1 root root 170052171 Sep 23 08:46 file.tar
drwxr-xr-x 5 root root      4096 Sep 23 08:39 mtprocs/
drwxr-xr-x 7 root root      4096 Sep 23 08:42 neural-api/
drwxr-xr-x 1 root root      4096 Sep 16 13:40 sample_data/

11. !tar -xvf ./file.tar

cifar-10-batches-bin/
cifar-10-batches-bin/data_batch_1.bin
cifar-10-batches-bin/batches.meta.txt
cifar-10-batches-bin/data_batch_3.bin
cifar-10-batches-bin/data_batch_4.bin
cifar-10-batches-bin/test_batch.bin
cifar-10-batches-bin/readme.html
cifar-10-batches-bin/data_batch_5.bin
cifar-10-batches-bin/data_batch_2.bin
  1. Copy check
if not os.path.isfile('./data_batch_1.bin'):
  print("Copying files to current folder")
  !cp ./cifar-10-batches-bin/* ./
Copying files to current folder

13. Start Running

if os.path.isfile(‘./data_batch_1.bin’):

  print(“RUNNING!”)

if os.path.isfile('./data_batch_1.bin'):
  print("RUNNING!")
  

  !neural-api/bin/x86_64-linux/bin/SimpleImageClassifier

RUNNING!
Creating Neural Network...
 Layers: 12
 Neurons:331
 Weights:162498 Sum:  -19.536575
File name is: SimpleImageClassifier-64
Learning rate:0.001000 L2 decay:0.000010 Inertia:0.900000 Batch size:64 Step size:64 Staircase ephocs:10

Training images: 40000
Validation images: 10000
Test images: 10000
File name is: SimpleImageClassifier-64
Learning rate:0.001000 L2 decay:0.000010 Inertia:0.900000 Batch size:64 Step size:64 Staircase ephocs:10
Training images: 40000
Validation images: 10000
Test images: 10000
RUNNING!
Creating Neural Network...
 Layers: 12
 Neurons:331
 Weights:162498 Sum:  -19.536575
VALIDATION RECORD! Saving NN at SimpleImageClassifier-64.nn
Epochs: 20 - Examples seen:800000 Validation Accuracy: 0.8077 Validation Error: 0.5409 Validation Loss: 0.5646 Total time: 69.72min
Layer  0     
Starting Testing.
Epochs: 20 Examples seen:800000 Test Accuracy: 0.8013 Test Error: 0.5539 Test Loss: 0.5934 Total time: 70.75min
Epoch time: 2.2958 minutes. 50 epochs: 1.9132 hours.
Epochs: 20. Working time: 1.18 hours.
Learning rate set to: 0.00082
Layer 11                                                     Max Output:  0.608 Min Output:  0.000 TNNetSoftMax 10,1,1 Times: 0.00s 0.00s Parent:10
Starting Testing.
Epochs: 50 Examples seen:2000000 Test Accuracy: 0.8393 Test Error: 0.4457 Test Loss: 0.4874 Total time: 176.12min
Epoch time: 2.3167 minutes. 50 epochs: 1.9306 hours.
Epochs: 50. Working time: 2.94 hours.
Finished.
14. from google.colab import files

!ls -l

-rw-r--r-- 1 root root        61 Sep 23 08:51 batches.meta.txt
drwxr-xr-x 2 2156 1103      4096 Jun  4  2009 cifar-10-batches-bin
-rw-r--r-- 1 root root  30730000 Sep 23 08:51 data_batch_1.bin
-rw-r--r-- 1 root root  30730000 Sep 23 08:51 data_batch_2.bin
-rw-r--r-- 1 root root  30730000 Sep 23 08:51 data_batch_3.bin
-rw-r--r-- 1 root root  30730000 Sep 23 08:51 data_batch_4.bin
-rw-r--r-- 1 root root  30730000 Sep 23 08:51 data_batch_5.bin
-rw-r--r-- 1 root root 170052171 Sep 23 08:46 file.tar
drwxr-xr-x 5 root root      4096 Sep 23 08:39 mtprocs
drwxr-xr-x 7 root root      4096 Sep 23 08:42 neural-api
-rw-r--r-- 1 root root        88 Sep 23 08:51 readme.html
drwxr-xr-x 1 root root      4096 Sep 16 13:40 sample_data
-rw-r--r-- 1 root root      3390 Sep 23 11:48 SimpleImageClassifier-64.csv
-rw-r--r-- 1 root root   2349757 Sep 23 11:41 SimpleImageClassifier-64.nn
-rw-r--r-- 1 root root  30730000 Sep 23 08:51 test_batch.bin
15. files.download('SimpleImageClassifier-64.nn')

16. files.download('SimpleImageClassifier-64.csv')

FileNotFoundError: Cannot find file: SimpleImageClassifier.csv
16. files.download('SimpleImageClassifier-64.csv')


Summary
of the 16 Steps:
# -*- coding: utf-8 -*-
"""Kopie von EKON_SimpleImageClassificationCPU_2021.ipynb

Automatically generated by Colaboratory.

Original file is located at
    https://colab.research.google.com/drive/1clvG2uoMGo-_bfrJnxBJmpNTxjvnsMx9
"""

!apt-get update

!apt-get install fpc fpc-source lazarus git subversion

!git clone https://github.com/joaopauloschuler/neural-api.git

!svn checkout https://svn.code.sf.net/p/lazarus-ccr/svn/components/multithreadprocs mtprocs

!lazbuild mtprocs/multithreadprocslaz.lpk

!ls -l neural-api/examples/SimpleImageClassifier/SimpleImageClassifier.lpi

!lazbuild neural-api/examples/SimpleImageClassifier/SimpleImageClassifier.lpi

ls -l neural-api/bin/x86_64-linux/bin/SimpleImageClassifier

import os
import urllib.request

if not os.path.isfile('cifar-10-batches-bin/data_batch_1.bin'):
  print("Downloading CIFAR-10 Files")
  url = 'https://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz'
  urllib.request.urlretrieve(url, './file.tar')

ls -l

!tar -xvf ./file.tar

if not os.path.isfile('./data_batch_1.bin'):
  print("Copying files to current folder")
  !cp ./cifar-10-batches-bin/* ./

if os.path.isfile('./data_batch_1.bin'):
  print("RUNNING!")
  !neural-api/bin/x86_64-linux/bin/SimpleImageClassifier

from google.colab import files
!ls -l

files.download('SimpleImageClassifier-66.nn')


files.download('SimpleImageClassifier-66.csv')

SNCF Quadri-Courant CC 40110 Nice
LIMA 8159LP
Shapes of EPFL

this first line fine
person : 13.743722438812256
person : 22.95577973127365
person : 34.45495665073395
person : 44.651105999946594
person : 45.853763818740845
person : 47.165292501449585
person : 89.50895667076111
person : 95.48800587654114
person : 97.00847864151001
person : 97.67321348190308
integrate image detector compute ends… elapsedSeconds:= 111.695549947051

The 5th Dimension

How to explain the 5th Dimension?

import numpy as np
np.ones([1,2,3,4,5])

import numpy as np
np.ones([1,2,3,4,5])
array([[[[[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]],

array
 ([[[[[1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.]], 
    
     [[1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.]],

     [[1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.]]],


    [[[1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.]],

     [[1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.]],

     [[1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.],
      [1., 1., 1., 1., 1.]]]]])

>

There are 5 columns of 4 rows in 3 blocks times 2!

It returns a 5-dimensional array of size 1x2x3x4x5 filled with 1s.

ExecString('import numpy as np'); 
//>>> import numpy as np
//>>> np.ones([1,2,3,4,5])
println(EvalStr('repr(np.ones([1,2,3,4,5]))'));
println(StringReplace(EvalStr('repr(np.ones([1,2,3,4,5]))'),'],',CRLF,[rfReplaceAll]));
writeln(CRLF);
array([[[[[ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.]

         [[ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.]

         [[ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.]]


        [[[ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.]

         [[ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.]

         [[ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.
          [ 1.,  1.,  1.,  1.,  1.]]]]])

The 5th dimension, according to the Kaluza-Klein theory is a concept that unifies two of the four fundamental forces of nature in a 5th dimension to explain how light (electromagnetism) interacts with gravity. Although the Kaluza-Klein theory was later deemed to be inaccurate, it served as a good starting point for the development of string theory …

maXbox and Python can show in a multidimensional matrix the 5th dimension
Topics

Security is Multi-Faceted

Security is a continuum requiring multiple angles and each of the items below can help:

  • Natively compiled applications
  • No dependency on a runtime execution environment
  • Use of vetted and trusted third party libraries and components
  • Committing to contribute back to open-source projects you leverage
  • Security focus when writing code (no copy-and-paste coding)
  • Tooling to verify an application source code
  • Secure storage of source code (to avoid source code injection)
  • Secure build environment (to avoid binary code injection)
  • Application executable signing

from Marcu Cantu

the babblefish

Earth Distance between 2 Points

Here’s a little program that estimates the surface distance between two points on earth defined by their latitude and longitude.

Vincenty’s formulae are two related iterative methods used in geodesy to calculate the distance between two points on the surface of a spheroid, developed by Thaddeus Vincenty (1975a) They are based on the assumption that the figure of the Earth is an oblate spheroid, and hence are more accurate than methods such as great-circle distance which assume a spherical Earth.

{Vincenty Inverse algorithm
Degrees, minutes, and seconds
Ref: P1 lat: 40:40:11N long: 73:56:38W //long NY
P2 47:22:00N 08:32:00E ZH
3937.9 Miles – 6339.3 Kilometers – 6339.255 Kilometers – 6339255.227 metres
https://geodesyapps.ga.gov.au/vincenty-inverse

 1     NY  40° 40' 11" N   73° 56' 38" W
 2     ZH  47° 22' 0" N        8° 32' 0" E
 53° 19' 36.22"     296° 7' 33.11"  6339254.547 metres

 decimals: 40.669722222222222 ;  -73.943888888888889
           47.366666666666667 ;   8.533333333333333

Calculate the geographical distance (in kilometers or miles) between 2 points with extreme accuracy. Between 2 algorithms we have 6339254.547 metres and 6339255.227 metres, difference: 680 meters!

with TPythonEngine.Create(Nil) do begin
    pythonhome:= PYHOME;
    try 
      loadDLL;
      println(EvalStr('__import__("geopy.distance")'));
      ExecStr('from geopy.distance import geodesic');
      ExecStr('from geopy.distance import great_circle');
      ExecStr('p1 = (40.669722222222222,-73.943888888888889)');//# (lat, lon)
      ExecStr('p2 = (47.366666666666667,08.533333333333333)');// # (lat, lon) 
      println('Distance met: '+EvalStr('geodesic(p1, p2).meters'));
      println('Distance mil: '+EvalStr('geodesic(p1, p2).miles'));
      println('Distance circ: '+EvalStr('great_circle(p1, p2).meters'));
      //- https://goo.gl/maps/lHrrg
      //println(EvalStr('__import__("decimal").Decimal(0.1)'));
    except
      raiseError;
    finally     
      Free;  //}
    end; 
  end;  

>>>
Distance met: 6339254.546711418
Distance mil: 3939.0301555860137
Distance circ: 6322355.530084518

This library implements Vincenty’s solution to the inverse geodetic problem. It is based on the WGS 84 reference ellipsoid and is accurate to within 1 mm (!) or better.

This formula is widely used in geographic information systems (GIS) and is much more accurate than methods for computing the great-circle distance (which assume a spherical Earth).

781u_LatLonDistanceTestmX22.pas
XMLHTTP.6.0 /gzp
function getGETRequest2Decompress(feedstream: string): string;
var
  Url,aAPI_KEY, source: string;
  hReq,hr: Olevariant;
begin
  hReq:= CreateOleObject('Msxml2.XMLHTTP.6.0');
 try 
   hr:= hReq.Open('GET','https://www.codever.land/api/version', false);
   hReq.setRequestheader('user-agent',CUSERAGENT);
   hReq.setRequestheader('accept','application/json');
   hReq.setRequestheader('Accept-encoding','gzip, deflate');
   if hr= S_OK then hReq.Send();
   If hReq.Status = 200 Then
     result:= hreq.responseText
   Else result:= 'Failed response:'+itoa(hreq.Status)+hreq.responseText;
   //writeln('unzip response '+hReq.GetAllResponseHeaders); 
    //writeln('debug:'+hreq.responseBody)
 finally
    hReq:= unassigned;  
 end;                  
end; 

Borkum

CR Code and ART

QR codes are now ubiquitous and their revival is due to two factors. For one, Apple and Android added QR code scanners in the smartphone cameras. And, QR codes are found everywhere during the global pandemic as restaurants and coffee shops use them to safely share their menus while following social distancing rules.

And it turns out that QR codes are a great tool for managing your art. It is able to do so because a QR code has a maximum symbol size of 177×177 modules. So, it can have as much as 31,329 squares which can encode 3KB of data.

var   QRCodeBitmap: TBitmap; 
const COLORONCOLOR = 3;

procedure QRCcode(atext: string);
var 
  aQRCode: TDelphiZXingQRCode;
  Row, Column, err: Integer; res: Boolean; //HRESULT;
begin
  aQRCode:= TDelphiZXingQRCode.Create;
  QRCodeBitmap:= TBitmap.Create;
  //QRCodeBitmap
  try
    aQRCode.Data:= atext;//'edtText.Text';
    aQRCode.Encoding:= qrcAuto; //TQRCodeEncoding(cmbEncoding.ItemIndex);
    //aQRCode.QuietZone:= StrToIntDef(edtQuietZone.Text, 4);
    QRCodeBitmap.SetSize(aQRCode.Rows, aQRCode.Columns);
    for Row:= 0 to aQRCode.Rows - 1 do 
      for Column:= 0 to aQRCode.Columns - 1 do begin
        if (aQRCode.IsBlack[Row, Column]) then 
          QRCodeBitmap.Canvas.Pixels[Column, Row]:= clBlack
        else  
          QRCodeBitmap.Canvas.Pixels[Column, Row]:= clWhite;
      end;
    //Form1.Canvas.Brush.Bitmap:= QRCodeBitmap;
    //Form1.Canvas.FillRect(Rect(407,407,200,200));
    SetStretchBltMode(form1.canvas.Handle, COLORONCOLOR);
	// note that you need to use the Canvas handle of the bitmap,
	// not the handle of the bitmap itself
	//QRCodeBitmap.transparent:= true;
	Res:=StretchBlt(
	  form1.canvas.Handle,300,150,QRCodeBitmap.Width+250,QRCodeBitmap.Height+250,
	  QRCodeBitmap.canvas.Handle, 1,1, QRCodeBitmap.Width, QRCodeBitmap.Height,
	  SRCCOPY);
	  if not Res then begin
	    err:= GetLastError;
	    form1.Canvas.Brush.Color:= clyellow;
	    form1.canvas.TextOut(20, 20, Format('LastError: %d %s', 
                                           [err, SysErrorMessage(err)]));
	  end;
  finally
    aQRCode.Free;
    Form1.Canvas.Brush.Bitmap:= Nil;
    QRCodeBitmap.Free;
  end;
end;  

Mondrian
TEE Arbalete
TEE Mistral
BB 15015
L.S. Models CC 6503
Der Magdalensberg (slow.: Štalenska gora; 1059 m ü. A.) in Kärnten (früher Helenenberg).
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
this first line fine
person : 40.269359946250916
person : 95.28620839118958
person : 61.63168549537659
person : 71.69047594070435
integrate image detector compute ends…
Lazarus Classifier on pretrained Model

Python4Delphi II

//////////////////////////////////////////////////////////////////////////////

Python4Delphi II

______________________________________________________________________________

maXbox Starter86_2 – Code with Python4Delphi

Doc as pdf: http://www.softwareschule.ch/download/maxbox_starter86_2.pdf

maXbox Starter86_3 – Code with Python4Delphi

Doc as pdf: http://www.softwareschule.ch/download/maxbox_starter86_3.pdf

Be yourself; Everyone else is already taken. — Oscar Wilde.

In the last Article we have seen that P4D is a set of free components that wrap up the Python DLL into Delphi and Lazarus (FPC). For the next section I want to show more practical implementations. Let’s start with P4D in Delphi:

First create a new Form

  • Drop a TMemo (or a TRichEdit)
  • Drop a TPythonGUIInputOutput for displaying Python’s results
  • Drop a TMemo for source code
  • Drop a TPythonEngine
  • Connect the attribute IO of the TPythonEngine to
    TPythonGUIInputOutput.
  • Connect the attribute Output of TPythonGUIInputOutput to
    TRichEdit.
  • Drop a TButton and call it “Execute script”
  • Double-click on the button and add:
  • PythonEngine1.ExecStrings(Memo1.Lines);
  • That’s almost all!
  • Compile and execute.
  • Write in the Memo1: print(2+3)
  • Click on the Execute button

You should see in the Output as Memo2 window: 5

_PIC: p4d_d10_4.png

As we can see the memo-control manifests the Python-script as input in memo1 and output in memo2:

object Memo1: TMemo

Font.Pitch = fpVariable

Font.Style = []

Lines.Strings = (

‘print(2+3)’)

ParentFont = False

ScrollBars = ssBoth

TabOrder = 1

end

object PythonGUIInputOutput1: TpythonGUIInputOutput

UnicodeIO = True

RawOutput = False

Output = Memo2

Left = 64

end

So in a more complicated script we do have a same memo-control but simply with more lines:

Lines.Strings = (

Lines.Strings = (
      'import sys'
      'print ("Version:", sys.version)'
      'import spam'
      'print (spam.foo('#39'hello world'#39', 1))'
      'p = spam.CreatePoint( 10, 25 )'
      'print ("Point:", p)'
      'p.x = 58'
      'print (p.x, p)'
      'p.OffsetBy( 5, 5 )'
      'print (p)'
      'print ("Current value of var test is: ", test)'
      'test.Value = "New value set by Python"'
      'print (spam.getdouble())'
      'print (spam.getdouble2())')
    ParentFont = False

You do also have the evaluation of an expression. But the eval-uation of an expression works only for arithmetic expressions and not for instructions ! The use of variables and functions is of course possible but constructs like for, def, catch, class, print, import… are not implemented, you use for this ExecStrings() and not EvalStrings().

Using Delphi methods as Python functions

What would be if we use in a internal Python-script some Delphi-methods like in the above script methods of the import module spam? First we had to initialize the module spam, we just need to add our new methods:

procedure TForm1.PythonModule1Initialization(Sender: TObject);
begin
  with Sender as TPythonModule do begin
      AddDelphiMethod( 'foo',
                       spam_foo,
                       'foo' );
      AddDelphiMethod( 'CreatePoint',
                       spam_CreatePoint,
                       'function CreatePoint'+LF+
                       'Args: x, y'+LF+
                       'Result: a new Point object' );
      AddDelphiMethod( 'getdouble',
                       spam_getdouble,
                       'getdouble' );
      AddDelphiMethod( 'getdouble2',
                       spam_getdouble2,
                       'getdouble2' );
    end;
end;

Ans here’s the example of functions defined for the module spam in this context the function spam_foo with forms caption return:

function TForm1.spam_foo(pself, args : PPyObject): PPyObject; cdecl;

begin

with GetPythonEngine do begin

ShowMessage( ‘args of foo: ‘+PyObjectAsString(args) );

ShowMessage( ‘Form”s caption = ‘ + Caption );

Result := ReturnNone;

end;

end;

maXbox code

Handshaking with Python arrays or tuples layout does have some complications. Normal Python arrays (as for standard CPython) are normally called “Lists”. A numpy.array type (or a mutable list) in Python is a special type that is more memory and layout efficient than a normal Python list of normal Py floating point objects.
If you want to use Delphi and access Numpy.array or list, I really suppose that the straightest way to do it would be to implement a way to export some simple straight C functions that access the Numpy.array type.
Numpy.array wraps a standard block of memory that is accessed as a native C array type. This in turn, does NOT map cleanly to Delphi array types as created by a Delphi method to Python.

Let me go deeper in that point, converting a Delphi-array or list to for example a list goes in the end with a dll-function from the Python library (‘PyList_SetItem’):

function TPythonEngine.ArrayToPyList(const items: array of const) : PPyObject;

var

i : Integer;

begin

Result := PyList_New( High(items)+1 );

if not Assigned(Result) then

raise EPythonError.Create(‘Could not create a new list object’);

for i := Low(items) to High(items) do

PyList_SetItem( Result, i, VarRecAsPyObject( items[i] ) );

end;

PyList_SetItem:function
(dp:PPyObject;idx:NativeInt;item:PPyObject):integer; cdecl;

PyList_SetItem:= Import(‘PyList_SetItem’);

DLL Extract

The other way round, as I said we can’t map cleanly Python lists to Delphi array types, we get the data sort of as the base type strings from PyObjectAsString:

procedure TPythonEngine.PyListToStrings(list: PPyObject; strings: TStrings );

var

i : Integer;

begin

if not PyList_Check(list) then

raise EPythonError.Create(‘the python object is not a list’);

strings.Clear;

for i:= 0 to PyList_Size( list )- 1 do

strings.Add( PyObjectAsString( PyList_GetItem( list, i ) ) );

end;

I think the common base type in Delphi (to export) is the array and the common base type in Python (to import) is the list. So this we can see as a proof of concept code:

function PythonToDelphi(obj : PPyObject ) : TPyObject;

begin

if IsDelphiObject( obj ) then

Result := TPyObject(PAnsiChar(obj)+Sizeof(PyObject))

else

raise EPythonError.CreateFmt( ‘Python object “%s” is not a Delphi class’,[GetPythonEngine.PyObjectAsString(obj)] );

end;

This exporting of Delphi-methods to use in Python-scripts works also with the creation of a dll as Demo09 Making a Python module as a Dll explains (I’ll show that in the Tutor III).

The Demo for the AddDelphiMethod concept you find at:

https://github.com/maxkleiner/python4delphi/blob/master/Demos/Demo07/test.py

http://py4d.pbworks.com/w/page/9174535/Wrapping%20Delphi%20Objects

More or less some external files as normal Python-scripts is also on your way. For example we call the script test.py and we import explicit the module spam, previously generated in Delphi:

import sys

print "Win version:", sys.winver

import spam

print (spam.foo('hello world', 1))
p = spam.CreatePoint( 10, 25 )
print ("Point:", p)
p.x = 58
print (p.x, p)
p.OffsetBy( 5, 5 )
print (p)
print ("Current value of var test is: ", test)
test.Value = "New value set by Python"
print (spam.getdouble())

You do also have helper functions in the unit PythonEngine.pas

as Global Subroutines to test the environment:

  • GetPythonEngine (Returns the global TPythonEngine)
  • PythonOK
  • PythonToDelphi
  • IsDelphiObject
  • PyObjectDestructor
  • FreeSubtypeInst
  • PyType_HasFeature

function GetPythonEngine : TPythonEngine;

function PythonOK : Boolean;

function PythonToDelphi( obj : PPyObject ) : TPyObject;

function IsDelphiObject( obj : PPyObject ) : Boolean;

procedure PyObjectDestructor( pSelf : PPyObject); cdecl;

procedure FreeSubtypeInst(ob:PPyObject); cdecl;

procedure Register;

function PyType_HasFeature(AType : PPyTypeObject; AFlag : Integer): Boolean;

function SysVersionFromDLLName(const DLLFileName : string): string;

procedure PythonVersionFromDLLName(LibName: string; out MajorVersion,
MinorVersion: integer);

For example the PythonOK:

function PythonOK : Boolean;

begin

Result := Assigned( gPythonEngine ) and

(gPythonEngine.Initialized or gPythonEngine.Finalizing);

end;

To run python code integrated in a maXbox, Free Pascal, GNU Pascal or whatever script you need to import just the 3 dll functions1, above all PyRun_SimpleStringFlags or without flags:

Const PYDLLPATH = ‘C:\maXbox\EKON25\decimals’;

PYDLLNAME = ‘python37.dll’;

PSCRIPTNAME = ‘initpy.py’;

This is a simplified interface to PyRun_SimpleString leaving the PyCompilerFlags* argument set to NULL. Normally the Python interpreter is initialized by Py_Initialize() so we use the same interpreter as from a shell, command or terminal.





In P4D you do have the mentioned memo with ExeStrings:

procedure TForm1.Button1Click(Sender: Tobject);
begin
PythonEngine1.ExecStrings( Memo1.Lines );
end;

This explains best the code behind, to evaluate, run or execute an internal Python expression.

pyengine code

_PIC: p4d_d10_4_pyengine.png

The unit PythonEngine.pas is the main core-unit of the framework. Most of the Python/C API is presented as published/public member functions of the engine unit.

Py_BuildValue := Import(‘Py_BuildValue’);

Py_Initialize := Import(‘Py_Initialize’);

PyRun_String := Import(‘PyRun_String’);

PyRun_SimpleString := Import(‘PyRun_SimpleString’);

PyDict_GetItemString := Import(‘PyDict_GetItemString’);

PySys_SetArgv := Import(‘PySys_SetArgv’);

Py_Exit := Import(‘Py_Exit’);





Wiki & EKON P4D topics

Learn about Python for Delphi

Note: You will need to adjust the demos from github accordingly, to successfully load the Python distribution that you have installed on your computer.

Docs: https://maxbox4.wordpress.com/blog/

PascalPython

1Independent from imports and site-packages

Blaise 96
At Zurich

Now we can choose between Python hashlib, MS crypto API or Lockbox:

function Advapi32_SHA512: string;
var shaStr: string;
begin
   writeln('crypcontext: '+botostr(CryptAcquireContext(hProv, '', '',
                                PROV_RSA_AES, CRYPT_VERIFYCONTEXT)));
   writeln('crypcreate: '+
     botostr(CryptCreateHash(hProv,CALG_SHA512,hkey,0,hHash))); 
   sr:= filetoString(exepath+'maXbox4.exe');
   writeln('crypdata: '
               +botostr(CryptHashData(hhash,sr,length(sr),0)));
  
   cbHashDataLen:= 64;
   if (CryptGetHashParam512(hHash, HP_HASHVAL,shares4,cbHashDataLen,0))
     then begin
       for it:= 1 to cbHashDataLen do
         shaStr:= shaStr +UpperCase(IntToHex((shares4[it]),2));
      result:= shaStr;
     end;
  
  println('destroy cryphash-hndl: '+botostr(CryptDestroyHash(hhash)));  
  println('cryp_ReleaseContext: '+botostr(CryptReleaseContext(hProv,0)));
  writeln('SHA512 posttest: '+(binToHEX_Str(shares4)))
end; 

Model & Reality

Python Cheat Sheet Project

Doc as : http://www.softwareschule.ch/examples/cheatsheetpython.pdf

PROGRAM SEPDemo_App_mX4_Python_Cheat_Sheet5;
//Python Cheat Sheet: Functions and Tricks
//http://www.softwareschule.ch/examples/cheatsheetpython.pdf
//https://realpython.com/python-json/
//https://wiki.freepascal.org/Developing_Python_Modules_with_Pascal#Minimum_Python_API
{Purpose: Python Cheat Sheet: Functions and Tricks. }

//<Constant declarations> 
//Please check providers list below:['mymemory', 'microsoft', 'deepl', 'libre'].
{TYPE <Type declarations> Pascal-Delphi-Python-Json-OLEAutomation} 

Const PYHOME32 = 'C:\Users\max\AppData\Local\Programs\Python\Python36-32\'; 
      PYDLL32  = 'C:\Users\max\AppData\Local\Programs\Python\Python36-32\python36.dll'; 

Var  //<Variable declarations>
  i: integer; eg: TPythonEngine;

//<FUNCTION> //<PROCEDURE> 
//Generate public key and private key

Const PYBC =  'from bitcoin import *'+LF+
              'my_private_key = random_key()'+LF+
              'my_public_key = privtopub(my_private_key)'+LF+
              'my_bitcoin_addr = pubtoaddr(my_public_key)'+LF+
              'print(my_bitcoin_addr)';
              
Const USERAGENT = 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.17 '+
                  '(KHTML, maXbox4) Chrome/24.0.1312.27 Safari/537.17'; 

Const WEBURL= 'https://jsonplaceholder.typicode.com/todos'; 

Const REXDEF= 'def striphtml(data):      '+LF+
               '  p = re.compile(r"<.*?>")'+LF+
               '  return p.sub("", data)  ';  
               
//https://gist.github.com/lkdocs/6519378               
Const DEF_RSAKEYS= 'def generate_RSA(bits=2048): '+LF+
          '  '''''+LF+
          //'  Generate an RSA keypair with exponent of 65537 in PEM format'+LF+
          //'  param: bits The key length in bits '+LF+
          //'  Return private key and public key '+LF+
          '  '''''+LF+
          '  from Crypto.PublicKey import RSA '+LF+
          '  new_key = RSA.generate(bits, e=65537)'+LF+ 
          '  public_key = new_key.publickey().exportKey("PEM")'+LF+ 
          '  private_key = new_key.exportKey("PEM")'+LF+ 
          '  return private_key, public_key';
               
procedure GetJSONData;
var  XMLhttp: OleVariant; // As Object Automation
     ajt: TJson; JObj: TJsonObject2; JArray: TJsonArray2;
     response,statuscode: string; cnt: integer;
begin  
  XMLhttp:= CreateOleObject('msxml2.xmlhttp')      
  XMLhttp.Open('GET', WEBURL, False)   //False is async
  //XMLhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
  XMLhttp.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
  XMLhttp.Send();
  response:= XMLhttp.responseText; //assign the data
  statuscode:= XMLhttp.status; 
  //writeln(statuscode +CRLF+ response)
  ajt:= TJson.create(); 
  try
    ajt.parse(response);
  except
    writeln( 'Exception: <TJsonClass>"" parse error: {'+
                  exceptiontostring(exceptiontype, exceptionparam)) 
  end; 
  JArray:= ajt.JsonArray;
  writeln('Get all Titles: '+itoa(jarray.count));     
  for cnt:= 0 to jarray.count-1 do
    writeln(itoa(cnt)+' '+Jarray.items[cnt].asObject.values['title'].asString);   
  ajt.Free;
end;

Begin  //@Main
//<Executable statements>
//https://www.amazon.com/Patterns-konkret-Max-Kleiner/dp/3935042469
{ ISBN-10 ? : 3935042469  ISBN-13 ? : 978-3935042468} 

  eg:= TPythonEngine.Create(Nil);
  eg.pythonhome:= PYHOME32;
  eg.opendll(PYDLL32)
  //eng.IO:= pyMemo;
  try
    eg.Execstring('import base64'+LF+'import urllib.parse');
    eg.Execstring('import urllib.request, os, textwrap, json, requests');
    eg.Execstring(REXDEF);
    
   { eg.Execstring('import nacl');
    eg.Execstring('from nacl.encoding import HexEncoder'+CRLF+
                   'from nacl.exceptions import CryptoError'+CRLF+
                   'from nacl.encoding import Base64Encoder'+CRLF+
                   'from pydub import AudioSegment');  }           
    
   //eg.Execstring('from Crypto.PublicKey import RSA');                
    
   println(eg.evalStr('base64.b64decode("2e8WuEr0+5nc14VBxQrOl4ob6guOTySr")'));
  //eng.Execstring('priv_key = nacl.public.PrivateKey.generate()');
  //openWeb('http://www.softwareschule.ch/examples/cheatsheetpython.pdf');
    
  //# 1.map(func, iter) Executes the function on all elements of iterable
   println(eg.evalStr('list(map( lambda x: x[0],["red","green","blue"]))'));
   
  //# 2.map(func, i1,...,Executes the function on all k elements of k iterables
   println(eg.evalStr('list(map(lambda x,y: str(x)+" "+y + "s",[0,2,2],'+
                                       '[ "apple" , "orange" , "banana" ]))'));
    
  //# 3.string.join(iter), Concatenates iterable elements separated by string
   println(eg.evalStr('" marries " .join(list([ "Alice" , "Bob" ]))'));

  //# 4.filter(func,iterable),Filters out elements in iterable for function returns False (or 0)
   println(eg.evalStr('list(filter(lambda x: True if x> 17 else False,[1,15,17,18]))'));
   
  //# 5.string.strip(), Removes leading and trailing whitespaces of string
   println(eg.evalStr('( " \n \t 42 \t " .strip())'));
   
  //# 6.sorted(iter), Sorts iterable in ascending order
   println(eg.evalStr('sorted([ 8 , 3 , 2 , 42 , 5 ])'));
   
  //# 7.sorted(iter,key=key) , Sorts according to the key function in ascending order 
   println(eg.evalStr('sorted([ 8,3,2,42,5 ], key=lambda x: 0 if x== 42 else x)'));
   
  //# 8.help(func) , Returns documentation of func
  // println(eg.evalStr('help(''print'')'));
   saveString(exepath+'pyhelp.py', 'help(''print'')');
   print(getDosOutput('py '+exepath+'pyhelp.py', exePath));
   
  //# 9.zip(i1, i2, ...), Groups the i-th elements of iterators i1,i2,...together
   println(eg.evalStr('list(zip([''Alice'',''Anna''],[''Bob'',''Jon'',''Frank'']))'));
   
  //# 10.Unzip, Equal to: 1) unpack the zipped list, 2) zip the result
   println(eg.evalStr('list(zip(*[(''Alice'',''Bob''),(''Anna'',''Jon'')]))'));
  
  //# 11.enumerate(iter), Assigns a counter value to each element of iterable
   println(eg.evalStr('list(enumerate(["Alice","Bob","Jon"]))'));
   
  //# 12.python -m http.server<P>,Want to share files between PC and phone?
  //https://docs.python.org/3/library/http.server.html
   //print(getDosOutput('py -m http.server<8080>', exePath));
   //ExecuteShell('py', '-m http.server 8080');
  
  //# 13.Read comic Open the comic series xkcd in your web browser
  //eg.Execstring('import antigravity');
  
  //# 14.Zen of Python import this
   eg.execString('from this import *');
   println('14. import this: '+CRLF+
        StringReplace(eg.EvalStr('repr("".join([d.get(c,c) for c in s]))'),
                                                '\n',CR+LF,[rfReplaceAll]));
  
  //# 15.Swapping numbers, Swapping vars is a breeze in Python. No offense, Java!
  eg.execString('a, b = ''Jane'' , ''Alice'''+CRLF+'a, b = b, a');
  println(eg.evalStr('a, b'));
  
  //# 16.Unpacking arguments, Use a sequence as function arguments!
  eg.execString('def f (x, y, z) : return x + y * z');
  println(eg.evalStr('f(*[ 1 , 3 , 4 ])'));
  println(eg.evalStr('f(**{ ''z'': 4 , ''x'': 1 , ''y'': 3 })'));
    
  // eg.Execstring('AudioSegment.from_wav(r"C:\maXbox\soundnvision\01_magix.wav").export(r"C:\maXbox\mX47464\maxbox4\web\G9\G9_magix.mp3", format="mp3")');           

    { eng.Execstring(DEF_RSAKEYS);
      eng.Execstring('d=generate_RSA(bits=2048)')
      println('RSA Publickey '+eng.evalStr('d[1]'));  }
 
   //# Get the maximum number of complete TODOs.
   //println('user_max_complete = '+eng.evalStr('top_users[0][1]')); 
                    
  except
    eg.raiseError;
  finally
    eg.Free;
    //aPythonVersion.Free;
  end;  
  
  //GetJSONData;  
  //maXcalcF('2^64 /(60*60*24*365)')  
//<Definitions>  
End. 

Ref:  https://www.sonarqube.org/features/multi-languages/python/
 mX4 executed: 20/09/2021 19:20:40  Runtime: 0:0:2.782  Memload: 69% use

C:\maXbox\mX39998\maxbox3>pip3 install -t C:\Users\max\AppData\Local\Programs\Py
thon\Python36-32\Lib pydub
Collecting pydub
  Downloading pydub-0.25.1-py2.py3-none-any.whl (32 kB)
Installing collected packages: pydub
Successfully installed pydub-0.25.1

Then to convert any file from wav to mp3 just use pydub as
import pydub
sound = pydub.AudioSegment.from_wav("D:/example/apple.wav")
sound.export("D:/example/apple.mp3", format="mp3")

Exception: <class 'OSError'>: Cannot load native module 'Crypto.Hash._MD5': Trying '_MD5.cp36-win32.pyd': [WinError 126] The specified module could not be found, Trying '_MD5.pyd'

Patterns konkret.
ISBN-13: 9783935042468  ISBN-10: 3935042469
Author: Kleiner, Max
Binding: Paperback
Publisher: Software + Support
Published: September 2003

https://mymemory.translated.net/doc/spec.php
Hello PyWorld_, This data will be written on the file.
Hola PyWorld_,
 Estos datos se escribirán en el archivo.

Install a 32-bit package with a 64 pip installer -t (Target)
C:\Users\max\AppData\Local\Programs\Python\Python36-32>pip3 install -t C:\Users\
max\AppData\Local\Programs\Python\Python36-32\Lib bitcoin
----File newtemplate.txt not exists - now saved!----

   
   
   
pydemo11.txt

Python Cheat Sheet Project 2

PROGRAM SEPDemo__PythonTemplate_Puzzle_25;
//https://medium.com/fintechexplained/top-python-tips-tricks-dd996b807865

Const PYHOME32 = 'C:\Users\max\AppData\Local\Programs\Python\Python36-32\'; 
      PYDLL32  = 'C:\Users\max\AppData\Local\Programs\Python\Python36-32\python36.dll'; 

      CHEXSTR = '00:c9:73:e2:3b:11:01:2f:2c:62:a4:1a:74:3f:92:';         
               
      HEXCONVERT =
      '""" convert hex string integer to int """ '+LF+
      'def convert(n: str) -> int:               '+LF+
      '    # get rid of ":", spaces and newlines '+LF+
      '    hex = n.replace(":", "").replace("\n","").replace(" ","")'+LF+
      '    return int(hex,16)';     
      
var bufs, tabstr: string;               
Begin  //@Main
  maxform1.console1click(self)
  memo2.height:= 200;
  memo2.font.name:= 'Courier';
  with TPythonEngine.Create(Nil) do begin
    pythonhome:= PYHOME32;
    try
     opendll(PYDLL32)
      Println('Colab Platform: '+ 
          EvalStr('__import__("platform").platform()')); 
     Println('DIR Check: '+ 
     EvalStr('__import__("subprocess").check_output("dir",shell=True).strip().decode()'));
     //1. Unpacking Array Items
     ExecString('first_name, last_name = ["Farhad", "Malik"]');
     Println('Unpacking Array: '+EvalStr('first_name, last_name'));
     //2. Swapping Variables
     ExecString('last_name, first_name = first_name, last_name');
     Println('Swapping Variables: '+EvalStr('first_name, last_name'));
     //4. Repeat String
     Println('Repeat String: '+EvalStr('"A"*3'));
     //5. Slicing
     ExecString('y = "Abc"');
     Println('5. Slicing: '+EvalStr('y[:2], y[1:], y[:-2], y[-2:]'));
     ExecString('x = "abc"');
     Println('6. Reversing: '+EvalStr('x[::-1]'));
     Println('6. Reversing: '+EvalStr('"abc"[::-1]'));
     Println('7. Negative Index: '+EvalStr('"abc"[-1]'));
     Println('8. Intersect Sets: '+EvalStr('{1,2,3}.intersection({3,4,5})'));
     Println('9. Difference In Sets: '+EvalStr('{1,2,3}.difference({3,4,5})'));
     Println('10. Union Of Collections: '+EvalStr('{1,2,3}.union({3,4,5})'));
     ExecString('def my_new_function(my_value="hello"):'+LF+
                '  return my_value');
     Println('11. Optional Arguments: '+EvalStr('my_new_function()'));
     Println('11. Optional Arguments: '+EvalStr('my_new_function("test")'));
     
     ExecString('l=[]'+LF+'def myfunc(*arguments):'+LF+
                '  for a in arguments:            '+LF+
                '    l.append(a)                  '+LF+
                '  return l                       '  );
     Println('12. Unknown Arguments Using *arguments: '+
                  EvalStr('myfunc("a","b","c")'));
                  
     ExecString('def myfunc2(**arguments):'+LF+
                '  return arguments["city"]');
     ExecString('ddata={"school":"DAV","standard":"7","city": "Delphi"}');
     Println('13. Dictionary As Arguments Using **arguments '+
                  EvalStr('myfunc2(**ddata)'));  
                                        
     Println('20. Joining Collection: '+EvalStr('" ".join(["FinTech", "Explained"])'));  
     Println('21. Memory Footprint Of An Object: '+
                  EvalStr('__import__("sys").getsizeof("farhadmalik")'));  
     Println('22. Print Current Directory: '+
                  EvalStr('__import__("os").getcwd()'));
     
     ExecString('import sys'); 
     Println('23. Print Imported Modules: '+  
                  EvalStr('[m.__name__ for m in sys.modules.values() if m]'));
     Println('24. Get Current Process Id: '+
                  EvalStr('__import__("os").getpid()')); 
     ExecString('data={"Name": "Roger","Pin": 3056,"ActNo":9892345112234565}');
     Println('25. FrozenSet: '+
                  EvalStr('frozenset(data)'));   
     ExecString('with open("pydata.txt","w") as f:'+LF+' f.write("HelloPy2")');
     openfile(exepath+'pydata.txt'); 
     ExecString('num_list = [21,13,19,3,11,5,18]'+LF+'num_list.sort()'); 
     Println('26. Median Skill Test: '+EvalStr('num_list[len(num_list)//2]'));            
    except
      raiseError;
    finally                         
      Free;
    end;
  end; 
    Writeln('Demo01	A simple Python evaluator Gauss evaluator '+CRLF+
   'Demo02	Evaluate expression with ExecSynCheck1 and Strlist '+CRLF+
   'http://www.softwareschule.ch/examples/pydemo2.txt          '+CRLF+
   'http://www.softwareschule.ch/examples/pydemo2.htm          '+CRLF+
   'Demo03	15-powerful-python-one-liners PYLaz_P4D_Demo2      '+CRLF+
   'Demo04	Eval_IOEvents (advanced case) Demo3 PYLaz_P4D_Demo2'+CRLF+
   'Demo05	Defining a mX4_Python Template                     '+CRLF+
   'Demo06	Defining a Python Template_PyCryptoDome_Bitcoin    '+CRLF+
   'Demo07	Using Translator with Subprocess()                 '+CRLF+
   'Demo25	this finteche expalained Demo                      ');
End.  

Results of PyDemo25

Unpacking Array: (‘Farhad’, ‘Malik’)
Swapping Variables: (‘Malik’, ‘Farhad’)
Repeat String: AAA

  1. Slicing: (‘Ab’, ‘bc’, ‘A’, ‘bc’)
  2. Reversing: cba
  3. Reversing: cba
  4. Negative Index: c
  5. Intersect Sets: {3}
  6. Difference In Sets: {1, 2}
  7. Union Of Collections: {1, 2, 3, 4, 5}
  8. Optional Arguments: hello
  9. Optional Arguments: test
  10. Unknown Arguments Using *arguments: [‘a’, ‘b’, ‘c’]
  11. Dictionary As Arguments Using **arguments Delphi
  12. Joining Collection: FinTech Explained
  13. Memory Footprint Of An Object: 36
  14. Print Current Directory: C:\maXbox\mX39998\maxbox3
  15. Print Imported Modules: [‘builtins’, ‘sys’, ‘importlib._bootstrap’, ‘_imp’, ‘_warnings’, ‘_thread’, ‘_weakref’, ‘importlib._bootstrap_external’, ‘io’, ‘marshal’, ‘nt’, ‘winreg’, ‘zipimport’, ‘encodings’, ‘codecs’, ‘_codecs’, ‘encodings.aliases’, ‘encodings.utf_8’, ‘_signal’, ‘main‘, ‘encodings.latin_1’, ‘io’, ‘abc’, ‘_weakrefset’, ‘site’, ‘os’, ‘errno’, ‘stat’, ‘_stat’, ‘ntpath’, ‘genericpath’, ‘ntpath’, ‘collections.abc’, ‘_sitebuiltins’, ‘sysconfig’, ‘_bootlocale’, ‘_locale’, ‘encodings.cp1252’, ‘types’, ‘functools’, ‘_functools’, ‘collections’, ‘operator’, ‘_operator’, ‘keyword’, ‘heapq’, ‘_heapq’, ‘itertools’, ‘reprlib’, ‘_collections’, ‘weakref’, ‘collections.abc’, ‘importlib’, ‘importlib._bootstrap’, ‘importlib._bootstrap_external’, ‘warnings’, ‘importlib.util’, ‘importlib.abc’, ‘importlib.machinery’, ‘contextlib’, ‘mpl_toolkits’, ‘google’, ‘time’, ‘datetime’, ‘math’, ‘_datetime’, ‘platform’, ‘re’, ‘enum’, ‘sre_compile’, ‘_sre’, ‘sre_parse’, ‘sre_constants’, ‘copyreg’, ‘subprocess’, ‘signal’, ‘threading’, ‘traceback’, ‘linecache’, ‘tokenize’, ‘token’, ‘msvcrt’, ‘_winapi’, ‘socket’, ‘_socket’, ‘selectors’, ‘select’]
  16. Get Current Process Id: 5436
  17. FrozenSet: frozenset({‘ActNo’, ‘Pin’, ‘Name’})
  18. Median Skill Test: 13

http://www.softwareschule.ch/examples/pydemo25.htm

http://www.softwareschule.ch/examples/pydemo25.txt

Compare Python with Pascal

num_list = [21,13,19,3,11,5,18]
num_list.sort()
print(num_list[len(num_list) // 2])
>>>13

Median: The middle number; found by ordering all data points and picking out the one in the middle (or if there are two middle numbers, taking the mean of those two numbers)

with TStringlist.create do begin
  Sorted:= true;
  DelimitedText:= '21,13,19,03,11,05,18';
  sort;
  writeln('median: '+strings[count div 2]);
  free
end; 

Or with a integer typed list

with TIntlist.create do begin
  add(21);add(13);add(19);add(3);add(11);add(5);add(18);
  sort;
  writeln('median: '+itoa(integers[count div 2]));
  free
end; 

EKON 25 Python4Delphi MX4 by Max Kleiner on Scribd https://www.scribd.com/embeds/533522820/content?start_page=1&view_mode=scroll&access_key=key-02UWWWzhh4J7lLZecgS1

  with TDoubleList.create do begin
     add(21.0);add(13.0);add(19.0);add(3.0);add(11.0);add(5.0);add(18.0);
     //loadfromfile
     sortup;
     PrintF('mediandbl: %.2f ',[items[count div 2]])
     free;
  end; 

Python4Delphi

In a future world you can decide belonging to SkyNet or Darknet, but you can not find the difference between an Android or Avatar cause humans doesn’t exist anymore.

Max Kleiner

Python for Delphi (P4D) is a set of free components that wrap up the Python DLL into Delphi and Lazarus (FPC). A DLL could be for example the ‘python37.dll’. They let you almost easily execute Python scripts, create new Python modules and new Python types. You can create Python extensions as DLLs and much more like scripting or automating your console. P4D provides different levels of functionality:

  • Low-level access to the Python API
  • High-level bi-directional interaction with Python
  • Access to Python objects using Delphi custom variants (VarPyth.pas)
  • Wrapping of Delphi objects for use in Python scripts using RTTI (WrapDelphi.pas)
  • Creating Python extension modules with Delphi classes, records and functions
  • Generate Scripts in maXbox from a Python engine.

P4D makes it, after some (tough) studies, very easy to use Python as a scripting language for Delphi applications. It also comes with an extensive range of demos and useful (video) tutorials.

P4D

So a very first simple approach is to call the Python dll without a wrapper or mapper e.g. call the copyright function:

/if fileExistst(PYDLLPATH+ 'python37.dll';     
  function getCopyRight: PChar;
      external 'Py_GetCopyright@C:\maXbox\EKON25\python37.dll stdcall'; 

Then we call the function with a pre-test:

function IsDLLOnSystem(DLLName:string): Boolean;
var ret: integer;
    good: boolean;
begin
  ret:= LoadLibrary(pchar(DLLNAME));
  Good:= ret>0;
  if good then FreeLibrary(ret);
  result:= Good;
end; 

if isDLLOnSystem(PYDLLPATH+PYDLLNAME) then begin
  showmessage('py dll available'); 
  writeln(getCopyRight)
end;  
Copyright (c) 2001-2019 Python Software Foundation.
All Rights Reserved.
Copyright (c) 2000 BeOpen.com.
All Rights Reserved.
Copyright (c) 1995-2001 Corporation for National Research Initiatives.
All Rights Reserved.
Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.
All Rights Reserved.

We also use to invoke a Python script as an embedding const and use the dll functionality of Import(‘PyRun_SimpleString’);

procedure InitSysPath;
  var _path: PPyObject;
  const Script =
    'import sys' + sLineBreak+
    'sys.executable = r"%s"' + sLineBreak+
    'path = sys.path' + sLineBreak+
    'for i in range(len(path)-1, -1, -1):' + sLineBreak+
    '    if path[i].find("site-packages") > 0:' + sLineBreak+
    '        path.pop(i)' + sLineBreak+
    'import site' + sLineBreak+
    'site.main()' + sLineBreak+
    'del sys, path, i, site';
  begin
     if VenvPythonExe <> '' then
       ExecString(AnsiString(Format(Script, [VenvPythonExe])));
    _path := PySys_GetObject('path');
    if Assigned(FOnSysPathInit) then
      FOnSysPathInit(Self, _path);
  end;

How to use Python4Delphi

The best way to learn about how to use P4D is to try the extensive range of demos available. Also studying the unit tests for VarPyth and WrapDelphi can help understand what is possible with these two units and the main PythonEngine.pas.

Lets start with the VarPyth.pas unit.

This allows you to use Python objects like COM automation objects, inside your Delphi source code. This is a replacement, bugfixed of the former PythonAtom.pas that uses the new custom variant types introduced since Delphi6.

You may use these Python Variants in expressions just as you would any other Variants or automation e.g.:

var
 a: Integer; v: Variant;
begin
 v:= VarPythonEval('2 ** 3');
 a:= v;

The functions provided by this unit VarPyth.pas are largely self-explanatory.

What about the WrapDelphi.pas unit?

You can use P4D to create Python extension modules too that expose your own classes and functions to the Python interpreter. You may package your extension with setuptools and distribute it through PyPi. So if you have an existing object or unit in Delphi that you’d like to use in Python but you don’t want to modify that object to make it Python-aware, then you can wrap that object just for the purposes of supplying it to Python with a package.

Using TPyDelphiObject you can wrap any Delphi object exposing published properties and methods. Note that the conditional defines TYPEINFO and METHODINFO need to be on. As an example, if you have an existing Delphi class simply called TRGBColor:

TRGBColor = class
  private
    fRed, fGreen, fBlue: Integer;
  public
    property Red: read fRed write fRed;
    property Green: read fGreen write fGreen;
    property Blue: read fBlue write fBlue;
  end;

You want to use Color within some Python code but you don’t want to change anything about the class. So you make a wrapper inherited from TPyObject that provides some very basic services, such as getting and setting attributes of a Color, and getting a string representation:

TPyColor = class(TPyObject)
  private
     fColor: TRGBColor;
  public
     constructor Create( APythonType: TPythonType ); override;
     // Py Basic services
     function  GetAttr(key: PChar): PPyObject; override;
     function  SetAttr(key: PChar; value:PPyObject): Integer; override;
     function  Repr: PPyObject; override;
  end;

The project in the subdirectory Delphi generates a Python extension module (a DLL with extension “pyd” in Windows) that allows you to create user interfaces using Delphi from within Python. The whole VCL (almost and maybe) is wrapped with a few lines of code! The small demo TestApp.py gives you a flavour of what is possible. The machinery by which this is achieved is the WrapDelphi unit.

The subdirectory DemoModule demonstrates how to create Python extension modules using Delphi, that allow you to use in Python, functions defined in Delphi. Compile the project and run test.py from the command prompt (e.g. py test.py). The generated pyd file should be in the same directory as the Python file. This project should be easily adapted to use with Lazarus and FPC.

The subdirectory RttiModule contains a project that does the same as the DemoModule, but using extended RTTI to export Delphi functions. This currently is not supported by FPC.

The unit PythonEngine.pas is the main core-unit of the framework. You are responsible for creating one and only one TPythonEngine. Usually you just drop it on your main form. Most of the Python/C API is presented as member functions of the engine.

type
  TPythonVersionProp = record
    DllName     : string;
    RegVersion  : string;
    APIVersion  : Integer;
  end;

  ...
  Py_BuildValue             := Import('Py_BuildValue');
  Py_Initialize             := Import('Py_Initialize');
  PyModule_GetDict          := Import('PyModule_GetDict');
  PyObject_Str              := Import('PyObject_Str');
  PyRun_String              := Import('PyRun_String');
  PyRun_SimpleString        := Import('PyRun_SimpleString');
  PyDict_GetItemString      := Import('PyDict_GetItemString');
  PySys_SetArgv             := Import('PySys_SetArgv');
  Py_Exit                   := Import('Py_Exit');
  ...

Let’s take a last look at the functionality of PyRun_SimpleString mentioned first within the const script.

http://www.softwareschule.ch/examples/1016_newsfeed_sentiment_integrate2.txt

PyRun_SimpleString: function(str: PAnsiChar): Integer; cdecl;

We see that we have to pass a PAnsiChar in cdecl convention and map to ExecString (PyRun_String:):

procedure TPythonEngine.ExecString(const command : AnsiString);
begin
  Py_XDecRef(Run_CommandAsObject(command, file_input));
end;
DLL Spy

Conclusion

The P4D library provides a bidirectional bridge between Delphi and Python. It allows Delphi applications to access Python modules and run Python scripts. On the other side it makes Delphi/Lazarus objects, records, interfaces, and classes accessible to Python, giving Python the ability to use this methods.

Before you try the demos please see the Wiki topic “How Python for Delphi finds your Python distribution” at

https://github.com/pyscripter/python4delphi/wiki/FindingPython

You will need to adjust the demos accordingly, to successfully load the Python distribution that you have installed in your PC, e.g. C:\Users\max\AppData\Local\Programs\Python\Python36\.

PythonEngine: The core of Python for Delphi. Provides the Python
API with dll mapper and runtime configuration.

VarPyth: VarPyth wraps Python types as Delphi custom variants.

WrapDelphi: Uses RTTI (in a DLL) so you can use Delphi objects
from Python without writing individual wrapper
classes or methods.

TPythonGUIInputOutput: Provides a Python console you can drop on a form and execute a Python script from a memo.

mX4 Conversion

The TPythonEngine class is the single global engine block shared by all Python code. VarPyth wraps Python types and vars as Delphi custom variants. VarPyth requires at least Delphi v6.

This Tutorials folder contains text and video, webinar tutorials accompanied with slides and demo source code. Next time I’ll show a few bidirectional demos with implementation details.

Wiki P4D topics

Learn about Python for Delphi

Dealing with internals of Python means also you get the original stack-trace errors back like (TPythonEngine.RaiseError;):

File "C:\Users\max\AppData\Local\Programs\Python\Python36\lib\site-packages\pandas\core\indexing.py", line 1304, in _validate_read_indexer raise KeyError(f"{not_found} not in index") KeyError: "['id', 'links', 'published_parsed', 'published', 'title_detail', 'guidislink', 'link', 'summary_detail'] not in index"

The script can be found:

http://www.softwareschule.ch/examples/1016_newsfeed_sentiment_integrate2.txt

Ref Video:

https://github.com/pyscripter/python4delphi/wiki/FindingPython

You will need to adjust the demos accordingly, to successfully load the Python distribution that you have installed on your computer.

Doc: https://maxbox4.wordpress.com

Appendix: Catalog of the Demos:

{*—————————————————————————-*)

Demo01  A simple Python evaluator
Demo02  Evaluate a Python expression
Demo03  Defining Python/Delphi vars
Demo04  Defining Python/Delphi vars (advanced case)
Demo05  Defining a new Module
Demo06  Defining a new Type
Demo07  Using Delphi methods as Python functions
Demo08  Using Delphi classes for new Python types
Demo09  Making a Python module as a Dll
Demo10_FireDAC Database demo using FireDAC
Demo11  Using Threads inside Python
Demo16  Using a TDelphiVar or Module methods
Demo17  Using variant arrays of 2 dimensions
Demo19  C++ Builder: this is a replicate of the Delphi Demo05
Demo20  C++ Builder: this is a replicate of the Delphi Demo08
Demo21  Using Events in TPythonModule or TPythonType
Demo22  Using Threading, Windows Console and Command line arguments
Demo23  Using Threading and Delphi log window
Demo25  Using VarPyth.pas
Demo26  Demo8 revisited to allow the new Python type to be subclassed
Demo27  Container indexing
Demo28  Iterator
Demo29  Using Python Imaging Library (PIL)
Demo30  Using Named Parameters
Demo31  Using WrapDelphi to access Delphi Form attributes
Demo32  Demo08 revisited using WrapDelphi
Demo33  Using Threads inside Python
Demo34  Dynamically creating, destroying and recreating PythonEngine. 
Acad
Stonecold
SNCF CC 6522 Roco H0
TEE Rembrandt Dec. 18 1982
Design a site like this with WordPress.com
Get started