Imothee

$ tail articles.txt

Great things come in beautiful packages

Posted by Timothy Marks / 2014-01-15

It’s no secret that product design is hot right now. Look no further than the immense success of Apple and the emergence of highly backed product projects on Kickstarter. Having a clever or quirkily designed product captures the consumers imagination and sets the immediate desire for a product.

There’s another saying, you only get one chance to make a first impression. With online fulfilment and ‘pre-release’ backing, the first experience most customers have with a product is the second they tear open the postal packaging. You only get one first impression, and these days it’s a box.

It’s no secret that Apple was a trailblazer in sexy packaging. Their white, minimal boxes promised the utmost pleasure as the top slides off and reveals the perfectly packed, not a single cm of space wasted caress of your new product. The unboxing experience became almost as rewarding and lusted for as the product itself.

That’s why I’m becoming more amazed at the detail, time and thought to turn what used to be waste and packaging into an unboxing experience.

Here are some great examples of a brilliant experience you can order at home. I won’t add the iPhone and I don’t have any pictures but the Leap Motion unboxing was great as well.

A very different shape and size, cleverly branded without being too blatant.




Clever, unobtrusive, classy. Love the raw look and feel. 


Mongo Near Me - an Introduction to MongoDB Geo Indexes

Posted by Timothy Marks / 2013-11-09

I’ve recently been playing around with Geolocation on Mobile again. I’m picking a trend now, geo will be one of the next big thing in we’ll see pushed as the new cool in iOS and Android apps and games.

I thought that while I wait for the trend to catch on I should bring myself up to speed with the new (well, as on 2.4) Geo indexes in MongoDB. My last foray into location based databases was Elasticsearch and before that Postgis so I was interested to see how Mongo stacks up.

This isn’t intended to be a benchmark of any of the systems, or a detailed comparison (on why I’m beginning to detest the instability of Elasticsearch) but to document the steps to go from no to geo.

First we need to create a collection and setup the GeoIndex.

db.geoexample.ensureIndex( {"location": "2dsphere"} )
We could use just a 2d index but I prefer to be more ‘correct’ and use proper spherical distance between GPS points.

Then we need to add some example data to the collection. Mongo uses standard geoJSON so lets add somewhere interesting, how about the Golden Gate Bridge.

db.geoexample.insert( { 
    "place": "Golden Gate Bridge”, 
    "location": { "type": "Point", "coordinates": [-122.477502,  37.810996] }
} )

Something to note is that Mongo and geoJSON use the format long, lat instead of the more common (and Google Maps) lat, long

Now that we have a location, lets pass through some here I am data to see what’s around me, first lets try searching in SOMA for places within 2km (2000m).

db.geoexample.find( { "location": { 
    "$nearSphere": { "$geometry": { 
        "type": "Point", "coordinates": [-122.408909, 37.779059]}, "$maxDistance": 2000 }
    }
} )

We get nothing back unsurprisingly, SOMA is at least 5km away from the Golden Gate Bridge. This time, lets try with a max distance of 10km.

db.geoexample.find( { "location": { "$nearSphere": { "$geometry": { 
    "type": "Point", "coordinates": [-122.408909, 37.779059]}, "$maxDistance": 10000 }}
} )

This time we get the Golden Gate Bridge back incredibly quickly.

{ "_id" : ObjectId("528772d7218c9a746c3b57a6"), 
    "place" : "Golden Gate Bridge", "location" : { 
    "type" : "Point", "coordinates" : [-122.477502,  37.810996 ]
} }

So far, Mongo looks like a very simple way to deal with Geolocation data. Turns out you can also run "$near” queries on a 2dsphere index as well so you can chop and choose regardless of the index! However, so far we’ve only been getting a list of what’s nearby, how about how far away it is? Is that possible, the object it returned is exactly what we saved in the database with no ‘magic’ attributes.

Turns out there is a way, my favourite Aggregation frameworks to the rescue again.

db.geoexample.aggregate( [{ "$geoNear": { 
    "near": [-122.408909, 37.779059], 
    "distanceField": "howFarAwayIsIt”, 
    "maxDistance": 10000, 
    "spherical": true }
} ] )

Returning the magical value

{
    "result" : [
        {
            "_id" : ObjectId("528772d7218c9a746c3b57a6"),
            "place" : "Golden Gate Bridge",
            "location" : {
                "type" : "Point",
                "coordinates" : [
                    -122.477502,
                    37.810996
                ]
            },
            "howFarAwayIsIt" : 0.0010980200058842591
        }
    ],
    "ok" : 1
}

There are a couple of points of interest here! 

Firstly, for aggregation queries you need to specify a spherical variable, based on whether your index was set as ‘2d’ or ‘2dsphere’. Unlike normal queries, the aggregation query will throw an exception if you specify spherical false (default) on a 2dsphere index or vice versa.

Secondly, the distance returned looks all sorts of weird! 1 mm away? No way, turns out the aggregation framework defaults distance to radians, even if it uses metres for all the other distances (such as maxDistance). Don’t worry, there’s an easy fix. We can provide a distance multiplier. Doing some research we find that The radius of the Earth is approximately 3,959 miles or 6,371 kilometres.

So lets run the query again but this time to get a result with a distance in km.

db.geoexample.aggregate( [{ "$geoNear": { 
    "near": [-122.408909, 37.779059], 
    "distanceField": "howFarAwayIsIt”, 
    "maxDistance": 10000, 
    "spherical": true, 
    "distanceMultiplier": 6371 }
} ] )

And we get

{
    "result" : [
        {
            "_id" : ObjectId("528772d7218c9a746c3b57a6"),
            "place" : "Golden Gate Bridge",
             "location" : {
                 "type" : "Point",
                 "coordinates" : [
                     -122.477502,
                     37.810996
                 ]
             },
             "howFarAwayIsIt" : 6.9954854574886145
        }
    ],
    "ok" : 1
}

Which gives us a fairly cool distance of 6.99km. Google maps confirms this is pretty accurate so there we go! All in all, it’s pretty damn simple to run your own Four Square clone (minus all the locations) on Mongo in minutes!

I’ve been using Rails for a few years and had heard numerous ‘best practices’ for arranging page specific javascript bindings. I’d tried Paloma but found too much overhead and code generation.

Then recently I stumbled upon This rails article. I highly recommend a read all the way through before coming to a conclusion. However, nested in the middle I found a link to the following, Simple JS Rails Controller Pattern. I love the simplicity and am happy to wear the cost of body data attributes.

This got me thinking, I’ve always disliked seeing Rails Coffeescript files, each containing their own Jquery.ready listeners and thought there must be a simpler way. Extending the above pattern, I added a shared array to the global object in Appname.js

this.Appname ?= {}
this.Appname.shared = []

Then we create the shared classes that should run on every controller and action.

class SomeSharedClass

  init: () ->
    console.log('Called shared function')

Appname.shared.push(new SomeSharedClass())

Then we add a function to iterate each shared from the global and run the init() function similar to the controller and action pattern within our app.js

(function($, undefined) {
  $(function() {
    var $body = $("body")
    var controller = $body.data("controller").replace(/\//g, "_");
    var action = $body.data("action");

    var activeController = Appname[controller];

    if (activeController !== undefined) {
      if ($.isFunction(activeController.init)) {
        activeController.init();
      }

      if ($.isFunction(activeController[action])) {
        activeController[action]();
      }
    }

    var shared = AppName.shared;
    $.each(shared, function(i, v) {
      v.init();
    });

  });
})(jQuery); 
This ensures that we have only one Jquery on ready listener and execute both the controller and action specific functions but also any global shared functions. It also maintains load order and dependency management ensuring all

First Post

Posted by Timothy Marks / 2013-10-29

Welcome to imothee.com, a new, old, new blog now hosted on our wonderful new blogging platform http://letterfully.com

I’ll be using this blog to share my stories as a developer, angel investor and startup crazed guy living in Brisbane, Australia. 

I’ll also be blogging under a pseudonym (ooh fancy) with some games reviews of games all the cool kids have already finished over at http://gradualgamer.letterfully.com. It’s game reviews for people with little time and little budget for gaming.

Stay tuned for some exciting posts and if you want to start your own blog with the simplest Evernote publishing ever, why not give Letterfully a whirl, it’s free!