by Lyle Seaman on (#6D5JW)
I have been surprised to find that some people who are in technologyfields don't have a clear grasp on the difference between RAM and "disk" storage. Or perhaps more accurately these days, "Direct Access Storage Devices." I've eventually become accustomed to it from ordinary folks, butPC World?An anonymous reader sent in this one, explaining "Yep. According to PC World Starfield will require 125GB of available RAM so you'll need at least 128 GB or more RAM installed to play.The Steam page correctly list the item as Storage: 125 GB available spaceso this is completely on PC World. To add insult to injury the post is titledBethesda's Starfield PC system requirements: An SSD is mandatoryso you'd expect at the very least to get the storage requirements right.Rush to print, trip and fall flat on your face. Thanks for the WTF, PC World!"
|
The Daily WTF
Link | http://thedailywtf.com/ |
Feed | http://syndication.thedailywtf.com/TheDailyWtf |
Updated | 2024-11-23 08:46 |
by Remy Porter on (#6D4Z2)
Today's an interesting case of code that seems perfectly reasonable at first glance. Sent to us from FinalGuy, this Java code caused no end of problems for him due to its rather unexpected behavior:
|
by Remy Porter on (#6D3EE)
Many years ago, Westie's employer got hired to help a client rebuild their tax advice website. The current version was... not in good shape, didn't provide a good user experience, and was incredibly unmaintainable. Westie's mission? Rewrite it from scratch.As these projects go, however, the requirements were ill documented, and basically were "Uh, just make it do all the same things, but it shouldn't suck anymore."Which meant Westie needed to use the existing site to understand what needed to be built. As a lark, Westie entered their income for the year as alert("Hello world") and oops! An alert box appeared when Westie hit submit.Similarly, entering JavaScript code into many of the numeric input boxes was allowed, and also executed that code. It didn't take long to unpick what anti-pattern was in play here.
|
by Remy Porter on (#6D2BZ)
Twenty years ago, Stefano Z worked with some Very Smart Very Senior Engineers. These Very Smart Senior Engineers liked to find all sorts of "interesting" solutions to common problems.For example, they had a module in C++ that needed to send data to other systems. To formalize this messaging, they needed a set of Data Transfer Objects (DTOs). Now, there are many libraries that might make generating these kinds of objects easier, but the Very Smart Very Senior Engineers didn't want to use a library. So they started out with just large piles of hand coded:
|
by Remy Porter on (#6D1CM)
Managing requirements for even a simple project is a nightmare. As projects get more complicated, "requirements management" mutates into "systems engineering". The requirements for, say, an entire IT migration, or an automobile, or a lunar lander turn into a tree of requirements, where each implementation step is traced back to an overall master requirement at the root of the tree. Five to one, your average project isn't this complicated, but you don't want to ship a product missing features and have to say "it slipped my mind".Enter a certain large vendor's Dynamic Object Oriented Requirements System (DOORS). Doors allows the requirements for a large, complicated product, to be organized into objects which are further organized into modules, where each object is a requirement, paragraph, section, table, figure, or anything that explains the nature of requirements.Greg L's team adopted DOORS for managing their requirements. Unfortunately for them, DOORS stored all its data in a proprietary database. If you wanted to automate anything in DOORS, or even if you just wanted to say "show me this requirement, its siblings, and all of its ancestors", you needed to learn the Doors eXtension Language (DXL).DXL was not the kind of language that would make you get up and dance. No, it would make your average developer an unhappy girl.For example, if you wanted to access the currently opened object, you could use the keyword current, but current was only available when using the assignment operator. You could assign to (and from) current, but not do anything else. Unless you're in a loop. Then it's fine.Property names on objects were allowed to have spaces, and many of the default properties did, so get used to writing o."Object Text" = "some text".Speaking of spaces, a single space was the concatenation operator. So, this would be one way to print out a list of variable values: print i " " r " " s " " d " " b "\n". It's also worth noting that non-string variables, like integers, can't be printed out unless they're converted to strings, which can be done via concatenation to an empty string: `print i " "Strings are also stored in a global string table. Each time you create string literals the entire literal ends up in that table and will live there for ever, so if you keep building strings incrementally, you'll very quickly fill up that table and crash the application with an out of memory error.Why is it like this? Well, we could say that people are strange, but the reality is that DXL was the kind of thing one employee invented to make their work easier, and then management and customers got wind of it and demanded that it be included in the product.Once there was an extension language, internal developers had to use that extension language, which means many features in DOORS were implemented in DXL. That includes the very obvious feature of "export your requirements as a human-readable word document".I'll let Greg explain:
|
by Lyle Seaman on (#6CZAR)
Warren D. takes the long view, explaining "I like a company that has an eye to the future. Maybe I'll stick with the Malwarebytes Premium trial for another few hundred thousand years."
|
by Remy Porter on (#6CYPK)
Rick is supporting a Magento-based e-commerce site. As many such sites, it uses a lot of third party plugins. One of those third party plugins wants to make sure no one "steals" its code, and thus obfuscates the code.
|
by Remy Porter on (#6CX7H)
C. Wiles has the "joy" of working on a SAS application for a large health insurance company. This snippet was extracted some time ago, but the application continues to live on. It has one job: pad the month part of dates to two digits. Let's see how it's done.
|
by Remy Porter on (#6CW80)
|
by Remy Porter on (#6CVBE)
Validating user input is one of those problems that's deceptively simple. The actual validation rules tend to be simple to describe: this field should be at least ten characters long, that field should match this regex, this one should be a number. But applying those rules can get cumbersome, especially when you write it yourself.It can quickly get as thorny and difficult as date handling.Well, Carole inherited some home-brew validation code. It's been running in the front-end of a web app for years.
|
by Lyle Seaman on (#6CSD8)
Hugops to Feedly who seem to have run into a snag this week.Feeder Brent N. fretted "Seems feedly's update isn't going well, with only 21 of 3 hours left to go."
|
by Remy Porter on (#6CRF3)
Andreas's employer recently upgraded their SQL Server databases to the latest version. During that upgrade, something went wrong, and performance dropped off a cliff. Applications which used to be merely slow to taking hours to query the data they required. Clearly, something was wrong in the upgrade process, but Andreas wasn't a DBA, so that wasn't specifically Andreas's problem. Instead, there were plenty of badly performing blocks of code- maybe now was the time to try and optimize them.That's where this block of Visual Basic comes from.
|
by Remy Porter on (#6CQFW)
Most (but clearly, not all) programmers have generally mastered the basic for loop. If you really want to separate the wheat from the chaff, ask them to write a for loop that counts by two, or three, or some other arbitrary number.That's what happened at J Banana's workplace, where they needed to parse in tokens from a config file. They come in key value pairs, so the code needs to count by twos. This was their solution:
|
by Remy Porter on (#6CPRX)
|
by Remy Porter on (#6CNY5)
Tina works for a major European government. During the height pandemic, her team needed to roll out many new sites to support remote, self-service interactions with government agencies.On one of these sites, they needed to create a contact form. The contact form was one of those that applied a character limit to the message. This character limit meant that the code needed to check the length of the input string, and then compare that against some max characters, and then output the "characters remaining" in an output field.
|
by Lyle Seaman on (#6CKX6)
I am ordinarily ambivalent about submissions of weirdstuff for sale at Amazon or elsewhere. They aren't greatError'd material; they're at worst an error in data. Buttoday I'm sharing two with you because they're just soridiculously funny that I think you'll get a kick out ofthem regardless.First, venerable memberThe Beast in Blackwants us to know that "Rubberbands can't fix everything" despite this fetching model who would have us believe otherwise. "PSA: DO NOT DO THIS!" He shouts, "if you're usingrubberbands to keep the gas tube attached to your AK-pattern rifle,you are about to have MUCH bigger problems."
|
by Remy Porter on (#6CK05)
Submitter "Anonymouse Lee" inherited a Pascal program that started its development back in 2002. It's seen some rough handling over the years, and that alone has bred some WTFs, but this particular block was created by the founder of the company, who bills themself as a "highly technical founder".The goal is this: the program needs to display a data grid, and depending on the recordType of each row in the grid, that row needs to be displayed slightly differently.Let's take a look at the code:
|
by Remy Porter on (#6CHXD)
Talking to external hardware is often hard. Especially niche hardware devices, which frequently have terrible documentation, bad APIs, and many undocumented quirks that can only be learned by working with them.For example, Sandra, still with InitAg frequently has to work with hardware. As Sandra puts it: "Most people tend to imagine agriculture as Farmer Bob and his tractor, these day's it's as much drones and high-precision GPS as it is tractors and manure." Which, the technological focus in agriculture is one of the key drivers of right to repair laws, but that's a whole different class of WTF.What needs to be repaired in today's story is one of Sandra's peers. They were writing code to interface with a hardware sensor on an agricultural device. Sandra omits the specifics, but the key details are that the device might be configured to have a left and right sensor, or it might have just one- either through configuration, debugging, or failure. Also, the vendor API wouldn't return the sensors in any particular order. The software needs to handle those scenarios, and then simply report a signal on the UI reflecting the sensor status.Now, one place to manage this would be to create some compartmentalized code, buried deep at a low level of the system, which handles and abstracts out all the hardware interfaces. Since it involves I/O, you'll also need to make sure that it doesn't block anywhere in the main loop while you're doing that. Wiring it up to the core software properly will likely involve some sort of message-oriented or event-based approach, probably wired into the message bus your complicated, multi-sensor hardware platform is already using, and is a super-standard approach for industrial hardware and robotics systems.The other place to manage it would be to just dump the code right in the middle of the main processing loop of your incredibly complex system, with fully synchronous I/O.
|
by Remy Porter on (#6CGRQ)
Jack's team was hiring a new web developer. As part of their interview process, they asked for some code samples- whether a public Github or just snippets to review. The goal isn't to be one of those companies that requires a super active Github history, but it's just helpful to get a sense of how someone approaches writing code before diving into some of the deeper interview challenges. No one has ever been disqualified for not being able to provide code, it just can streamline the interview process.As it turns out, it's also a pretty great filter for excluding candidates that probably shouldn't move on to the next round, or in this case, shouldn't be allowed to program at all.
|
by Remy Porter on (#6CFPX)
Don't write your own date functions. Don't write your own date functions. Erich sends us this beauty, which is meant to adjust a date based on the starting day of the week- which might be a day other than Sunday, for a variety of reasons.
|
by Lyle Seaman on (#6CDJE)
We had an unusual number (not that unusual, it was an integer) of interestingsubmissions this week; some were saved for special editions, some of the others follow.Ian C. obscured a part of his own unusual number, saying"New Scientist are taking the science a bit too far for your integer subscriber number."Just a case of better safe than sorry, or is that really a secret number, Ian?
|
by Remy Porter on (#6CCFB)
When I was young and dumb, my freshman year college CS program taught us Scheme. Now, thinking myself a rather accomplished C++ programmer by that point (I was not), I thought this was a bit of an insult. But I was still interested in learning new languages, so I chose to dabble in Perl.And I remember having the audacity to suggest to my professors that Scheme was a terrible introduction to programming, and instead we should start the students with an easy and accessible language, like Perl.As I said, I was young and dumb. Today's anonymous submitter was handed some Perl code from their senior developer. Let's take a look at what a real Perl master can do:
|
by Remy Porter on (#6CBAY)
At many a workplace, I've had the fortune to step into the company around when they were starting to get serious about standards, code quality, and generally pivoting into a mature development organization.When it comes to coding standards, everyone has strong opinions, though frankly consistency matters more than the standard itself. For example, with indenting, it doesn't really matter if you're doing Allman or something more K&R. Though we can all agree that anyone using [Whitesmiths] style has been hurt, and hurt deeply.Which brings us to today's code, from Christopher, which introduces an entirely new style: inverted.
|
by Remy Porter on (#6CA9N)
An eternal problem in programming is "empty strings are basically nulls, right?" Frequently, when someone hands us "", we know that represents "no value", and thus is basically null. Well, sometimes. Other times it's not. Tracking this chaos is a common source of bugs and WTFs.Martin's team had a problem in PHP. See, the is_null function is, well, checking for nulls. It isn't checking for empty strings. Being PHP, the empty function also doesn't check for empty strings, it checks for strings that can coerce to false (which includes the empty string, but also includes '0'). The "best" way in PHP to check for empty strings is just a direct comparison- $val == ''.That's awkward, so it's really good one of Martin's co-workers implemented a function that makes that easier to read:
|
by Remy Porter on (#6C9F5)
We return to Stefano Z, who once upon a time was a lowly junior developer surrounded by Very SmartTM and Very SeniorTM developers.Some of their code was written in a not-C language. It had to process many hundreds of millions of data points, and while it was fast, it wasn't fast enough. The senior devs had a solution: rewrite it in C, the fastest of all languages.The rewrite happened, and there was just one little problem: the performance was significantly worse, and it now crashed consistently. The senior developers had a solution for this, too: they blamed Stefano."Some of the code you wrote has to be breaking it, my code is highly optimized. Look at how few memory allocations it makes!"Let's walk through the highly optimized memory allocations for how this code serializes things. Let's start with a rough sketch of the structure they serialized:
|
by Lyle Seaman on (#6C7Z5)
BOINC, the Berkeley Open Infrastructure for Network Computing, is aproject to support public distributed computation, in service of efforts likeSETI@Home. Our reader Hans K. has a few grievances to share.First, Hans complained "I'm trying to add a BOINC project. Yes, I understand theconditions, just not which radiobutton I should choose.Although, with this one the next button is disabled,so I guess it's the other."
|
by Remy Porter on (#6C7Z6)
Today's anonymous submitter sends us some PHP exception logging code. This particular code shows a surprising understanding of some clever PHP tricks. Unfortunately, everything about it is still wrong.
|
by Remy Porter on (#6C7Z7)
Bitwise operations are one of those things that experienced developers find easy (if not intuitive), but are a fairly bad way to expose functionality without real careful design. After all, flags & 0x02 doesn't really mean much if you don't know what 0x02 is supposed to represent.But with named constants and careful thought, a bitmask can be a great way to pass flags around. At least, they can be if you understand how to use your language's bitwise operators.If you don't, then you end up writing this code, which Rensuka found many years ago.
|
by Remy Porter on (#6C7Z8)
Once upon a time, a company had several huge Delphi applications. These applications were pretty fundamental to company operations. And then those developers left, as they often do. Which means Darren has inherited multi-decade old Delphi code.Most of the problems in the code are structural. The average procedure itself is usually pretty okay, but the way they get strung together is an obscene nightmare of kruft. But this little snippet gives us a picture of what life is like here:
|
by Remy Porter on (#6C7Z9)
Eva's co-worker needed to strip the domain name off an email address, and then separate out the subdomains. The goal was that they wanted to be able to match foo.bar.com and bar.com as being the same domain.Now, for most of us, this would seem like a pretty straightforward application of a split function. If we're feeling like over-engineering it, we could break out a regex. (Please, don't use a regex for tasks like this)What we probably wouldn't want to do is this.
|
by Lyle Seaman on (#6C7ZA)
On a hazy evening, bookended by a pair of mouses, we bring you classic examples of the genre.The first Anon E. Mous with a better trap beat it straight to our door, crowing "I have to admit, 'Add a Catchy Header' is a pretty catchy header."
|
by Remy Porter on (#6C7ZB)
Johannes needed to convert some data from Base-36. A helpful peer offered this solution, which... works.
|
by Remy Porter on (#6C7ZC)
Twenty years ago, Stefano Z was a lowly junior developer, working with a set of senior developers, who had rules. A lowly junior developer, for example, couldn't be trusted to do something risky and dangerous, like serialize data to a buffer. Not without a safe API to keep them from foot-gunning themselves.The API interface went thus:
|
by Lyle Seaman on (#6BY4B)
Scraping the bottom of the barrel this week, we accepted a couple of submissions that aren't, by any means, Errors. But they're undoubtedly amusing to the likes of thosewho haunt these pages, and as such, bon appetit.Diner Dave A. wondered "I wasn't sure if you would really accept this as an Error'd,because it only *looks* like an error, which is why itcaught my eye, but it isn't! So, on with the snark:You'd think there'd be Null chance that someone wouldname a restaurant like this, right? But NO! (Or as YAMLwould say, Norway!) This really exists -- I haven't beenthere yet but at the very least its website isn't Null. Maybe two Nulls are like a double negative, making it positively exist?"It doesn't look very filling.
|
by Remy Porter on (#6BY4C)
We've already picked on bad logging code this week, but we haven't picked on PHP in awhile, so let's look at some bad PHP logging code, from Kris.
|
by Remy Porter on (#6BY4D)
Strings in C remain hard. They're complicated- they're complicated because of null termination, they're complicated because of memory management, they're complicated because of the behaviors of const. There's a lot going on in C strings.But Alice had a simple case: convert a true or false value into the string "true" or "false". Let's see how her co-worker solved this:
|
by Remy Porter on (#6BVTM)
The list of things never to write yourself contains some obvious stars: don't write your own date handling, your own encryption, your own authentication/authorization. It's not that no one should write these things, it's that these domains all are very complicated, require a great deal of specialized knowledge, and while easy to get almost correct, they're nearly impossible to get actually correct. If you embark on these tasks, it's because you want to create a product that solves these problems, hopefully not because you've got a terminal case of NIH syndrome.While it's not as big a star on the list, another domain you probably shouldn't try and solve yourself is logging. Today's anonymous submission isn't the worst home-grown logging I can imagine, but it's got enough bad choices in it to merit some analysis.
|
by Remy Porter on (#6BVTN)
Sami inherited some C# LINQ code. The actual behavior and purpose of this code is fairly simple. The way the code was written, however, well…
|
by Lyle Seaman on (#6BVTP)
We received a surfeit of submissions this week. The choices below were selected almost at random, but coincidentally two of them were sent in by regular reader Michael R. to start things off.Said Michael "Reading CodeSOD on 2023-05-15 made me brush up my knowledgeof log. Little did I know that it comes with its owndefects. Thank you Google."If you were a mathematician, and wanted to build a wooden table,what else would you use?
|
by Remy Porter on (#6BVTQ)
I've said many unkind things about ASP.Net WebForms in the past. While it leaves a lot to be desired as a web development environment, its event driven approach does map to a lot of folks understanding of software. Click a button, execute code in response. Change a radio button, execute code in response. A simple, easy to understand architecture.Well, sometimes simple and easy to understand.A number of years ago, Kyle was tasked with updating his employer's "benefits election" site for the new year, and found this:
|
by Remy Porter on (#6BVTR)
Krzysztof found themselves staring at a C++ function called intToString. And staring. And then realized that the function makes more sense if you don't look at the name. Let's take a peek:
|
by Remy Porter on (#6BVTS)
Normally, I wouldn't have much to say about a simple "it's a mere arithmetic error" type of code sample. But this submission from Taylor adds an important factor: it's a basic arithmetic mistake in date handling code, in a legacy product that's been in use for decades. Oh, and it's written in Delphi.
|
by Remy Porter on (#6BVTT)
Denise was supervising a developer who encountered a difficult problem: string handling in C. It's not particularly fun to work with strings in C, but it's certainly feasible.One of the key issues for strings is that you need to know how large the string is going to be so you can allocate a buffer for it. And while there's a strlen, there is no intlen, so when you want to turn a number into a string, you're faced with a branching path.The first path, would be to simply remember your logarithms from high school and know that the log10 of a number tells you how many digits (in base 10) it holds.The second path would be to learn how to use the printf family of functions, and let the C standard solve that problem for you.The third path would be to do this:
|
by Lyle Seaman on (#6BVTV)
Friday comes but once a week, so perhaps you should read this column very very slowly to make it last.Disoriented David declared "I legitimately was confused while reading this because I got my days of theweek mixed up. Too bad they couldn't tell me."
|
by Remy Porter on (#6BNMF)
Emma X maintains some software for a company that does mechanical engineering. In this specific case, her software needs to match a part on their equipment to a tube which can hold the part. They're operating on the order of millimeters, so the smallest tube is about 8mm, and the largest is 155mm.Now, obviously, not every possible millimeter size is possible- from 8mm to 58mm, the possible diameters all proceed at a step of 2mm. Between 60mm and 95mm, the step is 5mm, and between 100 and 150, the step is 10mm. As I describe this problem, you're probably imagining a lookup table of some kind, or maybe just a list of possible diameters generated by for loops or some similar construct. If that were how this worked, the code wouldn't be there.
|
by Remy Porter on (#6BMBA)
Ellen sends us a very simple WTF today, that she found in production code.
|
by Remy Porter on (#6BK5S)
Jeremy found this VB.Net code. It has a simple job: return a file back to the client, but with a twist: they don't know what the correct file extension is. So this was their solution for that problem:
|
by Remy Porter on (#6BHYV)
Many years ago, Matt left a position where he developed in FORTRAN, and went off to do other things. The company hired a replacement, and since no one else really understood FORTRAN, they assumed things were fine. Over the course of a decade, their development costs got more expensive, their software got buggier, and deadlines started flying by without a single new feature being released. It took a long time, but they eventually fired Matt's replacement. Since Matt was looking for a new position around that time, he ended up back in the FORTRAN shop: just when he thought he was out, they pulled him back in.Matt started going through the code that'd been implemented, and… well, here's an example function signature:
|
by Lyle Seaman on (#6BFJW)
With your weekly dose of snark, and just one execrable pun, here follows Error'd:A reader who asked to remainVery Anonymous sent us this suicide note for his reputation."Somehow, lyrics.com could get the right photo (fromWikipedia, it seems) of the country singer StonewallJackson, but ended up with the Confederate general's bio.PS: Please don't ask or judge me as to why I was looking for the lyrics toJesus Took The Outlaw Out Of Me." I'm sure we really don't want to know.
|
by Remy Porter on (#6BECQ)
Python is a language underpinned by a philosophy about how programming should work. It's opinionated. As a result, in the Python world, you'll hear constant debates over what is and is not "Pythonic", and you'll encounter all the weird ways in which the Python philosophy and real-world programming needs conflict: for example, you don't use switch statements in Python, you put callable functions in a dict instead.I bring that case up, specifically, because Python's philosophy is that there should be one correct way to do everything: since if statements handle branches, switch statements are unnecessary. Ternaries are also unnecessary by that rule- but they exist and Python has its own twist on them.In Python, you can do something like:
|