-
Content Count
1223 -
Joined
-
Last visited
-
Days Won
25
Everything posted by David Schwartz
-
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?
-
how to recognize cards drawn from a deck?
David Schwartz replied to David Schwartz's topic in General Help
I have no problem with licensing libraries, unlike a lot of programmers today. I draw the line at royalties on a per-use basis, however. A quick glance at this library tells me it's designed to be trained from a bunch of samples in order to classify and/or recognize unseen examples based on common features extracted from the samples. I only have a single example of each card. If you hold up the Ace of Spades, there's only one of them and it should not be confused by whether it's red or black, or a Club, Diamond, or Heart. I want to train it on all of the cards in the deck so it recognizes any given card from that deck that's held up to the camera. Noise might be present in terms of variances in color tint and hue, brightness, contrast, and orientation, but the same details are unchanged and not fuzzy nor ambiguous. -
Dynamic array used as a queue. Memory fragmentation?
David Schwartz replied to A.M. Hoornweg's topic in RTL and Delphi Object Pascal
What you want is a circular buffer that points to buffers in a memory pool if they're all the same size, or pools of different sizes if they vary. The pool pre-allocates (static) buffers that are re-used, so no fragmentation occurs. Memory fragmention is not your biggest issue, it's atomic reads and writes, or test-and-sets to avoid corruption and gridlock from race conditions. -
Embedded javascript engine in Delphi
David Schwartz replied to duzzell's topic in Network, Cloud and Web
Have you looked at TMS WEB Core? You can write your code in Dephi and it transpiles it into JS. You can use pretty much any 3rd-party JS lib. I use HTTP for I/O, but you could use JS just as easily. And the language has been extended to support async requests in-line. -
how to recognize cards drawn from a deck?
David Schwartz replied to David Schwartz's topic in General Help
Anything like that in just Delphi? -
Avoid parameter evaluation
David Schwartz replied to Maxime Janvier's topic in RTL and Delphi Object Pascal
Yup, you're right about Simula vs. Modula. I learned LISP in college. I found it to be a very strange language, but it helped me really understand recursive programming. It probably did support a lot of things, including anonymous functions, but we didn't get that far in the class. I wouldn't hold it up as an exemplar for much of anything other than an interesting experiment at the time. It was an interpreter that took very few resources and let you create programs by defining rabbit holes to go down. Unlike most other languages, iteration was much harder to do than recursion. But I guess it was a good learning tool for a few things, given what was available at the time. -
What is the best way to accomplish this?
David Schwartz replied to alank2's topic in Network, Cloud and Web
What comes to mind for me is a simple publish/subscribe model with a lightweight notification mechanism like MQTT. It would keep the overhead miminal and could easily be kept out-of-band relative to the actual data channels. -
Avoid parameter evaluation
David Schwartz replied to Maxime Janvier's topic in RTL and Delphi Object Pascal
Nope, as Remy pointed out, they weren't actually supported until Java 7 or 8. I remember reading a bunch of stuff back when Java 8 was released about how difficult it was for them to get the anonymous methods working, and they weren't even supported as "first class objects". They were improved in the next version and the syntax was simplified significantly. I was at some tech event shortly after Java 8 was released, and I happened to talk with the SW Dev Mgr who coordinated a rather large team of Java devs at a local company, and asked him what version of Java they were using. He admitted they has finally just switched over to Java 6 about 6 months earlier, and it took them a couple of years to do that. I asked what their plans were to migrate to Java 8. He said the architecture of their overall system was unable to handle it, and they had started on a mission to completely rebuild the system from scratch that could track newer Java releases. I played with Java for about a week and quickly got disgusted with it. I don't know who thought it would be a Good Idea to put Configuration Management stuff into a programming language, but I think it was a truly insane idea. That was what the aforementioned manager was referring to, because their system got boxed-in and the architecture calcified because of so much of that and how inflexible it was. Even Delphi does a better job at that than Java does! Delphi has supported lambdas and closures as "first class objects" since they were first introduced, or maybe the following update. (I wasn't paying much attention at the time.) -
Avoid parameter evaluation
David Schwartz replied to Maxime Janvier's topic in RTL and Delphi Object Pascal
I'm still using D10.4.2, and it has trouble dealing with inline vars that have been in C++ since it was released in 1985. -
Avoid parameter evaluation
David Schwartz replied to Maxime Janvier's topic in RTL and Delphi Object Pascal
IIRC, Smalltalk was the first language that popularized the notion of 'classes' and OOP, although classes were first implemented in Modula which never really got much traction. Both Modula and Smalltalk were way ahead of their time. -
Avoid parameter evaluation
David Schwartz replied to Maxime Janvier's topic in RTL and Delphi Object Pascal
Delphi is a few decades behind contemporary language features today. The last several language additions have been around since the 90's. I'm not sure how far into the 2000's they are yet. I think I'll be long dead before they catch up with the more popular language features that most languages already support today in 2024. I mean ... hey ... the only thing added in D12 was multi-line string literals. WOOT! WOOT! I'm not moving off of D10.4.2 until they start focusing on real language improvements. Given how many emails I'm getting lately trying to urge people to get back onto maintenance plans, I'm guessing the user base is shrinking ... maybe because nobody wants to use a language that's still stuck in the 90's when most contemporary languages are still evolving quite steadily. I think Delphi introduced anonymous methods and closures before Java did. But since then, Java has updated them with nearly every release, and they look nothing like they did initially. I can't think of anything that has changed with Delphi's syntax. -
I have a list of company names + phone# / city / state. I want to find their main website URL and/or a google business page? What tools are available to do this (without any programming needed)?
-
I've had to deal with several variations of that over time. Are there web-hooks in place that call the system to hand over each JSON packet? Or are they just dumped in chunks into a file, accessible by something like FTP? Or do you have to poll a system periodically for new data that has accumulated? 60k records per day isn't that big of a deal. And text is quite easy to compress, especially if there's a limited lexicon involved. Then there's the backing store, where it really depends on the total lifetime of that data, what the half-life of searches is (so you know when you can flush it out to secondary storage with low likelihood of needing the majority of it), and tuning the DB to optimize the queries that come in. In America, certain types of records need to be kept for a legally-defined minimum length of time, like 7 years for corporate and financial records. Most of it isn't ever looked at, but it needs to be kept online and backed-up in case of audits or lawsuits. Just figure out how to compress the crap out of it and stash it away so it's easy to retrieve when needed. The point is, your job is to make sure the recent data is quickly accessible, while the older data is on slower more massive drives but still accessible in a reasonable amount of time. (A subpoena for data might give a month or more to provide it, which should be plenty of time to deal with slower backing stores, or even mag tapes.) Do NOT try to make 100% of it accessible "instantly". The client might have some temporal requirements, but make sure they're reasonable.
-
Just with Delphi? Do you use other languages with frameworks that provide a cleaner solution? I've only used Delphi. Prior to that I spent most of 15+ years doing embedded systems programming, and they never used DBs for performance reasons. It was pretty low-level C and C++. Frameworks were fairly primitive back then. And there were lots of Delphi apps I worked on that were essentially embedded systems, like stand-alone kiosks, that had content created externally and manually installed -- no DBs were used here either.
-
Yeah, it often is. What if you're not using DB-aware controls? The OP didn't sound like he was. As I said, the DB-aware controls add a lot of buffering and logic to simplify this. If you just have any random form that's got edits and grids and checkboxes and whatnot on it, and they are NOT DB-aware controls, then what do you do? Like, say, you have a form that displays data returned from an HTTP GET request as a JSON packet that consists of an array of objects, and you want to scroll through the objects as if they're records in a table? I'm genuinely curious. This wide disparity between forms that are used for interacting with DBs that have DB-aware controls on them vs. those that don't -- because you're not using DB -- has always perplexed me with Delphi. I've seen at least a half-dozen different solutions used over the years for the latter case, none of which were particularly elegant. Sometimes I asked the developer why he didn't just use an in-memory table and DB-aware controls, and the excuse was usually that it "added too much overhead to the app". OTOH, there have been numerous situations where I got rid of a bunch of code that did this and replaced it with an in-memory table and DB-aware controls, and the performance actually improved.