Rspec Candies and Cookies

it "include_hash tests nested hashes" do
 { foo: 'a', bar: {nested_hash: {fi: 'c', baz:'b'} }}.should include_nested_hash(nested_hash: {fi: 'c', baz:'b'})
 end

Combining Mandraka’s  Rspec Candy with this little find from CookiesHQ, led me to a nested hash matcher

Very useful for testing API responses.


def find_first_value_for(hsh, key)
 return hsh[key] if hsh[key]
 hsh.values.each do |hash_value|
   values = [hash_value] unless hash_value.is_a? Array
   values.each{ |value|   return find_first_value_for(value, key) if value.is_a? Hash }
 end
end

RSpec::Matchers.define :include_nested_hash do |expected|
 match do |actual|
   if !actual.nil? and expected.is_a? Hash
     if expected.keys.count > 1
       keys.map do |key|
         value = find_first_value_for actual(actual, key)
         !value.nil? ? {key.to_sym => value} : {}
       end
     elsif expected.keys.count == 1
      {expected.keys.first => find_first_value_for(actual, expected.keys.first)}
     else
      {}
     end
     !actual.nil? && result == expected
   else
     false
   end
 end
end

Just include it in your spec_helper.rb or custom matcher module then test with something like this:

context "when testing with rspec candy" do
 it "include_hash is available" do
 { foo: 'a', bar: 'b' }.should include_hash(foo: 'a')
 end
 it "include_hash tests nested hashes" do
 { foo: 'a', bar: {nested_hash: {fi: 'c', baz:'b'} }}.should include_nested_hash(nested_hash: {fi: 'c', baz:'b'})
 end
end

Ruby CSV write to a file – Gotcha!

Unlike the beautifully concise and familiar 1 liner of code to dump a document to a text file:

File.open(local_filename, 'w') {|f| f.write(doc) }

The ruby csv library requires quite a bit more typing, and the documentation for it is easy to misunderstand.

One of my primary needs, is often data wrangling.  Changing the contents of a csv file for use in another framework, whether it’s reverse coordinates, stripping unwanted columns, or adding needed columns to the data, and I always trip up on how to dump the changed CSV after manipulating it.

As a reminder to myself, and maybe a hint to others, I’ve include the proper way to dump out your arr_of_arrs, once you’ve manipulated it as you will,

CSV.open(newfilename, "w+",
             :write_headers => true,
             :headers => arr_of_arrs.headers) do |csv|
    arr_of_arrs.each{|row| csv << row}
 end

The important bit is remembering to do an each loop of your arr_of_arrays object. This for instance will not produce the desired results:

CSV.open(newfilename, "w+",
                :write_headers => true,
                :headers => arr_of_arrs.headers) do |csv|
   csv << arr_of_arrs
end

Bone Yard for Travel Startups

My personal math has the Travel Startup success rate at lower than 1/2 of 1%. I’m calculating over 1000 travel startups in the last decade with less than 50 ‘successful’ startups. The rate for Big Time success is even lower maybe 1/10 of 1% It may…

My personal math has the Travel Startup success rate at lower than 1/2 of 1%.

I’m calculating over 1000 travel startups in the last decade with less than 50 ‘successful’ startups.

The rate for Big Time success is even lower maybe 1/10 of 1%

 

It may be too early to tell, but I essentially agree with this post on Pando Daily from a few months ago.  Travel was one of the early candidates for a market that could be disrupted by the creation of the Internet.  There are several very profitable companies that have fundamentally monopolized the space.  In the US Market, there is Expedia (created by Microsoft in partnership with GDS’s) 1996.
Orbitz.com (created by United Airlines, Delta Air Lines, Continental Airlines & Northwest Airlines in 1999).  Two of Orbitz’s founding creators no longer exist.   Travelocity.com  was created by Sabre (a GDS) which was wholly owned by American Airlines at the time.  Priceline.com was founded by Walker Digital (a very successful company with over $300M in revenues in 1998).  
So of the big 4 Online Travel Agencies in the US, none  represents what we typcially consider a startup, and 2 were actuall existing players in the market just shifting from offline to online.

If you look at the last decade, there a few very successful companies but very few that started in a dorm room.  Kayak was started by Paul English (an exec at Intuit) and Steve Hafner who was part of the original Orbitz team.  They started with a ton of funding and industry experience.

ITA Software was essentially a true startup.  It slogged along in the “Might Make it” status for 15 years before getting snatched up by Google.  Granted they had > $100M in revenues and > $200M in funding for many of their final years, but with a limited supplier chain and colossal failures in attempting to scale from Shopping Engine to PSS provider there was never going to be any future other than an acquisition for ITA.  Still an $800M acquisiton deal is clearly a SUCCESS.

 

Tripadvisor.com (11 years since founding) certainly meets the criteria.

As does Tripit.com which was acquried for $120M by Concur.

Farecompare has done very well (founded by Rick Seaney & Graeme Wallace from work they did at Hotels.com)

There’s also Farecast (founded by Oren Etzioni) purchased by Bing.

Flightcaster (Evan Konweiser, ex-kayak staff member) was purchased by NextJump.  I’m not sure NextJump is successful, but I guess I count this as a good exit.

Portland based Flightstats.com (a Datalex spin-out) seems to be doing quite well.

More recently there is Gogobot (too soon to tell whether it will last, but it has strong user growth)

And of course there is star-studded Hipmunk.com

 

Sidestep and Swoodo, both acquired by Kayak can probably also be considered true startups that succeeded by getting acquired. ($200M for Sidestep, unknown for Swoodo).  But now we’re venturing outside the US Market where there are a few other notables:

 Cheapflights.com (founded in 1996)

 Skyscanner (11 years in the making, started on the backs of 3 guys, 2 of whom kept their fulltime jobs for a while)

Danish born Momondo, (6 years old),

Maybe you can count Datalex (founded in 1985) but they don’t really fit the criteria of a start-up

There are many more notables like ClearTrip.com from India, but the point I’m trying to get it is this:

In just 2010-2011 Tnooz lists in excess of 300 startups in the travel space, only Gogobot and Hipmunk from that era are surviving at any significant level of success.

The era of the Travel startup may be over.  The cost of creating a startup in other areas is just too low, and trying to disrupt the travel space without serious connections and money is seeming less and less likely.  I’m not sure if developers will ever stop trying to tackle this space, but it’s certainly beginning to seem less and less likely that they will succeed.

Want to mention some other companies that you think qualify as ‘successful’ travel startups?  Send me a note or comment and I’ll update my post. 

 

Startup Failure Analysis

I saw this on Mashable.com but the original source was AllmandLaw.com I’m always astonished by the articles that discuss startup failures. There are many definitions, but in the tech community. If you’re not fully funded or have overwhelming user …

I saw this on Mashable.com  but the original source was AllmandLaw.com 

I’m always astonished by the articles that discuss startup failures.  There are many definitions, but in the tech community.  If you’re not fully funded or have overwhelming user acquisition momentum within the 1st 12 months, you probably fall in the FAILED category.  This one doesn’t attempt to cover the whole 90% statistic, but looks at a few side by side cases.  Worth looking at.

 

Mountain Lion killed my apache, fixed

So, Mountain Lion upgrade generally went fine, but had some real problems with my MAMP stack (Mac, Apache, Mysql, Php). I program in a lot of languages in and keeping my stacks working with current development machine is usually no problem, but I …

So, Mountain Lion upgrade generally went fine, but had some real problems with my MAMP stack (Mac, Apache, Mysql, Php).  I program in a lot of languages in and keeping my stacks working with current development machine is usually no problem, but I ran into about 3 hours of confusion with Mac Mountain Lion and Apache.

 

Thanks to Neil Gee and this very idiot proof walk thru, I got it fixed up in a few minutes once I started looking for help.  Mysql,php,phpmyadmin on OS X 10.8 Mountain Lion

photo via

http://www.cultofmac.com/146957/mountain-lion-kills-os-x-support-for-a-number…

Quit while you are behind

This is in response to a recent post by OM Malik http://om.co/2012/03/20/entrepreneur-lesson-1-from-mark-pincus-stay-with-it/ Basically it’s that Stick With It advice you hear so often. I usually agree with most of his insights but this one just r…

This is in response to a recent post by OM Malik

http://om.co/2012/03/20/entrepreneur-lesson-1-from-mark-pincus-stay-with-it/

Basically it’s that Stick With It advice you hear so often.  I usually agree with most of his insights but this one just rubbed me the wrong way.

FACT => Most startups fail
CONJECTURE => Many go down in flames with debt, unpaid salaries, legal liabilities, broken promises, divorces, friendships ended etc

CONCLUSION => Most startups fail too late.


In my experience startup Entrepeneurs have by definition already got the stick with it gene. They wouldn’t be doing a startup of they didn’t. In fact I would say too many of them have a delusional sense that of they just keep trying to hang on, somehow it will all work out allright.

In fact the best piece of advice I can give is this: When you find yourself with a shovel, deep in a hole, STOP DIGGING.

Practically what this means is that it’s better to retreat when the writing is CLEARLY on the wall, regroup, maybe take a temp job, and come at it again a bit later when you’ve digested what went wrong how your luck worked against you.

So stick with it by all means, but don’t believe the fantasy that if you stick with something that isn’t working, all you need is persaverence.

Suits Versus Nerds

I’ve been working for a while on trying to develop a toolbox for the Suits I meet to understand the Geeks I work with. One of the most common process problems I’ve encountered in a mangement culture is a complete and total misunderstanding of how …

I’ve been working for a while on trying to develop a toolbox for the Suits I meet to understand the Geeks I work with.  One of the most common process problems I’ve encountered in a mangement culture is a complete and total misunderstanding of how tech works, what motivates technical people, and the value that technical teams bring.  The reverese is also completely true.

Ask any developer what the non-technical people in their organization do, and usually you’ll get an answer like:  

“There are non-technical people here?”

“The have meetings?”

or “I have no frigging clue.”

I’m designing a series of surveys (non-scientific) to suss out the nature of the most common problems and possible solutions.  If you’re a Geek, a tech person, a designer (still on the technical side of Suits versus Nerds) please help me out and take the survey.

Nerds Click Here

If you’re ALL Business, please help by taking the Survey for Suits!

Suits Click Here

XML, Violence, Nokogiri and Xpath

I love Xpath. It makes XML easy to use and easy to query. Gone are the days of parsing things with a SaxParser unless you’re really hard up for control of you text. Also, I love the Ruby Nokogiri Gem. XML is like violence – if it doesn’t solve you…

I love Xpath.

 It makes XML easy to use and easy to query.  Gone are the days of parsing things with a SaxParser unless you’re really hard up for control of you text.

 

Also, I love the Ruby Nokogiri Gem.  

XML is like violence – if it doesn’t solve your problems, you are not using enough of it.

– Nokogiri docs

But I do have to say that there is a lack of good examples and documentation for anything particularly advanced.  I found a working solution to my issue, but thought I’d paste here what I wanted to do versus what I ended up doing.

Given the following XML, 

 

https://gist.github.com/1577136

 

I’d like to grab two elements that include “Cover” in the tag, and then operate on each of them.

Nokogiri’s use of Xpath easily allows the first query expression like so: price_xml = doc_xml.xpath('Container/Set/*[contains(name(), "Cover")]')

I’ve selected all the elements (using *) in Set, and then used an Xpath Expression function:

contains, in order to specify that Adult must be in the name.  This returns two Nokogiri XML Nodes in Nodeset.

 

What I wanted to do was then select one of these elements based on a pattern in the tagname use my favorite tool, Xpath.

But I just couldn’t get Nokogiri to give it to me, and several solutions ending up selecting way more than the 1 element I wanted. (Because the nodes in the Nodeset still contain relationships with their parents)

https://gist.github.com/1579343

 

I’m cross posting this on StackOverflow as a question, just in case any Nokogiri Xpath enthusiasts want to recommend a solution that doesn’t resort to find()

 

 

Rails Rake tips

This is the Hay Magnum-Hay CCM-8 Max Wheel Rake. Now you might think it should have a name like: Hay Magnumator 8000 but it doesn’t. It doesn’t take long playing with Rake before you starting thinking of it like the Hay Magnumator 8000. By Rake, I…

longviewcart
rake tasks

Here’s a tip:
If some of these tasks are actually “private” tasks that only get called by other Rake tasks,
leave off the “desc” line in the task definition.  And Voila, your rake -T list will get a lot cleaner.

 

Thanks to Erik Debill for his nice post on Rake and some Advanced Tips for using it.