<?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/"
	>

<channel>
	<title>Code Presence</title>
	<atom:link href="http://www.codepresencelabs.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.codepresencelabs.com</link>
	<description>Building software people love</description>
	<lastBuildDate>Thu, 26 Aug 2010 18:23:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>Bing Food Cart Finder</title>
		<link>http://www.codepresencelabs.com/2010/08/24/bing-food-cart-finder/</link>
		<comments>http://www.codepresencelabs.com/2010/08/24/bing-food-cart-finder/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 21:41:30 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[What We Do]]></category>

		<guid isPermaLink="false">http://www.codepresencelabs.com/?p=145</guid>
		<description><![CDATA[The Bing Food Cart Finder helps hungry foodies locate and learn about places to eat. The app initially covers only Portland and tracks over 250 food carts in the area. It shows Foursquare activity associated with each cart, allows you to slice and dice them by their various attributes, and even maps tweets related to [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.bingfoodcarts.com">Bing Food Cart</a> Finder helps hungry foodies locate and learn about places to eat. The app initially covers only Portland and tracks over 250 food carts in the area.  It shows Foursquare activity associated with each cart, allows you to slice and dice them by their various attributes, and even maps tweets related to the carts.  We delivered all of the code for this project in a crazy short time frame.  It has a silverlight experience which lives within the Bing Map App framework, a downlevel experience for this without silverlight <a href="http://www.bingfoodcarts.com/js">here</a> and an iphone optimized experience using jQTouch.</p>
<p>Here are some pics of it in action:</p>
<p style="text-align: center;">
<p style="text-align: center;"><a href="http://www.codepresencelabs.com/wp-content/uploads/2010/08/5758.03_twitter_thumb_36EF6B8D.jpg"><img class="aligncenter size-full wp-image-152" title="5758.03_twitter_thumb_36EF6B8D" src="http://www.codepresencelabs.com/wp-content/uploads/2010/08/5758.03_twitter_thumb_36EF6B8D.jpg" alt="" width="566" height="314" /></a></p>
<p style="text-align: center;">and</p>
<p style="text-align: center;"><a href="http://www.codepresencelabs.com/wp-content/uploads/2010/08/4762.01_initload_thumb_20BD8E691.jpg"><img class="aligncenter size-full wp-image-153" title="4762.01_initload_thumb_20BD8E69" src="http://www.codepresencelabs.com/wp-content/uploads/2010/08/4762.01_initload_thumb_20BD8E691.jpg" alt="" width="566" height="300" /></a></p>
<p style="text-align: center;">
<p style="text-align: left;">Press: <a href="http://www.nytimes.com/external/readwriteweb/2010/08/24/24readwriteweb-bing-goes-hyperlocal-with-portland-food-car-94574.html?partner=rss&amp;emc=rss">New York Times</a>, <a href="http://news.cnet.com/8301-27076_3-20014620-248.html">CNet</a>, <a href="http://blog.seattlepi.com/microsoft/archives/219295.asp">Seattle PI</a>, <a href="http://seattletimes.nwsource.com/html/microsoftpri0/2012719126_bingmapshasafoodcartfinderforportland.html">Seattle Times</a>, <a href="http://www.readwriteweb.com/archives/bing_goes_hyperlocal_with_portland_food_cart_site.php#comment-238411">Read Write Web</a></p>
<p style="text-align: center;">
]]></content:encoded>
			<wfw:commentRss>http://www.codepresencelabs.com/2010/08/24/bing-food-cart-finder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Home Turf Finder</title>
		<link>http://www.codepresencelabs.com/2010/08/15/home-turf-finder/</link>
		<comments>http://www.codepresencelabs.com/2010/08/15/home-turf-finder/#comments</comments>
		<pubDate>Mon, 16 Aug 2010 02:32:48 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[What We Do]]></category>

		<guid isPermaLink="false">http://www.codepresencelabs.com/?p=58</guid>
		<description><![CDATA[Home Turf Finder was a Bing Map App, developed in Silverlight and Javascript (downlevel) for Bing Maps to help users find a great place to watch their favorite team during the 2010 World Cup.  It mashed up data from Bing Maps, ThrillList and FourSquare to show the most popular destination to watch your team.  We [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.hometurffinder.com/">Home Turf Finder</a> was a Bing Map App, developed in Silverlight and Javascript (downlevel) for <a href="http://maps.bing.com/">Bing Maps</a> to help users find a great place to watch their favorite team during  the 2010 World Cup.  It mashed up data from Bing Maps, ThrillList and  FourSquare to show the most popular destination to watch your team.  We  did all of the development work for this application and worked with  8Ninths and Microsoft Marketing to bring it to completion.  This  application was covered by <a href="http://techcrunch.com/2010/06/10/bing-foursquare-badge/">TechCrunch</a>, <a href="http://www.thrillist.com/allied/138294?">ThrillList</a>, and others.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codepresencelabs.com/2010/08/15/home-turf-finder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ROBOblaster</title>
		<link>http://www.codepresencelabs.com/2010/08/15/roboblaster/</link>
		<comments>http://www.codepresencelabs.com/2010/08/15/roboblaster/#comments</comments>
		<pubDate>Mon, 16 Aug 2010 02:28:49 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[What We Do]]></category>

		<guid isPermaLink="false">http://www.codepresencelabs.com/?p=54</guid>
		<description><![CDATA[ROBOblaster.com is a full service online marketing solution that specializes in the housing rental industry.  It offers automated ad syndication, conversion rate tracking of pageviews, phone calls, sms and email and advanced analytics on properties managed through ROBOblaster.   Initially Code Presence was asked to help the company meet some aggressive technical deadlines but that [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.roboblaster.com/">ROBOblaster.com</a> is a full  service online marketing solution that specializes in the housing rental  industry.  It offers automated ad syndication, conversion rate tracking  of pageviews, phone calls, sms and email and advanced analytics on  properties managed through ROBOblaster.   Initially Code Presence was  asked to help the company meet some aggressive technical deadlines but  that relationship quickly developed into much more and Josh is currently  serving as their CTO.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codepresencelabs.com/2010/08/15/roboblaster/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zistle</title>
		<link>http://www.codepresencelabs.com/2010/08/15/zistle/</link>
		<comments>http://www.codepresencelabs.com/2010/08/15/zistle/#comments</comments>
		<pubDate>Mon, 16 Aug 2010 02:26:27 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[What We Do]]></category>

		<guid isPermaLink="false">http://www.codepresencelabs.com/?p=50</guid>
		<description><![CDATA[Zistle.com is a sports card community built around our collection management suite of tools in PHP and then Ruby on Rails.  We own this website and continue to actively develop it.  It was initially launched in early 2009 as a beta project to experiment with crowd-sourcing and data manipulation at large scale.  It has since [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zistle.com/">Zistle.com</a> is a sports card  community built around our collection management suite of tools in PHP  and then Ruby on Rails.  We own this website and continue to actively  develop it.  It was initially launched in early 2009 as a beta project  to experiment with crowd-sourcing and data manipulation at large scale.   It has since taken off in the sports card community and has received  rave reviews from users both for its ease of use as well as its  performance.  It has quickly become the definitive online resource for  sports cards collection management and is one of the largest databases  of sports card images on the internet.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codepresencelabs.com/2010/08/15/zistle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WorkSimple</title>
		<link>http://www.codepresencelabs.com/2010/08/15/worksimple/</link>
		<comments>http://www.codepresencelabs.com/2010/08/15/worksimple/#comments</comments>
		<pubDate>Mon, 16 Aug 2010 02:23:49 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[What We Do]]></category>

		<guid isPermaLink="false">http://www.codepresencelabs.com/?p=46</guid>
		<description><![CDATA[WorkSimple is the first social approach to talent management.  It is the recommended tool for workplaces that embrace the ROWE ideology.  We worked with them from their inception, helping to craft their message, application and brand.  We were the primary development team on the product and implemented it in Ruby on Rails.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.getworksimple.com/">WorkSimple</a> is the first  social approach to talent management.  It is the recommended tool for  workplaces that embrace the ROWE ideology.  We worked with them from  their inception, helping to craft their message, application and brand.   We were the primary development team on the product and implemented it  in Ruby on Rails.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codepresencelabs.com/2010/08/15/worksimple/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lolligift</title>
		<link>http://www.codepresencelabs.com/2010/08/15/lolligift/</link>
		<comments>http://www.codepresencelabs.com/2010/08/15/lolligift/#comments</comments>
		<pubDate>Mon, 16 Aug 2010 02:15:39 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[What We Do]]></category>

		<guid isPermaLink="false">http://www.codepresencelabs.com/?p=39</guid>
		<description><![CDATA[Lolligift.com is a fun, affordable and secure way for friends to pool their money and buy a gift for a special occasion.  It is the first incubation to come out of Seattle based 8ninths.com and the underlaying architecture is being used as a white labeled gift pooling service for a variety of clients.  We were [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.lolligift.com/"></a>Lolligift.com is a fun,  affordable and secure way for friends to pool their money  and buy a  gift for a special occasion.  It is the first incubation to come out of  Seattle based <a href="http://www.8ninths.com/">8ninths.com</a> and the  underlaying architecture is being used as a white labeled gift pooling  service for a variety of clients.  We were involved in the project from  its inception and helped shape the idea, application work flow and  business model.  We have subsequently done development work in Ruby on  Rails for the platform as it has looked to expand its reach.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codepresencelabs.com/2010/08/15/lolligift/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thumbtack</title>
		<link>http://www.codepresencelabs.com/2010/08/15/thumbtack/</link>
		<comments>http://www.codepresencelabs.com/2010/08/15/thumbtack/#comments</comments>
		<pubDate>Mon, 16 Aug 2010 02:07:58 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[What We Do]]></category>

		<guid isPermaLink="false">http://www.codepresencelabs.com/?p=34</guid>
		<description><![CDATA[While at Microsoft Live Labs, Josh built the now defunct thumbtack application.  Thumbtack was a revolutionary new way to archive your daily web use by saving snippets from the web and use machine learning to enhance those clips and their ability to help you make decisions.  Josh worked on this project from inception to launch, [...]]]></description>
			<content:encoded><![CDATA[<p>While at Microsoft Live Labs, Josh built the now defunct <a href="http://livelabs.com/PastProjects.html">thumbtack</a> application.  Thumbtack was a revolutionary new way to archive your  daily web use by saving snippets from the web and use machine learning  to enhance those clips and their ability to help you make decisions.   Josh worked on this project from inception to launch, helping to brand  and design the application, as well as implementing the ground-breaking  UI in Javascript and implementing a relational object store for the  backend on the .NET stack.  During this time he helped build the <a href="http://livelabs.com/PastProjects.html">web sandbox</a> as a means for creating a secure javascript gadget platform for thumbtack.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codepresencelabs.com/2010/08/15/thumbtack/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bullet plugin</title>
		<link>http://www.codepresencelabs.com/2009/11/03/bullet-plugin/</link>
		<comments>http://www.codepresencelabs.com/2009/11/03/bullet-plugin/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 03:56:13 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://www.codepresencelabs.com/2009/11/03/bullet-plugin/</guid>
		<description><![CDATA[<p></p>
]]></description>
			<content:encoded><![CDATA[<p>Recently I have been working on improving the performance in one of my clients Rails applications, trying to get page load times down. &nbsp;Looking at the query log it was obvious that there was way too much activity going on for what was being rendered on the page&#8211;there were <a href="http://stackoverflow.com/questions/97197/what-is-the-n1-selects-problem">N+1 queries</a> all over the place. &nbsp;This was nothing a few joins (or <a href="http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations">eager loads</a> as the rails folks like to say) wouldn&#8217;t fix. &nbsp;So after changing the queries to make sure that all the necessary data was gathered in just one pass, I wondered how many other places this was cropping up in the application.&nbsp;That is when I stumbled upon <a href="http://github.com/flyerhzm">flyerhzm</a>&#8216;s <a href="http://github.com/flyerhzm/bullet">Bullet Gem</a>.</p>
<p>In short the gem monitors the queries that your server is making and notifies you as to whether or not you are encountering any N+1 scenarios. &nbsp;It also notifies you as to whether or not you have unused eager loads. &nbsp;It can be configured to notify you via javascript alerts, growl notifications, firebug notifications, or just log the instances.</p>
<p>Thus far it has been invaluable in finding instances where an eager load would help. &nbsp;It can (and should) be configured to run only in Development mode and will sit in the background until it has something to notify you about, so you can just turn it on, keep coding, and as you browse around your local instance, get notified as to potential areas for optimization.</p>
<p>While it is definitely worth installing a few things to note:</p>
<ol></p>
<li>You still need to use your judgement as to what is the right call, this just points out areas to investigate (though it does tell you what models to include)</li>
<p></p>
<li>It has some bugs still. &nbsp;There are instances where it correctly insists that you should include something, and then incorrectly tells you that you have an unused eager load once you include it</li>
<p></ol>
<p>If you have your development.rb file in source control and shared among developers, one slight modification to the code on the github site that removes the gem dependency from your fellow developers is as follows:</p>
<pre class="code">  <code class="ruby">
config.after_initialize do
begin
require 'bullet'
Bullet.enable = false
Bullet.alert = false
Bullet.bullet_logger = true
Bullet.console = true
Bullet.rails_logger = true
Bullet.disable_browser_cache = true
begin
require 'ruby-growl'
Bullet.growl = true
rescue MissingSourceFile
end
rescue MissingSourceFile
end
end
</code>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.codepresencelabs.com/2009/11/03/bullet-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LAMP Development for Windows</title>
		<link>http://www.codepresencelabs.com/2009/04/14/lamp-development-for-windows/</link>
		<comments>http://www.codepresencelabs.com/2009/04/14/lamp-development-for-windows/#comments</comments>
		<pubDate>Wed, 15 Apr 2009 02:32:57 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://www.codepresencelabs.com/2009/04/14/lamp-development-for-windows/</guid>
		<description><![CDATA[<p></p>
]]></description>
			<content:encoded><![CDATA[<p>I have been doing development in PHP for a long time and have yet to find a really satisfactory solution on Windows. &nbsp;When I recently flattened my home PC and had to restart I thought I would try a new setup and here is what I&#8217;m using. &nbsp;Its pretty good to me so far, and I think I&#8217;m going to run with it for the time being:</p>
<h3></h3>
<h3><strong>IDE</strong></h3>
<p><strong>&nbsp;</strong>For an IDE I am using <a href="http://www.easyeclipse.org/site/distributions/lamp.html">EasyEclipse for LAMP</a> which is a nice little package. &nbsp;It uses Eclipse as its base IDE but integrates plugins for PHP, Python, Ruby on Rails (not that good), Subclipse and others. &nbsp;Just download the latest build and install it.</p>
<h3></h3>
<h3><strong>XAMPP</strong></h3>
<p><strong>&nbsp;</strong>To run locally you can install <a href="http://www.wampserver.com/en/">WAMP</a> (I used to use this, it was good)&nbsp;or <a href="http://www.apachefriends.org/en/xampp.html">XAMPP</a>. &nbsp;I am trying XAMPP for now because it is integrated nicely into Eclipse. &nbsp;Out of the box you will get MySQL, Apache, FileZilla and Mercury up and running if you install this.</p>
<p>At this point you can import directly from you subversion repository into the xampp\htdocs directory and you should have a working enlistment deployed (make sure Apache is started) to http://localhost/your_enlistment</p>
<p>There are a few more things that you might want to install, including PEAR and Memcached.</p>
<h3></h3>
<h3><strong>PEAR</strong></h3>
<p>To install <a href="http://pear.php.net/">PEAR </a>for XAMPP, open a command prompt (cmd.exe) as an Administrator (Vista only).</p>
<p>Then navigate the your xampp\php\PEAR\PEAR and execute the go-pear.phar script (its PHP) via:</p>
<p><em>php go-pear.phar</em></p>
<p>You should be able to use the default settings (unless you&#8217;ve tweaked your XAMPP installation). &nbsp;When prompted as to whether you would like to update your php.ini file, say Yes.</p>
<p>At this point you should be done and can now reference PEAR libraries in your PHP scripts.</p>
<h3></h3>
<h3><strong>Memcached</strong></h3>
<p>If you need <a href="http://www.danga.com/memcached/">memcached</a> you can get this up and running in a variety of ways. &nbsp;If you want to build from source you can find it <a href="http://www.danga.com/memcached/download.bml">here</a>. &nbsp;Otherwise search for a <a href="http://www.splinedancer.com/memcached-win32/">pre-compiled windows32 version</a>. &nbsp;Copy the binaries to some place on your development machine and then you will need to start and install the service.</p>
<p>To install the service open a command prompt as an administrator and navigate to the directory with memcached.exe. &nbsp;Install the service by typing:&nbsp;<em>memcached -d install</em></p>
<p>To start the service type:&nbsp;<em>memcached -d start</em></p>
<p>Note that the default reserved cache size for memcached is only 64MB, so if you would like it to be larger, launch the service and append a -m followed by the number of megabytes as an integer. &nbsp;So to launch and reserve a half gig you would launch it as:<em> memcached -d start -m 512</em></p>
<p>Now that the service is running, you will need to let php know that it is. &nbsp;Make sure that you have the correct extension (php_memcache.dll) in the php\ext folder in your xampp directory. &nbsp;After you have verified that this is there, you should update the php.ini file and uncomment (remove the preceding &#8220;;&#8221;) the following line:</p>
<p><em>extension=php_memcache.dll</em></p>
<p>Make sure that this is the php.ini file associated with apache if you want to test this on your local pc (i.e. the one in your apache folder), otherwise you will just have access to this via the CLI version of PHP. &nbsp;Restart Apache and you should be good to go. &nbsp;If you are having issues make sure that there is a Memcache section in your phpinfo() output to verify that the extension is being loaded.</p>
<p>Hope this helps, leave any questions in the comments and I&#8217;ll try to help.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codepresencelabs.com/2009/04/14/lamp-development-for-windows/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Building Grammars in .NET</title>
		<link>http://www.codepresencelabs.com/2008/09/12/building-grammars-in-net/</link>
		<comments>http://www.codepresencelabs.com/2008/09/12/building-grammars-in-net/#comments</comments>
		<pubDate>Fri, 12 Sep 2008 20:09:57 +0000</pubDate>
		<dc:creator>josh</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://www.codepresencelabs.com/2008/09/12/building-grammars-in-net/</guid>
		<description><![CDATA[<p></p>
]]></description>
			<content:encoded><![CDATA[<p>As I&#8217;ve shown before (<a href="/blog/2008/6/5/microsoft-speech-i-getting-your-computer-to-talk.html">here</a>, <a href="/blog/2008/6/11/microsoft-speech-ii-getting-your-computer-to-listen.html">here</a>, and <a href="/blog/2008/6/13/microsoft-speech-iii-setting-up-a-pluggable-infrastructure.html">here</a>), the <a href="http://msdn.microsoft.com/en-us/library/ms723627(VS.85).aspx">Microsoft .NET Speech API</a> allows you  to quickly and easily build applications that take advantage of the good folks at <a href="http://research.microsoft.com/">Microsoft Research</a>&#8216;s work on speech recognition.  The general process is that you can construct a grammar that the engine will recognize for you, and then event handlers for those recognized events will be triggered.  This process then, will only be as effective as the grammars that you can construct for the the <a href="http://msdn.microsoft.com/en-us/library/system.speech.recognition.speechrecognitionengine.aspx">SpeechRecognitionEngine</a>.  In this post I&#8217;ll show you some of the things that you can do to construct Grammars in C#.</p>
<p>The SpeechRecognitionEngine class can load one or many Grammar objects.  The MSDN page describes these Grammar objects in the following way:</p>
<blockquote><p>The System.Speech.Recognition..::.Grammar class provides run time objects that allow an application to specify a specific combination of words, choices of words, and other speech elements that the Speech platform uses to identify meaningful phrases.</p>
<p>The Grammar object fully supports the W3C Speech Recognition Grammar Specification (SRGS) and Context Free Grammar (CFG) specifications. For more information, see SpeechRecognitionGrammar <a href="http://www.w3.org/TR/speech-grammar/">Specification</a>.</p>
<p>Grammars may be precise word phrases, such as &#8220;Turn the computer off,&#8221; or provide choices, semantic lookup tables or wildcards, such as &#8220;Change color to&#8221; and a look up table of acceptable values.</p>
<p>An application&#8217;s recognition engine, as managed by instances of SpeechRecognizer or [T:System.Speech.Recognition.SpeechRecognitionEngine,] may create and load one or more instances Grammar, independently enabling or disabling particular grammars instance, and set Grammar properties such as priorities (Priority and weight (Weight)</p></blockquote>
<p>So you can see that we can construct Grammars that will recognize certain types of input and then load these into the SpeechRecognitionEngine.  These can be <a href="http://msdn.microsoft.com/en-us/library/system.speech.recognition.grammar.priority.aspx">prioritized</a> to help with conflict resolution as well as toggled on and off if you know that only certain grammars are appropriate for a certain context.</p>
<p>So how do we construct these grammars?  Grammars can be constructed in a variety of ways, but we are going to examine the <a href="http://msdn.microsoft.com/en-us/library/system.speech.recognition.grammarbuilder.aspx">GrammarBuilder </a>Class as this is the easiest way to programmatically construct a Grammar.</p>
<p>The simplest example is simple string matching.  If you have a discrete atomic command (e.g. shutdown) that takes no parameters, you can <a href="http://msdn.microsoft.com/en-us/library/ms554229.aspx">initialize a GrammarBuilder with a string</a> and it will fire its recognize event when that string is heard.</p>
<pre class="code">  <code class="csharp">
GrammarBuilder stringGb = new GrammarBuilder("shutdown");
</code>
</pre>
<p>If this was added to a Grammar and loaded in the Recognizer it would fire a recognized event for this Grammar whenever the word &#8220;shutdown&#8221; was heard.  This is easy enough, but somewhat limited, because what if you wanted to also allow them to say &#8220;turn off&#8221; or &#8220;quit&#8221;?  At this point you would have to add 3 Grammars, one with each of those strings.  Enter the <a href="http://msdn.microsoft.com/en-us/library/system.speech.recognition.choices.aspx">Choices</a> class.</p>
<p>The Choices class allows us to create a phrase where one part of the phrase may have many different acceptable values.  In our above example, we want the verbs &#8220;shutdown&#8221;, &#8220;turn off&#8221; and &#8220;quit&#8221; to be interchangeable.  To show how this can be used with a phrase, lets make the user ask nicely by preceding either of those with &#8220;please&#8221;.</p>
<pre class="code">  <code class="csharp">
GrammarBuilder choicesGB = new GrammarBuilder("please");
Choices verbChoices = new Choices("shutdown", "turn off", "quit");
choicesGB.Append(verbChoices);
</code>
</pre>
<p>Now our grammar will trigger an event for all of the following phrases:</p>
<ul>
</p>
<li>please shutdown</li>
<p></p>
<li>please turn off</li>
<p></p>
<li>please quit</li>
<p>
</ul>
<p>You can probably now imagine how you could combine strings and choices to come up with a variety of different recognizable phrases.  However, there is a lot more that this engine can handle, but before we get into that lets review what happens when a phrase is recognized by the SpeechRecognitionEngine.</p>
<p>Remember that when a phrase is recognized, all that the engine will trigger is a <a href="http://msdn.microsoft.com/en-us/library/system.speech.recognition.speechrecognizedeventargs.aspx">SpeechRecognizedEvent</a> to which you can assign a handler.  This same event is fired for all phrases in all grammars that are loaded, so the problem becomes figuring out which phrase triggered the event.  There are numerous strategies for dealing with this so I won&#8217;t go into detail here, but note that the <a href="http://msdn.microsoft.com/en-us/library/system.speech.recognition.recognitioneventargs.result.aspx">SpeechRecognizedEventArgs </a>object has a <a href="http://msdn.microsoft.com/en-us/library/system.speech.recognition.recognitionresult.aspx">RecognitionResult</a> that contains a pointer to the Grammar as well as the Text of the phrase in addition to any Semantic Values that you have assigned (more on that later).  For an example see [post=16 text='here'].</p>
<p>Why take that little detour?  Because once you&#8217;ve tried to actually do something with the result of a recognition event you&#8217;ll realize the utility of <a href="http://msdn.microsoft.com/en-us/library/system.speech.recognition.semanticvalue.aspx">SemanticValues</a>.  Semantic Values allows you to assign values to certain responses so that you do not have to do annoying string parsing in the event handler.</p>
<p>Our first basic example will show how we can simply get the appropriate text in the event handler without having to do string parsing.  Lets say that we know that the user is either going to say &#8216;yes&#8217; or &#8216;no&#8217; to a request, but we want to recognize synonyms of those phrases.  We can do something like the following:</p>
<pre class="code">  <code class="csharp">
GrammarBuilder yesChoices = new Choices("yes", "yeah", "ok").ToGrammarBuilder();
yesChoices.Append(new SemanticResultValue(true));
GrammarBuilder noChoices = new Choices("no", "nope").ToGrammarBuilder();
noChoices.Append(new SemanticResultValue(false));
Choices allChoices = new Choices(yesChoices, noChoices);
SemanticResultKey choiceKey = new SemanticResultKey("YesNoBool", allChoices);
GrammarBuilder choiceGB = new GrammarBuilder(choiceKey);
</code>
</pre>
<p>What does this do for us?  It creates a GrammarBuilder that has 2 choices.  Each of these Choices has a SemanticValue that can be obtained in the recognition handler.  Semantically there is a Yes choice (which is actually itself a choice of &#8220;yes&#8221;, &#8220;yeah&#8221; and &#8220;ok&#8221;) and a No choice (&#8220;no&#8221; and &#8220;nope&#8221;).  The Recognition engine, since we have assigned semantic values to these, will set the &#8220;YesNoBool&#8221; variable to either true or false depending on which Semantic choice the user makes.  This is great for us.  No string parsing, and thus we can easily build up grammars with many synonyms and never worry about adding more complexity in the event handler.</p>
<p>So far we have looked at inputs that are just combinations of predefined words.  This is great for many scenarios, but what if we want to allow more free form input?  Lets say that our grammar is built to allow users to get a current stock price.  You would probably want to match on any of the following phrases:</p>
<ul>
</p>
<li>Show me the stock price of foo</li>
<p></p>
<li>Let me see the stock price of foo</li>
<p></p>
<li>What is the price of foo</li>
<p>
</ul>
<p>Here foo may be any stock ticker and lets say we&#8217;re lazy so we don&#8217;t want to hard code all of them.  The solution lies in the <a href="http://msdn.microsoft.com/en-us/library/system.speech.recognition.dictationgrammar.aspx">DictationGrammar </a>class.  This class is exactly what it sounds like&#8211;a class for dealing with understand user dictation.  Now, extracting the &#8216;foo&#8217; from any of those in the event handler could be error prone, especially as you add more and more recognized ways of asking for a stock price.  This is where semantic values come into play again.  So lets see how this might work:</p>
<pre class="code">  <code class="csharp">
GrammarBuilder stockGB = new GrammarBuilder();
GrammarBuilder dictation = new GrammarBuilder();
dictation.AppendDictation("spelling");
stockGB.Append(new Choices("Show me the stock price of", "Let me see the stock price of", "What is the stock price of"));
stockGB.Append(new SemanticResultKey("DictationInput", dictation));
</code>
</pre>
<p>This code creates a choice of antecendents and then appends a SemanticResultKey whose name is DictationInput.  Note that since we assigned no semantic value, the value that is assigned to DictationInput will be the actual text of the dictation.  Finally, note that when we <a href="http://msdn.microsoft.com/en-us/library/ms576566.aspx">created the Dictation we passed the parameter &#8220;spelling&#8221;</a>.  This was to let the Recognizer know that we wanted the user to spell out the ticker name and that it should not interpret the input as words.  If we had not passed that parameter it would have tried to match the input to words.  That type of dictation might be useful if you were trying to build a voice IM client for example.</p>
<p>That&#8217;s all for now.  Good luck and let me know if you build anything cool <img src='http://www.codepresencelabs.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.codepresencelabs.com/2008/09/12/building-grammars-in-net/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>

