<?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>Mark W. Shead &#187; Technology</title>
	<atom:link href="http://blog.markwshead.com/category/technology/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.markwshead.com</link>
	<description>Mark's thoughts on being Mark Shead and other random subjects</description>
	<lastBuildDate>Mon, 02 Jan 2012 16:04:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Simple Made Easy &#8211; Rich Hickey</title>
		<link>http://blog.markwshead.com/1069/simple-made-easy-rich-hickey/</link>
		<comments>http://blog.markwshead.com/1069/simple-made-easy-rich-hickey/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 22:12:59 +0000</pubDate>
		<dc:creator>Mark Shead</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.markwshead.com/?p=1069</guid>
		<description><![CDATA[Notes from Rich Hickey&#8217;s talk on simplicity at Strangeloop 2011. The video is now available here. Word origins: Simple  = sim &#8211; plex = one braid Easy = adjacent = lie near Simple: Simple means having one of something, one braid, one fold, one role, one concept, one task, one dimension. Simple can involve many [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>Notes from Rich Hickey&#8217;s talk on simplicity at Strangeloop 2011.</p>
<p><strong>The video is now available <a href="http://www.infoq.com/presentations/Simple-Made-Easy">here</a>.</strong></p>
<p><strong>Word origins:</strong></p>
<ul>
<li>Simple  = sim &#8211; plex = one braid</li>
<li>Easy = adjacent = lie near</li>
</ul>
<div><strong>Simple:</strong></div>
<div>
<ul>
<li>Simple means having one of something, one braid, one fold, one role, one concept, one task, one dimension.</li>
<li>Simple can involve many things, but not having interleaving.</li>
<li>Simple is an objective notion.</li>
</ul>
</div>
<div><strong>Easy:</strong></div>
<ul>
<li>Near, at hand.</li>
<li>Near to our understanding&#8211;being familiar.</li>
<li>Near to our capabilities. We don&#8217;t like to talk about this because it tramples on our egos.</li>
<li>We are far to interested in things being <strong>easy. </strong>This is to our detriment.</li>
<li>Easy is relative (unlike &#8220;simple&#8221;). Music and German are hard from some and easy for others.</li>
</ul>
<div><strong>Construct vs Artifact</strong></div>
<div>
<ul>
<li>We become to infatuated with things being easy  instead of being simple.</li>
<li>Long term use is a better indication of simplicity and helps keep use from focusing on things being easy.</li>
</ul>
<p>We can only hope to make reliable those things we can understand. There is a limit to how much we can keep in our mind at the same time. Intertwined things have to be considered together and this taxes our brains. Fewer &#8220;braids&#8221; means less complexity and less complexity means we can hold it in our minds better.</p>
<p>To change software requires analysis and decisions. You must be able to reason about your program to be able to reliably change it.</p>
<blockquote><p>We say, &#8220;I can make a change because I have tests.&#8221; Who does that? Who drives their car around banging into the guard rails!?</p></blockquote>
<p>Easy things make us feel like we are fast.</p>
<blockquote><p>What type of runner can run full speed from the very start of the race? Thats right. Someone who runs very short distances. But as programmers, we are smarter than that. We just fire the starter pistol again every 100 yards.  I don&#8217;t know why runners haven&#8217;t figured that out.</p></blockquote>
<p>Ignoring complexity will slow you down if you aren&#8217;t just doing a very small project.<br />
There are many constructs that are easy to use, but are very complex.</p>
<p><strong>Benefits of Simplicity:</strong></p>
<ul>
<li>Ease of understanding</li>
<li>Ease of change</li>
<li>Easier debugging</li>
<li>Flexibility</li>
<li>More independence for change.</li>
</ul>
<p><strong>Making Things Easy:</strong></p>
<ul>
<li>Making it &#8220;at hand&#8221; by bringing it into our environment&#8211;installing it.</li>
<li>Become familiar with it by learning it.</li>
<li>There is a mental barrier. We can&#8217;t really get much smaller.</li>
</ul>
<p>We are all very limited compared to the complexity we create. The difference between a really smart programmer and an average programmer is minimal&#8211;no one can really understand all of the complexity we can create.  A juggler can juggle 3 balls. A really good juggler can juggle 9. No juggler can juggle 90 or 900.</p>
<blockquote><p>Everyone has seen parenthesis, but they haven&#8217;t seen it on THAT SIDE of the method. Thats crazy!</p></blockquote>
<p>Parenthesis are overloaded in lisp. They do several different things so they are complex. By removing this complexity the ease problem is back in the domain of what we can change.</p>
<p>Everyone is happy to grab benefits of new tools, but no one takes the time to see if there are any trade offs.</p>
<ul>
<li>Complect = braid together.</li>
<li>Compose = place together.</li>
</ul>
<p>We can write modules that are completely complected. What are your modules allowed to &#8220;think&#8221; about. Just partitioning doesn&#8217;t give you simplicity.</p>
<p>Having state is never simple because it complects value and time. It is easy, familiar, at hand, etc. The only way to get rid of state is to put it in a box that gives you a functional interface where you always get the same output with the same input.</p>
<p>Simplicity is a choice. It is your fault if you don&#8217;t have a simple system.</p>
</div>
<h4>People Found This When Looking For:</h4><ul><li>simple made easy rich hickey (40)</li><li>simple made easy (30)</li><li>rich hickey simple made easy (17)</li><li>rich hickey strangeloop (13)</li><li>rich hickey strange loop (13)</li><li>simple made easy hickey (11)</li><li>download simple made easy rich hickey (11)</li><li>strangeloop rich hickey (10)</li><li>rich hickey simplicity (8)</li><li>hickey simple made easy (6)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.markwshead.com/1069/simple-made-easy-rich-hickey/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BitCoin Talk at Strangeloop</title>
		<link>http://blog.markwshead.com/1066/bitcoin-talk-at-strangeloop/</link>
		<comments>http://blog.markwshead.com/1066/bitcoin-talk-at-strangeloop/#comments</comments>
		<pubDate>Mon, 19 Sep 2011 21:22:52 +0000</pubDate>
		<dc:creator>Mark Shead</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.markwshead.com/?p=1066</guid>
		<description><![CDATA[My notes from a talk by Eric Brigham from TruCoin talking about BitCoin. BitCoin is &#8220;digital cash&#8221; &#8212; you can lose it just like you can lose a $100 bill and there isn&#8217;t a central source. Digicash (1990 &#8211; 1998) focused on security. Paypal (1998 &#8211; ) focused on convenience. Both required centralize servers to [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>My notes from a talk by Eric Brigham from <a href="http://www.trucoin.com/">TruCoin</a> talking about <a href="http://bitcoin.org/">BitCoin</a>.</p>
<ul>
<li>BitCoin is &#8220;digital cash&#8221; &#8212; you can lose it just like you can lose a $100 bill and there isn&#8217;t a central source.</li>
<li>Digicash (1990 &#8211; 1998) focused on security.</li>
<li>Paypal (1998 &#8211; ) focused on convenience.</li>
<li>Both required centralize servers to solve double spending problem.</li>
<li>BitCoin solves the double spending problem without needing a centralized server. The transaction log is handled via P2P.</li>
<li>BitCoin was created by <a href="https://en.bitcoin.it/wiki/Satoshi_Nakamoto">Satoshi Nakamoto</a> &#8211; it is unclear to who he actually is or even if he is a single person.</li>
<li>A look at the code reveals that Satoshi is not a professional developer.</li>
<li>BitCoin is the worlds first cryptographically secure distributed digital notary service.</li>
<li>The number of BitCoins should level off to about 21,000,000 over the next 50 years.</li>
<li>BitCoins are created via computational effort so they represent &#8220;computer work&#8221;.</li>
<li>Cheating isn&#8217;t prevented, it is just made very expensive.</li>
<li>A BitCoin address is a base 58 encoded public key.</li>
<li>A transaction is simply a digitally signed message.</li>
<li>It is theoretically possible to rewrite the transaction history, but it is very computationally expensive and is getting exponentially more expensive.</li>
<li>If two separate people find the next coin at the same time, the chain that wins is the one that gets the next coin found on top of it.</li>
<li>Most of the security issues have nothing to do with BitCoin, but they can be stolen in the same way that cash can be stolen.</li>
<li>DOS attack are possible, but haven&#8217;t been much of an issue.</li>
<li>Biggest known attack is if someone possesses &gt;50% of the total network computational power you can double spend coins.</li>
<li>It is very difficult to operate anonymously with BitCoin.</li>
<li>People are working on a multi-signature transaction that would allow e-wallet type transactions similar to Paypal where a central site would keep part of your signature.</li>
</ul>
<h4>People Found This When Looking For:</h4><ul><li>bitcoin (12)</li><li>strangeloop bitcoin (3)</li><li>trucoin (3)</li><li>bitcoins (2)</li><li>rich hickey strangeloop (2)</li><li>eric brigham strange loop (2)</li><li>bitcoin convenience (2)</li><li>bitcoin talk (2)</li><li>rich hickey strange loop video (1)</li><li>hickey strangeloop video (1)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.markwshead.com/1066/bitcoin-talk-at-strangeloop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tapestry and testng.xml</title>
		<link>http://blog.markwshead.com/1007/tapestry-and-testng-xml/</link>
		<comments>http://blog.markwshead.com/1007/tapestry-and-testng-xml/#comments</comments>
		<pubDate>Sun, 07 Aug 2011 04:06:49 +0000</pubDate>
		<dc:creator>Mark Shead</dc:creator>
				<category><![CDATA[Tapestry]]></category>

		<guid isPermaLink="false">http://blog.markwshead.com/?p=1007</guid>
		<description><![CDATA[You can use a testng.xml file to help control the tests and browser used by Selenium in Tapestry.  However, you have to tell Maven to look for the testng.xml file or it will ignore it.  You do this by putting the following in your pom.xml -&#62; build -&#62; plugins: People Found This When Looking For:testng [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>You can use a testng.xml file to help control the tests and browser used by Selenium in Tapestry.  However, you have to tell Maven to look for the testng.xml file or it will ignore it.  You do this by putting the following in your pom.xml -&gt; build -&gt; plugins:</p>
<pre class="brush: xml; title: ; notranslate">
			&lt;plugin&gt;
				&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
				&lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
				&lt;version&gt;2.6&lt;/version&gt;
				&lt;configuration&gt;
					&lt;suiteXmlFiles&gt;
						&lt;suiteXmlFile&gt;src/test/conf/testng.xml&lt;/suiteXmlFile&gt;
					&lt;/suiteXmlFiles&gt;
				&lt;/configuration&gt;
			&lt;/plugin&gt;
</pre>
<h4>People Found This When Looking For:</h4><ul><li>testng xml (23)</li><li>testng xml example (5)</li><li>testng xml file (3)</li><li>tapestry testng (3)</li><li>testng xml sample (2)</li><li>testng version tapestry pom (1)</li><li>testng testng xml (1)</li><li>what is tapestry? (1)</li><li>TestNG testng = new TestNG(); xml (1)</li><li>testng tapestry (1)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.markwshead.com/1007/tapestry-and-testng-xml/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sonar Installation Problems</title>
		<link>http://blog.markwshead.com/989/sonar-installation-problems/</link>
		<comments>http://blog.markwshead.com/989/sonar-installation-problems/#comments</comments>
		<pubDate>Sat, 16 Jul 2011 21:34:10 +0000</pubDate>
		<dc:creator>Mark Shead</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.markwshead.com/?p=989</guid>
		<description><![CDATA[I ran into a bunch of problems getting Sonar installed in Tomcat 6 as a war file.  It turns out I just didn&#8217;t understand the installation process.  To install Sonar as a war, you have to download it, unzip it, build the war using a script, and then deploy the war file.  During the period [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I ran into a bunch of problems getting Sonar installed in Tomcat 6 as a war file.  It turns out I just didn&#8217;t understand the installation process.  To install Sonar as a war, you have to download it, unzip it, build the war using a script, and then deploy the war file.  During the period where it builds the war file, it links the war back to the directory you are building from.  If you move the unzipped directory, the war won&#8217;t work.</p>
<p>So unzip the directory somewhere you can keep it, make it owned by Tomcat6, set your configuration file, then create the war and deploy it.  You can make configuration changes by coming back to the directory you unzipped, making a change and then restarting Tomcat.</p>
<p>I was deleting or moving the unzipped directory before deploying the war.  The errors were odd though because it kept saying that it couldn&#8217;t bind to the address because the part was already in use.  When trying to use Derby, it kept saying that something was already running on that port.  The same thing happened with MySQL.  Leaving the unzipped directory in place fixed the problem.</p>
<h4>People Found This When Looking For:</h4><ul><li>sonar tomcat (12)</li><li>sonar installation (10)</li><li>sonar address already in use (5)</li><li>sonar installation steps (4)</li><li>problems with sonar vs (3)</li><li>install sonar on tomcat (2)</li><li>sonar war (2)</li><li>sonar war download (2)</li><li>install sonar tomcat (2)</li><li>sonar derby address already in use (2)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.markwshead.com/989/sonar-installation-problems/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Voice Mail Notifications Won&#8217;t Go Away</title>
		<link>http://blog.markwshead.com/970/voice-mail-notifications-wont-go-away/</link>
		<comments>http://blog.markwshead.com/970/voice-mail-notifications-wont-go-away/#comments</comments>
		<pubDate>Sun, 29 May 2011 23:14:35 +0000</pubDate>
		<dc:creator>Mark Shead</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.markwshead.com/?p=970</guid>
		<description><![CDATA[I have a Nexus S from Sprint and set it up with Google Voice.  Unfortunately when I was getting Google Voice set up, I tried calling my number and leaving a message from another phone.  This voice mail got put on Sprint&#8217;s voice mail system.  When I switched over to Google Voice, my Sprint voice [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I have a <a href="http://www.productivity501.com/nexus-s-4g-sprint-android-phone-review/8648/">Nexus S from Sprint</a> and set it up with Google Voice.  Unfortunately when I was <a title="Sprint &amp; Google Voice Integration Error" href="http://blog.markwshead.com/943/sprint-google-voice-integrationerror/">getting Google Voice set up</a>, I tried calling my number and leaving a message from another phone.  This voice mail got put on Sprint&#8217;s voice mail system.  When I switched over to Google Voice, my Sprint voice mail was deleted, but it continued to send me notifications of the voice mail.</p>
<p>So if you are looking at switching to Google Voice, be sure to make the switch when someone isn&#8217;t likely to leave you a voice mail.  Sprint tried all kinds of things and eventually said I needed to reset my Nexus S back to factory settings.  They said that the problem was on the phone because Sprint wasn&#8217;t sending out any type of voice mail notifications to me. I wiped it, turned it back on and immediately got the little tape recorder notification from Sprint voice mail.</p>
<p>There are things I like about Sprint, but sometimes it seems like their whole system is a piece of alien technology and works most of the time, but they have not idea what is going on or how it actually works.</p>
<p>Finally I went into www.google.com/voice and disabled the Sprint/Google Voice integration.  The Sprint Voicemail notification went away within a few minutes.</p>
<p>I had to wait 15 minutes to reactivate Google Voice again, but once that was done everything seemed to work fine.</p>
<h4>People Found This When Looking For:</h4><ul><li>nexus s voicemail notification (87)</li><li>nexus s 4g voicemail notification (64)</li><li>Voicemail notification wont go away (16)</li><li>nexus s voicemail notification wont go away (14)</li><li>nexus s clear voicemail notification (13)</li><li>nexus s 4g voicemail (8)</li><li>nexus s 4g clear voicemail (8)</li><li>nexus s voicemail notification won\t go away (8)</li><li>nexus s voicemail (8)</li><li>Sprint voicemail notification wont go away (6)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.markwshead.com/970/voice-mail-notifications-wont-go-away/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lucene MoreLikeThis Example Code</title>
		<link>http://blog.markwshead.com/966/lucene-morelikethis-example-code/</link>
		<comments>http://blog.markwshead.com/966/lucene-morelikethis-example-code/#comments</comments>
		<pubDate>Thu, 26 May 2011 23:10:09 +0000</pubDate>
		<dc:creator>Mark Shead</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.markwshead.com/?p=966</guid>
		<description><![CDATA[I was recently working on a simple application where the user will enter famous quotations.  Obviously we want to avoid duplicates so I needed a way to check for quotations that were substantially similar before a new quote was added to the database. The idea was to show the top 5 most similar quotes before letting the [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I was recently working on a simple application where the user will enter <a href="http://www.noteaquote.com/">famous quotations</a>.  Obviously we want to avoid duplicates so I needed a way to check for quotations that were substantially similar before a new quote was added to the database.</p>
<p>The idea was to show the top 5 most similar quotes before letting the user save the new quotation to the db. I used Lucene for this which allowed me to punt on the more difficult task of figuring out if two quotes were similar or not. I left that up to Lucene and only had to worry about how to get my information in and out of Lucene in a usable manner.</p>
<p>Below is the interesting method that uses Lucene to build an index of all the quotes in the system and then returns the five quotes that are most similar to the new quote text.  Obviously creating a new index each time a quote is added isn&#8217;t particularly efficient, but makes it easier to demonstrate how it works and processor efficiency isn&#8217;t much of an issue with this particular task.</p>
<pre class="brush: java; title: ; notranslate">
    public List&lt;Quote&gt; getSimilarQuotes() throws CorruptIndexException, IOException {

        String quoteText = quote.getText();
        logger.info(&quot;creating RAMDirectory&quot;);
        RAMDirectory idx = new RAMDirectory();
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_31, new StandardAnalyzer(Version.LUCENE_31));
        IndexWriter writer = new IndexWriter(idx, indexWriterConfig);

        List&lt;Quote&gt; quotes =  session.createCriteria(Quote.class).list();

        //Create a Lucene document for each quote and add them to the
        //RAMDirectory Index.  We include the db id so we can retrive the
        //similar quotes before returning them to the client.
        for (Quote quote : quotes) {
            Document doc = new Document();
            doc.add(new Field(&quot;contents&quot;, quote.getText(),Field.Store.YES, Field.Index.ANALYZED));
            doc.add(new Field(&quot;id&quot;, quote.getId().toString() ,Field.Store.YES, Field.Index.ANALYZED));
            writer.addDocument(doc);
        }

        //We are done writing documents to the index at this point
        writer.close();

        //Open the index
        IndexReader ir = IndexReader.open(idx);
        logger.info(&quot;ir has &quot; + ir.numDocs() + &quot; docs in it&quot;);
        IndexSearcher is = new IndexSearcher(idx, true);

        MoreLikeThis mlt = new MoreLikeThis(ir);

 		//lower some settings to MoreLikeThis will work with very short
        //quotations
        mlt.setMinTermFreq(1);
        mlt.setMinDocFreq(1);

		//We need a Reader to create the Query so we'll create one
        //using the string quoteText.
        Reader reader = new StringReader(quoteText);

        //Create the query that we can then use to search the index
        Query query = mlt.like( reader);

        //Search the index using the query and get the top 5 results
        TopDocs topDocs = is.search(query,5);
        logger.info(&quot;found &quot; + topDocs.totalHits + &quot; topDocs&quot;);

        //Create an array to hold the quotes we are going to
        //pass back to the client
        List&lt;Quote&gt; foundQuotes = new ArrayList&lt;Quote&gt;();
        for ( ScoreDoc scoreDoc : topDocs.scoreDocs ) {
            //This retrieves the actual Document from the index using
            //the document number. (scoreDoc.doc is an int that is the
            //doc's id
            Document doc = is.doc( scoreDoc.doc );

            //Get the id that we previously stored in the document from
            //hibernate and parse it back to a long.
            String idField =  doc.get(&quot;id&quot;);
            long id = Long.parseLong(idField);

            //retrieve the quote from Hibernate so we can pass
            //back an Array of actual Quote objects.
            Quote thisQuote = (Quote)session.get(Quote.class, id);

            //Add the quote to the array we'll pass back to the client
            foundQuotes.add(thisQuote);
        }

        return foundQuotes;
    }
</pre>
<h4>People Found This When Looking For:</h4><ul><li>lucene indexwriterconfig (168)</li><li>lucene example (150)</li><li>lucene morelikethis (109)</li><li>IndexWriterConfig example (90)</li><li>IndexWriterConfig (51)</li><li>morelikethis lucene (38)</li><li>lucene indexwriterconfig example (34)</li><li>lucene more like this (33)</li><li>lucene examples (31)</li><li>lucene morelikethis example (30)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.markwshead.com/966/lucene-morelikethis-example-code/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Nexus S 4G and Google Apps</title>
		<link>http://blog.markwshead.com/961/nexus-s-4g-and-google-apps/</link>
		<comments>http://blog.markwshead.com/961/nexus-s-4g-and-google-apps/#comments</comments>
		<pubDate>Thu, 26 May 2011 22:40:42 +0000</pubDate>
		<dc:creator>Mark Shead</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.markwshead.com/?p=961</guid>
		<description><![CDATA[I recently switched phones to the Nexus S 4G. (Take a look at my detailed Nexus S Review.) I&#8217;ve been pretty impressed with how well the Nexus S integrates with Google Apps.  I suppose this is expected because it is a Google phone, but experience tells me that just because a company makes a device [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I recently switched phones to the Nexus S 4G. (Take a look at my detailed <a href="http://www.productivity501.com/nexus-s-4g-sprint-android-phone-review/8648/">Nexus S Review</a>.) I&#8217;ve been pretty impressed with how well the Nexus S integrates with Google Apps.  I suppose this is expected because it is a Google phone, but experience tells me that just because a company makes a device doesn&#8217;t mean it will work well with their software and services.</p>
<p>Google apps has really gown into a nice business package. Here are a few things that impressed me when I was setting up the <a href="http://www.productivity501.com/nexus-s-4g-sprint-android-phone-review/8648/">Nexus S 4G</a>.</p>
<ul>
<li>You can define security policies for Android devices so they can be managed centrally.  For example, you can make the Nexus S require a password or not.</li>
<li>You can remotely ring your Nexus S 4G at full volume using the web interface&#8211;regardless of what the volume is set on.</li>
<li>You can find the device on a map.</li>
<li>You can lock the Nexus S 4G remotely.  For example, if you lose it, you can lock it so it will require a pin to log back in.</li>
<li>The Nexus S 4G can be wiped remotely.  So if you lose your phone, you can delete everything on it by logging into Google Apps</li>
<li>It appears that most of the Nexus S 4G settings are backed up to the Google App servers, so if you do need to wipe your device, you can easily reinstall and set everything back up again once you get it back again.</li>
<li>Giving the Nexus S 4G your Google App account will let you connect to most Google services without needing to log back in again.</li>
<li>The Nexus S 4G appears to support multiple Google accounts so you can use your business account and a gmail account if you like.</li>
</ul>
<h4>People Found This When Looking For:</h4><ul><li>nexus s apps (245)</li><li>nexus s 4g apps (183)</li><li>apps for nexus s 4g (120)</li><li>best apps for nexus s 4g (70)</li><li>google nexus s apps (48)</li><li>apps for nexus s (46)</li><li>how to backup nexus s 4g (38)</li><li>cool apps for nexus s 4g (34)</li><li>nexus 4G apps (32)</li><li>nexus s app (31)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.markwshead.com/961/nexus-s-4g-and-google-apps/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Sprint &amp; Google Voice Integration Error</title>
		<link>http://blog.markwshead.com/943/sprint-google-voice-integrationerror/</link>
		<comments>http://blog.markwshead.com/943/sprint-google-voice-integrationerror/#comments</comments>
		<pubDate>Thu, 19 May 2011 20:22:12 +0000</pubDate>
		<dc:creator>Mark Shead</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.markwshead.com/?p=943</guid>
		<description><![CDATA[I recently bought a Nexus S 4G and I&#8217;m trying to use the Sprint/Google Voice integration, but the following error keeps popping up. We have a problem Sorry, there was a problem determining your eligibility for a Sprint integrated account. Please try again at a later time. It looks like this might mean several different [...]]]></description>
			<content:encoded><![CDATA[<p><a class="post_image_link" href="http://blog.markwshead.com/943/sprint-google-voice-integrationerror/" title="Permanent link to Sprint &#038; Google Voice Integration Error"><img class="post_image aligncenter" src="http://blog.markwshead.com/wp-content/uploads/2011/05/Screen-shot-2011-05-21-at-7.49.19-AM.png" width="658" height="308" alt="Post image for Sprint &#038; Google Voice Integration Error" /></a>
</p><p>I recently bought a <a href="http://blog.markwshead.com/961/nexus-s-4g-and-google-apps/">Nexus S 4G</a> and I&#8217;m trying to use the Sprint/Google Voice integration, but the following error keeps popping up.</p>
<blockquote><p>We have a problem<br />
Sorry, there was a problem determining your eligibility for a Sprint integrated account. Please try again at a later time.</p></blockquote>
<p>It looks like this might mean several different things. Google lists these possible reasons:</p>
<div>
<ol>
<li>Users who are behind on your phone bill.  Please check with Sprint to remedy this.</li>
<li>Users who have a corporate number oa landline number.  Currently, we don&#8217;t offer the ability to integrate corporate or landline phone numbers.</li>
<li>You are not using a Sprint-branded mobile phone.  Nextel, PowerSource, corporate, and pre-paid phones are not compatible with Google Voice.</li>
<li>We were in a &#8216;maintenance window&#8217; during the time you tired to sign up.  Please try again in 24 hours. If you try again and are still unable to integrate your number, it is likely because of the previously mentioned reasons.</li>
<li>If you have call blocking enabled on your account, you cannot use Google Voice on Sprint.  In order to be eligible for Google Voice on Sprint, please contact Sprint to remove this feature and then re-try. You can use Google Voice to block unknown callers and send straight to voicemail.</li>
<li>If you have call tones enabled on your account, you cannot use Google Voice on Sprint.  We recommend contacting Sprint to remove this feature and then re-trying the integration.</li>
</ol>
<p>None of those appeared to be my issue. My cell phone is listed on two Google Voice accounts.  So there are two GV numbers that will ring my cell phone.  Evidentially this will cause a problem on the Google end of things. I removed the cell phone number from the other Google voice account and it is letting me go through the process correctly so my Google Voice account now shows my cell phone number as the Google Voice number.</p>
<p>However, I still can&#8217;t login to Google Voice on my phone.  It gives me the same error. However, Google Voice seems to be working correctly and calls to my number are handled by Google Voice voicemail, transcribed and sent as a text message.</p>
<p>I&#8217;m curious if there is a problem with the fact that my Sprint number was set to forward to my Google voice number when it wasn&#8217;t answered.  The other issue that might be hanging things up is the fact we have a discount on the plan because of our Costco membership.</p>
<p>I got someone on Sprint&#8217;s chat support and they said to undo the integration and then redo it.  They also said that they reset the Google Voice settings on my account. I tried redoing it.  Google voice calls me and has me enter the verification number, but as soon as I enter it, the message on the web page changes to:</p>
<blockquote><p>Unable to update your account. Your last change needs to be fully  implemented before we can make additional changes to your account.  Please try again in 15 minutes.</p></blockquote>
<p>The tech I&#8217;m chatting with says to just wait it out. He is sure the problem will be solved when I wait. I&#8217;m asking a few questions to keep him on the chat. Now it is letting me go through the process again. Much to &#8220;Jack&#8217;s&#8221; surprise it doesn&#8217;t work.  He describes the issue as a &#8220;technical glitch&#8221; and says they have specialists who can take care of this if I call Sprint.</p>
<p>I&#8217;m not having much luck getting him to explain exactly what the &#8220;technical glitch&#8221; is.  However it appears that he saw something on my account that was wrong, reset it, and then when I got the error message it came back again.</p>
<p>Someone else is helping me and we&#8217;ve gotten the Google Voice setup again on the Google side of things, but when trying to use Google Voice on the Nexus S, it still just says:</p>
<blockquote><p>We have a problem<br />
Sorry, there was a problem determining your eligibility for a Sprint integrated account. Please try again at a later time.</p></blockquote>
<p>The current technician said that the problem is that my account is listed as a Corporate or Corporation Individual type.  The only reason I can figure out why it might be listed like this is because I have a discount by being a CostCo member.  Tech support says this can be changed to an Individual Liable account without messing up anything else on the account, but for some reason tech support can&#8217;t do this.</p>
<p>Ok now I&#8217;m talking with another tech support person. I&#8217;m not sure why I was transfered to him since the last guy just told me tech support couldn&#8217;t help me.  This new tech wants to check everything again.  Sprint could save everyone a lot of time if they would actually add notes to the account about what they did so the next person could read them and not try the same thing over and over again.</p>
<p>This guy is having me turn the phone off and back on again to see if that fixes it. :(</p>
<p>I&#8217;m on hold and the recorded message keeps saying:</p>
<blockquote><p>Waiting is difficult and we know your time is important.</p></blockquote>
<p>No they don&#8217;t know that my time is important. If it was half as important to them as it is to me, I wouldn&#8217;t be stuck explaining the same thing over and over again to people and spending long periods on hold while they try to figure out who to pass me off to next.</p>
<p>Now I&#8217;m talking to Joe. He says the CostCo discount is the problem. Evidentially it has me listed as a CostCo employee. I asked him if he could switch my account over to whatever it needs to be to work properly without changing the current rate I&#8217;m paying.  He is checking with a supervisor and I&#8217;m on hold again with the woman&#8217;s voice who is very concerned about how important my time is.</p>
<p>Joe did say that the limitation is something that Google is doing&#8211;not something that Sprint is enforcing.  I&#8217;m not sure if I believe him or not, but it might be part of Google wanting to keep Google Voice from being used for business. I think their terms of service basically say not to use it for a business although a lot of people do.</p>
<p>Joe said my account is setup as a Corporate Liable account. I asked if that means CostCo is liable for my bill, but he said they weren&#8217;t. He can&#8217;t give me the discount unless I&#8217;m listed as a Corporate Liable&#8211;which will keep the Google Voice account from working.</p>
<p>Talking to Joe involves me asking a question and him pausing for 30 to 45 seconds before giving me a response that usually has nothing to do with what I asked. Maybe he is looking for a scripted response to, &#8220;how does that make any sense?&#8221;</p>
<p>I asked what the logic was behind classifying accounts in such a way that they won&#8217;t work with the Google Voice integration&#8211;something that they have heavily promoted and is one of the things I was very interested in having when I bought this new phone.  His response was, &#8220;well since you said you will cancel your account over this I can get you to the retention department.&#8221; I&#8217;m not sure he is even listening to anything I say. Maybe this is some type of very human sounding auto voice prompt system.</p>
<p>He is blaming it on Google and saying I need to call them. (That sounds more like the humans I&#8217;m used to talking to.  I pointed out that Sprint has been just bouncing me around for the past five hours and I really don&#8217;t want to have to deal with them just bouncing me to another company.  If he thinks I need to talk to Google then he should conference them in so the three of us can talk. (Not that I think this is going to happen.) He said he would see if he can make that happen.</p>
<p>Waiting&#8230;..</p>
<p>Perhaps the goal is to just keep my on hold until their phone system finally drops my call.</p>
<p>Still waiting about 20 minutes later.  I seriously think this is what he is doing because he isn&#8217;t allowed to just hang up on me.</p>
<p>Joe says he can&#8217;t get ahold of  Google, but now he is saying that this account should work.  He is transfering me to someone in technical support who has done this before.</p>
<p>Ok this guy can&#8217;t hear me very well&#8230; Argh.  The call dropped.</p>
<p>The new guy, John, called me back on my cell phone.  Now he is calling me on my land line.  Arghhh.  I can hear him, but he can&#8217;t hear me.</p>
<p>Ok talking to him now on my wife&#8217;s cell phone.</p>
<p>He is reseting something while I have the battery out of the phone.  Now he is asking me if I think the world is going to win tomorrow and telling me about a co-worker who quit their job because they thought the world was going to end.</p>
<p>Hm.  Maybe this guy just has false confidence.  I told him what the previous guy told me&#8211;that it wouldn&#8217;t work with my phone because to have the discount it must be a corporate type of account. He is going to check with a supervisor about that to make sure it will work. :(</p>
<p>Just found an Engadget post that seems to <a href="http://www.engadget.com/2011/05/12/sprint-google-voice-integration-now-available-for-discounted-a/">indicate</a> the problem should be fixed now.</p>
<p>John suggested I change my password. Now I&#8217;m able to login to Google Voice on my phone!</p>
<p>Ok not so great.  When I call my cell phone number it gets answered by Sprint Voicemail not Google Voice.  I&#8217;m going to try to undo the Sprint Integration and then redo it.</p>
<p>I waited about an hour and tried it again and now everything seems to be working ok. I&#8217;m not exactly sure what fixed things, but I can log into Google Voice on my phone now and calls are answered by Google Voice.</p>
<p>Google Voice on the <a href="http://www.productivity501.com/nexus-s-4g-sprint-android-phone-review/8648/">Nexus S</a>, is very nice.  The only problem I&#8217;m seeing is that the voice mail notification from the old Sprint voicemail is still coming up. I can&#8217;t delete the voicemail because the account is gone.  Sprint says it should go away in 30 days if I ignore it.</p>
<p>If you are thinking about making the switch, I&#8217;d wait awhile&#8230;</p>
</div>
<h4>People Found This When Looking For:</h4><ul><li>we could not set your google voice number (99)</li><li>Unable to update your account Your last change needs to be fully implemented before we can make additional changes to your account Please try again in 15 minutes (46)</li><li>google voice we could not set your google voice number (8)</li><li>sprint we could not set your google voice number (7)</li><li>undo sprint google voice integration (7)</li><li>google voice error (6)</li><li>we have a problem We could not set your google voice number (6)</li><li>sorry there was a problem determining your eligibility for a sprint integrated account (5)</li><li>sprint google voice we could not set your google voice number (4)</li><li>could not set your google voice number (4)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.markwshead.com/943/sprint-google-voice-integrationerror/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tapestry 5 &#8211; 10 Minute Demo of Apache Tapestry</title>
		<link>http://blog.markwshead.com/900/tapestry-5-10-minute-demo/</link>
		<comments>http://blog.markwshead.com/900/tapestry-5-10-minute-demo/#comments</comments>
		<pubDate>Tue, 15 Feb 2011 04:07:18 +0000</pubDate>
		<dc:creator>Mark Shead</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tapestry]]></category>

		<guid isPermaLink="false">http://blog.markwshead.com/?p=900</guid>
		<description><![CDATA[This is a demonstration of about 10 minutes of programming in Tapestry 5 creating a sample application. The app is pretty basic and just lets you add URLs to a list and then vote on them-similar to the idea behind Digg or Reddit. I didn&#8217;t really explain things in great detail so it is more of a [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>This is a demonstration of about 10 minutes of programming in Tapestry 5 creating a sample application. The app is pretty basic and just lets you add URLs to a list and then vote on them-similar to the idea behind Digg or Reddit. I didn&#8217;t really explain things in great detail so it is more of a demonstration of some of the things you can do than it is a step by step tutorial.<br />
<span id="more-900"></span><br />
<iframe width="853" height="510" src="http://www.youtube.com/embed/-vzCfzJ7ETA" frameborder="0" allowfullscreen></iframe><br />
General steps in making the application:</p>
<ul>
<li>Create a Quickstart application from the Maven archetype.</li>
<li>Add the dependencies and configs for Hibernate.</li>
<li>Create an Item entity to store our url, title, and number of votes.</li>
<li>Use a BeanEditForm and onSuccess method to create Items.</li>
<li>Use a Loop to show the items in the database</li>
<li>Use an ActionLink and onActionFromVote method to count the votes</li>
<li>Add onValidate method to do validate the URLs.</li>
<li>Stick the loop in a Zone and update it with the ActionLink</li>
</ul>
<p>The app uses the Quickstart archetype from 5.3 so it uses the new green theme.</p>
<h3>Errata</h3>
<ul>
<li>I used @Component on the BeanEditForm, but I should have used @InjectComponent.  As you can see in the comments, Howard isn&#8217;t really sure why this worked. So use @InjectComponent instead.</li>
<li>The zone should have gone around the ul elements instead of within it.  The zone renders as a div and we shouldn&#8217;t have a div inside of the open/close ul.</li>
</ul>
<h4>People Found This When Looking For:</h4><ul><li>tapestry 5 (75)</li><li>apache tapestry (26)</li><li>tapestry demo (19)</li><li>tapestry tutorial (16)</li><li>tapestry 5 demo (14)</li><li>tapestry 10 minute (10)</li><li>apache tapestry tutorial (9)</li><li>tapestry 5 example (8)</li><li>tapestry hibernate (8)</li><li>tapestry5 demo (7)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.markwshead.com/900/tapestry-5-10-minute-demo/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>State Machines &#8211; Basics of Computer Science</title>
		<link>http://blog.markwshead.com/869/state-machines-computer-science/</link>
		<comments>http://blog.markwshead.com/869/state-machines-computer-science/#comments</comments>
		<pubDate>Sat, 12 Feb 2011 18:02:53 +0000</pubDate>
		<dc:creator>Mark Shead</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.markwshead.com/?p=869</guid>
		<description><![CDATA[Computer science is what enables programming, but it is possible to do a lot of programming without understanding the computer science concepts underlying the process of computation. This isn&#8217;t always a bad thing.  When we program we work at a much higher level of abstraction.  When we drive a car, we only concern ourselves with [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>Computer science is what enables programming, but it is possible to do a lot of programming without understanding the computer science concepts underlying the process of computation. This isn&#8217;t always a bad thing.  When we program we work at a much higher level of abstraction.  When we drive a car, we only concern ourselves with two or three pedals, a gearshift and a steering wheel.  You can safely operate a car without having any clear idea of how it works. However, if you want to operate a car at the very limits of its capabilities, you need to know a lot more about automobiles than just the three pedals, gearshift and steering wheel.</p>
<p>The same is true of programming.  Much mundane everyday work that can be accomplished with little or no understanding of computer science. You don&#8217;t need to understand computational theory to build a &#8220;contact us&#8221; form in PHP.  However, if you plan to write code that requires serious computation, you are going to need to understand a bit more about how computation works under the hood.</p>
<p>The purpose of this article is to provide some fundamental background for computation. If there is interest I may follow up with some more advanced topics, but right now I want to look at the logic behind one of the simplest abstract computational devices&#8211;a finite state machine.</p>
<h3>Finite State Machine</h3>
<p>A finite state machine is a mathematical abstraction used to design algorithms. In simple terms, a state machine will read a series of inputs.  When it reads an input it will switch to a different state.  Each state specifies which state to switch for a given input.  This sounds complicated but it is really quite simple.</p>
<p>Imagine a device that reads a long piece of paper.  For every inch of paper there is a single letter printed on it&#8211;either the letter a or the letter b.</p>
<p><img class="aligncenter size-full wp-image-870" title="finite-state-machine-tape" src="http://blog.markwshead.com/wp-content/uploads/2011/02/finite-state-machine-tape.png" alt="" width="463" height="94" />As the state machine reads each letter it changes state.  Here is a very simple state machine.</p>
<p><img class="aligncenter size-full wp-image-871" title="simple-state-machine" src="http://blog.markwshead.com/wp-content/uploads/2011/02/simple-state-machine.png" alt="" width="304" height="183" />The circles are &#8220;states&#8221; that the machine can be in.  The arrows are the transitions.  So if you are in state <em>s</em> and read an <em>a</em> you&#8217;ll transition to state <em>q</em>.  If you read a <em>b</em>, you&#8217;ll stay in state <em>s</em>.</p>
<p>So if we start on s and read the paper tape above from left to right, we will read the <em>a</em> and move to state <em>q</em>.  Then we&#8217;ll read a <em>b</em> and move back. Another <em>b</em> will keep us on s followed by an <em>a</em> which moves us back to the <em>q</em> state. Simple enough, but whats the point?</p>
<p>Well it turns out that you can run a tape through the state machine and once it is done tell something about the sequence of letters by examining the state you end up on.  In our simple state machine above, if we end on <em>s</em>, the tape ends with the letter <em>b</em>, if we end on <em>q</em>, the tape ends with the letter <em>a</em>.</p>
<p>This may sound pointless, but there are an awful lot of problems that can be solved with this type of approach. A very simple example would be to determine if a page of HTML contains these tags in this order:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;html&gt;
	&lt;head&gt;
	&lt;/head&gt;
	&lt;body&gt;
	&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>The state machine can move to state that shows it has read the html tag, loop until it gets to the head tag, loop until it gets to the head close tag, etc. If it successfully makes it to the final state, then you have those particular tags in the right order.</p>
<p>Finite state machines can also be used to represent the mechanics of a parking meter, pop machine, automated gas pump and all kinds of other things.</p>
<h3><strong>Deterministic Finite State Machine</strong></h3>
<p>The state machines we&#8217;ve looked at so far are all deterministic state machines.  From any state there is only one transition for any allowed input.  In other words there aren&#8217;t two paths leading out of a state when you read the letter <em>a</em>. At first this sounds silly to even make this distinction.</p>
<p>What good is a set of decisions if the same input can result in moving to more than one state?  You can&#8217;t tell a computer, if x==true then execute doSomethingBig or execute doSomethingSmall, can you?</p>
<p>Well you kind of can with a state machine. The output of a state machine is its final state.  It goes through all its processing and then the final state is read and <strong>then</strong> an action is taken. A state machine doesn&#8217;t <strong>do</strong> anything as it moves from state to state.  It processes and then when it gets to the end, the state is read and something external triggers the desired action (dispenses a soda can, etc.).  This is an important concept when it comes to non-deterministic finite state machines.</p>
<h3>Non-deterministic Finite State Machine</h3>
<p>Non-deterministic finite state machines are finite state machines where a given input from a particular state can lead to more than one different state.  For example, lets say we want to build a finite state machine that can recognize strings of letters that start with a and are then followed by zero or more occurrences of the letter b or zero or more occurrences of the letter c terminated by the next letter of the alphabet. Valid strings would be:</p>
<ul>
<li>abbbbbbbbbc</li>
<li>abbbc</li>
<li>acccd</li>
<li>acccccd</li>
<li>ac (zero occurrences of b)</li>
<li>ad (zero occurrences of c)</li>
</ul>
<p>So it will recognize the letter <em>a</em> followed by zero or more of the same letter of <em>b</em> or <em>c</em> followed by the next letter of the alphabet. A very simple way to represent this is with a state machine that looks like the one below, where a final state of <em>t</em> means that the string was accepted and matches the pattern.</p>
<p><img class="aligncenter size-full wp-image-876" title="non-deterministic-finite-state-machine" src="http://blog.markwshead.com/wp-content/uploads/2011/02/non-deterministic-finite-state-machine.png" alt="" width="417" height="360" />Do you see the problem?  From starting point s, we don&#8217;t know which path to take.  If we read the letter <em>a</em>, we don&#8217;t know whether to go to the state <em>q</em> or <em>r. </em>There are a few ways to solve this problem.  One is by back tracking.  You simply take all the possible paths and ignore or back out of the ones where you get stuck.</p>
<p>This is basically how most of the chess playing computers work.  They look at all the possibilities and all the possibilities of those possibilities and choose the path that gives them the greatest number of advantages over their opponent.</p>
<p>The other option is to convert the non-deterministic machine into a deterministic machine. One of the interesting attributes of a non-deterministic machine is that there exists an algorithm to turn any non-deterministic machine into a deterministic one.  However, it is often much more complicated.  Fortunately for us, the example above is only slightly more complicated. In fact this one is simple enough we can transform it into a deterministic machine in our head without the aid of a formal algorithm.</p>
<p>The machine below is a deterministic version of the non-deterministic machine above.  In the machine below, a final state of <em>t</em> or <em>v </em>is reached by any string that is accepted by the machine.</p>
<p><img class="aligncenter size-full wp-image-892" title="deterministic-conversion" src="http://blog.markwshead.com/wp-content/uploads/2011/02/deterministic-conversion2.png" alt="" width="337" height="405" /></p>
<p>The non-deterministic model has four states and six transitions.  The deterministic model has 6 states, 10 transitions and two possible final states. That isn&#8217;t that much more, but the complexity usually grows exponentially and a moderately sized non-deterministic machine can produce an absolutely huge deterministic machine.</p>
<h3>Regular Expression</h3>
<p>If you have done any type of programming, you&#8217;ve probably encountered regular expressions.  Regular expressions and finite state machines are functionally equivalent.  Anything you can accept or match with a regular expression can be accepted or matched with a state machine. For example the pattern above could be matched with:</p>
<p>a(b*c|c*d)</p>
<p>Regular expressions and finite state machines also have the same limitations.  In particular they both can only match or accept patterns that can be handled with finite memory.  So what type of patterns can&#8217;t they match?  Lets say you want to only match strings of a and b, where there are a number of a&#8217;s followed by an equal number of b&#8217;s. Or n a&#8217;s followed by n b&#8217;s where n is some number. Examples would be:</p>
<ul>
<li>ab</li>
<li>aabb</li>
<li>aaaaaabbbbbb</li>
<li>aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbb</li>
</ul>
<p>At first this looks like an easy job for a finite state machine. The problem is that you&#8217;ll quickly run out of states or you&#8217;ll have to assume an infinite number of states&#8211;at which point it is no longer a finite state machine. Lets say you create a finite state machine that can accept up to 20 a&#8217;s followed by 20 b&#8217;s.  That works fine until you get a string of 21 a&#8217;s followed by 21 b&#8217;s at which point you either need to rewrite your machine to handle a longer string. For any string you can recognize, there is one just a little bit longer that your machine can&#8217;t recognize because it runs out of memory.</p>
<p>This is known as the Pumping Lemma which basically says, if your pattern has a section that can be repeated like the one above then the pattern is not regular.  In other words you can&#8217;t use a regular expression or finite state machine to recognize all the strings that <em>do</em> match the pattern.</p>
<p>If you look carefully, you&#8217;ll notice that this type of pattern where every a has a matching b, looks very similar to HTML where within any pair of tags you may have any number of other matching pairs of tags. So while you may be able to use a regular expression or finite state machine to recognize if a page of HTML has the html, head and body elements in the correct order, you can&#8217;t use a regular expression to tell if an entire HTML page is valid or not because HTML is not a regular pattern.</p>
<h3>Turing Machines</h3>
<p>So how do you recognize non-regular patterns?  There is a theoretical device that is similar to a state machine called a Turing Machine.  It is similar to a finite state machine that it has a paper strip that it reads, but a Turing Machine can erase and write on the paper tape. Explaining a Turing Machine will take more space that we have here, but there are a few important points relevant to our discussion of finite state machines and regular expressions.</p>
<p>Turing Machines are computationally complete and anything that can be computed can be computed on a Turing Machine. Since a Turing Machine can write as well as read from the paper tape, it is not limited to a finite number of states. The paper tape can be assumed to be infinite in length.  Obviously actual computers don&#8217;t have an infinite amount of memory, but they contain enough memory that you don&#8217;t hit the limit for the type of problems they process.</p>
<p>Turing Machines give us an imaginary mechanical device that lets us visualize and understand how the computational process works. It is particularly useful in understanding the limits of computation. If there is interest I&#8217;ll do another article on Turing Machines in the future.</p>
<h3>Why does this matter?</h3>
<p>So whats the point?  How is this going to help you create that next PHP form?  Regardless of their limitations state machines are a very central concept to computing.  In particular the recognition that for any non-deterministic state machine you can design, there exists a deterministic state machine that does the same thing.  This is a very key point because it means you can design your algorithm in which ever way is the easiest to think about.  Once you have a proper algorithm, you can convert it into whatever form is most efficient.</p>
<p>The understanding that finite state machines and regular expressions are functionally equivalent opens up some incredibly interesting uses for regular expression engines&#8211;particularly when it comes to creating business rules that can be changed without recompiling a system.</p>
<p>A foundation in computer science allows you to take a problem X that you don&#8217;t know how to solve and reason, &#8220;I don&#8217;t know how to solve X, but I do know how to solve Y and I know how to convert a solution for Y into a solution for X.  Therefore I now known how to solve X.&#8221;</p>
<h4>People Found This When Looking For:</h4><ul><li>state machine (2777)</li><li>finite state machine (333)</li><li>state machines (202)</li><li>statemachines (131)</li><li>basics of computer science (115)</li><li>finite state machines (102)</li><li>fundamentals of computer science (100)</li><li>fundamentals of computer (66)</li><li>computer science basics (56)</li><li>what is a state machine (45)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.markwshead.com/869/state-machines-computer-science/feed/</wfw:commentRss>
		<slash:comments>62</slash:comments>
		</item>
	</channel>
</rss>

