Flattening the Backbone.js Learning Curve

I just spent some time getting into Backbone.js finally.  The learning curve was a little steeper than I expected, mostly because I think I expected Backbone.js to be something that it is not.

From the docs:

Backbone.js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions,views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.

Well not exactly. Backbone.js doesn’t give structure. It gives you the tools to create structure.  A minor nitpick maybe, but it makes a difference when you are trying to understand how something works and you can’t find the parts you expect to be there.

The docs are well written, the examples numerous, and there are also several blog posts which try to help you get started. Oh, and there is the totally awesome annotated source.

Still there were a few things I wish I had understood before I dove into a tutorial.  This post is my attempt to try to help boost someone up the learning curve a bit. The idea is not to get into many details or app design philosophy.  Not being an MVC ideologue myself, I care little about how things ought to be.  I am just trying to get to the essence of what the parts actually are. I’m also skipping some things on purpose, as I said the docs are well written.

Models/Collections

Key Idea 1: Wrapper for a hash of properties and that can trigger events when the properties change

Key Idea 2: Includes code to load and store from a Rest API

Models and Collections are the data management objects in Backbone.js.  The Model is really a wrapper for state for an object. Each model object has a field “.attributes” which is a map of the data managed by this model.  Since you change the data using .set methods of the model, this allows the model to trigger events when the data changes:

A Collection is a collection/list of models. Duh.

Both Collections and Models are able to fetch themselves from a server if you have a nice API.  Just set .url for the object foo and call foo.fetch().  An ajax call will be made to the server and the data will be loaded or added (you can chose with an option). You can also save a model to the server. And you can do lots more, including overriding virtually all of this.

Views

Key Idea: Wrapper for a DOM object which renders it based on events and other state

Views are what tie into the DOM. Each view attaches to a DOM object. You can set this to one in your document or the View will create a new one ( a <div> by default) when you create the View object.  It’s your job to make sure the element is in the page in the right place in the hierarchy. The View always keeps a reference to the DOM element in .el or .$el if you prefer the JQuery wrapped version.

A view generally has an associated model and listens for changes in that model,  re-rendering the DOM objects when a change occurs. The view subscribes to events on the model and calls the views render method to update the DOM objects based on the new data. Generally this is done via a client side template mapping the Model’s attributes into HTML.

Routes

Key Idea: Custom events or state which work with browser history

Routes allow you to define new URLs within a single page application that can trigger events in your app. You create a router object which includes a bunch of defined url routes which are pretty similar to the urls.py in django actually. The routes/urls have parameters which are passed to the callback function when that state is reached.

Calling router.navigate() will set a new state which allow the user to move around using forward and back in the browser. This is done via #tags which you give as names to the routes.

Don’t forget to call Backbone.history.start() before using Routes.

 


 


Advice for Tech Handicapped Computer Users

After several years of helping non tech savvy neighbors with various problems, I wanted to make this list as a standard advice that anyone should follow. This is not intended to be a list of best practices, rather a list of simple important practices. If you are smart enough to figure out a better solution go for it. I don’t personally follow much of  this advice, I just wish my neighbors did.

DO: Use a router when you connect to the internet
DSL or Cable, It doesn’t matter. What does matter is that you don’t connect a computer directly to your DSL or cable modem. If you don’t know what this means then you are at risk for having violated this one. Using a router is the first line of defense against involuntary participation in Anonymous.  Some providers include a router with the modem but in most cases if you only have 1 little box next to your computer and you don’t have wifi, then you need another one. It doesn’t really matter which one you get so just get one from linksys.

Seriously, if you don’t understand the above have someone help you.

DO: Use Gmail
Don’t use email from your internet company. This means if your email ends with @comcast, @centurylink, @bellsouth etc. then its time to switch to using webmail. There is no best solution here, but they are all better than using @comcast so just sign up for www.gmail.com

DO: Use good passwords
You should probably use 1Password or a similar product or service but you probably won’t so just remember the most important password is the one for your email. DONT USE THIS FOR ANYTHING BUT YOUR EMAIL. Once someone can read your email they can pretty much get all your other passwords if they are clever, so every place you use your email password is a potential place where someone can get all your stuff. Its also a good idea to have another separate password you use only for banking.

Tip:
Have a personal affirmation statement and use the first character of each word as you password. If you are Stuart Smiley “I’m Good Enough, I’m Smart Enough, and Doggone It, People Like Me!” your password is Igeise&dgiplm!. That way you can start the day with a little positive thinking.

DO: Turn on Auto Updates and Accept Updates
Always have your operating system set to auto update or notify you and always install all the updates. Same goes for software you installed on your machine.

DO: Buy a Mac
If you have money to spend (like $1500) get the 13in Macbook Pro. Select Apple Care then then Click Add to cart. There isn’t any need to anguish over this.

DO: Okay if you insist or can’t afford a Mac By a Windows PC
If you are trying to save money buy a ASUS laptop for around $400-600$. If you want to spend $1000 on a pc, buy a Mac instead.

DONT: Obsess about Antivirus Software
If you want to purchase something go ahead I won’t stop you. Not doing stupid things, see Below is more important.

DO: Use Google Chrome as your browser
If you don’t understand what that means. Than its ok, keep using the Blue E for be “the internet”.

DONT: Use your PC to look at Porn, or Pirate things
Look I don’t care what you do with your time, and I don’t care about the moral implications of either of those things but this is the kind of stuff that will end up getting your computer infected with viruses etc, and I don’t want to have to come figure out what happened and stumble on your search history.

DONT: Accept any “toolbars”, “spyware cleaners”, “accelerators”, etc.

DONT: Click on any links in an email.

DO: Backup what you care about
If your email is all you care about then gmail will do it for you. If you have other stuff sign up for www.backblaze.com and backup over the internet while you sleep (if your pc is on). Local backups are likely to fall victim to crime, fire, or laziness

DONT: Forward chain emails
No matter how clever, funny, important you think they are.

DONT: Be paranoid about using your computer one the wifi at the coffee shop
Despite what you have read (possibly in a chain email) its not that unsafe. If you are really concerned or have special needs, get a VPN or use your own wireless connection.

DO: Get a no spill coffee (or other beverage) cup
The Contigo is a nice one. Keyboard spills are a pain and they happen to everyone.

DO: Reboot the pc every few days
If you leave your pc on its good to restart it every few days to clean out any crap and make sure you haven’t installed or done something to mess it up. When you get that funky message on startup you might remember what you did if it has only been a day or two since the last reboot.

 

Learning Spanish

For the past few years I have been trying to learn Spanish. My main motivation is that I enjoy traveling in Latin American and speaking the language opens up many opportunities. I have tried several different methods, cds, books, rosetta, immersion school in Costa Rica, personal tutors etc. They all have their benefits but in many ways my current method is my favorite when all the time and cost is factored in.

What I am doing now is paying for a personal tutor who lives in Guatemala to talk with me over Skype twice a week. The cost is fair and I get the added benefit of learning about the culture there which is exactly the vocabulary and context I am interested in. Things like local politics etc. My favorite thing I learned had to do with the most recent presidential elections in Guatemala. The president is elected for 6 years and cannot be re-elected, and neither can they be followed by a close family member. Last year, the president and first lady got divorced so that she could run for president but in the final weeks the Supreme Court ruled her ineligible, although I think the divorce was still valid.

I also learned about the difference between Elote and Maiz.

There are several services you can go through to find a tutor, I ended up just working directly with mine. If you are interested in trying it out, let me know in the comments and I will hook you up.

Sshuttle

Thanks to @elasticdog I now have sshuttle all set up on my laptop. He has an excellent guide here. Personally I just went with the brew install option and its working just fine. Seems much easier to maintain than setting up a real VPN on the server side.

There is really no server side config at all. Its all just magic.

Oversampling Canvas for better quality

The html5 canvas is a very fast and simple immediate mode graphics system, but unfortunately the image quality (especially text rendering) is often lacking. A quick and easy way to address this is to oversample the canvas.  This works by making the internal size of the canvas a multiple of the size you want it to appear on the screen. Doubling the size is generally good enough for most purposes.

The following image (made with chrome) shows the difference. The text on top was rendered with a standard canvas and the bottom text was rendered with an oversampled canvas.

 

The code for this is pretty straightforward.

In the document you can set up a canvas with double the resolution “canvas_big”  you need and then use a css style to resize it to the same visual size as “canvas_small”.

<!DOCTYPE html>
<html>
<head>
  <!-- A style to scale down the oversampled canvas -->
  <style> #canvas_big { width: 300px; } </style>
</head>
<body>
  <!-- This is a standard html5 canvas -->
  <canvas id="canvas_small" width=300 height=50></canvas>
  <br />
  <!-- This canvas is oversampled. -->
  <!-- Its internal size is 600 but it is set to display at 300 -->
  <canvas id="canvas_big" width=600 height=100></canvas>
</body>

In the javascript you can use scale on the oversampled canvas so that the same coordinates you were using before will still work on the larger canvas.

<script type="text/javascript" language="javascript">
  // Get the context for the standard canvas
  context = document.getElementById('canvas_small').getContext('2d')
 
  // Draw some text
  context.font = "22pt Arial"
  context.fillText("This text looks bad", 20, 25)
 
  // Grab the context for the oversampled canvas
  context = document.getElementById('canvas_big').getContext('2d')
  // Scale the transform so the coordinates are the same as before
  context.scale(2,2)
 
  // USe the same drawing commands as before
  context.font = "22pt Arial"
  context.fillText("This text looks better", 20, 25)
</script>
</html>

The Grok Point

Whenever I have a significant programming task to complete I usually begin the process not by thinking about all the data structures I want, or how the output will look, or what will the biggest concerns for efficiency etc.

What I am usually doing at the start is trying move as fast as I can towards the “Grok Point”. This is the point in the process where you have gained a full understanding of what you are working with. Specifications,  Example Code, Documentation, Tests, etc all of these are tools on the way to this moment as are throwaway script, staring at code,  bike rides, and caffeine.

Before the Grok Point – the code is still doing things you don’t quite follow,  you can’t find the right channel of data in the new undocumented file format,  or you are unable to get even one triangle to draw on the display. After the Grok Point – that data schema you are forced to use may still be lame but you are now its master.

Reaching this point doesn’t mean you are close to done, mostly it just means you can really get started. Generally it means you now finally have a good boundary of the problem. There may still be a huge wildfire out there but you have fire breaks all around it and you know its not going to get out. The Grok Point should be where your ability to plan or schedule begins to have some meaning. Anything can happen, the fire does sometimes jump over the river, but we have at least accounted for all the known unknowns and should be able to really think about how you are going to finish.

I feel that we often don’t give the moment the full credit it is due. We move from start to end tweaking, pushing, testing, etc until we are done. When you have spent some time working on something and reach the Grok Point I think its a good time to stop and reflect. Make notes of what you need to so you can be sure you won’t forget but then maybe its time to step away from the keyboard for a bit. Enjoy it, it feels good.

This is also a great time to think about your goals again for this task.  You are smarter now than when you began. You have just inflected from “WTF is this doing?” to “A-ha!”. At this point anything is possible. Once you start coding again you will be making choices, some of which may be hard to undo.

These moments of inspiration are sacred, use them wisely.

Doing what you aren’t supposed to do with Django tests

So I wanted to run my django test scripts against my development database. The django test system really wants to create a database from scratch but I wanted to see whether I could run against my local scratch copy since its already got a lot of data in it and I am too lazy to make fixtures etc.

Some googling produced alot of very helpful “You are doing it wrong!” comments which is fine as far as that goes but I am not good at taking advice.

Digging a little deeper I found you can override the DjangoTestSuiteRunner. Now we are getting somewhere.

put this in settings.py:


TEST_RUNNER = 'myapp.test_extras.NoTestDbDatabaseTestRunner'

And then define the NoTestDbDatabaseTestRunner:


from django.test.simple import DjangoTestSuiteRunner
class NoTestDbDatabaseTestRunner(DjangoTestSuiteRunner):
    def setup_databases(self, **kwargs):
        pass
    def teardown_databases(self, old_config, **kwargs):
        pass


I’m feeling pretty good about this. I try a simple “test” which just counts the number of items in a particular table.

Only what I get is a completely wiped out local db. Nice.

The trick is that my TestCase was using


from django.test import TestCase

which has its own ideas about what to do with the database and it was wiping it out. Switching to:


unittest.TestCase

or

from django.test import SimpleTestCase

if you are using django trunk. Looks like it fixes the problem, but it doesn’t make me feel any better.

Maybe I should just listen more.

Making a nice little Netbook

Step 1: Get an Acer Aspire One
I got mine at Costco, last time I was there they were on sale/instant rebate. Model D255E

Step 2: Add Ubuntu Natty Narwal
I went with splitting the disk in 1/2 because its pretty big and If I want to punish myself I can still run windows 7.

Step 3: Upgrade the Ram
I had a few things which didn’t work for me with 1GB (under windows) so I bumped it to 2G for < $25.00. This part worked for me: Kingston ValueRAM 2GB 1333MHz PC3-1066 DDR3 SO-DIMM Notebook Memory (KVR1333D3S9/2GETR) http://www.amazon.com/gp/product/B0039Z81JK. I had tried an different one from crucial that did not work. The upgrade is not too hard. The trickiest part is prying out the keyboard. You can push the little tabs back with a tiny flat screwdriver and then you pry out the keyboard. I recommend a credit card to help. Then you remove 4 screws marked "DOOR" and you can then push out the door at the bottom to access the Ram. There are vids/howtos on Youtube. Step 4: Add a wireless mouse and keyboard Step 5: Connect it to a big monitor Less cool factor than an Ipad but cheaper and no real limits on what kind of software it can run.

The other reason why Fixed Rate Contracts suck

You have a prospective client and you are discussing the project. Often the client would like you to quote a fixed fee for the work, so maybe you think thats ok and come up with some number by using a fancy estimation tool or tossing chicken bones. It really doesn’t much matter, something is likely to go wrong anyways.

The most obvious problem is the one everyone talks about. The client wants more work for the same price or changes his mind and wants you to just do the changes for free. Sure you could go down the route of detailed specs and change requests etc. but that’s means you are spending your time pushing paper instead of making code work, which is hopefully why you are in this game in the first place. So often we absorb a little bit (which hopefully we accounted for in the quote) and it only becomes a real problem when you have a particularly difficult client. There’s alot more to say about this and I don’t pretend to be an expert on the situation or how to resolve it.

I’d like to talk about the other side of this problem.

You agree to do a job for a fixed fee. While doing the work, you realize that there is much more you could do to make the product better than was originally envisioned by you or the client. In a good situation you can talk it over with the client and they will to pay more for this additional value. However, often the client’s budget is limited and they are unable to pay for this work that you know “ought to be” done. I run into this relatively often my desire to build something great runs up against my desire to not work for free. Usually the two desires compromise but that never leads to a feeling of satisfaction.

The simple answer is to just avoid doing fixed fee work. Is there a better answer?