Full Stack iPhone
I’m pretty excited to see if http://fullstackiphone.com succeeds in connecting those creating iPhone/iPad businesses with those who can help them with the tech side.
The Goal by Eliyahu M. Goldratt
Wow. What a book. Who would have thought that a book about how to convert a factory from a money loser to a profitable enterprise could be so entertaining and engaging? Who would have thought that you could teach business principles using a novel? It’s really a brilliant book.
I can’t stop thinking about how to apply the principles to Spreedly and No Kahuna.
This book makes me want to someday own a factory and make “real” stuff. I wonder if there’s a business owner out there who can actually put this book down.
The Well-Grounded Rubyist
This past Tuesday, we had a pretty enjoyable book exchange at the Raleigh Area Ruby Brigade meetup. Before the gathering, I had some food with Matt Bass. He mentioned that he was bringing a book he was hopeful would help someone who hadn’t been using Ruby for very long. It turns out that I ended up pulling the book Matt brought (The Well-Grounded Rubyist). My first thought was, oh well, I’ve been using Ruby for years, this probably isn’t a book I’d be into reading. I even tried to convince folks to exchange for it.
When I got home that night, I started looking at it a bit and it seemed interesting. The next morning, I read a bit more and I was hooked. I declared yesterday to be an axe sharpening day. I didn’t code a bit. I spent the entire day reading the book. And about half of today doing the same. I’ve got about 3 chapters left to read. It’s one of the best technical books I’ve read in a long time. David A. Black is an amazing author. The book is filled with crystal clear explanations and I’ve been quite surprised how many aspects of Ruby I didn’t truly undertand.
Ever been confused by some of the code that _why’s written? Ever been unsure how some of the code in the guts of Rails really works? Ever read someone else’s code and had the thought, “why don’t they write simpler code that doesn’t utilize such wacky aspects of the Ruby language?” Ever thought some code was too magical? I know I have. No more. This book has been quite motivational in terms of increasing my desire to reach a new level of Ruby mastery. If there’s some code I don’t understand, it’s on me to understand it. Time to take more responsibility.
I’ve noticed that the folks on the Rails core team and other advanced Ruybists like Nathaniel Talbott regularly take advantage of parts of the Ruby language I haven’t been an expert in. They know what self is, they know that a class method is a singleton method on the class object, they truly understand the more dynamic aspects of Ruby and how and when to customize an object. In short, they own Ruby.
The book has given me even more of an appreciation for how beautiful and powerful the Ruby language is. Thanks for the book Matt!
One person makes a difference
We’ve all had experiences as a customer when we’ve heard things like “I don’t have the authority to do that” or “Sorry, we have this policy…”.
It can be pretty frustrating and it seems to happen more when dealing with big companies than small companies.
Recently, I became a customer of a big company named Sprint. You’ve probably heard of them. :) I wouldn’t expect excellent customer service. In this case though, there’s one person named Dennis who works in the store in Garner, NC who seems to consistently attempt to delight customers. He’s one person working for a large corporation whose actions affect customers on a daily basis and cause them to start yapping about how great their experience was as a customer of Sprint.
Example 1: I was having trouble getting my new 4G card activated because it doesn’t handle Macs well yet. Dennis tried a bunch of things and then offered to let me follow him home so he could activate the card on his home computer since there were no available PC’s in the store. A crazy offer. Not something most folks would offer. One I accepted. One that helped me get up and running with the card.
He’s also going to get a PC running at the store for new Mac customers because he knows this solution won’t work long term.
Example 2: Here’s part of an email I just received from Dennis:
This is Dennis at the Garner Sprint store. I was nosing around our 4G rate plans and found a better 4G plan for you. Unlimited 3G+4G for… $10 less than you’re paying now! It will take effect on the start of your next bill cycle, 12/07/2009. Let me know if you have any questions.
This is amazing to me. It’s a remarkable thing when we’re delighted as customers. Perhaps because so few people consider unconventional solutions. Perhaps because there’s often little incentive to delight the customers you interact with when you’re working for a conglomerate. When it happens though, customers remember it and talk about it.
Customer Service Delight
In writing about customer service, Seth Godin has said that
every interaction matters and every customer is precious… Every interaction is both precious and an opportunity to delight.
I think this is extremely wise advice and it’s incredibly difficult to implement. It takes time, effort, patience, and perseverance. It takes love. It takes actually caring about the person on the other end of the support request.
For the last few days, I’ve been on point for Spreedly support while Nathaniel’s been on vacation. The experience has given me an entirely new appreciation for how challenging the task is, and how adept Nathaniel is at it.
The question that comes to mind is, if the business you’re creating has a product or service that’s remarkably good and you knock customer service out of the park by attempting to delight people, how could it not succeed?
Prefixed pluralize
I’d like the view to be smart and say something like “There are 3 plans available” or “There is 1 plan available” based on the number of plans.
Icky:
%p There #{( current_gym.membership_plans.count == 1 ) ? "is" : "are"} #{pluralize(current_gym.membership_plans.count, "membership plan")}.
Better:
%p There #{prefixed_pluralize(current_gym.membership_plans.count, "is", "are", "membership plan")}.
Here’s the little helper method:
def prefixed_pluralize(count, singular_prefix, plural_prefix, singular_suffix, plural_suffix = nil)
prefix = (count == 1) ? singular_prefix : plural_prefix
"#{prefix} #{pluralize(count, singular_suffix, plural_suffix)}"
end
And the test:
test "prefixed_pluralize" do
assert_equal "are 7 dogs", prefixed_pluralize(7, "is", "are", "dog")
assert_equal "is 1 dog", prefixed_pluralize(1, "is", "are", "dog")
assert_equal "are 0 animals", prefixed_pluralize(0, "is", "are", "animals")
assert_equal "are 5 users", prefixed_pluralize(5, "is", "are", "person", "users")
assert_equal "are now 2 penguins", prefixed_pluralize(2, "is now", "are now", "penguin")
end
Helpful?
Time Freedom
I met a dad in the pediatric intensive care unit whose child had been in the neonatal area of the hospital for 3 months. I asked him how things went with work and how he and his wife were able to spend so much time at the hospital. He replied that he’s a business owner and that his work wasn’t too affected by the long hospital stay.
Creating assets that provide value to people is important. Producing more than we consume is important. Figuring out how to live in a way such that your income is not solely based on the time you spend working is important.
Ready for real customers?
You’re creating a website that you’d like to release to the general public. One of the questions that needs answering is, which features do you need to make it to that first release?
I’ve been enjoying creating sites that I personally use like Spreedly and No Kahuna. When I’m an actual user of the site I’m making, it makes the decision about what to implement a bit easier.
The goal is to get to market and have the site being used by real customers as quickly as possible. For No Kahuna, that happened in 2 days. Spreedly took many weeks of effort before a real customer started using it. To release to a real customer, we’re only trying to make something that’s slightly better than what’s out there. We’re only trying to provide some value to the customer, not all of the value we’re ever going to provide. Does the site in its current state improve the lives of our customers?
When you’re your own customer, this becomes fun because you’re only working on the features that you’re quite sure would improve your life. If you’re at all unsure whether a feature provides value, defer it. Only do the stuff you’re confident about. This is fine because you’ll be released soon, and then customers will start giving you real feedback which is much more valuable than your guesses about what’s important.
Once you’re released, then you need to be judicious about which features to implement and be willing to say no to many requests from customers. In Getting Real, the 37 Signals guys said this:
And one more thing: it’s not just about the sheer number of requests (we don’t recommend adding something just because X# of people requested it), it’s about customers planting a seed in your mind. If they keep reminding you of something, it forces you to think about it. Maybe it is a good idea. Maybe it isn’t. But at least it’s important enough to consider if so many people keep asking for it.
Command history meme
Why not? Everyone else seems to be.
history | awk '{a[$2]++}END{for(i in a){print a[i] " " i}}' | sort -rn | head
125 git
66 gs
64 rake
56 cd
45 cap
33 ls
18 g
16 ./script/server
9 mv
8 svn
g is an alias for `git`. gs is an alias for `git status`. I like Chu’s alias of ss for `script/server`. I think I’ll do that.
cap deploy:pending
Running `cap deploy:pending` displays the commits since your last deploy. I wanted it’s output to be a bit different primarily so I could send a message to the others on the team about what’s just been deployed.
Specifically, I wanted the output to look something like this:
Deployment revision 49c45b7
I deployed the latest. It includes:
* Added avatar support (Duff)
* Cleaned up the project switcher (Alex)
To do that, I added the following capistrano recipe:
namespace :deploy do
namespace :pending do
desc <<-DESC
Show the commits since the last deploy
DESC
task :default, :except => { :no_release => true } do
deployed_already = current_revision
to_be_deployed = `git rev-parse --short "HEAD"`
puts "\n\nDeployment revision #{to_be_deployed}"
puts "I deployed the latest. It includes:"
puts
system(%Q{git log --no-merges --pretty=format:"* %s %b (%cn)" #{deployed_already}.. | replace '<unknown>' ''})
puts "\n\n\n"
end
end
end
Then I added a hook in my deploy.rb to run this automatically whenever someone deploys:
before "deploy:update_code", "deploy:pending:default"
The next piece of automation I’d like is to have it automatically post a message to basecamp.
