![]() |
by Remy Porter on (#6A8DW)
While the world has switched to RESTful APIs, the magical power of SOAP-based web-services was that they made code generation easy. Well, easy-ish. Well, easy when it worked right, and then hard the rest of the time. But if it worked, if the WSDL was up to date and sane, you'd get a nice client-side API to invoke methods on the remote server.Andrew inherited one such client-side C# API. It looked something like this:
|
The Daily WTF
Link | http://thedailywtf.com/ |
Feed | http://syndication.thedailywtf.com/TheDailyWtf |
Updated | 2025-10-03 05:46 |
![]() |
by Remy Porter on (#6A74Z)
Dates and times are way more complicated than we usually think they are, especially when we're talking about historical dates and times. The solution, of course, is to always use someone else's work, whether it's a library or your language's built-ins, never implement date handling yourself.For a long time, though, Java's date handling left something to be desired. Which is why Sven found this history lesson in his company's code base:
|
![]() |
by Lyle Seaman on (#6A4PF)
Many years ago, at the height of the Industrial Revolution, theUnited States was criscrossed by a riot of regional railroads.Gradually, these were acquired or merged until nowthere are only about a half-dozen majornational railroads. In a similar fashion,at the birth of the public Internet, there musthave been thousands of community Internetservice providers. It seemed like every town had its own entrepeneurial enterprise, with some racks of modemsin an office somewhere. Those quickly got snapped upor forced into bankruptcy, as legacy cabletelecoms companies leveraged their existing monopolies into a new line of business. Which brings us to this week's Error'd. Enjoy(?) it.First up,Adrian McCarthy grumbles "Getting help can be difficult when your regional monopolyinternet service provider cannot assemble a functionalweb site. Note that the understandably required Descriptionfield in this online support contact form is disabled."
|
![]() |
by Remy Porter on (#6A3KS)
Ah, the joys of stringly typed code. Everything can be turned into a string, so why not treat everything as a string? It certainly worked for Sebastian's co-worker, who also took it to another level:
|
![]() |
by Remy Porter on (#6A27Q)
We like using constants instead of magic numbers. Today, we see an unusual misuse of them. It's unusual because, while it's a set of bad choices, it's not quite a `#define ONE 1` level of silliness.First, a little background. Benjamin inherited a building automation system. This building automation system was implemented in Microsoft's Visual C++, version 6.0, way back in the 90s. As of the late 2010s, not only was it still in use, it was still pinned to the same compiler version. So not exactly the most modern of applications, but it accomplished the business goals, albeit with a lot of bugs, errors, and mysterious glitches.Here is how the application checked how long an operation took:
|
![]() |
by Remy Porter on (#6A105)
Pretty much all object oriented languages have some concept of "destruction": objects need to release any resources they acquired at construction. In a lot of cases, we don't need to customize this terribly much, but when we do, it's vitally important to do it correctly.Nancy's co-worker perhaps didn't understand the "correctly" part. So this was the standard pattern of C++ destructor that they wrote:
|
![]() |
by Remy Porter on (#69ZRG)
Managing the requirements for an application is a huge challenge. The hardest part of the challenge is that, very frequently, the user's don't know what they really want or need. Prying it out of them, and giving them an application that actually solves the real problem they have, is an art.The worst situation is when the users are absolutely certain that they do know what they want. This was the situation that Irini found herself in.The project started, as many such projects do, in the wake of a disaster. One of the company's many Capital Improvement Projects (CIP) slipped through the cracks during budgeting. It ran six months past schedule, but managed to close out with a few hundred grand still unspent in its budget. When someone tried to reallocate that money, the management team in charge of managing CIPs found out, they went full code-red, trying to do two things at the same time: understand why that project got lost in tracking, and also why when they tried to reallocate the money, it kept getting reset in their Enterprise Resource Planning (ERP) system.Eventually, that lead them to Sofia, the VP of Finance, and managed them all through a spreadsheet she had created by herself. The ERP kept getting reset because she manually updated it based on the contents of the spreadsheet. The project got lost because she manually color-coded the projects in her spreadsheet, and one day accidentally hid the row, instead of making it yellow.No one liked that there was a manual process. No one liked that only one person ever touched this system. Management wanted a robust, backed-up IT system, and wanted to open the management of this process to more of the finance team, so Sofia wasn't the only failure point.The solution was clear: gather requirements from Sofia and either purchase a product or develop something in house to replace the spreadsheet. Very quickly, it was decided that "develop in house" was the only way to customize the tool to what Sofia's process already looked like, and "standardizing the process" was not an option.Irini was on the IT team that was chosen to build this product. A business analyst tried to sit down with Sofia to suss out her actual requirements, but hit a brick wall. The spreadsheet already did everything she wanted. The spreadsheet was the requirements. She gave the analyst a copy and sent him on his way to get something built.As mentioned, Sofia manually color-coded the rows in the sheet to help with project tracking. Fortunately for the development team, her spreadsheet included a key, describing what the colors meant. Unfortunately, it was this "technicolor yawn", as Irini puts it:Now, as "re-implement this spreadsheet as an application" goes, this isn't terrible. It's an ugly, complicated set of rules, but at least it's documented. But what we have here is a case of one person's idiosyncratic style of organization determining the features for all users of the application.This is what the users said they wanted. This was what the dev team implemented. Everyone on the dev team suggested that maybe they needed a better way of letting users filter, sort, and prioritize their capital projects, possibly even allowing each user to manage custom filters, but no- the spreadsheet was the requirements.When the app launched, the Finance team was excited to have more control over their capital projects. Then they started to use the application, and quickly got confused. It was built, not to solve the problem of managing projects, but to fit Sofia's workflow, and her workflow alone. It was impenetrable and opaque to everyone else. After a few months of endless tickets as users got lost in the confusing interface, most of them gave up.Sofia stuck with it longer, but she hated the application. As it turned out, automatic color coding was a big anti-feature for her, because the rules she had in the sheet were just guidelines, and she wanted to be able to apply any color to any project based on information that existed only in her head.The application is still technically running, but nobody in Finance is using it. They've reverted back to "Sofia has a spreadsheet for it." [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
|
![]() |
by Lyle Seaman on (#69X8V)
We got quite a few irregular submissions this week from regularcontributors. Which is to say routine contributors. We're not qualified to make judgements about whether or not anyone is whatwhat most folks would call normal.First up,Isaac D. is struggling with localization,kvetching"Apparently this number format is ALIVE and WELL in partsof India and Afghanistan, but us poor Australians on desktopbrowsers also seem to be visually assaulted with it. Iwonder if the Zuck will pay me $1,00,000 for reportingit or do real country borders mean nada in the Metaverse? ;)"This would ordinarily be controlled by some operatingsystem or browser configuration, would it not?
|
![]() |
by Remy Porter on (#69W1A)
James's management had more work than they had staffing for, so they did what any company would do in that situation: expand their staff. No, of course not, I'm kidding. They bundled up a pile of work and shipped it off to the contractor who gave them the lowest bid, provided absolutely no oversight or code-quality standards in the contract, and hoped for the best.What they got back was a gigantic pile of code that compiled. That is the only positive thing one can say about the code, because it certainly didn't work. Within a few weeks of starting reviewing the gigantic pile of garbage the contractors turned in, the dev team reached the decision that it would be quicker to rewrite from scratch than it was to try and pick apart the trashpile and reshaped the refuse into something approaching their actual requirements.James sends us just one small VB .Net property definition which summarizes the kinds of problems they were dealing with:
|
![]() |
by Remy Porter on (#69TRE)
Mira was trawling through some old Python code. This particular block of code needed to load some data from JSON. The data was an array, and the code needed to know how long the array was.Python has a handy len function that does this on anything enumerable. If our developer had used len, we'd be looking at different code today.This was their approach:
|
![]() |
by Remy Porter on (#69SEY)
One of Tim's co-workers needed to handle a simple condition: if a control in their web app was enabled, show it, otherwise hide it.Now, if you or I were writing that, we might write some awfully verbose code, like:
|
![]() |
by Remy Porter on (#69R6F)
Iterating across a list is a very simple task. It's a CS-101 type thing, and if anything, it's the one thing I'd expect any developer to be able to do without confusing me too much.Brendan has a co-worker that wants to change my mind about this.They write Java code like this:
|
![]() |
by Lyle Seaman on (#69NHP)
IBM Profs was introduced in 1980 including both email and calendaring support. Onlinecalendaring is now old enough to have grandchildren, but we still can't get the simplest things right.As our friendRomeo rhetorically wonders "Million dollar question: What calendar does Microsoft use?"
|
![]() |
by Remy Porter on (#69M5V)
If you're writing an application with a drop-down list, it's typical and reasonable to auto-select a certain option in the list. But John found an approach to doing this that's anything but typical.
|
![]() |
by Remy Porter on (#69JX8)
Gennifer had a job. Her employer got bought out by another company, and the purchaser was notorious for gobbling up companies, taking over their processes, and then doing mass layoffs. Seeing the writing on the wall, Gennifer started job hunting.Before too long, she had two very likely candidates. The first was Initrode. It wasn't a great match- Gennifer's skills didn't overlap well, and while the salary was respectable, it wasn't as good as the other position, at Initech.Gennifer interviewed at Initrode first. She did a single round of interviews, and left the interview with an offer. She told them that she'd consider it, but also let them know she was engaged in the recruitment process elsewhere. They understood, but did let her know that they would need a response relatively soon.The Initech interviews were wildly different. First, she did an hour and a half interview with the head-hunting agency that connected her with the position. That went well, so the next step was an online coding assessment, which she aced. The final round was a remote interview with Initech, sitting in with Bob, Bob, and Bill."Great to have you on the call," said the first Bob. "Let's just get right into it.""Where do you see yourself in five years?" asked the other Bob.That was a strong opener. What followed were the other typical soft questions: what's your biggest strength, what's your biggest weakness, tell me about a time you had to resolve a conflict, etc.Then Bill got into it. "Pick up an object on your desk," Bill said. "Pick anything."Gennifer picked up an eraser and held it in front of the camera."Okay, now explain multiple inheritance in C++ using that object."Gennifer blinked, surprised. "Um, an eraser has the 'remove marks' functionality. A pencil would have the 'make marks' functionality. Some pencils have erasers on the end, so those pencils are also erasers, so we could say that they inherit from both the regular pencil class and the eraser class."Bill shook his head. "That isn't really the best example."Gennifer put the eraser down."How about this," the other Bob said. "How would you test a coffee mug?"Gennifer thought that was a better question for an engineer at Pfaltzgraff or a similar company, but she described a series of tests, starting with basic functionality (I can lift it by the handle, I can pour liquid into it) to more stress testing type considerations. That answer they liked."What I need you to tell me," Bill said, "is why I should hire you?""I mean, you're actively looking for developers, my skills are a perfect match for the position. That seems like a good reason to hire someone."Bill shook his head. "What I need to know is that you're not going to take this job and leave after several months."The Bobs nodded. One of them said, "We've had a little problem with retention, lately.""We think it's millennials," the other said. "They can't really commit to a hard day's work.""They just take the job, discover they don't like it here, and leave.""How do we know you're not going to do that to us, too?" Bill asked.That exchange raised so many red flags that it could have collapsed the USSR all over again. Gennifer replied with a statement about how her job history showed that she tended to stick it out in jobs, and wasn't simply running from job to job as a form of career advancement. They concluded the interview."Someone from our office will be in touch in the next two weeks with feedback," the Bobs said.Gennifer left the interview sure of two things: they didn't want to hire her, and she didn't want to work there. So she wrote up an email, thanking them for their time, but she was going to move forward with a different opportunity. She sent it off and thought that was the end of that.The headhunter called a few minutes after she hit send. "What are you doing? You can't decline this offer.""They haven't made an offer," Gennifer said, "and I don't think they're going to.""Are you kidding? I just got off the phone, and they were raving about you. They think you're great. They definitely want to move forward. They just have a hard interviewing style, everyone walks out thinking they whiffed it. The job is yours.""Well, I don't think I'm interested.""Oh, so you're wasting my time, then?" the recruiter said, angrily."No- it's just-"Gennifer didn't want to burn a bridge with the headhunter- in her locale, it was a small industry and everyone knew everyone- so she politely let him rant for nearly an hour about how great the opportunity was, how much Initech wanted her on their team, and how absolutely rude it would be if she didn't take the position. She'd be wasting everyone's time."I apologize for my rudeness," she said, "but I have to do what's best for my career. And honestly, if that's their normal interview process, and this is their normal communication style, I don't want to work there. Thank you for your time."Gennifer now works with Initrode. The headhunter still sends her messages on LinkedIn, suggesting she should reconsider. [Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
|
![]() |
by Remy Porter on (#69HMA)
Another day, another terrible way to validate integers. Today's submission comes from Sluiper.This approach, at least, contains a mild bit of cleverness. It's not the good kind of cleverness that makes a complicated problem more clear and easier to understand, but the bad kind that exploits assumptions about low-level technical details.
|
![]() |
by Remy Porter on (#69GE6)
Sandra, still at InitAg, has to work with Brad. Some time ago, Brad was assigned a slew of front-end development tasks, since he's a web developer. But Brad isn't a front-end developer, and doesn't really have a good grasp of front-end development. Management isn't clear on the difference: "Aren't you a web developer? I don't care which end you use, just develop." Brad is also game to tackle whatever task is assigned to him, regardless of whether he has any sense of how to solve the problem.When Brad needed to display data on a map, the requirements wanted the map layers to be distinguished by color. So Brad did the usual thing one might do in this situation: he created a gigantic array of all possible colors that might be used on the map. Actually, he created two: colors and colorsBlackWhite.
|
![]() |
by Lyle Seaman on (#69DSD)
Automotive afficionado Mike S. proudly relates "My first and only car has been a classic 1965 6-cyl FordNull. I've always loved it but it does crash from timeto time, even though I've received many pointers on howto avoid that. I've considered getting an Infiniti andthen would divide my time between the two." Avoid pointers,Mike.
|
![]() |
by Remy Porter on (#69CJJ)
Pieter-Jan needed to add some features to a PHP-based site for managing student assessments. Students would complete projects, submit them, and then receive feedback from their peers. The number of peers providing feedback is variable, so the application has to manage that. Which, you might be thinking, "that sounds like not a big deal to manage," but for Pieter-Jan's predecessor, it seems like it may have been.
|
![]() |
by Remy Porter on (#69BB1)
Stack V supports a web application that accepts regexes from users. For legacy reasons, the users must supply the surrounding / characters, as well. There was some validation to ensure that the inputs were correct, but QA discovered that invalid regular expressions were getting through.They filed a bug, it got triaged, and then shipped off to a contractor to patch. This was the contractor's solution:
|
![]() |
by Remy Porter on (#69A2Z)
A true confession: I absolutely cannot successfully edit a crontab file without spending a lot of time reading docs on what all the little date/time/interval flags mean. Partially, it's just that I don't do it very often, but mainly the information flies right out of my head once I've done it. I can absolutely understand why someone might want to write a little helper program to help themselves manage their crontab.I just can't understand why they'd write this one, sent to us Beorn. We'll have to take this one in chunks, because it's 18,905 lines.We'll start with the function dayofweek, so you can get a sense of the pattern that gets used. Here's the first if condition for its core logic:
|
![]() |
by Remy Porter on (#6991Y)
A former co-worker of David S wanted to check for nulls, and apparently, they had just learned about the ternary operator, so they wanted to combine these actions. That, itself, isn't a WTF- using ternaries to coalesce nulls is a time-honored tradition and generally pretty effective.Let's see how this Java developer approached it:
|
![]() |
by Remy Porter on (#698W3)
A former co-worker of David S wanted to check for nulls, and apparently, they had just learned about the ternary operator, so they wanted to combine these actions. That, itself, isn't a WTF- using ternaries to coalesce nulls is a time-honored tradition and generally pretty effective.Let's see how this Java developer approached it:
|
![]() |
by Lyle Seaman on (#69679)
Slow news week at Error'd, so we're dusting off a couple of submissions from earlier. That last one's a beauty, eh?Special Dave flexes"Got my annual request for a donation to Habitat forHumanity. Not sure if their new URL is meant to conveyjust how special I am as a donor, or if someone wasgoofing off with a test for formatting the form andforgot to change before their production run." We loveyou too, sweet cheeks.
|
![]() |
by Remy Porter on (#694WZ)
As we frequently note, a staggering number of real-world software products start their lives as Access databases running from a shared folder somewhere. There are professional developers who end up maintaining these monstrosities.Gregory has had the misfortune of being one of those developers. A client has a terribly performing Access database, and it happens to be the driver of their business: it generates insurance quotes for an insurance company.Let's take a look at some of the code.
|
![]() |
by Remy Porter on (#693V3)
Magic strings are as bad as magic numbers, if not worse. So when Tomasz found this block, it didn't seem so bad:
|
![]() |
by Remy Porter on (#692G1)
"Why aren't we using microservices?"It was an odd way to start a meeting, but it got Mr. TA's attention. TA was contracting with a client, and sitting in a meeting with their senior architects. TA and one of his peers exchanged a glance and a small eye-roll. They knew exactly what had happened: Alvin, the senior architect, had learned about a new fad.The application that TA's team was working on, and the core product which the client offered, was a pretty simple data-driven application. It was, at its core, one SQL Server database, a simple front-end, and could easily run reliably off of a moderately powerful server. With co-location and rackspace costs, it could cost them a few thousand a month to operate.But the senior engineers heard about the cloud. And they wanted everything in the cloud. And they wanted all the latest features that Azure had to offer. Which meant they were spending hundreds of thousands a month to host the application."It doesn't matter why we aren't using microservices," the senior architect went on. "What matters is that we're getting left behind. If we want to operate at webscale and provide maximum advantage to our users, with always-on reliability, we need to be using microservices. And don't worry: I have a plan for the transition."Alvin pulled up a PowerPoint slide entitled "Initech's Microservice Migration".Alvin's microservice plan called for dividing the application up into 13 modules. The boundaries were arbitrary, with only the vaguest sense of putting common functionality into the same microservice. Most of the proposed microservices weren't single purpose- they each contained multiple unrelated pieces of functionality, making them not exactly micro.But that wasn't the biggest issue. Alvin had a vision of 13 different microservices, and each microservice needed to have its own database. After all, each microservice was supposed to be independently deployable from any other. So their single SQL Server database got split into 13 different databases.Of course, this created all sorts of new problems. The "Admin" "micro"service (which contained a few hundred endpoints, once again, stretching the definition of "micro") had all the admin tables siloed off into its own database. But every other "micro"service needed to access the data in those admin tables.Now, if this all stayed in one database, it'd be easy to do joins. Heck, even if this were just an on-prem SQL Server deployment, cross-database queries are completely doable. But in Azure, your only option is to use the "Linked Tables" feature, which means creating an object for each remote table you want to access. Since you have 13 databases, all needing several tables from every other, you can see how this quickly spirals out of control in terms of complexity."But that's not a problem," Alvin explained, when TA pointed out this problem. "We're using microservices, which means we scale horizontally.""What do you mean by that?""We just add more resources to the cloud, and let our microservices collaborate," Alvin said."I'm not clear how that solves the problem.""That's why I'm the architect."It took several weeks of back-and-forth to get Alvin to explain his brillant architecture. What Alvin intended was to have every microservice fetch the related data by talking to other microservices. All the joins would just be done in the application layer, and any performance problems could be solved by going "webscale", which is to say: throwing money into a pit and setting it on fire to please the great god Azure.Despite Mr. TA's protests, that was the direction everyone marched off in. When it rapidly became clear that this was non-viable, Alvin adapted."So, to boost performance, we'll replicate a few tables between databases."Replication was an initial bulk copy, and then updating the "micro"service responsible for those tables to do its update multiple times in multiple databases. Unfortunately, due to the mess Alvin had made of things, the databases had lost referential integrity, which meant they couldn't leverage foreign key constraints to protect the data.The worst "replicated" table was the one for tracking shipments. In the original, "source of truth" location, it was designed with a slew of NVARCHAR columns named UserDefinedField01, and UserDefinedField27 and UserDefinedField112. There was an additional lookup table that applications could use to map those fields to UI elements, but that didn't exactly help all the other "micro"services that wanted that data. So Alvin set up a replication process that normalized that data into a more traditional database schema in the other 12 databases that wanted the data. Unfortunately, it wasn't the same normalization of the data in each of those remote databases, making the maintenance of replication a gigantic pain.At this point, it should surprise no one to learn that Alvin also just used NVARCHAR fields for basically everything, even things that absolutely have no reason to be. For example, the Users table, quite reasonably, had an autonumbered UserId field. It also had a UserName field. Every table that related (or "related", in the databases that didn't contain user information), used UserName as the foreign key.Eventually, Alvin's microservice migration limped across the arbitrarily defined finish line. Alvin presented management with a self-congratulatory project retrospective that highlighted his leadership, his technical vision, and how their were now well positioned for the future, by using the latest techniques.Interestingly, this retrospective completely ignored the costs of the migration, or the fact that to maintain the same level of performance as the old architecture, they had to spent almost 75% more on cloud services. [Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.
|
![]() |
by Remy Porter on (#691FW)
Ryan's co-worker caught a high priority ticket- certain features of their dashboard app were crashing when anyone tried to access them. It didn't take long to figure out that there was a stack overflow, and that some recursive function was blowing out the stack.It took a little longer to find the recursive function in their C# code base:
|
![]() |
by Lyle Seaman on (#68Z8K)
When the New Year just isn't exciting anymore, and youneed an extra dose of that New Year smell, you can getit right here at Errorerr'd. Again. Dates are(not this) hard.We are very satisfied with this submission from Ben S. who pithily noted "This was the 2023 survey."
|
![]() |
by Remy Porter on (#68Y0P)
Discerning the type of data stored in a file is frequently a challenge. We've come up with all sorts of ways to do it- like including magic bytes at the start of a file, using file extensions, appending MIME type information where possible, and frequently just hoping for the best. Ivan was working on a Python system that needed to handle XML data. Someone wanted to make sure that the XML data was actually XML, and not some other file format.
|
![]() |
by Remy Porter on (#68WQQ)
Ben ran into some misbehaving C# code- handling users was not doing what it was supposed to do, and when "what it's supposed to do" is "prevent users from seeing content owned by other users without permission", that's a bad thing.The code Ben found wasn't the cause of the bug, but it ended up wasting a bunch of his time as he tried to understand why it existed.It starts with:
|
![]() |
by Remy Porter on (#68VDR)
Ah, the joy of comments. Good comments can illuminate complicated code, explain a programmer's reasoning, or even just do their best to absolve a burned out programmer of their sins. "Yes, it's bad, but it works."Then there's this comment, sent to us by Mark B. This is from a configuration file format, "helpfully" explaining what the flag does.
|
![]() |
by Remy Porter on (#68T88)
Today, Morpheus sends us a SQL injection vulnerability. But it's a peculiar version that only uses parameters. Let's start with the bit that looks normal:
|
![]() |
by Lyle Seaman on (#68QJQ)
No real theme this week, just some random groaners to tide you through the weekend.Historian Drew W. wonders"I'm not sure which is weirder: the fact that Verizon hasa bunch of numbers after it or that AT&T seems to bestuck in roughly 2013 (when Sprint killed the Nextel network for good)."
|
![]() |
by Remy Porter on (#68P9Y)
One of the most powerful features of using exceptions for error handling is that they let you create your own exceptions, and thus accurately describe the family of exceptional situations your code could generate. On the flip side, some developers over-specialize, creating custom exceptions for every different place an out-of-range error could happen, for example.Then there's the code Nasch was debugging recently. The previous developer found a different way to create unique exceptions for every place an error might occur.
|
![]() |
by Remy Porter on (#68N30)
Way back when Microsoft added LINQ to .NET, the real selling point was lazy evaluation. You could do something like var x = someList.Skip(3).Where((x) => x > 3).Take(5) and nothing would actually happen until you attempted to interact with the value of x. This can be especially great when interacting with a database, avoiding the round-trip until you actually need the data, and then only fetching the data which fulfills your request. If you understand what's happening, this can be pretty great.If you understand. Which brings us to Simon, who has inherited a "particularly bad" code base. This particular system is for tracking attendance, and the pool of individuals being tracked is rather large, so someone wanted to make sure that they were processed in batches of no more than 30. This is how they accomplished that.
|
![]() |
by Remy Porter on (#68KV4)
Unit tests are important, but unit tests alone don't guarantee a good code base. Sandra, still suffering at InitAg brings us a bug that was sitting in their project for months, undetected.In this case, Sandra's team needed to work with geographic information. Now, this is hard. Geography is hard. Maps are hard. Coordinate systems are hard.These complexities can express themselves in surprisingly simple ways. In common communication, many of us likely describe the coordinates as "latitude and longitude". It's how textbooks and even Wikipedia describe locations. But Geographic Information Systems do it the opposite way- lon/lat. Longitudes first.In fact, there's a standard for it, called GeoJSON, which defines a point thus:
|
![]() |
by Remy Porter on (#68JN2)
Visual Basic for Applications represents the core mistake of putting a full-featured programming environment on every desktop. That so much VBA code is bad is not remarkable- that any good code exists would be shocking.We rarely cover VBA code, because most of it is written by a non-programmer who discovered they could solve real business problems in Microsoft Access. TRWTF is, in fact, how much of the world runs on an Access database stuffed into a network share somewhere. But there are organizations that hire developers and then shove them into writing VBA, which is what happened to Doug. This code comes from quite awhile ago.Doug inherited a bunch of VBA code written by another developer. It has… issues. One issue, which Doug didn't send us, was a 500 switch statement followed by a 700 line switch statement where the vast majority of the clauses were duplicated between the two, and also all the bodies were simply setting a boolean variable to true or false.That's ugly and awful, but what Doug sent us is just weird:
|
![]() |
by Lyle Seaman on (#68G1Y)
Audiophile Gear H. enthused "Love me some Bob Dylan. But it looks like I'llneed to save up to complete my collection."
|
![]() |
by Remy Porter on (#68EXH)
We constantly see developers finding… creative solutions to the requirement that they avoid magic numbers in their code. Refactoring to define a constant is just too hard, apparently.Today, Maklemore sends us a short snippet that neatly solves the problem of magic numbers by making sure the number isn't a number, at least to start:
|
![]() |
by Remy Porter on (#68DN3)
Dave does a little work on a website when the core developers are in over their heads on maintenance. Which is a thing that happens a lot.Let's see if we can get a sense of why, starting with this little method here:
|
![]() |
by Remy Porter on (#68CBG)
GRH inherited an application written by someone who is no longer employed with the company, as part of a project managed by someone who is no longer at the company, requested by an executive who is also no longer at the company. There are no documented requirements, very few tests, and a lot of "don't touch this, it works".Well, it worked until it didn't. On a Friday before a long weekend, the application broke. As you might expect, it has a relatively small user pool, but is absolutely vital to the company's operations- if it fails, widgets don't get shipped and invoices don't get paid. So GRH got to spend that long weekend fixing the application.In this case, the application is a Microsoft ClickOnce deployment (essentially "install without showing the user an installer") distributed through a shared network drive.The specific section that broke was some code responsible for converting a PDF file into plain text.
|
![]() |
by Remy Porter on (#68B6V)
In the bad old days of web development, you had to deal with the fact that there weren't really any standards, and you had to customize your code for different browsers. The "right" way was to sniff for which features were available, but the most commonly used way was to check the user-agent string and guess based on the browser name. Because of this, browsers started to keyword spam their user-agent, to pass these checks, which is why my browser reports as Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36. My browser of choice is a Chrome fork, and I'm running on an M1 Mac, so basically none of those things are true.But let's look back at some code Lucas found, still lingering in a web app he maintains.
|
![]() |
by Lyle Seaman on (#688M7)
This week I read an article which asserted that the AI singularity is still several years away.Maybe they should wait until then before they start threatening us?The first of the last of the humans, Greg took the time to wonder about the meaning of this warning. Or is it a threat?"One of our in-house web applications implements an automaticlogout, but also lets you get a warning when you have afew minutes left before it does this. Their warning leavesme a bit puzzled, though, since it seems to imply thatit's a manual session timeout, and perhaps if I don'tclose the session in 5 minutes, I'll stay logged in? Orwill the world just end?" Run, Greg. Run.
|
![]() |
by Remy Porter on (#687BX)
Validating your inputs is important, even when the sender is an API- in the land of JSON-based data exchange, we can't guarantee which keys exist without checking.Philipp's team uses the "Runtypes" library to solve this problem. It lets them write code like this:
|
![]() |
by Remy Porter on (#6861D)
LK was browsing a local job site for a new position. The site was flaky, which lead LK to look into the code, and it looks like if anything, this job site should be hiring a new web developer.
|
![]() |
by Remy Porter on (#684RP)
If you want to configure a Java application, the standard way to do it is to use the Java Properties class. This class wraps around a simple, text-based file format (or an XML file, if you're into that) that allows you to store key/value pairs. It helpfully inherits from the HashMap class, letting you interact with those key/value pairs using a well understood API. The file format handles all the details of encoding and managing things like multiline strings.So you could just do that. Or, you could do what this senior dev with over a decade of experience did.
|
![]() |
by Remy Porter on (#683HT)
Code reviews are an important part of development processes, but sometimes, some developers manage to sneak around the process. That was the case with Orien's team, where most of the team were constantly checking in with each other, doing peer reviews, and trying to collaborate on a rather gigantic Perl codebase. One team member, on the other hand… didn't. Management wasn't interested in pushing the issue, so this developer got to do their own thing.And then the developer left. Over the next thirteen months, bug after bug started cropping up. Minor changes that should have been easy would unleash a ball of spaghettified nonsense that was impossible to debug but also emphatically didn't work. Things got so bad that the entire team needed to stop doing any new development for three months, and just fix bugs and refactor.In those three months, they mostly fixed things up. Mostly. There are still moments where someone is trawling through the code and finds something that just leaves them scratching their heads.This is one of those finds:
|
![]() |
by Lyle Seaman on (#68100)
Abandoning alliteration, the column this week isexperimenting with consonance. Next week, perhapswe'll see howeveryone feels about assonance.Job-hunterDespreately Looking for Internshipshared this job posting, writing "AMD Job Lsiting forgot to add in the deatils". Seems like a pretty easy job to perform;Mx. Des should apply.
|
![]() |
by Remy Porter on (#67ZQ0)
Denilson was doing some appliance shopping, and upon submitting a form, it errored out. Denilson was sure the form was correct, and did what any of us would do: pop open the developer console and check the code.The console dumped out a huge number of errors. And to no one's shock, the code had all sorts of home-made validation methods, like validateNumber. And, much to my surprise, they found new ways to make the simple task of validating a number horrible.
|