Multi-code programming refers to the practice of integrating multiple programming languages, paradigms, or models within a single system or application. This approach is particularly useful in scenarios where different languages or tools excel at specific tasks, allowing developers to leverage their strengths for optimal performance and flexibility.
Also Modern CLIs do more than run multi-commands. They:
– Save time with automation
– Integrate with cloud and AI tools
– Keep your focus in one window
– Work the same across Linux, macOS, and Windows
So CLI Tools still matter and I want to show that with one problem from rosettacode and the corresponding 5 solutions:
The advantages of multi-code (or multi-core) are:
Optimized Performance: Each language or tool is used where it performs best.
Flexibility: Adapts to diverse project requirements.
We combine languages like Python, Pascal, Delphi, Free Pascal and Javascript with the following problem: “Split a (character) string into comma (plus a blank) delimited strings based on a change of character (left to right)”. Blanks should be treated as any other character (except they are problematic to display clearly). The same applies to commas. For instance, the string: gHHH5YY++///\ should be split and show: g, HHH, 5, YY, ++, ///, \
We start with the Pascal solution:
function SplitAtChars(const S: String):String;
var i : integer; lastChar:Char;
begin
result:= '';
IF length(s) > 0 then begin
LastChar:= s[1];
result:= LastChar;
For i:= 2 to length(s) do begin
if s[i] <> lastChar then begin
lastChar:= s[i];
result:= result+ ', ';
end;
result:= result+ LastChar;
end;
end;
end;
The second, the Delphi one has a form to conigure the output:
const S1 = 'gHHH5YY++///\';
procedure ShowSplitString(Memo: TMemo);
var S2: string;
begin
Memo.Lines.Add(S1);
S2:= SplitStringCharChange(S1);
Memo.Lines.Add(S2);
end;
It works with: Delphi version 6.0 and needs the Library SysUtils and StdCtrls, in maXbox there are precompiled on board.
The third one is Free Pascal and runs on the internet with the help of TIO: The web server of and the arenas (where user code is executed) are currently run on three separate servers. TIO is getting more and more traffic, so additional arenas will be required. Also, server-side permalinks will eventually require a separate storage. With your help, I hope to ensure a smooth operation of all TIO services.
TIO is powered by Digital Ocean .
The next is Java Script and will also run in a browser but a local based one. With WebView2 in Microsoft Edge, developers can now embed web content directly within native Windows applications. WebView2 offers a simple way to display web-based content using the Chromium engine inside your apps or scripts. Specifically, WebView2 can run HTML, CSS, and JavaScript inside a standard non-web program, like something written in Visual C++, Delphi or .NET apps.
Support for Edge WebView2 on Windows 7, 8, Server 2012 and 2012R2, ended at Edge WebView2 version 107 in October of 2022 because those operating systems are no longer supported.
procedure JS_Solution;
begin
with TEdgeViewForm.create(self) do begin
width:= 1500;
pagecontrol1.height:= 540;
icon.loadfromresourcename(hinstance,'XJICON');
Caption:= 'maXbox5 EdgeView2BrowserFeed_JScriptSolution' ;
panel1.ParentBackground:= false;
panel1.color:= clnavy;
sleep(500);
navigate('https://maxbox4.wordpress.com/2025/07/01/ekon-29/');
memoJavaScript.text:= JSCRIPT;//JS_InitFunc;
PageControl1.ActivePageIndex := 1;
memoHTML.font.size:= 26;
memoJavaScript.wordwrap:= true;
memoJavaScript.lines.linebreak:= lf;
tabsheet3.caption:= 'Result';
panel3.caption:= 'Source: Result';
sleep(300)
ExecuteScript(JSCRIPT);
sleep(1600);
writeln('result of js webview2: '+memoHTML.text);
writeln('scriptresult of js webview2: '+getScriptresult);
showmodal; //save resources
free;
end;
end;
pic: with TEdgeViewForm.create(self) dobegin
const JSFunc ='function stripchars(string, chars) { '+lf+
' return string.replace(RegExp("["+chars+"]","g"), ""); }'+lf+
'stripchars("She was a soul stripper. She took my heart!","aei")';
procedure JS_Solution;
begin
with TEdgeViewForm.create(self) do begin
sleep(500)
ExecuteScript(JSFunc);
sleep(400)
//)ExecuteScript('23*4');
//memoJavaScript.text:= '23*4';
//ExecuteScript('stripchars("She was a soul stripper. She took my heart!","aei"');
sleep(2200);
//writeln('result of js webview2: '+memoHTML.text);
writeln('scriptresult jswebview2: '+getScriptresult);
//showmodal; //save resources
free;
end;
end;
The different sleep() is a bit tricky cause you need them to control the async return, otherwise you cant catch the result at the time you expect it. It took some time to execute the script and a wait state is missing. The destination folder can contain the script, or in the script itself as a const or you can invoke scripts as an URL from a server with:
The above is the basic usage of the WebView2 handling. You can customize the parameters and error handling based on specific needs. There’s a tutorial about the topic: Tutorial 129 Using WebView2, October 2024. The last solution is the Python one procedure:
Const PYFUNC =
'def splitter(text): '+lf+
' return ", ".join("".join(group) for key, group in groupby(text)) ';
procedure PY_Charsplit_Solution;
begin
with TPythonEngine.Create(Nil) do begin
autofinalize:= false;
loadDLL;
try
ExecString('import sys; from itertools import groupby');
ExecString(PYFUNC);
addclient(TEngineClient.create(nil));
execstr('txt = ''gHHH5YY++///\\''
# Note backslash is Python escape char.');
println(evalstr('f''Input: {txt}\n Split: {splitter(txt)}'''));
println(evalstr('sys.version'));
except
raiseError;
finally
unloadDll;
Free;
end;
end;
end;
Conclusion
Multi-code programming is a powerful approach for modern software development, especially in domains requiring high efficiency and adaptability.
Put simply Microsoft EdgeWebView2 is a stripped down version of the Microsoft Edge browser- based on Google Chrome that developers can use to run web code inside of applications you are using. By leveraging the web platform inside desktop scripts, developers can create rich user experiences, improve performance, and utilize modern web capabilities.
The challenges are:
Complexity: Managing multiple languages can increase development and debugging effort.
Interoperability Issues: Ensuring smooth communication between components.
Learning Curve: Requires expertise in multiple programming paradigms.
Facilitates communication between different languages or frameworks, often through APIs, shared memory, or intermediate representations.
The Jaro distance is a measure of edit distance between two strings; its inverse, called the Jaro similarity, is a measure of two strings’ similarity: the higher the value, the more similar the strings are. The score is normalized such that 0 equates to no similarities and 1 is an exact match.
//converted from C source by /u/bleuge
function ssJaroWinkler(s1, s2: string): double;
var
l1, l2, match_distance, matches, i, k, trans: integer;
bs1, bs2: array[1..255] of boolean; //used to avoid getmem, max string length is 255
begin
l1:= length(s1);
l2:= length(s2);
//fillchar(bs1, sizeof(bs1), 0); //set booleans to false
for it:= 1 to sizeof(bs1) do bs1[it]:= false;
//fillchar(bs2, sizeof(bs2), 0);
for it:= 1 to sizeof(bs2) do bs2[it]:= false;
if l1 = 0 then
if l2 = 0 then begin
result:= 1
exit;
end else begin
result:= 1
exit; end;
match_distance:= (max(l1, l2) div 2) - 1;
matches:= 0;
trans:= 0;
for i:= 1 to l1 do begin
for k:= max(1, i - match_distance) to min(i + match_distance, l2) do
begin
if bs2[k] then
continue;
if s1[i] <> s2[k] then
continue;
bs1[i]:= true;
bs2[k]:= true;
inc(matches);
break;
end;
end;
if matches = 0 then begin
result:= 0;
exit end;
k:= 1;
for i:= 1 to l1 do begin
if (bs1[i] = false) then
continue;
while (bs2[k] = false) do
inc(k);
if s1[i] <> s2[k] then
inc(trans);
inc(k);
end;
trans:= trans div 2;
result:= ((matches / l1)+(matches / l2)+((matches - trans)/matches)) / 3;
end;
Cet ouvrage offre aux passionnés de chemin de fer plus de 500 compositions détaillées des trains Trans Europ Express et assimilés, de 1929 à 2004, couvrant trois quarts de siècle d’histoire ferroviaire européenne, des express aux TGV et ICE. Ouvrage en français et en anglais.
Dieses Buch sammelt nicht nur die Formationen der 66 TEE-Züge, die von 1957 bis 1995 zirkulieren, sondern auch mögliche Züge mit dem gleichen Namen, ob vor 1957 oder nach 1995. So konnte man neben dem Express und Fasten die deutsche Fernschnellz-ge, die Intercity, dann die EuroCity und schließlich TGV und ICE finden. So haben Modellbauern und andere Eisenbahnfreunde mehr als 500 verschiedene Formationen dieser berühmten Züge zur Verfügung, die sich von Epoche II (1929 für die älteste) bis zur Epoche V (2004 für die letzte) erstrecken, ein Überblick über ein dreiviertel Jahrhundert Eisenbahngeschichte.
Impressum – p.3 Préface – p.4 Foreword – p.5
1 – LES TEE INTERNATIONAUX / INTERNATIONAL TEE TRAINS – p.6-7 1.1 France – Belgique : TEE Memling, Watteau (I), Oiseau Bleu, TEE 112, 123, 130, Brabant, Rubens – p.8-15 1.2 France – Belgique – Pays-Bas : TEE Étoile du Nord, Ile de France (I) – p.16-21 1.3 France – Belgique – Allemagne : TEE Paris Ruhr, Molière, Parsifal – p.22-27 1.4 Allemagne – Belgique : TEE Saphir – p.30-31, TEE Diamant (I) – p.32-33, TEE Albert Schweitzer – p.34-35, TEE Goethe (I) – p.36-37 1.5 France – Allemagne – p.34 1.6 Pays-Bas – Belgique – Luxembourg – France – Suisse : TEE Edelweiss – p.38-39 1.7 Belgique – Luxembourg – France – Suisse : TEE Iris – p.40-41 1.8 France – Suisse : TEE Arbalète – p.44-45 1.9 Allemagne – Suisse : TEE Helvetia – p.48-49 1.10 Allemagne – Suisse – Italie : TEE Roland (I), Mont Cenis, Ligure – p.52-59 1.11 France – Italie : TEE Cisalpin – p.60-61 1.12 France – Suisse – Italie – p.60 1.13 Suisse – France – Espagne : TEE Catalan Talgo – p.64-65 1.14 Suisse – Italie : TEE Gottardo, Ticino, Lemano – p.66-71 1.15 Allemagne – Autriche – Suisse : TEE Bavaria – p.74-75 1.16 Allemagne – Autriche – Italie : TEE Mediolanum – p.76-77 1.17 Allemagne – Autriche : TEE Blauer Enzian (II), Prinz Eugen – p.78-83 1.18 Allemagne – Danemark : TEE Merkur – p.86-87 1.19 Allemagne – Pays-Bas : TEE Rhein Main, Van Beethoven, Rembrandt, Erasmus – p.88-95 1.20 Pays-Bas – Allemagne – Suisse : TEE Rheingold – p.98-99 2 – LES TEE NATIONAUX / NATIONAL TEE TRAINS – p.100-101 2.1 France : TEE Le Mistral, Lyonnais, Rhodanien, Capitole (matin et soir), Aquitaine, Étendard, Kléber, Stanislas, Faidherbe, Gayant, Watteau (II), Jules Verne – p.102-125 2.2 Allemagne : TEE Bacchus, Goethe (II), Roland (II), Diamant (II), Friedrich Schiller, Lufthansa Airport Express, Heinrich Heine – p.126-141 2.3 Italie : TEE Adriatico, Settebello, Colosseum, Ambrosiano, Vesuvio, Cycnus, Aurora – p.142-153
procedure TForm8FormShow(Sender: TObject);
begin
// setup cport (already set to 9,600 baud rate)
try
if IsCOMPortReal(3) then begin
ApdComPort1.ComNumber:= 3;
writeln('debug comport: '+objtostr(apdcomport1)) ;
//connect up the data-in event
if (FStatusTrigger = 0) then begin
FStatusTrigger:= ApdComPort1.AddStatusTrigger(stline); //sline
ApdComPort1.SetStatusTrigger(FStatusTrigger,
lsOverrun or lsParity or lsFraming or lsBreak,
True);
end;
end;
except
writeln('ArdEWI_Exc:'+ExceptiontoString(exceptiontype,exceptionparam));
finally
ApdComPort1.free;
writ('debug finfree')
end;
// For this sensor we know the data is coming in within this data range
// so am setting Left Axis Min Max accordingly
Chart1.Axes.Left.SetMinMax(-1,4);
//ChartTool1.Value := 2.5; //colorline as threshold line
end;
Example of TMS Script
unit fMain;
interface
uses
Windows, Messages, SysUtils,
Variants,
Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, atScript, FormScript, atPascal, ScrMemo, Scrmps,
Vcl.ScripterInit;
type
TForm1 = class(TForm)
Button1: TButton;
log: TListBox;
countrycombo: TComboBox;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
atPascalFormScripter1: TatPascalFormScripter;
ScrMemo1: TScrMemo;
ScrPascalMemoStyler1: TScrPascalMemoStyler;
procedure Button1Click(Sender: TObject);
procedure StAdd;
procedure StClear;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
// learns TatPascalScripter how to execute the Add & Clear methods for TStrings
with atPascalFormScripter1.AddDelphiClass(TStrings) do begin
AddMethod('Add',1,tkNone,nil,StAdd);
AddMethod('Clear',0,tkNone,nil,StClear);
end;
atPascalFormScripter1.SourceCode.Assign(ScrMemo1.Lines);
atPascalFormScripter1.Execute(null);
end;
// implementation of component method Add of TStrings
procedure TForm1.StAdd;
begin
TStrings(atPascalFormScripter1.CurrentObject).Add(atPascalFormScripter1.GetInputArgAsString(0));
end;
// implementation of component method Clear of TStrings
procedure TForm1.StClear;
begin
TStrings(atPascalFormScripter1.CurrentObject).Clear;
end;
end.
Connect to an ADO ODBC Database
Const CSTRING5= 'Provider=MSDASQL.1;Persist Security Info=False;Data Source=countries64japan;';
function DataBaseConnection_Test(bMessage: Boolean): AnsiString;
var
asTimeout, asUserName, asPassword, asDataSource, ConnectionString: AnsiString;
iReturn: Integer; OldCursor: TCursor;
begin
OldCursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
asTimeout := '150';
asUserName := 'NT_Server'; asPassword:= 'SA';
asDataSource := 'SQL Server - My DataBase';
{ ConnectionString := 'Data Source = ' + asDataSource +
'User ID = ' + asUserName +
'Password = ' + asPassword +
'Mode = Read|Write;Connect Timeout = ' + asTimeout; }
ConnectionString:= CSTRING5;
try
iReturn:= OpenConnection(ConnectionString);
if (bMessage) then begin
if (iReturn = 0) then begin
(Application.MessageBox(utf8toansi('Connection_OK!'), ('Information'), MB_OK))
writeln('ADO Connection OK!');
end else if (iReturn = -1) then
Application.MessageBox(utf8toansi('Connection Error!'), 'Error', MB_ICONERROR + MB_OK);
end;
if (iReturn = 0) then
Result:= ConnectionString
else if (iReturn = -1) then
Result:= 'no thing';
finally
Screen.Cursor:= OldCursor; //crDefault; //OldCursor;
end;
end;
function OpenConnection(ConnectionString: AnsiString): Integer;
var ADODBConnection: OleVariant; rs: Olevariant;
sqlQuery: string;
begin
ADODBConnection:= CreateOleObject('ADODB.Connection');
ADODBConnection.CursorLocation:= 3; // User client
ADODBConnection.ConnectionString:= ConnectionString;
Result:= 0;
try
ADODBConnection.Open;
sqlQuery:= 'SELECT * FROM Countries'; //Table1';
rs:= ADODBConnection.Execute(sqlQuery)
While Not rs.EOF do begin
writeln(inttostr(rs.Fields('ID').Value)+': '+rs.Fields('Country').Value+
#9#9#9#9#9+' code: '+rs.Fields('Code').Value);
//writeln((rs.Fields('Country').Value));
rs.MoveNext;
end;
except
Result:= -1;
finally
rs.close;
ADODBConnection.close;
end;
end;
We found a solution with Github as a media server. Our URL to MP3 converter stream server serves as an open source for online song downloading or streaming. Either you play in a desktop app or you run it with WebView2 embedding. You can copy the URL of the song you want to download, or paste it to our online MP3 converter website or play it direct as an URL stream in the following script:!
var mp3Stream: TMemoryStream;
mp3Stream:= TMemoryStream.create;
Http_GetStream(SongURL5, mp3Stream);
PlayMp3FromStream(mp3stream);
mp3stream.free; //}
A raw GitHub link allows you to access the raw content of a file stored in a GitHub repository. This can be useful for directly accessing files such as images, songs, text files, or scripts without the GitHub interface. We use this also to execute a JavaScript link to run in a local embedding browser in maXbox.
Sound Stream Shell
The ComObject CreateOleObject(‘WMPlayer.OCX’) control gives you direct control of media, including reading and writing to the files or metadata/tags. Additionally, some automation interfaces are implemented by automation objects, and the properties and methods of those interfaces are inherited by the objects like wmp.controls.play.
const SoundCloudURL = 'https://soundcloud.com/max-kleiner-481715070/sternenhaufen';
procedure PlaySurprise_MP3_Media2;
var wmp: Variant;
//Maybe you'll be more comfortable with automation.
//I believe it would provide most of functionality as interfaces provide.
begin
wmp:= CreateOleObject('WMPlayer.OCX');
if ISInternetconnected then begin
wmp.URL:= SongURL5;
wmp.OpenPlayer(wmp.URL);
end else //}
wmp.OpenPlayer(Exepath+'examples\Sternenhaufen_Max_SunoAI.mp3');
//wmp.controls.play;
end;
Conclusion
The SndPlaySound API only supports waveform audio. It is not a general purpose multi-media API and as such does not (directly nor easily) support MP3 playback. To play your audio through this API you would first need to decode the MP3 into the waveform format that the API expects. With the Comobject CreateOleObject(‘WMPlayer.OCX’) you get an URL enabled player for streaming an MP3 file.
TResourceStream is a memory stream that provides access to the compiled resources in an application. Use TResourceStream to read the resources of an application. An instance of TResourceStream holds the value of a single resource in a memory buffer where it is accessible to the application.
Minitrix 12820CC 6544Minitrix, Arnold Maurienne CC 6544, CC 6541
TheOpen Railway Map API
The OpenRailwayMap (ORM) is an OpenStreetMap-based project designed to create a detailed map of the world’s railway infrastructure. It provides a variety of tools, APIs, and map styles to visualize railway data, including tracks, stations, signals, and speed limits.
Key Features and Usage
The OpenRailwayMap database is built on OpenStreetMap data and is available under the Open Database License (ODbL). The rendered map tiles are distri-buted under the CC-BY-SA 2.0 license. The project is non-commercial and main-tained by volunteers, relying on donations for its operation.
The database supports querying railway-related information through a RESTful API. This API allows users to search for stations by name or reference code and retrieve mileage data for specific railway lines. The API documentation is hosted on GitHub.
Map Styles and Tile Access
The map tiles are rendered in Web Mercator projection and are available in different styles, such as:
Standard: Displays railway infrastructure like tracks, stations, and switches.
Signals: Visualizes railway signals and train protection systems.
Maxspeed: Shows maximum speeds and speed signals for railway lines.
Here, ${s} can be replaced with subdomains (a, b, or c) for faster loading, and ${style} specifies the map style.
Integration with Tools
The OpenRailwayMap tiles can be integrated into various mapping libraries and tools:
OpenLayers and Leaflet: Easily add OpenRailwayMap layers using their respective APIs.
OsmAnd: Overlay OpenRailwayMap tiles on offline maps with the “Online maps” plugin.
QGIS: Load OpenRailwayMap tiles as XYZ layers for GIS analysis.
The OpenRailwayMap API and tiles are free for non-commercial, small-scale applications. Commercial use requires setting up a private server. Bulk requests and misuse of headers (e.g., faking user-agent) are prohibited. Applications must include proper attribution when using the tiles or API. For example we search for Kamakura Station, Japan:
The project operates without guarantees of availability or support. Users requiring high reliability are encouraged to deploy their own instances of the API or image tile server.
For further details, visit the OpenRailwayMap GitHub repository or the OpenStreetMap Wiki page.
So first we call the REST-API to get a stations facility information in JSON:
const URL_ORM_GET9 =
'https://api.openrailwaymap.org/v2/facility?name=%s&limit=1';
function API_GEOLocation_ORM9(AURL, aloc, aApikey: string;
verbose: boolean): Tlatlong;
var Httpreq: THttpRequestC; httpres: string; jsn: TMcJsonItem;
begin
httpreq:= THttpRequestC.create(self);
httpreq.headers.add('Accept: application/json; charset=utf-8');
//httpreq.headers.add('X-Api-Key:'+aAPIkey);
httpreq.useragent:= USERAGENT5;
httpreq.SecurityOptions:= [soSsl3,soPct,soIgnoreCertCNInvalid];
try
if httpreq.get(Format(AURL,[aloc])) then begin
httpres:= (httpreq.Response.ContentAsUTF8String)
writeln('conttype '+httpreq.Response.ContentType);
if verbose then writ('debug back '+formatJson(httpres));
jsn:= TMcJsonItem.Create;
jsn.AsJSON:= httpres;
writ('debug name: '+jsn.at(0,'name').asstring)
writ('debug operator: '+jsn.at(0,'operator').asstring)
result.lat:= jsn.at(0,'latitude').asnumber;
//in the api now fixed
result.long:= jsn.at(0,'longitude').asnumber;
result.descript:= Format('Coords: lat %2.5f lng %2.5f %s
osm_id: %s operator: %s',
[result.lat,result.long,jsn.at(0,'name').asstring,
jsn.at(0,'osm_id').asstring,
jsn.at(0,'operator').asstring]);
end else Writeln('APIError '+inttostr(Httpreq.Response.StatusCode2));
except
writeln('EWI_APIHTTP:
'+ExceptiontoString(exceptiontype,exceptionparam));
finally
writeln('Status3: '+gethttpcod(httpreq.Response.statuscode2))
httpreq.Free;
sleep(200);
jsn.Free;
end;
end;
The API returns JSON formatted data with following fields:
latitude: latitude, longitude: longitude
osm_id: OSM node ID
rank: an importance rank calculated by taking the public transport route relations into account using this station/halt. All OSM tags present on this object. The following tags are very often in use. See the OSM wiki and Taginfo for a more comprehensive list of possible tags.
name: name, uic_name: UIC station name
railway:ref: reference assigned by the operator of the infrastructure railway: type of the facility following Tagging rules), e.g. station, halt, junction, yard.
operator: operator of the infrastructure
Open Railway Map:________________________________________________
got also a mail from a bugfix which is now solved1. Thank you for the bug report and the comment reminding me. I adapted the frontend JavaScript code as well because it assumed latitude and longitude to be swapped as well. It seems that the old API had this bug, too. 🫢
The call for the map above has to be set with the coordinates, which we got from the facility API:
A string is a sequence of zero or more Unicode characters [UNICODE]. An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array. An array is an ordered sequence of zero or more values.
Most API requests should normally take no longer than 3 seconds. In any case, you should write your application so that it will time out requests after ca. 5 seconds. Applications must send a unique HTTP User-Agent. If map tiles are embedded into a website, browsers must send a valid HTTP referer instead.
Nominatim can power the search box on your website, allowing your users to type free-form queries (“Cafe Paris, Cologne”) in any language. It also offers a structured query mode (“postcode=12345”, “city=London”, “type=cafe”) that helps you to automate geocoding of extensive address lists.
Sometimes life is like playing with us: You write some useful code that solves a problem, and then someone comes along and makes the problem much harder. Here’s how to continuously integrate new solutions without having to rewrite your old solutions (as much). Means you don’t have to change the language, you change the environment.
Let’s start with a simple problem: Get the distance between two earth-coordinates. Calculating the geographical distance between two points on the Earth’s surface can be done using the Haversine formula. This formula accounts for the spherical shape of the Earth. Below is a Delphi and Python function that performs this calculation:
type
TipGeolocation = record
Latitude: Double; //read Coordinates[0] write SetLatitude;
Longitude: Double; //read Coordinates[1] write SetLongitude;
end;
For the purposes of this task we make the problem harder, a geocoding function with a record pair of coordinates:
This function calculates the distance between two points given their latitude and longitude in degrees. The example usage calculates the distance between Bern and Paris. Feel free to adapt the coordinates to your specific needs!
def haversine_distance(lat1, lon1, lat2, lon2):
# Radius of the Earth in kilometers
R = 6371.0
# Convert latitude and longitude from degrees to radians
lat1_rad = math.radians(lat1)
lon1_rad = math.radians(lon1)
lat2_rad = math.radians(lat2)
lon2_rad = math.radians(lon2)
# Differences in coordinates
dlat = lat2_rad - lat1_rad
dlon = lon2_rad - lon1_rad
# Haversine formula
a = math.sin(dlat / 2)**2 + math.cos(lat1_rad) *math.cos(lat2_rad) * math.sin(dlon / 2)**2
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
# Distance in kilometers
distance = R * c
return distance
# Example usage
lat1 = 46.94809 # Latitude of Bern
lon1 = 7.44744 # Longitude of Bern
lat2 = 48.8566 # Latitude of Paris
lon2 = 2.3522 # Longitude of Paris
distance = haversine_distance(lat1, lon1, lat2, lon2)
print(f"The distance between Bern and Paris is {distance:.2f} kilometers.")
>>> The distance between Bern and Paris is 434.96 kilometers.
Often, we calculate the great-circle distance of given two points in geophysics, for example, the distance from the seismic station to the epicenter. Supposing that we have two geographical points, and let’s say P1:(ϕ1,λ1)and P2:(ϕ2,λ2), where,ϕ and λ represent the latitude and longitude, respectively. Using Haversine formula, we can calculate the great-circle distance. The great-circle distance, orthodromic distance, or spherical distance is the distance between two points on a sphere, measured along the great-circle arc between them.
Paris Place Madeleine Place de la Madeleine
Next we need a geocoding API. Geocoding is the process of transformation of any location name into geographical coordinates, and the other way around (reverse geocoding). OpenWeather’s Geocoding API and OpenStreetMap supports both the direct and reverse methods, working at the level of city names, areas and districts, countries and states:
Nominatim uses OpenStreetMap data to find locations on Earth by name and address (geocoding) as you can see in the const URL_GEOLOCURL9. It can also do the reverse, find an address for any location on the planet. The Geocoding API relies on a redundant infrastructure of geocoder nodes powered by the Nominatim software with edge servers for fast delivery of results. Note that when you get an
You’ll have to be esp. careful about including a unique user agent for your application and change from time to time;
It sounds like you’re encountering a “403 Forbidden” error when trying to use the Nominatim API. This error typically indicates that your request is being blocked, possibly due to rate limiting, incorrect usage, or IP blocking. Here are a few steps you can take to troubleshoot and resolve this issue:
Check API Usage Limits: Ensure that you are not exceeding the usage limits set by Nominatim. They have strict policies to prevent abuse. Review their usage policy to make sure you’re compliant.
User-Agent Header: Nominatim requires a valid User-Agent header in your requests. Make sure you include a descriptive User-Agent string that identifies your application. Best is do rotate useragents:
const
USERAGENT5 = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko)'+
' Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0 ';
USERAGENT2 = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1';
USERAGENT3 = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
Gecko)'+' Chrome/125.0.0.0 Safari/537.3'; // chrome + win
USERAGENT4 = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15'+
' (KHTML, like Gecko) Version/17.4.1 Safari/605.1.1'; // safari + mac
USERAGENT1 = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '+
'(KHTML, like Gecko) Chrome/126.0.0.0 Edg/126.0.0.'; // edge + win
Most of the time, ~ 75% in this case, it is spent with API IP-connection. So we put in maXbox processmessagesOFF; and processmessagesON; between start and stop-time for time measure.
The interesting point is to know where the code is running and how it is stored in an executable or script itself. Solution 1 and 2 can running on the web or on premise all others run locally or on a server.
3 Solutions Overview of GEO Distance Math Solver
Internal scripted TipGeolocationDistanceInMetersTo() in maXbox5
External def haversine_distance () call of Python for Delphi(P4D)
Internal compiled function SphericalEarthDistance()
Past
Present
known
Big Bang
Future
unknown
unchangeable
changeable
Time/Space
The multiplication of past times future is a vector with the function: known = f(changeable) [y=f(x)] as distance over time, so distance is a function of time: d=f(t)
Time Space Matrix States
Conclusion
When it comes to problem-solving, there are often multiple solutions that can be used to solve the same problem. The choice of solution depends on various factors such as performance, storage, implementation, simplicity, and also scaleability and security in different environments. The code is more or less the same but the choice of the environment (script, executable, container, hosting, web or cloud API) could be a response of different requirements.
Great Circle Mapper is a tool that shows the shortest route between two or more locations on a globe. You can enter airports, cities, or coordinates and get a distance back with a geocode API.
Garmin GPS Distance TrackingTGV Inoui 543-550-540 Paris Gare d’Est Ostern 2025Published on Page 10, Geocoding Distance
From our technical advisor, Jerry KingFrom your Editor
Why ‘OPEN SOURCE’ AI isn’t truly Open By Stefano Maffuli
Geocoding DistanceBy Max Kleiner
Alea Iacta Est, the die is cast By Reinhold Schmitt
Programming the QUEENS puzzle By David Dirkse
Threading in the Browser Understanding how to create a WEBASSEMBLY APPLICATION
By Michael van Canneyt
ORMs for various platforms A blog created by Kim Madsen (kbmMW)
Quantum Network Explorer By Prof.Dr. Stephanie Wehner
Explaining the extended RTTI in PAS2JS By Michael van Canneyt
CC 21004 by JouefParisBerlinAmsterdam3 Main CityPolytension Locs CC 40109, BB 1606, Br 184 001-6Polytension Locs II 3 NationsGeneva May 2025Roter Pfeil RBe 2/4Piko 5420Kali Linux 2025.2 with Wine 10
Data science is a multidisciplinary field that combines math, statistics, computer science, machine learning, and domain expertise to extract insights from data. While data science algorithms often put the spotlight, a solid foundation in statistical methods can be just as pivotal.
The code in script is build on Python especially Python4Delphi as P4D.
1. Bayesian Inference
Bayesian inference uses Bayes’ theorem to update the probability of a hypothesis as more evidence or information becomes available.
Bayesian statistics offers a robust and flexible framework for understanding how beliefs should be updated in light of new evidence. This approach stands in contrast to classical statistics,
import pymc as pm
import numpy as np
//# Suppose we observed 20 coin flips with 12 heads and 8 tails
execstr('observ_heads = 12; observ_tails = 8');
execstr('with pm.Model() as model: '+
'# Prior for the bias of the coin (theta) '+LF+
'theta = pm.Beta(''theta'', alpha=1, beta=1) '+LF+
'# Likelihood '+LF+
'y= pm.Binomial(''y'',n=observ_heads+observ_tails,p=theta,observed=observ_heads)'+
'# Posterior sampling '+LF+
'trace = pm.sample(200, tune=1000, cores=1, chains=2) ');
execstr('pm.summary(trace)');
We perform Bayesian parameter estimation for a Bernoulli process (e.g., coin flips).
2. Hypothesis Testing (t-test)
Hypothesis testing involves formulating a null hypothesis (no difference/effect) and an alternative hypothesis. A t-test specifically checks if the means of two groups are significantly different.
A t test is a statistical test that is used to compare the means of two groups. It is often used in hypothesis testing to determine whether a process or treatment actually has an effect on the population of interest, or whether two groups are different from one another.
3. Factor Analysis (Loading Analysis)
Oh thats a real big topic in statistics. Factor Analysis models the observed variables as linear combinations of latent (unobserved) factors, often used for dimensionality reduction or to uncover hidden structure.
Factor Analysis is a statistical method used to describe variability among observed, correlated variables in terms of a potentially lower number of unobserved variables called factors1. This technique helps in reducing the number of variables by identifying a smaller number of underlying factors that explain the correlations among the observed variables2.
Key Principles
Factors: In factor analysis, a factor refers to an underlying, unobserved variable or latent construct that represents a common source of variation among a set of observed variables1. These observed variables are measurable and directly observed in a study.
Factor Loadings: Factor loadings represent the correlations between the observed variables and the underlying factors. They indicate the strength and direction of the relationship between each variable and each factor1.
Factor Analysis is a method for modeling observed variables, and their covariance structure, in terms of a smaller number of underlying unobservable (latent) “factors.” The factors typically are viewed as broad concepts or ideas that may describe an observed phenomenon. For example, a basic desire of obtaining a certain social level might explain most consumption behavior.
4. Cluster Analysis (K-means)
Clustering partitions data into homogeneous groups (clusters) based on similarity. K-means is a popular centroid-based clustering technique.
This code snippet trains a linear regression model, predicts the target values for the test set, andthen calculates and prints the R² score and Mean Squared Error (MSE) for the model. Feel free to adapt it to your specific dataset and model! Scikit-learns model.score(X,y) calculation works on co-efficient of determination i.e R^2 is a simple function that takes model.score= (X_test,y_test). It doesn’t require y_predicted value to be supplied externally to calculate the score for you, rather it calculates y_predicted internally anduses it in the calculations.
We have 20 samples to compare (test_size=0.2 of 100) , we got 14 right predictions, that means 70 % of 20 samples (14/0.2=70) just so the score 0.7 aka 70 %!
Monte Carlo simulations use repeated random sampling to estimate the probability of different outcomes under uncertainty.
This interactive simulation estimates the value of the fundamental constant, pi (π), by drawing lots of random points to estimate the relative areas of a square and an inscribed circle.
execstr('np.random.seed(42) '+LF+
'n_samples = 10_000_00 '+LF+
'xs = np.random.rand(n_samples) '+LF+
'ys = np.random.rand(n_samples) '+LF+
'# Points within the unit circle '+LF+
'inside_circle = (xs**2 + ys**2) <= 1.0 '+LF+
'pi_estimate = inside_circle.sum() * 4 / n_samples ');
execstr('print("Estimated π:", pi_estimate)');
Estimated p: 3.141864
7. Time Series Analysis (ARIMA)
ARIMA (AutoRegressive Integrated Moving Average) is a popular model for forecasting univariate time series data by capturing autocorrelation in the data.
In time series analysis used in statistics and econometrics, autoregressive integrated moving average (ARIMA) and seasonal ARIMA (SARIMA) models are generalizations of the autoregressive moving average (ARMA) model to non-stationary series and periodic variation, respectively. All these models are fitted to time series in order to better understand it and predict future values.
pip install statsmodels
C:\maxbox\maxbox4\maxbox5>py -0
-V:3.12 * Python 3.12 (64-bit)
-V:3.11 Python 3.11 (64-bit)
-V:3.11-32 Python 3.11 (32-bit)
-V:3.10-32 Python 3.10 (32-bit)
-V:3.8 Python 3.8 (64-bit)
execstr('from statsmodels.tsa.arima.model import ARIMA ');
//# Synthetic time series data
execstr('np.random.seed(42); data = np.random.normal(100, 5, 50)');
execstr('time_series = pd.Series(data)');
//# Fit ARIMA model (p=1, d=1, q=1)
execstr('model = ARIMA(time_series, order=(1,1,1))');
execstr('model_fit = model.fit()');
//# Forecast next 5 points
execstr('forecast = model_fit.forecast(steps=5)');
execstr('print("Forecast:", forecast.values)');
From understanding Bayesian inference and Cluster, through advanced concepts like Logistic Regression or LinearRegrison and ARIMA, these 7 advanced statistical approaches form a comprehensive and useful toolkit for any data scientist.
This we can transpile in maXbox with Python for Delphi:
//# Create Employee Dataset
execstr('data = { '+LF+
'"Employee_ID": range(1001, 1011), '+LF+
'"Name":["Alice","Bob","Charlie","David","Emma","Max","Grace","Helen","Isaac","Julia"],'+LF+
'"Age":[25, 28, 35, 40, 22, 30, 45, 50, 29, 38], '+LF+
'"Department":["HR","IT","IT","Finance","HR","Finance","IT","Marketing","HR","Finance"],'+LF+
'"Salary":[50000,70000,85000,92000,48000,78000,110000,65000,52000,88000],'+LF+
'"Experience_Years":[2, 4, 10, 15, 1, 8, 20, 12, 3, 11],'+LF+
'"Performance_Score":[3.2,4.5,4.8,3.7,2.9,4.2,4.9,3.8,3.5,4.1]'+LF+
'} ');
//# Convert to DataFrame
execstr('df = pd.DataFrame(data)');
//# Display first few rows
execstr('print(df.head())');
//Data Cleaning # Check for missing values
execstr('print(df.isnull().sum()); # Check data types print(df.dtypes)');
//# Convert categorical columns to category type
execstr('df[''Department''] = df[''Department''].astype(''category'')');
//# Add an Experience Level column
execstr('df[''Experience_Level''] = pd.cut(df[''Experience_Years''],'+LF+
'bins=[0,5,10,20], labels=[''Junior'',''Mid'',''Senior''])');
//# Show the updated DataFrame
execstr('print(df.head())');
//Find Employees with High Salaries
execstr('high_salary_df = df[df[''Salary''] > 80000]');
execstr('print(high_salary_df)');
//Find Average Salary by Department
execstr('print(df.groupby(''Department'')[''Salary''].mean())');
//Find the Highest Performing Department
execstr('print(f"Highest Performing Department: {df.groupby("Department")["Performance_Score"].mean().idxmax()}")');
Now, we create meaningful visualizations using Matplotlib & Seaborn modules:
//Step 4: Data Visualization
//📊 1. Bar Chart — Average Salary by Department
execstr('import matplotlib.pyplot as plt');
execstr('import seaborn as sns');
execstr('plt.figure(figsize=(8,5))'+LF+
'sns.barplot(x=df[''Department''],y=df[''Salary''],estimator=np.mean,palette="coolwarm")'+LF+
'plt.title(''Average Salary by Department'', fontsize=14) '+LF+
'plt.xlabel(''Department'', fontsize=12) '+LF+
'plt.ylabel(''Average Salary'', fontsize=12) '+LF+
'plt.xticks(rotation=45) '+LF+
'plt.show() ');
//📈 2. Scatter Plot — Salary vs Experience
execstr('plt.figure(figsize=(9,5))'+LF+
'sns.scatterplot(x=df["Experience_Years"],y=df["Salary"],hue=df["Department"],palette="Dark2",s=100)'+LF+
'plt.title(''Salary vs Experience'', fontsize=14) '+LF+
'plt.xlabel(''Years of Experience'', fontsize=12) '+LF+
'plt.ylabel(''Salary'', fontsize=12) '+LF+
'plt.legend(title="Department",bbox_to_anchor=(1, 1),fontsize=8) '+LF+
'plt.show() ');
//📊 3. Histogram — Salary Distribution
execstr('plt.figure(figsize=(8,5)) '+LF+
'plt.hist(df["Salary"], bins=5, color="blue", alpha=0.7, edgecolor="black") '+LF+
'plt.title("Salary Distribution", fontsize=14) '+LF+
'plt.xlabel("Salary", fontsize=12) '+LF+
'plt.ylabel("Frequency", fontsize=12) '+LF+
'plt.show() ');
//📊 4. Box Plot — Salary by Department
execstr('plt.figure(figsize=(8,5)) '+LF+
'sns.boxplot(x=df["Department"], y=df["Salary"], palette="pastel") '+LF+
'plt.title("Salary Distribution by Department", fontsize=14) '+LF+
'plt.xlabel("Department", fontsize=12) '+LF+
'plt.ylabel("Salary", fontsize=12) '+LF+
'plt.xticks(rotation=45) '+LF+
'plt.show() ');
And the graphical result will be:
barchart-scatterplot-histogram-boxplot
To go further, try working with larger datasets, dive into more advanced Pandas functions, or explore machine learning with Scikit-learn like above with statistical methods.
Correlation Matrix
Checking for correlation, and quantifying correlation is one of the key steps during exploratory data analysis and forming hypotheses.
//Start with Tutor 140
//# Target column is under ch.target, the rest is under ch.data
execstr('ch = fetch_california_housing(as_frame=True)');
execstr('df = pd.DataFrame(data=ch.data, columns=ch.feature_names)');
execstr('df["MedHouseVal"] = ch.target; print(df.head())');
execstr('fig, ax = plt.subplots(figsize=(10, 6)) '+LF+
'plt.title("corr. matrix - california_housing mX5") '+LF+
'sns.heatmap(df.corr(),ax=ax,annot=True); plt.show() ');
Correlations
Several types of visualizations are commonly used in EDA using Python, including:
Bar charts: Used to show comparisons between different categories.
Line charts: Used to show trends over time or across different categories.
Pie charts: Used to show proportions or percentages of different categories.
Histograms: Used to show the distribution of a single variable.
Heatmaps: Used to show the correlation between different variables.
Scatter plots: Used to show the relationship between two continuous variables.
Box plots: Used to show the distribution of a variable and identify outliers.
Correlation Matrix shows relations to each other variable
Import Delphi Double Arrays to Python Numpy Arrays and show Correlation Matrix
First we have to create data features:
type DMatrix = array of array of double;
procedure TForm1DataCreate(Sender: TObject);
var i,j,tz: integer;
//mData: dMatrix; //array of array of Double;
begin
// Example reference data as 4 features with 7 samples
SetMatrixLength(mData, 4, 7);
SetMatrixLength(corrMatrix, 4, 4);
mData[0]:= [1.0, 2.0, 3.0, 4.0, 5.0,6.0,7.0];
mData[1]:= [22.5, 32.0, 42.0, 52.0,55.7,50.1,55.5];
mData[2]:= [15.0, 16.0, 17.0, 19.0,28.9,30.0,32.4];
mData[3]:= [25.0, 126.0, 127.0, 119.0,118.9,120.8,12.7];
writeln('Test Matrix Data TM: '+flots(mdata[2][3]));
CalculateCorrelationMatrix2(mdata, corrMatrix);
A heatmap in seaborn requires 2D input. Use data = np.asarray([b]) in this case. Then we convert those array into a numpy array and reshape it for a panda dataframe:
//4. Matplotlib & Seaborn Correlation Matrix
execstr('import matplotlib.pyplot as plt; import seaborn as sns');
it:= 0;
execstr('arr2 = np.empty(28, dtype = float)');
for x:= 0 to 6 do
for y:= 0 to 3 do begin
execstr('arr2['+itoa(it)+']= '+flots(mdata[y][x]));
inc(it)
end;
execstr('data2 = np.asarray(arr2).reshape(7,4)'+LF+
'df = pd.DataFrame(data2)');
execstr('fig, ax = plt.subplots(figsize=(8, 6))'+LF+
'plt.title("Delphi Matrix 2 PySeaborn Plot")'+LF+
'sns.heatmap(df.corr(), ax=ax,annot=True); plt.show()');
//}
As the plot in seaborn has the right shape (7,4) we compute the correlation matrix:
The Gemini API is a set of tools and interfaces that allow developers to integrate Google’s Gemini family of large language models (LLMs) into their applications and services. It’s essentially your access point to leverage the power of these powerful AI models.
First to get your API Key
Here’s a breakdown of what that means:
Key Concepts:
Gemini Family of LLMs: Gemini refers to Google’s suite of multimodal AI models, designed to understand and generate text, code, images, audio, and video. They come in various sizes (e.g., Gemini Ultra, Gemini Pro, Gemini Nano) optimized for different use cases and performance requirements.
API (Application Programming Interface): An API is like a messenger that allows different software applications to communicate with each other. The Gemini API provides a standardized way for your application to send requests to the Gemini models and receive responses.
{$I .\GAPIKEY.INC}
function TRestClient3_AskChatGPTGemini(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}'; *)
JPostDat:= '{'+
'"contents": [{'+
'"parts": [{"text": "%s"}]'+
'}]}';
with TRestClient.create(self) do begin
rest:= Resource('https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key='
+GEMINI_APIKEY);
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.createstring(format(JPostDat,[askstream]))));
//result:= jo.values['candidates'].asarray[0].asobject['parts'].asobject['text'].asstring;
result:= jo.values['candidates'].asarray[0].asobject['content'].asobject['parts'].asarray[0].asobject['text'].asstring;
//writeln(formatjson(jo.stringify));
finally
Free;
jo.Free;
except
writeln('EWI_Exc:'+ExceptiontoString(exceptiontype,exceptionparam));
end;
end; //with
end;
Call:
writeln('resreal: '+TRestClient3_AskChatGPTGemini('Why is the earth blue?', Nil));
Integration: The Gemini API allows you to seamlessly incorporate the capabilities of these AI models into your applications. This means you can use them to build features that understand language, generate content, translate text, analyze data, and much more.
JSON Structure for Gemini API
The Gemini API uses the following basic structure when specifying generation parameters like temperature:
The Gemini API opens up a wide range of possibilities, including:
Natural Language Processing (NLP):
Text generation: Generate creative content like poems, stories, articles, code, etc.
Text summarization: Condense large blocks of text into key points.
Text translation: Translate text between various languages.
Sentiment analysis: Determine the emotional tone of text.
Question answering: Provide answers to questions based on provided text.
Chatbots and conversational AI: Build interactive and engaging chatbot experiences.
Multimodal Understanding:
Image understanding: Extract information and context from images.
Video analysis: Analyze and understand video content.
Audio transcription and analysis: Convert speech to text and extract insights.
Combined text and image reasoning: Understand relationships between text and visual content.
Code Generation:
Code completion: Suggest code snippets and complete lines of code.
Code explanation: Provide explanations of existing code.
Code translation: Convert code between different programming languages.
Customization: Fine-tune the models for specific tasks and industries.
And much more: The capabilities are constantly evolving, making the possibilities virtually limitless.
Key Features of the Gemini API:
Scalability and Reliability: Built on Google’s robust infrastructure to handle high volumes of requests.
Ease of Use: Provides well-documented APIs with various client libraries (e.g., Python, Java, Go) to simplify integration.
Security: Implements security measures to protect your data and the models.
Flexibility: Supports various input and output formats, allowing for diverse application integration.
Regular Updates: Models are continuously improved with the latest advancements in AI research.
How to Access the Gemini API:
Google Cloud Platform (GCP): The Gemini API is primarily accessed through Google Cloud Platform (GCP). You’ll need a GCP project and enable the API.
API Keys and Authentication: You’ll use API keys or other authentication mechanisms to authorize your application to use the API.
Client Libraries: Use the provided client libraries for your programming language of choice to interact with the API.
Billing: API usage is typically based on the number of requests and model compute resources consumed.
The Google AI Python SDK is the easiest way for Python developers to build with the Gemini API. The Gemini API gives you access to Gemini models created by Google DeepMind. Gemini models are built from the ground up to be multimodal, so you can reason seamlessly across text, images, and code.
Get started with the Gemini API in Python
The Google AI Python SDK is the easiest way for Python developers to build with the Gemini API. The Gemini API gives you access to Gemini models created by Google DeepMind. Gemini models are built from the ground up to be multimodal, so you can reason seamlessly across text, images, and code.
#Get the Python Package
pip install -U google-generativeai
#Import the SDK and configure your API key.
import google.generativeai as genai
import os
genai.configure(api_key=os.environ["GEMINI_API_KEY"])
#Create a model and run a prompt.
#model = genai.GenerativeModel('gemini-pro')
model = genai.GenerativeModel('gemini-1.5-flash')
response = model.generate_content("Why is the earth blue?")
print(response.text)
Answer: The Earth is blue because of the oceans. Water absorbs longer wavelengths of light (like red and yellow) and reflects shorter wavelengths (like blue). Since the Earth’s surface is about 71% water, the blue light reflected from the oceans dominates the color we see from space.
const DEF_llmfunc =
'def llm_function(query): '+LF+
' response = model.generate_content(query) # Generate response '+LF+
//' st.markdown(response.text) # Print it out using streamlit ';
' print(response.text) # Print it out using NOT streamlit ';
procedure Gemini_PySolution(loc: string);
begin
with TPythonEngine.Create(Nil) do begin
//pythonhome:= PYHOME64;
loaddll;
autofinalize:= false;
try
Execstring('from math import sqrt');
Execstring('import streamlit as st');
Execstring('from bs4 import BeautifulSoup');
Execstring('import os, requests');
Execstring('import google.generativeai as genai');
// Execstring('from PIL import Image; import os, math, collections');
Execstr('import io, sys');
//Execstring('import plotly.express as px');
Execstr(PY_count);
Execstr(DEF_llmfunc);
Execstr(DEF_GEMiniInput);
execstr('output = io.StringIO()')
execstr('sys.stdout = output');
execstr('st.title("Proposal Calls") # Title for the page');
execstr('os.environ[''GOOGLE_API_KEY'']='+loadfile3(exepath+'geminiapikey.txt')+'');
//execstr('os.environ[''GOOGLE_API_KEY'']="'+loadfile3(exepath+'geminiapikey2.txt')+'"');
execstr('genai.configure(api_key = os.environ[''GOOGLE_API_KEY''])');
//execstr('model = genai.GenerativeModel(''gemini-pro'')');
execstr('model = genai.GenerativeModel(''gemini-1.5-flash'')');
execstr('response = model.generate_content("Why is the earth blue?")');
execstr('print(response.text) ');
//execstr('(read_http_input()) ');
println(stringreplace(evalstr('output.getvalue().strip()'),
#10,#13#10,[rfReplaceAll, rfIgnoreCase]));
except
raiseError;
finally
UnloadDll;
Free;
end;
end;
end;
In Summary:
The Gemini API is the bridge that empowers developers to integrate the transformative capabilities of Google’s Gemini AI models into their applications. It opens up a world of possibilities for building innovative solutions, enhancing existing services, and creating entirely new user experiences. By utilizing the power of these advanced language models, developers can revolutionize how users interact with technology.
Interact with Python or Delphi
Thats what Google AI Studio says:
Okay, let’s talk about using maXbox5 in conjunction with the Gemini API. While maXbox5 is a powerful environment for scripting and automation, there are some important limitations and considerations when it comes to directly programming with the Gemini API within maXbox5 itself:
Challenges:
Direct API Access:
maXbox5 is primarily designed for its own scripting language (based on Pascal) and system-level interactions. It doesn’t inherently have built-in support for making direct HTTP requests or handling complex JSON responses required by web APIs like the Gemini API.
Authentication:
Accessing the Gemini API requires authentication with API keys or OAuth tokens. Managing these securely and implementing the complex authentication protocols within maXbox5 would be quite challenging.
Complex Data Structures:
The Gemini API returns data in complex JSON formats, which maXbox5’s scripting language might not readily parse. You’d need to write custom parsing logic, which could become quite cumbersome.
External Libraries and Dependencies:
The most practical way to interact with the Gemini API is using a programming language with a suitable client library (e.g., Python’s google-generativeai library). maXbox5’s scripting environment doesn’t allow direct inclusion of these external libraries.
Performance:
If you tried to handle all API requests and response processing directly within maXbox5’s scripting, performance might become a concern, especially for larger or more complex interactions.
How You Could Potentially Integrate (with Limitations):
Given the limitations, directly calling the Gemini API from within maXbox5’s scripts isn’t the most practical approach. Here’s how you could theoretically integrate them, but with significant limitations:
Using External Executables or Scripts:
Python Script: You could write a separate Python script that uses the google-generativeai library to interact with the Gemini API. The script would accept input arguments and return results.
maXbox5 Calls: Your maXbox5 script could then use the ExecuteProcess function (or similar) to call this external Python script, passing data via command-line arguments.
Parsing Results: You’d need to parse the output from the Python script (likely in JSON format) back into a format that maXbox5 can use. This would involve string manipulation and potentially some custom parsing functions.
// maXbox5 script example (VERY SIMPLIFIED): var PythonScript: string; Prompt : string; Output: string; Cmd : string; begin PythonScript := 'C:\path\to\your\gemini_script.py'; Prompt := 'Write a short poem about flowers'; Cmd := Format('%s "%s"', [PythonScript, Prompt]); Output := ExecuteProcess(Cmd, nil); if Output <> '' then begin writeln('Output from Python: ', Output); // parse the output for needed values end; end;content_copydownloadUse code with caution.Maxscript
Using HTTP GET/POST (Very Complicated):
You could potentially use the HTTP functions (if available in maXbox5) to try and construct direct HTTP requests to the Gemini API.
JPostDat:= '{'+
'"contents": [{'+
'"parts": [{"text": "%s"}]'+
'}]}';
with TRestClient.create(self) do begin
rest:= Resource('https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key='
+GEMINI_APIKEY);
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.createstring(format(JPostDat,[askstream]))));
However, this would involve complex manual construction of HTTP headers, JSON data, handling authentication tokens, and processing the responses. This would be incredibly complex and error-prone. I wouldn’t recommend it.
Why It’s Not Recommended:
Complexity: The integration approach is quite complex. It would involve a considerable amount of custom coding and is far from being a natural fit for maXbox5’s intended use.
Maintenance: This setup becomes brittle and difficult to maintain. If the Gemini API changes, you would likely need to update both the Python script and your maXbox5 script.
Performance: The overhead of executing external processes, parsing data, etc., would negatively impact the performance of your automation.
Security Risks: Hardcoding credentials within scripts, even in external ones, poses security risks.
Best Approach:
If your goal is to use the Gemini API for scripting and automation tasks, it’s highly recommended to use a more suitable scripting language like Python, Delphi or JavaScript, which offer excellent libraries for interacting with web APIs like the Gemini API and much better JSON handling capabilities.
Conclusion:
While you could technically try to integrate maXbox5 with the Gemini API through external scripts or direct HTTP requests, it’s not a practical or efficient approach. MaXbox5 is best used for its core strengths in system automation and scripting with its own internal environment. For interacting with complex APIs like the Gemini API, other languages and ecosystems are better suited.
If you can share what kind of task you’re trying to accomplish, I can suggest better tools and approaches.thumb_upthumb_down
8.1s
JSON Testtemplate
const JSONGEMINI_TEST =
' { '+LF+
' "candidates": [ '+LF+
' { '+LF+
' "content": { '+LF+
' "parts": [ '+LF+
' { '+LF+
' "text": "The Earth is blue because of the oceans. Water absorbs longer wavelengths of light, '+LF+
' like red and yellow, and reflects shorter wavelengths, like blue. Since the Earth''s surface is '+LF+
' about 70% water, the blue light reflected from the oceans dominates the light we see from space, '+LF+
' making the planet appear blue." '+LF+
' } '+LF+
' ], '+LF+
' "role": "model" '+LF+
' }, '+LF+
' "finishReason": "STOP", '+LF+
' "avgLogprobs": -0.10744373122258, '+LF+
' "parts": null '+LF+
' } '+LF+
' ], '+LF+
' "usageMetadata": { '+LF+
' "promptTokenCount": 6, '+LF+
' "candidatesTokenCount": 67, '+LF+
' "totalTokenCount": 73 '+LF+
' }, '+LF+
' "modelVersion": "gemini-1.5-flash" '+LF+
'} ';
getGemini AI__________________:
@addr:TRestResource@AA15A2B0
@addr:TRestClient@B0861030 response cont: {
"candidates": [
{
"content": {
"parts": [
{
"text": "The Italian word \"conclusione\" translates to **Schlussfolgerung** or **Fazit** in German. Both words convey the idea of a conclusion, but there's a subtle difference:\n\n* **Schlussfolgerung** emphasizes the process of drawing a conclusion, the reasoning leading to it. It's more formal.\n\n* **Fazit** is a more concise summary of the main points, the final statement. It's often used in a less formal context.\n\nSo, depending on the context of the Italian \"conclusione,\" either \"Schlussfolgerung\" or \"Fazit\" could be the best translation.\n"
}
],
"role": "model"
},
"finishReason": "STOP",
"avgLogprobs": -0.10391504961745184
}
],
"usageMetadata": {
"promptTokenCount": 11,
"candidatesTokenCount": 133,
"totalTokenCount": 144
},
"modelVersion": "gemini-1.5-flash"
} response code: 200 enabled compression True content-encoding: verifycert: True
The General MIDI specification defines 128 instruments, and 47 percussion sounds. All channels except channel 9 (counting from zero) play instruments, channel 9 plays percussion sounds, with different note numbers resulting in different sounds. The MIDI standard itself does not define any instruments or percussion sounds.
Other specifications (General MIDI 2, GS, XG etc.) define more sounds, and have mechanisms to select which channel(s) to use for percussion sounds.
So first we set our Midi Controller or Device:
var note: TMidinote;
tmidi: TJclMIDIOut;
fMidiOut: IJclMidiOut;
fChannel: TMidiChannel;
mlist:= THashedStringList.create;
GetMidiOutputs(mlist); //check for midi devices
writeln(mlist.text)
mlist.free;
fmidiout:= MIDIOut(0);
//fmidiout.SendMessage(const Data: array of Byte);
fmidiout.SwitchPolyModeOn(16);
writ(fmidiout.getname);
fmidiout.SendNoteOn(2, note+36, $7f); //test tone
So we set an interface from IJclMidiOut and we get an instance of JclWinMIDI.MIDIOut(DeviceID);
type
TJclWinMidiOut = class(TJclMidiOut, IJclWinMidiOut)
function MidiOut(DeviceID: Cardinal): IJclWinMidiOut;
procedure GetMidiOutputs(const List: TStrings);
procedure MidiOutCheck(Code: MMResult);
We can see our device as Microsoft GS Wavetable Synth
This tune is from a G Phrygian and the key of G Phrygian has a key signature of 3 flats (B♭, E♭, and A♭). In our notation its a sharp so A♭ is a g#.
PlayTune is a procedure which calls the midi device and controller in the following way:
procedure PlayTune(tune: array of string;pause: integer;octave: byte;fin: boolean;fmidi: IJclMidiOut);
var i, anote: integer;
begin
for i:= 0 to High(tune) do begin
anote:= StrtoMIDINote2(tune[i],octave);
fmidi.SendNoteOn(2, anote, $7f);
delay(pause)
fmidi.SendNoteOff(2, anote, $7f);
end;
if fin then sleep(1500);
end;
We send note on and off messages in a sequence and we pass the device as fmidi. Noteon (i-rate note on) and noteoff (i-rate note off) are the simplest MIDI OUT opcodes. noteon sends a MIDI noteon message to MIDI OUT port, and noteoff sends a noteoff message. A noteon opcode must always be followed by an noteoff with the same channel and number inside the same instrument, otherwise the note will play endlessly. So we can also change the instrument in passing a midi channel and the instrument id:
To get a midi note we call the function StrtoMIDINote2(tune[i],octave); function StrtoMIDINote2(Notestr: string; octave: byte): TMIDINote;
This conv.implementation assumes that the input string is in the format ‘NoteOctave’ (e.g., ‘C4’, ‘F#3’, ‘B5’,A4). It handles both sharp notes (with ‘#’) and natural notes but not flats one. If an invalid note is provided, the function returns -1.
It converts a string representation of a musical note to its corresponding MIDI note number. Here’s an implementation: This function does the following:
It defines a constant arrayof note names. mnotes:= [‘C’,’C#’,’D’,’D#’,’E’,’F’,’F#’,’G’,’G#’,’A’,’A#’,’B’];
It extracts the note name and octave from the input string. NoteName := AnsiUpperCase(Copy(NoteStr, 1, Length(NoteStr) – 1)); Octave := StrToIntDef(Copy(NoteStr, Length(NoteStr), 1), 4);
It finds the index of the note in the Notes mnotes array by looping.
for I:= 0 to High(mNotes) do
if mNotes[I] = NoteName then begin
NoteIndex:= I;
write(mnotes[i]+' ')
Break;
end;
It calculates the MIDI note number using the formula: (Octave + 1) * 12 + NoteIndex.
The Windows implememtation of the IJclWinMidiOut interface (not to confuse with the MIDI hardware interface) defines also stereo channels (not to confuse with a midi channel) with volume controls by both sides:
type
TStereoChannel = (scLeft, scRight);
// MIDI Out Definition
IJclWinMidiOut = interface(IJclMidiOut)
['{F3FCE71C-B924-462C-BA0D-8C2DC118DADB}']
// property access methods
function GetChannelVolume(Channel: TStereoChannel): Word;
procedure SetChannelVolume(Channel: TStereoChannel; const Value: Word);
function GetVolume: Word;
procedure SetVolume(const Value: Word);
// properties
property ChannelVolume[Channel: TStereoChannel]: Word read GetChannelVolume write SetChannelVolume;
property Volume: Word read GetVolume write SetVolume;
end;
In music theory, the circle of fifths (sometimes also cycle of fifths) is a way of organizing pitches as a sequence of perfect fifths. Starting on a C, and using the standard system of tuning for Western music (12-tone equal temperament).
So we always start with C-Major and add an note-offset of 7 (a quint):
//g - a - h ^ c - d - e - fis ^ g G-Dur
playTune2(['c4','d4','e4','f4','g4','a4','b4','c5'],300,7,true,fmidiout);
//d - e - fis ^ g - a - h - cis ^ d D-Dur
playTune2(['c4','d4','e4','f4','g4','a4','b4','c5'],300,14,true,fmidiout);
//a - h - cis ^ d - e - fis - gis ^ a A-Dur
PlayTune2(['c4','d4','e4','f4','g4','a4','b4','c5'],300,21,true,fmidiout);
//e - fis - gis ^ a - h - cis - dis ^ e E-Dur
//https://de.wikipedia.org/wiki/E-Dur
playTune2(['c4','d4','e4','f4','g4','a4','b4','c5'],300,28,true,fmidiout);
The code is straight and based on conversions with StrtoMIDINote3(tune[i], offset); to set the offset and octave. This conversion as an array of string implementation assumes that the input string is in the format ‘NoteOctave’ (e.g., ‘C4’, ‘F#3’, ‘B5’,A4) and calls a function StrtoMIDINote3 within the procedure PlayTune2():
function StrtoMIDINote3(Notestr: string; offset: byte): TMIDINote;
var i: integer;
NoteName: string;
Octave, NoteIndex: Integer; note:TMidinote;
begin
mnotes:=['C','C#','D','D#','E','F','F#','G','G#','A','A#','B']; //+
NoteName:= AnsiUpperCase(Copy(NoteStr,1, Length(NoteStr)- 1));
Octave:= StrToIntDef(Copy(NoteStr,Length(NoteStr), 1), 4);
// Find note index
NoteIndex:= -1;
for I:= 0 to High(mNotes) do
if mNotes[I] = NoteName then begin
NoteIndex:= I+offset;
Break;
end;
// Calculate MIDI note number & display
if NoteIndex <> -1 then begin
Result:= (Octave+1)*12 + NoteIndex
write(midiNotetostr(result+12)+'('+itoa(result)+')'+' ');
end else
Result:= -1; // Invalid note
end;
procedure PlayTune2(tune: array of string; pause,offset: integer; fin:boolean; fmidi: IJclMidiOut);
var i, anote: integer;
begin
for i:= 0 to High(tune) do begin
anote:= StrtoMIDINote3(tune[i], offset);
fmidi.SendNoteOn(2, anote, $7f);
delay(pause)
fmidi.SendNoteOff(2, anote, $7f);
end;
if fin then sleep(1500);
writeln(CRLF);
end;
For the sake of simplicity, the examples shown above are formed by natural notes (also called “white notes”, as they can be played using the white keys of a piano keyboard). However, any transposition of each of these scales is a valid example of the corresponding mode.
Object Detection APIs and Libraries provides a fast and accurate image object recognition using advanced neural networks developed by machine learning experts and models. It also supports object detection, video detection and object tracking using RetinaNet, YOLOv3 and TinyYOLOv3 pre-trained on datasets.
As we can see the algorithm, data and the result is distributable and scalable:
Algorithm (model) Data (image) Result (Json) Tech 1. local - local - local python core 2. cloud - local - local/cloud post API 3. cloud - cloud - local/cloud get API 4. cloud - cloud - local rest API
The first solution starts with tiny-yolov3.pt model from imagai:
'#using the pre-trained TinyYOLOv3 model,
detector.setModelTypeAsTinyYOLOv3()
detector.setModelPath(model_path)
'#loads model path specified above using setModelPath() class method.
detector.loadModel()
custom=detector.CustomObjects(person=True,laptop=True,car=False,train=True, clock=True, chair=False, bottle=False, keyboard=True)
S.A.C.M. Elsässische Maschinenbauanstalt Graffenstaden C-Kuppler (2x) – Baujahr 1900The reference image for the solutions
Result: Start with maXbox5 ImageAI Detector —> this first line fine person : 99.29 % person : 99.58 % person : 98.74 % integrate image detector compute ends… elapsedSeconds:= 4.686975000000 – no console attached.. mX5🐞 executed: 29/07/2024 10:09:30 Runtime: 0:0:7.948 Memload: 77% use
You can see one false positive in the green bounding box above!
const URL_APININ_DETECT= 'https://api.api-ninjas.com/v1/objectdetection/';
function TestHTTPClassComponentAPIDetection2(AURL, askstream, aApikey: string): string;
var HttpReq1: THttpRequestC;
Body: TMultipartFormBody;
Body2: TUrlEncodedFormBody; //ct: TCountryCode;
begin
Body:= TMultipartFormBody.Create;
Body.ReleaseAfterSend:= True;
//Body.Add('code','2','application/octet-stream');
//Body.AddFromFile('image', exepath+'randimage01.jpg');
Body.AddFromFile('image',
'C:\maxbox\maxbox51\examples\1316_elsass_20240728_resized.jpg');
HttpReq1:= THttpRequestC.create(self);
httpreq1.useragent:= USERAGENT3;
httpReq1.headers.add('X-Api-Key:'+AAPIKEY);
httpReq1.headers.add('Accept:application/json');
hthtpReq1.SecurityOptions:= [soSsl3, soPct, soIgnoreCertCNInvalid];
try
if HttpReq1.Post1Multipart(AURL, body) then
result:=HttpReq1.Response.ContentAsString
else Writeln('APIError '+inttostr(HttpReq1.Response.StatusCode2));
finally
writeln('Status3: '+gethttpcod(HttpReq1.Response.statuscode2))
HttpReq1.Free;
sleep(200)
// if assigned(body) then body.free;
end;
end;
This result is a post from a multipartform body stream and you need an API key, then the result is a JSON back, as you can see, we need a call to HttpReq1.Post1Multipart for uploading files.: POST data using the Content-Type multipart/form-data
The third solution wants to get the text back from the image. The Image to Text API detects and extracts text from images using state-of-the-art optical character recognition (OCR) algorithms. It can detect texts of different sizes, fonts, and even handwriting on pictures or draws.
Built with simplicity in mind, ImageAI supports a list of state-of-the-art Machine Learning algorithms for image prediction, custom image prediction, object detection, video detection, video object tracking and image predictions trainings. ImageAI currently supports image prediction and training using 4 different Machine Learning algorithms trained on the ImageNet-1000 dataset. ImageAI also supports object detection, video detection and object tracking using RetinaNet, YOLOv3 and TinyYOLOv3 trained on COCO dataset. Finally, ImageAI allows you to train custom models for performing detection and recognition of new objects. https://github.com/OlafenwaMoses/ImageAI
Recognizes and reads the text embedded in images very accurare and usable. Image to Text API uses a neural net (LSTM) based OCR engine which is focused on line recognition, but also supports recognizing the character patterns. It supports both handwriting and printed materials. It will extract the text information easily, even though the text or number is positioned with angle, like Berthold. https://apilayer.com/marketplace/image_to_text-api
The Requests library in Python is one of the integral parts of Python for making HTTP requests to a specified URL as post or get. Whether it be REST APIs or Web Scraping, requests are a must to be learned for proceeding further with these technologies.
Out of the examples above but also mention it: The Face Detect API uses state of the art computer vision algorithms to accurately and efficiently detect faces in images. https://api-ninjas.com/api/facedetect
After you got you API-Key (API Key associated with your account) we need a httpcomponent of classes which are enable to post multipart-formdata-feed or streams. An HTTP multipart request is an HTTP request that HTTP clients construct to send files and data over to an HTTP Server. It is commonly used by browsers and HTTP clients to upload files to the server.
The content type “multipart/form-data” should be used for submitting forms that contain files, non-ASCII data, and binary data combined in a single body.
Live Deno of the API
So a multipart request is a request containing several packed requests inside its entity and we can script that:
const URL_APILAY_DETECT = 'https://api.api-ninjas.com/v1/objectdetection/';
function TestHTTPClassComponentAPIDetection2(AURL, askstream, aApikey: string): string;
var HttpReq1: THttpRequestC;
Body: TMultipartFormBody;
Body2: TUrlEncodedFormBody;
begin
Body:= TMultipartFormBody.Create;
Body.ReleaseAfterSend:= True;
//Body.Add('code','2','application/octet-stream');
Body.AddFromFile('image', exepath+'randimage01.jpg');
HttpReq1:= THttpRequestC.create(self);
HttpReq1.headers.add('X-Api-Key:'+AAPIKEY);
HttpReq1.headers.add('Accept:application/json');
try
if HttpReq1.Post1Multipart(AURL, body) then
writeln(HttpReq1.Response.ContentAsString)
else Writeln('APIError '+inttostr(HttpReq1.Response.StatusCode2));
finally
writeln('Status3: '+gethttpcod(HttpReq1.Response.statuscode2))
HttpReq1.Free;
sleep(200)
// if assigned(body) then body.free;
end;
end;
print(TestHTTPClassComponentAPIDetection2(URL_APILAY_DETECT,' askstream',N_APIKEY));
The result returns a return a list of detected objects labels, confidence percentages and bounding boxes. Objects with confidence less than 0.3 (30%) are filtered out.
Discussion: Yeah the machine learnings got the person with high confidence and the surfboard is more likely than the skis, which are out of probability context; I mean do you see any sea or snow?!
mX5🐞 executed: 27/04/2024 10:21:59 Runtime: 0:0:6.160 Memload: 74% use RemObjects Pascal Script. Copyright (c) 2004-2024 by RemObjects Software & maXbox5
To discuss a distributed and dependent software we need a code schema as a template for example a routine which counts words distributed in a text:
function CountWords_(const subtxt: string; Txt: string): Integer;
begin
if (Length(subtxt)=0) Or (Length(Txt)=0) Or (Pos(subtxt,Txt)=0) then
result:= 0
else
result:= (Length(Txt)- Length(StringReplace(Txt,subtxt,'',
[rfReplaceAll]))) div Length(subtxt);
end;
We can show that the function itself uses other functions from libraries to fullfill the main topic as count or search words in a text, so data (words) and functions are distributed and dependent to each other.
Also a code contract as a precondition makes sure to get valuable data with an if statement:
function CountWords__(const subtxt:string; Txt:string): Integer;
begin
if (len(subtxt)=0) or (len(Txt)=0) or (Pos(subtxt,Txt)=0) then
result:= 0
else
result:= (len(Txt)- len(StringReplace(Txt,subtxt,'',
[rfReplaceAll]))) div len(subtxt);
end;
An optimization to operate with or and len in the function above.
function HTTPClassComponentAPIDetection2(AURL,askstream,aApikey:string): string;
var HttpReq1: THttpRequestC;
Body: TMultipartFormBody;
Body2: TUrlEncodedFormBody; //ct: TCountryCode;
begin
Body:= TMultipartFormBody.Create;
Body.ReleaseAfterSend:= True;
//Body.Add('code','2','application/octet-stream');
Body.AddFromFile('image',
'C:\maxbox\maxbox51\examples\TEE_5_Nations_20240402.jpg');
HttpReq1:= THttpRequestC.create(self);
HttpReq1.headers.add('X-Api-Key:'+AAPIKEY);
HttpReq1.headers.add('Accept:application/json');
HttpReq1.SecurityOptions:= [soSsl3, soPct, soIgnoreCertCNInvalid];
try
if HttpReq1.Post1Multipart(AURL, body) then
writeln(HttpReq1.Response.ContentAsString)
else Writeln('APIError '+inttostr(HttpReq1.Response.StatusCode2));
finally
writeln('Status3: '+gethttpcod(HttpReq1.Response.statuscode2))
HttpReq1.Free;
sleep(200)
// if assigned(body) then body.free;
end;
end;
Distributed Time App
10
DayTime protocol is not the NTP protocol. DayTime uses port 13, not 37. 37 is used by the Time protocol, which, again, in not the NTP protocol, which uses 123 (UDP). I do not know if time.windows.com supports the DayTime and Time protocols, the most common used protocols to get time from a reliable time source nowadays is NTP, and its simpler sibling SNTP, which superseded both DayTime and Time protocols.
var ledTimer2: TTimer;
ledLbl2: TLEDNumber;
procedure CloseClickCompact(Sender: TObject; var action: TCloseAction);
begin
if ledTimer2 <> Nil then begin
ledTimer2.enabled:= false;
ledTimer2.Free;
ledTimer2:= Nil;
end;
action:= caFree;
writeln('compact timer form close at '+FormatDateTime('dd/mm/yyyy hh:nn:ss', Now));
end;
procedure updateLED2_event(sender: TObject);
begin
ledLbl2.caption:= TimeToStr(time);
end;
procedure loadcompactTimeForm;
var frm: TForm;
begin
frm:= TForm.create(self);
frm.Setbounds(10,10,400, 300)
frm.onclose:= @CloseClickCompact;
frm.icon.loadfromresourcename(hinstance, 'TIMER2');
frm.color:= clblack;
frm.show;
ledlbl2:= TLEDNumber.create(Frm)
with ledlbl2 do begin
Parent:= Frm;
setBounds(35,140,350,100)
caption:= TimeToStr(time);
columns:= 10;
size:= 3;
end;
ledtimer2:= TTimer.create(self);
ledtimer2.interval:= 1000;
ledtimer2.ontimer:= @updateLED2_event;
end;
const
ArgInstallUpdate = '/install_update';
ArgRegisterExtension = '/register_global_file_associations';
procedure SetSynchroTime;
var mySTime: TIdSNTP;
begin
mySTime:= TIdSNTP.create(self);
try
mySTime.host:='0.debian.pool.ntp.org';
writeln('the internettime '+
datetimetoStr(mystime.datetime));
// needs to be admin & elevated
writeln('IsElevated '+ botostr(IsElevated));
writeln(Format('IsUACEnabled: %s',[BoolToStr(IsUACEnabled, True)]));
writeln('run elevated: '+itoa(SetLastError(RunElevated(ArgInstallUpdate, hinstance, nil))));//Application.ProcessMessages));
if mySTime.Synctime then begin
writeln('operating system sync now as admin & elevated!');
Speak('System time is now sync with the internet time '+TimeToStr(time))
end;
finally
mySTime.free;
end;
end;
TIdSNTP.SyncTime() uses the Win32 SetLocalTime() function, which requires the calling process to have the SE_SYSTEMTIME_NAME privilege present in its user token (even if it isnot enabled, it just needs to be present – SetLocalTime() will enable it for the duration of the call). By default, only an elevated admin has that privilege present in its token. So, you will have to either run your whole app as an elevated user, or at least split out your sync code into a separate process or service that runs as an elevated admin or the SYSTEM account.
Triemli I + IITEE InsideSolution Finder Solution FinderBuild Info V 5.1.4.98 IVFS and SNCF
Special 95 et 105Locomotive LEMACO H0-097/2 SNCF CC 40108Version 5.1.4.98 VIVersion 5.1.4.98 VIILast Teaching List LTLVirus Total Top VTTTeach the ToolInternet of Things 2024Teaching at IPSO Baselmy clock rock
V5.1.4.98 IX – 3720 Units ExecuteGLPanel ExecuteidWebSocket uPSI_ExecuteGLPanel uPSI_ExecuteidWebSocket Winapi.OpenGL Winapi.OpenGLext
25.05.2024 17:18
Release Notes maXbox 5.1.4.98 IX May 2024 Ocean950 SHA1: 5.1.4.98 IX maXbox5.exe d5e5728f0dbfe563ffb8960341cee4949aa6fa31 SHA1: ZIP maxbox5.zip ABF343E710050CC4C3C0276E2815F7C908C8DC6E https://archive.org/details/maxbox5
maXbox AgendaBale last Teaching HelvetiaCrypto BoxDistributed Software Development
Start with maXbox5 ImageAI Detector —> this first line fine person : 99.97 person : 99.98 person : 99.87 person : 99.83 person : 99.87 person : 99.78 person : 99.51 person : 99.82 integrate image detector compute ends…
elapsedSeconds:= 4.415644700000 debug: 8-I/O error 105 0 err:20 no console attached.. mX5🐞 executed: 13/06/2024 22:27:36 Runtime: 0:0:7.308 Memload: 66% use
The third solution wants to get the text back from the image. The Image to Text API detects and extracts text from images using state-of-the-art optical character recognition (OCR) algorithms. It can detect texts of different sizes, fonts, and even handwriting.
function Image_to_text_API2(AURL, url_imgpath, aApikey: string): string;
var httpq: THttpConnectionWinInet;
rets: TStringStream;
heads: TStrings; iht: IHttpConnection; //losthost:THTTPConnectionLostEvent;
begin
httpq:= THttpConnectionWinInet.Create(true);
rets:= TStringStream.create('');
heads:= TStringlist.create;
try
heads.add('apikey='+aAPIkey);
iht:= httpq.setHeaders(heads);
httpq.Get(Format(AURL,[url_imgpath]), rets);
if httpq.getresponsecode=200 Then result:= rets.datastring
else result:='Failed:'+
itoa(Httpq.getresponsecode)+Httpq.GetResponseHeader('message');
except
writeln('EWI_HTTP: '+ExceptiontoString(exceptiontype,exceptionparam));
finally
httpq:= Nil;
heads.Free;
rets.Free;
end;
end; //}
And the model is available to read the name of the Locomotive:
{“lang”:”en”,”all_text”:”18130\nBERTHOLD”,”annotations”:[“18130″,”BERTHOLD”]} mX5🐞 executed: 29/07/2024 11:04:12 Runtime: 0:0:3.527 Memload: 81% use
The forth and last solution in this machine learning package is a Python one as in Python for maXbox or Python4Delphi available:
procedure PyCode(imgpath, apikey: string);
begin
with TPythonEngine.Create(Nil) do begin
//pythonhome:= 'C:\Users\breitsch\AppData\Local\Programs\Python\Python37-32\';
try
loadDLL;
autofinalize:= false;
ExecString('import requests');
ExecStr('url= "https://api.apilayer.com/image_to_text/url?url='+imgpath+'"');
ExecStr('payload = {}');
ExecStr('headers= {"apikey": "'+apikey+'"}');
Println(EvalStr('requests.request("GET",url, headers=headers, data=payload).text'));
except
raiseError;
finally
free;
end;
end;
end;
Built with simplicity in mind, ImageAI supports a list of state-of-the-art Machine Learning algorithms for image prediction, custom image prediction, object detection, video detection, video object tracking and image predictions trainings. ImageAI currently supports image prediction and training using 4 different Machine Learning algorithms trained on the ImageNet-1000 dataset. ImageAI also supports object detection, video detection and object tracking using RetinaNet, YOLOv3 and TinyYOLOv3 trained on COCO dataset. Finally, ImageAI allows you to train custom models for performing detection and recognition of new objects.
This API recognizes and reads a text embedded in pictures or photos. Image to Text API uses a neural net (LSTM) based OCR engine which is focused on line recognition, but also supports recognizing the character patterns. It supports both handwriting and printed materials as well as street maps.
APILayer is an API marketplace where also your API can reach a broader audiences, but first you need an API-key for free:
First we need a picture to analyze, it was a photo for which I hadn’t the time to read the content:
Latinum Museum at Neuchâtel
We use WinHttp.WinHttpRequest, JSONObjects and TGraphics library with loading and testing the REST-client. Also we pass the API-key as a request-header, so get a key first at: https://apilayer.com/marketplace
Then you must upload your image and put the link in a constant for passing at the API:
The data represents is JSON data with all the text extracted and even the language of the text to scan is auto detected. Before we dive into code this is the main part of the script:
function Image_to_text_API2(AURL, url_imgpath, aApikey: string): string;
var httpq: THttpConnectionWinInet;
rets: TStringStream;
heads: TStrings; iht: IHttpConnection; //losthost:THTTPConnectionLostEvent;
begin
httpq:= THttpConnectionWinInet.Create(true);
rets:= TStringStream.create('');
heads:= TStringlist.create;
try
heads.add('apikey='+aAPIkey);
iht:= httpq.setHeaders(heads);
httpq.Get(Format(AURL,[url_imgpath]), rets);
if httpq.getresponsecode=200 Then result:= rets.datastring
else result:='Failed:'+
itoa(Httpq.getresponsecode)+Httpq.GetResponseHeader('message');
except
writeln('EWI_HTTP: '+ExceptiontoString(exceptiontype,exceptionparam));
finally
httpq:= Nil;
heads.Free;
rets.Free;
end;
end; //}
When you first call the API all the JSON encodings like \u0027 and \n or d\u00e9tecteur results (A JSON string must be double-quoted), so you need a stringify or parseJsonValue function to correct or escape d\u00e9tecteur to détecteur:
Or can you guess what’s this is: Il s’agit de d\u00e9p\u00f4ts\nd’objets m\u00e9talliques
Answer: Il s’agit de dépôts d’objets métalliques, dont l’existence est largement attestée à l’âge du Bronze.
If your programming language is not listed in the Code Example above, you can still make API calls by using a HTTP request library written in your programming language and following the above documentation.
This is an example in Python (Python4Delphi):
procedure PyCode(imgpath: string);
begin
with TPythonEngine.Create(Nil) do begin
pythonhome:= 'C:\Users\breitsch\AppData\Local\Programs\Python\Python37-32\';
try
loadDLL;
ExecString('import requests');
ExecStr('url= "https://api.apilayer.com/image_to_text/url?url='+imgpath+'"');
ExecStr('payload = {}');
ExecStr('headers= {"apikey": "dy5L70eQx72794XBZ8sewEgYTZR85_yourAPIKey"}');
Println(EvalStr('requests.request("GET",url, headers=headers, data=payload).text'));
except
raiseError;
finally
free;
end;
end;
end;
Image2Text or Image to Text live demo is providing an API service on its APILayer publication platform. Live Demo feature allows you to test the API within your browser; no need to install or code anything. You can modify all the parameters as you like and interact with the API from many languages.
The result can be (99.97%):
{"lang":"fr","all_text":"TSAPIENS Des rives du lac au pied du Chasseral: découvertes inédites de dépôts de l'âge du Bronze 10 La collaboration initiée depuis quelques années entre la section Archéologie de l'Office du patrimoine et de l'archéologie du canton de Neuchâtel (OPAN) et des prospecteurs amateurs a conduit à la découverte d'un type de sites rare dans notre région. Il s'agit de dépôts d'objets métalliques, dont l'existence est largement attestée à l'âge du Bronze à l'échelle européenne. Ces découvertes manifestent une complémentarité exemplaire entre professionnels et amateurs d'archéologie dans le cadre de projets explorant l'occupation du territoire neuchitelois à travers le temps.
LS Models & HAGSt. Gallen Queen LocomotionCode AI Generator ChallengeV 5.1.4.95 Release\maxbox5\1234_NeuralNetwork2_XOR_sampleEU_EKON27_64.pas File storedLiliput 1042 VintageLiliput 1042CC 6500 50 Ans
QR Code Generator API
The QRCode API generates custom QR codes for any content. It supports custom colors, size, and several image formats.
function GEO_getQRCode(AURL, aformat, adata, aApikey: string): string;
var httpq: THttpConnectionWinInet;
rets: TMemoryStream;
heads: TStrings; iht: IHttpConnection;
begin
httpq:= THttpConnectionWinInet.Create(true);
rets:= TMemoryStream.create;
heads:= TStringlist.create;
try
heads.add('X-Api-Key='+aAPIkey);
heads.add('Accept= image/png');
iht:= httpq.setHeaders(heads);
httpq.Get(Format(AURL,[aformat, adata]), rets);
if httpq.getresponsecode=200 Then begin
writeln('size of '+itoa(rets.size));
rets.Position:= 0;
//ALMimeBase64decodeStream(rets, rets2)
rets.savetofile((exepath+'qrcodeimage.png'));
openfile(exepath+'qrcodeimage.png');
end
else result:='Failed:'+
itoa(Httpq.getresponsecode)+Httpq.GetResponseHeader('message');
except
writeln('EWI_HTTP: '+ExceptiontoString(exceptiontype,exceptionparam));
finally
httpq:= Nil;
heads.Free;
rets.Free;
end;
end; //}
The heads.add(‘Accept= image/png’); is important, if you don’t set this request you have to put the stement ALMimeBase64decodeStream(rets, rets2) woth a second memorystream to get image format you want.
Sometimes life is like playing with us: You write some code that solves a problem, and then someone comes along and makes the problem harder. Here’s how to continuously integrate new solutions without having to rewrite your old solutions (as much).
Let’s start with a simple problem: You’ve written and testing a class that returns a QR-Code from a text line:
procedure QRCcode(apath:string; atext: string); var aQRCode: TDelphiZXingQRCode; QRCodBmp: TBitmap; Jpg: TJpegImage; Row,Column,err: Integer; res: Boolean; //HRESULT; var form1: TForm; begin aQRCode:= TDelphiZXingQRCode.Create; QRCodBmp:= TBitmap.Create; form1:= getform2(700,500,123,'QR Draw PaintPerformPlatform PPP5'); try aQRCode.Data:= atext; aQRCode.Encoding:= qrcAuto; //TQRCodeEncoding(cmbEncoding.ItemIndex); //aQRCode.QuietZone := StrToIntDef(edtQuietZone.Text, 4); QRCodBmp.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 QRCodBmp.Canvas.Pixels[Column,Row]:= clBlack else QRCodBmp.Canvas.Pixels[Column,Row]:= clWhite; end;
That class is currently used by a single application in a scripting environment. Inside the class you might have Delphi.VCL Java.FX or ADO.NET code or LINQ/Entity Framework code, but either way, you’re accessing an internal component on your operating system on your desktops hard-disk.
Then you realize that, because your component data/algorithm doesn’t change very often, as long as you don’t update or rebuild your component, so your are not up to date with newer features like encoding or error correcting level.
This leads to a second solution of an external service call like Google Chart Tools. 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 hard-links or physical world hyperlinks.
The Google Chart Tools also let you generate QR-code images using an HTTP POST or short messages. All do you need to generate a Qr-Code is make a get request to this URI:
cht=qr this tells Google to create a QR code; chld=M the error correction level of the QR code (more later); chs=wxh the width and height of the image to return (e.g. chs=250×250); chl=text the URL encoded text to be inserted into the qr-code.
As the URL is https with a certificate, an application can identify himself and authenticate himself to any organization trusting the third party.
The second thing to consider is that (I assume) if the web service object is working right we can compare the resulting picture with the first solution. So lets make the call with WinInet Win-API:
So what’s the meaning of the SHA1 hash? For this we compare with a third solution of internet-call with the Indy10 framework. In comparison with Wininet as the internal WinAPI library, Indy is an external library also based on OpenSSL and we compare the result to get the same hash:
//2. Indy 10 Socks Lib -GoogleAPI procedure GetQrCodeIndy(Width,Height: Word; C_Level,apath: string; const Data: string); var encodURL: string; idhttp: TIdHttp;// THTTPSend; pngStream: TMemoryStream; begin encodURL:= Format(URLGoogleQRCODE,[Width,Height,C_Level, HTTPEncode(Data)]); idHTTP:= TIdHTTP.Create(NIL) pngStream:= TMemoryStream.create; idHTTP.Get1(encodURL, pngStream) //writeln(idHTTP.Get(encodURL)); //Exception: if not Dll-Could not load SSL library. at 827.447 try pngStream.Position:= 0; writeln(itoa(pngStream.size)); pngStream.savetofile(apath); sleep(500); OpenDoc(apath); finally idHTTP.Free idHTTP:= Nil; pngStream.Free; end; end;
As I said we need two DLLs to support the OpenSSL lib; provided OpenSSL is installed in your system. The call arguments are the same so we get the same hash back:
In cryptography, PKCS #12 defines an archive file format for storing many cryptography objects as a single file. It is commonly used to bundle a private key with its X.509 certificate or to bundle all the members of a chain of trust.
multicode in hybridcode
pic1: tutor119_signobjectscreen_6.png
You can either sign files out of a working directory, or you can place them in your Windows SDK\bin folder or key store.
Source Organisation for Multicode
This separation of now three solutions is reflected in a number of ways. The most important distinction is that the code schema for developers in the script division has now 3 folding sections and can be different from a current configuration design:
1. Solution 1 with the internal class needs no https and component.
2. Solution 2 is dependent from external Google API and based on internal OS WinInet.
3. Solution 3 is also dependent on Google but has its own internet suite as Indy 10 but dependent on OpenSSL.
This we should consider and document in our source code repository:
BDS 22.0
pic2: tutor119_catrepo.png
The interesting point is to know where the code is running and how it is stored in the executable or script itself. Embedding Wininet as one function is nice: HttpGet(encodURL, pngStream);//WinInet, but you don’t have the flexibility to change for example request- or response-headers of the external web service you consume, so we test a forth solution in detail also to debug with more verbosity:
//4. Internal Class mXLib5 -GoogleAPI
procedure GetQrCodeWininetClass(Wid,Hei:Word; C_Level,apath:string; const Data:string); var httpR: THttpConnectionWinInet;
procedure GetQrCodeWininetClass(Wid,Hei:Word; C_Level,apath:string; const Data:string); var httpR: THttpConnectionWinInet; ms: TMemoryStream; heads: TStrings; iht:IHttpConnection; //losthost: THTTPConnectionLostEvent; begin httpr:= THttpConnectionWinInet.Create(true); ms:= TMemoryStream.create; try //iht:= httpRq.setHeaders(heads); httpR.Get(Format(URLGoogleQRCODE,[Wid,Hei,C_Level,HTTPEncode(Data)]),ms); //httpRq.setRequestheader('x-key',aAPIkey); if httpr.getresponsecode=200 Then begin ms.Position:= 0; ms.savetofile(apath); sleep(500); OpenDoc(apath) end Else writeln('Failed responsecode:'+ itoa(HttpR.getresponsecode)); except //writeln('Error: '+HttpRq.GetResponseHeader('')); writeln('EHTTP: '+ExceptiontoString(exceptiontype, exceptionparam)); finally httpr:= Nil; ms.Free; end; end;
Therefore we can or must parametrize the handler procedure, in order to have a possibility of indicating the type of request.
This is the good old Wininet API but this time as an object oriented class with methods and attributes, for example to check the response code of the get request. Also in this mapped import library we get the same hash: intern: FE526D46BA48DFD820276872C969473A7B7DE91C
My goal in refactoring or recoding is to supply “enough engineering” to support the current problem without over-engineering a solution to some later problem that might never exist. Said it another way: A solution is never more complicated than the problem it’s solving. But you know it can be the other way round for example in cryptography: Simple problem but complex solution.
The fifth solution is tricky and only in an interpreted script possible, we call the second solution pre-compiled as one function.
5 Solutions Overview
Internal QR-Component Class mXLib5 TDelphiZXingQRCode
External call of script with procedure WinInet & Google API
External call of script with Indy class & Google API
Internal call of THttpConnectionWinInet class of external API
Internal call direct in script (precompiled): GetQrCode5(150,150,’Q’,QDATA, ExePath+AFILENAME);
The Mystery of solution 6 and 7
To be really independent from internal calls and run just on runtime a late binding solution can be considered.
Early (or static) binding refers to compile time binding as before and late (or dynamic) binding refers to runtime binding (for example when you use reflection or retyping).
Late binding uses CreateObject to create and instance of the application object, which you can then control. For example, to create a new instance of WinHttp.WinHttpRequest.5.1 using late binding in our sixth solution:
function QRCcodeOle(Wid,Hei:Word; C_Level,apath:string; const Data:string): string; var httpReq,hr: Olevariant; instream: IStream;
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;
This 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 the binary QR-code image file as a *.png graphic image).
REgEx as multicode
Pic3: tutor119_regex_multicod.png
The Crux is the getmemStreamfromIStream2 function. 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;
And the last one as solution 7 catches everything from external even the language and library, its a Python for Delphi Solution (P4D):
procedure PYdigitQRCode;
procedure PYdigitQRCode; begin with TPythonEngine.Create(Nil) do begin pythonhome:= 'C:\Users\user\AppData\Local\Programs\Python\Python312\'; //SetPythonHome; //pythonpath OnPathInitialization:= @TPathInitialization; try loadDLL; //opendll(PYDLL64) execstr('import sys, os, json, qrcode'); println(EvalStr('sys.version')); println(EvalStr('sys.executable')); execstr('qr=qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_Q)'); execstr('qrcode.make("'+QDATA+'").save(".\examples\'+AFILENAME+'")'); // println('is posix '+EvalStr('lib_platform.is_platform_posix')); except raiseError; finally unloadDll; free; end; end; //with end;
>>>3.12.1 (tags/v3.12.1:2305ca5, Dec 7 2023, 22:03:25) [MSC v.1937 64 bit (AMD64)]
As a standard install uses pypng to generate PNG files and can also render QR codes directly to the console. A standard install is just:
pip install qrcode;
Just for the record, found another solution as solution eight with an Aduino Board to send the text and get an bitmap back (in this context below only as a serial monitor graph):
for (uint8_t y = 0; y < qrcode.size; y++) { // Left quiet zone Serial.print(" "); // Each horizontal module for (uint8_t x = 0; x < qrcode.size; x++) {
// Print each module (UTF-8 \u2588 is a solid block) Serial.print(qrcode_getModule(&qrcode, x, y) ? "\u2588\u2588":" "); } Serial.print("\n"); } // Bottom quiet zone Serial.print("\n\n\n\n"); }
void loop() { }
QRCode Generator on a Microprocessor Aruino UnoOutput to Serial Monitor with each module (UTF-8 \u2588 is a solid block)!Connect to Arduino UNO with Async Pro
Conclusion
When it comes to problem-solving, there are often multiple solutions that can be used to solve the same problem. The choice of solution depends on various factors such as performance, storage, correctness, implement-ation, simplicity, and also scaleability and security.
The Google Chart Tools (Chart API) also let you generate QR-code images using an HTTP POST call. A Quick Response code is a two-dimensional pictographic code used for its fast readability and comparatively large storage capacity.
Early binding refers to assignment of values to variables during design time whereas late binding refers to assignment of values to variables during run time as a concept of multicode programming. Implemented often using [special] dynamic types, introspection /reflection, flags and compiler options, or through virtual methods by borrowing and extending dynamic dispatching.
Then you test the connection and open Table1 in the viewer:
64 bit in view for modify
Microsoft ODBC Driver for Access and SQL Server is a crucial component for developing native-code applications that connect to SQL Server and Azure SQL Database. It provides runtime support for applications using native code APIs to establish connections with SQL Server.
LS 6503 & LS 6535Cité du TrainJouef CC 6511 & 6512
Game of Life Sequence
Game of Life Cellular SequenceArnold NFleischmann BR 103 242
XN Resource Editor
Based on the latest publicly available sources of Colin Wilson’s XN Resource Editor.
In our clock we are going to represent each of the six digits used for hours, minutes and seconds as a binary number. Since each number represents a single decimal digit, we will need 4 binary digits for each. The maximum number we can represent with three binary digits (bits) is 111 which is 4+2+1=7 and we will also need to show bit representation of 8 and 9, thus the need for four.
To match the hardware version of the clock, I represent the numbers vertically with the top LED representing “8” . So, using “light off” for 0 and “light on” for 1, the clock above represents 09:50:34.
Binary Values
Decimal value of row
0
1
0
0
0
0
“8”
0
0
1
0
0
1
“4”
0
0
0
0
1
0
“2”
0
1
1
0
1
0
“1”
H
H
M
M
S
S
0
9
5
0
3
4
Decimal «– time
Bin System Table
The clock starts with the current system clock time and is updated every second. You may left click anywhere on the clock to start and stop it. Right mouse clicks will bring up a configuration panel with a number of options. You can change the background, LED, and label colors, set 12 or 24 hr. time formats, hide or display labels, etc.
AM and PM System
{************** FormResize **************}
procedure TForm1FormResize(Sender: TObject);
{Recalculate clock display parameters when form size changes}
var rx,ry:integer;
begin
cellwidth:=form1.clientwidth div 7;
cellheight:=form1.clientheight div 5;
offsetx:=cellwidth div 2;
offsety:=cellheight div 2;
rx:=form1.clientwidth div 50;
ry:=form1.clientheight div 50;
if rx>ry then radius:=ry else radius:=rx;
form1.font.height:=cellheight div 2;
LW:=form1.canvas.textWidth('H') div 2;
LH:=form1.canvas.textheight('H') div 2;
end;
In this case, it is adequate just to call FormPaint from UpdateTime. We will be waiting for the next timer pop most of the time anyway, so there is plenty of time for windows to update the screen. Just for fun, I tried several other techniques and left them as comments in the code. The only noticeable difference is a slight flicker when Invalidate is used. I suppose because it erases the background before repainting the screen.
Test Compare Script and EXE
There is some confusion over the best way to update a form’s canvas. We can choose from calling FormPaint procedure directly, Invalidate, Update, Repaint.
procedure fmakebinary(val:integer; col:byte; var bin:TALed);
//array of array of boolean
var n:integer;
begin
for n:= 3 downto 0 do begin
bin[col][n]:= val mod 2 =1;
val:= val div 2;
end;
end;