Skip to content

select * from Aggghhhhhh;

My efforts at being efficient were thwarted this evening by a rather annoying Castle ActiveRecord buu — err – behavior.  I decided to juice these lemons into lemonade by turning this aggravation into a blog post, as maybe it will help someone else out there.

It all started when I added a new column to the Users table.  This was an Int64 type mapped to the Postgres “bigint” data type.  After getting this all setup and finishing the code I was working on, I copied the bits out to the Alpha server to be used by my small contingent of test volunteers.  Right when I logged on to the production site, the main “page loading” web method call threw an exception which indicated a SQL error.  The SQL log file informed me that my unique constraint on my new column was being violated.  This was odd, since nothing I was doing should even update that column.  What was more odd is that this behavior didn’t repro on my development database.  So I decided to point my dev machine over to the production database and see what was going on.

The crash was one of the weirdest things I’ve seen.  The following line of code, which is part of the user authentication mechanism, was the culprit:

int i = User.Count(“UserId = ? and SecurityGuid = ? and SessionGuid = ?”, credentials.UserId, credentials.SecurityGuid, credentials.SessionGuid);

This is of course odd because this statement should do nothing but count some rows in the database, there’s no way in a million years this should be updating any data!  Plus, the line of code had already been run several times successfully.  It gets weirder.  After looking at the inner exception, which contained the root SQL text being run, I noticed the UPDATE command was attempting to update other users in the database!  The code was not only modifying data in the database, it was attempting to modify other user accounts!  Ok now this is annoying.

Well, clearly there were some pending updates in the buffer, and Count() was flushing the buffer to ensure an accurate count.  But what was updating the Users table?  After spending about 20 minutes stepping through each line of code, adding a plethora of strategic breakpoints, I had exhausted all my patience and was getting no closer to figuring out what was going on.  This annoyance was compounded by the fact that my production server was now down.  It was 2am and I wanted to go to bed!

At this point, I decided to DROP the unique constraint on the new column, which was of course the symptom of the error and not the cause.  Out of any other ideas, I figured this would either completely corrupt my database or perhaps provide some insight on the nature of the problem.  The latter was thankfully what occured.

When I dropped the constraint, as expected the crash went away.  What was in the database was nothing less than enlightening.  Several of the users had the new column set to 0.  A ha!  It was making sense now.

Stop reading here if you’re adventurous enough to hypothesize the nature of the problem.  It took me a few minutes to understand what was going on.

The new bigint column is nullable (by design,) however the Int64 mapped property was not.  It turns out, I was reading a set of recipes which have a relationship with the Users table (through the recipe owner).  When my code read the user’s cookbook, some User objects were instantiated.  The new column was set to 0, since Int64 is a value type.  Since the database value was known to be null, the record was flagged as dirty.  When the HQL was run, NHibernate decided it needed to update those dirty records and flush the buffer.  The second user updated violated the unique constraint since both rows had a new value of 0.  The reason this appeared on the production server and not my development database was that my production user account had recipes in the cookbook owned by other users.

The solution was of course change the Int64 to Int64? so that the null’ed value could be represented.  This is just another tale where an hour of debugging results in a one character fix.  If I had a nickel for all of those.

CrowdPitch

This afternoon, I decided to check out CrowdPitch, an event organized by FundingUniverse and hosted by Amazon’s AWS team.  FundingUniverse sponsors about 50 events per year.  There were five presenting companies, all of which were fantastic and had very well thought-out business plans.  The judges were also notable and gave excellent feedback.  I thought I’d share some of my notes to those of you who are interested.

Judges:

John Cook (TechFlash) – John is one of the co-founders of TechFlash, a news site targetting tech startups.  He has a background in journalism as well, and used to be a writer for the Seattle PI covering techie news.

Lucinda Stewart (OVP Venture Partners) – This VC firm has offices in Seattle and Portland and has been around for 25 years.  They specialize in funding early stage IT startup companies.

Jeff Barr (AWS) – Jeff is a technical evangelist for Amazon Web Services, which is heavily used by FundingUniverse.

Tim Porter (Madrona Venture Group) – This Northwest Based VC firms is one of the biggest in the area, with around $700MM in capital.  They’ve been around for about 15 years.

Contestants:

CloudPack – This company specializes in hosting extremely large digital images in the cloud, mostly targeting the medical industry.  These images use JPEG2000 compression and can be several gigabytes in size, and contain multi-spectral, 3D imagery.  They basically target organizations that don’t wish to, or don’t have the resources to host their own data.  They can provide services like annotation, deep-zoom, collaboration and sharing, and management of extremely large files.  Their revenue model is charging companies an amount based on the compressed size of the data they host.  The pitch was well done and on time, however a lot of the slides contained way too much information to read.  The presenter moved extremely fast to fit everything he had to say into his four minute allotted time.  I thought he gave a decent pitch, but had one of the more viable business ideas.  He obviously had found his market, and delivered a good solution to a problem they have.  Since there’s many ways to store huge images online, I wish he had done more to explain the exact feature set his service delivered to provide a competitive advantage.

CupAd – These guys pretty much put ads on paper coffee cups.  Yes, that’s their entire 30 seconds elevator pitch.  The idea is they find a company who wishes to advertise on a coffee cup and then order the cups and give them to local coffee stands for free.  Coffee stands save a few hundred dollars per month getting free cups, and CupAd makes money from the advertisers.  CupAd charges the advertiser about 25-30 cents per cup, and pays around half that to manufacture each cup so they make a pretty decent profit.  They also have the ability to target various demographics, income levels, age groups, etc.  They lined up 88 coffee stands in their first month (mostly by cold calling), and there’s tens of thousands of stands in the area to go after next.  I was curious about the types of cups they would manufacture, such as earth friendly corn based cups, various sizes, etc.  Also, I’m wondering if there’s any barrier to entry in this market or if other copy-cat companies could be successful driving competition in this area.

MobileOn Services – This company allows consumers to create a mobile cell phone app using a web based wizard.  These apps can deliver various features such as displaying data from an RSS feed, maps, calendars, and other data.  The backend generates and compiles source code for different mobile platforms such as iPhone, Android, Windows Mobile and BlackBerry.  The idea definitely intrigues me as I’ll be needing a KitchenPC mobile app very soon and am dreading the idea of writing apps for all the various platforms.  The idea was promising, however the pitch was awful.  I was watching the clock, and two minutes into the pitch I still had absolutely no clue what they did.  The presenter seemed to be totally oblivious to the clock, and didn’t even get through half of his slides.  Luckily, he was able to clear up some of the questions during the three-minute audience Q&A and the judges’ feedback.  When I got home, I logged on to the site and deemed the types of apps they can create too limited for what I’d need to do.  Even so, I really want to see someone nail a cross-platform development process for mobile phones.  The fact that this industry exists is valuable information for me.

TextADay – This company is dedicated to mobile giving, such as donating money to a charity via a text message.  This concept has really taken off since the Haiti relief efforts, and this company has setup a platform for charities to accept donations via SMS.  The cell phone providers don’t charge a fee for this, and TextADay will charge 10% of the donation and the charity will keep 90%.  Right now, users can text either $5 or $10 donations, and are limited to $40 per month.  This is a limitation put in place by cell phone companies, as to minimize bill disputes if an unauthorized person gets ahold of your phone.  The pitch was well done, and I think the company definitely has a viable offering.

TShirts4Hire.com – Ever wanted to get paid to wear a T-shirt for a day?  These guys will arrange just that.  As the T-shirt wearer, you get to decide whose T-shirt you’ll wear and how much you’ll charge them.  In return, you’re supposed to walk around all day, talk to people about the product you’re advertising, and talk about the company on social media or a blog.  Advertisers can decide whose “bid” to accept.  They also take care of T-shirt fulfillment for companies who don’t yet have T-shirts to send.  TShirts4Hire takes a fee from the bid amount (I wasn’t sure if this fee was taken from the wearer or the advertiser) and also has some sort of rating system to weed out wearers who try to game the system.  I thought their pitch was the best out of the group.  I knew exactly what they were doing within the first two sentences, and everything was laid out very clearly.

Winners:

Each member of the audience was given two fake $50 bills that were supposed to represent VC money.  We were told to give this money to the presenters we liked best, as if we were investing in their company.  We could either give all the money to one company, or split it up among two companies.  I decided to split up my money between TShirts4Hire (who I thought had the best pitch, but not the greatest business idea) and CloudPak, who I thought had the most viable business but not the best pitch.  The winner was decided by the company who got the most fake money, which turned out to be CupAd.  CupAd received about $4,800 worth of prizes, including $500 worth of AWS hosting, 12 hours of financial and accounting services, and various services from FundingUniverse.

After the presentations, I got to hang out and pitch KitchenPC to several people in the room, all of which really seemed to love the idea.  I exhausted my supply of business cards, and got a stack of other business cards to take home with me.  The next CrowdPitch will be on October 14th, and I’m thinking about trying to get selected to pitch KitchenPC.  We’ll see!

There’s no place like 127.0.0.1

As I anxiously wait for my Polish design company to create a suitable template for my site, I’ve started spending some cycles comparing hosting providers.  Ideally, I’d like a company that I can grow with; cheap prices up front for a single server to run the beta on, and the resources to scale out if and when the site becomes more popular.  Since my site uses an enormous amount of RAM (creating graph DBs in memory, caching, and indexing ingredient names), as well as depends on a queue service to perform various tasks, any sort of shared hosting solution is pretty much out.  This means I need root access on the machine and must be able to connect directly to the box.  A dedicated managed server would probably run around $300-$400/mon, so cloud solutions utilizing virtual machines are something I’m very interested in.  Today’s virtualization platforms, be it VMWare ESXi or Citrix XenServer, are becoming increasingly performant even for tasks such as running database servers.  Plus, it’s probably still cheaper to buy a bunch of virtual machines instead of leasing an entire server you may or may not use.  I doubt you’d want to run Facebook on VMs, but for my purposes they should be fine.

One conclusion I’ve come to is I need to stick with a Windows solution for now.  Though I’ve tested the site on Mono, I just don’t really trust it yet for production use and would like to do a lot more testing.  My current plan is to find a cloud hosting solution that supports Windows virtual machines and use that for the Beta site.  In the mean time, I’ll setup my own UNIX servers at home and do some more in-depth testing with a Mono build of KitchenPC where I can do things like remote debug, stress test (looking for memory leaks and performance bottlenecks), and isolate any Mono runtime specific problems.  Since the Mono project is one I’d really love to see succeed, I’d like to be able to give back to the open source community by helping out with this project.  Testing KitchenPC on this runtime will hopefully generate a few bug reports and testing data that might be helpful to the Mono team.

In this blog post, I’ll compare a few Windows cloud hosting solutions.

Hosting.com

I first ran across Hosting.com when I was shopping around for dedicated managed servers and their sales staff impressed me with their knowledge and helpfulness.  Though they came across somewhat bitter, as half of their sales pitch was about how much Rackspace sucks.  Nevertheless, I believe they’re a great hosting company and have a lot of offer.  However, I think their cloud hosting solutions are not quite there yet to really be competitive in today’s industry.  First off, they don’t seem to really know the definition of “elasticity.”  If I provision a new virtual machine, it can take up to 24 hours for the machine to be provisioned and online.  What the heck are they doing?  This task should be completely automated and machines should be available within minutes.  Unlike most services, they do have the ability to upload a VMWare virtual disk image and provision a machine based on that, but the feature is rendered almost useless due to a few limitations.  When you upload the image (which is most likely several gigs), the machine can take up to a day to become available, and once it is, the file you uploaded is deleted!  This means you can’t store a “base image” of your server online and provision new nodes as traffic increases.  To make this even more ridiculous, last I checked they had no ability to backup or checkpoint virtual machines, so there’s no way to “clone” a machine.  Imagine the scenario where you want to add new node to your website because you got Dugg and millions are coming to your site.  You’d first have to upload a image of several gigs, wait 24 hours for the machine to come online, and then of course run any other configuration scripts needed for the machine.  I do believe they have the ability to instantly “resize” a machine, but it just doesn’t seem to me that Hosting.com understands the elastic cloud computing world.  On the plus side, they do support Windows and their pricing is fairly competitive at $139/mon for 1.2GHz virtual CPU, a gig of RAM and a terabyte of traffic included.

Amazon EC2

Everyone loves Amazon!  Their Elastic Computing services have been the subject of many news headlines over the past year or two, so I’d be silly not to dig in to their offering a bit.  Amazon just started offering Windows virtual machines recently, which works by allowing you to lease the cost of a Windows Server license by the hour.  The first thing I noticed about EC2 is their pricing reads like an obscure legal contract and reading it will usually result in a headache.  They totally lost me when they started talking about “compute cycles” or some such thing.  However, from what I understand, a small instance (which equates to a single virtual core with 1.7GB of RAM and 160GB of storage) will run about 12 cents per hour for Windows instance.  However, if you’re running to pay $227.50 up front, you can “buy down” the price for the year making it 5 cents per hour.

In other words, at 12 cents per hour you’d be paying (0.12 x 24 x 365) $1051.20 per year, or about $88 bucks a month.  If you wanted to pay up front, you’d be paying (227.50 + (.05 x 24 x 365)) $665.5 per year, or about $55 bucks a month.  This of course does not include bandwidth, which is 15 cents per gig, the first gig being free.  They also don’t charge for incoming data, though this will be changing in November.

Another thing I like about EC2 is they have built-in load balancing solutions (at 2.5 cents/hour), which can actually direct traffic intelligently to geographically convenient servers.  After checking into this technology, it was revealed that this is simply software load balancing which one could just setup themselves on any host.  Now if they threw some BigIP hardware in front of their cloud, man now they’d have something!  Even so, having load balancing at the click of a button sounds pretty nice.

Amazon most likely has the best developer resources as well.  They have a library of machine images to choose from with all sorts of stuff pre-installed, and you can even make your own and upload them.  Their API is rich and well documented, and you can scale up and down as needed automatically.  The idea of being able to detect high server load and automatically provision a new machine and add it to a web farm is very intriguing.

One thing I don’t like is I don’t really feel I’d get good customer support with Amazon.  They have forums and a very well documented API, but I can’t talk with a human 24 hours a day without paying at least $100/mon extra.

Windows Azure

Being a Microsoft employee for 11 years would result in a bit of guilt if I didn’t look into my old employer’s solution.  Though this service has been re-invented many times and is still in beta stages, it does look promising.  They do a lot of interesting things like allow services in the cloud to interact programmatically.  For example, I could write a stock price lookup web service, then allow other services in the cloud to call into my APIs, all internally within their network.  This creates an interesting ecosystem where new cloud features could be written and sold by third parties.

Azure has a huge advantage for the KitchenPC Beta, as the current Community Technology Preview is free.  They have announced their pricing, however it appears to be fairly competitive with Amazon EC2 at about 12 cents per hour.

In typical Microsoft fashion, the system is extremely closed.  To me, it seems designed only to work if you want to live and breath the Microsoft world.  This means using Windows servers, Visual Studio to develop everything (though I’m sure there’s manual ways to deploy), and SQL Server to run your database on.  Only applications that are built on the common language runtime can be hosted on Azure at this time.  Since I’m using PostgreSQL, I believe this fact would be a deal breaker.  However, watching a Channel 9 video on Azure, it appears they do have plans of giving people root access to individual leased machines which might make Azure more of an option at some point.  Overall, I think if Microsoft gets its act together, this might turn into the first real cloud based operating system.

Rackspace CloudServers

Rackspace has been my favorite hosting company for ages now.  They’re the best of the best, have an amazing track record, have an impressive portfolio of clients (such as Nike.com and YouTube, before being acquired by Google that is.)  Every time I call them, they’re friendly and helpful and completely dedicated to providing awesome customer service.  I’m fully confident KitchenPC would be in good hands with Rackspace.

Their cloud solutions are somewhat new, after purchasing a company by the name of SliceHost for their virtualizing technology.  Their API is well documented and rich, and machines can be modified or provisioned by calling RESTful web services.  Machines can also be checkpointed and backed up, and new machines can be provisioned from existing backups.  At this time, they don’t have the ability to upload a virtual disk (they use Citrix Xen which might make this less than straight forward), but this probably isn’t too important if you can store your images online.  They also have probably one of the most advanced server farms ever built.  Virtual disks run off a SAN and can actually float to another disk array in case of any hardware failure, without even interrupting the machine state.  The last sales person I talked to was quick to point out that if Amazon suffers any sort of failure, your virtual machine is probably toast.

Rackspace just recently announced Windows CloudServers, which has secured their place in my list of finalists.  However, since this service is in Beta, it’s not “recommended” for production use and is limited in several ways.  For example, I can’t backup a disk image yet.  Backing up my database would require me to push the data off their network, which would be somewhat of a hassle.  Rackspace does have my trust that if anything were to go wrong, even in their beta stages, they’d be all over it and address the issue as soon as possible.  Plus, the service should be fully featured and backed up by their SLA within months.

The pricing is also competitive.  I can get a single virtual CPU machine with 512MB of RAM and 20 gigs of space for 4 cents an hour, or a gig of RAM and 40 gigs of space for 8 cents an hour.  Data per gig costs 22 cents out, and 8 cents in.  Their selection of machine choices (all the way up to around 16gigs of RAM) is much more diverse than other providers I’ve looked at.

I have a feeling that Rackspace would be a great choice for the beta version of KitchenPC, even with their limited Windows hosting features.  Furthermore, if I were to switch to Unix hosting or even dedicated servers, Rackspace would by far be my first choice.  This means that as my company grows, I’d be able to stick with the same hosting company as my requirements changed.

Conclusion

At this point, I’m leaning towards Rackspace as my choice for the KitchenPC Beta.  I trust the company, admire their customer focus, and believe they have the resources to take care of me now and in the future.  For the beta version, I’ll probably just need a single virtual machine and can backup the data nightly over a secure channel to either my home server or one of the many file backup solutions on the Internet.  With prices starting around $30/mon, they’re among the cheapest solution and would of course allow me to resize the machine within minutes as needed.

Now if only the Polish designers would hurry up with my site so I could get the thing online!

UI Challenge Part Deux

One of the most demo-able features of KitchenPC is the ability to take a set of available ingredient amounts and automatically determine a set of recipes that will utilize those ingredients, leaving the fewest amount of surplus.  I’ve been calling this concept “meal modeling”, though I doubt that’ll turn into any sort of marketing catch phrase.  In the computer science world, we call this an NP-Complete problem.  More analogously, this problem can also be referred to as a 0-1 knapsack problem.  The basic idea is that the only way to figure out the exact set of recipes you would have to make to result in the fewest number of leftover ingredients would be to actually iterate through every combination of possible recipes and keep score.  This might be fine with a small set of recipes, but if the site takes off and the database acquires hundreds of thousands of recipes, the computational requirements would start to become quite substantial.  To add another layer of complexity, we don’t want to assign the same “weight” to every recipe.  Ideally, we should prefer recipes that the user is more likely to enjoy cooking based on an analysis of their previous ratings, their ingredient blacklist, their favorite recipe tags, etc.  Now this becomes a fun problem to solve.  However, this post is not about that because I’m sure not gonna be giving away those secrets!  However, I do want to talk about the challenges in creating the user interface in front of this “meal modeling engine.”

First off, the user needs to be able to define the criteria they wish to use to create a model.  It’s up to them how many recipes they want to have in their plan, which tags they wish to allow (by default, this is set to Dinner, Main Dish, Side or Dessert), and whether to use their saved pantry or manually type in ingredients they have available (as not everyone wants to use the pantry, remember?)

At the bottom of the page is a sliding scale containing five radio buttons.  The left-most radio button has a caption that says, “Find recipes that use my ingredients most efficiently.”  The right-most radio button is labeled, “Find recipes I’m most likely to rate highly.”  The middle option, and default, is simply titled, “Balanced.”

This simple scale is not just there to give the user the illusion of power; this information is taken into account by the meal modeling engine when considering various recipe combinations.

The results page is slightly more challenging from a usability point of view.  I initially considered just using the standard search results template to display the resulting recipes, but this felt like a cop-out for various reasons:

  • There’s no visible correlation between the desired run criteria and the resulting recipe list.  In other words, as far as the user is concerned I just spouted out some random recipes and they’re supposed to trust that this is the best meal plan for them.  Yeah right.
  • It lacks the ability for the user to judge the results as a potential fit for their available ingredients.  The user may ask themselves, “Ok, if I make all of these, am I going to use up that asparagus that’s been sitting in my fridge for a week?”
  • It doesn’t provide the ability for the user to partially select a subset of the results and receive visual feedback on the efficiency of their selection.  “If I only want to use 3 of the 7 recipes suggested, will I need to buy more cheese or do I have enough?”

Ok, so how do we address these issues?  It seems a bit lame to build such a cool meal planning engine and not build an equally cool interface to use it.  I’m still mocking up a wireframe in Balsalmic, but I’d like to share my initial thoughts on this layout.

This results page will share a lot of similarities with the search results page, as users should recognize this user interface and know how to use it already.  For example, the results will be listed vertically with the same information provided (picture, title, description, rating, etc.)  The meal calendar will also be available at the top of the list and fixed on the screen statically so the user can scroll through recipes and still drag any recipe onto the meal calendar.  So far, this design is exactly identical to the search results page.  However, on this page, recipes will also contain a checkbox to check or uncheck individual results.  Checking the box will visually light up the row to make it very obvious this recipe is now part of a group selection.  By default, all rows will be checked.  Furthermore, when a user drags a recipe, the entire selected group will be dragged along with it.  Visual cues will indicate this behavior.  This allows a user to “check” a bunch of recipes and drag them all at once onto the calendar.  When multiple recipes are dragged on to the calendar, they will be spread out starting on the date the user dropped them on to.  Each day after will receive up to one main dish, one side and one dessert.  The user can then arrange these recipes in any way they like by dragging them between dates.

The other UI element on this page is something I’ve been calling an “efficiency graph”, but will probably just be titled “Ingredient Usage.”  This will be a tall, skinny box that lists all ingredients being used by the resulting recipes along with the total amount of that ingredient required to make these recipes.  For example, if one recipe required 3 eggs and the other required 2 eggs, the efficiency graph would contain an entry for “Eggs: 5”

The graph would also be color coded.  At the top of the list would be a section with a green background.  If an ingredient appears in this section, the total required amount would be less than or equal to that which the user has available.  In other words, you have enough of that ingredient to make these recipes so there’s no need to worry.  Below that would be a “yellow” section.  This would contain ingredients that you have some of, but not enough to make all of the desired recipes so you’ll have to buy more.  But at least you’ll use up old stuff!  Below that would be a “red” section indicating you don’t have any of this ingredient and you’ll need to go buy some.  I’m considering providing additional detail using tooltips, which would answer questions such as how much would still be leftover in the green section, or how much you’ll need to buy in the yellow section.  Another “bells and whistles” feature could be when you hover over a recipe, the ingredients light up in the efficiency graph.

As the user checks or unchecks recipes, the efficiency graph would update in real time.  This would give the user a visual representation of what ingredients they’ll be using and what kind of shopping they’ll need to do.  Here, they can play around with scenarios and get instant feedback until they find a set of recipes that works for them.

Ideally, if the user selects the “Use my ingredients efficiently” side of the scale, they should get all green ingredients in the efficiency graph and not have to buy anything.  If they select the “find recipes I’ll like” side of the scale, they’ll see more recipes they would in theory rate higher, but they’ll be more yellow and red items.  Seeing the data represented in this way will allow the user to go back and make changes to their meal plan criteria if they’re unhappy with the results.  Also, since it’s fairly obvious that very few users will keep an extensive pantry stored online, they’ll be able to quickly scan over the red section and double check if they actually have those items on hand.

A poor college student could very quickly find a week’s worth of meals with the ingredients in their fridge and see what they’ll need to pick up at the store.  Other people might not care so much and just use the results as a quick look at what they’ll need as they check off recipes that sound good to them, or just enter the ingredients they want to get rid of and make sure those ingredients end up in the green section.

This is definitely an area that I’m anxious to get real feedback on from beta users during the coming months.  It’s definitely not an easy user interface to design, but my attempts are based on the customer scenarios that I envision for this feature.  It’s also a good example of a design that caters to the “mature” meal planners, who keep an accurate inventory of their pantry online at all times, while still providing some power to the more casual KitchenPC user.  Either way, I’m happy with this as a “first stab” at solving a user interface paradigm that, to my knowledge, no one has really done yet.

House cleaning

Last night, I completely re-wrote my shopping list serialization code.  The old code worked fine, but I just didn’t like the design that much.  With the old design, I used the JSON encoder to serialize the entire shopping list class as one “blob” and stick it in a text field in the database.  This was pretty good for saving, but when the user wanted to add a single item to their shopping list, I’d have to deserialize the existing list, add a single item, then serialize the entire list again.  Removing an item entailed the same ordeal.  Plus, being a serialized text field means performing any sort of query on this data is virtually impossible.

The new design is a bit more straight forward.  I use one table row per shopping list item, with a unique constraint on any user/ingredient pair.  The amounts are always stored in the default unit type of that ingredient.  I do this because this design perfectly matches that of the “user pantry” schema, which has a number of advantages.  Mainly, my “shopping list balancing” code can now be run entirely in SQL.  I can loop through the overlap of pantry/shopping list ingredients and “balance” each row, all with no middleware code since I never have to convert between units.

This design also makes updates and deletes much more efficient.  An update is simply looking for the existence of a single row in the table, and incrementing the value or creating said row.  A delete is a single SQL DELETE statement.

Though this change wasn’t critical for the beta release, there was one incentive that drove me to get this out of the way.  It would virtually be impossible to “upgrade” any existing shopping lists from using JSON serialized data to a fully normalized row based representation.  Sure, I could write a program that cracked open each blob and created the rows, but I’d rather not have to mess with that.  For the Alpha site, I’m perfectly content deleting everyone’s shopping list when I apply the new schema.

When triaging bugs and to-do list items, it’s always good to look down the road and weigh the impacts of putting off potentially destabilizing changes.

Don’t mock me!

Now that I have a UI designer on board, one of the challenges I’ve been facing over the past few days is how to clearly communicate design ideas and keep multiple brains on the same wavelength.  Piotr (my account manager  at Merix) has of course used my prototype site to learn about the product, but the problem with the prototype is the prototype sucks!  The last thing I’d want them to do is use the prototype KitchenPC site as a baseline to understand my design goals and usability requirements.  I’ve also sent them an 18 page Word document that illustrates every page, every common control, and basic user scenarios.  This has the advantage of a feature spec, but as they say, a picture is worth 2^10 words.  Or something like that.

Traditionally, I’ve been mocking up UI prototypes using my favorite tool.  This would be pen and paper.  It’s fast, it’s flexible, and let’s me really visualize a concept and decide if I like it.  If not, I can crumple it up and play basketball with the trash bin.  However, now my desk is littered with dozens of sheets of notebook paper and Piotr would hate me if he had to work with any of my muddled nonsense.  It was actually he that recommended I check out Balsamiq Mockups.  I have to hand it to him, this software is awesome!

It’s an Adobe Air product that runs on Mac, Windows, or Linux and can also be run offline.  The main thing that impressed me about Balsamiq is it has a learning curve of about zero.  I watched a short video on the product which looked impressive, but I just figured that guy knew exactly what he was doing and probably wrote the thing.  However, the very first time I used the product, I mocked up a wireframe of the KitchenPC home page in about ten minutes; and it looked more impressive than anything I could have done with pen and paper.  The images it creates are actually intended to look like “sketches”, using a human handwriting style font, pen looking shading, and lots of rough angles and curves.  Best of all, I can make changes, erase stuff, and drag shapes around.  When I’m done, I can export the file as a PNG image and email it to Piotr.

The product has a seven day free trial, and runs for $79 bucks (though various discounts apply, especially if they consider you a “do-gooder”.)  I haven’t created too many wireframes, but I think this’ll be software I would get my money’s worth from.

KISS me…

I ran across an interesting UI problem the other day, one which made me have to stop and think for a bit rather than rushing in to code (as most programmers are all too eager to do.)  An important paradigm within KitchenPC is the organizational relationship between a shopping list (representing what a user needs to purchase) and a pantry (what the user has available.)  However, keeping these two lists in sync is somewhat of a challenge.  Imaging a user adds a recipe calling for 5 eggs to their shopping list.  Normally, said user would expect to see a list created listing 5 eggs.  However, if the user’s pantry had 3 eggs, only 2 eggs need be purchased.  Should we take the user’s pantry into account when creating a shopping list, and only add 2 eggs to the list?

This was a direction I was pondering.

However, after considering the importance of understanding the varying discipline levels of users, I decided this approach could end up horrendously bad.  Not only does this make an assumption about the validity of the user’s pantry, attributing a sense of narcissism to my software (of course every user will slave away all day creating accurate pantries!) but also makes an assumption about the user’s desired way of working.  After reading my earlier post about Microsoft Project, one may have a more well defined appreciation of this concept.

Ok, let’s make our first decisions about what not to do.  We will not assume the user’s pantry is accurate or that the user wants to deduct inventory from their pantry when creating a shopping list.  We do not want seemingly random results to appear on the shopping list with no indication that KitchenPC was just “being smart” and utilizing your so-called inventory.  However, we are meal planning software and designed to manage inventory, suggest meals that are possible to create with your inventory, and attempt to provide accurate information on what you need to acquire to make your meal plan possible.  Thus, there needs to be a feature set that makes possible the scenario of comparing a set of recipes to what you have, and ascertaining what you need.

One solution I considered was to make this behavior optional.  When you add a recipe to your shopping list that contains 5 eggs and your pantry contains 2, the UI could present the user with a choice: “Hey user, your pantry contains 2 eggs and this recipe calls for 5.  Do you wish to subtract the 2 eggs from your pantry and add the remaining 3 eggs to your shopping list?”  This has the following problems:

  1. It’s annoying.  If I click on a button I want stuff to happen.  If anything pops up, studies suggest no one actually reads it and they’ll just assume it’s an error case.  If there’s a Yes button, they’ll immediately click on it just hoping it’ll do the thing they wanted to get done in the first place.
  2. It doesn’t scale.  If I add a recipe with 50 ingredients, I don’t want this massive UI to settle “conflicts” between my pantry and shopping list.
  3. It doesn’t adapt to all UI paradigms.  Adding a single recipe to a shopping list through a toolbar might be okay, but dragging recipes onto the shopping list should be seamless, not spawn questions for the user to answer.
  4. It assumes a finality of decision.  I shall explain this.

Point #4 is the one that led me to rethink my logic.  Dragging meals onto a calendar, creating shopping lists, removing items from the shopping list, etc, are all what I consider “draft actions.”  That is, they’re intermediary steps taken by the user during the process of assembling a final meal plan.  Imagine if I subtracted items from the user’s pantry for a certain recipe, then they removed said recipe from their shopping list or meal plan.  Do I “restock” their pantry with the items I took away?  Oh boy, this could get confusing real fast!  In actuality, doing anything at all was premature at this stage.  This made me realize that I was missing a dirt simple solution that solved all the problems above.  Let the user tell me when to “balance” the shopping list and pantry.

The implementation that, in the end, made the most sense to me is a single button on the shopping list widget.  Clicking on this button subtracts any amounts from the pantry from the shopping list.  If the shopping list contained 5 eggs and the pantry contained 3, the eggs would be removed from the pantry and the shopping list would be updated to 2.  If the shopping list contained 1 apple and the pantry contained 3, the apple would be removed from the shopping list and the pantry would be updated to contain 2.  This has the following advantages:

  1. It’s optional.  If the user doesn’t like or use the pantry, they need never click this button.  A user who never discovers this button would not be inconvenienced by an assumption made about the way the user uses the product.
  2. It’s intended to be used as a final step.  The user can meal plan all day long, or all week and not mess with this button.  When the user is about to head to the store, only then will they click this button.  They can even go through their pantry first and make sure everything’s up to date.
  3. It explains exactly what’s going on.  The button, once clicked, would explain to the user exactly what it’s doing.  Since the action is not linked to an unrelated feature (such as adding a recipe to a shopping list), assumptions are not made about any popup alert that appears.  A user clicking on this button either has no idea what it will do and will tread carefully, or they will be aware of the feature and know how to use it.

In my mind, this is a prime example of KISS.  Keep It Simple Stupid.  Trying to make the system too smart, or “merge” features in with other features, often just leads to confusion, or bad assumptions about the scenarios those features are based on.  An advanced feature such as “pantry balancing” (no, I’m not attached to that name) is one that should exist on its own and not try to “pop up” when it wasn’t invited.

Mike

What do Microsoft Project and KitchenPC have in common?

For about three quarters of my Microsoft career, I worked on Microsoft Project.  To some, it may seem like leaving to pursue meal planning is about the most radical switch I could make.  For one, rather than business customers I’m now focusing on poor college students, aspiring cooks, and soccer moms.  Second, it’s a web site rather than a boxed product or server software you install.  However, there’s a key similarity; a parallel I’ve drawn which leads me to believe there’s some lessons I can take away from my work on Project.  That would be in our respective ability to tolerate and adapt to the maturity of our costumer base.  I’m not talking about maturity as in fart jokes, but rather the discipline in which one regulates their lives through our respective products.

Project really didn’t understand this for ages.  They didn’t even really “get it” until Project 2010, which was just signed off on the day I left.  For Project to be incredibly useful to people, it has to know about the entire universe of your project.  Every tiny little detail, every work item, every resource involved, how these resources work, how they bill, their schedules, you name it.  This is fine if you have a professional project manager who wants to plug in all this data, and you have resources that are more than willing to enter accurate data regarding how long they’ve worked on a task, how much work is left, when it will be finished, or even the percent complete the task is.  For most industries, people just won’t want to do this.  In fact, the cost overhead of managing this level of detail and keeping it up to date is such where one wouldn’t realize any cost savings until they were dealing with huge projects with hundreds or thousands of tasks and dozens of resources.  For this reason, Project was relegated to industries that managed large, multi-million dollar projects.  For smaller customers, our biggest competitor was Excel.  Using a simple Excel spreadsheet, one could create a short list of items, type in some assignees, and manage attributes on these tasks in a free-form manner.  One of the big features of Project 2010 was the ability to enter arbitrary dates on a task, such as “someday” or “First Quarter” or just leave it blank.  The Project scheduler could run in such a way where it would “do its best” with the information it had available, without pestering users to provide data that might not be known at the time.  In short, it targeted less mature organizations that didn’t have disciplined project management techniques.

KitchenPC, due to its orginal desires to be an actual PC in the kitchen, is designed from the ground up to be not only a handy website for cooks, but also a platform for developers and hardware manufacturers.  The long term business goal is to get companies such as LG, Samsung, KitchenAid, etc to want to tie their hardware into the KitchenPC backend.  These products might have their own “skinned” user interfaces, but ultimate call into KitchenPC’s network and access those data.  Imagine a fridge that keeps track of its own inventory, or an oven that will pre-heat because it knows what recipe you’re cooking.  All these things might not be too far off.

However, this vision at the moment can only be seen on a few science fiction movies that take place in the future, some less realistic than others.  For this platform to achieve usefulness with today’s cooks, it has to realize that very few users will actually plan meals in advance,actually stick to that exact meal plan, or have any desire to maintain their exact set of available ingredients, and amounts, online.  Imagine having to type in exactly what you used every time you ate.  Sure, the website would be incredibly powerful if it actually did have this information, but for now, it needs to be able to deal with ambiguities.  The same way Project had to learn to deal with not having all the data, all the time.

This is a challenge that has not gone unnoticed, and a parallel that has manifested itself on several occasions over the past few months of development efforts.  While designing features, I need to provide a lot of reward for those who actually wish to accurately track all meals and all inventories (these target customers might be retirement homes, very large families, jails, hospitals, etc) while not annoying the crap out of everyone else or making assumptions about data.  Features such as subtracting amounts from the pantry when you cook a meal have to be optional and controllable by the user.  No feature can assume the pantry to be an end-all-be-all tally to the user’s inventory.  And it should be expected that a user’s tally will not be maintained, kept up to date, or maybe even used at all.  If ever, it might be used to store the major ingredients that have a shorter shelf life, or favorite ingredients that the user wants to find recipes for.  How people use the pantry is something I’m very exciting about seeing during the beta release.

I hope some day in the not too distant future, we’ll have smart homes that use RFID tags to manage ingredients on hand.  When users purchase ingredients at the grocery store, their purchases should automatically be tied into their account and show up online.  These are the kinds of things I want to build with this platform down the road, but for now I have to build a product that’s fun, useable and useful to the regular people of today.

Zgoda!

So I’ve accepted an offer from Merix Studio (the design firm located in Poland) and the contract should be finalized tomorrow!  This is exciting, I just can’t wait to see my visions for KitchenPC really come to life through the talents of a professional and committed design firm.  Their bid was slightly higher than Duck Pond, Inc but their portfolio really impressed me and gave me no doubt that they’ll be more than equipped to handle my little site.

I think another thing that made this work out was the fact I was able to talk with their sales manager on Skype for several hours to really discuss ideas in a lot more detail.  This worked a lot better than email, and I think led to a bid that was more detailed and really spelled out exactly what it would entail.  I felt with the other bid, it was just a rough estimate to get the job, and there might be future “nit picking” about exactly what they’d be responsible for doing.  With that said, the two companies were very competitive and the decision was not easy.  I think I made the right choice though.

Hmm this recipe calls for a whole chicken, and 3 eggs

Being involved in the Seattle entrepreneur scene, I hear no shortage of dot-com startup ideas.  Some better than others.  However, I’ve noticed a recurring trend in a lot of these ideas.  They depend on their own success before they can be successful.

Many of these ideas are basically social networks, which help a community of users achieve some sort of goal.  For example, maybe a location driven service that pops up advertisements or coupons when you walk by a store.  Or an online storefront engine to allows people to sell their products online.  These ideas are all incredibly difficult to get off the ground for one simple reason.  They have to be successful first before anyone will start using them.  You probably wouldn’t use Facebook unless all your friends were on there.  You probably wouldn’t advertise on Craig’s List unless thousands of people were reading your post.  Sure, these sites became successful but they probably did something right and also got extremely lucky.  You pretty much need something to take off virally in order to get any traction with this approach.

For those coming up with business ideas, I think it’s important to imagine a scenario where there’s only one user, or only 10 users.  Is it still a good idea?  Is it still useful in the least?  What value will you provide immediately, before you have a million users?

One goal for KitchenPC is to really provide value to a single user.  KitchenPC will have social networking features, subscriptions, shared calendars, etc; however those features are all secondary to the simple ability to make meal planning easier and fun for the average person.  Once you’re providing the individual with a service and your user base grows, only then can you capitalize on business or revenue strategies that make use of the network of people you’ve built.

Just something I’ve been thinking about while cooking dinner.

Mike