-Поиск по дневнику

Поиск сообщений в rss_thedaily_wtf

 -Подписка по e-mail

 

 -Постоянные читатели

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 06.04.2008
Записей:
Комментариев:
Написано: 0

The Daily WTF





Curious Perversions in Information Technology


Добавить любой RSS - источник (включая журнал LiveJournal) в свою ленту друзей вы можете на странице синдикации.

Исходная информация - http://thedailywtf.com/.
Данный дневник сформирован из открытого RSS-источника по адресу http://syndication.thedailywtf.com/thedailywtf, и дополняется в соответствии с дополнением данного источника. Он может не соответствовать содержимому оригинальной страницы. Трансляция создана автоматически по запросу читателей этой RSS ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

[Обновить трансляцию]

CodeSOD: The Forest of Trees

Четверг, 07 Мая 2015 г. 14:00 + в цитатник

Sallys co-worker wanted to turn some data into HTML. It would flow from his application into client-side JavaScript which would build the DOM. He decided that it made sense to use a tree to represent the data as its translated.

The C# declaration of his tree looked something like this:

Dictionary>> treeOBJMODEL;

Isnt it fantastic how Generics can make your code more readable and type-safe? I mean, thats not whats happening in this example, but…

To traverse the tree, he used a terse, readable block like this :

Dictionary>> treeOBJMODEL = (Dictionary>>)Application["ProductTypesTree"];

foreach (int level in treeOBJMODEL.Keys)
{
        Dictionary> levelNodes = treeOBJMODEL[level];
        if (level == 1)
        {
                foreach (List rootNodeL in levelNodes.Values)
                {
                        foreach (CatalogLoader_Helper.CatalogNode rootNode in rootNodeL)
                        {
                                if(this.IsLeaf(rootNode, level))
                                {
                                        // ...
                                } 
                                // ...
                        }
                }
        }
        else
        {
                foreach (CatalogLoader_Helper.CatalogNode parentNode in levelNodes.Keys)
                {
                        List childSiblingNodesOf1AndTheSameParent = levelNodes[parentNode];
                        foreach (CatalogLoader_Helper.CatalogNode leafNodeToAdd in childSiblingNodesOf1AndTheSameParent)
                        {
                                if(this.IsLeaf(leafNodeToAdd, level))
                                {
                                        // ...
                                } 
                                // ...                                  
                        }
                }
        }
}

Thanks to the super-powerful (ab)use of Generics, Sallys co-worker was able to write even more streamlined code for normally challenging functions, like IsLeaf:

private bool IsLeaf(CatalogLoader_Helper.CatalogNode node, int nodeLevel)
{
        //It enters the collection and checks:
        //If the nodeLevel is the highest (we are on the last level)
        //then it immediately returns true: it is definitely a leaf;
        //Otherwise:
        //It procures itself the level mapping for the next level
        //and checks if it finds itself in its keys 
        //if yes, then it immediately returns false and exits;
        //otherwise it returns true.

        int nextLevel = nodeLevel + 1;
        if (!treeOBJMODEL.ContainsKey(nextLevel))
        {
                return true;
        }
        else
        {
                string thisNodeNumRef = node.numRef;

                Dictionary> levelMapping = treeOBJMODEL[nextLevel];
                foreach (CatalogLoader_Helper.CatalogNode parentsForNextLevel in levelMapping.Keys)
                {
                        if (parentsForNextLevel.numRef.Equals(thisNodeNumRef)) return false;
                }
                return true;
        }
}
[Advertisement] Use NuGet or npm? Check out ProGet, the easy-to-use package repository that lets you host and manage your own personal or enterprise-wide NuGet feeds and npm repositories. It's got an impressively-featured free edition, too!

http://thedailywtf.com/articles/the-forest-of-trees


Метки:  

The Daily WTF: Live: The Life and Death of Steel City Ruby Con

Среда, 06 Мая 2015 г. 14:00 + в цитатник

On April 10th, I hosted The Daily WTF: Live! in Pittsburgh. It was a blast. We had a great crowd, and some great performances.

Today's installment investigates exactly how a conference comes into being, told from the inside of Steel City Ruby Con.

Direct Link (mp3).

This episode is brought to you by our sponsor, Puppet Labs. Check out their intro video, it gives a pretty good overview of how they help their customers get things done. Start a [free trial](http://puppetlabs.com/download-puppet-enterprise) today!

Transcript

We'll elide the boiler-plate of your host and get straight to the story

Hi, everyone! Hey, my name is Jean. Hi, everyone!

For the last 3 Augusts, weve held a community-run Ruby (the programming language) conference in Pittsburgh called Steel City Ruby Conference. Has anyone here heard of SCR? Yeah? How about attended? Yeah, me too! I got more deeply involved every year, from being a privileged attendee at the first to speaking at, MC-ing, & organizing last years. It wasnt the biggest or most famous conference in the world - people outside of the coding community probably never knew about it, and we never invited the creator of Ruby to speak (though we thought about it!) - but it wasnt just a few local schmucks hanging out together, either. It was a thing. I say was because its not a thing this year - were not putting on SCR this summer. And thats ok! It might happen again someday, but it might not, too. So I want to tell you about what it was like to bring life to this one local conference, what it was like to help stand it up and lay it back down. Of course, I was just one of many people involved with this one conference, and had a limited view - I might even get some things wrong. I have specifically invited Carol to heckle me as necessary - I extend that invitation to anyone else who saw things differently from how I tell them!

Heres your first chance: This is how it started: this is the first piece of lore about conference. There was an irc channel where a bunch of Pittsburgh Rubyists hung out. A bunch of them were from my company because wed recently started doing Ruby together and wanted to get with the community a little. So one day, Carol there, she says in chat: Lets have a ruby conference! and a slew of people basically said yeah, well help!

And thats how it worked from beginning to end. Organizing SCR has always been a matter of a prime mover, a bunch of people stepping up to do their parts, and a great informality, a kind of worry? hurry? why?.

Carol has been the conferences prime mover throughout its life, although she was later joined in this role by Justin. She (and then they) set some expectation and tone that gave SCR the feel that it had. They were the heart of the organizing group, the secret heart of the conference. One of the first things Carol led the organizing group to determining is that they werent going to be able to please everyone, so theyd focus on one group and make that focus absolutely clear, let it guide the rest of their decisions. And so the first year of SCRC was all about people whod never been to a conference before. They tried to make it the best first conference. And this focus absolutely shaped the conference, in size (small enough to not be overwhelming), price (not a huge commitment), format (single track, so no one has to figure out how to choose what to go to), half of the time given to the hallway track (this is one of the most valuable parts of conferences for many people, and we wanted to emphasize it), and which talks were given (first one was about how to get the most out of a conference, talks encouraging community orientation).

SCR1 was awesome. It set off a buzz in the Ruby world about this conference that was about people, not just code. And attending it made me so jealous of the organizing group, who were largely my friends and coworkers. I wanted to be up on that stage! I wanted to have helped make this amazing thing happen! I wanted to be part of that close-knit circle of people working together!

I joined the organizing group for the first time at the after-conference potluck and retrospective at the end of that summer, in Carols back yard. It was this huge group of people whod been working together for a year to make the conference happen, and while I knew 2/3 of them, I didnt know them in this new capacity, didnt know about the skills and dedication they had that had made this conference appear out of nothingness. I felt a little shy (unusual!), and a little like an outsider, pretending to remember the names I didnt know, voicing my opinions about what theyd done right and wrong. We retrospected in the time honored fashion - with hundreds of stickies and sharpies, talking about what went well, what hurt us, and what could grow to be something beautiful next year. The posterboards spilled out over the edges of the folding tables, covered with sticky notes and citronella candles, and the talking went on and on, until we couldnt read the stickies anymore in the dark.

The thing that was most unnecessarily awful about the first SCRC, as clearly shown in the retrospective, was registration. I remember running out of things to say to the people around me in line as we waited for an hour and the whole conference starting late, which impacted the whole days schedule. So the second year, we fixed that by putting swag bags together the night before registration so people just had to say their last name and pick up their bag to register. What an amazing swag bag party. It was three hours of fun? drudgery?, with about 20 people crowded around some long tables at the office (near to our venue) of some of the organizers. Jenny ordered the weirdest, awesomest pizza Ive ever had (it had plums on it), we plundered the drink fridges, we over-logicd our way through alphabetically organizing 400 nametags and folding 400 tshirts, then matching the sizes to the nametags and making sure everything stayed alphabetized as it moved to the venue. We iterated into this efficient machine of making everything work so that all our lives would be easier at 8am the next day - and registration didnt have a line the second year. We were so triumphant!

But that was at the end, right before the conference. Before that was a whole year of occasional organizing. The first meeting, Carol projected the list of things that had needed to be done last year and started putting names next to them: Well, who will take care of this this year?. Social media. Finances. Venue negotiation. Party venue. Food & drink. Speaker proposals. Sponsor solicitation. Carol was head delegator and taker-care-of-the-leftovers. I grabbed up the jobs of MC and speaker liason.

Who was there? Some of the same people from last year, who knew what they wanted to do (either the same thing as last year, or emphatically not the same thing). Some of them had quit working at my company, started somewhere else, and brought new coworkers. Some new folks from our company. It was a bigger group then than it was at the swag bag party, and the people who stayed were the people who claimed things to do.

We met maybe once a month, with lots of emailing in between, and people doing work on their own. At meetings, wed talk about what needed to be done next, make group decisions based on research, and ask for opinions and help as needed. Carol and Justin would run the meetings and give opinions about what the conference /was/ when we needed help deciding. I took notes, including writing down a lot of action items, and organized the Google drive folder. We never reviewed the action items from past meetings - people did what theyd signed up to do. It turns out that nothing that we did was magic - all that it was was doing it, doing the work. Each person was choosing to dedicate their time to this thing we were doing together& and seeing things get done, progress get made, it engendered trust and confidence in each other.

There were a few topics that werent owned by any one person or small group, but decided by the entire group, most notably the speaker selection process. That was another thing we decided to do differently the second year, and the thing that was most awful about organizing that year. Heres what made it awful: we decided to do a CFP for the first time, and we didnt know or didnt think about how much time wed have to review the talks so we could announce the speakers in time for ticket sales. We got 200? submissions, which we needed to cut down to the final 12 that would make it into the conference next to our 4 invited speakers - in 2 weeks. And we had no infrastructure for doing this. There was this awful spreadsheet and blinding and voting process, and it took forever, and we had really low participation in the process because it was so bad. I was out of state at my cousins wedding during round 3 of the process, and I remember just ignoring it. I was glad I had a good excuse not to participate in round 4, where they were locked in a room until they came out with a schedule.

But we ended up with a great round of speakers that year, and another excellent conference. And we fixed the speaker selection process the next year with some tooling.

We also kept the swag bag party that third year, and it was similarly bonding. Again, another office of some of the organizers. Again, folding a million tshirts whose design we loved. Again, a lot of M&Ms and Swedish fish. You know, the minutia of finding the paper cutter to cut apart sheets of stickers and deliver them to the bag packers, then switch to folding the local restaurant listings so that they didnt run out of that stack. I came home full of triumph and excitement for the next morning.

We never did manage to fix the problem that it is apparently impossible to provide enough coffee for a conference full of programmers. Our attendees and speakers managed to forgive us somehow. At the end of the third SCR, all the yellowshirts emerged from the audience and the lobby and backstage and everywhere theyd been working and came together as a group to be acknowledged and to thank everyone for coming, and my heart swelled with pride to be part of that.

Thats how organizing SCRC worked - an informal group of people splitting up the work that needed to be done, clustering around a heart and driving force, coming together to make one amazing thing. That division of labor was, like in a bad interview question, both the strength and the weakness of our organizing group. When Carol and Justin let us know that they needed to not be SC this next year because they wanted to move on to other things in their life, no one was willing to step up and say I am SCRC, I devote myself to this. We were all willing to take on parts, but not to be the conference, the motive force behind it, the opinion that made the decisions that were unsure.

SCR was famous as a conference for being about community just as much as technology. And organizing it was about community, too, I think. Not just the community that actually happened at the conference itself, but mostly the smaller community that formed around making the conference happen.

We became friends & part of the same thing. We started out as unknowns, and through sharing work and boring awful things and tough things and triumphant things, we ended up as trusting partners who could put on an awesome conference and decide together that it was ok to not do it again.

Thats what it was like for me to work on SCRC. Thanks for listening!


Tune in next week for the thrilling tale of Mark Bowytz's first WTF!
[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!

http://thedailywtf.com/articles/the-life-and-death-of-steel-city-ruby-con


Метки:  

CodeSOD: Version Logging

Вторник, 05 Мая 2015 г. 14:00 + в цитатник

/creativecommons.org/licenses/by-sa/2.0)], via Wikimedia Commons" href="http://commons.wikimedia.org/wiki/File%3A251220061158_(335194668).jpg">251220061158 (335194668)

When a system evolves and grows, it's usually necessary to identify various versions of software living in the wild. There are many ways to do that: some hide their version numbers in code, some keep them in configuration and metadata files, and others store them in the application's database.

No matter the scheme, accessing and modifying the current version number should be easy and painless- that is, unless you're working with Stan K.'s codebase. In a truly brillant case of reusing existing system facilities, the developers resorted to a much less common method of determining which patches and upgrades have been applied:

my $path = "/var/log/";
my $rval = MyOwn::System::ls({ file => $path });
my @things = split(/\n/, $rval->{'stdout'});

foreach my $item (@things) {
    my $checkver = undef;

    ### ignore everything but Patches and Upgrades
    ### 'prev' indicates that a patch was uninstalled
    if ($item =~ "Patch" && $item !~ "prev" && $item !~ "rollback") {
        my @parts = split(/Patch\-/, $item);
        $checkver = $parts[1];
    } elsif ($item =~ "Upgrade" && $item !~ "prev" && $item !~ "rollback") {
        my @parts = split(/Upgrade\-/, $item);
        $checkver = $parts[1];
    }
    #snip...
}

Abusing the fact that every upgrade and patch installation leaves a log file behind, the code browses the /var/log/ directory looking for them, and determines the version number using their filenames. While mind-bending, the solution does work- until the application server starts running low on disk space, and the system admins decide to clean up the old logs...

[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!

http://thedailywtf.com/articles/version-logging


Метки:  

More is Better, They Said

Понедельник, 04 Мая 2015 г. 14:00 + в цитатник

Steves group was quite good,
they made quality software.
Then came Initech.

Initech bought them,
management had a field day
restructuring teams.

Haiku 2008-02-19

Steve was a mid-level developer when his company got purchased by Initech. Naturally, the new owners wanted to change everything. Old people were fired, new people were hired, and HR promised to take this group to the next level.

They hired a man named Ty, who replaced the senior developer on Steves team.

He was an expert
and his experience would
bring much rejoicing.

Or so said HR.
Steve quickly found himself to
disagree with them.

Early on in his new employment, Ty called Steve to his desk. Ive got this requirement, but I just cant quite get the code to work. Im getting an input from the user, and if its a number or a string, I have to do something different in each case. I can get it to work one way or another, but not both! Steve quickly showed Ty the documentation for Integer.TryParse and the if statement. As he left, he heard Ty mutter, his framework is way too complex! Nobody trained me for this!

This was a common scenario. Steve had to hold Tys hand through even the most basic programming tasks.

Give him an input
and ask him to validate,
and he wont get it.

Hand him a double
and have him round it to tenths,
and mainframes will crash.

Show him an error
and stacktrace, his own brain will
overheat and melt.

Fizz-Buzz would have been
enough of a test to stop
his acquisition.

Ty blamed everyone but himself for his problems. Someone checked in bad code. It worked yesterday! My computer is broken! Steve is an idiot! This last was exactly the sort of thing the new management wanted to hear. They pulled Ty into a critical new feature: new reports for their BI application. This happened to mirror work Steve had done just a year before.

When Ty was tasked to
develop BI reports,
Steve kept his distance.

Ty coded and worked,
and after several months his
work was deployed live.

But celebration
was not in order, there
was a big problem.

Steve! We have a huge problem here! said Tyler, as he burst into Steves workspace. The numbers in my reports dont match the numbers in your old reports. You need to figure out what you did wrong.

Steve blinked. No one has noticed any problems before. Are you sure your report is right?

Of course its right! retorted Tyler. Now go fix your bugs- we need an answer by the end of the week.

Steve looked at Tys code
and found bad SQL joins.
The output was wrong!

Because of the joins,
sums grew exponentially
based on project count.

Employees with few
projects were in the ballpark,
but still not correct.

Employees with tons
of projects were millions of
bucks overstated!

Steve gathered his findings and prepared for an end-of-the-week meeting. Both Ty and the BI director scoffed at what he found.

Though Steves old reports
had not changed in many years,
they had to be wrong.

Tys report output
contained a lot more data!
And thats a good thing!

You see, the BI director explained, look at how many more rows are in Tys reports than yours. His shows more information. More information is always better!

But, Steve tried to explain, the data is wrong. Hes doing cross-joins where he shouldnt be!

How can more data be wrong? Ty challenged. The BI director nodded in agreement.

Since more is better,
Steve was given a new task.
His heart grew heavy.

Lo, his own reports
must be re-written to work
just like Tys reports!

Loosely inspired by this thread

Image Credit: KAMiKAZOW Haiku: Contributors (Own work) [MIT (http://opensource.org/licenses/mit-license.php) or MIT (http://opensource.org/licenses/mit-license.php)], via Wikimedia Commons

[Advertisement] BuildMaster is more than just an automation tool: it brings together the people, process, and practices that allow teams to deliver software rapidly, reliably, and responsibly. And it's incredibly easy to get started; download now and use the built-in tutorials and wizards to get your builds and/or deploys automated!

http://thedailywtf.com/articles/more-is-better-they-said


Метки:  

Error'd: Used Shellfish

Пятница, 01 Мая 2015 г. 13:00 + в цитатник

"According to channel 7 in Australia these guys are right into trawling for content," Martin.

Maciek asks,, "So...Where do you submit an issue with Office 365's Issue List?"

"Plug Samsung Galaxy 4 Active into Windows 7 computer. Wait. Windows chooses the BEST driver for mounting a mobile phone share via USB. Cry," writes Anon.

"Some industry-specific terminology in a company manual I'd imported into Google Docs was not found Google's spellcheck dictionary," writes Louis N., "It turns out that Google's dictionary wasn't just missing industry lingo."

Mike writes, "If only I had a time machine, then I could travel into the future to get a machine that meets these specs!"

"Apparently the Industrial Revolution was a little more revolutionary than I first realized," writes Kartikeya I.

"Wow - I'm torn. I usually go with google.co.uk, but I'd be willing to give google.co.uk a shot too," wrote John.

"I just noticed this on a package of Bluetooth dongles we ordered," Tim T. wrote, "A quick Google search seems to indicate it's a VB.NET error message."

[Advertisement] Use NuGet or npm? Check out ProGet, the easy-to-use package repository that lets you host and manage your own personal or enterprise-wide NuGet feeds and npm repositories. It's got an impressively-featured free edition, too!

http://thedailywtf.com/articles/used-shellfish


Метки:  

Source History Information Tool

Четверг, 30 Апреля 2015 г. 14:00 + в цитатник

In technology as in life, some folks get it, and some dont. Trying to make the ones who dont get it get it can sometimes challenge even the hardiest of tech-souls. Michelle made a valiant effort to enlighten one such individual, and failed. This is her story.

Dunny

Michelles predecessor had migrated their code-base from VSS to SVN, before fleeing for the hills. Michelle was the replacement. Before she finished finding her cube, she was cornered by her manager and peers with some concerns. About this new-fangled SVN source control system, they began, and then they tried to pin her down as to how she could address their issues&

Specifically, Bob, the manager asked: Is it true that in SVN, anyone can check-out the code?

Of course, Michelle replied. She explained that anyone with an account can check out the source code at any time. This started an avalanche of stupidity that, not unlike one of snow, only gained mass and momentum with time.

Jim, the lead developer, said that this was a problem. If I checked out a file, I would have no idea if someone else was working on that file as well. When Michelle just looked at him, blankly, he continued: VSS was much better in that respect.

Michelle explained that this was the whole point, and in fact, one of the main benefits of SVN. Unlike VSS, SVN supports concurrent development, and its smart enough to automatically keep track of whos changing what for you.

Jim was worried that if he was working in an area of code, he needed to know that nobody else was working on it, so his change(s) wouldnt get overwritten by the other developer.

Michelle went on to console him by explaining the concept of merges and how merge collisions would be handled.

Yeah, but were working on a major bug and need to know that no-one else is working on those files!

Michelle then explained the concept of branches. She further explained that the file history was available for examination, and in an extreme case, an automatic email notification could be sent where anyone on the mailing list would receive notification every time someone committed code.

Bob and Jim would have none of that. Bob complained, No thats not good enough. We cant risk developers clobbering each others code. You need to change this. When I go to the bathroom, I have exclusive use of the stall. Others can only use it before me or after me, but not at the same time as me. We need this same level of isolation in handling our source code.

Try as she might, there was no explaining that this was really not necessary, as going to the bathroom and editing source code were, in fact, two very different things, and that it defeated the point of a multi-versioned, concurrent development environment&

Bob insisted, in absolute finality: No its too dangerous. Please change SVN to make to make it single check-out only; now! Before something terrible happens!

In reality, something terrible already had. Michelle resigned herself to the stupidity of running source control in the same way as accessing a toilet, she wrote a trigger script hack to disable parallel check outs. But at the end of the day, she couldnt bring herself to activate crap mode.

[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!

http://thedailywtf.com/articles/source-history-information-tool


Метки:  

CodeSOD: One In a Million

Среда, 29 Апреля 2015 г. 14:00 + в цитатник

Marcus inherited a big-ol-ball-of-mud PHP application. The entire thing is one difficult to summarize pile of WTF, but he searched long and hard to find one snippet that actually summarizes how awful the code is.

That snippet is this :

function generate_confirmation_number(){
        //compact the job number to two digits by adding digits 1+2 and appending to the sum of digits 3+4
        $c_jobno = ($jobno{0}+$jobno{1}).($jobno{2}+$jobno{3});        
               
        //generate an array with 1 million elements        
        $numbers = range(0,999999);

        //get all the confirmation numbers that have been used
        $rs = $this->_conn->execute("SELECT used_num FROM used_num WHERE used_num LIKE '%s' ORDER BY used_num ASC",$jobno.'%');
        
        if ($rs->get_record_count() > 0)
        {
            while (!$rs->eof)
            {
                //delete elements in array corresponding to the last six digits of the confirmation number            
                unset($numbers[substr($rs->value('used_num'),4)]);
                $rs->move_next();
            }
        }
        
        //randomize the order of the remaining numbers
        shuffle($numbers);        
        
        //glue the compacted job number to the first element in the numbers array (which is ordered randomly)
        return $jobno.$numbers[0];
}

The goal here is to find a number that hasnt been used for a previous confirmation. To find that, they generate an array with every number from 0 to 999,999, and then query the database for previously used confirmation numbers. They then look at every previously used number, and then try to delete it from the array, if it exists.

[Advertisement] BuildMaster is more than just an automation tool: it brings together the people, process, and practices that allow teams to deliver software rapidly, reliably, and responsibly. And it's incredibly easy to get started; download now and use the built-in tutorials and wizards to get your builds and/or deploys automated!

http://thedailywtf.com/articles/one-in-a-million


Метки:  

The Daily WTF: Live: Killing the Virus

Вторник, 28 Апреля 2015 г. 14:00 + в цитатник

On April 10th, I hosted The Daily WTF: Live! in Pittsburgh. It was a blast. We had a great crowd, and some great performances.

Our first story is one of my own- a tale about how one computer virus finds its violent end.

Direct Link (mp3).

This episode is brought to you by our sponsor, Puppet Labs. Check out their intro video, it gives a pretty good overview of how they help their customers get things done. Start a [free trial](http://puppetlabs.com/download-puppet-enterprise) today!

Transcript

Host (Remy Porter):
Today’s Daily WTF Live is brought to you by Puppet Labs. Manage your infrastructure as code across all environments with Puppet. Start your free trial today!

Welcome to The Daily WTF Live. I’m your host Remy Porter, and over the next few weeks, we’ll be sharing a series of stores that were recorded at The Daily WTF Live show, held at the Maker Theater in Pittsburgh. We got local IT professionals up on stage to share their real-world, from-the-trenches stories in front of a live audience. Everybody who attended had a blast, I really enjoyed putting this together, and I look forward to doing this again sometime in the future.

For the moment, let me give a little bit of a shout-out to Puppet Labs. It was their sponsorship that made this show possible.

Our first story is one of my own. This is from a time when I was much, much younger, and much much braver. This particular story involves a little swashbuckling, a little derring-do… and in the end, something gets stabbed to death. Enjoy!


Storyteller (Remy Porter)
Like so many IT professionals, our lives from the trenches start quite young. Who here, you know, their first computer was a childhood memory? Right? So many of us, right? My first computer was a VIC20. I remember as a wee lad my dad plugging it into the television, ‘cause that’s what you plugged computers into back then.

And I grew up with a computer in the house the entire time. We had the VIC20, we had the Commodore 64… eventually we got the PS/1, which is the really really crappy version of the IBM PS/2. Like, imagine, you know… it was awful, it was a terrible computer. But, it was what I had when I was growing up. I thought it was the greatest thing.

And so, when I turned sixteen- like all aspiring nerds, I’d been saving up a lot of money, and it was not so I could go and buy a car. It was so that I could go to the Kingston Armory, where they were having a computer show. And I had, you know, all of my money saved up. I emptied my entire bank account to buy my first computer, the one that was mine to own.

This, this changed my life- or at least it was going to, right? Because I no longer had to get yelled at by my dad when something went wrong on the computer and it was like, “No, that’s your fault.”

I’m like, “I didn’t even touch it today! It’s not my…!” [sigh]

I didn’t have to put up with that anymore! I had my own computer! I could get any game I wanted. I could install it. This was going to be the big moment for me.

So I get home- and this was a computer show, so the computer wasn’t fully assembled. I had a motherboard, I had a processor, I had all of these things. And so I spend hours putting it all together. I had never done anything like this before. Sure it snaps together like Legos, but this is still the late 90s. It’s not fully like Legos, quite like it is today. You gotta mount it to the case right, and all of this stuff.

So, I spend hours doing this. This is my big moment for the weekend. And then I get it finally booted up, and I have to install all my software… hours and hours there… this is- I’m so excited. And the thing that really puts it over the top for me is that I have a friend who’s given me a lovely little floppy disk with… it was probably Doom 2, or Duke Nuke’em, something like that. And I had this illegally pirated floppy disk, and I built this computer just so I could put that floppy disk in there, load that program, and blow something to hell with all sorts of gory violence.

That was the perfect moment for me. Until… things just started getting weird with my computer.

I had just put it together. I had taken everything from my bank account, put it into this computer… my computer started acting weird… immediately after I put this floppy disk in there. I’m like, “Oh, this is… this is a problem. This isn’t good. This is… oh no.”

And I couldn’t pin down exactly what was weird. It was just all sorts of things like sounds wouldn’t play, but then they would, or the monitor would do weird things. I wasn’t really sure what was going on until I talked to the friend who gave me the floppy disk. And he said “Yeah, my computer had a virus. It was AntiCMOS.A, which did something to my motherboard, which destroyed my computer. I just had to get a new one.”

And I’m like, OK… That doesn’t sound entirely plausible, but at the same time, I’m utterly terrified, because I had just done everything. This- If I lost this computer, if I had to get a new one, I was done.

And this was the 90s, right? This was mid90s. I couldn’t just go online and look up this virus. So I had to sit there and I had to reason about it. I had to think about it. You know, virus programs couldn’t get it because it was actually in the hardware. AntiCMOS.A actually infected the CMOS chip that controls your BIOS.

And I’m like, OK, I know it’s called AntiCMOS.A, so I know, I know, that this virus is somehow tied to my CMOS. And because I was a good nerd, I didn’t read the manuals, but I did have them. So I went to my motherboard manual, and I start flipping through, and I see stuff about the CMOS. And I see that to resolve my issues, or to purge the CMOS- to wipe it- there’s a jumper that you can close on the motherboard.

Now, this was a computer show motherboard, so it did not actually come with any spare jumpers. There were none of those little plastic gates that I could put over those pins- there wasn’t one. I didn’t have an extra one that I could just move from someplace else.

So I just sat and thought to myself and said, “I have a screwdriver.”

And I took the screwdriver and I put it between the two pins, and I hit the power button, and absolutely nothing happened. Nothing turned on, no lights flashed, and I’m like, “All right, that’s it. I’ve just stabbed my computer to death, aaand that is going to be the end of my life for the foreseeable future.”

But I take the screwdriver out, and I hit the power button again, just hoping against hope- and sure enough, my computer boots up. The problem is solved. I no longer have that virus, until I borrow another floppy disk from that friend- but at least then I knew what to do about it.

And as far as I know, this makes me the only person who has killed a computer virus with a screwdriver.


Host (Remy Porter)
And so that was my adventure with my first computer virus. A little bit of a violent ending there. Next week, our speaker will be Jean Lang, and she’s gonna be pulling back the curtain and explaining how the Steel City Ruby Conference came to be. Thank you for listening, tune in next week for more stories.

[Advertisement] BuildMaster is more than just an automation tool: it brings together the people, process, and practices that allow teams to deliver software rapidly, reliably, and responsibly. And it's incredibly easy to get started; download now and use the built-in tutorials and wizards to get your builds and/or deploys automated!

http://thedailywtf.com/articles/killing-the-virus


Метки:  

CodeSOD: Universal Printout

Понедельник, 27 Апреля 2015 г. 14:00 + в цитатник

Dorian Gray

It had been a long meeting, and Bert was exhausted. Now, normally when a story on TDWTF starts that way, we go on to tell you about a hapless developer trapped in management hell, but this time, we're flipping the script on you: Bert was the Business Analyst on a project to enhance some self-check software for a number of supermarket chains. Ernie, the Software Engineer, was one of those braindead devs who needs everything spelled out before he'll write so much as a line of code, and Bert was much more comfortable with the looser specs in Agile projects.

Since the fourth Requirements Clarification Meeting was dragging on into hour two, Bert was getting a little snippy. So when Ernie asked for clarification on exactly how long a given printout might be, in millimetres, Bert couldn't help himself: he cracked. "Well, potentially infinite, I guess!"

The code Ernie delivered:


 public override SizeF PaperSizeInMM
 {
 get { return new SizeF(110F, float.MaxValue); }
 }
 
 

To put this in perspective: float.MaxValue here is 3.4x10^38 millimetres. This equates to about 11,018,635,432 gigaparsecs. A single parsec is 13 trillion kilometres; a gigaparsec is 1 billion of those. The observable universe is a sphere with a diameter of about 29 gigaparsecs. This author's spellcheck doesn't even recognize gigaparsec as a word!

But it wasn't just silly: it was bug-inducingly silly. On some versions of Windows, this would cause GDI+ to throw up its proverbial hands and emit a "Generic Error", crashing the self-check machine.

Next time, Bert would just rattle off some large number and call it a day...

[Advertisement] BuildMaster is more than just an automation tool: it brings together the people, process, and practices that allow teams to deliver software rapidly, reliably, and responsibly. And it's incredibly easy to get started; download now and use the built-in tutorials and wizards to get your builds and/or deploys automated!

http://thedailywtf.com/articles/universal-printout


Метки:  

Error'd: The Answer to this Question is WTF?!

Пятница, 24 Апреля 2015 г. 13:00 + в цитатник

"For a site that is used to view pay stubs, you'd think that they'd come up with better security questions," Carter K. wrote.

Shelly writes, "I'm not sure exactly how much I'd be paying at checkout with the Disney Premium Visa, but just to be safe, I think I'll use my Discover Card instead."

"Once you make it past the front doors of the retirement home where my friend's mother lives, you'll be faced with this layer of security," writes David N..

"We all know freemium games have a way to make you pay to avoid waiting. This will be a hard one to avoid for even the most patient ones among us - 2000 years?" writes Maarten.

"I just had to look and see this huge discount in my cart while searching for a new Logitech remote," Jeff T. wrote.

"I'm so glad that not every piece of software alerts me when there's no error, like iTunes does. I'd be clicking 'OK' all day," Daryl D. writes.

Gaelan S. wrote, "Does this mean I don't have to wash it?"

"I just wanted to resize a picture in Microsoft Word for a report,"Tyrone S. writes, "I guess I could try writing my report in Excel instead because it is better with numbers and math and stuff."

[Advertisement] BuildMaster is more than just an automation tool: it brings together the people, process, and practices that allow teams to deliver software rapidly, reliably, and responsibly. And it's incredibly easy to get started; download now and use the built-in tutorials and wizards to get your builds and/or deploys automated!

http://thedailywtf.com/articles/the-answer-to-this-question-is-wtf-


Метки:  

CodeSOD: Open And Shut

Четверг, 23 Апреля 2015 г. 14:00 + в цитатник

Our anonymous friend writes: I was tasked with figuring out why invalid XML was being output by a homegrown XML parser.  As I looked into the code, I found the way this code handles writing out XML files…

Yes, it really does open and close the file handle for every xwrite call.  This means that it opens and closes it 3 times PER TAG when writing out the XML.


// xml_t is - essentially - a linked list of xml nodes.
void xmlwrite_file(xml_t* node, char* pFilename, int bNew)
{
        char WriteBuff[1024 * 17];
        char nodevalue[1024 * 16];
        char* nodeattribs;//[ATTRIBUTE_LEN];
        char nodename[256];
        char spacer[16];
        xml_t* pSib;
        int sc = 0;

        if (!node)
        {
                return;
        }

        nodeattribs = (char*)malloc(ATTRIBUTE_LEN);

        strcpy(nodename, "");
        FillNodeName(nodename, node);

        strcpy(nodevalue, "");
        FillNodeValue(nodevalue, node);
        strcpy(nodeattribs, "");
        FillNodeAttribs(nodeattribs, node);


        if (strlen(nodeattribs))
        {
                strcpy(spacer, " ");
        }
        else
        {
                strcpy(spacer, "");
        }

        sprintf(WriteBuff, "

http://thedailywtf.com/articles/open-and-shut


Метки:  

The Industry Vet

Среда, 22 Апреля 2015 г. 14:00 + в цитатник

Like most schools, Andys requried a capstone project for their software engineering track. It was a group project, which meant the projects success was largely dependent on the luck of the draw. For his partners, Andy drew Mindy and Al. Mindy, he knew from other classes and had worked with before.

The Intellectual Group

Al was a stranger, but Al had made his presence known from the very first day of class. You see, Al had industry experience. Al had been working with a global manufacturing company for a few years, and didnt really need this class. He lived this stuff. He knew more than the professor, so Al spent most of his time trying to help the other students, even going so far as to hold is own informal office hours in one of the computer labs. At their first team meeting in one of the conference rooms in the library, Al explained, This project here looks pretty close to some of the work Ive been doing.

Youve implemented a database for a library to track users and assets?

Not exactly, Al said, but its a basic data-driven application. Ive written thousands of these.

Thats really great to hear, Andy said, because Mindy and I havent actually taken the databases class yet- we dont really know SQL.

Great! Al said. I can work on the data-layer.

As an experienced enterprise developer, Al took the weekend to write up a specification for the database layer, which he gave to Andy and Mindy. They could use a stubbed version of the database layer, while Al did all the work on that side.

Now, Al warned as they reviewed the latest ER diagrams in a quiet corner of the campus coffee shop, Ive worked on a lot of projects like this, so let me warn you- well probably need to spend some time doing some serious integration testing to link all of these modules together.

Oh, Id expect as much, Andy said. If you can finish your work within the next week, well have two weeks left to do our testing.

Will do, Al said.

Al didnt do. He didnt get his database layer committed until one week before the due date. He skipped the next team meeting and sent an email, Project crunch at work, not available. Will send updates.

Andy and Mindy fired the application up with a pile of instructor-provided test data. It took nearly 100 seconds to filter through the 1000 test users and find a single users account. Performance got worse with larger data-sets, like the list of books in their library.

If it were just poor performance, Andy would have thrown indexes at the problem and hoped that cleared things up. There were worse problems, though. For example, according to the database, todays date was Martha Sawyer. User Jim Mahony had $155132 in late fees, there were 15,005.542 books in the database, and 16,000 of them were available to be checked out to users.

Andy decided to take a look and see if he could address those bugs. He immediately regretted the decision, because one look at the code told him that he had just given up on getting any sleep for the next week. Al did okay at managing database connections, but his vast industry experience apparently didnt include the use of the where clause. Every single query he wrote followed the pattern:

SELECT * FROM `table`

Al always loaded the results into a 2-d array. If Al needed to filter, he passed the matrix into a linear search. If Al needed to sort, he passed the matrix into a bubble sort.

Andy didnt really have any choice. He threw out Als work and reimplemented the database layer from scratch. At their final meeting before turning the project in, Andy diplomatically explained, I had to make some changes to your code.

Oh, sure, Al said. I know there were a few bugs in there. Its not like youre my parter in the Digital Electronics class- the day before our logic circuit project was due, he ripped out all of the wiring Id done on the bread-board and did it from scratch. That guy was a real jerk.

Well… actually… 

[Advertisement] BuildMaster is more than just an automation tool: it brings together the people, process, and practices that allow teams to deliver software rapidly, reliably, and responsibly. And it's incredibly easy to get started; download now and use the built-in tutorials and wizards to get your builds and/or deploys automated!

http://thedailywtf.com/articles/the-industry-vet


Метки:  

CodeSOD: Once You Eliminate the Impossible…

Вторник, 21 Апреля 2015 г. 14:00 + в цитатник

&Whatever remains, no matter how improbable, must be XML.

William Hogarth - Absurd perspectives.png

Developers have many weaknesses, among them this: they dont like to say that something cant be done. Thats why when Glenn Ms client, TelCo, asked if their request was really impossible, instead of apologizing and vigorously nodding his head, Glenn said, Well, technically&

And thats how he ended up writing this.


    
        
            
                
                    
                        
                            
(?:0x)?([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F]) .1.3.6.1.4.1.2011.2.217.1.4.1.1.6 %4$s%3$s%2$s%1$s 8388607 8388608
1
1 (?:0x)?([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F]) .1.3.6.1.4.1.2011.2.217.1.4.1.1.6 %4$s%3$s%2$s%1$s 23 255 127
(?:0x)?([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F]) .1.3.6.1.4.1.2011.2.217.1.4.1.1.6 %4$s%3$s%2$s%1$s 31 1 1 -1 1

Thats an XML DDF, a Data-Definition File for the systems-monitoring application Glenn supports. See, the system can read data from any device that supports the Modbus/TCP or SNMP protocols, as long as it has a DDF file that defines the data points and how theyre to be displayed. The DDF schema includes the arithmetic, boolean, regex, and conditional operators you see above, to let the system know how the data should be cleaned up.

Logic via XML? Thats a WTF all by itself, sure. But TRWTF is what that snippet above is actually doing. TelCo was monitoring a device that spat out temperature values (simple enough), but it presented them as an eight-character string representing the hexadecimal value of an IEEE754 32-bit floating-point number. The task that Glenn probably should have said was impossible was to cast that bizarre value back into its numeric equivalent. DDF, for all its awesome expressive power, lacked a typecast operator.

Thats why Glenn wrote the DDF shown above, which does this:

  • Since the byte order was flipped, use to put them back in an order we can work with
  • Use to convert from octetString to uint_32
  • Use and to isolate the sign bit, exponent and mantissa
  • Convert the sign bit to +/1
  • Unbias the exponent, then 1 by that many
  • Divide the mantissa by 2^23
  • Multiply the last three items together to get the final result. Since and other operators only accept 2 operands, these need to be nested

Next time, Glenn plans to stick to his guns, because he just heard that TelCo will be modifying their device to present temperature using integers.

[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!

http://thedailywtf.com/articles/once-you-eliminate-the-impossible-


Метки:  

The Third (Party) Circle of Hell

Понедельник, 20 Апреля 2015 г. 14:00 + в цитатник

While Ian was working at Initech, one of the major projects he undertook was an integration with a third-party vendor. They had recently gotten set up with this product that became known internally as the Third Circle of Hell (3CoH), and wanted to export some data from it over to the vendor's website. Sales agents needed some information during cold calls, and 3CoH promised to provide the data interactively, so that they could continue their call somewhat intelligently.

Circle of Jheronimus Bosch - Hell landscape

Getting in to the 3CoH might be easy, but getting out is another matter.

The existing system was manual and thus slow and rife with error. Sales agents would have to copy all of a customer's information, by hand, from 3CoH into a web form, which boiled down to a lot of copying and pasting. But since the vendor provided a SOAP API and 3CoH had its touted scripting language (essentially Java with some syntactic sugar for querying the 3CoH database), there was probably a way to automate the process. The task of doing that was assigned to Ian.

Of course, going directly from 3CoH to the vendor was out of the question, as it would involve hand-crafting a SOAP request and filling in fields by just concatenating together a giant string of XML with some variables. Some of his predecessor PHP developers at the company had thought that was a perfectly fine thing to do, and had created some scripts to employ that anti-pattern.

Ian had a less fragile idea in mind. With the aid of a Java library that generated Java classes from a WSDL, he set up a bridge server to stand between 3CoH and the vendor. 3CoH would package up all the needed information into JSON and send it to the bridge server. The bridge server would shuffle the data from the incoming JSON into the objects representing the SOAP request, generate the SOAP request, and send it off. When the reply came back, the process would go in reverse; the bridge server would pull out the URL returned by the vendor, and send it back to 3CoH as a regular HTTP response.

After a few development iterations, it worked, albeit slowly. That is, it would take about 30 seconds for the whole process, which is a long time when you're on a cold-call with a customer. Even worse, it would make Chrome assume the page had frozen and pop up a scary-looking dialog box to that effect. Ian was testing by pointing to the vendor's QA website and not the real one, so he naturally assumed this was the cause of the slowdown.

He was wrong.

Once they went live, he found that it was still just as slow, and the sales agents and managers were not happy, summarily resulting in various high-level managers alternately panicking about a failed project and spewing brimstone and fire down his neck about getting it fixed.

But the surprise came when Ian timed each segment:

Full Process
(3CoH -> Bridge -> Vendor -> Bridge -> 3CoH):
31 seconds
3CoH -> Bridge:1 second
Bridge -> Vendor -> Bridge:5 seconds
Bridge -> 3CoH:25 seconds(!)

Amazingly enough it was neither the huge block of JSON, nor the massive SOAP request that was the slowest part of the loop; it was the tiny HTTP response containing nothing more than a 200 for the status code and a URL in its body. After a few repetitions of the test to ensure that this wasn't a fluke, Ian had verified that his timing measurements were correct, that he hadn't gone insane, and that perhaps he had fallen into the 4CoH. He directed a few expletives in the direction of the authors of 3CoH, and Googled around. He found nothing and had to fall back on the last resort of the desperate programmer: Reckless Experimentation.

What if I sent a code other than 200? Still slow.

What if I removed https:// from the beginning? Still slow.

What if I returned something other than a URL? Still slow.

What if I returned a blank string? Still slow.

What if I put the URL into a header and sent a 309 redirect instead? ...instantaneous!

As it turned out, having a body element present in the HTTP request, in any shape or form, even an empty one, would cause 3CoH to block it at the gate, presumably for customs, interrogation or a full-cavity search, and then for no apparent reason other than to be annoying, delay about 25 seconds before continuing code execution.

But there was a saving grace; it would ignore the headers! Thus the return values could be stuffed into the header instead, and it would happily send the HTTP response, with no body, on its way and resume the script.

In the end, the other developers found this a source of great mirth. Thanks to his descent into the 3CoH, Ian died a little on the inside. But the integration was up and running.

Ian made sure to leave a long, detailed series of comments so that his successors in the 3CoH would know exactly why they could never, ever, under any circumstances return data in the message body.

[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!

http://thedailywtf.com/articles/the-third-party-circle-of-hell


Метки:  

Error'd: Nothing Refreshes like Lorem Ipsum

Пятница, 17 Апреля 2015 г. 13:00 + в цитатник

"How new is this beer? They didn't even finish the packaging!" wrote J'er^ome.

"Wow! Truly a one-stop-shop!," writes Diederik.

Alexandre A. wrote, "The Barracuda XT Desktop Hard Drive sure comes with a lot of features!"

"I've been saving for a while to buy a new Lenovo laptop," writes Brandon R., "Looks like I have a little bit longer to go to get the one I want."

"I do feel a little bad for having tried a right-click. Shame on me, what was I thinking?" writes Chris Dotson.

"I'm glad to see that the University of Washington," Matt B. wrote, "Oh and look! They know JavaScript too!"

"At first, I was excited when I found out that Domino's Pizza can be paid with PayPal, but then, my hopes were dashed," Sav writes.

Jeff R. writes, "Monarch Pro gives more than 100% when processing my data. Now that's service!"

[Advertisement] Use NuGet or npm? Check out ProGet, the easy-to-use package repository that lets you host and manage your own personal or enterprise-wide NuGet feeds and npm repositories. It's got an impressively-featured free edition, too!

http://thedailywtf.com/articles/nothing-refreshes-like-lorem-ipsum


Метки:  

Failure is OK

Четверг, 16 Апреля 2015 г. 14:00 + в цитатник

Roland was working on code that implemented HTTP service methods. The 'status' variable held one of those pass-it-everywhere objects that were sometimes called 'RunData'. It contained the request, response, security context, and other needed information. When JavaScript sent an asynchronous HTTP request, one of the service methods performed some backend magic and returned a JSON object with the appropriate data.

Teton Dam failure

That was the good case. In the bad case, the service method called status.fail, added one or more user messages, and returned without sending a reply. The error handling in the base class detected that the call failed, and sent an error response containing the user messages.

Roland had just introduced that pattern, which was meant to put an end to the convoluted error handling in older parts of the codebase. It seemed to work well. Then one day, he encountered a different use case: a service method that didn’t return any data in the good case. For the sake of symmetry, he decided it would return an empty JSON object, and got to work implementing that.

You're doing something wrong, his inner voice cautioned.

Roland had just copied some code from the good case of another service method: setting the MIME type and charset of the response, getting the OutputWriter, writing the data, closing the stream. Five lines total.

Still, he supposed his inner voice was right. Five lines of code for an empty reply was a bit excessive, but that was how he’d implemented the good case elsewhere.

Yes it is, the voice said. But for this? There's got to be a better way.

Roland reviewed the base class, checking whether there was any code he could reuse. Unfortunately not. The five lines were built into the error handling logic, and could not be invoked directly.

Time for some refactoring, the voice said.

Roland cringed hard at the thought. He’d spent so much time in the base class already. He was thoroughly fed up with refactoring.

You've got all the access you need, and you've got the source code in the editor already! Go on now...

Just as he was about to give in, Roland noticed something interesting: when he triggered the error handling without adding user messages, it sent an empty JSON object.

What the hell?

And he could specify the HTTP status code! Roland set it to 200.


  // slight abuse of the fallback error handling: send back status OK
  status.fail(HttpServletResponse.SC_OK);

You've got to be kidding.

It returned an empty JSON object with status OK. That was exactly what Roland needed.

Whoever sees that code will think it’s completely screwed up and 'fix' it for the worse. This is unmaintainable!

“That's why I put that comment in there,” Roland muttered under his breath.

Oh come on, you're not serious. Just check out the base class and put in a little helper method-

“No, damn it!” Roland snapped, waking up all cubicle-nappers in the vicinity. “I’m coding business logic now! No refactoring! This is the only service method that sends an empty reply! I'm not going to implement a helper in a base class for that! Look, it's either this, or the five-line block of code from the other good cases!”

No, please! Nooo!

And that was how Roland introduced a little WTFery into his otherwise fine code. Of course, it didn't stop there. Over time, more service methods were added- some of them with empty replies. No problem- Roland just followed the pattern of the first one. And the one-liner spawned many offspring.

Everything worked fine, but it was a dirty stain on his programming psyche. Over a year later, when Roland had to change something in the class where it all started, he used the opportunity to clean up those ridiculous one-liners.

There were still one or two spawns that had escaped to other classes, but he’d get to them eventually. And when he did, the inscription on their gravestones would read:

sendJsonReply(status, “{}”);
[Advertisement] BuildMaster is more than just an automation tool: it brings together the people, process, and practices that allow teams to deliver software rapidly, reliably, and responsibly. And it's incredibly easy to get started; download now and use the built-in tutorials and wizards to get your builds and/or deploys automated!

http://thedailywtf.com/articles/failure-is-ok


Метки:  

CodeSOD: Tri-State Boolean

Среда, 15 Апреля 2015 г. 14:00 + в цитатник

Five-leaf Clover, Megan McCarty128

"Lindsay."

Lindsay did her best to ignore her co-worker, Asher. Ever since management had removed cubicle walls (to "facilitate communication"), it had been a never-ending trial focusing on fixing bugs with the world's most annoying webdev prodding her every few minutes to talk about some inane television reference or sports event.

"Lindsay."

Lindsay closed her eyes, picturing the Maui beaches where she hoped to be reclining in two days time. Surely she could hold out that long, right?

"Lindsay!"

"What?!" She snapped, ripping off her headphones to look at his screen.

"Did you see that P1?"

Stunned that Asher was actually bothering her about, wonder of all wonders, work, Lindsay closed her travel agent's website and pulled up the bug tracker.

Sure enough, she'd been assigned a P1 defect. In the self-service component of the Procurement website, all users were able to download a spreadsheet containing the price lists for...

Lindsay gave a low whistle. "Is that every client's price sheet?"

Asher nodded, face grim. Pricing was a strictly held secret in the business-to-business world; if one client found out another was getting a deal they didn't qualify for, there'd be hell to pay. Only admins should've had download privileges, but somehow, that download button was enabled for every user of the site.

Priority one was usually reserved for "the entire site is down." A price sheet leak was pretty much the one exception.

It was easy enough for Lindsay to pull up and duplicate. She wondered how long the button had been incorrectly enabled. There was no indication in the ticket. Lindsay called the user, who explained they'd just noticed the problem. "But who knows how long it's been that way?"

Crap. It wasn't just a simple matter of reviewing what had changed since the last build. Lindsay pulled her headphones back on, switching from relaxing white-noise to something more upbeat while she brought up the debugger. Three grueling hours later, she found the reason why any and every user was able to download the price sheet:


if(userCanDownload != true && file != null || userCanDownload != false)
{
	EnableDownloadButton();
}
Else
{
	DisableDownloadButton();
}

"Huh," she said, tilting her head slightly to the side as she puzzled over the inanity.

"What?" asked Asher, coming up behind her.

"You know... somehow I expected FILE_NOT_FOUND."

[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!

http://thedailywtf.com/articles/tri-state-boolean


Метки:  

Seven Minutes in Heaven

Вторник, 14 Апреля 2015 г. 14:00 + в цитатник

Steven quietly bowed his head as the planning meeting began. Their leader, messiah, and prophet was Jack, and todays sermon was was the promise of Heaven- Heaven being the codename of their ground-up rewrite of their e-commerce solution.
Franz Von Stuck - Sisyphus
Jack sat at the head of the table, in front of the projection screen. Behind him glowed the Spreadsheet of Pending Tasks, and the cells surrounded his head like rectangular halos. His eyes glowed with the power of his vision. In Heaven, our customers will be able to customize everything. Everything!

Jack had lead the development on Heavens predecessor. Like Heaven, it was endlessly customizable. It was also slow, buggy, impossible to maintain, utterly incomprehensible, and tied to a deceased proprietary technology stack. Jack had climbed the mountain and brought back word from management: a total rewrite.

We made some mistakes in our last version, Jack admitted, but this new version wont suffer from the legacy of history. Were making a clean break with the past. Ive already gotten a great start on the project.

Steven didnt groan, but couldnt fully suppress his shudder. Jacks coding style had a lot of quirks, but his worst quirk was that he never deleted a line of code. If a line of code were no longer used, hed wrap a conditional block around it, e.g. if VERSION < 1.2 { doThisDeadThing(); } else { doTheProperThing(); } Jack also tended to over-engineer… everything.

Jacks great start didnt include any e-commerce functionality, but it included Jacks greatest invention yet- JSQL (Jacks Smart Query Language, or as most people knew it, Job Security Query Language). The language itself was simple: JSON documents, loosely modeled on MongoDBs query language, but without any aggregate functions and broken filtering syntax.

Worse than that, they werent really using a NoSQL database. Jack had read that NoSQL was highly customizable, and decided to implement his own NoSQL database… on top of MySQL. This mostly meant a table with the columns: PK_ID, KEY, VALUE, PARENT_ID. PARENT_ID, of course, was a foreign key back to PK_ID, which allowed him to build arbitrary document structures if you nested the relationships deeply enough.

It was ugly, it was slow, and it didnt work. After a few weeks getting nowhere with the system, Steve decided to bring it up at the next planning meeting. Weve debugged a hundred issues in the JSQL layer- this week. And its not really getting us anything- most of our data is still relational in nature, were just storing it as documents. We should just switch to a normal database design.

But then, Jack proclaimed, our users wont be able to customize everything!

Do our customers really need to define arbitrary data-structures to represent their products? Couldnt we just give them some metadata tables or something?

Maybe, Jack said, the JSQL layer isnt for you. Perhaps you need to work on HARP. Yes, I think youll work on HARP now. Youre more of a UI person, anyway.

Steven wasnt a UI person, but that was okay, HARP wasnt the UI layer.The Heavenly Application Rendering Platform simplified user interface development. Like JSQL, it was its own language, a declarative language that mixed presentation and behavior into the same big ball of mud, then shoved that ball of mud against the rest of the application code until bits of it leaked over everything. Changes to HARP could successfully break JSQL. Steven found this out when he broke JSQL repeatedly.

The project ground on, weeks turned to months, months to more months, and after nearly a year of work, the application had exactly zero e-commerce functionality. Steven had tried to sneak some in when Jack forgot to assign him tasks on building their Inner-Platform, but Jack broke the functionality when he completely re-wrote HARP over one weekend.

This lack of progress got the attention of the CEO, who rounded Jack and the project team up for a meeting to identify the problem. Jack once again took a seat at the head of the table, with his Spreadsheet of Pending Tasks giving him the managerial aura he wanted to project. As you can see from the burndown, were making great progress, Jack said.

The CEO nodded sagely, as Jack pointed out the many, many completed tasks on the spreadsheet.

Weve made great progress on nothing, Steven said, hoping the CEO would listen to reason. Were building this framework that solves the wrong problem- our real problem is, how do our customers sell things? Instead, were building our own database engine and writing programming languages!

If we didnt do that, our customers wouldnt be able to program their own stores, Jack said.

Why would they want to? Making everything customizable just gives our users more ways to break everything. What business wants to program their own storefront? They want to buy something ready to go and tweak the look and feel!

Our users should be able to customize everything, Jack said.

The CEO nodded sagely. Yes, I like the idea of everything being customizable. That sounds great, guys. Lets go and make the best e-commerce app ever!

Jack didnt take kindly to Stevens heresy. Stevens eternal punishment (or, at least his punishment until he found a new job) was the Sisyphean task of trying to roll e-commerce functionality into Heaven, only to have Jacks every check-in break his changes entirely. By the time Steven left for greener pastures, Heaven still had no core functionality, but had grown an impressively bloated database engine.

[Advertisement] Use NuGet or npm? Check out ProGet, the easy-to-use package repository that lets you host and manage your own personal or enterprise-wide NuGet feeds and npm repositories. It's got an impressively-featured free edition, too!

http://thedailywtf.com/articles/seven-minutes-in-heaven


Метки:  

CodeSOD: Descriptive Overload

Понедельник, 13 Апреля 2015 г. 14:00 + в цитатник

Information Overload

Unquestionably, a good method name should be descriptive. With today's code completion and code analysis features, almost all developers expect the names to give them at least an idea of what a method should do. When you write a library, or work on a shared codebase, it's a must- and even if one doesn't expect anybody else to use their code, it's still good not to have to remember what stuff doStuff() does.

Some people, however, take it a bit too far. Today's example of abusing good practices was provided by David, who sent the following code with a comment: "This code takes $10 million USD in transactions a month". After reading it, it's fairly obvious the developers shouldn't be trusted with the loose change in their pockets:


class [snip] extends Mage_Sales_Model_Order{

    public function getStatususThatShouldntBeLightlyTrifledWith(){
        return array('paid_fulfilled','paid_unfulfilled');
    }

    public function isAStatusToNotBeLightlyTrifledWith($status){
        return in_array($status,$this->getStatususThatShouldntBeLightlyTrifledWith());
    }

    public function orderIsInAStatusNotToBeTrifledWith(){
        return $this->isAStatusToNotBeLightlyTrifledWith($this->getStatus());
    }

    private function disableHistorySaveCallParentMethoThenReenableHistorySaveThenReturnResultOfCallingParentMethod(){
        $this->internalHistoryDisable = true;
        $backTrace = debug_backtrace()[1];
        $toRet = call_user_func_array(
        array('parent',$backTrace['function']),
            $backTrace['args']
        );
        $this->internalHistoryDisable = false;
        return $toRet;
    }

    public function addStatusHistory(Mage_Sales_Model_Order_Status_History $history){
        return $this->disableHistorySaveCallParentMethoThenReenableHistorySaveThenReturnResultOfCallingParentMethod();
    }

    protected function _setState($state, $status = false, $comment = '',
        $isCustomerNotified = null, $shouldProtectState = false){
        return $this->disableHistorySaveCallParentMethoThenReenableHistorySaveThenReturnResultOfCallingParentMethod();
    }

    public function addStatusHistoryComment($comment, $status = false){
        return $this->disableHistorySaveCallParentMethoThenReenableHistorySaveThenReturnResultOfCallingParentMethod();
    }
 
}

We're not sure what's the biggest WTF here: the ridiculously obtuse method names, the abundance of typos, or the disableHistorySaveCallParentMethoThenReenableHistorySaveThenReturnResultOfCallingParentMethod() function, which walks the backtrace to re-call the function that called it. That last one is certainly an example that sometimes, no matter how hard you try to describe your function, you can still leave your fellow developers completely stumped.

[Advertisement] Use NuGet or npm? Check out ProGet, the easy-to-use package repository that lets you host and manage your own personal or enterprise-wide NuGet feeds and npm repositories. It's got an impressively-featured free edition, too!

http://thedailywtf.com/articles/descriptive-overload


Метки:  

Error'd: Laser Targeted Advertising

Пятница, 10 Апреля 2015 г. 14:00 + в цитатник

"I know that whenever I sit down to watch the adventures of brutal 14th century Mongolian warlords and Italian explorers, I want to dress the finest from my Ralph Lauren collection. And you should too!" writes Mike S.

"I don't know what two words I'm supposed to use here. Even if I use the numbers as the first word, what is the second word? Tree? Post? Lincoln Log?," writes Keith S.

Jerason B. wrote, "While not saving the world, the Avengers deal with the implications of Western-style beauty pageants disrupting traditional Hindu society!"

"Error based advertising -- it's the wave of the future!," writes Chris Z.

Alex S. wrote, "According to the Heisenburg uncertainty principle, it is impossible to know both the location and closing time of a pizza place."

"So, whether your answer is yes or no, you've only got 4000 characters to fit it all in," David writes.

Egor found this in the "allegedly technical" BRW magazine.

Steve D. writes, "While shopping for new boots online, my decision is nearly final - I just can't decide between the...knife and diamond ring?!"

[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!

http://thedailywtf.com/articles/laser-targeted-advertising


Метки:  

Поиск сообщений в rss_thedaily_wtf
Страницы: 124 ... 23 22 [21] 20 19 ..
.. 1 Календарь