|
by TJ Mott on (#338WZ)
One of the major goals of many software development teams is to take tedious, boring, simplistic manual tasks and automate them. An entire data entry team can be replaced by a single well-written application, saving the company money, greatly improving processing time, and potentially reducing errors.That is, if it’s done correctly.Peter G. worked for a state government. One of his department’s tasks involved processing carbon copies of forms for most of the state’s residents. To save costs, improve processing time, and reduce the amount of manual data entry they had to perform, the department decided to automate the process and use optical character recognition (OCR) to scan in the carbon copies and convert the handwritten data into text which was eventually entered into a database.By By Aaron Logan
|
The Daily WTF
| Link | http://thedailywtf.com/ |
| Feed | http://syndication.thedailywtf.com/TheDailyWtf |
| Updated | 2025-12-09 14:32 |
by Remy Porter on (#335DR)
Chris M works for a “solutions providerâ€. Mostly, this means taking an off-the-shelf product from Microsoft or Oracle or SAP and customizing it to fit a client’s specific needs. Since many of these clients have in-house developers, the handover usually involves training those developers up on the care and maintenance of the system. Then, a year or two later, the client comes back, complaining about the system. “It’s broken,†or “performance is terrible,†or “we need a new featureâ€. Chris then goes back out to their office, and starts taking a look at what has happened to the code in his absence.It’s things like this:
by Mark Bowytz on (#32WZA)
"I'm not sure how I can give feedback on this course, unless, figuring out this matrix is actually a final exam," wrote Mads.
|
by Charles Robinson on (#32SEJ)
James was getting anxious to land a job that would put his newly-minted Computer Science degree to use. Six months had come to pass since he graduated and being a barista barely paid the bills. Living in a small town didn't afford him many local opportunities, so when he saw a developer job posting for an upstart telecom company, he decided to give it a shot.We do everything in-house! the posting for CallCom emphasized, piquing James' interest. He hoped that meant there would be a small in-house development team that built their systems from the ground up. Surely he could learn the ropes from them before becoming a key contributor. He filled out the online application and happily clicked Submit.Not 15 minutes later, his phone rang with a number he didn't recognize. Usually he just ignored those calls but he decided to answer. "Hi, is James available?" a nasally female voice asked, almost sounding disinterested. "This is Janine with CallCom, you applied for the developer position."Caught off guard by the suddenness of their response, James wasn't quite ready for a phone screening. "Oh, yeah, of course I did! Just now. I am very interested.""Great. Louis, the owner, would like to meet with you," Janine informed him."Ok, sure. I'm pretty open, I usually work in the evenings so I can make most days work," he replied, checking his calendar."Can you be here in an hour?" she asked. James managed to hide the fact he was freaking out about how to make it in time while assuring her he could be.He arrived at the address Janine provided after a dangerous mid-drive shave. He felt unprepared but eager to rock the interview. The front door of their suite gave way to a lobby that seemed more like a walk-in closet. Janine was sitting behind a small desk reading a trashy tabloid and barely looked up to greet him. "Louis will see you now," she motioned toward a door behind the desk and went back to reading barely plausible celebrity rumors.James stepped through the door into what could have been a walk-in closet for the first walk-in closet. A portly, sweaty man presumed to be Louis jumped up to greet him. "John! Glad you could make it on short notice. Have a seat!""Actually, it's James..." he corrected Louis, while also forgiving the mixup. "Nice to meet you. I was eager to get here to learn about this opportunity.""Well James, you were right to apply! We are a fast growing company here at CallCom and I need eager young talent like you to really drive it home!" Louis was clearly excited about his company, growing sweatier by the minute."That sounds good to me! I may not have any real-world experience yet, but I assure you that I am eager to learn from your more senior members," James replied, trying to sell his potential.Louis let out a hefty chuckle at James' mention of senior members. "Oh you mean stubborn old developers who are set in their ways? You won't be finding those around here! I believe in fresh young minds like yours, unmolded and ready to take the world by storm.""I see..." James said, growing uneasy. "I suppose then I could at least learn how your code is structured from your junior developers? The ones who do your in-house development?"Louis wiped his glistening brow with his suit coat before making the big revelation. "There are no other developers, James. It would just be you, building our fantastic new computer system from scratch! I have all the confidence in the world that you are the man for the job!"James sat for a moment and pondered what he had just heard. "I'm sorry but I don't feel comfortable with that arrangement, Louis. I thought that by saying you do everything in-house, that implied there was already a development team.""What? Oh, heavens no! In-house development means we let you work from home. Surely you can tell we don't have much office space here. So that's what it means. In. House. Got it?James quickly thanked Louis for his time and left the interconnected series of closets. In a way, James was glad for the experience. It motivated him to move out of his one horse town to a bigger city where he eventually found employment with a real in-house dev team. [Advertisement] Otter, ProGet, BuildMaster – robust, powerful, scalable, and reliable additions to your existing DevOps toolchain.
|
by Remy Porter on (#32NZF)
I’ve had to write a few domain-specific-languages in the past. As per Remy’s Law of Requirements Gathering, it’s been mostly because the users needed an Excel-like formula language. The danger of DSLs, of course, is that they’re often YAGNI in the extreme, or at least a sign that you don’t really understand your problem.XML, coupled with schemas, is a tool for building data-focused DSLs. If you have some complex structure, you can convert each of its features into an XML attribute. For example, if you had a grammar that looked something like this:
|
by Jane Bailey on (#32JGV)
"So there's this developer who is the end-all, be-all try-hard of the year. We call him Shoe. He's the kind of over-engineering idiot that should never be allowed near code. And, to boot, he's super controlling."Sometimes, you'll be talking to a friend, or reading a submission, and they'll launch into a story of some crappy thing that happened to them. You expect to sympathize. You expect to agree, to tell them how much the other guy sucks. But as the tale unfolds, something starts to feel amiss.They start telling you about the guy's stand-up desk, how it makes him such a loser, such a nerd. And you laugh nervously, recalling the article you read just the other day about the health benefits of stand-up desks. But sure, they're pretty nerdy. Why not?"But then, get this. So we gave Shoe the task to minify a bunch of JavaScript files, right?"You start to feel relieved. Surely this is more fertile ground. There's a ton of bad ways to minify and concatenate files on the server-side, to save bandwidth on the way out. Is this a premature optimization story? A story of an idiot writing code that just doesn't work? An over-engineered monstrosity?"So he fires up gulp.js and gets to work."Probably over-engineered. Gulp.js lets you write arbitrary JavaScript to do your processing. It has the advantage of being the same language as the code being minified, so you don't have to switch contexts when reading it, but the disadvantage of being JavaScript and thus impossible to read."He asks how to concat JavaScript, and the room tells him the right answer: find javascripts/ -name '*.js' -exec cat {} \; > main.js"Wait, what? You blink. Surely that's not how Gulp.js is meant to work. Just piping out to shell commands? But you've never used it. Maybe that's the right answer; you don't know. So you nod along, making a sympathetic noise."Of course, this moron can't just take the advice. Shoe has to understand how it works. So he starts googling on the Internet, and when he doesn't find a better answer, he starts writing a shell script he can commit to the repo for his 'jay es minifications.'"That nagging feeling is growing stronger. But maybe the punchline is good. There's gotta be a payoff here, right?"This guy, right? Get this: he discovers that most people install gulp via npm.js. So he starts shrieking, 'This is a dependency of mah script!' and adds node.js and npm installation to the shell script!"Stronger and stronger the feeling grows, refusing to be shut out. You swallow nervously, looking for an excuse to flee the conversation."We told him, just put it in the damn readme and move on! Don't install anything on anyone else's machines! But he doesn't like this solution, either, so he finally just echoes out in the shell script, requires npm. Can you believe it? What a n00b!"That's it? That's the punchline? That's why your friend has worked himself into a lather, foaming and frothing at the mouth? Try as you might to justify it, the facts are inescapable: your friend is TRWTF.[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
|
by Remy Porter on (#32F6K)
Just last week, I was teaching a group of back-end developers how to use Angular to develop front ends. One question that came up, which did suprise me a bit, was how to deal with race conditions and concurrency in JavaScript.I’m glad they asked, because it’s a good question that never occurred to me. The JavaScript runtime, of course, is single-threaded. You might use Web Workers to get multiple threads, but they use an Actor model, so there’s no shared state, and thus no need for any sort of locking.Chris R’s team did have a need for locking. Specifically, their .NET backend needed to run a long-ish bulk operation against their SqlServer. It would be triggered by an HTTP request from the client-side, AJAX-style, but only one user should be able to run it at a time.Someone, for some reason, decided that they would implement this lock in front-end JavaScript, since that’s where the AJAX calls were coming from..
by Mark Bowytz on (#3276C)
"You can have any graphics you want, as long as it's Intel HD Graphics 515," Mark R. writes.
by Remy Porter on (#323V8)
Anonymous sends us this little blob of code, which is mildly embarassing on its own:
|
by snoofle on (#320M6)
The progenitor of this story prefers to be called Mr. Syntax, perhaps because of the sins his boss committed in the name of attempting to program a spreadsheet-loader so generic that it could handle any potential spreadsheet with any data arranged in any conceivable format.The boss had this idea that everything should be dynamic, even things that should be relatively straightforward to do, such as doing a web-originated bulk load of data from a spreadsheet into the database. Although only two such spreadsheet formats were in use, the boss wrote it to handle ANY spreadsheet. As you might imagine, this spawned mountains of uncommented and undocumented code to keep things generic. Sin was tasked with locating and fixing the cause of a NullPointerException that should simply never have occurred. There was no stack dump. There were no logs. It was up to Sin to seek out and destroy the problem.Just to make it interesting, this process was slow, so the web service would spawn a job that would email the user with the status of the job. Of course, if there was an error, there would inevitably be no email.It took an entire day to find and then debug through this simple sheet-loader and the mountain of unrelated embedded code, just to find that the function convertExcelSheet blindly assumed that every cell would exist in all spreadsheets, regardless of potential format differences.[OP: in the interest of brevity, I've omitted all of the methods outside the direct call-chain...]
|
by Ellis Morning on (#31X4Q)
Paul R. shows us a classic example of the sort of case statement that maybe, you know, never should've been implemented as a case statement:
by Remy Porter on (#31SXS)
Ah, consumer products. Regardless of what the product in question is, therre’s a certain amount of “design†that goes into the device. Not design which might make the product more user-friendly, or useful, or in any way better. No, “designâ€, which means it looks nicer on the shelf at Target, or Best Buy, or has a better image on its Amazon listing. The manufacturer wants you to buy it, but they don’t really care if you use it.This thinking extends to any software that may be on the device. This is obviously true if it’s your basic Internet of Garbage device, but it’s often true of something we depend on far more: consumer grade routers.Micha Koryak just bought a new router, and the first thing he did was peek through the code on the device. Like most routers, it has a web-based configuration tool, and thus it has a directory called “applets†which contains JavaScript.Javascript like this:
by Mark Bowytz on (#31HVA)
Drew W. writes, "If I'm already at (undefined), why should I pay $389.99 to fly to (undefined)?"
by Remy Porter on (#31EF1)
Matthew H was given a pretty basic task: save some data as a blob. This task was made more complicated by their boss’s core philosophy, though.Never. Bother. The. Customer..“Right, but if the operation fails and we can’t continue?â€Never. Bother. The. Customer.“Okay, sure, but what if they gave us bad input?â€Never. Bother. The. Customer.“Okay, sure, but what if, by hitting okay, we’re going to format their entire hard drive?â€Never. Bother. The. Customer.As such, for every method that Matthew wrote, he was compelled to write a “safe†version, like this:
|
by Erik Gern on (#31B65)
Tyler G.’s “engagement managerâ€, Sheila, had a new gig for him. The Global Chemical Society, GCS, had their annual conference coming up, and their system for distributing the schedules was a set of USB thumb-drives with self-hosting web apps.“You’ll be working with two GCS representatives, Jeff and Graham,†Sheila explained. “They’ll provide you with last year’s source code, and the data for this year’s schedule. You’ll need to wire them up.â€Later that day, the four of them- Tyler, Sheila, and Jeff and Graham- joined a Skype call. Only the top of Jeff’s shiny, bald head could be seen on his webcam, and Graham had joined audio-only.Sheila managed the introductions. Tyler started the discussion by asking what format they could expect the schedule data to come in.Jeff shrugged, or at least that’s what they guessed from the way the top of his head bobbed. “Graham, do you know?â€â€œI think it might be XML,†Graham replied, his voice muffled with static and saturated with background noise. “I can’t say for sure. We’ll send a preliminary data dump first.â€The BlobThe data arrived that afternoon, as a single XML file.The first time Tyler tried to open it, Notepad++ crashed in protest. After a few attempts, he finally coaxed the editor into letting him see the file. It had no uniform format. Individual fields might be HTML-formatted strings, indecipherable base64-encoded binary blobs (with no indicator as to what data was encoded), and even their plaintext encodings switched from 8-bit to 16-bit arbitrarily.As soon as Tyler explained to Sheila what a mess the data as, she called GCS reps for another video conferece. Jeff’s shiny pate bobbed around as he listened to their complaints. Sheila finally asked, “Can you do anything to clean up the data?â€â€œNot really, no,†Jeff replied. “This is how we get the data ourselves.â€â€œAbsolutely not,†Graham concurred.“We did this last year,†Jeff replied, “and we didn’t have any trouble.â€A Lack of SupportFor weeks, Tyler worked on an importer for the XML blob. He figured out what the base64-encoded data was (PDF files), why the encoding kept changing (different language encodings), and why some text was HTML-formatted and some wasn’t (the entries were copied from email, with some as HTML and some as plaintext).Jeff and Graham had no interest in the action items assigned no them, and continued to be the largest obstacles to the project. They offered no help, they changed their minds nearly daily, and when Sheila started scheduling daily calls with them, they used those calls as an opportunity to be sarcastic and insult Tyler.Sheila, who had begun the project in a cheerful manner, started balling her fists during each call with Jeff and Graham, now nicknamed “Statler and Waldorfâ€. After one particularly grueling call, she cursed and muttered dark things about “How do they get anything done?â€After weeks of frustration, pulled hair, and cranky calls, Tyler’s importer was finished. With a few days to go before the conference, they had just enough time to hand the software off and get the USB sticks loaded.During that morning’s video conference, Jeff and Graham announced that the format had changed to CSV. Sheila, barely keeping her voice level, asked why the format had changed.“Oh, the industry standard changed,†Graham said.“And why didn’t you tell us?â€Jeff’s shiny scalp tilted as part of an offscreen shrug. “Sorry. Guess we forgot.â€The Bitter EndThe CSV-encoded data, the final and official data-dump for the conference, arrived just one day before the app was due. It came in three files, seemingly split at random, with plenty of repetition between the files. It was all the same, insanely encoded data, just wrapped as CSV rows instead of XML tags.Tyler crunched his way through an all-nighter. By morning, the importer was finished. He sent the code to GCS’s servers, went home, and collapsed.The coming Sunday, attendees would arrive at the GCS conference. They would be given a USB stick, that they could plug into their laptops. The conference app would work perfectly, taking the fractured, convoluted data, and presenting it as a scrollable, interactive calendar of panels, presentations, and convention hall hours. Some graduate student, a lab assistant to a Nobel lauerate, would open the app and wonder:“This programming thing doesn’t seem like a lot of work.â€[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
|
by Remy Porter on (#317YC)
LINQ brings functional programming and loads of syntactic sugar to .NET languages. It’s a nice feature, although as James points out, it helps if your fellow developers have even the slightest clue about what they’re doing.
|
by Alex Papadimoulis on (#31597)
|
by Mark Bowytz on (#30XRB)
Dima R. wrote, "Running out of space on this old XP machine. I know, I'll just uninstall TurboTax 2014!"
|
by Remy Porter on (#30T2Y)
The exotic and exciting life of the world-traveling contractor wasn’t exactly what Angie had been expecting. It mostly meant living in a dreary apartment on the outskirts of some city in a short drive from an industrial park where she’d go to try and keep 30-year old C code and their new ERP from fighting to the death. Six months later, she’d be off to the same apartment near the same industrial park in a different country.When the crash came, it came hard. Hard enough that Angie ditched IT and got a temp job working in a customer service call-center for a greeting card company. She wasn’t exactly the best person on the phone, and nobody was giving her stellar marks for her cheerful demeanor during her quarterly review.What her boss did notice though, is that when she did order entry, it was accurate. This was surprisingly a big deal, because the number of orders with typos coming from the other reps was remarkable. “We really appreciate your attention to detail,†he said. He offered to make the temp job permanent and start working on some career advancement within the company.Angie took it. Over months, she spent less time on the phone, and more time putting her attention to detail to work: cleaning up order entry processes. Since Angie was a developer, she wrote some scripts to streamline the process and shared them with her team. Now, her boss was praising her attention to detail and her initiative.Within a few months, the dev team offered to bring her aboard. The salary bump was nothing to sneeze at, and they didn’t care that she knew C and Java and Ruby, but not their language of choice- C#. So she moved departments, and started working for Liam.Liam was the lead architect, and back in the early days, he was their only developer. Most of the software was home-grown extensions to their ERP, or their CRM. Since engraving printing plates was itself pretty complicated, he’d whipped up a program that could generate output to control the engraving system that made printing plates.Like a lot of smaller software teams in large companies that don’t view software as a priority, the code quality was… special. For any given program, most of the code was in one gigantic do-everything class, or worse, just in the main method. Version control was naming files “Foo.cs.old†or “Foo.cs.dontuseâ€, and release management was hitting “build†and copying the output to a network share.Liam, as the lead architect, didn’t want Angie wasting her time on the “big picture†stuff. “You’ve got such a great attention to detail,†he said. This meant she ended up being the SQL and regular expression expert who also tested the programs (often in production, because that was the only way to test). The result was far fewer bugs, fewer accidents from testing in production, and happier end users.The work was messy, but it wasn’t hard, and the card company didn’t really expect a lot from their software team. Angie appreciated sleeping in the same bed every night, and actually having a social life.Late on a Friday, the head of the company’s charity efforts burst into their cube-farm. The charity team had just run a major fund drive, and now needed to send out custom “Thank You†cards. There was only problem- the template they used (which drove Liam’s program to control the engraver) needed space for one additional line of text. “We need to get these running on the presses tomorrow so we can send them out next week!â€It was a four-alarm, hair-on-fire crisis, according to the charity chief. They were more than happy to provide dinner for the team who worked late, but it needed to be done. Since Angie was “detail orientedâ€, she drew the short straw, but she needed Liam’s help to get the changes made. “I don’t understand any of this code, and I can’t follow the logic.â€â€œWell,†Liam said, “I can’t say that I do, either.â€â€œBut you wrote it!â€â€œOkay, yeah, let’s take a look.â€Over some surprisingly high-quality Thai takeout, Liam and Angie did their best to trace through the logic of the code, understanding how it consumed the template and converted it into something the engraver could understand. Because there was a lot of code-reuse by copy-and-paste, they identified three places that needed changes.“Are you sure that’s it?†Angie asked.“Yeah, absolutely.â€â€œOkay… but how do we test this?â€â€œThe only way to test it is to send it to an engraver.â€â€œOkay, well… let’s go through it again and make sure it’s right,†Angie suggested.It was rubbing up against 10PM, and Liam had enough of that. “Let’s just run it and get the plate engraved. I’ve done this sort of thing a bunch, it’ll be fine.â€It wasn’t. By the time anyone had noticed, however, the plate was already off to the presses. The resulting run cost the company $10,000 in materials, and delayed the sending of the “thank you†cards by three days, which the charity team warned could seriously hurt their charity efforts in the future. The big bosses stormed into the development team’s office, demanding: “Who’s responsible for this?â€The bus was coming, and Liam was ready to throw Angie right in front of it. “We assigned that project to Angie,†he said. She was escorted out of the office that day, and on her exit paperwork, the reason for termination was "insufficient attention to detail". [Advertisement] BuildMaster integrates with an ever-growing list of tools to automate and facilitate everything from continuous integration to database change scripts to production deployments. Interested? Learn more about BuildMaster!
|
by Remy Porter on (#30PN5)
Imagine, if you will, that you have 64-bits of data. From this 64-bits of data, you need to extract a nibble, which contains the value that you care about. Now, I’m sure you’re imagining an integer with some bitmasks to extract the data, which is a perfectly sane approach. Tomasz inherited some code from his company’s German office. It took the approach of taking the 64-bits and storing the 64-bits in an eight element byte array. Then, it extracted the values from that array with code looking like this:
by snoofle on (#30K96)
In the U.S., individuals are expected to file federal and state tax returns once a year by April 15. The tax forms are quite complicated, and have all sorts of sub-forms and schedules to support and detail the numbers on the main form. The tax code of the U.S. is approximately 74,000 pages of special cases.For many items, the same data needs to be entered on multiple forms, usually as the starting point for different calculations that depend upon the same information; these are duplicated again on both federal and state returns. It follows that tax preparation software needs to put the relevant numbers in all the places that they are needed.Why? Because if it doesn't, the preparer needs to manually copy numbers to each of several places, leading to all sorts of omission/accidental editing issues. Just to make it needlessly complicated interesting, in many cases, the numbers need to be transformed via some formula before copying, and the formulas vary from form to form, and from state to state. Complicating this process is the fact that tax forms stating your earnings from employers and financial institutions can be re-issued with new values if tax laws are changed too close to the end of the year. This means that new numbers need to be entered, propagated, calculated and checked on your tax forms, usually after they were initially prepared.If you're preparing your own tax returns, then they probably aren't all that complicated, and there isn't too much copy/pasting to be done. If you have multiple businesses in different states/countries, multiple properties, use multiple banks/brokerages, etc., then there are many, many forms and worksheets detailing the same information, leading to a whole lot of copy/pasting of data. When the complexity of what must be prepared gets beyond a certain point, you go to a professional preparer who will just enter your information once, and the very expensive professional tax software will put the numbers on all the relevant forms automatically. This way, it only takes a few minutes to enter the data, hit calc and a mountain of completed tax forms spews forth from the printer.Julie is a highly experienced accountant, and was partnering with a large, national chain of tax preparers that used their own in-house tax preparation software. They had a large IT team of several hundred assorted developers and support staff. Each year, they'd wait for Congress to decide on changes to the tax laws, and then begin the process of implementing those changes in their software so that they could get it to the accountants in time for tax season.Unfortunately, Congress doesn't take programming time into account when they bicker back and forth over changes to the tax law. Last year, Congress passed a whole slew of changes at the very last minute, leaving insufficient time to implement all the changes in the software (at least not without the usual magic happens here programming of experienced developers). The solution that the blockhead managers came up with was to only implement part of each change prior to distributing the software. They called this "being agile".When Julie started to prepare tax returns, she realized that the inputs to the same calculation were different on different forms. The numbers were not being propagated to the places that needed them, or worse, were being propagated incorrectly. Additionally, some calculations only performed the first 10 steps of a 12 step form. Upon raising bugs, she was told We know about these issues and have no plans to fix them!Wait, manually propagating numbers and checking every calculation defeats the purpose of using the software in the first place; the numbers can't be close, they have to be exact and consistent across forms!The debate about the importance of exact and correct calculations went back a forth and while until it was escalated sufficiently high to warrant an official response:Our software is only intended to guide you in the general direction of preparing tax returns. It only needs to be reasonably functional, not "useful".Julie, at this point, was desperate, so she contacted an insider at the company. "Is there *any* chance this is going to be working in time for tax season?""Oh, man… noooooo," her contact said. "A lot of the developers are on contract, so somebody ran the numbers comparing the hours of development time against paying penalties from audits. They figured out that they could do about… 90% of the changes. It's cheaper to just pay the penalties later."Julie is no longer partnering with this conglomerate. [Advertisement] Application Release Automation for DevOps – integrating with best of breed development tools. Free for teams with up to 5 users. Download and learn more today!
by Remy Porter on (#30G32)
Melody got tapped to do a code review on a pull-request from a veteran team-member. It was… an interesting PR, in that very, very little changed. The code was terrible before anyone touched it- for example, the C-file started with 355 lines of variable declarations inside of the main method.It was, in fact, down around line 354 where Melody noticed the change.
by Mark Bowytz on (#308BH)
"Oh boy! I wonder how they'll top this for the end-of-week bonus prize?" writes Zak.
by Remy Porter on (#304ZA)
We do our best to anonymize submissions, but there’s always a chance that some dangerously identifying detail slips through. Every once in a while, a submitter contacts us to ask for a modification. More rarely, a submitter’s employer contacts us.Our rule is to make edits more or less as requested, then move on without comment. There’s nothing about an article so sacrosanct that it’s worth going to war over. However, we recently got a request that was itself too much of a WTF to pass up.An old Errord—practically antique—contained a picture of a freaked-out Windows login screen, submitted by someone we’ll call Johnny. The post contained Johnny's name, username, and an Active Directory Domain. It did not identify the company Johnny worked for. But the company—we’ll call them “Lagomorphic Cogitationsâ€â€”recently performed a security audit and sent us a message:
by Remy Porter on (#301N5)
Every line of code tells a story. It never just… appears. Someone made and crafted that code. There’s a story, and an explanation for how that code could be. The world, even the bad, awful corners of it, makes sense and can be understood.For example, Luke sends us this block.
|
by Jane Bailey on (#2ZYBV)
When people think about government, they usually think about a President or Prime Minister, Senators, MPs, or what have you. But government isn't just a handful of people at the top of the food chain: there's government all the way down to the city level, quietly making the country run. Driver's licenses have to be issued, as do pet licenses. Buildings have to be inspected and certified. All those elevator certificates get printed up somewhere. Increasingly, these small functions are being computerized—in bits and pieces, in incompatible systems—and hooked up to the Internet.Lisa was the lead engineer for one of these public websites. At its core, it took in personally identifying details and spat out some sort of official document. This meant they had to deal with the PII issues that come with taking people's information: encrypting and salting the data, securing the database backend, et cetera.One of the pieces in this chain was a separation of data: until the user had paid for the document, proving their identity (or at least their possession of the credit card for the person they claimed to be), their data sat in a frontend database accessible to the Internet. After payment was taken, the data was sent to a more secure database in the backend and removed from the potentially hackable frontend. The frontend ran in a VM that could only make an outgoing connection to the database. It could receive incoming connections and respond, but not initiate them. Basic security for this type of system.There was one issue, however, that Lisa struggled to track down. It seemed that a small percentage of users, fewer than 1%, were getting an error page immediately after payment. Their application was fine; payment was received, and their document was sent to them along with a confirmation. But they saw an error page suggesting they hadn't completed their transaction.When Lisa managed to catch the issue in the act, she was able to reconstruct the sequence from the logs:
|
by Remy Porter on (#2ZV3S)
For a change of pace, the code in this CodeSOD isn’t the real WTF. Our Anonymous submitter works for a company that handles meeting scheduling for corporate customers. This entails shipping off loads of HTML-emails, and that means using a relatively terrible WYSIWYG editor that generates code like this:
by Mark Bowytz on (#2ZKDR)
Michael R. wrote, "So, https://TfL.Gov.UK...does that bus go on the 'Information Superhighway'?"
by Remy Porter on (#2ZG92)
As you know, Hired has been sponsoring the site for the past few months. I went “behind the scenes†to have a brief chat with Michael Mitchell, a full stack web engineer focused on their “Candidate Experience†features.To ease in, I started with the only truly important question about life at Hired: how’s the coffee. “It’s amazing,†Michael replied. “We have an operations coordinator that worked at a few large coffee roasters, so she takes care of coffee and makes large batches of cold-brew for the office.†That last is an important one- I’ve had too many cups of “iced†coffee that were just, well, hot coffee with ice in it.Michael was an electrical engineer before becoming a web engineer; while high voltage might kill you, NPM will make you wish you were dead. “I’m partial to the story Overpowered,†Michael said. While he never used angular momentum to destroy a hard disk drive, he did build the automation for an industrial packaging line. That automation was entirely run through a single Arduino.“I wasn’t a complete idiot,†Michael said. “All of the safety critical systems were hardwired in a fail-safe manner, and didn’t depend on the Arduino.†It operated for years without incident, and as the line grew, that Arduino ended up running a multi-million dollar business. Eventually, the support contract for the line went elsewhere, and the company taking it over wanted to know what that tiny little board running the line was, and how they could interface with it. “I told them to rip it out and replace it with a PLC, because they really didn’t want to hear the answers to those questions.â€Michael isn’t in the business of hacking together millions of dollars of business on hobbyist equipment anymore. Their current stack- mostly Ruby/React.js, with Postgres on the backend, and a bit of Scala/Python data-science for matching/ranking- doesn’t have any of those kinds of hacks. “Our code review process is fairly well enforced- culturally, not through tools. Probably, the most horrific stuff I’ve done is commit some pretty tortured CSS.â€Despite that, there are lots of growing pains. When Hired was in its early startup phases, it was “move fast and break things,†but as their customers grew, they needed to shift gears. “When you have large client teams relying on your product, moving a button can break an entire HR team’s workflow.â€The upshot is that Michael works with a strong team. “Everyone here is incredibly collaborative and easy to work with.†How do they build the right team? Using Hired, of course! At least half of the engineering team were placed through Hired. “The founders started Hired because they had issues hiring good talent for their previous companies. The company was practically founded to dog-food its own product.â€Speaking of, Michael’s team is tackling a lot of work- in addition to two web engineers, they have two mobile engineers and a single designer. Five people supporting web, iOS, and working on delivering an Android app. “That’s with only four engineers, so I’d say our bottleneck is mainly engineering resources. We’re currently Hiring!â€Hired was also Michael’s chance to dodge a bit of a bullet. When he was last job hunting, he was shopping around, and interviewed with another startup. The CEO may have been the subject of many an article here: the “I know better than you, and you’re lucky I’m even talking to you,†sort. Michael explains:
by Remy Porter on (#2ZD7H)
Writing quality database code is a challenge. Most of your commands need to be expressed in SQL, which is a mildly complicated language made more complicated by minor variations across databases. Result sets often have a poor mapping to our business logic’s abstractions, especially in object-oriented languages. Thus, we have Object-Relational-Mapping tools, like Microsoft’s EntityFramework.With an ORM, you use an object-oriented approach to fetching your objects, and could write something like: IList<HJFRate> rates = db.HJFRates.where(rate=>rate.typeOfUse == typeOfUse) to return all the rows as objects. There’s no concern about SQL injections, no need to process the result set directly. While ORMs can generate poor SQL, or create really inefficient data-access patterns, their ease-of-use is a big selling point.Which is why Bob Zim was surprised to find this EntityFramework code in a C# web-service:
|
by Charles Robinson on (#2ZA53)
Marcus worked on a small networking team responsible for keeping a series of UK-based garages interconnected with the world-wide web. Seymour, the Team Leader (in title only), knew far less about networking than Marcus, but that didn't stop him from acting like the big shot. Seymour was working a cash register at the original garage several years ago when the owner asked him, "You're a young guy, right? That means you know how the internet works. What can we do to make this place internet-friendly?" After taking a Networking 101 course, Seymour managed to get the garage online, then enabled it to monitor gas prices and perform credit card transactions. This made Seymour a hero to the owner, and earned him the title, "Networking Team Leader" before he even had a team.Eventually the garage grew from a single location into a chain. When each new location opened, Seymour made it "internet-friendly", using the same techniques he learned at the original store, which usually involved sloppy cable runs and the cheapest router he could buy. When it came time to do more than just have the ISP arrive to show where Seymour to plug in the network cable, he was completely lost. Having multiple locations networked together was really advanced stuff, so he convinced the owner to hire some help.Enter Marcus, who was willing to be hired on as Seymour's subordinate while realizing he would be the de facto brains of the networking team. It didn't take long for Marcus to realize he had his work cut out for him to get things in order. There were several hack-y solutions put in place that Marcus was able to improve upon, but in the end he got no credit for it because Seymour was there to take the accolades.
|
by Remy Porter on (#2Z76M)
“Mrs S†works for a large software vendor. This vendor has a tendency to quickly increase staffing to hit arbitrary release targets, and thus relies heavily on contractors. Since they’re usually doing this during a time crunch, these contractors may have a… dubious skill set.They also don’t care. There is no documentation, no tests, and no explanation. They are just paid tho write the code, not maintain it. They’ll be on another contract before long, so it’s some other schmuck’s problem.Which is why “Mrs S†found this code, which takes a version number, as a pair of integers, and converts them to a string, but still couldn’t tell you why it does any of the things that it does.
by Mark Bowytz on (#2YZSS)
John A. writes, "Um, you know, I don't think this was a brilliant idead."
by Remy Porter on (#2YWQR)
Given the common need to have getter/setter methods on properties, many languages have adopted conventions which try and make it easier to implement/invoke them. For example, if you name a method foo in Ruby, you can invoke it by doing: obj.foo = 5.In the .NET family of languages, there’s a concept of a property, which bundles the getter and setter methods together through some syntactical sugar. So, something like this, in VB.Net.
|
by Erik Gern on (#2YSGB)
It was a mandatory change control meeting. Steven S.’s department, a research branch of the Ministry of Social Affairs and Health in Belgium, assembled in a cramped meeting room without enough chairs for everyone. Camille, head of IT, was nonplussed.“These orders come directly from Security,†she began. “Just last month, we monitored over a hundred attempts to break into the HCP.†The Home Care Platform was a database of citizens’ requests for doctors’ visits, prescription coverage, etc. Steven’s team had developed a mobile app that gave citizens access to HCP’s records.“An automated script,†she continued, “purged our server logs before Security could investigate. Now we have little information on what these attackers were trying to access, nor if they were able to find a breach.â€
|
by Remy Porter on (#2YP8B)
Zenith’s company went ahead on and outsourced 95% of their development to the lowest bidder. Said bidder promised a lot of XML and MVC and whatever TLAs sounded buzzwordy that day, and off they went. It’s okay, though, the customer isn’t just taking that code and deploying it- “Zenith†gets to do code reviews to ensure code quality. The general flow of the post-code-review conversation goes something like:
by Ellis Morning on (#2YK2K)
John S. worked with a customer who still owned several Windows 2008/R2 servers. Occassionally during automated management and deployments, these machines threw exceptions because they weren't configured for remote management. One day, John caught an exception on a SQL box and remoted in to address the problem.The RDP login process always felt like accessing a portal into the distant past. This time, just after the ancient Windows interface appeared, a Notepad document popped open. John skimmed the so-called Readme.txt file—then read through it again (grammatical errors preserved):
by Mark Bowytz on (#2YBP3)
"You know, usually these statements are just marketing B.S., but I think this guy's got the right idea," wrote Philip K.
|
by Remy Porter on (#2Y8D5)
About two years ago, we took a little trip to the Galapagos- a tiny, isolated island where processes and coding practices evolved… a bit differently. Calvin, as an invasive species, brought in new ways of doing things- like source control, automated builds, and continuous integration- and changed the landscape of the island forever.Or so it seemed, until the first hiccup. Shortly after putting all of the code into source control and automating the builds, the application started failing in production. Specifically, the web service calls out to a third party web service for a few operations, and those calls universally failed in production.“Now,†Hank, the previous developer and now Calvin’s supervisor, “I thought you said this should make our deployments more reliable. Now, we got all these extra servers, and it just plumb don’t work.â€â€œWe’re changing processes,†Calvin said, “so a glitch could happen easily. I’ll look into it.â€â€œLooking into it†was a bit more of a challenge than it should have been. The code was a pasta-golem: a gigantic monolith of spaghetti. It had no automated tests, and wasn’t structured in a way that made it easy to test. Logging was nonexistent.Still, Calvin’s changes to the organization helped. For starters, there was a brand new test server he could use to replicate the issue. He fired up his testing scripts, ran them against the test server, and… everything worked just fine.Calvin checked the build logs, to confirm that both test and production had the same version, and they did. So next, he pulled a copy of the code down to his machine, and ran it. Everything worked again. Twiddling the config files didn’t accomplish anything. He build a version of the service configured for remote debugging, and chucked it up to the production server… and the error went away. Everything suddenly started working fine.Quickly, he reverted production. On his local machine, he did something he’d never really had call to do- he flipped the build flag from “Debug†to “Release†and recompiled. The service hung. When built in “Release†mode, the resulting DLL had a bug that caused a hang, but it was something that never appeared when built in “Debug†mode.“I reckon you’re still workin’ on this,†Hank asked, as he ambled by Calvin’s office, thumbs hooked in his belt loops. “I’m sure you’ve got a smart solution, and I ain’t one to gloat, but this ain’t never happened the old way.â€â€œWell, I can get a temporary fix up into production,†Calvin said. He quickly threw a debug build up onto production, which wouldn’t have the bug. “But I have to hunt for the underlying cause.â€â€œI guess I just don’t see why we can’t build right on the shared folder, is all.â€â€œThis problem would have cropped up there,†Calvin said. “Once we build for Release, the problem crops up. It’s probably a preprocessor directive.â€â€œA what now?â€Hank’s ignorance about preprocessor directives was quickly confirmed by a search through the code- there was absolutely no #if statements in there. Calvin spent the next few hours staring at this block of code, which is where the application seemed to hang:
|
|
by Remy Porter on (#2Y4YN)
Tim was debugging one of those multithreading bugs, where there appeared to be a race condition of some kind. The developer who had initially written the code denied that such a thing could exist: “It’s impossible, I used locks to synchronize the threads!â€Well, he did use locks at the very least.
|
|
by Jane Bailey on (#2Y1M9)
There are many kinds of jackasses in this world, from the pretentious prick to the smug cynic. Each has their own flavor of awfulness, their own way of making you hate not only them but the entire world that gave birth to them. This story is about one kind of jackass in particular, perhaps the most classic flavor: the man so sure of his own greatness that he becomes enraged at the world whenever it fails to bow before his massive intellect.You see these people a lot on Twitter these days. With self-righteous fury, they demand that you get with the program and acknowledge their clear superiority. But as obnoxious as they are online, they're worse in person ... especially if they turn up at your job interview.Today's candidate applied for a job at a government IT department. Unlike stories you've seen on this site before, this government shop was actually fairly efficient and pleasant to work for. They were hiring Java developers, preferably ones that also had UI and database skills. As such, they had over 100 CVs to skim through for their first 2 positions. After removing those written in crayon, with massive coffee rings obscuring the text, or which had return addresses in prison, they were able to narrow the field to a mere 30, but it was still far more candidates than they wanted to interview in a few short days.But interview they did. At 10 candidates a day, they barely had time to weed through people; however, it didn't take long to eliminate most of the candidates. Some lacked a basic understanding of computers, such as how to launch applications when they're not strewn across the desktop. Others lacked a basic understanding of programming, being entirely unable to tell Java apart from Microsoft Word. Still others—disturbingly many others—lacked a basic understanding of hygiene.For Round 2, they decided only to work with agencies they'd had firsthand experience with, either from that office or from previous companies. They also put together a quick "sniff test" to filter the wheat from the chaff. This 30-minute test checked for basic logic skills, including some open-ended CS questions and Java code to debug. They were looking more for the explanations behind the answers than the answers themselves, hoping to get some idea of how these people reasoned.It worked like a charm. Those who scored under 50% were always appalling in the interview, and those who scored highly were always at worst acceptable. They quickly found their candidates. When it came time to fill the next junior opening, the decision was unanimous: they would use the sniff test as a screen, refusing to interview anyone who failed.Enter The Architect, our aforementioned jackass. This guy seemed pretty good on paper: "10 years experience in infrastructure architecture, design patterns, certifications, and software development practices" according to his cover letter. Applying for a junior role was a bit odd for this veteran, to be sure, but they gave him the test anyway.And boy, did he fail. His final score was a mere 5%. Every answer included a tirade about how the question was wrong. Every. Single. One.Some of you may not believe this man exists. But some of you have met him, or one of his many counterparts the world over. This is the man who, when faced with a question like:
|
|
by Remy Porter on (#2XYCS)
Groovy was one of those programming languages that spent about six months as the trendy language du jour, and I haven’t heard much about it since. If I were to learn it, I’d want to learn by example- going through real-world Groovy code and seeing how it works.An anonymous submitter has provided one sample for me to learn from:
|
by Mark Bowytz on (#2XPM1)
"I tried to export my game to HTML5, but I guess it just wasn't meant to be," Edward W. writes.
|
by Remy Porter on (#2XFWT)
About a decade ago, Gerald worked at a European nuclear plant. There was a “minor†issue where a controller connected to a high-voltage power supply would start missing out on status messages. “Minorâ€, because it didn’t really pose a risk to life and limb- but still, any malfunction with a controller attached to a high-voltage power supply in a nuclear power plant needs to be addressed.So Gerald went off and got the code. It was on a file share, in a file called final.zip. Or, wait, was it in the file called real-final.zip? Or installed.zip? Or, finalnew.zip?It took a few tries, but eventually he picked out the correct one. To his surprise, in addition to the .c and .h files he expected to see, there was also a mysterious .xls. And that’s where things went bad.Pause for a moment to consider a problem: you receive a byte containing an set of flags to represent an error code. So, you need to check each individual bit to understand what the exact error is. At this point, you’re probably reaching for a bitshift operator, because that’s the easiest way to do it.I want you to imagine, for a moment, however, that you don’t really know C, or bitwise operations, or even what a bit is. Instead, you know two things: that there are 255 possible error codes, and how to use Excel. With those gaps in knowledge, you might perhaps, just manually write an Excel spreadsheet with every possible option, using Excel's range-drag operation to fill in the columns with easily predictable values. You might do this for 254 rows of data. Which, as a note, the range of possible values is 255, so guess what was causing the error?
|
|
by Jane Bailey on (#2XCDW)
She'd resisted the call for years. As a senior developer, Makoto knew how the story ended: one day, she'd be drafted into the ranks of the manager, forswearing her true love webdev. When her boss was sacked unexpectedly, mere weeks after the most senior dev quit, she looked around and realized she was holding the short straw. She was the most senior. This is her story.As she settled into her new responsibilities, Makoto started coming in earlier and earlier in the hopes of getting some development work done. As such, she started to get accustomed to the rhythm of the morning shift, before most devs had rolled out of bed, but after the night shift ops guys had gone home.Bad sign number 1: the CEO wandering past, looking a bit lost and vaguely concerned."Can I help you?" Makoto asked, putting down her breakfast pastry.Bad sign number 2 was his reply: "Does the Internet look down to you?"Makoto quickly pulled up her favorite Internet test site, /r/aww, to verify that she still had connectivity. "Seems all right to me.""Well, I can't get online."Webdev-Makoto would've shrugged and thought, Not my circus. Manager-Makoto forced a grin onto her face and said, "I'll get my guys on that.""Thanks, you're a real champ." Satisfied, the CEO wandered back to whatever it was he did all day, leaving Makoto to explain a problem she wasn't experiencing to guys way more qualified to work on this than she was.Hoping to explain the discrepancy, she unplugged her laptop. This time, the adorable kittens failed to load."Success!" she told the empty office. "This is officially some weird wi-fi problem."She drafted up a notice to that effect, sent it to the office mailing list, and assigned her teammate Sven to find and fix the problem. By 9:00 AM, all was well, and her team had sent out an update to that effect.Now well into her daily routine, Makoto put the incident behind her. After all, it was resolved, wasn't it?4:00 PM rolled around, and Makoto was somehow the recipient for an angry email from Greg in Sales. Is the internet still out? I need to close out my sales!!! Why hasn't your team fixed this yet! We could lose $300,000 if I can't close out my sales by 5PM!!!!!Makoto rolled her eyes at the unnecessary number of exclamation points and checked the sales pipeline. Sure enough, there was nothing preventing her from accessing Greg's queue and verifying that all $100 worth of sales were present and accounted for.Makoto cracked her knuckles and crafted the most polite response she could muster: As per my update at 9am, the Internet is back online and you should be able to perform any and all job duties at this time.The reply came 2 minutes later: I cannot close my opportunities!!!Makoto forwarded the email chain to Sven before rolling over to his desk. "Greg's being a drama llama again. Can you pull the firewall logs and prove he's got Internet?""'Course."10 minutes and 4 raised eyebrows later, Sven replied to the ticket, copying Greg's boss and attaching a screenshot of the logs. As Makoto stated, we are online at this time. Is it possible your computer received a virus from browsing PornHub since 9:30 this morning?Greg spent the next day in meetings with HR, and the next week on unpaid leave to think about what he'd done. To this day, he cannot look Sven or Makoto in the eye as they pass each other in the hallway. Makoto suspects he won't suffer long—only as long as it takes him to find another job. Maybe one with IT people who don't know what search keywords he uses. [Advertisement] Scale your release pipelines, creating secure, reliable, reusable deployments with one click. Download and learn more today!
|
|
by Remy Porter on (#2X97T)
Processing financial transactions is not the kind of software you want to make mistakes in. If something is supposed to happen, it is definitely supposed to happen. Not partially happen. Not maybe happen.Thus, a company like Charles R’s uses a vendor-supplied accounting package. That vendor has a professional services team, so when the behavior needs to be customized, Charles’s company outsources that development to the vendor.Of course, years later, that code needs to get audited, and it’s about then that you find out that the vendor outsourced their “professional services†to the lowest bidder, creating a less-than-professional service result.If you want to make sure than when the country code is equal to "HND", you want to be really sure.
|
by Mark Bowytz on (#2X27X)
"I guess we're not allowed to thank the postal carriers?!" Brian writes.
|
by Remy Porter on (#2WYXT)
Max’s team moved into a new office, which brought with it the low-walled, “bee-hive†style cubicle partitions. Their project manager cheerfully explained that the new space “would optimize collaborationâ€, which in practice meant that every random conversation between any two developers turned into a work-stopping distraction for everyone else.That, of course, wasn’t the only change their project manager instituted. The company had been around for a bit, and their original application architecture was a Java-based web application. At some point, someone added a little JavaScript to the front end. Then a bit more. This eventually segregated the team into two clear roles: back-end Java developers, and front-end JavaScript developers.“Silos,†the project manager explained, “are against the ethos of collaboration. We’re all going to be full stack developers now.†Thus everyone’s job description and responsibilities changed overnight.Add an overly ambitious release schedule and some unclear requirements, and the end result is a lot of underqualified developers rushing to hit targets with tools that they don’t fully understand, in an environment that isn’t conducive to concentration in the first place.Max was doing his best to tune out the background noise, when Mariella stopped into Dalton’s cube. Dalton, sitting straight across from Max, was the resident “front-end expertâ€, or at least, he had been before everyone was now a full-stack developer. Mariella was a long-time backend JEE developer who hadn’t done much of the web portion of their application at all, and was doing her best to adapt to the new world.“Dalton, what’s the easiest way to get the minimum value of an array of numbers in JavaScript?†Mariella asked.Max did his best to ignore the conversation. He was right in the middle of a particularly tricky ORM-related bug, and was trying to figure out why one fetch operation was generating just awful SQL.“Hrmmmm…†Dalton said, tapping at his desk and adding to the distraction while he thought. “That’s a tough one. Oh! You should use a filter!â€â€œA filter, what would I filter on?â€Max combed through the JPA annotations that controlled their data access, cursing the “magic†that generated SQL queries, but as he started to piece it together, Dalton and Mariella continued their “instructional†session.“In the filter callback, you’d just check to see if each value is the lowest one, and if it is, return true, otherwise return false.†Dalton knocked out a little drum solo on his desk, to celebrate his cleverness.“But… I wouldn’t know which value is the lowest one, yet,†Mariella said.“Oh, yeah… I see what you mean. Yeah, this is a tricky one.â€Max traced through the code. Okay, so the @JoinColumn is CUST_ID, so why is it generating a LIKE comparison instead of an equals? Wait, I think I’ve-“Ah ha!†Dalton said, chucking Max’s train of thought off the rails and through an HO-scale village. “You just sort the array and take the first value!†*Thumpa thumpa tadatada* went Dalton’s little desk drum solo.“I guess that makes sense,†Mariella said.At this point, Max couldn’t stay out of the conversation. “No! Don’t do that. Use reduce. Sorting’s an n(lg n) operation.â€â€œHunh?†Dalton said. His fingers nervously hovered over his desk, ready to play his next drum solo once he had a vague clue what Max was talking about. “In logs in? We’re not doing logging…â€Max tried again, in simple English. “Sorting is slow. The computer does a lot of extra work to sort all the elements.â€â€œNo it won’t,†Dalton said. “It’ll just take the first element.â€â€œAhem.†Max turned to discover the project manager looming over his cube. “We want to encourage collaboration,†the PM said, sternly, “but right now, Max, you’re being disruptive. Please be quiet and let the people around you work.â€And that was how Dalton’s Minimum Finding Algorithm got implemented, and released as part of their production code base.[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!
|
|
by Remy Porter on (#2WVHX)
Microsoft’s SQL Server Integration Services is an ETL tool that attempts to mix visual programming (for designing data flows) with the reality that at some point, you’re just going to need to write some code. Your typical SSIS package starts as a straightforward process that quickly turns into a sprawling mix of spaghetti-fied .NET code, T-SQL stored procedures, and developer tears.TJ L. inherited an SSIS package. This particular package contained a step where a C# sub-module needed to pass a date (but not a date-time) to the database. Now, this could be done easily by using C#’s date-handling objects, or even in the database by simply using the DATE type, instead of the DATETIME type.Instead, TJ’s predecessor took this route instead:
|