thedailywtf

thedailywtf.com

Error'd: amp, #039 and a0B30000004la04EAA& - Fri, 03 Feb 2012

"I saw this on my way home from work," Daniel Moore writes, "thank goodness CVS is doing something about Maryland's crippling shortage of whooping cough!"

 

"While trying to learn Open Bravo," writes Otmane Malih, "I learned that there are countries I've never heard of."

 

"My university has a site license of Mathematica for all Mathematics and Physics students," Simon Hollingshead wrote, "when trying to view some information about the license key, I got this message. Not to worry, it can go in my binder named 'Error messages from various websites'."

 

"Woah, bad password," wrote Micah, "that's cool man."

 

"Now that's a lot of readme," writes Frank de Weger.

 

"I was filling out a satisfaction survey after buying a new car," writes Jeremy Hutchinson, "even the optional questions required an answer."

 

"This is from a well-known vendor of libraries," writes Adrian Edmonds, "what to do next is a bit of a puzzle."

 

"This Mongolian ATM had a rather unique way to notify that it could not print a receipt," writes Matthew Asquith.

 


CodeSOD: The Percent Conversion - Thu, 02 Feb 2012

"Lucky me," writes Joe from the Submit-To-WTF Visual Studio Add-In, "I just inherited a home-grown system information application."

"Judging from the code the previous programmer wrote, this is sadly one of the better pieces."

Public ReadOnly Property BatteryPercent()
    ' This code will retrieve the BatteryLifePercent property and convert it to a percent.
    Get
        If SystemInformation.PowerStatus.BatteryLifePercent.ToString = "1" Then
            Return "100%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.99" Then
            Return "99%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.98" Then
            Return "98%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.97" Then
            Return "97%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.96" Then
            Return "96%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.95" Then
            Return "95%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.94" Then
            Return "94%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.93" Then
            Return "93%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.92" Then
            Return "92%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.91" Then
            Return "91%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.9" Then
            Return "90%"
        '...
        'snip
        '...
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.2" Then
            Return "20%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.19" Then
            Return "19%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.18" Then
            Return "18%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.17" Then
            Return "17%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.16" Then
            Return "16%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.15" Then
            Return "15%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.14" Then
            Return "14%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.13" Then
            Return "13%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.12" Then
            Return "12%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.11" Then
            Return "11%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.1" Then
            Return "10%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.09" Then
            Return "9%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.08" Then
            Return "8%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.07" Then
            Return "7%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.06" Then
            Return "6%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.05" Then
            Return "5%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.04" Then
            Return "4%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.03" Then
            Return "3%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.02" Then
            Return "2%"
        ElseIf SystemInformation.PowerStatus.BatteryLifePercent.ToString = "0.01" Then
            Return "1%"
        Else
            Return "NA"
        End If
    End Get
End Property


Announcements: Code PaLOUsa 2012 - Tue, 31 Jan 2012

Last year's Code PaLOUsa (held in downtown Louisville) was a blast, and it was great to meet up with some of you guys who were able make it out. I'm definitely excited about Code PaLOUsa 2012; there's a lot of great speakers, and it's right in the heart of bourbon country.

My Talk — Ugly Code: Beauty is in The Eye of the Beholder

It's said that without evil there can be no good and that without darkness, there can be no light. Is the same true of ugly and beautiful code? Maybe... but that's certainly not a question I'll be answering in this talk. Instead, we'll talk about ugly code, where it comes from, how to avoid it, and how to rid your codebase of it. And of course, I'll share some of my favorite anti-examples from The Daily WTF.

The TDWTF Discount + Bonus!

How about a $50 discount? If you register before Febuary 21st, it will only cost you $200 (instead of $250) using discount code TDWTF at checkout. Not only that, but you'll also get one of the elusive The Daily WTF mugs.

15oz of Awesomeness

About Code PaLOUsa

Code PaLOUsa is a three-day software development conference that covers all aspects of software development regardless of technology stack. The first day consists of hands-on workshops, followed by two-days of ten different development tracks:

  • Cloud - All things about the cloud, including the who, what, where, when, why, and how about cloud computing
  • Mobile - All things mobile - platforms, devices, content distribution, social networking, community building, and anything else used in conjunction with those devices which have small screens
  • Web Development - Web services, Ajax frameworks, and all things related to the browser
  • Methodologies - Anything pertinent to how modern development methodologies help build software faster, cheaper , and better
  • Languages - Discussions on what's new and cool in software development languages such as C#, Java, PHP, Python, Ruby, Visual Basic, etc.
  • Entrepreneur - Envision MDM Strategy as Part of Broader Information Strategy to Treat Information as Corporate Asset
  • Desktop Development - Standard applications, fat/smart client, client/server, and all things running local on Windows, Mac, or Linux
  • Architecture - SOA, W3C standards, WS* implementations, interoperability, and all things 30,000 feet or higher

There will be 62 technical presentations and panel discussions from well-known professionals in the software development community and two keynote talks from Billy Hollis and Jim Benson.


Save the Project for Failure - Tue, 31 Jan 2012

If it takes two contract developers six months to drive a project to failure, then four developers should be able to fail in half the time! Josh assumed that was why he and Sam were carted out to the client site and tossed into the oubliette of the PowerPac project. They were armed with nothing but a rusty spoon and a requirements document so old it needed to be stored in an oxygen-free environment.

The original development pair was Sally "I can code but I'm more of a designer" Jorgensen (the CEO's daughter) and Billy "I taught myself HTML in a week and am now a programmer" Jorgensen (the CEO's brother). They ran the project exactly like you'd expect such a dynamic duo to run it- directly into the ground. By the time Josh and Sam joined, it was already well past deadline and over budget.

To make a good impression on the client, Billy and Sally didn't work out of the consulting firm's office, but instead moved to the client site. The pair had improvised a server room to work out of. It could be easily distingushed from a broom closet by the piece of duct tape with "SEVER ROOM" sharpied onto it. Inside, an overheating rackmount server balanced on a crate of toilet paper. On a sagging plastic card table sat the developer workstation running VS2005, which doubled as their source control box, since it ran Visual Source Safe.

Josh thought their physical environment was bad, and then he looked at their application. Billy, it seemed, had read one website on database design and walked away with the idea, "if normalizing data across tables is good, normalizing it across databases bust be even better!" Their wheezing Sql Server instance hosted a dozen databases, one for each entity and an extra DB to hold tblIncrementingIDs(strCurrentID VARCHAR(50)), so that unique IDs could be consistent across all of these databases.

The first and last thing Josh noticed about the web code was the fact that each page had a multi-megabyte ViewState. Coupled with terrible coding practices, Josh and Sam junked the VSS repo and then started laying out a plan to rescue the application. They moved the dev team back to the consulting firm's main office, where they had a true development environment, complete with modern dev tools and a well administered TFS2010 instance, along with labs for automated testing. They rounded up people from the client and pinned them down on requierments. They beat Billy and Sally about the head and shoulders with three-tiered architecture until the two of them got it, and proceeded to wrench the project back onto course.

Four months later, Josh and Sam had accomplished the impossible- twice. They had gotten Billy and Sally to turn out code that wouldn't flunk a 100-level college course. The slighly less impossible achievement was that they had turned the project around. It went from "this is never going to be finished" to "it's late, overbudget, but we're within striking distance of an actual deliverable product." They were on track to deliver in two more months.

This kind of success on a project draws accolades and back-pats and lunches paid for by the consulting company for a job well done. It also draws something far more sinister: project managers who want to steal that glory for themselves. Doug, from the client-site, was exactly that kind of project manager. In the closing months of the project, he swooped in with the promise to manage the hell out of this project and keep it on track.

Doug did everyone the favor of standardizing the process. The QA Officer (Doug) had to approve any code before it could be checked into source control. The Compliance Officer (Doug) needed a report of every file modified before any build could be run, down to the specific line numbers changed. He couldn't just extract this information from TFS because, "It's part of the developer's job!"

Only the Build Officer (Doug) could kick off a new build, and not using TFS (a developer tool). Doug would run builds from his own computer, and if he forgot to perform a Get Latest to ensure he had all of the changes, well, that was the developer's problem. They should have followed the communication plan.

Josh protested and escalated and did all of the things you're supposed to do when someone's tanking your project, but to no avail. He couldn't understand how Doug was getting away with this until he sat in on Doug's status meeting. Doug had compiled a PowerPoint full of pretty graphs and dashboards showing nothing but green boxes. He used words like synergy, Agile, "code coverage", "core principles" and "industry standard best practices". It was entirely fabricated nonesense, but management swallowed every drop.

When they didn't hit Josh's original target dates, the money officially ran out. The project was cancelled, and the client informed the consulting company that Josh and his team should never be assigned to one of their projects again. Doug got transferred to another "at risk" project for the client, so that he could "save" it.


CodeSOD: The .NET Whistleblower - Mon, 30 Jan 2012

Terry had spent the better part of the past decade digging through the trenches of QuidCorp's flagship application QuidFlow -- a program used to flowchart business processes. Though QuidFlow performed well and, overall, customers were happy with the product, whenever it came time to address a bug or investigate just how the filename validation worked; the source code was beginning to show its age.

Terry raised his concerns to management. Much to his surprise, management approved a plan to transition their C++ developers into the world of .NET through a little on-the-job experience.

Homemade with Love

Paired up with a senior programmer who had been working on QuidDoc, an ASP.NET document control app written in VB.NET, Terry was handed some completed quality assurance (QA) test plans.

"Don't stress yourself out trying to figure out how to solve every problem just yet," the senior programmer advised, "really just get yourself versed in how to check the code out, compile it and poke around a bit."

The application refused to start and when Terry eventually managed to get it going, exceptions were thrown all over the place by the runtime environment when he tried to run the application on his local machine.

Throughout the codebase, there was one section of code common to all the pages. Sharing common code is a great thing -- Terry had employed a similar method in C++. However, in this one module, above all others, there was something funny about how it all worked.

Not in Kansas Anymore

First of all, in his old role functions returned a meaningful value. However, littered through QuidFlow were functions, which always returned the same value of False, whether they were completed successfully or not:

Function UnLockRecord(strTableName) As boolean
  if strTableName = "" then
    strSQLText = "DELETE FROM LOCKINFO 
    WHERE PERSNO=" & SQLQuote(session("LOGGEDUSER"))
  Else
    strSQLText = "DELETE FROM LOCKINFO 
    WHERE TABLENAME = " & SQLQuote(strTableName) & " AND PERSNO=" & SQLQuote(session("LOGGEDUSER"))
  End If
  ExecSQL(strSQLText)
  Unlockrecord = false
End Function

Function SystemInfoClear() As boolean
  ExecSQL("DELETE FROM SYSTEMINFO")
  SystemInfoClear = False
End Function

It was widely known that QuidFlow would kick back strange and frightening messages when things went horribly wrong. As such, Terry could appreciate why a developer would want to shield a division by zero error or a similar condition from a user. However, this feeling of appreciation was reversed somewhat after seeing two similarly named functions immediately thereafter.

Though he wasn't even remotely close to being able to call himself a Web developer, Terry felt that there had to be an easier way of rendering the HTML at the top of each page:

if cSYS_NONAVFRAME<>"1" Then 
   response.write("" & Chr(13) & Chr(10))
End If

Whistleblow

Concerned that QuidCorp might actually ship something so fetid and maligned, Terry decided he had to pay a visit to QuidFlow's project manager.

"You're right, Terry, this is in no way a solid application, but unfortunately, it is what it is," the project manager explained. "However, that's why we're assigning all you C++ guys with your awesome track record to look into these bugs so we'll be able to ship QuidFlow!"

Somehow, the compliment didn't feel right. At the end of the week, Terry and his fellow QuidFlow developers were pulled from their on-the-job .NET training. QuidCorp had just sold a motherload of QuidFlow licenses to a corporate client and they were asking for some big-time enhancements, which would of course mean they needed all C++ developers on hand immediately.

While the move of QuidFlow to .NET was on hold until some time freed up, their hands-on .NET training wasn't all for nothing. When the time came, at least they would know how not to develop a .NET app.


The .NET Whistleblower was originally published in the December 2010 edition of Visual Studio Magazine. VSM is the leading site for enterprise .NET developers, and offers a free magazine subscription for influential readers.


Leave a Reply