Feed the-daily-wtf The Daily WTF

Favorite IconThe Daily WTF

Link http://thedailywtf.com/
Feed http://syndication.thedailywtf.com/TheDailyWtf
Updated 2024-05-12 18:17
CodeSOD: Contractor's Leftovers
There once was a developer who had a lot of hustle. They put out a shingle as a contractor, knocked on doors, made phone calls, and targeted those small businesses that needed something a little more custom than just off-the-shelf could get, but didn't have the money to afford a larger dev shop.And after finishing a handful of projects and building a reputation, this developer took a job at a large firm, in another town, and left a lot of unhappy customers with unfinished software behind.This is where Graeme comes in. He got a call from a local hotel who needed their booking system finished up. It had some… colorful choices.
CodeSOD: A Repetition of Repetition to Repeat
Inheritance is often described as a tool for code reuse, and those discussions inevitably wander down an alley parsing out the nature of has a and is a relationships, when to favor composition, and how inheritance trees get fragile.When Megan D inherited a Java application which had been largely untouched since 2006, she expected it to be full of all kinds of ugly problems. But they couldn't be that ugly- the software was used and well liked by the end users. Of course, it was hard to tell if they actually liked it, or had just been with it so long they'd adjusted to its flaws, because the whole workflow was extremely fragile and frequently failed.One feature in the large application was a reporting subsystem which could display line graphs. The three classes we'll look at form a nice inheritance hierarchy. There is the LineGraphTableModel, and then specifically the XLineGraphTableModel and the YLineGraphTableModel.These classes exist to let the user configure the way the graph renders. The user interface displays the options that can be set for each axis in a JTable view. Each data series on the graph gets a row in the table, each setting you can control on the data series gets a column.The first thing we'll highlight is that LineGraphTableModel contains a enum called TableColumns, which are the columns on our table.
Error'd: Is This The Real Life
To atone for last week's errant Error'd, this week we're giving you 20% extra at no additional charge. For reals.Ananonymous submission starts us off. Ordinarily we wouldn't repostfrom social media but this is just too delicious.
CodeSOD: Users That Bug You
I frequently write bad code. I mean, we all do, but I frequently write bad code with full knowledge that it's bad, because I first want to test out an idea. Or, I want to inject some additional behavior just for one run, because I'm trying to debug something. If that idea or debugging hook turns out to be valuable, I'll frequently refactor it into something useful and enable it via a flag or something.Which brings us to the crash Doug was investigating in a VB.Net application. For some reason, the username field was an empty string after logging in, and a bunch of methods which expected the username to have a value misbehaved after that.Well, one of the debugging hooks was turned on, and it called GetReplacementUser, which… is interesting.
Committed Database
Database administrators tend to be pretty conservative about how databases are altered. This is for good reason- that data is mission critical, it's availability is vital, and any change you make threatens that stability and reliability. This conservatism ranges from "we have well defined processes for making changes" all the way to "developers are dangerous toddlers playing with guns and we can't allow them to do anything lest it break our precious database.""Grumpy" Gus worked with some DBAs that fell much more on the "developers can't be trusted" end of the spectrum. This meant they had big piles of rigorous processes to make sure only the most important, definitely required changes to the database ever got made. The process involved filing several documents, marking an entry on a spreadsheet, emailing a dba@initech.com inbox, and then waiting. Your request would snake its way through a Database Management Subcommittee, then get kicked over to a Business Need Evaluation Working Group. If the working group agreed that this change met a level of business need, it went back to the subcommittee, which reviewed the findings and if they agreed escalated it to the monthly Database Administration Steering Committee and Database Users Group meeting. Once again, it would get reviewed. If accepted, the DBAs could write a change script, and apply it in the next database maintenance window.From start to end, the process took a month, if not longer, and your request could be kicked back at any step in the process. If you didn't fill out the initial documents in the correct order, and to the satisfaction of the groups, down to using, commas, correctly, it could be rejected. You may or may not be told why.All this created a problem: the "big boss" wanted three new boolean fields in the database, and wanted it yesterday. There was no guarantee that the committees would even let Gus finish the process. And it was impossible to get it done in any sort of timely fashion.But Gus was smart, creative, and aware that the FAX_PHONE_NUMBER field on all of their customer records were blank. Gus couldn't change the schema, but he could change the way his application used the database fields.
CodeSOD: Patching Over Your Problem
Deanna inherited some code which had gone through many, many previous hands. Like a lot of JavaScript/TypeScript code, it needed to be able to compare objects for deep equality. This is fraught and complicated, and there are many many many solutions available in NPM.NPM, of course, is its own fraught thing. Widely used libraries frequently have vulnerabilities, and even if you don't use them directly, the nature of dependency management via NPM means that libraries your libraries depend on might.If you want to avoid that, you could whip up your own deep equals function, with a little recursion. Or, if you're a real hack, you might gamble on JSON.stringify(a) == JSON.stringify(b) working (which is a gamble, as it depends on key insertion order being the same).Deanna's predecessors found a different solution. They did go off to use a library- but the library they chose is a bit surprising for this task.
CodeSOD: Read the Comments
Many many years ago, when I took my first programming course in high school, our instructor had… opinions. One of those opinions was that you should manually syntax check your code and not rely on compiler errors, because back in her day, you had to punch your program into cards, drop it off in the computer lab, wait for the technician to run your batch, and then pick up the results on the printer. It needed to work the first try or you might be waiting a whole day before you could try again.One of her other opinions was that your code should contain as many comments as it contained lines of code. Everything needed comments. Everything. Which brings us to this code from Doug.
Error'd: Outages, Prices, and Catastrophe
Shaun F noticed an outage."Maybe," Shaun writes, "they should use the Cloudflare Always Online service."Meanwhile, at Subway, Maurice R has found the deal of a lifetime.And as we get into Autumn, Lincoln Ramsay warns you to be on the lookout for sudden cold snaps. [Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!
Performance Tuning for Exabyte Queries
While NoSQL databases have definitely made their mark and have an important role in applications, there's also still a place for RDBMSes. The key advantage of an RDBMS is that, with a well normalized schema, any arbitrary query is possible, and instead of optimizing the query, you optimize the database itself to ensure you hit your performance goals- indexes, statistics, materialized views, etc..The reality, of course, is wildly different. While the execution plan used by the database shouldn't be dependent upon how we write the query, it frequently is, managing statistics and indexes is surprisingly hard, and when performance problems crop up, without the right monitoring, it can be difficult to track down exactly which query is causing the problem.Which brings us to this query, which TJ found while analyzing a performance problem.
CodeSOD: A Ritual Approach
Frequent contributor Russell F stumbled across this block, which illustrates an impressive ability to make a wide variety of bad choices. It is written in C#, but one has the sense that the developer didn't really understand C#. Or, honestly, programming.
CodeSOD: Low (Quality) Code
Like the tides, the popularity of low-code development environments comes in ebbs and flows. With each cycle, the landscape changes, old tools going away and new tools washing up on shore. One one hand, democratizing access to technology is good, on the other, these tools inevitably fail to actually do that. Instead, we get mission critical developed by people who don't understand how to develop, and are thus fragile, and released on platforms that are almost certainly going to be on legacy support in the next cycle.I don't want to imply that low-code tools are automatically bad, or insult non-developers who want to give developing in a low-code environment a shot, though. Especially when professional developers can't really do any better.John F's company has adopted one of the new tools in this cycle of low-code tools, Microsoft Power Apps, using the Power FX scripting language. One of the screens in their application needs to display a table of sales data, organized by month. This is how one of their developers decided to generate the list of months to draw:
CodeSOD: An Hourly Rate
When someone mentioned to Abraham, "Our product has an auto-sync feature that fires every hour," Abraham wasn't surprised. He was new to the team, didn't know the code well, but an auto-sync back to the server sounded reasonable.The approach, however, left something to be desired.
Error'd: Counting to One
Two of today's ticklers require a little explanation, while the others require little.Kicking things off this week, an anonymous reporter wants tokeep their password secure by not divulging their identity. It won't work,that's exactly the same as my Twitch password."Twitch seems to be split between thinking whethermy KeePass password is strong or not," they wrote.Explanation: The red translates to "This password is too easy to guess",while the green 'Stark' translates as "you've chosen a very good passwordindeed."
CodeSOD: Joining the Rest of Us
Using built-in methods is good and normal, but it's certainly boring. When someone, for example, has a list of tags in an array, and calls string.Join(" ", tags), I don't really learn anything about the programmer as a person. There's no relationship or connection, no deeper understanding of them.Which, let's be honest, is a good thing when it comes to delivering good software. But watching people reinvent built in methods is a fun way to see how their brain works. Fun for me, because I don't work with them, probably less fun for Mike, who inherited this C# code.
CodeSOD: Supporting Standards
Starting in the late 2000s, smartphones and tablets took off, and for a lot of people, they constituted a full replacement for a computer. By the time the iPad and Microsoft Surface took off, every pointy-haired-boss wanted to bring a tablet into their meetings, and do as much work as possible on that tablet.Well, nearly every PHB. Lutz worked for a company where management was absolutely convinced that tablets, smartphones, and frankly, anything smaller than the cheapest Dell laptop with the chunkiest plastic case was nothing more than a toy. It was part of the entire management culture, led by the CEO, Barry. When one of Lutz's co-workers was careless enough to mention in passing an article they'd read on mobile-first development, Barry scowled and said "We are a professional software company that develops professional business software."Back in the mid 2010s, their customers started asking, "We love your application, but we'd love to be able to access it from our mobile devices," Barry's reply was: "We should support standards. The standard is Microsoft Windows.""Oh, but we already access your application on our mobile devices," one of the customers pointed out. "We just have to use the desktop version of the page, which isn't great on a small screen."Barry was livid. He couldn't take it out on his customers, not as much as he wanted to, but he could "fix" this. So he went to one of his professional software developers, at his professional software company, and asked them to professionally add the following check to their professional business software:
CodeSOD: Like a Tree, and…
Duncan B was contracting with a company, and the contract had, up to this point, gone extremely well. The last task Duncan needed to spec out was incorporating employee leave/absences into the monthly timesheets."Hey, can I get some test data?" he asked the payroll system administrators."Sure," they said. "No problem."
CodeSOD: Price Conversions
Russell F has an object that needs to display prices. Notably, this view object only ever displays a price, it never does arithmetic on it. Specifically, it displays the prices for tires, which adds a notable challenge to the application: not every car uses the same tires on the front and rear axles. This is known as a "staggered fitment", and in those cases the price for the front tires and the rear tires will be different.The C# method which handles some of this display takes the price of the front tires and displays it quite simply:
Error'd: Money for Nothin'
... and gigs for free."Apple is magical," rhapsodizes music-lover Daniel W.
CodeSOD: Making Newlines
I recently started a new C++ project. As it's fairly small and has few dependencies, I made a very conscious choice to just write a shell script to handle compilation. Yes, a Makefile would be "better", but it also adds a lot of complexity my project doesn't need, when I can have essentially a one-line build command. Still, my code has suddenly discovered the need for a second target, and I'll probably migrate to Makefiles- it's easier to add complexity when I need it.Kai's organization transitioned from the small shell-scripts approach to builds to using Makefiles about a year ago. Kai wasn't involved in that initial process, but has since needed to make some modifications to the Makefiles. In this case, there's a separate Makefile for each one of their hundreds of microservices.Each one of those files, near the top, has this:
Editor's Soapbox: Eff Up Like It's Your Job
This past Monday, Facebook experienced an outage which lasted almost six hours. This had rattle-on effects. Facebook's pile of services all failed, from the core application to WhatsApp to Oculus. Many other services use Facebook for authentication, so people lost access to those (which highlights some rather horrifying dependencies on Facebook's infrastructure). DNS servers were also strained as users and applications kept trying to find Facebook, and kept failing.CloudFlare has more information about what went wrong, but at its core: Facebook's network stopped advertising the routes to its DNS servers. The underlying cause of that may have been a bug in their Border Gateway Protocol automation system:
CodeSOD: Unzipped
When you promise to deliver a certain level of service, you need to live up to that promise. When your system is critical to your customers, there are penalties for failing to live up to that standard. For the mission-critical application Rich D supports, that penalty is $10,000 a minute for any outages.Now, one might think that such a mission critical system has a focus on testing, code quality, and stability. You probably don't think that, but someone might expect that.This Java application contains a component which needs to take a zip file, extract an executable script from it, and then execute that script. The code that does this is… a lot, so we're going to take it in chunks. Let's start by looking at the core loop.
Totally Up To Date
The year was 2015. Erik was working for LibCo, a company that offered management software for public libraries. The software managed inventory, customer tracking, fine calculations, and everything else the library needed to keep track of their books. This included, of course, a huge database with all book titles known to the entire library system.Having been around since the early 90s, the company had originally not implemented Internet connectivity. Instead, updates would be mailed out as physical media (originally floppies, then CDs). The librarian would plug the media into the only computer the library had, and it would update the catalog. Because the libraries could choose how often to update, these disks didn't just contain a differential; they contained the entire catalog over again, which would replace the whole database's contents on update. That way, the database would always be updated to this month's data, even if it hadn't changed in a year.Time marched on. The book market grew exponentially, especially with the advent of self-publishing, and the Internet really caught on. Now the libraries would have dozens of computers, and all of them would be connected to the Internet. There was the possibility for weekly, maybe even daily updates, all through the magic of the World Wide Web.For a while, everything Just Worked. Erik was with the company for a good two years without any problems. But when things went off the rails, they went fast. The download and update times grew longer and longer, creeping ever closer to that magic 24-hour mark where the device would never finish updating because a new update would be out before the last one was complete. So Erik was assigned to find some way, any way, to speed up the process.And he quickly found such a way.Remember that whole drop the database and replace the data thing? That was still happening. Over the years, faster hardware had been concealing the issue. But the exponential catalogue growth had finally outstripped Moore's Law, meaning even the newest library computers couldn't keep up with downloading the whole thing every day. Not on library Internet plans.Erik took it upon himself to fix this issue once and for all. It only took two days for him to come up with a software update, which was in libraries across the country after 24 hours. The total update time afterward? Only a few minutes. All he had to do was rewrite the importer/updater to accept lists of changed database entries, which numbered in the dozens, as opposed to full data sets, which numbered in the millions. No longer were libraries skipping updates, after all.Erik's reward for his hard work? A coupon for a free personal pizza, which he suspected his manager clipped from the newspaper. But at least it was something. [Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!
Error'd: Persnickety Sticklers Redux
This week's installation of Error'd includes a few submissionswhich honestly don't seem all that WTFy. In particular, this firstone from the unsurnamed Steve. I've included it solely so I can pedantically proclaim "24 is not between 1 and 24!"There is still a wtf here though. What is withthis error message?Insufficiently pedantic Steve humorlessly grumbles"Configuring data pruning on our Mirth Integration Engine.Mirth can do many things, just can't count up to 24."
The Boulder Factory
Like a lot of HR systems, the one at Initech had grown into a complicated mess of special cases, edge cases, and business rules that couldn't be explained but had to be followed.Mark was assigned to a project to manage another one of those special cases: Initech had just sold one of its factories. Their HR system needed to retain information about the factory and its employees up until the point of the sale, but it also needed to be disconnected from some future processing- they certainly didn't want to send anybody any paychecks, for example. But not all processing. If an employee had started a health insurance claim before the factory was sold, they needed to keep that active in the system until it was completed (but also not allow the employee to file new claims).It was going to be a lot of special processing, so Mark made a simple suggestion: "Why don't we add a 'sold' checkbox, or a 'decommissioned' flag, or something like that? We add that as a data-field to a factory, and then we know all employees associated with that factory go down a different processing path.""Oh, we can't do that," Mark's boss, Harlan, countered. "It would be a new database field, changes to the factory edit screen, we'd have to document it for the users, probably add an 'are you sure' confirmation dialog, it's just too much work to do that and then also add all the special processing rules."It was okay, though, because Harlan had a simpler solution. Just do the special processing rules. IF factory_id == 27 THEN doTheSoldFactoryStuff() ELSE doTheRegularFactoryStuff(). No changes to the database, no changes to any screens, they just had to go through thousands of lines of code, scattered across hundreds of different modules and individual programs, and jam that special branch in there, in the right spot."Right," Mark cautioned, "but the next time we sell a factory, we'll have to do this all over again. Whereas if we add the checkbox-""How often do you think we're going to be selling factories? It's fine," Harlan said.The next six months were the tedious process of going through all the places in the software where the special branch needed to go. Of course, no one was precisely documenting this, no one was really concerning themselves with any minutae like a "clean commit history": patch the code, maybe add a comment, and move on with your day. And it's not the case that every place they were changing the code fit exactly that pattern of IF factory_id == 27; not every system used the same naming conventions, or even the same language.It was a rough six months, but at the end of it, the factory was sold, the HR systems processed everything correctly, and management was happy with the end result. There was just one more thing…"Welp," Harlan said as he called everyone in for the new project kickoff. "We've sold another factory, and I have a plan for how we're going to make that change, without needing to add any database fields or modify any UI elements."As Camus said, "One must imagine Sisyphus happy," but Mark was significantly less happy. If Harlan had taken his input, this wouldn't be an IT task at all. As it was, Mark had a good sense of what the next six months of work was going to look like. [Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.
And FORTRAN, FORTRAN So Far Away
A surprising amount of the world runs on FORTRAN. That's not to say that huge quantities of new FORTRAN are getting written, though it's far from a dead language, but that there are vital libraries written fifty years ago that are still used to this day.But the world in which that FORTRAN was written and the world in which we live today is wildly different. Which brings us to the story of George and Ike.In the late 1960s, the company that Ike worked for got a brand-spanking new CDC 6600 mainframe. At the time, it was the fastest computer you could purchase, with a blistering 3MFLOPS performance- 3 million floating point operations per second. The company wanted to hand this off to their developers to do all sorts of fancy numerical simulations with FORTRAN, but there was just one problem: they wanted to do a lot of new programs, and the vendor-supplied compiler took a sadly long time to do its work. As they were internally billing CPU time at $0.10/second, teams were finding it quite expensive to do their work.
CodeSOD: Golfing Over a Log
Indirection is an important part of programming. Wrapping even core language components in your own interfaces is sometimes justifiable, depending upon the use cases.But like anything else, it can leave you scratching your head. Sam found this bit of indirection in a NodeJS application:
CodeSOD: Terned Around About Nullables
John H works with some industrial devices. After a recent upgrade at the falicity, the new control software just felt like it was packed with WTFs. Fortunately, John was able to get at the C# source code for these devices, which lets us see some of the logic used…
Error'd: ;pam ;pam ;pam ;pam
One of this week's entries is the type that drives me buggy. Guess which one.Regular contributorPascal splains this shopping saga:"Amazon now requires anti-virus software to have an EPARegistration number."
CodeSOD: A Dash of SQL
As developers, we often have to engage with management who doesn't have a clue what it is we do, or how. Even if that manager was technical once, their technical background is frequently out of date, and their spirit has been sapped by the endless meetings and politics that being a manager entails. And it's often these managers who have some degree of control over where our career is going to progress, so we need to make them happy.Which means… <clickbait-voice>LEVEL UP YOUR CAREER WITH THIS ONE SIMPLE TRICK!</clickbait-voice>. You need to make managers happy, and if there's one thing that makes managers happy, it's dashboards. Take something complicated and multivariate, and boil it down to a simple system. Traffic lights are always a favorite: green is good, red is bad, yellow is also bad.It sounds stupid, because it is, but one of the applications that got me the most accolades was a dashboard application. It was an absolute trainwreck of code that slurped data from a dozen different silos and munged it together via a process the customer was always tweaking, and turned the complicated mathematics of how much wasteage there was in an industrial process into a simple traffic light icon. Upper managers used it and loved it, because that little glowing green light gave them all the security they needed, and when one of those lights went yellow or worse, red, they could swoop in and do management until the light turned green again.Well, Kaspar also supports a dashboard application. It also slurps giant piles of data from a variety of sources, and it tries to turn some key metrics into simple letter grades- "A" through "E".This particular query is about 400 lines of subqueries connected via LEFT JOIN. The whole thing is messy in the way that only giant SQL queries that are trying to restructure and reshape data in extreme ways can be. That's not truly a WTF, but several of these subqueries do something… special.
Some Version of a Process
When you're a large company, like Oracle, you can force your customers to do things your way. "Because we said so," is something a company like that can get away with. Conversely, a small company is more restricted- you have to work hard to keep your customers happy.When Doreen joined Initech, they were a small company with a long history and not too many customers. In the interests of keeping those customers happy, each customer got their own custom build of the software, with features tailored to their specific needs. So, Initrode was on "INITRODE.9.1", while the Soggy Beans coffee shop chain was on "SOGGY.5.2". Managing those versions was a pain, but it was Doreen's boss, Elliot, who ensured that pain escalated to anguish.Elliot was the one who laid out their software development and source control processes. It was the Official Process™, and Elliot was the owner of the Official Process™. The Official Process™ was the most elegant solution Elliot could imagine: each version lived in its own independent Subversion repository. Changes were synced between those repositories manually. Releases were also manual, and rare. Automated testing was non-existent..Upper management may not have understood the problems that created, but they knew that their organization was slow to release new features, and that customers were getting frustrated with poor response times to bugs and feature requests. So they went to the list of buzzwords and started pushing for "Agile" and "DevOps" and "Continuous Delivery".Suddenly, Doreen and the other developers were given a voice. They pushed to adopt Git, over Subversion. "I've looked into this," Elliot said, "and it looks like Git uses GitHub and stores our code off-site. I don't trust things that are off-site. I want our code stored here!""No, you don't have to use GitHub," Doreen explained. "We can host our own server- I've been playing around with GitLab, which I think will fit our needs well."Elliot grumbled and wandered off.Doreen took a few hours to configure up a GitLab instance, and migrate their many versions of the same code into something approaching a sane branching structure. It'd be a lot of work before the history actually made any sense, but it allowed her to show off some of the benefits, like that it would build and run the handful of unit tests she whipped up on commits to certain branches."That's fine," Elliot said, "but where's the code?""What… do you mean? It's right here.""That's the code for Soggy Beans, where's the Initrode version?" Elliot demanded.Doreen switched branches. "Right here.""But where did the Soggy Beans version go?!" Elliot was getting angry."I… don't understand? It's stored in Git. We're just changing branches.""I don't like this magical nonsense. I want to see our code in folders, as files, not this invisible shapeshifting stuff! I don't want our code where I can't see it!"Doreen attempted to explain what branches were, about how Git stored files and tracked versions, but Elliot was already storming off to raise hell with the one upper manager who still listened to him. And a few days later, Elliot came back with a plan."So, since we're migrating to Git," Elliot explained to the team, "that poses a few challenges, in terms of the features it lacks. So I've written a script that will supplement it."The script in question enumerated all the branches and tags in the repository, checked each one out in turn then copied it to another folder. "Once you've run this, you can navigate to the correct folder and make your changes there. If you need to make changes that impact multiple customers, you can repat those changes on each folder. Then you can run this second script, which will copy the changed folders back to the repository and commit it." This was also how code would be deployed: explode the repository out into folders, and copy the appropriate folder to the server.At first, Doreen figured she could just ignore the script and do things the correct way. But there were a few problems with that. First, Elliot's script created commits that made it look like every file had been changed on every commit, making history meaningless. Second, it required you to be very precise about which branches/versions you were working on, and it was easy to make a mistake and commit changes from one branch into another, which was a mistake Elliot made frequently. He blamed Git for this, obviously.But third, and most significantly: Elliot's script wasn't a suggestion. It was the Official Process™, and every developer was required to use it. Oh, you could try and "cheat", but your commits would be clean, clear, and comprehensible, which was a dead giveaway that you weren't following the Official Process™.Doreen left the company a short time later. As far as anyone knows, Elliot still uses his Official Process™. [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
CodeSOD: Globalism
When Daniel was young, he took one of those adventure trips that included a multi-day hike through a rainforest. At the time, it was one of the most difficult and laborious experiences he'd ever had.Then he inherited an antique PHP 5.3 application, written by someone who names variables like they're spreadsheet columns: $ag, $ah, and $az are all variables which show up. Half of those are globals. The application is "modularized" into many, many PHP files, but this ends up creating include chains tens of files deep, which makes it nigh impossible to actually understand.But then there are lines like this one:
CodeSOD: Expiration Dates
Last week, we saw some possibly ancient Pascal code. Leilani sends us some more… modern Pascal to look at today.This block of code comes from a developer who has… some quirks. For example, they have a very command-line oriented approach to design. This means that, even when making a GUI application, they want convenient keyboard shortcuts. So, to close a dialog, you hit "CTRL+C", because who would ever use that keyboard shortcut for any other function at all? There's no reason a GUI would use "CTRL+C" for anything but closing windows.But that's not the WTF.
Error'd: In Other Words
We generally don't like to make fun of innocentmisuses of a second language. Many of us strugglewith their first. But sometimes we honestly can'ttell which is first and which is zeroeth.Whovianstombaker pontificates"Internationalization is hard.Sometimes, some translations are missing, someother times, there are strange concatenationsdue to language peculiarities. But here, we haveeverything wrong and no homogeneity in the issues."
CodeSOD: Subbing for the Subcontractors
Back in the mid-2000s, Maurice got less than tempting offer. A large US city had hired a major contracting firm, that contracting firm had subcontracted out the job, and those subcontractors let the project spiral completely out of control. The customer and the primary contracting firm wanted to hire new subcontractors to try and save the project.As this was the mid-2000s, the project had started its life as a VB6 project. Then someone realized this was a terrible idea, and decided to make it a VB.Net project, without actually changing any of the already written code, though. That leads to code like this:
CodeSOD: The Programmer's Motto and Other Comments
We've got a lovely backlog of short snippets of code, and it's been a long time since our last smorgasbord, so let's take a look at some… choice cuts.Let's open with a comment, found by Russell F:
CodeSOD: Wise About Bits
The HP3000 was the first mini-computer that supported time-sharing. It launched in 1972, and HP didn't end-of-life it until 2010, and there are still third-party vendors supporting them.Leonora's submission is some code she encountered a number of years ago, but not as many as you might think. It's in Pascal, and it's important to note that this version of Pascal definitely has bitwise operators. But, if you're programming on a 40 year old minicomputer, maybe you couldn't do an Internet search, and maybe Steve from down the hall had bogarted the one manual HP provided for the computer so you can't look it up because "he's using it for reference."So you end up doing your best with no idea:
CodeSOD: A Coded Escape
When evaluating a new development tool or framework, the first thing the smart developer does is check out the vendor documentation. Those docs will either be your best friend, or your worst enemy. A great product with bad documentation will provide nothing but frustration, but even a mediocre product with clean and clear documentation at least lets you get useful stuff done.Stuart Longland's company has already picked the product, unfortunately, so Stuart's left combing through the documentation. This particular product exposes a web-socket based API, and thus includes JavaScript samples in its documentation. Obviously, one could use any language they like to talk to web-sockets, but examples are nice…
Error'd: Swordfish
Despite literally predating paper, passcodes and secret handshakescontinue to perplex programmers, actors, and artists alike.For our first example, auteurAndy stages a spare play in three acts.
CodeSOD: Going Through Some Changes
Dave inherited a data management tool. It was an antique WinForms application that users would use to edit a whole pile of business specific data in one of those awkward "we implemented a tree structure on top of an RDBMS" patterns. As users made changes, their edits would get marked with a "pending" status, allowing them to be saved in the database and seen by other users, but with a clear "this isn't for real yet" signal.One developer had a simple task: update a text box with the number of pending changes, and if it's non-zero, make the text red and boldfaced. This developer knew that some of these data access methods might not return any data, so they were very careful to "handle" exceptions.
CodeSOD: Columns of a Constant Length
Today's submitter goes by "[object Object]", which I appreciate the JavaScript gag even when they send us C code.This particular bit of C code exists to help output data in fixed-width files. What you run into, with fixed-width files, is that it becomes very important to properly pad all your columns. It's not a difficult programming challenge, but it's also easy to make mistakes that cause hard-to-spot bugs. And given that most systems using fixed-width files are legacy systems with their own idiosyncrasies, things could easily go wrong.Things go more wrong when you don't actually know the right way to pad strings. Thus this excerpt from constants.h.
CodeSOD: Insertion
Shalonda inherited a C# GUI application that, if we're being charitable, has problems. It's slow, it's buggy, it crashes a lot. The users hate it, the developers hate it, but it's also one of the core applications that drives their business, so everyone needs to use it.One thing the application needs to do is manage a list of icons. Each icon is an image, and based on user actions, a new icon might get inserted in the middle of the list. This is how that happens:
Classic WTF: Crazy Like a Fox(Pro)
Error'd: Just Doer It
Testing in production again, here's five fails for the fifth day of the week. Or the sixth. Or is it the fourth?Anonymous Ignoronymous declares "Dude! Science tests were never popular!"
CodeSOD: Dangerous Tools for Dangerous Users
Despite being a programmer, I make software that goes in big things, which means that my workplace frequently involves the operation of power tools. My co-workers… discourage me from using the power tools. I'm not the handiest of people, and thus watching me work is awkward, uncomfortable, and creates a sense of danger. I'm allowed to use impact drivers and soldering irons, but when it comes time to use some of the more complex power saws, people gently nudge me aside.There are tools that are valuable, but are just dangerous in the hands of the inexperienced. And even if they don't hurt themselves, you might end up boggling at the logic which made them use the tool that way. I'm talking, of course, about pre-compiler macros.Lucas inherited some C++ code that depends on some macros, like this one:
CodeSOD: Maintaining Yourself
When moving from one programming language to another, it's easy to slip into idioms that might be appropriate in one, but are wildly out of place in another. Tammy's company has some veteran developers who spent most of their careers developing in COBOL, and now' they're developing in C#. As sufficiently determined programmers, they're finding ways to write COBOL in C#. Bad COBOL.Methods tend towards long- one thousand lines of code isn't unusual. Longer methods exist. Every method starts with a big long pile of variable declarations. Objects are used more as namespaces than anything relating to object-oriented design. So much data is passed around as 2D arrays, because someone liked working with data like it lived in a table.But this method comes from one specific developer, who had been with the company for 25+ years. Tammy noticed it because, well, it's short, and doesn't have much by way of giant piles of variables. It's also, in every way, wrong.
CodeSOD: Mark it Zero
Sometimes, we get a submission and the submitter provides absolutely no context. Sometimes, the snippet is even really short, or the problem is "subtle" in a way that means we can't spot it when skimming the inbox.Which is why this submission from "Bus Error" has been sitting in the inbox for seven years, and why just today, as I was skimming old submissions, I finally saw what was great about this little block of C-code.
CodeSOD: By Any Other Name
One of the biggest challenges in working with financial data is sanitizing the data into a canonical form. Oh, all the numeric bits are almost always going to be accurate, but when pulling data from multiple systems, is the name "John Doe", "John Q. Doe", "J. Doe"? What do we do when one system uses their mailing address and another uses their actual street address, which might use different municipality names? Or in all the other ways that important identifying information might have different representations.This is Andres' job. Pull in data from multiple sources, massage it into some meaningful and consistent representation, and then hand it off to analysts who do some capitalism with it. Sometimes, though, it's not the data that needs to be cleaned up- it's the code. A previous developer provided this Visual Basic for Applications method for extracting first names:
Error'd: Hunger
No real theme this week, just a handful of whoopses, culminating in a whoopsiedaisytopsyturvysuperduper huh?Excited Python fanAdam B. sneaks in some low-key publicity for the 3.10 release, saying "The community is so excited about the upcoming3.10 release, they ensured that everyone notices theannouncement."
Ten Days
Steffen is the tech lead for an online shop. It's the kind of online shop that sell items with large enough prices that financing is an important function. They offer loans through a payment provider, and the payment provider handles all of the details.Anything relating to finance is complicated, and loans can get very complicated, especially these shorter-term loans. Generating a payment plan for a customer's order means creating a list of all the expected monthly installments, including the due dates, the remaining principal on the loan after the payment, how much goes to principal repayment, how much goes to interest, and the new balance of the loan after interest is added. It's a lot of information, and it's information that the payment provider can provide.But, in the interests of keeping their application responsive when providing a potential payment plan to their end user, Steffen's company opted to implement their own financial calculations. For actual payment handling, they'd still let the payment provider handle it, but for showing the customer "if you order now, this is what your payment plan will look like!", they could do that all on their side.Or could they? While it's complicated to calculate out all the loan elements, it's also well understood. There are libraries for it, there are copy/pasteable code snippets for it. It was complicated, but not hard.After ten days of effort, however, it wasn't working. Their test plan was simple: since the payment provider was the source of truth, they generated 10,000 sample payment plans. They fed those plans into their system, then into the payment provider's system, and then compared the results. And the results mostly matched. Mostly.There were a handful of test cases that were off by hundreds of Euros. That was way too much. Steffen called a meeting with the payment provider's technical staff, and developers from both companies sat down to go through the code, line by line.It was a long, tedious meeting, and while questions were raised about the varying implementations, by the end of the meeting, both companies agreed: the code was correct. But the output was wrong. The meeting ended with nothing resolved.So Steffen grabbed one of the developers, and they sat down to go through the test cases. They chose the one which had the largest deviation from the payment provider's values, and walked through each month of the payment plan.On the first month, both Steffen's code and the payment provider were in perfect agreement. But on the second month, Steffen's code said it was €932.28, while the payment provider said that it was €631.54. That was more than €300 off. But on the third month, things got weirder: the payment provider's plan said that the amount of interest owed went up. Loans don't work that way: as you pay the principal, the amount of interest you pay each month goes down. "Do you think they got it wrong?" Steffen wondered.It seemed promising, but then Steffen looked at the results in more detail. They had generated 10,000 random sample loans. This included random dates ranging from antiquity all the way out to the 30th century. It was very thorough testing.This particular loan's first due date was October 1st, 1582. When Steffen spotted that, he laughed and turned to the developer. "This is a joke, right?" When the developer didn't see the humor, Steffen explained.You see, Steffen didn't start life as a software developer. Before moving into the industry, he worked as a professional historian. And October 1582 was a very special month in history. A unique point in history: it was the month the Western world shifted from the Julian calendar to the Gregorian calendar.The Julian calendar assumed a year was exactly 365.25 days, which is not correct. Following that rule adds an extra leap day roughly every century. The Gregorian calendar was more precise, and mostly accurate about such thing. But to shift calendars, the Greogrian calendar needed to be synced with the seasons. That meant removing a few centuries worth of extra days left over from the Julian calendar. Call it "paying down calendrical debt". So, October 4th, 1582 was followed by October 15th, 1582. Ten days just vanished, and October 1582 had only 21 days in it.The payment provider's calendar system handled this perfectly well. Steffen's calendar system did not. That explained why they over-charged for October, and it also explained why it seemed like the interest payment went up- November 1582 was a normal, 30-day November.Since they would never be originating loans in the 16th century, Steffen's team generated a new set of test data, all after the start of the 21st century. This solved the problem, and after fixing a few minor bugs, their implementation matched the payment provider's.In the end, the Pope removed ten days from October 1582, and Steffen's team put them back, spending almost exactly that time on fixing this bug. [Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.
CodeSOD: Exceptional Numbers
"When handling user input, make sure to handle exceptions," is good advice. But sometimes, that can lead you astray.Bob is a junior programmer surrounded by veterans with 20+ years of experience. Normally, this means that when there's something unusual in the code, Bob writes it off as the senior devs vast experience. But not this time.
...10111213141516171819...