Wednesday, May 9, 2012

May 2012 Review

Reasons to use RSpec
Make IRB much more useful
Ruby and Rails
The Rest
  • Anonymouse: I made some changes to my domain hosting configuration. I couldn't tell if the lack of response in my browser was due to caching issues. Anonymouse solved that.
  • Bootstrap: Clean CSS/HTML template.
  • Focus: Identify 3 MIT's (most important things) each day, and commit to doing them.
  • LESS: Cleaner CSS.
  • Mint: Become financially self-aware. 
  • ShiftIt: My new Cinch
  • Willpower: I'm finally productive for the first time in my life after reading this book. Two key insights. 1) Multiple goals saps willpower. 2) Productive people have a way of tying their big picture to their daily routine.

Sunday, January 22, 2012

Lean Startup Machine Cheat Sheet

Hey guys, we're really looking forward to LSM Toronto, coming up in 4 days. To help get you started, this post documents some basic ideas on how to get the most out of the event.

What's Lean Startup Machine all about?
"Lean" doesn't refer to money. It refers to shortest time to learn.

The point of Lean Startup is to maximize learning and validation/invalidation of your business model in the shortest amount of time. The goal of Lean Startup Machine is to have paying customers for an MVP in a weekend.

How do I start?
Write one sentence answers to each of the following questions: Who is my customer? What is their problem? What is my solution? Record your answers in Unassumer.

My customer is "small retail businesses". Is that a good answer?
Use a persona. It helps to be concrete. For example, instead of "small retail businesses", you might come up with the persona, "Mary owns a small successful fashion store. She's 29, single, has a degree in Business. Mary has 3 employees. 30% of revenue comes from online international sales."

Personas are great because they allow you to quickly evaluate any idea by asking, "Would Mary want this?" Personas help you focus to identify your MVP at the start, but don't spend too much time refining your persona. You'll be changing, or even tossing your persona, once you start talking with real customers, and you'll want to talk to real customers as soon as possible.

What's next?
You want to validate/invalidate your problem.

How do I do that?
Call up people, or hit the street and find people, that are similar to your target customer, and start pitching the problem. Don't mention your solution. Also, don't mention your problem. Start with an open-ended "As a small retail business owner, what is your biggest problem?" People will start talking about nothing that you're interested in.

So why is that useful?
The value of starting with this question is that if 3 people mention the same problem, and it's a problem you can solve, and make money off of, then you abandon your original problem.

Okay, after you get an answer to that question, then you pitch the problem. Say, "We've been hearing that lack of online advertising is a problem for small retail businesses?" Then be quiet and listen.

Only interview a handful of people. Don't interview 20 people before iterating.

If the problem is invalidated, then pivot, and repeat. If the problem is validated, go to the next step, which is to validate/invalidate the solution?

How do I validate/invalidate the solution?
Sell it. Call people up, and sell it. Get a credit card number.

What?! I don't even have the service yet.
So, the point of collecting the credit card number is not to make money. You don't do anything with the number. You tear it up and toss it. The point of collecting the credit card number is to collect data. It's very different if a potential customer says, "Yeah, I'm interested. Send me a link to your website." than "I'm buying. Here's my credit card number."

Okay, I've validated the solution. What's next?
Build a landing page, put a way for people to pay online and start selling. Use Unbounce.

What?! But my product doesn't even exist yet.
Remember, what we're doing here is collecting data. Paying customers is hard data. If you find out that there's very little interest in buying the product, then you simply return the money. If you collect $60k over the weekend, then you build the product before you have to return the money.

Any last words of advice?
Lean Startup is not about practices. It's about achieving validated learning. You don't get any points for filling out a Business Model Canvas. The only thing that counts is validating your business model against reality (i.e. paying customers).

Friday, November 4, 2011

Deliberate Practice Session at Agile Tour

I had a lot of fun facilitating the workshop with Alex Aitken. A big thank you to all the participants for the coding during the randori, and for the great discussion!

Session slides on SlideShare

Friday, July 15, 2011

TDD Workshop

Thanks to everyone for coming out to the TDD workshop (the first in a series that Alistair McKinnell and I are facilitating). Thanks to Guidewire for providing the space. I've published the workshop outline, and an updated Ruby Cheat Sheet.

What if I missed the workshop?

You can do the workshop on your own. Do the FizzBuzz kata. Next, do the String Calculator kata. For both katas, use TDD, Ruby, and pair.

There are 2 tools that will help you get started with TDD:
  • The TDD cycle. Red-Green-Refactor will help you remain focused and work in small steps.
  • Learn Arrange-Act-Assert. This will provide a mental model for how you structure your tests, and allow you to break down writing the test into smaller steps. Here's a tip: when you write a test, start with the Assert, and work backwards to the Act section, and finally write the Arrange section.
Choose one of the 4 following missions (to be completed before Aug 14):

What if I don't know ruby?

A good online ruby resource is Ruby Essentials.

What if I don't know how to program?

I recommend the book Learn to Program.

When's the next workshop?

Right now we're looking for a space. If you're happy to provide a space with wireless access for 20 developers one evening, drop me a line.

How can I help improve the workshop?

Let me know what worked and didn't work for you in the first workshop. Post a comment or email me.

Tuesday, January 4, 2011


I just finished reading A Guide to the Good Life: The Ancient Art of Stoic Joy. This book really resonated with me. Here's the gist...Without a philosophy of life (i.e. a life goal, and a means of attaining that goal), you may realize in the last moments of your life that you have lived without purpose. Stoicism is a philosophy of life. It claims that the goal of life is tranquility.

One obstacle to tranquility is insatiability--the continuous pursuit of things that we don't have. Stoicism's response to this is to be satisfied with what we already have. The tool to achieve this is negative visualization...contemplating losing the things that we already possess (e.g. our loved ones dying, losing our ability to see). Negative visualization is not to be confused with worrying.

Another obstacle to tranquility is anxiety--worrying about things outside of our control. Stoicism addresses this by categorizing all things into 3 categories: things over which you have no control, complete control, and partial control. Things in the first category, you cease to worry about. Things in the second category are not problematic. The last category is problematic. Stoicism says that for things you have partial control over, you want to adopt internal goals, and avoid external goals. For example, if you're playing a tennis match, you only have partial control over the outcome. Stoicism says that instead of trying to win the tennis match (an external goal), you should instead try to play the best game you can (an internal goal).

Stoicism has a really interesting take on discomfort. Stoics seek out discomfort. They will voluntarily create experiences of discomfort (e.g. taking a cold shower). This is not to be confused with asceticism--extreme deprivation and relinquishing of all material comforts. Ascetics seek to remove all dependency on luxury. Stoics believe in enjoying the good things in life. Their aim of seeking out experiences of discomfort is to build strength for when life throws at you uncomfortable experiences which are not voluntary. Stoics welcome the "tragedies" of life. In the way a trained fire fighter welcomes fires. It gives them an opportunity to exercise their training.

Fascinating insights on Buddhism, evolutionary psychology, sex, religion, grief, and insults. Highly recommended.

Thursday, September 9, 2010

Upgrading to Rails 3


This post documents the steps I took to upgrade from Rails 2.3.8 to Rails 3.0.0 on Mac OS X 10.5.8 with Ruby 1.8.7.

The Steps

I started with these guides: Part 1, Part 2, Part 3.

I followed the instructions in Part 1 to use Ruby 1.9.2, but I had problems using Ruby 1.9.2, so I used Ruby 1.8.7 instead.

Factory_girl failed to install, so I installed factory_girl_rails instead. [reference]

Subdomain-fu failed to install, so I installed nhowell's version of subdomain-fu instead. [reference]

Date and time format configuration changed in Rails 3. [sample]

Authlogic authenticates_many failed with Rails 3. I used authenticates_many :user_sessions, :find_options => { :limit => 1 } to workaround this. [reference]

Webrat failed with Rails 3, so I used Capybara instead. [reference]

Since my application uses subdomains, I assigned a value to Capybara.default_host to get my tests to pass. [reference]

Authlogic failed with Rails 3, so I used odorcicd's rails3 branch instead. [reference]

I needed to call html_safe() for all return values from my custom form builder method. [sample]

I'm using jQuery in my app, so I downloaded the jQuery version of 'rails.js' according to Part 3. I'm using the exception_logger gem, which requires the Prototype version of 'rails.js'. So I made 'rails.js' the Prototype version, and I created the file 'rails-jquery.js', which is the jQuery version.

I was using the exception_logger plugin, which is not Rails 3 compatible. There is an exception_logger gem which is almost Rails 3 compatible, but not quite, so I forked my own version.

I followed the instructions in Part 2 to define APP_CONFIG, but that didn't work for me. So I defined APP_CONFIG in its own initializer file. [sample]

With Rails 3, protect_from_forgery for delete buttons does not work without some work. I temporarily disabled protect_from_forgery for all delete actions.

I got an ActiveRecord::ReadOnlyRecord exception on update. To fix this, I pass :readonly => false to the related find. [reference]

The form_for method was failing for a scoped resource, so I switched to using a form_tag for that view.

Instead of using the dynamic_form plugin as specified in Part 3, I used the dynamic_form gem.

There was an issue related to time zones with some code that used Chronic. I had to build a UTC time manually to restore the application's behavior. [sample]

I followed the instructions in Part 2 to autoload the lib directory, but that didn't work for me, so I created an initializer file to load the lib directory. [sample]

Here are the final changes to my gem configuration.

Final Statement

My favorite feature of Rails 3? Bundler. I didn't realize how cool Bundler was until I understood the Bundler lock file. That eliminates a whole class of dependency problems that Rails projects were vulnerable to.

Thursday, August 12, 2010

Gmail - Stripped

I like a clean distraction-free workspace. I spend a lot of time in Gmail, so when I came across the Firefox add-on, Minimalist Gmail, I was very happy. I didn't realize how spoiled I was by Minimalist Gmail until Gmail changed their site format a couple days ago. Matt Constantine, the author of Minimalist Gmail, is working on updating his add-on, but I am so painfully aware of the visual noise that I put together my own Stylish script.