Feed the-daily-wtf The Daily WTF

Favorite IconThe Daily WTF

Link http://thedailywtf.com/
Feed http://syndication.thedailywtf.com/TheDailyWtf
Updated 2025-10-26 13:16
A Backup Pipeline
“Um… can you come take a look at something for me?”Pat looked up from happily hacking away at some new features to see Milton hovering at the edge of the cubicle.“I think I messed up,” Milton added.One of their company’s main internal systems was a data processing pipeline. “Pipeline” might be a bit generous, as in practice, it was actually a webwork of shell scripts and Python that pulled data in from files, did “stuff” to that data, and dropped the results into other files, which could then be read in by different scripts. In actual use, this usually meant people grabbed the latest version of the scripts from source control, modified and tweaked how they executed to answer one specific data-related question, and if that particular process seemed like it might have value, they’d clean the code up a bit and then try and merge it back up into source control. Otherwise, if they didn’t think they’d need it again, they’d just reset back to HEAD.Some folks, though, like Milton, mostly kept their own copy of all the scripts. Or in Milton’s case, multiple copies. Milton knew the data processing pipeline better than anyone, but the vast majority of that knowledge was locked up in his personal scripting library.“I was thinking I should probably try and contribute changes back upstream,” Milton said. “So, like, I’ve got a script that’s called by a script, which is called by a script, and it depends on having a bunch of shell variables created, like $SETUP_DIR.”Pat nodded along.“So I wanted to refactor that into an argument, so other people could use it. And I did… but I forgot to change the calling scripts to pass the argument before I tried to test it.”Specifically, Milton’s script had a line like this:
CodeSOD: A Knotted String
Rita caught a weird bug. It was weird, in part, because there hadn’t been any code changes in their label printing application for ages. Yet, there was a sudden new bug. Labels were printing with what was obviously unicode garbage. Interestingly, the application definitely supported unicode- there had been a huge effort a few years back to move the C++ code from chars to wchars.Rita started debugging, and confirmed that when the label text was populated, memory stored correct values. By the time the data was printed, it no longer did. Obviously, there was something wrong with memory management- something was touching the end of the string and throwing off the output. That was an easy enough bug to make in C++, but tracing through 7,000 lines of label printing code to figure out where things got thrown off was more of a chore, especially with the… “friendly” variable naming convention the original developer had used.
CodeSOD: The Double Bind Printer
Printer jams are an unavoidable circumstance. Paper might not seem sticky, but static electricity and humidity can to horrible things, and all the protections in the world can't stop them. Printers are also objectively terrible, and always have been.Years ago, when Coyne T was a fresh-faced youth, he supported an aging COBOL-based warehouse system. Their reports went to a noisy continuous feed line printer. The printer was a finicky beast, and no matter what sacrifices were made before printing, it had a tendency to devour pages, or have the gears slip and misprint lines. Because the report data came straight from a COBOL job, there was no cached output to reprint- the entire reporting process would need to be re-run every time the printer got angry.About thirty pages of a report got chewed up a few days after Coyne joined the team. As the new kid, re-running the report fell to him. "But, before you go and re-run the report," the team lead, Herschel, said, "there's a few things you should know."Herschel laid out the key facts. The report generating program didn't just generate the report. It also could clear the monthly totals and update the day's inventory as part of running the report. Doing either of those in the middle of the day was absolutely wrong, and would create a lot of manual work to fix it. Even worse, doing both of those during the same run would stomp all over the data files and absolutely corrupt the entire mainframe."Fortunately, I added two flags- CLEAR-SWITCH and UPDATE-SWITCH. Just make sure they're both set to 'N', and you should be fine."Coyne checked and double checked the instructions, ensured that the flags were definitely set to 'N', and then ran the report.After the mainframe team had restored from backup and recovered as much of the data that they could (losing only the past three days worth of inventory), Coyne was called out on the carpet to explain how he'd destroyed the database. Despite being a newbie, Coyne had been cautious from the start, and reviewed the instructions which Herschel had given him, as well as how he'd verified that he'd followed the instructions. But Coyne had also gone the extra step, to look up the code block which checked those flags. He came to the meeting prepared.
Error'd: Quite Powerful Errors Indeed
"I was considering this recorder for my son, but I think 120W might be a bit over the top," writes Peter B.
CodeSOD: A Policy Exception
“So, we have a problem. A… a big one.”Andrea C worked for an insurance company. In terms of software development, a “problem” meant she’d misfiled one of her TPS coversheets or something like that. A big problem meant she’d accidentally checked in code that contained a comment with some profanity in it.“It’s actually, well, it’s actually huge,” her boss continued.She’d never had a “huge” problem before.Someone had discovered that, if they knew a customer’s policy number and were currently logged in- they could see that customer’s policy. It didn’t have to be their policy. Any policy, so long as they had a valid login and the policy number.That was pretty huge. Andrea hadn’t gotten too deep into that section of the application before, but the original developer had moved on, so it was time for her to dig in. She pulled up the JSP code which served the page.
CodeSOD: Double Up
Carl works in research, and like most research organizations, half their code is carelessly glued together GUI tools, command line interfaces, and shell scripts. The other half, the half which does the real work, is Fortran. Sure, the code was written forty years ago, but the laws of physics haven’t changed, so it’s still good and it’s still fast.Carl usually doesn’t have to touch the Fortran half. Instead, he usually looks at the other bit. Most things are run from shell scripts, and most of the work of the shell scripts is getting environment variables configured so that they Fotran code can actually run its model without having a heart attack.So, for example, one of those environment variables is WORKINGDIR. WORKINGDIR holds a /very/long/path/to/a/deeply/nested/folder/someplace The Fortran model code also needs to know the location of the SYSDIR, which is always exactly two levels up from WORKINGDIR. No, the Fortran code can’t figure this out on its own, it’s too busy doing calculus. The shell script needs to figure it out.The shell script which calculates it throws in a little wrinkle though: # calculate dir 2 levels up (Program doesn't allow .. in pathnames). So, no $WORKINGDIR/../.. here.There are a number of ways one could solve this problem. The wrong way to solve this problem is this ksh script…
Set the Flux Capacitor for 12/30/1899
I mentally think of the early 2000s as "the XML Age". XML was everywhere. Everyone wanted to put XML into their applications. Java was the XML king, using XML for everything. People were starting to ask themselves, "do we need the big expensive RDBMS, when we can just use XML instead?"In other words, just like JSON today, but worse. Tomislav A inherited one such database- a clunky pile of XML documents with only the vaguest hint of a schema to them, and a mix of valuable, useful data, and a mountain of crap. With the assumption that all data validation was happening in the application layer, the database was mostly "garbage in, garbage sits there forever and can never be deleted because it might be important".Tomislav's job was to filter out the garbage, find the actually useful information, and move it into a real datastore. There were loads of problems and inconsistencies in the data, but with a little Python in his toolkit, Tomislav could mostly handle those.For example, dates. Dates were stored in the XML as just text strings, because why would you use a structured document format to represent structured data? Since they were just strings, and since there was no data validation/sanitization in the application layer, there was no system to the strings. "31-DEC-2002" sat next to "12/31/2002" and "31/12/2002". With some help from dateutil.parser, Tomislav could handle most of those glitches without difficulty.Until, when importing a date, he got the error: ValueError: year 39002 is out of range.One of the dates in the document was just that- 39002. Knowing that there was no validation, Tomislav was ready to dismiss it as just corrupt data, but not before taking a stab at it. Was it the number of days, or maybe weeks since the Unix Epoch?
CodeSOD: Collect Your Garbage Test
Alex L works for a company with a bunch of data warehousing tools. One of the primary drivers for new features is adding bits which make the sales demos shinier, or in marketing speak, "delivers a value add for a prospective customer".One of those "shinies" was a lightweight server which would gather stats from the data warehousing engine and provide a dashboard with those stats, and notifications about them. Prospective customers really love it when the machine goes "bing" and shows them an interesting notification.As the notifications were becoming a bigger feature, the system needed a way to remember notification configuration between sessions, and that meant there needed to be a better persistence layer.To add the feature, Alex started by looking at the existing tests for the notification system.
Error'd: Please Select All Errors that Apply
"It doesn't impact me, but just wondering...which one would I pick if my spouse was named Elisabeth?" wrote Jon T.
CodeSOD: A Date with a Consultant
Management went out and hired a Highly Paid Consultant to build some custom extensions for Service Now, a SaaS tool for IT operations management. HPC did their work, turned over the product, and vanished the instant the last check cleared. Matt was the blessed developer who was tasked with dealing with any bugs or feature requests.Everything was fine for a few days, until the thirthieth of January. One of the end users attempted to set the “Due Date” for a hardware order to 03-FEB–2019. This failed, because "Start date cannot be in the past".Now, at the time of this writing, Feburary 3rd, 2019 is not yet in the past, so Matt dug in to investigate.
Temporal Obfuscation
We've all been inflicted with completely overdesigned overly generalized systems created by architects managers who didn't know how to scope things, or when to stop.We've all encountered premature optimization, and the subtle horrors that can spawn therefrom.For that matter, we've all inherited code that was written by individuals cow-orkers who didn't understand that this is not good variable naming policy.Jay's boss was a self-taught programmer from way back in the day and learned early on to write code that would conserve both memory and CPU compilation cycles for underpowered computers.He was assigned to work on such a program written by his boss. It quickly became apparent that when it came to variable names, let's just say that his boss was one of those people who believed that usefully descriptive variable names took so much longer to compile that he preemptively chose not to use them, or comments, in order to expedite compiling. Further, he made everything global to save the cost of pushing/popping variables to/from the stack. He even had a convention for naming his variables. Integers were named I1, I2, I3..., strings were named S1, S2, S3..., booleans were named F1, F2, F3...Thus, his programs were filled with intuitively self-explanatory statements like I23 = J4 + K17. Jay studied the program files for some time and had absolutely no clue as to what it was supposed to do, let alone how.He decided that the only sane thing that could be done was to figure out what each of those variables represented and rename it to something appropriate. For example, he figured out that S4 was customer name, and then went through the program and replaced every instance of S4 with customer_name. Rinse and repeat for every variable declaration. He spent countless hours at this and thought that he was finally making sense of the program, when he came to a line that, after variable renaming, now said: account_balance = account_balance - zip_code.Clearly, that seemed wrong. Okay, he must have made a mistake somewhere, so he went back and checked what made him think that those variables were account balance and zip code. Unfortunately, that's exactly what they represented... at the top of the program.To his chagrin, Jay soon realized that his boss, to save memory, had re-used variables for totally different purposes at different places in the program. The variable that contained zip code at the top contained item cost further down, and account balance elsewhere. The meaning of each variable changed not only by code location and context, but also temporally throughout the execution of the program.It was at this point that Jay began his nervous breakdown. [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
A Mean Game of Pong
Mark J spent some time as a contractor in the Supply & Inventory division of a Big Government Agency. He helped with the coding efforts on an antiquated requisition system, although as he would come to find, his offers to help went unappreciated.
CodeSOD: Sort Sort Sort Your Map, Functionally Down the Stream
A while back, we saw "Frenk"'s approach to making an unreadable pile of lambda-based Java code. Antonio has some more code, which didn't come from Frenk, but possibly from one of Frenk's disciples, who we'll call "Grenk".Imagine you have a list of users. You want to display those users in order by "lastname, firstname". Your usernames happen to be in the form "firstname.lastname". You also have actual "firstname" and "lastname" fields in your dataset, but ignore those for the moment, because for whatever reason, they never made it to this block of code.There are a lot of relatively straightforward ways you can solve this problem. Especially, as there is already a TreeMap implementation in Java, which accepts a comparator and ensures the keys are sorted. That wouldn't let Grenk show off the cool new things they learned to do with streams and lambdas. There's a (relatively) new toy in the Java language, and gosh darn it, it needs to be used.
Error'd: The Results are (Almost) In!
"Oh man! This results of this McDonalds vote look like they're going to be pretty close...or miles apart...," Pascal writes.
CodeSOD: Giving 104%
Dates, as we have explored exhaustively, are hard. And yet, no matter how much we explore dates, and the myriad ways developers can completely screw them up, there are constantly new borders of date-related idiocy ahead of us.The app Michael supported was running on a server running an Ubuntu version that was more than a little ancient, so as a test, he upgraded to the latest LTS version. That also included upgrades to the MySQL version they were running.And right after doing the upgrade, errors like this started to appear: ERROR 1292 (22007): Incorrect datetime value: '2019-07-23 24:59:59' for column 'update_endDate'Well, obviously, 24:59:59 is not a valid datetime value. Obviously, someone rolled a custom date-handling function, and something in the upgrade revealed an off-by-one error. Off-by-one bugs (or “OBOB” as one professor I had liked to call them) are common and easy.Michael’s guess was technically correct. There was an off-by-one error, only it wasn’t in the code. It was in the original developer’s brain:
CodeSOD: Internal Validation
If you’re doing anything financial in Brazil, you have to manage “CNPJ” numbers. These numbers are unique identifiers for every business and every branch of that business, along with a pair of check-digits to validate that it’s a correct code. Everyone from banks to accountants to businesses needs to track and manage these.When Patria joined a microscopic startup as an intern. The startup made an accounting package, and thus needed to track CNPJs. She asked the lead developer, “Hey, how do I validate those check-digits?”“Actually, as an intern, that’s probably a really good beginner task for you.”They were a very new startup, so it wasn’t a surprise that the current validation routine was simply return True. Patria, with no industry experience, had her task, and ran off to solve the problem.“Could you review my code before I merge?” she asked the lead dev.“Nah, just go ahead and merge, I’m sure it’s fine.”This is what Patria merged.
CodeSOD: Why Is This Here?
Oma was tracking down a bug where the application complained about the wrong parameters being passed to an API. As she traced through the Java code, she spotted a construct like this:
Relative Versioning
Today's submission comes from someone going by Albert Einstein. Before we look at what they sent us, let's talk a little bit about version numbers.Version numbers, if you think about it, are a deeply weird construct, and they're trying to balance a lot of difficult goals. At its simplest, a version number is meant to order your releases. Version 2 comes after version 1. Version 3 comes next. But even this simple goal is surprisingly difficult, because your releases only exist in order if you only have one chain of history for your product. The instant you have to have a custom build for one customer, or you start doing AB testing, or your library has to provide multiple interfaces for different deployment conditions, or one developer down in the basement decides to fork and not tell anyone- releases cease to have a linear order.Well, those kinds of disordered changes and branching versions sounds like a directed acyclic graph, which not only sounds extremely clever, but is how Git manages your history. We could theoretically just tag our releases with the commit hash, giving us a unique version number that allows us to quickly and cleanly know what version of the code we're talking about. But commit hashes are opaque and meaningless- which brings us to the other goal of version numbers.Version numbers not only order our releases, they also are meant to convey information about the content and delta between those releases. Semantic versioning, for example, tries to guarantee that we can make certain assumptions about the difference between version 1.0.1, 1.0.5, 1.1.2, and 2.1.1. Changes to the last digit imply that it's only patches and bugfixes, and shouldn't change behavior. That can get you pretty far, assuming you don't bump into one of those cases where "every change breaks somebody's workflow". Even then, though, incrementing the major version number means there might be breaking changes, but doesn't require that there are, which is why Angular is on version 247 but hasn't seen much by way of breaking changes since version 4.And that's another thing version numbers need to accomplish: they're a marketing/communication tool to educate your public about your product. Anyone who can count can understand that higher version numbers must be newer, and thus be the preferred version. People watch those version numbers tick up, and it gives them a sense that active development is ongoing.With all of these goals, I don't think there is a single way to solve the version numbering problem. Maybe you use semantic versioning. Maybe you go the Chrome route and just increment the major version every Tuesday. Maybe you go the Microsoft route and have piles of hot patches and fixes with no clear order or relationship to their application.What you probably don't want to do is go the route which Albert Einstein's company has gone. What follows is a full listing of every version, in chronological order of release, for a single product. Each entry on this list represents a single release.
Error'd: An Internet of Crap
"One can only assume the CEO of Fecebook is named Mark Zuckerturd," writes Eric G..
CodeSOD: The Pair of All Sums
Learning about data structures- when to use them, how to use them, and why- is a make-or-break moment for a lot of programmers. Some programmers master this. Some just get as far as hash maps and call it a day, and some… get inventive.Let’s say, for example, that you’re Jim J’s coworker. You have an object called a Closing. A Closing links two Entrys. This link is directed, so entry 1->2 is one Closing, while 2->1 is another. In real-world practice, though, two Closings that are linked together in both directions should generally be interacted with as pairs. So, 1->2 and 2->1 may not be the same object, but they’re clearly related.Jim’s coworker wanted to gather all the pairs were together, and put them into groups, so 1->2 and 2->1 are one group, while 3->1 and 1->3 are another. This was their approach.
CodeSOD: Ternt Up GUID
UUIDs and GUIDs aren’t as hard as dates, but boy, do they get hard, don’t they. Just look at how many times they come up. It’s hard to generate a value that’s guaranteed to be unique. And there’s a lot of ways to do it- depending on your needs, there are some UUIDs that can be sorted sequentially, some which can be fully random, some which rely on hash algorithms, and so on.Of course, that means, for example, your UUIDs aren’t sequential. Even with time-based, they’re not in sequence. They’re just sortable.Pitming S had a co-worker which wanted them to be sequential.
CodeSOD: Switch the Dropdown
Bogdan Olteanu picked up a simple-sounding bug. There was a drop-down list in the application which was missing a few entries. Since this section of the app wasn't data-driven, that meant someone messed up when hard-coding the entries into the dropdown.Bogdan was correct. Someone messed up, alright.
Crushing Performance
Many years ago, Sebastian worked for a company which sold self-assembled workstations and servers. One of the company's top clients ordered a server as a replacement for their ancient IBM PS/2 Model 70. The new machine ran Windows NT Server 4.0 and boasted an IPC RAID controller, along with other period-appropriate bells and whistles. Sebastian took a trip out to the client site and installed the new server in the requested place: a table in front of the receptionist's desk, accessible by anyone walking through the main entrance. Not the best location from a security standpoint, but one of the new server's primary tasks in life would be to serve the company's telephone directory, installed on CD-ROM.Two weeks later, the client called back, irate over the fact that the new server performed terribly compared to their old one. Troubleshooting efforts via phone were ineffective; the client demanded on-site support. After several frantic conference calls involving Sales, Support, and nosebleed-level management, Sebastian was on a plane back to the client site.Once back within the client's stuffy lobby, he could see that the server setup had in fact changed since he'd last been there, despite the client's repeated insistence to the contrary. Someone had placed both the old and new server boxes under the table. Two CRT monitors sat side-by-side on the table along with their corresponding mice. The keyboards were on a roll-out drawer just under the surface. Both machines were already logged in as administrator, waiting for anyone to come along and not exploit that fact.After checking in with his on-site contact and securing a cup of coffee, Sebastian got to troubleshooting. First thing, he used the mouse to open the Start menu on the new server—but as soon as he released the mouse button, the Start menu collapsed. He tried a few more times with no success.Frowning, Sebastian rolled out the keyboard drawer, hoping to try a keyboard shortcut next. When he did so, he found the keyboards set up one in front of the other. The strain relief on the back of the old server's keyboard was sitting right on top of the space bar of the new server's keyboard. Apparently, it'd been holding down the space bar for the past two weeks straight.Sebastian pulled the old server keyboard onto the table. Sure enough, the new server behaved normally from then on. Thousands of dollars spent, hundreds of miles flown—all to lift one keyboard away from another. [Advertisement] Forget logs. Next time you're struggling to replicate error, crash and performance issues in your apps - Think Raygun! Installs in minutes. Learn more.
Announcements: TheDailyWtf.com Server Migration Complete
If you're reading this message, then it means that I managed to successfully migrate TheDailyWTf.com and the related settings from our old server (74.50.110.120) to the new server (162.252.83.113).Shameless plug: I did all of this by setting up a configuration role in our internally-hosted Otter instance for both old and new servers (to make sure configuration was identical), deploying the last successful build to the new server using our internally-hosted BuildMaster instance, and then manually installing the certificate and configuring the database. Here's what the OtterScript looks like for the server's configuration. I'd love to move this to a publically-hosted instance, soon!
Error'd: Next Stop...Errortown
"Rather than tell me when the next train is supposed to arrive, this electronic sign is helpfully informing me that something's IP address is...disabled?" Ashley A. writes.
CodeSOD: Certifiable Success
“Hey, apparently, the SSL cert on our web-service expired… in 2013.”Laura’s company had a web-service that provided most of their business logic, and managed a suite of clients for interacting with that service. Those clients definitely used SSL to make calls to that web-service. And Laura knew that there were a bunch of calls to ValidateServerCertificate as part of the handshaking process, so they were definitely validating it, right?
Representative Line: It Only Crashes When It Works
We already know that Kara’s office has a problem with strings. Kara’s back again, with more string related troubles.These troubles are a bit worse, once we add in some history. You see, some of their software does machine control. That is to say, it sends commands to some bit of machinery, which then moves or extrudes or does whatever the machine does. Kara wasn’t specific, only granted that this machine was neither large enough or mean enough to kill someone. Minor cuts, burns, scrapes, bruises and damage to the equipment itself is still possible, but nobody will die.Once upon a time, the bulk of this code was written in C. Then someone wanted a better UI. So that C code got replaced by the perfectly natural solution of… Visual Basic. There’s still some C in there somewhere, hidden behind interops and marshalled calls to native code, but most of the GUI and logic is pure VB.Net. Which brings us to our representative line.
CSS (Under)Performance
Ah, WordPress. If you hadn't heard of it by reputation, it sounds pretty good: one platform where you can build a blog, an e-commerce site, an app, or some combination of all of the above. Their site is slick, and their marketing copy sounds impressive: "Beautiful designs, powerful features, and the freedom to build anything you want. WordPress is both free and priceless at the same time." With WordPress, the hype insists, anyone can build a website without having to know anything about coding. Just pick a template, add free modules, and it'll look great without any effort.If you've worked anywhere remotely connected to web design, you've heard of WordPress, and likely by reputation. The engine has maintained backwards compatibility since day one, which means it's the usual spaghetti system of duct tape and prayers you get when you prioritize backwards compatibility over systems engineering. It was more of a success than the designers intended, having been built solely as a (pretty decent) blogging platform at first, so the more use cases it expands to cover, the worse the learning curve becomes. Many web designers refuse to touch the system at all, preferring to roll something by hand that they understand than to untangle the snarl of "free" modules their clients installed when something goes wrong.Two days before launch, Lukas was nearly done with a contract job: a custom marketing site with a contact form, exactly the kind of thing Wordpress has for Use Case #2. Testing the site before handing it over, he noticed one page loading slowly. VERY slowly. Like, 60 seconds slowly.It seemed odd that a page with only static resources could even be that slow, so he ran a profile on the page:For those of you who don't speak browser profile, that's the CSS engine that's stalling out for a whole minute. Usually, unless you're doing awful things in your CSS or have megabytes worth of it to render, the CSS engine is very fast; the usual culprit in Wordpress is client-side Javascript. But the CSS looked perfectly fine—messy and WordPressy, but fine, once it was all compiled.Searching for answers, Lukas compared the markup on the page to the CSS stylesheet, trying to deduce what it was doing. A fancy heading here, a custom font there ... everything looked normal until he got to the top of the footer area, where he found the totally normal and not at all strange sequence of 131,074 empty paragraph tags.Did I mention WordPress is built in PHP?Some rogue bit of PHP code had gone into a horrible loop, dumping out empty paragraph tags 131,074 times right before the footer element. Pages upon pages of <p> with nary a </p> in sight. Paragraph tags default to display:block, meaning every time the engine gets to one, it causes the browser to execute layout, paint, and composite operations on the rest of the page—including the up to 131,073 other paragraph tags it may have already encountered. And this gnarly bit of nothing began after 1,482 lines of useful HTML, so it wasn't as if the page were tiny to begin with.It gets better: this was all just before the custom footer, which can have inline CSS in WordPress, as it's a quick way to tweak a theme without having to create what's called a "child theme." The client had some inline CSS in place, and yes, it applied to the paragraph tag. It set padding-bottom: 0px !important;, forcing the CSS engine to re-render the entire set of paragraph tags once more.And that's why no matter how good platforms become, no matter how rich the plugin ecosystem, there will always be work for web devs. [Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!
CodeSOD: Without Compare
Operator overloading is a messy prospect. In theory, it means that you can naturally extend a language so that you can operate on objects naturally. An introductory CS class might have students implement a Ratio or Fraction class, then overload arithmetic operators so you can (a + b).reduce().In practice, it means you use the bitshift operator also as the stream insertion operator. Thanks C++.Java decided to chuck the baby out with the bathwater, and simply didn't allow operator overloading, but this introduced its own challenges. How do I tell if one instance of MyObject type is greater than another instance? That's important if I want to sort these objects, for example.Thus, Java has the Comparator interface. Implement Comparator<MyObject> and now you can compare two instances of that object. The comparator object can be passed to all sorts of built-in methods for sorting, filtering, etc. At least, that's the theory.An anonymous submitter found this unique approach to that problem.
Error'd: All Aboard the System Bus
"The classic 'If transportation had evolved at the same pace as computers...' comparison is no longer merely academic as this TTC streetcar proudly displays it's nearing 32K RAM," Carlos writes.
CodeSOD: Is Num? I'm Numb
"The hurrider I go, the behinder I get," is one of the phrases I like to trot out any time a project schedule slips and a PHB or PM decides the solution is either crunch or throwing more bodies at the project.Karl had one of those bosses, and ended up in the deep end of crunch. Of course, when that happens, mistakes happen, and everything gets further behind, or you're left with a mountain of technical debt because you forgot that Integer.TryParse was a function in C#.Which is what happened to Karl. And that's why Karl wrote… this.
Representative Line: Innumerable Enum
Ah, the enumerated type. At its core, it's really just a compile-time check to ensure that this constant containing 1 isn't getting confused with this other constant, also containing 1.We usually ignore the actual numbers in our enums, though not always. Perhaps, though, we should just pay more attention to them in general, that way we don't end up with code like Andrew found.
Best of…: 2018: Another Bitmask Fail
Best of…: 2018: The Wizard Algorithm
Error'd: A Sour Currency Mix
"Lime bikes are finally in my city! Let's pay for it...So if my USD balance goes below GBP 0 it'll top up with ...AUD?" Ben writes.
Best of…: 2018: Shiny Side Up
Best of…: 2018: JavaScript Centipede
A Lumpy Christmas
Every "enterprise" shop has that one system you hope you never need to touch. It's older than you are, "documentation" consists of whispers and rumors about its behavior, and it is absolutely 100% business critical. If it goes down, the business goes down.Fortunately, you'll never have to touch that system, because there's an Ancient Wizard who has been sitting in the same cube since 1973, and knows its secrets. As long as the Wizard is around, you'll never touch it. Of course, if the system goes down when the Wizard is out of the office… well, fixing that would require a Christmas miracle.Renee was a programmer-elf in Santa's Workshop. It was a huge organization with many layers of middle-elfagent, so 90% of her job was sitting in pointless meetings with no agenda. In the remaining 10%, she occasionally added features to their in-house legal invoice processing software. Since nearly every present they shipped was an elf-produced knockoff of a large company's trademarks, legal billing was one of the Workshop's largest line items.There were other important IT systems. Supply chain was massive. All raw materials, aside from the naturally-occurring candy canes, had to be imported. Whether it was fabric for producing dolls, or ABS plastic and injection molds for producing dolls action figures. While shipping had a special organizational importance, IT rarely was engaged. The CEC (Chief Executive Claus) had learned to do pivot tables and VLOOKUPs in Excel, and did all his shipment planning himself.The 100% business-critical mystery system was NNOSE: Naughty/Nice Observation and System Evaluator. It was the "source of truth" for the all important TPS reports: Total Presents Sacked. The Ancient Wizard who cared for it was literally an Ancient Wizard, Merlin. And yes, Merlin really was Santa's sidekick. NNOSE ran on a piece of NORAD surplus computer hardware and was programmed in a dialect of MUMPS nicknamed "Sugar LUMPS" or just "LUMPS". Merlin was the only one who knew how the system worked and what the system did, and Merlin was the only one who was ever supposed to touch it.As the clock clicked closer to 12/24, the shipping deadline, the Workshop got busier and busier, while software developers got less and less busy. Since time was critical, no software changes went into production unless there was an absolute show-stopping bug. The software teams basically were on an extended break until the New Year, and no code releases would happen until mid-January at the earliest.So, during the busiest, most critical time of the year, the development team mostly spent their vacation hours. Merlin was out in Avalon, trying to patch things up with his ex. The senior Project Elfagers were on a retreat in Cancun. All through the shop, not a developer was stirring, aside from Renee. Renee loved to work during the quietest time of the year, when no one scheduled any meetings. It was its own kind of vacation…… at least until Hermie, the lead developer who really wanted to be an MBA, popped his head into her cube."NNOSE is down. The Big Guy just tried to pull the final TPS report for the year, and not only did it not have a cover sheet, it printed ten pages of errors instead of data. I've already tried to raise Merlin, but he's not on Slack, and there's no cell service in Avalon."If the TPS report were wrong or unavailable, Santa couldn't accurately match kids up with presents. Naughty kids could get great gifts, nice ones might get useless garbage like an Amazon Echo or Google Home. He needed that report."Okay, but I know the report has been run previously," Renee said. "Can't they just run with an old version?""There aren't any old versions. TPSes get shredded after review, ever since GDPR went into effect."Against her better judgment, Renee set down her hot cocoa and said, "I'll see what I can do."Merlin didn't keep any digital documentation for NNOSE. Everything about the system was stored in binders full of parchment in his cube. Calling the contents "documentation" would be generous. Merlin had written most of it in High Enochian, and what little bits were in Elvish just seemed to be rants and raves about changes management had requested, and how wrong those changes were. The only system diagram was arranged into an Elder Sign. The most useful thing Renee found in her first pass were post-it notes with login credentials for the various bits.Still, it was enough for Renee to start piecing together the system. The TPS report came from data managed by NNOSE, but the mainframe-based CLI interface had been abandoned circa 2002. At that point, someone had purchased an expensive mainframe integration package from Initech, which was basically a way of slapping XML/SOAP webservices on top of existing mainframe code. A few years later, someone had slapped together a VB.NET (framework version 1.0) UI which called into that webservice. The VB.NET program actually extracted and printed the report.Great! Renee kind of knew Visual Basic, or at least could fake it. And it wasn't LUMPS. She started by testing the NNOSE XML interface- she sent a few SOAP requests manually and verified that she got correct output. Then she fired up the VB.NET app. It had a basic UI for setting filters and criteria, but once you hit "run report", everything—even the error messages—went to the printer. Worse, you couldn't tell it what printer to use. Every print went to one printer down in the reindeer stables.Cue the testing cycle of "try running the report, ride the world's slowest elevator to the basement, walk through the reindeer stables, wait for the printer to finish running off its pages of error messages, drag the ream of paper back upstairs and try to match it to the code." Through this process, Renee learned a few important things. First, no matter how Christmas-y and magical reindeer were in spirit, in odor they were more Halloween Horror. Second, for some reason, there were SQL errors showing up in the stack traces. But everything was supposed to be webservices wrapped on mainframes, so why were there database calls?Renee went back to Merlin's binders, and with the help of what little High Enochian she could remember from high school, Renee started to piece together what was happening.Circa 2004, against Merlin's protests, there had been a project code-named RED. The goal of RED was to "upgrade" NNOSE to a full J2EE system with an Oracle backend. If Renee was reading the Enochian correctly, Merlin had banished the elf responsible for contracting the vendor to the Astral Plane, where they were surely captured by Githyanki."Well, that's got to be a violation of HR policies," Renee noted to herself.The project never completed, but progressed to the point where the Oracle backend had been running in parallel with NNOSE ever since. That explained the SQL errors. The VB.NET app had functionality added to talk to the "upgraded" RED system. At some point in its history, the VB.NET app had been pointed to that backend, and had been querying it instead of the mainframe. Sure enough, when Renee logged into Oracle directly, most commands returned errors as something in this more-or-less unmaintained and unpatched Oracle instance was completely FUBAR.Renee poked at the VB.NET app until she figured out how to resurrect the webservice-based data access layer. One more olfactory offense later, and Renee was holding a TPS report. Off it went to Santa, and off she went to give an after action to Hermie."Great work! You've saved Christmas!" Hermie said. "Shame about Merlin, though.""What about Merlin?""Oh, the whole banishing poor Roger to be soulsucked on the Astral Plane. That is absolutely a firing offense, and we're going to have to let Merlin go. Don't worry, though. After this, I'm confident that you can fill in as our new NNOSE and LUMPS expert. You can think of it like a promotion, and maybe in a few years, it'll involve a salary increase!" [Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!
Classic WTF: Power Supply
Error'd: A Generic Holiday Title Goes Here
"Sure, there's the obvious 'they didn't put any effort into the email subject,' but the placeholder kind of shows they didn't intend to in the first place," Chris wrote.
Representative Line: Explicitly True
Part of Python’s appeal is its rich class library. The old XKCD about import antigravity sometimes doesn’t feel that far off. Combined with a few third-party libraries, like NumPy, you can do a lot with very little code.Of course, that feels a bit like magic. As Python gurus like to say, “Explicit is better than implicit”. One of Mark’s co-workers took this perhaps a bit too far, when they started adding this import to every file:
Assumptions are the Mother of all Bugs
A long time ago in my "C" programming days, I learned that when you code up anything that depends on any sort of external data, be it a file, database or socket, you should be paranoid and do it defensively. After all, you can't control those things and there's no guarantee that they will always work the way you hope. Sometimes you care about every possible error code; sometimes just success or failure. The point is to check the result of what you tried to do. Fast forward through several years of C++ and ten years into Java, and our boss calls us into the office.
CodeSOD: Trim the Tree
Tis the season to think of trees.Our Anonymous submitter has a program with a tree in it, and it’s a relatively big one: 7 levels deep, with 200,000 leaf nodes. Oh, and it’s managed in client-side JavaScript. In other words, it’s the sort of thing you really want to make sure you’re accessing efficiently.Since it’s a tree, and since in this case, all the nodes are doubly linked (each child contains a reference to its parent), it’s easy to get from any one node to any other, with a minimal number of steps. There’s never a good reason to traverse the entire tree.Which is why Anonymous facepalmed when they found this code:
CodeSOD: A Short Leap
You know the story. A report is spitting out the wrong dates. Someone gets called in to investigate what’s wrong. After digging through piles of deeply nested SQL queries and views and trying to track down the problem, it turns out someone wrote their own date handling code which is wrong.Darin P found the code this time.
Error'd: Trouble at the End of the World
"Normally, the solar face in Apple Watch, is supposed to show a single 24-hour period," writes Juan C. wrote, "It turns out that going to Ushuaia (the southernmost city in the world) makes it a bit confused, specifically stating that noon is midnight and showing more than one day."
Politics Rules! Common Sense Drools!
As programmers, we all need to fix bugs. As experienced programmers, we recognize that sometimes, the ability to fix one bug depends upon first fixing another bug. Managers, on the other hand, don't always get that simple concept.At the beginning of my career, I worked for Initrode where I wrote software to run a test-station that diagnosed assorted electronic components of jet fighters. Initrode acted as a government-supplier of the test station to another government contractor (LUserCorp) that used the station to write the test sequences to diagnose electrical faults. If the test station hardware malfunctioned, or there were bugs in the software that made the electronics tests fail to work properly, then LUserCorp could use that as an excuse for time and cost overruns. If that happened, then the government would penalize Initrode to recoup those costs.Over time and several releases of the hardware and software, a series of hardware faults and software bugs managed to creep into the system. Since LUserCorp was running behind schedule anyway, they decided that they'd use this as an excuse to hit the government for more time and money. Naturally, the brass at Initrode fought back because they didn't want to take the financial hit.After lots of political back-and-forth, an official prioritized bug list was created, and it was mandated by LUserCorp that the bugs had to be fixed in the order in which they appeared on the list.To this end, me and another junior developer were sent to LUserCorp to act as a Tiger Team. Basically, this means we are in a locked room, alone with the test station. The LUserCorp people were not allowed in the room with us. We brought the source code on our own disk pack which one of us had to be with at all times. This meant that if we went to lunch, or both had to hit the restroom at the same time, we had to power everything down and take the disk with us.The list of bugs to be addressed was provided to us only after we were on site. The first and most important bug on the list was something I had coded that had an off-by-one error in a nested loop, that only appeared at the end of the third iteration of the outer loop. Since each inner loop processed and printed the 6-line result of each of 4K tests (to a very slow thermal printer), it took 6 hours to print out 3*4K*6 => 72K lines of test results.Our software also had stop-at-test-n functionality. We noticed that bug number 2 on the list was in the stop-at-test-n functionality (it prevented that feature from being used).In the ideal case where all other functions were working, we'd do:
CodeSOD: Identify Yourself
Brian B stumbled across a bit of code to generate UUIDs. Seeing that tag-line, I was worried that they invented their own UUID generator. The good news, is that they just use java.util.UUID. The bad news is that they don’t understand how if statements work.
CodeSOD: Strongly Unrecommended
Asynchronous programming is hard. Because it’s so difficult, developers are constantly trying to find ways to make it simpler, whether it’s promises or callbacks, or the async/await pattern. It gets more difficult when you need to deal with handling exceptions- when a task fails, trying to recover from that failure in a separate thread is an extra special challenge.Which brings us to Betty’s co-worker. Using C#’s Task objects, which tie into the async/await pattern, they wanted to simply ignore any exceptions thrown by one of those tasks. That’s your first WTF, of course. Their approach, however, is a larger one:
CodeSOD: The Key to Using Dictionaries
It's easy to use dictionaries/maps to solve the wrong kinds of problems, but deep down, what's more elegant than a simple hashed map structure? If you have the key, fetching the associated value back out happens in constant time, regardless of the size of the map. The same is true for inserting. In fact, hash maps only become inefficient when you start searching them.Concetta recently started a new job. Once upon a time, a developer at the office noticed that the user-facing admin pages for their product were garbage. They whipped up their own internal version, which let them accomplish tasks that were difficult, time-consuming, or downright impossible to do in the "official" front end. Time passed, someone noticed, "Hey, this is better than our actual product!", and suddenly the C# code that just lived in one folder on one developer's machine was getting refactored and cleaned up into an application they could release to the public.Concetta wasn't surprised to see that the code wasn't exactly great. She wasn't surprised that it constantly threw exceptions any time you tried to change anything. But she was surprised by this:
Error'd: The Error is ...Terror?
"Lasterror...Las terror...Terrorist...Zoroaster...They're all so close! Which one do I choose??" wrote Ralph.
...32333435363738394041...