Code

Error'd: amp, #039 and a0B30000004la04EAA&

The Daily WTF - Fri, 03/02/2012 - 22:00

"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.

 


Categories: Code

Listen to Your Community, But Don't Let Them Tell You What to Do

Coding Horror - Fri, 03/02/2012 - 18:18

You know how interviewers love asking about your greatest weakness, or the biggest mistake you've ever made? These questions may sound formulaic, maybe even borderline cliche, but be careful when you answer: they are more important than they seem.

So when people ask me what our biggest mistake was in building Stack Overflow I'm glad I don't have to fudge around with platitudes. I can honestly and openly point to a huge, honking, ridiculously dumb mistake I made from the very first day of development on Stack Overflow – and, worse, a mistake I stubbornly clung to for a solid nine month period after that over the continued protestations of the community. I even went so far as to write a whole blog post decrying its very existence.

For the longest time, I had an awfully Fight Club-esque way of looking at this: the first rule of Stack Overflow was that you didn't discuss Stack Overflow! After all, we were there to learn about programming with our peers, not learn about a stupid website. Right?

Fight-club-soap

I didn't see the need for a meta.

Meta is, of course, the place where you go to discuss the place. Take a moment and think about what that means. Meta is for people who care so deeply about their community that they're willing to go one step further, to come together and spend even more of their time deciding how to maintain and govern it. So, in a nutshell, I was telling the people who loved Stack Overflow the most of all to basically … f**k off and go away.

As I said, not my finest hour.

In my defense, I did eventually figure this out, thanks to the continued prodding of the community. Although we'd used an external meta site since beta, we eventually launched our very own meta.stackoverflow in June 2009, ten months after public beta. And we fixed this very definitively with Stack Exchange. Every Stack Exchange site we launch has a meta from day one. We now know that meta participation is the source of all meaningful leadership and governance in a community, so it is cultivated and monitored closely.

I also paid penance for my sins by becoming the top user of our own meta. I've spent the last 2 years and 7 months totally immersed in the morass of bugs, feature requests, discussions, and support that is our meta. As you can see in my profile, I've visited meta 901 unique days in that time frame, which is disturbingly close to every day. I consider my meta participation stats a badge of honor, but more than that, it's my job to help build this thing alongside you. We explicitly do everything in public on Stack Exchange – it's very intentionally the opposite of Ivory Tower Development.

Along the way I've learned a few lessons about building software with your community, and handling community feedback.

1. 90% of all community feedback is crap.

Let's get this out of the way immediately. Sturgeon's Law can't be denied by any man, woman, child … or community, for that matter. Meta community, I love you to death, so let's be honest with each other: most of the feedback and feature requests you give us are just not, uh, er … actionable, for a zillion different reasons.

But take heart: this means 10% of the community feedback you'll get is awesome! I guarantee you'll find ten posts that are pure gold, that have the potential to make the site clearly better for everyone … provided you have the intestinal fortitude to look at a hundred posts to get there. Be prepared to spend a lot of time, and I mean a whole freaking lot of time, mining through community feedback to extract those rare gems. I believe every community has users savvy enough to produce them in some quantity, and they're often startlingly wonderful.

2. Don't get sweet talked into building a truck.

You should immediately triage the feedback and feature requests you get into two broad buckets:

We need power windows in this car!

or

We need a truck bed in this car!

The former is, of course, a reasonable thing to request adding to a car, while the latter is a request to change the fundamental nature of the vehicle. The malleable form of software makes it all too tempting to bolt that truck bed on to our car. Why not? Users keep asking for it, and trucks sure are convenient, right?

Don't fall into this trap. Stay on mission. That car-truck hybrid is awfully tempting to a lot of folks, but then you end up with a Subaru Brat. Unless you really want to build a truck after all, the users asking for truck features need to be gently directed to their nearest truck dealership, because they're in the wrong place.

3. Be honest about what you won't do.

It always depressed me to see bug trackers and feedback forums with thousands of items languishing there in no man's land with no status at all. That's a sign of a neglected community, and worse, a dishonest relationship with the community. It is sadly all too typical. Don't do this!

I'm not saying you should tell your community that their feedback sucks, even when it frequently does. That'd be mean. But don't be shy about politely declining requests when you feel they don't make sense, or if you can't see any way they could be reasonably implemented. (You should always reserve the right to change your mind in the future, of course.) Sure, it hurts to be rejected – but it hurts far more to be ignored. I believe very, very strongly that if you're honest with your community, they will ultimately respect you more for that.

All relationships are predicated on honesty. If you're not willing to be honest with your community, how can you possibly expect them to respect you … or continue the relationship?

4. Listen to your community, but don't let them tell you what to do.

It's tempting to take meta community requests as a wholesale template for development of your software or website. The point of a meta is to listen to your community, and act on that feedback, right? On the contrary, acting too directly on community feedback is incredibly dangerous, and the reason many of these community initiatives fail when taken too literally. I'll let Tom Preston-Werner, the co-founder of GitHub, explain:

Consider a feature request such as “GitHub should let me FTP up a documentation site for my project.” What this customer is really trying to say is “I want a simple way to publish content related to my project,” but they’re used to what’s already out there, and so they pose the request in terms that are familiar to them. We could have implemented some horrible FTP based solution as requested, but we looked deeper into the underlying question and now we allow you to publish content by simply pushing a Git repository to your account. This meets requirements of both functionality and elegance.

Community feedback is great, but it should never be used as a crutch, a substitute for thinking deeply about what you're building and why. Always try to identify what the underlying needs are, and come up with a sensible roadmap.

5. Be there for your community.

Half of community relationships isn't doing what the community thinks they want at any given time, but simply being there to listen and respond to the community. When the co-founder of Stack Exchange responds to your meta post – even if it wasn't exactly what you may have wanted to hear – I hope it speaks volumes about how committed we are to really, truly building this thing alongside our community.

Regardless of whether money is changing hands or not, you should love discovering some small gem of a community request or bugfix on meta that makes your site or product better, and swooping in to make it so. That's a virtuous public feedback loop: it says you matter and we care and everything just keeps on getting better all in one delightful gesture.

And isn't that what it's all about?

[advertisement] What's your next career move? Stack Overflow Careers has the best job listings from great companies, whether you're looking for opportunities at a startup or Fortune 500. You can search our job listings or create a profile and let employers find you.
Categories: Code

CodeSOD: The Percent Conversion

The Daily WTF - Thu, 02/02/2012 - 22:00

"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


Categories: Code

The One Button Mystique

Coding Horror - Thu, 02/02/2012 - 05:15

I enjoy my iPhone, but I can't quite come to terms with one aspect of its design: Apple's insistence that there can be only ever be one, and only one, button on the front of the device.

Iphone-4s-button

I also own a completely buttonless Kindle Fire, and you'll get no argument from me that there should be at least one obvious "Jesus Handle" button on the front of any gadget. I do wonder why Amazon decided to make the Fire buttonless, when every other Kindle they ship has a home button. Amazon has a track record of making some awfully rough version 1.0 devices; I'm sure they'll add a home button in a version or two. And, hey, at only $199 I'm willing to cut them a little slack. For now.

Even Apple is no stranger to buttonless devices. Consider the oddly buttonless third generation iPod Shuffle, where you had to double and even triple click the controls on the headphones to do basic things like advance tracks. Oh, and by the way, this also made every set of headphones you own obsolete, at least for use with this model. The fourth gen shuffle rapidly switched back to physical controls on the device, and the fifth gen went to touch controls on the device, as expected.

Ipod-shuffle-3g-vs-4g

Microsoft is just as guilty. I sometimes struggle with the otherwise awesome Xbox 360 Wireless Microphone. It has only a power button and some lights.

Xbox-360-wireless-microphone

In its defense, for the most part it does just work when you pick it up and start singing (badly, in my case), but I admit to being slightly perplexed every time I have to sync it with an Xbox, or figure out what's going on with it. Can you blame me?

When you turn on the microphone, the built-in lights shine to display the microphone status as follows:

  • Power on: lights flash green one time every second
  • Connecting: lights flash green four times every second
  • Connection complete: lights flash blue, and then stops

When your battery power is low, the built-in lights shine to display the battery charge status as follows:

  • Low: Lights flash amber one time every three seconds
  • Critical: Lights flash amber one time every second

When your microphone moves out of the wireless range of your console, the lights flash green one time every second. The lights can also change color together with supported game titles.

If we can agree that no buttons is clearly a bad idea, I think it follows that one button is problematic in its own way. I have the same issue with the single button on the iPhone that I do with the single button mouse – it may be OK-ish at the very beginning, but over time it leads to absurd, almost comical overloading of functionality. Consider how many different things the single button on the face of an iPhone now controls:

How-to-use-the-home-button-excerpt
(diagram courtesy Andrew Durdin, source)

The iPhone home button? Why, it's easy! You have your choice of…

  • single-click
  • double-click
  • triple-click
  • click and hold
  • click and pause and click again

All of which have different meanings at different times, of course. In particular I spend a lot of time double-clicking to get to the active apps list, and I often mis-tap which kicks me over to the home screen. I have so many apps installed on my iPhone that search is the only rational way to navigate. This means I search a lot, which requires clicking once to get to the default home page, pausing, then clicking again. Sometimes I click too long, which is then detected as click-and-hold, and I get the voice search app which I am … er, not a fan of, to put it mildly.

I've gotten to the point where I dread using the home button on my iPhone because it Makes Me Think. And I get it wrong a significant percentage of the time. This isn't the way it's supposed to be.

You might be expecting me to turn into a rabid Windows Phone or Android fanboy about now and snarkily note how they get it right. I'm not sure they do. Either of them. They all manage to suck in their own special way.

Phone-windows-and-android-buttons

When there's one button on the device, at least it's clear what that button is supposed to do, right? Well, sometimes.

There is one theme I agree with here – the clearly marked back button on both Android and Windows phones, just like a web browser. I mostly use my iPhone as a platform for the Internet, and the simplicity of the Internet is its primary strength: a collection of obvious things to click, and an easy, giant honking back button so you never get lost in its maze of twisty passages, all alike. It is true that browsers have a home button, but the latest versions of Chrome, Firefox, and Internet Explorer have all but pushed that home button off the UI in favor of the ginormous back button. While I'll tentatively agree that not all phone apps have to behave like the Internet, the Internet is becoming more and more of a platform for bona fide applications every day. The back button is a UI paradigm that works like gangbusters for webapps, and I'd argue strongly in favor of that being a hard button on a device.

But once you add three buttons, thinking starts to creep in again. Am I pressing the correct button? That's never good. And I don't even know what that third button is supposed to be on the Android phone! I could possibly be in favor of the hard search button on the Windows phone, I suppose, but I'd rather see good, consistent use of two buttons on the face of a device before willy-nilly adding Yet Another Button. I think there's a reason the industry has more or less standardized on a two-button mouse, for example. (Yes, there is that pesky middle button, but it's a nice to have, not an essential part of the experience.)

What about the one finger solution? Even with touch devices, one finger does not seem to be enough; there's a curious overloading of the experience over time.

On the iPad, there are a number of system-wide gestures, such as swiping left or right with four fingers to switch between apps. Four-finger swipes? That's convoluted, but imagine a virtual mixing console with horizontal sliders. Quickly move four of them at once...and you switch apps. Application designers have to work around these, making sure that legitimate input methods don't mimic the system-level gestures.

The worst offender is this: swipe down from the top of the screen to reveal the Notification Center (a window containing calendar appointments, the weather, etc.). A single-finger vertical motion is hardly unusual, and many apps expect such input. The games Flight Control and Fruit Ninja are two prime examples. Unintentionally pulling down the Notification Center during normal gameplay is common. A centered vertical swipe is natural in any paint program, too. Do app designers need build around allowing such controls? Apparently, yes.

Yes, our old friend overloading is now on the touch scene in spades: for all but the simplest use of a tablet, you will inevitably find yourself double-tapping, tapping and holding, swiping with two fingers, and so on.

Apple's done a great job of embodying simplicity and clean design, but I often think they go too far, particularly at the beginning. For example, the first Mac didn't even have cursor keys. Everything's a design call, and somewhat subjective, but like Goldilocks, I'm going to maintain that the secret sauce here is not to get the porridge too cold (no buttons) or too hot (3 or more buttons), but just right. I'd certainly be a happier iPhone user if I didn't have to think so much about what's going to happen when I press my home button for the hundredth time in a day.

[advertisement] What's your next career move? Stack Overflow Careers has the best job listings from great companies, whether you're looking for opportunities at a startup or Fortune 500. You can search our job listings or create a profile and let employers find you.

Categories: Code

Announcements: Code PaLOUsa 2012

The Daily WTF - Wed, 01/02/2012 - 04:00

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.


Categories: Code

Save the Project for Failure

The Daily WTF - Tue, 31/01/2012 - 23:30

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.


Categories: Code

CodeSOD: The .NET Whistleblower

The Daily WTF - Mon, 30/01/2012 - 22:00

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("<script language=Javascript>" & Chr(13) & Chr(10)) response.write("if (top.location == self.location) {" & Chr(13) & Chr(10)) if Session("NAV_TOP") Then response.write("document.write('<html><head><title>" & session("WINDOWTITLE") & "</title></head>')" & Chr(13) & Chr(10)) response.write("document.write('<frameset ID=QUIDPROFRAME rows=" & Chr(34) & "0,25,*" & Chr(34) & " cols=" & Chr(34) & "*" & Chr(34) & ">');" & Chr(13) & Chr(10)) response.write("document.write('<frame id=USERDEFINEDFRAME framespacing=0 frameborder=0 border=0 name=USERDEFINEDFRAME>');" & Chr(13) & Chr(10)) response.write("document.write('<frame id=NAVFRAME framespacing=0 frameborder=O border=0 name=NAVFRAME >');" & Chr(13) & Chr(10)) response.write("document.write('<frame id=MAINFRAME framespacing=0 frameborder=O border=0 name=MAINFRAME>');" & Chr(13) & Chr(10)) response.write("document.write('</frameset>');" & Chr(13) & Chr(10)) response.write("document.write('</html>');" & Chr(13) & Chr(10)) response.write("parent.USERDEFINEDFRAME.location='" & application("SYS.QUIDPROROOT") & "basetable/general/userframe.aspx';" & Chr(13) & Chr(10)) response.write("parent.NAVFRAME.location='" & application("SYS.QUIDPROROOT") & "navigator/top/topnavigation.aspx';" & Chr(13) & Chr(10)) response.write("parent.MAINFRAME.location='" & strRealPage & "';" & Chr(13) & Chr(10)) Else response.write("document.write('<html><head><title>" & session("WINDOWTITLE") & "</title></head>');" & Chr(13) & Chr(10)) response.write("document.write('<frameset ID=QUIDPROFRAME rows=" & Chr(34) & "0,*,25" & Chr(34) & " cols=" & Chr(34) & "*" & Chr(34) & ">');" & Chr(13) & Chr(10)) response.write("document.write('<frame id=USERDEFINEDFRAME framespacing=0 frameborder=0 border=0 name=USERDEFINEDFRAME >');" & Chr(13) & Chr(10)) response.write("document.write('<frame id=MAINFRAME framespacing=0 frameborder=O border=0 name=MAINFRAME >');" & Chr(13) & Chr(10)) response.write("document.write('<frame id=NAVFRAME framespacing=0 frameborder=O border=0 name=NAVFRAME >');" & Chr(13) & Chr(10)) response.write("document.write('</frameset>');" & Chr(13) & Chr(10)) response.write("document.write('</html>');" & Chr(13) & Chr(10)) response.write("parent.USERDEFINEDFRAME.location='" & application("SYS.QUIDPROROOT") & "basetable/general/userframe.aspx';" & Chr(13) & Chr(10)) response.write("parent.NAVFRAME.location='" & application("SYS.QUIDPROROOT") & "navigator/bottom/bottomnavigation.aspx';" & Chr(13) & Chr(10)) response.write("parent.MAINFRAME.location='" & strRealPage & "';" & Chr(13) & Chr(10)) End If response.write("}" & Chr(13) & Chr(10)) response.write("</script>" & 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.


Categories: Code

Error'd: 19999 Below

The Daily WTF - Fri, 27/01/2012 - 22:00

"Mac OS X has an odd definition of gigabyte," writes Kevin Kelly.

 

"I saw this when on holiday to Barcelona," writes Greig Hamilton, "it was a huge screen on La Rambla, the busiest street in Barcelona"

 

Drake wonders, "just what would I be saying 'Yes' or 'No' to?"

 

"Well, apparently it actually is possible to get colder than 0 Kelvin," Dorian H, "and of course I'm right there."

 

"In the end," Mark wrote, "I just ended up spelling out 'thirteen'."

 

Bryan Scott writes "at least it doesn't charge me when they give me thanks for choosing Dell."

 

"I tried to resolve a simple bug submitted to our tracker," writes Michael, "and it clearly didn't appreciate the ease with which this bug was quashed."

 


Categories: Code

Sketchy Skechers.com

The Daily WTF - Thu, 26/01/2012 - 22:00

Imagine yourself as an eager, young developer. After many long months of self-study, you’ve carefully honed your craft and have skillfully mastered virtually all development technologies from enterprisey to hipster. Your twelve-page résumé could land you a job anywhere, and as it would happen, the job you decided to take was at a highfalutin consultancy filled with like-minded developers who were almost as skilled as you.

You and you cohorts could build anything. Literally, anything: a software cure for cancer; a software cure engine that could dynamically load cure plug-ins at runtime to cure anything; or even a software engine factory that could dynamically create engines that could dynamically load plug-ins that could do anything.

And as it so happened, your virtually unbounded skillset was desperately needed to solve an otherwise unsolvable problem: build skechers.com. The requirements for the shoe company’s website were mind-bogglingly complex: retrieve product information from some enterprisey ERP system, format it prettily on the web, and let people place orders online.

Although no one in the history of software development had ever undertaken a project of such scale, you were prepared for anything. In fact, even before hearing what the website would be for, you had already spec’d-out the architecture: use XML-based XSL to transform server-generated XML into XHTML and JavaScript.

Hopefully now you can appreciate the mindset that the developer(s) of Skechers’ website must have had. Their masterpiece can be seen by a simple view-source of skechers.com:

That’s the XML data sent by the server when visiting http://skechers.com/. Your browser then spends a bit of time transforming into HTML and JavaScript using the following XSL:

While the idea of building a website like this in XML and then transforming it using XSL is absurd in and of itself, digging through the code is a treasure trove of WTF. I’m sure there are at least three levels of Hell that are more pleasant than having to maintain this JavaScript-generating XSL code:

<script type="text/javascript"> var skxProduct = {}; var skxStyle = '<xsl:value-of select="$style/@code"/>'; <xsl:for-each select="$style/product"> skxProduct['<xsl:value-of select="@color"/>'] = { color: '<xsl:value-of select="@primary-color"/><xsl:if test="@secondary-color"> / <xsl:value-of select="@secondary-color"/> </xsl:if>', images: [ <xsl:for-each select="media"> <xsl:sort data-type="number" select="@view"/> <xsl:if test="position() &lt; 7"> '<xsl:value-of select="@image"/>' <xsl:if test="position() != 7">,</xsl:if> </xsl:if> </xsl:for-each> ], inventory: [ <xsl:for-each select="sku"> <xsl:sort data-type="number" select="@pos"/> { size: '<xsl:value-of select="@size"/>', <xsl:if test="@type"> type: '<xsl:value-of select="@type"/>', </xsl:if> stock: '<xsl:value-of select="@in-stock"/>', <xsl:if test="@disc"> disc: '<xsl:value-of select="@disc"/>', </xsl:if> price: '<xsl:value-of select="@price"/>', upc: '<xsl:value-of select="@upc"/>' } <xsl:if test="position() != last()">,</xsl:if> </xsl:for-each> ] }; </xsl:for-each> </script>

I shudder at the thought of how labyrinthine the server-side code generating this must be.

I’ve preserved (well, after some indentation/formatting) some of the files for posterity. Just right-click download, then view in your favorite text editor for best experience.

I’m sure there’s plenty more fun examples to be found at all levels of skechers.com; feel free to share them in the comments or send them to me if you think they’d deserve an article of their own.


Categories: Code

Tales from the Interview: The Storage Warehouse, The Most Ethical, and The Customizer

The Daily WTF - Tue, 24/01/2012 - 22:00

The Storage Warehouse (from Grig)
The first recession I remember was in the early 1990’s, and I remember it so well because I was looking for a job. The want ads listed an opening for a UNIX admin – something which was right up my alley – so I gave the company a ring.

“Ye-LLO!” was the greeting after a couple of rings. In the background, it sounded like John Philip Sousa March music was playing on a 1960s AM transistor radio.

“Um… I am calling about the want ad in the paper for a UNIX admin?”

“Yeah yeah, sure sure,” he responded enthusiastically.

After a long pause, I asked “is the position still available?”

“Uh nuh.”

Another long pause led me to ask “So it is?”

“Yah.”

“Would you like me to come in for an interview?”

“Nah, I can do it over the phone,” the sound of a chair squeaking came through the line and the music stopped playing, “Okay… I am looking for someone who can program UNIX. Also, has to know PASCAL pretty well. Processor design. Vast familiarity with X.25 protocol. Some BASIC, ALGOL, Lisp, Borland, relational databases, Lotus spreadsheets, VAX administration, PC repair, all those sorts of things. Oh, and also, have a degree in engineering and computer programming.”

“Um, really? Processor design? What kind of job is this?”

“Well, it’s an assistant manager of a storage warehouse.”

“You mean, like a data center?”

“No, no,” he chuckled, “self-storage. You know, like U-Haul and EZ-Storage.”

“So why would an assistant manager of a storage place need all those skills?”

“They don’t. I am just sick of getting dumbass applicants. I thought I’d raise the bar a little and only get smart college guys and the like.”

I didn't know what to say. I wished him well, and hung up. That ad was up for nearly a year in the want ads.

 

The Customizer (from D Lewis)
When I walked in for my interview, I saw that the receptionist was on the phone so I smiled at her to make my presence known and waited quietly near the back of the room. Looking around, I admired the outdated wallpaper falling off the walls and the non-framed artwork Scotch-taped to the wallpaper. I also couldn’t help but overhear the receptionist’s conversation; it definitely wasn’t business related.

“They better give me my raise,” she said with an attitude, “it’s been three years and I am well overdue.” A few moments later, “mmmkay, well I’ll talk to you later then, I gotta go anyway.”

The experience didn’t inspire a lot of confidence. Eventually, the receptionist let them know I had arrived and the development manager lead me to the board room. She boasted that the company made three million last year, and they were really on a growth path. As she described their application portfolio, she kept mentioning that they’re doing all of their work in Microsoft Access.

“But this is something you’re looking to move away from,” I said inquisitively, “as part of the expansion?”

“Oh no no,” she replied, “Microsoft Access is by far the best model for our company. Here, let me show you why.”

She then pulled out her laptop and navigated to a folder on her drive that had a hundred or so different Access databases. Each was for a different customer and was slightly customized to have proper label names, field names, form fields, etc. A large part of my job would be rolling out “product wide” features to each and every database.

“You know, a .NET-based solution using SQL Server would scale much better,” I explained, “you could use plug-ins, templates, or all sorts of things to keep each customer’s database unique but share a common code base.”

“Well,” she responded, “they already do, we just make sure to copy and paste the same module code across each database. Everyone’s familiar with it, so we’re sticking with Access.”

Shortly after that, the HR Manager walked to discuss other aspects of the job. When he opened up his briefcase, a Knife, Fork and Spoon fell out onto the table, making a loud clanking noise. “The cleaner has a habit of stealing silverware,” he quipped, “so, I tend to bring my own.”

By this point, I had decided there was no way I’d ever work at such a place. Of course, I was too shy to walk out, so I let the HR manager give his spiel.

“We have had a problem with people leaving prematurely,” he said, “so you would need to sign an agreement that you’ll work here for two years.”

I said nothing.

“But after that, we give great raises.”

 

The URL Rewriter (from Jon)
Despite overseas developers getting some bad press now and then, one has to feel sorry for the working conditions they must have to put up with. According to this guy's CV not only did he have to code on paper, but they also made him stand in for the web server some of the time.

Responsibilities: * Coding in C#.net (asp.net). * Written Java Script functions, bug fixing. * Url rewriting.

 

The Most Ethical (from Fred Rosenberger)
“We’re different than all the rest,” the smiling account manager at a recruiting agency told me, “we pride ourselves on being the most honest and the most ethical of all placement firms.” That same line was repeated by nearly everyone I met at the organization: the technical interviewer, the senior headhunter, and even the president himself.

They all seemed nice enough, but in a nice used car salesman sort of way. As we reviewed different job openings they were trying to fill, one in particular was seeking a candidate with an Electrical Engineering degree who had moved over into software.

“You mentioned that your father was an Electrical Engineering professor for thirty-five years, right?”

I nodded, not sure where that was going.

“Well, I’m sure in all those years you learned a thing or two about Electrical Engineering? I mean, how could you not with your father talking about it so much.”

I furrowed my brow a little bit.

“Let’s figure out a way to get your father’s experience in Electrical Engineering on your resume – that’ll certainly get you past HR and score an actual interview.”

I almost laughed out loud. Not wanting to get in an argument with them, I made some excuses that I didn’t want to drive that far. In retrospect, they still may have been the most honest and the most ethical of all placement firms.

 


Categories: Code

CodeSOD: Globally Coupled

The Daily WTF - Tue, 24/01/2012 - 00:15

"I work on a team maintaining a large and enterprisey PHP system," writes Amber, "and as such, my job mostly involves doing enhancements and fixing bugs."

"It sounds normal enough, if not for the fact that almost all variables are globals and each of them might or might not be initialized in the same way, or the same place, as seen in this screenshot."

"That's tolerable, but the real problem arises when I need to reuse a function in a different location. I've added line breaks and formatting to make some sense of things..."

global $dbCon; $dbCon->InitOpen($cf_db, 'db1'); .... snip a few hundred lines .... function getRanking () { global $dbCon, $dbCon_test, $dbCon2, $cf_db; include '../rtuser/rtutil.php'; $dbCon_test-> InitOpen($cf_db, 'db2'); ..... snip .... /* rt_rank() requires $dbCon as db connection to testdb * in this context, $dbCon currently points to Db1 thus * temporarily pointing $dbCon to testdb is necessary (fred) */ $tempdbConDb1 = $dbCon; //assign $dbCon_test to $dbCon to have testdb connection $dbCon = $dbCon_test; $memcacheKey = 'hof_ranking_' . $cntr . ':' . $offset; //call rtutil.php's getrtRank() // cache db r in memcache for 5 minutes $r = unserialize(getMemCache($dbCon2, $memcacheKey, '5 minute', 'getrtRank', $args)); //swap back $dbCon so that the code relying on $dbCon pointing to Db1 won't be affected $dbCon = $tempdbConDb1; include '../rateuser/rateutil.php'; ... snip ... /* rate_rank() requires $sql as db connection to testdb * in this context, $sql currently points to gm thus * temporarily pointing $sql to testdb is necessary (fred) */ $tempSqlGm = $sql; //assign $sql_test to $sql to have testdb connection $sql = $sql_test; $memcacheKey = 'hof_ranking_' . $cntr . ':' . $offset; //call rateutil.php's getRateRank() $result = unserialize(getCacheInfo($sql2, $memcacheKey, '5 minute', 'getRateRank', $args)); list($uidlist, $nicks, $votes, $imageIds, $genders) = $result; //swap back $sql so that the code relying on $sql pointing to gm won't be affected $sql = $tempSqlGm; //.... }

Amber continues, "what happened here was that, in file A, a global database link identifier pointed to database 1 but in the include file B, the same variable was supposed to point to database 2. What I did was to swap out the link identifier whenever a function in file B was involved, then swap back whenever a function in file A was involved. Injection was not an option as the Globals were so deeply and variably coupled that decoupling them needs to be done on a case-by-case basis. And that was just one place...


Categories: Code

Error'd: Sponsor Appreciation, SQL Scourge, and More Error'd

The Daily WTF - Fri, 20/01/2012 - 23:00

We've got some great companies that sponsor The Daily WTF. And all they ask in return... just take a moment or two to check out what they do. It's some pretty cool stuff.

TDWTF Sponsors Singlehop Logo   SingleHop Cloud Instances 98% off - Design, deploy and manage your cloud instance on the public cloud for only $1 for your 1st month (normally $50/month!) Use your Cloud Instnace to test new code, experiment with new software or gain extra development time...it's your choice! Try it today with coupon code "CLOUD1". New Relic   New Relic is basically a magical, real-time performance and user monitoring tool that works on virtually any web platform: Java, Ruby, PHP, .net, Python, Ruby on Rails. I'm not sure how it works (magic?), but it's incredibly easy to use and is pretty inexpensive. Remember: performance is a must-have feature! New Relic   Monetate - their testing, targeting and personalization platform for online retailers is used on leading websites like Best Buy, Sports Authority and Urban Outfitters. If you’re a problem-solver who is passionate about rich web applications, scaling Internet applications to billions of page views, and working with big data, then you’re a perfect fit for our close-knit and agile team.! BuildMaster   Inedo - the makers of BuildMaster, the free, and easy-to-use, web-based deployment and release management tool. Going far beyond Continuous Integration, BuildMaster delivers a series of robust features unparalleled by other build-promote-deploy-distribute tools. Oh, did I mention it's free? Singlehop Logo   Amazon DynamoDB - is a fully managed NoSQL database service that provides fast and predictable performance with seamless scalability. With a few clicks in the AWS Management Console, you can launch a new Amazon DynamoDB database table, scale up or down request capacity for the table without downtime or performance degradation, and gain visibility into resource utilization and performance metrics.

And now for our regularly scheduled program...

"When filling out a web health assessment, I'm pretty sure I didn't mention the scourge of %_SQL_TEXT that runs in my family," writes Josh Ward, "it's an embarrassing condition, to be sure!"

 

"I knew Ikea carried a lot of stuff, but a Petabyte is bigger than I expected," Nero Imhard, "still, I waited until I was within WiFi reach before proceeding."

 

"I got this while trying to start DBArtisan," writes Willy, "is it telling me or asking me?"

 

"I read that the HTC Thunderbolt has great download speeds but poor battery life," Andrew writes, "but I noticed that the clocks are a little out of sync. Maybe I can find an app that syncs both clocks to the correct time."

 

Erkki Laite found this in his local paper, the Finnish Turun Sanomat on 02.11.2011.

 

Jim Moyle spotted this on the front page of booking.com.

 

"I guess if someone at the mall searched to find where multi(0)disk(0)rdisk(0)partition(1) was, the directory would have been correct," writes Darin Rousseau.

 


Categories: Code

CodeSOD: Pluralized!

The Daily WTF - Fri, 20/01/2012 - 01:00

"When digging through some code that was on the refactor list, I came accross some validation logic that checks if the user selected enough options on the form," writes Chris Osgood, "if enough options weren't selected, you'd get an error message along that said something like 'at least 3 options are required'."

"It took a little bit of coding to get that validate message. The '3' was obviously dynamic, and if there was only one missing selection, then 'are' was replaced with 'is'. As for the word 'option'...it was is PLURALIZED!"

/// <summary> /// Changes a singular string to plural e.g. "Monkey" => "Monkeys". /// </summary> /// <param name="text">The text to PLURALIZE!</param> /// <returns>A plural string.</returns> public static string Pluralize(string text) { if (text.Length == 0) { return text; } string result = text; if (result.Equals("sheep", StringComparison.OrdinalIgnoreCase)) { return "sheep"; } else if (result.Equals("leaf", StringComparison.OrdinalIgnoreCase)) { return "leaves"; } else if (result.Equals("thief", StringComparison.OrdinalIgnoreCase)) { return "thieves"; } else if (result.Equals("potato", StringComparison.InvariantCultureIgnoreCase)) { return "potatoes"; } else if (result.EndsWith("y", StringComparison.InvariantCultureIgnoreCase) && !result.EndsWith("ey", StringComparison.InvariantCultureIgnoreCase)) { // Don't pluralize "by" if (result.Length > 2 && !result.EndsWith(" by", StringComparison.InvariantCultureIgnoreCase)) { result = result.Truncate(result.Length - 1) + "ies"; } } else if (result.EndsWith("us", StringComparison.InvariantCultureIgnoreCase)) { // http://en.wikipedia.org/wiki/Plural_form_of_words_ending_in_-us result += "es"; } else if (result.EndsWith("x", StringComparison.InvariantCultureIgnoreCase)) { result += "es"; } else if (!result.EndsWith("s", StringComparison.InvariantCultureIgnoreCase)) { result += "s"; } return result; }

Chris continued, "naturally, this was the only usage of this otherwise highly useful function. We could have easily utilized this function to pluralize things like foots, tomatos, boies, wifes, and etc.!"


Categories: Code

Defeating SOPA and PIPA Isn't Enough

Coding Horror - Thu, 19/01/2012 - 07:00

SOPA and PIPA are two pieces of proposed legislation designed to "stop" Internet piracy… in the most hamfisted way imaginable. As Mitchell Baker explains:

Assume there's a corner store in your neighborhood that rents movies. But the movie industry believes that some or even all of the videos in that store are unauthorized copies, so that they're not being paid when people watch their movies. What should be done?

SOPA/PIPA do not aim at the people trying to get to the store, or even the store itself. The solution under the proposed bills is to make it as difficult as possible to find or interact with the store:

  1. Maps showing the location of the store must be changed to hide it.
  2. The road to the store must be blocked off so that it is difficult to physically get to there.
  3. Directory services must delist the store’s phone number and address.
  4. Credit card companies would have to cease providing services to the store.
  5. Local newspapers would no longer be allowed to place ads for the video store.
  6. To make sure it all happens, any person or organization who doesn’t do this is subject to penalties. Even publishing a newsletter that tells people where the store is would be prohibited by this legislation.

    Just substitute "corner store" with "website" and I think you can see where this is going. These bills are so rife with potential for abuse and misuse, so clearly dangerous to the very fabric of the Internet, that frankly I have a hard time getting worked up about them. The Internet is under constant siege by large companies, and will be for the forseeable future. This is nothing new. These bills will be defeated, because they must be.

    Instead, I'm scratching my head and wondering how such boneheaded bills made it this far in Congress. I can think of a few reasons:

    • Average people don't understand how the Internet works and thus can't comprehend the danger.
    • Nobody pays attention to what our government does until it hits them in the pocketbook (or below the belt).
    • These bills were pushed through by highly paid lobbyists for the entertainment industry.

    I often bemoan the state of Slacktivism on the internet, where changing your Facebook or Twitter picture is considered a valid and effective form of protest. But this time, I am happy to say, was indeed different.

    Perhaps because of the obvious danger of these bills, geek websites and communities banded together weeks ago to protect themselves and the greater Internet. Like many other technical communities, we wrote about it on our blog, talked about it on our podcast, and even put up a little banner on Stack Overflow for a day. Users were encouraged to call, fax, and write their representatives in Congress and express their concerns. And they did, in droves! But outside of our technical geek ghettos, there was precious little mainstream coverage of this dangerous legislation.

    That is, until major sites like Wikipedia, Google, and Craigslist joined the bandwagon today. Most notably, Wikipedia actually went dark for all of today, January 18th, rendering all of English language Wikipedia inaccessible. That turned the tide, and transformed SOPA/PIPA into something that average people would actually talk about and care about. There's no better way to raise awareness of the danger these bills pose than blacklisting one of the greatest resources the Internet has ever produced.

    Wikipedia

    While SOPA/PIPA are still alive -- barely -- for now, I think it's safe to say that they are well on their way to defeat. I'm glad to be a part of that, however tiny, but I cannot in good conscience celebrate.

    Yes, we likely succeeded in defeating these two specific bills and galvanizing the political will of major Internet communities, including our very own Stack Exchange. These are good and noble and just and necessary things. They are things to be proud of. But instead of celebrating, let's take this time to reflect and ask ourselves a deeper question: how is it that these dangerous bills came to exist in the first place?

    First, and again, this is a critical battle to wage and win. SOPA is just the latest, but in many ways, the most absurd campaign in the endless saga of America’s copyright wars. It will be yet another failed attempt in a failed war, and I obviously believe it should be opposed.

    But second, and as you describe, this isn’t my war anymore. Not because my heart isn’t in it, but because I don’t believe we will win that war (or better, win the peace and move on) — even if we can win battles like this one — until the more basic corruption that is our government gets addressed. That’s the fight I have spent the last 4 years working on. That’s where I’ll be for at least the next 6.

    For this is what I know: We will never (as in not ever) win the war you care about until we win the war against this corruption of our Republic.

    Republic-lost-cover

    Of course, as my book, Republic, Lost: How Money Corrupts Congress -- and a Plan to Stop It, describes, this is an insanely difficult, possibly impossible, fight. But whether difficult or not, it is the fight that must be waged.

    We have done much. But in our celebratory enthusiasm, please take a moment to hear out Mr. Lessig, and appreciate just how far we have yet to go.

    So yes, join us in fighting the obvious insanity of legislation like SOPA and PIPA that threaten the open, unfettered Internet. But please, please also join us in attacking the far more pernicious problem of lobbyist money subtly corrupting our government. If we don't deal with that, we will never stop fighting bills like SOPA and PIPA.

    [advertisement] What's your next career move? Stack Overflow Careers has the best job listings from great companies, whether you're looking for opportunities at a startup or Fortune 500. You can search our job listings or create a profile and let employers find you.

Categories: Code

Support The Daily WTF in Supporting the Support SOPA Movement

The Daily WTF - Wed, 18/01/2012 - 13:00

It’s January 18, 2012 and, while most of the internet has decided to blackout their sites in opposition to the Stop Online Piracy Act (SOPA), we’re taking an opposite stance and are whiting-out The Daily WTF in support of SOPA supporters.

If there’s one thing that SOPA proponents like myself and SOPA opponents can agree on, it’s that PROTECT-IP and the Stop Online Piracy Act have little to do with protecting intellectual property and stopping online piracy.

After all, those who choose to steal creative works like the “I Have a Dream” speech from artists like Martin Luther King Jr. can already be sued and prosecuted under existing United States copyright laws. IP thieves living overseas can already be extradited to face justice in our federal courts. And the Department of Homeland Security can already arbitrarily seize domain names that fit its arbitrary standard of violating national something-or-other.

While these laws will make such acts more illegal (and therefore reduce infringement), they’re doing something much, much more important: helping dismantle DNS and the internet as we know it. And that’s something that we firmly support and can stand by.

You see, back in the day, if you wanted to get online and access electronically-stored information like digitized photographs, electronic bulletin boards, and informational databanks, there was only one thing you needed: a telephone number. You’d simply fire up your favorite telecommunications program (mine was Telix), have it dial that phone number, and after a refreshing symphony of beeps and hisses, you were online.

Each phone number transported you to a quaint, peaceful community that was almost entirely self-sufficient. There was no “hyperlinking” between systems: you simply wrote down the phone number, signed-off of the current system, and then dialed into the new system. And let me tell you, there are few experiences in life that can parallel the utter bliss of discovering a new phone number and a new electronic resource.

And then the Information Superhighway – and its tightly integrated Domain Name System – came along, decimating these peaceful, independent communities. The bulletin boards of old were ground up and churned in the giant “dot com” machine, leaving an interconnected web of domain names. There’s no more “going online” – you’re already online – and if you want to access an electronic resource, you can use a “domain name” like TheDailyWTF.com.

Domain names are highly confusing in that they not only describe what the electronic resource is, but where it is as well. Nothing else in the world works like this for obvious reasons. Could you imagine the complete confusion in day-to-day things like getting a phone number? Is that “jenny eighty-six dot com” or “jenny eighty-six dot net”? We would be in complete chaos.

SOPA and PROTECT-IP offer hope in returning to the golden age of telecommunications, and to the days before the Information Superhighway polluted the online culture with this domain name nonsense. Let the Domain Name System a natural death and prepare yourself for the Internet Protocol Number (IPN) renaissance. All you need to do is start a notebook that lists electronic resource names and their corresponding IPN. And let the first entry in your notebook be

The Daily WTF 74.50.110.120

We can only hope that our legislators introduce common sense guidelines to ban HTTP (and HTML/JavaScript) as well so we can all return to the more sensible GOPHER standard.

Update 2012-01-19 00:01 - thank you all for supporting the Support The Daily WTF in Supporting the Support SOPA Movement article! In case you missed it, any request simply to content on thedailywtf.com served up this:

Things should be restored to normal (in theory), and note that the server IP did actually change from 74.50.106.245 to 74.50.110.120. If you are still hitting the old server, your DNS is a little behind in catching up to the change.


Categories: Code

Terrorists!

The Daily WTF - Wed, 18/01/2012 - 01:00

“She’s convinced that terrorists have compromised her computer,” Tom Davidson’s colleague – a front-line helpdesk technician – reported, “best I can tell, it’s some sort of virus problem, or something. It’s is a bit out of my league, but I’m hoping you can help.”

As a junior sysadmin for a mid-sized university, Tom found himself playing second-tier helpdesk support more often than not. He didn’t mind – it was certainly better than first-tier, after all – and he appreciated solving the unique problems that were escalated to him. The terrorist virus was definitely one such problem, and it was nothing he had heard of before.

He opened up the ticket the ticket report to see what sort of troubleshooting the technician was able to do.

****************************************************** * TICKET #APX-914321 *OPEN* 2001-05-13 * ****************************************************** * * * ASSIGNED : Tom Davidson * * DEPT CODE : T2-SUP * * CUSTOMER : Wendy G------ * * HARDWARE : Standard Desktop D8-AM6 * * RESOLUTION: * * * * * * __ ISSUE __ * * * * The user reports that her computer may have been * * compromised by hackers or terrorists. * * * * __ TROUBLESHOOTING __ * * * * #2001-05-13 9:33 AM # * * For the last few days, whenever she is using any * * Microsoft product -- Word, Outlook, even Excel - * * her screen will suddenly start filling up with * * text. Most of it will be gibberish, but there * * are frequent references to guns and bombs and * * terrorists. She believes it's a person and not a * * virus, as there are sometimes were weird ref- * * erences to local news. * * * * Her computer is currently turned off. Perhaps * * sensibly, she will not turn anything on until a * * technician physically disconnects it from the * * network. I will visit ASAP. * * * * * * #2001-05-13 11:18 AM # * * When I arrived, the computer was still turned on * * but the monitor was turned off. She left open * * Microsoft Word, and there was indeed lots of * * gibberish on the screen. I shut down and ran a * * full scan off boot. No problems reported. I * * could not find any evidence of any problems, and * * the problem would not appear when I was there. * * * * * * #2001-05-16 10:03 AM # * * The user called again, and said that the problem * * started happening again in Microsoft Excel. I * * advised her to not touch a thing, and I headed * * over immediately. I was able to observe the * * problem first-hand. After disconnecting network, * * problem still occurred. I opened up Notepad, and * * noticed text continued to be entered. Most is * * gibberish, but the intelligible text and words * * implies that it's not bad keyboard, etc. * * * ******************************************************

Tom was intrigued. He called up the end user to say that he’d be over in just a bit. He wandered down to her office, one of those cozy professorial spaces packed tight with decades of accumulated unlabeled folders and empty tea tins, and tried repeatedly and unsuccessfully to reproduce the problem. The soft instrumental music on the radio soothed him a bit, but he definitely was getting a little frustrated. She felt it, too, and practically shouted: “I’m not crazy! I don’t understand! Usually whenever I open anything, they start right up!”

And at that moment, the words appeared. “Stand, you silly. We never eye a penny thing they start. Dry up.”

The classical piece on the radio came to a conclusion, and the announcer let listeners know that they had been listening to Bach. So did Notepad, although it spelled it “Bock” and said something about the “fast circling wagons” instead of “last symphony”. and it otherwise did a pretty good job.

It took another couple of minutes to figure out how to turn off Speech Recognition, since it wasn’t a feature that Tom – or quite obviously the user – had knowingly used before.


Categories: Code

Coded Smorgasbord: Schizophrenic Haiku Comments and More

The Daily WTF - Mon, 16/01/2012 - 22:00

"I found a schizophrenic comment that either intentionally or unintentionally happens to be a haiku," wrote Ben Vanik, "svn blame says this single line is the work of 3 different people across 3 years of coding."

// should delete the temp files here, no cannot because, we havent read it in yet!

 

"I'm modifying some firmware for a product that has a serial connection," Fahrzin Hemmati writes, "this was found in the method that translates the incoming data into useful bytes."

//Clear it, or it, smack it, flip it, rub it down //(Oh nooooo...) mem[iAddress] &= ucClearBit; mem[iAddress] |= ucAssignBit;

 

"How do you feel when you see this code on the first day of your job?" wonders Ritesh

#define EIGHTY 256

 

"I found this piece of java code in our corporate directory," writes Peter S, "two of our JUnit test classes end in this method. I do not know if these were intended phuns/easter eggs."

@Test public void testNothing() { assertTrue("Assert just to keep JUnit happy!", true); }

 

"When debuging some client code I came across this," wrote Blair, "tmpnum8 was wrong. Now I just have to figure out what all the other tmpnums are..."

tmpnum6 = tmpnum2 + tmpnum * (tmpnum4 - tmpnum2); tmpnum7 = tmpnum3 + tmpnum * (tmpnum5 - tmpnum3); tmpnum8 = tmpnum6 + tmpnum1 * (tmpnum7 - tmpnum6);

 

"The previous developer on our OBIEE environment had some interesting ways of developing queries," wrote Bart, "not only did he not know about Oracle functions like NVL(), requiring him to write everything using lengthy CASE statements, also using joins seemed out of the question. This code is een excerpt from a _large_ view unioning large blocks of codes like this to eachother. I also like how he did code reuse, he copied large pieces of code to different views."

SELECT decode(authorization_kd, 3,3, 4,3, 6,3, 7,3, 34,3, 55,3, 57,3, 58,3, 24,4, 10,4, 11,4, 21,4, 71,4, 36,4, 37,4, 38,4, 13,4, 14,4, 84,4, 53,4, 15,4, 33,4, 31,4, 32,4, 09,5, 12,6, 52,6, 54,7, 19,8, 20,8, 79,8, 99,8, 9) process_kd FROM dossier WHERE authorization_kd NOT IN (1, 30, 35, 85, 86, 87, 16, 17, 18)

 

"Starting a work in a project is always a kind of challenge," notes Wiadran, "if the project is developed for years and written mostly in ASP classic... it might become a nightmare. Nevertheless, projects developed for years have some bright side as well: parts of not-understandable code and commentaries."

For intI = 7450 To 7450 'Now lets go and create the f*&ker ... snip... Next

 

Jimmi found yet another wrapper for the illusive '!' operator.

private static bool InvertBool(bool org) { bool returnValue = false; if (org) { returnValue = false; } if (!org) { returnValue = true; } return returnValue; }

 

"How many naming conventions can you find in the following line of code?" writes Malcom

StandardResponse UnSubscribeNewsletterUserAccount( string opTinGUID,string email, string sellingRegion, string source, DateTime opt_out_date, string strevent, string reason);

 

"While diving through some old code I'm maintaining, I found this jewel," Frank writes from the Submit-To-WTF Visual Studio Add-In, "Not only is this snippet a part of a rather intricate XML merge system, but it also merges the XML by string operations. To add insult to injury, the XML is not possible to define in a schema (as elements have to occur in certain patterns, while the name of the only valid elements in the XML 'schema' is either FLD or REC. The types of REC depends on the NAME attribute, and it is the NAME attribute that ultimately decides the order of the REC elements in the document. In other words, a truly fubar mess."

// Dear future developer(s): // I have no idea who actually came up with such a glorious violation of the // XML definition, but legacy systems being legacy systems means that we can't // switch this. // I feel for you, young padawan; I'd rahter kiss a wookie than mess with this. if (line.IndexOf("REC NAME=\"Hovednivå\"") <= -1) continue;

 


Categories: Code

Classic WTF: Rutherford, Price, Atkinson, Strickland, and Associates Dentistry, Inc

The Daily WTF - Thu, 12/01/2012 - 22:00

I'm at CodeMash today (stop by the Inedo booth if you're there!), so I thought it'd be a great time for this classic. Rutherford, Price, Atkinson, Strickland, and Associates Dentistry, Inc was originally published on January 30th, 2008.

Dr. Rutherford July 19th, 2004 marked a new chapter in New Portlandopolis’s rich dentistry history. It was on that day that the bitter rivalry between Dr. Rutherford, DDS; Dr. Price, DMD, DDS; Dr. Atkinson, DMD; and Dr. Strickland, DDS/DDS-PhD, had finally come to an end. Though there’s much debate on what exactly started the feud, everyone knows what brought the dentists together: the nationwide “denta-corps” that can out-price, out-service, and out-anything their small, family dental practices.

Although the partnership talks had begun years before, July 19th was their agreed-upon D-Day, wherein the four separate practices would officially combine to be Rutherford, Price, Atkinson, Strickland, and Associates Dentistry, Inc. In the months leading up to D-Day, and after much bickering and debate, the four dentists got everything ready from new signage to new logoed toothbrushes. The only thing that remained was combining their computer systems. That task was left to Aaron B, an IT consultant who had the pleasure of working with each office through many of the “ugly years.”

Fortunately for Aaron, each of the dentists used the same practice management system: Beaglesoft’s Practice EnterprisePlus. It certainly wasn’t the best software, but it was among the most expensive. Perhaps more-importantly, Beaglesoft offered all sorts of outrageously-priced add-ons that the dentists could buy to one-up one another. For example, a wand-shaped oral camera required a $7,000-per-site “camera driver,” in addition to the ungodly amount the camera cost in the first place. When Aaron plugged the camera into his laptop (which didn’t have any Beaglesoft software running), it was recognized as a plug-and-play camera and immediately started streaming video. Not that it mattered though; as soon as Dr. Price had his installed, the other three dentists had to get one as well. 

“While our prices might seem high,” a Beaglesoft rep once told Aaron, “keep in mind that you’re paying for quality. Our products are rigorously tested to work in today’s and tomorrow’s high-tech dental office.”

And for that reason, Aaron wasn’t too worried about Beaglesoft’s portion of the D-Day migration. They assured him on several occasions that their latest and greatest – Beaglesoft Practice EnterprisePlus Elite with Networking – could network a “virtually unlimited” number of practices. The four Aaron was linking together was “chump change” compared to what the system could do.

When Friday, July 16th – the weekend before D-Day – had finally come, the dentists were ready. They closed their offices at noon and, per Beaglesoft’s instructions, initiated the migration process. Over the next twelve hours, so the plan went, each practice’s system would upload its data to the Central Server at Dr. Strickland’s office. Naturally, none of the other dentists were too thrilled about having a “Central Server”, especially one at Dr. Strickland’s.

Aaron arrived at Dr. Strickland’s office early Saturday morning to find a surprising message on the server: “Migration Completed Successfully.” He ran through some initial smoke tests and it appeared that the migration did, in fact, complete successfully. After a trip to the other three dentist offices, Aaron verified that he could access any patient’s file from any office. He called up the four dentists to share the good news: come Monday, they should be in business.

Monday came and, shortly thereafter, the four offices were out of business. The system had completely grinded to a halt. Every click of the mouse was met with a several-minute delay, and every delayed response was met with more clicking. Aaron, who happened to be on-site “just in case,” immediately suspected the newly-installed T1 lines.

Aaron called up the phone company. They ran a few diagnostics on their end, only to find that each office’s T1 line was completely pegged. Most certainly, the technician claimed, the problem was on their end. Perhaps a router gone haywire?

Aaron checked and rechecked the switches, the hardware, the ports, and the routers. He rebooted once, twice, and thrice. Everything seemed functional, aside from the fact that the Central Server was firing packets off non-stop.

Not sure what else to do, Aaron bridged his laptop between the Central Server and its switch. Within seconds, he logged hundreds of megabytes of data, far too much for anyone to go through in the middle of such a crisis. He had no choice but to take the “satellite” dentists offline to investigate the problem. They grew suspicious of this and, of course, Dr. Strickland, and demanded that there was foul-play involved.

With only a couple users accessing the Beaglesoft system, Aaron was able to get a handle on the traffic. As he assuaged the other dentists over the phone, Aaron noticed that a lot of the data seemed to be coming from SQL Server. Specifically, it was from queries like this:

 SELECT * FROM Patients

Digging further, Aaron figured out that, whenever a user wanted to look up a patient, the program would run “SELECT * FROM Patients” query, returning the entire Patients table to the client computer.

What’s worse, the query would run any time a character was typed in the patient search box. Searching for just his first name – A-A-R-O-N – resulted in five SELECT * queries.

What’s still worse, the same method of client-side filtering was used for appointments. It wouldn’t just get, say, today’s appointments. Or this week’s. Or, say, any that haven’t happened yet. It would query for every appointment that they ever had or would have in the future. That’s about 100,000 rows.

And since each appointment involved a patient, it’d have to fire off queries for each appointment to download and filter information about the patient.

It was apparent that Beaglesoft’s “rigorous testing” of “Practice EnterprisePlus Elite with Networking” involved, perhaps, a single computer and two, maybe three patient records. He immediately called Beaglesoft to report their issues and a demand a resolution.


(an actual screenshot from Beaglesoft’s install directory)

Within a few hours, three of Beaglesoft’s finest were on a plane to New Portlandopolis. When they arrived, two of them split off to work on “de-migrating” the system into the original four databases. The other Beaglesoftie, a product manager, worked on “damage control” – and boy did she have a lot of damage to control.

By that time – ten hours into Rutherford, Price, Atkinson, Strickland, and Associates Dentistry, Inc’s first day – the dentists were at each other’s throats. Dr. Price blamed the mess on Dr. Strickland who was “online the entire time, ” while Dr. Strickland was convinced that Dr. Atkinson had somehow “spiked the T1s,” while Dr. Rutherford believed that Dr. Price “wanted to retire, and was bringing everyone else down.” Eventually, Dr. Atkinson stormed out and tore down the new "Rutherford, Price, Atkinson, Strickland, and Associates Dentistry, Inc" sign. As he stomped the sign into pieces, he vowed never to work together again. Things pretty much went downhill from there.

After things cooled down a bit with the dentists, the product manager met with Aaron. Angered that his future prospects looked like a repeat of the “ugly years”, he lambasted Beaglesoft’s latest and greatest, and asked why, oh why, they couldn’t have done some client-side caching. Or, at the very least, use the magical WHERE clause.

She was astonished by Aaron’s technical knowledge and eagerly asked more questions on “WHERE clauses and other optimization techniques.” Near the end of their conversation, she actually offered Aaron a job as a Lead Developer at Beaglesoft.

Aaron ended up declining the position. He figured that they’d never be willing to tar and feather the existing development staff. That, and after the Beaglesoft Fiasco of 2004 (as it’s called today), he’d have a lot of cleaning up and intra-dentist diplomacy to do. Besides, how could he miss taking part in the latest exciting chapter in the dentistry history of New Portlandopolis?


Categories: Code

CodeSOD: The XML Escape

The Daily WTF - Wed, 11/01/2012 - 22:00

"One day, our logistics analysis vendor interface completely broke down," wrote Ben Davis, "that's a Bad ThingTM, as our primary focus is to provide logistical services to our clients."

"Fortunately, it didn't take too long to track the problem down. Our vendor was sending over unescaped ampersands in their XML API."

<customer_name>Brandon & Sons</customer_name>

"When I reported the problem to them, they responded rather curiously: technically, we are sending back valid XML as the ampersand does not necessarily need to be escaped.

"I pointed them to the XML specification along with a simple request to encode their XML properly. Instead, they responded with this. Is there something else we can switch it to on our side that you could look for and replace on yours? I.e. some kind of flag character we use in place of an ampersand? What about a $ symbol? So, if there's a $ sign in the name, you could convert that to an ampersand. On our side, we'll convert the ampersand to a $ sign and pass it over like that. Then your piece would do a search/replace on the account name and replace the $ with an ampersand?"

"Long story short, it was absolutely impossible for them to do a multi-character replacement... and somehow none of this is an issue for any of their other users. Oh, and now I'm replacing $ with ampersands in our code."


Categories: Code

The Shredder

The Daily WTF - Tue, 10/01/2012 - 23:00

The company break room was, well, a company break room. Dull grey walls, acoustical tile dropped ceiling, burned coffee and a motivational poster featuring a sun setting over a beach. Leo sipped his coffee, pulled a face at the bitter taste, and muttered to Mike, "This sucks."

The Carribean island of Curaçao is known for sandy beaches, oil refining and open-air brothels. It's also notable for being a key junction where fiber lines from around the world branch off through the Americas. That last bit means that it's a popular location for running global datacenters. Leo's employer was a global business, and had not one, but two datacenters located on the island. The production datacenter handled millions of dollars of transactions every day. The backup datacenter didn't- in fact, it was being decomissioned, starting on this particular Monday.

Leo had been looking forward to decomissioning for months. The company scheduled a week for someone to run a disk shredder and pack the machines away into boxes. That basically amounted to a week long Carribean vacation, and Leo had seniority- in theory, that cushy gig was his.

It was a wonderful theory, but having seniority also meant having real work. Leo only loitered in the breakroom for a moment, dreaming of Curaçao, and then got back to the work of administering the IT resources of a global company. Leo, and his aides Mike, Rafe, and Don, were far too busy to jaunt off for a week in the Carribean. Instead, they needed to send someone they could spare. Someone who had nothing to contribute to their daily operations, but who could handle the simple task of booting machines off a thumb drive, waiting on a beach, and then boxing them up, and then waiting. On a beach.

They needed James Avery (A+, NET+, Security+, MCSE, MCSE+I, MCP, CCNA, CCNP). James had "worked" for the company since before Leo started, and would likely continue to "work" there long after. He was that peculiar class of over-certified dead weight that burrowed into an IT organization like a candiru. James was the sort of guy that felt putting the SQL Server Databases on the Internet-facing side of the firewall was fine- Windows security was really strong! He couldn't explain the difference between TCP and UDP, but he could hang every certification he ever got on the wall of his cube.

In its own weird way, sending James off to Curaçao was a bit of a vacation. Sure, Leo was stuck in the office, commuting into work in the dead of winter, but at least he didn't have to clean up after James's mess. For a week, James couldn't cause a single problem, because he'd be destroying HDDs in the backup datacenter.

Leo's phone dinged. He set his coffee down and checked his SMS alert. Before he even had it out of his pocket, it dinged three more times. A flood of texts from their monitoring system paralyzed his phone. Servers were going down, left and right. All of them.

Leo called the production DC even as Mike called the backup DC. James had never arrived at the backup DC, Mike learned. But he had definitely showed up at the production datacenter. James Avery (A+, Net+, Security+, MCSE, MCSE+I, MCSA, MCP, MOS, CCNA, CCNP, CCDE, SCSAS) had gone to the wrong address. He had flashed his ID badge, and without thinking once, let alone twice, he had started rebooting everything in a rackmount using the disk-shredding thumbdrive he brought with him.

The end result was a 24 hour outage, and a new nickname for James Avery (A+, Net+, Security+, RHCSA, MCSE, MCSE+I, MCSA, MCT, MCP, MOS, CCNA, CCNP, CCDE, SCSAS): "The Shredder". "The Shredder" didn't lose his job, but his co-workers didn't let him live down the mistake. They made it a habit of relocating the office paper shredder to his cube. He made a habit of complaining to HR about it.

Eventually, "The Shredder" had enough of this treatment, and left the company. He now adminsters the Windows network at the local nuclear power plant.


Categories: Code
Syndicate content