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

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

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

The Big Box Hot Box

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

The average big-box hardware store is like a small city. They have every piece of hardware or tool imaginable (except, of course, the one youre looking for). Youll find no less that 15 aisles of power tools stocked with everything from battery operated screwdrivers to arc welders. To store all these tools, you can purchase the 6-foot-tall rolling toolbox, with a 20-watt stereo, built-in beer chiller, wi-fi connectivity, and a Twitter or Facebook app. One aisle over, theres row after row of pristine white toilets, occupied by a small army of playing children. Near the back of the store, nestled between endless rows of storm doors and windows is a quaint grocery section, as if someone uprooted and transplanted a gas station convenience store, and trimmed away all of the bits that werent junk food. Finally, outside the building, is the drive-thru lumber yard, where you drive to the end to purchase your 20 cubic feet of mulch and invariably get stuck behind an idling vehicle abandoned by a socially-clueless DIY-er who either disappeared on an epic quest to find help loading 200 short tons of bagged white river rock into his 1993 Ford Ranger, or more likely, thought it was a convenient parking spot while he left for an 8-week sabbatical on a mountain in Tibet.

Home Depot - Waterloo, Ontario

Scott loved working in such a store while going to college for an IT degree. He didnt work on the floor, where the poor retail staff dealt with angry customers trying to negotiate down the price of a few 2x4s, or trying to return 1000 pounds of tile (which was clearly defective because it shattered when they dropped it on concrete). Scott was the stores IT tech, doing all the tasks that Bob, the stores IT Associate and self-proclaimed computer expert, should know how to do but didnt.

Scott got an after-hours call that the computer system was entirely down, and Bob couldnt figure out the problem. This was strange, since Bob was the expert. The small server closet, designed and installed by Bob, was supposed to be entirely redundant. The server had a hot spare and both systems had redundant power supplies.

Scott, glad youre here! a panicked cashier greeted him as he ran into the store. We cant run any transactions and the customers are getting furious!

Scott quickly made his way to the small closet in the back of the office area. Both servers were off, with no power at all. Pushing the power buttons did nothing. Meanwhile, he could hear irate customers with access to power tools and sledgehammers berating the helpless cashiers whose registers were offline.

He traced the power cables from the server and facepalmed when he discovered the problem. Each server had two power supplies. The first power supplies were plugged into a nice, long-corded surge protector, which connected to the wall outlet. The backup power supplies were plugged into a $3.50 power strip somebody had pulled from the stores shelves. Those cords werent long enough to reach a separate outlet, thus it was plugged into… the first surge protector!

The room was fairly warm, and with the full load of two redundant circuits, the surge protector had overheated and tripped its breaker. Scott rewired the power supplies into an actual redundant fashion, reset the surge protector, and had the registers back up and running within half an hour. He called it a day and went back home.

Until an hour later, when the cashiers called him back in: everything was down again. Now that the servers didnt die when it got mildly warm in the room, it had turned into a furnace. Bob, the expert, was busy trying to fan the heat out with a towel when Scott arrived. Scott set up one of the industrial fans in the store to ventilate the room and called maintenance to get someone to look at the HVAC system.

The fan got the servers cool enough to keep running, but Scott and Bob waited around to see what maintenance found. One of the technicians grabbed them. Did you know the thermostat was set to 45oF?

What? Scott blurted.

Of course, Bob said. Computers should be as cold as possible. They run better.

Not that cold! Scott said.

Well, you cant keep them that cold, the tech said. The AC unit just runs continuously, and the coils get so cold that they start to freeze. Literally- your AC unit is a block of ice right now. Leave it off for a few hours, and then turn it back on at a reasonable temperature.

That day, Bob and Scott followed their instructions, but Bob remained unconvinced about these warnings. As the seasons transitioned into summer, he cranked the thermostat lower and lower. Through the hottest months of the year, Bob caused six more heat-related outages as he did his best to destroy the AC unit. Fortunately, they worked in a hardware store. Scott installed a lock-box over the thermostat and told Bob that maintenance had done it.

[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-big-box-hot-box


Метки:  

CodeSOD: Delete if Not Exists

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

Early in life, we learn to grab the food and then put in in our mouths. Later, it's grab the ball and then roll it. In general, you must have something before you can attempt to do something with it.

...Or so you'd think.

While trudging through the migration of their code from one SharePoint solution to another, S. T. encountered this soul-sucking comment about the code that follows:

 // Comment to this idiotic code:
 // This code will never work. It tries to delete the lists if they DON'T exist, 
 // but since they exist it will never try to delete them. I have to leave it here, 
 // even though it hurts my soul. Time is scarce and I don't have the luxury to 
 // make sure it works. I hate everything.
 
 web.AllowUnsafeUpdates = true;
 
 if (ListAlreadyExists(web, "Title") == false) {
    this.DeleteList(web, "Title");
 }

 if (ListAlreadyExists(web, "Self service") == false) {
    this.DeleteList(web, "Self service");
 }

 if (ListAlreadyExists(web, "Links") == false) {
    this.DeleteList(web, "Links");
 }

 if (ListAlreadyExists(web, "Self service links") == false) {
    this.DeleteList(web, "Self service links");
 }
[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/delete-if-not-exists


Метки:  

The Monolith

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

Itll be a cold day in Hell, Roger said, when this system goes down.


With those words, Roger, Systems Architect, went on sabbatical from Monocorp. The edifice he left behind served its purpose as foretold, until the day Danny O. was pulled out of a meeting by a panicked intern. Everything is down, the young man panted, short of breath and sweaty from a brisk dash around the office, trying to find which boardroom the IT team had been assigned for that days conference. Everything! All requests to the web tier are returning some kind of duplicate record error that doesnt even make sense! Were dead in the water!

Danny shook the intern briskly to help restore his composure, and hurried back to his workstation. It was true: all production systems were inaccessible, all requests returning the duplicate record error. It sounded like a database problem, so Danny turned to The Database. The Database, as the 90 application servers, each running the same enormous Program that hosted all of Monocorps internal and external web services, connected to the same one. Roger had designed The Program to be stateless, so that an arbitrary number of copies could be run in parallel. The single catalog in the single database instance not only provided these copies with their data, but was also the single point of coordination between them.

The Program, meanwhile, was Rogers answer to the problem of providing a set of web-facing services with common functionality, a sort of framework for the web, if you will. It had a sub-system for receiving and routing HTTP requests on top, a sub-system for talking to the database on the bottom, and, sandwiched between, a series of modules that contained all of Monocorps business logic, producing results that the web tier could package up as either an HTML or JSON response. Everything, from the Monocorp website to the apps used internally on the employees mobiles, relied on The Program. And The Program was trying and failing to put something in The Database.

Dannys first port of call in The Database was the ERRORS table, a central repository of everything that ever went wrong in any copy of The Program. He could see the duplicate record errors, a couple thousand by now, but none of them mentioned a particular module. The errors seemed to be happening in the web tier itself. Danny turned to the MONITORING table next, and saw something very unusual. There was code in the web tier that captured the start and end time of every single web request and saved them to the MONITORING table. A module within The Program kept an eye on this table and analyzed the data for trends and problems, emailing regular reports to the IT team. What Danny noticed when he checked the records in the table since the problems started was& there werent any. The last record in MONITORING bore a timestamp from an hour earlier. Though web requests were obviously being received, hence the records in the ERRORS table, they werent being logged. Could the monitoring code itself be causing the problem?

Danny studied that last MONITORING record for a long while when it struck him: the ID of the record was 2147483647. Im sure you noticed, just as Danny did, that this number is the arithmetic limit of a signed, 32-bit integer! The MONITORING table had an auto-incrementing primary key, and when it reached its limit it just kept on trying to insert the same key into the table, resulting in the duplicate record errors… on every single request to every copy of The Program. Danny wasnt sure how to solve the problem, other than sacrificing the existing monitoring data by truncating the table. Before his bosses would allow that, however, they wanted the Architect to weigh in.

It took three tries before Roger answered his phone. Clearly irritated at being interrupted on his sabbatical- Danny could hear the faint sounds of seagulls and surf- he nonetheless listened intently as they described the problem. His thoughts went quickly to the defense of his vision.

Its not a problem with the architecture, he assured them. The bosses nodded, but Danny was unconvinced.

Are you sure? Were currently logging a couple million web requests per day across the entire business. If the monitoring table can only hold two billion records, well have to empty the table every year or two. The monitoring system doesnt have any provision for doing that, or any way to archive historical data&

Did you say millions of requests per day? Roger asked. It was only maybe ten thousand when I left&

Weve added a lot of modules since then, Danny explained.  That was the point of your architecture, right? That we could fit whatever web apps and APIs we needed inside it?

Listen, Roger said, you cant blame the architecture when you change the requirements.

Dannys boss saw the look on his face and quickly gestured for him to bite his tongue. They confirmed that nothing terrible would happen if they truncated the MONITORING table, and left it at that. When the work was done, Monocorp shuddered back into motion, and Danny put something else in motion, too: his search for a new job. He swore that, by the time the MONITORING table needed truncating again, Monocorp would have to find another monkey to maintain their monolith.

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


Метки:  

Announcements: The Daily WTF: LIVE! - This Friday

Понедельник, 06 Апреля 2015 г. 18:30 + в цитатник

This is your reminder: TDWTF's live show is happening this Friday, from 810PM at the Maker Theater in Pittsburgh. Tickets are available now.

We still have room for a few more storytellers, so if you're in the Pittsburgh area, pitch us your "real life" IT story. It need not be a WTF, just a story. Send a brief (12 paragraph) pitch for your story to storytelling@jetpackshark.com, and Remy will be in touch to discuss. We'll work with you to build up a great 8-10 minute piece you can perform.

This event is brought to you by our awesome and proud sponsor, Puppet Labs*. As we mentioned in their sponsorship announcement article, thanks to their support, well be able to create some exciting new content, do more meet-ups, and have a lot more fun all-around. This is an example of that and we are still very excited to be working with them! Check out their intro video, it gives a pretty good overview of how they help their customers get things done.

Wed also like to thank Code & Supply for helping us network with the Pittsburgh IT community. Code & Supply is the largest IT community group in Pittsburgh, with frequent meetups and a variety of activities. Theyve helped connect us with performers and are helping promote the show with their community. They even let this guy give a talk on using storytelling to communicate technical details.

[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-daily-wtf-live-this-friday


Метки:  

Classic WTF: The .NET Bridge to Nowhere

Понедельник, 06 Апреля 2015 г. 14:00 + в цитатник
It's Easter, so we're taking a little break around here. Instead, enjoy this classic from Alex. Stories like this inspired "Remy's Law of Requirements": no matter what the requirements say, what the users actually want is Excel.
-- Remy

For as long as The City (as I'll call it) has supplied water to its residents, it has had one big headache called "The Annual Water Survey." Like residents of all large metropolises, The City's residents want to make sure the water they drink has only a miniscule amount of the "bad stuff," such as heavy metals and pathogens, and just the right amount of the "good stuff" -- chlorine, fluoride, etc. The water survey -- a 100-plus-page report that details test after test after test -- was their vote of confidence.

Compiling the survey had always been a long and tedious process. At first, field technicians would take samples from across The City, add drops of various indicator chemicals and record the results in their logbooks. From there, lab technicians would transcribe the numbers and use special slide rules to create tables of meaningful results. Typists would then compile the various tables into a giant binder and send it off for duplication.

Technology helped speed things up a little. Electronic testers replaced drip kits, spreadsheets replaced slide rules and word processors replaced typewriters. But for the most part, the process remained the same. All of that changed, however, when The City -- with its grand plan to automate the water survey -- wanted to make everyone's lives easier.

After 18 long months of development, the highly paid consultants hired by The City presented their solution. Field technicians would be equipped with ruggedized, Internet-enabled PDAs that would instantly upload test results to the .NET-based central server. From there, lab technicians would use an ASP.NET-based app to verify and analyze the data. Reports -- including the monstrous, 100-plus-page water survey -- could easily be generated from the lab data. It was a big investment, but The City knew it would pay off.

Not Quite Field-Tested

Shortly after going live, field technicians across The City noticed a bit of an issue. Because water testing often occurred in low-coverage areas, the PDAs would routinely toggle between offline and online modes. This resulted in a several-seconds-long synch process, which would often fail and require a reboot when the PDA lost its connection. The technicians just resorted to doing the tests, writing the results in a notepad and entering them on the PDA later.

Either way, the field technicians weren't too thrilled about the PDAs. Their old process of entering data into Excel spreadsheets and e-mailing the spreadsheets in was much faster than struggling with a little stylus to tap out numbers. To make the techs "lives easier, the consultants built several Excel spreadsheets -- each with a heavy dose of VBA -- that would serialize data into XML and send it through a Web service to the central server.

Not Lab-Tested, Either

As the lab technicians began their analyses of the new data they, too, noticed a bit of an issue. Although the Web-based app mimicked a cell-based spreadsheet, it lacked the robustness of Excel that the techs had grown accustomed too. There was no auto-fill, quick-sum, conditional formatting or any of the other must-haves.

The consultants quickly responded by building Excel export functions, but that proved to be deficient. The techs couldn't interlink spreadsheets or easily keep their local, heavily modified spreadsheets in synch with data on the server. The consultants finally settled on a solution that the lab technicians could use: They built several Excel spreadsheets, each with a heavy dose of VBA, that would de-serialize data from the central server, display it and then upload any changes through the same mechanism.

As for the Reports ...

Once the lab technicians compiled enough real data to create a survey, the writers were ready to begin generating reports. However, that system also proved to be a bit cumbersome. Although the Web-based reporting module provided them with significant control over how the PDFs would look, it lacked some of the finer details of their former tool, Microsoft Word.

The biggest annoyance was that they were no longer able to instantly preview layout changes, such as changing font size to make a table fit on a page. Try as they might, the consultants simply could not figure out a way to allow them to easily tweak the layout. Instead, they presented a solution that the writers could use: They built several Word documents -- each with a heavy dose of VBA -- that would automatically download and de-serialize data from the central server, and then serialize and upload the saved report.

The Final System

After three years of tweaking and hundreds of thousands of dollars in consulting fees, The City ended up with a system that everyone could live with. Field technicians used Excel to enter data, lab technicians used Excel to process data and writers used Word to create reports. Granted, it was exactly what they had before, but at least now they had a .NET server to bridge it all together.

[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/classic-wtf-the-net-bridge-to-nowhere


Метки:  

Error'd: Phenomenesia

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

"We don't know what it is, but it must be bad, so we'll wake you up in the middle of the night to let you know about it!," writes David L.

"SendGrid's new app really associates with the hip, youth of todays mass email sending market...yo," writes Eion R.

Raghunathan N. wrote, "Of course this pairing makes sense. I mean, who'd ever listen to an iron by putting it next their ear?"

"I'm looking at courses at a local college, but I'm kind of conflicted as to how I should apply," writes Steve.

Angela A. wrote, "Either nothing is going on at the mall, or maybe Batman is coming. Not sure."

Oradim writes, "So, if you pick the United Nations as your country, what do you enter for your postal code?"

Michael S. wrote, "Drupal users have transcended and no longer require speech to communicate."

It was a big day for Bernie when, during a bicycle tour in the middle of nowhere, he discovered where he could find both WTF and Innovation.

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


Метки:  

CodeSOD: Scheduling Buttumptions

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

Steph had been at this job long enough to be fairly good at it, but not quite long enough to have peeked in all the dark corners yet. As such, when she heard that there was an issue with scheduled jobs, her first thought was to poke through cron to see if she could pick out what schedule was misbehaving. Apparently, all of them- cron was empty.

Schedule

Confused, she went to her team lead Greg, asking about where she might find the scheduling setup. And that was when she heard about Travie the Whiz Kid. A junior developer with no degree, he'd been hired solely based on his ability to talk a big game about how he single-handedly saved several companies by providing them with innovative websites during the dot-com bubble... when he was twelve. The Whiz Kid was a Special Snowflake; he preferred to reinvent the wheel rather than implement stable but "boring" code. Upper management was convinced he was an unparalleled genius, and had exempted him from the usual QA standards. Unfortunately, he'd grown utterly bored with Business Intelligence and transferred to the Web team, leaving his inventions behind for Steph to maintain.

Travie had been tasked with writing a helper application in Java to interact with and process data from a third-party web service. The third party processed their data on certain days at certain, known times, and their app needed to wait and pull down the data after it was guaranteed to be there. The ticket involved the wrong data being collected: at 5:15AM on the second of the month, the script was pulling in the previous month's data to process, rather than the current. Was it running early?

Steph found the repo with the Java code The Whiz Kid had written and checked it out, skimming over the list of files as she finished her morning latte. She opened the Schedule class, winced, and closed it again. "Definitely need more coffee."


 private static int eighth_hour_of_day = cal.getActualMinimum(Calendar.HOUR_OF_DAY) + 8;
 private static int ninth_hour_of_day = cal.getActualMinimum(Calendar.HOUR_OF_DAY) + 9;
 private static int eleventh_hour_of_day = cal.getActualMinimum(Calendar.HOUR_OF_DAY) + 11;
 private static int zero_minute_of_hour = cal.getActualMinimum(Calendar.MINUTE);
 private static int first_day_of_month = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
 private static int fourth_hour_of_day = cal.getActualMinimum(Calendar.HOUR_OF_DAY) +4;
 private static int fifth_hour_of_day = cal.getActualMinimum(Calendar.HOUR_OF_DAY) +4;
 private static int sixth_hour = cal.getActualMinimum(Calendar.HOUR_OF_DAY) + 6;
 private static int last_minute_of_hour = cal.getActualMaximum(Calendar.MINUTE) ;
 private static int second_of_month = cal.getActualMinimum(Calendar.DAY_OF_MONTH) + 1;
 private static int fifteenth_minute = cal.getActualMinimum(Calendar.MINUTE) + 15;
 private static int last_day_of_month = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
 private static int last_hour_of_day = cal.getActualMaximum(Calendar.HOUR_OF_DAY)-2;
 private static int thirty_fifth_minute = cal.getActualMinimum(Calendar.MINUTE) + 35;


A second, larger latte obtained, Steph took a deep breath and opened the class again. By the time her third latte was finished, she'd tracked down the issue: fifth_hour_of_day was accidentally, ridiculously defined as 4, meaning the code was pulling down the data at 4:15AM, before the new month's data was available.

Code fixed and checked in, Steph rapidly deleted her working copy and closed the ticket. At least I'll never have to-

"Good work, Steph!" Greg said. "I'll send you the other ticket now."

Head met desk.

The second ticket turned out to be no more obvious than the first at first glance. Now that the constants were fixed, there seemed no reason for a second event, scheduled for 4:00AM on the dot, not to fire. This would require debugging the while loop that did the scheduling, which she had avoided as much as possible during the first ticket:


while (true) {
 try {
 Thread.sleep(60 * 1000);
 Properties sysProperties = new Properties(); // Re-read properties file
 FileInputStream f = new FileInputStream(System.getProperty("jboss.server.home.dir")+"/conf/xxxxxxxxxx.properties");
 sysProperties.load(f);
 f.close();
 
 //Call Web service every day 8am 
 Calendar today = Calendar.getInstance(); 
 if ( today.get(Calendar.HOUR_OF_DAY) == eighth_hour_of_day 
 && today.get(Calendar.MINUTE) == zero_minute_of_hour) {
 PendingData.getPendingData(sysProperties);
 }
 //Call Web service every 1st of the month at 4am
 if (today.get(Calendar.HOUR_OF_DAY) == fourth_hour_of_day 
 && today.get(Calendar.DAY_OF_MONTH) == first_day_of_month
 && today.get(Calendar.MINUTE) == zero_minute_of_hour) {
 AllData.updataDatabase(sysProperties);
 }
 //Call Web service 2nd of month at 5:15am
 if (today.get(Calendar.HOUR_OF_DAY) == fifth_hour_of_day 
 && today.get(Calendar.DAY_OF_MONTH) == second_day_of_month
 && today.get(Calendar.MINUTE) == fifteenth_minute){
 OtherData.getOtherData(sysProperties); //Anon'd
 }
 // etc etc etc
 } catch ( /* etc */ ) {
 }
}


Of course, the solution is likely obvious to you by now: what happens if it takes longer than a minute to update the database? One of the snipped instances, far down the page and added later, executed at 03:59:59.987, taking just over a minute to complete, preventing the 4:00AM job from executing. They both had to execute, but obviously were incompatible with each other given the current architecture.

Finally, Steph went to her team lead. "I can't fix this," she said, rubbing her temples. "I guess I'm just not enough of a whiz to figure it out."

Greg made a face. "Don't tell management, but I've got a prototype using an actual scheduler I suggested when this was made."

"I'll replace the whole damn thing from scratch on one condition," she said, holding up her empty Starbucks cup.

"Don't worry, I've got this," Greg said.

Later that day, he tracked down Travie, and encouraged the Whiz Kid to chip in on a $50 Starbucks gift card for Steph.

[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/scheduling-buttumptions


Метки:  

Radio WTF Presents: Quantity of Service

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

Radio WTF Presents!

Today's episode: "Quantity of Service", adapted for radio by Lorne Kates, from a submission by Lyfe



Links To Downloads

"Quantity of Service" on Soundcloud (192k, mp3, 41.3mb), ... Direct Download
"Quantity of Service" on Soundcloud (96k, mp3, 20.6mb) for dial up, yo!... Direct Download

Starring (in order of appearance)

  • Remy Porter... as Leif
  • Mark Bowytz... as Daryl
  • Lorne Kates... as various callers
  • Alex Papadimoulis... as Kevin

Featuring the voice of Paul Rousse of VoiceByPaul.com, and the songs "Slow Burn" and "Mining by Moonlight" by Kevin MacLeod of Incompetech.com.

Note: Transcript to follow later today.

And if you're nostalgic for radio of days past, last year's episode MAKE IT WORK is still online

Jump to comments

BONUS! OUTTAKE!

I know you all love the Ring Tones and Empty Threes and bits and stuff. So have fun with these:

Transcript

Scene: 1

NARRATOR
Radio W.T.F. presents...

SOUND: INTRO MUSIC STING

NARRATOR
The Daily WTF

SOUND: END OF INTRO MUSIC STING

NARRATOR
Today’s episode, "Quantity of Serivce", adapted for radio by Lorne Kates, from a submission by Lyfe.

NARRATOR
The year is late nineteen-ninety something. Business is booming at Initech Personal Computers, a low cost, high volume retailer of end-user PCs. They had a shop in every town, an ad during every commercial break, and a toll-free number open 24/7 ready to take your order. Sure, they weren’t actually called "Initech Personal Computers", but you know who I mean. I bet you can still remember their jingle-- and now that I’ve reminded you, it’ll be lodge in your skull on an endless, incessant loop for days. Yes-- THAT Initech Personal Computers.

They dominated the PC market with extremely low prices. Surprisingly low. Or, as Leif would come to realize during his tenure as head of 2nd level support-- "lowest bidder" low.

(DURING THE HEYDAY, JUST AS THE FALL BEINGS. IN LEIF’S OFFICE)


SOUND: LOTS OF PEOPLE. RINING PHONES IN BACKGROUND. BUSY

SOUNDING. LEIF’S PHONE RINGS.

DARYL

(ON PHONE)
Hey, Leif. Can you take a support escalation?

LEIF
Sure thing, Daryl. What’s the problem?

DARYL
The problem is the call’s taking WAY too long. It’s really effecting my average time to call completion.

LEIF
I meant, what’s the customer’s problem? What’s wrong with their computer?

DARYL
No idea. None of my techs can get anything from him. I even tried, but he won’t follow the troubleshooting script.

LEIF
Did you at least get the serial number?

DARYL
He can’t even figure that out.

LEIF
Oof. Okay, send him through.

DARYL
Great, I’ll transfer the whole ticket to Customer Service. Thanks, that guy was just killing Support’s clearance rate.

SOUND: SFX PHONE RING

LEIF
Initech Personal Computers support, Leif speaking. How can I help you, Mr. Berry?

MR. BERRY

(ON PHONE)
I don’t want to hear one more minute of that damn on hold music! If you put me on hold again, I’mma coming down there and put my foot through your tape deck, then up the ass of whoever picked that loop!

LEIF
I’ll relay your feedback on our hold music to the appropriate department. I apologize for the wait time, Mr. Berry, but I’m here for you now. Let’s see if we can address your problem.

MR. BERRY
This computer’s a piece of crap that doesn’t even turn on!

LEIF
I’m sorry to hear you’re experiencing problems. Let’s look into that together. Can I first ask for the serial number, please?

MR. BERRY

(SNORTS)
"look into it"-- no one there actually knows how to fix computers, do they?

LEIF
I’m trying to help you now. I just need the serial number to start the process.

MR. BERRY
Why, so you can also pretend the number’s "not in the system", and pass me off to the next schmuck like last week’s bong water?

LEIF
I assure you I won’t do that. I just need the serial number so I can look up your computer’s configuration. It’s the only way I can help you troubleshoot. The serial number’s on a red or green tag on the back of the computer.

MR. BERRY
I know where it is, you jerks have had me read it enough times. It’s W43325-TF-1.

LEIF
Um-- that’s-- that’s an odd format. My apologies, but can I have you double check the number?

MR. BERRY
It’s the number on the back of the computer. I’m not a moron!

LEIF
I’m not saying that, Mr. Berry. Sometimes there are multiple numbers on the back of the computer. That may be the power supply, or the video card. It would be a huge favor to me if you could just check again. Do you have access to the back of the computer right now?

MR. BERRY

(ANNOYED)
yes, fine, whatever...

SOUND: SFX SCUFFLING BEHIND COMPUTER

MR. BERRY
I’m staring right at it-- back of the computer. Red sticker that says Serial Number. W43325-TF-1! It isn’t the power supply, it isn’t the video card, it isn’t a tap-dancing dust bunny. It’s the computer’s serial number! Red sticker on the blue faceplate.

LEIF
That is strange, our serial numbers start with IPC-- wait, did you say BLUE faceplace?

MR. BERRY
Yeah, the one covering the ports. Blue, like the buttons on front.

LEIF
Blue buttons? The computer isn’t just solid black or beige? There’s blue on it?

MR. BERRY
Yes, of course there’s blue on it! The case color was the main selling point for me.

LEIF
ooo... uh, the front of the computer-- are there any other buttons or markings?

MR. BERRY
The power button, the reset button, the CD ROM, and the Fruits logo.

LEIF
The-- Fruits logo? It isn’t a stylized "IPC"? Sir-- is this even an Initech Personal Computer?

MR. BERRY
No, I bought it from Tech Town PC.

LEIF
....!!! Sir, I can’t support another brand of computer!

MR. BERRY
Why not?

LEIF
This is the Initech Personal Computer support line! We only support Initech Personal Computers

MR. BERRY
Well, that’s just blatant false advertising! Your newspaper ad CLEARLY says you offer 24/7 Computer Support!

LEIF
FOR OUR OWN COMPUTERS!

(REGAIN COMPOSURE)
Sir

MR. BERRY
Well then, maybe you should rebrand your phone line to Initech ONLY Computer Support.

LEIF
That’s a-- suggestion.

MR. BERRY
So you’re refusing to fix my computer?

LEIF
I-- I can’t--

MR. BERRY
I bet you expect me to buy a new computer from you, huh? That’s your scam, isn’t it? Bait and switch!

LEIF
No, sir, not at all, but maybe if you called the store you bought your computer from--

MR. BERRY

(INTERRUPTING)
Oh, so now you expect me to start all over again on hold with THEM because you’re refusing to help me?!? What a waste of my time, and it’s all your fault! I’m going to file a formal, written complaint. Expect it along with my phone bill for the time you’ve wasted. Thanks for nothing!

LEIF
Have a nice d--

SOUND: PHONE HANGING UP ON OTHER END

LEIF
-- day sir.

SOUND: SOUND FX LEIF HANGING UP PHONE, SITTING BACK IN CHAIR

LEIF
Wow.

SOUND: LEIF STANDS UP, WALKS TO SUPPORT. SUPPORT FLOOR SOUNDS GET LOUDER. DARYL IS ON A PHONE CALL, HIS VOICE GETS LOUDER AS LEIF APPROACHES

DARYL
(SPEAKING WITH A LOUD, OVERLY CHEERFUL "PHONE SUPPORT" VOICE) Yes, ma’am. Start - Shutdown - Restart. Uh-huh. Yes, it IS silly that you click Start to Stop, hahahahaha.

(HIS LAUGHTER IS SACCHRINE SWEET)
The reboot and update can take up to half and hour, so I’ll let you go. Please call back and the next tech will guide you through the rest of the install. Have a great day and thank you for calling Initech Personal Computers.

SOUND: CLICK OF PHONE HANGING UP, THEN DOUBLE CLICK OF MOUSE

DARYL
And call closed!

LEIF
But isn’t the case still open?

DARYL
Sure, but the metric is "call completion", not "case completion". How did that escalation go?

LEIF
About that-- did you actually get his serial number during your call?

DARYL
Yeah, sure, but the number he gave was invalid. I couldn’t proceed with an invalid serial number.

LEIF
But didn’t you recognize the number format wasn’t IPCs?

DARYL
Sure, but an invalid number is as good as no number. The script’s only choices are for him to call back later, or escalate.

LEIF
If you knew it wasn’t an Initech number, did you even think to ask him if he was calling about an Initech computer?

DARYL
Of couse I knew it wasn’t and IPC computer. But the script doesn’t have that question to ask.

LEIF
Then ask the question anyways! Sometimes you have to go off script!

DARYL

(SHOCKED, TRYING TO KEEP LEIF’S VOICE DOWN)
Whoa whoa whoa... shhh... close my door.

SOUND: DOOR CLOSING, OFFICE NOISE FADING AWAY

LEIF
I’m sorry, I didn’t mean to attack your script-- I know it’s your baby-- but troubleshooting is a problem solving skill. Having a best practice guide is good, but maybe you need to encourage your techs to-- think critically.

DARYL
This isn’t about my script being a pet sacred cow. This is about the pile of gibbering helldesk morons out there being biologically incapable of coherent thought! I wouldn’t trust them to walk a customer through complex troubleshooting without a script telling them exactly what to say and do. Hell, I’m surprised they can walk without a cue card telling them "left, right, left, right".

LEIF
That’s a horrible thing to say about your team!

DARYL
But it’s true, Leif. I know you haven’t been with IPC long, but surely you’ve noticed the company’s main competitive advantage is "lowest cost". That attitude isn’t limited to the computers we sell. What caliber of worker do you think a "lowest cost" salary attracts? Idiots. I’m pretty sure that red-head in the front row is legally brain dead. Like, if Safety and Standards every inspected, we could be charged with improper storage of a corpse! I wouldn’t let them handle a computer without guidance. I’m shocked we let them have sharpened cutlery in the lunch room.

LEIF
That’s just a training issue! Have a troubleshooting primer. Have new techs shadow experienced ones for a while. Run educational Lunch and Learns on new techniques. It takes so little effort for such a massive return on the quality of support.

DARYL
No no no. A "lowest price" company isn’t concerned about quality. It’s quantity. Volume. Amounts. The bosses aren’t looking for the best technical catch, or the smartest troubleshoot. They’re looking at calls per hour, which really means cost per call.

LEIF
But the customers...

DARYL
"Lowest cost" products attract the sort of customers who BUY the lowest price commodities. Idiots. Drooling, gibbering morons. They can’t handle advanced troubleshooting either. They can barely handle breathing and controlling their bowels at the same time. It’s a miracle if a day goes by without a "drink holder tray" call. If I let customers and techs have their way, they’d tie up the line all day turning computers off and back on again. That’s why my script is the first, last, and only way of doing tech support. It’s fine-turned perfection at achieving Support’s goals.

LEIF
It doesn’t achieve that goal! It couldn’t even diagnose a simple problem that we had just now!

DARYL
And that’s just it. Solving the problem ISN’T the goal. They can have their problem solved, or hang up, or demand a refund. I really don’t care which, as long we achieve Support’s one and only true goal-- {let the gravity of this line sink in} getting the customer off the phone as quickly as possible.

Scene 2

NARRATOR
After a couple months at Initech, Leif got used to handling all the calls that the support script couldn’t handle-- or wouldn’t handle. Even with a sizable support team, the department could barely keep up. For each call completed, two more were waiting on hold. Since Leif was the escalation desk, and effectively autonomous from support, he adhered to achieving his own personal support goal for customers sent his way: actually solving their problems!

NARRATOR
But, as Leif would discover, having a reputation for solving problems meant that others would have an expectation for him to handle impossible problems of their own making...

SOUND: SOUND OF SUPPORT MIXED WITH SOUNDS OF PACKING. LEIFS PHONE RINGS

LEIF
Morning, Daryl. What’s with the packing?

DARYL

(ON PHONE)
Support’s relating to the office area downstairs. Something about it being closer to the fire exits. I think the bosses just want to save the cost of heating the upper floor come winter.

LEIF
Isn’t the downstairs office area, like, half the size?

DARYL
The term is "cozier". Or-- {hushed voice}-- half those desk just won’t get unpacked. By no coincidence, the month-end numbers will be in before the move is complete. {back to normal voice} Anyways, there’s an escalation ticket waiting for you. check your email.

SOUND: EMAIL BEEP

LEIF
Thanks, I’ll take it.

SOUND: DOUBLE CLICK.

LEIF
Okay, Mr. Wedgewood.

SOUND: DIALTONE, DIALING. RING.

WEDGEWOOD

(ON PHONE)
Yes, hello?

LEIF
Hello, this is Leif from Initech Personal Computers returning your call. I understand you’re having some OS issues?

WEDGEWOOD

(IS A VERY STRESSED, FRAZZED CALLER)
Please tell me you can help me! I just bought this computer last year and I can’t afford a new one. I’m just trying to run Aquarium Serenity 98 on my PC. Fishes are the only thing that keeps me relaxed, and I can’t afford real ones. Not like I could keep them in my apartment anyways. You gotta help me man!

LEIF
Certain. I see here in the case notes you’re trying to run Aquarium Serenity, but you have...

WEDGEWOOD

(INTERRUPTING)
No, it’s Aquarium Serenity 98. The new version, with the Malawi Cichlid. The blue/orange contrast is therapeutically relaxing.

LEIF
My apologies, Aquarium Serenity 98. I see in the case notes that unfortunately, you have Windows 95, and that program requires Windows 98, so...

WEDGEWOOD

(INTERRUPT AGAIN)
Yes, yes, yes I know I have to upgrade but no one will sell me the upgrade I need!

LEIF
That’s unusual. I’m certain we stock upgrades to Windows 98, and if we don’t then surely--

WEDGEWOOD

(STILL INTERRUPTING)
I can’t afford the full Windows 98 upgrade, and no one will sell me Windows 96.5!

LEIF
Sorry-- 96.5?

WEDGEWOOD
Yes, obviously! I explained this all to Kevin, the nice man who sold me the computer last year-- and he said you could charge me for half an upgrade, just enough to get Aquarium Serenity 98 running. He understood I couldn’t afford going from Windows 95 all the way to 98, but he said you techs could upgrade me halfway to Windows 96.5. But now no one will actually do the upgrade for me!

LEIF
I-- uh-- are you sure that’s what was recommended?

WEDGEWOOD
Yes, absolutely. Half an upgrade is the only upgrade I can afford. I need my fish!

LEIF
Uh-- can I put you on hold while I look into this?

WEDGEWOOD
Oh-- okay, yeah. That’s fine. Your music is very serene.

LEIF
Sure.

SOUND: ON HOLD MUSIC

LEIF
Oh boy.

SOUND: GETTING UP, WALKING TO SUPPORT-- NOISE OF PEOPLE ON PHONE, SHUFFLING EQUIPMENT, ETC. ON HOLD MUSIC FADES. TRY TO SOUND MORE FRAZZLED IN SUPPORT

LEIF
Hey, Daryl, do you know where I can find Kevin in Sales?

DARYL
Sure, corner cubicle. Can’t miss him. And hey, on your way back, can you grab me back a coffee.

LEIF
Huh? Um, okay.

SOUND: WALKING SOUNDS, DOWN STAIRS, GOES INTO ANOTHER OFFICE-- IT SOUNDS ALL NICE AND HUSH AND QUIET AND THERE’S NICE MUSIC, AND HE’S WALKING ON CARPET RATHER THAN CONCRETE

LEIF

(RADIO WHISPER TO SELF)
Never been here before. Swanky. {sniff sniff} Is that fresh roast? Focus-- okay, corner cubicle--

KEVIN

(ON PHONE, BOISTEROUS SALES PERSON)
... no, of course our computers are top of the line. You’re a smart guy, your kid could spill grape juice on the laptop, something could happen. So I’ll just get you that extended warranty, right. Yeah! So you just call support and you’re their number one priority! Pleasure doing business with you, and congratulations again for being an Initech Personal Compter owner. Bye bye

SOUND: KEVIN HANGS UP PHONE

LEIF
Hi, I’m Leif, head of Customer Service.

KEVIN
Nice to meet you, Lem. Ah-- I bet you’re looking to take advantage of that employee discount, are we? Get you a coffee while we look at laptops? The new models are beautiful.

LEIF
No thanks-- wait, you guys get a coffee maker? Never mind. I’m just here to talk about a customer. He was sent to tech support looking for an OS upgrade. Mr. Wedgewood?

KEVIN
Yes, charming man. Sold him his computer last year, and he was so happy with it he just called me back looking to do an upgrade.

LEIF
Yes, exactly. Somehow, he must have gotten confused about the upgrade, and called back to tech support looking for a "half upgrade" to Windows 96

KEVIN
Yes? And?

LEIF
.... and, I just wanted to know what you actually told him.

KEVIN
Well, that is what I told him.

LEIF
What? How can you tell him that?

KEVIN
How couldn’t I? Mr. Woodworm is a good customer of mine, I know y’all boys in tech support would take care of him great!

LEIF
But what you told him is impossible!

KEVIN
Aw, look man, it’d be a big favor. I know he can’t afford the whole upgrade, so just charge him for half and tune him up to 96.5. All he wants to do is see his silly dolphins.

LEIF
They’re fish.

KEVIN
Dolphins aren’t fish. They’re mammals.

LEIF
That-- ahh! No! There isn’t such a thing as Windows 96.5. There isn’t such a thing as a "half upgrade"! That isn’t how computers work!

KEVIN
Son, how computers work isn’t my department.

LEIF
But selling them is!

KEVIN
Yes? And?

LEIF
And you have to have some knowledge of what you’re selling! You have to understand what your customer’s technical needs are, and which are the best quality components!

KEVIN
Nah. All I need is the weekly spreadsheet with base costs, and to memorize the silly techie buzzwords with the highest profit margins. They need a cheap computer, and whatever bits and rams cost the least-- well, those sell the most. There’s a reason I’m #1 in sales by quantity every quarter...

LEIF

(EXASPERATED, DEFAEATED. STAGE WHISPER TO SELF)
There’s a reason we have so many support calls...

KEVIN
... and a #1 sales rep takes care of his customers, so I really hope you’ll do right by my man Walter Woods.

LEIF
There’s nothing to "do right" by! You promised him something that doesn’t exist, for half the price of the thing he actually needs! What do you expect me to do, upgrade him to Windows 98 at half price?

KEVIN
Well, heck, he’ll be thrilled at that! I appreciate it, Lem.

LEIF
Are you serious?!?

KEVIN
Absolutely. I’d never be able to sell something like that at a loss.

LEIF
But you expect me to?

KEVIN
There’s a reason your department is a cost center, while my department gets a coffee maker. Either that, or I guess you’ll just have to flush Mr. Wigglewood’s fish down the virtual toilet.

LEIF
... ugh.

KEVIN
It was a blast talking with you Larry. Stop by again when you want to buy that new laptop, alright? And-- grab a coffee on your way out.

Scene 3

NARRATOR
Over the next six months, Leif watched the support department get moved into smaller and smaller offices, and then finally into a converted room under the stairs in the basement. Initech’s dramatic drop in sales was a well known secret. Cost cutting measures were implemented across the company, hitting every department-- but missing the root cause of the problem entirely. Leif was under pressure to avoid replacement whenever possible-- and refunds altogether. He knew his decisions would be under scrutiny-- but until that one day, he had no idea to what depth.

(NEED TO ADD BASEMENT ECHO. LEIF’S DOOR IS RUSTY AND CREAKY. THE ONE TECH SUPPORT VOICE IN BACKGROUND IS DEPRESSED AND ZOMBIE LIKE)


SOUND: INCOMING EMAIL

LEIF
What does Daryl want now?

SOUND: DOUBLE CLICK, READING

LEIF
Regarding Ms. Edna Germaine’s request for replacement of... What? Denied? Oh come on!

SOUND: SQUEAKY CHAIR, RUSTY DOOR, ECHOEY FOOTSTEPS

LEIF
Daryl? What-- where did he go?

TECH
He said he’d be in Sales, getting a coffee. {cough}

LEIF
What? Come on!!

SOUND: WALKING OUT OF DANK ROOM, UP SEVERAL FLIGHTS OF STAIRS, THROUGH HEAVY OLD RUSTY METAL DOOR. TO CARPET, SAME SOUNDS AS BEFORE IN SALES.

LEIF

(NOT HAPPY)
Why did reject Mrs. Germaine’s RMA for a mouse?

DARYL
Oh, just a bit of due diligence. The bosses asked me to rein in the staggeringly high cost of returns. She broke her mouse, that isn’t Initech’s responsibility

KEVIN
This is THAT case? She thought it was a footpedal! Now that’s funny.

LEIF
She bought an extended warranty!

KEVIN
That doesn’t cover accidental or intentional physical damage.

LEIF
Then goodwill it! It’s an off the shelf commodity mouse for a customer who just dropped two grand on a brand new computer.

DARYL
Profits margins are already razor-thin on PCs and accessories. I’m sorry, hands are tied here. But tell you what, if she wants to buy a new, more rugged mouse, I’ll authorize half-priced shipping.

LEIF

(SARCASTIC)
Gee thanks, she’ll love that.

DARYL
Great, another satisfied customer! And speaking of which, glad you came around-- Kevin has a very important customer! He’s got a new laptop--

KEVIN

(INTERJECTING)
top of the line!

DARYL
-- that’s having a technical issue. Just need you to authorize the replacement.

LEIF

(RECOMPOSING, STILL SORE ABOUT THIS)
Whatever. Just forward me the ticket, I’ll look at it back at my desk.

DARYL

(VERY MUCH NEED TO GET THE SOMETHING OUT OF THE ORDINARY / PULLING A FAST ONE VIBE)
Already have the case open here.

LEIF

(SUSPICOUS BUT NOT SURE WHY)
Reeealy? Let me see the case notes.

SOUND: TAKING THE KEYBOARD, READING

DARYL
See? I’ve already confirmed it, all you have to do--

LEIF
He has an "Imploding keyboard"?

KEVIN
Oh yeah! It’s a very common problem with laptops these days.

DARYL
Already verified by the customer’s IT people! But... I knew you’d need proof so I had him send a photo. Here, check it out.

SOUND: HAND OVER MANILLA ENVELOP, OPEN, PAPER OUT

LEIF
What is this? It’s all blurry and black and white-- did you print it out like this?

DARYL
That’s the photo he mailed us. Perfectly acceptable. About that RMA number--

LEIF
It looks like a squid wiped its ass with it!

KEVIN
Looks fine to me.

LEIF
No. This "picture" isn’t proof. And "imploding keyboard" sounds like something Kevin would just make up. I’m going to call the customer and we’ll clear this up.

DARYL
There’s really no need--

SOUND: SPEAKERPHONE, DIALING

KEVIN
He is an excellent customer, and just wants to be assured that we stand behind the quality of our laptops.

LEIF
Oh, so NOW you’re worried about quality?

KEVIN
I, uhh--

SOUND: FINISHES DIALING. RINGING. PHONE PICKUP, CUSTOMER "MR STRATTON" PICKS UP

STRATTON

(ON PHONE)
Joseph Stratton speaking.

LEIF
This is Leif from Initech Personal Computers support calling about your laptop.

STRATTON
About time! When shall I expect my replacement?

LEIF
I’m just verifying the claim, but need a better photo of the damage. Can you resend it, please?

STRATTON
Excuse me, but don’t try to pull that on me. I went through EXTREME difficulty getting you this digital photo as requested. Don’t make me jump through more hoops. I’m looking at my copy of the photo, and it is as pristine as when I faxed it to office’s mail room.

LEIF
Wait, you faxed it to be mailed?

STRATTON
Of course I did, I’m not spending any more money on this laptop until it’s fixed, not even on a stamp!

LEIF
Then why didn’t you mail me the photo?

STRATTON
I’m not sending you my only copy of the photo!

LEIF
You can always print another photo if you needed a hardcopy.

STRATTON
You can’t PRINT a photo. Photos come from cameras! I was already developing this roll of film, so I didn’t mind that expense, but I was not paying for duplicates from the negatives.

LEIF
So this is a photo of the laptop?

STRATTON
Nice try, but no. Your tech support department specifically asked for a DIGITAL photo, and my camera is not digital. So I photocopied the laptop, since the Xerox is digital, and took a photo of THAT. And that is the digital photo you have. I’ve now provided a digital photo exactly as requested. Don’t try to pull a fast one on me.

DARYL

(STAGE WHISPER)
Leif, just authorize the request. I need this laptop replaced today!

KEVIN

(STAGE WHISPER)
He’s my best account!

LEIF

(DEEP BREATH, TRYING TO REGAIN CONTROL)
Okay-- okay-- Mr. Stratton, you have my sincere apologies for the confusion-- but--

(PAUSE, MOMENT OF TRUTH)
-- the moment you faxed the photo, it stopped being a digital photo and became a digital fax. I’m sorry, I can’t accept it.

DARYL

(STAGE WHISPER)
What are you doing?!?

STRATTON
Hmm. Yes, that makes sense. But the fact remains I have bought this very expensive laptop-- and I have no confidence in equipping my entire office with this model if I cannot be assured of it’s quality.

LEIF
A bulk order for your office? Ahh-- and there’s the quantity shoe dropping.

STRATTON
Pardon?

LEIF
Never mind. Look, Mr. Stratton, I could go through a whole rigirmoral of teaching you how to use a digital camera and email, but I think I know what I’d see from your "imploded keyboard". You’ve got a bunch of keys pressed inwards from a single spot, and cracks radiating out from that point. Right?

STRATTON
Yes, exactly!

LEIF
This is your first laptop, right?

STRATTON
Yes, it’s my very first one. And it’s been great, otherwise.

LEIF
They sure are. Don’t you love being able to just work anywhere with it?

STRATTON
Yes, it’s such freedom.

LEIF
Take it with you. Lounge on the couch with it.

STRATTON
So much freedom to work anywhere.

LEIF
Put it down, and get up for a nice refreshing stretch.

STRATTON
One must keep up their constitution when using these technologies.

LEIF
Forget that it’s on the couch, sit down on it--

STRATTON
Oh, it’s so easy to overlook-- I MEAN NO! No, not at all.

LEIF
Yeah, I figured. You broke it, Mr. Stratton, and that isn’t Initech’s responsibility. Unfortunately, your extended warranty doesn’t cover accidental or intentional physical damage. But if you’d like pay for the repairs, and a gesture of goodwill, I’ll authorize half-priced shipping.

STRATTON
Unacceptable! You owe me a new laptop! You’ll be hearing from my lawyer over this!

LEIF
Make sure not to sit on them.

SOUND: HANG UP OF PHONE

KEVIN
What did you do? We can’t afford to lose those sales!

LEIF
If you want to RMA it, do it yourself. I’m done being your cost center.

DARYL
But he’ll sue us!

LEIF
Let him. The quality of the suit is junk-- and low quality junk never stands up to actual scrutiny.

KEVIN
Initech can’t afford even a single lawsuit! It’ll be cheaper to give him a new laptop.

LEIF
Wow-- you guys will bend over backwards for one sales account-- but you couldn’t afford to replace a mouse. A single, bog-standard, off the shelf mouse. You’re both so blindingly obsessed with quantity, quantity, quantity! Well, you know what there’s a finite quantity of? CUSTOMERS! They’re a limited, and non-renewable resource. And they don’t exist in a vacuum. You think Mrs. Germaine is going to ever buy a computer from Initech again, when we screw her over a mouse? Nope. Never. BAM, one customer gone. And you think anyone SHE talks to is going to want to do business with a company that was more concerned over a tiny amount of money than a customer? Nope. Never. BAM BAM BAM! More customers gone. And the people they talk to, and the people they talk to. Each customer who gets a broken-out-of-the-box computer because you couldn’t bother to learn which motherboard is better manufactured? BAM! BAM! Each person whose call is "completed" without actually solving their problem? BAM BAM BAM!

Y’all love metrics-- but I can see them too. I know that our Dead On Arrival rate is an order of magnitude greater than the industry average. I know our incoming support calls to technician ratio is astronomic. The only thing I don’t know for sure is how close Initech’s costs are to being greater than the profit margin-- but judging from that phone call, I can make a pretty damn quality guess. And if there isn’t even going to be an effort to pilot this ship more ethically, then I don’t want to be here when it sinks.

I quit.

DARYL
Leif, I know you’re upset, but you can’t quit.

LEIF
I can. I did. And I didn’t even need a script to do it!

DARYL
Please-- I’m asking you to stay, as a favor to me. I’m understaffed, and you’re the best at support...

LEIF
I know, right? Total quality. Oh well. Bye.

DARYL
If you stay, I can get you a raise. Name it! What do you want?

LEIF
{beat} I don’t want this job. I don’t want your money. All I want is...

SOUND: SHUFFLING OF PAPER, GRABBING AN ENVELOP

LEIF
... this pre-paid mailer and... this!

SOUND: SFX OF MOUSE BEING GRABBED OFF DESK

KEVIN
Hey! That’s my mouse!

LEIF
Not any more. Now it belongs to...

SOUND: SFX SQUEAKY MARKER WRITING ON EVELOPE

LEIF
Ms. Edna Germain. I’ll drop it off at shipping on my way out.

Ending

NARRATOR
After Leif left, his position was eliminated entirely. The rest of the support department was replaced with an offshore team who could stick to a script, come in under budget-- and who performed with the exact quality you’d expect from a "lowest cost" support solution. Initech went under shortly after, and was bought up by their main competitor-- who also went bankrupt in short time and for the same reasons.

And as the 1990s drew to a close, so did the dynasty of low cost, high volume computer retailers. If you owned one of Initech’s PCs back then, Leif is truly sorry-- but he had no control over QC. Although he was powerless to effect change at Initech, his time there was an eye-opening lesson. Ever since, he’s dedicated his own career to ensuring that every job he does, regardless of the size, will always be of the upmost quality.

SOUND: OUTRO MUSIC

NARRATOR
For The Daily WTF, this was "Quantity of Service". In order of appearance, "Remy Porter" was Leif, "Mark Bowytz" was Daryl, "Lorne Kates" was Mr. Berry, Mr. Wedgewood, Nervous Technician, and Mr. Stratton-- and "Alex Papadimoulis" was Kevin. I’m your announcer Paul Rousse of "Voice By Paul dot com". Theme song was "Slow Burn", and on-hold music was "Mining by Moonlinght", both by Kevin MacLeod of incompetech dot com.

This has been a W.T.F. Radio presentation. After Credit Sting

(END CREDIT MUSIC FADES AWAY. ON HOLD MUSIC FADES BACK IN AND PLAYS FOR A COUPLE SECONDS. WE ADDRESS A PLOT HOLE)

WEDGEWOOD
.... uh, I hope they take me off hold eventually.

(MUSIC FADES AWAY. FIN.)


[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/radio-wtf-presents-quantity-of-service


Метки:  

The Upgrade

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

James stood on the precipice of a significant upgrade to his companys reporting capabilities. Purchasing had cut a deal with the vendor "UberWarehouse to upgrade their warehouse inventory tracking system from a basic .NET application with limited functionality to a full-blown data warehousing system. He jokingly called it the Warehousing the Warehouse Project. He was the only one who found it funny.

"UberWarehouse wasnt about to give that upgrade away for free, though. They sent James an invoice that could have easily filled his Yoda piggy bank with all the change from the nickel-and-diming contained within. The total of the invoice was significantly over the budget of the project, and that was a problem. Of particular interest was something "UberWarehouse called Memory Database. The line item listed it as a required component, and it came with a price tag of $5,500USD.

James wanted answers from ^UberWarehouse in person, with hopes that he could negotiate the price down to something more palatable. They agreed to send Spencer, their head architect and chief excitement-generator to give James a demo that would knock his socks off.

Hey there, James! Glad to be here! Spencer said. He shook James hand with the kind of enthusiasm that lead to muscle strains. So, you are interested in upgrading your "UberWarehouse solution.

Thats right, James said. Were intrigued by your new web component; allowing 20 simultaneous users to run reports against our inventory data is a big win. The thing Im not so sure about is the price. Our current solution works well enough, and its a fraction of the cost. This upgrade easily exceeds our budget. Our total budget is only $6,000, and your memory database alone costs $5,500! Could you explain that to me?

Oh, sure! Spencer brushed past Jamess uncertainty and whipped out a glossy folder stuffed with marketing materials. I get this question all the time. My answer is: you get what you pay for, dont you James? You care about your company, dont you? Once you implement our upgraded solution, youll forget all about the price. Its that good!

Uh huh… James pushed the folder back. Could you tell me what this memory database thing actually is? Do we really need it?

Do you need it? Do you need it? Spencer chuckled. James, my friend, thats the most important part! Would you rather have a report take 10 minutes to run, or one minute?! Our brilliant Memory Database design gets you the data you want 10 times faster than it does without!

That sounds good, I guess… James mentally noted that waiting even one minute for a report was long. How does it actually work, though? Why is there such a big time difference?

Spencer frowned condescendingly, nodded, and smiled in one smooth movement. Lets just say in a couple of years from now, you have a lot of inventory updates. You want a lot of inventory updates, am I right? Good for business! So lets say you have a BAJILLION records. That would be difficult to search, right? So what we do, and this is clever, we copy that important data to its own table, then we add this thing called an index, which gives everything a unique identifier, and voil`a! Memory Database!

James held a blank stare for a long moment before snapping out of the marketing-induced haze and back to the discussion. Interesting… but if we have up to 20 users accessing this database at a time, arent we going to be stepping on each others data toes?

Of course not! Spencer scoffed. That comes down to communication, and everyone loves effective communication, right? If you want to run a long report, just let all the other users know youre taking control of the Memory Database and there wont be any issues! We even have a button in the user-interface to let people know.

Ok… so you said you have a demo loaded with our data, right? Let me try for myself. James connected and fired up a report with a broad date range that would return roughly 750,000 rows. He sat with Spencer, in absolute silence. 5 minutes and 57 seconds later, he had his report.

Now, this is just a demo computer! Spencer reassured him. Surely your beefy hardware will make it lightning fast!

While Spencer got defensive, James logged into the back-end database. Or, we could just do this, he said. He quickly added a secondary index to the vaunted Memory Database, then ran the same report a second time. It returned in 3 seconds flat.

Wow! Spencer shouted in amazement. You should come work for us!

Sure, James said. Ill start working for you right after we finish deploying this upgrade to our environment.

Well, I cant actually hire you… but when do you think youd be finished deploying the upgrade? James could see visions of commission dancing in his eyes.

Never. Were not buying this. Thank you for your time, Spencer.

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


Метки:  

Announcements: Another Tokyo Meet-up: Sakura Edition

Вторник, 31 Марта 2015 г. 06:00 + в цитатник

I'll be in Japan once again, and figured it'd be the perfect opportunity to celebrate Hanami with Tokyo-area TDWTF readers:

Hanami (

http://thedailywtf.com/articles/another-tokyo-meet-up-sakura-edition


Метки:  

Announcements: Would You Like to Take a Survey?

Понедельник, 30 Марта 2015 г. 17:00 + в цитатник

Our sponsor, Puppet Labs, wants to know what your DevOps needs look like. Take their survey, and be entered to win some valuable prizes.

[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/would-you-like-to-take-a-survey-


Метки:  

CodeSOD: Rube Goldberg's Password Generator

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

One of the well-known rules of life is that the most straightforward solution is usually the best solution. Obviously it's not always possible to "keep it simple, stupid," but one should aim to make their creations as self-explanatory and to-the-point as possible- otherwise it's easy to end up with a nightmare in terms of both maintainability and performance.

Photo of the Week- More than One Way to Hammer a Nail (8722944827)

Some people, however, have chosen to defy that rule. One of them was Rube Goldberg. This engineer turned cartoonist became famous for inventing ridiculously complex contraptions to achieve the simplest tasks. And while Mr. Goldberg passed away in 1970, the concept of a "Rube Goldberg machine" outlived him, showing up in hundreds of cartoons, events, and comedy movies.

And, as Matt R. learned, it also made its way into his codebase. While refactoring and rewriting a 32,000-line long file, he came across this incredible machine:

private string GeneratePassword()
{
    string guid = Guid.NewGuid().ToString().ToUpper();
    while (guid.Contains("-"))
    guid = guid.Remove(guid.IndexOf("-"), 1);
    string guidInt = "";
    int i = 0;
    char c;
    while (i < guid.Length)
    {
        c = guid[i];
        if ((c < '0') || (c > '9'))
        {
            ++i;
            continue;
        }
        guidInt += c.ToString();
        ++i;
    }

    int seed = 0;
    if (guidInt != "")
    {
        try
        {
            guidInt = guidInt.PadRight(9, '0').Substring(0, 9);
            seed = System.Convert.ToInt32(guidInt);
        }
        catch
        {
        }
    }
    Random random = new Random(seed);
    string pwd = "";
    while (pwd.Length <= 8)
    {
        c = (char)random.Next(48, 123);
        if ((c < 48) || ((c > 57) && (c < 65)) || ((c > 90) && (c < 97)) || (c > 122))
            continue;
        pwd += c.ToString();
    }

    // 05.08.2014 sometimes the PW has no number in it and that is required, so add it here if needed
    i = 0 ;
    bool bNumberFound = false;
    while( i < pwd.Length )
    {
        char x = System.Convert.ToChar(pwd.Substring(i,1));
        if (Char.IsNumber(x))
        {
            bNumberFound = true;
            break ;
        }
        i++;
    }
    if (!bNumberFound) { pwd = pwd + "1"; } 

    return pwd;

}

Tracing the code, we see that first it generates a GUID and turns it into uppercase. In any normal code, this would merely be a warning sign. GUIDs aren't a good source of randomness, and as such don't belong anywhere near a function for generating random passwords. In this code, however, it's more of a sinister omen of things to come...

In the next step, all dashes are removed from the GUID. Of course, using String.Replace would be a simple solution, so instead, the programmer opted for another one: the while loop looks for a single dash, then if one is found, the string is searched again to determine where that dash is, and finally it's removed from the string, shifting all the following characters to the left. It's a good thing GUIDs are relatively short.

After that, the real fun begins. The GUID is used to seed a random number generator (since seeding with current time is, again, a simple solution). How does one do that? Well, of course, by extracting every numeric character from the GUID, collectng them into a string, padding the string with zeroes, trimming it to nine digits, converting the string to an integer, and finally using that to seed the generator. Whew! Oh, and if the conversion fails for some reason, or if the GUID contains no digits, you get a seed of 0.

After all that, finally a 9-character password is generated. Occasionally, however, it will fail to contain any numbers, so the code just checks whether that's the case, and slaps a "1" at the end if so- rendering the attempt of increasing password entropy entirely pointless.

With all the effort put into the solution, it's hard to know whether to be amused or terrified. Personally, I think this code warrants at least a commemorative real-life Rube Goldberg machine- preferably ending with an anvil hanging above the developer's cubicle.

[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/rube-goldberg-s-password-generator


Метки:  

Error'd: We'll Take All the Help We Can Get

Пятница, 27 Марта 2015 г. 07:30 + в цитатник

"I was casually browsing Bingo games and this one asked me to finish developing their site for them," writes Steven W.

Mike Rippon wrote, "As much as I want to use Google Earth, I'm not sure that I want to install what it's asking."

"I was searching for a camera lens and, well, I found one with some interesting features...including a slight vinegar scent," writes Joshua Armstrong.

"Apparently, availability is merely an illusion," writes Alex H.

Aaron wrote, "A car that produces a gallon of gas for every 25 miles it travels?! Wow!"

"I was short one string of rope lights that I had bought last year, so I turned to Google for help in finding a matching set," Dean C. writes, "I'm not sure if the diapers will fit my snowman as well as the lights would, but hey, what the heck!"

Dan S. wrote, "Thanks {3}, I'll get my {4} all over this {5} right away!"

Traver writes, "My user name had to be seven, too, and when I did enter a seven-digit password I got a "Not a password field" dialog, just to rub it in."

[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/we-ll-take-all-the-help-we-can-get


Метки:  

A Petite Change Request

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

Robert ran a web service used to store legal file data for a number of clients. One day, he received an email from his biggest client, Exc'edent, asking to meet about a new requirement.

"We've purchased new accounting software that requires us to track an additional piece of data," Philippe, Robert's contact from Exc'edent, explained over the conference call a few days later. "Each of our cases must now have a ‘cost center' associated with it. There are a lot of these cost centers, so when our employees enter case data, we'd like for them to be able to pick the one they need from a list."

Robert frowned in thought. "Well, you guys already use every available field in my database. This would require me to add a new field to the database and web forms." A database change on a web service used by many clients wasn't horrible, but not exactly a prospect Robert relished either.

"Is that a problem?" Philippe asked. "We're getting a lot of pressure from above on this. We really need it as soon as possible."

Robert couldn't refuse his largest client. Besides, it was one measly field. "No, it should be OK. I'll figure out the nitty-gritty details myself. In the meantime, can you put your cost centers in a spreadsheet and send them to me? I'll import them into the database when I'm ready."

"Sure!" Philippe said.

It didn't take Robert long to create the new cost center table (VARCHAR(100) seemed safe), link it to the case data tables, and update his web forms with a new dropdown field. However, the spreadsheet from Philippe took longer. Much longer.

Where the heck is this thing? Robert wondered. Wasn't this supposed to be "urgent?"

Over the following several weeks, Robert sent a few gentle prodding emails. Finally, Philippe responded. Sorry for the delay! I was cleaning up the data. The list is about half as long as it used to be. Thanks!

Robert smiled. That was nice of him, whittling down the list to, what a couple hundred or so? Time to import them and test everything out…

He opened up the spreadsheet- and froze in horror.

Spreadsheet screenshot

Robert realized he'd made one of those terrible assumptions we all make from time to time: believing a client's simple request was just as simple as it sounded. There were nearly 1800 "Cost centers" in Philippe's spreadsheet, each one with 17 fields (four of which aren't visible in the screenshot).

Exc'edent employed 3600 people. Philippe claimed to have whittled the list down by half- meaning that before he'd scrubbed the data, there'd been nearly one cost center per employee.

Robert scrolled up and down the spreadsheet in mute horror for several minutes before grabbing the phone and ringing Philippe's desk. "This is kind of a lot of data to put into a dropdown," he explained, heart pounding. "Is there any way to simplify this further?"

"No, sorry," Philippe said. "That's the best I could do."

Who's going to scroll through 1800 cost centers every time they log a case? Robert wondered. Panic transitioned to desperation. "I think we need another call."

A week later, Robert met with the client to explain that the "cost center" ""field"" was simply too complex for him to accommodate. They decided not to import the list after all, and to have employees manually enter cost centers into a text field (ex. "345 Water Distribution"). Not optimal, but it worked.

To Robert's complete lack of surprise, a quick browse of those values manually entered over time showed that only a tiny handful of the 1800 cost centers had ever been used.

[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-petite-change-request


Метки:  

CodeSOD: Are You Down With PHP?

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

Whos Down With PHP?

PHP often gets a bad rap. A lot of the time, thats because its used by developers that dont know what theyre doing, just like theres nothing inherently wrong with spandex, but there are times, places and people where it is inappropriate. And dont get me wrong, the language has made big strides in recent years (good luck finding a web server hosting one of those versions, though). But there are just uses of PHP that reinforce that reputation. Robert Osswald provides this example from the contact-form editing code of a domain registrar database.

Lets say you have some JSON data from an AJAX request, and it looks like this:

	array(13) {
		["controller"]=>
		string(7) "account"
		["action"]=>
		string(10) "changedata"
		["module"]=>
		string(7) "default"
		["data"]=>
		string(314) "[{"name":"adAddress","value":"Address 123"},{"name":"adCity","value":"MyCity"},{"name":"adZip","value":"12345"},{"name":"adState","value":"RS"},{"name":"adTelephone","value":"0112323555"},{"name":"adJMBG","value":"1706987782831"},{"name":"check[]","value":"domain_adminperson"},{"name":"cp_osobaid","value":"156"}]"
		["ajax"]=>
		string(15) "json_serialized"
		["adAddress"]=>
		string(11) "Address 123"
		["adCity"]=>
		string(6) "MyCity"
		["adZip"]=>
		string(5) "12345"
		["adState"]=>
		string(2) "RS"
		["adTelephone"]=>
		string(10) "0112323555"
		["adJMBG"]=>
		string(13) "1706987782831"
		["check"]=>
		array(1) {
			[0]=>
			string(18) "domain_adminperson"
		}
		["cp_osobaid"]=>
		string(3) "156"
	}

You want to turn the fields in that check[] array into an object, like this:

	object(stdClass)#208 (1) {
		["AdministrativniKontakt"]=>
	 object(stdClass)#207 (6) {
	 	["Adresa"]=>
	 	string(11) "Address 123"
	 	["Grad"]=>
	 	string(6) "MyCity"
	 	["PostanskiBroj"]=>
	 	string(5) "12345"
	 	["Drzava"]=>
	 	string(2) "RS"
	 	["Tel"]=>
	 	string(10) "0112323555"
	 	["MaticniBroj"]=>
	 	string(13) "1706987782831"
	 }
	}

To map one to the other, you also have an .ini file like this:

	form.domain_adminperson.prefix = ad
	form.domain_adminperson.object = AdministrativniKontakt
	form.domain_adminperson.field.adName = Ime
	form.domain_adminperson.field.adLastname = Prezime
	form.domain_adminperson.field.adEmail = Email
	form.domain_adminperson.field.adAddress = Adresa
	form.domain_adminperson.field.adCity = Grad
	form.domain_adminperson.field.adState = Drzava
	form.domain_adminperson.field.adTelephone = Tel
	form.domain_adminperson.field.adJMBG = MaticniBroj
	form.domain_adminperson.field.adZip = PostanskiBroj

Once youve mapped the request array to the defined object, you want to persist it and return the object in the JSON response. Would you do it& like this?

	class RequestToRegObjectMapper
	{
		public static function parseRequestToObj($request, $saveInSession = false)
		{
			$iniFile = new Zend_Config_Ini(APP_FS_ROOT.'/lib/spec/formtoservice.ini','default', true);

			if($saveInSession == true){
				$sessionHandler = new Zend_Session_Namespace('domainreg'); 
			}

			$response = new stdClass();

			foreach($request['check'] as $elem){

				$elemIniData = $iniFile->form->{$elem};
				$elemObjectName = $elemIniData->object;
				$response->{$elemObjectName} = new stdClass();
				$response->{$elemObjectName} = $sessionHandler->{$elemObjectName};

				foreach($request as $k=>$v){
					$key = isset($elemIniData->field->{$k}) ? $elemIniData->field->{$k} : null;
					if(!is_null($key) && !empty($v)){
						$response->{$elemObjectName}->{$key} = $v;
					}
				}

				if($saveInSession == true){
					if(!isset($sessionHandler->{$elemObjectName}))
						$sessionHandler->{$elemObjectName} = $response->{$elemObjectName};
					else{
						foreach (get_object_vars($response->{$elemObjectName}) as $key => $value) {
							$sessionHandler->{$elemObjectName}->{$key} = $value;
						}
					}
				}  
			}

			return $response;
		}
	}

	public function changedataAction(){

		$this->_helper->layout->disableLayout();
		$this->_helper->viewRenderer->setNoRender(true); 
		$request = RequestToRegObjectMapper::parseRequestToObj($this->REQPARAMS, false);

		if(in_array("domain_dns", $this->REQPARAMS["check"])){

			$requestParams = new stdClass();
			$requestParams->IdDomena = $this->REQPARAMS["cp_domenid"];
			if (!empty($request->DNS->Nazivservera1)) {
				$requestParams->NazivServera1 = $request->DNS->Nazivservera1;
			}
			if (!empty($request->DNS->Ipadresa1)) {
				$requestParams->IPAdresa1 = $request->DNS->Ipadresa1;
			}
			if (!empty($request->DNS->Nazivservera2)) {
				$requestParams->NazivServera2 = $request->DNS->Nazivservera2;
			}
			if (!empty($request->DNS->Ipadresa2)) {
				$requestParams->IPAdresa2 = $request->DNS->Ipadresa2;
			}

			$response = $this->serviceClient->call('izmeniDNSServereZaDomen', $requestParams);
			echo json_encode($response);
			die();
		}

		if(in_array("domain_regperson", $this->REQPARAMS["check"])){

			$requestParams = new stdClass();
			$requestParams = $request->Registrant;
			$requestParams->Id = $this->REQPARAMS["Id"];

			$response = $this->serviceClient->call('izmeniRegistranta', $requestParams);
			if($response->status == 0){
				$this->redirectToActionController('index', 'account');
			}
		}

		if(in_array("domain_adminperson", $this->REQPARAMS["check"]) || in_array("domain_payperson", $this->REQPARAMS["check"])){
			$requestParams = new stdClass();
			if(in_array("domain_adminperson", $this->REQPARAMS["check"]))
				$requestParams = $request->AdministrativniKontakt;
			else if(in_array("domain_payperson", $this->REQPARAMS["check"]))
				$requestParams = $request->KontaktZaPlacanje;
			$requestParams->Id = $this->REQPARAMS["cp_osobaid"];

			$response = $this->serviceClient->call('izmeniOsobu', $requestParams);
			echo json_encode($response);
			die();
		}
	}

There are lots of reasons to use PHP on your next project! Alas, brevity and readability arent two of them.

[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/are-you-down-with-php-


Метки:  

The A(nti)-Team

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

In the 1980s, there was a TV show called The A-Team. There was the scrounger, who could scam anyone out of anything. He would make promises that were sort of true to get what he wanted (sound like marketing?) There was the tough guy who could intimidate anyone into doing anything. He knew how to get things done, but underneath it all, was a nice guy. There was the leader, who could always come up with a plan to save the day. And there was the one guy who was a little crazy (the good kind of crazy), but who you could count on in a pinch. There was also the occasional outside helper who would run interference and recon. This was a group of folks who worked as a well-oiled machine to get the job done. Failure was not an option! They were a team!

The A-Team never filed a project methodology document. No wonder they were wanted criminals.

Alex had taken a job on a new greenfield development effort to replace an aging and unsupportable birds-nest-o-wtf™. Naturally, the position was advertised as we intend to do things right! The project is fully funded. We will have the proper equipment and team personnel to get this job done. We have the full support of six layers of management plus all of the users. Alex was optimistic.

The first thing they did was spend several months wrapped in those numerous layers of management, end users, support folks, senior people who used to support the project (to explain the problems that plagued the old system), and the three architects of the new system. The new architecture was heavily documented, presented to and signed off on by all of the above. It was even reviewed with a critical eye by an independent third party regulatory auditing agency to ensure that the overseeing authorities were confident that the correct approach was being taken.

An 8 page document detailing development coding guidelines (e.g.: code formatting settings, naming conventions, unit tests, code coverage and other such team-wide items) was created, reviewed and decreed to be followed by all who worked on the project.

The project was off to a good start.

Job one was to hire the development part of the team. For this, they looked (very far) offshore to find the cheapest possible talent. After all, anyone can be trained, right? A team of 11 developers who collectively had 13 years of experience, and a team leader with 5 years of experience were hired and put in place.

The next major decision was which database should be used. There were three in widespread use at the company. Since all of the databases were hosted on centralized servers, one was immediately ruled out because the hardware that hosted the data servers was insufficiently powerful to handle the expected load in a reasonable time frame. Of the other two, one was widely used by everyone on the team. They knew its syntax, quirks and limits. The the third was mis-configured to have a reputation as being flaky. However, that one also was the corporate standard. In spite of the objections of the team, they used the third one.

Project management decided that QA folks could be brought in later.

Finally, it was time to begin doing detailed design. The offshore lead decided that a lot of time could be saved by doing design on-the-fly as required. Of course, the architects objected, but the project manager agreed to it.

And so the architects started working on building the controller engine and other such mainstays of the project. The junior team, which was to query numerous remote systems for input data, merge, filter and pre-process it, decided that they knew better than what was specified in the architecture document, and started designing their own way of doing things. Without telling the architects or management.

Come time for the first sprint check-in and all sorts of red flags flew up during code reviews. The junior lead decreed that the architecture document was only a suggestion that could be ignored in favor of the developers desires. Naturally, this spawned lots of are-you-fg-kidding-mes and emails up the chain. The project manager and above seemed disinterested, saying that the junior developers shouldnt be doing that, but we trust them to do the right thing.

This went on, with the architects pointing out implementation flaws and shortcomings that would not support the requirements. All suggestions were ignored, because the offshore lead said Google fosters an environment of innovation and creativity; we should too! He was reminded that Google is (in large part) a think-tank, and that this was a highly regulated project within a highly regulated industry. The architecture, which had been signed off by more than 40 managers, was not optional or a suggestion, but mandatory. This was not kindergarten, where creativity is fostered; you had to stick to the approved plan! Now, were not talking about how to write a subroutine, or encapsulate an object; were talking about using threading incorrectly and in the wrong places, doing database accesses and interprocess communication in such ways that would not be scalable, or provide enough throughput to finish daily runs by regulatory deadlines. Spawning multiple processes instead of just using threads. Using files to act as semaphores, because thats how they did it in school. The list goes on.

None of that mattered. The junior developers resented that they were not consulted on the architecture, and so were bent on ignoring it - with the blessing of their lead. The project manager continued to acknowledge the problems, but didnt do anything about them. The problems were reported up the chain, and nothing was done. Everyone on the team should have an equal say in things.

In the real world, if a student thinks the teacher is wrong, he doesnt get to change his grade. The surgical resident cuts where the surgeon says and not the other way around. The general doesnt discuss strategy with the privates. If you join a union, and as the new guy demand to have equal say on policy with the union bosses, youll be bunking with Jimmy Hoffa. Experience speaks with exclamation points. Inexperience speaks with question marks.

Except on this team.

The junior developers continued to do what they thought was best, ignoring the architects at every turn. Much of their code was written and rewritten several times over because the designs by the juniors didnt take things into account. Things more experienced folks know to plan for. By the time 8 months had passed, so much damage had been done that some of the more complex requirements simply couldnt be hooked in, and more than a month of back-pedaling had to be done on a greenfield development project.

About this time, management acquiesced and asked some of the business users to write business-level tests (e.g.: via a spreadsheet that would be fed into JBehave to JUnit test things). The developers would provide the underlying code and some sample entries in the spreadsheets. The architects said that QA folks should be hired because business folks rarely know how to deal with edge cases, precision issues, etc. But the money was not to be spent. After six months of effort, the business users proudly decreed that all the tests for the entire application (e.g.: the entire requirements document) had been set up. A five minute glance showed that they didnt handle edge cases, null cases, precision cases, or most of the other things that usually require tests. In fact, they had put all of the records that could possibly be processed (at least in their minds) into one giant pass-fail test. Of course, when something changed and it inevitably failed, there was no way to know what failed.

Finally, it got so bad that the architects built a physical wall in the code between the setup code (written by the offshore folks) and main engine (written by the architects) sections of the application. Immediately before the main engine began to grind the data, every single variable in the system would be flushed to a state table in the database, so that when something would inevitably be challenged, they could show the inputs that were provided and send the fix-it work to the offshore team. At least this way, they could insulate the main engine from the debris.

The department saved a lot of money by using cheap labor, no QA folks and the politically expedient database. Of course, all of the code of the setup portion done by the offshore team was a disaster, and for the most part, very difficult to learn, support, debug and enhance.

The product hadnt even been deployed yet, and the users were already complaining that it took too long to diagnose and fix problems (one of the main reasons the whole rewrite project was authorized), that perhaps the rewrite wasnt satisfying the main purpose of the rewrite, and that perhaps something might be wrong&

[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-a-nti-team


Метки:  

CodeSOD: Regularly Expressing Hate

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

Perl is jokingly referred to as a write-only language. This is because Perls primary solution to any problem is to throw a regular expression at it. Regexes are powerful, but cryptic.

Metamucil

Imagine RJs joy at starting a new contract for an OCR/document-management system that makes heavy use of regexes. Even better, the system doesnt use widely implemented Perl-compatible regular expressions syntax, but instead, uses its own, slightly tweaked version.

So, for example, when the system needs to pick the document ID out of the scanned document, it uses this regex:

([:-.,;/\\(]{0,2}(( [C|c][P|p][K,<|k,<][0-9]{11} )||([:#.$",'#-/|][C|c][P|p][K,<|k,<][0-9]{11} )||( [C|c][P|p][K,<|k,<][0-9]{11}[:.$",'#-/|l\\])||([:.$",'#-/|][C|c][P|p][K,<|k,<][0-9]{11}[:.$",'#-/|l\\])||( 01[A|a|C|c|D|d|E|e|R|r][0-9]{7} )||([:#.$",'#-/|]01[A|a|C|c|D|d|E|e|R|r][0-9]{7} )||(01[A|a|C|c|D|d|E|e|R|r][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]01[A|a|C|c|D|d|E|e|R|r][0-9]{7}[:#.$",'#-/|l\\])||( 02[A|a|B|b|C|c|D|d|E|e|F|f][0-9]{7} )||([:#.$",'#-/|]02[A|a|B|b|C|c|D|d|E|e|F|f][0-9]{7} )||( 02[A|a|B|b|C|c|D|d|E|e|F|f][0-9]{7}[:#.$",'#-/|l\\])||([:#-/|]02[A|a|B|b|C|c|D|d|E|e|F|f][0-9]{7}[:#.$",'#-/|l\\])||( 04[C|c|D|d|F|f|V|v][0-9]{7} )||([:#.$",'#-/|]04[C|c|D|d|F|f|V|v][0-9]{7} )||( 04[C|c|D|d|F|f|V|v][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]04[C|c|D|d|F|f|V|v][0-9]{7}[:#.$",'#-/|l\\])||( 05[M|m|A|a][0-9]{7} )||([:#.$",'#-/|]05[M|m|A|a][0-9]{7} )||( 05[M|m|A|a][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]05[M|m|A|a][0-9]{7}[:#.$",'#-/|l\\])||( 06[B|b|C|c|G|g|H|h|J|j|K|k|L|l|M|m|S|s|U|u|Y|y][0-9]{7} )||([:#.$",'#-/|]06[B|b|C|c|G|g|H|h|J|j|K|k|L|l|M|m|S|s|U|u|Y|y][0-9]{7} )||( 06[B|b|C|c|G|g|H|h|J|j|K|k|L|l|M|m|S|s|U|u|Y|y][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]06[B|b|C|c|G|g|H|h|J|j|K|k|L|l|M|m|S|s|U|u|Y|y][0-9]{7}[:#.$",'#-/|l\\])||( 07[U|u][0-9]{7} )||([:#.$",'#-/|]07[U|u][0-9]{7} )||( 07[U|u][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]07[U|u][0-9]{7}[:#.$",'#-/|l\\])||( 08[A|a][0-9]{7} )||([:#.$",'#-/|]08[A|a][0-9]{7} )||( 08[A|a][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]08[A|a][0-9]{7}[:#.$",'#-/|l\\])||( 09[A|a|B|b|C|c|D|d|F|f][0-9]{7} )||([:#.$",'#-/|]09[A|a|B|b|C|c|D|d|F|f][0-9]{7} )||( 09[A|a|B|b|C|c|D|d|F|f][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]09[A|a|B|b|C|c|D|d|F|f][0-9]{7}[:#.$",'#-/|l\\])||( 10[M|m|F|f][0-9]{7} )||([:#.$",'#-/|]10[M|m|F|f][0-9]{7} )||( 10[M|m|F|f][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]10[M|m|F|f][0-9]{7}[:#.$",'#-/|l\\])||( 13[A|a][0-9]{7} )||([:#.$",'#-/|]13[A|a][0-9]{7} )||( 13[A|a][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]13[A|a][0-9]{7}[:#.$",'#-/|l\\])||( 14[A|a][0-9]{7} )||([:#.$",'#-/|]14[A|a][0-9]{7} )||( 14[A|a][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]14[A|a][0-9]{7})||( 15[D|d|E|e|R|r|T|t][0-9]{7} )||([:#.$",'#-/|]15[D|d|E|e|R|r|T|t][0-9]{7} )||( 15[D|d|E|e|R|r|T|t][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]15[D|d|E|e|R|r|T|t][0-9]{7}[:#.$",'#-/|l\\])||( 17[A|a|E|e|L|l|M|m|P|p|S|s|U|u|W|w][0-9]{7} )||([:#.$",'#-/|]17[A|a|E|e|L|l|M|m|P|p|S|s|U|u|W|w][0-9]{7} )||( 17[A|a|E|e|L|l|M|m|P|p|S|s|U|u|W|w][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]17[A|a|E|e|L|l|M|m|P|p|S|s|U|u|W|w][0-9]{7}[:#.$",'#-/|l\\])||( 18[A|a][0-9]{7} )||([:#.$",'#-/|]18[A|a][0-9]{7} )||( 18[A|a][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]18[A|a][0-9]{7}[:#.$",'#-/|l\\])||( 21[A|a|C|c|D|d][0-9]{7} )||([:#.$",'#-/|]21[A|a|C|c|D|d][0-9]{7} )||( 21[A|a|C|c|D|d][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]21[A|a|C|c|D|d][0-9]{7}[:#.$",'#-/|l\\])||( 23[A|a|B|b|C|c|D|d|L|l|M|m][0-9]{7} )||([:#.$",'#-/|]23[A|a|B|b|C|c|D|d|L|l|M|m][0-9]{7} )||(23[A|a|B|b|C|c|D|d|L|l|M|m][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]23[A|a|B|b|C|c|D|d|L|l|M|m][0-9]{7}[:#.$",'#-/|l\\])
||( 24[A|a|B|b|C|c|F|f|K|k|M|m|T|t][0-9]{7} )||([:#.$",'#-/|]24[A|a|B|b|C|c|F|f|K|k|M|m|T|t][0-9]{7} )||( 24[A|a|B|b|C|c|F|f|K|k|M|m|T|t][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]24[A|a|B|b|C|c|F|f|K|k|M|m|T|t][0-9]{7}[:#.$",'#-/|l\\])
||( 25[A|a][0-9]{7} )||([:#.$",'#-/|]25[A|a][0-9]{7} )||( 25[A|a][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]25[A|a][0-9]{7}[:#.$",'#-/|l\\])||( 32[A|a|F|f|H|h|X|x|Y|y|Z|z][0-9]{7} )||([:#.$",'#-/|]32[A|a|F|f|H|h|X|x|Y|y|Z|z][0-9]{7} )||( 32[A|a|F|f|H|h|X|x|Y|y|Z|z][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]32[A|a|F|f|H|h|X|x|Y|y|Z|z][0-9]{7}[:#.$",'#-/|l\\])||( 34[A|a][0-9]{7} )||([:#.$",'#-/|]34[A|a][0-9]{7} )||( 34[A|a][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]34[A|a][0-9]{7}[:#.$",'#-/|l\\])
||( 35[A|a|B|R|r|S|s|T|t|U|u][0-9]{7} )||([:#.$",'#-/|]35[A|a|B|R|r|S|s|T|t|U|u][0-9]{7} )||( 35[A|a|B|R|r|S|s|T|t|U|u][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]35[A|a|B|R|r|S|s|T|t|U|u][0-9]{7}[:#.$",'#-/|l\\])||( 39[C|c|P|p][0-9]{7} )||([:#.$",'#-/|]39[C|c|P|p][0-9]{7} )||( 39[C|c|P|p][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]39[C|c|P|p][0-9]{7}[:#.$",'#-/|l\\])||( 40[A|a|C|c|D|d|S|s][0-9]{7} )||([:#.$",'#-/|]40[A|a|C|c|D|d|S|s][0-9]{7} )||( 40[A|a|C|c|D|d|S|s][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]40[A|a|C|c|D|d|S|s][0-9]{7}[:#.$",'#-/|l\\])||( 46[A|a|B|b][0-9]{7} )||([:#.$",'#-/|]46[A|a|B|b][0-9]{7} )||( 46[A|a|B|b][0-9]{7}[:#.$",'#-/|l\\])||([:#.$",'#-/|]46[A|a|B|b][0-9]{7}[:#.$",'#-/|l\\])
||( 01[A|a|C|c|D|d|E|e|R|r][0-9]{9} )||([:#.$",'#-/|]01[A|a|C|c|D|d|E|e|R|r][0-9]{9} )||(01[A|a|C|c|D|d|E|e|R|r][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]01[A|a|C|c|D|d|E|e|R|r][0-9]{9}[:#.$",'#-/|l\\])||( 02[A|a|B|b|C|c|D|d|E|e|F|f][0-9]{9} )
||([:#.$",'#-/|]02[A|a|B|b|C|c|D|d|E|e|F|f][0-9]{9} )||( 02[A|a|B|b|C|c|D|d|E|e|F|f][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]02[A|a|B|b|C|c|D|d|E|e|F|f][0-9]{9}[:#.$",'#-/|l\\])
||( 04[C|c|D|d|F|f|V|v][0-9]{9} )||([:#.$",'#-/|]04[C|c|D|d|F|f|V|v][0-9]{9} )||( 04[C|c|D|d|F|f|V|v][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]04[C|c|D|d|F|f|V|v][0-9]{9}[:#.$",'#-/|l\\])||( 05[M|m|A|a][0-9]{9} )||([:#.$",'#-/|]05[M|m|A|a][0-9]{9} )||( 05[M|m|A|a][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]05[M|m|A|a][0-9]{9}[:#.$",'#-/|l\\])||( 06[B|b|C|c|G|g|H|h|J|j|K|k|L|l|M|m|S|s|U|u|Y|y][0-9]{9} )||([:#.$",'#-/|]06[B|b|C|c|G|g|H|h|J|j|K|k|L|l|M|m|S|s|U|u|Y|y][0-9]{9} )||( 06[B|b|C|c|G|g|H|h|J|j|K|k|L|l|M|m|S|s|U|u|Y|y][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]06[B|b|C|c|G|g|H|h|J|j|K|k|L|l|M|m|S|s|U|u|Y|y][0-9]{9}[:#.$",'#-/|l\\])||( 07[U|u][0-9]{9} )||([:#.$",'#-/|]07[U|u][0-9]{9} )||( 07[U|u][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]07[U|u][0-9]{9}[:#.$",'#-/|l\\])||( 08[A|a][0-9]{9} )||([:#.$",'#-/|]08[A|a][0-9]{9} )||( 08[A|a][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]08[A|a][0-9]{9}[:#.$",'#-/|l\\])||( 09[A|a|B|b|C|c|D|d|F|f][0-9]{9} )||      ([:#.$",'#-/|]09[A|a|B|b|C|c|D|d|F|f][0-9]{9} )||( 09[A|a|B|b|C|c|D|d|F|f][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]09[A|a|B|b|C|c|D|d|F|f][0-9]{9}[:#.$",'#-/|l\\])||( 10[M|m|F|f][0-9]{9} )||([:#.$",'#-/|]10[M|m|F|f][0-9]{9} )||( 10[M|m|F|f][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]10[M|m|F|f][0-9]{9}[:#.$",'#-/|l\\])||( 13[A|a][0-9]{9} )||([:#.$",'#-/|]13[A|a][0-9]{9} )||( 13[A|a][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]13[A|a][0-9]{9}[:#.$",'#-/|l\\])||( 14[A|a][0-9]{9} )||
([:#.$",'#-/|]14[A|a][0-9]{9} )||( 14[A|a][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]14[A|a][0-9]{9}[:#.$",'#-/|l\\])|| ( 15[D|d|E|e|R|r|T|t][0-9]{9} )||([:#.$",'#-/|]15[D|d|E|e|R|r|T|t][0-9]{9} )||( 15[D|d|E|e|R|r|T|t][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]15[D|d|E|e|R|r|T|t][0-9]{9}[:#.$",'#-/|l\\])||( 17[A|a|E|e|L|l|M|m|P|p|S|s|U|u|W|w][0-9]{9} )||([:#.$",'#-/|]17[A|a|E|e|L|l|M|m|P|p|S|s|U|u|W|w][0-9]{9} )||( 17[A|a|E|e|L|l|M|m|P|p|S|s|U|u|W|w][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]17[A|a|E|e|L|l|M|m|P|p|S|s|U|u|W|w][0-9]{9}[:#.$",'#-/|l\\])||( 18[A|a][0-9]{9} )||([:#.$",'#-/|]18[A|a][0-9]{9} )||( 18[A|a][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]18[A|a][0-9]{9}[:#.$",'#-/|l\\])
||( 21[A|a|C|c|D|d][0-9]{9} )||([:#.$",'#-/|]21[A|a|C|c|D|d][0-9]{9} )||( 21[A|a|C|c|D|d][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]21[A|a|C|c|D|d][0-9]{9}[:#.$",'#-/|l\\])||( 23[A|a|B|b|C|c|D|d|L|l|M|m][0-9]{9} )||([:#.$",'#-/|]23[A|a|B|b|C|c|D|d|L|l|M|m][0-9]{9} )||( 23[A|a|B|b|C|c|D|d|L|l|M|m][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]23[A|a|B|b|C|c|D|d|L|l|M|m][0-9]{9}[:#.$",'#-/|l\\])||( 24[A|a|B|b|C|c|F|f|K|k|M|m|T|t][0-9]{9} )||([:#.$",'#-/|]24[A|a|B|b|C|c|F|f|K|k|M|m|T|t][0-9]{9} )||( 24[A|a|B|b|C|c|F|f|K|k|M|m|T|t][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]24[A|a|B|b|C|c|F|f|K|k|M|m|T|t][0-9]{9}[:#.$",'#-/|l\\])||( 25[A|a][0-9]{9} )||([:#.$",'#-/|]25[A|a][0-9]{9} )||( 25[A|a][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]25[A|a][0-9]{9}[:#.$",'#-/|l\\])
||( 32[A|a|F|f|H|h|X|x|Y|y|Z|z][0-9]{9} )||([:#.$",'#-/|]32[A|a|F|f|H|h|X|x|Y|y|Z|z][0-9]{9} )||( 32[A|a|F|f|H|h|X|x|Y|y|Z|z][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]32[A|a|F|f|H|h|X|x|Y|y|Z|z][0-9]{9}[:#.$",'#-/|l\\])||( 34[A|a][0-9]{9} )||([:#.$",'#-/|]34[A|a][0-9]{9} )||( 34[A|a][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]34[A|a][0-9]{9}[:#.$",'#-/|l\\])||( 35[A|a|B|b|R|r|S|s|T|t|U|u][0-9]{9} )||([:#.$",'#-/|]35[A|a|B|b|R|r|S|s|T|t|U|u][0-9]{9} )||( 35[A|a|B|b|R|r|S|s|T|t|U|u][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]35[A|a|B|b|R|r|S|s|T|t|U|u][0-9]{9}[:#.$",'#-/|l\\])||( 39[C|c|P|p][0-9]{9} )||([:#.$",'#-/|]39[C|c|P|p][0-9]{9} )||( 39[C|c|P|p][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]39[C|c|P|p][0-9]{9}[:#.$",'#-/|l\\])
||( 40[A|a|C|c|D|d|S|s][0-9]{9} )||([:#.$",'#-/|]40[A|a|C|c|D|d|S|s][0-9]{9} )||( 40[A|a|C|c|D|d|S|s][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]40[A|a|C|c|D|d|S|s][0-9]{9}[:#.$",'#-/|l\\])||( 46[A|a|B|b][0-9]{9} )||([:#.$",'#-/|]46[A|a|B|b][0-9]{9} )||( 46[A|a|B|b][0-9]{9}[:#.$",'#-/|l\\])||([:#.$",'#-/|]46[A|a|B|b][0-9]{9}[:#.$",'#-/|l\\]))[-.,;:Il|/\\]{0,2} )

RJ added, Given the scale of WTF in this place, I was only mildly surprised such an abomination existed. I share it for your amusement. If this is only a mild surprise, RJ, may the gods have mercy on your soul.

http://thedailywtf.com/articles/regularly-expressing-hate


Метки:  

Error'd: Pretty Please?

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

"Hey, may I get your permission...quickly? I'm about to leave for a world tour and I have a LOT of ground to cover," writes John

Tobi wrote, "I was configuring a new password for my new router when this absurd 'your password is too weak' dialog was thrown my way."

"In hindsight, November flew by, but October felt like it was 2 months long," writes Kyle U.

"I went to BMW's website and requested a new password," writes Chris, "and this is what I received."

Aaron wrote, "I'm curious how this 404 error page was found when I got an error page stating the contrary. Maybe there is a try/catch that failed to preserve the stack trace?"

"I browsed on some art site apparently affiliated with some discount program McAfee has, courtesy of SiteAdvisor," Andrew R. writes, "Needless to say, I didn't take up the offer."

The curse says that Lucien C. must keep providing his auction with new souls or it will never end.

Renan B. writes, "An ad for CCleaner? I can't say it looks all that effective..."

[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/pretty-please-


Метки:  

The Record Setting Score

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

A few years ago, Joel Spolsky wrote his simple, 12-point test to measure how good a software team is. Stan was thinking about this test quite a bit, when he started a new job at a company which set a new record for failure.

Stans journey started after an excited recruiter told him, I have a great role for you, working for a cutting edge online retailer in London! Stan became a Senior PHP Developer on a team of three others. Each day there, he asked another question from the Joel Test.

Lets review Stans experience against the 12 questions from the Joel Test.

1. Do You Use Source Control?

Stan asked about source control during the interview, and the interviewer replied, No, we dont have any at the moment. But we will soon! When Stan started, he found that the only copy of the source code was the live website. Any changes meant downloading the site, altering the files, and re-uploading the changes over FTP. He very quickly got used to hearing the question, Is anyone changing users.php?, or Hey, where are all my changes from yesterday?! Having four people work on a live website using only FTP to synchronize work caused friction, like throwing sand in an engine.

Joel Test Question 1: Fail

2. Can You Make a Build in One Step?

Building should be as easy as possible. The best solution is to have a script which can handle the entire build process from start-to-end. Check everything out from source control (if you have one!), compile binaries, and create the installation packages. Without this, building will be error prone.

Without source control, and without any concept of development servers or test servers, builds were deployed via FTP. The team made database schema changes by uploading specific PHP scripts with the required SQL and loading them as a page while praying that nothing breaks. When things did break, it was extremely difficult to debug or rollback the changes. Im not sure build or release are even valid terms for this company, any more than architect describes a kid who lobs globs of mud at a wall.

Joel Test Question 2: Fail

3. Do you make daily builds?

Daily builds make sure your repository trunk is in good working condition. At least once a day, obvious errors like incomplete check-ins or missing dependencies are easily discovered, and discovered early, before any software enters production use. The term daily build implies some sort of integration and testing environment, not ad-hoc FTP uploads to a live site.

Joel Test Question 3: Fail

4. Do you have a bug database?

You need a good way to track defects. Whats the error? Who reported it? How can it be reproduced? Whats the priority? When was it fixed? Of course, tracking bugs is meaningless when one developers FTP upload can overwrite another developers previous efforts, causing the bug fix to be lost for all eternity.

Joel Test Question 4: Fail

5. Do you fix bugs before writing new code?

Stans company fixed bugs all of the time, as any software firm must. However, those bugs regressed all the time too, since one developers fix could easily be rolled back when another developer uploads their version of the PHP file a few hours later. This methodology ends up like this.

Joel Test Question 5: Fail

6. Do you have an up-to-date schedule?

Having a schedule would mean having a list of features, a timeline by which they need to be finished, and priorities to help determine what gets in and what doesnt if the timeline slips. Instead, Stan had a constant stream of emails, memos, and Post-It Notes handed down from management.

Stan might be half-finished with a top priority feature when a different director would storm into his cube. Did you fix my issue yet? Get on it! Now! NOW! Its an EMERGENCY!

Joel Test Question 6: Fail

7. Do you have a spec?

Good software has some kind of list of requirements, or at least a description of what the software should do. For Stan, his spec was determined by which director was currently in his cube, screaming about their personal fire that needed to be extinguished. Its only by the grace of good fortune that his cube was too small for two directors to be badgering him at once- that situation might have come to blows.

Joel Test Question 7: Fail

8. Do programmers have quiet working conditions?

Are you aware of the exciting new opportunities available to you, with our products?

One of the many top priorities for their company was marketing, so they hired a stable of telemarketers. Short on office space, they stuffed them in the only place that was free: next to the development team. Within a few days, the developers wanted to chop off their own ears, just to quit hearing the marketing script on endless repeat.

Are you aware of the exciting new opportunities available to you, with our products?

Some offices invest in cheap white-noise generators to cut down on that sort of cross-talk. Stans wasnt one of those.

Are you aware of the exciting new opportunities available to you, with our products?

In fact, the office had other infrastructure problems. When winter arrived, the buildings heater broke down. Working from home was out of the question- how could directors storm into your cube to clarify priorities? Instead, everyone was forced to work in the sub-zero office.

Are you aware of the exciting new opportunities available to you, with our products?

Developers huddled in their cubicles, wearing coats, hats and gloves. Imagine the quality software written by a team-

Are you aware of the exciting new opportunities available to you, with our products?

-wearing gloves, in the freezing cold, while listening to the steady mumble of marketing copy.

Joel Test Question 8: Fail

9. Do you use the best tools money can buy?

Developers need to have powerful PCs. If you give your development team a stack of Pentium M laptops with single-core CPUs and 512MB of RAM in 2015, theyll spend 90% of their time standing on their rolly office chairs and fencing with makeshift swords, or just watching Chrome cry while rendering web pages.

When Stan first started, he was assigned a nice, shiny MacBookPro, stuffed to the gills with RAM and an SSD. Shortly after he got it set up for development use, the sysadmin informed him that this was a requisition mistake. This machine was actually for one of the new graphic designers. You get this one.

The replacement was a 5 year old machine that was suitable for email, Solitaire, and virtually nothing else.

Joel Test Question 9: Fail

10. Do you have testers?

Stans company almost wins this one on a technicality. While they didnt employ any testers, they had customers. They were abused as testers, since they would naturally call in and complain when ~a software release~ big ball of mud was FTPd to the live server.

A generous grader might be tempted to give partial credit for this, since they at least recognize that testing needs to happen. But lets repeat this: their customers were their dedicated testers on a production website.

Joel Test Question 10: Double Fail

11. Do new candidates write code during their interview?

During Stans interview, he was not asked to write any code. In fact, his interviewer didnt speak English terribly well, so the interview was mostly the two of them smiling and nodding at each other. It probably didnt matter, since most of Stans day wasnt spent writing code- it was spent rewriting the code that got deleted after the last FTP-based screw-up.

Joel Test Question 11: Double Fail

12. Do you do hallway usability testing?

A good way to test is to grab a random person as they walk through the hallway, and force them to use the software you just wrote. They dont work on your team, and may not be familiar with the project or its requirements. Can they use it? Is it intuitive? Does the user interface make sense? This is a great way to discover usability issues that developers easily overlook.

In Stans company, they sort of did the opposite. Random directors would storm into Stans cube, not to try the software, but to dictate a new mandate without any thought to whether or not it made sense.

Joel Test Question 12: Reverse Fail

Total Score: 2.0000000000000000001420001, thanks to two double fails, and the floating point rounding error is caused by the Reverse Fail.


As the new Senior PHP Developer, Stan fought to clean things up somewhat. He got a Subversion server set up on a spare box, and managed to get a development server with a clone of the live system. In a few months, they started working almost like a real software team. Productivity went up, bugs got patched before users saw them, and FTP-induced rework was almost entirely killed.

Sadly, after all these changes, management called in the team and complained that they were all overpaid, lazy, and a drag on the company. Stan quit on the spot, and over the next few days, the rest of his developers followed him. Weeks later, he heard through the grapevine that theyd brought on a new team, and were undoing Stans wasteful changes.

Apparently, the highest priority directive was to ensure their record-setting score on the Joel Test.

[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-record-setting-score


Метки:  

Announcements: The Daily WTF: LIVE!

Среда, 18 Марта 2015 г. 17:00 + в цитатник

Youve read the posts. Youve submitted your own WTFs. Now its time to take it to the next level: The Daily WTF: Live is coming to Pittsburgh, PA.

In the style of The Moth or Risk! podcasts, were getting our fellow IT drones up on stage, to share their tales of their worst WTFs, their successes, and true tales of life in the IT trenches.

The live show is April 10th, 810PM at the Maker Theater in Pittsburgh. Tickets are available now.

Dont worry if you cant make it to Pittsburgh. Well be recording the show, and sharing the best stories here on the site from time to time, in addition to our normal stream of WTFs.

If youre in around around Pittsburgh, and think youve got a killer story and want to get in front of those lights, we still have open slots for storytellers. Send a brief (12 paragraph) pitch for your story to storytelling@jetpackshark.com, and Remy will be in touch to discuss. (Your story doesnt have to be a pure WTF) We'll work with you to build up a great 8-10 minute piece you can perform.

This event is brought to you by our awesome and proud sponsor, Puppet Labs*. As we mentioned in their sponsorship announcement article, thanks to their support, well be able to create some exciting new content, do more meet-ups, and have a lot more fun all-around. This is an example of that and we are still very excited to be working with them! Check out their intro video, it gives a pretty good overview of how they help their customers get things done.

Wed also like to thank Code & Supply for helping us network with the Pittsburgh IT community. Code & Supply is the largest IT community group in Pittsburgh, with frequent meetups and a variety of activities. Theyve helped connect us with performers and are helping promote the show with their community. They even let this guy give a talk on using storytelling to communicate technical details.

[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-daily-wtf-live-


Метки:  

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