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

Поиск сообщений в 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 ленты.
По всем вопросам о работе данного сервиса обращаться со страницы контактной информации.

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

Coded Smorgasbord: A Type of Insanity

Вторник, 13 Октября 2015 г. 13:30 + в цитатник

Types are fundamental to most programming languages. Even the loosest, duckiest type system is still a system of some kind. Its impossible to be a programmer if you dont at least have a vague understanding of what types are, what they mean, and how you use them.

Well, not impossible.

The Null Type

Kelly came across some C# code that needed to take the value in one variable (which may be null), and store it in the property in an object. Instead of writing the obvious statement:

someObj.SomeProperty = instanceOfAClass

Kellys predecessor wrote this:

someObj.SomeProperty = (AClass) null != null ? null : instanceOfAClass;

That conditional is a mystery: cast null to a class type, and if it somehow ceases to be null in this process, return null, otherwise return an instanceOfAClass.

The Flip Flop

That, of course, was just some copy-pasted code. Cara recently had to delve into the sewer- er, I mean plumbing- of an enterprise application. There, she found this pattern, copy-pasted everywhere:

String st_id = Integer.valueOf(rs.getString("student_id")).toString();
msgData.setSID(Integer.parseInt(st_id));

Hey, strings everybody! Strings. And integers.

Birthyear

We usually avoid running date-related code, because dates are the easiest thing to screw up. The venerable Falsehoods Programmers Believe About Time (Part 1, Part 2) remain a great reference for all of the ways people can screw it up. But dates are a data type, so they're on theme for this article.

My personal favorite bad-date code is when they obviously know enough to use the date-related operations and functions provided by their standard library, but still mysteriously feel the need to reinvent their own at the same time. It shows knowledge without understanding . Dominique stumbled across this:

now = datetime.now()
days_per_year = 365.24
for age in ages: 
    result['years'].append((now - timedelta(days=age*days_per_year)).year)

I like its attempt at handling leap years- they even recognize that the centennial years dont get leap years and drop 1/100 (of course, that only applies to centennial years divisible by 4, like 2000, but not 1900) . Of course, theyre already using the .year property of the timedelta object, which is a property also mirrored on date objects- they were so close, yet so far.

[Advertisement] Scout is the best way to monitor your critical server infrastructure. With over 90 open source plugins, robust alerting, beautiful dashboards and a 5 minute install - Scout saves youvaluable engineering time. Try the server monitoring you'll M today.Your first 30 days are free on us. Learn more at Scout.

http://thedailywtf.com/articles/a-type-of-insanity


Метки:  

Run Crash Crash Run

Понедельник, 12 Октября 2015 г. 13:30 + в цитатник

As Max entered the room, he was instantly greeted by a scorching wave of heat.

BSoD in Windows 1.0

As it turned out, even the freezing Russian weather was no match for the boiling hot atmosphere at Sturmovik Games' office. The small Moscow-based company with a humble portfolio of mobile games was just days away from a major content update for one of them. Naturally, the whole place was on red alert. Said update had been in the works for over six months, and had been widely advertised as the greatest overhaul the three year-old game had ever seen.

During those six months, Max and his two coworkers put in an insane amount of work, implementing the ever-changing feature requests, writing and rewriting swathes of code, and fighting against the buggy third-party libraries they had to use. Finally, the stress and overtime hours were about to pay off. Every deadline had been met. All they had to do was deploy the update.

Or so Max thought. The booming voice behind him brought him back to harsh reality.

"Who broke the build?!"

The dreaded question hung in the air. Max turned to find Ivan, his fellow developer, standing and looking around the room to find the culprit. With the third developer on sick leave, there weren't many other people to whom the question could be addressed.

"What do you mean?" Max asked. "It worked yesterday, and ..." He trailed off when he noticed an email that had just arrived in his mailbox:

From: Alexey <apajitnov@sturmovikgames.net>
To: Icarus Flight DEV team <dev-2@sturmovikgames.net>
Subject: CRITICAL Bug - game does not start

The game fails to start two out of three times. Please investigate.

A.

Klaxons went off in Max's head. "What?! I ran the game a million times yesterday. It was fine!"

"Okay then, let's see it." Ivan went up to his desk with his cellphone in hand. "I just cleared it off my phone, we'll reinstall it."

The game launched and ran properly the first time they ran it. On the second launch, it crashed seconds into the splash screen.

Max stifled an expletive, his heart pounding. "Again."

Ivan tried running the app, only to have it refuse to start again.

"Again," Max urged.

That time, the game started without a hitch.

They launched it about twenty times. The pattern remained unbroken: the game started up once, then crashed twice, then started up once, then crashed twice ...

At first, Max had wondered if he could write it off as a connection problem, but the regularity of the pattern made him curious.

"Okay, this freaks me out," Ivan said. "Let's dig into the code, there's some seriously eerie stuff going on."


After a whole morning of peeking and poking at the code, Max finally felt like all the pieces of the puzzle were coming together. He double-checked the lines he'd just modified. "Either I'm right, or I've lost all concept of reality."

Max pulled the trigger and rebuilt the game. When he ran it for the first time, it worked as expected. Then, the moment of truth. He ran it a second time ...

It didn't crash. He did it. He broke the pattern. Max fell back against his desk chair with a sigh of relief.

"Hey, you fixed it!" Ivan was happy as a kid with a new toy. "What was the problem?"

"That stupid new XML save file," Max groaned.

As part of the update, management had decided that all save files for all games were to be migrated from undocumented binary blobs to a common XML-based format. Max hadn't been too pleased about the change, but he'd written some migration code to change the file format on the first startup.

"See, on the first run, the game reads the old binary file, then saves it out as XML," Max explained. "The game runs fine. Unfortunately, the new save file was broken. There was an unclosed tag right at the end."

"Oh," Ivan moaned, seeing where this was going.

"Wait, you don't know the half of it," Max said. "On the second run, the game tried to load the broken XML file, and failed. So it loaded the old binary file instead. But since the XML file was there, just broken, it got moved to the backup save location. Then a flag got set that said the save had been loaded from XML. So we had a binary file loaded, but the game thought it was running off the XML file. So it got confused and crashed."

"Man, I'm confused," Ivan muttered.

"On the third run, no XML file was present in the save directory, so the game tried to load one from backup," Max continued. "But the only XML file in that location was the broken save from before, so that failed. It fell back to loading the binary save again. Since that succeeded, it deleted the broken XML file in the backup location, then tried to move the current XML save file there. Except there was no XML file to be moved to backup, so the app crashed again. And since we deleted the backup, all we had left was the old binary blob. Which meant we were back to where we started."

By the time Max finished his explanation, Ivan's head was visibly spinning. "It's fixed now, right?"

"Right." Max smiled, wiping sweat off his brow. After braving this fire unscathed, nothing would stop them from a timely, functional release.

[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/run-crash-crash-run


Метки:  

Error'd: Installing Flash Player is Hard Work

Пятница, 09 Октября 2015 г. 13:00 + в цитатник

"Installing Flash Player sure is hard work," Mike H. wrote, "good thing that Adobe suggested taking a bit of a break afterwards."

Andrew K. writes, "Amazon must be targeting robots with the product description on this one."

"The irony definitely wasn't lost on me for this one," wrote Declan H.

"The position is tempting," Justin C. wrote, "So long as it isn't a professorship in database design, I guess we are OK."

"A gentle reminder that tapping through to the Selfridges sale would result in null feelings of fulfilment and happiness," Hannah S. writes.

Julian wrote, "How does this even work? Did I walk backwards for a while but didn't notice it?!"

Thomas P. writes, "Can I just get one ounce of each clipper and see which one I like best before I buy?"

"I recently downloaded Polish localization for Visual Studio and I was really impressed by the quality of it," wrote Marcin Z., "There were small issues here and there, but nothing harmful. That is, until I wanted to remove a file from a project."

[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/installing-flash-player-is-hard-work


Метки:  

Announcements: Sponsor Announcement: Scout

Четверг, 08 Октября 2015 г. 17:00 + в цитатник

Our sponsorship program has been a great success, and weve got another great sponsor to help us keep this site running and bring you the horrors that your jaded eyes crave, along with special features like TDWTF Live and our recent BYOC contest about the Lucky Deuce. Our newest sponsor is Scout. They donate $10 to the Larimer County Humane Society every time somebody tries out Scout, and now theyre launching a new tool…


Founded in 2009, Scout has been delivering SaaS based server monitoring software for over 6 years. With StatsD & AWS support, Scout Server Monitoring has been the clean, reliable alternative to expensive build-your-own monitoring solutions.

Now, due to overwhelming customer demand for a fresh approach to APM, Scout has built a cloud-based / SaaS Application Performance Management tool for critical web applications. Dominant SaaS APM solutions (e.g. New Relic) are almost a decade old. Scout APM is a fresh take with modern, streamlined interface and unmatched capabilities.

Scout APM provides deep metrics, analysis and solutions for performance problems in production web application. For developers, Scout APM is the fastest path from performance nightmares to the specific line-of-code. With built-in git integration, Scout APM can even identify the specific developer who can solve the problem based on code commit history.

For managers and business owners, Scout APM prioritizes slow performance according to business impact. Scout APM allows customers to add context to find out who is affected most by slow performance.

Find out more at: apm.scoutapp.com, or if you’re in Las Vegas for AWS re:Invent 2015 stop in at booth #1130. Be sure to ask about the Oculus Rift give-away

[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/sponsor-announcement-scout


Метки:  

CodeSOD: Not So Unique

Четверг, 08 Октября 2015 г. 13:30 + в цитатник

When designing a database schema, it's often important to assign a unique identifier to each record. Such surrogate keys almost always make querying for data both simpler and faster, and the overhead of an additional column is usually a cost worth paying. As such, nearly all databases provide some means of generating such identifiers, either in form of sequential numbers, or more fancy UUID schemes.

Snowflake macro photography 1

As is often the case at The Daily WTF, however, many developers prefer to reinvent the wheel. Today's code came to light when our Anonymous submitter—a mid-level programmer maintaining the codebase written by a team of senior developers and highly paid consultants—was tasked with investigating a failing bulk import from an external system. The procedure didn't throw any errors, but for some reason only half of the 12 million records ended up inserted into the database.

Digging through the code, he finally found the source of all his problems:

 public static int GetUniqueKey(int value1, string value2)
    {
      int key = value1.GetHashCode();
      key = (key * 3) + value2.GetHashCode();
      return key;
    }

The original developer thought she was being clever, using a pair of keys that uniquely identified a record to generate an ID for the insert (and multiplying one of them by 3 for whatever godawful reason). What she failed to account for, however, was the birthday problem. With the identifier being only a 32-bit integer, it was almost certain that among the 12 million IDs generated, many of them would not be unique. Together with the insert library silently dropping entries with the same key, our poor submitter ended up with a recipe for disaster on his hands.

Our submitter suggested using an MD5 hash to generate unique keys instead, not realizing that this code was guarded by the red-taped barbed wire of cronyism. He was told that his approach would introduce an unacceptable performance hit. And after all, this code had been written by the lead-est of lead developers. It was copy/pasted throughout the codebase. How could he possibly improve upon it?

Code that simply generates sequential IDs would be an improvement, but our submitter's too busy applying to new jobs elsewhere to bother pointing this out.

[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/not-so-unique


Метки:  

Dual Helix

Среда, 07 Октября 2015 г. 13:30 + в цитатник

Bruce B., a recent high school graduate in need of a job, thought it was a good opportunity. A friend had set him up with a job at a one-man development shop. His new boss, Louis, would provide on-the-job training, and it paid well for an entry-level position.

Louis met Bruce at the formers house and led him to a basement office. Your friend told me a lot about you, Bruce, Louis said. He had a smile like Jack Torrance from The Shining. Is it true you can already program?

DNA helix-structures

Oh, sure, Bruce said. Ive been coding C# for a while now. Ive learned how to use classes and interfaces

C#? What a useless language. Louis waved his hand. Ive got the real deal.

Louis led Bruce an Apple LC. On the screen were displayed rounded rectangles, with labels such as Unique and If/Then/Else, linked together by arrows. It was as if someone had created a flowchart using childrens wooden letter blocks.

Helix, Louis announced. The pinnacle in computer programming languages.

A Normalized Genome

Double Helix, Louis explained, was the most advanced version of a series of database management systems, using a fully-graphical programming language for its procedural code. Introduced early in the 1980s, Helix became a niche product by the end of the decade, overtaken by dbase and other, less GUI-reliant relational databases.

Ill give you an ebook that will teach you the language, Louis said. He stared longingly at the screen. Its truly a magnificent piece of software.

Bruce shook off the cultish feeling that afternoon before reading Louiss email. He had attached a PDF of Riding the Helix Express. Bruce stayed up all night, reading it in morbid fascination.

The next day he mentioned a passage on normalization to Louis. The book doesnt go into much detail. What do you use for normalization?

What? Forget that. Louis waved his arms around. In fact, delete that book. Its no good. Helix doesnt need old-fashioned normalization. It has its own way of normalizing data.

Bruce didnt remember that part from Riding the Helix Express, but Louis had already moved on. He put Bruce to work correcting some records in a car dealerships database.

Flowchart DNA

None of the data, Bruce discovered, had been normalized. Salespeople would routinely mistype IDs and other fields, filling the database with mismatched data. In fact, there was no validation on any fields. As Bruce worked on other databases Louis had created, he found similar data integrity issues.

Louiss Helix code, which Bruce routinely had to troubleshoot, was worse. Those block-like flowcharts were much harder to follow than a regular, typed programming language, exacerbated by Louiss spaghetti coding patterns. Fixing it was like untangling Christmas lights.

But the money was good, so Bruce kept coming into work.

Meanwhile, Louis showed growing disappointment in his new hire. Bruce, I dont know why I put up with you. Youre always critizing my work, you dont follow my advice, and Ive seen you reading that ebook I told you to delete. I really need you to shape up, or Ill have to let you go.

Unwound Helix

One day, Bruce arrived in the basement to find Louis in a huff.

Ive put up with your shenanigans all summer, Bruce. Normalization, indexing, its just one excuse after another with you! He pointed at his screen. Now, this procedure isnt working. Show me youre still capable of doing this job.

Bruce sighed, sat at his computer, and tried to make sense of Louiss code. It was the worst tangle that he had seen since he started working for Louis. Worse, Bruce had skipped his coffee that morning, leaving him unable to concentrate.

I dont think I

Gaaah! Louis pushed Bruce aside and sat himself in front of the computer. He started playing with the blocks, teasing apart the code. Bruce, sitting nearby, watched in silence, listening to the clock ticking on the wall, the click-click of the mouse, Louiss little groans of frustration. The Helix code swam in front of his eyes, filling the room, enveloping him

Bruce woke just before he hit the floor. He had fallen asleep and slipped out of his chair.

Louis, caught up in his work, hadnt even noticed.

As his boss continued to untangle his own Helix code, Bruce quietly wrote a resignation note and left it on his desk. In his opinion, Double Helix should never have left the 1980s.

[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/dual-helix


Метки:  

CodeSOD: The Most Pessimistic Search

Вторник, 06 Октября 2015 г. 13:30 + в цитатник

Sometimes here at TDWTF, we get code snippets that are immediately obvious in their wrongness. But sometimes, the code only looks mildly inefficient, and it's up to the submitter to let us know how bad it actually is.

Common snail

Take the following snippet:


logdest=0;
if(DbSetFirst(dbptr)!=-1) {
    while(DbGetNext(dbptr, destptr)!=-1) {
        if(destptr->physical==DestnameToDest(data[i].Destname)) {
            logdest=destptr->logical
        }
    }

Sure, it doesn't early exit, but depending on the size of the row set, that might be only a minor tweak, right?

Submitter Anders K. tells us this code was typically looping through datasets of around 4,000 rows, and performing successfully with that. When it had to process a 42,000 row batch, however, it took around 20 minutes to update what should have been a once-per-minute status report. That innocent-looking DestnameToDest() is an expensive operation that makes a linear search of a 2048-element array.

The rewritten code, which takes only a few seconds to perform the update?


destptr->physical = DestnameToDest(data[i].Destname);
if (DbFind(dbptr, destptr) != -1) {
    logdest = destptr->logical;
}

Our submitter writes: "I challenged a few of my colleagues to come up with a worse implementation, that would still seem reasonable. No one was able to do so." I imagine some of you in the comments will take that as a challenge.

[Advertisement] Scout is the best way to monitor your critical server infrastructure. With over 90 open source plugins, robust alerting, beautiful dashboards and a 5 minute install - Scout saves youvaluable engineering time. Try the server monitoring you'll M today.Your first 30 days are free on us. Learn more at Scout.

http://thedailywtf.com/articles/the-most-pessimistic-search


Метки:  

Eins, Zwei, Zuffa!

Понедельник, 05 Октября 2015 г. 13:30 + в цитатник

Dave had been at Initech for a few years, and things were looking pretty good. Everyone was working towards a big project launch, and every team was on target, on schedule, and on budget. The management, however, was not confident, and decided to increase quality. Their solution was to bring in two experienced, highly-paid consultants from the land of engineering excellence: Germany.

A glass of beer

The two consultants were Bob Schl"udell and Bob Gep"acktr"ager. They became known as Bob Eins and Bob Zwei. They assessed the situation, then rolled up their sleeves and started hacking on all of the projects and code bases with their special skills.

And how special those skills were.

Bob Eins had two favorite things: C++ templates and threads. Anything that used both of these was good, and everything that did not was garbage and had to be rewritten to use threading and templates. He would take whatever library the company was using, reimplement about half of it with layer upon layer of templated classes, and inform the team that, You will use this from now on! Then he would start working on a new library and abandon the previous one, meaning that all of his code was unmaintained.

Bob Zwei was a different kind of beast. At his previous job, he had worked on some project codenamed Volcano, and that was all he ever wanted to talk about. Ask him any question from, Have you seen this compiler error before? to Hey, were all going out to lunch today, wanna come?, and hed respond with, You know, back when I was working on Project Volcano… followed by twenty minutes of chatter about design problems completely irrelevant to the initial topic of discussion.

Dave managed to keep under the radar of the Bobs for awhile, but eventually they found him. They gave him a new core library to use. He sighed and went back to work. How bad could it be?

It was much, much worse than he could possibly imagine. The first thing he learned was that these two Germans were very organized. Majorly, pedantically, obsessive-compulsively organized. Even the most uptight librarian would tell them to loosen up. Due to this, the Bobs demanded that everyone follow strict namespacing standards to keep code organized. However, each of the Bobs had their own radically different scheme.

For example, a network socket class implemented by Bob Eins because socket.h was Not Invented Here, and thus not good enough was namespaced as base::universe::posix::network::socket::Constants::IPV4. It was unclear what existed outside of the base::universe namespace. Meanwhile, Bob Swei organized all his classes along the convention com::initech::divisionname::projectname::objectname, and refused to accept the reality that some projects spanned divisions, and thus couldnt be slotted into that hierarchy.

This was all somewhat manageable until Bob Eins dropped the biggest bomb. His NIH-itis flared up again, so he wrote his very own signal/slot mechanism. All existing code needed to be converted away from Qts perfectly usable mechanism as soon as possible. The unique feature of Bobs version was that everything was a thread. Every service? Thread. Every operation? Thread. Every object? Thread. Every method call? Thread. Everything. This would, it was gloriously announced, get rid of the bottleneck of having a single event loop running on the main thread.

Bob Eins answered every objection raised by the other developers with a variation of, That is not an issue! No reasoning was ever given. Future maintenance costs were Not an issue! Throwing away a years worth of working code was Not an issue! The massive amount of threading bugs, resource contention, and overhead were Not an issue!

Bob Zwei answered every objection raised by the other developers with a variation of, You know, back when I was working on Project Volcano…

All work ground to a halt. Because of the liberal use of templates, the projects compile speed would have brought ridicule from a severely asthmatic snail. A Hello World for their framework took two minutes to compile. The full suite could take hours. Most developer time not wasted waiting for the compiler was spent adding mutexes everywhere, since you could no longer rely on any variable not magically changing out from under you. And the rest of their time was spent debugging race conditions, deadlocks, and resource leaks.

Eventually, the Bobs stepped in with a new solution: every object in every thread would run its own personal event loop.

Nothing was getting done, and management started getting anxious. One morning, Daves cube-mate was grabbed from his multiple week stint of fixing threading bugs into a meeting and shouted at for what seemed like forever. Dave could hear the muffled shouts. Because your component isnt finished, you are personally jeopardizing the future of the entire company!

After a particularly fruitless bug hunt, Dave had no idea what could be causing his race conditions, so he figured hed ask Bob Eins. He described his problem. Herr Eins glanced at his code for a microsecond and said, There is nothing wrong in the platform. You are just using it incorrectly.

Is there any documentation on how to do this correctly?

There is no need for documentation. Just read the source code, Bob Eins replied. He waved a hand and wandered off to do more template metaprogramming.

Dave went to Bob Zwei next. You know, he began, back when I was working on Project Volcano…

Dave didnt want to look at the library sources, for they used every possible C++ misfeature and were as impenetrable as Mirkwood. After battling the digital equivalents of spiders and elves in a dense thicket of intertwined templates, he finally found what he was looking for: a helper class for the signal system. It was unusual, in that it had a comment, possibly the only one in the entirety of the Bobs code. It looked like this:

    // This class is not thread safe

Daves jaw dropped so low that you could have flown a 747 through his mouth. How could a core component that was used everywhere in this multithreaded messaging system be thread unsafe? He filed a bug asking if this issue could be fixed.

A few hours later, Daves boss tapped him on the shoulder. In a strange tone, he said, Ive been told that you filed a bug on Bobs new signaling system.

Thats right…

I want you to know that sort of behavior is totally unprofessional.

Instead of shouting, What? at the top of his voice, all Dave could do was sit there, stunned.

You really shouldnt be spending your time finding bugs.

This sentence was even more incomprehensible than the previous one, so Dave just kept staring.

In this company, we need to have an agile, startup-like mentality, with a focus on results and collaboration, rather than over-polishing minor niggles in our already established core infrastructure.

Dave wondered if he had been teleported to Bizarro World, because not a single word he heard made sense.

This is the last straw in a long line of disappointments, and we feel that there is no future for you in this company. Please clean your desk and leave the premises immediately. Five minutes later, Dave was standing alone in the parking lot.

Then it struck him. The unemployed dont have to deal with threading issues, namespaces, or supertaxonomies. Dave smiled, for the first time in months, and decided to celebrate by going on vacation. He started thinking of good places to unwind, but with two hard requirements.

One: it must not be in Germany. Two: it must not have any volcanoes.

[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/eins-zwei-zuffa


Метки:  

Error'd: Adult Supervision Required

Пятница, 02 Октября 2015 г. 15:00 + в цитатник

"I was found that my NAS was choking on small files," Lionel S. writes, "Now I know it was a marble all along."

"I'm glad that Visual Studio is looking out for me," wrote Connor O.

"Yes. That's SO much easier to understand," Lucas M.

"This is the Yellow Pages (yp.com) listing for Blackjack Marina in Perry, MO." Travis H. wrote, "Based on that second link, I hope it hasn't dried up."

"Here's an error message that I received while trying to renew my domain on DirectNIC," Shreerang wrote, "Yeah, I'm not sure about that date, but I definitely can't argue with the price."

"I needed to do a factory reset on my Windows Phone, but it turned out that the Settings app could not be opened. Maybe an update is available?," writes James Wright.

Dave C. wrote, "I'm impressed that Intuit was able to condense testimonies from all 5 million small businesses into one small window."

"Latest version? Older version? I can't choose!", writes Jason.

[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/adult-supervision-required


Метки:  

CodeSOD: A Handle on Events

Четверг, 01 Октября 2015 г. 13:30 + в цитатник

As developers, we try to write software that will be helpful to our users. Sometimes, we'll do key-by-key examination of what they're typing to do auto-complete. Sometimes, we'll look at a type-field entry to display the relevant subset of subordinate fields to be entered. Sometimes, we'll even try to coalesce error messages so that the user gets one message with a list of mistakes as opposed to one message per mistake.

Of course, it helps if the logic to detect multiple errors and coalesce them into one is correct.

Mike M. was supporting a system that had an event queue. In the case of this particular queue, the messages were all for the same condition. To be helpful, the cow-orker who wrote it decided to only display the pop-up for the first message in the queue and silently swallow the rest.

For the longest time, the system generated a single message for the given condition and so only a single pop-up was ever displayed.

Recently, something unrelated changed, and the system started generating a large number of identical events at once on the queue, which exposed a flaw in the coalescing logic; it took Mike four minutes of continuous clicking to get through the queue of event messages:

SomeClass::eventHandler(Event e) {
   if (!necessaryThing) {
      static bool showingError = false;
      if (showingError)
         return ;
      showingError = true;
      QMessageBox::warning(this, tr("App"), tr("Error message"));
      showingError = false;
      return ;
   }
}
[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/a-handle-on-events


Метки:  

Editor's Soapbox: Processing a Rant

Среда, 30 Сентября 2015 г. 13:30 + в цитатник

In addition to being your intrepid editor, Im an independent consultant. People hire consultants because they want someone to inform their process. How do we do Agile better? Do we do Scrum or Kanban? Can we do scrumfall instead? Should we do BDD, TDD, or ATDD? Or combine them? Are there any other acronyms we should be doing?

The ITIL 2011 Processes Model
Ugh. This diagram makes me physically ill.

This week, Im guiding a company on ATDD- Acceptance Test Driven Development, and while I was at it, I went off on a rant. I went off on a forty-five minute rant about processes and the role of having process in an organization, and how small organizations and large organizations use processes to shoot themselves in the foot in vastly different ways. It was quite a rant, and I discovered that I had a lot of strong feelings about how organizations adopt, employ, and adapt processes, and how the processes they use define their culture and also define what they can successfully accomplish as an organization.

So lets take a minute to talk about process.

First, though, lets talk about my last day at my old job. I worked the traditional 9-to5 at a gigantic manufacturing company. It was the kind of company that had a Project Management Office. The PMO had two main jobs: it made a list of the required project documents that had to be uploaded to SharePoint during the lifecycle of your project, and it administered the Project Server instance you had to use to track your project.

I, on the other hand, was a developer who also inherited the responsibility of administering our TFS instance. On the latter part, my job was mostly supporting push-button deployments and reminding people that VM images dont go in source control.

One day, our users asked us to turn on the functionality that TFS sync data about its work items with tasks in Project Server. To do that requires a handful of steps. Project Server needs a plugin installed, and a switch flipped. The TFS team project has to be configured to talk to Project Server. Then, anyone using MS Project can set up their project to sync data between the two environments. This was a trivial, low-risk change, so I brought it to the PMO to make it happen. The PMO was happy to install the plugin, but when we asked them to flip the switch, the effort died.

The effort died because the PMO wanted to fit the act of flipping the switch into their process. And it quickly became clear, as they asked their questions. No matter what question they asked, we had a simple reply that addressed their concern, which only meant that they had to re-ask the same question in a different way until we ran out of ways to say the same thing. Simply flipping the switch and letting the TFS administration team worry about administering TFS was not an option them, and they needed to control access to this feature. The idea that any Project Owner could just turn this on just by asking was an absolutely terrifying concept. The fact that it was on a per-project basis and not a global change was honestly worse, in their opinion, than a global change, because that meant decisions had to be made for each project, based on the needs of that project. Everything the PMO did was built around removing flexibility for decision-making.

This culminated in a meeting between the PMO and the TFS team on my last day of work. I had already quit my job- amicably- and was trying to help wrap up some final projects before I walked out the door. The meeting took the form of the TFS team saying, You just need to flip a switch and everything after that is our problem and you dont need to be involved, and the PMO trying to toss their process over our own and suffocate us with it. Every solution we proposed was countered with a new obstacle, a new checkbox that had to be checked, a new document which needed to be generated. They weren't interested in posing challenges and getting solutions, they just wanted to make sure they were in control of the process.

Voices got raised, tempers flared, and in a fit of dontgiveashititis, I turned to the head of the PMO and said something like, I give up. We are going to cancel this effort, because you have officially made it not worth doing. You are the obstacle, and since we cant get rid of you, we just arent going to bother with you, and our developers get to suffer, so thanks.

Its probably not my proudest moment, but it was damn satisfying.

I relate this story, because its a perfect example of two different approaches to process. Every process we had regarding TFS was built with one goal: to help developers get things done. It was formal, and documented, but it was also nearly invisible. The PMO, on the other hand, wanted to use process as a tool for control. They wanted it to be governance and a series of checkpoints, and the philosophy was, if we build good checkpoints, and force people to go through our good checkpoints, we will have good end results. (They were consistently wrong, and more projects failed than ever succeeded under their watch).

A lot of developers, especially the ones who work in large or enterprise organizations, take a very dim view of processes, because theyve dealt with too many groups like the PMO I dealt with. They hear things like Agile, or Test Driven Development, or Business Driven Development, and all they hear is a new set of policies and practices that are going to be foisted upon them without any sense of the underlying reality.

On the other side, you have those tiny shops, who see process as nothing but an obstacle. Were just hackers, bro. The attitude is best typified by an organization thats small in spirit, in this bizarre slide deck from a FaceBook developer, which argues that their terrible practices arise from their scale, and thats why the FaceBook iOS app has to be a 187MB behemoth to show you your newsfeed.

Like most Internet debates, both sides are beating the snot out of a straw man, so lets just say the actual truth: Process is important, and it doesnt have to suck. And lets add onto that: process is never a cure for a problem, but it might be a treatment.

Lets be honest, managing developers is like herding cats, and you need to point them all in the same direction by giving them some sort of guidance and organizing principle. Processes are a way to scale up an organization, a way to build towards consistent results, and a way to simplify the daily job of your developers. With that in mind, I want to talk about development processes and how organizations can make process work for them, with the following guidelines.

Have a purpose. Why are you making the software that youre making? What is its purpose? The software product they create is supposed to accomplish something for their end users. In enterprises, youll often hear the phrase business value, which is a fancy way of saying, why does this matter? Understand why youre developing the software youre making.

How does having a purpose help you with defining your processes? Simple: every process that makes it easier to achieve that purpose is good. Any process that erects an obstacle between you and your goal is bad. Stop doing that.

Buzzwords are not processes. Ive been doing an incredible amount of ATDD consulting. We have to do ATDD, organizations say. ATDD- Acceptance Test Driven Development- is not a process. Its a collection of practices that you can employ to build your own process. This goes for anything thats trendy. We need to do Agile. No, you dont do Agile. You examine the various Agile processes and methodologies and adapt them to your organization and build your own process. Dont do things just because somebody else told you to.

How do you know which practices are the right ones to adapt? Try them out, and then ask yourself: are we doing a better or worse job of achieving our goals.

Guidelines are better than checkpoints. A lot of organizations use process to control their employees. You must do this, and you must do it this way. Compliance is enforced, sometimes with a carrot, usually with a stick. This grows from bureaucracy, which itself grows from a fairly natural need to ensure consistent performance regardless of which human resources are involved in an effort. Bureaucracies dont care if they turn into a Harrison Bergeron dystopia where performance is consistently poor- just as long as its consistent.

The purpose of a process is not to ensure compliance. Its to provide a well-paved path that guides your developers to success. Which brings us to our penultimate point.

Processes should grow from institutional best practices. While you can certainly learn from other organizations, and trade magazines, and articles like this one, the only people who know how to do what you specifically do are the people who do it- you.

Roger Corman, the master of the B-movie, was infamous for shooting movies on tight schedules with budgets that couldnt afford rent in San Francisco right now. Many of those movies were bad, most of them are, well, B-movies, and a few of them are actually pretty great. He consistently delivered product on time and on budget, and the results were usually acceptable. As a producer, he would take new directors aside and lay down The Process. He would lay out the workflow for these directors, in almost a draconian way: You block like this, you light like this, you shoot like this, you run your team and departments like this, and you never try and take shortcuts.

In fact, the Corman process contradicts much of what I said above- he didnt give guidelines, he gave mandates. If you directed a Corman flick, you directed it according to the Corman process. But heres the kicker: the Corman process was a best practice that Corman himself developed and refined over his career, and it was built to serve his institutional purpose (to make an acceptable film, quickly and cheaply).

Processes have to be built by people who use the process. They have to support the organizations purpose. A well designed process encourages compliance because it is an effective process. A good process should not require management to get engaged in its adoption, because a good process has clear benefits.

Finally, processes that result in additional meetings, documents nobody reads, work that doesnt directly support the organizations purpose, or involve erecting obstacles to keep people on the correct path- these are bad processes.

[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/processing-a-rant


Метки:  

CodeSOD: MacGyver's XMLHTTPRequest

Вторник, 29 Сентября 2015 г. 13:30 + в цитатник

In these days of browser standards, its easy to forget that once upon a time, simple tasks like an HTTP request from JavaScript were difficult or even impossible, and if you wanted it to work in every browser, you were going to have to write wrappers to try and create a consistent API.

Zeke inherited an application back from those bad old days. It needs to poll a server, and based on the response, it performs an action, but it does this in an inventive way.

First, they fashion a rudimentary enum:

    var Response = {
            nothing: 1,
            showInviteNewWin: 2,
            showInviteSameWin: 3,
            pushPageSamewin: 4,
            pushPageNewWin: 5,
            inviteTimeOut: 6,
            resendInfo: 7,
            neverInvite: 8,
            stop: 9,
            notCurrentPage: 10
        };

Theyre going to use that in a moment to parse the servers response, but first- how are they going to send a request?

    var na_pro_img = null;
    function sendVisitInfo() {
        setCurrentPageId();
        na_pro_img = null;
        na_pro_img = new Image();
        na_pro_img.onload = checkResponse; /*imageLoaded;*/
        var d = new Date();
        na_pro_img.src = prefix + 'Visitor.aspx?Cmd=1&TITLE=' + escape((document.title != "") ? document.title : document.location) + '&REFERRER=' + escape(document.referrer) + '&LASTVISIT=' + escape(lastVisitCookie) + '&LASTINVITE=' + escape(lastInviteCookie) + '&RSND=' + resendCount + '&CUSTOMVARIABLES=' + escape(custProp) + '<=' + d.getTime() + ((neverCookie != null) ? ('&NEVERINVITE=' + escape(neverCookie)) : "") + '&cpId=' + curPageID;
        d = null;
    }

Well, that will generate a request, I suppose, with the SRC property passing a bunch of stuff in the URL parameters. But how on Earth are they parsing anything useful out of the response? And what does this have to do with their rudimentary enum?

    function checkResponse() {
        switch (na_pro_img.width) {
            case Response.nothing:
                break;
            case Response.showInviteNewWin:
                sessWin = 'n';
                popInvite();
                break;
             // more cases cut for brevity
         }
    }

They use the width. The width of the image is matched against their enum. Through modern eyes, this is the sort of thing that makes you want to go WTF, but for those of us that had the misfortune to do web development back in the days when JavaScript was a novelty and autoplaying MIDI files was the coolest thing you could have on your page…

[Advertisement] Scout is the best way to monitor your critical server infrastructure. With over 90 open source plugins, robust alerting, beautiful dashboards and a 5 minute install - Scout saves youvaluable engineering time. Try the server monitoring you'll M today.Your first 30 days are free on us. Learn more at Scout.

http://thedailywtf.com/articles/macgyver-s-xmlhttprequest


Метки:  

Announcements: Release! at Ohio Linux Fest

Понедельник, 28 Сентября 2015 г. 17:00 + в цитатник

To introduce myself, that’s me over in the right corner. Hi. You might remember that, a year or so back, this site got a face lift. We still love the way it looks, but, if we are being straight with you, the CSS and HTML are a damn mess. So, I’ll be re-building the site while maintaining the same look, and maybe writing an article here and there.

Most of you are familiar with Release!, the card game, which Inedo came out with last summer. The support on Kickstarter was fantastic, especially from the Daily WTF community. I was the lead game designer on Release!, and I was also on the team for our more recent Kickstarter campaign, ABC++.

This October, I am pleased to participate in an event in my town: Ohio Linux Fest in Columbus will feature Release! during its game nights, and give me the opportunity to speak about the overlap of game and software design.

Catch my talk, Pinochle, Dungeons and Dragons, and Software Usability, as well as some Release! demos during Friday’s happy hour, and at the afterparty.

The talk revolves around how board games utilize a very similar design infrastructure as software UIs to communicate with their users. It mostly discusses the lessons we can take from these cardboard interfaces and how to apply them to digital ones.

God, that sounds nerdy as hell.

Anyway, I will be sure to bring some TDWTF Mugs, and copies of Release! with me too. So, if you don’t have the game yet you might wind up scoring a free pack!

[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/release-at-ohio-linux-fest


Метки:  

You're Not My MIME Type

Понедельник, 28 Сентября 2015 г. 13:30 + в цитатник

Andrew performed corporate support for a giant multinational. One day, he was assigned what looked like a straightforward bug: a new Intranet webpage for one business unit was failing to accept CSV spreadsheets containing product information from another business unit.

FortranCodingForm

After obtaining the proper permissions, Andrew first attempted to duplicate the issue. He browsed to the Intranet upload page, then tried to upload the user’s example CSV files. Each attempt failed with the oh-so-helpful message “Invalid file type.”

Well, they were perfectly valid CSV files. Andrew tracked down the developer support contact for the site—Brian—and forwarded him the ticket.

Not an hour later, the ticket boomeranged right back to Andrew, with a note from Brian attached. The code that handles file uploads is a third-party library. You’ll have to contact them for help.

Ugh. The very thought set Andrew’s teeth on edge. First, he decided to see if there was the slightest chance of resolving the error himself. He googled every search string combination he could think of for the library name, error, scenario—no dice. The company website offered no useful documentation, either. It had support forums, but they were ghost towns.

Andrew’s dread amplified. Realistically, this wasn’t going to get fully resolved before the heat death of the universe. That whole time, Andrew was sure to have users breathing down his neck. His next effort was to get a workaround in place. After making several phone calls and painfully backtracking his way to the people in charge of the dual business unit venture (“Tiffany? Oh, she doesn’t even work here anymore. You want Rob!”), he arranged things so that his users could email their CSV files directly to one person in the other business unit.

These herculean efforts garnered Andrew nothing but huffy scorn. “This is really inconvenient for us,” nagged the user who’d logged the ticket.

“It’s the best we can do until we get this third-party code fixed,” Andrew replied, taking it in stride.

Well, he’d done what he could. It was time to give third-party support a call. After navigating an extensive phone tree, he had a (presumed) live specimen on the other end to whom he could explain the issue.

“So why’s this happening?” he asked.

“That doesn’t sound familiar,” Carl, the rep on the other side, told him. “We’ll have to try to duplicate the issue on our end. Do you have some of these files?”

“Yes, I can email them to you,” Andrew said.

“Great! We’ll test that out and let you know what we find.”

To his credit, Carl called back within a few days to notify Andrew that the behavior had been duplicated. However, he didn’t know what was going wrong either, and would have to escalate the ticket on his end.

A few weeks later, Andrew received another call from Carl. “All right, this is admittedly a strange case. Let me explain. To determine a valid file type, our code checks and ensures that the MIME type of an uploaded file matches the known MIME types associated with the file extension. It does this by looking at the beginning of the file and following some rules of thumb.”

“OK,” Andrew said, furiously scribbling all this down in a notebook for future reference.

“It’s a safety feature,” Carl said. “Looking at your example files, they all begin with entries that start with C, then a space.”

“Yeah,” Andrew confirmed. “Those are part numbers.”

“Well, back in the days of punch cards, FORTRAN programs indicated comment lines by punching a ‘C’ character in the first column, usually followed by a space.”

Andrew froze for a few seconds. “Wait—so your code sees our part numbers and concludes the file is a FORTRAN program?”

“I’m afraid so,” Carl said. “It’s working as designed.”

“Working as designed?! It’s not flipping working at all!” Andrew cried.

“This is expected behavior given your input,” Carl said. “You can edit your CSV files to not start with C-space values, or modify your logic around our library so that—”

“No, I can’t do either of those things!” Andrew cut him off. “The users aren’t gonna change their files, and I have no access to the code! Couldn’t you edit the library to not make that check, and just be happy with a .csv file extension?”

“We’re not prepared to do that at this time, but we can file a feature request.” In other words, Sorry, buddy. Your company doesn’t spend enough money with our company.

“Fine,” Andrew growled, then hung up the phone. He pulled up his original support ticket to add this information and escalate it back to Brian, wondering how many minutes it would take to get kicked back with another blas'e retort.

As always, thanks for reading! If you like my articles, you might just love my new sci-fi/fantasy adventure novel about a knight who travels the galaxy with a starship, going on quests and getting into mischief. It has no WTFs in it (intentionally anyway), but hopefully the sword-fighting and deadly court intrigue make up for that. Enjoy! -Ellis


[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/you-re-not-my-mime-type


Метки:  

Error'd: The Little Application That Couldn't

Пятница, 25 Сентября 2015 г. 13:00 + в цитатник

"I don't know what it was trying to do, but it just couldn't do it," Bert writes, "It also looks like it couldn't finish the error message."

"After a decade and a half, I thought that we were past using Windows 2000, but apparently the sketchiest arcade I've ever set foot in disagrees," writes Erik M..

"I question the integrity of the London Free Press if they aren't going to attribute their quotes," wrote Kate D.

"Signing up for a free course 'Oracle Massive Open Online Course: Java SE 8 Lambdas and Streams', I was invited to complete my user profile," Ed R. wrote, "My email address was already pre-filled, the only option was to select my time zone. Upon pressing 'Create', this reward was immediate and highly satisfactory."

Erik wrote, "I was checking my portfolio at Avanza when I noticed some very strange temporal things had been going on in Dow Jones World Index this last month."

"I came across a very bombastic find in a vendor's Bill of Materials software," Mike N. writes.

Dave C. wrote, "Now that's what I call a long running transaction."

"Alright! I win!...wait a minute, that's a familiar looking IP", wrote Nicolas.

[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/the-little-application-that-couldn-t


Метки:  

CodeSOD: Sorting Cabinets

Четверг, 24 Сентября 2015 г. 13:30 + в цитатник

Sorting. Its a well-studied class of problem, with a number of well-understood solutions. These days, pretty much any time you need to sort a collection, theres a language-or-framework-provided function that handles it for you. Sure, a Better Idiot™ might try and implement their own sorting algorithm from scratch, but your Regular Idiot™ just has to call .sort- its Idiot Proof™, right

Well, David S. found a better idiot.

    public List getAllCabinets() {
        try {
            List m = new Vector();
            List cabinets = SpecificObjectManager.getAllPrograms();
            Iterator it = cabinets.iterator();
            while (it.hasNext()) {
                CabinetAjax ca = new CabinetAjax();
                SearchProgramShell cabinet = (SearchProgramShell) it.next();
                ca.setId(cabinet.getCabinetId());
                ca.setTitle(cabinet.getCabinetTitle());
                Collections.sort(m, new CabinetAjaxTitleComparator());
                m.add(ca);
            }
            return m;
        } catch (Exception e) {
            log.error(e.toString(), e);
        } finally {
            HibernateSessionFactory.closeSession();
        }
        return null;
    }

The goal here is to return sorted list of Cabinet details- which youll note is just an ID and Title, meaning this could just be a map instead of a class, but thats barely a WTF. No, its the call to sort every time. According to David, there are 12,000 Cabinet objects, so thats 12,000 sorts, with one more element each time. I leave the total Big-O for this implementation up to the reader.

http://thedailywtf.com/articles/sorting-cabinets


Метки:  

Registered Students

Среда, 23 Сентября 2015 г. 13:30 + в цитатник

Tim C. took pride in his work. He debugged Clockaburra, a timetabling and management suite, used in Australian high schools. Oftentimes, it was a simple problem that could be reproduced after a quick phone call from a client- usually a vice principal or the secretary. Its when a bug cant be reproduced that things get tricky, but Tim had the solution for that as well.

Class schedule

One day, he got a call shortly after lunch from a Mrs. Harriet, the vice principal of Charles Perkins High School. All of our mathematics classes have disappeared from the schedule, she said. It just happened this morning.

What was the last thing anyone did to the schedule before the error?

Oh, I wouldnt know, Mrs. Harriet said. Theres a few of us who use it. It could have been anything, really.

This was, of course, the worst-case scenario. Tim had to go with Plan B. Okay, Im going to need part of your registry tree.

Step-by-Step

Standard procedure of quality assurance is to recreate the reported environment as closely as possible, then isolate all the variables which could cause the issue until you find the root cause. Due to Clockaburras architecture, the easiest way of recreating the users environment on his machine was to get the client to send him the registry tree for Clockaburra in a .res file.

Oh, Im not sure I could do that, she replied. I wouldnt know how.

Oh, its easy, Tim said. Ill walk you through it. Although it nearly broke his stress ball, he managed to guide Mrs. Harriet through the process. Then he walked her through attaching the file to an email, which was a bit of a puzzle for her. The email arrived, titled, VERY IMPORTANT FILE, with a .res file attached. The file was a surprisingly large 5MB, but Tim assumed they must just have an unusual installation on their end. He updated his registry with that file and rebooted.

Identity Crisis

Tim blinked. His screen displayed a login that read Charles Perkins High School. Above that was an image of Charles Perkins in his football kit. He tried his credentials and was met with an Invalid Username error.

His phone rang. It was Mrs. Harriet, who was eager to get all of those mathematics classes back on the schedule.

He laughed nervously. Its… uh… well underway, he said. Ill get back to you with a full report once we have it fixed.

Things not well underway, it was his turn to call his tech support, Bennelong.

This is a first for me, BEnnelong said, after taking one look at Tims new login screen. What did you do last?

I was updating my registry with one a client sent. She sent me the tree for Clockaburra which shouldnt have-

Tim remembered that the .res file Mrs. Harriet had sent was a chunky 5MB. She had sent her entire computers registry, not just for Clockaburra. His computer was tricked into thinking it was hers.

Academic Discretion

Bennelong used System Restore to get Tims system back to just before the call with Mrs. Harriet. Tim isolated the Clockaburra registry tree in the file, and soon pinpointed the issue as some invalid settings. Mrs. Harriet- or someone else- had blindly mis-configured the application in the most creative way Tim had seen yet. He returned Mrs. Harriets phone call late that afternoon with instructions on how to fix the problem.

That took quite awhile, she said. Nothing serious, was it?

It was more of a snafu on my end, Tim admitted. I actually had to call tech support to get me out of a jam. Im very sorry for the delay.

Well, I wont tell if you wont, Mrs. Harriet said. We all have our moments.

[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/registered-students


Метки:  

CodeSOD: The Coercive Types

Вторник, 22 Сентября 2015 г. 13:30 + в цитатник

Loosely typed languages may offer certain advantages in terms of ease of use and flexibility, but they bring another challenge: its difficult to know what it is youre looking at. With no compiler type checking, its hard to compare two things, and that becomes extremely problematic when youre working with languages like, say, JavaScript.

Ruby, in its quest to make programmers happy, took a simplistic approach to the Truthy vs. Falsy problem. False is false. Nil is false. Everything else is True. Ruby is often used by web developers, who may be more comfortable in languages like JavaScript and PHP.

That is presumably why Lisa found this debacle in her code base, placed there by a co-worker who preferred other web languages:

  def equivalent_values(old_value, new_value)
    if (old_value == false && new_value == "0") ||
       (old_value == "0" && new_value == false) ||
       (old_value == "1" && new_value == true) ||
       (old_value == true && new_value == "1")
      return true
    end
    if (old_value.is_a?(Array) && old_value[0].to_s == new_value.to_s && old_value.size == 1) ||
       (new_value.is_a?(Array) && new_value[0].to_s == old_value.to_s && new_value.size == 1)
      return true
    end
    false
  end

Yes, this also does some type coercion, after a fashion, so its a little broader that mere Truthiness, so my initial description may have been incomplete or misleading. For this block of code, that wouldnt be the first time. For reasons no one can explain, this method was part of a module called TimestampHelper.

[Advertisement] Scout is the best way to monitor your critical server infrastructure. With over 90 open source plugins, robust alerting, beautiful dashboards and a 5 minute install - Scout saves youvaluable engineering time. Try the server monitoring you'll M today.Your first 30 days are free on us. Learn more at Scout.

http://thedailywtf.com/articles/the-coercive-types


Метки:  

The Graduate

Понедельник, 21 Сентября 2015 г. 13:30 + в цитатник

Management will frequently hire young developers just out of school because a) they're cheap, and b) a developer is a developer is a developer. Graduates, especially from advanced degree programs, always have more advanced training than those with lesser degrees, and should be able to bring advanced skills to the table on day-1. Sometimes management gets lucky, and with a bit of proper guidance and oversight, the newbie can create something reasonably functional, performant and maintainable. This is not one of those occasions.

In the aftermath of that strategy when management realizes that perhaps something is amiss and the usual threats of get it done don't seem to work, management crowbars open the purse strings and highly paid consultants are often sought after to clean up the mess. Sometimes the consultant can fix the mess. Sometimes the power of management to $*#%& up a project far outstrips anyone's ability to fix it.

Jenny was lured hired to make some minor modifications to speed up a system of the latter variety that was written by an unsupervised fresh-out. It was way over budget, behind schedule, full of bugs and not feature-complete. The customers were not happy campers, and were not bashful about expressing their outrage dismay at the cost and progress. Basically, just another day in the office for Jenny.

The application itself was run-of-the-mill case management software, storing basic demographic information about clients, the people that referred them and the history of their cases. It's a SQL Server database with ASP.NET forms to interact with the data. It should have been pretty simple stuff. Except...

The design documents were literally coffee-stained napkins and Jenny was forewarned not to discard them. There had never been a DBA on the project. Naturally, this led Jenny down the rabbit hole...

One of the first things she encountered everywhere was that columns that stored Yes/No data were declared as VARCHAR(20), and stored the literal strings "Yes", "No" and a variety of things that conjured up nightmares of FILE_NOT_FOUND.

The application also had a number of data fields where the user must select a value from a pre-determined list, and the list is stored in the database. That is, there is a list of Suburbs, a list of PostCodes, a list of Illness types, etc. Rather than have tables called Suburbs, PostCodes and Illnesses, the developer opted for one table for all of them (interestingly, the booleans were not stored here, and commanded their own dedicated table). The table is called RefData_5, and whenever you want the data for any list (e.g.: the list of suburbs) you have to select from that single reference table and filter to get the records where RefType is "Suburb"). To complicate things, the table contained constant string values, numeric postal codes and enumerated values. Thus, once you queried the data, you needed to explicitly convert it to the correct type before you could use it.

Of course, prior versions of the table still existed: RefData_4, RefData_3, RefData2 and RefData_1. Unfortunately, they weren't just there as unreferenced remnants. Some of them were referenced here and there throughout the code base and stored procedures, which led to all sorts of instability as table definitions changed over time.

Adding to the woes, the code was not stored in any source control system; Jenny was handed the good copy on a USB key.

Just to make things interesting, once a constant had been identified as applying to a particular situation, the PK of that constant record was not stored in the foreign record. Instead, the constant literal and the single character key (e.g.: "12345" and "P"ostcode) were stored. Of course, you had to ensure that you never used the same key for two different data types in the REF_DATA_n table, or going the other way might become an interesting challenge.

Perhaps most impressive, is that the graduate managed to write queries on this structure. They were hundreds of lines of T-SQL if-else's and ran, well, glacially, and mostly returned the correct data. Mostly.

So now Jenny gets to explain to management why their system that was inexpensively developed by the graduate ran so slowly and inconsistently, could not simply be tweaked to make it faster, and that a full rewrite was in order; all to hear in return: you're a highly paid consultant and you can't fix it?! Why are we paying you?

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


Метки:  

Error'd: Blah, blah, blah!

Пятница, 18 Сентября 2015 г. 13:00 + в цитатник

"Believe it or not, I've actually seen less helpful content on StackOverflow," Luc F. writes.

"Apparently they know a lot Tims," writes Ben.

"Adobe Illustrator simply CANT open this SVG file," wrote Samuel W.

"A Google search for 'http error 403' offered me a link to this page as first hit," Peter W. wrote, "Good to know that Knoppix is Good Ol' Windows at heart, and that I can override server-side denials by fixing a DLL on the client."

Dave L. wrote, "After checking my DuneHD media box, I think that I'm going to pass on visiting downtown Reading."

"With an offer like that, who needs deals?", wrote Eagle A.

"Experts unsure whajavascript:void(0)t future will bring?", wrote Adam B., "They must be pretty lame experts, as I'm pretty sure that void brings nothing."

"Either anonymize to protect the innocent or don't to humiliate the guilty," Bert writes.

[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/blah-blah-blah


Метки:  

Поиск сообщений в rss_thedaily_wtf
Страницы: 124 ... 29 28 [27] 26 25 ..
.. 1 Календарь