Last updated: February 15, 2019 09:22 PM (All times are UTC.)

February 13, 2019

Here’s a talk I did at a lovely inclusive, anarchic, friendly conference last month called Monki Gras. It was great; a low ticket-price, proper food, craft beers and melted cheese snacks, a diverse group of speakers and a diverse audience. I made loads of new friends and heard loads of new perspectives.

February 12, 2019

February 10, 2019

Solve the problem then make the app.

I’ve been guilty of designing and launching products that I’ve personally wanted to see on the market and guess what, most of them failed.

Understanding why they fail is important to any aspiring startup founder. Learn from it and make your next project awesome.

In this blog I talk about how your next project should solve a problem or take an existing problem and out a unique spin on it.

olav-ahrens-rotne

Mike Cappucci, a colleague and good friend in the US and I often talk about new product ideas and he’s constantly reminding me to find the problem before I get too excited about my new idea.

Here’s where I fail. I think of an idea, I get excited and I want to design it. That’s just how I work.

There’s nothing wrong with this approach but if I could take back the hours and hours of design time that wen’t nowhere I would. I’d probably use those hours elsewhere with more value to my business.

It’s important to have someone within your professional network that will tell you honestly that your idea is bad. It will save you time. You’ll find that new ideas grow from bad ones, it’s just part of the process.

So let’s start with a basic rule. Find a problem and work with it.

The problem doesn’t need to be big or have world changing effects, it just needs to be there. It needs to be something that you think could be solved with a simple technical solution.

I bolded simple. Because ideas can be complex but the solution should be simple. Uber didn’t become the go-to taxi app by being confusing, it just works — even your grandma could use it.

Now you have your problem workshop it. Ask everyone you know about the problem and how they tackle it, you may be surprised with their solutions. Next, run it by someone you trust in the startup game. Someone that will tell you truth as quite often people tell you what you want to hear.

Problem identified, research done – get together a MVP. It doesn’t need to be much it just needs to showcase your solution – after that… well that’s another blog entirely.

clark-tibbs

Solution already exists but I have a unique spin on the idea.

The problem doesn’t need to be original it just needs to exist. You may think that you could do what the Deliveroo app does but for every meal you sell you plant a tree. Go for it. The world needs green thinkers like you. Build it.

Make sure your solution ticks new boxes. If you just want to be Deliveroo and you launch… people will just want to use Deliveroo as it’s established and they have an account already active.

BUT if you want to be the green version of Deliveroo and you have an audience you can target the differences too, you have yourself a unique market opportunity.

rawpixel

Although brief, this blog should highlight one important thing.

Find the problem first, then make the app.

If you’ve enjoyed this blog, I have many more. Plus you can follow me on Twitter for more thoughts.

The post Solve the problem then make the app. appeared first on .

February 09, 2019

Future tech thoughts: e-sports for fitness

A month ago I purchased a smart trainer for my bike. I liked the idea of having an indoor activity that would link up to some cool apps to track and monitor my fitness progress.

I like it. I go to the garage early in the morning, spin up for an hour, sweat loads and come out of it feeling energised and ready for the day.

I’ve also been testing some of the main smart trainer apps on the market (Zwift, TrainerRoad, Rouvy, FulGaz & The SufferFest to name a few). Perhaps I’ll write a separate blog on those as they range in quality and price.

Zwift + Smart Trainer

This got me thinking, what does the future of smart training look like and how do they make money from it?

We all know gaming e-sports is huge with many tournaments having multi million dollar prizes (The record is for DOTA2 at $24.6 million). e-sports isn’t a new term, it’s been growing at crazy rates for years and will only keep growing.

Sponsors throw money at these tournaments, some tournaments are like Olympic games with huge stadiums! It really is exciting but why stop at gaming?

DOTA 2 Tournament

There’s huge potential for other indoor training types to become e-sports. Ultra marathons via your treadmill. Rowing championships via your machine in the basement.

You could apply the same gaming formula to loads of low-cost smart products that are sweeping the market. It just takes some vision and lot’s of funding.

Zwift + Treadmill

My smart trainer has the ability for me to ride alongside with thousands of other cyclists all over the world and while there are some prize based online tournaments now… in the future this could be worth billions.

We’re likely to see a huge surge in smart fitness products in the coming years. We’ll probably see ordinary products like trainers get smarter.

Anything you can do at home or without any professional gym setting could be weaponised into a smart product.

I really believe that smart tournaments will attract huge sponsors and million dollar prizes for those who take part.

Wattbike Atom via Bike Radar.

Imagine the scene. A stage with 10 smart trainers with Manic Street Preacher level stadium rock lights beaming down onto them. The gun goes and we’re off, ten work class cyclists race to the finish line while users at home try to keep up.

The victor stands on the stage panting while holding a check for $40million, cut to Cat Deeley who’s live with the person who finished top of the home racers via video link. “Congratulations, you’ve also won a million dollars”. Cut to commercials.

So what do we call it. Is it e-sports or is it f-sports, f for fitness. Perhaps s-sports for smart. One way or another I believe we’ll be reading lots more about smart tournaments in 2019 onwards.

Enjoyed this blog? follow me on Twitter

The post Future tech thoughts: e-sports for fitness appeared first on .

February 08, 2019

In no particular order, here are some of my favourite reads from 2018:

Atomic Habits Atomic Habits by James Clear

Of all the books I read last year, this had the biggest impact on me. James Clear shares a framework for building good habits, which can be reversed to help stop bad habits. It’s packed full of practical advice. A book I’ll be revisiting often.

The quality of our lives often depends on the quality of our habits.

Every action you take is a vote for the type of person you wish to become.

It is so easy to overestimate the importance of one defining moment and underestimate the value of making small improvements on a daily basis.

Making Websites Win Making Websites Win by Karl Blanks and Ben Jesson

I build websites for a living, so I was obviously excited to pick this up when I heard about it. The market is flooded with books about how to design and build websites, but very few teach how to make effective websites. This is that book. At the time of writing, the digital edition is £1.99/$1.95. It’s crazy how much value you’ll get for less than a cup of coffee.

If you do make your website more beautiful, ensure your designs are minimalist—visually and technically. Keep them elegantly simple and easy to update. And don’t forget that—like the Stanley hammer—good functional design has a beauty of its own.

The top companies make frequent, incremental changes, and rarely (if ever) have huge website redesigns.

The best marketers create funnels that counter each objection at the exact moment that the visitors are thinking it. And the only way to do that is to understand the visitors well.

Lying Lying by Sam Harris

A thought-provoking quick read (it’ll only take about an hour) on the damage that can be caused by lying. Harris makes a clear argument that few of us are ever in a situation where lying is necessary or beneficial.

Honesty is a gift we can give to others.

Unlike statements of fact, which require no further work on our part, lies must be continually protected from collisions with reality.

Lies are the social equivalent of toxic waste: Everyone is potentially harmed by their spread.

How To Be Right: … in a world gone wrong How To Be Right: … in a world gone wrong by James O’Brien

James O’B – radio presenter on LBC and host of one of my favourite podcasts, Mystery Hour – has spoken to more disgruntled people than most of us. In this book, he dissects the “faulty opinions” from callers to his phone-in show. This book reinforced my belief that most people aren’t inherently bad, but have been misled by politicians and media organisations.

The challenge is to distinguish sharply between the people who told lies and the people whose only offence was to believe them.

Hardly anyone is asked to explain their opinions these days; to outline not just what they believe, but why.

I believe it boils down to a simpler truth than many of us are prepared to admit to: some people are determined to believe in the fundamental badness of others. They choose to.

The Obstacle Is the Way The Obstacle Is the Way by Ryan Holiday

I’ve read Obstacle Is The Way twice now, and I got just as much from it on the second pass. This book serves as a practical introduction to stoicism. If you’re new to the subject of stoic thinking, there’s much to be gleaned from these pages.

Today, most of our obstacles are internal, not external.

Think progress, not perfection.

If an emotion can’t change the condition or the situation you’re dealing with, it is likely an unhelpful emotion. Or, quite possibly, a destructive one.

When When by Daniel H. Pink

Daniel Pink, in this well-researched book, shares his findings on the science of when things should be done. You might be pleased to hear that he doesn’t advocate waking up at 4am to workout (as seems the craze in the productivity space). Instead, reading this book will make you more aware of your own patterns and routines and make the most of them. As the author says, “I used to believe in ignoring the waves of the day. Now I believe in surfing them.”

First, our cognitive abilities do not remain static over the course of a day. During the sixteen or so hours we’re awake, they change—often in a regular, foreseeable manner. We are smarter, faster, dimmer, slower, more creative, and less creative in some parts of the day than others.

Ericsson found that elite performers have something in common: They’re really good at taking breaks.

I used to believe in ignoring the waves of the day. Now I believe in surfing them.

Daring Greatly Daring Greatly by Brené Brown

I read this book as part of the book club I’m in. After the first chapter, I wasn’t sure where the book was heading and if I was going to connect with the message, and honestly, if it wasn’t for the book club, I’d have put the book down and moved on. I’m glad I kept reading, because this a wonderfully warm and tender book about vulnerability. It’s a book I needed to read.

We are a culture of people who’ve bought into the idea that if we stay busy enough, the truth of our lives won’t catch up with us.

Connection is why we’re here. We are hardwired to connect with others, it’s what gives purpose and meaning to our lives, and without it there is suffering.

Vulnerability is the core of all emotions and feelings. To feel is to be vulnerable. To believe vulnerability is weakness is to believe that feeling is weakness.

It Doesn't Have to be Crazy at Work It Doesn’t Have to be Crazy at Work by Jason Fried and DHH

The founders of Basecamp have written a much-needed manifesto for running a calm business. Social media is full of workaholics touting that you need to pull in all-nighters to be successful,  but this book shows that it is possible to run a successful business by working sensible hours, taking vacations, spending time with family and getting a good nights sleep.

The answer isn’t more hours, it’s less bullshit. Less waste, not more production. And far fewer distractions, less always-on anxiety, and avoiding stress.

Cutting back when times are great is the luxury of a calm, profitable, and independent company.

A business is a collection of choices. Every day is a new chance to make a new choice, a different choice.

Notes on a Nervous Planet Notes on a Nervous Planet by Matt Haig

Following up from Reasons to Stay Alive, Matt Haig has written a manual on how to live a sane life in a world that is trying to make us crazy. He covers a breadth of topics that cause anxiety and unhappiness: consumerism, social media, technology, and even reading or watching the news.

The thing with mental turmoil is that so many things that make you feel better in the short term make you feel worse in the long term. You distract yourself, when what you really need is to know yourself.

There is no shame in not watching news. There is no shame in not going on Twitter. There is no shame in disconnecting.

The whole of consumerism is based on us wanting the next thing rather than the present thing we already have. This is an almost perfect recipe for unhappiness.

The Entrepreneur’s Guide to Keeping Your Shit Together The Entrepreneur’s Guide to Keeping Your Shit Together by Sherry Walling

Sherry Walling, co-host of the Zen Founder podcast, has written an important book on staying healthy while dealing with the stresses of running a business. The premise is loud and clear: “the reality is that without a healthy founder, it is impossible to have a healthy business.”

When we lose deep connection with others, our health suffers and our businesses suffer.

Freedom and anxiety. Ingenuity and failure. Adventure and instability. Meaning and isolation. These stand in stark contrast to each other and represent the great risk of being an entrepreneur.

As an entrepreneur, one of the smartest things you can do is to make sure you are in a community—not only with your family and friends, but also in a community with other entrepreneurs.

Profit First Profit First by Mike Michalowicz

While I found the author annoying at times (it’s another business book that should have been 100 pages or less), there’s a lot of learn from this book. In fact, it changed the way I run the finances in my own business. Recommended if you run a small business.

Putting your nose to the grindstone is a really easy way to cover up an unhealthy business.

At the end of the day, the start of a new day, and every second in between, cash is all that counts. It is the lifeblood of your business.

Eliminating unnecessary expenses will bring more health to your business than you can ever imagine.

The Simple Path to Wealth The Simple Path to Wealth by J.L. Collins

This book is a mix of advice on investments and general financial health and surprisingly isn’t as dry or boring as you might expect. There’s plenty of wisdom to found. I loved the concept of ‘F-You money’, which means having enough savings to give you control and autonomy.

It’s your money and no one will care for it better than you.

There are many things money can buy, but the most valuable of all is freedom. Freedom to do what you want and to work for whom you respect.

It’s a big beautiful world out there. Money is a small part of it. But F-You Money buys you the freedom, resources and time to explore it on your own terms.

Psychopath Test The Psychopath Test by Jon Ronson

After reading So You’ve Been Publicly Shamed, and more recently The Psychopath Test, Jon Ronson has quickly become one of my favourite authors. This books follows Ronson’s journey into psychopathy and how dangerous it can be to misdiagnose people. I also found it interesting that “a disproportionate number of psychopaths can be found in high places”, such as CEOs or politicians. Makes sense when you think about current world affairs.

I wondered if sometimes the difference between a psychopath in Broadmoor and a psychopath on Wall Street was the luck of being born into a stable, rich family.

‘Sociopaths love power. They love winning. If you take loving kindness out of the human brain there’s not much left except the will to win.’ ‘Which means you’ll find a preponderance of them at the top of the tree?’ I said.

If you’re after more book recommendations, I also made a list of the best books I read in 2017. I’d love to hear your book recommendations too! Shoot me a tweet.

Reading List 222 by Bruce Lawson (@brucel)

January 31, 2019

Model Software by Andy Wootton (@WooTube)

Today, I had to stop myself writing “solving the problem” about developing software. Why do we say that? Why do software people call any bounded area of reality “the problem domain”?

My change of mind has been fermenting for a while, due to modelling business processes, learning about incremental, agile software development and more recently writing and learning functional programming. In the shower this morning, I finally concluded that I think software is primarily a modelling medium. We solve problems using the models we build.

Wanting to create another first-person shooter game or to model the fluids in a thermo-nuclear reactor are challenges, not problems. We build models of systems we have defined and the systems don’t even have to be real. I read a couple of days ago that a famous modern philosopher said our world is made of both reality and our ideas. Assuming the computer hardware is real, the software can model either reality or our imagination; our chosen narrative.

‘Digital’ gets everyone working with software models instead of reality. Once everyone lives inside the shared model, when does it become our reality?

Or when did it?

January 30, 2019

Chicken McNuggets by Stuart Langridge (@sil)

Back in the old days, when things made sense, you could buy Chicken McNuggets in boxes of 6, 9, and 201. So if you were really hungry, you could buy, for example, 30: two boxes of 9 and two boxes of 6. If you weren’t that hungry you’re a bit scuppered; there’s no combination of 6, 9, and 20 which adds up to, say, 14. What if you were spectacularly hungry, but also wanted to annoy the McDonalds people? What’s the largest order of Chicken McNuggets which they could not fulfil?

Well, that’s how old I am today. Happy birthday to me.

Tomorrow I’m delivering my talk about The UX of Text at BrumPHP, and there may be a birthday drink or two afterwards. So if you’re in the area, do drop by.

Best to not talk about politics right now. It was bad two years ago and it’s worse now. We’re currently in the teeth of Brexit. I thought this below from Jon Worth was a useful summary of what the next steps are, but this is no long-term thing; this shows what might happen in the next few days, which is as far out as can be planned. I have no idea what I’ll be thinking when writing my birthday post next year. I’m pretty worried.

Right, back to work. I’d rather be planning a D&D campaign, but putting together a group to do that is harder than it looks.

  1. yes, yes, now you can get four in a Happy Meal, but that’s just daft. Who only wants four chicken nuggets?

January 29, 2019

Grooming the Backfog by Graham Lee

This is “Pub Walks in Warwickshire”. NEW EDITION, it tells me! This particular EDITION was actually NEW back in 2008. It’s no longer in print.

Pub Walks in Warwickshire

Each chapter is a separate short walk, starting and finishing at a pub with a map and instructions to find your way around the walk. Some of the instructions are broken: a farmer has put a barbed wire fence across a field, or a gate has been replaced or removed. You find when you get there that it’s impossible to follow the instructions, and you have to invent a new route to get back on track. You did bring a different map, didn’t you? If not, you’ll be relying on good old-fashioned trial and error.

Other problems are more catastrophic. The Crown at Napton-on-the-hill seems to have closed in about 2013, so an attempt to do a circular walk ending with a pint there is going to run into significant difficulties, and come to an unsatisfactory conclusion. The world has moved on, and those directions are no longer relevant. You might want to start/end at the Folly, but you’ll have to make up a route that joins to the bits described here.

This morning, a friend told me of a team that he’d heard of who were pulling 25 people in to a three-hour backlog grooming session. That sounds like they’re going to write the NEW EDITION of “Pub Walks in Warwickshire” for their software, and that by the time they come around to walking the route they’ll find some of the paths are fenced over and the pubs closed.

Decomposing the Analogy

A lengthy, detailed backlog is not any different from having a complete project plan in advance of starting work, and comes with the same problems. Just like the pub walks book, you may find that some details need to change when you get to tackling them, therefore there was no value in spending the time constructing all of those details in the first place. These sorts of changes happen when assumptions about the organisation or architecture of the system are invalidated. Yes, you want this feature, but you can no longer put it in the Accounts module because you found that customers think about that when they’re sorting their bills, not their accounts. Or you need to put more effort into handling input from an external data source, because the way it really works isn’t quite the same as the documentation.

Or you find that a part of the landscape is no longer present and there’s no value in being over there. This happens when the introduction of your system, or a competitors’, means that people no longer worry about the problem they had back at the start. Or when changes in what people are trying to do mean they no longer want or need to solve that problem at all.

A book of maps and directions is a snapshot in time of ways to navigate the landscape. If it takes long enough to follow all of the directions, you will find that the details on the ground no longer match the approximation provided by the book.

A backlog of product features and stories is a snapshot in time of ways to develop the product. If it takes long enough to implement all of the features, you will find that the details in the environment no longer match the approximation provided by the backlog.

A Feeling of Confidence

We need to accept that people are probably producing this hefty backlog because they feel good about doing it, and replace it with something else to feel good about. Otherwise, we’re just making people feel bad about what they’re doing, or making them feel bad by no longer doing it.

What people seem to get from detailed plans is confidence. If what they’re confident in is “the process as documented says I need a backlog, and I feel confident that I have done that” then there’s not much we can do other than try to change the process documentation. But reality probably isn’t that facile. The confidence comes from knowing where they’re trying to go, and having a plan to get there.

We can substitute that confidence with frequent feedback: confidence that the direction they’re going in now is the best one given current knowledge, and that it’s really easy to get updates and course corrections. Replace the confidence of a detailed map with the confidence of live navigation.

On the Backfog

A software team should still have an idea of where it’s going. It helps to situate today’s development in the context of where we think (but do not know) we will be soon, to organise the system into a logical architecture, to see which bits of flexibility Ya [Probably] Ain’t Gonna Need and which bits Ya [Probably] Are. It also helps to have the discussion with people who might buy our stuff, because we can say “we think we’re going to do these things in the coming months” and they can say “I will give you a wheelbarrow full of money if you do this one first” or “actually I don’t need that thing so I hope it doesn’t get in my way”.

But we don’t need to know the detailed steps and directions to get there, because building those details now will be wasted effort if things change by the time we are ready to tackle all of the pieces. Those discussions we’re having with the people who might buy our stuff? They might, and indeed probably should, change that high-level direction.

Think of it like trying to navigate an unknown landscape in fog. You know that where you’re trying to get to is over there somewhere, but you can’t clearly see the whole path from here. You probably wouldn’t just take a compass bearing and head toward the destination. You’d look at what you can see around, and what paths there are. You’d check a map, sure, but you’d probably compare it with what you can see. You’d phone ahead to the destination, and check that they expect to be open when you expect to get there. You’d find out if there are any fruitful places to stop along the way.

So yes, share the high-level direction, it’s helpful. But share the uncertainty too. The thing we’re doing next should definitely be known, the thing we’re doing later should definitely be guesswork. Get confidence not from colouring in the plan all the way up to the edges, but by knowing how ready and able you are to update the plan.

January 18, 2019

Reading List by Bruce Lawson (@brucel)

A (usually) weekly round-up of interesting links I’ve tweeted. Sponsored by Smashing Magazine who slip banknotes into my lacy red manties so I can spend time reading stuff.

January 17, 2019

Are you a recent graduate (or current student) from the School of Computer Science at the University of Birmingham? Stickee is a technology company based...

The post Calling all UoB CompSci students & grads appeared first on stickee.

The Difference Engine – the Charles Babbage machine, not the steampunk novel – is a device for finding successive solutions to polynomial equations by adding up the differences introduced by each term between the successive input values.

This sounds like a fairly niche market, but in fact it’s quite useful because there are a whole lot of other functions that can be approximated by polynomial equations. The approach, which is based in calculus, generates a Taylor series (or a MacLaurin series, if the approximation is for input values near zero).

Now, it happens that this collection of other functions includes logarithms:

\(ln(1+x) \approx x – x^2/2 + x^3/3 – x^4/4 + \ldots\)

and exponents:

\(e^x \approx 1 + x + x^2/2! + x^3/3! + x^4/4! + \ldots\)

and so, given a difference engine, you can make tables of logarithms and exponents.

In fact, your computer is probably using exactly this approach to calculate those functions. Here’s how glibc calculates ln(x) for x roughly equal to 1:

  r = x - 1.0;
  r2 = r * r;
  r3 = r * r2;
  y = r3 * (B[1] + r * B[2] + r2 * B[3]
    + r3 * (B[4] + r * B[5] + r2 * B[6]
        + r3 * (B[7] + r * B[8] + r2 * B[9] + r3 * B[10])));
  // some more twiddling that add terms in r and r*r, then return y

In other words, it works out r so that it is calculating ln(1+r), instead of ln(x). Then it adds together r + a*r^2 + b*r^3 + c*r^4 + d*r^5 + ... + k*r^12…it does the Taylor series for ln(1+r)!

Now given these approximations, we can combine numbers into probabilities (using the sigmoid function, which is in terms of e^x) and find the errors on those probabilities (using the cross entropy, which is in terms of ln(x). We can build a learning neural network!

And, more than a century after it was designed, our technique could still do it using the Difference Engine.

January 15, 2019

My goals are in sight by Daniel Hollands (@limeblast)

My goals are in sight

Since the end of 2015 I've been using a board on Trello to log and track my yearly goals.

The setup is quite simple - at the start of each year I review the goals in the previous year's column, using a sticker to indicate success or otherwise, then create a new column for the upcoming year. Each goal is written using the SMART methodology, and added as a card, then embellished with an image that represents the goal to serve as visual reminder.

My goals are in sight

For the most part this has worked pretty well. It informs me where I was in previous years, reminding me what problems I wanted to solve at the time, and lets me appreciate how far I've progressed since.

But it suffers from the same issue that other new year's resolutions suffer from - they're too easy to forget about. Sure, you start the year full of enthusiasm (despite the hangover), but by the 2nd of January you're back at work, by the end of the week all your festive cheer has drained away, and there's a good reason the 12th of January is known as Quitter's Day.

But what kind of maker would I be if I didn't attempt to solve this problem?

I figured the easiest way to keep my goals in mind was to setup a display somewhere in the house that used the Trello API to show the goals, reminding me at a glance what they are every time I walk past.

Mirror mirror on the wall

My first attempt at this was to use the MagicMirror² platform, as since my earliest maker days I've wanted to construct my own MagicMirror, but always fell short of actually starting because I didn't feel my woodworking abilities were up to scratch.

Not content to let something as silly as that stop me, I reached into my LEAN methodology toolkit, grabbed a Raspberry Pi and an old laptop screen, and set about creating a Minimum Viable Product (MVP) - that is, just enough to prove the concept without using too many resources. In this instance, that meant installing the software and exploring the options provided within.

My goals are in sightIllustration by Henrik Kniberg.

Now, the MagicMirror² platform seems very well designed, with a lot of support for pulling data from a range of sources, but it wasn't quite what I wanted for this project. It had the benefit of being able to read directly from my Trello list, but each goal was nothing more than an entry on a small bulleted list, lost in among a whole bunch of other information.

I could have spent some time building my own module for the platform, but this felt like a step in the wrong direction as rather than solving the direct problem - that of displaying my goals - I'd instead be spending my time Yak shaving in the guise of learning how to build the module.

Digital signage solution

It was actually during the initial install of Raspbian for the above idea that I first saw what would end up being my solution to the problem, an operating system offered via the NOOBs installer called Screenly.

Screenly, it turns out, is a digital signage platform which lets you remotely configure any number of assets (such as webpages, images, YouTube videos, et al) to display, in rotation, upon your Pi's screen. I'd never heard of it before, but figured if I could find a suitable HTML carousel or sideshow template, I'd be able to host it for free using GitHub Pages, so I set out to find a suitable template.

I reviewed a couple of choices, including a Fullscreen Background Image Slideshow with CSS3 template, and the Vegas 2 Background Slideshow jQuery Plugin, but settled upon the Fullscreen Image Blur Effect with HTML5 template provided by codrops, as this provided the quickest route to the features I wanted - namely the ability to automatically switch between multiple images and messages at an easily controlled rate, all without requiring me to spend too long learning anything new.

I already had the images and wording for the goals, so it took no more than about an hour to update my own content into the template, and make some small changes to the design and functionality, and before I knew it, I had a sideshow hosted on GitHub.

My goals are in sight

Of course, all this information is hard-coded into the template, rather than being dynamically supplied by the Trello API - but do I really need it to be dynamic?

By definition, a yearly goal is something you set once a year, and the 30 minutes it might take each year to update the sideshow is easily more justifiable than the several hours it'll take to implement something which pulls in from the API, not to mention the relative complexity and cost of hosting a dynamic script over that of a static page which I can host for free.

That's not to say I'd never make the slide show dynamic - it might be fun to learn the Trello API, and I could probably do the whole thing using client side JavaScript, or as a Ruby Serverless application, but the LEAN methodology advocated failing fast, such as I did with the MagicMirror² approach, so there's no point spending any time even looking at anything like that when there's a quicker way of achieving the same end result.

My goals are in sight

Bringing it all together

Now that I had an eye-catching slide show of goals hosted on GitHub, all that remained was to install Screenly and point it at the page. But it's at this point that I took a second pivot - given the sheer mess of components needed to make the laptop screen work, was this really the best approach?

My goals are in sight

To make a suitable enclosure for the display, driver board, and Pi, would take more effort that I really wanted to spend, and seeing as I am still planning on building my own smart mirror (spurred on by how impressed I was with the MagicMirror² platform, even if it wasn't suitable for this project) I'd rather keep these components for that.

So instead, as you will see from the feature image for this post, I used my 7" touchscreen display instead. This has the benefit of being compact and self contained, providing something that was large enough to grab your attention, but small enough that you can use it like a picture frame, and with as much versatility.

All in all, I'm very happy with the outcome of this project, even if it didn't end up look anything like I thought it would, because I think the end result is far better than what I initially had in mind, and I was able to reach it quickly and easily.

My goals are in sight

My goals are in sight by Daniel Hollands (@limeblast)

My goals are in sight

Since the end of 2015 I've been using a board on Trello to log and track my yearly goals.

The setup is quite simple - at the start of each year I review the goals in the previous year's column, using a sticker to indicate success or otherwise, then create a new column for the upcoming year. Each goal is written using the SMART methodology, and added as a card, then embellished with an image that represents the goal to serve as visual reminder.

My goals are in sight

For the most part this has worked pretty well. It informs me where I was in previous years, reminding me what problems I wanted to solve at the time, and lets me appreciate how far I've progressed since.

But it suffers from the same issue that other new year's resolutions suffer from - they're too easy to forget about. Sure, you start the year full of enthusiasm (despite the hangover), but by the 2nd of January you're back at work, by the end of the week all your festive cheer has drained away, and there's a good reason the 12th of January is known as Quitter's Day.

But what kind of maker would I be if I didn't attempt to solve this problem?

I figured the easiest way to keep my goals in mind was to setup a display somewhere in the house that used the Trello API to show the goals, reminding me at a glance what they are every time I walk past.

Mirror mirror on the wall

My first attempt at this was to use the MagicMirror² platform, as since my earliest maker days I've wanted to construct my own MagicMirror, but always fell short of actually starting because I didn't feel my woodworking abilities were up to scratch.

Not content to let something as silly as that stop me, I reached into my LEAN methodology toolkit, grabbed a Raspberry Pi and an old laptop screen, and set about creating a Minimum Viable Product (MVP) - that is, just enough to prove the concept without using too many resources. In this instance, that meant installing the software and exploring the options provided within.

My goals are in sightIllustration by Henrik Kniberg.

Now, the MagicMirror² platform seems very well designed, with a lot of support for pulling data from a range of sources, but it wasn't quite what I wanted for this project. It had the benefit of being able to read directly from my Trello list, but each goal was nothing more than an entry on a small bulleted list, lost in among a whole bunch of other information.

I could have spent some time building my own module for the platform, but this felt like a step in the wrong direction as rather than solving the direct problem - that of displaying my goals - I'd instead be spending my time Yak shaving in the guise of learning how to build the module.

Digital signage solution

It was actually during the initial install of Raspbian for the above idea that I first saw what would end up being my solution to the problem, an operating system offered via the NOOBs installer called Screenly.

Screenly, it turns out, is a digital signage platform which lets you remotely configure any number of assets (such as webpages, images, YouTube videos, et al) to display, in rotation, upon your Pi's screen. I'd never heard of it before, but figured if I could find a suitable HTML carousel or sideshow template, I'd be able to host it for free using GitHub Pages, so I set out to find a suitable template.

I reviewed a couple of choices, including a Fullscreen Background Image Slideshow with CSS3 template, and the Vegas 2 Background Slideshow jQuery Plugin, but settled upon the Fullscreen Image Blur Effect with HTML5 template provided by codrops, as this provided the quickest route to the features I wanted - namely the ability to automatically switch between multiple images and messages at an easily controlled rate, all without requiring me to spend too long learning anything new.

I already had the images and wording for the goals, so it took no more than about an hour to update my own content into the template, and make some small changes to the design and functionality, and before I knew it, I had a sideshow hosted on GitHub.

My goals are in sight

Of course, all this information is hard-coded into the template, rather than being dynamically supplied by the Trello API - but do I really need it to be dynamic?

By definition, a yearly goal is something you set once a year, and the 30 minutes it might take each year to update the sideshow is easily more justifiable than the several hours it'll take to implement something which pulls in from the API, not to mention the relative complexity and cost of hosting a dynamic script over that of a static page which I can host for free.

That's not to say I'd never make the slide show dynamic - it might be fun to learn the Trello API, and I could probably do the whole thing using client side JavaScript, or as a Ruby Serverless application, but the LEAN methodology advocated failing fast, such as I did with the MagicMirror² approach, so there's no point spending any time even looking at anything like that when there's a quicker way of achieving the same end result.

My goals are in sight

Bringing it all together

Now that I had an eye-catching slide show of goals hosted on GitHub, all that remained was to install Screenly and point it at the page. But it's at this point that I took a second pivot - given the sheer mess of components needed to make the laptop screen work, was this really the best approach?

My goals are in sight

To make a suitable enclosure for the display, driver board, and Pi, would take more effort that I really wanted to spend, and seeing as I am still planning on building my own smart mirror (spurred on by how impressed I was with the MagicMirror² platform, even if it wasn't suitable for this project) I'd rather keep these components for that.

So instead, as you will see from the feature image for this post, I used my 7" touchscreen display instead. This has the benefit of being compact and self contained, providing something that was large enough to grab your attention, but small enough that you can use it like a picture frame, and with as much versatility.

All in all, I'm very happy with the outcome of this project, even if it didn't end up look anything like I thought it would, because I think the end result is far better than what I initially had in mind, and I was able to reach it quickly and easily.

My goals are in sight

My goals are in sight by Daniel Hollands (@limeblast)

My goals are in sight

Since the end of 2015 I've been using a board on Trello to log and track my yearly goals.

The setup is quite simple - at the start of each year I review the goals in the previous year's column, using a sticker to indicate success or otherwise, then create a new column for the upcoming year. Each goal is written using the SMART methodology, and added as a card, then embellished with an image that represents the goal to serve as visual reminder.

My goals are in sight

For the most part this has worked pretty well. It informs me where I was in previous years, reminding me what problems I wanted to solve at the time, and lets me appreciate how far I've progressed since.

But it suffers from the same issue that other new year's resolutions suffer from - they're too easy to forget about. Sure, you start the year full of enthusiasm (despite the hangover), but by the 2nd of January you're back at work, by the end of the week all your festive cheer has drained away, and there's a good reason the 12th of January is known as Quitter's Day.

But what kind of maker would I be if I didn't attempt to solve this problem?

I figured the easiest way to keep my goals in mind was to setup a display somewhere in the house that used the Trello API to show the goals, reminding me at a glance what they are every time I walk past.

Mirror mirror on the wall

My first attempt at this was to use the MagicMirror² platform, as since my earliest maker days I've wanted to construct my own MagicMirror, but always fell short of actually starting because I didn't feel my woodworking abilities were up to scratch.

Not content to let something as silly as that stop me, I reached into my LEAN methodology toolkit, grabbed a Raspberry Pi and an old laptop screen, and set about creating a Minimum Viable Product (MVP) - that is, just enough to prove the concept without using too many resources. In this instance, that meant installing the software and exploring the options provided within.

My goals are in sightIllustration by Henrik Kniberg.

Now, the MagicMirror² platform seems very well designed, with a lot of support for pulling data from a range of sources, but it wasn't quite what I wanted for this project. It had the benefit of being able to read directly from my Trello list, but each goal was nothing more than an entry on a small bulleted list, lost in among a whole bunch of other information.

I could have spent some time building my own module for the platform, but this felt like a step in the wrong direction as rather than solving the direct problem - that of displaying my goals - I'd instead be spending my time Yak shaving in the guise of learning how to build the module.

Digital signage solution

It was actually during the initial install of Raspbian for the above idea that I first saw what would end up being my solution to the problem, an operating system offered via the NOOBs installer called Screenly.

Screenly, it turns out, is a digital signage platform which lets you remotely configure any number of assets (such as webpages, images, YouTube videos, et al) to display, in rotation, upon your Pi's screen. I'd never heard of it before, but figured if I could find a suitable HTML carousel or sideshow template, I'd be able to host it for free using GitHub Pages, so I set out to find a suitable template.

I reviewed a couple of choices, including a Fullscreen Background Image Slideshow with CSS3 template, and the Vegas 2 Background Slideshow jQuery Plugin, but settled upon the Fullscreen Image Blur Effect with HTML5 template provided by codrops, as this provided the quickest route to the features I wanted - namely the ability to automatically switch between multiple images and messages at an easily controlled rate, all without requiring me to spend too long learning anything new.

I already had the images and wording for the goals, so it took no more than about an hour to update my own content into the template, and make some small changes to the design and functionality, and before I knew it, I had a sideshow hosted on GitHub.

My goals are in sight

Of course, all this information is hard-coded into the template, rather than being dynamically supplied by the Trello API - but do I really need it to be dynamic?

By definition, a yearly goal is something you set once a year, and the 30 minutes it might take each year to update the sideshow is easily more justifiable than the several hours it'll take to implement something which pulls in from the API, not to mention the relative complexity and cost of hosting a dynamic script over that of a static page which I can host for free.

That's not to say I'd never make the slide show dynamic - it might be fun to learn the Trello API, and I could probably do the whole thing using client side JavaScript, or as a Ruby Serverless application, but the LEAN methodology advocated failing fast, such as I did with the MagicMirror² approach, so there's no point spending any time even looking at anything like that when there's a quicker way of achieving the same end result.

My goals are in sight

Bringing it all together

Now that I had an eye-catching slide show of goals hosted on GitHub, all that remained was to install Screenly and point it at the page. But it's at this point that I took a second pivot - given the sheer mess of components needed to make the laptop screen work, was this really the best approach?

My goals are in sight

To make a suitable enclosure for the display, driver board, and Pi, would take more effort that I really wanted to spend, and seeing as I am still planning on building my own smart mirror (spurred on by how impressed I was with the MagicMirror² platform, even if it wasn't suitable for this project) I'd rather keep these components for that.

So instead, as you will see from the feature image for this post, I used my 7" touchscreen display instead. This has the benefit of being compact and self contained, providing something that was large enough to grab your attention, but small enough that you can use it like a picture frame, and with as much versatility.

All in all, I'm very happy with the outcome of this project, even if it didn't end up look anything like I thought it would, because I think the end result is far better than what I initially had in mind, and I was able to reach it quickly and easily.

My goals are in sight

January 14, 2019

On Smart TVs by Bruce Lawson (@brucel)

When I was doing developer relations at Opera, I did everything I could to avoid having to go near the Opera TV part of the business – which was basically an app store of HTML5 websites for “Smart” TVs. This was for three reasons: the world of Smart TVs was a world of closed standards. Secondly, as Patrick Lauke wrote, the chips in the early Smart TVs were cheap and crappy which seriously crippled the web experience.

But the main reason was that I felt Smart TVs were a solution looking for problem.

TVs are big, beautiful screens and good speakers, sitting in a social space. No-one wants to surf Facebook on a screen that mum and dad are also watching, especially controlling it with arrows on a remote control unit.

A cheap device like a Chromecast allows people to control the content with a portable device they already have and know how to use – be it a laptop, tablet or phone, and see the movie/ photos on a big screen with family and friends. TVs are meant to be dumb; your phone is smart and a little USB gizmo connects the two.

So why did Opera have a B2B division developing Smart TV offerings? (And after the dismemberment of Opera, it continues as Vewd). The answer: because TV set manufacturers wanted Smart TV, so would throw money at us. But why did the set manufacturers want it?

A news report last week made it clear: it’s about collecting data off users, hitting the network a lot to phone that data back to HQ, then “monetizing” it, in some cases, advertising to viewers. That helps reduce the cost at sale of TVs. As the Verge puts it: Taking the smarts out of smart TVs would make them more expensive. From their interview with TV manufacturer Vizio’s CTO Bill Baxter:

So look, it’s not just about data collection. It’s about post-purchase monetization of the TV.

This is a cutthroat industry. It’s a 6-percent margin industry, right? I mean, you know it’s pretty ruthless. You could say it’s self-inflicted, or you could say there’s a greater strategy going on here, and there is. The greater strategy is I really don’t need to make money off of the TV. I need to cover my cost.

…there are ways to monetize that TV and data is one, but not only the only one. It’s sort of like a business of singles and doubles, it’s not home runs, right? You make a little money here, a little money there. You sell some movies, you sell some TV shows, you sell some ads, you know.

I have a Smart TV (it’s difficult to find a new one that isn’t). I’ve never connected it to the web, for just this reason.

January 11, 2019

Reading List by Bruce Lawson (@brucel)

January 08, 2019

Java by Contract is an implementation of Design by Contract, as promoted by Bertrand Meyer and the Eiffel Software company, for the Java programming language. The contract is specified using standard Java methods and annotations, making it a more reliable tool than earlier work which used javadoc comments and rewrote the Java source code to include the relevant tests.

Which is all well and good, but how do you use it? Here’s an example.

The problem

There is a whole class of algorithms to approximately find roots to a function, using an iterative technique. Given, in Java syntax, the abstract type MathFunction that implements a function over the double type:

interface MathFunction {
    double f(double x);
}

Define the abstract interface that exposes such an iterative solution, including the details of its contract.

The solution

The interface is designed using the Command-Query Separation Principle. Given access to the function f(), the interface has a command findRoot(seed1, seed2) which locates the root between those two values, and a query root() which returns that root. Additionally, a boolean query exhaustedIterations() reports whether the solution converged.

Both of the queries have the precondition that the command must previously have successfully run; i.e. you cannot ask what the answer was without requesting that the answer be discovered.

The contract on the command is more interesting. The precondition is that for the two seed values seed1 and seed2, one of them must correspond to a point f(x) > 0 and the other to a point f(x) < 0 (it does not matter which). This guarantees an odd, and therefore non-zero, number of roots[*] to f(x) between the two, and the method will iterate toward one of them. If the precondition does not hold, then an even number of roots (including possibly zero) lies between the seed values, so it cannot be guaranteed that a solution exists to find.

In return for satisfying the precondition, the command guarantees that it either finds a root or exhausts its iteration allowance looking. Another way of putting that: if the method exits early, it is because it has already found a convergent solution.

Many, but not all, of these contract details can be provided as default method implementations in the interface. The remainder must be supplied by the implementing class.

/**
 * Given a mathematical function f over the doubles, and two bounds for a root to that function,
 * find the root using an (unspecified) iterative approach.
 * A root is an input value x such that f(x)=0.
 */
public interface RootFinder {
    /**
     * @return The function that this object is finding a root for.
     */
    MathFunction f();
    /**
     * A root to the function f() is thought to lie between seed1 and seed2. Find it.
     * @param seed1 One boundary for the root to f().
     * @param seed2 Another boundary for the root to f().
     */
    @Precondition(name = "seedGuessesStraddleRoot")
    @Postcondition(name = "earlyExitImpliesConvergence")
    void findRoot(double seed1, double seed2);
    /**
     * @return The root to the function f() that was discovered.
     */
    @Precondition(name = "guessWasCalculated")
    Double root();
    /**
     * @return Whether the iterative solution used the maximum number of iterations.
     */
    @Precondition(name = "guessWasCalculated")
    boolean exhaustedIterations();

    default Boolean guessWasCalculated() {
        return this.root() != null;
    }
    default Boolean seedGuessesStraddleRoot(Double seed1, Double seed2) {
        double r1 = f().f(seed1);
        double r2 = f().f(seed2);
        return ((r1 > 0 && r2 < 0) || (r1 < 0 && r2 > 0));
    }
    Boolean earlyExitImpliesConvergence(Double seed1, Double seed2, Void result);
}

Example usage

There are swaths of algorithms to implement this interface. See, for example, the book Numerical Recipes. Given a particular implementation, we can look for roots of a simple function, for example f(x) = x^2 - 2:

    RootFinder squareRootOfTwo = SecantRootFinder.finderForFunction((double x) -> x*x - 2);
    squareRootOfTwo.findRoot(1.0, 2.0);
    System.out.println(String.format("Root: %f", squareRootOfTwo.root()));
    System.out.println(String.format("The solution did%s converge before hitting the iteration limit",
            squareRootOfTwo.exhaustedIterations()?"n't":""));

This suggests that a root exists at x~=1.414214, and that it converged on the solution before running out of goes. Let’s see if there’s another root between 2 and 3:

Exception in thread "main" online.labrary.javaByContract.ContractViolationException:
  online.labrary.javaByContract.Precondition seedGuessesStraddleRoot had unexpected value false on object
  online.labrary.jbcTests.TestGeneratorTests$SecantRootFinder@29774679
    at javaByContract/online.labrary.javaByContract.ContractEnforcer.invoke(ContractEnforcer.java:92)
    at jdk.proxy1/com.sun.proxy.jdk.proxy1.$Proxy4.findRoot(Unknown Source)
    at javaByContract/online.labrary.rootFinder.RootFinder.main(RootFinder.java:10)

Whoops! I’m holding it wrong: the function doesn’t change sign between x=2 and x=3. I shouldn’t expect the tool to work, and indeed it’s been designed to communicate that expectation by failing a precondition.

[*] Nitpick: roots _or singularities_.

January 05, 2019

The last few months of 2018 have been scrappy. I’ve been busy but not all that productive – mostly due to the fact that we’re having a house extension built – which has left me feeling a little flat about 2018.

One of the wonderful benefits of these annual reviews is that it encourages you to look back at the year as a whole. I was reminded that 2018 was actually a really good year.

This is my fourth annual review. I also posted reviews in 2015, 2016 and 2017.

What went well

Travel

One of my goals for 2018 was to travel more and boy did we do that!

We kicked off the new year in Edinburgh for Hogmanay with our good friends Stu and Chloe.

Ju and I in front of Edinburgh castle

Ju and I at Edinburgh Castle

In February, we travelled to Iceland which was a 30th birthday present from my wife. We went dog sledding (one of the best experiences of my life) and bathed in the geothermal spa’s while it was -5°. We got a faint glimpse of the northern lights, but we’re leaving this on our bucket list. What a beautiful country! We can’t wait to visit again.

Dog sledding in Iceland

Dog sledding in Iceland was one of the highlights of the year

Ju wrapped up warm with one of the running dogs

Ju with one of the running dogs

The colourful city of Reykjavik

The colourful city of Reykjavik

In May, we spent Ju’s 30th birthday exploring Singapore. We then spent a week in Borneo’s rainforests. It was an amazing experience to watch orangutans, but also saddening to see just how much rainforest has been replaced by palm tree plantations. We sunbathed on a beach with wild pigs and monkeys – not something we’ve done before!

Gardens by the Bay in Singapore

Gardens by the Bay in Singapore (one of my favourite photos of the year)

Orangutans

Seeing orangutans up close and personal was another highlight of the year

Sunrise over the Kinabatangan river in Borneo

Sunrise over the Kinabatangan river in Borneo

Ju and I looking out over Mount Kinabalu

Then in September, we travelled to Italy to spend a few days in Rome. The weather was glorious and we walked over 60 miles in 5 days to explore as much of the city as we could on foot.

The Colosseum in Rome was even more impressive than I thought it would be

House extension

We’ve been mulling over whether to extend or move house for the past few years. Our goal for 2018 was to finally make that decision: do we extend or move?

After a lengthy process of having architect plans drawn up, getting planning permission, and securing the money we’d need, we finally kicked off the house extension project in August.

We were lucky to find builders whom we get on well with and trust. A project of this size is stressful enough as it is, so I couldn’t imagine the stress we’d be under if we had unreliable builders.

We’re hoping that the builders will be done in spring 2019, but we’ll need to finish decorating once they’re done. We expect to spend most of our weekends until the summer painting and decorating but we’ll eventually end up with a home that we’ve made our own. And I’m super excited about getting a bigger home office!

Our home in August 2018

Our home in August 2018

The house extension taking shape in December 2018

The house extension taking shape in December 2018

Finances

A big focus of mine during 2018 was my finances. We knew our living costs would increase with the house extension (larger mortgage payments), so I wanted to get my finances in order before then.

I read two personal finances books, The Simple Path to Wealth and Total Money Makeover, both of which I’d recommend. I paid off some personal debt (we’re both 100% debt free other than our mortgage), set up a personal pension and moved an old pension (more time consuming than you’d think), started saving for an emergency fund and set up a monthly household budget that we try to stick to each month.

I also read Profit First (highly recommended if you’re a business owner) and began implementing some of the principals in my business. I also cut down my business expenses, which seem to slowly accumulate over time if you don’t keep an eye on them.

Food and cooking

In October, Ju and I decided to go pescatarian. That’s no meat except fish, which we eat once or twice a week. It’s revitalised my interest and enjoyment in cooking. We’ve had to find new vegetarian recipes to cook and we now have around 10 excellent veggie recipes that we’re really happy with (all of them, in my mind, taste better than their meat counterparts).

This year I feel I’ve really got back into cooking and have made some of my best food. I can’t wait to cook for friends and family more this year.

Client work

I spent the whole year more-or-less fully booked, which is obviously a nice feeling when you’re self-employed. It also presented the problem of trying to tell potential prospects that you’re not available for 8 weeks. I worked on some really exciting projects with great clients (many of which, unfortunately, are under NDA).

Annual mastermind retreat

I attended my second mastermind retreat in October. This retreat was bigger and better than my previous retreat. 5 of us travelled to a beautiful Airbnb home in Sussex for a few days to discuss business. It’s something I really enjoy and get a lot of value from, so it’s something I plan to continue to do on an annual basis.

Other things that I’ve enjoyed or accomplished in 2018

  • I read 19 books
  • Started using Michael Hyatt’s Full Focus Planner to plan out my days and weeks and found it incredibly useful
  • Started wearing contact lenses for the first time
  • Went to Adam’s for lunch to celebrate our 5 year anniversary (Adam’s is the best restaurant in Birmingham)
  • Drove a Subaru WRX STi, Porchshe Cayman, Nissan GTR and Lamborghini Aventador around a race track
  • Gave blood for the first time
  • Quit Facebook in May and haven’t looked back
  • Upgraded my work gear and picked up a new MacBook Pro 15” and Viewsonic 32” 4k monitor
  • Also purchased an Apple Watch Series 4, which has encouraged me to move more on a daily basis
  • Saw Steven Wilson live with my Dad (gig of the year for me)

What went badly

Writing

I only published 3 blog posts and sent 6 newsletters this year. That’s my lowest output in quite some time. I write best in the early hours of the morning, but I let my morning routine suffer and wasn’t waking up at my preferred time of 6am. There are lots of reasons for this, but suffice to say, it’s something I’ll be focusing on in 2019.

Lack of systems

I diligently tracked my time over the past year. I spent an awful lot of time and effort writing proposals and carrying out trivial admin tasks. I put this down to a lack of systems such as not having a solid proposal template I can use, or not outsourcing or automating admin tasks. In 2019, I plan to start optimising my business so that I can run it more efficiently.

Deep work

Especially in the later part of the year, I struggled to get a lot of deep work done. Part of that was due to the house extension and working from home while builders are around, but it was also due to letting distractions back into my life. Deep work (intense focus on the task at hand) is a muscle you need to build, and I let mine atrophy this year.

Weight loss

For the past few years, I’ve been trying to reach a target weight of 70kg (154 pounds). Over the past year, my weight has fluctuated very little, which I suppose is a good thing, but I’ve not lost any weight either. I’m currently 78kg (172 pounds). I’d be over the moon if I can hit my target by the summer, but it’s going to require a change of diet and exercise routine to get there.

How I did against my 2018 goals

In my previous year in review post, I wrote about a few things I was thinking about. Here’s how I got on:

Website growth. This didn’t happen. I did spend some time tweaking copy and the design, but I didn’t publish nearly enough to move the needle of any numbers.

Business growth. This was good and bad. I had my best year yet in terms of revenue, but I didn’t create any products to sell which I had intended.

More writing. Complete fail. This will stay on my list for 2019.

Social media fasting. Mostly a success. I deleted my Facebook account in May and have locked down my phone to 15 minutes social media time per day. It’s working well and I don’t feel social media is a major distraction at the moment.

More travelling and photography. Definitely a success. We travelled to 5 countries, I bought some new camera gear, and I took plenty of photos.

Weekly gratitude journaling. Success. This worked really well, even if I didn’t do it every single week. At the end of a week, I’d write down the things I was grateful for and things I’d accomplished during the week. Often I’d start by staring at a blank screen, assuming my week had been rubbish, but after a few minutes, I’d have a list of 5-10 things. Add that up over the year and that’s a lot of little moments to cherish that would have otherwise been forgotten. It’s a practice I’ll continue in 2019.

Things I’m thinking about for 2019

I know 2019 is going to be a very different year for us. We’re not going to travel nearly as much, and much of the year will be spent on the house.

Complete the house extension

The main goal will be to get the house extension complete so that we can start inviting friends and family over again. Most of our weekends in the early part of the year will be spent with a paintbrush in hand.

Systems for my business

I want to put more processes and systems in places to help my business run more efficiently. I’m also super excited about creating an awesome work environment in my new home office.

Reading

I read 19 books last year, down from 23 the previous year. All of the books I read were non-fiction. While I enjoy reading non-fiction books, I’ve missed reading fiction. This year I want to read at least 6 fiction books and I’d like to read a few more biographies too.

Fitness and health

I know looking after my body and mind is important for everything that I do. There are a few changes I’d like to make this year:

  • continue with our pescatarian diet, tweaking and finding new healthy recipes
  • improve the quality of my sleep with a better shutdown ritual in the evening
  • close the activity rings daily on my Apple Watch
  • start my daily meditation practice again
  • continue playing squash 2-3 times per week
  • get a new dog

Writing

Writing is something that features in every one of my year reviews because I know it’s something I should be doing. 2019 is the year where I get my writing habit back on track.

That’s all from me. Wishing you all the best for 2019.

January 04, 2019

We utilize composer heavily for plugin development and versioning at Substrakt so when we need to add new features to a plugin it becomes a great big composer and git dance. My preferred way to work with package development is to symlink the development version of the package I’m working on into the composer project […]

Reading List by Bruce Lawson (@brucel)

A (usually) weekly round-up of interesting links I’ve tweeted. Sponsored by Smashing Magazine who slip banknotes into my lacy red manties so I can spend time reading stuff.

Some improvements to JavaByContract, the design-by-contract tool for Java:

  • Preconditions, Postconditions and Invariants now appear in the Javadoc for types that use JavaByContract. While this is only a small source change, it’s a huge usability improvement, as programmers using your types can now read the contracts for those types in their documentation.
  • There is Javadoc for the JavaByContract package.
  • The error message on contract violation distinguishes between precondition, postcondition and invariant violation.

I’m speaking generally about moving beyond TDD, using JavaByContract as a specific example, at Coventry Tech Meetup next week. See you there!

January 02, 2019

One of the early goals written into the mission statement of the Labrary was an eponymous app for organising research notes. I’ve used Mekentosj Springer Readcube Papers for years, and encountered Mendeley and others, and found that they were all more focussed on the minutiae of reference management, rather than the activity of studying and learning from the material you’re collecting in your library. Clearly those are successful apps that have an audience, but is there space for something more lightweight?

I talked to a few people, and the answer was yes. There were people in software engineering, data science, and physics who identified as “light” consumers of academic literature, people who read the primary literature to learn from and find techniques to apply, but do not need or even want the full cognitive weight of bibliographic reference management. They (well, “we”, I wanted it too) wanted to make notes while they were reading papers, and find those notes again. We wanted to keep tags on interesting references to follow up. We wanted to identify the questions we had, and whether they were answered. And we wanted to have enough information—but not more—to help us find the original article again.

My first prototype was as simple as I could make it. There’s a picture below: it’s a ring binder, with topic dividers, and paper notes (at least one separate sheet for each article) which quickly converged on a pro forma layout as shown.

An early prototype of the Labrary app.An early prototype of the Labrary app.

I liked it, in fact I quickly got to a point where I wouldn’t read an article unless I had access to a pad and pen to add a page to my binder. People I showed it to liked it, too. So this seemed like a good time to crack open the software making tools!

The first software prototype was put together in spare time using GNUstep and Renaissance, and evinced two problems:

  • The UI design led back down the route of “bibliopedantry”, forcing students to put more effort into getting the citation details correct than they wanted to.
  • Renaissance lacked support for some Cocoa controls it would have been helpful to use, so there was a choice to be made to invest more into improving Renaissance or finding a different UI layout tool.
A screenshot of the ill-fated "Library" window in Labrary's GNUstep prototype.A screenshot of the ill-fated “Library” window in Labrary’s GNUstep prototype.

This experience made me look for other inspiration for ways to organise the user interface so that students get the experience of taking notes, not of fiddling with citation data. I considered writing Labrary as a plugin for the free Calibre e-reader app, so that Labrary could focus on being about study notes and Calibre could focus on being about library management. But ultimately I found the tool that solved the problem best: Apple’s Finder.

The Labrary pro forma note as Finder stationery.The Labrary pro forma note as Finder stationery.

I’ve recreated the pro forma note from the binder as a text file, and set the “Stationery Pad” flag in the Finder. When I open this file, Finder creates a duplicate and opens that instead, in my editor of choice: ready to become a new study note! I put this in a folder with a Zim index file, so I can get the “shoebox” view of all the notes by opening the folder in Zim. It also does full-content searching, so the goal of finding a student’s notes again is achieved.

Zim open on my research notes folder.Zim open on my research notes folder.

I’m glad I created the lo-fi paper prototype. It let me understand what I was trying to achieve, and show very quickly that my software implementation was going in the wrong direction. And I’m always happy to be the person to say “do we need to write this, or can it be built out of other bits?”, as I explored for this project with Zim and Calibre.

December 27, 2018

Brum tech pub crawl 2018 by Stuart Langridge (@sil)

It’s time for the Birmingham tech pub crawl! Saturday 29th December 2018.

This is called a pub crawl, but it’s really an excuse to get together, hang out, have a couple of drinks — alcoholic or not, that’s entirely up to you and there’s no pressure — in various places around the Jewellery Quarter. Get away from the turkey and chill out and meet people. Bring your family and your friends along. Pop in for an hour while you’re in town and say hello, or show up at 12 noon and still be there at midnight, it’s up to you. Lots of people come at various points during the day, and it’s all very friendly, so if you don’t think you know anyone, or you’re on your own, that’s not a problem. Come, chat to people, have a drink, have a laugh. The agenda this year is, roughly, six different places and a couple of hours in each, so we move around a bit, but it’s all in the Jewellery Quarter so there’s not a lot of walking. If you’re feeling unsure do feel free to ping me — @sil on Twitter — and I can tell you where we are, and I’ll try to keep things updated during the day. Everyone is welcome, and everyone is invited.

A rough agenda:

  • The Lord Clifden, 12pm - 2pm (they do food if you fancy lunch)
  • The Church, 2pm - 4pm
  • 1000 Trades, 4pm - 6pm
  • The Rose Villa Tavern, 6pm - 8pm (probably grab a bite to eat here if we haven’t already)
  • The Queen’s Arms, 8pm - 10pm
  • The Actress and Bishop, 10pm - whenever

December 20, 2018

Reading List by Bruce Lawson (@brucel)

A (usually) weekly round-up of interesting links I’ve tweeted. Sponsored by Smashing Magazine who slip banknotes into my bellydancing costume so I can spend time reading stuff.

I introduced Java by Contract, a tool for building design-by-contract style invariants, preconditions and postconditions in Java using annotations. It’s MIT licensed, contributions are welcome, and I hope this helps lots of people to introduce stronger correctness checking into your software. And book office hours if you’d like me to help you with that.

Java by Contract came about as part of Research Watch, a new blog series over at The Labrary where I talk about academic work and how us “practitioners” (i.e. people who computer who aren’t in academia) can make use of the results. The first post considers a report of Teaching Quality Object-Oriented Programming to computer science students.

By the way, I will be speaking at Coventry Tech Meetup on 10th January on the topic “Beyond TDD”, and Java by Contract will make an appearance there.

Long-time SICPers readers will remember Programming Literate, a Tumblr discussing results from empirical software engineering. And if you don’t, you’ll probably remember your feeds exploding on July 15, 2013 when I imported all of the posts from there to here. You can think of Research Watch as a reboot of Programming Literate. There’ll be papers new and vintage, empirical and opinionated, on a range of computing topics. If that sounds interesting, subscribe to the Labrary’s RSS feed.

2018 reviewed by Substrakt (@substrakt)

December 19, 2018

Why isn’t it their job by Stuart Langridge (@sil)

Bruce Lawson has written a rather nice description of the practical value of semantic HTML, and you should read it, especially if you’re a full-stack developer who feels that HTML is the super-easy part of your toolkit and the components are the most important. But there’s one extra argument I’d like to add to his list; less important than some of the others, but a different nuance.

Sometimes, when I find myself doing a bit of extra work to accommodate some users with unusual requirements, I find myself thinking: why isn’t it their job to fix this, rather than mine? This is an unworthy thought, and I don’t like that I have it, and I don’t respond to this thought; doing the right thing so all my users can use my stuff is important. But I do have the thought, nonetheless. Whether I’m adding aria labels for screenreaders, or doing extra work to build sites that layer behaviour on top as additional rather than critical, or checking text contrast ratios, or testing on unusual mobile phones I don’t and won’t have, there’s a sneaky little bit of my brain saying “why is this my problem? if someone wants to buy a weird phone, it’s their problem that websites don’t work right, isn’t it?”

Leave aside here, for now, that there is no such thing as a “normal” experience, and even saying that people differ from the “normal” experience means that you are thinking about things the wrong way because you’re assuming that there is a normality and then there’s divergence and that’s wrong. I know this. You know this too, or at least should.

Here’s the secret. Someone who has a web experience different from what the industry perceives as the norm is normally actually pretty happy to try, for themselves, to make their web experience better. Someone with poor motor control generally will be happy to learn the keyboard shortcuts for their browser, which the “norm” don’t bother to do. Someone who listens to the web rather than reads it generally will be happy to learn how to skip over your header using an option available in their tool but not yours, so you don’t have to add “skip header” links. Someone who is desperate for all bold text to appear in bright green and with sparkles generally will be happy to learn how to customise their user stylesheet to make that happen.

The secret is: if you use semantic HTML, then they do the work, not you. Their browser does the work, not you. If your pages use semantic HTML, you’re not going to get bug reports saying that your web app doesn’t work in a screenreader, or your buttons don’t work without mouse clicks, or your site doesn’t show anything on a Yoyodyne SuperPhone 3 running FailBrowser, because it will and they will and it will. And using semantic HTML elements is no more effort; it’s just as easy to use <main> as it is to use <div id="main">. Easier, even. You get to offload some of that work onto the people who need it, and they are happy to do it, as long as you aren’t actively working to stop them.

Bruce’s guide to writing HTML for JavaScript developers

It has come to my attention that many in the web standards gang are feeling grumpy about some Full Stack Developers’ lack of deep knowledge about HTML. One well-intentioned article about 10 things to learn for becoming a solid full-stack JavaScript developer said

As for HTML, there’s not much to learn right away and you can kind of learn as you go, but before making your first templates, know the difference between in-line elements like <span> and how they differ from block ones like <div>. This will save you a huge amount of headache when fiddling with your CSS code.

This riled me too. But, as it’s Consumerfest and goodwill to all is compulsory, I calmed down. And I don’t want to instigate a pile-on of the author of this piece; it’s indicative of an industry trend to regard HTML as a bit of an afterthought, once you’ve done the real work of learning and writing JavaScript. If the importance of good HTML isn’t well-understood by the newer breed of JavaScript developers, then it’s my job as a DOWF (Dull Old Web Fart) to explain it.

Gather round, Fullstack JavaScript Developers – together we’ll make your apps more usable, and my blood pressure lower.

What is ‘good’ HTML?

Firstly, let’s reach a definition of ‘good’ HTML. Many DOWFs used to get very irked about (X)HTML being well-formed: proper closing tags, quoted attributes and the like. Those days are gone. Sure, it’s good practice to validate your HTML, just like you lint your JavaScript (it can catch errors and make your code more maintainable), but browsers are very forgiving.

In fact, part of what we commonly call ‘HTML5’ is the Parsing Algorithm which is like an HTML ninja – incredibly powerful, yet rarely noticed. It ensures that all modern browsers construct the same DOM from the same HTML, regardless of whether the HTML is well-formed or not. It’s the greatest fillip to interoperability we’ve ever seen.

By ‘good’ HTML, I mean semantic HTML, a posh term for choosing the right HTML element for the content. This isn’t a philosophical exercise; it has directly observable practical benefits.

For example, consider the <button> element. Using this gives you some browser behaviour for free:

  • A button is focusssable via the keyboard. I bet you, dear reader, know all the keyboard shortcuts for your IDE; it makes development much faster. Many people use only the keyboard when using a webpage. I do it because I have multiple sclerosis – therefore the fine motor control required to use a mouse can be difficult for me. My neighbour has arthritis, so she prefers to use the keyboard.
  • Buttons can be activated using the space bar or the enter key; you don’t have to remember to listen for these keypresses in your script.
  • Inside a <form>, it doesn’t even need JavaScript to work.

“What’s that?”, you say. “Everyone has JavaScript”. No, they don’t. Most people do, most of the time. But I guarantee you that everyone is without JavaScript sometimes.

Here’s another example: semantically linking a <label> to its associated <input> increases usability for a mouse-user or touch-screen user, because clicking in the label focusses into the input field. See this in action (and how to do it) on MDN.

This might be me, with my MS; it might be you, on a touch-screen device on a bumpy train, trying to check a checkbox. How much easier it is if the hit area also includes the label “uncheck to opt out of cancelling us not sending you spam forever”. (Compare the first and second identical-looking examples in a checkbox demo.)

But the point is that by choosing the right element for the job, you’re getting browser behaviour for free that makes your app more usable to a range of different people.

Invisible browser behaviours

With me so far? Good. The browser behaviours associated with the semantics of <button> and <label> are obvious once you know about them – because you can see them.

Other semantics aren’t so obvious to a sighted developer with a desktop machine and a nice big monitor, but they are incredibly useful for those who do need them. Let’s look at some of those.

HTML5 has some semantics that you can use for indicating regions on a page. For example, <nav>, <main>, <header>, <footer>.

If you wrap your main content – that is, the stuff that isn’t navigation, logo and main header etc – in a <main> tag, a screen reader user can jump immediately to it using a keyboard shortcut. Imagine how useful that is – they don’t have to listen to all the content before it, or tab through it to get to the main meat of your page.

And for people who don’t use a screenreader, that <main> element doesn’t get in the way. It has no default styling at all, so there’s nothing for you to remove. For those that need it, it simply works; for those that don’t need it, it’s entirely transparent.

Similarly, using <nav> for your primary navigation provides screenreader users with a shortcut key to jump to the navigation so they can continue exploring your marvellous site. You were probably going to wrap your navigation in a <div class=”nav”> to position it and style it; why not choose <nav> instead (it’s shorter!) and make your site more usable to the 15% of the world who have a disability?

For more on this, I humbly point you to my 2014 post Should you use HTML5 header and footer?. A survey of screenreader users last year showed that 80% of respondents will use regions to navigate – but they can only do so if you choose to use them instead of wrapping everything in <div>s. Now you know they exist, why wouldn’t you use them?

New types of devices

We’re seeing more and more types of devices connecting to the web, and semantic HTML can help these devices display your content in a more usable way to their owners. And if your site is more usable than your competitors’, you win, and your boss will erect a massive gold statue of you in the office car park. (Trust me, your boss told me. They’ve already ordered the plinth.)

Let’s look at one example, the Apple Watch. Here are some screenshots and excerpts from the transcript of an Apple video introducing watchOS 5:

We’ve brought Reader to watchOS 5 where it automatically activates when following links to text heavy web pages. It’s important to ensure that Reader draws out the key parts of your web page by using semantic markup to reinforce the meaning and purpose of elements in the document. Let’s walk through an example. First, we indicate which parts of the page are the most important by wrapping it in an article tag.

diagram of an article element wrapping content on an Apple Watch

Specifically, enclosing these header elements inside the article ensure that they all appear in Reader. Reader also styles each header element differently depending on the value of its itemprop attribute. Using itemprop, we’re able to ensure that the author, publication date, title, and subheading are prominently featured.

Apple Watch diagram showing how it uses microdata attributes to layout and display information about an article

itemprop is an HTML5 microdata attribute. There are shared vocabularies documented at schema.org, which is founded by Google, Microsoft, Yahoo and Yandex. Using schema.org vocabularies with microdata can make your pages display better in search results:

Many applications from Google, Microsoft, Pinterest, Yandex and others already use these vocabularies to power rich, extensible experiences.

(If you plan to put things into microdata, please note that Apple, being Apple, go their own way, and don’t use a schema.org vocabulary here. Le sigh. See my article Content needs a publication date! for more. Or view source on this page to see how I’m using microdata on this article.)

Apple WatchOS also optimises display of items wrapped in <figure> elements:

Reader recognizes these tags and preserves their semantic styles. For this image, we use figure and figcaption elements to let the Reader know that the image is associated with the below caption. Reader then positions the image alongside its caption.

Apple Watch diagram showing how it lays out figures and captions if appropriately marked up

You probably know that HTML5 greatly increased the number of different <input> types, for example <input type=”email”> on a mobile device shows a keyboard with the “@” symbol and “.” that are in all email addresses; <input type=”tel”> on a mobile device shows a numeric keypad.

On desktop browsers, where you have a physical keyboard, you may get different User Interface benefits, or built-in validation. You don’t need to build any of this; you simply choose the right semantic that best expresses the meaning of your content, and the browser will choose the best display, depending on the device it’s on.

In WatchOS, input types take up the whole watch screen, so choosing the correct one is highly desirable.

First, choose the appropriate type attribute and element tag for your form controls.
WebKit supports a variety of form control types including passwords, numeric and telephone fields, date, time, and select menus. Choosing the most relevant type attribute allows WebKit to present the most appropriate interface to handle user input.

Secondly, it’s important to note that unlike iOS and macOS, input methods on watchOS require full-screen interaction. Label your form controls or specify aria label or placeholder attributes to provide additional context in the status bar when a full-screen input view is presented.

Apple Watch showing different full-screen keyboards for different email types

I didn’t choose to use <article> and itemprop and input types because I wanted to support the Apple Watch; I did it before the Apple Watch existed, in order that my code is future-proof. By choosing the right semantics now, a machine that I don’t know about yet can understand my content and display it in the best way for its users. You are opting out of this if you only use <div> or <span> because, by definition, they have “no special meaning at all”.

Summary

I hope I’ve shown you that choosing the correct HTML isn’t purely an academic exercise. Perhaps you can’t use all the above (and there’s much more that I haven’t discussed) but when you can, please consider whether there’s an HTML element that you could use to describe parts of your content.

For instance, when building components that emit banners and logos, consider wrapping them in <header> rather than <div>. If your styling relies upon classnames, <header class=”header”> will work just as well as <div class=”header”>.

Semantic HTML will give usability benefits to many users, help to future-proof your work, potentially boost your search engine results, and help people with disabilities use your site.

And, best of all, thinking more about your HTML will stop Dull Old Web Farts like me moaning at you.

What’s not to love? Have a splendid holiday season, whatever you celebrate – and here’s to a semantic 2019!

More!

December 18, 2018

Cleaner Code by Graham Lee

Readers of OOP the easy way will be familiar with the distinction between object-oriented programming and procedural programming. You will have read, in that book, about how what we claim is OOP in the sentence “OOP has failed” is actually procedural programming: imperative code that you could write in Pascal or C, with the word “class” used to introduce modularity.

Here’s an example of procedural-masquerading-as-OOP, from Robert C. Martin’s blog post FP vs. OO List Processing:

void updateHits(World world){
  nextShot:
  for (shot : world.shots) {
    for (klingon : world.klingons) {
      if (distance(shot, klingon) <= type.proximity) {
        world.shots.remove(shot);
        world.explosions.add(new Explosion(shot));
        klingon.hits.add(new Hit(shot));
        break nextShot;
      }
    }
  }
}

The first clue that this is a procedure, not a method, is that it isn’t attached to an object. The first change on the road to object-orientation is to make this a method. Its parameter is an instance of World, so maybe it wants to live there.

public class World {
  //...

  public void updateHits(){
    nextShot:
    for (Shot shot : this.shots) {
      for (Klingon klingon : this.klingons) {
        if (distance(shot, klingon) <= type.getProximity()) {
          this.shots.remove(shot);
          this.explosions.add(new Explosion(shot));
          klingon.hits.add(new Hit(shot));
          break nextShot;
        }
      }
    }
  }
}

The next non-object-oriented feature is this free distance procedure floating about in the global namespace. Let’s give the Shot the responsibility of knowing how its proximity fuze works, and the World the knowledge of where the Klingons are.

public class World {
  //...

  private Set<Klingon> klingonsWithin(Region influence) {
    //...
  }

  public void updateHits(){
    for (Shot shot : this.shots) {
      for (Klingon klingon : this.klingonsWithin(shot.getProximity())) {
        this.shots.remove(shot);
        this.explosions.add(new Explosion(shot));
        klingon.hits.add(new Hit(shot));
      }
    }
  }
}

Cool, we’ve got rid of that spaghetti code label (“That’s the first time I’ve ever been tempted to use one of those” says Martin). Incidentally, we’ve also turned “loop over all shots and all Klingons” to “loop over all shots and nearby Klingons”. The World can maintain an index of the Klingons by location using a k-dimensional tree then searching for nearby Klingons is logarithmic in number of Klingons, not linear.

By the way, was it weird that a Shot would hit whichever Klingon we found first near it, then disappear, without damaging other Klingons? That’s not how Explosions work, I don’t think. As it stands, we now have a related problem: a Shot will disappear n times if it hits n Klingons. I’ll leave that as it is, carry on tidying up, and make a note to ask someone what should really happen when we’ve discovered the correct abstractions. We may want to make removing a Shot an idempotent operation, so that we can damage multiple Klingons and only end up with a Shot being removed once.

There’s a Law of Demeter violation, in that the World knows how a Klingon copes with being hit. This unreasonably couples the implementations of these two classes, so let’s make it our responsibility to tell the Klingon that it was hit.

public class World {
  //...

  private Set<Klingon> klingonsWithin(Region influence) {
    //...
  }

  public void updateHits(){
    for (Shot shot : this.shots) {
      for (Klingon klingon : this.klingonsWithin(shot.getProximity())) {
        this.shots.remove(shot);
        this.explosions.add(new Explosion(shot));
        klingon.hit(shot);
      }
    }
  }
}

No, better idea! Let’s make the Shot hit the Klingon. Also, make the Shot responsible for knowing whether it disappeared (how many episodes of Star Trek are there where photon torpedoes get stuck in the hull of a ship?), and whether/how it explodes. Now we will be in a position to deal with the question we had earlier, because we can ask it in the domain language: “when a Shot might hit multiple Klingons, what happens?”. But I have a new question: does a Shot hit a Klingon, or does a Shot explode and the Explosion hit the Klingon? I hope this starship has a business analyst among its complement!

We end up with this World:

public class World {
  //...

  public void updateHits(){
    for (Shot shot : this.shots) {
      for (Klingon klingon : this.klingonsWithin(shot.getProximity())) {
        shot.hit(klingon);
      }
    }
  }
}

But didn’t I say that the shot understood the workings of its proximity fuze? Maybe it should search the World for nearby targets.

public class World {
  //...

  public void updateHits(){
    for (Shot shot : this.shots) {
      shot.hitNearbyTargets();
    }
  }
}

As described in the book, OOP is not about adding the word “class” to procedural code. It’s a different way of working, in which you think about the entities you need to model to solve your problem, and give them agency. Obviously the idea of “clean code” is subjective, so I leave it to you to decide whether the end state of this method is “cleaner” than the initial state. I’m happy with one fewer loop, no conditions, and no Demeter-breaking coupling. But I’m also happy that the “OO” example is now object-oriented. It’s now looking a lot less like enterprise software, and a lot more like Enterprise software.

December 17, 2018

Woah, too many products. Let me explain. No, it will take too long, let me summarise.

Sometimes, people running software organisations call their teams “product teams”, and organise them around particular “products”. I do not believe that this is a good idea. Because we typically aren’t making products, we’re solving problems.

The difference is that a product is “done”. If you have a “product team”, they probably have a “definition of done”, and then release software that has satisfied that definition. Even where that’s iterative and incremental, it leads to there being a “product”. The thing that’s live represents as much of the product as has been done.

The implications of there being a “product” that is partially done include optimising for getting more “done”. Particularly, we will prioritise adding new stuff (getting more “done”) over fixing old stuff (shuffling the deckchairs). We will target productish metrics, like number of daily actives and time spent.

Let me propose an alternative: we are not making products, we are solving problems. And, as much out of honesty as job preservation, let me assure you that the problems are very difficult to solve. They are problems in cybernetics, in other words in communication and control in a complex system. The system is composed of three identifiable, interacting subsystems:

  1. The people who had the problem;
  2. The people who are trying to solve the problem;
  3. The software created to present the current understanding of the solution.

In this formulation, we don’t want “amount of product” to be a goal, we want “sufficiency of solution” to be a goal. We accept that the software does not represent the part of the “product” that has been “done”. The software represents our best effort to date at modelling our understanding of the solution as we comprehend it to date.

We therefore accept that adding more stuff (extending the solution) is one approach we could consider, along with fixing old stuff (reflecting new understanding in our work). We accept that introducing the software can itself change the problem, and that more people using it isn’t necessarily a goal: maybe we’ve helped people to understand that they didn’t actually need that problem solved all along.

Now our goals can be more interesting than bushels of software shovelled onto the runtime furnace: they can be about sufficiency of the solution, empowerment of the people who had the problem, and improvements to their quality of life.

December 14, 2018

Reading List by Bruce Lawson (@brucel)

A (usually) weekly round-up of interesting links I’ve tweeted. Sponsored by Smashing Magazine who slip banknotes into my underwear so I can spend time reading stuff.

Despite the theory that everything can be done in software (and of course, anything that can’t be done could in principle be approximated using numerical methods, or fudged using machine learning), software engineering itself, the business of writing software, seems to be full of tools that are accepted as de facto standards but, nonetheless, begrudgingly accepted by many teams. What’s going on? Why, if software is eating the world, hasn’t it yet found an appealing taste for the part of the world that makes software?

Let’s take a look at some examples. Jira is very popular among many people. I found a blog post literally called Why I Love Jira. And yet, other people say that Jira is an anti pattern, a sentiment that gets reasonable levels of community support.

Jenkins is almost certainly the (“market”, though it’s free) leader among continuous delivery tools, a position it has occupied since ousting Hudson, from which it was forked. Again, it’s possible to find people extolling the virtues and people hating on it.

Lastly, for some quantitative input, we can find that according to the Stack Overflow 2018 survey, most respondents (78.9%) love Rust, but most people use JavaScript (69.8%). From this we draw the interesting conclusion that the most popular tool in the programming language realm is not, actually, the one that wins the popularity contest.

So, weird question, why does everybody do this to themselves? And then more specifically, why is your team doing it to yourselves, and what can you do about it?

My hypothesis is that all of these tools succeed because they are highly configurable. I mean, JavaScript is basically a configuration language for Chromium (don’t @ me) to solve/cause your problem. Jira’s workflows are ridiculously configurable, and if Jenkins doesn’t do what you want then you can find a plugin to do it, write a plugin to do it or make a Groovy script that will do it.

This appeals to the desire among software engineers to find generalisations. “Look,” we say, “Jenkins is popular, it can definitely be made to do what we want, so let’s start there and configure it to our needs”.

Let’s take the opposing view for the moment. I’m going to drop the programming language example of JS/Rust, because all programming languages are, roughly speaking, entirely interchangeable. The detail is in the roughness. The argument below still applies, but requires more exposition which will inevitably lead to dissatisfaction that I didn’t cover some weird case. So, for the moment, let’s look at other tools like Jira and Jenkins.

The exact opposing view is that our project is distinct, because it caters to the needs of our customers and their (or these days, probably our) environment, and is understood and worked on by our people with our processes, which is not true for any other project. So rather than pretend that some other tool fits our needs or can be bent into shape, why don’t we build our own?

And, for our examples, building such a tool doesn’t appear to be a big deal. Using the expansive software engineering term “just”, a CD tool is “just” a way to run each step in the deployment pipeline and tell someone when a step fails. A development-tracking tool is “just” a way to list the things the team is or could be working on.

This is more or less a standard “build or buy” question, with just one level of indirection: both building and buying are actually measured in terms of time. How long would it take the team to write a new CD tool, and to maintain it? How long would it take the team to configure Jenkins, and to maintain it?

The answer should be fairly easy to consider. Let’s look at the map:

We are at x, of course. We are a short way from the Path of Parsimony, the happy path along which the generic tools work out of the box. That distance is marked on the map as .

Think about how you would measure for your team. You would consider the expectations of the out-of-the-box tool. You would consider the expectations of your team, and of your project. You would look at how those expectations differ, and try to quantify the result.

This tells you something about the gap between what the tool provides by default and what you need, which will help you quantify the amount of customisation needed (the cost of building a spur out from the Path of Parsimony to x). You can then compare that with the cost of building a tool that supports your position directly (the cost of building your own path, running through x).

But the map also suggests another option: why don’t we move from x closer to the path, and make smaller? Which of our distinct assumptions are incidental and can be abandoned, which are essential and need to be supported, and which are historical and could be revised? Is there a way to change the context so that adopting the popular tool is cheaper?

[Left out of the map but just as important is the related question: has somebody else already charted a different path, and how far are we from that? In other words, is there a different off-the-shelf product which needs less configuration than the one we’ve picked, so the total migration-plus-configuration cost is less than sticking where we are?]

My impression is that these questions tend to get asked once at the start of a project or initiative, then not again until the team is so far away from the Path of Parsimony that they are starting to get tangled and stung by the Weeds of Woe. Teams that change tooling such as their issue trackers or CD pipeline tend to do it once the existing way is already hurting too much, and the route back to the path no longer clear.

December 12, 2018

December 11, 2018

The Magpie team at Stickee builds clever things (software, mostly) for some of the world’s biggest companies. Following a strong 2018, 2019 is going to...

The post PHP Software Developers for the Magpie team appeared first on stickee.

December 10, 2018

Christmas Gifts for Designers

It’s that time of year where you feel the urge to buy your friends and family gifts, sometimes it’s easy and sometimes it can be a tough old slog. Well, if they’re a designer try buying them some of these cool products.

Panobook Notebook

pano book

Panobook is a panoramic notebook for your desk, and eventually, your shelf. Made of quality materials and thoughtful details, and includes a slipcase for archiving when you’re finished. It features a dot grid with device guides and is a seriously high quality product.

Prices start from $19 each but worth buying the three pack for $57

Learn More >

 

Socks in a Box Subscription

Socksinabox Subscriptions have socks to suit everybody – simply select the range of socks that most suits the person you are buying for. Perfect for the sock lover.

Subscriptions start from £19.99

Learn More > 

 

Pantone Candles

Pantone Scented Candles release a selection of fragrances to suit any mood or taste. They are presented within coloured glass vessels the colours of which were inspired by the standardised colours of the world-renowned Pantone Colour Matching System book.

Small candles start at around £6

Learn More >

 

UI Stencils Starter Pack

Get your sketch on. This starter pack comes with everything you need to jump start your prototyping chops. Features your choice of Web, iPhone, or Android Stencil Kits, Accompanying Sketch Pad, UI Stencils Case & Pentel p207 Drafting Pencil.

This set will cost you £67  

Learn More >

 

Wireframe Deck

The Wireframe Deck includes 80 2×2″ double-sided cards of common website and UI elements, lo-fi on one side and hi-fi on the other. A great way to get creative away from the computer.

You’ll pay $19 for this.

Learn More >

 

Dot Grid Journal Pack

Dotgrid.co Journal Pack contains one A5 and one A6 dot grid journal. It also comes with a Staedtler Fineliner Pen in a Dotgrid.co branded bag and is available in six fun colours. A great bundled gift for any designer friends in some really cool colours.

A bargain at £28!

Learn More >

 

Logi Wireless Charger

Logitech’s Powered wireless charging stand delivers convenient hands-free wireless charging for your iPhone. Its thoughtful design lets you charge your iPhone while still making calls — without ever cutting power. And a U-shaped cradle ensures effortless charging placement every time you rest your iPhone inside. Side-note, great for unlocking with FaceID without touching it.

This is a pretty £60 but will transform your desk.

Learn More >

 

Pixel Ruler

The ultimate tool for responsive screen size sketching. Heavy-duty gauge stainless steel ruler with pixel increments. Markers for mobile, tablet and widescreen (laptop) sizing.

If you want to pay $36 for a ruler this one is for you.

Learn More > 

There’s a few ideas for you. Send me over any other cool designer related gifts for future posts.

I cover lots of things on my blog, perhaps you’ll enjoy reading ‘Be a better freelance designer’

The post Christmas Gifts for Designers appeared first on .

December 09, 2018

I frequently meet software teams who describe themselves as “high velocity”, they even have graphs coming from Jira to prove it, and yet their ability to ship great software, to delight their customers, or even to attract their customers, doesn’t meet their expectations. A little bit of sleuthing usually discovers the underlying problem.

Firstly, let’s take a look at that word, “velocity”. I, like Kevlin Henney, have a background in Physics, and therefore I agree with him that Velocity is a vector, and has a direction. But “agile” velocity only measures amount of stuff done to the system over time, not the direction in which it takes the system. That story may be “5 points” when measured in terms of heft, but is that five points of increasing existing customer satisfaction? Five points of new capability that will be demoed at next month’s trade show? Five points of attractiveness to prospects in the sales funnel?

Or is it five points of making it harder for a flagship customer to get their work done? Five points of adding thirty-five points of technical debt work later? Five points of integrating the lead engineer’s pet technology?

All of these things look the same in this model, they all look like five points. And that means that for a “high-velocity” (but really low-velocity, high-speed) team, the natural inclination is to jump on it, get it done, and get those five points under their belt and onto the burn down chart. The faster they burn everything down, the better they look.

Some of the presenting symptoms of a high-speed, low-velocity team are listed below. If you recognise these in your team, book yourself in for office hours and we’ll see if we can get you unstuck.

  • “The Business”: othering the rest of the company. The team believes that their responsibility is to build the thing that they were asked for, and “the business” needs to tell them what to build, and to sell it.
  • Work to rule: we build exactly what was asked for, no more, no less. If the tech debt is piling up it’s because “the business” (q.v.) doesn’t give us time to fix it. If we built the wrong thing it’s because “the business” put it at the top of the backlog. If we built the thing wrong it’s because the acceptance criteria weren’t made clear before we started.
  • Nearly done == done: look, we know our rolling average velocity is 20 bushels of software, and we only have 14 furlongs and two femtocandela of software to show at this demo. But look over here! These 12 lumens and 4 millitesla of software are in QA, which is nearly done, so we’ve actually been working really hard. The fact that you can’t use any of that stuff is unimportant.
  • Mini-waterfall: related to work to rule (q.v.), this is the requirement that everyone do their bit of the process in order, so that the software team can optimise for requirements in -> software out and get that sweet velocity up. We don’t want to be doing discovery in engineering, because that means uncertainty, uncertainty means rework, and rework means lower velocity.
  • Punitive estimation: we’re going to rename “ambiguity” to “risk”, and then punish our product owner for giving us risky stories by boosting their estimates to account for the “risk”. Such stories will never get scheduled, because we’ll never be asked to do that one risky thing when we can get ten straightforward things done in what we are saying is the same time.
  • Story per dev: as a team, our goal is to shovel as much software onto the runtime furnace as possible. Therefore we are going to fan out the tasks to every individual. We are each capable of wielding our own shovel, and very rarely do we accidentally hit each other in the face while shovelling.

December 07, 2018

Reading List by Bruce Lawson (@brucel)

A (usually) weekly round-up of interesting links I’ve tweeted. Sponsored by Smashing Magazine who slip banknotes into my underwear so I can spend time reading stuff.

December 06, 2018

I received an invitation reading

Acme Inc is organizing and sponsoring Timbuktu’s biggest annual developer conference called “Timbuk-Toot!”. Past speakers include Richard Stallman, Morgan Freeman, Humphrey Bogart and Cruella de Vil.

Would you like to give a workshop or a talk at Timbuk-Toot! in February 2019?

Let me know!

And that was it. It’s not nearly enough information to make a decision, so —unless it’s from someone I know, or I’ve always always wanted to visit Timbuktu— I park this, thinking “I’ll email back and ask them for more information”. Then, of course, the rest of the day happens and I forget about it.

So, if you’re emailing someone to ask them to speak, at a minimum I’d need this information:

  • what do you want me to talk about? What’s the theme of the conference?
  • How long is a talk? How long is a workshop?
  • Are the talks recorded? Are they available to all, e.g. over YouTube?
  • How many people attend? Who attends?
  • You mention Acme Inc; is it an internal Acme staff conference, or open to the public?
  • What are the dates? How can I answer when i’m only told “February 2019”?
  • Are you paying for my flights/ accommodation? I suspect not, as you don’t mention it.
  • If you are covering travel expenses, am I expected to pay them and get them reimbursed? If yes, how many days does it take for me to get my money back? (A the moment, over Xmas, I’m giving an two-month interest-free loan of 1000Euro to a conference.)
  • If I’m a freelancer, are you paying a fee for my time? I suspect not, as you don’t mention it.
  • Is there a code of conduct? Where is it? Is the speaker line-up inclusive? (Probably not, if you’re not paying expenses or a speaker fee.)

You need to tell me why I should care about it. You might be huge in the Timbuktu web industry, but I don’t know you. So far, all you have done is raise questions which means I have to reply to you and ask them, on top of all the other things I have to do today.

Don’t make me think!

Donald Knuth is pretty cool. One of the books he wrote that I own and have actually read[*] is Literate Programming, in which he describes (among other things) weaving program text and documentation together in a single narrative.

Two of his books that I own and have sort of dipped into here and there are TeX: the Program, and METAFONT: the Program. These are literate programs, created from webs in which Human text and Computer text are interleaved to tell the story of what the program does.

Human text and computer text, but not images. If you want pictures, you have to carry them around separately. Even though we are highly visual organisms, and many of the programs we produce have significant graphical components, very few programming environments treat images as anything other than external files that can be looked at and maybe previewed. The only programming environment I know of that lets you include images in program source is TempleOS.

I decided to extend the idea of the Literate web to the realm of Figurative Programming. A gloom (graphical loom) web can contain human text, computer text, and image descriptions (e.g. graphviz, plantuml, GLE…) which get included in the human-readable document as figures.

The result is gloom. It’s written in itself, so the easiest way to get started is with the Xcode project at gloomstrap which can extract the proper gloom sources from the gloom web. Alternatively, you can dive in and read the PDF it made about itself.

Because I built gloomstrap first, gloom is really a retelling of that program in a Figurative Programming web, rather than a program that was designed figuratively. Because of that, I don’t really have experience yet of trying to design a system in gloom. My observation was that the class hierarchy I came up with in building gloomstrap didn’t always lend itself to a linear storytelling for inclusion in a web. I expect that were I to have designed it in noweb rather than Xcode, I would have had a different hierarchy or even no classes at all.

Similarly, I didn’t try test-firsting in gloom, and nor did I port the tests that I did write into the web. Instinct tells me that it would be a faff, but I will try it and find out. I think richer expressions of program intention can only be a good thing, and if Figurative Programming is not the way in which that can be done, then at least we will find out something about what to do instead.

[*] Coming up in January’s De Programmatica Ipsum: The Art of _The Art of Computer Programming_, an article about a book that I have _definitely_ read _quite a few bits here and there_ of.

December 03, 2018

Two books by Graham Lee

A member of a mailing list I’m on recently asked: what two books should be on every engineer’s bookshelf? Here’s my answer.

Many software engineers, the ones described toward the end of Code Complete 2, would benefit most from Donald Knuth’s The Art of Computer Programming and Computers and Typesetting. It is truly astounding that one man has contributed so comprehensively to the art of variable-height monitor configurations.

If, to misquote Bill Hicks, “you’ve got yourself a reader”, then my picks are coloured by the fact that I’ve been trying to rehabilitate Object-Oriented Design for the last few years, by re-introducing a couple of concepts that got put aside over the recent decades:

  1. Object orientation; and
  2. Design.

With that in mind, my two recommendations are the early material from that field that I think shows the biggest divergence in thinking. Readers should be asking themselves “are these two authors really writing about the same topic?”, “where is the user of the software system in this book?”, “who are the users of the software system in this book?”, and “do I really need to choose one or other of these models, why not both or bits of both?”

  1. “Object-Oriented Programming: an evolutionary approach” by Brad Cox (there is another edition with Andrew Novobilski as a co-author). Cox’s model is the npm/CPAN model: programmers make objects (“software ICs”), describe their characteristics in a data sheet, and publish them in a catalogue. Integrators choose likely-looking objects from the catalogue and assemble an application out of them.

  2. “Object-Oriented Software Construction” by Bertrand Meyer. Meyer’s model is the “software engineering” model: work out what the system should do, partition that into “classes” based on where the data should naturally live, and design and build those classes. In designing the classes, pay particular attention to the expectations governing how they communicate: the ma as Alan Kay called the gaps between the objects.

November 30, 2018

InVision Studio. First Impressions.

I made yogamoji in around 3 hours in InVision Studio. Check out the prototype here & Upvote it on Dribbble for me!

InVision Studio

Why now?

I downloaded InVision Studio all the way back in April and left it sitting in my applications folder like a pack of Pot Noddles you’re to embarrassed to eat. I’ve been a dedicated Sketch user for years, so much so that over 12 months ago I stopped paying for Adobe CC and have no regrets.

I’ve also been using InVision + Craft + Sketch for years too so I didn’t have much desire to open up Studio and start learning something new. For my UI Design needs Sketch + Craft did everything I needed. I could make nice designs and make prototypes in no time whatsoever so why would I switch?

Fast forward to today and UI animations are becoming such an important part of any designers workflow I thought to myself “Heck, I’m going to get left behind here…”. I started my journey giving Framer X a trial and while I have a high opinion of Framer X I needed something to compare it to… so that’s the reason why I picked up InVision Studio.

Here’s my first impressions of InVision Studio 

Familiar

InVisionStudio

If you’re a Sketch user you’ll be able to pick InVision Studio up in no time, the layout is similar and most importantly so are the shortcuts.

I found myself forgetting I wasn’t in Sketch which was a good thing, while Framer X had more of a learning curve, more errors, more frustration.

I liked that Studio’s interactions were more powerful than craft in Sketch. Studio feels like Sketch with benefits.

Pretty

yogamoji

Studio is beautiful, every pixel has been expertly designed.

Sketch at times can feel a bit dated with it’s choice of UI and often release updates, while Studio feels clean, sharp, crisp and functional.

Everything is tucked out of the way, they’re aware their users are typically clever creative folks so won’t mind if a menu is hidden, especially if it’s not used much.

Talking of menus, they’re small and inoffensive. We don’t need a merge button that’s 80 pixels do we? We just need to get to it and Studio makes access really easy.

Powerful

yogamoji

As I mentioned before, InVision feels like Sketch with Benefits. This brings some serious prototyping power. I’ve been used to basic animations and they served me well but Studio opens a whole new dimension of possibilities to how my future prototypes could work.

I can now go and create scrolling elements and animate popups, move elements around the screen as you interact with other elements… you don’t need me to tell you all this but It feeds the imagination.

My creative senses are tingling at the prospect of more animation in my projects.

Pains

macpains

Sadly my Mac didn’t enjoy the animation process as much as I did, my poor machine struggled with some of the more complicated animations.

Without getting into it too deep, you have to make sure both art boards you’re trying to animate between contain the same elements so if you have a long image heavy list that needs to be on both pages + 0% alpha which can get in the way and in my case cause memory issues.

Side note: I was recoding the screen at the same time so perhaps this was the cause of the mini melt down.

I missed having all my Sketch plugins but sure in time Studio will catch up.

But as pains go, pretty minimal.

Conclusion

InvISIONsTUDIO

I don’t really scratch the surface in this post as many of you have been using it for months and know all this but my verdict is Studio is a great alternative to Sketch, especially for those projects that require more animation.

Will it replace Sketch for me? Unsure at this point. Possibly.
Is it better than Framer X? Yes and No. It’s different.
Adobe XD? No idea. Probably will never be in my workflow because of Adobe’s cost.

My next steps would be to use Studio on a professional project and see how I get on, if you want to hire me to design you something, please do so 🙂

Before I sign off… I’ve written about InVision before, so why not read that too?

The post InVision Studio – First Impressions appeared first on .

November 27, 2018

Spotify Playlists to help you work

If you’re like me you need music or a podcast on in the background to get you working. I had a job years ago that had a no music rule and as a result it was like working in a library, that job didn’t keep me for very long.

Over the years I’ve collected a fair few Spotify playlists that I like to throw on to help me work. My music tastes are fairly alternative but hopefully there will be something for everyone here, enjoy.

Alternative 70’s

alternative70s

This playlist is awesome. It’s a full decade before I was even born but contains some of my favourite songs. You’ll find bands like The Cure, Joy Division, Undertones, Iggy Pop and loads more.

Listen to ‘Alternative 70s’ here>

Billy’s Playlist

billys playlist

Around 4,000 alternative songs that are every 6 Music listeners dream. A mix of Arcade Fire, Arctic Monkey’s, Underworld, Kanye… all sorts.

Listen to ‘Billy’s Playlist’ here>

Last Man on Earth Soundtrack

lastmanonearth

A fan of the awesome TV show has painstakingly collected all the awesome songs from this comedy show. You’ll find old classics and new tunes. Kinks, Foo Fighters, Buddy Holly, Cat Power…

Listen to ‘Last Man on Earth Soundtrack’ here>

Classic Acoustic.

classic acoustic

Another Spotify managed playlist full of beautiful acoustic songs, many classics and some you may not of heard of. Simon and Garfunkel, Beatles, Bob Dylan, Elton John, Nick Drake. This playlist will make your heart ache but it’s brilliant.

Listen to ‘Classic Acoustic’ here>

Hip Hop Evolution

hiphopevolution

If Hip Hop is your jam then you have no choice but give this playlist your time. It’s a soundtrack from the amazing HBO doc-series Hip Hop Evolution and contains all the classics from 2-Pac to Kurtis Blow.

Listen to ‘Hip-Hop Evolution’ here>

Almost Famous

Almost Famous

Another collection of songs put together from a fan of the excellent film of the same name, this playlist has all the classics from Elton John to David Bowie.

Listen to ‘Almost Famous’ here>

Best of Alt

bestofalt

And finally it wouldn’t be right without sharing a playlist I’ve been adding to for years, Best of Alt. I know some friends have been playing this in their offices over the last few years to mixed results. You can expect a wide range of everything, from heavy metal to pop. If I like the song (or once did) it’s in there. You’ll find Smashing Pumpkins, Deftones, Arctic Monkeys, Jeff Buckley, Idlewild etc etc

Listen to ‘Best of Alt’ here>

 

 

Thanks for reading and make sure you check out my other Blog posts.

The post Spotify Playlists to Help you Work appeared first on .

Packaging software by Graham Lee

I’ve been learning about Debian Packaging. I’ve built OS X packages, RPMs, Dockerfiles, JARs, and others, but never dpkgs, so I thought I’d give it a go.

My goal is to make a suite of GNUstep packages for Debian. There already are some in the base distribution, and while they’re pretty up to date they are based on a lot of “default” choices. So they use gcc and the GNU Objective-C runtime, which means no blocks and no modern objc features. The packages I’m making are, mostly thanks to overriding some choices in building gnustep-make, built using clang, the next-generation objc runtime, libdispatch etc.

The Debian packaging tools are very powerful, very well documented, and somewhat easy to use. But what really impressed me along this journey was CPack. I’ve used cmake before, on a team building a pretty big C++/Qt project. It’s great. It’s easier to understand than autoconf, easier to build correct build rules over a large tree than make, and can generate fast builds using ninja or IDE-compatible projects for Xcode, IntelliJ and (to some extent) Eclipse.

What cpack adds is the ability to generate packages, of various flavours (Darwin bundles, disk images, RPMs, DEBs, NullSoft installers, and more) from the information about the build targets. That’s really powerful.

Packaging software is a really important part of the customer experience: what is an “App Store” other than a package selection and distribution mechanism? It irks me that packaging systems are frequently either coupled to the target environment (Debian packages and OpenBSD ports are great, but only work in those systems), or baroque (indeed autoconf may have gone full-on rococo). Package builder-builders give distributors a useful respite, using a single tool to build packages that work for any of their customers.

It’s important that a CD pipeline produces the same artefacts that your customers use, and also that it consumes them: you can’t make a binary, test it, see that it works, then bundle it and ship it. You have to make a binary, bundle it, ship it, install it, then test it and see that it works. (Obviously the tests I’m talking about here are the “end-to-end”, or “customer environment” tests. You don’t wait until your thing is built to see whether your micro-tests pass, you wait until your micro-tests pass to decide whether it’s worth building the thing.)

I know that there are other build tools that also include packaging capabilities. The point is, using one makes things easier for you and for your customers. And, it turns out, CMake is quite a good choice for one.

November 24, 2018

Long ago, I took 4/9ths of an undergraduate physics degree, along with 4/9ths computer science and 1/9th mathematics. Having had little or no contact with physics in the intervening years, I’ve started to do some light reading about relativity in the last couple of years. This week, I came across a tip on Quora * to a fellow traveller in space-time: “stop thinking of the speed of light as a number”. Erm… WHAT?! As every school child knows, the maximum  speed of light (or any other form of electromagnetic radiation) in a vacuum is about 600,000 Km/s. That sounds like a number to me. The problem with speed in Einstein’s relativistic model of reality though, is that distance and time get very weird. That makes them hard to think about, so the advice was to ignore what we think we know and look at things in a new way.
[* – I’ll add an acknowledgement to the author of  the comment on Quora, if I ever find it again. It took me a while to understand what I’d read. ]

I’m not sure I was entirely paying attention when I studied physics last time. I don’t remember anyone explaining the precise nature of the the scientific method, or indeed what physics actually is; that’s metaphysics. This time around I see science as the process of understanding how nature works, using evidence rather than guessing then arguing the case for your beliefs. That is philosophy, or a religion. Physics, in particular, is about observing reality and working out what the rules are. It is NOT about saying why things happen. As science was becoming formalised, it was known as ‘natural philosophy’ i.e. philosophy that refers to evidence from nature.

Einstein’s Theories of Relativity say that matter and energy are equivalent. His equation of mass-energy equivalence records the relationship between the alternative mass and energy forms of matter. It is a very well known equation, even with people who have no idea what it refers to.

The form of the equation we are most familiar with is

E = mc²

E is the concentrated energy contained in a mass, m. E is a much bigger number than m because we know that c is a big number AND it’s squared.

This equation can be re-arranged to a form I don’t remember seeing or taking note of before:

c = √(E/m)

This new way (at least to me) of looking at this century old theory says that c is related to the ratio between the Energy and mass of an object. This ratio stays the same, even as space-time expands or contracts, according to the General Theory of Relativity. The recent confirmation by the LIGO project of gravitation waves that also travel at c, were also predicted, so this gives extra weight to the theory

I’ve realised that physics often relates things to each other, without saying which is the ‘fundamental thing’. Does gravity bend space-time or is the curvature of space-time what causes gravity? The equations work either way.

John Archibald Wheeler said it a different way: “Space-time tells matter how to move; matter tells space-time how to curve” and matter can be converted to energy, energy to matter.

November 22, 2018

Workaround App for iPhone

Book flexible workspace in hotels around Germany

Workaround is the project of German entrepreneur Maxim Streletzki. The idea is simple. You pack your laptop and rent workspace in some of Germanys most luxurious hotels. You pay by the hour and get free access to WIFI. It was solving the issue many hotel chains have, lots of dead space. This was perfect for them to not only look busy but make extra money from their lobby.

Workaround App for iPhone

Maxim first approached me to design him some concepts for his app, this quickly grew into creating a full interactive prototype that he could show his investors and business partners. The prototype took you from logging in all the way to paying for your time at the flexible workspace.

The app was designed to be simple to use and make use of lots of beautiful whitespace. We wanted to get away from the traditional ways apps were being designed and dropped list views to be purely location based views. You can then click through to the hotel and view it’s photos, amenities and how to get there.

Workaround App for iPhone

This project played to my strengths, lots of creativity and white space! It made use of my ability to use clean, functional design as a feature and really pleased with how it turned out.

Workaround App for iPhone

If you have an app you want me to design feel free to drop me a message and we can get something in the diary.

 

 

I write lots of blogs about design and freelancing so why not head over and have a read.

The post Workaround App for iPhone appeared first on .

The Weekend Woodworker course review

As anyone that follows this blog knows, I've slowly been working my way though the Weekend Woodworker course by Steve Ramsey.

I found the course enlightening and educational, as well as entertaining, so when I was given the opportunity to write a review of it for HackSpace magazine, I jumped at it - and today that review has been published in issue 13.

If you're not a subscriber to the magazine, you can download the PDF edition for free from their site, although I personally find the dead tree edition much better, having been a subscriber since the first issue.

I hope you enjoy the review - feel free to let me know what you think -  and if you want more content like it, subscribe to the blog.

The Weekend Woodworker course review
The Weekend Woodworker course review

As anyone that follows this blog knows, I've slowly been working my way though the Weekend Woodworker course by Steve Ramsey.

I found the course enlightening and educational, as well as entertaining, so when I was given the opportunity to write a review of it for HackSpace magazine, I jumped at it - and today that review has been published in issue 13.

If you're not a subscriber to the magazine, you can download the PDF edition for free from their site, although I personally find the dead tree edition much better, having been a subscriber since the first issue.

I hope you enjoy the review - feel free to let me know what you think -  and if you want more content like it, subscribe to the blog.

The Weekend Woodworker course review
The Weekend Woodworker course review

As anyone that follows this blog knows, I've slowly been working my way though the Weekend Woodworker course by Steve Ramsey.

I found the course enlightening and educational, as well as entertaining, so when I was given the opportunity to write a review of it for HackSpace magazine, I jumped at it - and today that review has been published in issue 13.

If you're not a subscriber to the magazine, you can download the PDF edition for free from their site, although I personally find the dead tree edition much better, having been a subscriber since the first issue.

I hope you enjoy the review - feel free to let me know what you think -  and if you want more content like it, subscribe to the blog.

The Weekend Woodworker course review

Sling App for iOS / iPhone

A handy way to send your friends a drink for any occasion.

Australian entrepreneurs (and siblings) Phil and Jane Lawlor approached me for a UI design and brand for their new product Sling. The idea behind Sling is simple, you send your loved one or friends a drink.

The drink is already paid for all they have to do is go to the bar and pick it up.

Sling App for iOS / iPhone

Sling uses your friends checked in locations to alert you when they’re at a bar or restaurant. You can then buy them a drink via the app wherever you are in the world. This then alerts your friend to go to the bar and collect their free drink. Who doesn’t want to pick up a free Margarita?

The app produces an exclusive code that would be redeemed via the bars purchase software, this then transfers payment to the vendor and your friends gets the drink.

Sling App for iOS / iPhone

The nice thing about Sling is you don’t even need to have any friends out. If you’re out or been somewhere recently and tried a nice cocktail you can buy that same drink for your friend. “You must try this cocktail, have one on me!”.  It’s a great way of sharing experiences.

This will then send a notification to your friend that gives them a set period of time to claim the drink. If the time expires, the users card is refunded.

Sling App for iOS / iPhone

Part of this project was branding. The logo below is made up of two shapes, the shape if you look closely is the top of a wine glass turned on it’s side. They are they cut together to form boomerang shapes to suggest you’re slinging something (and the founders being Australian also came to mind).

Sling App for iOS / iPhone

I really enjoyed working on this project. It was a complicated one and I found it challenging due to the amount of features we wanted to get into the app but really happy with the results. If you need a beautiful app design please contact me to talk.

“Professionalism and skill are hard to find in consultants for startups. Mike has both. He provided high quality designs, to spec, on time and within budget. I could not ask for more.”

Phil Lawlor, Founder Sling App.

I write lots on my design blog. Try reading “It’s OK Not to Chase Constant Growth With Your Freelance Business”

The post Sling App for iPhone appeared first on .

November 21, 2018

Representing concurrency in an object-oriented system has been a long-standing problem. Encapsulating the concurrency primitives via objects and methods is easy enough, but doesn’t get us anywhere. We still end up composing our programs out of threads and mutexes and semaphores, which is still hard.

Prior Art

It’s worth skimming the things that I’ve written about here: I’ve put quite a lot of time into this concurrency problem and have written different models as my understanding changed.

Clearly, this is a broad problem. It’s one I’ve spent a lot of time on, and have a few satisfactory answers to if no definitive answer. I’m not the only one. Over at codeotaku they’ve concluded that Fibers are the right solution, though apparently on the basis of performance.

HPC programs are often based on concurrent execution through message passing, though common patterns keep it to a minimum: the batch processor starts all of the processes, each process finds its node number, node 0 divvies up the work to all of the nodes (a message send), then they each run through their part of the work on their own. Eventually they get their answer and send a message back to node 0, and when it has gathered all of the results everything is done. So really, the HPC people solve this problem by avoiding it.

You’re braining it wrong, Graham

Many of these designs try to solve for concurrency in quite a general way. Serial execution is a special case, where you only have one object or you don’t submit commands to the bus. The problem with this design approach, as described by Bertrand Meyer in his webinar on concurrent Object-Oriented Programming, is that serial execution is the only version we really understand. So designing for the general, and hard-to-understand, case means that generally we won’t understand what’s going on.

The reason he says this is so is that we’re better at understanding static relationships between things than the dynamic evolution of a system. As soon as you have mutexes and condition locks and so on, you are forced to understand the dynamic behaviour of the system (is this lock available? Is this condition met?). Worse: you have to understand it holistically (can anything that’s going on at the moment have changed this value?).

Enter SCOOP

Meyer’s proposal is that as serial programs are much easier to understand (solved, one might say, if one has read Dijkstra’s A Discipline of Programming) we should make our model as close to serial programming as possible. Anything that adds concurrency should be unsurprising, and not violate any expectations we had if we tried to understand our program as a sequential process.

He introduced SCOOP (Simple Concurrent Object-Oriented Programming) developed by the Concurrency Made Easy group at ETH Zürich and part of Eiffel. Some of the design decisions he presented:

  • a processor is an abstraction representing sequential execution
  • there is a many-to-one mapping of objects to processors (this means that an object’s execution is always serial, and that all objects are effectively mutexes)
  • where an object messages another on a different processor, commands will be asynchronous (but executed in order) and queries will be synchronous
  • processors are created dynamically and opportunistically (i.e. whenever you create an object in a “separate” and as-yet unpopulated domain)

An implementation of this concurrency model in Objective-C is really easy. A proxy object representing the domain separation intercepts messages, determines whether they are commands or queries and arranges for them to be run on the processor. It inspects the objects returned from methods, introducing proxies to tie them to the relevant processor. In this implementation a “processor” is a serial operation queue, but it could equivalently be a dedicated thread, a thread pulled from a pool, a dedicated CPU, or anything else that can run one thing at a time.

This implementation does not yield all of the stated benefits of SCOOP. Two in particular:

  1. The interaction of SCOOP with the Eiffel type system is such that while a local (to this processor) object can be referred to through a “separate” variable (i.e. one that potentially could be on a different processor), it is an error to try to use a “separate” object directly as if it were local. I do not see a way, in either Swift’s type system or ObjC’s, to maintain that property. It looks like this proposal, were it to cover generic or associated types, would address that deficiency.

  2. SCOOP turns Eiffel’s correctness preconditions into wait conditions. A serial program will fail if it tries to send a message without satisfying preconditions. When the message is sent to a “separate” object, this instead turns into a requirement to wait for the precondition to be true before execution.

Conclusions

Meyer is right: concurrent programming is difficult, because we are bad at considering all of the different combinations of states that a concurrent system can be in. A concurrent design can best be understood if it is constrained to be mostly like a serial one, and not require lots of scary non-local comprehension to understand the program’s behaviour. SCOOP is a really nice tool for realising such designs.

This is something I can help your team with! As you can see, I’ve spent actual years understanding and thinking about software concurrency, and while I’m not arrogant enough to claim I have solved it I can certainly provide a fresh perspective to your team’s architects and developers. Book an office hours appointment and let’s take a (free!) hour to look at your concurrency problems.

November 19, 2018

Wildcat is live (and angry)

This is the third post in the Wildcat saga, so if this is your first time reading this blog it might be worth catching up - to find out more about the antagonist of our story, start with Introducing Apricat, and to understand our approach to solving the problem (and one of the challenges I've encountered on the way), read Project Wildcat... has been delayed.

All caught up? Good. Because I'm happy to reveal that Wildcat is live.

Wildcat is live (and angry)

I spoke a little about the technical hardware and general software approach in my last post, so instead of rehashing that I'm simply going to supply a link to the git repo for the project which I'm hoping, combined with the diagram below, will be self explanatory:

Wildcat is live (and angry)

For this post I'm more interested in talking about the fabrication of the non-technical parts of the project, most of which were designed around a cat ear frame we found in HomeSense.

The front panel was designed in about an hour (based on some initial measurements of the frame and LEDs) using Tinkercad, then after 3D printing and realising that nothing fit, slightly refined into what you see below:

This second print fit perfectly, so was primed using Rust-Oleum Surface Primer, expertly painted by Lucy using acrylics, then glued into the frame using Gorilla glue.

The next problem was housing the electronics. Thankfully Adafruit provide a really cool system for printing modular Feather cases, of which I used a tall variation, allowing the stacking headers on my Huzzah to fit.

Before attaching the board into the case with some bolts, I removed the plastic housing from the female ends of a couple of jumper wires (so they'd also fit in the case), and slipped them into the pins of the header, wrapped them around the internal case mounts (to help stop them being tugged out) and lead them out the hole in the side, ready to be attached to the button.

Wildcat is live (and angry)

I could have soldered the jumper wires to the pins, which I'm sure would make them more secure, but one of my guiding principles with this build was the ability to disassemble everything easily if I wanted to salvage any of the electronics.

I wanted the button to be hidden but easily accessible, so using two strips of copper tape and some glue, I attached it to the back of the left ear, soldering the contacts to one end of the strips and the jumper wires to the other.

Wildcat is live (and angry)

The final bit of assembly was sticking the lid from the case module to the back of the front panel. Due to the size of the LED matrix there was a small gap between them when dry fitted, but half a Command Strip either side not only filled this gap nicely, but will allow me to easily separate the two if I need to.

Wildcat is live (and angry)

And that's the build. I asked Apricat what she thought of the project, and think the look she gave me summed it up:

Wildcat is live (and angry)

In truth, she had calmed down a lot before I even started making this project, and I think she's truly feeling at home with us. So of course this project isn't designed for punishment, instead it's just a bit of fun and an excuse to build something, because we really love Apricat, and know that when she does bite us, it's not aggressive, but instead just her playful way of showing she loves us.

Wildcat is live (and angry)

This is the third post in the Wildcat saga, so if this is your first time reading this blog it might be worth catching up - to find out more about the antagonist of our story, start with Introducing Apricat, and to understand our approach to solving the problem (and one of the challenges I've encountered on the way), read Project Wildcat... has been delayed.

All caught up? Good. Because I'm happy to reveal that Wildcat is live.

Wildcat is live (and angry)

I spoke a little about the technical hardware and general software approach in my last post, so instead of rehashing that I'm simply going to supply a link to the git repo for the project which I'm hoping, combined with the diagram below, will be self explanatory:

Wildcat is live (and angry)

For this post I'm more interested in talking about the fabrication of the non-technical parts of the project, most of which were designed around a cat ear frame we found in HomeSense.

The front panel was designed in about an hour (based on some initial measurements of the frame and LEDs) using Tinkercad, then after 3D printing and realising that nothing fit, slightly refined into what you see below:

This second print fit perfectly, so was primed using Rust-Oleum Surface Primer, expertly painted by Lucy using acrylics, then glued into the frame using Gorilla glue.

The next problem was housing the electronics. Thankfully Adafruit provide a really cool system for printing modular Feather cases, of which I used a tall variation, allowing the stacking headers on my Huzzah to fit.

Before attaching the board into the case with some bolts, I removed the plastic housing from the female ends of a couple of jumper wires (so they'd also fit in the case), and slipped them into the pins of the header, wrapped them around the internal case mounts (to help stop them being tugged out) and lead them out the hole in the side, ready to be attached to the button.

Wildcat is live (and angry)

I could have soldered the jumper wires to the pins, which I'm sure would make them more secure, but one of my guiding principles with this build was the ability to disassemble everything easily if I wanted to salvage any of the electronics.

I wanted the button to be hidden but easily accessible, so using two strips of copper tape and some glue, I attached it to the back of the left ear, soldering the contacts to one end of the strips and the jumper wires to the other.

Wildcat is live (and angry)

The final bit of assembly was sticking the lid from the case module to the back of the front panel. Due to the size of the LED matrix there was a small gap between them when dry fitted, but half a Command Strip either side not only filled this gap nicely, but will allow me to easily separate the two if I need to.

Wildcat is live (and angry)

And that's the build. I asked Apricat what she thought of the project, and think the look she gave me summed it up:

Wildcat is live (and angry)

In truth, she had calmed down a lot before I even started making this project, and I think she's truly feeling at home with us. So of course this project isn't designed for punishment, instead it's just a bit of fun and an excuse to build something, because we really love Apricat, and know that when she does bite us, it's not aggressive, but instead just her playful way of showing she loves us.

Wildcat is live (and angry)

This is the third post in the Wildcat saga, so if this is your first time reading this blog it might be worth catching up - to find out more about the antagonist of our story, start with Introducing Apricat, and to understand our approach to solving the problem (and one of the challenges I've encountered on the way), read Project Wildcat... has been delayed.

All caught up? Good. Because I'm happy to reveal that Wildcat is live.

Wildcat is live (and angry)

I spoke a little about the technical hardware and general software approach in my last post, so instead of rehashing that I'm simply going to supply a link to the git repo for the project which I'm hoping, combined with the diagram below, will be self explanatory:

Wildcat is live (and angry)

For this post I'm more interested in talking about the fabrication of the non-technical parts of the project, most of which were designed around a cat ear frame we found in HomeSense.

The front panel was designed in about an hour (based on some initial measurements of the frame and LEDs) using Tinkercad, then after 3D printing and realising that nothing fit, slightly refined into what you see below:

This second print fit perfectly, so was primed using Rust-Oleum Surface Primer, expertly painted by Lucy using acrylics, then glued into the frame using Gorilla glue.

The next problem was housing the electronics. Thankfully Adafruit provide a really cool system for printing modular Feather cases, of which I used a tall variation, allowing the stacking headers on my Huzzah to fit.

Before attaching the board into the case with some bolts, I removed the plastic housing from the female ends of a couple of jumper wires (so they'd also fit in the case), and slipped them into the pins of the header, wrapped them around the internal case mounts (to help stop them being tugged out) and lead them out the hole in the side, ready to be attached to the button.

Wildcat is live (and angry)

I could have soldered the jumper wires to the pins, which I'm sure would make them more secure, but one of my guiding principles with this build was the ability to disassemble everything easily if I wanted to salvage any of the electronics.

I wanted the button to be hidden but easily accessible, so using two strips of copper tape and some glue, I attached it to the back of the left ear, soldering the contacts to one end of the strips and the jumper wires to the other.

Wildcat is live (and angry)

The final bit of assembly was sticking the lid from the case module to the back of the front panel. Due to the size of the LED matrix there was a small gap between them when dry fitted, but half a Command Strip either side not only filled this gap nicely, but will allow me to easily separate the two if I need to.

Wildcat is live (and angry)

And that's the build. I asked Apricat what she thought of the project, and think the look she gave me summed it up:

Wildcat is live (and angry)

In truth, she had calmed down a lot before I even started making this project, and I think she's truly feeling at home with us. So of course this project isn't designed for punishment, instead it's just a bit of fun and an excuse to build something, because we really love Apricat, and know that when she does bite us, it's not aggressive, but instead just her playful way of showing she loves us.

Wildcat is live (and angry)

This is the third post in the Wildcat saga, so if this is your first time reading this blog it might be worth catching up - to find out more about the antagonist of our story, start with Introducing Apricat, and to understand our approach to solving the problem (and one of the challenges I've encountered on the way), read Project Wildcat... has been delayed.

All caught up? Good. Because I'm happy to reveal that Wildcat is live.

Wildcat is live (and angry)

I spoke a little about the technical hardware and general software approach in my last post, so instead of rehashing that I'm simply going to supply a link to the git repo for the project which I'm hoping, combined with the diagram below, will be self explanatory:

Wildcat is live (and angry)

For this post I'm more interested in talking about the fabrication of the non-technical parts of the project, most of which were designed around a cat ear frame we found in HomeSense.

The front panel was designed in about an hour (based on some initial measurements of the frame and LEDs) using Tinkercad, then after 3D printing and realising that nothing fit, slightly refined into what you see below:

This second print fit perfectly, so was primed using Rust-Oleum Surface Primer, expertly painted by Lucy using acrylics, then glued into the frame using Gorilla glue.

The next problem was housing the electronics. Thankfully Adafruit provide a really cool system for printing modular Feather cases, of which I used a tall variation, allowing the stacking headers on my Huzzah to fit.

Before attaching the board into the case with some bolts, I removed the plastic housing from the female ends of a couple of jumper wires (so they'd also fit in the case), and slipped them into the pins of the header, wrapped them around the internal case mounts (to help stop them being tugged out) and lead them out the hole in the side, ready to be attached to the button.

Wildcat is live (and angry)

I could have soldered the jumper wires to the pins, which I'm sure would make them more secure, but one of my guiding principles with this build was the ability to disassemble everything easily if I wanted to salvage any of the electronics.

I wanted the button to be hidden but easily accessible, so using two strips of copper tape and some glue, I attached it to the back of the left ear, soldering the contacts to one end of the strips and the jumper wires to the other.

Wildcat is live (and angry)

The final bit of assembly was sticking the lid from the case module to the back of the front panel. Due to the size of the LED matrix there was a small gap between them when dry fitted, but half a Command Strip either side not only filled this gap nicely, but will allow me to easily separate the two if I need to.

Wildcat is live (and angry)

And that's the build. I asked Apricat what she thought of the project, and think the look she gave me summed it up:

Wildcat is live (and angry)

In truth, she had calmed down a lot before I even started making this project, and I think she's truly feeling at home with us. So of course this project isn't designed for punishment, instead it's just a bit of fun and an excuse to build something, because we really love Apricat, and know that when she does bite us, it's not aggressive, but instead just her playful way of showing she loves us.

November 16, 2018

A little challenge by Graham Lee

A little challenge today: create a JS function that turns its arguments into a list of pairs. Actually, the brief was “using Ramda” but I ended up not doing that:

function basePairwise(xs) {
  if (xs.length == 0) return [];
  if (xs.length == 1) return [[xs[0], undefined]];
  return [[xs[0], xs[1]]].concat(basePairwise(xs.slice(2)));
}

function pairwise(...xs) {
  return basePairwise(xs);
}

One of the nice things about JavaScript (I won’t say that often, so note the date) is the introspective nature: the fact that I get to just look at the way a function was called, rather than saying “you must use exactly these types and this arity always”. Here, I’ve done that with the JS spread operator: I could have used the arguments pseudo-list for only a little more work.

Reading List by Bruce Lawson (@brucel)

A (usually) weekly round-up of interesting links I’ve tweeted. Sponsored by Smashing Magazine who slip banknotes into my underwear so I can spend time reading stuff.

November 13, 2018

I already wrote about the Ultimate Programmer Super Stack, a huge bundle of books and courses on a range of technologies: Python, JS, Ruby, Java, HTML, node, Aurelia… and APPropriate Behaviour, my book on everything that goes into being a programmer that isn’t programming.

Today is the last day of the bundle. Check it out here, it won’t be available for long.

November 12, 2018

I was on a “Leadership in Architecture” panel organised by RP International recently, and was asked about problems we face using new techniques like Microservices, serverless and machine learning in the financial technology sector. The biggest blocker I see is the RFP (Request for Proposals), RFI (Request for Information), the MSA (Master Service Agreement), any document with a three-letter acronym. We would do better if they disappeared.

I’m fully paid up in my tithe to the church of “customer collaboration over contract negotiation”, and I believe that this needs to extend beyond the company boundary. If we’re going to spend a few months going back and forth over waving our certifications about, deciding who gets to contact whom within what time, and whether the question they asked constitutes a “bug report” or a “feature request”, then I don’t think it matters whether the development team use two-week sprints or not. We’ve already lost.

We’ve lost because we know that the interactions between the people involved are going to be restricted to the terms agreed during that negotiation. No longer are people concerned about whether the thing we’re making is valuable; they’re concerned with making sure their professional indemnity insurance is up to date before sending an email to the DRI (Definitely Responsibility-free Inbox).

We’ve lost because we had a team sitting on its hands during the negotiation, and used that time “productively” by designing the product, putting epics and stories in a backlog, grooming that backlog, making wireframes, and all of those other things that aren’t working software.

We’ve lost because each incompatibility between the expectation and our intention is a chance to put even more contract negotiation in place, instead of getting on with making the working software. When your RFI asks which firewall ports you need to open into your DMZ, and our answer is none because the software runs outside of your network on a cloud platform, we’re not going to get into discussions of continuous delivery and whether we both read the Phoenix Project. We’re going to get into discussions of whether I personally will warrant against Amazon outages. But here’s the thing: we don’t need the software to be 100% up yet, we don’t even know whether it’s useful yet.

Here’s an alternative.

  1. We, collectively, notice that the software we make solves the problem you have.
  2. We, collectively, agree that you can use the software we have now for a couple of weeks.
  3. We, collectively, discuss the things that would make the software better at solving the problem.
  4. We, collectively, get those things done.
  5. We, collectively, GO TO 2.

Notice that you may have to pay for steps 2-4.

Back to Top