-
Content Count
1237 -
Joined
-
Last visited
-
Days Won
25
Everything posted by David Schwartz
-
I'm curious if anybody knows of any FOSS Delphi interpreters. TMS has had one for quite a while, and I worked with it on a project many years ago. But I think it's overkill for what I'm looking for. Besides, it's not FOSS. What I'm interested in is building a REST service that runs on a standard Linux host (eg., CentOS) and has a way of adding services by uploading a source file written in Delphi rather than having to upload compiled code. Delphi purists will say that's way too inefficient, but It's not like running interpreters on back-end servers is an unusual thing, since most such services are written in php, python, and even VB. Anyway, it doesn't need to "run fast", as long as you can easily spin-up multiple servers running the same code. I don't think it needs to support 100% of the latest Delphi language features, maybe just to D7 or even the version after D2010 with stable generics. As an aside, I cannot comprehend why Delphi has no support for Linux except for distros that conform to specific UI needs, when most people want to use Linux to run services, and most Linux hosting is all headless. There should be a way to build headless apps (ie, no UI parts) for common Linux distros in all Delphi versions.
-
Open-source Delphi interpreters?
David Schwartz replied to David Schwartz's topic in Network, Cloud and Web
Thanks for this. Is it useful without a run-time license for DevEx? if you use generic Delphi code that can be tested in Delphi then loaded somewhere to run under DWScript, can you get by without DevEx? -
I hate SOAP. I've used it on a couple of Delphi projects, and worked on a couple more where someone else was dealing with it, and the amount of effort needed just to get it to do basic stuff is horribly distorted. But when you're forced to interact with a system where all of their external APIs are built in SOAP, you're stuck with a pig-in-a-poke, IMHO. I know one guy who'd first build it in C# just to make sure the specs he was given were correct, because he said that devs frequently update the interface but don't update the public docs (that often involves two different teams). In one of my cases, Delphi's WSDL compiler generated crap, and I had to use a 3rd-party compiler to make my Delphi code work. Good luck with it!
-
The title of this thread is "Backward compability". That's referring to the ability to take OLDER versions of projects and build them in NEWER versions of Delphi, and it mainly applies to the language features and VCL. For example, you can still compile programs that declare 'object' types that existed briefly before the 'class' designation showed up. It has been deprecated for 25+ years, but it still works. You can even build old TurboPascal apps and there's a very good chance they'll compile and run without any issues. However, going from a NEWER version to an OLDER version has NEVER been supported. Needless to say, the error you're pointing to is not even in the language nor the VCL, so it's totally outside of Delphi's product domain. Meaning ... you're barking up the wrong tree. Third-party vendors frequently add updates to their libraries. Embt updates Delphi's language and the VCL very infrequently, mostly when a new major version is released. OTOH, companies like TMS Software (among others) frequently release updates based on bugs and requests submitted by their users. I don't know what library this is, but if it's DevEx, then I believe they update their subscribers quarterly. I've worked on projects where we used components from TMS, and in some cases, certain team members loved to complain about the frequency of updates, and they didn't bother doing them sometimes. I always update my libraries regularly, especially if there's something pushed out that fixes a bug or problem I encountered. If I do that and then commit an update, it's highly likely that someone who has not updated their TMS libs will encounter these same errors when attempting to build my code. That's not my fault! Nor does it have anything to do with either Delphi or "backward compatibility". (Frankly, it's a Project Management issue.) The moral of the story is, if you update a library and commit the code for it to your repo, then try opening that latest version on a machine that's got an older version of the library installed, then this is something that's VERY likely to happen. It doesn't matter what version of Delphi it is -- this is saying a property added to a class recently is missing from the version you've got installed on that machine, which is not terribly uncommon. You need to update the library, not Delphi.
-
Meta-Delphi question about web hosting..
David Schwartz replied to jglosz's topic in Network, Cloud and Web
If you've ever seen a FOREX dashboard built in Delphi running on a high-speed link, you wouldn't be asking these questions about whether it's possible. Yes, it absolutely is. What problem are you REALLY trying to solve? Also, shopping carts are DESIGNED to be STATIC, so they're an inappropriate example. Stock, bond, and FOREX trading are examples of HIGHLY dynamic apps, and Delphi has been used to build all of them. -
Circular references with API design
David Schwartz replied to Darian Miller's topic in Algorithms, Data Structures and Class Design
When you've got a platform that has 64-bit integers that have values that actually range from, say, 0..27, and you think that having a dozen of them in a record is somehow more efficient than using an object with a single 64-bit pointer, I'm not clear what you think is being saved. Pointers might make use of half of a 64-bit data element, but there aren't a lot of applications that have that kind of dynamic range on the values they manipulate. Floating-point values ... ok, you get a little more precision for calculating the trajectory of things flying around the solar system. But for most routine programming tasks that the typical UI does ... it's way overkill. Consider that JSON is more or less a big record with labels but not types, meaning all of the data fits into 8-bit chunks, while accesses are usually done with very inefficient linear searches. So the first thing you often do is parse them into some kind of typed data structure as a more efficient container, unless you only refer to a few of the fields and then toss the the entire JSON string away. Records are fine when all of the data is managed by a single interface; but when you're passing them around and lots of different methods are touching them, and a change is made in one instance that's not propagated down the line and nobody else knows that the value has changed, they can be horribly time-consuming to debug. Or you can make a change that you do NOT want propagated but it DOES get propagated, simply because their use is mainly pass-by-value semantics but there's a hidden copy-on-write going on. But when a Record's data is managed by a single interface, you're just simulationg a Class. So ... what's the point? You're just having to write more management code that the compiler provides for free if you use a Class instead. It's like saying you won't sell your 1980-vintage car because you like being able to tweak the carb to assure optimal fuel efficiency, while ignoring the fact that electronic fuel injection can double or triple your overall mileage -- at the expense of having to trust that it's actually doing its job. I prefer to use Classes and trust the compiler to do its job. -
Buying a mini pc to install Delphi
David Schwartz replied to Alberto Paganini's topic in Tips / Blogs / Tutorials / Videos
What I mean is, can you compile for Intel platforms and test them? I seem to recall there's a translation layer that came with the M-series chips, but I don't hear much about it when it comes to using Delphi to build WinTel code. -
Buying a mini pc to install Delphi
David Schwartz replied to Alberto Paganini's topic in Tips / Blogs / Tutorials / Videos
I do my Delphi development in a VM running Windows on my Mac. I don't know what VMs let you run Windows on non-Intel Macs -- I think VMWare Fusion is the only one ... does anybody know for sure? (I don't have an M-series Mac so I'm wondering.) The most unstable part of my systems are the browsers that slowly eat up memory because javascript doesn't have any sort of memory management and nobody seems to bother freeing anything. From what I can tell, it's the same on all platforms because it's a javascript issue. Otherwise my experience has been that Macs are far more stable than Windows machines. My Win-based VMs implode from time to time, far more frequently than my Macs do. Again, what kills my Macs is because of excessive and uncontrolled memory leakage from javascript in the browsers. I totally minimize my use of browsers inside of the VM, but it still crashes for indeterminate reasons, just like every Windows laptop and desktop I've ever used. That's what I'd call the "Windows tax". I prefer the "Apple tax", thank you. There's also the well-known fact that Windows is targeted by hackers a couple of orders of magnitude more frequently than MacOS is. To deal with this, you need to run a steadily growing layer of screening tools that eat up a big chunk of the performance boost you get from upgrading your machine. This is the "other Windows tax". -
Yes, this is rather vague. But if you're using D10.4 and it's a VCL DB app, then I'm guessing you're using some kind of TDatabase component to connect to your local DB? If so, it may be as simple as changing your provider interface and connecting to that. If you're using MySQL or SQL Server locally, you can connect to the same DBs remotely. But you could also be asking a more generic question, like what's involved replacing a local DB with a REST-based service API? I mean, you mentioned RadServer, so maybe that's what you're looking for instead? That's a whole nuther can of worms! But if that's what you want, then you need to start shifting how you think about your DB. In Delphi, using DB-aware controls, you're using a traditional client/server model where the app is simply connecting to a DB server and issuing queries and processing the responses. However, those queries tend to be invisible unless you're using explicit SQL queries. Issuing SQL queries for tables and rows is often a lot more overhead than what you want to do if you have a REST-based API -- in that case you need the queries to be more granular. A lot of client/server apps issue things like, "SELECT * FROM ...." and get back thousands and thousands of records, then filter them down. Using a REST-based API, it's best to issue extremely specific queries. Like if you're using a grid to show some data, you'd issue queries that only request to get the number of rows and columns in the grid. If it's a master/detail list, then when the user clicks a row, you'd issue a request to get the data for that specific row. Client/Server stuff often pulls everythign into memory when you open the tables. That is way to inefficient for remote services. If your app IS more of a traditional client/server app, they're you're going to need to re-do the forms and logic that's used to populate the forms, rather than relying on the underlying DB-aware components. There are some provider components that you can replace your existing ones with that add some level of intelligence to the underlying data management without needing a lot of rework on your part, but that would be more of a stop-gap IMHO. Another approach you can use retains the current providers but you'd want to lean more heavily on SQL and stored procs. If you plan it out correctly, the stored procs can be replaced by API calls to a back-end service with endpoints that call the same stored procs. Whatever approach you take, you MUST get away from the traditional client/server practices that simply open the tables and load the entire dataset into local memory.
-
Buying a mini pc to install Delphi
David Schwartz replied to Alberto Paganini's topic in Tips / Blogs / Tutorials / Videos
That's why I prefer to buy stuff that's out-of-warranty and do my own upgrades. It's WAY CHEAPER that way! Most of what we're talking about is purely mechanical work; very little soldering is needed. Besides, I can't recall the last time I had any piece of electronics that failed and I was able to get it fixed under warranty. Seriously. FWIW, I spent most of today at a car dealer. I got a new car on Friday and while going through the paperwork yesterday (Sunday) I found that a few things that I kept telling them I wanted and hearing them say, "Ok, that's what you've got" -- but that ended up being far different than what was in the agreement they had me sign. It all had to do with warranties. If you want to find an industry that has figured out how to leverage people's fear of things breaking down vs. the cost to get it fixed, the automotive industry has perfected this to the max. My experience with electronics is they either fail in the first few hours of use, or they don't. That applies especially to computers and peripherals. I don't know how many dozens of computers are contained in the newest cars, but no matter what they say, most of them are NOT covered under ANY warranties. But they'll tell you they are -- or they'll say they're NOT just to get you to buy an extended warranty plan that you don't need, and when they fail they'll tell you they're NOT covered. I got this new car because my last car had a problem that originated with the previous owner. In spite of all of all the warranties and assurances that I didn't have to worry about ANY problems that might arise with my electrical system (it's an EV) they were all just a big pack of lies. My fast charge port stopped working, and they wanted $6500 to replace the entire wiring harness in it -- even though the warranty I paid $5k for was supposedly designed to cover things like this -- "from stem to stern" they said. "Anything that goes wrong" they said. Just not "pre-existing conditions". Oops. Now they tell me that after 3+ years! I'm the wrong person to talk to about the perceived value of warranties -- to me, they're utterly worthless. And if you ask most people who've had any kind of insurance policy on things that failed and then their "warranty" denied coverage (esp. health care plans!) they'll say the same thing. I put zero faith in warranties. It's easier to get things "fixed" by filing a dispute with your charge card company than to deal with warranties! Thankfully, most companies are easier to manipulate via social media than the useless warranties they offer. -
Buying a mini pc to install Delphi
David Schwartz replied to Alberto Paganini's topic in Tips / Blogs / Tutorials / Videos
You're welcome to spend your time however you want. Just like some people love to constantly tinker on their own cars, and won't own anything built after 1990. That's perfectsly fine! I'm just as uninterested in futzing with my car as I am with constantly futzing with my OS and computer hardwere. There was a time when I totally LOVED futzing with the OS and hardware. Today I just want it to run. Apple's OS is basically Unix, and I can get at it via the Terminal app any time I want; I do that very rarely any more. It's not about the cost to me, but how little I have to actually think about it and am forced to deal with it. Some people prefer to clean their own homes, and some prefer to have someone clean it for them. Arguments can be made on both sides. But saying you do your own cleaning just because you think "the cost [to have someone else do it] is outrageous", then it's not about the cleaning any more, is it? Neither one is "right" or "better". I just find that Apple's ecosystem takes far less of my time and attention to maintain than Windows. That's priceless to me. YMMV. -
Buying a mini pc to install Delphi
David Schwartz replied to Alberto Paganini's topic in Tips / Blogs / Tutorials / Videos
I didn't realize this forum caters to "average consmers". -
Buying a mini pc to install Delphi
David Schwartz replied to Alberto Paganini's topic in Tips / Blogs / Tutorials / Videos
"the Apple Tax"? I've got a 2014 Mac Mini and a 2018 Mac Mini, as well as a 2014 MacBook Pro. They all still run just fine. I use the Mac Minis pretty much every single day. I have yet to own a Windows PC that lasts more than 3-4 years. My suggestion is to buy an Intel-based Mac Mini with an i7, 256GB or more of SSD. These devices let you upgrade the RAM, so you could get one with just 8GB and put in a couple of 16GB DRAMs. Also, you can get more SSD, but it's cheaper to get a Samsung T5, T7, or T9 external SSD (USB 3.2) rather than pay the cost of adding more SSD to the base machine. A 512 GB SSD + a 2TB T7 may be an optimal choice. Set it up with a VM and load Delphi into that. I use VirtualBox, but I just read where VMWare just announced that Workstation and Fusion are now FREE. Be sure to back them up; mine take up 100GB or so, which only takes a few minutes to copy to a T5 and less on the faster ones. As far as connecting to whatever you get, I access my 2014 Mac Mini via the 2018 one using an RDP connection (shared desktop). That would work as well for Windows as Macs. I'm looking at getting a new Mac Mini with the M4 chip ... does anybody know how well VMs running Windows work on Apples Mx series chips? Does the Intel CPU emulation layer slow things down very much? -
Meta-Delphi question about web hosting..
David Schwartz replied to jglosz's topic in Network, Cloud and Web
I second the recommendation for TMS WEB Core. It's just like building a VCL or FMX app, but it runs in the web browser. The language has been enhanced a bit to deal with async issues, but it's easy to learn. (Once you do, you wonder why it's not in Delphi's core.) -
I Need Assistance Linking Delphi Applications to Cloud Services
David Schwartz replied to mirellehgf's topic in Network, Cloud and Web
I'd suggest TMS Software's various Cloud Packs. The most challenging thing in using ANY REST-based service is that they're inherintely asynchronous in nature. Delphi has nothing built-in to handle that. A lot of people use tasks or multi-threading, but a lot of libraries provide a way to have callbacks so they look more like ordinary TEvents. I've switched to using something from TMS called WEB Core that lets you write code in the Delphi IDE and it's transpiled into javascript. They've extended the language with some things to make accessing async services much easier. They've got something in beta that will add a WYSIWYG HTML form designer that integrates into the Delphi IDE to use with WEB Core, so you're not stuck doing design work in one window and having to see how it looks at run-time in another window. Any latency and security issues you have will depend on the services you're using, not so much your app -- there's nothing you can do in your app to address latency issues, and you can only use the secure interfaces the services offer, but they tend to offer the latest security options. -
What are you using AI code-gen tools for that's working well?
David Schwartz posted a topic in General Help
I've been playing around with ChatGPT to help with certain Delphi coding tasks and I find it's really great at coding import/export routines between classes where the field names and types are the same. It's also great for generating template code for large Case statements, and certain kinds of refactoring. Coming up with functions to do specific things is not something it's very good at. I think with more popular languages, it would do a better job. But it makes up lots of stuff and if you try drilling-down it will eventually go in circles explaining how to implement things that don't really exist. I'm curious what sorts of things others are successfully using some AI tools for that help with Delphi code? -
IOW, use ChatGPT as an SME. That might be somewhat informative, but not a very smart approach for a start-up. TBH, if you don't already know most of this information and/or you don't have an SME involved in your project, then this is a waste of time and money because nobody is going to buy it. Keep in mind that ChatGPT only looks backward. It's not going to inform you of anything users would like to see in the future, which is what you're going to need to deliver if you want to gain a foot-hold over incumbant providers who are failing to deliver on what their users have been requesting for months if not years because the exising backlog is so huge. These AI systems are trained on what's known. The generative parts are not likely to take you in a direction that a creative person with decades of experience in one or more fields might propose. I'm building a meditation app. There are literally thousands of them available today, and if you asked ChatGPT to describe the structure, it's easy because they're all the same: they're like an MP3 player loaded up with some pre-recorded materials. Mine is NOT THAT. ChatGPT is never going to offer an example of what MY app's design is like. Why? Because it does not exist anywhere! What's worse is when I talk to potential investors and explain everything that makes mine unique, they come back to me later and say, "Well, I had my team look into this and they said they don't see any differences between yours and the others they found." What I have taken away from that is that Steve Jobs' infamous quote has a lot of merit: "Sometimes people don't know what they want until you show it to them." And even then it might take them a while to figure out it's really different. Back in the 80's I'd go to a big annual trade show called COMDEX and ask phone vendors how I could get access to their SDK to write apps that run on their phones. Some said they don't do that, and some said things like "it's $50k plus I'd have to pay them a licensing fee to keep the app included on the phone", plus I'd have to update it for each new phone release. But all of them were of the opinion that they could not see a world where anybody would want to waste time developing apps to run on cell phones. Which is perhaps why all of them lost their dominance as leaders in the cell phone industry believing that Apple's approach would never succeed. ChatGPT would only give you suggestions on how to build a better cell phone. It would never suggest adding apps and an app-store; focusing on the built-in camera's features; and make it so people can use it to create pro-quality videos. When was the last time you saw an ad for a phone that touts a bunch of new features for the PHONE part? Today they replace what a PC in 2000 did with 40 apps and a dozen hardware accessories!
-
What are you using AI code-gen tools for that's working well?
David Schwartz replied to David Schwartz's topic in General Help
"Yes!" to all of these. I've also used it to do refactoring that's too complex to do with RegEx patterns. Like if you have "a.x := b.x" and you want to change everything to "b.x := a.x", or changing a Case statement into cascaded if..then..else or the other way around. You could give it a class with just variables and have it write all of the properties using either in place vars or methods. If you have a particular structure you want to follow, you can say, "create a class like xyz using this list of fields instead". -
I'm trying to build a small test bed in Delphi for accessing an internal company API and there's a swagger link published for it. What I want to do is suck in the Swagger definition and use it to build something that lets me query the API in Delphi. I'm not sure what all that requires. I guess most of the time people use some kind of javascript framework for this; I want to use Delphi. I searched around on Google and found this project: https://github.com/marcelojaloto/SwagDoc There's a demo in it named 'GenerateUnitFileForMVCFramework' that lets me put in the Swagger URL and it generates a Delphi unit. It works fine, but there may be a bug in this code in that it duplicates every class and interface definition. I was able to fix that without much trouble in the code generator, but there may be a problem in the part that's parsing the Swagger. (Right now I don't care.) I guess the MVC Framework comes from here: https://github.com/danieleteti/delphimvcframework I'm not exactly sure what to do from here. I need a way to connect to the service with OAuth2, and then make some queries and display the results in a form, like in a TListview. I'm looking for suggestions on how to proceed. Thanks! FWIW, someone here wrote a similar thing that generates C# code from a Swagger URL, and that code looks very similar to the Delphi code that's generated by this SwagDoc tool.
-
You are facing the wrong direction in asking this question. You can only get the answer to "what belongs in our MVP" by asking prospective users of your software. In fact, you need to ask Subject Matter Experts (SMEs) in that domain who have a deep understanding of how your prospective users work and what kinds of functions and services they need to do their jobs better than what's already available. For a Corporate-level CRM package, you're going to be fighting a huge investment in their current solution, and a TON of resistance to change. You can minimize the latter by making your solution as compatible with whatever turnkey solution they might be using. But most of them are customized, and the companies pay a LOT of money in maintenance fees to keep them moving forward. First, you'd have to duplicate what they've already got, then you'd have to figure out what their 3-5 year backlog of change requests is and implement the most significant of them, then get that into the hands of their Corporate IT people so far ahead of what their expectations of the current platform are that it's enough for them to go to their CIO and say, "We need to jump ship and go with this other product!" at which point they're likely to be fired. Facebook did not start out as a better MySpace. But it wasn't long before they put MySpade out of business. You need to find a small specific niche and start building something that's simple yet unique that solves a glaring problem, as laid out by an SME in that niche. Make it available cheaply or free and then listen to your customers and build new features they're looking for, but in a more abstract way. If you're lucky, in 10 years you'll have something that one of the elephants in the field will want to buy you out for 9 figures. But asking a bunch of people who are SMEs for writing software in Dephi about what they think should go into an MVP targeted at Corporate Sales, Marketing, Support, and Management is not going to get you anywhere. Reach out to SMEs in THAT domain, and the first thing you should ask is, "What's it going to take to get a typical Corporation to adopt a new and unproven CRM product? You're not going to like their answer.
-
This looks great, although it's 4 years after I created this thread and I am long gone from that employer. The article says a command-line version is "coming soon". Generally that would be sufficient for my typical needs. Is there any way to get updates on its progress?
-
ifthen strange return value !
David Schwartz replied to bravesofts's topic in Algorithms, Data Structures and Class Design
@bravesofts Tell me, if you go to a restaurant and they don't use a dishwasher, but instead simply wipe off dishes that people use and then use them again, what do you get served a drink in? You'd call it a "dirty cup". The cup or dish itself is there -- it's intact, it's complete, it's ready to go. But it's "dirty" -- its contents have not been set to "clean", initialized as it were, or NIL if it's an object. A variable in Delphi is a pointer. The assumption is that it points to an object somewhere. The language requires you to set it to a known initial state -- that's called INITIALIZATION. You can initialize it to either NIL or a valid pointer. Just leaving it uninitialized raises a compiler warning and usually leads to bugs if ignored. Declaring a variable as an object allocates a pointer and you don't know until run-time if what it's pointing at is a valid object or not. If you're lucky it throws a memory error; if you're unlucky, it goes off into the weeds because the data appears valid and eventually crashes on something unrelated, sending you down a rabbit hole that's unrelated to the REAL error. Your code is correct as far as Delphi's syntax and semantics go. Only it's not reflecting what you think it is. You're testing the contents of the pointer var itself, not the OBJECT. There's a built-in function called Assigned(x) that you should be using, not your own method, IsAllocated, because all Delphi knows is if the reference is NIL or not. If it's not, then it assumes it's a pointer to a valid instance of said object. It has no way of knowing if it's allocated or not, or even if it's valid or not. If your code NEVER INITIALIZES it, then local variables take on whatever value is in the memory allocated on the stack for that variable. You need to INITIALIZE IT BEFORE USING IT. Usually, that means you say: myVar := NIL; You can also say something like: myVar := TMyObject.Create(); In C++ you can specify initialization values for specific fields in the class IN THE DEFINITION so that when you DECLARE AN INSTANCE then those fields are AUTO-INITIALIZED. This is not possible in Delphi. Declaring a variable for an object does not create an instance of it; the value of that pointer is not auto-initialized -- you have to do it yourself, usually by setting it to NIL. -
Don't re-invent the wheel. Use a TClientDataSet or some other in-memory table with indices set up on the columns and it should run like greased lightning. (That's what adding an index to a column is for!)
-
It would help a lot if you'd explain the problem you're having. Looking at the code, I'm _guessing_ that you only have a single vertical list of panels on that scrollbox. However, I can't tell if you have horizontal scrolling active or not. Assuming you don't want the panels resized, then they should all have the same relative positioning. I'm doing something similar with some panels on a scrollbox that does not do horizontal scrolling. It put three across and unlimited rows. I have a list of things and I go through the list and display them like this: 1 ---- 2 ---- 3 4 ---- 5 ---- 6 7 ---- 8 ---- 9 . . . I have a row_count and col_count, and position them with a gutter above and to the left, and derive the Top and Left position of each one with simple math based on curr_row and curr_col that I track as I'm laying them down. I save the Top, Left, Height, and Width in the objects in the list. The Height and Width are always constant, but the Top and Left change based on whether I want to show or hide them based on filtering. I have no problem scrolling vertically. I don't want or need horizontal scrolling. And the form isn't sizeable. But there's no reason this approach shouldn't work. When the form size changes, check the dimensions and if the number per row changes, then hide then reset the panels on the scrollbox area to maximize the number you can have with the given gutter size you're using. (I'm using 20 for both, but you seem to be using 5 for Vertical and you're ignoring Horizontal.) But if there was a problem based on this code, I'd say it's because you're calculating the positions by deriving them by SUMMING things up while scanning through your list. If you do allow horizontal scrolling, then that's just not going to work. The summing approach you're using will ONLY work properly if there's JUST ONE COLUMN. If there are multiple columns, you're going to get a steadily growing gap between rows in increments of the panel.Height+5. That might be happening simply because you have horizontal scrolling enabled. You need to use indices and calculate the TOP and LEFT based on a panel's index, the number of columns and rows you have, the gutter size between them, and current row and column.
-
I'd like to build something that can be trained to recognize a deck of playing cards or flash cards, both upright and upside-down. Why? Because it's far easier and cheaper to be able to use a set of existing cards to do this as opposed to printing up a set with barcodes on them that the computer can read. Copyright issues aside, it's really expensive to print a set of playing cards. You need to print them by the 1000s if not 10,000s and then you have to sell them. It's not a quick process. Or print unique barcodes / QR codes / NFC tags and stick them on all of the cards. This is the "age of AI" so why not just be able to use a deck of cards and train the software to recognize each one? Once trained and incorporated into an app, you could hold up a card in front of the video camera and it would recognize it and as one of the cards it was trained on, say as an index into the list of cards, and be able to process it via the index from that point forward. I'm looking at a relatively limited set of cards, up to 100 or so, with images of varying complexity, and recognize each one with a high degree of accuracy. This is just pattern recognition, not any kind of generative aspect. What's the best way to go about something like this in Delphi?