<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>KitchenPC</title>
	<atom:link href="http://blog.kitchenpc.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.kitchenpc.com</link>
	<description>A Day in the Life of a Seattle Entrepreneur</description>
	<lastBuildDate>Wed, 30 May 2012 18:09:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.kitchenpc.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/928baf1945eb2fa76a731ad797a59e5b?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>KitchenPC</title>
		<link>http://blog.kitchenpc.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.kitchenpc.com/osd.xml" title="KitchenPC" />
	<atom:link rel='hub' href='http://blog.kitchenpc.com/?pushpress=hub'/>
		<item>
		<title>The Itsy Bitsy Spider (Part 1)</title>
		<link>http://blog.kitchenpc.com/2012/05/30/the-itsy-bitsy-spider-part-1/</link>
		<comments>http://blog.kitchenpc.com/2012/05/30/the-itsy-bitsy-spider-part-1/#comments</comments>
		<pubDate>Wed, 30 May 2012 18:09:01 +0000</pubDate>
		<dc:creator>kitchenpc</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://blog.kitchenpc.com/?p=994</guid>
		<description><![CDATA[Spiders have existed for millions of years, as one of the most diverse members of the animal kingdom.  Relatively recently, their digital counterparts also started crawling over a different kind of web, attempting to find every last web page on the Internet.  This has been a tool used by search engines since the early days <a href="http://blog.kitchenpc.com/2012/05/30/the-itsy-bitsy-spider-part-1/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=994&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Spiders have existed for millions of years, as one of the most diverse members of the animal kingdom.  Relatively recently, their digital counterparts also started crawling over a different kind of web, attempting to find every last web page on the Internet.  This has been a tool used by search engines since the early days of the Internet, employing hundreds of thousands of servers which do nothing all day but surf the web.</p>
<p>Fortunately, KitchenPC doesn&#8217;t need to index the entire Internet, however as a recipe search engine, it needs an automated way to search for recipes online and cache them locally to provide users with the ability to locate recipes quickly and easily.</p>
<p>Since I&#8217;ve never worked for a search engine company, I had pretty much zero experience building a web crawler.  I made a few mistakes along the way, which I&#8217;ve decided might be helpful or at least interesting enough to write a two-part blog series on.</p>
<p>My implementation is divided into two separate processes.  The first process does nothing but crawl websites, slurping any HTML it can find into a database.  The second process processes that database and attempts to parse any recipes it can find out of that HTML data.  This post will go into details about that first process.</p>
<h3>The First Attempt</h3>
<p>Having very little experience in this field, I decided it best to use something already available and preferably open source to actually crawl websites.  Knowing I wasn&#8217;t the first one to have such a need, I looked into a few platforms that do this sort of thing.  The one I decided upon is called <a href="http://scrapy.org/" target="_blank">Scrapy</a>, and is a Python based framework for writing fast, efficient and scalable crawlers.</p>
<p>Scrapy is very quick to get up and running, even if you have next to zero Python knowledge, and is also very well documented.  It has various behaviors built in, such as the ability to read <a href="http://www.sitemaps.org/" target="_blank">sitemaps</a>, follow any link it finds, and honor <a href="http://www.robotstxt.org/" target="_blank">robots.txt</a> restrictions.  Of course you can also override any of these behaviors, and use as little or as much of it as you&#8217;d like.</p>
<p>Scrapy has the ability to parse HTML and extract only the data it needs out of each webpage it finds.  That data can be serialized as XML or JSON, or just dumped out to the console.  One of the first mistakes I made was attempting to extract the actual recipe data at this stage.  The <em>documented</em> way of parsing HTML with Scrapy is using a built in DOM parser that offers an XPath style navigator.  Though this might be useful for crawling a site where the format is exactly known, I found this too limited in my case.</p>
<p><a href="http://kitchenpc.files.wordpress.com/2012/05/cookieresult.png"><img class="alignright size-medium wp-image-995" title="CookieResult" src="http://kitchenpc.files.wordpress.com/2012/05/cookieresult.png?w=300&h=57" alt="" width="300" height="57" /></a>My case is somewhat special, as I&#8217;m not exactly trying to crawl a specific site in particular.  Instead, I want to crawl <em>any</em> site that exposes data using the <a href="http://microformats.org/wiki/hrecipe" target="_blank">hRecipe Microformat</a>.  Web and SEO experts will know this is a special markup that allows parsers to extract specific data from a website, abstracted from the layout itself.  For example, certain sections of HTML can be tagged as a recipe title, an ingredient, a rating, etc.  If you&#8217;ve ever searched for recipes on Google and seen a result such as the chocolate chip cookie recipe above, this is because the site encodes its data in this format.</p>
<p>The issue is the hRecipe specification is unfinished, incomplete, and implemented differently on almost every site I&#8217;ve found.  It also creates various situations where a single XPath query wouldn&#8217;t be able to handle <em>any</em> valid hRecipe markup.  I&#8217;ll get more into this in Part 2.</p>
<p>So instead I ripped out the default DOM parser in Scrapy and decided to go with a more powerful one instead.  This parser might be familiar to other Python coders; <a href="http://www.crummy.com/software/BeautifulSoup/" target="_blank">BeautifulSoup</a>.  BeautifulSoup not only has one of the coolest names, it&#8217;s hands down the best HTML parser I&#8217;ve ever used &#8211; on <em>any</em> platform.  Rather than static XPath expressions, you&#8217;re able to really craft an expression using the power of Python.  For example, if I wanted to find all hyperlinks with a <em>Class</em> attribute of <em>Test</em> that contained the word &#8220;foo&#8221; somewhere in the title, I could do something like:</p>
<pre><code>soup.FindAll("a", new { Class = "Test", Title = new Regex("foo") }); </code></pre>
<p>BeautifulSoup is actually so cool, I&#8217;m tempted to write a .NET port of it if I ever find the time for such side projects.</p>
<h3>No Soup For Me</h3>
<p>Unfortunately, BeautifulSoup still had some issues.  I&#8217;m quite sure it would technically be possible to write an hRecipe parser in Python, but my Python is a bit weak and I kept running into little edge cases that were very difficult to work around.  For example, some recipe sites put HTML markup inside the recipe title, and this became hard to convert to raw text.</p>
<p>A huge reason why I halted efforts on this route was to avoid a Python reliance in the future.  Eventually, I&#8217;d like users to be able to add recipes to menus either by pasting in a URL directly or by using a browser extension that&#8217;s able to recognize recipe websites automatically.  Since I don&#8217;t want to have to call into Python code on the website, it became clear that I eventually needed to migrate my recipe parsing code to C#.</p>
<p>There&#8217;s also one other huge issue.  I was bound to screw up.  Crawling hundreds of thousands of webpages and extracting recipe information is something that takes weeks or even months.  Suppose I forgot one little piece of metadata, or later on I improved my parser to do x, y and z?  Surely, I didn&#8217;t want to have to re-crawl all those websites over again.  At this point, I made the decision to use Scrapy to simply store the entire HTML response rather than trying to parse anything at all.  That way I could handle the recipe extraction as a separate process offline, and redo it as many times as I wanted without re-downloading gigs of data from the Internet.</p>
<h3>A Somewhat Working Design</h3>
<p>I now had a design that worked pretty well.  Scrapy would crawl a website, following any link it could find, and whenever it came across a page with the word <em>hrecipe</em> in the HTML, it would dump that HTML to a Postgres database I had setup for indexing.</p>
<p>At least I could now start crawling, a process I knew needed to get underway as soon as possible.  I let the default Scrapy crawler run (which is able to download the Sitemap as well as follow any links it finds in the HTML) on a couple major websites.</p>
<p>After about two weeks running nonstop, I had about 20,000 recipes in the database.  That is until a bit of wind knocked out the power to my house.</p>
<h3>Oh Noes!</h3>
<p>I had one small design flaw with my crawler.  If it were interrupted for whatever reason, it had no way to resume where it left off.  I really didn&#8217;t want to waste another two weeks starting over again, so I decided to take that opportunity to improve the design a bit.</p>
<p>First off, the crawler was far too slow.  Looking at the output, I noticed that <em>most </em>pages the crawler was finding were not recipes at all.  For example, some of the more popular recipes would have 50 or 60 pages of comments, so I would find myself crawling URLs such as <em>/Recipes/Foo/Comment.aspx?page=37</em> and what not.  Surely there had to be a better way.</p>
<p>Another huge issue surfaced when I started looking at the URLs in the SQL database as well.  Scrapy is smart enough to not crawl the same URL twice, but it&#8217;s only as reliable as the uniqueness of the URL itself.  Out of the 20,000 or so recipes I had, I noticed a lot were of the same recipe only with different URL parameters.  These URLs might be something like <em>/Recipes/Cake.aspx?src=home</em> and <em>/Recipes/Cake.aspx?src=comment</em>.  There were also some URLs that redirected to another already existing URL, and Scrapy would only know about the first URL.  Long story short, I had somewhere around 9,000 recipes that were a part of a duplicate set, and they were incredibly hard to get rid of.  I ended up just getting rid of these, as I didn&#8217;t trust the integrity of the data.</p>
<p>At this point, I came to the conclusion that deep-crawling any site was the wrong approach.  Though this might work well for a search engine like Google, which simply lists all the pages that match a given query, it does <em>not </em>work well for a recipe search engine where I want to display each recipe only once.</p>
<h3>Finally, a Working Design!</h3>
<p>Most sites export a list of their URLs through a Sitemap file located in the root directory.  Search engines use this file as a &#8220;starting point&#8221; to crawl a site, and also discover pages that might not be linked to from elsewhere.  Luckily, the major recipe websites provide a list of most, if not all, of the recipes on their site.</p>
<p>I decided to download the Sitemap files of several major recipe websites, remove any patterns that were not actual recipes, and then add this list to a Queue table in my database.  I just did this by hand, though it could  be easily automated later on.  Rather than follow any link found, I would now just query the <em>Queue</em> table.  This allowed me to create a SQL view called <em>Pending</em>, which returns the rows from <em>Queue</em> that do not have a matching record in the <em>Pages</em> table, meaning they have not yet been crawled.  I also return the rows in <em>Pending</em> in a random order, as not to pound on a single site too much at once.</p>
<p>I then modified my Scrapy script to <em>SELECT * From Pending</em> and start its work.  Now if the power went out again, the script could be resumed right where it left off!</p>
<div id="attachment_996" class="wp-caption alignleft" style="width: 310px"><a href="http://kitchenpc.files.wordpress.com/2012/05/count1.png"><img class="size-medium wp-image-996" title="Indexer Count" src="http://kitchenpc.files.wordpress.com/2012/05/count1.png?w=300&h=190" alt="100,000 Recipes Crawled!" width="300" height="190" /></a><p class="wp-caption-text">100,000 Recipes Crawled!</p></div>
<p>This design was far more efficient.  In less than a day, I was already back at the 20,000 mark, which took me over two weeks to get to the first time.  After about a week or so, I had parsed over 100,000 recipes from various sites on the Internet for a total of about 16 billion bytes of data downloaded.</p>
<p>Finally, I had a working crawler that would efficiently gather recipes from the Internet, have the ability to start and stop at any time, and save HTML in a database to be parsed later down the line.</p>
<h3>A Few Ideas</h3>
<p>Obviously, this is just a rough prototype of a fully automated crawler that would require no human interaction and support any number of websites.  I already have a few ideas in mind that would make this crawler even better.</p>
<p>First off, the crawler needs to be able to re-crawl a URL after a certain period.  I might want to re-check a URL after 30 days or so, and if the recipe has been changed, import the new HTML and update the existing linked recipe on KitchenPC.  Right now, I store timestamps for everything so it wouldn&#8217;t be too much work to modify the <em>Pending</em> view to also return URLs that were already crawled, but have a <em>LastCrawled</em> date of more than 30 days ago.</p>
<p>Second, disk space is potentially an issue if I truly want to index millions of recipes.  Luckily, Postgres will <a href="http://www.postgresql.org/docs/9.0/static/storage-toast.html" target="_blank">TOAST </a>these rows automatically, compressing the data if possible.  The 16 gigs I&#8217;ve crawled only take up about 7 gigs on the disk.  I&#8217;ve considered using a byte array in the database instead, and storing the HTML data as a compressed gzip stream, however I&#8217;m unsure if I&#8217;d get any better compression out of that.</p>
<p>Though storing the entire HTML has its advantages, it might be overkill especially once the parser itself is relatively stable.  I could potentially modify the crawler to only store the HTML related to the hRecipe microformat itself.  This would save considerable disk space, while still allowing me to re-parse recipes if my indexing code changed.</p>
<p>I&#8217;m also still worried about duplicate recipes.  One solution would be to implement a hash algorithm at the recipe level.  I could combine the ingredients, title, description, method, etc and calculate an MD5 hash of the data.  I would store this hash within the Recipes table, and check to see if the hash already existed before adding a new recipe to KitchenPC.  I spent quite a bit of time mucking with Sitemaps in a text editor (some of them millions of lines long!) attempting to remove duplicate recipes or irrelevant URLs, all because I was so nervous about having the same recipe twice in KitchenPC.  Adding this hashing check would definitely ease my fears.</p>
<h3>Stay Tuned!</h3>
<p>In the next post, I&#8217;ll be talking about the actual indexer.  This code is written in C#, and is able to actually parse the HTML obtained from the web crawler into valid KitchenPC formatted recipes.  Exciting stuff!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kitchenpc.wordpress.com/994/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kitchenpc.wordpress.com/994/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kitchenpc.wordpress.com/994/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kitchenpc.wordpress.com/994/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kitchenpc.wordpress.com/994/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kitchenpc.wordpress.com/994/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kitchenpc.wordpress.com/994/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kitchenpc.wordpress.com/994/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kitchenpc.wordpress.com/994/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kitchenpc.wordpress.com/994/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kitchenpc.wordpress.com/994/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kitchenpc.wordpress.com/994/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kitchenpc.wordpress.com/994/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kitchenpc.wordpress.com/994/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=994&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kitchenpc.com/2012/05/30/the-itsy-bitsy-spider-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4df33f9e8a81cc9d8046f057dbb4debc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kitchenpc</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/05/cookieresult.png?w=300" medium="image">
			<media:title type="html">CookieResult</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/05/count1.png?w=300" medium="image">
			<media:title type="html">Indexer Count</media:title>
		</media:content>
	</item>
		<item>
		<title>Mechanical Turkey</title>
		<link>http://blog.kitchenpc.com/2012/05/23/mechanical-turkey/</link>
		<comments>http://blog.kitchenpc.com/2012/05/23/mechanical-turkey/#comments</comments>
		<pubDate>Wed, 23 May 2012 22:55:52 +0000</pubDate>
		<dc:creator>kitchenpc</dc:creator>
				<category><![CDATA[Business]]></category>

		<guid isPermaLink="false">http://blog.kitchenpc.com/?p=968</guid>
		<description><![CDATA[These days, much of the time that I would like to devote to working on my web crawler has been usurped by randomizations with pre-made meal plans.  I fret that I&#8217;m woefully behind on my goal of having ten pre-made meal plans (one for each category) by launch; though I have been moderately successful in getting <a href="http://blog.kitchenpc.com/2012/05/23/mechanical-turkey/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=968&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>These days, much of the time that I would <em>like </em>to devote to working on my web crawler has been usurped by randomizations with pre-made meal plans.  I fret that I&#8217;m woefully behind on my goal of having ten pre-made meal plans (one for each category) by launch; though I have been moderately successful in getting some friends, as well as  some in the professional realm, to assist with this project.  One thing I have <em>not</em> been able to get much assistance with is recipe photography.</p>
<p>It&#8217;s very important to me to have ten really good, well tested and well thought-out meal plans for launch.  I want to show off what the site can do with these plans.  I want to individually advertise each of these plans on Facebook and Google.  I want whatever press I can muster up for launch to eat these plans up, and keep users coming back for more.</p>
<p>Obviously, one of the keys to good recipe content is good recipe pictures.  Unfortunately, most of the content I&#8217;m getting from nutritionists and dieticians is in the form of a Word document or PDF, and usually sans pictures.  I&#8217;ve had a little luck getting some friends to try some of the recipes out and snap some shots, however this approach would result in me losing friends faster than achieving my goals.</p>
<p>Yesterday, I decided to try a new approach.  Yes, once again, Amazon&#8217;s <a href="https://www.mturk.com" target="_blank">Mechanical Turk</a> service.</p>
<p>Those who frequently peruse my ramblings might be asking, &#8220;But Mike?  Didn&#8217;t you try out Mechanical Turk before and declare it a scam-ridden wasteland of automated succubots, ensuring any user dumb enough to use it would surely spend more time cleaning up the mess it created than any time savings yielded?&#8221;</p>
<p>Well, yes I probably did say something similar to that.  But this is different!  Let me tell you why!</p>
<h3>Protip: Ignore Amazon when they tell you Turk is designed for short, quick repetitive tasks.</h3>
<p>&nbsp;</p>
<p>When I tried Mechanical Turk before, I was using it for ingredient matching.  For example, I&#8217;d upload a list of ingredient usages found across thousands of recipes.  The goal would be to match something like &#8220;4 cups of shredded cheddar cheese&#8221; to the number 4, the unit &#8220;cups&#8221; and the &#8220;shredded&#8221; form of &#8220;cheddar cheese&#8221;.  This was somewhat of a crowd sourced version of the <a href="http://blog.kitchenpc.com/2011/07/06/chef-watson/" target="_blank">natural language parsing technology</a> I have since developed.</p>
<p>This approach failed because the results would be tainted by scammers that are hoping to make a quick buck.  I&#8217;m quite certain some of them are running automated scripts to just fill out random answers to any Turk HIT they can find.  This caused issues such as over 1,000 HITs getting matched with <a href="http://blog.kitchenpc.com/2010/11/04/show_me_the_content/" target="_blank"><em>Captain Crunch cereal</em></a>.  This created a mess that was nearly as difficult to clean up as the BP oil spill.</p>
<p>Turk experts would chime in here saying building a reliable team of workers is something that doesn&#8217;t just happen overnight.  I should have tests to pass first, approve each worker individually, assign each HIT to multiple workers to ensure a consensus, blah blah blah.  Unfortunately, I had time for <em>none</em> of that so I&#8217;ve instead declared Mechanical Turk to be a bad fit for that particular task.  It turned out writing a natural language parser was a lot more <del></del>geeky anyway.</p>
<p>So, I gave this another shot with recipe pictures.  Who wouldn&#8217;t want to cook a recipe and take a picture of it for money, right?  I decided to start out with a meal plan being developed by <a href="http://www.sayidonutrition.com/" target="_blank">Say I Do Nutrition Services</a> in Seattle.  This plan has seven recipes, and I already had pictures for two of them.  I created five Mechanical Turk HITs that basically said, &#8220;Cook this recipe, take a picture of it, make sure it&#8217;s not a crappy picture or I&#8217;ll reject it, and don&#8217;t just steal a picture of something similar online because I&#8217;ll know.&#8221;</p>
<p>I gave each worker 12 hours to complete the job after they accepted the HIT, allowing people to make it for their families for dinner last night.  Oh, and I also restricted the work force to only those in the U.S.  I&#8217;m not racist or xenophobic or anything, I just think most of the scams and bot-thingies are going on over seas, perhaps funded by fake Nigerian princes.  For this job, I require nice southern housewives trying to feed their two-and-a-half kids.</p>
<p>I also paid $20 a HIT, which I think should more than cover all the ingredients involved.</p>
<h3>The Results</h3>
<div id="attachment_969" class="wp-caption alignright" style="width: 121px"><a href="http://kitchenpc.files.wordpress.com/2012/05/sandwich.jpg"><img class=" wp-image-969  " title="NOT Beef Stew" src="http://kitchenpc.files.wordpress.com/2012/05/sandwich.jpg?w=111&h=147" alt="NOT Beef Stew" width="111" height="147" /></a><p class="wp-caption-text">NOT Beef Stew</p></div>
<p>Within about 20 minutes, I got one HIT completed for a beef stew recipe.  Considering that recipe takes four hours to cook, I knew it was a fake.  Sure enough, attached to the HIT was a link to a random picture on the Internet of a sandwich.  Mmm, sandwich.  But no, this was not what I was hoping for.  Within a few clicks, I was able to reject the HIT, sending it back to the available HIT pool for someone else, as well as block the user so they could bother me no more with their sandwich-based trickery.  Only worrying about five HITs was <em>far </em>easier to manage, so this slight detour was hardly annoying and perhaps slightly entertaining.</p>
<p>One thing that Mechanical Turk lacks is the ability to see how many workers have accepted a HIT.  In fact, you get no feedback at all until they actually submit the results.  For this reason, nothing happened for about five hours.</p>
<div id="attachment_970" class="wp-caption alignleft" style="width: 160px"><a href="http://kitchenpc.files.wordpress.com/2012/05/broiledsalmon.jpg"><img class="size-thumbnail wp-image-970" title="Broiled Salmon" src="http://kitchenpc.files.wordpress.com/2012/05/broiledsalmon.jpg?w=150&h=99" alt="Broiled Salmon" width="150" height="99" /></a><p class="wp-caption-text">Broiled Salmon</p></div>
<p>Then, all evening, I started getting various pictures submitted of each of the five recipes.  A lot of the submissions contained a dozen or more pictures, from various angles and lighting.  Several were very artistic, such as the recipe for <em>wine stew </em>included a glass of red wine next to it. A few included comments saying how much they enjoyed the recipe, and that this was the best job they&#8217;ve ever found on Mechanical Turk.  I had absolutely no problems with any of the photos submitted, and I added all five workers to a custom group so I can use them again later.</p>
<h3></h3>
<h3>Bonus!</h3>
<p>Another highlight of this approach was free advertising.  Not only did I see a huge spike in website traffic right after I posted the HITs, I also got a few unsolicited emails, such as this one:</p>
<blockquote><p><em>I wouldn&#8217;t be able to make the meal though I would love to. I just wanted to let you know that I am impressed with the recipe site and will be using it in the future! Thank you!</em></p></blockquote>
<p>Several of the workers also said they loved the site and would be coming back as well.  This makes sense, of course, as the posted job seeks the exact same target demographic as my website itself does; people who can and love to cook.  Not only did I get photos for all five recipes, I also got a few new users for the site!</p>
<p>Though this approach is a bit expensive, at $100 bucks for 5 recipe photos, it might be the best way to get ten meal plans up and ready for launch.  I don&#8217;t think going much lower than $20 per recipe would yield the quality I expect, plus I think it&#8217;s fair to at least cover the cost of the ingredients.</p>
<p>With that said, I think I&#8217;ll try to cook as many recipes as I can myself, and continue to pester friends and family to help out as well, but knowing I can quickly get photos of any leftover recipes I have within a day definitely lifts away a lot of the stress associated with building this content.</p>
<table style="border:0;" width="433" border="0" rules="none">
<tbody>
<tr>
<td>
<p><div id="attachment_971" class="wp-caption aligncenter" style="width: 160px"><a href="http://kitchenpc.files.wordpress.com/2012/05/flanksteak.jpg"><img class="size-thumbnail wp-image-971 " title="Flank Steak" src="http://kitchenpc.files.wordpress.com/2012/05/flanksteak.jpg?w=150&h=112" alt="Flank Steak" width="150" height="112" /></a><p class="wp-caption-text">Flank Steak</p></div></td>
<td>
<p><div id="attachment_973" class="wp-caption aligncenter" style="width: 160px"><a href="http://kitchenpc.files.wordpress.com/2012/05/winestew.jpg"><img class="size-thumbnail wp-image-973 " title="Wine Stew" src="http://kitchenpc.files.wordpress.com/2012/05/winestew.jpg?w=150&h=111" alt="Wine Stew" width="150" height="111" /></a><p class="wp-caption-text">Wine Stew</p></div></td>
</tr>
<tr>
<td>
<p><div id="attachment_972" class="wp-caption aligncenter" style="width: 160px"><a href="http://kitchenpc.files.wordpress.com/2012/05/salmonstirfry.jpg"><img class="size-thumbnail wp-image-972 " title="Salmon Stir Fry" src="http://kitchenpc.files.wordpress.com/2012/05/salmonstirfry.jpg?w=150&h=111" alt="Salmon Stir Fry" width="150" height="111" /></a><p class="wp-caption-text">Salmon Stir Fry</p></div></td>
<td>
<p><div id="attachment_974" class="wp-caption aligncenter" style="width: 160px"><a href="http://kitchenpc.files.wordpress.com/2012/05/tofu-stir-fry.jpg"><img class="size-thumbnail wp-image-974 " title="Tofu Stir Fry" src="http://kitchenpc.files.wordpress.com/2012/05/tofu-stir-fry.jpg?w=150&h=112" alt="Tofu Stir Fry" width="150" height="112" /></a><p class="wp-caption-text">Tofu Stir Fry</p></div></td>
</tr>
</tbody>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kitchenpc.wordpress.com/968/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kitchenpc.wordpress.com/968/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kitchenpc.wordpress.com/968/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kitchenpc.wordpress.com/968/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kitchenpc.wordpress.com/968/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kitchenpc.wordpress.com/968/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kitchenpc.wordpress.com/968/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kitchenpc.wordpress.com/968/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kitchenpc.wordpress.com/968/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kitchenpc.wordpress.com/968/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kitchenpc.wordpress.com/968/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kitchenpc.wordpress.com/968/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kitchenpc.wordpress.com/968/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kitchenpc.wordpress.com/968/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=968&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kitchenpc.com/2012/05/23/mechanical-turkey/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4df33f9e8a81cc9d8046f057dbb4debc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kitchenpc</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/05/sandwich.jpg?w=225" medium="image">
			<media:title type="html">NOT Beef Stew</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/05/broiledsalmon.jpg?w=150" medium="image">
			<media:title type="html">Broiled Salmon</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/05/flanksteak.jpg?w=150" medium="image">
			<media:title type="html">Flank Steak</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/05/winestew.jpg?w=150" medium="image">
			<media:title type="html">Wine Stew</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/05/salmonstirfry.jpg?w=150" medium="image">
			<media:title type="html">Salmon Stir Fry</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/05/tofu-stir-fry.jpg?w=150" medium="image">
			<media:title type="html">Tofu Stir Fry</media:title>
		</media:content>
	</item>
		<item>
		<title>Data, data everywhere: Using DBLink for PostgreSQL</title>
		<link>http://blog.kitchenpc.com/2012/05/15/data-data-everywhere-using-dblink-for-postgresql/</link>
		<comments>http://blog.kitchenpc.com/2012/05/15/data-data-everywhere-using-dblink-for-postgresql/#comments</comments>
		<pubDate>Tue, 15 May 2012 19:19:44 +0000</pubDate>
		<dc:creator>kitchenpc</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://blog.kitchenpc.com/?p=949</guid>
		<description><![CDATA[Those who know me know I&#8217;m a huge fan of PostgreSQL.  In fact, KitchenPC uses it exclusively for all its database needs.  Recently, I developed a solution to easily facilitate the moving of data between my production database and staging database, as the latter is currently being used to test the re-invention of the site. <a href="http://blog.kitchenpc.com/2012/05/15/data-data-everywhere-using-dblink-for-postgresql/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=949&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Those who know me know I&#8217;m a <em>huge</em> fan of <a href="http://www.postgresql.org/" target="_blank">PostgreSQL</a>.  In fact, KitchenPC uses it exclusively for all its database needs.  Recently, I developed a solution to easily facilitate the moving of data between my production database and staging database, as the latter is currently being used to test the re-invention of the site.</p>
<p>Since the two database schemas are often slightly different, traditional approaches of exporting and importing database dumps simply don&#8217;t work very well, and would be cumbersome if I simply wanted to pull in a few rows of data.  In fact, one scenario in particular where this ability comes in handy is creating meal plans.  Those who have recently volunteered to help me build these plans are able to enter in recipes using the current implementation of the site, and I can then quickly run a single SQL query to pull in all new recipes from production into my staging database.  To do this, I&#8217;m using a PostgreSQL package called <a href="http://www.postgresql.org/docs/9.1/static/dblink.html" target="_blank">DBLink</a>.  I figured I&#8217;d write a quick tutorial on how to set this up, in case anyone runs into a similar need.</p>
<h3>Step 1: Setup DBLink</h3>
<div id="attachment_950" class="wp-caption alignright" style="width: 310px"><a href="http://kitchenpc.files.wordpress.com/2012/05/dblink.png"><img class="size-medium wp-image-950" title="DBLink" src="http://kitchenpc.files.wordpress.com/2012/05/dblink.png?w=300&h=281" alt="Running the dblink.sql script" width="300" height="281" /></a><p class="wp-caption-text">Running the dblink.sql script</p></div>
<p>With Postgres 9.0 and above, the binary modules required for linking across databases are installed by default.  However, you&#8217;ll need to run a SQL script to create the necessary functions to access them from your database.  This SQL script is called <em>dblink.sql</em> and should exist on both Windows and Unix installations of Postgres in the <em>contrib</em> directory.  Depending on your OS and installation, you might have to install a separate <em>contrib</em> package to get this file.  For example, on Ubuntu you can install the necessary package using:</p>
<p><pre class="brush: plain;">
sudo apt-get install postgresql-contrib
</pre></p>
<p>Once you find <em>dblink.sql</em>, you can simply run the file using <em>psql</em>, or your query tool of choice.  This command will look something like:</p>
<p><pre class="brush: plain;">
psql -h localhost -p 5432 -f dblink.sql -d dbname -U root -W
</pre></p>
<p>The <em>-h</em> option specifies the <em>hostname</em> and should use the local instance by default.  The <em>-p</em> option specifies the <em>port</em>, which will usually be <em>5432</em>.  The <em>-f</em> option tells psql to run the SQL commands in a file.  It is assumed you&#8217;ll be running this command from the <em>contrib</em> directory, so I didn&#8217;t fully qualify the path.  Replace <em>dbname</em> with the database you&#8217;d like to create the dblink functions in, and you can replace <em>root</em> with any user with sufficient privileges in this database.</p>
<p>When you run this command, you will hopefully see something like the picture above.</p>
<h3>Step 2: Making Sure It Works</h3>
<p>Next, open up your favorite database program, such as pgAdmin, and connect to your database.  You should now be able to run a command such as:</p>
<p><pre class="brush: plain;">
select * from dblink(
   'hostaddr=10.0.0.1 dbname=ProductionDB user=Website password=secret',
   'select * from users')
as t1(
  userid uuid,
  email varchar(50),
  alias varchar(50),
  fullname varchar(50),
  password varchar(100)
);
</pre></p>
<p>The <em>dblink</em> function above takes two parameters.  The first is a connection string and the second is a SQL command to run on the remote server.  You&#8217;ll also need to specify the columns and data types being returned by your query.</p>
<p>Once you get to this point, the rest is easy!</p>
<h3>The KitchenPC Implementation of DBLink</h3>
<p>What I chose to do was create a new DB schema called <em>ProdLink</em> that mirrors the table schema of production.  Within this schema, I create a series of views that return the matching data from the remote database.  First, I create the schema:</p>
<p><pre class="brush: plain;">
CREATE SCHEMA ProdLink;
</pre></p>
<p>Next, I create a VIEW within this schema for each table.  For example:</p>
<p><pre class="brush: plain;">
CREATE OR REPLACE VIEW ProdLink.Recipes AS
  select * from dblink(
    'hostaddr=1.2.3.4 dbname=KitchenPC user=mike password=pwd',
    'select * from Recipes')
  as t1(
    recipeid uuid,
    title varchar(100),
    description varchar(255),
    dateentered timestamptz,
    imageurl varchar(100),
    credit varchar(100),
    crediturl varchar(255),
    servingsize smallint,
    preptime smallint,
    cooktime smallint,
    rating smallint,
    steps text,
    ownerid uuid,
    publicedit boolean,
    textsearch tsvector);
</pre></p>
<p>This view simply runs a query through DBLink to pull in every recipe from the production database.  Once that view is created, I can now just run:</p>
<p><pre class="brush: plain;">
SELECT * From ProdLink.Recipes;
</pre></p>
<p>and instantly see every recipe in production.  Since this is simply a database view, I can now do anything I could with a normal view.  For example, if I want to pull in any recipe from production that doesn&#8217;t already exist in my staging database, I can run:</p>
<p><pre class="brush: plain;">
INSERT INTO Recipes
  SELECT * FROM ProdLink.Recipes L WHERE NOT EXISTS
    (select 1 from Recipes where Recipes.RecipeId = L.RecipeId);
</pre></p>
<p>One nice thing about this method is the schemas between databases can be out of sync, and I can handle this through the INSERT statement itself.  I can specify default values for newly created columns, use conditional logic, etc.</p>
<p>After creating a VIEW within the <em>ProdLink</em> schema for each production table, I then created a series of commands to freshen the data in my staging database with production data, which I can run on a daily basis or as I see fit.</p>
<p>My goal is to keep my staging database up to date with the latest data from production so that when the new site launches, I can minimize downtime by simply migrating the staging data itself into the new production database, rather than having to worry about upgrading the old production database to the new schema.</p>
<p>This may or may not be the best way to handle data migration between production and an evolving schema under development, but so far it has worked pretty well for me.  It&#8217;s quite possible that this may be an awful solution for massive databases, as each of these views is going to &#8220;download&#8221; all the data every time, however that could probably be improved with some sort of time stamp or watermark.  Luckily, I&#8217;m not yet to the point where I need to worry about huge amounts of data.</p>
<p>Not a Postgres fan?  Other major database systems have similar database linking features, so it&#8217;s quite possible to adopt these techniques using your database of choice.  However, I&#8217;ll leave that up to you!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kitchenpc.wordpress.com/949/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kitchenpc.wordpress.com/949/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kitchenpc.wordpress.com/949/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kitchenpc.wordpress.com/949/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kitchenpc.wordpress.com/949/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kitchenpc.wordpress.com/949/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kitchenpc.wordpress.com/949/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kitchenpc.wordpress.com/949/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kitchenpc.wordpress.com/949/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kitchenpc.wordpress.com/949/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kitchenpc.wordpress.com/949/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kitchenpc.wordpress.com/949/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kitchenpc.wordpress.com/949/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kitchenpc.wordpress.com/949/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=949&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kitchenpc.com/2012/05/15/data-data-everywhere-using-dblink-for-postgresql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4df33f9e8a81cc9d8046f057dbb4debc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kitchenpc</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/05/dblink.png?w=300" medium="image">
			<media:title type="html">DBLink</media:title>
		</media:content>
	</item>
		<item>
		<title>Now I see why people hire UX professionals</title>
		<link>http://blog.kitchenpc.com/2012/04/14/now-i-see-why-people-hire-ux-professionals/</link>
		<comments>http://blog.kitchenpc.com/2012/04/14/now-i-see-why-people-hire-ux-professionals/#comments</comments>
		<pubDate>Sat, 14 Apr 2012 21:04:07 +0000</pubDate>
		<dc:creator>kitchenpc</dc:creator>
				<category><![CDATA[Business]]></category>

		<guid isPermaLink="false">http://blog.kitchenpc.com/?p=922</guid>
		<description><![CDATA[Yesterday, I spent the afternoon running a second round of usability testing to verify the changes I&#8217;ve made over the past few weeks result in an improved perception of the site.  Overall, I just have to say wow!  The results were an improvement by leaps and bounds, and pretty much all the major issues were <a href="http://blog.kitchenpc.com/2012/04/14/now-i-see-why-people-hire-ux-professionals/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=922&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Yesterday, I spent the afternoon running a second round of usability testing to verify the changes I&#8217;ve made over the past few weeks result in an improved perception of the site.  Overall, I just have to say <em>wow</em>!  The results were an improvement by leaps and bounds, and pretty much all the major issues were addressed.  I think I&#8217;m finally to the point where I can put this site out into the world and be confident that the average Internet user won&#8217;t run away screaming.</p>
<p>This is not to say there were no problems with the second round of testing, because there were.  However, the problems I encountered were minor and very easy to remedy.</p>
<h3>People Need Buttons</h3>
<p>This simple UI fact still just blows my mind.  If you provide a text box and nothing to click on after the user enters something, you&#8217;ve basically screwed yourself usability wise.  People simply don&#8217;t press <em>Enter</em> when they&#8217;re done typing.  It&#8217;s good practice to <em>allow</em> them to press enter if they wish, but you absolutely positively need a button next to any text box, no exceptions.  <em>Ever</em>.</p>
<p>The simple act of putting a &#8220;<em>Go</em>&#8221; button next to the keyword search improved the experience by leaps and bounds.  Absolutely no one had any problems understanding the design.  Absolutely no one confused the Meal icons for <em>submit</em> buttons.</p>
<p>There was one screw-up that still bit me though.  Which leads me to my next piece of advice.</p>
<h3>Buttons Next to Text Boxes <em>Can</em> and <em>Will Be</em> Confused With Dropdowns</h3>
<p>As mentioned in my <a href="http://blog.kitchenpc.com/2012/04/13/the-white-whale-of-usability/" target="_blank">previous post</a>, I ditched the ingredient auto-complete mechanism for a simple text box that will parse whatever you type in.  In case you don&#8217;t remember, here&#8217;s what the new UI looks like now:</p>
<div id="attachment_906" class="wp-caption aligncenter" style="width: 510px"><a href="http://kitchenpc.files.wordpress.com/2012/04/search1.png"><img class="size-full wp-image-906" title="NewSearch" src="http://kitchenpc.files.wordpress.com/2012/04/search1.png?w=500&h=162" alt="" width="500" height="162" /></a><p class="wp-caption-text">Notice &quot;+&quot; icons next to both ingredient text boxes</p></div>
<p>The intended design was for users to click on the text box, type something in, then either press Enter or click on the &#8220;+&#8221; icon to the right of the text box.  Wow, did this backfire big time.</p>
<p>9 out of 10 users clicked on the &#8220;+&#8221; icon <em>first</em>, expecting to see some sort of dropdown or popup to allow them to select an ingredient from a list.  The problem with this was clicking on the &#8220;+&#8221; icon with a blank input did absolutely nothing.  That&#8217;s right; zilch, no-op, no error message&#8230; <em>nothing</em>.  Even more disheartening was the fact that 4 out of 10 users <em>never</em> figured it out, and thus were unable to ever use the feature.</p>
<p>The solution?</p>
<p>Very simple, I hope.  Now, when you click on the &#8220;+&#8221; icon and there&#8217;s no text input, I set the focus to the text box itself, which of course automatically shows a helpful tooltip on what to enter.  This one line of code - <em>input.focus(); -</em> will hopefully remedy this problem.</p>
<h3>Seriously, Quit Trying to be Fancy with Non-Standard UI</h3>
<p>I also mentioned in my previous post that I ditched the fancy checkmark graphics and went with standard HTML input controls.  I was also blown away by the dramatic change of perception that change resulted in as well.  9 out of 10 users immediately used the check boxes to mark off several recipes, rather than going into the recipe viewer to add a recipe to a menu.  Most didn&#8217;t even pause to think twice about this feature, they simply saw the check boxes they&#8217;re used to on the web and knew they could select multiple recipes to add to a menu.  This is fantastic!</p>
<p>The one user who failed to use the check boxes I had some other problems with.  I felt she rushed through the script, and flat out skipped several of the tasks.  I don&#8217;t believe she provided feedback that exemplified the average Internet user.</p>
<h3>Confusion on De-Queue</h3>
<p>The simple re-wording of the &#8220;remove from Queue&#8221; popup also made a huge difference.  10 out of 10 users understood immediately that the rating was indeed optional.  Most simply ignored it and clicked Ok, and a few made comments that indicated they understood they could optionally rate the recipe.  However, there was one user who was confused that the recipe rating was pre-filled in with 5 stars rather than blank.  I&#8217;ve only seen this happen occasionally though (perhaps on certain browsers), so I&#8217;m pretty sure it&#8217;s a bug rather than a usability issue.</p>
<h3>More Options</h3>
<p>Like the last test, most people were still lost on how to narrow down recipes to those under 30 minutes, failing to find the &#8220;More Options&#8221; button.  Again, their first instinct was to use the sorting options to manually find these recipes.  Since I simplified sorting, I believe the experience was much better, however I&#8217;m still giving this area some thought.</p>
<p>With a usability test, users are instructed on tasks to perform.  If I tell them to &#8220;narrow down recipes to those that can be made in 30 minutes or less,&#8221; they immediately know such a task is <em>possible</em> and just have to figure out how to do it.  A normal user would simply not know if such a feature existed, and would thus not be confused with what they don&#8217;t know how to do.  I&#8217;ve said before I prefer simplicity over powerful features, and have purposely only exposed the filtering abilities that the majority of surveyed users said they would use.  Other features are out of the way as not to clutter the interface with features only 5% of users might ever bother with.  Thus, drawing more attention to the &#8220;<em>More Options</em>&#8221; button is not something I&#8217;m convinced is a necessity.  If people find it, great!  It will be like a treasure chest of new features, buried to await discovery by my most loyal users.  On the other hand, maybe making the button brighter and more noticeable might be the way to go still.  We&#8217;ll see.</p>
<h3>People Still Don&#8217;t Get &#8220;What Can I Make?&#8221;</h3>
<p>Though people understand that they can enter a few ingredients in, they really don&#8217;t seem to understand what the results mean.  When I told users to enter &#8220;12 eggs, a dozen bananas, and asparagus&#8221; to see what they could make, several made comments like &#8220;How in the world could you make anything with <em>that</em>?&#8221; &#8211; obviously assuming I would find a single recipe that utilized such randomness.  Others thought that KitchenPC would somehow generate an original recipe on the fly (Icon Chef Watson??) that perhaps infused asparagus purée into banana bread or some such.  Wouldn&#8217;t that be interesting.</p>
<p>A good chunk of users, once seeing the results, understood the relationship between the input and said results, most providing praise of the feature&#8217;s usefulness.  Others flat out still didn&#8217;t get it, wondering why only five recipes in my database used any of those ingredients.  Attempting to explain that this set of five most efficiently uses the ingredients and amounts specified is a challenge, since it&#8217;s most likely the most original feature of KitchenPC and users have a hard time identifying with something they&#8217;ve never seen before.</p>
<p>I think the only real way to articulate the purpose of the meal planner is to create a popup video that demos the feature and really shows off what the results mean.  This will for sure be a weekend project before the site is launched.  I&#8217;m hoping once I can educate users on the purpose of this feature, it&#8217;ll really click with them and keep them coming back for more.  Maybe it will start a new Internet trend and other sites will try to copy it!</p>
<h3>Next Steps</h3>
<p>I also found a few minor bugs while watching the usability tests, but nothing too concerning.  Hopefully, these issues will be addressed this weekend.</p>
<p>The next task will be starting to assemble pre-made meal plans.  Since this is a huge task, I&#8217;m hoping to call upon the powers of the Internet to recruit some help.  I&#8217;ll be reaching out to bloggers, friends, nutritionists, personal trainers, and other experts to see if I can find some people to put together these plans.  In return, they&#8217;ll be able to link to their site or product which will hopefully provide some incentive for their work.</p>
<p>If you know of anyone who might be willing to help out, please let me know as well!  I&#8217;m hoping to get at least 10 pre-made meal plans (at least one in each category) for launch, and hopefully more as time goes on.</p>
<p>While that work is being done, my next technical task is to finish up the web crawler and parser.  I need to be able to import tens of thousands of recipes from other recipe websites automatically, hopefully this time providing near perfect accuracy.  The recipes on the site right now are simply not good enough and contain too many errors.  These recipes need to go!  I also need to work on the categorization code that will classify each recipe and tag it correctly, which is probably a topic for another post.</p>
<p>So much work!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kitchenpc.wordpress.com/922/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kitchenpc.wordpress.com/922/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kitchenpc.wordpress.com/922/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kitchenpc.wordpress.com/922/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kitchenpc.wordpress.com/922/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kitchenpc.wordpress.com/922/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kitchenpc.wordpress.com/922/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kitchenpc.wordpress.com/922/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kitchenpc.wordpress.com/922/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kitchenpc.wordpress.com/922/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kitchenpc.wordpress.com/922/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kitchenpc.wordpress.com/922/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kitchenpc.wordpress.com/922/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kitchenpc.wordpress.com/922/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=922&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kitchenpc.com/2012/04/14/now-i-see-why-people-hire-ux-professionals/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4df33f9e8a81cc9d8046f057dbb4debc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kitchenpc</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/04/search1.png" medium="image">
			<media:title type="html">NewSearch</media:title>
		</media:content>
	</item>
		<item>
		<title>The White Whale of Usability</title>
		<link>http://blog.kitchenpc.com/2012/04/13/the-white-whale-of-usability/</link>
		<comments>http://blog.kitchenpc.com/2012/04/13/the-white-whale-of-usability/#comments</comments>
		<pubDate>Fri, 13 Apr 2012 17:09:19 +0000</pubDate>
		<dc:creator>kitchenpc</dc:creator>
				<category><![CDATA[Business]]></category>

		<guid isPermaLink="false">http://blog.kitchenpc.com/?p=902</guid>
		<description><![CDATA[Over the past couple weeks, I&#8217;ve been working hard on usability improvements for the new version of the site.  This effort has been mainly spurred by my recent testing on UserTesting.com, however I also took the opportunity to throw in a few extra bells and whistles inspired by what I had learned. I figured I&#8217;d <a href="http://blog.kitchenpc.com/2012/04/13/the-white-whale-of-usability/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=902&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Over the past couple weeks, I&#8217;ve been working hard on usability improvements for the new version of the site.  This effort has been mainly spurred by my recent testing on <a href="http://www.usertesting.com" target="_blank">UserTesting.com</a>, however I also took the opportunity to throw in a few extra bells and whistles inspired by what I had learned.</p>
<p>I figured I&#8217;d write a quick post on a few of the changes I made, and why I believe these relatively minor changes will make a <em>huge</em> difference in the next round of testing.</p>
<h3>Quit Trying to be Fancy with Non-Standard UI</h3>
<p>One of the great things you can do with KitchenPC search results is<em> check off</em> multiple results and save them as menus.  This feature is  unique to KitchenPC (as far as a I know,) as most search engines just display your search results and say, &#8220;good luck&#8221; from there.  I wanted to make these check boxes big and bold and easy to click on.  For this reason, I used huge check mark graphics that would change color as they were clicked.  Huge mistake.  Pretty much no user even <em>noticed</em> them since they did not look like the typical HTML checkbox people are used to.</p>
<table width="100%">
<tbody>
<tr>
<td>
<p><div id="attachment_903" class="wp-caption aligncenter" style="width: 310px"><a href="http://kitchenpc.files.wordpress.com/2012/04/checks.png"><img class="size-medium wp-image-903 " title="OldChecks" src="http://kitchenpc.files.wordpress.com/2012/04/checks.png?w=300&h=251" alt="The original easy to click on check boxes" width="300" height="251" /></a><p class="wp-caption-text">Original Prototype</p></div></td>
</tr>
<tr>
<td>
<p><div id="attachment_904" class="wp-caption aligncenter" style="width: 310px"><a href="http://kitchenpc.files.wordpress.com/2012/04/checks1.png"><img class="size-medium wp-image-904 " title="NewChecks" src="http://kitchenpc.files.wordpress.com/2012/04/checks1.png?w=300&h=253" alt="" width="300" height="253" /></a><p class="wp-caption-text">Standard HTML checkboxes</p></div></td>
</tr>
</tbody>
</table>
<p>Not as pretty, but the average user will be more likely to notice they can check on results.  I also now include a text blurb above the results mentioning that you can check individual recipes to add them to a menu.</p>
<h3>Give Users a Place to Click On</h3>
<p>One thing I learned is users <em>love</em> their mice.  If you give them a text box, but nothing to click on when they&#8217;re done typing, they usually click outside the text box to indicate they&#8217;re done.  Almost <em>no one</em> will press Enter, or try to tab away.  This caused huge issues with my search interface, which efforts to find recipes as you <em>enter</em> data, rather than making you click a &#8220;Search&#8221; button when you&#8217;re done.  I decided to stick with the real time result updating, since I believe people will catch on after using the site for a few minutes, but I added buttons to click on near each text input field to provide the illusion of submitting data.</p>
<table width="100%">
<tbody>
<tr>
<td>
<p><div id="attachment_905" class="wp-caption aligncenter" style="width: 310px"><a href="http://kitchenpc.files.wordpress.com/2012/04/search.png"><img class="size-medium wp-image-905" title="OldSearch" src="http://kitchenpc.files.wordpress.com/2012/04/search.png?w=300&h=97" alt="" width="300" height="97" /></a><p class="wp-caption-text">Original Search UI</p></div></td>
</tr>
<tr>
<td>
<p><div id="attachment_906" class="wp-caption aligncenter" style="width: 310px"><a href="http://kitchenpc.files.wordpress.com/2012/04/search1.png"><img class="size-medium wp-image-906" title="NewSearch" src="http://kitchenpc.files.wordpress.com/2012/04/search1.png?w=300&h=97" alt="" width="300" height="97" /></a><p class="wp-caption-text">Improved Search UI - Now with Buttons!</p></div></td>
</tr>
</tbody>
</table>
<p>There are a few aspects of this interface worth pointing out.</p>
<ol>
<li>On the original UI, users would often enter text into the Quick Search and then grab the mouse and click on one of the meal icons below, wanting desperately for that to be some sort of <em>Submit</em> action.  This would work okay in certain cases, but cause all sorts of frustration when the user then changed their query and wanted to re-submit.  The new UI has a &#8220;<em>Go</em>&#8221; button to the right of the text box.  Clicking &#8220;<em>Go</em>&#8221; or pressing <em>Enter</em> will update the results.  Just for kicks, users can also click on a meal icon to update the results, even if that meal icon is already selected.</li>
<li>Both the <em>Ingredient Include</em> and <em>Ingredient Exclude</em> lists also now have a &#8220;+&#8221; icon to add input.  Another huge change made here is I completely got rid of the auto-complete mechanism and now parse input through the <a href="http://blog.kitchenpc.com/2011/07/06/chef-watson/" target="_blank">natural language parsing engine</a> instead.  The number of usability issues auto-complete caused was absolutely mind-boggling.  Users would refuse to select an item from the list, or just click on something else on the screen when they were done.  Without the auto-complete, it&#8217;s a little more typing now, but it&#8217;s quite obvious how the interface works.</li>
</ol>
<h3>Huh?  Why Do I Need to Rate That Recipe?</h3>
<div id="attachment_908" class="wp-caption alignright" style="width: 310px"><a href="http://kitchenpc.files.wordpress.com/2012/04/dequeue1.png"><img class="size-medium wp-image-908   " title="Dequeue" src="http://kitchenpc.files.wordpress.com/2012/04/dequeue1.png?w=300&h=158" alt="" width="300" height="158" /></a><p class="wp-caption-text">New wording for de-queue dialog</p></div>
<p>The <em>Queue</em> allows users to queue up recipes that they&#8217;re interested in without having to formally organize these recipes into menus.  When you <em>de-queue</em> a recipe, it&#8217;s <em>assumed</em> that you probably made it and KitchenPC takes this opportunity to ask what you thought of it.  This was an attempt to counter the fact that only around 2% of KitchenPC users would ever rate a recipe, since the site can do all sorts of nifty things when it has ratings.</p>
<p>It turned out this assumption was bad, and asking users to rate recipes on de-queue was confusing.  Rather than completely doing away with this concept, I attempted to re-word the de-queue dialog to be a bit more clear about what was going on.</p>
<h3>Did Clicking On That Do Anything?</h3>
<p><a href="http://kitchenpc.files.wordpress.com/2012/04/menucount.png"><img class="alignleft size-full wp-image-909" title="MenuCount" src="http://kitchenpc.files.wordpress.com/2012/04/menucount.png?w=500" alt=""   /></a>One other common issue that came up was with users adding recipes to a menu, especially when they were creating new menus.  When the user would click on &#8220;<em>Add To Menu</em>&#8220;, then create a new button and click &#8220;<em>Ok</em>&#8220;, a popup would show, &#8220;<em>New Menu Created!</em>&#8220;  Many users were unclear that the recipe was <em>also</em> added to their newly created menu, so they would try adding it again.  It also didn&#8217;t help that the recipe viewer doesn&#8217;t indicate whether a recipe is added to any menus.  I decided to address both issues.  First, the popup tip will now say, &#8220;This recipe has been added to a new menu.&#8221;  Second, the recipe viewer itself now shows a count of how many menus the recipe appears in.  When a recipe is added to a menu, this count updates instantly (using a cute animation of course) which provides further feedback that the action indeed did something.</p>
<h3>Tell Me When I Mess Up!</h3>
<p>The problem with text input boxes is it&#8217;s very hard to control exactly what the user types in.  If this is just a keyword search, this might not matter.  If it&#8217;s someone&#8217;s name or address, this might not matter.  However, if it&#8217;s an instruction for the server to parse and take action upon, it&#8217;s critical that user input is gathered in an expected format.  Search parameters such as &#8220;<em>Ingredients to include or exclude</em>&#8221; as well as the <em></em>&#8220;<em>I have&#8230;</em>&#8221; text box suffer from this problem.</p>
<p>During testing, a lot of users would enter invalid input in the <em>Ingredient to Include</em> text box.  For example, &#8220;<em>12 eggs</em>&#8221; or even &#8220;<em>bananas, eggs, pears</em>&#8220;.  Since this text box was ruled over by an evil auto-complete system (which would basically ignore you when you messed up,) understanding what was expected was near impossible.  Using natural language parsing for each of these inputs is a great step forward (provided my NLP engine actually works well,) but I also decided the user needs more feedback when they enter something that isn&#8217;t understood.</p>
<div id="attachment_911" class="wp-caption alignright" style="width: 339px"><a href="http://kitchenpc.files.wordpress.com/2012/04/cantparse1.png"><img class="size-full wp-image-911" title="CantParse" src="http://kitchenpc.files.wordpress.com/2012/04/cantparse1.png?w=500" alt=""   /></a><p class="wp-caption-text">Error message if input cannot be parsed</p></div>
<p>I decided to return an error when an ingredient or ingredient usage could not be parsed, even if it might frustrate users at first.  I do log invalid input, so I can keep an eye on what users are typing in and improve the database over time.  I also now greet them with a friendly error message that offers to take users to a help page or perhaps a video demonstration on how the feature works.  I also changed a lot of the verbiage on the site to make it more clear that ingredients need to be entered one at a time.</p>
<h3>Small Fixes go a Long Way</h3>
<p>Most of the other changes to the site were minor changes of wording.  The Queue page now includes a full description of what the <em>Queue</em> actually <em>is</em>.  The <em>Menus</em> page now includes instructions, and tells users they can drag recipes between menus.  I&#8217;ve also included several new tooltips, and changed the wording of several popups to be more clear and address specific issues that I&#8217;ve seen users have.</p>
<p>I also took the opportunity to change the behavior of a couple of site features:</p>
<ol>
<li>The Popup Recipe viewer will now &#8220;tag along&#8221; as you scroll the page up and down.  This will hopefully prevent the recipe viewer from getting lost if the user scrolls back up to the top of the page without first closing the viewer.  This happened to at least 2 or 3 people during testing, though they did realize their mistake after a few seconds.</li>
<li>Sort can now only be done in one direction.  Allowing users to flip the sort order between <em>ascending</em> and <em>descending</em> sort order only complicates the UI, and provides almost no benefit.  After all, why would anyone want to sort &#8220;<em>Cook Time</em>&#8221; by maximum time first, or see the lowest rated recipes at the top of the list?  This allows me to grey out the currently selected sort order, making it a lot more clear what&#8217;s going on.  I also now show the &#8220;<em>Total Time</em>&#8221; on each line to be consistent with the fact you can sort by total time.</li>
</ol>
<p>The next step will be to do yet another usability study with ten more users.  I&#8217;m confident that the next round will show a massive improvement, but I&#8217;m also nervous that I&#8217;ll simply uncover a huge list of even more major issues that need to be corrected.  I&#8217;m sure I could go on forever, hunting for that perfect user interface like Captain Ahab hunting his white whale.  With any luck, the next set of usability results will instill me with the confidence I need to declare this UI go for launch, and I can start working on building site content.  Fingers crossed!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kitchenpc.wordpress.com/902/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kitchenpc.wordpress.com/902/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kitchenpc.wordpress.com/902/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kitchenpc.wordpress.com/902/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kitchenpc.wordpress.com/902/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kitchenpc.wordpress.com/902/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kitchenpc.wordpress.com/902/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kitchenpc.wordpress.com/902/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kitchenpc.wordpress.com/902/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kitchenpc.wordpress.com/902/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kitchenpc.wordpress.com/902/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kitchenpc.wordpress.com/902/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kitchenpc.wordpress.com/902/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kitchenpc.wordpress.com/902/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=902&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kitchenpc.com/2012/04/13/the-white-whale-of-usability/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4df33f9e8a81cc9d8046f057dbb4debc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kitchenpc</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/04/checks.png?w=300" medium="image">
			<media:title type="html">OldChecks</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/04/checks1.png?w=300" medium="image">
			<media:title type="html">NewChecks</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/04/search.png?w=300" medium="image">
			<media:title type="html">OldSearch</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/04/search1.png?w=300" medium="image">
			<media:title type="html">NewSearch</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/04/dequeue1.png?w=300" medium="image">
			<media:title type="html">Dequeue</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/04/menucount.png" medium="image">
			<media:title type="html">MenuCount</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/04/cantparse1.png" medium="image">
			<media:title type="html">CantParse</media:title>
		</media:content>
	</item>
		<item>
		<title>Hello Phoenix!</title>
		<link>http://blog.kitchenpc.com/2012/03/22/hello-phoenix/</link>
		<comments>http://blog.kitchenpc.com/2012/03/22/hello-phoenix/#comments</comments>
		<pubDate>Fri, 23 Mar 2012 04:46:09 +0000</pubDate>
		<dc:creator>kitchenpc</dc:creator>
				<category><![CDATA[Business]]></category>

		<guid isPermaLink="false">http://blog.kitchenpc.com/?p=885</guid>
		<description><![CDATA[This morning at around ten, I happened to glance up at the Clicky Chrome Plug-In, which provides me a real-time count of how many people have visited the site today.  To my shock and surprise, it was up well over 300!  Normally around this time of day, I was lucky to have 40 or 50. <a href="http://blog.kitchenpc.com/2012/03/22/hello-phoenix/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=885&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This morning at around ten, I happened to glance up at the <a href="https://chrome.google.com/webstore/detail/nhdlcoplfdhmdbeleincmcnmgdajohig" target="_blank">Clicky Chrome Plug-In</a>, which provides me a real-time count of how many people have visited the site today.  To my shock and surprise, it was up well over 300!  Normally around this time of day, I was lucky to have 40 or 50.  Even more shocking was when I logged on to Clicky and saw there was 44 visitors online at that very moment!</p>
<div id="attachment_886" class="wp-caption alignleft" style="width: 310px"><a href="http://kitchenpc.files.wordpress.com/2012/03/hightraffic.png"><img class="size-medium wp-image-886" title="HighTraffic" src="http://kitchenpc.files.wordpress.com/2012/03/hightraffic.png?w=300&h=163" alt="" width="300" height="163" /></a><p class="wp-caption-text">Clicky Real-Time Stats</p></div>
<p>This isn&#8217;t the first time the site was rewarded with some generous PR or mention in some high-profile blog, but what was strange was that pretty much all the traffic was either direct (people just typing in <em>www.kitchenpc.com</em> in their browser) or through a Google search for &#8220;<em>KitchenPC</em>&#8221; or &#8220;<em>KitchenPC.com</em>.&#8221;  This led me to believe someone mentioned me either on a TV show or on a radio program, which would require users to type in my address rather than click on some link.  But who?</p>
<p>I soon noticed another trend in the traffic.  Over half the visitors were around Phoenix, AZ.  Apparently, my site was all of a sudden famous there.</p>
<p>A few minutes later, I was notified by email of a new comment made on <a href="http://kitchenpc.uservoice.com" target="_blank">UserVoice</a>, which I use to allow visitors to provide feedback on the site or feature suggestions.  The comment started out, &#8220;I have heard on the TV about this [site].&#8221;</p>
<p>Oooh, TV show!</p>
<div id="attachment_887" class="wp-caption alignright" style="width: 310px"><a href="http://kitchenpc.files.wordpress.com/2012/03/phoenix.png"><img class="size-medium wp-image-887" title="Phoenix" src="http://kitchenpc.files.wordpress.com/2012/03/phoenix.png?w=300&h=187" alt="" width="300" height="187" /></a><p class="wp-caption-text">Phoenix, AZ traffic today</p></div>
<p>Since the poster was kind enough to leave their email address, I decided to inquire as to which TV show mentioned the site, and it turned out to be a segment on Fox 10, where a local radio DJ shares her &#8220;tip of the day.&#8221;  Today&#8217;s tip was that KitchenPC is a fantastic online meal planning tool.  That&#8217;s a good tip!</p>
<p>A quick Google search turned up the <a href="http://www.myfoxphoenix.com/dpp/more_azam/kez/kez-03222012" target="_blank">video which aired today</a>, which I invite you all to watch.  Feel free to fast-forward to around the 5 1/2 minute mark if you&#8217;re not exactly obsessed with American Idol.</p>
<p>Needless to say, this was a pleasant surprise.  I&#8217;ve never heard of the show nor was I made aware of this segment in advance.  I guess Beth simply stumbled across the site and decided to let her listeners know about it!  Though this isn&#8217;t perfect timing, as I&#8217;m completely re-inventing the site at the moment and thus shy away from too much publicity, it was still completely appreciated.  Around 1 in 10 visitors went on to create accounts, and stayed on the site for an average of 5 minutes and 54 seconds with a <a href="http://en.wikipedia.org/wiki/Bounce_rate" target="_blank">bounce rate</a> of only 12.9%.  For anyone who found the site today, welcome and stick around for exciting new things to come!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kitchenpc.wordpress.com/885/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kitchenpc.wordpress.com/885/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kitchenpc.wordpress.com/885/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kitchenpc.wordpress.com/885/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kitchenpc.wordpress.com/885/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kitchenpc.wordpress.com/885/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kitchenpc.wordpress.com/885/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kitchenpc.wordpress.com/885/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kitchenpc.wordpress.com/885/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kitchenpc.wordpress.com/885/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kitchenpc.wordpress.com/885/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kitchenpc.wordpress.com/885/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kitchenpc.wordpress.com/885/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kitchenpc.wordpress.com/885/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=885&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kitchenpc.com/2012/03/22/hello-phoenix/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4df33f9e8a81cc9d8046f057dbb4debc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kitchenpc</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/03/hightraffic.png?w=300" medium="image">
			<media:title type="html">HighTraffic</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/03/phoenix.png?w=300" medium="image">
			<media:title type="html">Phoenix</media:title>
		</media:content>
	</item>
		<item>
		<title>C:\&gt; KitchenPC.exe -search -maxtime 30 -avoid eggs</title>
		<link>http://blog.kitchenpc.com/2012/03/15/c-kitchenpc-exe-search-maxtime-30-avoid-eggs/</link>
		<comments>http://blog.kitchenpc.com/2012/03/15/c-kitchenpc-exe-search-maxtime-30-avoid-eggs/#comments</comments>
		<pubDate>Fri, 16 Mar 2012 04:50:03 +0000</pubDate>
		<dc:creator>kitchenpc</dc:creator>
				<category><![CDATA[Business]]></category>

		<guid isPermaLink="false">http://blog.kitchenpc.com/?p=873</guid>
		<description><![CDATA[Before launching a new version of a website, especially one that radically changes the entire purpose of the site, it&#8217;s usually a good idea to go test it out on a few strangers.  I&#8217;ve found asking friends and family usually results in less than honest feedback, as those are the types who are verbally throttled <a href="http://blog.kitchenpc.com/2012/03/15/c-kitchenpc-exe-search-maxtime-30-avoid-eggs/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=873&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Before launching a new version of a website, especially one that radically changes the entire purpose of the site, it&#8217;s usually a good idea to go test it out on a few strangers.  I&#8217;ve found asking friends and family usually results in less than honest feedback, as those are the types who are verbally throttled by their pesky respect for your hard work.  Also, the people we get along with are usually the people who think like us too.  That&#8217;s no good.</p>
<p>A while back, I gave the site <a href="http://www.usertesting.com" target="_blank">UserTesting.com</a> a go and was very pleased with the <a href="http://blog.kitchenpc.com/2011/02/09/usability-testing-part-1/" target="_blank">results</a>.  Though they&#8217;re a bit pricy, I found the data I were able to ascertain from the experience worth their weight in gold.  So back I went for another round, this time going all out and purchasing not one but <em>ten</em> testers to give the new KitchenPC a whirl.</p>
<p><strong>Turns out, my new design is a complete disaster!</strong></p>
<h2>The Good</h2>
<p>Overall, people have a good first impression of the site.  They understand it allows them to find recipes (no one mentioned meal planning, which means my pivot is a success,) and organize the results they find.  Almost everyone understood what a &#8220;<em>menu</em>&#8221; was before even trying out the feature, and several people understood &#8220;<em>What Can I Make?</em>&#8221; just by the description alone.  Very few people had a clue what &#8220;<em>Pre-Made Meal Plans</em>&#8221; were, but most admitted they were intrigued by the idea and wanted to click on it.</p>
<p>I also got several compliments on the overall look and feel of the site.  People said it was simple and straight-forward.  One tester even signed up with her real email address, claiming she&#8217;d be back.</p>
<p>People seem to connect with the value proposition of KitchenPC.  They like the idea of finding recipes and organizing them into menus. They like the idea of finding out what they can make with ingredients they have on hand.  They like the idea of saving time and money, and believe KitchenPC can help them do that.  This means if KitchenPC can deliver on that promise, there&#8217;s a customer base out there waiting.</p>
<h2>The Bad</h2>
<p>Everything else.  The entire search interface was a swing and a miss for strike one.  As the title of this post suggests, sometimes I think I&#8217;d be better off re-writing the entire thing as a command line tool.</p>
<p>Nine out of ten testers were completely and utterly confused simply by trying to search for recipes, which is somewhat important to really nail being a recipe search engine and all.  Though all were eventually able to get recipes to come up, very few were able to successfully narrow down their search to desserts without eggs that could be made in 30 minutes or less.</p>
<div id="attachment_875" class="wp-caption alignright" style="width: 310px"><a href="http://kitchenpc.files.wordpress.com/2012/03/newsearch.png"><img class=" wp-image-875    " title="New search interface" src="http://kitchenpc.files.wordpress.com/2012/03/newsearch.png?w=300&h=96" alt="" width="300" height="96" /></a><p class="wp-caption-text">New search interface, no submit button!</p></div>
<p><strong>The huge culprit here is the lack of a Submit button on the search interface</strong>.  I decided to be clever and implement an interface that allows users to narrow down results on the fly, however users just don&#8217;t understand this.  Not just some users, <em>all users</em>.   At least half the testers mistook the &#8220;<em>Meal</em>&#8221; filter (<em>All, Breakfast, Lunch, Dinner, Dessert</em>) as a submit button.  Thus, they would type in something like &#8220;<em>Chocolate cake</em>&#8221; and click &#8220;<em>Dessert</em>&#8220;.  In their mind, this means &#8220;Find me all chocolate cakes in the dessert category.&#8221;  They would then type in something else in the keyword textbox, and then click on &#8220;<em>Dessert</em>&#8221; again.  Unfortunately, this does absolutely nothing on KitchenPC as these are filter buttons that can be toggled, and not submit buttons.</p>
<p>Five out of ten users tried to type in <em>multiple</em> ingredients in either the &#8220;<em>Include</em>&#8221; or &#8220;<em>Exclude</em>&#8221; text boxes as well.  For the most part, they would just ignore the auto-complete that would pop up.  At least two users would type in an ingredient such as &#8220;<em>eggs</em>&#8221; and then click elsewhere on the screen rather than pressing enter or clicking on an auto-complete option.  A definite trend I noticed is that very few people expect the <em>Enter</em> key to do anything on a website.  Most people will look for something to click on once they finish typing.  Only a few users were able to successfully narrow down recipes to those that don&#8217;t include eggs, and almost all of them were looking for something to click on to update the results.</p>
<div id="attachment_877" class="wp-caption alignleft" style="width: 310px"><a href="http://kitchenpc.files.wordpress.com/2012/03/checkboxes.png"><img class="size-medium wp-image-877  " title="Checkboxes" src="http://kitchenpc.files.wordpress.com/2012/03/checkboxes.png?w=300&h=282" alt="" width="300" height="282" /></a><p class="wp-caption-text">Impossible to see checkboxes</p></div>
<p>Once users found results, they were tasked to add a few recipes to a <em>menu</em>.  Nine out of ten of them completely ignored the checkboxes next to each recipe, and instead used the popup recipe viewer to create a new menu.  Adding a new menu was also confusing, as several weren&#8217;t sure the creation of the menu would <em>also</em> add the desired recipe to the menu as well.  This was because the recipe viewer still shows &#8220;<em>Add To Menu</em>&#8221; even though the recipe is already in one menu.  However, KitchenPC allows a recipe to exist in more than one menu, so in my mind the verbiage is still correct.</p>
<p>Next, users were asked to narrow down recipes to only those that could be made in 30 minutes or less.  Only a couple users found the &#8220;<em>More Options</em>&#8221; button and thought to actually click it.  Some finally ran into it by chance after fumbling around for a while.  The majority of users tried to <em>sort</em> the results by time, and were completely confused by the sorting experience.  This is mostly because I allow users to sort by &#8220;<em>Total Time</em>&#8220;, but I don&#8217;t actually display &#8220;<em>Total Time</em>&#8221; in the result list anywhere (I only display prep time and cook time).  Users were frustrated that they were expected to add up the two numbers in their head to find recipes that met this criteria.  One user was confused by the concept of toggling between <em>ascending</em> and <em>descending</em> sort order, since the UI provides no feedback on which direction the recipes are currently sorted in.  She was frustrated that each time she clicked on the sort link, the results would change seemingly at random.</p>
<p>Next, users were asked what they could make with &#8220;<em>12 eggs, a dozen bananas and asparagus.</em>&#8221;  This was one of the biggest disasters of all.  The majority of users never thought to click on the &#8220;<em>What Can I Make?</em>&#8221; circle at the top, even though several had already mentioned earlier they were intrigued by the feature.  Most users simply typed in the list of ingredients and amounts into the &#8220;<em>Ingredients to Include</em>&#8221; filter, and of course got absolutely nothing helpful.  Several users gave up on the task, never once getting to the meal planner page.  Those unlucky enough to get past the first step were greeted by the usability catastrophe that awaited them.</p>
<p>On the &#8220;<em>What Can I Make</em>&#8221; tab, most users attempted to type in all the ingredients at once.  I&#8217;ve purposely designed KitchenPC to accept any input here without complaint, since the natural language parsing that goes on behind the scenes is so new and I was afraid of frustrating users when I didn&#8217;t understand the input.  I figured I&#8217;d just parse what I could and log everything else so I could fix it behind the scenes.  For this reason, if a user <em>does</em> type in &#8220;<em>12 eggs, a dozen bananas and asparagus</em>&#8221; on one line, the meal planner will still run and take none of those ingredients into consideration, yet yield no errors either.  I think this made people think the feature was just broken or useless.  A few users <em>did</em> figure out you had to enter the ingredients one at a time, and did get some valid results back.</p>
<p>Only one tester seemed to understand that the ingredients listed on the right were perhaps the aggregate of all the ingredients in the selected recipes, which is the entire point of the feature (to minimize total ingredients.)  Obviously, I need to find a good way to educate users on the power of this feature, as no other site really does this.</p>
<p>Users were also asked to add some of the results to the <em>queue</em>.  Half the users admitted they had no idea what the queue was, but several made some correct assumptions about the feature or at least admitted they were interested in it.  I think even one user mentioned &#8220;Netflix&#8221;, which is why I chose the word &#8220;queue&#8221; in the first place.</p>
<p>Again, users did not use the checkboxes to select recipes to add to the queue, but added them one at a time using the recipe viewer.  Unfortunately, the recipe viewer uses the caption &#8220;<em>Plan To Make</em>&#8221; instead of &#8220;<em>Add To Queue</em>&#8220;, which caused a lot of confusion.  Several users then noticed the &#8220;<em>Add selected to queue</em>&#8221; button near the recipe list, and then <em>finally</em> noticed the checkboxes (usually grumbling that the checkboxes were difficult to see.)</p>
<p>On the queue page, users had to <em>remove</em> an item from their queue.  They easily found the red X to remove the item, but most users were confounded by what came next.  You see, the queue was designed to allow users to temporarily store recipes they were <em>interested</em> in before organizing those recipes into a menu.  This is probably why the recipe viewer calls it &#8220;<em>Plan to Make.</em>&#8221;  The <em>intended</em> design is for users to try out the recipe, then &#8220;<em>de-queue</em>&#8221; it and possibly add it to an official menu if they liked it.  For this reason, I nag the user to rate the recipe when they remove it from the queue, since only around 2% of users decide to rate recipes on their own.</p>
<div id="attachment_876" class="wp-caption alignleft" style="width: 310px"><a href="http://kitchenpc.files.wordpress.com/2012/03/dequeue.png"><img class="size-medium wp-image-876" title="De-queue Popup" src="http://kitchenpc.files.wordpress.com/2012/03/dequeue.png?w=300&h=147" alt="" width="300" height="147" /></a><p class="wp-caption-text">De-Queue popup</p></div>
<p>Unfortunately, the appearance of a rating dialog only leads to mass confusion.  Though a few users just ignored it completely and pressed the &#8220;<em>Ok</em>&#8221; button without selecting a rating, 3 different testers simply had no idea what to do.  Most would just hit <em>Cancel</em> thinking they clicked on the wrong thing.  One user even opened the dialog 4 of 5 times before figuring out the rating was simply optional.</p>
<p>The last thing users were asked to do was go to the menu page.  Fortunately, people understand menus and really like the idea.  On this page, they were asked to <em>move</em> a recipe from one menu to another.  8 out of 10 users immediately tried to drag and drop a recipe from one menu to another, however at least a couple were confused because they &#8220;missed&#8221; the drop area and then assumed there was some other way to do it.  To one user, it never occurred to her to try to drag a recipe (even though she was actively hovering over a tooltip that says &#8220;You can drag this recipe to another menu&#8221;) so her instinct was to click on the recipe and select &#8220;<em>Add to Menu</em>&#8221; again.  In theory, this should work well (though the recipe would be <em>added</em> to the new menu, not <em>moved</em> from the old menu.)  However, since the page requires a refresh before the newly added recipes would show up, she figured the feature wasn&#8217;t working as she saw no indication the recipe was moved.  This also caused some bugs to surface with &#8220;out of date&#8221; menus in the UI, causing a few embarrassing script errors as well.</p>
<p>9 out of 10 users were immediately able to rename a menu simply by clicking on the title, and the remaining user eventually figured it out after trying to right click on things.  All users were able to print a menu too, however there seems to be a bug on Firefox that prevents the print dialog from actually coming up.</p>
<p>Overall, it seems I have a lot of work to do.  <strong>So, what needs to change?</strong></p>
<p>First off, the search page needs a &#8220;<em>Submit</em>&#8221; button.  There at least needs to be a &#8220;<em>Go</em>&#8221; button next to the keyword text box so users have something to click on.  The meal filters need to be labeled as such to avoid confusion.  The ingredient inclusion and exclusion text boxes need to make it clear to enter one ingredient at a time, and the interface needs to be more forgiving when users tab away without selecting an item or pressing enter.  I&#8217;m actually thinking of just removing the auto-complete mechanism all together, since it has always just felt clunky.</p>
<p>Sorting needs to make more sense and show which direction results are being sorted in.  Either &#8220;<em>Total Time</em>&#8221; should be removed from the sorting options, or I should display the total time for each recipe in the list.</p>
<p>There needs to be visual cues when search results are updated, especially for those users lacking the sufficient screen real estate to see both the search interface and result list on the screen at once.</p>
<p>The checkboxes need to be made more obvious, or I need to use standard (albiet ugly) HTML check boxes instead.  My original design used standard check boxes, but I absolutely hated how they looked.  The fact that 100% of web users are trained to recognize a standard checkbox might outweigh my fetish for visual appeal.</p>
<p>When a new menu is created, a popup needs to explicitly state how many recipes were added to the menu, and the recipe viewer needs to visually indicate if the displayed recipe is part of one or more menus.</p>
<p>The queue page needs a full description of what the queue is, and the Queue top menu link needs a tooltip such as &#8220;Click here to learn about the queue!&#8221;</p>
<p>The &#8220;<em>What Can I Make</em>&#8221; feature needs to clarify that only a single ingredient should be entered at a time, and provide a submit button rather than assuming users will hit <em>enter</em>.  Perhaps there should be some subtle UI indication if an ingredient is not understood.</p>
<p>When removing a recipe from the queue, I should either not ask the user to rate the recipe, or make it abundantly clear that the rating is optional, or provide a special button that says &#8220;I did not make this!&#8221; or something.</p>
<p>Drag and drop between menus needs to work better, and users should be able to drop anywhere in the menu, not just on the title bar.  Perhaps once the user starts dragging (which almost everyone intuitively does), the UI can change and guide them visually in some way.</p>
<h2>The Surprising</h2>
<p>Several things really surprised me about the feedback I got.  First was how dependent the average user is on the mouse.  When people are done typing, they want to click on things.  They do not assume they can press enter.  Power users and programmers are the ones that like keyboard shortcuts for things.</p>
<p>I was also very surprised at the sheer number of people who understand drag and drop.  Even more surprising was the reaction they had after drag and drop <em>worked</em>.  They would usually shout &#8220;Wow!  I didn&#8217;t expect that would work!&#8221; or something similar.  Which is odd, since why would your first instinct be to try something that you don&#8217;t think will work.</p>
<h2>What I Will Do Next Time</h2>
<p>Unfortunately, the feedback shows that I&#8217;m nowhere close to having this site ready to launch any time in the near future.  This also means I will need to do a second round of usability testing after fixing the major issues that were uncovered.</p>
<p>I think a bit of the confusion was caused by the script itself.  The instructions for the testers might have been a bit too vague.  For example, I asked them what they could make with &#8220;12 eggs&#8221;, but I didn&#8217;t tell them to click on &#8220;<em>What Can I Make?</em>&#8221;  This meant the user knew it could be done, but had to figure out how to actually do it.  A typical user might not try typing in &#8220;<em>12 eggs</em>&#8221; into the &#8220;<em>Ingredients to Include</em>&#8221; textbox on their own.  I felt it was an expensive way to learn this mistake as well.  Several testers never even got to the &#8220;<em>What Can I Make?</em>&#8221; tab so I lost a lot of potential feedback on it.  I think it might have been smart to &#8220;test out&#8221; the script on a friend first (for free) to make sure I was communicating each step clearly.</p>
<p>So, with that said I guess there&#8217;s nothing left to do but get back to work!  Though these results were quite discouraging, they did show definitive patterns.  If each user fumbled on completely different tasks, that would be one thing.  However, there are clear parts of the interface that <em>every single person</em> failed miserably on, and these things absolutely have to be fixed.  I&#8217;m definitely glad I know about these things now rather than launching the site to huge fanfare, only to wonder why no one came back.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kitchenpc.wordpress.com/873/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kitchenpc.wordpress.com/873/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kitchenpc.wordpress.com/873/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kitchenpc.wordpress.com/873/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kitchenpc.wordpress.com/873/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kitchenpc.wordpress.com/873/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kitchenpc.wordpress.com/873/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kitchenpc.wordpress.com/873/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kitchenpc.wordpress.com/873/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kitchenpc.wordpress.com/873/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kitchenpc.wordpress.com/873/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kitchenpc.wordpress.com/873/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kitchenpc.wordpress.com/873/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kitchenpc.wordpress.com/873/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=873&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kitchenpc.com/2012/03/15/c-kitchenpc-exe-search-maxtime-30-avoid-eggs/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4df33f9e8a81cc9d8046f057dbb4debc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kitchenpc</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/03/newsearch.png?w=150" medium="image">
			<media:title type="html">New search interface</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/03/checkboxes.png?w=300" medium="image">
			<media:title type="html">Checkboxes</media:title>
		</media:content>

		<media:content url="http://kitchenpc.files.wordpress.com/2012/03/dequeue.png?w=300" medium="image">
			<media:title type="html">De-queue Popup</media:title>
		</media:content>
	</item>
		<item>
		<title>A First Look at the New KitchenPC! (Video)</title>
		<link>http://blog.kitchenpc.com/2012/03/04/a-first-look-at-the-new-kitchenpc-video/</link>
		<comments>http://blog.kitchenpc.com/2012/03/04/a-first-look-at-the-new-kitchenpc-video/#comments</comments>
		<pubDate>Sun, 04 Mar 2012 08:34:58 +0000</pubDate>
		<dc:creator>kitchenpc</dc:creator>
				<category><![CDATA[Business]]></category>

		<guid isPermaLink="false">http://blog.kitchenpc.com/?p=854</guid>
		<description><![CDATA[Note: I&#8217;d recommend clicking the little &#8220;HD&#8221; button in the top right corner of the video player :)<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=854&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h3><div id="v-dgQ1C4Ao-1" class="video-player" style="width:500px;height:312px">
<embed id="v-dgQ1C4Ao-1-video" src="http://s0.videopress.com/player.swf?v=1.03&amp;guid=dgQ1C4Ao&amp;isDynamicSeeking=true" type="application/x-shockwave-flash" width="500" height="312" title="KitchenPC &#8211; First Look" wmode="direct" seamlesstabbing="true" allowfullscreen="true" allowscriptaccess="always" overstretch="true"></embed></div></h3>
<h4></h4>
<h5 style="text-align:center;">Note: I&#8217;d recommend clicking the little &#8220;HD&#8221; button in the top right corner of the video player :)</h5>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kitchenpc.wordpress.com/854/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kitchenpc.wordpress.com/854/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kitchenpc.wordpress.com/854/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kitchenpc.wordpress.com/854/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kitchenpc.wordpress.com/854/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kitchenpc.wordpress.com/854/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kitchenpc.wordpress.com/854/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kitchenpc.wordpress.com/854/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kitchenpc.wordpress.com/854/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kitchenpc.wordpress.com/854/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kitchenpc.wordpress.com/854/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kitchenpc.wordpress.com/854/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kitchenpc.wordpress.com/854/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kitchenpc.wordpress.com/854/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=854&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" /><div><a href="http://blog.kitchenpc.com/2012/03/04/a-first-look-at-the-new-kitchenpc-video/"><img alt="KitchenPC &#8211; First Look" src="http://videos.videopress.com/dgQ1C4Ao/final_std.original.jpg" width="160" height="120" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.kitchenpc.com/2012/03/04/a-first-look-at-the-new-kitchenpc-video/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<enclosure url="http://videos.videopress.com/dgQ1C4Ao/final_dvd.mp4" length="205949952" type="video/mp4" />

		<media:content url="http://0.gravatar.com/avatar/4df33f9e8a81cc9d8046f057dbb4debc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kitchenpc</media:title>
		</media:content>

		<media:group>
			<media:content url="http://videos.videopress.com/dgQ1C4Ao/final_dvd.mp4" fileSize="205949952" type="video/mp4" medium="video" bitrate="1528" isDefault="true" duration="1053" width="640" height="400" />

			<media:content url="http://videos.videopress.com/dgQ1C4Ao/final_std.mp4" fileSize="107288064" type="video/mp4" medium="video" bitrate="796" isDefault="false" duration="1053" width="400" height="250" />

			<media:content url="http://videos.videopress.com/dgQ1C4Ao/final_fmt1.ogv" fileSize="107288064" type="video/ogg" medium="video" bitrate="796" isDefault="false" duration="1053" width="400" height="250" />

			<media:rating scheme="urn:mpaa">g</media:rating>
			<media:title type="plain">KitchenPC &#8211; First Look</media:title>
			<media:description type="plain">A first look at the new KitchenPC website.</media:description>
			<media:thumbnail url="http://videos.videopress.com/dgQ1C4Ao/final_std.original.jpg" width="256" height="160" />
			<media:player url="http://s0.videopress.com/player.swf?v=1.03&#38;guid=dgQ1C4Ao&#38;isDynamicSeeking=true" width="400" height="250" />
		</media:group>
	</item>
		<item>
		<title>How SOPA will destroy the country in 6 months</title>
		<link>http://blog.kitchenpc.com/2012/01/14/how-sopa-will-destroy-the-country-in-6-months/</link>
		<comments>http://blog.kitchenpc.com/2012/01/14/how-sopa-will-destroy-the-country-in-6-months/#comments</comments>
		<pubDate>Sun, 15 Jan 2012 04:52:55 +0000</pubDate>
		<dc:creator>kitchenpc</dc:creator>
				<category><![CDATA[Technical]]></category>

		<guid isPermaLink="false">http://blog.kitchenpc.com/?p=839</guid>
		<description><![CDATA[I figured I&#8217;d take a break from my usual KitchenPC related postings and talk about something near and dear to the tech community. This evening, a friend and I were having a mostly civil discussion about the effects of SOPA and exactly what it would mean for privacy, free speech and the future of the <a href="http://blog.kitchenpc.com/2012/01/14/how-sopa-will-destroy-the-country-in-6-months/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=839&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I figured I&#8217;d take a break from my usual KitchenPC related postings and talk about something near and dear to the tech community.</p>
<p>This evening, a friend and I were having a mostly civil discussion about the effects of SOPA and exactly what it would mean for privacy, free speech and the future of the Internet.  It became clear to me that, while this proposed bill is for sure scary, there is absolutely no technical implementation that I can see which would have any affect on software piracy or copyright infringement.  The only thing that this would do is push further components of the Internet&#8217;s architecture underground.</p>
<p>I&#8217;ve decided it would be fun to outline my hypothetical six-month timeline for the universe post-SOPA.  It&#8217;s for sure hyperbole, but it also provided me with some amusement to contemplate.  I&#8217;m far from an expert on Internet architecture, and even I was able to come up with reasonable workarounds for this proposed &#8220;DNS-blocking&#8221;.  Imagine what real hackers could do, given enough time and snacks from Circle K.</p>
<h3>Month 1: SOPA is passed, and domains can be blocked without court order</h3>
<p>Within days, copyright owners complain about thousands of sites that contain links to or posts about copyrighted materials.  Every day, YouTube is threatened to remove content or name resolution for youtube.com will point into a black hole.  Larger sites have the legal resources to deal with this, but this causes a huge amount of overhead and their earnings suffer.  Apparently, users don&#8217;t like it when every third Wednesday, YouTube becomes blocked for three hours.  Thousands of tech jobs are lost as the casualties pile up.  Smaller sites don&#8217;t stand a chance and go under immediately.</p>
<h3>Month 2: Pirate sites decide DNS servers are lame anyway.</h3>
<p>Pirates are keenly aware that only name resolution (which is done through any DNS server you care to configure your network interface to use) is inconvenienced by this law.  They figure they&#8217;re already running their own pirate sites, why not just run their own pirate DNS servers?  The more technically savy quickly configure their computers to use these DNS servers instead of the legitimate, law-respecting ones run by ISPs and schools.</p>
<p>These DNS servers respond like anything else, but also resolve special names such as &#8220;http://PiratesRUs/&#8221;.  Who needs top level domains anyway?  These DNS servers would of course completely ignore any request to block certain legitimate domains accused of piracy.</p>
<h3>Month 3: Lobby groups pressure congress to outlaw these rogue DNS servers</h3>
<p>After becoming irate that people can apparently still get to these pirate sites, copyright owners demand a more aggressive solution.  Non-compliance with SOPA laws while running your own DNS server is a crime, and the government spends massive resources trying to track down offenders.  The problem is, most of these pirate DNS servers &#8211; like spammers &#8211; are operated off shore.</p>
<h3>Month 4: The government starts blocking IPs known to operate rogue DNS servers</h3>
<p>Each and every time a rogue DNS server is shut down, three new ones pop up.  The government even attempts to port scan over four-billion IP addresses (2<sup>32</sup>) looking for &#8220;unregistered&#8221; DNS servers.  Hackers decide that IPv4 is lame anyway.</p>
<h4>Month 5: People start using IPv6 networks for name resolution</h4>
<p>Since every major OS now supports IPv6, these networks start to become increasingly popular especially for name resolution.  The government attempts to use the same tactics to enforce the law, however trying to police 2<sup>128</sup> possible IP addresses becomes impossible.  Every time an IPv6 address is blocked, it just changes to something else.  New schemes involving IPv6 addresses that change every 30 seconds also become available, but are too much of a hassle for people to use.  Peer-to-peer name resolution is also considered, but has its own problems.</p>
<p>The hacker community once again steps back and says, &#8220;Wait a second.  There are enough IP addresses every living organizing on the planet, including bacteria.&#8221;</p>
<p>A new architecture for name resolution is devised.  Users can now send a request for their own personal IP address by using a known public-key and a numeric code generated randomly by their own computer.  That numeric code is used as a shared key to exchange the newly generated IPv6 address, ensuring no one could have possibly intercepted the communication.  That user will then use their personalized IPv6 address to reach pirate DNS servers operating in countries all over the world.  These IPv6 addresses are unknown to anyone but the holder.  Even if your personal IPv6 address did leak, you could just get a new one in a few minutes.</p>
<p>Software is released on the black market with open-source implementations of name resolution layers that pretty much do all of this and more transparently.  Name resolution itself is also done with the originally generated encrypted shared key, as certainly criminal name resolution will be considered terrorism and wire-tapped.</p>
<h3>Month 6: The tech economy is in ruins, everyone hates the RIAA and piracy is still thriving.</h3>
<p>Since every legitimate place to download legal content is in ruins, more and more people turn to piracy as it&#8217;s the only way to watch the latest episode of <em>Glee</em>.  The American people are now so angry at the record industry and movie distribution studios for ruining the Internet, that no one ever again bothers to buy a CD or BluRay disc.  Record labels and motion picture distributors begin to file for bankruptcy.  The government has wasted considerable amounts of time and money trying to stamp out piracy, and every step of the way has been thwarted by minds more creative than their own.  A new wave of politicians run on the promise of change, and bring net neutrality and free speech back to the Internet.  Yay!</p>
<p>Oh, of course by that time everyone just pirates everything, all the tech giants have collapsed, the stock market has tanked and SOPA advocates no longer have the money to purchase their own congressmen to do their bidding.  Oh well.</p>
<p><a href="http://americancensorship.org/" target="_blank">Click Here to make your voice heard!</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kitchenpc.wordpress.com/839/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kitchenpc.wordpress.com/839/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kitchenpc.wordpress.com/839/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kitchenpc.wordpress.com/839/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kitchenpc.wordpress.com/839/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kitchenpc.wordpress.com/839/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kitchenpc.wordpress.com/839/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kitchenpc.wordpress.com/839/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kitchenpc.wordpress.com/839/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kitchenpc.wordpress.com/839/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kitchenpc.wordpress.com/839/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kitchenpc.wordpress.com/839/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kitchenpc.wordpress.com/839/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kitchenpc.wordpress.com/839/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=839&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kitchenpc.com/2012/01/14/how-sopa-will-destroy-the-country-in-6-months/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4df33f9e8a81cc9d8046f057dbb4debc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kitchenpc</media:title>
		</media:content>
	</item>
		<item>
		<title>Pivot Guilt</title>
		<link>http://blog.kitchenpc.com/2012/01/11/pivot-guilt/</link>
		<comments>http://blog.kitchenpc.com/2012/01/11/pivot-guilt/#comments</comments>
		<pubDate>Thu, 12 Jan 2012 04:14:57 +0000</pubDate>
		<dc:creator>kitchenpc</dc:creator>
				<category><![CDATA[Business]]></category>

		<guid isPermaLink="false">http://blog.kitchenpc.com/?p=831</guid>
		<description><![CDATA[One of the unfortunate inevitabilities created by the pivoting of any web startup as it searches desperately for a business model is the complete and utter alienation and ungrateful dismissal of the few users you did manage to scrounge up in cyberspace.  Sometimes it may feel difficult to cut off a finger to save the <a href="http://blog.kitchenpc.com/2012/01/11/pivot-guilt/" class="excerpt-more-link">[&#8230;]</a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=831&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>One of the unfortunate inevitabilities created by the pivoting of any web startup as it searches desperately for a business model is the complete and utter alienation and ungrateful dismissal of the few users you did manage to scrounge up in cyberspace.  Sometimes it may feel difficult to cut off a finger to save the whole arm.  What about those 1,000 early adopters who were kind enough to put up with all the bugs and work around all the limitations in your software?  Are they to be thrown to the gutter, their time and effort completely unappreciated?  What about the content they contributed to your site, shall it be wiped from disk as if it had never existed?</p>
<p>These questions have bounced around in my head lately, like little rubber guilt balls.</p>
<p>To me, it’s obvious that KitchenPC needs to become the most powerful recipe search engine on the Internet.  People search for recipes, tens of millions of them.  Powerful search algorithms are <em>hugely</em> valuable.  Companies like Google, Yahoo! and Microsoft purchase powerful search technology.  KitchenPC can pivot into this market by taking advantage of several of its technical abilities such as ingredient aggregation and complete recipe normalization and allow users to intelligently find recipes and manage those search results in groups rather than one at a time.</p>
<p>The failed experiment of trying to build a respectable recipe database on my own taught me many lessons; chief among them was not to try to build a respectable recipe database on my own.  The <em>Internet</em> should be my recipe database.  Users do not want to manage recipe data themselves online, nor do they want to use a completely convoluted web-based editor that’s limited beyond reason due to a level of backend normalization that borders on digital OCD.</p>
<p>So, if this is the direction of KitchenPC’s future, is it possible to respect the past?  I do know for a fact that several users have typed in dozens of recipes on their own, and adore KitchenPC as a place to store their personal favorites online.  Obviously, I’m not going to just delete their content.  I’m not that kind of person.</p>
<p>There are a few ideas I’m considering, which I’d like to go over from worst-case scenario but completely practical to purely ideal but would cause <a href="http://en.wikipedia.org/wiki/Eric_Ries" target="_blank">Eric Ries</a> to knock on my door and proceed to beat me over the head with a club.</p>
<h3>Worst Case: Just keep everyone’s recipes in the database</h3>
<p>At the very least, I’d like to just keep everyone’s recipes in the database.  They’ll exist just as if they’d been crawled from the web somewhere, however they won’t have any source URL.  They’ll never expire from the cache or be updated.  If you’ve uploaded a recipe to KitchenPC, it will automatically be saved in a default menu called “Favorites”, allowing you to quickly find content you’ve contributed.  However, since recipes can no longer be edited on KitchenPC (since, you know, I’m a search engine now) these recipes will just sort of “sit in limbo” forever.  Sorry if you made any typos.  As far as the 10,000 or so recipes my hired help created, I will probably be able to salvage the majority of these as they do have source URLs.  My crawler can re-import these automatically and most likely do a better job at it as well.  Basically, these recipes will be nothing more than leads for my crawler to use.  This will allow me to preserve existing user cookbooks, so any recipes you&#8217;ve saved links to on KitchenPC will hopefully still exist.</p>
<h3>Private Recipes</h3>
<p>Another option is to resurrect my recipe editor and allow the concept of personal recipes.  These recipes would be linked to an individual user account, and those users could access them through their own saved menus, but they wouldn’t appear on any searches or be accessible for anyone else.  This prevents potentially bad content for surfacing in search results.  The recipe editor is so awful that the majority of recipes created by users are missing lots of data or hacked into working out of pure frustration.  The problem with this is that I was truly looking forward to completely doing away with the recipe editor page.  Not only is it a usability nightmare, but it also contains an insane amount of code I have to support.  Furthermore, the second I start allowing user-created content, I go counter to my vision of re-inventing KitchenPC as a search engine.  It becomes a search engine plus a place to store your recipes online.  If I were to resurrect Steve Jobs and, as repayment for his extended life, I enslaved him as my personal business advisor, he would tell me to focus on doing one thing and doing it really well.  Zombie Jobs would be right.</p>
<h3>The Dropbox of Recipes</h3>
<p>This one really resonates with users well.  A huge chunk of my survey respondents store recipes, or links to recipes, on their computers.  They want some sort of centralized place to organize them.  They want to consolidate their browser links, their Word documents, their recipe emails, etc.  KitchenPC would be an awesome place to do that.  I’ve spec’ed out features that would provide exactly this ability.  Users could upload plain text (or just paste it in), Word documents, PDF files, or just plain URLs.  If KitchenPC was able to crawl or index the data, it would.  URLs would simply be added to the crawler queue, and other unformatted data would be accessible privately for that user.  Users would be able to add these private recipes to menus along with other saved search results, but features such as ingredient totals wouldn’t be available.</p>
<p>I think this would be a very useful feature, and I think it might be the eventual direction for KitchenPC.  However, I just can’t make myself admit that it’s important enough to launch in this first wave.  I need to be able to sell KitchenPC as a simple, easy to understand vision that anyone can grasp right away.  If I tell someone that KitchenPC is “the most powerful recipe search engine on the Internet,” they immediately understand.  They think, “Cool!  <em>I</em> search for recipes!” and will give it as shot.  If I sell it as a search engine that also allows private recipe collections, user content, and all sorts of other directions not relevant to the core vision, they tune out and go back to playing Angry Birds.</p>
<h2>So Now What?</h2>
<p>While I’m making great progress on the KitchenPC re-invention, it’s looking less and less likely that I’ll have time to do everything I want.  Fail early, fail often.  If features need to be cut, the first to go will be anything not directly related to being the most powerful recipe search engine on the Internet.  So I do apologize in advance to my users who have uploaded a few of their favorite recipes.  I promise I will keep the data at the very least, and you&#8217;ll be able to access this data!  Hopefully, down the road I’ll be able to build some scenarios around personalized recipe management and all your content will once again be fully available to you in all sorts of great ways.</p>
<p>I’ll end this post by apologizing for the lack of status updates recently.  I’m still working hard on KitchenPC pretty much every night, and making amazing progress.  The new interface is almost to the point where I can “leak” some screen captures or video demos of this new direction as somewhat of an appetizer for what’s to come.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/kitchenpc.wordpress.com/831/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/kitchenpc.wordpress.com/831/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/kitchenpc.wordpress.com/831/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/kitchenpc.wordpress.com/831/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/kitchenpc.wordpress.com/831/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/kitchenpc.wordpress.com/831/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/kitchenpc.wordpress.com/831/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/kitchenpc.wordpress.com/831/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/kitchenpc.wordpress.com/831/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/kitchenpc.wordpress.com/831/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/kitchenpc.wordpress.com/831/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/kitchenpc.wordpress.com/831/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/kitchenpc.wordpress.com/831/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/kitchenpc.wordpress.com/831/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.kitchenpc.com&#038;blog=14224043&#038;post=831&#038;subd=kitchenpc&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.kitchenpc.com/2012/01/11/pivot-guilt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4df33f9e8a81cc9d8046f057dbb4debc?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">kitchenpc</media:title>
		</media:content>
	</item>
	</channel>
</rss>
