|
by Remy Porter on (#5MKFD)
Last week, we took a look at a hash array anti-pattern in JSON. This week, we get to see a Python version of that idea, with extra bonus quirks, from an anonymous submitter.In this specific case, the code needed to handle CSV files. The order of the columns absolutely matters, and thus the developer needed to make sure that they always handled columns in the correct order. This led to code like this:
|
The Daily WTF
| Link | http://thedailywtf.com/ |
| Feed | http://syndication.thedailywtf.com/TheDailyWtf |
| Updated | 2025-10-24 10:46 |
|
by Lyle Seaman on (#5MGP9)
Music fan Erina leads off this week with a double contraction!"Who knew Tom Waits was such a gravelly-voiced Relational Databasepoet?" she Mused. "You'd've thought that SQL modes wasmore of an indy garage esthetic." You might've, Erina, but I wouldn't've.
|
|
by Remy Porter on (#5MFCX)
Validating email addresses according to the actual email specification is more complicated than you usually think. Most homebrew validation tends to just get something that's relatively close, because hitting all the rules requires some fancy regex work. And honestly, for most applications, "pretty close to correct" is probably fine. If you actually care about collecting valid email addresses, you'll need to actually send mail to the address and have the user confirm receipt to "prove" that the email address is real, valid, and actually accessible.Still, some "close enough" solutions are better than others. Jon found this C# code:
|
|
by Remy Porter on (#5ME90)
Validation highlights the evolution of a programmer as they gain experience. A novice programmer, when given a validation problem, will tend to treat the string like an array or use substrings and attempt to verify that the input is the correct format. A more experienced programmer is going to break out the regexes. A very experienced programmer is going to just find a library or built-in method that does it, because there are better ways to use your time.Andrea provides a rare example of a developer on the cusp between regexes and built-in methods.
|
|
by Remy Porter on (#5MCTK)
There's a lot of room for disagreement in technology, but there's one universal, unchangeable truth: Oracle is the worst. But a second truth is that there's nothing so bad a programmer can't make it worse.Someone at Ben's company needed to take data from a database and write it to a file. That file needed to have some specific formatting. So they used the best possible tool for the job: a PL/SQL stored procedure.Now, PL/SQL is a… special language. The procedural elements it adds to SQL have a distinctly "we want to sell this to mainframe programmers" vibe, which makes the syntax verbose and clumsy. It frequently creates situations where things which should be easy are incredibly hard, and things which should be hard are impossible. But it's technically a feature-rich language, and you can even write web servers in it, if you want. And if you want to do that, you either work for Oracle or you should go work for Oracle, but certainly shouldn't be allowed out to mix with the general public.In any case, Ben's predecessor decided to generate a carefully formatted text file in PL/SQL, and had… their own way of accomplishing things.
|
|
by Remy Porter on (#5MBPK)
When Arbuzo joined a new team, they helpfully provided him some sample code to show him how to interact with their JSON API. It was all pretty standard-looking stuff. If, for example, they fetched a Customer object, it would have some fields about the customer, and an array containing links to orders that customer had made. One of the samples helpfully showed iterating across the orders array:
|
|
by Lyle Seaman on (#5M908)
This week's opening Error'd submission required a bit of translation forthe monoglots among us, but it was worth the work. Not speaking even een beetje of Dutch, I was forced to use Google's own translationservice to see what it was that had so worried our friend Sebas. And it's a doozy.
|
|
by Remy Porter on (#5M7MJ)
Pete has had some terrible luck with the lead programmers he's worked with. He's had a few which are… well, they don't take feedback well. Like his current team lead, who absolutely doesn't let any of the other developers review or comment on his code. "Don't ask me questions, you should know this already," is a common refrain. Speaking of questions:
|
|
by Remy Porter on (#5M618)
Jan's company has an application which needs to handle an Excel spreadsheet, because as I'm fond of pointing out, users love spreadsheets.The JavaScript code which handles parsing the spreadsheet contains… some choices. These choices caused it to fail on any spreadsheet with more than twenty six columns, and it's not hard to see why.
|
|
by Remy Porter on (#5M4JG)
One of the arguments against comments in code is that they create a need to have two things updated: the code and the documentation have to be kept in sync. Inevitably, they'll drift apart.David works with a junior developer who came onto the team with strong opinions about, well, everything. One of those strong opinions is that every single line needs to have comments. Each and every one.This is the end result:
|
|
by Remy Porter on (#5M3GJ)
Folks who first learned to type on typewriters tend to prefer putting two spaces after a period. Most of the rest of us prefer just one. And this may have caused a performance problem.Rob's application had a quick search feature to track down customer claims. One day, the quick search was running quickly and efficiently. A user could type in a claim number, hit enter, and a moment later their screen would show the claim. Suddenly, it slowed down. It wasn't just the gradual decline of growing data or stale statistics or bad indexes. It was a code change, and it didn't take long to find the problem:
|
|
by Lyle Seaman on (#5M14Q)
In the wake of yet another extraordinary ransomware attack, most businessesare finally beginning to implement the sorts of security measures they knewall along they should put in place. "Someday soon, when we get the time."Some writers have been calling it "unprecedented" but you and I know just how precedented it really is.Loyal reader Aubrey leads off with an insider report,writing "Corporate IT recently migrated the entire companyto a new antivirus program, and it seems to have flagged*its own update* as likely malware." That's what we callfastidious.
|
|
by Remy Porter on (#5M00R)
One of the "legacy" PHP applications needed a few bugfixes. "Legacy" in this case, means "written by a developer who doesn't work here anymore", so mostly everyone tried to dodge getting those bugfixes assigned to them. Joe was taking a three day weekend at the time, so a helpful co-worker assigned the tickets to him.The code wasn't an absolute disaster, but it suffered from being written by a "smart" programmer. Since they were so smart, they couldn't just do things using the basic language constructs, they had to find clever ways to abuse them.For example, why would you write a for loop, with a counting variable, when you could do this instead?
|
|
by Remy Porter on (#5KYW4)
Arguably, the biggest problem with SQL as a query language is that we usually execute SQL statements from inside of some other programming language. It tempts us into finding quick hacks to generate dynamic SQL statements, and if we do it the quick way, we find ourselves doing a lot of string concatenation. That way lies SQL injection vulnerabilities.Constructing SQL statements by stringing together text is always a bad idea, even if you're still using query parameters. There's a reason why most modern database wrappers provide some sort of builder pattern to safely construct dynamic queries. Even so, everyone wants to find their own… special way to accomplish this.Take this sample from Sciros:
|
|
by Remy Porter on (#5KXSN)
The story of the week in software development is Github's Copilot, which promises to throw machine learning at autocomplete for a "smarter" experience.Notably, one of their examples highlights its ability to store currency values in a float. Or to generate nonsense. Or outputting GPLed code that was used in its training set.That last one raises all sorts of questions about copyright law, and the boundaries of what constitutes fair use and derivative works, and whether the GPL's virality can "infect" an ML model. These are questions I'm not qualified to answer, and that may not have a good answer at the moment. And certainly, the answer which applies to the US may not apply elsewhere.Besides, copyright law is boring. What's fun is that Copilot also spits up API keys, because it was trained on open source projects, and sometimes people mess up and commit their API keys into their source control repository. Oops.And even their examples don't really constitute "good" code. Like their daysBetweenDates, straight from their website:
|
|
by Mark Bowytz on (#5KWNH)
|
|
by Lyle Seaman on (#5KSV6)
Last week we lightly brushed on the novel conspiracy theory thatperhaps the HBO hullabaloo had been intentionally inspiredby their social media team, and suggested you might join them.Apparently the media managers at Subway had been hungering forpublicity as well.TDWTF sandwich specialist Carlos buttered us up, saying "I'm sure you've receiveda ton of these already [ed: we hadn't], but what's one more?"
|
|
by Remy Porter on (#5KRA3)
Good logging is an invaluable tool for debugging and diagnosing your applications. No logging makes that job harder, but not as hard as bad logging. Logging that doesn't log useful information, that doesn't help highlight the flow of the application, etc.Volker was trying to track down a bug that was only raising its head in production, but the log files were spammed with nothing more than "echo". Millions and millions of log lines that were just that. A quick CTRL+F through the code later, and the offending method was found:
|
|
by Remy Porter on (#5KPSJ)
C++ templates are, notoriously, a Turing complete language on their own. They're complicated, even when you're trying to do something simple. Related languages avoid that complexity, and favor generics. Generics are templates with all the sharp bits filed down, but still powerful enough to make datastructures that don't need to know the details of the data they're operating on.This article isn't about generics, though. It's about ORMs, specifically the .NET Entity Framework system. It's common to use the Repository Pattern to abstract out data access a bit. Coupled with the underlying DBSet class, which roughly represents a database table, you can easily create repository objects and related mocks for testing.Making your repository class generic is also a good idea. Basic CRUD operations don't really need to know the details the data they're operating on. You can create one repository instance for each type of data you need to store- each table- all based on the same generic type.But it's possible to make your repository too generic. Take Paulina's company. Here's a few key lines from their generic repository.
|
|
by Remy Porter on (#5KN9E)
Patsy's company has a product that's "number one" in their particular industry. It generates lots of revenue, but a lot of the code dates back to the far-off year of… 2017. Coding practices were… uh… different, four years ago? Especially in the rapidly maturing language of… Java?Within Patsy's company, they do refer to their 2017 code as "legacy" code, and it has left quite the legacy. For example, here's how they parse numbers:
|
|
by Remy Porter on (#5KKWW)
When we write code, we have certain assumptions. Most of these times, these assumptions are fine, and allow us to skip past some hard decisions. But sometimes, these can lead to problems. The infamous example would be the Y2K problem- the assumption that nobody'd be running this program in 40 years seemed reasonable at the time. We might assume that nobody'd type too fast. We might assume our sensor is accurate.Darren sends us some code that has a much milder assumption than those:
|
|
by Lyle Seaman on (#5KGWY)
The most eventful day in Error'dland narrowly missed our publication windowlast week. As everyone must surely know by now, somebody at HBO Max wastesting in production. And the Internet blew up.
|
|
by Ellis Morning on (#5KFD1)
|
|
by Alex Papadimoulis on (#5KDWQ)
|
|
by Remy Porter on (#5KC8S)
|
|
by Alex Papadimoulis on (#5KANQ)
|
|
by Lyle Seaman on (#5K7QF)
Greenville resident Terry K. discovers the weather is on the fritz today. "The chanceOfTemplateFailure seems high today," says he.
|
|
by Remy Porter on (#5K67G)
Mark's team needed someone to write a pretty straight-forward report for their Python application. It would take a set of keyword arguments, turn those into a filter, apply the filter, and get the results back.This was implemented in two methods. First:
|
|
by Remy Porter on (#5K4QF)
The time and effort needed to complete a project and the amount of time available rarely line up well. Wayne M's company found themselves in a position where what they needed to deliver and what they could deliver by the deadline simply didn't match up.The requirements were well specified, so they bundled up a bunch of requirements for search-related functionality, and handed them off to a self-described "world class" developer working on contract.When the developer handed off their C# code, well, there were some problems. Like the code didn't work. It didn't even compile. Even if it did compile, it was just… bad.
|
|
by Remy Porter on (#5K336)
Once upon a time, someone wanted to add a banner to a web page. They also wanted the banner to only appear after a certain date. Jack stumbled across their implementation when trying to understand why the banner would vanish for two weeks at the start of every month.
|
|
by Remy Porter on (#5K1NJ)
Behind every code WTF is a process WTF. For example, Charles W was recently tasked with updating some file-handling code to match changes in the underlying file-format it parses. This is the C code which parses an integer:
|
|
by Lyle Seaman on (#5JYC7)
It's been quite a few years since I was last in Silicon Valley.So it wouldn't surprise me at all if someenterprising restaurateur has unveiled a trendy pub and stolenallthe humorous thunder from Sean's submission. I'll be more surprisedif they haven't.Says Sean K."I love trying new beers, but these varieties remind me too much of work."418's all around! Alas, the keg of 204 has kicked.
|
|
by Remy Porter on (#5JWT6)
A few years back, Alvin was in college, and took his first formal summer job as a programmer. It was supposed to be just some HTML layout work, and the designer handed him a few sample pages. "Just do it like this."The "sample pages" were a mishmash of random indentation, huge swathes of commented out code, and all those other little traits of "someone's just coding in production, aren't they?" that crop up in files. Still, it was just some HTML layout work, so how hard could it be?Not too hard- until Alvin started popping up the DOM inspector. Every time he opened debugging windows in his browser, the page started misbehaving. Menus stopped staying popped open, or would pop open at seemingly random intervals. He could refresh, and it would go away, but the next time he opened (or closed) the DOM inspector, the problems would come back.In the one JavaScript file in the project, Alvin found this:
|
|
by Remy Porter on (#5JVDM)
Operator overloading is one of those "dangerous" features. Like multi-parent inheritance, it can potentially create some really expressive, easy to read code, or it can create a disaster of incomprehensible nonsense.In C++, many core classes use operator overloading, most notably the I/O classes, which reuse (or abuse) the bitshift operators into stream operators. So, for example, one possible way of converting a string into an integer might be to do something like this:
|
|
by Remy Porter on (#5JSQD)
Maximillion was hired to maintain a PHP CMS. His new employer, up to this point, had just been contracting out work, but as time went on, contracting rates got higher, the amount of time required to add basic features kept going up. It was time to go ta a full time employee."The system's pretty simple," the hiring manager explained during the interview, "as I understand it, it's basically just one PHP file."It was not just one PHP file, but the manager wasn't that far off. The front page of the site was 4.9MB. That's not 4.9MB rendered, that's the PHP file. PHP and HTML existed side by side with in-line JavaScript and in-line CSS.And the code had some… treats.
|
|
by Remy Porter on (#5JR9T)
Cornelius was working with some code where the objects might be "active" or "inactive". His code needed to do something different, depending on whether the objects were "active" or not, but fortunately, there was a handy-dandy IsActive method. Weirdly, that method required a bool parameter, but also returned a bool. Since there wasn't any useful documentation, Cornelius checked the C++ code.
|
|
by Lyle Seaman on (#5JN89)
Renault driver Oisin H. writes <<I had no idea French week had only six days>>It seems they too have never got the hang of Thursdays.
|
by Remy Porter on (#5JKQR)
Matt has plans for the next few years: dealing with the "inheritance" of some legacy systems.They're written in VB.Net, which isn't itself a problem, but the code quality leaves just a bit to be desired.
by Remy Porter on (#5JJ89)
Jesse had a "special" co-worker, Rupert. Rupert was the sort of person that thinks they're the smartest person walking the Earth today, and was quite happy to loudly proclaim that everyone else is wrong. Rupert was happy so long as everyone else was ready to bask in his "genius".Fortunately for Jesse, Rupert left, because he'd received a huge offer for a senior developer role at a different company. Everyone at Jesse's company privately chuckled about it, because this is the kind of code Rupert's genius produced:
by Remy Porter on (#5JGR9)
Virginia N (previously) needed to maintain some authentication logic. The actual rules for authentication weren't actually documented, so her choices were to either copy/paste some authentication code from a different project, or try and refactor the authentication method in this one.It was a hard choice. We'll dump the whole block of code, but I want to pull out a few highlights, starting with the opening condition:
by Alex Papadimoulis on (#5JFG7)
by Lyle Seaman on (#5JCES)
In this process of collecting your submissions, the single most commoncategory has been string conversions of NaN, null, and undefined. They areso common, I've become entirely bored with them. Date conversions, however,still do amuse a bit. Or will do. Or will did? Will have did? In any case,here's another installment of wibbly bits. They may not be clever, but someare a little funny.Competitive programmer Laks may have got the answer technicallyincorrect, but he did it REALLY fast. Shouldn't he have won on speed?Says Laks "It turns out you can implement flux capacitor in software."
by Remy Porter on (#5JAXZ)
In functional programming languages, you'll frequently see some variation of the car/cdr operations from LISP. Given a list, these functions can split it into the head (or first element) of the list, and the tail (the rest of the list). This is often used to traverse a list recursively: function f performs an operation on the head of the list, and then recursively calls f on the tail of the list.I bring this up because we're talking about C# today. C# has plenty of fun functional programming features, and you can certainly use them to write very clean, comprehensible code. Or, like Nico's co-worker, you could do something like this.
by Remy Porter on (#5J9DE)
Ali was working on an app for a national government. The government provided its own mapping API for its own custom mapping services. It did not provide any documentation, and the only "sample" code was hitting "view source" on an existing map page on the government's websites.Ali writes: "I was going through their own implementations, looking for something that would help, when I stumbled upon this gem. I think it speaks for itself, no?"
by Remy Porter on (#5J7WQ)
There are times when performance absolutely matters. And the tech lead that Janell was working with (previously) was absolutely certain that their VB.Net project needed to be "designed for performance". Performance was so important that in the final design, they used a home-brewed JSON database (which, at its lowest level, was just a JSON file on disk), and it took 7 round-trips to their home-brewed database to read a single record.Despite all this attention on performance, the system had a memory leak! As we've covered in the past, garbage-collected languages can have leaks, but they may take a little more effort than the old-school versions. Janell fired up a debugger, looked at the memory utilization, and started trying to figure out what the problem was.The first thing Janell noticed was that there were millions of WeakReference objects. A WeakReference can hold a reference to an object without preventing garbage collection. This is the sort of thing that you might use to prevent memory leaks, ensuring that objects get released.A little more poking revealed two layers to the problem. First, every business object in the application inherited from BaseObject. Not the .NET object type that's the base class for all objects, but a custom BaseObject. Every class had to inherit from BaseObject.
by Jane Bailey on (#5J6G7)
The year was 2001: the year before many countries in the EU switched from using their national currency to the new euro. As part of the switch, many financial software packages had to be upgraded. Today's submitter, Salim, was hired as an IT support staffer in a medium-sized healthcare organization in the Netherlands. While Salim had a number of colleagues, they had to support a greater number of small satellite offices, and so on occasion any of them would be left to hold the main office alone. It just so happened that Salim's first solo day was the day they were testing the software upgrade, with the CFO himself executing the test.The manager of IT had prepared well. Every aspect of the test had been thought through: the production server had been cloned into a fresh desktop computer, placed in the server room, set apart from the other servers so that the CFO wouldn't accidentally touch the production server. To make it stand out, rather than a rack they'd placed the computer on one of those thin little computer desks that were in fashion at the time, a little metal contraption with a drawer for the keyboard and wheels so it could be moved. The setup got an office chair and a phone, for comfort and so that the CFO could summon help if needed. The CFO had been given step-by-step instructions from the software vendor, which he and the manager had gone over ahead of time. All the bases were covered. Hopefully.Early in the morning the day of the test, the CFO walked to the support desk and asked for access to the server room. Salim walked him to the room, unlocked the door for him, and pointed him to the computer desk. Before he left, he pointed out the phone and gave the CFO his direct extension in case anything went wrong. The CFO thanked him, and Salim left him to it.No sooner had he sat down than the call came: the CFO asking for help. Although he had a good deal of general IT knowledge, Salim hadn't personally inspected any of the instructions and didn't know much about the software. So he walked back to the server room, anxiety growing.Arriving in the server room, Salim found the CFO standing next to the computer desk. Salim sat down, pulled the keyboard out from under the monitor, and flicked on the screen. Summoning up his most professional voice, he asked, "Right, how can I help?""Ah ... thanks," came the reply. "I can manage from here."Salim writes: "To this day, I do not know if his problem was not being able to find the keyboard, or switch on the monitor." [Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.
by Lyle Seaman on (#5J3GZ)
Baby Boomer Eric D. accidentally shares the prototypical Gen Xexperience, this time via Pella windows. "I guess I can't actually buy stuffbecause I'm in the unlucky 55-64 age band." Welcome to irrelevance, Eric!
by Remy Porter on (#5J1XZ)
Have you ever needed to prune an order line? Y'know, prune them. This is an entirely common operation you do on orders all the time, and requires absolutely no context or explanation. There's absolutely no chance that you might need to wonder, exactly what is being pruned.Bartholomew A. was a little bit confused by the prune method in the codebase. Fortunately, reading through the code makes everything clear:
by Remy Porter on (#5J0D5)
There was an era where UI designer tools output programmatic code representing that UI. So, say, if you were dragging and dropping objects in the Windows Forms designer in Visual Studio, the output would be C# code. Now, the designer would have some defaults. When you added a new button, it might identify it as button15. Of course, you wouldn't leave that name as it was, and you'd give it a meaningful name. That name would then become the property name of that field in the class generated by the designer.Well, you might give it a meaningful name. Gormo inherited some Windows Forms code, which challenges the meaning of "meaningful names".
by Remy Porter on (#5HYTM)
When I was a baby programmer, I subscribed to a computer magazine. In those olden times, these magazines would come with pages of program code, usually BASIC, so that you could type this program into your computer and run it. If you were careful about typos, you could accomplish quite a bit of "programming" without actually programming. What you were doing, in practice, was just typing.One of Anthony's predecessors was quite the accomplished typist.They needed to take the built-in .NET XmlDocument class and add a one method to it. Now, C# offers a few techniques for doing this. The "traditional" object-oriented approach is to use inheritance. Now, that's not without its downsides, so C# also has the concept of "extension methods". This is a little bit of syntactic sugar, which allows you to declare static method that takes a parameter of XmlDocument, but invoke it as if it were an actual instance method. Of course, depending on what you're doing, that might not give you all the functionality you need. And outside of those techniques, there are a number of the good-ol' Gang of Four design patterns, like the Visitor pattern which could solve this problem without loads of complexity. Or even just "a plain old static method" might fit.But Anthony's predecessor didn't want to do any of those. They instead chose to use typing.