by Remy Porter on (#6QNYA)
Let's say you had 6 different labels to display. There are many, many ways to solve this problem. Most of them are fine. Some of them are the dreaded loop-switch anti-pattern.Julien unfortunately inherited one of those.
|
The Daily WTF
Link | http://thedailywtf.com/ |
Feed | http://syndication.thedailywtf.com/TheDailyWtf |
Updated | 2024-11-21 14:46 |
by Remy Porter on (#6QN18)
As frequently discussed here, there are scientists who end up writing a fair bit of code, but they're not software engineers. This means that the code frequently solves the problem in front of them, it often has issues.Nancy works in a lab with a slew of data scientists, and the code she has to handle gets... problematic.
|
by Remy Porter on (#6QM3Y)
Once upon a time, a company started a large React application. Like so many such projects, the requirements were vague and poorly understood, the management didn't have any sort of plan, and the developers didn't understand the framework. Once this inevitably started to go off the rails, all the developers were fired and then contractors were brought in, because that would be "cheaper".Spoilers: it was not. So all the contractors were fired, and a new round of hires were brought in. This time, though, they'd correct their mistakes by strictly enforcing Scrum practices to be "agile".This is where Gretchen entered the story.The code was a mess, and every feature was fragile if not outright broken. The project was overbudget and behind schedule before Gretchen even started. In other words, things were going great.Gretchen started with what appeared to be a simple task- fixing the fact that many text fields overflowed their bounding box and were thus unreadable. She dug in, and started going through the component code, which is where she found this:
|
by Remy Porter on (#6QK4K)
The number of web applications which need to generate PDFs is too damn high, in my experience. But it's a requirement which continues to exist for a variety of reasons, so we just have to accept it.Derek was accepting of it, at least until he found this attempt to add ten lines of space between paragraphs.
|
by Lyle Seaman on (#6QH6N)
This week, we discover an answer to the questionthat has eternally plagued us: "is time travel possible?"I won't swear it's the right answer, but it'sdefinitely an answer.But first, FaroguyChris P. both shared the same issue with us (if theyare in fact different people and not just each other's sock puppet)Snarked one of them: "A previous Teams "What's New" pop-up was empty. At leastthis one has content, even if part of it is a broken image and visible header name."
|
by Remy Porter on (#6QG7T)
Anton has the joy of doing PHP work using one of the more popular e-commerce platforms.Now, say what you will about PHP, its absolute mess of a root namespace has a function or class for just about everything. You want to split a string? We call that explode because that's way more radical than split. Want to join a string back together? We use implode, because that's the opposite of explode.Or, if you forget how to use implode, you could always write it yourself, which is what Anton found in the codebase:
|
by Remy Porter on (#6QF85)
Things weren't looking good for IniOil. It was the 1980s in the US: greed was good, anti-trust laws had been literally Borked, and financialization and mergers were eating up the energy industry. IniOil was a small fish surrounded by much larger fish, and the larger fish were hungry.Gordon was their primary IT person. He managed a farm of VAXes and other minicomputers, which geologists used to do complicated models to predict where oil might be found. In terms of utilization, the computer room was arguably the most efficient space in the company: those computers may have been expensive, but they were burning 24/7 to find more oil to extract.The CEO sent out a memo. "Due to economic conditions," it read, "we are going to have to cut costs and streamline." Cutting costs and streamlining meant "hiring a bunch of Ivy League MBAs" who had a long list of reforms they wanted the company to adopt. One of them was to force all the various business units to use internal billing and charge other business units for their services.At first, this looked like a good thing for Gordon. Their overhead costs were low- the IT team was small, and the VAXes were reliable, and the workloads were well understood. Billing out computer time was going to make all their metrics look amazing.Unfortunately, facilities also was a billable unit. And they charged by square foot. Suddenly, the IT team was paying through the nose for the computer room.What really stuck in Gordon's craw, however, was that it seemed like the computer room was getting billed at a more expensive rate than anything else in the building- it was about the same size as the sales floor, but was billed at double the rate.Gordon raised this with facilities. "That's not true," they said. "We bill by the square foot. You've got twice as much square footage."Gordon insisted that the computer room did not. He broke out a tape measure, went to the sales floor, took some measurements, then went to the computer room and repeated it. The difference was a matter of a few square feet.Gordon went back to facilities. "Your measurements are wrong.""They're square rooms," Gordon said. "How wrong could I be? A factor of two? Do you want to take the measurements?"Facilities didn't need to take measurements. They had drawings. And the drawings showed a room that was 80'x80'... and was 12,800 sq ft. Gordon pointed out how that didn't make sense, by basic arithmetic, and the facilities manager tapped an annotation on the drawing. "Raised flooring".Because the computer room had a raised floor, facilities was counting it as twice the floor space. Gordon tried to argue with facilities, pointing out that no matter how many raised floors were added, the actual building square footage did not change. But every business unit was looking to cut costs and boost internal profits, which meant "seeing reason" wasn't high on the facilities priority list.Gordon raised it up with management, but everyone was too panicked by the threat of mergers and losing jobs to start a major fight over it. Facilities said the square footage was 12,800, then that's what it was. But Gordon's management change had a solution."Gordon," his boss said. "Remove the raised flooring. Just rip it out."It was a quick and easy way to turn high billing rates into trip hazards and risks to equipment, but nobody was paying for risk mitigation and if there were any injuries because someone tripped over a cable, that'd come out of some other team's budget anyway.For a few months, the computer room was a hazard site, but the rent was at least cheap. In the end, though, none of it mattered- all the MBA driven cost "savings" weren't enough to stop a much bigger oil company from swallowing up IniOil. Most of the employees lost their jobs. The execs who owned most of the shares got a huge payout. And, well, the purchaser was interested in land leases and mineral rights, not computer rooms, so the VAXes were broken down and sold to a few universities. [Advertisement] Keep all your packages and Docker containers in one place, scan for vulnerabilities, and control who can access different feeds. ProGet installs in minutes and has a powerful free version with a lot of great features that you can upgrade when ready.Learn more.
|
by Remy Porter on (#6QEBP)
Stefan S has recently joined the ranks of software developers, having taken on his first job as a junior developer. After a few months of on-boarding with Terry, another new developer, they're now both actually getting assigned real work on tickets that deliver new functionality.Stefan proudly pushed his first feature, complete with plenty of unit, functional, and end-to-end tests. After a little brushing up during code-review, it was merged along with a few "atta boys", and Stefan was feeling pretty good about himself.A few days later, he pulled the latest changes, and ran the test suite. And all of the tests he wrote suddenly failed. Stefan's stomach dropped into his shoes, and he struggled to think: "How did I mess up this badly?"Except Stefan didn't mess up that badly. A quick check on source control history showed that Terry had added some new commits- one of which "optimized" Stefan's code by adding a NullPointerException.Stefan was relieved, but annoyed. He opted to, in his mind, "be a bro", and not open a ticket that the rest of the team could see, and instead messaged Terry directly. "Your changes have broken functionality. You need to fix it."At 5:05PM, Terry pushed a fix, and messaged Stefan, "Tests don't fail anymore," then left for the weekend. Terry was correct, the tests stopped failing.(Names anonymized by Stefan)
|
by Jake Vinson on (#6QDSC)
|
by Lyle Seaman on (#6QBYN)
On a vacation trip this week. The diligent will be able to discover the location with a tiny bit of sleuthing, but I won't be there now.An anonymous traveler reports "I've beentrying to contact them but I don't think they check their email very often."
|
by Remy Porter on (#6QAZE)
The addition of nullable or optional types to mainstream languages was a net good. It doesn't completely solve the billion dollar mistake, but it makes it far easier to write safe code.For most of us anyway.Sam found this representative line, which shows how one of his peers understand nullable types to work:
|
by Remy Porter on (#6QA2F)
Peter was tracking down some bugs, when he found code which looks like this:
|
by Remy Porter on (#6Q95E)
Lisa was working on a project she quite liked. The tech was cool, the problems being solved were interesting, and the team had a good working process. Company-wide, however, budgets were tight, and other projects were in much worse shape, so the project Lisa was on got put on pause, and her team was moved onto a different project.Someone wanted to make sure that functions which had large side effects were only called in the right places. Now, most of us might use some mixture of public/private, clear documentation, and maybe some key flags and error checking to ensure this was the case.This team had a... different approach.
|
by Remy Porter on (#6Q88N)
Today's anonymous submitter, who we'll call Sally, works on medical devices. As you can imagine, the development process for such devices is very strict. I mean, it should be, but we know that the industry has problems.Unfortunately for Sally, one of those problems is the tech lead on a project she is inheriting. Said tech lead is leaving, and Sally is coming on to replace them. The project is in C#, and Sally is the most experienced with the language, making her the obvious choice to step in.Now, the current tech lead had some concerns about the development cycle. You see, the whole process of writing code, compiling code, deploying that code onto hardware, and then running the code just took too darn long. If you wanted to iterate as fast as possible, you needed to skip some of those steps.
|
by Lyle Seaman on (#6Q6F0)
Elte Hupkes"Some weird Android behavior has my phone disconnectingfrom WiFi until I open it back up in the morning,triggering some backups. Unfortunately, WhatsApp Backupisn't a morning person."
|
by Remy Porter on (#6Q5HE)
Today's anonymous submitter found some Java code which finds the largest value in a quartet of floats. Now, the code is quite old, so it actually predates varargs in Java. That doesn't excuse any of what you're about to see.
|
by Remy Porter on (#6Q4H1)
Kendall found some recently written code, and had to wonder, "Who wrote this crap?" Much to Kendall's disappointment, source control knew who wrote it: Kendall.
|
by Remy Porter on (#6Q3PC)
Sebastian started a new job recently. Like a lot of "I started a new job," stories, this one starts with a 1,000 line class definition. What's notable about this one, however, is that most of that code is error handling. Now, you might think to yourself, "well, there's nothing inherently wrong with loads of error handling, if the problem calls for it.This code is getting posted here. Do you think the problem calls for it?
|
by Remy Porter on (#6Q2V9)
When discussing ternaries, we also have to discuss readability. While short and concise, they're in some ways too compact. But don't worry, Mark's co-worker has a wonderful simplification to ternaries. This representative line is a pattern used throughout the codebase.
|
by Lyle Seaman on (#6Q11J)
"Grocery stores are going too far with their energy foods" charged Tim DG. "I was just looking for some salads to go with my BBQ,"he complained. "I'm not sure they sell what I'm looking for."I've seen what your kin put in their Huzarensaladen, Tim,so I'm not entirely surprised about the Duracells.
|
by Remy Porter on (#6Q04W)
We all know that building SQL queries via string concatenation, and then sending them to the database, is just begging for fragile code and SQL injection attacks. But, what if the bad part is the "sending them to the database" part? Has anyone ever thought about that?Kris's predecessor has.
|
by Remy Porter on (#6PZ7C)
Many years ago, Sam was obeying Remy's Law of Requirements Gathering ("No matter what your requirements actually say, what your users want is Excel") and was working on a web-based spreadsheet and form application.The code is not good, and involves a great deal of reinvented wheels. It is, for example, Java based, but instead of using any of the standard Java web containers for hosting their code, they wrote their own. It's like Java Servlets, but also is utterly unlike them in important and surprising ways. It supports JSP for views, but also has just enough surprises that it breaks new developers.But let's just look at how it handles form data:
|
by Remy Porter on (#6PY99)
One of the first things anyone learns about object oriented programming is the power of inheritance and overriding functions. Isn't it great that you can extend or modify the implementation of a function in your derived classes? Don't you wish you could just do that for every function? Aash's co-worker certainly does.
|
by Remy Porter on (#6PXEX)
One of the clients for Rudolf's company was getting furious with them. The dev team was in constant firefighting mode. No new features ever shipped, because the code-base was too fragile to add new features to without breaking something else. What few tests existed were broken. Anyone put on the project burned out and fled in months, sometimes weeks, and rarely after only a few days.Rudolf wasn't too pleased when management parachuted him into the project to save it. But when he pulled the code and started poking around, it looked bad but not unsalvageable. The first thing he noticed is that, when following the instructions in the README, he couldn't build and run the application. Or maybe he wasn't following the instructions in the README, because the README was a confusing and incoherent mess, which included snippets from unresolved merges. Rudolf's first few days on the project were spent just getting it building and running locally, then updating the README. Once that was done, he started in on fixing the broken tests. There was a lot of work to be done, but it was all doable work. Rudolf could lay out a plan of how to get the project back on track and start delivering new features.It's about then that Steve, the product owner, called Rudolf in to his office. "What the hell do you think you're doing?"Rudolf blinked. "Um... what I was asked to do?""Three days and you just commit a README update? A couple of unit tests?""Well, it was out of date and meant I couldn't-""Our client is crazy about their business," Steve said. "Not about READMEs. Not about unit tests. None of that actually helps their business."Rudolf bit back a "well, actually," while Steve ranted."Next thing you're going to tell me is that we should waste time on refactoring, like everybody else did. Time is money, time is new features, and new features are money!"Suddenly, Rudolf realized that the reason the project had such a high burnout rate had nothing to do with the code itself. And while Rudolf could fix the code, he couldn't fix Steve. So, he did what everyone else had done: kept his head down and struggled through for a few months, and kept poking his manager to get him onto another project. In the meantime, he made this code slightly better for the next person, despite Steve's ranting. Rudolf eventually moved on, and Steve told everyone he was the worst developer that had ever touched the project.The customer continued to be unhappy. [Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!
|
by Lyle Seaman on (#6PVK9)
Daniel D. humblebrags that he can spell."Ordering is easy, but alphabet is hard. Anyway for this developerit was. Can anyone spot which sorting algo they used?"Next he'll probablyrub it in that he can actually read unlike the TDWTF staff.I guess we'll never know.
|
by Remy Porter on (#6PTNW)
There's nothing inherently wrong with the ternary operator. It's just the kind of thing that gets abused.Now, we all know how it should be used. We frequently would write something like this:
|
by Remy Porter on (#6PSSX)
"Dark Horse" inherited some PHP code. They had a hundred lines to submit, but only sent in a dozen- which is fine, as the dozen lines tell us what the other hundred look like.
|
by Remy Porter on (#6PRWM)
Sean was supporting a web application which, as many do, had required form fields for the user to fill out. The team wanted to ensure that the required fields were marked by an "*", as you do. Now, there are a lot of ways to potentially accomplish the goal, especially given that the forms are static and the fields are known well ahead of time.The obvious answer is just including the asterisk directly in the HTML: <label for="myInput">My Input(*)</label>: <input...>. But what if the field requirements change! You'll need to update every field label, potentially. So someone hit upon the "brillant" idea of tracking the names of the fields and their validation requirements in the database. That way, they could output that information when they rendered the page.Now, again, an obvious solution might be to output it directly into the rendered HTML. But someone decided that they should, instead, use a CSS class to mark it. Not a bad call, honestly! You could style your input.required fields, and even use the ::before or ::after pseudoelements to inject your "*". And if that's what they'd done, we wouldn't be talking about this. But that's not what they did.
|
by Remy Porter on (#6PR1P)
Today's anonymous submitter asks a question: "How do you imagine the rest of the codebase to be like?"Well, let's look at this snippet of TypeScript and think about it:
|
by Lyle Seaman on (#6PP6W)
Yes, the title misspelling was an intentional attempt at punnery.It's a compulsion, I'm sorry.I might have advisedAdam R. not to try to plan flights 4 years in advance, if asked. But he didn't ask, and so he discovered this. I'll let Adam explain.
|
by Remy Porter on (#6PNBN)
Today's anonymous submitter inherited an application with a huge list of bugs and feature requests for missing features. While tracking down a bug, our submitter learned a lot about why "Allow additional stores to be viewable in the store selector," was an unimplemented feature.
|
by Remy Porter on (#6PMA4)
Mike was doing work for a mobile services provider. He found this in their code:
|
by Remy Porter on (#6PKED)
Dan B is working on software which interacts with a bank. We'll get the REAL WTF out of the way right at the top: "The bank has requested that we send them an email containing the total of all the transactions..."Yes, core financial business functions being handled over email. I imagine some readers are probably thinking about drinking something stronger than coffee at the thought of it. A lot of readers, on the other hand, are already onto something stronger than coffee and going, "Oh, yeah, seen that before. Hell, I'm pretty sure that EDI explicitly supports email as a delivery mechanism."Let's dig into Dan's more specific challenge. The program he was supporting needed to take an input from their backend- a mainframe style, flat-file with fixed-width fields, and convert it into the format the bank wanted. Their input file tracked the value of each transaction as a zero-padded number in cents. E.g., a ten dollar transaction would be "0001000". The bank wanted a roll-up of all the line items, where the currency was represented as dollars and cents, e.g. "10.00". The email alert that needed to go out simply needed to be a summary of the file processed.Now, there's an obvious way to do this, even when we're worried about things like floating point rounding errors. There's also a wrong way to do this. Let's look at that one.
|
by Remy Porter on (#6PJHQ)
When "dragoncoder047" was but a junior developer, without very much experience at all, they were tasked with building error handling in a Python Flask web application.Now, they were a junior, and tossed into the problem without much preparation, or much supervision, and just told to "make it work". So they did. With this disaster:
|
by Lyle Seaman on (#6PGNX)
My plate has been full this week, but not as full as Walter's!"Maybe hold the cheese?" suggestsWalter T. regarding a pepper and steak grinder."Seen at Reading (MA) House of Pizza on Jul 24 2024." If youdecide to search around to try to understand the different names for this kind of sandwich, you willundoubtedly discover someone trying to claim that really, the hoagie is a different sandwich from a submarine,which is different from a grinder and so on. They are wrong,and this is how we know: if they truly were different kinds of sandwiches, then somewhere on this planet would be a shop selling examples of each of the differentvariants for your dining pleasure. There is not*. Q.E.D any consistent regional variation in bread choice, or dressing, or fillings, is simplythat: a regional variation of the same thing, not an entirelydifferent category.
|
by Remy Porter on (#6PFQ8)
Jaco's team had a problems with making an embedded web server shut down properly. Something about the shutdown process was deadlocking, so one of their "ninja Yoda coders" rockstarred their way to a solution.
|
by Remy Porter on (#6PEQA)
Andy has some concerns about future proofing. In this case, he sends us some C# code that's supposed to validate an IP address.
|
by Remy Porter on (#6PDT0)
We're not going to look at code today, and instead, we're going to talk about a code metric. Specifically, "NPath complexity".NPath complexity is a good metric to track, and many static analyzers will do it. Formally written, it's defined: "The NPath complexity of a method is the number of acyclic execution paths through that method." Or, more simply, not counting loop iterations, this is how many branches you have in a single method.Obviously, for simplicity's sake, this number should be small. Hell, ideally, it should be small enough that you can count it on your fingers. Ideally, small enough that you can count it on your fingers after attempting to drunkenly operate a bandsaw with no training.But a lot of code doesn't hit that threshold.Nikola's team decided it was time to start tracking some of those metrics. The tool they were using set the default threshold where it complains at 200- 200 different code paths in a single function.Nikola didn't provide the code. But she did provide a telling snippet from the report:
|
by Remy Porter on (#6PCYC)
Jan wrote some code that set a property, and a few lines later had to write code to read that value- and the compiler complained. Which is what drew his attention to this C# code:
|
by Lyle Seaman on (#6PB48)
Adrian M.lit up this blooper for us. "Apparently Siemens Mobility wasn't satisfied that a mere95-year copyright term would be enough for the brochureabout their m60-series traffic light controller. I hopeI won't have to wait until 2029 for a green light."See for yourself here.
|
by Remy Porter on (#6PA7T)
Languages which do type-coercion are generally setting users up for failure. At some point, you'll make some assumption about your inputs, and then type-coercion kicks in and changes what you expect. We see this all the time in JavaScript, and of course, in PHP. PHP booleans, for example, can surprise you: 0 is false, which is a common enough assumption, but so is "0"- the string zero. As are empty arrays.But what if you wanted more control over it? Peter sends us this PHP he found:
|
by Remy Porter on (#6P97Z)
When accepting user input for things like, say, accessing the filesystem, you need to do some validation. Bad or inappropriate characters could lead to surprises that no one is going to like.So when Christian first spotted this C# method called SanitizePath, he didn't think much of it. But then he looked at the implementation...
|
by Remy Porter on (#6P884)
Maciek has the distinct pleasure of working on Dynamics Ax, and ERP system. Like every other ERP system, it's endlessly customizable, and scriptable. In this case, scriptable in a custom language called "X++".While it's probably entirely possible to write good code under these circumstances, it's not an environment conducive to that. And that's how Maciek inherited this method:
|
by Remy Porter on (#6P7E5)
Running and hosting a database is expensive. Not only do you need the server for it (even if you rent in the cloud), you also need the expertise to administer it. And that's why Lucas ended up working on an application which used Google Sheets as its database.Now, this was an application used by a marketing team to create new marketing campaigns, so Google Sheets wasn't the worst choice made in the entire process. With only a handful of users and dozens of records, it was fine. You didn't need to put a huge amount of effort or expertise into it- at least, that's what management thought.The application didn't get the expertise it needed to work well, but "working badly" was sufficient for most cases.Since each row needed a unique identifier, here is how they handled that:
|
by Lyle Seaman on (#6P5R9)
This week, we saw some unexpected results in UK politics.Nothing was more unexpected than the dark-horse results thatRichard and a few anonymice remarked on."A glorious victory for the Undefined party!" crowed Richard"The UK general election has seen a surge of support for minor parties."
|
by Mark Bowytz on (#6P4VT)
|
by Alex Papadimoulis on (#6P3VD)
|
by Alex Papadimoulis on (#6P2Y0)
|
by Alex Papadimoulis on (#6P25M)
|
by Lyle Seaman on (#6P0GE)
This week's special edition is a series of Error'ds specificallydealing with trains, which geeks are for some reason especiallytaken with. It should go without saying that the reason these are predominantly from Europe is not an indication their infosystems are especially bad, but rather as we all know, US passenger trainsare so little used that there is far less opportunity to discover any wtfs.This entry byRobert G. requires explanation. London North East Rail hasa novel (six years old now but still new to me) point-of-use displayof seat reservations. In my train experience, a reserved seat ticketonly identifies a certain car but not a specific seat, so this ispretty slick. On LNER, if you don't have a seat reservation but you're traveling in the specified class, you can take any seat labelled"Available" but you'll need to vacate it at the "until XXX" station.The two rows in Robert's fuzzy image read "Current" and "Next",which should help to understand what has happened here. The two red lights indicate "Reservations". As Robert puts it,"My train was part cancelled, and a replacement coachwas provided to where it was now starting from. Unfortunatlythe coach arrived a few minutes after the train departed,so a new train was needed. Fortunatly the TOC's (TrainOperating Company) app allows seat reservations to madeup to 10 minutes from departure and the next train was inhalf an hour - given it's a long journey I was going toget a reservation. Apparently several other people hadthe same idea, resulting in two of us getting a confirmation(both email and in app) for the same seat."Apparently Robert reserved Edinburgh->KingsX and a randomcompetitor reserved Newcastle->KingsX at the same time.It seems that LNER's seat reservation application had afailure of transactional integrity. Hopefully it waseventually consistent.
|