Categories
Computing

Why are there so many recruiters?

I don't know about you, but 90% or more of my linkedin contact requests come from recruiters. I don't accept them all. Am I the kind of talented high-flyer you would want to headhunt? Probably not, in person I'm rather shy and certainly not management material. I suppose I just know a few esoteric programming tricks and have a good understanding of data and information architecture. What's more, apart from a few modules taken as part of an Open University degree, I'm entirely self-taught. With all these young whizkids graduating in IT-related degrees in a country obsessed with electronic gadgets multimedia wizardry, you'd think I'd have plenty of competition from young twenty-somethings. Despite high youth unemployment and free access to tutorials on just about any programming framework that takes your fancy, relatively few youngsters get beyond writing a few lines of Javascript. Unfortunately the tech industry does not need mediocre code monkeys who can churn out repetitive procedural scripts, for that task can be fully automated. In the software industry you do not judge someone's productivity by the amount of code they write or even by the number of hours they work, but how well their application performs. To produce lean and mean applications, you need to get your head around various programming algorithms and design patterns. Yes, it really does matter if you pass a variable by reference or by value or if you clumsily copy and paste variants of some old procedural routine rather than encapsulate it in a neat reusable function.

A good developer never stops learning new techniques to write better, more expressive, more maintainable and more efficient code, rather than clever tricks to automate monotonous tasks. That means good hands-on developers are nearly always geeks, as we have to dedicate much of our time to learning new languages and cutting-edge techniques We can learn some things by social osmosis, but only if we understand core concepts that relate to direct experience. Indeed if a subject does not actively interest us, that's what most of us do. We rely on other people's expertise, but know enough about the subject to avoid getting ripped off. In some academic fields a specialist in someone who has researched a subject extensively, but in most hard sciences specialists are people with active hands-on experience. Unless you have written and tested applications with complex and irregular business logic, you wouldn't be able to appreciate what application developers do. They just sit in front of screens writing quirky symbols with a few English-like key words. Concepts such as design patterns mean little if you have just learned how to do a simple loop. Now suppose you need to hire a new developer, for sake of argument, let's just assume you need a good NodeJS specialist. Who could possibly judge if a candidate knows their stuff? They may have an excellent CV, good qualifications and some good references, but in today's fast-changing world, these mean very little. Millions have worked directly or indirectly for major media multinationals. If you say you worked on the BBC news Website, which bit did you do? Did you just design a prototype for a new button or test a new interactive widget on different browsers? Does your recruiter really understand what skills are required?

Recruiter
Hello, Neil. It's Ryan Adams here. Look we've got a Drupal gig on at Arty Farty New Age Media over in Soho. They need a hard-core backend guy like yourself for a couple of weeks. Would £400 a day tempt you?
Me
Well, actually I'm very busy at moment (trying to fix someone else's awful code), but might be available in a couple of weeks (just in case my contract is cut short).
Recruiter
They really need someone to start straight away. This is for a massive media campaign of a leading household brand.
Me
What happened to the previous developer?
Recruiter
Oh, he had issues, some of kind of personality clash, I think. How about £450 a day?
Me
If we continue this conversation, my contract here will be terminated. Let me get back to undoing the mess the last developer here created.
Recruiter
Is your boss looking for any new developers?

One way or another for every real hands-on developer out there there's at least one recruiter, one project manager, 1 business analyst, a marketing wonk and an accountant (because many IT professionals are contractors with their own limited companies). For some jobs in London's frenetic media sector, I've been contacted by five or more recruiters from different agencies for the same job. "Do you have experience with Solr, the Zend framework, Git and IPTV?" enquires a 22 year old IT graduate. These are really just buzzwords, which mean little until more details are revealed. In most cases they just need an experienced developer who happens to have a used the required programming language in the context of a specific framework and has worked in small teams with agile methodology. Requiring a good understanding of business processes is a good way to weed out self-taught novice programmers or inexperienced IT graduates.

For over 20 years the UK education system has produced millions of graduates who can, figuratively speaking, talk the talk, and not so many who can walk the walk. Although our way of life relies on complex technology, few have more than a cursory overview of its inner workings, but millions are employed in managing the complex human interactions between business owners, government agencies and mission-critical human resources. If all recruiters went on strike tomorrow, no essential services would be disrupted. Life would carry on as usual, except slowly lead developers would have to spend a little more time hunting new talent and would probably choose other geeks just like themselves. That is precisely the scenario, that upper management would prefer to avoid. They do not want a new category of indispensable engineers who can hold their business to ransom. They do not want technical experts to see the whole picture or even gain credit for the fruits of their labour. Meeting business requirements often means just accepting you're a cog in a much bigger machine and cannot work out of sync with all the other cogs, chains, pulleys and lubricating fluids.

Categories
Computing

The Copy and Paste Design Pattern

copy paste

All good programmers understand the concept of design patterns, creational patterns, structural patterns and behavioural patterns. We apply these patterns in different aspects of our projects. It's good to recognise common patterns so we can generalise routines into reusable functions, methods or classes. I won't bore you with the details because you can learn more from a wealth of other online resources, but two key principles underly all design patterns:

  1. Think strategically about your application architecture
  2. Do not Repeat Yourself, aka, DRY. Organise your code so common routines can be reapplied.

Great, but in my humble experience we should add probably the most common design pattern of them all, though strictly speaking it's an anti-pattern: Adaptive Copy & Paste. The core idea here is if it works for somebody else you can just copy, paste and post-edit their code. Sometimes you can begin with some really good snippets of well-structured and commented code, but all too often online code samples are just formulaic and adapted from textbook boilerplate code. I've seen blocks of code pasted into Javascript files with references to StackOverflow.com complete with source URLs and deployed on high-traffic live sites. Let me show you a simple example:

var GBPExchangeRates = {
    USD: 1.52,
    EUR: 1.38,
    CDN: 1.57,
    SKR: 12.89,
    AUD: 1.45,
    CHF: 1.76
  };

  function convertGBPToEuro(GBPVal) {
    if (typeof GBPVal == 'string') {
        GBPVal = GBPVal.repplace(/[^0-9.]/g,'');
        if (GBPVal.length>0) {
            GBPVal = parseFloat(GBPVal);
        }
    }
        if (typeof GBPVal == 'number') {
        return GBPVal * GBPExchangeRates.EUR
    }
    return 0;
  }

  function convertGBPToUSD(GBPVal) {
    if (typeof GBPVal == 'string') {
        GBPVal = GBPVal.repplace(/[^0-9.]/g,'');
        if (GBPVal.length>0) {
            GBPVal = parseFloat(GBPVal);
        }
    }
    if (typeof GBPVal == 'number') {
        return GBPVal * GBPExchangeRates.USD
    }
    return 0;
  }
  
  var coffeePriceGBP = 1.90;
  
  var teaPriceGBP = 1.10;
  
  var orangeJuicePriceGBP = 1.50;
  
  var coffeePriceEUR = convertGBPToEuro(coffeePriceGBP);
  
  var teaPriceEUR = convertGBPToEuro(teaPriceGBP);
  
  var orangeJuicePriceEUR = convertGBPToEuro(orangeJuicePriceGBP);
  
  var coffeePriceUSD = convertGBPToUSD(coffeePriceGBP);
  
  var teaPriceUSD = convertGBPToUSD(teaPriceGBP);
  
  var orangeJuicePriceUSD = convertGBPToUSD(orangeJuicePriceGBP);
  

For a beginner, this is honestly not that bad at all. First we set up a simple object of common currencies with their exchange rates. In the real world this may come from some sort of feed. Next we devise a neat function to convert our GBP prices to Euros. Just to make it failsafe, we make sure we can handle strings with a mixture of numerals and currency symbols, which may include commas or other symbols than decimal points. If we only ever had to convert between British pounds and Euros, that would be just fine, though we may convert all prices via some sort of loop rather than make separate calls for each prices. Here for just three prices and three currencies, we need to set nine explicit price variants and six explicit function calls.

However, later an intrepid project manager decides we need to support other currencies and may need to convert other units too, such as measurements or clothes sizes, so a busy code monkey promptly copies, pastes and adapts the first method to USD. Not too bad we only have two functions, but they contain much shared logic. Indeed the only difference in the conversion rate. We should break down this logic into steps. First we test if the input is a number (Javascript has a generic Number type that covers both floats and integers). Next we strip any non-numeric characters and cast to a float if the result is not empty. Only then do we apply our conversion rate. The above code could be even worse. We could have opted to hard-code the conversion rate. This may work for constants, such inches to centimetres, but it doesn't work for variables like exchange rates. What we need a generic method to convert number-like strings to true floats and another generic method to apply conversion rates from simple key/value objects.
Javascript makes it very easy for us to apply the decorator pattern by extending an object's prototype. This allows us to chain methods in a very self-descriptive way.

String.prototype.numeralsOnly = function() {
    return this.replace(/[^0-9.]/g,'');
}

String.prototype.toFloat = function() {
    var self = this.numeralsOnly();
    if (self.length < 1) {
        self = 0;
    }
    return  parseFloat(self);
}

Number.prototype.toFloat = function() {
    return parseFloat(this);
}

Object.prototype.matchFloat = function(key) {
var obj = this, val;
    if (obj instanceof Object) {
        if (obj.hasOwnProperty(key)) {
            val = obj[key];
            if (val) {
                return val.toFloat();
            }
        }
    }
    return 0;
}

Number.prototype.convert = function(fromUnit,toUnit,units) {
    if (units instanceof Object) {
        return this * (
        units.matchFloat(toUnit) / units.matchFloat(fromUnit)
        );
    }
}

We then apply a simple conversion table:

  var rates = {
    GBP: 1,
    USD: 1.53,
    EUR: 1.37,
    YEN: 132.2,
    RUB: 12.7
  };

Then if we were to allow users to convert to the currency of their choice, we could simply add prices in the base currency (in this case GBP) via some hidden element and then apply the conversion factor via the Document Object Model (or DOM):

  $('table thead .currencies .option').on('click',function(e){
    var it = $(this),
      tb = it.parent().parent().parent().parent(),
      selEl = it.parent().find('.selected');
    if (selEl.length < 1) {
      selEl = it.parent('em').first();
    }
    var selCurr = selEl.text().trim().toUpperCase(), tgCurr = it.text().trim().toUpperCase();
    tb.find('.price').each(function(i){
      var td = $(this),
      nVl = td.attr('data-gbp').toFloat().convert('GBP',tgCurr,rates);
      td.html(nVl.toFixed(2));
    });
    
  });

This may look like more code, but we now have a solution that works with any currencies and any number of data items to be converted. Moreover, our convert method may be applied to any units. If we wanted to present volumes in either millilitres or fluid ounces we would just include our decorator methods as a library, set up a conversion table and write a short DOM script. 90% of the code would have been tested for other use cases:

var volumeUnits = {
    ml: 1,
    l: 1000,
    floz: 29.5625
}

Good programmers always think out of the box, not just how to solve the current problem as presented by a project manager, but how do I solve other problems like this? More important, we should ask how to make our code more maintainable and easier to test.

Common Mistakes

  1. Placing editorial content in code files that only developers know how to edit: e.g. A senior manager has decided to edit some text on your company's online shop. The only reason she needs to involve you in this editorial change is because your predecessor placed the text in a template or even worse embedded it verbatim on line 1451 of a fat controller file. What should you do? To make your life easy you could just edit the offending line and write a note for future developers that this text is hard-coded in such and such a file. Management will then think that whenever they wish to edit content they need to ask your project manager to ask you to apply some cryptic code change. However, later they will review their IT budget and decide you are too expensive and then outsource the whole project to a low-wage country or replace it with a state-of-the-art content management system that let's them edit any content without any programming knowledge. What you should do is suggest all such content should be editable in a special admin area and all hard-coded text, media or numbers should be replaced with references to editable content.
  2. Quoting one programming language in another: This is surprisingly common. The main reason for doing so is to inject server-side variables into client-side scripts, e.g. using PHP to build a Javascript routine with a few variables generated dynamically by the server. Not only does this make your Javascript very hard to debug, but it inevitably leads to more repetitive and thus slower Javascript. If you want to fetch data from the back-end, you should inject it as hidden attributes that Javascript can read or simply inject some JSON easily converted from native server-side objects or make an asynchronously request with a JSON response. Keep your javascript lean and mean and ideally in separate files, so your browser can cache these resources more efficiently. If you're using backbone.js or jQuery or other framework, these can be loaded from a content delivery network or CDN.
  3. Repeating routines: Whenever you find yourself repeating a routine more than once, you need a new function or at they very least a loop:
    var d = new Date(item.created);
   item.created_date = d.getDate() + '/' + (d.getMonth()+1) + '/' + d.getFullYear();
   
   var d = new Date(item.modified);
   item.modified_date = d.getDate() + '/' + (d.getMonth()+1) + '/' + d.getFullYear();

This is messy. What we need is a generic date conversion function:

var isoDateToEuroDate = function(strDate) {
    var d = new Date(strDate);
     return d.getDate() . zeropad(2) + '/' + (d.getMonth()+1) . zeropad(2) + '/' + d.getFullYear();
}

And if we're doing a lot of date manipulation,we might like to include a date library to make our code simpler. Your bosses may not notice that you are just writing the same code over and over again, but if your code becomes very expensive to maintain, they will either ditch it or outsource your work to some hapless code monkeys on a fraction of your wage.