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

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

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

Editor's Soapbox: Give Thanks for Well Routed Packets

Четверг, 23 Ноября 2017 г. 14:30 + в цитатник

It’s Thanksgiving here in the US, so we’re taking a long weekend. In lieu of a more traditional “from the archives” post, I’m going to give thanks.

You know what I’m thankful for? I’m thankful that data packets on the Internet are routed and handled the same way, regardless of which network originated them, nor which network is their destination, nor what they may contain. You could say that networks are… neutral about packets.

A parody of the Gadsden flag that is an ethernet cable poised like a snake

A few years ago, the FCC enshrined this common sense into its regulatory framework. We were all pretty happy about it, and were optimistic that it was done. Unfortunately, it’s never over, and the new management at the FCC wants to reverse that, and plans to vote about it in a few weeks.

Remember: prior to making Network Neutrality the regulated standard, network operators largely (but not completely) followed the rule anyway. Network Neutrality was the default, and then the bean-counters recognized an unexploited revenue stream (why should Netflix get to send data to our customers without paying us for the privilege?). The Internet worked under Network Neutrality, and the FCC only needed to enforce it by rule because network operators wanted to change the playing field.

In any case, if you’re thankful for an Internet that works, between gorging yourself in typical American fashion and arguing with your racist uncle, take a few minutes to do something about network neutrality.

I’d be ever so thankful if you did.

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

https://thedailywtf.com/articles/give-thanks-for-well-routed-packets


Метки:  

CodeSOD: Arrject

Среда, 22 Ноября 2017 г. 14:30 + в цитатник

There are some submissions that we get, and we simply sit on, because there’s nothing much to say about them. They’re awful code, but there’s no major comments to be added. It’s clear and simple in its awfulness.

For example, you have some code that needs to display details about colleges around the US. Each College has a name, a full name, a short name, a state and city where it exists, and full names for those states and cities. You are likely reaching for an object to store that information, but why do that, when you can employ what I call the “Arrject Pattern”. Y’know, when instead of using objects, you use multiple arrays and store related data at the same index? Stuff like what Kevin found in his codebase:

var schoolNames = new Array();
var schoolFullNames = new Array();
var schoolShortNames = new Array();
var schoolStates = new Array();
var schoolCities = new Array();
var schoolStateFullNames = new Array();
var schoolCityFullNames = new Array();

schoolNames[0] = "fsu";
schoolFullNames[0] = "Florida State University";
schoolShortNames[0] = "FSU";
schoolStates[0] = "fl";
schoolCities[0] = "tallahassee";
schoolStateFullNames[0] = "Florida";
schoolCityFullNames[0] = "Tallahassee";
schoolNames[1] = "tamu";
schoolFullNames[1] = "Texas A&M University";
schoolShortNames[1] = "Texas A&M";
schoolStates[1] = "tx";
schoolCities[1] = "college-station";
schoolStateFullNames[1] = "Texas";
schoolCityFullNames[1] = "College Station";
schoolNames[2] = "txstate";
schoolFullNames[2] = "Texas State University";
schoolShortNames[2] = "TX State";
schoolStates[2] = "tx";
schoolCities[2] = "san-marcos";
schoolStateFullNames[2] = "Texas";
schoolCityFullNames[2] = "San Marcos";
schoolNames[3] = "uaz";
schoolFullNames[3] = "University of Arizona";
schoolShortNames[3] = "U of A";
schoolStates[3] = "az";
schoolCities[3] = "tuscon";
schoolStateFullNames[3] = "Arizona";
schoolCityFullNames[3] = "Tuscon";
schoolNames[4] = "ucf";
schoolFullNames[4] = "University of Central Florida";
schoolShortNames[4] = "UCF";
schoolStates[4] = "fl";
schoolCities[4] = "orlando";
schoolStateFullNames[4] = "Florida";
schoolCityFullNames[4] = "Orlando";
schoolNames[5] = "ufl";
schoolFullNames[5] = "University of Florida";
schoolShortNames[5] = "UF";
schoolStates[5] = "fl";
schoolCities[5] = "gainesville";
schoolStateFullNames[5] = "Florida";
schoolCityFullNames[5] = "Gainesville";
schoolNames[6] = "uiuc";
schoolFullNames[6] = "University of Illinois at Urbana-Champaign";
schoolShortNames[6] = "U of I";
schoolStates[6] = "il";
schoolCities[6] = "urbana-champaign";
schoolStateFullNames[6] = "Illinois";
schoolCityFullNames[6] = "Urbana-Champaign";
schoolNames[7] = "uky";
schoolFullNames[7] = "University of Kentucky";
schoolShortNames[7] = "UK";
schoolStates[7] = "ky";
schoolCities[7] = "lexington";
schoolStateFullNames[7] = "Kentucky";
schoolCityFullNames[7] = "Lexington";
schoolNames[8] = "mizzou";
schoolFullNames[8] = "University of Missouri";
schoolShortNames[8] = "MIZZOU";
schoolStates[8] = "mo";
schoolCities[8] = "columbia";
schoolStateFullNames[8] = "Missouri";
schoolCityFullNames[8] = "Columbia";
schoolNames[9] = "usc";
schoolFullNames[9] = "University of Southern California";
schoolShortNames[9] = "USC";
schoolStates[9] = "ca";
schoolCities[9] = "los-angeles";
schoolStateFullNames[9] = "California";
schoolCityFullNames[9] = "Los Angeles";
schoolNames[10] = "ut";
schoolFullNames[10] = "University of Texas at Austin";
schoolShortNames[10] = "UT Austin";
schoolStates[10] = "tx";
schoolCities[10] = "austin";
schoolStateFullNames[10] = "Texas";
schoolCityFullNames[10] = "Austin";
schoolNames[11] = "utsa";
schoolFullNames[11] = "University of Texas at San Antonio";
schoolShortNames[11] = "UTSA";
schoolStates[11] = "tx";
schoolCities[11] = "san-antonio";
schoolStateFullNames[11] = "Texas";
schoolCityFullNames[11] = "San Antonio";

function showSearchResults(event, searchval) {

        var numResults = 0;
        var key = (event.keyCode || event.which);
        var results = "";
  var firstresult = "";
  if(searchval.length > 0) {
    var searchvalfixed = searchval.toLowerCase();
    if(searchvalfixed.indexOf("the") == 0) {
      searchvalfixed = searchvalfixed.substr(3);
    }
    searchvalfixed = searchvalfixed.trim();
    for(var i = 0; i < schoolNames.length; i++) {
      if(schoolFullNames[i].toLowerCase().indexOf(searchvalfixed) != -1 ||
         schoolShortNames[i].toLowerCase().indexOf(searchvalfixed) != -1 ||
         schoolCities[i].toLowerCase().indexOf(searchvalfixed) != -1 ||
         schoolStates[i].toLowerCase().indexOf(searchvalfixed) != -1 ||
         schoolStateFullNames[i].toLowerCase().indexOf(searchvalfixed) != -1 ||
         schoolShortNames[i].toLowerCase().indexOf(searchvalfixed) != -1 ||
         schoolCityFullNames[i].toLowerCase().indexOf(searchvalfixed) != -1) {
                 numResults++;
         results += "" + schoolFullNames[i] + "
"; if(firstresult.length == 0) { firstresult = schoolNames[i]; } } } if(numResults){ $("#resultsContainer").fadeIn("slow"); document.getElementById("resultsContainer").innerHTML = results; } else { $("#resultsContainer").fadeOut("slow"); } } else { $("#resultsContainer").fadeOut("slow"); } if (key==13 && firstresult.length > 0){ location.href = firstresult; } } function fillSearch(shortName,fullName){ document.getElementById("search_landing").value = ''; document.getElementById("search_landing").value = fullName; document.getElementById("search_shortname").value = shortName; $("#resultsContainer").fadeOut(); } function goToSchool(){ if(document.getElementById("search_shortname").value) location.href = document.getElementById("search_shortname").value; }

It’s worth noting that this was inlined in the HTML file, up in the header, and not included from a separate file.

[Advertisement] Application Release Automation – build complex release pipelines all managed from one central dashboard, accessibility for the whole team. Download and learn more today!

https://thedailywtf.com/articles/arrject


Метки:  

Jumped The Gun

Вторник, 21 Ноября 2017 г. 14:30 + в цитатник

1904 Olympic sprint

Sheldon was a support engineer at Generic Media Co. In his 6 years with the company, he'd enjoyed working for several great managers—but then came the reorg. Once the dust cleared, he found himself in the wrong department, reporting to one of the most loathed individuals in the entire organization.

Gene was the type of manager who believed his fancy title awarded him instant respect. No engineer who spent any time working with him had anything good to say. Sheldon went in hoping for the best ... but Gene's relentless micromanaging and childish stunts quickly ground Sheldon's optimism into dust. When it came time for Sheldon to go on an extended vacation, he felt like a shell-shocked veteran limping out of the trenches.

The months away were bliss, but Sheldon couldn't enjoy the last few days out of dread. To his surprise, though, Gene wasn't waiting at his cubicle with twelve urgent tasks upon his return. There hadn't been a peep from Gene all vacation long: no emails, no meeting requests. It was getting close to performance review time; nothing about that, either.

As Sheldon worked through his vacation backlong, it became starkly apparent that he was being allowed to work through his vacation backlog. No panicky IMs, emails, cubicle pop-ins. The radio silence extended into days, then weeks. Sheldon began to wonder whether Gene even still worked there. Not wanting to kick a potential sleeping dragon in the nose, he asked his coworkers instead.

"Of course he's still here," one of them grumbled. "If they haven't canned him by now, they're not going to."

Soon after, Sheldon found out he had it exactly backwards.

A meeting invitation from Gene landed in his inbox. Catch-up meeting, tomorrow. No agenda, no room booked. Distracted with work, Sheldon didn't immediately accept the meeting. By the end of the day, his desk phone rang.

Gene. When had Gene ever phoned his desk? Frowning, Sheldon picked up.

"I need you to accept the invite," Gene blurted with no preamble.

It was then that Sheldon's paranoia clued him into reality. Gene still works here. I'm the one who's out. Gene's extended avoidance had been just another of his immature games. They'd never even done that performance review, had they?

"I'll be there," Sheldon muttered.

All that night, Sheldon tried to put a positive spin on the situation. A job he'd enjoyed had been ruined by a terrible manager, it was true. But he'd soon be free to look for a better job and a better manager.

Sure enough, once the meeting began, Gene smugly informed Sheldon that his role was going offshore, making him redundant. (Sheldon later found out that the offshore bit was a lie, but you didn't hear it from us.) Sheldon hoped this would be the last of their interaction, but it wasn't to be.

Fast-forward to Sheldon's second-to-last day, 4:00 PM. Sheldon was leaving to pick up his kids from school. He was on a tight schedule, as he had a train to catch. He hurried to the lobby, summoned an elevator, and darted in.

Just as he turned around, he spied Gene entering the lobby from the stairwell. Gene saw Sheldon as well, and flashed him a big smile.

Not to be cowed, Sheldon smiled right back.

Gene frowned, confused. "Do you have a minute?"

"No," Sheldon answered honestly as the elevator doors began to close.

"I need to collect your badge!" Gene yelled.

The doors shut, and the elevator began its descent. You're a day early, Sheldon thought to himself, shaking his head.

He made it to his train and boarded just in time. While shuttling along, he grabbed his phone and sent Gene a quick message via Google Hangouts. I'll be in tomorrow. You can have my badge then.

The message seemed to have trouble going through. A few moments later, the Hangout closed. You have been successfully logged out.

Strange. Sheldon switched to Slack. You have successfully signed out.

"What?" Sheldon blurted aloud.

It got him thinking. Gene had just seen him leaving the building in a hurry, grinning like a fool. Did he think Sheldon had planted a bomb or something? Sheldon had no bombs, but he did have admin access to plenty of important systems. Had Gene gotten his account terminated in a panic?

Sheldon called the IT department and confirmed his suspicions. There was even a note attached to his account, from Gene: DO NOT RE-ENABLE.

"What am I supposed to do for my last day?" Sheldon asked.

"No worries," the tech replied. "I'll roll it back."

Upon returning the next day, Sheldon learned his security badge didn't work, either. The security guard at the front desk had to call Gene for authorization. Still too much of a wimp to show his face, Gene just told him to let Sheldon through.

"He couldn't even get my last day right," Sheldon said with a chuckle.

Gene kept his distance whole day. Sheldon left at 4:00 PM again, this time headed for the whiskey bar with a few ex-colleagues to celebrate freedom.

[Advertisement] Universal Package Manager - ProGet easily integrates with your favorite Continuous Integration and Build Tools, acting as the central hub to all your essential components. Learn more today!

https://thedailywtf.com/articles/jumped-the-gun


Метки:  

CodeSOD: The Generated JavaScript

Понедельник, 20 Ноября 2017 г. 14:30 + в цитатник

Once upon a time, I discovered a bug in some JavaScript. I went off to investigate the source, only to find… the JS wasn’t coming from a file. It was being generated by a server-side method. Through string concatenation. It was a simple generation, something along the lines of:

jsCode += "location.href = 'foo?id=" + someIdField + "';\n";

Bad, but a minor WTF- and the bug was caused because someIdField contained characters which needed to be escaped. It was actually unnecessary, and I could construct the logic completely on the client-side, which is what I ended up doing in that case.

I bring that tale up, because Konstantinos T has a special case of anguish.

https://thedailywtf.com/articles/the-generated-javascript


Метки:  

Error'd: Never ASSume that You're Free from Errors

Пятница, 17 Ноября 2017 г. 14:30 + в цитатник

"This was in an email from Nest. I'm sure in some other font this shows a heartwarming image of fluffy bunnies frolicking in an energy saving Utopia, but instead, we get this," wrote Matthew W.

 

"Um...yeah, sure I guess?" writes Chris U.

 

Stuart L. wrote, "Looks like the weather has made an 8-bit turn for the worse."

 

"I had no idea that the success of entering my enrollment depended on whether or not my donkey was nearby," writes Ernie D.

 

Jamie S. writes, "What exactly are you trying to smuggle in, Fujitsu updater?"

 

"I'm the fastest man alive. Don't believe me? Check this out," writes John W.

 

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

https://thedailywtf.com/articles/never-assume-that-you-re-free-from-errors


Метки:  

CodeSOD: Delebation

Четверг, 16 Ноября 2017 г. 14:30 + в цитатник

When faced with an API or programming paradigm that requires repetitive, boilerplate code, a developer is left with two options. They may refine or adapt the API/paradigm, using the idioms of their language to make something tedious and verbose into something elegant and clear.

Or they just automate it. If you have a mile of boilerplate that’s mostly the same across the application, just generate that. It’s like copy/paste, but, y’know… automatic.

Which is why Derf Skren found this pile in their codebase:

  public abstract class ExchangeSingleData : IExchangeData
  {
    private readonly string mName;
    private readonly int mLength;

    private Dictionary mMapValidData;
    private byte[] mBuffer;

    void AddValidValue(string name, string value) {
        mMapValidData[name] = value;
    }
    //...
    //...
  }

  public class NetChangeSign : ExchangeSingleData
  {
        public const string Plus = "+";
        public const string Minus = "-";

    public NetChangeSign()
      : base("NetChangeSign", 1)
    {
            AddValidValue("Plus", Plus);
            AddValidValue("Minus", Minus);
          }
  }

  public class BidPriceSign : ExchangeSingleData
  {
        public const string Plus = "+";
        public const string Minus = "-";

    public BidPriceSign()
      : base("BidPriceSign", 1)
    {
            AddValidValue("Plus", Plus);
            AddValidValue("Minus", Minus);
          }
  }

  public class AskPriceSign : ExchangeSingleData
  {
        public const string Plus = "+";
        public const string Minus = "-";

    public AskPriceSign()
      : base("AskPriceSign", 1)
    {
            AddValidValue("Plus", Plus);
            AddValidValue("Minus", Minus);
          }
  }

  // ... and 7 more versions of the same class

The goal of this code is so that they can prepend a “+” or a “-” to a transaction’s value. Note the mBuffer in the base class- they don’t use strings (or, y’know… numbers) to represent the transaction value, but a byte array instead. The “value” is that it lets them write a line like this:

lMessage.NetChangeSign.SetValue(GeneratePriceSign(lPrice));

Which allows the instance stored in NetChangeSign to flip that +/- based on the return value of GeneratePriceSign. Obviously, this lets the NetChangeSign instance have full control of the logic of how the sign gets set, right? I mean, each instance has its own map that contains all the allowed values, right? Well… sure, but how do they decide? Based on GeneratePriceSign… which looks like this:

  private static string GeneratePriceSign(Side aSide)
  {
    if (aSide.Equals(Side.Buy))
      return "+";
    else
      return "-";
  }

In design patterns terms, we call this “delebation”. It’s like delegation, but only the person doing it to themselves enjoys it.

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

https://thedailywtf.com/articles/delebation


Метки:  

The For While Loop

Среда, 15 Ноября 2017 г. 14:30 + в цитатник

Alex R. was the architect of a brand spanking new system that was to read inputs from numerous other internal systems, crunch a whole bunch of numbers, record everything in a database and spew forth a massive report file. He spent months designing the major details of the system, and more months designing the various sub-components. From all this came a variety of business-level data structures which spawned POJOs and the underlying DB tables to store assorted inputs, flags and outputs. He did a fairly thorough job of documenting all the interfaces, and provided detailed specifications for all of the next-level methods that were left as TBDs in the design.

Java Programming Cover

The project manager then assigned units of work to numerous offshored junior developers who managed to get virtually everything wrong. If they couldn't understand what a spec required, they changed the spec to reflect what they actually wrote. This caused Alex to start versioning the requirements document in order to catch the changes by the junior developers so that they could be rolled back.

After a while, the number of junior-developer-caused issues was piling up and Alex suggested some training sessions on certain ways of doing things to reduce the chaff he had to deal with. Management turned him down because they couldn't afford to take developers off of coding tasks for purposes of training; there was a schedule to keep! The fact that oodles of time were being wasted on them building the wrong stuff only to have to have why it was wrong explained and then have them go back and re-do it - sometimes 6 or 7 times - was irrelevant.

So how does one deal with idiotic management like this?

Alex thought that he had found a way to expose the problem and (hopefully) force something to be done. He would put in something (that any experienced developer should be able to spot as a simple code formatting issue) that the junior developers would never spot. The code would work correctly, but it would stymie them so that they had to first understand it before they could change it. He used the following coding style in a variety of locations throughout the codebase and waited:

  List widgets;
  for (int i=0; i; i++) {
      // Do stuff
  } while ((widgets = getWidgets()) == null);

For those not familiar with Java, the closing brace of a for-loop is followed by an implicit semicolon, so the while (expression); statement is unrelated to the for-loop. However, the junior developers didn't know this, and couldn't find any documentation on a for-while statement. Although they were able to create little test programs, they didn't understand how the while-expression controlled the for-loop (it doesn't). In this case, the underlying DAO either returned a populated list or threw an exception, so it was effectively while-false (the function call and assignment occurred once) and was just syntactic nonsense that confused the junior developers.

They couldn't recognize a Java 101 code format issue and they were sufficiently stubborn that they refused to simply ask Alex what the code was doing. They were even foolish enough to openly discuss it amongst themselves on a conference line - agreeing not to ask for help until they figured it out - before a meeting with Alex and his boss began.

After 6 weeks of them floundering around on it, the offshore manager finally brought the issue up with Alex and his boss, at which time Alex explained what running the code formatter would show. He then pointed out that since they didn't know the basics of reading Java code and preferred to waste massive amounts of time rather than just asking about something they didn't understand, it was clear that they didn't have the wherewithall to make technical decisions on a larger scale, or change the design documents as they saw fit.

He continued to point out that until the junior developers showed marked improvements in their understanding of simple code, they should concentrate on learning to do basic programming instead of trying to be architects. To this end, he again offered to have ongoing training sessions where he would attempt to raise their skill level.

Of course management backed the cheap offshore labor. It was at this point that Alex realized it was a lost cause, so he fixed all the for-while snippets and updated the latest version of the detailed design document with a new opening paragraph:

  To Whomever Inherits This System:

  Detailed design documents were created by experienced people. Management decreed
  that junior developers could ignore them, at will and without penalty. The state
  of the code reflects this.
  
  Fair Warning!

Then he committed it, secure in the knowledge that the junior developers would never bother to look at it again once he was gone. Then he gave two weeks notice.

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

https://thedailywtf.com/articles/the-for-while-loop


Метки:  

CodeSOD: One's Company

Вторник, 14 Ноября 2017 г. 14:30 + в цитатник

The more you learn about something, the less confident you often become in making statements about it, because you understand the complexities of the matter. If, for example, I asked you to help me refine my definition of how dates and times work, you know that many assumptions are wrong. Or if we tried to define what makes a string a person’s name, we’ll run into similar problems. This is even true for a value we’ve all probably seen implemented as a boolean value: gender. The more you learn about these subjects, the more complex and nuanced your understanding of them becomes. More and more, your answers start with, “It’s complicated…”.

Eugene was going through some code at a customer’s site, and he found that their business logic depended heavily on a flag ISCOMAPNY (sic), but there was no ISCOMPANY field anywhere in the database. There was, however, a SEX field on the customer records, implemented as an integer.

Digging through the queries, Eugene found a new approach to defining a company:

SELECT …, CASE ISNULL(c.SEX, '')
    WHEN '6'
THEN '-1'
    WHEN '9'
THEN '-1'
    ELSE '0'
END AS ISCOMAPNY, …
FROM customers
WHERE …

Like I said, it's complicated.

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

https://thedailywtf.com/articles/one-s-company


Метки:  

Representative Line: An Exceptional Contract

Понедельник, 13 Ноября 2017 г. 14:30 + в цитатник

The life of a contractor can be precarious. Contracts end- sometimes suddenly, and you rarely know what the organization you’re working for is actually like until it’s too late.

Ian S, for example, was contracting for a platform-as-a-service (PAAS) company, adding new features to their existing infrastructure automation system. It was the kind of place that had two copies of the same code-base, maintained side-by-side, just so that a single customer could use a script they’d written eight years prior.

That wasn’t too much of a challenge. The real challenge was that when things went wrong, there was almost no logging, and what little logging they got contained helpful, “[10:14:17] An error occurred” messages.

It wasn’t hard to see why that happened:

try {
    // Entry point to most of the program here
} catch (Exception e) {
    if ( e instanceof ProcessingException ) {
        throw new ProcessingException("An error occurred");
    } else if (e instanceof BatchException ) {
        throw new BatchException("An error occurred");
    } //… more types of exceptions
}

Ian describes this as “Pokemon Exception Handling”: you wrap the entire main method of your app in a single try, so you’re left with a single catch block that’s “gotta catch ’em all”. The use of instanceof is a nice touch, in the awfulness of it.

The developer responsible, John, was involved in a lot of important architectural decisions. For example, John decided “DevOps” and “Agile” meant that any code placed in the production branch needed to go to production, automatically. There were no checks around this, anyone with access to the main repo could merge-and-push.

“We enforce it by practice,” John explained. “We know that all of our developers, even the contractors, will follow the best practices.”

Late, on Friday afternoon, John was working on making some configuration file changes. Among other things, his changes caused the whole program to crash on startup- but not before messing up some rows in the database. That was no problem, he was working on a branch, and running against a local dev environment.

It what John claimed was a “simple mistake”, he merged that branch with master. Then he pushed to the central repo. “It could happen to anyone,” he said. At 4:59PM, on Friday, their entire PAAS configuration and management suite went down. Garbage data was thrown into the database, repeatedly, and since there was no exception handling, the only information they had was “An error occurred.”

Truly, the life of a contractor is perilous, and for management, this became a 4-alarm, hair-on-fire emergency. All hands on deck! Even the contractors!

There was just one problem. The PAAS company had decided that they weren’t going to renew the contract. They had gone further, and announced that with a day’s notice, which left a number of the contractors flapping in the wind, between gigs, Ian included. So at 5:00PM, when he officially didn’t work there anymore, he wished John the best and went home.

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

https://thedailywtf.com/articles/an-exceptional-contract


Метки:  

Error'd: It Doesn't Mean What You Think it Means

Пятница, 10 Ноября 2017 г. 14:30 + в цитатник

"TRWTF here is I can't believe they shorted me on my change!" writes Diane B.

 

"I'm trying to order a shirt but I can't decide on which size to pick," writes Mark L., "I mean, is 03-XL bigger than 02-XL?"

 

Alex wrote, "So, Slack, exactly what would you say isn't working here?"

 

"I have a lot of questions about this agreement, but not nearly as many as it seems to have about itself," writes Dan B.

 

Josh writes, "Go figure. Here I thought 19 characters was between 6 and 30."

 

"Nevermind the national meterological services, Outlook has the most precise weather around!" wrote Kris L.

 

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

https://thedailywtf.com/articles/it-doesn-t-mean-what-you-think-it-means


Метки:  

Theory Versus Reality

Четверг, 09 Ноября 2017 г. 14:30 + в цитатник

I went to college at the State University of New York at Albany, where back then, most of the Computer Science curriculum courses were entitled Theory of xxx. The programming assignments were the usual small-scope demonstrations of some feature of programming, typically something an experienced developer would code in 15-20 LOC.

My Masters project was to modify the TeX typesetting system (by Knuth) to leverage the more advanced features of a new typesetting system. It took me about two months to reverse engineer it only to find that the entire required modification amounted to a single character change.

Albert Einstein c1890s

The theory sunk in, but there was no practical application of it to reality.

Fast forward to my first programming job, where one of my tasks was to write a stand alone program that would read connection names from a file, verify that they were valid, and use them for something. There were about 350 different connection names, but they didn't follow any discernible pattern. There were a variety of letters and numbers in no particular ordering. However, there was a lot of substring duplication within the names.

Being a clueless but diligent noob, it dawned on me that I could leverage those semi-duplications so I wrote a huge progressive if-then-else statement to determine whether a name was valid.

For example, the list contained names like:

   AXLP1122
   AXLP1133
   BCXQ5566
   BCYZ7788

The code was in FORTRAN IV, so I'll just use pseudo code here. The logic for that little sub list looked like this:

   if (name.startsWith("AXLP11"))
      if (name.substring(6) = "22 or name.substring(6) = "33")
          name is valid
   else if (name.startsWith("BC")
      if (name.substring(2) = "XQ5566" or name.substring(2) = "YZ7788")
          name is valid
   else ...

This proceeded to about 5 levels deep and comprised several hundred lines of code. I even built a test case to verify every single one of the names.

Then I proudly turned it in to my boss, who instantly proceeded to laugh in my face. He pointed out that it would take forever to run through all of that logic for each of the millions of records (back then, the CPUs ran at a little below 4MHz with very little RAM), and that perhaps I should consider using an array and a binary search lookup.

It was at that moment that I realized the fallacy of taking only courses entitled Theory of xxx, that perhaps my college tuition didn't buy me all I had hoped, and started a years-long effort to learn Practical Application of xxx to make myself better at what I did.

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

https://thedailywtf.com/articles/theory-versus-reality


Метки:  

CodeSOD: Lowest-Bidder Conversion

Среда, 08 Ноября 2017 г. 14:30 + в цитатник

Circa 2003, or so, Annie’s employer contracted a lowest-bidder to produce a relatively massive .NET Web Forms project. The code was built, signed off, and chucked into production without any of the in-house developers being involved, despite being the team that would support it in the long term. There was no documentation, no knowledge transfer, and no code review.

Over the next few years, there was a rush of feature requests as gaps in functionality were found. A series of in-house developers passed through, doing their best to patch them in, but the original project’s code quality didn’t exactly make it maintainable, and since they were operating in a rush, they weren’t exactly improving the code quality.

Fast forward to 2017, and the code is finally unmaintainable enough that someone put together the budget for a ground-up rewrite in .NET MVC, and once again shopped it around to a different lowest-bidder, who would do the conversion. This time, at least, Annie gets to review the code before they accept it. It isn’t going well.

private string AddOne(int DecimalPlace)
{
    string Outpout = ".";
    for (int i = 1; i < DecimalPlace; i++)
    {
        Outpout = Outpout + "0";
    }
    Outpout = Outpout + "1";
    return Outpout;
}

Yes, that’s a stringly-typed operation to create a number in the form “.00001”.

But don’t worry, we can also get the integer value of any string (or any object), nice and easy:

/// 
/// Get Integer Value.
/// 
/// Object type obj
/// 
public int GetIntegerValue(object obj)
{
    return GetIntegerValue(obj, 0);
}
public int GetIntegerValue(object obj, int defaultReturnValue)
{
    try
    {
        if (obj != null && obj.ToString().Length > 0)
        {
            string objvalue = ClearSpecialChar(Convert.ToString(obj));
            defaultReturnValue = Convert.ToInt32(objvalue);
        }
        //else
        //{
        //    defaultReturnValue = Convert.ToInt32(obj);
        //}
    }
    catch
    {

    }
    return defaultReturnValue;
}

module also needs to handle rounding, and yes, that’s also stringly-typed.

/// 
/// This Methods for round off item weight for(USPS)
/// EX: .15 Pound =1 Pound
/// 
/// 
/// 
public int MakeRoundOffDecimal(string inPutVal)
{
    int contenerVal = 0;
    int intValAfterPoint = 0;

    string ValBeforePoint = inPutVal.Substring(0, inPutVal.IndexOf('.'));
    string valAfterPoint = inPutVal.Substring(inPutVal.IndexOf('.') + 1);

    try
    {
        contenerVal = Convert.ToInt32(ValBeforePoint);
        intValAfterPoint = Convert.ToInt32(valAfterPoint);
        if (intValAfterPoint > 0)
        {
            contenerVal += 1;
        }
    }
    catch
    {
        contenerVal += 1;
    }
    return contenerVal;
}

/// 
/// This Method  Can make decimal value with desiger
/// length with updating last number (if last number after decimel point >=5 then 6 and lessthan <5 then
/// the same value
/// Ex:- 10.012547 will be 10.01255 if i call this method with GetDecimalPlaceValue("10.012547",5)
/// and 12.012351 will be 12.01235 if i cakll this method with GetDecimalPlaceValue("12.012351",5)
/// 
/// 
/// 
/// 
public virtual decimal GetDecimalPlaceValue(string Value, int DecimalPlace)
{
    decimal RetunValue = 0.00M;
    int NextToDecimalPlaceValue = 0;
    int DecimalPlaceValue = 0;
    string InputValue = Value;
    try
    {
        RetunValue = Convert.ToDecimal(InputValue.Substring(0, (InputValue.IndexOf('.') + DecimalPlace + 1)));
        NextToDecimalPlaceValue = GetIntegerValue(InputValue.Substring(RetunValue.ToString().Length, 1));
        if (NextToDecimalPlaceValue > 4)
        {
            RetunValue = RetunValue + Convert.ToDecimal(AddOne(DecimalPlace));
        }
    }
    catch
    {
        RetunValue = GetDecimelValue(Value);
    }
    return RetunValue;
}

If you note, the GetDecimalPlaceValue method claims to round (despite not being named anything like it), but will round numbers off incorrectly- the input 1.9 yields 1.

Calls to these various methods are peppered throughout the code base. It appears to be a common utility library that’s simply dropped into every project by this lowest-bidder contractor, and everyone on their team knows to use this for data type conversions.

Annie raised her issues with management, who raised it with their lowest-bidder. Unfortunately, as the lowest-bidder, they’ve already been paid for the first milestone, and are perfectly happy to drag their feet until the code quality issues are forgotten before they bother delivering the second.

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

https://thedailywtf.com/articles/lowest-bidder-conversion


Метки:  

Replacement Trainwreck

Вторник, 07 Ноября 2017 г. 14:30 + в цитатник

GreenMountainTrainWreck

There's an old saying about experience in IT: Some people have 10 years of experience, and some have 1 year 10 times. Every day, someone learns the hard way how true this statement really is.

Raquel returned from holiday, only to get a call from above saying her contract would not be renewed, giving her 2 weeks' notice to find a new placement. The boss explained it was a budget thing, since contractors are often more expensive than salaried employees, especially ones working remotely in the Asia-Pacific region. C'est la vie.

Raquel's big project was a perl module to talk to a high-end but aging storage system. The hardware had no API, and the CLI was arcane, with wildly inconsistent formats in the command output. Raquel abstracted that all away to give a programmatic interface for the other developers. The downside of this approach was that every time they put out a firmware update, she had to modify the perl script to match the changes. The module had grown to 1600 lines of code through 400+ commits in the 3 years she'd been working there. The other developers would include this as a git submodule so they could pull in changes in an automated way and re-release their tooling.

Raquel was asked to hand off the module to John, who assured her he knew git really well and enough perl to figure things out. It seemed reasonable ... at first. She got John set up with another, smaller tool she'd written: a plugin for a popular monitoring system to read the storage drives. It used the library she'd written as a backend, so she figured it'd give him some understanding of the functionality. Since some of their customers used Windows, she taught him how to compile to an executable. Once John was compiled and running, Raquel sent him to their lab environment to test the plugin.

A few hours later, she got her first bit of bad news: the plugin was failing, and John didn't know why. He attached the error message:

SSH connection to 192.168.1.10 (22/TCP) failed after 1 attempt(s).

Now, the library used SSH to connect to the drive, so Raquel's first suggestion was to make sure John could SSH into the storage system from the host he was working on. Things went quiet after that, so she figured he'd sorted it out—likely a loose cable or a disabled Ethernet driver—and went on with her day.

The next day, however, she came in to a more urgent message: John was still having problems. She asked for more details, and this was all she got:

SSH connection to 192.168.1.10 (22/TCP) failed after 1 attempt(s).

Maybe he forgot what he was doing? Raquel reminded John about checking the connection, and he replied that he could SSH just fine from the machine.

Weird.... She fired up a WebEx call so she could see what was going on in the lab. Sure enough, John could SSH from that machine to the storage device ... but he was running the plugin on his laptop. He was genuinely puzzled why that mattered.

Over the next half hour, Raquel dug up a network architecture diagram to show how only the lab machines could talk to the lab storage devices. Finally, still confused, John agreed to just do his development on the machines in the lab and they hung up.

That afternoon, Raquel's favorite type of ticket came in: a nice easy feature add for the monitoring program. It'd require a new method in the library and a handler for the Nagios plugin; it was perfect for John to get his feet wet. She assigned it to him and attached a link to a method in the library that was about 97% similar to what was needed, for him to study (read: copy and paste).

Several days slipped past in silence. Since there'd been no commits, Raquel dropped John a note to say that her contract was almost up. If he wanted a code review, he should push his changes and let her know.

John replied that the code was "almost complete" and would be checked in "shortly."

Fair enough, Raquel figured, and let it go.

Her second-to-last day, John sent a note saying he'd checked in his changes. He also included a link—to a different git repo.

Maybe it's a fork? No such luck. It was a brand new repo with exactly 1 commit. Not only had John made a new repo, that repo contained both the library code and the Nagios plugin code, with no submodules in sight.

Raquel could hardly believe it. How am I supposed to review without a diff?

She set up another WebEx for early the next morning—her last day—and explained to John how the lack of history was a critical problem. He agreed with her and assured her she'd get the diff she wanted.

Now what, dear reader, do you think Raquel actually received? If you guessed an email with bullet points outlining "At line 75 in foo.pl, I changed A to B. At line 89 I changed C to D ...", you're today's lucky winner.

Glancing at the clock, Raquel decided she had time for one last good deed before departing forever. She ran diff on the 2 repos, then typed up a polite, precise email outlining her comments. John's code wasn't all that bad really; he needed to code more defensively, since the storage system would sometimes throw errors, and he probably shouldn't loop over output that would always be exactly 0 or 1 lines of code, but it functioned well enough. Oh yeah, and the big chunk in the middle of the original method that he'd elected not to copy over? That handled the fact that the storage system was a cluster, so you may not be on the host you want when you first SSH into the machine. But otherwise, it was decent code.

Raquel's final email arrived soon after that, from John's manager. Apparently, John had complained that she was unprofessional.

She wrote back to wish them both the best of luck, collected her things, and laughed her way home.

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

https://thedailywtf.com/articles/replacement-trainwreck


Метки:  

CodeSOD: The Distract Factory Pattern

Понедельник, 06 Ноября 2017 г. 14:30 + в цитатник

The Gang-of-Four design patterns have an entire category of creational patterns, to handle the complexities of creating objects. And yes, it can get complicated, especially when we think in terms of the single-responsibility principle. Often, creating an instance of an class is itself so complex that we need a new class to do it.

Thus, we have the Factory pattern. And the Abstract Factory Pattern. And the Abstract Factory Factory Abstract Provider Bean pattern, if you’re using Spring. The purpose of these patterns is to add indirection between the client, calling code, and the creation of the objects- different concrete implementations can be instantiated, without the client code needing to worry about what actual type it received. Polymorphism wins the day. Code is more loosely coupled, because the client code never needs to name the concrete type it uses.

Unless you want to do it wrong, in which case Jen M found this particular solution:

public abstract class TaskBase
{
        public static TaskBase CreateInstance(
                Manager manager,
                Type TaskType)
        {
                object[] args = {manager, -1};

                return Activator.CreateInstance(TaskType, args) as TaskBase;
        }

        public static TaskBase CreateInstance(
                Manager manager,
                int taskId,
                string fullyQualifiedTypeName)
        {
                var TaskType = TypeLoader.GetType(fullyQualifiedTypeName, true);

                object[] args = {manager, taskId};

                var taskInstance = Activator.CreateInstance(TaskType, args) as TaskBase;

                return taskInstance;
        }
}

In this version, you can specify the concrete child of TaskBase that you want an instance of, and this will helpfully call the constructor for you. That means you could write:

var task = TaskBase.CreateInstance(mgr, TypeOf(MyDll.MyPackage.BasicTask))

Which is obviously far more loosely coupled than:

var task = new BasicTask(mgr);

As Jen puts it: “Some of the code I see makes me want to quit my job and go hunt down the people who wrote it. This is one of those instances.” Instead, Jen replaced this code with an actual version of the Factory pattern.

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

https://thedailywtf.com/articles/the-distract-factory-pattern


Метки:  

Error'd: Going for the Gold!

Пятница, 03 Ноября 2017 г. 13:30 + в цитатник

"Starting from one star, I'm almost at that gold five-star rating," writes Sam K.

 

"The octopus in the exhibit was a no show, but hey, at least I have a desktop to play around in," wrote Steve W.

 

Mike N. "Thanks Walgreens! I'm looking forward to spending my $[mi_reward]."

 

"Salesforce Apex Code deployment is such a joy," Bruce C., "Turns out my 9 components are 11 in Salesforce's eye - maybe they're counting in octal?"

 

"That's so true of PayPal, those [object:Object] fees will get you every time," wrote Brian K.

 

Shahim M. writes, "Yeah. I'm going to have to pass on that offer to save Rs. 0.68."

 

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

https://thedailywtf.com/articles/going-for-the-gold


Метки:  

CodeSOD: Switching the Search

Четверг, 02 Ноября 2017 г. 13:30 + в цитатник

We return to Virginia N’s refactoring efforts (previously: here, and here).

This code is elegant in its stupidity, combining two anti-patterns in one glorious, “No, don’t do that, whyyyyyyyyyy!”. To wit, the for-switch, and the “build SQL statements through string concatenation”:

for (int i = 0; i < 16; i++)
{

    StringBuilder commandText = new StringBuilder();
    command = new OracleCommand();
    switch (i)
    {
        case 0:
                commandText.Append(searchbuyer);
                parameter = new OracleParameter(":BUYER_DEP", OracleDbType.Char, 2);
                parameter.Value = depBuyer;
                command.Parameters.Add(parameter);
                break;
        case 1:
                commandText.Append(searchStock);
                break;
        case 2:
                commandText.Append(searchArbo1+"E"+searchArbo2);

                break;
        case 3:
                commandText.Append(searchArbo1+"V"+searchArbo2);
                break;
        case 4:
                commandText.Append(searchArbo1+"M"+searchArbo2);
                        break;
        case 5:
                commandText.Append(searchArbo1+"P"+searchArbo2);
                        break;
        case 6:
                commandText.Append(searchArbo1+"S"+searchArbo2);
                        break;
        case 7:
                commandText.Append(searchArbo1+"O"+searchArbo2);
                break;
        case 8:
                commandText.Append(searchArbo1+"T"+searchArbo2);
                break;
        case 9:
                commandText.Append(searchArbo1+"A"+searchArbo2);
                break;
        case 10:
                commandText.Append(searchArbo1+"I"+searchArbo2);
                break;
        case 11:
                commandText.Append(searchDemandeur);
                break;
        case 12:
                commandText.Append(searchDoc);
                break;
        case 13:
                commandText.Append(searchForm);
                break;
        case 14:
                commandText.Append(searchCertif);
                break;
        case 15:
                commandText.Append(searchFormV);
                break;
    }
    //… use the query
}

And for bonus points, this takes a round trip to the database for every iteration of the loop, for 16 hits per search. EVMPSOTAI, indeed.

[Advertisement] Universal Package Manager - ProGet easily integrates with your favorite Continuous Integration and Build Tools, acting as the central hub to all your essential components. Learn more today!

https://thedailywtf.com/articles/switching-the-search


Метки:  

CodeSOD: An Academic Consideration

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

Becky is not a programmer, but a physicist. She works in academia, alongside other scientists. Modern science generally requires some sort of heavy computation, which means scientists write code. It’s often not very good code, but that’s just the nature of the beast. The code exists to provide an analysis, not to be deployed as an app to the masses.

Most of the time. A few civil engineers were working on a brand new Android app for traffic analysis, with plans to distribute it. Unfortunately, they had some problems, and wanted more experienced eyes. Becky set aside the Fortran77 she was working on to trace through their Java code, and found this:

public class MainActivity extends Activity {
    private static double GpsLon = 0.00;
    public double getGpsLon() { return GpsLon; }
    public void setGpsLon(double value) { GpsLon = value; }
    private static boolean saveComLogeFile = true;
    public boolean getSaveComLogeFile() {return saveComLogeFile;}
    public void setSaveComLogeFile(boolean saveComLogeFile) {this.saveComLogeFile = saveComLogeFile;}
    // more than 70 similar static variables with non-static getters and setters
}

public class GpsWlan implements Runnable
{
    static MainActivity ma = new MainActivity();
    @Override
    public void run()
    {
        ma.setGpsLon(1.234);
    }
}

At this point in the article, I’d normally explain to you what this code is trying to do, and why it’s bad. Honestly though, I can’t even answer the first question. MainActivity is a megaclass of properties- and those properties are all static. That’s a fine approach for configuration settings, but you usually pair it with static getters and setters.

But the place where they actually set these variables is the really weird part of this. By implementing Runnable, they’re implying that GpsWlan should be run as its own thread- great if you’re doing heavy I/O or something, but… for setting a property? A static property? With no syncing or locking? Sure, they are setting it to a literal value, so we apparently don’t need to be too worried about race conditions, but… why?

Well, there isn’t a reason. Becky explains the process used to develop this code: “Here, Researcher N learns to program by asking Researcher N–1 for their code, learning from it and tweaking what they had.” I'm going to add a little correction: they're not learning anything from the code. This is cargo cult programming- the code they borrowed did this, so their code does it too.

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

https://thedailywtf.com/articles/an-academic-consideration


Метки:  

With the Router, In the Conference Room

Вторник, 31 Октября 2017 г. 17:00 + в цитатник

This is a follow-up to With the Router, In the Conference Room, revealing the… STUNNING CONCLUSION!

How It Really Ended

Darren took the case up to his boss, and then to their boss, up the management chain. No one was particularly happy with Cathy’s tone, and there was a great deal of tut-tutting and finger-wagging about professional conduct.

Ms. Scarlett, in Clue, delivering the line 'Flames, flames on the side of my face'

But she was right. It was Mr. Green who failed to follow instructions, it was Mr. Green who cost the company thousands, along with the customer relationship problems caused by Cathy’s sudden emergency trip back to the home office.

In what can only be considered a twist ending by the standards of this site, it was Mr. Green who was escorted out of the building by security.

The killer was Cathy, in the issue tracking system, with the snarky bug report.

[Advertisement] Universal Package Manager – store all your Maven, NuGet, Chocolatey, npm, Bower, TFS, TeamCity, Jenkins packages in one central location. Learn more today!

https://thedailywtf.com/articles/with-the-router-in-the-conference-room-conclusion


Метки:  

With the Router, In the Conference Room

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

One of the most important aspects of software QA is establishing a good working relationship with developers. If you want to get them to take your bug reports seriously, you have to approach them with the right attitude. If your bugs imply that their work is shoddy, they are likely to fight back on anything you submit. If you continuously submit trivial “bugs”, they will probably be returned right away with a “not an issue” or “works as designed” status. If you treat any bug like it’s a critical showstopper, they will think you’re crying wolf and not immediately jump on issues that actually are critical.

Then there’s people like Mr. Green, a former coworker of submitter Darren A., that give QA a bad name. The Mr. Greens of the QA world are so incompetent that their stupidity can cause project delays, rack up thousands of dollars in support costs, and cause a crapstorm between managers. Mr. Green once ran afoul of Darren’s subordinate Cathy, lead developer on the project Mr. Green was testing.

A shot from the film Clue, where Mrs. White holds a gun in front of Col. Mustard

Cathy was en route to the United States from London for a customer visit when her phone exploded with voicemail notifications immediately upon disabling airplane mode. There were messages from Darren, Mr. Green, and anyone else remotely involved with the project. It seemed there was a crippling issue with the latest build that was preventing any further testing during an already tight timeline.

Instead of trying to determine the cause, Mr. Green just told everyone “Cathy must have checked something in without telling us.” The situation was dire enough that Cathy, lacking the ability to remotely debug anything, had to immediately return to London. Mr. Green submitted a critical bug report and waited for her to cross the Atlantic.

What happened next is perfectly preserved in the following actual bug report from this incident. Some developers are known for their rude and/or snarky responses to bug reports that offend them. What Cathy did here takes that above and beyond to a legendary level.

====
Raised:         14/May/2015
Time:           09:27
Priority:       Critical
Impact:         Severe
Raised By:      Mr. Green

Description
===========
No aspect of GODZILLA functions at present. All machines fail to connect with the server and we are unable to complete any further testing today.
All screens just give a funny message.
Loss of functionality severely impacts our testing timescales and we must now escalate to senior management to get a resolution.

15/May/2015 22:38
        User:   Cathy Scarlett
        Updated: Status
        New Value: Resolved - User Error
        Updated: Comment
        New Value:
                Thank you for this Mr. Green. I loved the fact that the entire SMT ordered me back to head office to fix
                this - 28 separate messages on my voicemail while I was waiting for my baggage.
                I was of course supposed to be fixing an issue our US customer has suffered for over a year but I
                appreciated having to turn around after I'd landed in New Jersey and jump back on the first return
                flight to Heathrow.

                Do you remember when you set up the Test room for GODZILLA Mr. Green?

                Do you remember hanging the WIFI router on a piece of string from the window handle because the
                cable wasn't long enough?

                Do you remember me telling you not to do this as it was likely to fall?

                Do you remember telling me that you sorted this out and got Networks to setup a proper WIFI router
                for all the test laptops?

                I remember this Mr. Green and I'm sure you'll remember when I show you the emails and messages.

                I walked into the test room at 10 o'clock tonight (not having slept properly for nearly
                3 days) to find the WIFI router on the floor with the network cable broken.
                        ROOT CAUSE: The string snapped

                There was a spare cable next to it so I plugged this one in instead.

                Then, because this was the correct cable, I put the WIFI unit into the mounting that was provided
                for you by networks.

                As if by magic, all the laptops started working and those 'funny messages' have now disappeared.
                GODZILLA can now carry on testing. I'm struggling to understand why I needed to fly thousands of
                miles to fix this given that you set this room up in the first place. I'm struggling to understand
                why you told the SMT that this was a software error. I'm struggling to understand why you bypassed my
                manager who would have told you all of this. I'm closing this as 'user error' because there
                isn't a category for 'F**king moron'

                72 hours of overtime to cover an aborted trip from London to New York and back:
                        lb3,600

                1 emergency return flight:
                        lb1,500

                1 wasted return flight
                        lb300

                1 very nice unused hotel room that has no refund:
                        lb400

                1 emergency taxi fare from Heathrow:
                        lb200

                16 man days of testing lost
                        lb6,000

                Passing my undisguised contempt for you onto SMT:
                        Priceless

Mr. Green was obviously offended by her response. He escalated it to his manager, who demanded that Cathy be fired. This left Darren in a precarious position as Cathy’s manager. Sure, it was unprofessional. But it was like getting a call from your child’s school saying they punched a bully in the nose and they want your child to be disciplined for defending themselves. Darren decided to push back at the QA manager and insist that Mr. Green is the one who should be fired.

This story might have ended with Mr. Green and Cathy forced into an uneasy truce as the company management decided that they were both too valuable to lose. But that isn’t how this story ended. Or, perhaps Darren's push-back back-fired, and he's the one who ends up getting fired. That also isn't how the story ended. We invite our readers to speculate, extrapolate and fabricate in the comments. Later this morning, we’ll reveal the true killer outcome…

And now, the conclusion to the story!

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

https://thedailywtf.com/articles/with-the-router-in-the-conference-room


Метки:  

CodeSOD: Drain the Swamp

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

You may remember Virginia N from An Extinction Event, where she struggles to refactor a legacy project with some… unusual design principles. ReSharper still continues to choke to death on their codebase, but her management haas let her know, this won’t be a problem going forward.

“You see,” her boss explained, “we’re going to move the logic into stored procedures. That way, we can more easily re-use the logic between the Windows Forms client and the Web app.”

“Oh, there’s going to be a web app, now?” Virginia asked.

“Yes! They’re going to use best practices, like unit testing, so that they don’t end up with the same kind of mess we have,” her boss said.

Virginia was halfway to filing a request for a transfer when she heard more about the web project. Then she heard about their plan. They weren’t going to simply build a web-client for their backend, but instead were going to build an inner platform. The page logic would be a simple template, and all of the rules, styling, data and display logic would be stored as data in the database. “It’s gonna be really flexible!”

Virginia decided to stick with the fetid field she knew, instead of the “green field” which was going to be a fetid swamp in a matter of weeks.

In Virginia’s swamp, she has many, many 40,000 line classes. That much code means the code has no real cohesion, so it leads to Virginia finding variables named thus:

public bool IReallyDontWantToFetchTheDataOnLoadButDontWantToChangeTheOtherVariablesCauseWhoKnowsWhatWillHappen=false;

It’s at least descriptive. It also exists in the class side-by-side with variables like blnGetData, GetDataOnFormLoad, and GetDataOnFormrLoadS.

Elsewhere in the same file, they have a different problem. They added a control to the view, and needed an accessor method to decide whether it was visible or not. Actually, they needed a few, and they knew that the form would be changing over time, so they needed something that was “dynamic”.

Now, they could have simply added properties and getters/setters as the form changed and dealt with the follow on changes, but someone decided it was time to stress “Closed for Modification” was a good object-oriented practice. They left out the “Open for Extension” part of the open/closed principle, so they used this code instead, which uses a few index properties to decide which control should be modified.

private void SetVisiblePicNdt()
{
    string NomBtnNDT="";
    string NomBtnChant="";
    if (m_IndexChant>0)
    {
            NomBtnNDT="btn"+(m_IndexChant+1).ToString();
            NomBtnChant="btn"+(m_IndexChant).ToString();
    }
    else
    {
            NomBtnNDT="btn"+(m_IndexLB+1).ToString();

    }

    Control sectMain=null;

    for (int i=0;icode>

Virginia has many more horrors to share, so expect more examples from this code base.

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

https://thedailywtf.com/articles/drain-the-swamp


Метки:  

Поиск сообщений в rss_thedaily_wtf
Страницы: 124 ... 58 57 [56] 55 54 ..
.. 1 Календарь