by Alex Papadimoulis on (#5JFG7)
The Daily WTF
Link | http://thedailywtf.com/ |
Feed | http://syndication.thedailywtf.com/TheDailyWtf |
Updated | 2024-11-22 03:01 |
by Lyle Seaman on (#5JCES)
In this process of collecting your submissions, the single most commoncategory has been string conversions of NaN, null, and undefined. They areso common, I've become entirely bored with them. Date conversions, however,still do amuse a bit. Or will do. Or will did? Will have did? In any case,here's another installment of wibbly bits. They may not be clever, but someare a little funny.Competitive programmer Laks may have got the answer technicallyincorrect, but he did it REALLY fast. Shouldn't he have won on speed?Says Laks "It turns out you can implement flux capacitor in software."
by Remy Porter on (#5JAXZ)
In functional programming languages, you'll frequently see some variation of the car/cdr operations from LISP. Given a list, these functions can split it into the head (or first element) of the list, and the tail (the rest of the list). This is often used to traverse a list recursively: function f performs an operation on the head of the list, and then recursively calls f on the tail of the list.I bring this up because we're talking about C# today. C# has plenty of fun functional programming features, and you can certainly use them to write very clean, comprehensible code. Or, like Nico's co-worker, you could do something like this.
by Remy Porter on (#5J9DE)
Ali was working on an app for a national government. The government provided its own mapping API for its own custom mapping services. It did not provide any documentation, and the only "sample" code was hitting "view source" on an existing map page on the government's websites.Ali writes: "I was going through their own implementations, looking for something that would help, when I stumbled upon this gem. I think it speaks for itself, no?"
by Remy Porter on (#5J7WQ)
There are times when performance absolutely matters. And the tech lead that Janell was working with (previously) was absolutely certain that their VB.Net project needed to be "designed for performance". Performance was so important that in the final design, they used a home-brewed JSON database (which, at its lowest level, was just a JSON file on disk), and it took 7 round-trips to their home-brewed database to read a single record.Despite all this attention on performance, the system had a memory leak! As we've covered in the past, garbage-collected languages can have leaks, but they may take a little more effort than the old-school versions. Janell fired up a debugger, looked at the memory utilization, and started trying to figure out what the problem was.The first thing Janell noticed was that there were millions of WeakReference objects. A WeakReference can hold a reference to an object without preventing garbage collection. This is the sort of thing that you might use to prevent memory leaks, ensuring that objects get released.A little more poking revealed two layers to the problem. First, every business object in the application inherited from BaseObject. Not the .NET object type that's the base class for all objects, but a custom BaseObject. Every class had to inherit from BaseObject.
by Jane Bailey on (#5J6G7)
The year was 2001: the year before many countries in the EU switched from using their national currency to the new euro. As part of the switch, many financial software packages had to be upgraded. Today's submitter, Salim, was hired as an IT support staffer in a medium-sized healthcare organization in the Netherlands. While Salim had a number of colleagues, they had to support a greater number of small satellite offices, and so on occasion any of them would be left to hold the main office alone. It just so happened that Salim's first solo day was the day they were testing the software upgrade, with the CFO himself executing the test.The manager of IT had prepared well. Every aspect of the test had been thought through: the production server had been cloned into a fresh desktop computer, placed in the server room, set apart from the other servers so that the CFO wouldn't accidentally touch the production server. To make it stand out, rather than a rack they'd placed the computer on one of those thin little computer desks that were in fashion at the time, a little metal contraption with a drawer for the keyboard and wheels so it could be moved. The setup got an office chair and a phone, for comfort and so that the CFO could summon help if needed. The CFO had been given step-by-step instructions from the software vendor, which he and the manager had gone over ahead of time. All the bases were covered. Hopefully.Early in the morning the day of the test, the CFO walked to the support desk and asked for access to the server room. Salim walked him to the room, unlocked the door for him, and pointed him to the computer desk. Before he left, he pointed out the phone and gave the CFO his direct extension in case anything went wrong. The CFO thanked him, and Salim left him to it.No sooner had he sat down than the call came: the CFO asking for help. Although he had a good deal of general IT knowledge, Salim hadn't personally inspected any of the instructions and didn't know much about the software. So he walked back to the server room, anxiety growing.Arriving in the server room, Salim found the CFO standing next to the computer desk. Salim sat down, pulled the keyboard out from under the monitor, and flicked on the screen. Summoning up his most professional voice, he asked, "Right, how can I help?""Ah ... thanks," came the reply. "I can manage from here."Salim writes: "To this day, I do not know if his problem was not being able to find the keyboard, or switch on the monitor." [Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.
by Lyle Seaman on (#5J3GZ)
Baby Boomer Eric D. accidentally shares the prototypical Gen Xexperience, this time via Pella windows. "I guess I can't actually buy stuffbecause I'm in the unlucky 55-64 age band." Welcome to irrelevance, Eric!
by Remy Porter on (#5J1XZ)
Have you ever needed to prune an order line? Y'know, prune them. This is an entirely common operation you do on orders all the time, and requires absolutely no context or explanation. There's absolutely no chance that you might need to wonder, exactly what is being pruned.Bartholomew A. was a little bit confused by the prune method in the codebase. Fortunately, reading through the code makes everything clear:
by Remy Porter on (#5J0D5)
There was an era where UI designer tools output programmatic code representing that UI. So, say, if you were dragging and dropping objects in the Windows Forms designer in Visual Studio, the output would be C# code. Now, the designer would have some defaults. When you added a new button, it might identify it as button15. Of course, you wouldn't leave that name as it was, and you'd give it a meaningful name. That name would then become the property name of that field in the class generated by the designer.Well, you might give it a meaningful name. Gormo inherited some Windows Forms code, which challenges the meaning of "meaningful names".
by Remy Porter on (#5HYTM)
When I was a baby programmer, I subscribed to a computer magazine. In those olden times, these magazines would come with pages of program code, usually BASIC, so that you could type this program into your computer and run it. If you were careful about typos, you could accomplish quite a bit of "programming" without actually programming. What you were doing, in practice, was just typing.One of Anthony's predecessors was quite the accomplished typist.They needed to take the built-in .NET XmlDocument class and add a one method to it. Now, C# offers a few techniques for doing this. The "traditional" object-oriented approach is to use inheritance. Now, that's not without its downsides, so C# also has the concept of "extension methods". This is a little bit of syntactic sugar, which allows you to declare static method that takes a parameter of XmlDocument, but invoke it as if it were an actual instance method. Of course, depending on what you're doing, that might not give you all the functionality you need. And outside of those techniques, there are a number of the good-ol' Gang of Four design patterns, like the Visitor pattern which could solve this problem without loads of complexity. Or even just "a plain old static method" might fit.But Anthony's predecessor didn't want to do any of those. They instead chose to use typing.
by Remy Porter on (#5HXAE)
John's employer needed a small web app built, so someone in management went out and hired a contracting firm to do the work, with the understanding that once it was done, their own internal software teams would do maintenance and support.Fortunately for John's company, their standard contract included a few well-defined checkpoints, for both code quality audits and security audits. It's the last one that's relevant in this case.There are three things you should never build for your application: date handling logic, encryption algorithms, or authentication mechanisms. These are all things that sound simple on the surface, but are actually quite difficult. You will mess them up, and you'll regret it. What's remarkable here, however, is seeing how badly one can mess up authentication:
by Lyle Seaman on (#5HT8Y)
Paul M. identifies an online vendor who isn't at all afraid of the bold ask. But he demurs. "Uh, I think I'll stick with the sale price thanks."
by Amit Kooner on (#5HRWS)
Basecamp Management Somehow Less Self-Aware Than Andrew YangIn the lead-up to the Chappelle Show sketch ‘When Keepin’ It Real Goes Wrong’, Dave Chappelle gives the following pretty great advice:“It’s good to be real sometimes. It’s good to be phony sometimes. Yes, I said it. Phony! You think I’m this nice in real life? F$ck that son!”We tend to stay real with the people when we benefit from telling the truth to them and hearing the truth from them, while we stay phony when we feel that we benefit from emotional investment.Take a second to do an exercise splitting society into those that you should be “real” to/with and those that you should stay “phony” to/with. Here’s my take: Be Real (to and with) Stay Phony (to and with) Parents, Spouses, Young Children*, Teenagers Extended Family Healthcare Workers Celebrities + Self-Promoters Political candidates (someone desperately needs to get real with Andrew Yang) Elected Officials + Business Leaders Co-workers Bosses + Management (In Venkatesh Rao’s amazing six-part Gervais Principle breakdown of ‘The Office’ and management, he would argue that there lies a third column of people who think they are Real but actually Phony. It’s seriously worth your time to read the full piece. But for simplicity sake, I will keep these two columns.)So where am I going with all this? Let’s talk about Basecamp.First, the definition of a ‘basecamp’ is the following: a main encampment providing supplies, shelter, and communications for persons engaged in wide-ranging activities, as exploring, reconnaissance, hunting, or mountain climbing. What does a company who builds project management and communications tools, who changed their name from 37 Signals in 2014, have to do with adventure sports? Unclear.Second, Basecamp had ~60 employees as of two weeks ago, but has written 5 books on management (!!). Basecamp must have the highest books written per employee rate of any company in history.Oh yeah and third, management decided to get real with their employees by setting up a company-wide meeting to discuss banning political discussion in the office and ⅓ of their employees immediately accepted buyouts afterwards.There are a lot of extremely smart pieces of the lead-up and aftermath of the debacle, so I recommend reading Casey Newton’s full piece at Platformer, Charlie Warzel’s piece at Galaxy Brain, and Vice’s piece.But here’s simple take:
by Remy Porter on (#5HQS2)
If you go by the popular press articles on the tech field, anyone who's anyone has migrated into the "machine learning" space. That's where all the "smart" programmers go.Of course, ML is really just statistics and automated model fitting. It's a powerful tool, and it does require some highly specialized skills- skills that might involve programming, but maybe don't quite overlap with programming.Noreen inherited some code from a highly-paid contractor who specializes in doing machine learning. The HPC put together an ML system capable of generating all sorts of useful output, output which the users at Noreen's company wanted compiled into nice PDFs. The HPC, being a very busy ML consultant who billed $300/hr didn't want to build this, so they subcontracted out to different HPC, who also was in the ML space, but billed at $200/hr.The result is about 500 lines of Python script, in one large Python file. There's no real organization, no clear entry point, and all sorts of… interesting choices. Let's start with the very first method:
by Remy Porter on (#5HPPT)
When RJ was trawling through some SQL Server stored procedure code, they spotted this line:
by Remy Porter on (#5HNAZ)
For those looking to get into software development, there's never been more access to tutorials, guides, training programs, and communities of developers ready to foster those trying to get started.Unfortunately, you've got folks that think because they've written a few websites, they're ready to teach others, and write up their own tutorials without having the programming background or the educational background to effectively communicate best practices to the public.A few years back, Rob Speed was poking at a course calling itself "JavaScript Best Practices". One slide, quite correctly, warned: "If numerical data comes from a form, it may appear as a string. Parse the data before performing validation." And, by way of example, it supplied this code, for parsing postal codes:
by Lyle Seaman on (#5HJ9Z)
With all the investments that have recently been made instatistical/brute-force methods for simulating machineintelligence, it seems that we may at least at last haveachievedthe ability to err like a human.Patient Paul O. demonstrates that bots don't work well before they've hadtheir coffee any more than humans do. "I spent 55 minutes on this chat, most of it with a human in the end, although they weren't a lot brighter than the bot."
by Remy Porter on (#5HGNP)
Sometimes bad code arises from incompetence, whether individual, or more usually institutional. Sometimes it's overly tight deadlines, misguided architecture. And sometimes… it's just the easiest way.Naomi writes in to confess to some bad code.
by Remy Porter on (#5HF1K)
Unit testing in C offers its own special challenges. Unit testing an application heavily dependent upon threads, written in C, offers even more.Brian inherited an application where the main loop of the actual application looked something like:
by Remy Porter on (#5HDG1)
Shipping meaningful data from one company's IT systems to another company's IT systems is one of those problems that's been solved a billion times, with entirely new failure modes each time. EDI alone has a dozen subspecifications and allows data transfer via everything ranging from FTP to email.When XML made its valiant attempt to take over the world, XML schemas, SOAP and their associated related specifications were going to solve all these problems. If you needed to communicate how to interact with a service, you could publish a WSDL file. Anyone who needed to talk to your service could scrape the WSDL and automatically "learn" how to send properly formatted messages. The WSDL is, in practice, a contract offered by a web service.But the WSDL is just one mechanism to provide a specification for software. Which brings us to Patrick.Patrick needed to be able to transmit financial transactions from one of their internal systems to a vendor in France. Both parties discussed the requirements, what specific fields needed to be sent, how, what they actually meant, and hammered out a specification document that confirmed their understanding. It would be a SOAP-based web service, and the French team would be implementing it on their end."Great," Patrick said in one of their meetings. "Once you've got the interface defined according to our specification, you should send us the WSDL file."The next day, they received a WSDL file. It was a "hello world" file, autogenerated for a stub service with one method- helloWorld."That isn't what we're expecting," Patrick emailed back. "Could you please send us a WSDL which implements the spec?"The next day, Patrick got a fresh WSDL. This one looked vaguely like the specification, in that some of the methods and fields were named correctly, but half of them were missing."We don't need to rush this," Patrick said, "so please review the specification and ensure that the WSDL complies with the specification we agreed to."Two days later, Patrick got a "hello world" WSDL again, followed by a WSDL for a completely unrelated web service.Over the next few weeks, the vendor team produced a steady stream of WSDL files. Each was incorrect, sometimes wildly off target, sometimes simply missing a few fields. One Thursday, seemingly by accident, the vendor team sent a correct WSDL, and immediately followed up with another one missing half the key fields.Eventually, they send a WSDL that more-or-less matched the spec, and stopped trying to "fix" it. Development on both sides progressed, at the glacial pace that any enterprise integration project goes. Development happened less often than meetings, and milestones slid by at an absolutely glacial pace.But even glaciers move. So the day came for the first end-to-end test. Patrick's team sent a SOAP request containing a valid transaction.They got no response back.Patrick got his opposite number in France, Jean, on the phone, and explained what he was seeing."No," Jean said. "I can see that you are sending requests, but your requests are empty.""We are not sending empty requests," Patrick said."Apologies, but yes, you are."Patrick's team set up logging and tracked every outgoing request, and its payload. They manually validated it against the WSDL. They programatically validated it against the WSDL.Patrick went back to Jean with his evidence."No, the problem must be on your side.""Well, I've provided my logs," Patrick said. "What logging are you getting on your side? Maybe something in the middle is messing things up?""One moment," Jean said. Patrick listened to him typing for a bit, and then some puzzled mumbling. Then a long stretch of silence."Uh, Jean?"The silence stretched longer."You still there?""Oui," Jean said, distantly. "I… ah, I cannot find the logs. Well, I can find logs, just not, the logs for this service. It appears it is not installed on our test server.""You… didn't install it? The thing we're explicitly testing? It's not installed.""Yes. I do not have permissions to release that code. I'll have to set up a meeting."They aborted the test that day, and for many days thereafter. When they did finally test, the vendor team deployed an old version, with a "hello world" WSDL. Eventually, the customer that requested this integration got frustrated with waiting, and switched to a different set of vendors that could actually communicate with each other. To this day, that test server is still probably running with a "hello world" WSDL. [Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!
by Remy Porter on (#5HC7F)
Much of the stories and code we see here are objectively bad. Many of them are bad when placed into the proper context. Sometimes we're just opinionated. And sometimes, there's just something weird that treads the line between being an abuse of code, and almost being smart. Almost.Nic was debugging some Curses-based code, and found this "solution" to handling arrow key inputs:
by Lyle Seaman on (#5H8WG)
We are all hopeful that there might be some cause for tentative optimism regarding the eventual end of coronavirus pandemic. But horror fan Adam B. has dug up a new side effect that may upend everything.
by Remy Porter on (#5H76C)
Many years ago, I worked for a company that mandated that information like user credentials should never be stored "as plain text". It had to be "encoded". One of the internally-developed HR applications interpreted this as "base64 is a kind of encoding", and stored usernames and passwords in base64 encoding.Steven recently encountered a… similar situation. Specifically, his company upgraded their ERP system, and reports that used to output taxpayer ID numbers now outputs ~201~201~210~203~… or similar values. He checked the data dictionary for the application, and saw that the taxpayer_id field stored "encrypted" values. Clearly, this data isn't really encrypted.Steven didn't have access to the front-end code that "decrypted" this data. The reports were written in SSRS, which allows Visual Basic to script extensions. So, with an understanding of what taxpayer IDs should look like, Steven was able to "fix" the reports by adding this function:
by Remy Porter on (#5H5JZ)
Pierre inherited a PHP application. The code is pretty standard stuff, for a long-living PHP application which has been touched by many developers with constantly shifting requirements. Which is to say, it's a bit of a mess.But there's one interesting quirk that shows up in the codebase. At some point, someone working on the project added a kinda stock way they chose to handle exceptions. Future developers saw that, didn't understand it, and copied it to just follow what appeared to be the "standard".And that's why so many catch blocks look like this:
by Remy Porter on (#5H3ZD)
At a certain point, it becomes difficult to write a unit test without also being able to provide mocked implementations of some of the code. But mocking well is its own art- it's easy to fall into the trap of writing overly complex mocks, or mocking the wrong piece of functionality, and ending up in situations where your tests end up spending more time testing their mocks than your actual code.Was Rhonda's predecessor thinking of any of those things when writing code? Were they aware of the challenges of writing useful mocks, of managing dependency injection? Or was this Java solution the best they could come up with:
by Remy Porter on (#5H2DQ)
Josh's company hired a contracting firm to develop an application. This project was initially specced for just a few months of effort, but requirements changed, scope changed, members of the development team changed jobs, new ones needed to be on-boarded. It stretched on for years.Even through all those changes, though, each new developer on the project followed the same coding standards and architectural principles as the original developers. Unfortunately, those standards were "meh, whatever, it compiled, right?"So, no, there weren't any tests. No, the code was not particularly readable or maintainable. No, there definitely weren't any comments, at least if you ignore the lines of code that were commented out in big blocks because someone didn't trust source control.But once the project was finished, the code was given back to Josh's team. "There you are," management said. "You support this now."Josh and the rest of his team had objections to this. Nothing about the code met their own internal standards for quality, and certainly it wasn't up to the standards specified in the contract."Well, yes," management replied, "but we've exhausted the budget.""Right, but they didn't deliver what the contract was for," the IT team replied."Well, yes, but it's a little late to bring that up.""That's literally your job. We'd fire a developer who handed us this code."Eventually, management caved on documentation. Things like "code quality" and "robust testing" weren't clearly specified in the contract, and there was too much wiggle room to say, "We robustly tested it, you didn't say automated tests." But documentation was listed in the deliverables, and was quite clearly absent. So management pushed back: "We need documentation." The contractor pushed back in turn: "We need money."Eventually, Josh's company had to spend more money to get the documentation added to the final product. It was not a trivial sum, as it was a large piece of software, and would take a large number of billable hours to fully document.This was the result:
by Lyle Seaman on (#5GZ8G)
Waiting for his wave to collapse, surfer Mike I.harmonizes "Nice try Power BI, but you're not doing quantum computing quite right." Or, does he?
by Remy Porter on (#5GXNH)
When you look at bad code, there's a part of your body that reacts to it. You can just feel it, in your spleen. This is code you don't want to maintain. This is code you don't want to see in your code base.Sometimes, you get that reaction to code, and then you think about the code, and say: "Well, it's not that bad," but your spleen still throbs, because you know if you had to maintain this code, it'd be constant, low-level pain. Maybe you ignore your spleen, because hey, a quick glance, it doesn't seem that bad.But your spleen knows. A line that seems bad, but mostly harmless, can suddenly unfurl into something far, far nastier.This example, from Rikki, demonstrates:
by Amit Kooner on (#5GW2G)
Let’s quickly recap the past three news roundups:
by Remy Porter on (#5GTDX)
Universally Unique Identifiers are a very practical solution to unique IDs. With 10^30 possible values, the odds of having a collision are, well, astronomical. They're fast enough to generate, random enough to be unique, and there are so many of them that- well, they may not be universally unique through all time, but they're certainly unique enough.Right?Krysk's predecessor isn't so confident.
by Remy Porter on (#5GRWM)
Imagine you were browsing a C++ codebase and found a signature in a header file like this:
by Lyle Seaman on (#5GNPM)
After reading through so many of your submissions these last few weeks,I'm beginning to notice certain patterns emerging. One of these patterns isthat despite the fact that dates are literally as old as time, people seem pathologically prone to bungling them. Surely our readers are already familiar with the notable "Falsehoods Programmers Believe" series of blog posts, but if you happen somehow to have been living under an Internet rock (or a cabbage leaf) for the last few decades, you might start your time travails at Infinite Undo.The examples here are not the most egregious ever (there are better coming later or sooner) but they are today's:Famished Dug S. peckishly pronounces "It's about time!"
by Remy Porter on (#5GM6X)
Steven was working on a temp contract for a government contractor, developing extensions to an ERP system. That ERP system was developed by whatever warm bodies happened to be handy, which meant the last "tech lead" was a junior developer who had no supervision, and before that it was a temp who was only budgeted to spend 2 hours a week on that project.This meant that it was a great deal of spaghetti code, mashed together with a lot of special-case logic, and attempts to have some sort of organization even if that organization made no sense. Which is why, for example, all of the global constants for the application were required to be in a class Constants.Of course, when you put a big pile of otherwise unrelated things in one place, you get some surprising results. Like this:
by Remy Porter on (#5GJJV)
When Andy inherited some C# code from a contracting firm, he gave it a quick skim. He saw a bunch of methods with names like IsAvailable or CanPerform…, but he also saw that it was essentially random as to whether or not these methods returned bool or string.That didn't seem like a good thing, so he started to take a deeper look, and that's when he found this.
by Remy Porter on (#5GH10)
Writing code that is reusable is an important part of software development. In a way, we're not simply solving the problem at hand, but we're building tools we can use to solve similar problems in the future. Now, that's also a risk: premature abstraction is its own source of WTFs.Daniel's peer wrote some JavaScript which is used for manipulating form inputs on customer contact forms. You know the sorts of forms: give us your full name, phone number, company name, email, and someone from our team will be in touch. This developer wrote the script, and offered it to clients to enhance their forms. Well, there was one problem: this script would get embedded in customer contact forms, but not all customer contact forms use the same conventions for how they name their fields.There's an easy solution for that, involving parameterizing the code or adding a configuration step. There's a hard solution, where you build a heuristic that works for most forms. Then there's this solution, which… well…. Let me present the logic for handling just one field type, unredacted or elided.
by Remy Porter on (#5GFF8)
Andres noticed this pattern showing up in his company's code base, and at first didn't think much of it:
by Lyle Seaman on (#5GCCK)
Today's Error'd submissions are not so much WTF as simply "TF?" Please try to explain the thought process in the comments, if you can.Plaid-hat hacker Mark writes "Just came across this for a Microsoft Security portal.Still trying to figure it out." Me, I just want to know what happens when you click "Audio".
by Remy Porter on (#5GAW1)
Chuck had some perfectly acceptable C# code running in production. There was nothing terrible about it. It may not be the absolute "best" way to build this logic in terms of being easy to change and maintain in the future, but nothing about it is WTF-y.
by Remy Porter on (#5G976)
Code, like anything else, ages with time. Each minor change we make to a piece of already-in-use software speeds up that process. And while a piece of software can be running for decades unchanged, its utility will still decline over time, as its user interface becomes more distant from common practices, as the requirements drift from their intent, and people forget what the original purpose of certain features even was.Code ages, but some code is born with an expiration date.For example, at Jose's company, each year is assigned a letter label. The reasons are obscure, and rooted in somebody's project planning process, but the year 2000 was "A". The year 2001 was "B", and so on. 2025 would be "Z", and then 2026 would roll back over to "A".At least, that's what the requirement was. What was implemented was a bit different.
by Remy Porter on (#5G7PQ)
Today's code is only part of the WTF. The code is bad, it's incorrect, but the mistake is simple and easy to make.Lowell was recently digging into a broken feature in a legacy C application. The specific error was a failure when invoking a sed command from inside the application.
by Remy Porter on (#5G6AK)
Many years ago, Kari got a job at one of those small companies that lives in the shadow of a university. It was founded by graduates of that university, mostly recruited from that university, and the CEO was a fixture at alumni events.Kari was a rare hire not from that university, but she knew the school had a reputation for having an excellent software engineering program. She was prepared to be a little behind her fellow employees, skills-wise, but looked forward to catching up.Kari was unprepared for the kind of code quality these developers produced.First, let's take a look at how they, as a company standard, leveraged C++ templates. C++ templates are similar (though more complicated) than the generics you find in other languages. Defining a method like void myfunction<T>(T param) creates a function which can be applied to any type, so myfunction(5) and myfunction("a string") and myfunction(someClassVariable) are all valid. The beauty, of course, is that you can write a template method once, but use it in many ways.Kari provided some generic examples of how her employer leveraged this feature, to give us a sense of what the codebase was like:
by Lyle Seaman on (#5G3DP)
“Some people,” said the sage, “are lucky enough to also have a completely separate environment for production.” Today's nuggets of web joy are pudding-proof. Hypothetically hypochondriac STUDENTS[$RANDOM] gasped “I tried to look up information about Covid tests at the institution. Instead I found…this.”
by Remy Porter on (#5G1WV)
Totally Fungible Tokens NFTs, or non-fungible tokens, are an exciting new application of Blockchain technology that allows us to burn down a rainforest every time we want to trade a string representing an artist's signature on a creative work. Many folks are eagerly turning JPGs, text files, and even Tweets into NFTs, but since not all of us have a convenient rainforest to destroy, The Daily WTF is happy to offer at alternative, the Totally Fungible Token What Is a Totally Fungible Token? A TFT is a unique identifier which we can generate for any file or group of files. It combines the actual data in the file(s) with a Universally Unique Identifier, and then condenses that data using a SHA-256 hashing algorithm. This guarantees that you have a unique token which represents that you have created a unique token for that data. How is this better than an NFT? There are a few key advantages that TFTs offer. First, they're computationally very cheap to make, allowing even a relatively underpowered computer participate actively in the token ecosystem. In addition, this breaks all dependencies on the blockchain, meaning that you don't need to use or spend cryptocurrency to create, purchase, or trade these tokens. Most important: much like NFTs, a TFT is absolutely worthless, but we're not promoting these as some sort of arcane investment instrument, so there won't be any sort of bubble. The value of your TFT will remain essentially zero, for the entire life of your TFT. There is no volatility. In the interests of efficiency, this also performs terribly on large files. How big is too big? That depends on your browser! Enjoy finding out what's too big to encode! Generate a TFT Use the button below to browse for a file on your computer, and this will generate a unique token showing that you generated a unique token. Feel free to share, sell, or trade these tokens with your friends! No information about your files is in the token, so it's guaranteed to be completely meaningless! Give it away, sell it, just write it down on a napkin, your TFT is yours to use as you please! Token: Grab the source and tweak the algorithm yourself!. Also, for convenience, there's a dedicated TFT page which, long term, is probably a better tool than this article, since you'll be wanting to play with TFTs for a long time yet, I imagine.Potential optimizations include: streaming the file conversion so we don't have to have the whole thing in memory, or just replacing all of this with a random number, which would likely be just as good.The TFT for the tft generator code is tft.js;dbbbf23d24502dba96913f18fa031203977b48db090a4a52ff6258a2c3bceecc, so enjoy! [Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.
by Remy Porter on (#5G0DM)
Query strings are, as the name implies, strings. Now, pretty much any web application framework is going to give you convenient access to the query string as a dictionary or map, because at the end of the day, it is just key/value pairs.But what's the fun in that? Glen's application needed to handle query strings in the form: zones=[pnw,apac]&account_id=55. Now, enclosing the list in square brackets is a little odd, but actually makes sense when you see how they parse this:
by Remy Porter on (#5FYMA)
An anti-pattern I've seen too many times is using display text to drive logic. For example, I've see things like:
by Jane Bailey on (#5FXFV)
There are often two types of software development departments mentioned: the kind where software is the product, and the kind where software enhances or sells the product. ChemCo is a third type: a physical chemistry lab, one with extensive customization of lab setups and computer-controlled devices that need to be programmed, as well as a need for statistics and simulations to handle the results. The team includes one C/LabVIEW magician, one Octave specialist, one Java developer, and one Python scripter. Therefore, most of the computer-controlled setups have LabVIEW GUIs and C DLLs for the logic, though some have Python over top of the DLLs instead.The year is 2016, and ChemCo has just bought a new signal generator. The team's newest engineer, one who knows only Perl, Octave, and R, is tasked with writing a DLL that can be called from their LabView application to control the generator. Faced with learning either C or C++, he chooses C because "the K&R is less than 300 pages while Prata has more than 1200."The device speaks SCPI, but since ChemCo has a real problem with Not Invented Here syndrome, the new guy writes the library from scratch. During the period that follows, he discovers:
by Lyle Seaman on (#5FTFE)
No loops, no branches, barely a pun and almost free of alliteration.Big-box shopper Worf discovers"This Chromebook's screensaver crash might be Truth In Advertising."
by Remy Porter on (#5FS0P)
Dan was reviewing some PHP code written by a co-worker, as part of taking on a project. The code was in “support” mode, rarely receiving changes, getting bug fixes only when absolutely necessary, and nobody really wanted to be the person responsible for it.One of those “not absolutely necessary” bugs was that sometimes, it just didn’t save data. The user would enter a product listing, hit save, get a success message back, but the listing wouldn’t actually be saved. No one had really dug into it, because having the end user do double data entry didn’t bother anyone but the end user.While thinking about that, Dan found this:
by Remy Porter on (#5FQKT)
Imagine, if you will, that you see a method called FileExists. It takes a string input called strPath, and returns a bool. Without looking at the implementation, I think you'd have a very good sense of what it's supposed to do. Why, you wouldn't even expect much documentation, because the name and parameters are really clear about what the method actually does.Unless this method was in the C# codebase "AK" inherited. In that case, the behavior of FileExists might surprise you:
by Remy Porter on (#5FP9H)
Today's sample comes from Vasiliy, with no real explanation for where it is, or where it comes from. Frankly though, it doesn't need much setup.