Category Archives: software

Giving a shit

Sturgeon’s law states that “90% of everything is crap”. He was probably an optimist. Here are some recent examples of the sort of crap I come across day to day:

The school selection website

My wife and I had to select which secondary school we want out son to go to, an important decision for our family. We had to do this via a website created on behalf of Swindon council. I won’t bore you with all the painful details, but only an impressive combination of incompetence and apathy could have produced something so egregiously awful. At the end of the process we got an error message and the promised confirmation email never arrived. We were left feeling confused and angry. Every other parent we spoke to had a similar experience.

The ATM

Feast your eyes on my local ATM:

ctnybk8wiaaqkza-jpg-large

Yes, that’s right, the buttons aren’t correctly aligned with the screen, so they have added some shonky visual cues in a feeble attempt to compensate for it. They failed – I have pressed the wrong button more than once. If they couldn’t move the buttons, why didn’t they just change the text positions in the software? I would like to know what sort of horrific set of bad decisions and sloppy planning led to this laughably bad design.

The in-flight meal

Check out this British Airways in-flight meal I was served:

IMG_1083.jpg

Behold, the cutlery is in a sealed plastic bag in the pasta. To get at your cutlery you have to open a slippery plastic bag covered in sauce with your fingers, which are now also covered in sauce. Who could have possibly have thought this was a good experience? You might as well just eat the pasta with your fingers. Or stick your face in the plate. Maybe the subliminal message is: if you won’t pay for business class we are going to make you eat like an animal.


You don’t have to look very hard to find crappy design. Badly designed parking buildings, confusing ticket machines, painful to use Sat Navs, packaging that is almost impossible to open, web forms that won’t let you use a space or a dash in a telephone number. I could go on, but I’m sure you could come up with plenty of examples from your own life. The most frustrating thing is that these issues could have been avoided with a little bit of thought and care. I doubt it would have added more than an extra 1% more effort or cost to get them right.

Crappy products and services make everyone’s life worse. Hold yourself to a higher standard. Take pride in your work. Do usability tests. Get feedback from your users. Fix things that are broken. Keep improving. Above all, give a shit.

sales sites and bundles

Promoting your software through 1-day sales and bundles

Hyper Plan, my visual planning software for Windows and Mac, has now been for sale for a bit less than 2 years. Given that I am (by choice) doing all the development, marketing and support for both Hyper Plan and my other product, PerfectTablePlan, I have had a limited amount of time to promote Hyper Plan. But Hyper Plan is in a  competitive market, where it is hard to get noticed using traditional promotional techniques such as SEO and PPC. So I have been experimenting with promotion via 1-day sales sites and bundles.

I did several promotions through both bitsdujour.com and macupdate.com promo. These were 50%-off sales for 1 day (sometimes extended for another day). The site takes 50% commission on the sale, so I only got $10 of my normal $40 ticket price. But I also got exposure to a whole new audience I wouldn’t normally reach.

I also included Hyper Plan in bundlehunt.com and macupdate.com software bundles. In these bundles customers purchased some 10 items of software at a big discount. The promotions lasted for a few weeks each. I am not at liberty to divulge how much I got for each licence, but a quick calculation based on the price of the bundles and the number of items in the bundle tells you that it was a lot less than $10!

My hopes related to sales sites and bundles were:

  1. A worthwhile amount additional sales revenue.
  2. Increased feedback, giving me more insight for improving the product.
  3. Making money further down the line from major upgrades (e.g. v1 to v2).
  4. That I wouldn’t be swamped in support emails from people who were paying me a lot less than the standard price.
  5. More word-of-mouth sales after the discount has finished.

On analysing the results, the first 4 turned out to be true.

I had previously tried promoting my PerfectTablePlan table planning software on bitsdujour.com, but the results were disappointing. It just wasn’t a good match for their audience. However Hyper Plan is a more general tool and it did a lot better. The bundles also sold in impressive volumes. The source of Hyper Plan sales revenues to date after commission (but not including upgrades) is show below.

sales-revenue-source

So the extra sales were certainly significant from a revenue point of view, bearing in mind that Hyper Plan is a relatively young and unknown product.

I also got some very useful feedback from the bitsdujour comments section.

I released v2 of Hyper Plan in March 2016. I have crunched the numbers to see how many v1 customers to date have paid for upgrades to v2.

percentage upgrades

I expected that the 1-day sale customers who had paid $20 for the initial licence would be less likely to pay $16 to upgrade to v2 than those who had hadn’t purchased at a heavy discount. I was surprised that the opposite turned out to be true. I don’t have a good theory why.

I don’t have any figures for bundle customer upgrades, as the bundles happened after v2 was released. Given that bundle purchasers probably only wanted a subset of the software in the bundle, I expect the upgrade percentages to be a lot lower than above.

I wasn’t swamped in support emails. In fact things were surprisingly quiet during the bundles, which makes me wonder how many people who purchased the bundle were interested in Hyper Plan.

There were no sustained jumps in traffic or sales after the 1-day sales or bundles ended.

Best of all, the 1-day sales and bundles don’t cost anything, apart from a modest amount of time to set-up.

I know some vendors promote these 1-day sales and bundles to existing customers. But I don’t understand why you would do that. The whole point of these channels is to reach new audiences. Also you risk annoying customers who have paid list price. If you already have an audience you can promote a sale to, then you don’t need 1-day sales sites or bundles. Just email them a discount voucher.

I had one complaint from an existing customer on a forum who had paid full price and then saw Hyper Plan in a 1-day sale. I offered to refund the difference back to them, but they didn’t take me up on it.

In conclusion, the sales and bundle sites brought in useful spikes of additional sales (especially when you include upgrades later on) and feedback, without a big jump in support burden. But they didn’t lead to a noticeable long-term increase in traffic or sales. Obviously every product is different. But if you have a product that needs exposure, isn’t too niche and doesn’t require a lot of support, it may be worth giving 1-day sales and bundles a try.

costa-rica-nikon-957

Google CPA bidding goes wild

I have been using Google’s AdWords Cost Per Action (CPA) bidding for a number of years. I set the maximum I was prepared to pay for a conversion  (e.g. a successful install of my software). AdWords then set the bid price to try and get me conversions at that price or less. It worked pretty well for a number years and it saved me a lot of time tweaking bid prices. But Google recently phased out Maximum CPA bidding and forced me to switch to Target CPA bidding. From this point I could only specify the average price I was prepared to pay per conversion. This is where it all started to go wrong.

AdWords started to bid crazy prices. Check out the screenshot below. You can see that in each case the average Cost Per Click (CPC) is more than the CPA price. For example, in the first row I have set £0.50 as the price I am prepared to pay for conversions from the ‘seating charts’ ad group. Typically about 10% of people who click on one of my Adwords ads will install the software and trigger a conversion (which is fairly standard). So a £0.50 CPA means that AdWords should be bidding somewhere around £0.05 per click. Google knows this, because they have vast amounts of data from my AdWords account (11 years worth). But the average price for the last 3 clicks was £1.17 per click. WTF Google – that’s my money!

Given that the base version of my software costs £19.95 (one time fee) there is no way I can make a profit at £1.17 per click. Not all the bids are this crazy. But there are enough crazy bids to put my whole AdWords campaign into a tailspin. So I have been forced to switch back to manual CPC bidding. If you have also been forced to switch from Maximum CPA to Target CPA bidding, then I suggest you keep a careful eye on your cost per click.

Costa Rica Nikon 135

How to make difficult decisions

When you run a business (even a small business like mine) you have to make a lot of decisions. Many of these decisions are complicated and have to be taken with incomplete information. But you can’t take too long over them, or you will never get anything done. Here are 3 techniques I use to help with difficult decisions.

Break it down

This is a very simple method for breaking a difficult decision down into smaller parts using a spreadsheet.

  • Decide the criteria that are important for the decision. Add a row for each.
  • Add a weighting column. Assign each criteria a weighting in the range 1 to 10, depending on its relative importance to you.
  • Add a column for each option you are considering.
  • Set each criterion/option cell a value in the range 0 to 10, depending on the extent to which the choice for that column fulfils the criteria for that row.
  • Calculate the weighted sum for each column.
  • Choose the outcome with the highest weighted sum.

Here is an example for choosing between 3 different types of hosting:

making difficult decisions

It’s not particularly scientific, but it does force you to systematically break down the problem into smaller parts and justify your decision.

Take the long view

It sometimes helps to stand back and look at the bigger picture. I can think of no better way to do that than to ask a hypothetical (hopefully elderly) future me, lying on my deathbed, which option they approve of. For example, given the choice between adding an innovative new feature to my product or improving the conversion funnel by a few percent, I think future me would be happier that I chose to add the innovative new feature. It is also a useful reminder that many decisions probably aren’t all that important in the grand scheme of things.

Flip a coin

Sometimes you need to make a decision, but you don’t have enough information or the time taken to get that information is going to cost you more than making the wrong decision. In that case, don’t agonise over it. Just roll a dice or flip a coin and move on.

Hammer For Mac static website generator

I prefer static websites to a CMS for simple product websites because:

  • Static websites are fast.
  • I have more low-level control over the HTML/CSS.
  • I don’t have to worry about the very-real threat of a CMS being hacked.

Obviously writing every page separately in raw HTML/CSS would go against one of the cardinal rules of development, Don’t Repeat Yourself. But you can avoid this using a static website generator such as Hammer for Mac.

hammer

Hammer uses a simple syntax embedded in HTML comments to ‘compile’ a website from source files. I have now used Hammer to create several static HTML/CSS websites, including my perfecttableplan.com and hyperplan.com websites.

I like the simple syntax of Hammer. For example:

I can put the HTML for a page header in an _header.html file and then each page just needs to start with:

<!-- @include _header.html -->

I can define and use variables:

<!-- $current_year 2016 -->
..
<p>Copyright <!-- $current_year -->.</p>

And I can let Hammer work out relative paths:

<img src="@path image.png" />

If Hammer can’t make sense of a source file (e.g. it can’t find the image file), it generates a compilation error.

Because everything is text based I can easily manage all the source in a version control system. Also, if I have to move away from Hammer, it should be relatively straightforward to change the syntax to another static generator (or even write a replacement for Hammer!).

Overall I like Hammer. But it does have a number of shortcomings:

1. The user interface is very limited. Hammer shows you a list of source files and you can click on a source file to see the compiled version or edit the source. But the source files are listed in the order they were edited and you can’t filter or sort the list. This seems such a simple and basic feature, that I can’t understand why the developers have omitted it.

2. Hammer takes a dumb, brute force approach to compilation. If you change any file in a source folder, it recompiles *everything*, without checking if other source files include that file. This is a pain if you have 100+ source files. Surely it wouldn’t be that hard to work out which files depend on which and only recompile the files that need recompiling?

3. You can’t nest variables. For example you can’t do this:

<!-- $current_year 2016 -->
<!-- $copyright_message Copyright <!-- $current_year --> -->

This might sound minor. But it limits the expressiveness of variables significantly.

4. The vendor doesn’t do email support. If you want to communicate with them you have to use Slack or Twitter. I am old fashioned, I like email.

5. It only runs on Mac OS X (the clue is in the name).

At one point Hammer looked like abandonware, but owner riothq.com sold it to beach.io and active development has resumed.

Currently Hammer is priced at £15.39 (and presumably some round number of US dollars). That seems way too cheap. I wish they would price it a bit higher and fix some of the issues above.

 

nam_2003_8_14 rock carvings

Updating the PerfectTablePlan website

I created the website for PerfectTablePlan back in 2005, using a dreadfully buggy piece of software called NetObjects Fusion (NOF). The sorry story of why I ended up using NOF is told here.

Until recently the front page looked like this.

old-website-design

I had done a fair amount of A/B test tweaking and it converted visitors to downloads and sales relatively well compared to other downloadable product websites. But it had that ‘designed by a programmer’ look and it wasn’t responsive, so it didn’t work on well on mobile devices. My software only runs on Windows and Mac, but I still want to appear in mobile searches. The HTML generated by NOF was also pretty horrible. Frankly, I was a bit embarrassed by it when I looked at websites for other products. I kept on meaning to update it, but there was always something more urgent or (to be honest) more interesting to do. I finally bit the bullet and had it redesigned in 2015. The front page now looks like this:

new-website-design

The process was:

  1. I wrote a specification for the new design.
  2. I ran a 99Designs.com competition to design a new home page based on the spec.
  3. I selected the winning designer and paid them to design 3 additional pages in the same style.
  4. I paid pixelcrayons.com to code up the 4 pages in responsive CSS/HTML.
  5. I poured all the old content into the new design. Being careful to maintain the existing page names, titles, text and images etc, so as not to lose existing organic traffic.

The whole process didn’t cost a great deal (somewhere around $2k), but it took quite a lot of my time, spread over 5 months. Especially the final step. This wasn’t helped by the size (some 128 pages were converted) and general cruftiness of the old website, and my lack of knowledge of CSS and responsive design.

I didn’t want to be locked in to a CMS, so I used Mac static website generator Hammer4Mac to generate the HTML. It goes without saying that I wrote a program to help me pull all the content out of the old website and into Hammer4Mac! While Hammer4Mac isn’t without flaws, I found it a vast improvement over NOF and the new website is now much easier to update and maintain than the old one.

The new website went live on 16-Dec-2015.

So how much difference did the redesign make? Here are the changes based on comparing 25 weeks of data before the change and 25 weeks of data after the change:

bounce rate +1.5%
time on page +16.0%
traffic +6.5%
        desktop traffic -2.2%
        mobile & tablet traffic +40.0%
completed installs +1.4%
sales transactions +11.4%
total sales value +21.8%
visit to sale conversion ratio +4.6%
average order value +9.4%

The increase in mobile traffic as a proportion of total traffic is pretty clear from analytics (the dip in December is seasonal):

traffic

I believe  a 21.8% improvement in sales is a lot more than I would have got by spending the same amount of time and money improving the product itself, which is pretty mature after 11 years of work.

Overall it looks pretty positive. But, as analytics data is fairly dirty (e.g. due to analytics spam) and I didn’t run a split test, I can’t definitely say that the changes above were due to the website changes. I wasn’t able to compare all the above data with the same time period for the previous year due to some missing analytics data. But the sales data for 25 weeks before and after 16-Dec in the previous year was:

sales transactions -9.9%
total sales value -2.7%
average order value +8.1%

Which implies that the sales changes are unlikely to be due to seasonal factors.

Best of all, I never have to use NetObjects Fusion again!

format

Pretty printing C++ with Clang-Format

I use some of the code generation and refactoring tools in QtCreator. These save a lot of time, but they don’t format C++ code how I like it. For example they produce C++ code like this:

void MyClass::foo(int *x)

But I like my code formatted like this:

void MyClass::foo( int* x )

The differences may seem minor, but they are a source of significant irritation to me. I like my code how I like it, goddammit! And consistent formatting enhances readability. However re-formatting it by hand is time-consuming and tedious.

What I need is a tool that can enforce consistent formatting in the style that I like, or something close. I have tried to use automatic C++ formatting (pretty printing) tools in the past, but I couldn’t get them to produce a format that was close enough to what I wanted. But I have finally found the tool for the job. Clang-Format.

Clang-Format is part of the LLVM family of tools. It is a free, command-line tool that reformats C++, Objective-C or C according to the settings in a config file. As with many free tools, it isn’t terribly well documented. Some of the documentation on the web is out of date and some of it is incomplete. But I have managed to find out enough to configure it how I like it.

To run it you just need to place your options in a .clang-format file, make sure the clang-format executable is in the path and then run it:

clang-format.exe -i -style=file <C++ file>

Here are the settings I am currently using in my .clang-format file:

Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
  AfterClass:      true
  AfterControlStatement: true
  AfterEnum:       true
  AfterFunction:   true
  AfterNamespace:  true
  AfterObjCDeclaration: true
  AfterStruct:     true
  AfterUnion:      false
  BeforeCatch:     true
  BeforeElse:      true
  IndentBraces:    false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Allman
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
ColumnLimit: 0
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 0
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IndentCaseLabels: true
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
PenaltyBreakBeforeFirstCallParameter: 100
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 10000
PointerAlignment: Left
ReflowComments: true
SortIncludes: false
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: true
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: true
SpacesInParentheses: true
SpacesInSquareBrackets: true
Standard: Cpp11
TabWidth: 4
UseTab: Never

It took me a few hours of fiddling with the settings to find the best combination. It would be really useful if someone could write a tool that would analyze your C++ code and create a .clang-format file for you. You would probably only want to do this once though, so I don’t think it has much potential as a commercial product.

There are only two things I couldn’t get quite right in the formatting:

  1. I couldn’t get it to add a blank line after public, protected and private declarations. I fixed this with a quick Perl hack (see below).
  2. I couldn’t get it to indent continuation lines how I would like (ideally indented 1 or 2 spaces from the first line). It is a small price to pay and I am just putting up with it for now.

Perhaps there are options to do these and I just didn’t find them.

Here is the Windows .bat script I used to format all the C++ files in a folder.

for %%f in (*.h *.cpp *.inl) do (
clang-format.exe -i -style=file %%f
)

for %%f in (*.h) do (
clang-format.exe -i -style=file %%f
perl -p -i.bak -e "s/public:/public:\n/g" %%f
perl -p -i.bak -e "s/protected:/protected:\n/g" %%f
perl -p -i.bak -e "s/private:/private:\n/g" %%f
perl -p -i.bak -e "s/    Q_OBJECT/Q_OBJECT/g" %%f
)

del *.bak
del *.tmp

No doubt there is a more elegant way to do the Perl, but it works.

I now just run this batch periodically to keep my code beautiful and consistent.