Asynchronous Auto-Complete Input Fields with Bootstrap Typeahead – Update

A while ago I posted about implementing the Bootstrap Typeahead component using an async call. Since that post I have received various requests from people with questions about this approach so I have taken the liberty to make a slightly more complete example than the one shown in the original post.

I have a ZIP file to download at the end of this post with the complete example but I’d like to quickly run through the code so it makes sense to anyone reading this.

This is the main script:

$(document).ready( function() {
   $('#myinput').typeahead( {
      source: function( query , process ) {
         $.get("mydata.json", {
            query: query
         },
         function( data ) {
            data = [
               "London (LON) London - United Kingdom",
               "Longana (LOD) Longana - Vanuatu",
               "Long Island (LGI) Deadmans Cay - Bahamas",
               "Londrina (LDB) Londrina - Brazil",
               "Changchun (CGQ) Longjia International - China",
               "Guiyang (KWE) Longdongbao International - China",
               "Long Banga (LBP) Long Banga Airfield - Malaysia",
               "Longyearbyen (LYR) Svalbard - Norway",
               "London (STN) Stansted - United Kingdom",
               "London (LCY) London City Airport - United Kingdom",
               "London (LHR) Heathrow - United Kingdom",
               "London (LGW) Gatwick - United Kingdom",
               "Islip (ISP) Long Island Macarthur - United States",
               "Long Beach (LGB) Long Beach Municipal - United States",
               "Lonorore (LNE) Lonorore - Vanuatu",
               "Long Island\/Happy Bay (HAP) Long Island - Australia",
               "Longreach (LRE) Longreach - Australia"
            ];
 
            process(data);
         } );
      },
   } );
} );

This code is basically the same as the code used in my previous post, however, I have changed the jQuery POST to a GET for the purpose of demonstration. The example in the ZIP file will run without needing the use of a web server but since that’s the case, it’s not possible to use an HTTP POST. Normally of course you’d use a POST in the same way I did it in the original example.

The example loads a dummy JSON file from the file system which triggers the onload callback. In the example above this callback is a nameless function defined at function( data ).

When the call back is trigger, normally we’d receive some data in the data parameter. However, since the example above doesn’t receive real data we’re hard coding a result set. This result set is a linear list of elements which get passed to the process function.

The process function is defined as part of the Bootstrap Typeahead component. All you have to do is pass on the result set to it and it will take care of the actual drop down with character highlighting etc.

So without further ado, please download the ZIP file: Bootstrap Typeahead demo.

Posted in Programming | Comments closed

WordPress Security: First Line of Defence

When you have set up your WordPress website and published it on the web it has become vulnerable to attacks. Most people don’t realise that there are automated processes scanning the web for vulnerable WordPress websites. These scanning “robots” will try to get into your “admin” account by guessing the admin password. Most of these robots are smart in how they do this. They don’t want to get IP blocked so they’ll try a dictionary attack every hour or so using some password from a list of words.

When you set up your WordPress site there is one thing you always need to do first; Create a new admin user and then remove all privileges from the original admin user. So, after installing your WordPress website you log in with “admin”. You now create a new user with a very different user name and you give this user admin privileges. You then log out from the original admin account and you log in with the newly created admin account. You are now going to change the password on the original admin account to something so strong that chances are unlikely it will ever gets hacked by an automated process. To create this password go over to Passly and select a password length of 48 and click generate. This should give you a strong enough password. You don’t have to save this password anywhere for later since you’re never going to use the original admin account to log in into your website anymore, it basically becomes a dummy account. Now change the privileges for the original admin to “No role for this site” and you’re done. You’ve just created your first line of defence.

By leaving the original admin account to exist we’ve given potential hackers the “idea” that there is an “admin” account. They will try to hack this account because they assume that this account is the fully privileged admin, but it’s not. Even if they were to bypass the ridiculously strong password they will find that this account has no privileges what so ever.

Like I was saying earlier, most people have no idea that these attacks happen. However, I’ve written a WordPress plugin that will send out an email to the website owner whenever a failed log in attempt takes place. Simply download and install it and see what happens. It might be that you website is being poked and probed without you even knowing it.

Posted in Programming | Comments closed

Beware the favicon feedback loop

The other day I noticed something strange happening on one of my servers. I have munin set up to monitor memory, cpu and disk space usage etc. and I noticed that for some reason memory consumption was going through the roof.

After checking the logs I noticed the following error:

PHP Fatal error: Allowed memory size of 10485760 bytes exhausted
 (tried to allocate 523800 bytes)

Hmm. My server has plenty of memory and PHP’s memory usage is set to 128Mb which should be more than enough to serve a WordPress website.

So I started to debug the website on my localhost. On my dev machine I have XDebug installed (if you develop for PHP you should too!).

When I did some digging and testing I noticed that I was able to reproduce the problem when I removed an image from my uploads directory that was supposed to be loaded on the home page. With XDebug disabled I was able to see in the logs that my PHP script was going into a recursive loop. This recursive loop ended up allocating all the available memory in small chunks until memory was completely exhausted, hence the error above.

After another hour of tracing and poking around I check finally checked my 404 template. In it I was doing something like this:

<?php get_header() ?>
 
....
 
<?php get_footer() ?>

After triggering a manual 404 page by browsing to a non-existing page on my site I did a massive face palm as I suddenly realised my mistake.

On my home page the favicon image could not be loaded which was triggering a 404 on that image being loaded. The 404 was handled by WordPress to display the 404 page, however, in the template I output the website header which has the favicon in it. This in turn would trigger a 404, and so… That’s your recursive loop right there.

After fixing the favicon the website’s behavior has again returned to normal.

Posted in Programming | Tagged | Comments closed

Javascript Preloader

The year was 2006. I was knee deep building websites with Flash and when I say Flash, I actually mean ActionScript. Fast forward to 2013 and guess what? Javascript today is pretty much what ActionScript was in 2006, at least, from a language point of view.

Anyway, I was working on this website recently and it had about 5 meg’s of graphics to load on just the home page. We wanted things to be smooth and instead of having images being loaded onto the page when ever the browser decided to load ‘m, we wanted to preload them into browser cache so that when they were needed on the page they would pretty much load instantly.

Since I had done this sort of stuff in ActionScript about a gazillion times before I decided to create a simple preloader class, this time in Javscript:

/**
 * Simple asset preloader class.
 *
 * @dependency: delegate
 */
function Preloader( assets, callback ) {
   this.assets = assets;
   this.asset = null;
   this.assetIndex = 0;
   this.callback = callback;
   this.loadNextAsset();
};
 
Preloader.prototype.loadNextAsset = function() {
   this.onupdate( 100 / this.assets.length * this.assetIndex );
 
   if( this.assetIndex >= this.assets.length ) {
      return this.callback.call();
   }
 
   this.asset = new Image();
   this.asset.onload = delegate(this, this.loadNextAsset);
   this.asset.src = this.assets[ this.assetIndex++ ];
};
 
Preloader.prototype.onupdate = function( percentage ) {
   // Default, do nothing.
};

As you can see. This is pretty straight forward. It basically cycles through all the assets provided to it sequentially and after the last asset is loaded it will trigger an event. I’ve added an extra event to capture a percentage loaded in case needed (I did).

One thing to point is that this Preloader class has a dependency on a “delegate” helper function. This helper function makes sure that functions are called in the correct context, preserving scope etc. Don’t forget to include it otherwise the above won’t work:

/**
 * Delegates callbacks while maintaining object scope.
 */
function delegate(scope, method) {
   if(arguments.length > 2) {
      var args = [];
      var numOfArgs = arguments.length;
      for(var i=2; i<numOfArgs; i++) {
         args.push(arguments[i]);
      }
      return function() { return method.apply(scope, args); }
   } else {
      return function() { return method.call(scope); }
   }
}

To actually use the preloader, simply specify a list of assets in the form of an array:

function onPreloadDone() {
   // Preload complete.
}
 
$(document).ready( function() {
   var assets = [
      "http://www.mydomain.com/assets/big-image.jpg",
      "http://www.mydomain.com/assets/other-big-image.jpg"
   ];
 
   var preloader = new Preloader( assets, onPreloadDone );
   preloader.onupdate = function( percentage ) {
      // percentage is between 0 and 100. You might want to round it.
   }
} );

That’s all there is to it. Happy preloading!

Posted in Programming | Comments closed

The Bank Statement

The banking saga continues at NAB.

I have a business bank account at NAB and I wish I never opened it. Anyway, the other day I needed to get the 2nd quarterly statements from my business bank account to do my quarterly GST (tax) tax return. So, I hop onto online banking and click into the main business account. The first thing I noticed was the “Export data” option. However, clicking this doesn’t actually let you select a range. After a few frustrating moments I noticed another option located slightly above it titled “Show filter”. Clicking this allowed me to set a date range. Hmm..

This is where the real nightmare began. It’s the end of January and I needed the date range since October 1 until December 31 of the previous year. When I entered this range I received a message that informed me that I had to “register” if I needed to select a range more than one month. WTF? It instructed me to go to a certain section in the Settings but it turns out, to actually “register” you need to go somewhere else. To figure this out took me a trip to the bank (who couldn’t tell me how it worked) and then another couple of frustrating hours.

Next problem. I haven’t received any paper statements in the mail so the only thing I have is the online banking portal. The next problem was that you cannot go further than 100 days in the past! WTF? This is online banking and I cannot go further back in time than 100 days? Another trip to bank.

Conveying my frustration to the teller they started to search, and search, and search. When I opened the account I never received any sort of welcome aboard pack with my banking details. The girl who opened the account for me wrote the account details on her business card. So, all I have are some scribbled down details regarding my account. Anyway, about 30 mins. later they finally found the problem. They had set my statement cycle to 6 months which means that once every 6 months I would receive a statement. Obviously not good enough. Is’t it common sense that a business bank account should have 3 month statement cycles?

Anyway, back to the 100 day limit. The teller explained to me how it worked and how it’s my fault. To get online statements I need to go into online banking every month and need to do an export manually. I mean, how dumb am I to assume that you can’t just select any date range to export data over? This is a bank and the 100 limit is simply the bank giving me the finger. If I had signed up for paperless statements I would be truly F’ed since I wouldn’t have neither.

Luckily I opened the account half way through November and I was within the 100 day limit. I’m sure that NAB will understand that this situation has caused my relationship with them to be a deal breaker.

Posted in Broken Bank | Comments closed

Responsive YouTube Video Embeds

I was recently working on a responsive website where YouTube videos could be embedded in the content. Since the website was responsive the embedded video had to resize based on the width of the content are but since YouTube iframe embeds have a hard coded width and height, the size of the iframe was always fixed regardless of the size of the content area.

One prerequisite I set was that the embed code should simply be copied in without any modifications. I knew that if the embed code was going to require changes that somewhere down the line things would go wrong since someone might forget to make these required changes. So, embed code should be pasted as is.

To make this work I required some Javascript:

function resizeIFrame() {
   $('article iframe').each( function() {
 
      // Obtain reference alias to iframe element. 
      var iframe = $(this);
 
      // Get the original iframe width and height.
      var w = iframe.attr('width');
      var h = iframe.attr('height');
 
      // Get the width of the <article> parent element.
      var cw = iframe.parents("article").width();
 
      // Calculate the aspect ratio factor for the new height.
      var s = 1.0 / w * cw;
 
      // Set the new width and height on the iframe.
      iframe.css('width', cw+"px");
      iframe.css('height', (h * s)+"px");
   } );
}
 
$(document).ready( function() {
   resizeIFrame();
 
   $(window).resize( resizeIFrame );
} );

The first important thing to understand about this snippet is that my page content is contained inside an <article> tag as any good front end dev would do these days. It’s also the <article> tag that is defining the width of the content. One thing WordPress does is, it’s wrap the iframe in a <p> tag. In the above Javascript you’ll notice that I use the following jQuery statement to obtain the current content width in pixels:

      // Get the width of the <article> parent element.
      var cw = iframe.parents("article").width();

This little snippet looks for the first <article> tag in one of the parent elements. This means that the iframe can be wrapped in as many tags as you want without breaking the code.

OK. So, the basic gist of the resize code is to use the width and height attributes that are set on the YouTube iframe. We then get the current width in pixels of the content area, calculate the ratio and use this factor to determine the height of the iframe.

In the document.ready we need to manually trigger the first resize and we make sure that when ever the browser is resized we update the size of all the iframes in the content.

Posted in Programming | Comments closed

Timesheets

Timesheets are the funniest thing I’ve come across during my career as a developer. Many companies use timesheets to track the amount of time a certain individual has been working on a certain task. Keeping accurate timesheets can be a great tool for gaining insight into your business. However, in every single instance that I’ve been forced to use timesheets it was used for a different purpose altogether; surveillance.

The problem with timesheets is that many businesses are simply using them the wrong way. When you work in a knowledge environment, such as an agency or development studio, your primary task is to solve a problem. Sometimes a problem is similar, or even very similar, to a problem you’ve solved before. Sometimes a problem is entirely new and forces you out of your comfort zone and learn new things. Within this context there is nothing wrong with keeping track of time.

The problem is that within a creative environment you also work with estimates. You could say that estimates are the enemy of timesheets. An estimate is usually made at the start of a project and is more than often a fixed number (a.k.a. the budget). When you start working on a project a funny thing happens which I call “Insight by Progess”. This means, the longer you work on a certain problem, the more insight you gain into this problem. When you made the estimate you had virtually no insight and half way through the project you understand a lot more of the nuances and edge cases of the problem at hand. Half way through the project the estimate suddenly no longer applies and either needs to be revised or the problem domain needs to change to fit the estimate.

I’m slightly digressing here but you might begin to understand what this might have to do with timesheets. Many companies are using timesheets to track how much time a certain individual has worked on a certain project. However, timehseets should be used to track how much time has been spend on solving a certain problem. The issue is that often timesheets are tied into the billing system of a company. One place I once worked at you had to write at least 40 hours into your timesheet every week and if you didn’t your company email would be cut off. These timesheets would then be used to bill the client (for as long the budget allowed). The problem here of course was that no one was really keeping track of the time they spend on their work and at the end of the week (or sometimes at the end of the month) would bang in a bunch of numbers into their timesheets to get their 40 hours, regardless on whether or not they had actually worked those hours.

This company lost a great opportunity to measure time spend vs estimates made since the timesheets mostly contained bogus information. In this company most projects went over budget and no one knew how to fix it.

Timesheets can be a great source of business information when used correctly and within the correct context but timesheets can also be a thorn in a company’s side when idiots make the rules.

Posted in Business, Management, Opinion | Comments closed

Custom Responsive Bootstrap Carousel

Some time ago I had to implement an image carousel and since I was using Bootstrap to build the website I thought I might as well use the built-in Bootstrap Carousel functionality. However, there was one little caveat. This carousel had to display a reflection overlay and on top of that, the carousel needed to be responsive as well.

Let have a look at the finished result before we move on:

The cool thing about this is, since it’s responsive the embedded iframe version you see above fits within any page column size. You can also check out the full browser version. If you open up the full browser version don’t forget to resize your browser window to see the responsive kick in.

OK. Now some code. This is the basic HTML structure. I’ve have skipped the boilerplate. If you want to have a look at that you’ll have to browse through the code in the link above.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div class="row">
   <div class="span10 offset1">
      <div class="carousel">
         <img src="img/leddisplay-big.png" class="layer display" />
         <img src="img/glass-shine-big.png" class="layer glare" />
 
         <div class="carousel-inner">
            <div id="slide0" class="item active">
               <img src="img/screentest1.jpg" />
            </div>
            <div id="slide1" class="item">
               <img src="img/screentest2.jpg" />
            </div>
         </div>
      </div>
   </div>
</div>

As you can see, the HTML is pretty simple. On line 2; we only want to use 10 out of the 12 spans so we offset 1 span from the left. On line 3 we’re defining some context by wrapping everything in a div with the “carousel” class. Doing this let’s us position the various layers for the background image (the display) and the display glare that overlays on top of everything. This is the CSS that goes along with it:

1
2
3
4
5
6
7
8
9
.carousel {
   min-height: 720px;
}
.carousel .layer {
   position: absolute;
}
.carousel .glare {
   z-index: 1000;
}

This basically sandwiches the div with the class “carousel-inner” declared on line 7 in between the background image and the display glare image, exactly the effect we want.

Now the tricky bit. Since we want it to be responsive we need to realign our image slides whenever our carousel is resized. This means we need to add some Javascript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function onResize() {
   var slide = {
      width: 708,
      height: 444
   }
 
   var original = {
      width: 780,
      height: 721,
   }
 
   var current = {
      width: $(".carousel img.display").width(),
      height: $(".carousel img.display").height()
   } 
 
   var s = 100 / original.width * current.width;
 
   $(".carousel-inner .item").each( function() {
      $(this).width( slide.width / 100 * s );
      $(this).height( slide.height / 100 * s );
 
      $(this).css('margin-top', 37 / 100 * s);
      $(this).css('margin-left', 38 / 100 * s);
   } );
 
   $(".carousel").css("min-height", current.height);
      $(".carousel-inner").css("height", current.height);
   }
}
 
$(document).ready( function() {
   $(window).resize( onResize );
}

We find need to define some information. We need to know the width and height in pixels of the slide (line 2). We also need to know the width and height of the background and glare image (line 7) and we need to get the current width and height of the background (line 12).

On line 17 we calculate the scale factor in percentage based on original and current background image size. This allows us to adjust the size of the slides accordingly.

On line 19 we loop through all the carousel slides and set the width and height based on the scale factor we calculated before. We also need to set the top and left margin since slide doesn’t start at 0,0. Again we use the scale factor to calculate the position.

Finally we can adjust the overall height of the carousel element so that content below it will flow nicely withing the page.

And there you go. That’s all there is to it.

Posted in Programming | Comments closed

We are a Factory!

Years ago I worked at a digital agency were an all company meeting was organised to rally the troops. The CEO took the stage and the first words out of his mouth were:

“We are a factory!”

I understand why CEO’s an other management types like to think of their organisation as a factory. When you think of a factory you think of things like streamlined processes and efficiency and CEO’s like their organisations to be like that.

However, not all organisations are factories. A factory is a very different environment compared to a creative environment. The way I see a factory is as large collection of simple tasks were as a creative environment is typically a small collection of complex tasks.

Factories are usually limited to producing the exact same thing over and over again with only predefined variations. E.g. the assembly line in a Toyota car factory can only produce the same model car over and over again until they physically reconfigure the assembly line to produce something different. Going to a Toyota car factory and asking them to build you a Ferrari is going to be futile, they can’t do it. Because factories produce the exact same thing over and over they can really break down the production process and heavily optimise and streamline it.

A creative environment is the complete opposite of that of a factory. In a creative environment problems are solved. A typical creative environment is a group of smart people solving difficult problems. Different problems might have commonalities but they will never be exactly the same. If you’re a software developer, graphics designer, architect or lawyer, the work you do and the problems you solve all share a common ground but they are unique each and every time and they all require their own unique solution and approach.

Applying Henry Ford style management in a creative organisation is asking for trouble. If you are in charge of a creative organisation where people expect to work autonomously and you start to micro manage them you will create friction and that will be catastrophic in a creative organisation. When a creative environment has a low retention rate then this is usually because of the management style applied in that environment.

We’re not a factory!

Posted in Opinion | Comments closed

WordPress Database Connection Error

The other day I ran into a problem with one of my clients websites that was throwing the Nemesis error for all WordPress developers:

Error establishing a database connection.

Not a very nice error to present to your users.

I was wondering if it was possible to change this message to something more meaningful, or at least, more user friendly. So I came up with the following message instead:

This website is currently experiencing some heavy traffic and is unable to fulfill your request.

The website administrators are working hard at the moment to allocate extra resources.

We appreciate your patience.

The idea is not to present the user with some technicality but to turn the error message into something slightly more positive. If a website is receiving “heavy traffic” then it must be in high demand right? This means that many people want what’s on this website. So even though the website is returning an error it’s not because it’s broken but because the demand is so high, which sort of makes it OK…

Of course, in reality there is a problem with the website that needs to be fixed but I think that presenting a message with a different tone can make a huge impact on how the visitor perceives the problem.

To change the error message for your WordPress installation create a file called db-error.php located in the wp-content directory of your WordPress installation. You can simply fill it with the HTML that you want. However, be aware that at this point the template system has not been loaded yet so you can’t access any of your template resources. At first glance this might come across as an oversight on the behalf of the WordPress core developers but many templates/themes need to access the database for various bits of information such as the website title etc. So you have to make do with the static page.

Posted in Programming | Comments closed

The Bank Transfer

I’ve been running into issues with banking here in Australia. I’d like to share with you some of the ridiculous scenarios I’ve been in. So, this will be the first installment of a series called “Broken Bank”.

The Transfer

Years ago I went into the bank to transfer money. I had recently moved to Australia and I didn’t have a new credit card set up yet to pay the down-payment on a new computer I wanted to buy online. So I go into the bank and wait in line. After 10 or so minutes it was my turn and I explain to the lady at the counter that I wanted to transfer money from my bank account to this other bank account and handed her a piece of paper on which I had carefully written down all the details. She looked at it for maybe 10 or 15 seconds and then slowly started to mumble something. Then she looked up and said to me “No. We don’t do that”. I asked her, “Sorry, what do you mean?”. She said, “We don’t transfer money like this. Well, we can, but it costs $25 and takes 5 working days”. When I asked her why she couldn’t tell me but the problem turned out to be that I was banking with NAB and I wanted to transfer money to CommBank. Apparently banks in Australia are so disjointed that they can’t transfer money to each other without undertaking a herculean effort. Her suggestion to me was to do the following: “Take the money out of the ATM and bring it to a CommBank branch to deposit into the bank account”.

Now, this is a organisation of which it’s core business is transferring money…

Banks in Australia are seriously broken!

Posted in Broken Bank | Comments closed

The Future of Music: Bytebeat

If you enjoy music this might come as a shock/surprise to you but there is a new form of music out there. No, not a style but a new form. It’s called “Bytebeat” and I must say I greatly enjoy it.

My personal favourite at the moment is a track called Crowd, however, if your system doesn’t play OGG’s out of the box there are some other samples on SoundCloud:

But what exactly is Bytebeat? This form a music is not created by instruments in the traditional sense. The music you hear is actually created by a formula. This is the formula for the track Crowd:

((t<<1)^((t<<1)+(t>>7)&t>>12))|t>>(4-(1^7&(t>>19)))|t>>7

Pretty nifty. This tiny formula creates a little over 8 and a half minutes of music.

It sounds a bit rudimentary at the moment but I guess this form of music is still very much in the hands of engineers. Maybe you can compare it with the first piano or organ, I’m sure it wasn’t created by a musician but an engineer instead. It would be interesting to see how this is going to sound in the future when musicians get their heads around this.

There seems to be an iOS application that will let you create this type of music called GlitchMachine. If you’re on iOS you might want to give it a try.

If you want to read more: http://canonical.org/~kragen/bytebeat

Posted in Stuff | Comments closed

Asynchronous Auto-Complete Input Fields with Bootstrap

Bootstrap is a great HTML framework and I’ve been using it a lot lately for most of my projects.

The other day I needed to add asynchronous auto-complete functionality to an input field and Bootstrap seems to offer type ahead functionality out of the box. However, from the documentation it wasn’t instantly clear on how to implement this with an asynchronous ajax call to retrieve the data.

It turns out to be pretty straight forward:

1
2
3
4
5
6
7
8
9
10
$('#myinput').typeahead( {
  source: function( query, process ) {
    $.post("/get-data", {
      query: query
    },
    function( data ) {
      process(data);
    } );
  },
} );

Besides including the bootstrap.js file into your page, you also need to include bootstrap-typeahead.js to add the auto-complete functionality.

Your server script needs to return a single JSON array with the entries you want to appear in the drop-down list. Also note, for Chrome I noticed I had to add the autocomplete="off" parameter to my input tag to prevent it from displaying the built-in browser auto-complete drop-down.

This was tested with Bootstrap v2.2.2

Posted in Programming | Comments closed

The Scale of Perfection

A great thinker once said:

Time is money.

When you start writing code for a living you’ll soon find out how true this statement actually is and unless you have a client who’s after perfection and willing to pay you by the hour for achieving it, you better be damn sure that your estimates are right.

I run a small web development business and in my line of work making accurate estimates is probably the most difficult part about my job. In essence, making estimates is a catch 22. The more time I invest in making an estimate, the more accurate that estimate will be, however, I do not get paid to make estimates. I.e, most of my clients will not pay me for making accurate estimates. This leaves me with the only viable option I have: to guess.

Of course, a guessed estimate isn’t just a random number picked out of thin air. It’s based on years and years of experience. What the good ‘ol gut is telling me.

One important aspect of experience is that when experience increases, the quality of the work also increases accordingly. This means that at some point it becomes difficult to do a mediocre job. Your experience has a direct effect on the quality of the work you deliver. E.g. young and inexperienced programmers are often not so much aware of all the things that can go wrong with the code they write. They mostly focus on the path of least resistance without realising the various “edge cases” such as stuff that could break or external dependencies that can stop working.

So, we can say that experience has a direct effect on the quality of work you deliver and therefore experience also has a direct effect on the estimates you make. In other words, someone with more experience will make different estimates than someone with less experience. Sounds reasonable, right?

Most of my clients intuitively think that because someone has more experience they will work more efficient and that therefore the estimates should be lower. However, this is a fallacy. We all know that delivering high quality work takes more time. I.e. craftsmanship.

So, what does this have to do with the Scale of Perfection? Let’s look at a simple graph:

This graph tries to demonstrate that the Perceived Quality decreases even though the Effort continues.

It’s often very difficult to explain to my clients why a certain job takes a certain amount of time and therefore has a certain associated cost. At the start of a project the Perceived Quality increases rapidly because you go from nothing to something in a short space of time.

Clients like this. They can see progress. However, when work moves behind the scenes and aren’t directly visible to the end user it becomes more difficult for my clients to evaluate progress and justify the cost. To them it might seem that nothing has happened for a week because they don’t “see” any difference and probably ask themselves; “What’s this guy doing, what I’m I paying him for?”. This is what I mean with Perceived Quality.

Note that the Perceived Quality is not the same as the Actual Quality. While the Effort continues, the Actual Quality keeps increasing. E.g. does your client see the value in implementing solid error handling? They might not at first until something goes wrong and when it does they will come back to you and ask you why it’s not working. You might rightfully say that this should be defined in a scope of work or a requirements document. This true. However, my clients are usually not in the business of software. They simply want a website or application that works and a scope or work and requirements document is usually not something they have a direct interest in.

Let’s look at another graph:

In the graph above, the red dot represents an unfinished product. The green dot represents a mediocre but supposedly finished product and the blue dot represents a finished product with a solid layer of polish.

Inexperienced developers will be happy to call a project finished at the green dot. The work is perceived to be finished and all functionality appears to be working. However, after a week or two orders have stopped coming in. After investigation the seems that there was a problem sending out emails because the hosting company changed something in the configuration of the web server. It was only because the client stopped receiving order emails and tried to submit a dummy order that he noticed the order wasn’t arriving. The inexperienced developer didn’t built in any error handling when sending out an email. When emails couldn’t be send out, the error message simply disappeared into the void. It’s unknown how many orders the client lost and what revenue the client missed out on.

The inexperienced developer simply wasn’t aware of things that could go wrong and didn’t cater for it. He certainly didn’t make developing error handling part of his estimate and was therefore cheaper when the client received his quote for the costs of the project.

Would this client have been better of in hiring a more experienced developer? A developer that would have taken notice of the things that could go wrong? A developer that probably would have been more expensive? The client would definitely have received a different estimate and very likely had to pay more to have his website build by a more experienced developer. However, the likelihood that this client would have had problems with his website would definitely have been less and the chance on losing out on revenue very slim.

Perceived Quality is a real thing and unfortunately it’s not always easy to explain why something is of better quality because it appears to “just” work. We only kick and scream at things when they’re broken and don’t coincide with our expectations. The Scale of Perfection is very much part of making correct estimates and being aware of it might make you look at you own estimates in a different way.

Posted in Business, Management, Productivity | Comments closed

Prometheus

I watched Prometheus again over the weekend. Actually, I didn’t. I only watched half. I had to stop half way through because it was so boring and cliché.

If you’re a lover of Sci-Fi, like me, then you’re probably just as disappointed after seeing Prometheus as I was. The first Alien movie released in 1979 is probably THE best Sci-Fi movie ever made. Difficult to top, even by the guy who made it.

Maybe my expectations of Prometheus were to high but then again, Ridley Scott did give us Alien, Blade Runner and Gladiator (OK, that last one is not Sci-Fi and already a bit Hollywood-esque but still a good movie). For those of you who didn’t know, he’s also responsible for the original 1984 Apple Mac commercial. Not a bad portfolio.

The premise of Prometheus is interesting. An Alien species seeds humanity through their own DNA. Somehow ancient human civilizations create star maps of the planetary system their makers originated from. Archaeologists are send to this planet system to investigate and that’s where the movie begins.

One of the cool things about the original Alien movie is where they enter the crashed alien space craft and they find the fossilised body of an alien species. The body seems to be seated in some sort of device, a telescope of some sort, and it’s clear that the chest of the creature has burst open. The original Alien movie doesn’t go into what this creature is or was, they’re to busy fighting for their lives I guess.

Prometheus picks up on this part of the story and I was hoping that they’d done something really interesting with this but they didn’t. Instead it seems like the movie has ended up as a compromise between a bunch of Hollywood studio execs who want a movie for an as broad as possible audience and the faded talent of a once brilliant film director/producer.

Prometheus has ended up as a boring and predicable 2 hour brainless Hollywood action flick. The moment characters are introduced you know who’s going die. It’s like watching an episode of Star Trek where there is suddenly a crew member added to the away team who you’ve never seen before. You know he’s going to die. Watching Prometheus is exactly like that.

It would have been so great if Prometheus had been a lot more scientific. I was actually thinking what it would have been like if Prometheus would have been shot as a fake documentary. I think that would have been very interesting, not only to watch but also for the fan base that has been established over the 30 odd years since Alien was released. It would also have been a great opportunity to give a new spin on the genre of Sci-Fi. We live in an age where everyone is much more in touch with technology and science. To me, Prometheus is a wasted opportunity to do something new and exciting.

Anyhow, I believe they’re working on a squeal to the prequel. I won’t hold my breath. I’m sure it’s going to be another blend Hollywood monstrosity. One can only hope I guess…

Posted in Opinion | Comments closed