Archive | Uncategorized RSS feed for this section

98, 99, 100!

Nice little milestone: Bingo Card Creator just crossed the 100th copy sold in February, for the first time.  The previous record was 93 back in October.

It is also fast approaching a much more consequential milestone, but more on that later.

Results of Native Compilation vs. Java Split Test

For the last month I’ve been testing a version of Bingo Card Creator compiled with Excelsior JET versus the standard Java one.  Half of all Windows downloaders have gotten one, half got the other.  I then have tallied when they confirm an installation (i.e. access my website through the application — for example by checking for updates or looking at the purchase page) and purchase the software.  

This is accomplished via a really simple expedient — Bingo Card Creator has a properties file in it, which contains all the strings for the interface like you would expect.  It also contains strings for the version number and site the trial was downloaded from, which I repurposed for the purpose of this split test (since I only track bingocardcreator.com versus “all the download sites” at present anyhow).  

So if you click “Purchase now” from version 2.51 of the Java version of the program after getting hit with the print quota limit, you end up accessing 

http://www.bingocardcreator.com/purchasing.htm?source=trial&version=2.51&site=bingocardcreator&button=printquota

At which point Google Analytics springs into action, uses some very simple logic to parse the query string, and cookies you up with that information.  If you purchase within the next 30 days, the cookie is passed in when you hit the order acknowledgement page and scored as a conversion.  There is a custom segment in Google Analytics devoted to both the JET-compiled and native versions of BCC 2.51.

Anyhow: in the last 30 days I have had 118 sales of Bingo Card Creator.  (Wow, that number shocks me.)  Google Analytics has racked up 116 conversions, meaning they caught the access of the confirmation page on almost all transactions.  Of these 116 conversions, 75 of them were cookied up with a cookie indicating they were positively part of this split test.  (You could easily have participated without getting cookied — for example, if you decided to buy the software and then opened up a browser and Googled [Bingo Card Creator], I would have no way of knowing which executable you had downloaded.)

Of the 75 purchases, 44 were for the JET version and 31 were for the native Java compiled version.  So what’s that mean?  OK, back to Stats 102: if we assume hypothetically that it doesn’t matter which version you were using, we would expect that 50% of the total number of conversions would turn out each way.  However, just like flipping a coin twice doesn’t automatically mean you get one head and one tail, it won’t necessarily be exactly 37.5 sales of each version.  (One would hope not, right?  I’d hate to support the half-and-half.)  

The probability of each possible outcome on the 0 purchases for JET through 75 purchases through JET continuum is given by the binomial distribution.  There is this notion of cumulative probability — given the assumption of 50/50 fairness between the two versions, the probability that any particular result is like to be random is equal to the sum of the probability of that result and all results less extreme than it.  

Plugging and chugging with a binomial probability calculator, we arrive at the result that, if the versions were fair, in only 8% of all samples of 75 sales would we find 44 or more sales for JET.  Accordingly, we conclude that JET is helping sales, by some amount which the binomial probability test is not quite sensitive enough to determine.

Which is good enough for me.  One niggle: I discovered that for reasons beyond my ken, the JET version cannot save to the program directory on Vista, whereas the Java version can.  I probably should have listened to the advice a year and change ago when people said I should revisit the choice of home directories.  (Vista prevents programs from writing to subdirectories of Program Files to prevent bad behavior.  However, it emulates writing to Program Files to avoid breaking legacy software, and that emulation is sufficient for BCC Java but apparently not good enough for BCC JET).  Ah, we live and we learn.  

After I patch that little issue, the JET compiled version of BCC is going to become the default version for all Windows users, and I will keep the Java version around only for support purposes, and to upgrade folks who already have one installed.

Much thanks to Dmitry at Excelsior, who donated a copy of JET to make this experiment possible.

Massive Update To Stats Tracking

Well, after a few hours of work I have revamped the way BCC presents its public stats.  You can now see everything from one single, easy location:  http://www.bingocardcreator.com/stats

Part of what I’ve been working on recently is taxes for 2008.  This required actually paging through and entering my expenses (oh, did I mention it tracks expenses now?), which is going to result in a bit of an earnings restatement for 2008.  I think I have everything but one stray freelancing invoice accounted for now.

Sales for 2008 (less returns): $21,116.65

Expenses for 2008 (excludes taxes): $11,782.62

Profit: $9334

You can see the detailed breakdown here — the big green slice is profit (~45% — a bit lower than I expected).  If you just want to see the relative expense breakdown that is available, too.  Unsurpisingly, my number one cost is advertising — the overwhelming majority of it is Google AdWords but I also paid much smaller amounts Microsoft, Stumbleupon, and a few directories. 

Since I’m using this to generate taxes for my business I included some things for my non-BCC projects which I intend to productize eventually but haven’t gotten around to yet.  Incidentally, expenses before 2008 aren’t totally entered yet, take that data with a grain of salt.  I don’t have easy access to all my old 2006/2007 credit card statements, and don’t even get me started about Paypal.

Ninety. Four. Percent. "()$#(")

The results from the shopping cart redesign are in.

Short version: Conversions increased by 94%.  I’m pretty flabbergasted.

Someday, someday…

… I will learn to not, under any circumstances, commit any code to the trunk which is not ready for immediate deployment.

Because when I do, I inevitably do “just a quick deploy to fix up that unrelated mistake” and then, boom, the lightbox on the front page silently fails for three days.

SIGH.

On the plus side, I once again have experimental confirmation that functional lightboxes beat the stuffing out of direct links to images!

Sales Up Massively, My Guesses As To Why

I have dumb-as-rocks logic on my dashboard that straight-line predicts sales out to the end of the month.  Currently, its suggesting I’m likely to have $3,000+ sales in February.  What is scary is that number is increasing every day — i.e. the projection keeps going up because the last day’s sales beat the straight-line projection.  (Or, in some cases, shattered it.  Today was my best day ever.)

What’s doing it?  Well, its a witches brew:

1)  Early indications are that the new cart that I was so excited about kicks royal buttocks.  There is an A/B test running at the moment.  Suffice it to say that if I told you the improvement I am seeing you would not believe me.  I’m not even sure I believe me.  The results are not statistically bulletproof yet and, against all my instincts to cry it from the rooftops, I’m going to wait until they are to show off.

2)  I am having good results from a really simple change to my Check for Updates page, which is seen by a large portion of trial downloaders.  The basic idea is simple: as long as I have you on my webpage because you’ve demonstrated that you care about having the latest and greatest, why don’t I sell you on the benefits of getting the latest and greatest forever?

3)  I’m having fairly decent results with the testing of the version of the software packaged with Excelsior JET versus the stock Launch4j wrapped executable.  It isn’t quite the murderously one-sided contest that the shopping cart appears to be, but hey, improvements are improvements.  I’ll wait until the test is over to unveil the results, although I gave an interim update here for those interested. 

4)  I made some changes to BCC 2.51 to make it more usable and, at the same time, make it sell better.  One alteration which might slip the notice of programmers was to the UI.  Can you find the change between these two screenshots?

Old version:

 

New version:

Give up?  Click on the second image and you’ll be taken to the annotated version, with the two important bits called out in red.  Or you could highlight the following text: [The number one reason to buy my software is to get randomly scrambled bingo cards.  Despite the fact that I hammer away at this on my website, many people don’t actually know that the program does this.  I get asked sometimes “How do I scramble the cards?”, which indicates that the whole Sample Cart element was an epic failure at comprehensibility.  Hence the clarification by it.  Similarly, users perceive a need to get unique bingo cards.  There are 24! bingo cards possible from the smallest possible word list.  That is 620 septillion bingo cards.  But users are worried that if they print some insanely big number, like twenty, they will get a repeat.]

Incidentally: if there is an exceptionally nice person out there who could reproduce the first image for me on a machine that has Windows XP on it, I would be very obliged.  Just open any of the Language Arts -> Reading -> Dolch Sight Words lists, and show the program with the word list opened and scrolled down, as that image does.   Thank you, Chris.

5)  BCC 2.51 includes a “soft” timed trial mechanic.  Here is how it works: the user gets to use the software for forever, as they always have been.  The software prompts to be updated once every 15 days, as it has for quite some time.  If a user says they want an update, the software then displays the following dialog after popping the website: 

Yes, that spelling mistake is in the original.  Sigh.  Just noticed it as I was grabbing this screen shot.  I’ll fix it tomorrow.  Anyhow, the idea here is that while nagging first time users of the application would be a little gauche, someone who has used the application for 15, 30, 45, etc days is clearly happy with it and just needs a bit of a nudge over the finish line.  So I offer them an incentive for registration.  

The nice thing about this one is it sounds like “getting something extra” rather than “getting something which was taken away from you”, like the ability to print 16+ cards or the ability to save, both of which are disabled in the free trial.  The upsell screens that pop up when those are triggered still account for the lion’s share of sales from the app, though.

Alright, that’s enough writing for one day.  I’ll keep you aprised as the month moves on.

Big Writeup About The New Cart

I wrote up approximately everything I know about shopping carts, plus everything I learned from my recent experience rewriting one, and made a proper article about it.  It ginormous.  It is also probably one of the best things I have ever written regarding my uISV, so if the topic interests you, go have a gander.

It includes a bunch of high level theorizing, some stats from BCC, and more code than you can shake a stick at.  (I released the whole cart into the public domain.)

Why put it on my site rather than the blog?  Well, it uses live data and integrates directly into the site, for one thing.  For another, I’m kind of hoping folks will say “Ooh, that is some wonderful stuff” and link to it.

iBox Overlay Doesn't Scroll

Hello, Google searcher!  I spent 2 hours so you don’t have to!

Search for the following line of code: 

els.overlay.style.height = height + ‘px';

Now add this after it.  Problem solved!

      //causes the overlay to scroll as the page scrolls — necessary for Safari/Chrome/FF3

      if (document.viewport && document.viewport.getScrollOffsets()) {

        var top = document.viewport.getScrollOffsets()[1];

        els.overlay.style.top = top + “px”;

      }

OK, back to regular readers of this blog: as mentioned previously, I’m testing a new shopping cart.  There were previously 3 known issues:

  1. the overlay didn’t scroll
  2. the price got all funky in Google Checkout under some conditions
  3. the quantity and price were inconsistent if you switched the item after closing the cart

I’m happy to report:

  1. I patched iBox to avoid this issue, and tested it in five browsers because I just have no life whatsoever.  Please see above code if you need it.
  2. e-junkie continued their years-long practice of above-and-beyond support and corrected my misunderstanding of their API, which let me patch my code around this
  3. I patched my code, in a ho-hum workmanlike fashion.

The more I use Javascript the more I feel that a) all websites I’ve ever used are missing massive opportunities to make their user interaction sexier than they can possibly imagine and b) I can understand why, because coding Javascript is the most painful programming I’ve done since C in college.  

Oh, God, the cross-browser issues!  The sheer complexity of the DOM model!  The paucity of good documentation available in my IDE next to autocomplete!  (Sorry, I will always be a Java programmer at heart.)

Anyhow, if you want to take a gander at the current version of the sample cart or compare it to the current cart, go nuts.  After I alter it a bit tomorrow to make the error handling sexier (i.e. for the disallowed multiple purchase through Google — it has never happened before but, eh, why not ship it right the first time), I am going to start the split test.

Finished My Mini-Development Project, Mostly

Yesterday I mentioned that I would be making a new shopping cart.  

I’ll be blogging about this much more extensively later, but after pouring 8 hours into the massive black hole of time that is Javascript (aaaaaaaahhhhh I hate you so), I got the new and improved cart working.  It isn’t quite user-ready yet and isn’t anywhere NEAR where I would consider releasing it as code for other uISVs, but you can go play around with it to get the general feel.

Known bug: e-junkie seems to have an issue when you override a price for an item and use a Google Checkout Buy It Now button.  I use this feature to move the pricing logic from the e-junkie servers to my Javascript, where it gets “bugs in your teeth fast” speed improvements.  I will probably delay releasing this until e-junkie fixes that issue or I decide to work around it with a business rule modification.

Known bug #2: If you pick a non-one number in the cart, then close it, then reopen it, your total is calculated incorrectly until you do at least one keypress in the quantity field.  I know what is causing this and will squash it fairly soon, but just feel like “I’m done for the day”.

Old cart, for comparison: Bingo Card Creator purchasing page.

New cart: http://www.bingocardcreator.com/purchasing-alternate.htm

How I feel:

  1. The new cart is bugs in your teeth fast for loading.  Mission accomplished.  Currently it takes the same amount of time when you click Checkout as the current cart does, which needs to get disguised a bit better.
  2.  Try adding a CD to your cart in both and tell me which you like better.  I think this is going to be worth significant money for me.
  3. In general, I think the user interaction simplifies markedly.  The new lightbox-esque effect, provided by iBox (a wonderful piece of software with some significant teething issues I’ll talk about later) makes the “Continue Shopping” button redundant.  Gone.  Because I no longer incur an AJAX roundtrip to another server every time the user does anything, I don’t need to tie their updates to the Update Cart button, hence it is gone.  
  4. I sort of like being able to customize the branding a little bit.  For example, while you and I know this is a shopping cart, I think that whole metaphor just confuses users.  Gone.  Instead, slap in logo and text.

Let me know what you think.  After I’ve sanded down the few issues I’m going to start the A/B test and then start packaging this so that other folks can use it.  Expect a very long “making of” post as well — I actually got to solve some fun technical issues for a change, so I’ll tell folks how I did it.

Inno Setup + Excelsior JET = Slice MBs Off Download

If you’ve been following the blog recently you know I’m running a split test on a self-contained executable (made with Excelsior JET) versus my standard wrapped JAR (made with Launch4j, requires Java installed).  The idea is to see whether the tradeoff of vastly increased download size of the native version makes up for eliminating the Java dependency.  Launch4j will prompt people to download Java if they don’t have a sufficient version installed, but that is one of those decision points where people might stop using the app.

Previously, the approximate size difference was 13 MB versus about 1 MB.  However, with a little help from Dmitry over at Excelsior, I was able to shave 4.5 MB off of the installer for the native version.  Here’s what I did:

1)  Used the detached package option, described at “Java Runtime Slim-Down” in the User’s Guide. 

2)  I removed all of the packages which were given the green light to remove — this included Cobra, Management, XML, and all that enterprise-y cruft for my application.  Packages which get the green light are always safe to nix.

3)  Then I made a judgement call about packages which got the red light.  Red light means they’re referenced in some code included in your program but, importantly, if they’re never actually loaded you’re in the clear.  I was pretty sure I could nix the JSound and RMI packages, as I don’t use either and I have a very good idea of what my 3rd party libraries needed (certainly not access to the sound card).  

The JET packager thing gives you a test option so that you can actually run through your program and see if you end up needing the detached packages.  If you do, they’re downloaded at need from your website (you get to upload them yourself).  I would strongly prefer avoiding that, so I stepped through all my functionality to make sure it didn’t fire a download.

4)  I used the “deploy as a self-contained folder” option, which let me copy/paste BingoCardCreator.exe and the rt/ folder produced by JET and move them into my folder for InnoSetup to take a stab at.

5)  I used the same InnoSetup script I use for the regular (Java-using version), making sure to modify it so that the rt/ directory was included in the installer and removed by the uninstaller.  This worked fine, functionally, but 13 MBs is a lot.

6)  Dmitry got in touch with me and told me that they have a tool which compresses a particular JAR file that the JET deployment comes with, much much more efficiently than the ZIP algorithm can compress it.  So if you fire that tool once on your system, and then once at install time (to uncompress it), you can save quite a bit of space.  So I packed up the JAR on my system, and then edited my InnoSetup script to call the unpacker right before exiting setup.  Easy peasy.  I can barely tell the difference in install times, but slimming the download 4 MB is easily worth it.

 

How To Pack The Jar (assuming you detached packages): 

cd C:\some\path\to\distribution\directory\rt\lib

c:\jet\directory\goes\here\profile{use tab complete}\jre\bin\pack200 -g rt-0.jar.pack rt-0.jar

As long as we’re at it, you can take a gander at my Inno Setup script if you want.  It is no great shakes but it might help you if you want an example of the whole picture at once.  Feel free to create derivatives from it if that saves you time.  (You’ll note that it is optimized largely to remove as many screens from the installer as I possibly can — no asking where to install, no asking whether to deposit shortcuts or not, etc.  I have non-technical users and don’t want to fatigue them with decisions that they’re largely not qualified to make anyway.)