-Ïîèñê ïî äíåâíèêó

Ïîèñê ñîîáùåíèé â 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 ëåíòû.
Ïî âñåì âîïðîñàì î ðàáîòå äàííîãî ñåðâèñà îáðàùàòüñÿ ñî ñòðàíèöû êîíòàêòíîé èíôîðìàöèè.

[Îáíîâèòü òðàíñëÿöèþ]

Error'd: Error Inception

Ïÿòíèöà, 26 Àïðåëÿ 2019 ã. 09:30 + â öèòàòíèê

"Behold how TDWTF commenters get their start in life!" Adam G. writes.

 

"We have this cable company called UPC here in Slovakia, and my freshly installed router failed showing Schrodinger's Connection symptoms," writes Daniel.

 

Mark J. wrote, "Apparently, AliExpress chooses its customers very carefully.

 

"I don't think that Medium knows what humor really is...or does it?" Bellons writes.

 

Tobias H. wrote, "While reading an article on heise.de, something apparently happened...or not?"

 

"While trying to purchase Satisfactory I got this message that aims to warn those who are not yet born," writes Nigel.

 

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

https://thedailywtf.com/articles/error-inception


Ìåòêè:  

Representative Line: Log Every Error

×åòâåðã, 25 Àïðåëÿ 2019 ã. 09:30 + â öèòàòíèê

Tom C inherited some Go from another developer, and writes, “I’m pretty sick of finding this sort of stuff in this code.”

	if log, err = dockerservice.GetLoggerInstance(); err != nil {
		log.Err(fmt.Sprintf("Logger error: %v \n", err))
  }

It’s good to log every error- it’ll help in the long run when you’re trying to trace through the problem which happens in production but the program works fine on your machine. This code knows that accessing the logger object is code that can throw an error, so if it gets an error fetching the logger object it… logs the error. With the logger object that returned some kind of error.

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

https://thedailywtf.com/articles/log-every-error


Ìåòêè:  

CodeSOD: A Linking Approach

Ñðåäà, 24 Àïðåëÿ 2019 ã. 09:30 + â öèòàòíèê

Web development has gone in a bizarre circle since the early 2000s. Whet ASP.NET launched, its “big sell” was Web Forms, which allowed developers to use a desktop model for handling interactive applications. The basic logic you used for building a desktop forms application would work for a web app, because at the time, everyone was a desktop developer.

Fast forward to today, where we bundle our applications up in web browsers and use web metaphors to build desktop applications, because everyone’s a web developer. This may be proof that developers can only ever learn a single way of doing things, and that two options is one too many.

Which brings us to some code Petr Tomanek recently inherited. The original developer, Josiah, started their career around the early 2000s. They were big advocates of the data row approach to data access. In code, they’d forget that they’d already run a query, and run it three more times just to be sure to get the data. Their approach to UI wasn’t even quite up to Web Forms standards, and was more, “mash together my personal library of snippets and Stack Overflow copy/paste”. The current incarnation of the application used the more modern ASP.NET MVC, but you wouldn’t know it to look at most of the code.

But Josiah would at least try to use the new features. For example, when they wanted the URL of a screen in the MVC application, they knew that the ActionLink method was how you created links in your view. There was also a Url.Action method which would construct just the URL. But that’s two different ways to do something, and that’s one too many. Josiah did this:

html.ActionLink(model.NextButtonText, model.RouteActionName, model.RouteControllerName, model.RouteValues, null).ToString().Split('"')[1];

The ActionLink method returns the full . Then we split on ", and grab the first element after a quote.

At least Josiah was consistent, and used this hammer everywhere they needed a URL.

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

https://thedailywtf.com/articles/a-linking-approach


Ìåòêè:  

Suffer Not The Virus To Live

Âòîðíèê, 23 Àïðåëÿ 2019 ã. 09:30 + â öèòàòíèê

/creativecommons.org/licenses/by-sa/4.0)], via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File:Computer_virus_illustration.jpg">Computer virus illustration

Not so long ago in 2015, Carl C. was asked to give a talk to an amateur radio club. The venue was a local church that rented out their meeting hall to various community groups, businesses, and even the odd academic session. The space boasted a multimedia setup with several video screens, making it a great place at which to present.

Carl prepared his talk, and a PowerPoint slide deck to go with. On the day of the presentation, he arrived at the meeting hall with plenty of time to spare. Alone in silence, he headed toward the front of the room and surveyed the technical setup. Thankfully, it was straightforward: there was a table set up in front of the projector screen, with a VGA connector resting directly on it. Carl unpacked his laptop, retrieved the HDMI-to-VGA adapter he'd brought along, and began plugging everything together.

"NOOO!"

Carl jumped, then glanced up wide-eyed like a deer in headlights. It wasn't a truck bearing down on him, but rather a flustered gentleman hugging a laptop to his chest.

"I'm the IT guru here," he introduced himself breathlessly, hurrying around the table to all but elbow Carl aside. "We don't allow outside computers to be connected to our system. That's how viruses spread! You'll have to run your presentation from our computer." He connected his own laptop to the AV system in lieu of Carl's.

"Uh ..." Carl blurted.

"Yes?" The guru fixed him with a withering stare.

I'm not joining your network, Carl thought. There's no such thing as VGA viruses! But the stare was so intense that the objections died before they left his throat.

"How, uh ... how do I get my presentation on there?" he asked instead, gesturing to the guru's laptop.

"Can you copy it to a USB stick?" the guru asked. "That's the best way."

Right. No one's ever gotten a virus from a random USB stick. Biting his lip to short-circuit a laugh, Carl dug through the side pockets on his laptop bag. "I think I've got one with me."

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

https://thedailywtf.com/articles/suffer-not-the-virus-to-live


Ìåòêè:  

CodeSOD: Be True to Yourself

Ïîíåäåëüíèê, 22 Àïðåëÿ 2019 ã. 09:30 + â öèòàòíèê

Ben M recently inherited some code from some Highly Paid Consultants. These consultants needed to be able to set some flags to control the behavior of the application, and for whatever reason, these flags needed to be strings. It probably wasn't a good reason, but there was some reason. The consultants wrote the module which set the flags, and guaranteed that the flags were only ever "true" or "false".

To parse those flags back into boolean values, they did it the true Highly Paid Consultant way: they used a generic "string to boolean" solution they copied from Stack Overflow instead of Boolean.Parse, the built-in C# method for turning "true" into a boolean value.

private bool ConvertBoolean(string value, bool defaultValue = false) { bool returnValue = defaultValue; if (value == null) { return returnValue; } if ("y".Equals(value, StringComparison.OrdinalIgnoreCase) || "yes".Equals(value, StringComparison.OrdinalIgnoreCase) || "true".Equals(value, StringComparison.OrdinalIgnoreCase) || "1".Equals(value, StringComparison.OrdinalIgnoreCase) || "on".Equals(value, StringComparison.OrdinalIgnoreCase)) { returnValue = true; } else if ("n".Equals(value, StringComparison.OrdinalIgnoreCase) || "no".Equals(value, StringComparison.OrdinalIgnoreCase) || "false".Equals(value, StringComparison.OrdinalIgnoreCase) || "0".Equals(value, StringComparison.OrdinalIgnoreCase) || "off".Equals(value, StringComparison.OrdinalIgnoreCase)) { returnValue = false; } return returnValue; }

Finally, this tells us the true value of FILE_NOT_FOUND, which is to say, whatever we passed in for our defaultValue, because that's what happens if this code doesn't understand how to parse the string.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

https://thedailywtf.com/articles/be-true-to-yourself


Ìåòêè:  

Error'd: On Second Thought, I'll Just Go Back to Bed

Ïÿòíèöà, 19 Àïðåëÿ 2019 ã. 09:30 + â öèòàòíèê

Gordon S. wrote, "In seeing how someone botched the deployment of Windows on the flight boards, I sure hope that's ALL that admin was allowed to work on."

 

"This is the login page for the French health insurance system. The red text says 'The Ameli portal will be unavailable from the 01/02/2003 to the 04/05/2006'," Joelle wrote, "Three years of maintenance downtime may seem a bit excessive, but at least they've chosen a time slot that will not affect many users."

 

Eric writes, "Somehow I don't think giving your card number as **Bunch_of_numbers** will work here."

 

"Charlotte Airport is here to remind us all that it's the computers, not the airplanes, that crash," David B. writes.

 

"I can see it now - a long time ago, someone named Craig hurt the BBC's web servers and now, it works tirelessly to ignore me," wrote Craig K.

 

"Was it helpful? Umm...was it anything?" Ian wrote.

 

[Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!

https://thedailywtf.com/articles/on-second-thought-i-ll-just-go-back-to-bed


Ìåòêè:  

CodeSOD: Waaaaaiiiiit for it…

×åòâåðã, 18 Àïðåëÿ 2019 ã. 09:30 + â öèòàòíèê

There are many moments where our multi-threaded code needs to gurantee only one code path is executing at a time. That’s why we have locks, semaphores, mutexes, and so on. But those are all pretty complicated. Vincent H recently was reviewing someone’s code, and they found a far more elegant solution, which simply uses booleans.

For example, you could whip up a wait loop with a simple block like this:

  while (Busy)
  {
      // wait for it..
  }

When Busy becomes false, thanks to another thread changing its value, this loop will exit. Of course, sharing values between threads introduces its own possible issues, so in context, we’ll write a method that looks more like this:

public static List GetMyList(this List list, bool Busy, string FilePath, string FileName)
{
  var myfilepath = FilePath + FileName;
  while (Busy)
  {
      // wait for it..
  }
  …
}

By passing Busy as a parameter (a by-value parameter, in this case), we guarantee that no other running threads will change the value of it while we’re waiting for it to change. This is a great solution to mutexes, because it guarantees that if you call this method while you’re Busy doing something else, this just enters an infinite loop from which it never exits, guaranteeing that you never accidentally do something you shouldn’t do.

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

https://thedailywtf.com/articles/waaaaaiiiiit-for-it


Ìåòêè:  

The Ballad of Bart

Ñðåäà, 17 Àïðåëÿ 2019 ã. 09:30 + â öèòàòíèê

Alvin had the fortune of working with an exceptional talent while he was employed at Virtucon. Bart knew how to do everything from desktop support to software development to database administration to IT security. Not only was he proficient in all of them, he also knew them better than those with many years of experience.

Bart had been with Virtucon since the early days, racking up nearly 20 years of tenure. During this time, he 'mastered' everything and asserted himself to the point that no changes could happen without his approval. His changes were auto-approved because of course any idea he had was a good one. This led to myriad problems for fellow IT people like Alvin, who were hired after Bart.

"Be wary of Bart," Alvin was warned by his coworker Bob, who was Bart's junior by a couple years. "He has a long history of buffoonery, yet has somehow ascended to the #3 position in IT." Alvin sipped on a generous mug of coffee while Bob regaled with the Ballad of Bart. From the time he was just a helpdesk intern that put his shoulder through a core switch after tripping while carrying boxes, Bart was wrecking things.

When Bart worked his way up to server support, he 'fixed' an Exchange issue by restoring a backup into production without warning because "It worked when the backup was taken." When he was assigned a web server problem, he spent a few days troubleshooting it without asking for any help. When he finally gave in, he told Bob that he couldn't figure out a frustrating IIS HTTPS binding issue. Bob explained to him that something else had to be the problem because the server was running Apache 2.4 on Ubuntu 16.04 LTS.

When Bart added software development to his repertoire, he clearly didn't understand how code changes worked. Or code repositories for that matter. He always wanted to be the one to fix problems, so he would stick his nose in code that it didn't belong.

Bart once tried to make fee schedule changes to accounting software by opening its PowerBuilder libraries in Notepad++. He proceeded to print out the .PBL and use a pencil to scribble out every value from the old schedule and wrote in the new ones. He then scanned his penciled changes in as a PDF and emailed it to Bob to implement.

Frustrated, Bob spent an entire day showing Bart how their GitHub repositories worked. He seemed to understand, so Bob went on his way. While Bob hoped Bart wouldn't actually produce any more code, perhaps it would save their printer some toner if he did. The next day, all the developers were complaining to Bob that they couldn't access GitHub. It turns out Bart saw GitHub as a threatening malicious code breeding ground so he had a network admin block it on the firewall. He then sent an email to development staff explaining this and that they were supposed to now use 'BartHub', a file share he set up on his own computer.

Bob and the developers managed to distract Bart by pointing out how the DBA team needed help. The first thing he did was try to create an SSRS report using a series of text boxes in a grid to make a matrix. The DBA's had a good laugh at that until Bart started to commit worse atrocities.

One day an entire metrics database suddenly became a bunch of null values, which is not very helpful for metrics. Bart threw a fit because the data he was working on was gone. He demanded whomever messed up the data be hunted down. He suggested that missing historical data could be found by performing 'key triggers', whatever those were. He emphasized his point by making hand motions like he was scrambling a Rubik's cube. They ignored him and a lead DBA ran a profiler trace to find that the unconstrained null updates came from... Bart's workstation.

Alvin had long since imbibed his coffee when Bob finished his story. Bob turned back to his workstation to check his email, "Oh, would you look at that. I guess we have some changes up top!" The email stated that the current VP of IT was announcing his retirement after 30 years at Virtucon. The CTO would be taking on that new role at the end of the month.

The transition plan began and the CTO was groomed to take over. That plan was shredded a week before it was to take place because the CTO suddenly found himself unemployed. The finance department was investigating his use of the company credit card and found thousands of dollars in personal charges, so he was unceremoniously terminated. Turmoil gripped the office as an entire department waited to find out who their new leader would be.

Everyone except Bart put in a good word for Bob to become the next VP of IT. At minimum, they should hire someone from the outside. Pretty much anyone but Bart was the popular suggestion.

Bart predictably put in a good word for himself and talked a big game about all of his expertise. He added security expert to his resume by talking about disabling his home WIFI’s SSID broadcast and changing the default password. Then there was the previously-unmentioned experience as an IT Project Manager where he apparently led several teams at Schmoeing.

That Friday, that dreaded email with the subject New VP of IT came out. Being the most tenured person remaining while having "great leadership qualities," Bart got the promotion and Bob didn't. Many job search sites probably thought they were getting a DDoS attack over the weekend while everyone in Virtucon IT looked to abandon ship. Bart's reign of terror lasted 18 months before Virtucon realized they made a grave mistake. Bob, Alvin, and many others weren't around to see the way it all ended.

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

https://thedailywtf.com/articles/the-ballad-of-bart


Ìåòêè:  

Representative Line: Tern Your View

Âòîðíèê, 16 Àïðåëÿ 2019 ã. 09:30 + â öèòàòíèê

We all just love ternaries around here. So much. A powerful form of code golf, they can clarify and they can confound, but usually it’s just confounding.

Christopher sends us this example, saying, “This is an accurate indicator of the rest of the code.”

not_mobile = viewport().width > 400 ? true : false;

Representative indeed, and there’s a lot packed into this beyond the ternary abuse. First off, our standard for being not_mobile, which I assume is “not a mobile device” for displaying this site, is a screen that’s 400 pixels wide. Which is fine, until someone turns their 2007 iPhone into landscape mode, which is 480px wide. I assume this site has a banner “Best Viewed using a Palm Pilot”.

Of course, the root WTF is trying to set responsive breakpoints in JavaScript, when CSS has a rich set of features to handle that. Then again, they’re apparently using a custom viewport object, which implies that perhaps the viewport element wasn’t fully supported when they wrote it, so maybe it’s just an old site?

Which brings us back around to the ternary abuse. Maybe the code is just plain bad.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

https://thedailywtf.com/articles/tern-your-view


Ìåòêè:  

CodeSOD: Typing for Types

Ïîíåäåëüíèê, 15 Àïðåëÿ 2019 ã. 09:30 + â öèòàòíèê

Today, any sort of data access layer we build is going to be rooted in some sort of object-oriented design. It might be a full ORM, it might be an object-store database, it might be one of any number of kinds of database mapping tool.

What we usually don't do anymore is get a resultset with no type information, where we have to invoke the proper "GetXXX" method to fetch data out of what behaves more-or-less like a dictionary. Oh, we might have to do this, but we'll almost always bury it under a layer of abstraction to hide the ugly details.

I bring this up because once upon a time, this was pretty standard stuff. Result sets and data readers were just how you talked to databases. It's old fashioned, but not wrong.

Russell F recently had to add some new fields to some code written in that style. This was wrong.

public WorkOrderCustomer(SqlDataReader dr) { WorkOrderCustomer_Num = Convert.ToInt32(dr["WorkOrderCustomer_Num"].ToString()); WorkOrder_Num = Convert.ToInt32(dr["WorkOrder_Num"].ToString()); CustomerStatusFlag_Num = Convert.ToByte(dr["CustomerStatusFlag_Num"].ToString()); Cust_FirstName = DBNull.Value.Equals(dr["Cust_FirstName"]) ? (string)null : Convert.ToString(dr["Cust_FirstName"].ToString()); Cust_LastName = DBNull.Value.Equals(dr["Cust_LastName"]) ? (string)null : Convert.ToString(dr["Cust_LastName"].ToString()); Cust_Phone = DBNull.Value.Equals(dr["Cust_Phone"]) ? (string)null : Convert.ToString(dr["Cust_Phone"].ToString()); Cust_PhoneCarrier_Num = DBNull.Value.Equals(dr["Cust_PhoneCarrier_Num"]) ? (short?)null : Convert.ToInt16(dr["Cust_PhoneCarrier_Num"].ToString()); Cust_Email = DBNull.Value.Equals(dr["Cust_Email"]) ? (string)null : Convert.ToString(dr["Cust_Email"].ToString()); Account_Num = DBNull.Value.Equals(dr["Account_Num"]) ? (int?)null : Convert.ToInt32(dr["Account_Num"].ToString()); ChargeCode_Num = DBNull.Value.Equals(dr["ChargeCode_Num"]) ? (short?)null : Convert.ToInt16(dr["ChargeCode_Num"].ToString()); CompanyName = DBNull.Value.Equals(dr["CompanyName"]) ? (string)null : Convert.ToString(dr["CompanyName"].ToString()); CompanyAddress = DBNull.Value.Equals(dr["CompanyAddress"]) ? (string)null : Convert.ToString(dr["CompanyAddress"].ToString()); CompanyCity = DBNull.Value.Equals(dr["CompanyCity"]) ? (string)null : Convert.ToString(dr["CompanyCity"].ToString()); CompanyState = DBNull.Value.Equals(dr["CompanyState"]) ? (string)null : Convert.ToString(dr["CompanyState"].ToString()); CompanyZipcode = DBNull.Value.Equals(dr["CompanyZipcode"]) ? (string)null : Convert.ToString(dr["CompanyZipcode"].ToString()); CompanyPhone = DBNull.Value.Equals(dr["CompanyPhone"]) ? (string)null : Convert.ToString(dr["CompanyPhone"].ToString()); DriverName = DBNull.Value.Equals(dr["DriverName"]) ? (string)null : Convert.ToString(dr["DriverName"].ToString()); LeasingCompany = DBNull.Value.Equals(dr["LeasingCompany"]) ? (string)null : Convert.ToString(dr["LeasingCompany"].ToString()); Fleet_Num = DBNull.Value.Equals(dr["Fleet_Num"]) ? (string)null : Convert.ToString(dr["Fleet_Num"].ToString()); Unit_Num = DBNull.Value.Equals(dr["Unit_Num"]) ? (string)null : Convert.ToString(dr["Unit_Num"].ToString()); ShipToDealerAccount_Num = DBNull.Value.Equals(dr["ShipToDealerAccount_Num"]) ? (string)null : Convert.ToString(dr["ShipToDealerAccount_Num"].ToString()); DeliveryReceipt_Num = DBNull.Value.Equals(dr["DeliveryReceipt_Num"]) ? (string)null : Convert.ToString(dr["DeliveryReceipt_Num"].ToString()); CompanyVendor_Num = DBNull.Value.Equals(dr["CompanyVendor_Num"]) ? (int?)null : Convert.ToInt32(dr["CompanyVendor_Num"].ToString()); Is_CDP_Account = DBNull.Value.Equals(dr["Is_CDP_Account"]) ? (bool?)null : Convert.ToBoolean(dr["Is_CDP_Account"].ToString()); IsNationalAccount = DBNull.Value.Equals(dr["IsNationalAccount"]) ? (bool?)null : Convert.ToBoolean(dr["IsNationalAccount"].ToString()); HasZZPermit = DBNull.Value.Equals(dr["HasZZPermit"]) ? (bool?)null : Convert.ToBoolean(dr["HasZZPermit"].ToString()); Cust_Address = dr["Cust_Address"] as string; Cust_City = dr["Cust_City"] as string; Cust_State = dr["Cust_State"] as string; Cust_Zip = dr["Cust_Zip"] as string; CustTempMaster_Num = dr["CustTempMaster_Num"] as int?; }

dr["fieldname"] is the simplest way to access a value in the dataset. It has the disadvantage of returning data as object, which means you're going to need to do a type conversion. This code demonstrates two different ways to do the type conversion. The last five lines, added by Russell, use the as string syntax. That's a relatively new addition to the C# language which does "safe" conversions- if the typecast isn't possible, it just returns null.

Of course, since you do know the types of the DB columns, you could also use a more traditional cast syntax, like CustNum = (Int32)dr["CustNum"]. That would have worked in every version of C#.

But that's not what the original developer did. They grabbed every field, converted it to a string, and then used a Convert method to parse it back into the expected data type.

That's the sort of code that makes you sigh and step away from your desk for a few minutes, because it's just so exhausting to see.

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

https://thedailywtf.com/articles/typing-for-types


Ìåòêè:  

Error'd: Are You Not Satisfied?

Ïÿòíèöà, 12 Àïðåëÿ 2019 ã. 09:30 + â öèòàòíèê

"Does this mean that Toyota believes that hybrid owners are fundamentally unhappy with their cars?" writes Thom.

 

Brian K. wrote, "When I clicked on a link on our intranet for a PowerPoint presentation, clearly Microsoft thought that perfectly valid server certificates are suspicious and asked me to confirm."

 

"Make? Model? Year? Bah...who needs them? ALL FALSE!" Walt S. writes.

 

Alex B. wrote, "My friend and I were at a mall in Los Angeles and he happened to use an old parking ticket from 6 months ago proving that the machine never forgets!"

 

"The lesson to learn here is 'Pick and language and just STICK with it!!'"Job writes.

 

Timothy wrote, "I didn't catch the name tag, but with a name like $driverName$, you could say he had his career path set from birth."

 

[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!

https://thedailywtf.com/articles/are-you-not-satisfied


Ìåòêè:  

CodeSOD: Oooooooooooooo no

×åòâåðã, 11 Àïðåëÿ 2019 ã. 09:30 + â öèòàòíèê

Kids these days have their flexboxes and their ems and their position absolutes. In the olden days of HTML, we arranged everything with table tags and we liked it. Well, some of us did. Mike was recently doing part of a redesign, and when the background color of the page was changed, a bunch of garbage text appeared in various input forms. How could changing the CSS background color cause garbage text to appear?

Billing Address Information

Billing Address 1:0ooo0.....

Billing Address 2:o00000...

Billing City:00o00..0.o...0..

It certainly gives new meaning to the term “whitespace”. The mix of characters implies that either the person responsible deeply understood how proportional fonts work in terms of sizing, or they absolutely didn’t. They almost certainly didn’t. Then again, this kept all the fields aligned on all the browsers anyone had tested with, so maybe they did?

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

https://thedailywtf.com/articles/oooooooooooooo-no


Ìåòêè:  

CodeSOD: It Just Won't Stop

Ñðåäà, 10 Àïðåëÿ 2019 ã. 09:30 + â öèòàòíèê

Kara's ongoing quest to tame her codebase continues. First it was serialization, then more strings, then some serial communication.

Today, it's threads.

The original developer was a physicist and an extremely smart person. They never learned too much about databases, but they knew their way around XML, so they had a simple solution to storing data: any time you wanted to save something, rewrite an entire XML file onto disk.

Now, in this case, the "something" being saved is data collected from a piece of scientific equipment. That data is collected by sending commands to the device, changing its state, and asking it for information about readings in that new state.

Since this is a complex, long-running process, the developer used threads. Since it's complex and long running, it needs to be stoppable. And this is how they chose to stop it:

System.Threading.Thread RunThread; enum StopReason { Completed, Aborted, Error } void StopRun(StopReason why) { try { if (RunThread != null) { RunThread.Abort(); } } catch (ThreadAbortException ex) { } finally { if (Thread.CurrentThread != RunThread) { RunThread.Join(); } OnRunStopped(why); } }

You'll note the catch block in there, the catch with absolutely no body. Fun fact: C# lets you omit the catch and do a simple try/finally pair.

Of course, the exception only is an issue because they're calling Abort. In .NET, an aborted thread has no chance to do any cleanup or shutdown. It just ends.

If you were, say, a piece of software that was interacting with a scientific instrument and writing data directly to an XML file, aborting the thread could leave both the instrument and the XML file in unknown, incoherent states.

Which is exactly what happened. Kara changed the stop behavior to actually stop the thread, gracefully.

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

https://thedailywtf.com/articles/it-just-won-t-stop


Ìåòêè:  

CodeSOD: Count Me Out

Âòîðíèê, 09 Àïðåëÿ 2019 ã. 09:30 + â öèòàòíèê

“My program needs to send some emails,” the developer thought to themselves. The then thought about how this could go wrong, probably thinking that, boy, they’ve got an external server, and boy, spam is a problem, and that server might get upset if you’re sending too many messages at once, or too quickly. That’s a thing which could happen, right?

That’s at least a plausible line of thought for the code Juana found, which looks something like this:

		public function processQueue($method)
		{
			$counter = 0;
			while (($result_item = $this->_getProcessableItem($method)) !== null) {

				// .....
				// Here we process the item, e.g. sending some email.
				// .....
                        
				if (++$counter % 10 == 0)
					sleep(2);
				else if (++$counter > 100)
					break;
			}
		}

So, this method grabs items out of a _getProcessableItem method, and as long as there are items in the queue to process, it does something to them, including sending an email. And then there are the if statements.

If you’re just skimming the code, it’s easy to miss the error. We check ++$counter to see if it’s divisible by ten, and if it is, sleep for two seconds. Why two? Why sleep at all? That information isn’t here, either in comment or commit message form. We just do.

Or do we? Because we also check if ++$counter > 100… which also increments the counter. That check works, but because it’s there, our mod–10 check doesn’t. Counting is hard, and since this loop essentially counts by two, ++$counter % 10 is always going to fail.

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

https://thedailywtf.com/articles/count-me-out


Ìåòêè:  

CodeSOD: Zoning Out

Ïîíåäåëüíèê, 08 Àïðåëÿ 2019 ã. 09:30 + â öèòàòíèê

Matthew D was recently helping a friend plan a trip to Europe from the US. After shopping around a bit, they found a rather affordable airline based out of Poland that fit both their budget and their destination, and started booking a flight.

It was going well until it came time for them to enter their passport information. The site complained that the expiry date was invalid. Since that complaint was happening without a page reload, Matthew was pretty sure it was a buggy bit of client-side validation, so he pulled up the dev tools and poked around.

var validExpiryDate = function(val, fieldNode, ruleValue){ var idField=fieldNode.attr("id").split("_"); var idPax=idField[idField.length-2]; var nDoc=idField[idField.length-1]; var type_document = A.one('#_retrievepnr_WAR_lotairwaysportlet_change-type-document_'+idPax+'_'+nDoc); if (type_document!=null && type_document.val() == "") { return true; } if (val.length <= 8) { var day_value = A.one('#_retrievepnr_WAR_lotairwaysportlet_change-expiry-day_'+idPax+'_'+nDoc).val(); var month_value = A.one('#_retrievepnr_WAR_lotairwaysportlet_change-expiry-month_'+idPax+'_'+nDoc).val(); var year_value = A.one('#_retrievepnr_WAR_lotairwaysportlet_change-expiry-year_'+idPax+'_'+nDoc).val(); if ((day_value == "" && (month_value != "" || year_value != "")) || (month_value == "" && (day_value != "" || year_value != "")) || (year_value == "" && (day_value != "" || month_value != ""))) { return false; } else if (day_value == "" && month_value == "" && year_value == "") { return false; } if (day_value.length < 2) { day_value = '0' + day_value; } if (month_value.length < 2) { month_value = '0' + month_value; } var date_select = new Date(Date.parse(year_value + "-" + month_value + "-" + day_value + "T00:00:00Z")); var day_select1 = date_select.getDate(); var month_select1 = date_select.getMonth() + 1; var year_select1 = date_select.getFullYear(); if (day_select1.length < 2) { day_select1 = '0' + day_select1; } if (month_select1.length < 2) { month_select1 = '0' + month_select1; } if (day_value != day_select1 || month_value != month_select1 || year_value != year_select1) { return false; } var ageDifMs = Date.now() - date_select.getTime(); var ageDate = new Date(ageDifMs); var age = Math.abs(ageDate.getUTCFullYear() - 1970); var isNotExpired = Date.now() < date_select.getTime(); if (isNotExpired) { return true; } else { return false; } } else { return false; } }

There's a lot of ugly in this code, with how it's grabbing DOM elements, how it's handling the validation and padding of the date input fields. It's hard to tell from just looking at the code, but the purpose is to make sure that the expiration date is a valid date in the future.

Someone once heard that comparing against timezones was dangerous, so they decided to coerce the date into the same timezone:

var date_select = new Date(Date.parse(year_value + "-" + month_value + "-" + day_value + "T00:00:00Z"));

That puts it all at UTC+0. Even there, that raises a curious boundary condition: if my passport expires on, say, 4/30/19 but was issued in UTC+5, is it still valid on 4/29/19 at 10PM in a location at UTC+0? I'm sure there are rules about that, and I'm sure the developer wasn't actually thinking about those rules at all.

And that's why, at the very end, their method of checking is simply Date.now() < date_select.getTime(). date_select contains a date in UTC+0. Date.now() will always contain a date in your local TZ.

Now, in most cases, that's probably not a serious problem, and the "key" not expired check- var isNotExpired = Date.now() < date_select.getTime(); will work most of the time.

The problem, and the real WTF, is that before doing that check, they also do this check:

if (day_value != day_select1 || month_value != month_select1 || year_value != year_select1) { return false; }

Here, they compare: if the value that came in from the form fields don't match the values in our time-zone converted date, their expiry is invalid.

Which, if you happen to be say, in UTC-8 and you're booking your flight in the evening, it's already the next day in UTC+0, so this won't pass. In fact, if you're in any TZ other than UTC+0, and you try and book your flight at the wrong time, it won't pass.

Of course, since this airline is based out of Poland, their home base is UTC+1, so this bug would almost *never* trigger there. Almost never.

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

https://thedailywtf.com/articles/zoning-out


Ìåòêè:  

Error'd: Absolutely Qualified

Ïÿòíèöà, 05 Àïðåëÿ 2019 ã. 13:30 + â öèòàòíèê

"Pi...eye...they rhyme, so naturally, I'm qualified to assist Nicole with her make up needs," Dave V. writes.

 

"Who needs fancy cooling setups when you can put your CPU's (normally) wasted heat to good use!" Valts S. wrote.

 

Shaun L. writes, "For an agency who focuses on the United States, you would think they would have a better understanding of the geography."

 

"Yes, Teamviewer, I am ready, but I'm not sure that you are though!" wrote Bryan K.

 

Steve M. writes, "Trying to get support on an update error on my new work-issue Surface, I've now got two errors. Or have I? If no error occurred to generate the error dialog, does that mean I've still only got one error?"

 

"This just in: A headline has gone missing," writes Mario C.

 

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

https://thedailywtf.com/articles/absolutely-qualified


Ìåòêè:  

CodeSOD: Going the Distwince

×åòâåðã, 04 Àïðåëÿ 2019 ã. 13:30 + â öèòàòíèê

Stored procedures are a bit of a WTF breeding ground. Your average stored procedure language is more limited than your average general purpose language, the syntax is usually clunkier, and everything is so data-focused that implementing logic beyond simplistic processes can be more challenging than one would expect.

Of course, this gets harder if you don’t bother to learn how to do string concatenation. Darrin found an example of that while debugging a store procedure:

if @_DistType = 1
   begin
	set @_Query = dbo.GetQuery('DistType1');
	execute sp_executeSQL @_Query
   end
if @_DistType = 2
   begin
      set @_Query = dbo.GetQuery('DistType2');
      execute sp_executeSQL @_Query
   end
if @_DistType = 3
   begin
   set @_Query = dbo.GetQuery('DistType3');
      execute sp_executeSQL @_Query
   end

-- snip

if @_DistType = 74
   begin
      set @_Query = dbo.GetQuery('DistType74');
      execute sp_executeSQL @_Query
   end
if @_DistType = 75
   begin
      set @_Query = dbo.GetQuery('DistType75');
      execute sp_executeSQL @_Query
end

Note how each branch of the ifs is checking the @_DistType variable, and then running a stored procedure with a parameter in the pattern 'DistTypeNN'. That means there are 375 lines of code here which could be condensed down quite a bit. Now, I’m going to assume that this is SQL Server (what with the DBO prefix), so…

SET @_Query = dbo.GetQuery('DistType' + CAST(@_DistType AS CHAR))
EXECUTE sp_executeSQL @_Query;

Now, my syntax may not be perfect, here. There are some good odds that I’ll have to fight a bit with type casting, and there’s probably gonna be some issue with passing a variable directly into a function, because y’know, there almost always is some gotcha on these kinds of queries. I’d have to poke at this a bit to make 100% certain that it works.

But what I’m not about to do is copy and paste the same block of code with minor variations.

And as angry as that makes me, you know what? That’s not even TRWTF. dbo.GetQuery is clearly looking up a SQL statement from a table in the database, and then we’re executing it. It’s not quite as bad as trying to build a query on the fly through concatenation, but it’s impossible to look at this block and have any idea what it’s actually doing. And since GetQuery is probably looking up in a table, what it does could change without any code ever changing. This usually is taken to mean the code is “flexible” but the reality is that it’s “unmaintainable”.

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

https://thedailywtf.com/articles/going-the-distwince


Ìåòêè:  

CodeSOD: The Myth of Datyphus

Ñðåäà, 03 Àïðåëÿ 2019 ã. 13:30 + â öèòàòíèê

PHP gets a lot of flack, but perhaps we're taking the wrong perspective on things. Perhaps the gods have condemned PHP to ceaselessly rolling CMSes and wikis up the hill, whence they roll back down under their own weight. The gods had thought, with some reason, that there is no more dreadful punishment than futile and hopeless labor.

I mean, look at this code:

$migrateStartTime = date("Y-m-d", strtotime(date('Y-m-d', time()))); // Four other lines of code $startDateTime = DateTime::createFromFormat('Y-m-d', date('Y-m-d')); $startDateTimeIdentifier = $startDateTime->format('Y-m-d');

Is there anything more futile than that first line? Get the current time, format it as a date, convert the formatted string back into a date, and then convert that date into a string with the same format.

I leave PHP at the foot of its codebase. One always finds one's burden again. But PHP teaches the higher fidelity that negates the gods and raises date handling code. It too concludes that all is well. This universe henceforth without a master seems to it neither sterile nor futile. Each date format string, each unnecessary conversion of that night filled codebase, in itself forms a world. The struggle itself toward the heights is enough to fill a man's heart. One must imagine PHP happy.

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

https://thedailywtf.com/articles/the-myth-of-datyphus


Ìåòêè:  

CodeSOD: An Objectionable Dictionary

Âòîðíèê, 02 Àïðåëÿ 2019 ã. 13:30 + â öèòàòíèê

You may remember Karl from a few months back. Karl's organization is notorious for crunch, and it results in some awful sins when you're trying to cram 50 hours of work into the last five hours before launch.

Karl didn't write this particular bit, but dreads the day when he has to look at it or change what it does.

private void InitializeDictionaries() { filePaths = new HashSet<string>(); preDecryptionFiles = new Dictionary<string, string>(); trailerInfo = new Dictionary<string, string[]>(); fileHeaders = new Dictionary<bool, Dictionary<string, string>>() { { true, new Dictionary<string, string>() }, { false, new Dictionary<string, string>() } }; separatedFiles = new Dictionary<bool, Dictionary<bool, Dictionary<string, List<string>>>> { { true, new Dictionary<bool, Dictionary<string, List<string>>> { { true, new Dictionary<string, List<string>>() }, { false, new Dictionary<string, List<string>>() } } }, { false, new Dictionary<bool, Dictionary<string, List<string>>> { { true, new Dictionary<string, List<string>>() }, { false, new Dictionary<string, List<string>>() } } } }; }

The job of this code is to prep some data structures which will be used to store the contents of some files. Writing a class to handle that would be the obvious solution, but this developer instead went with the "let's nest a bunch of dictionaries inside of each other," approach. The separatedFiles nest their dictionaries three deep, and contain a list of strings, so that's four tiers of nested generics. I do not know why there are the boolean keys. I don't think I want to know.

None of this is a "code smell". This is a "code stench", and it's not gonna wash out.

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

https://thedailywtf.com/articles/an-objectionable-dictionary


Ìåòêè:  

Radio WTF: Confidence

Ïîíåäåëüíèê, 01 Àïðåëÿ 2019 ã. 14:00 + â öèòàòíèê

Radio WTF Presents!

Jump to transcript

Welcome back to Radio WTF. This week, we learn of the power of confidence.



Soundcloud Links: Radio WTF: Confidence

Direct Download: Download

Starring (in order of appearance) Remy Porter... as Kyle
Adam S.... as Mark
Ulf S.... as Andris
Kacper M.... as Paul
Jane Bailey... as Trish
Lorne Kates... as The Boss
Alex Papadimoulis... as Mr. Sidwell
Heather... as The Narrator.

Theme song "Slow Burn" by Kevin MacLeod of Incompetech.com.

Dedicated to the memory of Paul Rousse

Transcript

(Please note: transcript was taken from final version of script, which changes slightly during recording. Any typos or confusing wording is entierly on me. Will attempt to transcribe actual audio, but no promises)

Scene: 1

(Narrator)

narrator

Radio W.T.F presents-- The Daily WTF.

Today’s episode: "Confidence", a written and adapted for radio by Lorne Kates, based on contributions by Jimmy W. and Polly G.

The offices of Initech are just the right size, for just the right team. Though the company is far enough past startup to be profitable, its small development team is still working on that one flagship, breakout product.

Today, that team becomes just slightly small as Mark, a junior coder looking for his own flagship, breakout entry resume, starts his first day.

Scene: 2

(office)

SOUND: Some light construction sounds, drilling, pulling cable

KYLE

... and this is the where all us techies work. We're doing some upgrades to the space, so mind the cables and stuff.

MARK

It's very roomy for such a small team.

KYLE

It's all about planning for the future. Once the main project launches, this whole bottom level will be absolutely lousy with wall-to-wall brains and keyboards. I've got a roadmap that might as well be a runway, because once I get this sucker moving, we're taking off to the limitless sky! I know you're going to be a big part of that launch; talent like you is just the kick in the arm this company needs right now. Don't get me wrong, those folks over there, they're not bad but-- architects like us who have the VISION we only need so many builders to do the heavy lifting on the plans, right?

MARK

Well, I hope I can do my part for the project in the time my contract allows.

KYLE

What? Oh ha, no, nope. You're great and all, but you're still a "you" and not a "me". No, I'm going to get you to work on an internal E.R.P. project that's been scoped out but stalled. On paper it's because all our resources are tied up in the main project. In reality, just between you and me, it's because I want to burn the entire shoddy codebase to the ground and start again. It's what happens when you let coders like them have too much free reign. On the main project, I can whip them back on track no problem, keep them to The Vision. Now you-- you're someone I'll gladly give a set of specs and a blank IDE, and you go at it. Heck, start it today as soon as we've got your computer hooked up.

MARK

Today-- I, uh, wow. Okay, I'm used to being eased into a codebase. Get some review and training from the rest of the team--

KYLE

Bah, forget that. Do your thing. Impress me. 'Cause if you can impress me, you'll absolutely bulldoze the boss's mind. And then he can stop arguing with me about making your contract permanent. The boss has a good heart, but his head's a few steps behind when it comes to knowing what's good for the company. If it were up to me, you'd be full time salary.

MARK

Well, I appreciate the confidence but still-- if I have questions or anything about the code, who should I go to?

KYLE

Me. Come straight to me, no one else. I know the codebase better than anyone else here. Heck, I wrote almost all of it-- especially the parts that work.

MARK

Okay-- but if you're not available,then...?

KYLE

Look, let me take what's between the lines, and put it right on the line; those guys out there-- you're really going to want to minimize your contact with them. They've got their wounded egos all up in a bunch over me bringing in outside talent. They can barely take criticism of their code as it is-- and they kinda see you as the living embodiment of criticism of their code; a deliberate and personal attack on their ability as coders. That isn't why I brought you on, and I don't want that to define your time here. Yes, you're here to do a job they couldn't, but that's just truthful facts, nothing personal to them or you. So just keep it quiet and cool-- last thing I want is them trying to start a seniority battle with you-- getting the boss involved and everything.

MARK

I guess every office has it's politics. Imagine how much work would get done without that.

KYLE

I know what you mean. But like I wisely say-- you have to not only pick your battles, but also pick WHEN you'll have the ones you have. Right now-- near the end of a major project-- isn't the right time. But afterwards-- my friend, I want you here to uplift this entire team. Until then-- your cube is over there. It's already hooked up to the network, and the source code repository. Here, take this-- it's a hardcopy of the specs to work against. Software shelf is over there, install what you need. Anything we don't have that you need, just let me know and I'll get it purchased.

MARK

Well, okay, I guess I'll get started.

KYLE

Great. Hey, you've got the signed contract and blank-voids?

MARK

Yeah, here you go.

SOUND: handing over an envelope

KYLE

Cool. I'll get this filed, you go ahead and get started doing your thing.

SOUND: getting up, walking away

(from a distance away)

andris

Hey, Kyle buddy, where do you want the cables dropped?

KYLE

Over by the wall

andris

where?

KYLE

OVER BY THE-- arg, look, I'll come over, one minute.

SOUND: GET UP, FOOT STEPS

Andris

Kyle buddy, I asked where do you want these cables dropped?

KYLE

I heard, Andris. Right here where I have it marked.

andris

Here?

SOUND: knocking on concrete

KYLE

Yes. Here.

andris

Huh, okay, gotta tell you, wasn't expeting to drill through concrete today. I mean, I can if that's what you need, but it ain't easy. I'm gonna have to get some drills and bits from the truck, gonna take longer than I thought-- prolly put things on the high end of the quote.

KYLE

Yeah, I understand. Sorry, I thought Trisha-- our office manager-- had sent you all the details of the room. Didn't think the drops in the concrete walls would get left out. Well, I guess I should have thought. She's a little bit-- ah-- more cocoon than butterfly. Kinda just take it for granted that something'd be forgotten these days. But yeah, sure, I understand. Add what you need to add to the invoice. After all, an estimate is an estimate, and work is work. And hey, while you're adding to the invoice, you can always bump it up a few extra percents and kick me back some of the difference, hey hey?

andris

(unamused)

I only charge for what I do.

KYLE

Relax, Andris, it's just a joke. Yeesh. When you get your drills, also grab a big set of pliers to get that stick out of your butt. Ha. But seriously, yeah, do what you need to and invoice it.

andris

Sure.

(he leaves)

SOUND: get up, foot steps, someone else gets up

paul

Kyle-- Kyle, hey Kyle--

SOUND: reluctantly stopping

KYLE

What is it now, Paul?

paul

Do you have a minute? I need to ask you something about the code in the checkout.

KYLE

(less jovial, almost caustic)

Paul, I've already given you way more minutes than I could ever bill for your 'questions'. But I'm sure this time it'll totally be worth it.

paul

(the beaten-puppy tone of voice is noticable. he's been put down enough that he's used to it, like he's accepted that little bit of his soul has been beated to death)

It's about the banking connector in the ecomm module. The checkout process keeps timing out, so the bank is taking the payment, but we don't record it. I think the was you're handling persistence in the object framework--

KYLE

(Interrupts)

Hang on, Trish just got here. TRISH! Dang it, I need to talk to her. Hold that thought. Hold onto it very, very tight, because you have so few. It's precious.

paul

But the checkout process--

KYLE

Paul, listen to me. I'm the Team Lead. A Team Lead's time is an extra special premium. One day you might be a Team Lead of your very own project. A very distant "might", but still, let's pretend. Then-- and only then-- will you get to make the choice to waste that premium time. Since today isn't that day-- just go back to your desk. My persistence code is fine. It's always been fine, and will always be fine, no matter how many times you try to "improve" it. Just get back to your desk and fix the bugs you've been assigned to fix. When you're done that, then fix the bugs your shoddy bugfixes will inevitably introduce. Keep up that pattern, and maybe we'll get the project done only MONTHS overdue instead of years.

(walks away)

SOUND: faster footsteps catching up to trish

KYLE

Trish-- hey Trish. Wanted to let you know the new guy started today.

trish

Yeah, I saw. Let me grab a coffee, then I'll come by, give him the orientation, do the usual new employee paperwork, get him on payroll--

KYLE

Yeah, it's okay-- I already did it for you. Here.

SOUND: handing over an envelope

trish

Uh-- thanks? Wasn't expecting you to do al that.

KYLE

No worries, just trying to lighten your load. I know the boss has you doing your job and then some-- office manager, HR, marketing--

trish

Bookkeeping, as I guess you know.

SOUND: flapping the envelope

KYLE

Exactly. And besides, it's hard not to overhear this that and the other thing-- boss having discussions with unhappy clients, talking about cost and budget whackery and everything. He doeesn't take slow business days very well. Kinda one of the reasons I was so eager to get the team down here and away from the main floor. It's tough enough wooing prospective clients with them being assaulted by the sea of Cheetos-breath and XBox-induced B.O.-- present companies excepted, of course.

trish

Yeah, you may be right-- but for the same reasons, the basement retrofit was still a real hard sell.

KYLE

Good thing I negotiated a ridiculously good rate then, huh? Any lower, and the contractor would be paying US.

trish

Hehe. Yeah. But on the same note, even though this new guy's a junior on a junior's salary-- the sooner he can justify his own cost, the better. I'll get his paperwork filed but-- yeah, any good news all this stuff brings, the better.

KYLE

I'll try to send only news that is good but-- well-- between you and me-- if there happens to be any "not good" news that crops up, maybe let me take it to the boss. For your sake.

trish

For my sake-- what?

KYLE

It's just that-- {quieter}-- sometimes the things I do just happen to overhear from the boss-- it isn't always just client-talk. I've already heard him talking about you with some choice words that I care not to repeat. It's like he thinks because you're responsible for so much of the daily operations of the company, that he can blame everything that goes wrong on you. It isn't fair.

trish

I haven't heard anything like that. The boss's been nothing but nice to me since I started.

KYLE

Well, of course he is nice when you're listening. But you know how he is-- says one thing to your face, then another being your back.

trish

I-- that's awful, I guess, but-- I don't think you have to worry. He's happy with me. He's said so.

KYLE

Sure, and he had nothing but praise for the last gal who had your job. Talked her up nice and sweet too. And it worked-- she was dedicated. Got really personally invested in the role. Working late, extra hours, above and beyond stuff. Then some clients weren't happy with the service they were getting for some stupid reason. Nothing to do with her but-- all of a sudden, she's the sacrifical scapegoat and poof her job is gone.

trish

I heard she's quit-- just up and left one day, no notice or anything. Left the company in a real pickle of a bind. If I'm honest I'm still straightening out that mess.

KYLE

Nope. She was canned harder than Granny's preserves. Who told you she quit?

trish

.... the boss.

KYLE

Yeah, see what I mean? You've only been here what, a month? A tad more? You just haven't been here long enough to see that side of him. In a word: spiteful. Just trust me-- if things are rocky and business is a bit shakey-- just keep your head down. Watch not only what you say to him, but how you say it. And for heck-on-a-stick's sake-- if there's really bad news you have to give him about anything-- especially anything project related-- tell me and I'll give it to him. He can go on one of his rampages on me if he wants. I can take it. But the thing is-- he won't. He knows I'm way too valuable to the project. He knows the whole damned project would collapse like a house of dominoes if I left.

Trish

Yikes. Well thanks-- I guess.

KYLE

No need to thank me, just doing what a good leader does. Just keep your eyes open and head down-- just like all of us here have to do every day.

SCENE: 3

(Narrator)

Narrator

Mark worked diligently, alone is his own cube somewhere over—there, in the same room as the rest of the development team, yet apart. Mark knew everyone else was building the product that would launch the company into the stratosphere—but he was confident his own project would be just as vital for keeping Initech aloft. After all, a company is only as good as its own internal functions, and the E.R.P. he was building would be the central intelligence that kept those functions functioning.

Likewise, a company is also only as good as its customers, and here came The Boss, giving a potential customer “the tour”.

SCENE: 4

boss

And here's where the development team works. We have all our equipment here, and the servers we run in-house.

MR. SIDWELL

I see. And these are new renos to the office?

boss

Yes, nessisary expenditure. The entire development team and all their equipment is located here. Say, where's Kyle

paul

He's off at the server colo checking on the new hardware we provisioned.

MR. SIDWELL

New hardware?

boss

We needed to scale up the hardware due to the expected revenue from traffic into the project.

MR. SIDWELL

Has that been realized yet?

boss

Well, at the moment it's not.

paul

Hopefully we won't need to provision any more. We might even be able to scale down the servers, if I can get my optimizations into the codebase.

MR. SIDWELL

Uh-- on this unlaunched project, are you expecting to need the cost of the hardware, or are you expecting to NOT need it?

Paul

I'm fairly confident we can stop throwing hardware at a software optimization problem.

boss

That's besides the point. Right now, at this moment, we're colo'ing the servers that we own and operate at XYZ Server Farms.

MR. SIDWELL

Thank you, that's what I needed to know. I think we can continue on upstairs.

boss

Yes, of course.

SOUND: footsteps going back upstairs

paul

Potential new clients. That's good. Could always use the extra work.

SOUND: office typing

MARK

(under breath to self)

don't say anything don't say anything come on cal just keep to your own self- grrr---

(out loud)

Uh, hey, Paul is it?

paul

Yes?

MARK

Look, I know freelancers and fulltimers are supposed to be mortal enemies, but I just hate thinking there's bad blood in the water or anything, so I want to just extend an olive branch.

paul

Uh-- okay? Not sure what you mean, but thanks?

MARK

It's just that I was told-- like, my understanding was the dev team wasn't so keen on help and-- you know what, never mind. Just new-guy nerves. Forget it. Anyways, I don't mean to step out of line or anything-- but what you were talking about just now. About the optimization in the persistence layer. I noticed it being sluggish too but didn't want to say anything and ruffle the wrong feathers...

paul

I really have to stop bringing it up. Kyle's design is the design, and the Team Lead has spoken, y'know.

MARK

Yeah, but it's just us talking, smart dev to smart dev, huh? The performacne just felt odd for a single user. What's up with that?

paul

I-- {hesitate}-- okay, it's this. Every section of each page is it's own little module, right?

MARK

Like a user-control?

paul

Yes, exactly. It's just one bit of the data the user needs. Like a name field, or their address, or phone number, or birthdate, right? Seems right-- keep things small and isolated and with minimal responsibility. Very modular.

MARK

Except...?

paul

(Getting really into it now, excited to be able to actually talk shop with a peer AND get his thoughts out instead of shut down)

Except that they're all being a bit TOO isolated. Each one of them goes into the database and gets the thing it represents. But, like, the whole thing. So the name field gets the entire Person object. So does the birthday field. And so on for every field on the screen. And when it gets persisted back to the database-- all those controls load the original Person again, and check to see if the value of that one field has changed. If it has, it will modify the Person object, and persist the entire Person back into the database. And there's this whole other chunk of logic that keeps collisions from happening-- like the name control changes the name and persists the Person but if the Birthday control had already persisted the Person, how do you keep the name control from wiping out the Birthday. And all that doesn't matter because if you're counting, every field will load the Person object twice and write it once.

MARK

Multiple that by the number of controls on the page...

paul

more than multiple, since the "who else has updated" logic makes every control talk to every other control, so it actually grows expotentially

MARK

... and the checkout page has a ton of information fields-- name, shipping address,billing address, payment-- more. Yikes.

paul

Exactly. So I want to see if there's a way to instead bring up a single copy of the entire Person object and hold it in memory, then have each field be responsible for modifying just their own bit of information in the held object-- and after all controls have had a chance to make modifications, then and only then perist the single instance of that Person. One read, one write.

MARK

That'd eliminate a ton of database calls...

paul

... and also eliminate the need for provisioning expensive hardware just to deal with all that un-needed work.

MARK

Sounds like a good idea.

paul

Nah-- just in theory, I suppose. The way the project is designed to abstract and compose disperate pieces of information together-- trying to simplify that defeats the entire design philosophy of the entire system.

MARK

(thoughtful)

I dunno. Yeah, it might be a bit of extra work up front-- but think about how much more versitile it'd be with a flexible peristence system that doesn't destory hardware resources.

paul

Nah-- Kyle's already reviewed and rejected various proposals to implement versions of that system.

MARK

huh, maybe if we draw one up together-- like, more than just how to do it, but, like, a cost:benefit section, too. Get that in front of the Boss during a design meeting?

paul

We don't really have design meetings like that. The boss is always so busy with the business end of things. Kyle's the Team Lead to keep that seperation of dev and business, so the boss can just focus on growing the company.

MARK

Maybe we should give it one try anyways. Y'know, fresh eyes, fresh mind, etc? Get a solid design to convince Kyle, and a really hammer home the short AND long term cost benefits to the boss.

paul

... you know what, sure, let's give it a shot. I--

SOUND: footsteps coming down stairs, knock on the wall

andris

Eh, hello? Looking for someone to find?

paul

Hi, come on down. Andris, right? The contractor.

andris

Yes, Andris The Contractor. Looking for Kyle The Guy Who Needs To Pay Andris The Contractor.

paul

Oh, um-- he's on a service call at the moment.

andris

Is this his desk?

paul

Yes. Do you want ot leave him a message or somethign?

andris

(pulls up a chair, very causal yet obstinent)

No "something" needed. I'll wait.

paul

O--kay. I'm not sure how long he'll be.

andris

I have fully charged phone and just installed Unhappy Avians. I can wait.

paul

If this is about an invoice, I can get Trish our Office Manager for you.

andris

This is Trish, the office manager who is also every other job all at once and none of them well?

paul

I think she does a good jobs-- a good job. Yes, that's her.

andris

Then no. I'll wait. Here. For Kyle.

MARK

Would it help if I called his cell for you?

andris

He don't answer when I call. But if you want to call from this office phone then yes. Call.

PAUl

You have Kyle's cell number?

MARK

You don't?

paul

... dial 9 for an outside line.

SOUND: dialing phone, picks up. background noise is very faint traffic. kyle is inside a car, but not driving.

KYLE

Go for Kyle.

MARK

Hi, Kyle, it's Cal and--

KYLE

My favorite Cal of the day! What up?

MARK

Hey, I'm at your desk and I have you on speaker with myself, Paul and Andris is here, too.

SOUND: as soon as andris name is said, sounds like phone is fumbling, car door opens, traffic noise is much louder, like standing next to a freeway

andris

Mr. Kyle, as he said this is Andris. Do you know what the phrase "Net 15" means?

KYLE

(very deliberately talking loud)

What? Sorry, this traffic is too loud, I can't hear you very well.

andris

(also deliberately talking louder)

"Net 15" does not mean "bounce check on day 15 then assume now Net 16 and counting is good".

KYLE

I'm sorry, I can't make out anythign you're saying!

andris

Your invoice! It's due!

KYLE

Listen, I'm about to go into the XYZ's Servers colo building, and I don't get any cell signal in there and I don't know when I'll be out.

andris

This only works once! I leave now. I be back tomorrow to talk about Net 17 late fees.

KYLE

Heading in now, I'll tal-- {phone cuts out}

SOUND: Hang up office phone

paul

If you're coming back tomorrow, he's usually in by 10am.

andris

He's coming back today. I wait.

paul

But you told Kyle you were leaving.

andris

Yes I did. He thinks I'm gone, he thinks he can come back. I wait.

MARK

Paul, maybe we should just keep working and let Kyle deal with this when he comes back.

andris

Yes, you go back to work. I go back to Unhappy Avians.

SOUND: video game sounds that fade as cal and paul go back to their workstation

paul

So, about the optimizations...

SCENE: 5

NARRATOR

Mark and Paul worked on optimizing the performance of the project in lieu of Kyle’s absence… and Andris worked on optimizing his high score in spite of that same absence. As lunchtime approached, Mark wondered if Andris would be better served coming back another day. But, as accurately as Andris could knock out verdant swine, he was just as correct about Kyle’s return.

KYLE

Good lunch time, everyone! I brought pizza, courtesy of all y'all doing a job well done and...

andris

Does that pizza bounce like check?

KYLE

Oh-- uh hi, Andris, wasn't expecting you.

andris

That was on purpose.

KYLE

(puts down the pizza)

Sorry, did you your check bounced? Oh jeeze, I'm sorry. You should have called before coming all the way out here.

andris

Again, that is on purpose. Checks don't get lost in mail when face-to-face.

KYLE

I understand your frustration. I'm angry too that the bank would do this to you. I'm going to get in touch with them right away. Heck, I'll go over in person. Get them to clean up their mess. You have my word.

andris

Hmm. Your word. My business is fairly new business. Outstanding invoices aren't good for growing business. Does your word pay my vendors, cover my payroll?

KYLE

Hey, I don't think I like that tone you're taking. You want to be mad at a bank, be mad at a bank. But that doesn't give you any right to come in here, attacking me and accusing me of anything when I'm acting in good faith.

andris

Funny thing about my company. Started recently-- but worked many years for other companies. Lots of big jobs. Some even needed wiring done in server colos. XYZ's most popular local one. So yeah I know there's no cell signal inside. I also know building isn't anywhere near the freeway.

(beat of silence)

KYLE

Look, Andris, I--

ANDRIS

Words blah blah blah. If that's the truth of your word, then maybe your words about office manager Trish also just as true. She can fix everythign up.

KYLE

No. Wait-- WAIT. Stop. Listen. I-- Yes, you are right. I wasn't at the colo. And I know what wrong-headed conclusion all y'all are thinking right now, "Was he ever at the colo anytime before". Yes, I was thank you very much-- except a couple times recently. And yes, this time included. I was-- well, let's just say I met a girl recently with the two best features a girl can have: she lives close to the office-- and is horny aaaaaaall the time. So I admit, I wasn't doing my job at the server farm-- I was on an extended lunch break, drilling for honey.

(again, stunned silence)

KYLE

Andris, my friend, from the bottom of my heart, I am sorry this invoice got so screwed up. The bank messed up so bad, and I'm ashamed on their behalf. I'm going to get on their case about it. Today. But as an act of goodwill-- here--

SOUND: desk drawer opening, ledger put on desk

KYLE

I'm going to write you a check straight from the department's discretionary funds. It's most of our operating budget but-- different account, different bank. I'm post-dating it to before the Net30 penalties kick in.

SOUND: tearing sheet, handing over

KYLE

You hold onto that. If the bank doesn't fix things, don't even hesitate. Deposit that. I'll worry about the rest. Okay?

(A bit of silence)

andris

(reulctantly, a bit suspicious)

Yes, okay. {sound of check being put into pocket}. But if anything goes wrong-- if I get even a whiff of doubt in my nose-- next you hear from me will be through lawyers.

KYLE

Understood. Thank you for working with me. I'll walk you out.

SOUND: two sets of footsteps going up

KYLE

Looks like Trish is out for lunch, but you know what? I'm going to take a page from your book. I'm going to go sit in her office, and I'm not moving until I can confront her face to face about how our banks can screw up so badly.

SOUND: door opening, can hear some mild traffic outside

KYLE

Be in touch.

ANDRIS

Hmm, yes.

SOUND: door closing, but still hearing the traffic sound, we are outside with andris. heavy footsteps as he is walking away. hear a car pull up, door open, female footsteps come out

trish

Mr. Andris, nice to see you again.

andris

Trish the Office Manager and Every Other Job, nice to see you, too. Must be going, good day.

trish

You too. {pause a bit} Is everything okay? I thought all the work was done.

andris

Funny story. I've worked with many men, most the same. Big, dumb, but good at what they do. The ones who can do-- they do by showing you. The ones who brag about how many nails and screws they've done-- they're telling you not what they've shown. And the ones who are only as good by comparing themselves to how bad others are-- well. Different sewer, same boat.

trish

That's-- a story?

andris

Yes. Moral is, I think you can handle me telling you check bounced.

trish

The hell? And I mean double "the hell?" because I haven't even gotten your invoice yet.

andris

Was dealing directly with Mr. Kyle. Implied he was better suited to dealing with than you.

trish

I mean-- I have been swamped so-- that's a bit true.

andris

Availability to do your job wasn't what was implied when he said he was better.

trish

Huh? Oh-- yeah, keeping my head down. I appreciate you guys looking out for me and keeping the bad news away from the boss but still-- a bounced check is maybe something I should be on top of? But if Kyle's handling it-- I don't know.

andris

Don't matter. Trish the office manager and also many other jobs, since bookkeeper is one of them-- here.

SOUND: Handing over an envelope

ANDRIS

Is the bounced check. My business is too small to keep that much in limbo. I feel you'll show me different than I've been told. But still-- I'll hold my collatoral, just in case.

trish

Yes, sure, Mr. Andris. This is the first I'm hearing of this, so let me look into it and I'll get back to you.

ANDRIS

Appreciations. Good day.

SOUND: heavy footsteps going away, truck start and drive away

trish

(while walking, talking to herself)

Wait-- "Bank of First Trust"? Why have I never heard of this bank? Or this account? Where is this coming from? Is this why the boss would be so angry with airquote "bad news"? What's he hiding?

SOUND: Door opening, boss and mr soandso coming out

boss

I think this is the best deal we can both hope for.

MR. SIDWELL

It is. Thank you for working with me. I'll run the numbers past my people and I should be back with a final answer in a day or two.

boss

Thanks, see you then. (pause) Oh, hi Trish, how was lunch.

trish

Huh? Oh, it was fine. New business contact?

boss

Of sorts, we'll see.

SOUND: them both going back inside

trish

Hey, boss-- got a minute?

boss

Never, but always have one for you. What's up?

trish

Can I close your door

boss

Um-- sure?

SOUND: door close

Boss

What is it?

trish

I-- Okay, I know this is against my better judgement-- and if you want to be angry, please just come right out and be angry to my face-- but I'd rather be fired for doing my job than have to live with compromising to keep it.

boss

I don't know where this is coming from?

trish

Okay, right flat out-- if you want me to be able to do my job right, I need to know everything there is to know about the company and it's finances.

boss

Oh. Uh, this is about Mr. SoAndSo...

trish

(Angry, feels like he's deflecting)

No! This, damnit.

SOUND: slaming on table

trish

This check-- from "Bank of First Trust". I didn't even know we had accounts with them! I have to know about everything-- every account and ledger and invoice that goes in our out.

boss

(sudden burst of anger)

Of course you should know, because that's your damn job, Trish, not mine! I can't handle everything!

trish

I see.

boss

(sobering up)

Trish, I'm sorry. No, you're right you are absolutely right. You do need to know and everything's a mess and I can't even make it right for you and it's all my fault.

trish

(taken aback, she was expecting anger, not co-operation)

Boss, sorry, I didn't mean to come of that harsh, it's just--

boss

-- I know, I know. It's the stress. I'm stressed with all these meetings. And-- Trish you must be going out of your mind trying to put all the books together. Honestly, I don't recognize the bank either, but my understanding of the books is worth as much as-- well, as that bounced check. They're a mess and my ass is covered in bites because of it. You need a proper ERP-- not random assortments of Quicken and Multiledger and 4th Dimension and Excel and probably some WordPerfect 5.0 and who knows what else. Everything was already a mess to begin with, and then it got worse and you got to inherit an incomprehnsible tangle of hair in a drain. I don’t envy you having to deal with the mess the last girl left behind.

trish

So my predecessor -- she really did quit and leave you in a lurch?

boss

Yeah, and worst is I don’t know what I did wrong by her. She was doing a great job. Went above-and-beyond, staying late to work hand-in-hand with dev team to get in-house ERP off the ground—- I tell you, if we had that to run everything end-to-end we wouldn’t have all these issues with everything books spread across dispirate systems. Even was going to shorten her probationary period so I could get her full time and on benefits. Then poof gone. Guess you never really know what drives another person, huh? Trying to dev an ERP without someone with domain knowledge is orders of magnitude harder, y’know? And by then, work for clients and the need for billable hours was piling up-- I couldn't justify keeping billable resources on an internal project. And here we are.

(Exhasperated)

Boss

Anyways—I’m sure you’ll figure it out. You’re good at your job—wouldn’t have hired you if you weren’t. I trust you and honestly, with everything I need to juggle right now—you being able to run with things on your own is exactly what I need—wouldn’t want it any other way.

trish

... thanks, boss. I think I really needed to hear that.

boss

Anytime.

trish

Door open?

boss

Please.

SOUND: footsteps in the hall

KYLE

Trish, just the person I wanted to see

trish

Yeah, same here. What about?

KYLE

Andris was lurking around earlier harassing the dev team because of a bank screw-up. Just wanted to let you know I've got everything under control-- one less thing for you to worry about and of course one less thing to-- y'know-- bad news shield and all.

trish

(Oh she's suspicious now)

Really, is that so? Because--

SOUND: footsteps coming upstairs, excited

paul

(interrupting)

Kyle, Boss, everyone's here, good.

MARK

We've worked out something amazing.

boss

Uh, can it wait, I'm a bit busy--

paul

(excited, him and cal are talking over each other's sentences-- yeah, they are brilliant but still very excitable and awkward)

No, see, that's it. We can wait, but shouldn't. It's performance optimization

MARK

-- hundred-fold decrease in processing times--

paul

-- cost:benefit is through the roof, like actual real numbers--

MARK

-- yes, exactly, we're talking every hour now saves fifty in dev and five hundred in support and hardware--

paul

-- ESPECIALLY hardware

KYLE

(dawning on him)

What are you two talking about?

paul

The performance problems with persestance. We've got a solution! It'll just take a major refactoring of the persistence layer, but we don't have to touch the UI or DB!

KYLE

(pauses a beat, then just literally laughs at them)

Oh for the love of everything lovable, you are STILL banging on about that? And you think NOW is the time to bring it up?

MARK

-- no really it sounds dumb to want to refactor this much now but I peer reviewed the idea--

KYLE

No. You have no idea the history behind this. I told you to keep this one at arm's length or else he'll draw you into a dead end that WE'VE ALREADY AGREED NOT TO FOLLOW.

paul

Boss, you've got to listen, seriously, this implementation is incredible AND money saving. Here, like, okay, there's all these parts to the page and each piece is responsible for it's own--

boss

Guys. All of you. Stop. I'm dealing with life and death business decisions right now. Why am I being dragged into a design session? You're the coders. You figure it out.

KYLE

Sorry boss, this shouldn't even be an issue. We already have a solid design and agreed not to change it.

paul

No YOU pulled rank and made a decision as Team Leader to ignore it, but I'm telling you, if you were right or wrong, it's different this timem and--

boss

Hang on-- rank? Team leader? That isn't how your department runs. You’re all equals on the team. There is no team lead.

(Oh the stunned silence this time)

paul

But—Kyle is the team lead. He has been ever since I was hired on with the others on the dev team. He’s said so himself.

KYLE

I’ve never said any such thing!

paul

I—but—you are—you have said so.

BOSS

What’s this about, Kyle?

KYLE

What do you mean “what’s this about”? There’s nothing “about”—and I have no idea what Paul mistakenly believes what’s “about”. What—you want to start recording everything said in the dev room so we can all hear when Paul mistakes what he’s heard. I mean, sure, we’ll have to sift through hundreds of hours of listening to Paul make mistakes with literally everything else he does, but sure. That’ll be a great use of everyone’s time! Hey, maybe we should march all the other devs up here and grill them too, get them to remember everything I’ve ever said, word-for-word, since they started working here, huh?

boss

Kyle, you know that isn’t what anyone’s talking about. No one is accusing you of lying.

paul

Well—I mean—no, I’m not—but—maybe—well, just after the server colo thing I—

KYLE

OH. MY. FLIPPING. GOURD. You are desperate to stir up the monkey barrel, aren’t you? I try to do my job—more than my job because of all the times I have to clean up everyone else’s messes—and the first chance you get you just jump right onto the knife and rally everyone up against me, huh? After all the times I covered for your mistakes and protected you—took responsibility for code that was your fault—took it for the TEAM—this is what you’re doing? See, Cal? Didn’t I tell you to watch out for this one?

MARK

Well—uh—to be fair, I kindof sortof got the impression that you were a team lead, too.

KYLE

Yup, there it is. Dogpile Kyle day’s here, everyone line up and put on your cleats. So tell me, Mr. New Guy Who Hasn’t Even Been Here A Month—tell me, when did the words “I am the team lead” come out of my mouth? Huh?

MARK

I mean, it might not have been those exact words, but the context—

KYLE

So it’s your SUBJECTIVE OPINION that you think I’m the team lead? Based on nothing.

MARK

Just you seemed to be in charge of all the projects and—

KYLE

: So based on the fact that I’m the one doing my damn job properly? Because I’m the one who has the most knowledge of the codebase—the most time put into designing it? I guess putting in the work to be knowledgabel and competent is a BAD THING now, huh? Well, I’m sorry if I’m the only one who is actually DEDICATED to this company and the projects, and I’m sorry you can’t tell the difference between a titled position and just someone with more knowledge because of seniority.

boss

Okay, everyone, calm down, this is out of hand. I don’t care who is what, I don’t want to hear any more about positions or code or design, I just want this project done. Quickly. So we can ship it before it’s too late.

KYLE

Exactly. Let’s stop wasting everyone’s time here and maybe we can all just forget this happened.

trish

Wait, hang on. “Seniority”? You only started two weeks before everyone else on the dev team.

boss

Huh. That’s right. Only two weeks before.

KYLE

Well thank you Miss Can Barely Keep the Books Straight, you managed to actually get one thing right. Two weeks is a lifetime in development time and that isn’t even counting how much someone can learn when they’re an EXPERT in their field.

trish

You know what—you’re right about that. You are. Two weeks is time enough for someone who is good at their job to accomplish a lot. Like untangling a jumbled knot of books and ledgers—and trying to balance out expense accounts against budgets. Which to the point I wanted to me—

KYLE

You too, Trish? {sounding now sad, verge of crying / breakdown} Of course. Sure. I get it. I do my best to help you, and this is what I get from you—same as I get from everyone else. Is this what you all want from me? Poke and prod at any tiny flaw and rip it open? Fine. You win. What do you want to hear? That I’m a “team lead”? Since we’re all calling being a mentor and resource to everyone a “team lead”? That trying to inspire everyone to rise to their potential so that we’re all “equals” in being great? Guilty. Horrible awful me, I’m a team lead. Congratulations, you called me out!

boss

Okay, this is enough. I’ve heard enough. Everyone stop now.

KYLE

{now sounding broken} No, no it’s okay. Yes, I admit, I took on the responsibly of team lead – and I’m willing to admit also—maybe I felt I’d deserved that role. That I earned it. But I understand—it wasn’t my title to self-appoint. Not in a team environment like this. I know I’ve betrayed your trust. Just understand it was only with the best intentions. It’s an explanation, not an excuse—not that I’d expect any excuse to be accepted or forgiven granted. All this—all this anger towards me, it couldn’t have just come out of nowhere. If it’s been building to this point for this long—I’m sorry I’ve let the whole team down, and I’ll save you all from having to say when I knew we’ve all concluded. I need to not be here anymore. I’ll have my letter of resignation to you by the end of the day.

boss

Kyle, that isn’t what any of us want.

KYLE

I think if you think about it—yeah, it kinda is what everyone wants. I’ve made up my mind. I’ll start the transitional handover but—if it’s okay with you, maybe we can start it tomorrow morning. Right now I just—I just want to go home and be alone for the rest of the day.

boss

Uh, yeah, sure. I’m sorry I let things get to this point, Kyle—sorry everyone.

SOUND: people getting up and leaving, Kyle walking out the door

trish

Well, that didn’t got as I expected but for some reason I can’t quite put my finger on—I’m not surprised.

SCENE: 6

(Narrator)

narrator

The next morning, Mark reviewed his E.R.P. specs and designs. He wanted to be aware of everything he didn’t know, so he could learn as much as possible in the time Kyle had left. For someone with as much knowledge of a custom system as Kyle had, no matter how much time there may be to transfer that knowledge, Kyle would surely leave with some of it. Initech would just have to deal with those problems after Kyle left. But—no one could have forseen that the real problem would be what Kyle would leave behind.

SCENE: 7

(back in the office)

trish

Hey, Paul, sorry to interrupt, just looking for Kyle.

paul

He isn’t in yet. If you want to stick around, he’s always in by 10. Well, usually in by 10. Mostly, come to think of it.

MARK

Unless he’s off rebooting a server.

paul

Or booting up into someone’s console, right?

MARK

hehe—yeah, we probably should stop that. I already feel bad enough about how this all shook down.

paul

Yeah. All things considered, we did kinda screw ourselves in the foot. I just wanted to get him to accept a solution to a problem. I didn’t know he was feeling so—attacked. I feel a right jerk.

trish

Yeah. Well, boss said I could offer him four weeks-notice—which is more than enough time to either transfer his knowledge—or work to the deadline of the project. It’s kind of gives him an out without having to feel like he’s “giving in” or whatever. It’s all such a stupid situation.

MARK

Didn’t think I’d be here longer than him. Which reminds me—I get these was no official “team lead” role and all, but technically my contract still had me working directly under Kyle. Who should I be reporting directly to now, since it won’t be him?

trish

You heard the boss. Team’s a team so—wait, what do you mean ‘rest of your contract’? You’re fulltime.

MARK

Uh, no, definitely not. Freelance, six months.

trish

No, you're in the system as an employee. Salaried. Just like everyone else who works here.

MARK

I have my contract here in my briefcase. Look…

trish

That—that’s not what our employment contracts look like. None of this is right. I don’t know what this is.

MARK

Well, no offense, but maybe weird inconsistencies like this is why your company’s got me building you a new ERP.

trish

Yeah, finishing off that ERP project would really help at this point.

paul

um, what? Why aren’t you using the one we already built?

trish

There isn't one as far as I know. The project stalled out.

paul

Bull. We finished it MONTHS ago.

MARK

Well—maybe it didn’t work well enough, so that’s why I was brought in to fix it up?

paul

There is nothing to fix! It’s working. I helped install it, get all the data imports working. Everything’s running off it—payroll, accounting, HR—everything!

trish

I’ve never seen anything like that. If I had, I wouldn’t be missing things like any employment contract or… uh-oh.

MARK

Look, I don’t know what’s what with this—all I know is my contract was to come in and spend six months building an ERP from scratch. I never heard of another version—in production or in the trash bin.

trish

Oh no. Do you have a paystub on hand?

MARK

Yeah, got one here too—here. Why?

trish

Bank of First Trust—what? Oh no oh no. Both of you, to my office now.

SOUND: footsteps, computer

trish

Cal, this is the information I have for your payroll. I’m guessing that direct deposit information isn’t familiar?

MARK

I don’t have my bank details memorized but—no, because my account isn’t with the Bank of First—Trust. Oh.

trish

This isn’t good. I was given false account information for an employee who effectively doesn’t exist.

MARK

And my paycheck’s been coming in fine, so I’m being paid from an account you don’t control?

paul

And only one person had complete and total access to an ERP with all the company’s financial information.

Trish

Embezzlement.

paul

Embezzlement-- but I don’t understand— if Kyle wass stealing money, then why is the amount that’s going from Company into his account much less than the amount Kyle's giving from his account to Cal?

MARK

Hey, I’m not part of this if that’s what you’re thinking! I’ll co-operate with any investigation.

trish

You’re right, that doesn’t make any sense—same as why he’d report this amount for the wiring upgrades—but then pay the contractor this much, much larger amount. It’d normally be the other way around, and he’d pocket the difference.

paul

I know I’m not the best judge of character, given how easily I was duped by Kyle—but even so, Andris doesn’t strike me as someone who'd go along with a scam.

trish

We can let the authorities sort this all out later. We need to go to the Boss. Now.

SOUND: rushing footsteps, opening boss door. boss and Mr. SIDWELL are having ipsum lorem talk

trish

Sorry to interrupt, Boss, but something’s come up.

boss

This isn’t a good time, I’m in a meeting.

trish

I don’t mean to take you away from a client meeting, but this is quite urgent.

boss

No, really, all of you, I can't do anything right now.

trish

But boss, it's about our financies...

boss

(finally breaks)

Finances don’t matter anymore—sigh--. I was hoping to break this lightly but—this is Mr. SoAndSo from Waterbond Liquidators. We’re out of money. Everyone give Mr. SoAndSo all your company property and passwords, and then go home. We’re done. We’re all done.

SCENE: 8

(narrator)

narrator

Initech’s vendors and creditors were already in line to collect what they could from the liquidator. All they cared about was recovering their losses—not how the losses occurred. The liquidator company took their cut. No one cared to look at the financial records. Had they looked, they would have seen checks written to Kyle that were never logged in the ledgers. If they had checked the middle of any interaction with Initech and its vendors, they would have seen Kyle in the middle—recording a $100 invoice as $90, and keeping that extra $10. Had they checked employment records, they would have seen the termination note given to the previous office manager who was getting too nosey, signed by Kyle—and the resignation notice that he had logged instead.

But that was only half the story those books would have told. Because at some point, they would have seen Kyle’s exit strategy. Lines of credits opened in Initech’s name, quickly drained and sent into overdraft. Vendors given lucrative, above-market-value contracts for goods and services. Even a certain six-month contract given to a junior developer, whose primary role would be to keep everyone’s attention away from even thinking about an ERP. Money silently hemorrhaging from the company, and debts piled up out of control. As Mark, Paul and Trish had observerd— Kyle was spending more money than he was taking for himself.

That was intentional. Because when the writing was on the wall, and that writing said “Look, everyone, Kyle is embezzling money!”—Kyle had done the only sensible, logical thing for a sociopathic thief to do: torch the wall, and burn the wall’s building down to ash and cinders.

Before anyone could even be aware of what was happening, the company was bankrupt. Creditors only wanted as much repayment as they could get from near-empty accounts, and whatever the office equipment would sell for. The books were closed for good. Even if anyone had cared to investigate Kyle—if that had even been his real name-- and his many personal accounts were gone, leaving only fake addresses behind.

In the end, there was far less than nothing left of Initech—only the crater left by the destructive force of a confident liar.

narrator

For the Daily W.T.F., that was “Confidence”, a story written and adapted for radio by Lorne Kates.

In order of appearance:

  • Remy Porter was “Kyle”
  • Adam S. was “Mark”
  • Ulf S. was “Andris”
  • Kacper M. was “Paul”
  • Jane Bailey was “Trish”
  • Lorne Kates was “The Boss”
  • and Alex Papadimoulis was “Mr. Sidwell”

Theme song was “Slow Burn” by Kevin MacLoud of Incompetech.com

Lorne and everyone at The Daily WTF dedicate this episode to the memory of Paul Rousse

I’m your announcer, Heather. This has been a W.T.F. Radio presentation.

[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!

https://thedailywtf.com/articles/radio-wtf-confidence


Ìåòêè:  

Ïîèñê ñîîáùåíèé â rss_thedaily_wtf
Ñòðàíèöû: 124 ... 77 76 [75] 74 73 ..
.. 1 Êàëåíäàðü