Thursday, September 12, 2013

gowen's interesting tip calculations

A program to calculate tips is classic, boring stuff, but my friend gowen has an interesting take on it: he requested an app that could help figure out the tip values that would result in "interesting" totals, like "43.21" or "33.33" or what have you.

tl;dr: see the bookmarklet-able result here.

I decided that I'd write a bookmarklet in Javascript as a prototype... this would allow for easy modifications and tweakings while still loadable on a portable device without going through an app store or any other flimflam. (Plus I'm a little lazy.)

I knew one basic rule: DO NO TRY TO DEAL WITH MONEY VALUES IN A FLOAT. Rounding errors are very likely to bite.

I had to throw away my first attempts at juggling currency because they were too complicated. I tried to store "dollars" and "cents" as separate parts of the same object, and then do all the math based on that... but stuff like negatives were going to get funky, and it was a pain in the butt.

A much easier system is to just store everything as cents and then translate to and from traditional "DDD.CC" notation.

So, with basic money wrangling down, I built an "interestingness detector" that would return what way a number was "interesting", or undefined if not. Here's what I decided was "interesting":
  • multiple of ten e.g. 40.00
  • digit repeating e.g. 44.44
  • ascending e.g. 45.67
  • descending e.g. 43.21
  • palindrome e.g. 43.34
  • even amount e.g. 41.00
  • repeated halves e.g. 43.43
Once I had most of that done, I needed a loop to generate values that I could test.

My first pass started from a minimum tip percentage and worked its way a penny at a time to a maximum tip percentage, printing out each one that met the criteria for interestingness. This generated too many values. I tweaked my loop so that it would only show the "first" interesting result for each type (i.e. one "even amount" value, one "palindrome" value, etc) but this was biased towards low tip amounts. I then made a loop that started with a base tip value, and then tried one cent more AND one cent less, then two cents more and two cents less, etc, and printed the first value for each interestness-type going either way, which keeps things closer to the target tip percentage.

So, the result was like this

Pretty geeky, huh?

Once that was set I made a bookmarket. At it's heart it's just wrapping the code in this block:
//code goes here
this creates a "self-executing block", and any variables I made are scoped inside of it, and so won't interfere with the current page when the bookmarklet is called. I had that whole block as a standalone js file and provided instructions to copy and paste that as the URL of a bookmark. I also embeded it in the href="" of a link for more immediate satisfaction. 

There might be a less clunky way of letting people make a bookmarklet, and I can't see a way of putting a link directly to the iOS homepage, say, like you can with normal sites, but this should do until I decide to make a real app.

Again, you can see the end result at

Now updated to recognize PI as an interesting value, as well as sorting the results by generosity, and putting the numeric values into something like columns for readability...

No comments:

Post a Comment