Noutați

Top 10 How-To’s: Delphi & Python

What would it be like to create tools that integrate Delphi with Python? How much fun would it be to allow Delphi to execute Python code and call Python libraries, and allow Python to call modules in Delphi and interact with Delphi code, objects, interfaces and records? Two-directional integration is a great boon to Delphi developers, and the open-source Python4Delphi (P4D) library by Kiriakos Vlahos, author of the popular PyScripter Python IDE, does precisely that. Through Python4Delphi, Delphi developers can leverage the entire collection of Python libraries directly from their favorite IDE. Python4Delphi also allows Delphi developers to execute easily execute Python scripts and create new Python modules and types directly from Delphi applications. If you work with both Delphi and Python, and want to, here are our 10 top How-To’s for combining the two languages: 1. How Can I Get Started With Python for Delphi Developers? Part 1 of the Python for Delphi Developers webinar. Agenda includes Motivation and Synergies, Introduction to Python, Introduction to Python for Delphi, Simple Demo, TPythonModule, TPyDelphiWrapper 2. How Can I Combine The Strengths of Delphi and Python? Part 2 of the Python for Delphi Developers webinar, with Q&A. 3. How Can I Get Started With Python4Delphi? SynEdit is an optional library that provides syntax highlighting and proper indentation behaviors if you want to allow users to edit Python code in your application. It is an open-source VCL only component set available via GetIt or on GitHub. Installing it via GetIt is the easiest. 4. How Can I Set And Get a Variant Array Between Delphi And Python For Building Windows Apps? Python4Delphi offers the TPythonModule component which has a method and procedure to exchange a variant array. This post guides you to do that. You can also use Python4Delphi with C++Builder. 5. How Can I Use Threads Inside Python For a Windows Delphi App? We know Delphi supports Multithreading. Multithreading in Python can be achieved using Python Module Threading. However, In a use case like Delphi Application embedding Python(Python4Delphi) or CPython, the interpreter is not fully thread-safe. 6. How Can I Run a Simple Python Script in a Delphi Application Using Python4Dephi? How about combining the strength of Delphi and Python for your applications to provide first-class solutions for your customer needs? Thinking about how to do it? Don’t worry! Python4Delphi does it for us. 7. How Can I Use Python4Delphi With C++Builder? David I. has a fantastic blog post on using Python4Delphi with C++Builder. This was inspired by our previous webinars on the topic. and is the result of his collaboration with Kiriakos (AKA PyScripter), the maintainer of Python4Delphi, who also made some changes in the library to work better with C++Builder. 8. How Can I Make a Python Module as a DLL Using Python4Delphi? Sometimes we may need to share the functionalities as DLL and we know, creating a DLL in Delphi is a simple task. We learned how to create a Python Module and add methods to it in Delphi. How about making a Python module as a DLL using Python4Delphi and importing this Python module in another application? This post will guide you to do that. You can also use Python4Delphi with C++Builder. 9. How Can I Wrap Delphi Objects to Python Objects With Python4Delphi? How to wrap the […]

Read More

How To Change Your Background On Windows

unit uMainForm;   interface   uses   System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,   FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,   FMX.Controls.Presentation, FMX.StdCtrls, Windows, FMX.Objects, System.IOUtils,   FMX.Layouts;   type   TMainForm = class(TForm)     MaterialOxfordBlueSB: TStyleBook;     BackgroundImage: TImage;     Button1: TButton;     GridPanelLayout1: TGridPanelLayout;     Button2: TButton;     Button3: TButton;     procedure Button1Click(Sender: TObject);     procedure Button2Click(Sender: TObject);     procedure Button3Click(Sender: TObject);   private     { Private declarations }   public     { Public declarations }     procedure SetWallpaper(APath: String);   end;   var   MainForm: TMainForm;   implementation   {$R *.fmx}   procedure TMainForm.Button2Click(Sender: TObject); begin   SetWallpaper(TPath.Combine(ExtractFilePath(ParamStr(0)),‘delphinaut.jpg’)); end;   procedure TMainForm.Button3Click(Sender: TObject); begin   SetWallpaper(TPath.Combine(ExtractFilePath(ParamStr(0)),‘cppnaut.jpg’)); end;   procedure TMainForm.SetWallpaper(APath: String); begin   SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, PChar(APath), SPIF_SENDCHANGE); end;   procedure TMainForm.Button1Click(Sender: TObject); begin   SetWallpaper(TPath.Combine(ExtractFilePath(ParamStr(0)),‘radnaut.jpg’)); end;   end.

Read More

Join The DelphiCon2021 Referral Program to Win Amazing Prizes, Including a Mac Mini!

DelphiCon is On! The world’s biggest annual online conference on, in and around Delphi is just a week away! DelphiCon 2021 is open, free, and loaded with incredible content and amazing prizes and giveaways. If you want to know just how hot Delphi is right now, this is an unmissable event! Here at Embarcadero we want to make this year’s DelphiCon the biggest ever, and to achieve that we need your help to reach everyone who loves Delphi. To make it easy to reach Delphi fans we’ve created a referral program that can also help you win big prizes! Here’s how it works: Refer And Win Big Prizes! The Prizes: 1. Top Prize: One randomly selected referrer will win a Mac Mini (with the powerful new M1 chip, which Embarcadero’s IDEs now support). 2. Two Runners Up: Two randomly selected referrers will each win a one-year Delphi license (without update subscription). 3. Everyone who successfully refers at least one signup will be granted access to the closed Special Session near the end of DelphiCon 2021. 4. Everyone who attends three or more sessions will win the Ultimate Delphi eBook Bundle, which contains: Alistair Christie’s “Code Faster in Delphi”, Nick Hodges’ “Coding in Delphi”, “More Coding in Delphi” and “Dependency Injection in Delphi”, and Marco Cantu’s “Object Pascal Handbook” (updated specially for DelphiCon 2021). 5. Everyone who signs up for DelphiCon 2021 will get a free version of Marco Cantu’s updated “Object Pascal Handbook”. The Rules: 1. Unique referral codes are used to track referrals. Only successful referrals with unique codes will be valid. 2. Each referral that leads to a signup will count as a “ticket” for the prize draw. The more people you successfully refer who sign up, the higher your chances of winning. 3. The winners will be randomly selected from the pool of referrers. How to Participate 1. Use your unique referral code to refer friends, colleagues and anyone you know who may be interested.  2. If you haven’t signed up for DelphiCon, do so here. You will be automatically redirected to a page where you can see your unique referral code and start referring. 3. If you’ve signed up already visit this page to get your unique referral code and check your activity. Note: If the DelphiCon 2021 referral program is a success, we will be introducing an ongoing referral program that will help our subscribers win incredible prizes, giveaways, discounts and more every month! Help us make this a reality! Good luck! More About DelphiCon More than 10,000 developers will be gathering together from November 16th to 18th for panel discussions and webinars on Delphi. Speakers DelphiCon has a top-tier lineup of speakers, including Marco Cantù, David Millington, Ray Konopka, Holger Flick, Nick Hodges, Alistair Christie, David Intersimone, Jim McKeeth. Find the complete list of speakers here. Themes Our speakers and guests will be discussing the future of development with Delphi, multi-platform app development, desktop UX, Rapid App Development, developer productivity, multi-threaded programming on multiple platforms, gaming, low-code and no-code, extending Delphi’s reach with C++Builder, Telegram bots, ethereum blockchain, connecting with REST, Windows 11, and IntraWeb apps. For a complete schedule of panel discussions click here.    See you there!

Read More

Another successful webinar!

Another successful webinar! On Thursday 4/11 we had a very successful webinar about our thriller project RADoween which we finalized in just 5 working days. It’s so cool that we can use our platform TMS Web Academy to reach people from around the world. Note that TMS Web Academy is, just like the RADoween app developed with TMS Web Core. One of the interesting features we have in TMS Web Academy is a view on our audience. On this map here you can see from which countries our viewers of the last webinar are attending from.  Viewers per country Can’t get enough? The recording of the webinar will be available on Tuesday next week for everyone.  You can also read this blogpost to learn more about the RADoween application. For those who missed this webinar and still want a similar experience of a live webinar, you’ll be able to attend Bruno Fierens session at Delphicon on Nov 16. Save your seat here!

Read More

Free Route Directions with OpenRouteService in TMS FNC Maps v2.3

TMS FNC Maps v2.3 now includes a new free service for geocoding and directions in addition to the existing supported directions services from Azure, Bing, Google, Here and MapBox. OpenRouteService The OpenRouteService API service provides geocoding, reverse geocoding and directions free of charge. It does, however, require the use of an API key. This service can be used in combination with all supported mapping services in TMS FNC Maps. Specifically in combination with the OpenLayers mapping service this is a worthwhile free alternative to comparable paying services. Geocoding A geocoding request converts a text address to a latitude & longitude coordinate. The coordinate can then be used to display a location on the map. With the following code we are going to look up the location of “Baker Street, London” and display it on the center of the map with a marker and a title that contains the address.Note that this example uses the asynchronous method with a callback. procedure TForm1.Button1Click(Sender: TObject); var Item: TTMSFNCGeocodingItem; begin TMSFNCGeocoding1.APIKey := ‘abc123’; TMSFNCGeocoding1.Service := gsOpenRouteService; TMSFNCGeocoding1.GetGeocoding(‘Baker Street, London’, procedure(const ARequest: TTMSFNCGeocodingRequest; const ARequestResult: TTMSFNCCloudBaseRequestResult) begin if (ARequestResult.Success) and (ARequest.Items.Count > 0) then begin Item := ARequest.Items[0]; TMSFNCMaps1.BeginUpdate; TMSFNCMaps1.SetCenterCoordinate(Item.Coordinate.ToRec); TMSFNCMaps1.AddMarker(Item.Coordinate.ToRec, Item.Address); TMSFNCMaps1.EndUpdate; end; end ); end; Reverse Geocoding A reverse geocoding request converts a latitude & longitude coordinate to a text address. The text address can then be used to display an address associated with a location on the map. With the following code we are going to track a click on the map, retrieve the address for that location and display it on the map with a marker and a title that contains the address Note that this example uses the synchronous method that provides an immediate result without a callback. procedure TForm1.TMSFNCMaps1MapClick(Sender: TObject; AEventData: TTMSFNCMapsEventData); var Address: string; begin TMSFNCGeocoding1.APIKey := ‘abc123’; TMSFNCGeocoding1.Service := gsOpenRouteService; Address := TMSFNCGeocoding1.GetReverseGeocodingSync(AEventData.Coordinate.ToRec); TMSFNCMaps1.BeginUpdate; TMSFNCMaps1.SetCenterCoordinate(AEventData.Coordinate.ToRec); TMSFNCMaps1.AddMarker(AEventData.Coordinate.ToRec, Address); TMSFNCMaps1.EndUpdate; end; Directions A directions request provides step by step directions between a start and end location. The directions data can then be used to display a route on the map. Additional options can be configured for the directions request, including: waypoints, alternative routes and language. With the following code we are going to retrieve driving directions between New York and Philadelphia. On the map, a marker is displayed at both the start and end location, a polyline displays the route and a label displays the distance and duration of the route.In the TListBox on the step by step directions are displayed for each step in the route directions. procedure TForm1.Button1Click(Sender: TObject); var cStart, cEnd: TTMSFNCMapsCoordinateRec; begin cStart.Latitude := 40.68295; cStart.Longitude := -73.9708; cEnd.Latitude := 39.990821; cEnd.Longitude := -75.168428; TMSFNCDirections1.APIKey := ‘abc123’; TMSFNCDirections1.Service := dsOpenRouteService; TMSFNCDirections1.GetDirections(cStart, cEnd, procedure(const ARequest: TTMSFNCDirectionsRequest; const ARequestResult: TTMSFNCCloudBaseRequestResult) var it: TTMSFNCDirectionsItem; I: Integer; p: TTMSFNCOpenLayersPolyline; Hours, Minutes: string; begin TMSFNCOpenLayers1.ClearPolylines; ListBox1.Clear; if ARequestResult.Success then begin if ARequest.Items.Count > 0 then begin TMSFNCOpenLayers1.BeginUpdate; it := ARequest.Items[0]; TMSFNCOpenLayers1.AddMarker(it.Legs[0].StartLocation.ToRec, ‘New York’, DEFAULTWAYPOINTMARKER); TMSFNCOpenLayers1.AddMarker(it.Legs[0].EndLocation.ToRec, ‘Philadelphia’, DEFAULTENDMARKER); Hours := IntToStr(Round(it.Duration / 60) div 60); Minutes := IntToStr(Round(it.Duration / 60) mod 60); p := TTMSFNCOpenLayersPolyline(TMSFNCOpenLayers1.AddPolyline(it.Coordinates.ToArray)); p.StrokeColor := gcBlue; p.StrokeOpacity := 0.5; p.StrokeWidth := 5; p.&Label.Text := FloatToStr(Round(it.Distance / 1000)) + ‘ km, ‘ + Hours + ‘h ‘ + Minutes + ‘ min’; TMSFNCOpenLayers1.ZoomToBounds(it.Coordinates.Bounds.ToRec); TMSFNCOpenLayers1.EndUpdate; ListBox1.Clear; for I := 0 to it.Steps.Count – 1 do begin ListBox1.Items.Add(it.Steps[I].Instructions) end; end; end; end ); end; Available Now The TMS FNC Maps v2.3 update is available now for Delphi & Visual Studio Code (with TMS WEB Core). You can download the latest version and start using the new features right away!

Read More

How To Get The DelphiCon 2021 Desktop Wallpaper

DelphiCon 2021 is coming up soon and in order to get in the spirit we created this desktop wallpaper that captures the essence of DelphiCon. DelphiCon 2021 is the best way to learn all about your favorite programming language. Sessions are planned around the latest features, as well as general best practices, and emerging technologies that apply to all versions. There are also sessions on integrations with other languages (C++, Python, etc.) and platforms. Where can I get the DelphiCon 2021 desktop wallpaper? What better way to apply your new DelphiCon 2021 desktop wallpaper than we a Delphi Win32 API call? This works in both VCL and FMX as long as you have the Winapi.Windows unit in your uses clause. For this API call we can use SystemParametersInfo() with SPI_SETDESKWALLPAPER as the first parameter. Download the DelphiCon 2021 desktop wallpaper now! What online sessions are available at DelphiCon 2021? Here are some of the sessions you will find at DelphiCon! Keynote – Beyond 10x – The Future of Development with Delphi Convert your VCL Database Application to Mobile and Multiplatform Entity Component Systems: A Different Approach to Coding How Tab Controls Can Ruin Desktop UX Effectively Using FMX List Controls Thriller: A Delphi Web App in 5 Work Days Move Your UI to the 23rd Century – Building a Data Dashboard with Delphi and Skia. Engage! Why Does the Cloud Matter for a Delphi Developer? Maximize Your Delphi Productivity Multi-Threaded Programming on Apple’s Mac M1 vs Mac Core i7 vs Windows Core i7 Developing Applications for the Raspberry Pi with Delphi 11 Castle Game Engine – Coming to Delphi! Delphi Does Low-Code: Cross-Platform REST Client in – 30 Minutes! Smartwatch Android Meets Delphi – Controlling Devices Multi-Platform Explorations using Delphi, FMX, Feeds, REST and More Control Arduino Manipulator with Delphi and Visuino over WiFi or Bluetooth Things That You Don’t Know About JSON in Delphi Leaving Delphi 7 – A Success Migration Case Using C++Builder to Extend the Reach of Delphi Invoice Generation via Telegram Bot Using FastReport VCL and Delphi FireDAC: Combining Power and Speed in Cross Platform Database Access (Live Panel) Fintech on the Ethereum Blockchain with Delphi Delphi Best Practices: The Top Seven Things you Should be Doing Building a Web Crawler with Delphi and Python APILayer: Features and Connecting with REST Check out the full list of sessions at DelphiCon 2021! Who is presenting at DelphiCon 2021? Who are these people in bright red Greek helmets? They’re the Delphi superheroes you’ll be running into at DelphiCon 2021! And which Delphi superpowers will they be talking about at DelphiCon? Find out on the Schedule & Talks page on the DelphiCon website. Sign Up Now! Who is sponsoring DelphiCon 2021? DelphiCon 2021 is has a huge number of sponsors this year and here are some of them: How can I sign up for DelphiCon 2021? Head over to the DelphiCon 2021 website and get your free ticket today!

Read More

How To Build a Digit Classifier In Tensorflow

procedure TForm1.Button2Click(Sender: TObject); var   i, X, Y: DWORD;     fLibrary: HMODULE;   fModel: Pointer;   fInterpreterOptions: Pointer;   fInterpreter: Pointer;   fStatus: TfLiteStatus;   fInputTensorCount, fOutputTensorCount, fNumDims: Int32;   fInputTensor, fOutputTensor: Pointer;   fInputDims: Integer;   fTensorName: PAnsiChar;   fTensorType: TfLiteType;   fTensorByteSize: SIZE_T;     // 28×28 pixel image as input   fInput: array [0 .. 28 * 28 – 1] of Float32;     // output 0 to 9   fOutput: array [0 .. 10 – 1] of Float32;     fValue: Extended; begin   fLibrary := LoadLibrary(LibraryName);     if fLibrary = 0 then   begin     ShowMessage(‘Error: Load tensorflow lite library ‘ + LibraryName + ‘ – ‘ +       SysErrorMessage(GetLastError));     Exit;   end;     try     fModel := TfLiteModelCreateFromFile(PAnsiChar(AnsiString(Edit1.Text)));       if fModel = nil then     begin       ShowMessage(‘Error: Create model from file – ‘ +         SysErrorMessage(GetLastError));       Exit;     end;       fInterpreterOptions := TfLiteInterpreterOptionsCreate;       if fInterpreterOptions > nil then     begin       TfLiteInterpreterOptionsSetNumThreads(fInterpreterOptions, 2);         fInterpreter := TfLiteInterpreterCreate(fModel, fInterpreterOptions);         // parameters / model can be removed immediately after the interpreter is created       TfLiteInterpreterOptionsDelete(fInterpreterOptions);       TfLiteModelDelete(fModel);         if fInterpreter > nil then       begin         fStatus := TfLiteInterpreterAllocateTensors(fInterpreter);           fInputTensorCount := TfLiteInterpreterGetInputTensorCount(fInterpreter);         fOutputTensorCount := TfLiteInterpreterGetOutputTensorCount           (fInterpreter);           // fLiteTensor* TfLiteInterpreterGetInputTensor(const TfLiteInterpreter* interpreter, int32_t input_index);         // returned structure TfLiteTensor         // an example is simple, there is no need to translate everything from the         // in general, the source of the: https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/c         { typedef struct TfLiteTensor {           TfLiteType type;           TfLitePtrUnion data;           TfLiteIntArray* dims;           TfLiteQuantizationParams params;           TfLiteAllocationType allocation_type;           size_t bytes;           const void* allocation;           const char* name;           struct TfLiteDelegate* delegate;           TfLiteBufferHandle buffer_handle;           bool data_is_stale;           bool is_variable;           TfLiteQuantization quantization;           TfLiteSparsity* sparsity;           const TfLiteIntArray* dims_signature; }         fInputTensor := TfLiteInterpreterGetInputTensor(fInterpreter, 0);         fOutputTensor := TfLiteInterpreterGetOutputTensor(fInterpreter, 0);           if fInputTensor > nil then         begin           // info about tensor           // fNumDims := TfLiteTensorNumDims(fInputTensor);           // fTensorName := TfLiteTensorName(fInputTensor);           // fTensorType := TfLiteTensorType(fInputTensor);           fTensorByteSize := TfLiteTensorByteSize(fInputTensor);             // writing pixels to fInput, top to bottom, left to right           for Y := 0 to Image1.Picture.Bitmap.Height – 1 do           begin             for X := 0 to Image1.Picture.Bitmap.Width – 1 do             begin               if (Image1.Canvas.Pixels[X, Y] > 0) then                 fInput[X + (Y * Image1.Picture.Bitmap.Width)] := 1               else                 fInput[X + (Y * Image1.Picture.Bitmap.Width)] := 0;             end;           end;             // fTensorByteSize = Length(fInput) * SizeOf(Float32)           fStatus := TfLiteTensorCopyFromBuffer(fInputTensor, @fInput,             fTensorByteSize);             fStatus := TfLiteInterpreterInvoke(fInterpreter);             if fStatus = kTfLiteOk then           begin             for i := 0 to High(fOutput) do               fOutput[i] := 0;               fOutputTensor := TfLiteInterpreterGetOutputTensor(fInterpreter, 0);               // info about tensor             // fNumDims := TfLiteTensorNumDims(fOutputTensor);             // fTensorName := TfLiteTensorName(fOutputTensor);             // fTensorType := TfLiteTensorType(fOutputTensor);             fTensorByteSize := TfLiteTensorByteSize(fOutputTensor);               if fOutputTensor > nil then             begin               // fTensorByteSize = Length(fOutput) * SizeOf(Float32)               fStatus := TfLiteTensorCopyToBuffer(fOutputTensor, @fOutput,                 fTensorByteSize);                 if fStatus = kTfLiteOk then               begin                 ListView1.Items.Clear;                   for i := 0 to Length(fOutput) – 1 do                 begin                   // ingenious solution, coolest conversion                   fValue := StrToFloat(Copy(FloatToStr(fOutput[i]), 1, 17));                     if fValue = 1 then                   begin                     with ListView1.Items.Add do                     begin                       Caption := FloatToStrF(fValue, ffNumber, 17, 17);                       SubItems.Add(IntToStr(i));                     end;                   end;                 end;                   ListView1.AlphaSort;                   Beep;               end;             end;           end;         end;       end;     end;   finally     FreeLibrary(fLibrary);   end; end;

Read More

Everything You Need To Know About Blockchain

Blockchain is a term utilized to represent distributed ledger technology. Blockchain is used to build a storage system for data in a distributed and immutable mode. So there are key features we need to mention. Immutability – this means that once data is written to a blockchain data storage or ledger, it cannot be changed – so it’s there forever. For instance, in a relational database, no matter how much security you have, the data can be accessed and modified on the system. A blockchain system guarantees that if one bit of data is altered it says it is in an invalid state, and since the data is distributed on various systems, the verified data with a justified state can be retrieved. Distribution – is the key to trust. As long as the data you see is in the blockchain and it’s in a valid state you can trust the data to be accurate. This trust is the key and this trust is achieved in a blockchain system by replicating the datastore on several hosts on the internet. For instance, as long as the peers accept that bit of data is valid, so you can completely trust that data that is stored on that system. In Blockchain the trust is requisite. Immutability – Trust Distribution – valid/invalid For many industries trust is a problem. The automobile industry is one of those where trust, or lack of it, causes problems. People order used cars from other countries which do not easily share tracking information and this can mean that faking data about the car’s prevenance and history is easier. For instance, odometer fraud is one of the problems that you can seriously impact the value of a vehicle. Representing a vehicle as having been used 5,000 miles instead of 50,000 miles can mean a huge difference in perceived value and potential usable life span of the car or truck. In many countries car service records are largely kept on paper which can of course very easy to be fake.  So, let’s imagine that pushing all service providers to a blockchain and all the readings kept on the blockchain. The integrity and immutability of the blockchain data means that a modification of the records would be detectable. Moreover, agencies such as insurance companies can also contribute by appending accident details of a car giving a much more complete picture of the vehicle’s history in a way which is very difficult or even impossible for dishonest vendors to fake. Transferring money from one country to another takes your time and can be expensive because of the need to comply with multiple different regulations and policies, but eventually, another person receives the money. Your bank updates its records and sends them to the main clearing bank in your country where they are passed through a number of systems where it analyzes them to prevent money laundering and to comply with various trade embargoes. Assuming your transaction passes the checks, the funds are then sent them to another country’s clearing bank. They again update the record and send it to the receiver’s bank account. Even in these highly automated times, it can take several days for the money to arrive in the destination account. This is where Bitcoin can offer an alternative to the traditional brocks and […]

Read More

Thriller: a story to go from idea to live web app in less than 5 working days

All Blog Posts  |  Next Post  |  Previous Post Bookmarks:  Thursday, October 28, 2021 This is a different article. It’s a little bit longer than usual. It’s the story of how a software developer team, working together, using wonderful & highly productive development tools, made an idea become real in less than 5 working days. It’s the story of how TMS Software, using Embarcadero Delphi 11, TMS Web Core and TMS XData, made an unexpected and time-constrained request from Embarcadero to create RADoween, a cloud app available on nearly every platform around. In less than 5 working days! We hope you enjoy the ride.   The start Thursday Oct 14 at 16:24, Bruno Fierens received an email from Embarcadero General Manager Atanas Popov with a “quick idea” to create a web app that can be used to organise a contest for Halloween fun pics. Basically the app needs to provide the capability to send pictures, show a list of pictures and let people vote for the nicest pictures.  Bruno saw this email only a bit later this same day at around 18:00 and replied: And yes, only a few minutes later, on Oct 14 18:23, Bruno learned that the web app had to be live on Oct 21, that is 5 working days later and that technically we basically had a free choice for the needs for hosting and back-end: Realizing the immense challenge this would be if Bruno accepted to create this web app, Bruno immediately reached out an hour later to colleague and architect of our REST back-end server product TMS XData, Wagner Landgraf:  Over a Whatsapp call this Thursday night of Oct 14, Wagner and Bruno first of all discussed if it was feasible at all to allocate on such a short term the time and resources to create this project and also importantly, what could be the potential benefit for the TMS team to accept this somewhat unusual challenge. Bruno and Wagner agreed that this was clearly a risk to deliver this in such an incredibly short time, that if this challenge was successfully handled, it would be a very nice demonstration of the productivity that Delphi developers can have with Delphi and the TMS products. And finally, when hard challenges are given, Bruno and Wagner share that competitive spirit to prove we can do the impossible. But having become a bit older (and wiser?), Bruno and Wagner decided to leave the call with the decision to ask  Atanas commitment that there could be a nice promotional action around it for Delphi 11 & TMS tools and at least sleep one night over it before making a final decision. Friday Oct 15th, Bruno wakes up and finds the email with the confirmation from Atanas about the commitments. So, now there isn’t much time left for doubts, sometimes in life, one just has to jump and with this in mind Bruno leaves home for the office and first thing is having a meeting with the whole Belgian team to inform them about the story that crossed our path. Given the extensive experience with TMS WEB Core from our colleague Bradley Velghe with developing the TMS Web Academy, we decided in the meeting that Bradley would be the main developer for the front-end with TMS WEB Core. Bruno […]

Read More

RADoween: Full-Stack Web App Development with Delphi and TMS

Up and running from concept to launch in just five days On October 14, Atanas emailed Bruno with an idea for a TMS WEB Core-powered web app to run our internal partner Halloween costume contest. The goal was for a simple web page where team members could submit pictures of their Halloween costumes, and then everyone could vote on their favorites. Oh, and we needed it ASAP so we would have time to use it. The idea is simple, but as any experienced programmer can tell you, there are a lot of technical questions and requirements to satisfy: Can you take pictures from the web app or just upload them? Setting up the back end to store the data Communication from the front end to the back end Preventing spam votes An administrative interface for everything Especially in web development, it is common to divide developers into two categories: front-end and back-end. The reason for this is that, most often, two completely different programming languages are required. The front end runs on JavaScript (with WebAssembly still gathering momentum), while the back end runs on various languages: PHP, C#, Java, Python, Perl, etc. The running joke in software development is that the front end looks impressive, but the back end is scary. From a conceptual point of view, a front-end developer builds the part the user sees, making UI and design esthetics important. In contrast, the back-end developer-only creates the part that other developers see. Ideally, both parts are well designed, but now I’m off in the weeds and forgot the purpose of this blog post. When you take all the software and tools used to build an application, that is referred to as the stack. The most common web stack is LAMP, an acronym that initially stood for Linux, Apache, MySQL, PHP, but this is incomplete as it assumes JavaScript is the only solution for the in-browser. One of the reasons Node.js was so popular is that it allowed developers to use JavaScript on the back end as well as the front-end. This made the concept of a full-stack more popular: No longer would two different skill sets and programming languages be needed: Everyone can just use JavaScript everywhere! Well, JavaScript isn’t the only full-stack programming language. In my mind, Delphi conceptualized full-stack development with its client-server architectures. Instead of using PHP or Java (both released the same year as Delphi) for the back end, and then something else for the front end, Delphi did everything in the same IDE with the same programming language. In 1995 most web applications were just static HTML (Cascading Style Sheets didn’t even appear until 1996, and they took a while to catch on). And while JavaScript was born in 1995 along with Delphi, PHP, Java, and many other modern programming languages, it still hadn’t seen widespread adoption. Today, most web pages make heavy use of JavaScript. Sometimes there is more JavaScript code than the rest of the HTML, CSS, and images combined. Okay, that was an interesting dive into stacks, front ends, back ends, and the history of web development, but what does all of that have to do with Halloween? Glad you asked—Delphi is still a fabulously productive full-stack development tool for web application development thanks to the power of TMS WEB Core front-end and TMS XData back end, and […]

Read More