Last minute geek

last minute tech news from around the net

Sunday, Apr 22nd

Last update01:00:00 AM

You are here: English WTF

WTF

Error'd: Placeholders-a-Plenty

"On my admittedly old and cheap phone, Google Maps seems to have confused the definition of the word 'trip'," writes Ivan.

 

"When you're Gas Networks Ireland, and don't have anything nice to say, I guess you just say lorem ipsum," wrote Gabe.

 

Daniel D. writes, "Google may not know how I got 100 GB, but they seem pretty sure that it's expiring soon."

 

Peter S. wrote, "F1 finally did it. The quantum driver Lastname is driving a Ferrari and chasing him- or herself in Red Bull."

 

Hrish B. writes, "I hope my last name is not an example as well."

 

Peter S. wrote, "Not sure what IEEE wants me to vote for. But I would vote for hiring better coders."

 

"Well, at least they got my name right, half of the time," Peter S. writes.

 

[Advertisement] Forget logs. Next time you're struggling to replicate error, crash and performance issues in your apps - Think Raygun! Installs in minutes. Learn more.

Read all

CodeSOD: A Problematic Place

In programming, sometimes the ordering of your data matters. And sometimes the ordering doesn’t matter and it can be completely random. And sometimes… well, El Dorko found a case where it apparently matters that it doesn’t matter:

DirectoryInfo di = new DirectoryInfo(directory);
FileInfo[] files = di.GetFiles();
DirectoryInfo[] subdirs = di.GetDirectories();

// shuffle subdirs to avoid problematic places
Random rnd = new Random();
for( int i = subdirs.Length - 1; i > 0; i-- )
{
    int n = rnd.Next( i + 1 );
    DirectoryInfo tmp = subdirs[i];
    subdirs[i] = subdirs[n];
    subdirs[n] = tmp;
}

foreach (DirectoryInfo dir in subdirs)
{
   // process files in directory
}

This code does some processing on a list of directories. Apparently while coding this, the author found themself in a “problematic place”. We all have our ways of avoiding problematic places, but this programmer decided the best way was to introduce some randomness into the equation. By randomizing the order of the list, they seem to have completely mitigated… well, it’s not entirely clear what they’ve mitigated. And while their choice of shuffling algorithm is commendable, maybe next time they could leave us a comment elaborating on the problematic place they found themself in.

[Advertisement] ProGet can centralize your organization's software applications and components to provide uniform access to developers and servers. Check it out!

Read all

The Proprietary Format

Have you ever secured something with a lock? The intent is that at some point in the future, you'll use the requisite key to regain access to it. Of course, the underlying assumption is that you actually have the key. How do you open a lock once you've lost the key? That's when you need to get creative. Lock picks. Bolt cutters. Blow torch. GAU-8...

In 2004, Ben S. went on a solo bicycle tour, and for reasons of weight, his only computer was a Handspring Visor Deluxe PDA running Palm OS. He had an external, folding keyboard that he would use to type his notes from each day of the trip. To keep these notes organized by day, he stored them in the Datebook (calendar) app as all-day events. The PDA would sync with a desktop computer using a Handspring-branded fork of the Palm Desktop software. The whole Datebook could then be exported as a text file from there. As such, Ben figured his notes were safe. After the trip ended, he bought a Windows PC that he had until 2010, but he never quite got around to exporting the text file. After he switched to using a Mac, he copied the files to the Mac and gave away the PC.

Handspring Treo 90

Ten years later, he decided to go through all of the old notes, but he couldn't open the files!

Uh oh.

The Handspring company had gone out of business, and the software wouldn't run on the Mac. His parents had the Palm-branded version of the software on one of their older Macs, but Handspring used a different data file format that the Palm software couldn't open. His in-laws had an old Windows PC, and he was able to install the Handspring software, but it wouldn't even open without a physical device to sync with, so the file just couldn't be opened. Ben reluctantly gave up on ever accessing the notes again.

Have you ever looked at something and then turned your head sideways, only to see it in a whole new light?

One day, Ben was going through some old clutter and found a backup DVD-R he had made of the Windows PC before he had wiped its hard disk. He found the datebook.dat file and opened it in SublimeText. There he saw rows and rows of hexadecimal code arranged into tidy columns. However, in this case, the columns between the codes were not just on-screen formatting for readability, they were actual space characters! It was not a data file after all, it was a text file.

The Handspring data file format was a text file containing hexadecimal code with spaces in it! He copied and pasted the entire file into an online hex-to-text converter (which ignored the spaces and line breaks), and voilà , Ben had his notes back!

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

Read all

CodeSOD: Breaking Changes

We talk a lot about the sort of wheels one shouldn’t reinvent. Loads of bad code stumbles down that path. Today, Mary sends us some code from their home-grown unit testing framework.

Mary doesn’t have much to say about whatever case of Not Invented Here Syndrome brought things to this point. It’s especially notable that this is Python, which comes, out of the box, with a perfectly serviceable unittest module built in. Apparently not serviceable enough for their team, however, as Burt, the Lead Developer, wrote his own.

His was Object Oriented. Each test case received a TestStepOutcome object as a parameter, and was expected to return that object. This meant you didn’t have to use those pesky, readable, and easily comprehensible assert… methods. Instead, you just did your test steps and called something like:

  outcome.setPassed()

Or

  outcome.setPassed(False)

Now, no one particularly liked the calling convention of setPassed(False), so after some complaints, Burt added a setFailed method. Developers started using it, and everyone’s tests passed. Everyone was happy.

At least, everyone was happy up until Mary wrote a test she expected to see fail. There was a production bug, and she could replicate it, step by step, at the Python REPL. So that she could “catch” the bug and “prove” it was dead, she wanted a unit test.

The unit test passed.

The bug was still there, and she continued to be able to replicate it manually.

She tried outcome.setFailed() and outcome.setFailed(True) and outcome.setFailed("OH FFS THIS SHOULD FAIL"), but the test passed. outcome.setPassed(False), however… worked just like it was supposed to.

Mary checked the implementation of the TestStepOutcome class, and found this:

class TestStepOutcome(object):
  def setPassed(self, flag=True):
    self.result = flag

  def setFailed(self, flag=True):
    self.result = flag

Yes, in Burt’s reluctance to have a setFailed message, he just copy/pasted the setPassed, thinking, “They basically do the same thing.” No one checked his work or reviewed the code. They all just started using setFailed, saw their tests pass, which is what they wanted to see, and moved on about their lives.

Fixing Burt’s bug was no small task- changing the setFailed behavior broke a few hundred unit tests, proving that every change breaks someone’s workflow.

[Advertisement] ProGet can centralize your organization's software applications and components to provide uniform access to developers and servers. Check it out!

Read all

CodeSOD: All the Things!

Yasmin needed to fetch some data from a database for a report. Specifically, she needed to get all the order data. All of it. No matter how much there was.

The required query might be long running, but it wouldn’t be complicated. By policy, every query needed to be implemented as a stored procedure. Yasmin, being a smart prograammer, decided to check and see if anybody had already implemented a stored procedure which did what she needed. She found one called GetAllOrders. Perfect! She tested it in her report.

Yasmin expected 250,000 rows. She got 10.

She checked the implementation.

CREATE PROCEDURE initech.GetAllOrders
AS
BEGIN
    SELECT TOP 10
        orderId,
        orderNo,
        orderCode,
        …
    FROM initech.orders INNER JOIN…
END

In the original developer’s defense, at one point, when the company was very young, that might have returned all of the orders. And no, I didn’t elide the ORDER BY. There wasn’t one.

[Advertisement] ProGet can centralize your organization's software applications and components to provide uniform access to developers and servers. Check it out!

Read all

Error'd: Surgeons, Put Down Your Scalpels

"I wonder what events, or lawsuits, lead TP-Link to add this warning presumably targeted individuals who updated firmware just ahead of performing medical procedures," writes Andrew.

 

"WalMart was very concerned I didn't bag my bags," wrote Rob C.

 

"I sure hope the pilots' map is more accurate than the one they show the passengers," wrote Maddie J.

 

"To me, messages like this are almost like saying to the user 'See? You are the reason why this is broken. Now go and code a fix for it.'," writes Philip B.

 

Brian J. wrote, "To add insult to injury here, neither the 'Yes' or 'No' button worked. Especially the "No" button."

 

Aankhen wrote, "If nothing else, CrashPlan is very confident, I’ll give it that."

 

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

Read all

To Suffer The Slings and Arrows of Vendor Products…

Being a software architect is a difficult task. Part of the skill is rote software design based upon the technology of choice. Part of it is the very soft "science" of knowing how much to design to make the software somewhat extensible without going so far as to design/build something that is overkill. An extreme version of this would be the inner platform effect.

A bike with square wheels

Way back when I was a somewhat new developer, I was tasked with adding a fairly large feature that required the addition of a database to our otherwise database-less application. I went to our in-team architect, described the problem, and asked him to request a modest database for us. At the time, Sybase was the in-house tool. He decreed that "Sybase sucks", and that he could build a better database solution himself. He would even make it more functional than Sybase.

At the time, I didn't have a lot of experience, especially with databases, but intuition told me that Sybase had employed countless people for more than a decade to build and tweak Sybase. When I pointed this out, and the fact the it was unlikely that he was going to build a better database than all that effort - by himself - in only a few days, I received a full-on dressing down because I didn't know what was possible, and that a good architect could design and build anything. While I agreed that given enough time it might be possible, it was highly unlikely that it would happen in the next three days (because I needed time to do my coding against the database to meet the delivery schedule). I was instructed to wait and he would get it to me in time.

My Spidy-Sense™ told me not to trust him, so I went to the DBAs that day and told them what I needed. Since I had little relevant experience with setting up a database, I told them of my inexperience with such things and asked them to optimize it with indices, etc. They created it for me that day. Since it was their implementation of my (DB) requirements, I knew that it would at least pass their review. I then coded the required feature and delivered on time. Was it perfect? No. Could it have been designed better? In retrospect, sure. But I was new to databases and it was fast enough for the need at the time.

At every meeting for the next three months, our manager asked the architect how his Sybase-replacement was coming along. He sheepishly admitted that while it was coming along well, coming up with a design that would support all of the features provided by Sybase was proving to be a bit more involved than he had imagined, and that it would take a while longer.

Several months after that, he was still making schematics and flow diagrams to try and build a new and improved Sybase.

Our manager never did do anything to stop him from wasting time.

As for me, I learned an important lesson about knowing when to write code, and when not to write code.

[Advertisement] ProGet supports your applications, Docker containers, and third-party packages, allowing you to enforce quality standards across all components. Download and see how!

Read all