Jiaaro

…on life, the universe, and everything

The Good Idea Lottery

Have you ever tried to sit down and come up with a good idea?

It's really hard.

After long, painful hours you still have a blank sheet of paper. Not a single good idea written down. Sound familiar?

I think we've all been there. If you've ever been a student you know exactly what I mean.

Blank notepad

The craziest part is that during those excruciatingly long minutes, you probably weren't even thinking of ideas the whole time. An idea comes into your mind, you consider it, decide it's not the one and then you try to think of something else.

But then you get distracted.

You'd be appalled how much time distractions take out of the process when you do “brainstorming” this way.

I've been in this situation many, many times, and I finally realized something that totally changed the way I approach creative thinking:

Coming up with 1 good idea is actually harder than coming up with 10 good ideas.

It sounds crazy, but I'm about to convince you it's true ;)

Being prolific when you're brainstorming is absolutely key to finding good ideas.

In part, because as humans, we're not very good at focusing our thoughts when the rest of our body is idle. But also because we're notoriously bad at identifying which ideas are good, and which ones aren't.

The trick is to accept failure from the start.

Most of your ideas will suck, but that's fine. Just write them all down. Every. Single. Stinking. Idea.

Don't stop until you have at least 15 (and hopefully 30, 50, or 100). Every idea you write down is a ticket in the Good-Idea Lottery.

Obviously this exercise leaves you with a list of dozens of ideas which you now have to vet, but (and here's a third reason to do it my way):

Vetting ideas and coming up with ideas are different frames of mind.

When you're coming up with ideas you want to be open minded, creative, and optimistic. When you're vetting ideas you want to be analytical, realistic, and tactical. Trying to do both is hard – yet another fault of our species – we suck at multi-tasking.

So how do you vet all these ideas?

Well, I thought about this for a while and the answer is really: "it depends" as it always seems to be (nod to startups for the rest of us).

But in most cases (all?) you are well served by soliciting opinions from others.

So do that.

If it's artwork, show it to people with good taste.

If it's a business idea, show it to some would-be customers.

If it's a blog post… well if it's a blog post quit loafing and just post it ;) Your loyal readers are step 1 in vetting the content. When something seems to resonate with them, *that's* when you go all-out and try to promote it.

I started doing this sort of thing a lot.

At first I was just keeping hand written lists of people's feedback. Then it was excel spreadsheets.

Business ideas, marketing plans, songs, resume designs… all kinds of stuff.

I was really just collecting anecdotes – I'd ask 3 people here, 5 people there – sometimes that's good enough. It's certainly a good place to start.

As I continued my education I learned about statistical significance, and other fun things and the urge to make these decisions based on (more) data resurged.

I was an economics student, and a closet hacker.

There are a lot of ways to gather data, but I didn't use any of them. I did want any naïve hacker would: I built myself a tool that took all these unwashed ideas and ranked them.

And I called it the Whicher. (this may sound familiar if you follow me on twitter, facebook, etc).

Essentially, you put in a question, and 20 images and it shows people 2 at a time until they've gone through all of them.

You're probably wondering at this point, "why not just ask people to rank the ideas instead of this convoluted tournament thing?"

That was my first plan.

Let's rewind. It's story time…

My band was making a CD. There were 6 of us which meant lots of arguments about how much violin should be in the chorus of song X, and whether or not it was a good idea to cover songs our friends had written.

One day we're all sitting around in the "Recording Studio" (e.g., my parent's formal living room) trying to pick which 10 of our 30ish songs deserved to be included in the album.

We took ourselves very seriously. Don't laugh, this is important.

So Matt (drummer) proposes that we all make a top 10 list and then we'll all compare. 10 minutes of scribbling, crossing out, eraser dust, new sheets of paper, and general kindergarden activity ensues.

When Matt read my list his reaction was, "really? you like Song A more than Song B?". And answer was, "No." I didn't.

That's the funny thing about rankings. You can get circular logic: Song A beats Song B, Song B beats Song C, but Song C beats Song A.

In other words, lots of rankings aren't necessarily transitive. A brief aside: Phil Haack wrote a fascinating article about this in regards to political elections.

Our (again, suboptimal) human brains end up performing the ranking process as a series of X vs Y choices anyway.

“Do I like this song more than that one, and less then the one above it? Perfect. I'll just slip it in there.”

And it occurred to me,

why don't we just simplify the whole thing to just A vs B choices?

My hacker brain took off from there.

In fact it's not just simpler, but now we can get useful data even if the person don't make a choice about every song.

And besides, who are we do choose? We should ask THE FANS.

So here we are… in the present day. I didn't actually build the tool because I was too busy economics-ing or whatever.

I think we voted on which songs to put on the album. yay irony!

But I did eventually build this thing.

I'm still working on it, but you can check out theWhicher.com.

Also, there's a little more history to the story, which you can read on the Whicher's About Page.

But really, seriously, in conclusion: Stop doing it the hard way

Don't let your single-minded, reptilian, teenaged, brain thing hold you back.

Please consider brainstorming without any fear of failure; in fact, do it for me. Plan on coming up with swaths of bad ideas.

It's a good idea.

And you'll have plenty of time to vet them afterward ;)

You need to support mobile, even if you don't support mobile

Your application emails people when important things happen, right? 

If it doesn't it should. People like to know about important things (and it's the best marketing you could ask for).

Most people check email on their phones – among other places – and the best email is actionable.

…so they log in to take care of whatever you emailed about.

On their phone.

You probably have more mobile traffic than you think. And if you don't, you probably don't use email very effectively.

tl;dr: You need to support mobile, even if you don't.

Python performance the easy(ish) way

Ctypes is great. Let's start with a simple (and trite) example: Summing a range of numbers.

Here it is in python:

def sumrange(arg):
    return sum(xrange(arg))

Very nice! But let's say we're summing a LOT of numbers, like 0 through 10**8 (that's 100,000,000).

>>> %timeit sumrange(10**2)
1000000 loops, best of 3: 1.42 us per loop

>>> %timeit sumrange(10**8)
1 loops, best of 3: 1.13 s per loop

>>> %timeit sumrange(10**10)
1 loops, best of 3: 701 s per loop

Well that's no fun. Let's try something else:

def sumrange2(arg):
    x = i = 0
    while i < arg:
        x += i
        i += 1
    return x

How'd we do?

>>> %timeit sumrange2(10**2)
100000 loops, best of 3: 14.9 us per loop

>>> %timeit sumrange2(10**8)
1 loops, best of 3: 16.5 s per loop

Wow... that's even worse... (I dare not attempt this one with 10**10) so how do we speed it up? (don't suggest math tricks... this is the the new world of computing!)

*edit*: yes I know there's a constant time algoritm, n*(n+1)/2 . That isn't the purpose of this post

how about ctypes?

sumrange.c

#include <stdio.h>

unsigned long long sumrange(unsigned long long arg)
{
    unsigned long long i, x;
    x = 0;

    for (i = 0; i < arg; i++) {
        x = x + i;
    }
    return x;
}

compile it:

$ gcc -shared -Wl,-install_name,sumrange.so -o sumrange.so -fPIC sumrange.c -O2

and the python code...

import ctypes
sumrange_ctypes = ctypes.CDLL('/path/to/sumrange.so').sumrange
sumrange_ctypes.restype = ctypes.c_ulonglong

I learned on StackOverflow that you have to set the restype or else python will assume it's an int (which will overflow)

And the winner is...?

>>> %timeit sumrange_ctypes(10**8)
1000000 loops, best of 3: 590 ns per loop

Wow that's fast... too fast. Let's experiment

>>> %timeit sumrange_ctypes(10**2)
1000000 loops, best of 3: 601 ns per loop

>>> %timeit sumrange_ctypes(10**10)
1000000 loops, best of 3: 592 ns per loop

>>> %timeit sumrange_ctypes(10**16)
1000000 loops, best of 3: 602 ns per loop

It seems gcc has optized this into a constant time algorithm LOL. Let's try without the optimize flag (for the record I tried with -O1 and it was still contant time)

$  gcc -shared -Wl,-install_name,sumrange.so -o sumrange.so -fPIC sumrange.c

... and in python (ipython in my case)...

>>> %timeit sumrange_ctypes(10**2)
1000000 loops, best of 3: 807 ns per loop

>>> %timeit sumrange_ctypes(10**8)
1 loops, best of 3: 214 ms per loop

>>> %timeit sumrange_ctypes(10**10)
1 loops, best of 3: 3.01 s per loop

Roundup!

iterations      |   10**2       10**8       10**10
--------------------------------------------------
pure python     |   1.42 us     1.13 s      701 s
ctypes          |   807 ns      214 ms      3.01 s

That is a hell of a performance boost!

For nodejs hackers, the node equivalent of ctypes is FFI (Foreign Function Interface): https://github.com/rbranson/node-ffi

Why do we still hate Microsoft but love Apple?

Apple has grown larger than Microsoft. This is old news. Steve Jobs (RIP) never became a philanthropist like Bill Gates. So why do the technorati hold Jobs in such high regard will still harboring resentment for Gates?

I think the differentiation is in the context under which we use their products.

I find myself with other options in every arena in which I use Apple's products. I choose to use them because I want to.

Let's compare this with Microsoft. I often find myself using Microsoft products because I have no other choices.

I use Excel because Google docs wasn't able to open a complex spreadsheet created with Excel.

I use Word because Open Office couldn't display the track changes recorded in Word.

I use Windows to test my websites in Internet Explorer because IE isn't available anywhere else.

The one notable exception is Xbox; I love my Xbox. I chose it over playstation.

I wasn't strong-armed into using Xbox through anti-competitive practices, it's a good product that I wanted to use.

I don't think profit, or good vs. evil has anything to do with it. We simply like companies when we choose to use their products -- over and over -- because they're better.

960gs Reference

I am sick of the 960.gs webpage I have shit to get done and I don't want to be sold on 960 -- just remind me what the damn css classes are.

Here is my own personal 960.gs documentation :)

note: In the list below XX is used to denote a number of columns

Quick reference:

  • container_XX
  • grid_XX
  • prefix_XX
  • suffix_XX
  • push_XX
  • pull_XX
  • alpha
  • omega
  • clear

container_XX

All elements in the page should be inside one of these -- it tells the grid system how many columns your layout should be.

grid_XX

Makes the element XX columns wide

prefix_XX

Shift the element XX columns to the right (take up XX more columns on the left)

suffix_XX

Push the next element XX columns to the right (take up XX more columns on the right)

push_XX

Shift this element XX columns to the right without affecting any other elements

pull_XX

Shift this element XX columns to the left without affecting any other elements

alpha / omega

When using grid_XX inside another grid_XX element. use alpha and omega on the first and last element respectively to avoid doubling the gutter padding.

clear

clears floated elements in a way that doesn't suck