Wednesday, February 28, 2018

CodeSOD: The Part Version

Once upon a time, there was a project. Like most projects, it was understaffed, under-budgeted, under-estimated, and under the gun. Death marches ensued, and 80 hour weeks became the norm. The attrition rate was so high that no one who was there at the start of the project was there at the end of the project. Like the Ship of Theseus, each person was replaced at least once, but it was still the same team.

Eric wasn’t on that team. He was, however, a consultant. When the project ended and nothing worked, Eric got called in to fix it. And then called back to fix it some more. And then called back to implement new features. And called back…

While diagnosing one problem, Eric stumbled across the method getPartVersions. A part number was always something like “123456–1”, where the first group of numbers were the part number itself, and the portion after the “-” was the version of that part.

So, getPartVersions, then, should be something like:

String getPartVersions(String part) {
    //sanity checks omitted
    return part.split("-")[1];
}

The first hint that things weren’t implemented in a sane way was the method’s signature:

    private List<Integer> getPartVersions(final String searchString)

Why was it returning a list? The calling code always used the first element in the list, and the list was always one element long.

    private List<Integer> getPartVersions(final String searchString) {
        final List<Integer> partVersions = new ArrayList<>();
        if (StringUtils.indexOfAny(searchString, DELIMITER) != -1) {
            final String[] splitString = StringUtils.split(searchString, DELIMITER);
            if (splitString != null && splitString.length > 1) {
                //this is the partIdentifier, we make it empty it so it will not be parsed as a version
                splitString[0] = "";
                for (String s : splitString) {
                    s = s.trim();
                    try {
                        if (s.length() <= 2) {
                            partVersions.add(Integer.parseInt(s));
                        }
                    } catch (final NumberFormatException ignored) {
                        //Do nothing probably not an partVersion
                    }
                }
            }
        }
        return partVersions;
    }

A part number is always in the form “{PART}-{VERSION}”. That is what the variable searchString should contain. So, they do their basic sanity checks- is there a dash there, does it split into two pieces, etc. Even these sanity checks hint at a WTF, as StringUtils obviously is just wrappers around built-in string functions.

Things get really odd, though, with this:

                splitString[0] = "";
                for (String s : splitString) //…

Throw away the part number, then iterate across the entire series of strings we made by splitting. Check the length- if it’s less than or equal to two, it must be the part version. Parse it into an integer and put it in the list. The real “genius” element of this code is that since the first entry in the splitString array is set to an empty string, Integer.parseInt will throw an exception, thus ensuring we don’t accidentally put the part number in our list.

I’ve personally written methods that have this sort of tortured logic, and given what Eric tells us about the history of the project, I suspect I know what happened here. This method was written before the requirement it fulfilled was finalized. No one, including the business users, actually knew the exact format or structure of a part number. The developer got five different explanations, which turned out to be wrong in 15 different ways, and implemented a compromise that just kept getting tweaked until someone looked at the results and said, “Yes, that’s right.” The dev then closed out the requirement and moved onto the next one.

Eric left the method alone: he wasn’t being paid to refactor things, and too much downstream code depended on the method signature returning a List<Integer>.

[Advertisement] Application Release Automation for DevOps – integrating with best of breed development tools. Free for teams with up to 5 users. Download and learn more today!


To read the full article, please visit The Daily WTF

Tuesday, February 27, 2018

-0//

In software development, there are three kinds of problems: small, big and subtle. The small ones are usually fairly simple to track down; a misspelled label, a math error, etc. The large ones usually take longer to find; a race condition that you just can't reproduce, an external system randomly feeding you garbage, and so forth.

Internet word cloud

The subtle problems are an entirely different beast. It can be as simple as somebody entering 4321 instead of 432l (432L), or similar with 'i', 'l', '1', '0' and 'O'. It can be an interchanged comma and period. It can be something more complex, such as an unsupported third party library that throws back errors for undefined conditions, but randomly provides so little information as to be useful to neither user nor developer.

Brujo B encountered such a beast back in 2003 in a sub-equatorial bank that had been especially fond of VB6. This bank had tried to implement standards. In particular, they wanted all of their error messages to appear consistently for their users. To this end, they put a great deal of time and effort into building a library to display error messages in a consistent format. Specifically:

  $TITLE - $CODE / $DESCRIPTION / $SOURCE

An example error message might be:

  File Not Found - 127 / File 'your.file' could not be found / FileImporter

Unfortunately, the designers of this routine could not compensate for all of the third party tools and libraries that did NOT set some/most/all of those variables. This led to interesting presentations of errors to both users and developers:

  - 34 / Network Connection Lost /
  Unauthorized - 401 //

Crystal Reports was particularly unhelpful, in that it refused to populate any field from which error details could be obtained, leading to the completely unhelpful:

  -0//

...which could only be interpreted as Something really bad happened, but we don't know what that is and you have no way to figure that out. It didn't matter what Brujo and peers did. Everything that they tried to cajole Crystal Reports into giving context information failed to varying degrees; they could only patch specific instances of errors; but the Ever-Useless™ -0// error kept popping up to bite them in the arse.

After way too much time trying to slay the beast, they gave up, accepted it as one of their own and tried their best to find alternate ways of figuring out what the problems were.

Several years after moving on to saner pastures, Brujo returned to visit old friends. On the wall they had added a cool painting with many words that "describe the company culture". Layered in were management approved words, like "Trust" and "Loyalty". Some were more specific in-jokes, names of former employees, or references to big achievements the organization had made.

One of them was -0//

[Advertisement] BuildMaster integrates with an ever-growing list of tools to automate and facilitate everything from continuous integration to database change scripts to production deployments. Interested? Learn more about BuildMaster!


To read the full article, please visit The Daily WTF

Monday, February 26, 2018

CodeSOD: Waiting for the Future

One of the more interesting things about human psychology is how bad we are at thinking about the negative consequences of our actions if those consequences are in the future. This is why the death penalty doesn’t deter crime, why we dump massive quantities of greenhouse gases into the atmosphere, and why the Y2K bug happened in the first place, and why we’re going to do it again when every 32-bit Unix system explodes in 2038. If the negative consequence happens well after the action which caused it, humans ignore the obvious cause and effect and go on about making problems that have to be fixed later.

Fran inherited a bit of technical debt. Specifically, there’s an auto-numbered field in the database. Due to their business requirements, when the field hits 999,999, it needs to wrap back around to 000,001. Many many years ago, the original developer “solved” that problem thus:

function getstan($callingMethod = null)
{

    $sequence = 1;

    // get insert id back
    $rs = db()->insert("sequence", array(
        'processor' => 'widgetsinc',
        'RID'       => $this->data->RID,
        'method'    => $callingMethod,
        'card'      => $this->data->cardNumber
    ), false, false);
    if ($rs) { // if query succeeded...
        $sequence = $rs;
        if ($sequence > 999999) {
            db()->q("delete from sequence where processor='widgetsinc'");
            db()->insert("sequence",
                array('processor' => 'widgetsinc', 'RID' => $this->data->RID, 'card' => $this->data->cardNumber), false,
                false);
            $sequence = 1;
        }
    }

    return (substr(str_pad($sequence, 6, "0", STR_PAD_LEFT), -6));
}

The sequence table uses an auto-numbered column. They insert a row into the table, which returns the generated ID used. If that ID is greater than 999,999, they… delete the old rows. They then insert a new row. Then they return “000001”.

Unfortunately, sequences don’t work this way in MySQL, or honestly any other database. They keep counting up unless you alter or otherwise reset the sequence. So, the counter keeps ticking up, and this method keeps deleting the old rows and returning “000001”. The original developer almost certainly never tested what this code does when the counter breaks 999,999, because that day was so far out into the future that they could put off the problem.

Speaking of putting off solving problems, Fran also adds:

For the past 2 years this function has been returning 000001 and is starting to screw up reports.

Broken for at least two years, but only now is it screwing up reports badly enough that anyone wants to do anything to fix it.

[Advertisement] Easily create complex server configurations and orchestrations using both the intuitive, drag-and-drop editor and the text/script editor.  Find out more and download today!


To read the full article, please visit The Daily WTF

Sunday, February 25, 2018

Bear And Man Spook Each Other

Pretty cool thumbnail right? You’ll never guess what happens next!! Or maybe you will, as I already put that in the video title. Nonetheless it’s a pretty rare and unique encounter these two had!

The post Bear And Man Spook Each Other appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

This Boxer Is Her New Best Friend

Nothing feels better as a parent than your baby and your dog getting along famously. These two are on the path for an everlasting friendship, and they both couldn’t be more happy with each other!

The post This Boxer Is Her New Best Friend appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

Saturday, February 24, 2018

42,000 Match Sphere Gets Lit

This video is pretty long. That’s mostly because it’s quite fascinating. What happens when you put together a big ball of matches and light it up? The process of the thing slowly burning out is […]

The post 42,000 Match Sphere Gets Lit appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

Sea Otter Tries Sleeping On His Mom

For us, moms are pretty freaking important. And I have a feeling they are pretty important for otters as well. This video is all the evidence you need basically.

The post Sea Otter Tries Sleeping On His Mom appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

Friday, February 23, 2018

Nothing Can Beat A Baby Laugh

I mean, do I even need to add a description? You know a baby’s laugh is going to cheer you up. Just watch them damn video, smile a little and your overall happiness will be […]

The post Nothing Can Beat A Baby Laugh appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

Whale Spray Shower Time

Whale-watching is for most a very unique and special adventure. Some of them go home disappointed, as you’re not guaranteed to see a whale. But some of them go home ecstatic, because the whale that […]

The post Whale Spray Shower Time appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

Error'd: Everybody's Invited!

"According to Outlook, it seems that I accidentally invited all of the EU and US citizens combined," writes Wouter.

 

"Just an array a month sounds like a pretty good deal to me! And I do happen to have some arrays to spare..." writes Rutger W.

 

Lucas wrote, "VMWare is on the cutting edge! They can support TWICE as much Windows 10 as their competitors!"

 

"I just wish it was CurrentMonthName so that I could take advantage of the savings!" Ken wrote.

 

Mark B. "I had no idea that Redboxes were so cultured."

 

"I'm a little uncomfortable about being connected to an undefined undefined," writes Joel B.

 

[Advertisement] Easily create complex server configurations and orchestrations using both the intuitive, drag-and-drop editor and the text/script editor.  Find out more and download today!


To read the full article, please visit The Daily WTF

Thursday, February 22, 2018

Propose To Your Girlfriend Through Mario Maker

To be honest, you both have to be kind of nerdy for this to have its desired effect. But when that’s the case, success guaranteed (we’re not liable in any way if results are different…)! […]

The post Propose To Your Girlfriend Through Mario Maker appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

Soldier Surprises Mother At Work

We’ve seen these videos a thousand times, but what makes this one special is the great set up. The soldier goes incognito behind his newspaper, and sends his mom on a little hide-and-seek mission. Her […]

The post Soldier Surprises Mother At Work appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

CodeSOD: Functional IsFunction

Julio S recently had to attempt to graft a third-party document viewer onto an internal web app. The document viewer was from a company which specialized in enterprise “document solutions”, which can be purchased for enterprise-sized licensing fees.

Gluing the document viewer onto their internal app didn’t go terribly well. While debugging, and browsing through the vendor’s javascript, he saw a lot of calls to a function called IsFunction. It was loaded from a “utilities.js”-type do-everything library file. Curious, Julio pulled up the implementation.

function IsFunction ( func ) {
    var bChk=false;
    if (func != "undefined") bChk=true;
    else bChk=false;
    return bChk;
}

I cannot emphasize enough how beautiful this block of code is, by the standards of bad code. There’s so much there. One variable, bChk uses Hungarian notation. Nothing else seems to. It’s a totally superfluous variable, as we could just do return func != "undefined".

Then again why would we even do that? The real beauty, though, is how the name of the function and its implementation have no relationship to each other, and the implementation is utterly useless. For example:

IsFunction("Hello World"); //true
IsFunction({spam: "eggs"}); //true
IsFunction(function() {}); //true, but it was probably an accident
IsFunction(undefined); //true
IsFunction("undefined"); //false

Yes, the only time this function returns false is the specific case where you pass it the string “undefined”. Everything else IsFunction apparently. The useless function sounds important. Someone wrote it, probably as a quick attempt at vaguely defensive programming. “I should make sure my inputs are valid”. They didn’t test it. The certainly didn’t think about it. But they wrote it. And then someone else saw the function in use, and said, “Oh… I should probably use that, too.” Somewhere, there’s probably a “Style Guide”, which mandates that, before attempting to invoke a variable that should contain a function, you use IsFunction to confirm it does. It comes up in code reviews, and code has been held from going into production because someone didn't use IsFunction.

And Julio probably is the first person to actually check the implementation since it was first written.

[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!


To read the full article, please visit The Daily WTF

Wednesday, February 21, 2018

Smartest Police Dog Ever

It takes some skills and some brains to join the police (although that depends on who you ask), but this smart dog certainly deserved his spot. No task too big and no bridge too far. […]

The post Smartest Police Dog Ever appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

More Catnip!!1!

Is there anything cuter than a cat nipping on some cool beverage? She licks as if her life depends on it. Luckily, she looks very happy and healthy, so no need to be concerned for […]

The post More Catnip!!1! appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

Shiny Side Up

CD-ROM

It feels as though disc-based media have always been with us, but the 1990s were when researchers first began harvesting these iridescent creatures from the wild in earnest, pressing data upon them to create the beast known as CD-ROM. Click-and-point adventure games, encyclopedias, choppy full-motion video ... in some cases, ambition far outweighed capability. Advances in technology made the media cheaper and more accessible, often for the worst. There are some US households that still burn America Online 7.0 CDs for fuel.

But we’re not here to delve into the late-90s CD marketing glut. We’re nestling comfortably into the mid-90s, when Internet was too slow and unreliable for anyone to upload installers onto a customer portal and call it a day. Software had to go out on physical media, and it had to be as bug-free as possible before shipping.

Chris, a developer fresh out of college, worked on product catalog database applications that were mailed to customers on CDs. It was a small shop with no Tech Support department, so he and the other developers had to take turns fielding calls from customers having issues with the admittedly awful VB4 installer. It was supposed to launch automatically, but if the auto-play feature was disabled in Windows 95, or the customer canceled the installer pop-up without bothering to read it, Chris or one of his colleagues was likely to hear about it.

And then came the caller who had no clue what Chris meant when he suggested, "Why don't we open up the CD through the file system and launch the installer manually?"

These were the days before remote desktop tools, and the caller wasn't the savviest computer user. Talking him through minimizing his open programs, double-clicking on My Computer, and browsing into the CD drive took Chris over half an hour.

"There's nothing here," the caller said.

So close to the finish line, and yet so far. Chris stifled his exasperation. "What do you mean?"

"I opened the CD like you said, and it's completely empty."

This was new. Chris frowned. "You're definitely looking at the right drive? The one with the shiny little disc icon?"

"Yes, that's the one. It's empty."

Chris' frown deepened. "Then I guess you got a bad copy of the CD. I'm sorry about that! Let me copy down your name and address, and I'll get a new one sent out to you."

The customer provided his mailing address accordingly. Chris finished scribbling it onto a Post-it square. "OK, lemme read that back to—"

"The shiny side is supposed to be turned upwards, right?" the customer blurted. "Like a gramophone record?"

Chris froze, then slapped the mute button before his laughter spilled out over the line. After composing himself, he returned to the call as the model of professionalism. "Actually, it should be shiny-side down."

"Really? Huh. The little icon's lying, then."

"Yeah, I guess it is," Chris replied. "Unfortunately, that's on Microsoft to fix. Let's turn the disc over and try again."

[Advertisement] Incrementally adopt DevOps best practices with BuildMaster, ProGet and Otter, creating a robust, secure, scalable, and reliable DevOps toolchain.


To read the full article, please visit The Daily WTF

Tuesday, February 20, 2018

CodeSOD: The Telltale Snippet

True! nervous, very, very dreadfully nervous I had been and am; but why will you say that I am mad? The disease had sharpened my senses, not destroyed, not dulled them. Above all was the sense of hearing acute. I heard all things in the heaven and in the earth. I heard many things in hell. How then am I mad? Hearken! and observe how healthily, how calmly I can tell you the whole story. - “The Telltale Heart” by Edgar Allen Poe

Today’s submitter credits themselves as Too Afraid To Say (TATS) who they are. Why? Because like a steady “thump thump” from beneath the floorboards, they are haunted by their crimes. The haunting continues to this very day.

It is impossible to say how the idea entered TATS’s brain, but as a fresh-faced junior developer, they set out to write a flexible web-control in JavaScript. What they wanted was to dynamically add items to the control. Each item was a set of fields- an ID, a tool tip, a description, etc.

Think about how you might pass a list of objects to a method.

    ObjectLookupField.prototype._AddItems = function _AddItems(objItems)
    {
        if (objItems && objItems.length > 0)
        {
            var objItemIDs = [];
            var objTooltips = [];
            var objImages = [];
            var objTypes = [];
            var objDeleted = [];
            var objDescriptions = [];
            var objParentTreeCodes = [];
            var objHasChilderen = [];
            var objPath = [];
            var objMarked = [];
            var objLocked = [];

            var blnSkip;

            for (var intI = 0; intI < objItems.length; intI++)
            {
                objItemIDs.push(objItems[intI].ID);
                objImages.push((objItems[intI].TypeIconURL ? objItems[intI].TypeIconURL : objItems[intI].IconURL));
                objTooltips.push(objItems[intI].Tooltip ? objItems[intI].Tooltip : '');
                objTypes.push(objItems[intI].TypeID);
                objDescriptions.push(objItems[intI].Description);
                objParentTreeCodes.push(objItems[intI].ParentTreeCode);
                objMarked.push(objItems[intI].Marked ? 'Marked' : '');
                objLocked.push(objItems[intI].Locked);

                                // SNIP, not really related
            }
                            //TATS also implemented `addItems` which requires all these arrays
            window[this._strControlID].addItems([objItemIDs, objImages, objPath, objTooltips, objLocked, objMarked, objParentTreeCodes, objHasChilderen]);
        }
    }

TATS used the infamous “Arrject” pattern. Instead of having a list of objects, where each object has all of the fields it needs, the Arrject pattern has one array per field, and then we’ll hope that each index holds all the related data for a given item. For example:

    arrNames = {"Joebob", "Sallybob", "Suebob"};
    arrAddresses = {"123 Street St", "234 Road Rd", "345 Lane Ln"};
    arrPhones = {"555-1234", "555-2345", "555-3456"};

The 0th index of every array contains everything you want to know about Joebob.

Most uses of the Arrject pattern end up in code that doesn’t use objects at all, but TATS adds their own little twist. They explode an object into a set of arrays, and then pass those arrays to their own method which creates the necessary DOM elements.

TATS smiled, for what did they have to fear? They bade the senior developers welcome: use my code. And they did.

Before long, this little bit of code propagated throughout their entire codebase; copied, pasted, dropped in, loaded as a JS dependency, hosted on a private CDN. It was everywhere. Time passed, and careers changed. TATS got promoted up to senior. Other seniors left and handed their code off to TATS. And that’s when the thumping beneath the floorboards became intolerable. That is why they are “Too Afraid to Say”. This little ghost, this reminder of their mistakes as a junior dev is always there, waiting beneath their feet, and it keeps. getting. louder.

“Villains!” I shrieked, “dissemble no more! I admit the deed!—tear up the planks!—here, here!—it is the beating of his hideous heart!”

[Advertisement] Onsite, remote, bare-metal or cloud – create, configure and orchestrate 1,000s of servers, all from the same dashboard while continually monitoring for drift and allowing for instantaneous remediation. Download Otter today!


To read the full article, please visit The Daily WTF

Monday, February 19, 2018

Cousin of ITAPPMONROBOT

Logitech Quickcam Pro 4000

Every year, Initrode Global was faced with further and further budget shortages in their IT department. This wasn't because the company was doing poorly—on the contrary, the company overall was doing quite well, hitting record sales every quarter. The only way to spin that into a smaller budget was to dream bigger. Thus, every quarter, the budget demanded greater and greater increases in sales, and the exceptional growth was measured against the desired phenomenal growth and found wanting.

IT, being a cost center, was always hit by budget cuts the hardest. What did they need money for? The lights were still on, the mainframes still churning; any additional funds would only encourage them to take wild risks and break things.

One of the things people were worried about breaking were the thin clients. These had been purchased some years ago from Smyrt, who had been acquired the previous year by Hell Computers. There would be no tech support or patching, not from Hell. The IT department was on their own to ensure the clients kept running.

Unfortunately, the things seemed to have a will of their own—and that will did not include remaining up for weeks on end. Every once in a while, when booting Linux on the thin clients, the Thin Film Transistor screen would turn dark as soon as the X server started. They would remain dark after that; however, when the helpdesk SSH'd into the system, the screen would of course render perfectly on their end. So there was nothing to do to troubleshoot except lug a thin client to their work area and test workarounds from there.

The worst part of this kind of troubleshooting is when the problem is an intermittent one. The only way they could think to reproduce the problem was to spend hours in front of the client, turning it off and back on again. In the face of budget cuts, the already understaffed desk had no manpower to do something so trivial and dull.

Tedium is the mother of invention. Many of the most ingenious pieces of automation were put in place when an enterprising programmer was faced with performing a mind-numbing task over and over for the foreseeable future. Such is the case in this instance. Lacking the support staff to power cycle the machine over and over, the staff instead built a robot.

A webcam was found in the back room, dusty and abandoned, the last vestige of a proposed work-from-home solution that never quite came to fruition years before. A sticker of transparent rubber someone found in their desk was placed over the metal rim of the camera so it wouldn't leave any scratches on the glass of the TFT screen. The webcam was placed up close against one strategically chosen corner of the screen, and attached to a Raspberry Pi someone brought from home.

The Pi was programmed to run a bash script, which in turn called a CLI image-grabbing tool and then applied some ImageMagick filters to determine the brightness value of the patch of screen it could see. This brightness value was compared against a known list of brightnesses to determine which state the machine was in: the boot menu, the Linux kernel messages scrolling past, the colorful login screen, or the solid black screen representing the problem. When the Pi detected a login screen, it would run a scripted reboot on the thin client using SSH and a keypair. If, instead, the screen remained dark for a long period of time, it would send an IM through the company messaging solution to alert the staff that they could begin their testing, then exit.

We've seen machines with the ability to manipulate physical servers. Now, we have machines seeing and evaluating the world in front of them. How long before we reach peak Skynet potential here at TDWTF? And what would the robot revolution look like, with founding members such as these?

[Advertisement] Incrementally adopt DevOps best practices with BuildMaster, ProGet and Otter, creating a robust, secure, scalable, and reliable DevOps toolchain.


To read the full article, please visit The Daily WTF

Sunday, February 18, 2018

Spiderman Dances Like There Is No Tomorrow

Even Spiderman would like a day off now and then. What better way to truly express yourself and free your mind than dancing passionately to one of the biggest hits of all time?

The post Spiderman Dances Like There Is No Tomorrow appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

Saturday, February 17, 2018

Best Fails Of The Week: It’s Raining Inside!

As soon as you see the first clip of the mountain-biking people, you know you’re in for a good one. Their fail isn’t that big or unexpected, but it’s just the tip of the iceberg […]

The post Best Fails Of The Week: It’s Raining Inside! appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

The Evolution Of Windows Startup Sounds

Remember the golden old days of our digital life? Computers were a novelty back then, and so were the sounds that came with them. To be honest, not much has changed in this department.

The post The Evolution Of Windows Startup Sounds appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

Friday, February 16, 2018

Best New Bloopers Of January 2018

Another day of news, another day of news people doing weird stuff. Day after day after day… It’s only natural a compilation of these fails exists and can get updated every month. There is plenty […]

The post Best New Bloopers Of January 2018 appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

Best Pets Of The Month

We humans invented all kinds of silly awards for ourselves, but what about our most loyal friends? Don’t they deserve an award for something as well sometimes? Well, at least some of them made it […]

The post Best Pets Of The Month appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

Error'd: Preparing for the Future

George B. wrote, "Wait, so is it done...or not done?"

 

George B. (different George, but is in good company) is seeing nearly the same thing with Crash Plan Pro where the backup is done ...maybe.

 

"I swear, that's the last time that I'm flying with Icarus Airlines" Allison V. writes.

 

"The best I can figure, someone wanted to see what the simulation app would do if executed in some far flung future where months don't matter and nothing makes any sense," writes M.C.

 

Joel C. wrote "I can't help it - Next time my train is late, I'm going to immediately think that it's because someone didn't click to dismiss a popup."

 

"I'm not sure what this means, but I guess it's to point out that there are website buttons, and then there are buttons on the website," Brian R. wrote.

 

[Advertisement] Atalasoft’s imaging SDKs come with APIs & pre-built controls for web viewing, browser scanning, annotating, & OCR/barcode capture. Try it for 30 days with included support.


To read the full article, please visit The Daily WTF

Thursday, February 15, 2018

Excited Puppy Spots Its Owner

We all know and love the videos where a dog is over the moon for their owners to return home after their job or something, but this one has a little twist. The dog spots […]

The post Excited Puppy Spots Its Owner appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

Helium Opera Singing

People still get amazed and surprised by the sound you produce when helium is involved. Don’t ask me the scientific stuff behind all that, all I know is this girl produces some amazing music when […]

The post Helium Opera Singing appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

It's Called Abstraction, and It's a Good Thing

Steven worked for a company that sold “big iron” to big companies, for big bucks. These companies didn’t just want the machines, though, they wanted support. They wanted lots of support. With so many systems, processing so many transactions, installed at so many customer sites, Steven’s company needed a better way to analyze when things went squirrelly.

Thus was born a suite of applications called “DICS”- the Diagnostic Investigation Console System. It was, at its core, a processing pipeline. On one end, it would reach out to a customer’s site and download log files. The log files would pass through a series of analytic steps, and eventually reports would come out the other end. Steven mostly worked on the reporting side of things.

While working on reports, he’d sometimes hear about hiccups in the downloader portion of the pipeline, but as it was “not his circus, not his monkeys”, he didn’t pry too deeply. At least, he didn’t until one day, when his boss knocked on his cubicle divider.

“Hey, Steven. You know Perl, right?”

“Uh… sure.”

“And you’ve worked with XML files, right?”

“I… yes?”

“Great. Bob’s leaving. You’re going to need to take over the downloader portion of DICS. Talk to him ASAP. Great, thanks!”

Perl gets a reputation for being a “write only language”, which is at least partially undeserved. Bob was quite sensitive about that reputation, so he stressed, “I’ve worked really, really hard to keep the code as clean and clear as possible. Everything in the design is object oriented.”

Bob wasn’t kidding. Everything was wrapped up as a class. Everything. It was so class-happy it made the Spring framework jealous. JEE consultants would look at it and say, “Whoa, maybe slow down with the classes there.” A UML diagram of the architecture would drain ten printers worth of toner. The config file was stored in XML, and just for parsing out that file and storing the results, Bob had written 25 different classes, some as small as three lines. All in all, the whole downloader weighed in at about 5,000 lines of Perl code.

In the whirlwind tour, Steven asked Bob about the complexity. “It’s not complex. Each class is extremely simple. Well, aside from the config file wrapper, but it needs to have lots of methods because it has lots of data! There are so many fields in the XML file, and I needed to create getters and setters for them all! That way we can have Data Abstraction! That’s important! Data Abstraction is how we keep this project maintainable. What if the XML file format changes? It’s happened, you know. This will make it easy to keep our code in sync!”

Steven marveled at Bob’s ability to pronounce “data abstraction” as if it were in bold face, and resolved to touch the downloader script as little as possible. That resolution failed pretty much a week after Bob left, when the script fell down in production, leaving the DICS pipeline empty. Steven had to roll up his sleeves and get hands on with the code.

Now, one of Perl’s selling points is its rich library. While CPAN may have its own issues as a package manager, if you want to do something like parse an XML file, there’s a library that does it. There’s a dozen libraries that’ll do it. And they all follow a vaguely Perl-idiom, and instead of classes, they’ll favor associative arrays. That way, when you want to get something like the contents of the ip_addr tag from the config file, you could write code like this:

$ip_addr = $config->{hosts}[$n]{ip_addr}

This makes it easy to understand how the structure of the XML file relates to the Perl data structure, but that kind of mapping means that there isn’t any Data Abstraction, and thus was utterly the wrong approach. Instead, everything was done as a getter/setter method.

$ip_addr = $Config_object->host($n)->get_addr();

That doesn’t look too different, perhaps, but the devil is in the details. First, 90% of the getters were “thin”, so get_addr might look something like this:

sub get_addr { return $self->{Addr}; }

That raises questions about the value of these getters/setters for fetching config values, but the bigger problem was this: there was nothing in the config file called “Addr”. Does this method return the IP address? Or a string in the from “$ip_addr:$port”? Or maybe even an array, like [$ip_addr, $port].

Throughout the whole API, it was a bit of a crapshoot as to what any given method might return. And as for checking the documentation- they’d created a system that provided Data Abstraction, they didn’t need documentation, did they?

To track any given getter back to the actual field in the XML file it was getting, Steven had to trace through half a dozen different classes. It was frustrating and tedious, and Steven had half a mind to just throw the whole thing out and start over, consequences be damned. When he saw the “Translation” subsystem, he decided that it really did need to be thrown out, entirely.

You see, Bob’s goal with Data Abstraction was to make it so that, if the XML file changed, it would be easy to adapt the code. But the code was a mess. So when the XML file did change a few years back, Bob couldn’t update the config handling classes in any way that worked. So he did the next best thing- he wrote a “translation” module that would, using regular expressions, convert the new-style XML files back into the old-style XML files. Then his config-file classes could load and parse the old-style files.

Steven sums it up perfectly:

Bob’s classes weren’t data abstraction. It was just… data abstracturbation.

When Steven was done reimplementing Bob's work, he had about 500 lines of code, and the downloader stopped failing every few days.

[Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!


To read the full article, please visit The Daily WTF

Wednesday, February 14, 2018

Best Twin Baby Surprise For Grandma

I’m not a grandma myself, but I can imagine the most precious moments of my life will be the time I spend with my offspring. This grandma agrees with me, by the looks of it. […]

The post Best Twin Baby Surprise For Grandma appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

8 Simple Dollar Store Hacks To Save You Money

Every penny counts. Definitely in these days when stocks and other monetary assets are struggling. So this compilation with eight excellent tips that can be used by anybody. Act accordingly and you’ll be surprised by […]

The post 8 Simple Dollar Store Hacks To Save You Money appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

CodeSOD: All the Rest Have Thirty One…

Aleksei received a bunch of notifications from their CI system, announcing a build failure. This was interesting, because no code had changed recently, so what was triggering the failure?

        private BillingRun CreateTestBillingRun(int billingRunGroupId, DateTime? billingDate, int? statusId)
        {
            return new BillingRun
            {
                BillingRunGroupId = billingRunGroupId,
                PeriodStart = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1),
                BillingDate = billingDate ?? new DateTime(DateTime.Today.Year, DateTime.Today.Month, 15),
                CreatedDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 30),
                ItemsPreparedDate = new DateTime(2017, 4, 7),
                CompletedDate = new DateTime(2017, 4, 8),
                DueDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 13),
                StatusId = statusId ?? BillingRunStatusConsts.Completed,
                ErrorCode = "ERR_CODE",
                Error = "Full error description",
                ModifiedOn = new DateTime(2017, 1, 1)
            };
        }

Take a look at the instantiation of CreatedDate. I imagine the developer’s internal monologue went something like this:

Okay, the Period Start is the beginning of the month, the Billing Date is the middle of the month, and Created Date is the end of the month. Um… okay, well, beginning is easy. That’s the 1st. Phew. Okay, but the middle of the month. That’s hard. Oh, wait, wait a second! It’s billing, so I bet the billing department has a day they always send out the bills. Let me send an email to Steve in billing… oh, look at that. It’s always the 15th. Great. Boy. This programming stuff is easy. Whew. Okay, so now the end of the month. This one’s tricky, because months have different lengths, sometimes 30 days, and sometimes 31. Let me ask Steve again, if they have any specific requirements there… oh, look at that. They don’t really care so long as it’s the last day or two of the month. Great. I’ll just use 30, then. Good thing there aren’t any months with a shorter length.
Y’know, I vaguely remember reading a thing that said tests should always use the same values, so that every run tests exactly the same combination of inputs. I think I saved a bookmark to read it later. Should I read it now? No! I should commit this code, let the CI build run, and then mark the requirement as complete.
Boy, this programming stuff is easy.

[Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!


To read the full article, please visit The Daily WTF

Tuesday, February 13, 2018

Koala Brawl On Australian Road

Koalas usually don’t seem to be overly aggressive or anything, but when a certain boiling point is reached… Phew, can they explode! These two rascals were having an argument, probably over something silly or over […]

The post Koala Brawl On Australian Road appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

The Frozen Ocean

Water only freezes when it’s still, they say. Well, look again, because this bloody ocean consists of ice as far as the eye can see. I guess that’s what happens when the cold is freezing […]

The post The Frozen Ocean appeared first on Viral Viral Videos.



To read the full article, please visit Viral Viral Videos

Budget Cuts

Xavier was the head of a 100+ person development team. Like many enterprise teams, they had to support a variety of vendor-specific platforms, each with their own vendor-specific development environment and its own licensing costs. All the licensing costs were budgeted for at year’s end, when Xavier would submit the costs to the CTO. The approval was a mere formality, ensuring his team would have everything they needed for another year.

Unfortunately, that CTO left to pursue another opportunity. Enter Greg, a new CTO who joined the company from the financial sector. Greg was a penny-pincher on a level that would make the novelty coin-smasher you find at zoos and highway rest-stops jealous. Greg started cutting costs left and right immediately. When the time came for budgeting development tool licensing, Greg threw down the gauntlet on Xavier’s “wild” spending.

Alan Rickman, in Galaxy Quest, delivering the line, 'By Grabthar's Hammer, what a savings' while looking like his soul is dying forever. "By Grabthar's Hammer, what a savings."

“Have a seat, X-man,” Greg offered, in a faux-friendly voice. “Let’s get to the point. I looked at your proposal for all of these tools, your team supposedly ‘needs’. $40,000 is absurd! Do you think we print money? If your team were any good,, they should be able to do everything they need without these expensive, gold-plated programs!”

Xavier was taken aback by Greg’s brashness, but he was prepared for a fight. “Greg, these tools are vital to our development efforts. There are maybe a few products we could do without, but most of them are absolutely required. Even the more ‘optional’ ones, like our refactoring and static analysis tools, they save us money and time and improve code quality. Not having them would be more expensive than the license.”

Greg scowled and tented his fingers. “There is no chance I’m approving this as it stands. Go back and figure out what you can do without. If you don’t cut this cost down, I’ll find an easier way to reduce expenses… like by cutting bonuses… or staff.”

Xavier spent the next few days having an extensive tool review with his lead developers. Many of the vendor-specific tools had no alternative, but there were a few third party tools they could do without, or use an open-source equivalent. Across the team of 100+ developers, the net cost savings would be $4,000, or 10%.

Xavier didn’t expect that to make Greg happy, but it was the best they could do. The following morning, Xavier presented his findings in Greg’s office, and it went smoother than expected. “Listen, X. I want this cost down even more, but we’re running out of time to approve this year’s budget. Since I did so much work cutting costs in other ways, I’ll submit this to finance. But enjoy your last year of all these fancy tools! Next year, things will be different!”

Xavier was relieved he didn’t have to fight further. Perhaps, over the next year, he could further demonstrate the necessity of their tooling. With the budget resolved, Xavier had some much-overdue vacation time. He had saved up enough PTO to spend a month in the Australian Outback. Development tools and budgets would be the furthest thing from his mind.

Three great weeks in the land down under were enhanced by being mostly cut off from communications from anyone in the company. During a trip through a town with cell phone reception, Xavier decided to check his voicemail, to make sure the sky wasn’t falling. Dave, his #2 in command, had left an urgent message two days prior.

“Xavier!” Dave shouted on the other end. “You need to get back here soon. Greg never paid the invoices for anything in our stack. We’re sitting here with a huge pile of unlicensed stuff. We’ve been racking up unlicensed usage and support costs, and Greg is going to flip when he sees our monthly statements.” With deep horror, Dave added, “One of the licenses he didn’t pay was for Oracle!”

Xavier reluctantly left the land of dingoes and wallabies to head back home. He arrived just about the same time the first vendor calls demanding payment did. The costs from just three weeks of unlicensed usage of enterprise software was astronomical. Certainly more than just buying the licenses would have been in the first place. Xavier scheduled a meeting with Greg to decide what to do next.

The following Monday, the dreaded meeting was on. “Sit,” Greg said. “I have some good news, and some bad news. The good news is that I’ve found a way to pay these ridiculous charges your team racked up.” Xavier leaned forward in his chair, eager to learn how Greg had pulled it off. “The bad news is that I’ve identified a redundant position- yours.”

Xavier slumped into his chair.

Greg continued. “While you were gone, I realized we were in quite capable hands with Dave, and his salary is quite a bit lower than yours. Coincidentally, the original costs and these ridiculous penalties add up to an amount just a little less than your annual salary. I guess you’re getting your wish: the development team can keep the tools you insist they need to do their jobs. It seems you were right about saving money in the long run, too.”

Xavier left Greg’s office, stunned. On his way out for the last time, he stopped by Dave to congratulate him on the new promotion.

“Oh,” Dave said, sourly, “it’s not a promotion. They’re just eliminating your position. What, you think Greg would give me a raise?”

[Advertisement] Infrastructure as Code built from the start with first-class Windows functionality and an intuitive, visual user interface. Download Otter today!


To read the full article, please visit The Daily WTF