Thursday, 31 January 2013

EU Cookie Disclaimers: A Review

In the wake of another confusing announcement by the ICO (the body responsible for information about cookie legislation in the UK) that they won't ask users for explicit consent to use cookies, perhaps it's time to take a look back at what effect the law has had in the last couple of years. Putting to one side the controversy surrounding the legislation itself, it is interesting to survey the way different sites have reacted, and the solutions they came up with.

The Giant Header

This approach has been adopted by the BBC. A big orange and grey banner pushes down the rest of the content with a big continue button. Because it is so enormous, it assumes you didn't miss it and dismisses itself on any subsequent pages

Channel 4 has gone for a very similar approach, this time in shiny silver. Annoyingly it insists on the close button being clicked, so continues to interrupt your viewing until you put the lawyers out of their misery. TFL does the same, presumably on the basis that TFL customers are already accustomed to inconvenience.

An enjoyable example is the aesthetic abberation atop the Unison website, where a gigantic purple banner greets you. At least they are kind enough to only show it once.

  • Technical Achievement: 6/10
  • Legal Paranoia: 8/10
  • User Friendliness: 4/10

The Animated Foldout

For some reason, some organisations opted to animate their legal notices. One can only imagine the bitter UX tears..

Channel 5 have gone for a thin banner which folds down. Given the advertising takeover graphics and the rest of the site, the jQuery animation isn't really up to the task of animating the banner down smoothly - on my PC at least - so it comes down in a distinctly jagged manner. It also neatly covers up prime real estate which probably annoys advertisers.

MoneySavingExpert perform a similar trick, but its so silky smooth you miss it when it isn't there. Nationwide are kind enough to wait a few seconds before showing the banner, and it politely dismisses itself after being viewed once.

  • Technical Achievement: 8/10
  • Legal Paranoia: 8/10
  • User Friendliness: 3/10

The Modal Model

The FT went all out and decided to present their cookie legalese in a modal dialog. It won't dissappear until you click the close button. The Church of England has gone for a similar idea, although as Christians they are merciful enough to show it once only.

When I first checked the Greenpeace site in December, they appeared not to use cookies so didn't need a disclaimer at all. As of January they have opted for the most elaborate modal dialog of all - a gigantic box with two accept buttons, a friendly cartoon and a blurred out background (alas an image; not some great feat of Canvas/WebGL).

  • Technical Achievement: 7/10
  • Legal Paranoia: 10/10
  • User Friendliness: 1/10

The Minimal Viable Product

The majority of commercial companies have, unsurprisingly, decided not to confront their users' initial experience with take-it-or-leave-it messages. Fortunately the legislation is delightfully vague when it comes to deciding how to present these disclaimers. Big companies whose lawyers took a look at the rules have generally judged a cookie notice in the footer to be perfectly adequate and entirely within the rules. Indeed most reputable sites published cookie information within the privacy section long before it became mandatory.

Sites with a simple static link in the footer include Debenhams, NatWest, Facebook, the pretty new itv.com, Lloydstsb.com, and Halifax, Veolia and Tesco and M&S.
  • Technical Achievement: 1/10
  • Legal Paranoia: 2/10
  • User Friendliness: 10/10

The Bigger Picturers

Duchy Originals doesn't appear to publish a cookie policy - as least one that I could find - despite using Google Analytics. This is ironic, since they are the only organisation here which produces actual cookies. Never mind, the British public trusts Waitrose and Prince of Wales implicitly. Long live the King!
  • Technical Achievement: N/A
  • Legal Paranoia: 0/10
  • User Friendliness: 10/10

Tuesday, 29 January 2013

Replacing C2A0 Spaces in JavaScript

I've been doing some work recently with input entered into a contenteditable="true" element, rather than a plain old text input box. This allows me to do some nice styling on the inputted text, but can cause unwanted side effects.

One of these is the appearance of the C2A0 character, otherwise known as the non-breaking space. When typing a space within a content editable, some browsers will insert   instead of a normal ASCII 32 space character.

Here's some code that shows what happens

// suppose this is the content editable..
var element = document.createElement("div");
// and you just typed a space
element.innerHTML=" "

// we get the text to send to the server
var text = element.innerText; 
// on Chrome text will a string that looks like " "
// on Firefox you'll get undefined
// and on IE you'll get an ASCII 32 space!
// so on some browsers..
text == " "; // returns false
The difference becomes obvious when you encode it:
encodeURIComponent(" "); // returns "+"
encodeURIComponent(text); // returns "%C2%A0"
To get around this problem, I wrote the following.
This uses jQuery for brevity. It also yields consistent results across different browsers.

(function() {
    var nbsp = jQuery("
 
").text(); return { getText: function(element) { return jQuery(element).text().replace(nbsp, " "); } } })();
Hope it helps somebody.

Thursday, 22 November 2012

iFrames in 2012. Really?

It is fashionable for web programmers to hate iFrames. I very recently heard some reasons why you might wish to use one. For a social widget placed on a CMS driven page the benefits of an iFrame were:
  • CSS sandboxing
    Iframed content is guaranteed to be unaffected by any styles on the parent page.
  • JS sandboxing
    Similarly, iframes don't inherit a polluted global scope or adjustments to object prototypes.
  • Cross Domain Simplicity
    If the social service runs off a different domain to the parent website, the iframe content (if also hosted on the other domain) will not suffer any cross domain issues.
Let's have a look at each benefit in turn, starting with CSS sandboxing.

The primary purpose of CSS is that it cascades. This is what it was designed for and is generally a good thing. This is easily worked around by making selectors more specific, usually by prepending a classname as a namespace in front of the rules.

However, iframe content that ignores the parent site's CSS required the creation of another set of rules which are separate but in all likelihood highly similar. Any changes to the design or UX of the main site will require developers making changes in two places. 

JS Sandboxing. The main app may have a bunch of stuff sitting on the global scope. It may also have done some things to the prototypes of common objects like Array. This pattern doesn't appeal to everybody, but there is no obligation to use any prototypal enhancements. If the parent app is doing something literally insane on an object prototype then its probably best to tell the developers, rather than working around the problem. 

Things are also messier if the iframe needs to communicate with its parent, even with window.postMessage. Primitives may be passed easily enough, but object instances or events will confuse IE7.

Cross domain issues. Adding a rewrite rule in the Apache / server on nginx etc to point to the other service from the main domain(s) is the way to go. iframes are notorious for introducing their own cross domain issues.

There are some good reasons to use iframes, particularly for serving content/adverts on third party sites over which there is genuinely no control (the HTML5 folks went so far as to reestablish the iframe in the spec: http://dev.w3.org/html5/spec/single-page.html#the-iframe-element). 

In short, if the integration takes place within a single organisation, these benefits only increase the technical debt for everybody. Code may be more complex and harder to maintain. The user's browser will consume more memory due to double evaluations. Sizing and scrolling inconsistencies may crop up across different mobile platforms. iframes are unfashionable for good reason.

Sunday, 9 September 2012

Assertable Pattern: Fluent BDD style test assertions in Pure Java

I'm a fan of expressing unit test logic in terms of behaviour rather than a series of assertions which imply that behaviour. My long term favourite pattern of expressing behaviour has been to use the given, when, then style, for instance:

given(some prior state)
when(something occurs)
then(this should have happened)

Unfortunately, as a static and strongly typed language, Java doesn't make it easy to express things in these terms and you can quite quickly get tied in knots trying to express yourself fluently. For this reason a number of frameworks like EasyB provide an abstraction over the top of the programming language in order to do this easily - and provide a means for non programmers to write tests.

However, the downside is that this logic must at some point be connected to the underlying language, and so you can get into the situations where you're writing Java/Java-like code in a non .java file. At which point your IDE doesn't know what is going on and syntax highlighting - let alone refactorings - no longer work. This is the worst of both worlds.

Therefore, I try to stick with pure Java. Because I don't like asserts, I write what I call "Assertable" classes, which make the assertions, but express them in a more natural way. When combined with a few chained function calls, you can start to make things fairly reasonable.

Suppose I have a bean called "Field" with a couple of getters on it, which I want to test. I can do a bit of assertion in the classic JUnit style:

assertEquals("The field should be required", true, field.isRequired());
assertEquals("The field should not be visible", false, field.isVisible());

I can keep going like this, but a few copy and pastes down the line and my test is a mess, and reading the thing is just so exhausting.

In this case I like to write a nice helper class, which:

  • Doesn't use the word assert - because non-programmers don't use words like that.
  • Is chainable, so you can avoid repetition.
  • Splits the expectation from the test, so you can modify your checks easily.
  • Sits in a different file, so its internal ugliness is hidden and its functions can be reused.
  • Provides helpful failure messages

My FieldAssertable class can be used in a test like this:

thenThe(field)
        .shouldBe().required()
        .shouldNotBe().visible();

This is still Java, but a non Java programmer can read and understand it, and my tests look cleverer.

Here is an implementation of FieldAssertable:

public class FieldAssertable {

  private Field field;
  private boolean booleanExpectation;

  public FieldAssertable(Field field) {
    this.field = field;
  }

  public FieldAssertable shouldBe() {
    this.booleanExpectation = true;
    return this;
  }

  public FieldAssertable shouldNotBe() {
    this.booleanExpectation = false;
    return this;
  }

  public FieldAssertable required() {
    assertEquals(
        getNiceFailureMessage("required"),
        this.booleanExpectation,
        field.isRequired());
    return this;
  }

  public FieldAssertable visible() {
    assertEquals(
        getNiceFailureMessage("visible"),
        this.booleanExpectation,
        field.isVisible());
    return this;
  }

  private String getNiceFailureMessage(String property) {
    return "Field `" + field.getId() + "` " +
           (this.booleanExpectation ? "should be " : "should not be ") +
           property;
  }

}

To finish, I add a means of accessing the Assertable without needing to know its name - using a method that can be statically imported into your test.

public static FieldAssertable thenThe(Field f) {
  return new FieldAssertable(f);
}

This doesn't solve the problem of allowing non-programmers to write acceptance tests (although I think that is always difficult, even with a framework), and it does still require an amount of OO hoop jumping, but it works for me, and it might work for you.

Sunday, 15 April 2012

Gaussian / Normal Functions in JavaScript

Recently I've been indulging myself writing a small game in JavaScript. It didn't take long before I realised I'd need to use some Gaussian / Normal functions to get what I wanted. Firstly, I wanted my AI players and monsters to behave in a non-deterministic manner while tending towards a given decision. Secondly, I wanted to produce animations with a decent easing function.

The former, I decided, relied upon being able to generate random numbers in JavaScript that are not uniformly distributed (noise), but are normally distributed: being more likely to cluster around a distribution defined by a mean and standard deviation. There is good support for this in Java, but JavaScript only supports the uniform random numbers between 0 and 1.

Gaussian Random Numbers in JavaScript

You can use the Box Muller Transform to transform two uniform random numbers into two normally distributed random numbers. There is a subtlety about caching the second number for later use, which can be done neatly in JavaScript.

   /**
     * Returns a Gaussian Random Number around a normal distribution defined by the mean
     * and standard deviation parameters.
     *
     * Uses the algorithm used in Java's random class, which in turn comes from
     * Donald Knuth's implementation of the Box–Muller transform.
     *
     * @param {Number} [mean = 0.0] The mean value, default 0.0
     * @param {Number} [standardDeviation = 1.0] The standard deviation, default 1.0
     * @return {Number} A random number
     */
    Math.randomGaussian = function(mean, standardDeviation) {

        mean = defaultTo(mean, 0.0);
        standardDeviation = defaultTo(standardDeviation, 1.0);

        if (Math.randomGaussian.nextGaussian !== undefined) {
            var nextGaussian = Math.randomGaussian.nextGaussian;
            delete Math.randomGaussian.nextGaussian;
            return (nextGaussian * standardDeviation) + mean;
        } else {
            var v1, v2, s, multiplier;
            do {
                v1 = 2 * Math.random() - 1; // between -1 and 1
                v2 = 2 * Math.random() - 1; // between -1 and 1
                s = v1 * v1 + v2 * v2;
            } while (s >= 1 || s == 0);
            multiplier = Math.sqrt(-2 * Math.log(s) / s);
            Math.randomGaussian.nextGaussian = v2 * multiplier;
            return (v1 * multiplier * standardDeviation) + mean;
        }

    };

Gaussian Probability Density Function in JavaScript

The second function here returns a probability density function for a given shape of distribution which I found handy in my animations. By changing the mean and standard deviation, it becomes really easy to make one thing happen after another, and everything is nice and smooth due to the nature of the bell curves. The function below returns a probability density function which returns the value of the distribution at x.

/**
     * Returns a normal probability density function for the given parameters.
     * The function will return the probability for given values of X
     *
     * @param {Number} [mean = 0] The center of the peak, usually at X = 0
     * @param {Number} [standardDeviation = 1.0] The width / standard deviation of the peak
     * @param {Number} [maxHeight = 1.0] The maximum height of the peak, usually 1
     * @returns {Function} A function that will return the value of the distribution at given values of X
     */
    Math.getGaussianFunction = function(mean, standardDeviation, maxHeight) {

        mean = defaultTo(mean, 0.0);
        standardDeviation = defaultTo(standardDeviation, 1.0);
        maxHeight = defaultTo(maxHeight, 1.0);

        return function getNormal(x) {
            return maxHeight * Math.pow(Math.E, -Math.pow(x - mean, 2) / (2 * (standardDeviation * standardDeviation)));
        }
    };

You can find the complete, up-to-date file here on GitHub

Saturday, 10 March 2012

The Downsides of TDD and other Mantra in Software Religion: QCon London 2012

Science at school was fun, wasn't it? Peering at cells through the microscope, igniting tiny lengths of magnesium. Even physics got pretty good once you got past over-stretching springs. The experiments were the best part, the practical act of discovering whether a hypothesis could be believed or not. Good old Scientific Method. It was drilled into us for years.

Then I went to University, learned to program, and it never occurred that I ought to apply the same principle to my code. Some years later, when I discovered test driven development (TDD), it was a revelation. I was a Born Again tester. I could write something, and then prove that it worked. I was a proper computer Scientist!

What's more, I could always be sure that some idle, careless mistake I made later would not ruin the party later. And of course, testable code is always well-designed code. TDD became part of my religion, and rightly so. Scientific method, better design and a bulletproof guarantee: TDD for the win, right?

Well, not always. A theme running through a number of presentations at this year's QCon London conference was to challenge our unthinking adoption of best-practices, including automated builds, component-based architectures, asynchronous IO etc, which have entered software development lore. Dan North's entertaining talk "Decisions Decisions" neatly exposed the trade-offs that we make when utilising them. None of these are complex, or obscure. It is just that as problem solvers we tend to focus on the benefits and rarely on the costs. In short, we are not always very good scientists.

And TDD is unmistakably a trade-off. Well-tested code doesn't half take a long time to do properly (more so if you favour the super-readable Behaviour Driven Development, invented by Mr North himself). This is a fine for mission-critical code, of course. But when does your code become mission-critical? By definition, it can't be until it is running in production, which presumably will be some time after you wrote it, which rather conflicts with that Write-Tests-First mantra.

And what happens if I do release it to production, but nobody likes it? In that situation I'd like to have done as little work as possible on what amounted to a prototype. I would certainly prefer to not spend hours writing an eloquent suite of tests that formalise a feature nobody wants.

Oh, and thinking back, I have seen many examples of extensively tested code that was both horribly written and horribly tested. Encapsulation and Dependency injection alone, it seems, are not enough to make well designed software.

Daniel Worthington-Bodart's talk on 10-second-builds revealed another major issue with heavily tested projects: they can take ages to build (especially when checking integration points), which can become a major problem in itself. If you follow another best practice of making many small, incremental changes, then waiting for a clean build after each can seriously damage your effectiveness. Coffee run build times can be handy, but you don't want that sort of disruption for the whole day.

Rich Hickey's presentation on simplicity touched on our over-reliance of tools in general. Running a suite of automated tests against some code can and does provide a false sense of security. Code with high test coverage isn't necessarily (or ever) bug free. Your change didn't break any existing tests, so it can't possibly have broken anything. Still... those new bugs in production... how did they happen?

The purpose of these speakers was not to rail, Quixote-like, against these techniques. Despite their drawbacks they remain exactly what you'd expect - best practice. The point was to dismantle some of the religious fervour with which we sometimes adopt them and evangelise them to others. As programmers, we enjoy patterns, and best practices provide general building blocks for writing decent code, which is definitely a good thing. However, as can be the case with Agile adoption, weeks or months pass by and the practices become routine, then habit. Eventually the brain disengages as we degenerate into unthinking adherence.

My takeaway message from QCon was this: never stop thinking, and never stop questioning why you're doing something - especially when somebody else tells you to do it. Good programmers follow these principles, but better programmers always understand and remember their cost.