My Amazon Boycott

Until recently, I had used Amazon without issue for many years. Then…

After weeks of agonising, I decided to treat myself to an XP-Pen 22″ drawing monitor. Of all the Wacom alternatives, XP-Pen appear to have a good reputation and Amazon had the “Artist 22 HD” on sale for £500 – down from £800. It’s important to note that this is described as “brand new” – and the term “brand new” has a very specific meaning: “completely new, especially not yet used.”


So the item turns up and… it has very clearly already been opened and probably used. I say “probably used” because everything that was open was everything you would use to get the unit working: one pen wrapper had been opened, the screen protector already applied to the monitor, the power cable had been opened and untied, etc.

Note also that the item is described as “fulfilled by Amazon.” What this means is, Amazon hold on to the item in their warehouse and they are wholly responsible for it. They openly admit this in their terms and conditions, where it’s stated that they’ll respond to negative feedback about the experience by claiming responsibility for it – which they indeed did when I left negative feedback:


Let’s get one thing clear: This was no mistake. One or more Amazon employees consciously knew that this item was not “new” and tried to palm me off with it anyway. I was already in the throes of two weeks of bad luck with deliveries (things turning up late, being lied to by delivery companies, having to return faulty goods, etc) so when I contacted Amazon’s customer services, I wanted blood.

I told them – politely, but in no uncertain terms – that a) I didn’t believe this was a mistake i.e. that it was intentional; b) that I was insulted that they had even tried to do this, especially to a customer of nearly 10 years; and c) that I didn’t appreciate having my time wasted and I expected some form of compensation or “good will gesture” to make things somewhat right.

They offered me £5. Apparently this is the maximum the customer service agent was allowed to offer. I told him that £5 is an offensively low offer (he even admitted that it’s insignificant compared to the value of the item in question) and I suggested he go speak to his superiors and come back with a better offer before this turns ugly. He came back and reiterated that £5 was the most he was able to offer. I declined it.

So I had no choice. Over the next hour, I:

  • Cancelled my Prime Video subscription. I’ll miss you, Lucifer, but it had to be done.
  • Left the 1 star feedback on the seller’s profile. Note that the UK seller XP-PEN is XP-Pen’s official Amazon account. *
  • Left a 1 star review on Trustpilot. Coincidentally, Amazon UK’s rating on there is an abysmal – but not surprising – 2 stars.
  • Wrote directly to XP-Pen’s main HQ. Not through Amazon or the XP-PEN seller account, but directly to their main email address, through their company website.
  • Dug up all of the blog posts and video reviews of the Artist 22 HD that had lead me to make the purchase in the first place, leaving comments warning people away from buying the item through Amazon.

* Remember that Amazon responded to the feedback. This also leads to it being “struck off” i.e. it no longer counts towards the seller’s overall rating – which is how sellers get to keep their shiny 4/5 star ratings, despite all of the negative feedback left against them. That’s something to think about.

Fortunately, XP-Pen themselves got back to me and offered me a much more reasonable £40 discount, if I decide to buy the item again – which I’m still debating. I’ll reiterate: I’m inclined to believe this whole thing was entirely Amazon’s responsibility. (If you’re wondering why buying the item again is even on the table, it’s because Amazon said that a replacement wasn’t possible and I could only be given a full refund. Therefore, if I still want one, I have to buy another.)

But my issues with Amazon don’t even end there. Just getting the courier to pick up the item was difficult. It was supposed to be collected within 2 days, but they never showed. A new collection was arranged and I was again told that I’d be called by the courier before collection. That call never happened; a woman just turned up at my house unannounced, at 8 in the morning. On top of this, it’s now 7 days since then – 10 days since I requested the refund – and Amazon still hasn’t given me my £500 back. I spoke to customer services again (for the 3rd time) and she said it could take 20-30 days for the refund to be processed. For me, that’s far too long for a company to hold on to such a significant amount of money.

One curious anomaly is that, a few days after I enforced my scorched earth policy, I noticed this little addition to the purchase options:


This wasn’t an option originally. Is this an admission of defeat? They’ve maybe realised that trying to flog used/reburbished items as “brand new” can lead to unacceptable levels of backlash? I’d like to think so.

As I was reading into other people’s experiences with Amazon – covering everything from slow refunds to Amazon Logistics being a dreadful courier service – I also uncovered some things I was less aware of, like Amazon’s treatment of its employees and its tax avoidance practices in the UK.

Add this all together and you see why I’ll be giving Amazon a miss from now on. They’re not the first company I’ve boycotted either; I’ve not bought from Ebuyer since 2012, when their rude customer services tried to deny me my basic consumer rights. There have been multiple occasions where I’ve found an item cheaper on Ebuyer than anywhere else and still refused to buy from them. Some of us actually stick to our principles.

Just to give a quick write-up on the Ebuyer situation: They refused to allow me to return an item, despite 2 different acts in UK law making this a legal requirement – and then when I was putting together a case with Trading Standards and requested that Ebuyer send me copies of all recorded phone calls, internal notes on my case, etc – this being my legal right under the Data Protection Act – they tried to charge me £15 in administration fees. Under the Data Protection Act, the maximum a company is allowed to charge in administration fees is £10 – so trying to scam me out of that extra £5 was veeery naughty.

Anyway. Amazon’s treatment of its employees:

Amazon’s tax:

Amazon UK on Trustpilot:

PS. Fun fact: Amazon owns the domains and; they just forward you to the Amazon website. The poor bastards.

The Tale of Sammy Jo

In this latest installment in the Tales series, we’ll explore the peculiarities of human nature with the help of four aluminium sheep, a hacksaw and a girl named Sammy Jo.

I took a “Design and Technology” class at secondary school, which was a mixture of woodwork, metalwork and electrical engineering. On this particular occasion I had decided to create a mobile (the kind you’d hang over a baby’s crib; not the portable telephone) featuring four dangling aluminium sheep.

Somewhere towards the end of the session, I noticed Sammy Jo storming frantically around the workshop, wearing signs of distress very clearly upon her face. Eventually she reached my workbench and caught sight of my expertly-crafted sheep. She then handed me a sheet of aluminium and a drawing – and pleaded, “Can you help me make this? I’m really struggling.”

I was happy to oblige – so I took her sheet of aluminium, placed it in my vice and then began hacking around a rough outline of the desired shape. As I did this, I noticed the expression on her face gradually change from relief to confusion and eventually, disgust. She interjected, “Stop! Actually, I think I’ll find someone else to help me.” She then removed the aluminium from the vice and stormed off again.

I knew immediately what had happened. Despite the fact that the reason she came to me for help in the first place was because she had seen what I was capable of (i.e. my sheep), she must not have understood or agreed with my methods and instead opted to find help elsewhere. Again, this is despite the fact that the reason she came to me for help in the first place was because she had seen what I was capable of.

It’s a memory that spontaneously pops into my mind occasionally – and I giggle every time. Oh, my dear Sammy Jo. Humans are funny.

The Tale of Leopard Software

The story of this company randomly came to my mind whilst I was showering this morning. Based in the humble town of Knutsford, Leopard Software is the company responsible for the technology behind another, much larger Knutsford-based company: de Poel. To understand the relationship between these two companies – and the circumstances that eventually lead to the inception of Leopard Software to begin with – we must go back to pre-2014.

At one time, de Poel had its own in-house software development team. I interviewed there myself, but after a 5 (yes, 5) minute interview, I unsurprisingly (and thankfully) never heard from them. It was only a year later that I gained some insight into why I might have been so quickly rejected, when I was told the story of a programmer who worked for the company, who was given a disciplinary for wearing the wrong coloured tie with the wrong coloured shirt.

It seems the CEO was well known to be a bit “eccentric” (read: nuts) and insisted that all of his employees dress immaculately – including the software team. It then makes sense that when my interviewer saw me turn up with my long hair and dressed like a lumberjack, he knew I didn’t stand a chance. Apparently no one told this guy that software developers aren’t really in the economic position that they have to put up with this shit – and de Poel developed a terrible reputation amongst programmers in the area.

And that is where Leopard Software comes in. During a conversation with one particular headhunter who was trying to recruit me to work for them, I learned that, so bad was de Poel’s reputation and such was their struggle to employ new programmers that they had to create a new company with a new name and new leadership, just to stand any chance of employing new staff. I don’t know how well that strategy worked out for them, as just knowing they were even loosely associated with de Poel was enough for me to turn them down.

Copestake’s Law

The Turing test is a test … of a machine’s ability to exhibit intelligent behavior equivalent to, or indistinguishable from, that of a human.

So that the machine is judged only on its intelligence and not its ability to imitate human communication, an added stipulation is that the machine need only communicate via text i.e. it need not produce convincing human speech.

I believe that – using only today’s technology – it’s possible to create a very simple AI that would pass the Turing test 100% of the time, if only we were allowed to add one extra condition: The topic of conversation must be football.

Some background

Over the course of my 27 years of life, I’ve had the opportunity to overhear many conversations about football, whether at social gatherings or around the workplace. It was only as recently as 2014 that I began to notice a pattern.

I observed that conversations would begin with openers such as, “Did you see [team x]‘s game at the weekend?” To which the other party would reply, “I know, mate. Shocking.” At this point, one of the two will posit, “They need to start playing [player y].” The other party will now conclude the discussion by expressing some form of agreement.

And it’s here that we arrive at Copestake’s law:

Any one conversation about football is identical to any other conversation about football, with the exception of two variables.

Passing the Turing test

Copestake’s law allows for a beautifully simple algorithm capable of passing our hypothetical Turing test. Depending on whether the AI instigates the conversation or is the respondent, one out of two courses of action can be taken. Below is some illustrative pseudocode.

If (human initiates)
    read input;
    print "I know, mate. Shocking.";
    read input;
    print "I know, mate.";
    set x to (team name);
    print "Did you see " + x + "'s game at the weekend?";
    read input;
    set y to (player name);
    print "They need to start playing " + y + ".";
    read input;

Closing comments

I had to get some amusement out of this Euro 2016 bollocks – so this is it. Forgive me, world.

A quirky solution to HackerRank’s “Team Formation” problem

As a preface, I’d like to say that this article isn’t intended to help people cheat at the problem, but is posted for the intellectual exercise contained within. Hopefully the folks in and around the HackerRank community won’t mind.

Lately I’ve been having some fun with the challenges on HackerRank. By all accounts, the general (and consensual) solution/s to the Team Formation problem involve some combination of data structures, sorting algorithms and such.

That’s all well and good, but having hit my head many times as a child, something in the back of my mind was nagging away at me, insisting that there existed a more specialized solution. As is a recurring theme of this blog – and indeed my life – I could not resist its call. Fortunately, this one actually paid off.

The algorithm I subsequently developed does not (in theory) depend on any particular data structure nor require sorting; it satisfies the condition of being “greedy“; (potentially) has a time complexity of O(n), requiring only 1-2 loops; and for added lolz, can be made stable and even online if necessary.*

* While this is all possible, in some cases it’s not practical; in one particular implementation I did have to use std::sort. I’ll elaborate more on this at the end of the post.

The problem (briefly)

The objective of the Team Formation challenge is to accept a list of integers representing skill values for members of a team – and to organise those members such that a) for any one member with skill x, either that member is the lowest skilled member of the team or there exists another member of the team with the skill x-1 – and b) the members are organised into as few teams as possible, with members being spread as evenly as possible across every team. To pass the test, one must output the size (number of members) of the smallest team.

For example, given the set \{ 4, 5, 2, 3, -4, -3, -5 \}, the two teams that can be formed are \{ -5, -4, -3 \} and \{ 2, 3, 4, 5\}. The smallest team is \{ -5, -4, -3 \} and so the correct output for this test case is 3. (Note that it would be erroneous to organise this input into the teams \{ -5 \}\{ -4, -3 \} and \{ 2, 3, 4, 5\}, for example.)


Imagine a grid. If you’re struggling, below is a visual to help you along:


A graph, similar in style to those pioneered by William Playfair in the late 1700s.

For an example input of \{ 51, 47, 45, 46, 46, 47, 48, 47, 50, 47, 47, 49, 51 \}, the correct team formation can be visualised as:


If another value 48 were to be added, it would travel down the x axis towards 0 to the next free slot, resulting in:


This works because there is a “free” 47 at coordinates (3, 47). If this were not the case, the new value 48 would be placed at the end of the row – at (5, 48). Below is another example, using an additional value of 50.

You get the idea by now.

You get the idea by now.

Following a set of rules for how to handle various local conditions when a new member is added, it’s possible to organise and – if implemented properly – effortlessly reorganise the members into their most appropriate structure. You can even track the size of each team on the fly.

The implementation

For the same reason that I’ve not gone into the algorithm in much depth (i.e. not wanting to help out the dirty cheaters too much), I won’t post any code here. However, I did write an implementation which passed the HackerRank test cases.

Following that, I decided to grab a few of the other top scoring solutions along with some of the larger test cases and benchmark them locally against my algorithm using Very Sleepy. The numbers are listed below (lower is better):

User Average time
surwdkgo 0.494
visanr 0.275
Kostroma 0.182
Meeeeee! 0.166

As you can see, I outperformed the competition – which was a reassuring conclusion to this little experiment, having spent far more time and energy than was warranted.

Some notes about implementation

This algorithm doesn’t require use of any particular data structure or sorting algorithm; you can just use the integer value of the skill level x and perform local operations on x-1 and x+1 and such.

Under certain conditions (e.g. access to large memory or some assurance that x will be within a certain range) this means you can perform all necessary operations using a regular unsorted integer array. However, as the conditions of the challenge state that x may be as large as 10^9 – which is far too big for the test scenario – that leaves two options: use another lookup method (e.g. hash tables) or sort the array.

In my first attempt I did use an unordered_map, but lookups created a bottleneck so I tried out the sorting approach, which significantly improved performance.

Even after all of this, there’s still a voice in my head telling me that an even better algorithm exists, but… I must move on. I’ve satisfied my curiosity (mostly). And I have things to draw.

Fuck it

For a while now (and by “while” I mean 5+ years) I’ve been wanting to create a web comic. By some miracle I have taken the first step towards that goal and set up a Tumblr blog to host said strips.

For those who are interested, the URL is I’ll probably also be pestering my Twitter followers with updates – so there’s the option of following me there

My intention is that the cartoons will feature a number of topics, from gaming to world events. This is all assuming I actually post anything further in the future (I will try, I promise).