<?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>Coding Loudly &#187; Coding</title>
	<atom:link href="http://www.charlesmerriam.com/blog/category/coding/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.charlesmerriam.com/blog</link>
	<description>Charles Merriam&#039;s loud tales of coding and technology</description>
	<lastBuildDate>Sun, 05 Sep 2010 09:35:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>JavaScript and JQuery:  Add Two Numbers&#8230; and fail.</title>
		<link>http://www.charlesmerriam.com/blog/2010/09/javascript-and-jquery-add-two-numbers-and-fail/</link>
		<comments>http://www.charlesmerriam.com/blog/2010/09/javascript-and-jquery-add-two-numbers-and-fail/#comments</comments>
		<pubDate>Sun, 05 Sep 2010 07:22:36 +0000</pubDate>
		<dc:creator>charles</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JQuery]]></category>

		<guid isPermaLink="false">http://www.charlesmerriam.com/blog/?p=210</guid>
		<description><![CDATA[In which I program with JavaScript and JQuery 1.1.4, write a sample HTML and JavaScript page to add two numbers together. And fail. The goal: This was a goal in writing a program in JavaScript to add two numbers. I picked jQuery as the &#8220;less evil than working directly in the DOM&#8221; solution. The entire [...]]]></description>
			<content:encoded><![CDATA[<p><em>In which I program with JavaScript and JQuery 1.1.4, write a sample HTML and JavaScript page to add two numbers together.  And fail.</em> </p>
<h1>The goal:</h1>
<p>This was a goal in writing a program in JavaScript to add two numbers.  I picked jQuery as the &#8220;less evil than working directly in the DOM&#8221; solution.   The entire application runs in one web page.  Writing this program was significantly harder than a &#8220;hello world&#8221; program, but still manageable.   At least, easy to get sort of working.</p>
<h1>Step 1:  Find the tools.</h1>
<p><a title="jQuery" href="http://jquery.com/" target="_blank">JQuery</a> is the emerging library of choice for working in JavaScript.  It smooths over most of the odd differences between browsers and brings a little sanity to the world.  There are a million extensions for better UI elements, form validation, and such.  I stuck to the basic jQuery for its stability and popularity.</p>
<p>As a library, jQuery is just a big JavaScript file which defines a couple entry points into a library of functions.  It gets little enhancements between versions; while I used version 1.4.2, your experience and knowledge will work for future versions.  You can read the jQuery source code, and Paul Irish has <a title="learned from jquery source" href="http://paulirish.com/2010/10-things-i-learned-from-the-jquery-source/" target="_blank">a great screencast of what they learned by reading it</a>.  As long as you are watching video, you should watch <a title="JavaScript, the good parts" href="http://www.youtube.com/watch?v=hQVTIJBZook" target="_blank">JavaScript, the Good Parts</a>.</p>
<p>Next, I looked at tools.  I tried to use Eclipse, and <a title="Stack Overflow question on HTML editors for Eclipse" href="http://stackoverflow.com/questions/54868/what-is-the-best-html-editor-for-eclipse" target="_blank">installed the web editor</a>.  I looked at <a title="Aptana.." href="http://www.aptana.com/">Aptana</a>, which is a customized version of Eclipse, though it didn&#8217;t really help either.  The <a title="W3Schools TryIt in jQuery Tutorial" href="http://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_hide" target="_blank">w3schools TryIt box</a> gave instant feedback for little tests.  I also used <a title="Firebug site" href="http://getfirebug.com/" target="_blank">FireBug</a> with <a title="FireQuery" href="http://firequery.binaryage.com/" target="_blank">FireQuery</a>, which worked exceedingly well.  FireBug is an extension to FireFox that debugs web pages and JavaScript; FireQuery adds clean debugging for jQuery calls.  My final toolset ended up as Vim, FireBug and FireQuery.</p>
<p>JQuery documentation works well.  Most quick Google hits for docuementation ended up at the jQuery site.  Also, the <a href="http://www.w3schools.com/jquery/default.asp">w3Schools jQuery tutorial</a> provides good information.  Also helping was a random chunk of code from a friend&#8217;s large JavaScript project.  I use <a href="http://my.safaribooksonline.com/">Safari Books Online</a> for books, and skimmed the JavaScript the Good Parts book.    I also evaluated some the of the books on jQuery.  I looked at quick reference sheets.   My advice is to skip all the books, stick to Google and w3schools.</p>
<h1>Step 2:  The Application</h1>
<p>My application had a simple defined goal:</p>
<p style="padding-left: 30px;">Have two input boxes.  When a number is entered into an input box, the sum of the two input boxes is updated whenever the boxes are changed.</p>
<p>I downloaded the latest version of jQuery.  Grab the &#8216;Development Version&#8217;, meaning the uncompressed version that you need to Save As &#8220;jquery.js&#8221;.   I found it faster for development to stick my JavaScript into my HTML file.  Here is my basic &#8220;hello world&#8221; to see the parts work:</p>
<pre class="brush: jscript; html-script: true;">
&lt;html&gt;
&lt;head&gt;
  &lt;script type=&quot;text/javascript&quot; src=&quot;jquery.js&quot;&gt;&lt;/script&gt;
  &lt;script type=&quot;text/javascript&quot;&gt;
    /* Ready function called once after loading */
    $(document).ready(function(){
       $(&quot;#bang&quot;).html(&quot;&lt;b&gt; Go jQuery Go! &lt;/b&gt;&quot;);
    });

  &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div id=&quot;bang&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>All the JavaScript in all my examples was  inside that <em>ready()</em> call.  Keeping the indentation straight in the nested mess is a pain, and I would occasionally just ignore it for a while.   Also, I kept getting the wrong prefix (<em>#id</em>, <em>.class</em>, or <em>selector</em>) as well has trying to use the wrong HTML tag attribute (<em>id, class, name,</em> etc.).  The script would happily go forward, but without any valid values or updates.    For example, were I to type:</p>
<pre id="line1">$(".bang").html("<strong>Stop, Javascript, stop!</strong>");
</pre>
<p>the system would quietly go its way ignoring this line.  This was the most common error I made in coding.</p>
<p>I found myself going back to quick and dirty debugging, checking each line for some silly error.  I would throw up debug messages in alert boxes, which pause execution:</p>
<pre class="brush: jscript; first-line: 4; html-script: true;">
&lt;script type=&quot;text/javascript&quot;&gt;
  /* Ready function called once after loading */
  alert(&quot;In Script&quot;);
  $(document).ready(function(){
    alert(&quot;In ready&quot;)
    $(&quot;#bang&quot;).html(&quot;&lt;b&gt; Go jQuery Go! &lt;/b&gt;&quot;);
    alert(&quot;Just set it. Html is now&quot; + $(&quot;#bang&quot;).html());
  });
&lt;/script&gt;
</pre>
<p>This gets choppy quickly as the alert boxes pile up.  I used this construct and added a &#8216;<em>&lt;div id=&#8221;messages&#8221;&gt;&lt;/div&gt;</em>&#8216; to have a long line of running messages:</p>
<pre class="brush: jscript; html-script: true;">
var messages = &quot;&quot;;
function update_message(a_message) {
  $(&quot;#messages&quot;).html(&quot;&lt;b&gt;&quot; + a_message + &quot;&lt;/b&gt;:&quot; + messages);
  messages = a_message + ':' + messages;
} ;
update_message(&quot;Running&quot;);
...
update_message(&quot;step 2.  X = &quot; + x + &quot;and y = &quot; + y);
</pre>
<p>Sometimes I would use the breakpoint in FireBug to stop the code in the correct scope and start typing expressions in the console.  Sometimes FireBug would find syntax errors if I noticed the &#8216;ERROR&#8217; indicator on the bottom of the screen.  Remember the JavaScript, jQuery, HTML, and CSS are all utterly silent on most typos, so &#8220;don&#8217;t trust and verify&#8221; is your mantra.  You can disable the test code by commenting out the function body.</p>
<p>I ended up with this basic code:</p>
<pre class="brush: jscript; html-script: true;">
&lt;html&gt;
  &lt;head&gt;
    &lt;script type=&quot;text/javascript&quot; src=&quot;jquery.js&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;
      /* Ready function called once after loading */
      $(document).ready(function(){
        var new_sum = function() {
        //$('#sum_value').html('in new_sum' + Math.random() + ' ' + $('#sum_value') + &quot;.&quot; + $('[name=first_number]').val() + &quot;+&quot; + $('[name=second_number]').val());
        update_message(&quot;in new_sum&quot;);
        var first = $('[name=first_number]').val();
        var second = $('[name=second_number]').val();
        var total = parseFloat(first) + parseFloat(second);
        $('#sum_value').html(total);
        update_message(&quot;first [&quot; + first + &quot;] second [&quot; + second + &quot;] total [&quot; + total + &quot;]&quot;);
      }    

      var messages = &quot;&quot;;
      function update_message(a_message) {
        $(&quot;#messages&quot;).html(&quot;&lt;b&gt;&quot; + a_message + &quot;&lt;/b&gt;:&quot; + messages);
        messages = a_message + ':' + messages;
      } ;
      update_message(&quot;Running&quot;);

      $('.numbers').change(function() { update_message(&quot;change&quot;); new_sum();} );
      $('#sum_value').html('no sum yet.');
    });
    &lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;messages&quot;&gt;&lt;/div&gt;
    &lt;div id=&quot;title1&quot;&gt;First Number&lt;/div&gt;
    &lt;input type=&quot;text&quot; name=&quot;first_number&quot; value=&quot;1&quot; /&gt;
    &lt;div id=&quot;title2&quot;&gt;Second Number&lt;/div&gt;
    &lt;input type=&quot;text&quot; name=&quot;second_number&quot; value=&quot;2&quot; /&gt;
    &lt;div id=&quot;sum_title&quot;&gt;Sum&lt;/div&gt;
    &lt;div id=&quot;sum_value&quot;&gt;&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Yes, JavaScript and HTML both get verbose quickly.  I think the verbosity encourages the lack of comments, white space, and the long chained function calls commonly found in this type of code.  Of course, one could always claim &#8216;performance&#8217;.</p>
<h1>Step 3:   The Event Bugs</h1>
<p>If you play with the code, you will find it doesn&#8217;t quite work.  You need to switch away from the text field before the <em>change</em> event gets called.  The situation gets better by catching not just the <em>change</em> event but also <em>keyup</em> and <em>click</em>.  It still gets broken on cut and paste.  I looked at <a title="A relevant Stack Overflow question" href="http://stackoverflow.com/questions/686995/jquery-catch-paste-input">Stack Overflow questions</a>, read available documentation, experimented, and figured out that the program will never quite work.</p>
<p>jQuery is built on JavaScript and the HTML standards.  These standards are fundamentally flawed, though some flaws get fixed like upkeep on an old house.  Most GUI toolkits would have a pair of events for &#8220;About to change value&#8221; and &#8220;Value was just changed.&#8221;.  HTML and JavaScript do not.  I can catch the cut and paste events before they make a change, wait some time, and hope to catch it after the event was processed.  I can make a busy loop which just updates the total every little bit of time.  Still, it will never be perfect.  &#8220;Good enough&#8221; appears to be the mantra for web programming.</p>
<p>So, that&#8217;s the experiment.  It took about a day, mostly figuring out the event bugs and that the problem could not be properly fixed.  As always, if there enough questions or comments, I&#8217;ll expand the blog entry.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charlesmerriam.com/blog/2010/09/javascript-and-jquery-add-two-numbers-and-fail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>git-serve:  Serve a Git Repository from a Remote Server</title>
		<link>http://www.charlesmerriam.com/blog/2010/08/git-serve-serve-a-git-repository-from-a-remote-server/</link>
		<comments>http://www.charlesmerriam.com/blog/2010/08/git-serve-serve-a-git-repository-from-a-remote-server/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 08:31:41 +0000</pubDate>
		<dc:creator>charles</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[bash]]></category>

		<guid isPermaLink="false">http://www.charlesmerriam.com/blog/?p=204</guid>
		<description><![CDATA[Have a small Bash shell function to serve the current Git distributed version control system repository from a remote host.  The second time I needed to do this, it was time to add a function tomy .bash_site file. Enjoy: # Serve this repository from a remote host. # Run without arguments from the current directory, [...]]]></description>
			<content:encoded><![CDATA[<p>Have a small Bash shell function to serve the current Git distributed version control system repository from a remote host.  The second time I needed to do this, it was time to add a function tomy  <code>.bash_site</code> file.  Enjoy:</p>
<p style="padding-left: 30px;">
<p><code>
<pre>
# Serve this repository from a remote host.
# Run without arguments from the current directory, puts a new repository
# on $remote_host, and let's you do "git push" commands.   Thanks to
# ToolManTim who wrote http://toolmantim.com/thoughts/setting_up_a_new_remote_git_repository
# a few years back.
git-serve () {
    # set remote_host to name in your .ssh/config file.
    remote_host='dream'
    repo_name=$(basename $PWD)
    # if current directory a git repo and name not taken on remote.
    if [ -d .git ] &amp;&amp; [ $(ssh $remote_host "ls git/$repo_name 2&gt; /dev/null" | wc -c) -eq 0 ]
    then
        ssh $remote_host "mkdir -p git/$repo_name &amp;&amp; cd git/$repo_name &amp;&amp; git init --bare"
        git remote add origin $remote_host:git/$repo_name
        git push origin master
        echo '[branch "master"]
      remote = origin
      merge = refs/heads/master
' &gt;&gt; .git/config
      echo "Set up the repository on $remote_host in git/$repo_name.  Please double check your .git/config file:"
      cat .git/config
    else
      echo "Current directory not a repository (no .git) or name taken at $remote_host:git/$repo_name"
    fi
    unset remote_host repo_name
}
</pre>
<p></code><br />
So here is an example working with a small, existing repository:</p>
<pre>
chasm:(master)~/junk$ ls -a
.  ..  .git  hello

chasm:(master)~/junk$ git-serve
Initialized empty Git repository in /home/gizbot/git/junk/
Counting objects: 3, done.
Writing objects: 100% (3/3), 217 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To dream:git/junk
 * [new branch]      master -> master
Set up the repository on dream in git/junk.  Please double check your .git/config file:
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[remote "origin"]
	url = dream:git/junk
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
      remote = origin
      merge = refs/heads/master

chasm:(master)~/junk$ echo "Hi" > hello; git commit -a -m "Hi."
[master dbdcb0a] Hi.
 1 files changed, 1 insertions(+), 1 deletions(-)

chasm:(master)~/junk$ git push
Counting objects: 5, done.
Writing objects: 100% (3/3), 239 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To dream:git/junk
   bb04a32..dbdcb0a  master -> master

chasm:(master)~/junk$ git-serve
Current directory not a repository (no .git) or name taken at dream:git/junk

chasm:(master)~/junk$
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.charlesmerriam.com/blog/2010/08/git-serve-serve-a-git-repository-from-a-remote-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>7 minute talk follow-up</title>
		<link>http://www.charlesmerriam.com/blog/2008/08/7-minute-talk-follow-up/</link>
		<comments>http://www.charlesmerriam.com/blog/2008/08/7-minute-talk-follow-up/#comments</comments>
		<pubDate>Fri, 15 Aug 2008 22:50:20 +0000</pubDate>
		<dc:creator>charles</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Reviews]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Write-up]]></category>
		<category><![CDATA[Google App Engine]]></category>

		<guid isPermaLink="false">http://www.charlesmerriam.com/blog/?p=160</guid>
		<description><![CDATA[Some follow-ups, corrections, and expansions.  Being correct takes effort. First, someone very knowledgeable on the internals noted that I was sloppy with the terms &#8216;datastore&#8216;, &#8216;GBase&#8216;, &#8216;GoogleBase&#8216;, &#8216;GQL&#8216;, and &#8216;BigTable&#8216;.  Mea culpa.  Datastore is the most generic term and the specific one for Google App Engine is referred to as the &#8220;App Engine datastore&#8220;.  The [...]]]></description>
			<content:encoded><![CDATA[<p>Some follow-ups, corrections, and expansions.  Being correct takes effort.</p>
<p>First, someone very knowledgeable on the internals noted that I was sloppy with the terms &#8216;<em>datastore</em>&#8216;, &#8216;<em>GBase</em>&#8216;, &#8216;<em>GoogleBase</em>&#8216;, &#8216;<em>GQL</em>&#8216;, and &#8216;<em>BigTable</em>&#8216;.  Mea culpa.  <strong>Datastore</strong> is the most generic term and the specific one for Google App Engine is referred to as the &#8220;<a href="http://code.google.com/appengine/docs/gettingstarted/usingdatastore.html"><strong>App Engine datastore</strong></a>&#8220;.  The App Engine datastore is accessed through <strong><a href="http://code.google.com/appengine/docs/datastore/gqlreference.html">GQL</a></strong>, a language reminiscent of SQL.  The App Engine datastore is built on BigTable and exposes some of BigTable&#8217;s capabilities (see <a href="http://en.wikipedia.org/wiki/BigTable">Wikipedia</a>, a <a href="http://labs.google.com/papers/bigtable-osdi06.pdf">formal paper</a>,  or <a href="http://video.google.com/videoplay?docid=7278544055668715642">video</a> documentation).    <a href="http://www.google.com/base">GoogleBase</a> is an independent Google product that is also built on BigTable.  GBase is a guitar search engine and the naturally elided form of &#8220;GoogleBase&#8221; after saying it a hundred times.   Whew!  Terms.</p>
<p>Speaking of terms, the contract term dealing with indemnification in the <a href="http://code.google.com/appengine/terms.html">Terms of Service</a>:</p>
<p><em>13.1. You agree to hold harmless and indemnify Google, and its subsidiaries, affiliates, officers, agents, employees, advertisers, licensors, suppliers or partners, (collectively &#8220;Google and Partners&#8221;) from and against any third party claim arising from or in any way related to (a) your breach of the Terms, (b) your use of the Service, (c) your violation of applicable laws, rules or regulations in connection with the Service, or (d) your Content or your Application, including any liability or expense arising from all claims, losses, damages (actual and consequential), suits, judgments, litigation costs and attorneys&#8217; fees, of every kind and nature. In such a case, Google will provide you with written notice of such claim, suit or action.</em></p>
<p>The annoying clause is <em>&#8220;(b) your use of the Service&#8221;</em>.   Given how claims are written in patents, it is entirely likely that use of the API would be an actionable breach if the Google App Engine violated patents.  Google could require indemnification by users of the API.  For most people and smaller companies, the reputation of Google and pledges to &#8220;not be evil&#8221; should be sufficient.</p>
<p>Speaking of evil (<em>note the clever transistion</em>), the lazy index evaluation that makes the database look like &#8220;read committed&#8221; is discussed <a href="http://code.google.com/appengine/articles/transaction_isolation.html">here</a>.</p>
<p>Finally, high availability is hard, and &#8220;9&#8242;s&#8221; go faster than you remember.</p>
<p>90% (1-nine) is a downtime of 36.5 days per year.<br />
99% (2-nines) is a downtime of 3.65 days per year.<br />
99.9% (3-nines) is a downtime of 8.65 hours per year.<br />
99.99% (4 nines) is a downtime of 52 minutes per year.<br />
99.999% (5 nines) is a downtime of 5.2 minutes per year, or six seconds per week.</p>
<p>A claim of about 2-nines reliability is reasonable.  Google App Engine was launched around four months ago <a href="http://news.cnet.com/8301-10784_3-9913631-7.html">in mid-April</a>, so about a day of downtime is 2-nines.  It was down on June 17 for some unreported number of hours, and was down again on June 19 and June 25.  Add in little outages where various features broke, blocking PayPal, and other nits.  There is <a href="http://groups.google.com/group/google-appengine-downtime-notify">a list</a> that occasionally reports downtime, but no exact statistics are available.  If there were no future outages, and you wanted to demonstrate four nines reliability, it would need to take years to overcome the existing outages.</p>
<p>Keep on working on it.  I hope that Google App Engine will be more fun in the future.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charlesmerriam.com/blog/2008/08/7-minute-talk-follow-up/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Google App Engine &#8211; 7 minute talk</title>
		<link>http://www.charlesmerriam.com/blog/2008/08/google-app-engine-7-minute-talk/</link>
		<comments>http://www.charlesmerriam.com/blog/2008/08/google-app-engine-7-minute-talk/#comments</comments>
		<pubDate>Fri, 15 Aug 2008 10:18:08 +0000</pubDate>
		<dc:creator>charles</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Reviews]]></category>
		<category><![CDATA[Write-up]]></category>
		<category><![CDATA[Google App Engine]]></category>

		<guid isPermaLink="false">http://www.charlesmerriam.com/blog/?p=155</guid>
		<description><![CDATA[[I gave this talk at the BayPiggies Meeting on August 14, 2008.  The 'Newbie Nugget' talk ran about seven minutes and used only spoken words.  This is my recollection of what I said.] I drove here today.  I got in my car, used the six speed manual transmission, steering wheel, and pedals.  I had to [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://flickr.com/photos/erica_marshall/2737425814/"><img class="aligncenter size-full wp-image-158" title="Stopwatch" src="http://www.charlesmerriam.com/blog/wp-content/uploads/2008/08/stopw.jpg" alt="" width="160" height="240" /></a></p>
<p><em>[I gave this talk at the BayPiggies Meeting on August 14, 2008.  The 'Newbie Nugget' talk ran about seven minutes and used only spoken words.  This is my recollection of what I said.]</em></p>
<p>I drove here today.  I got in my car, used the six speed manual transmission, steering wheel, and pedals.  I had to know how to change lanes and the rules of the road.  I needed to know traffic patterns, and directions from my house to Google.  I got here.</p>
<p>It was the most dangerous thing I did today.  Traffic accidents kill about 40,000 people a year in the U.S. alone.   It&#8217;s the number one cause of death for everyone from age five to about my age where heart disease and cancer start catching up.  We just take it for granted.   That&#8217;s not the car I want.</p>
<p>I Want My Autodriving Car!  I want to push a button on my cell phone, walk out the door a minute later, and hop into the open door of a car.  It would take me where I want to go, take the best route given current traffic, and drop me in front of the door.   It would never crash.  It would just work.  That&#8217;s what I want in a car.</p>
<p>Here&#8217;s what I want in an application engine.   I want to write in one language.  I want one set of tools.  One naming convention.  I want to be able to translate my thoughts into code cleanly.  I want the application to be on the Internet and scale and to share that application with everyone through a url or something like the IPhone App Store.   That&#8217;s what I want in an application server.</p>
<p>Google App Engine is not there yet.   Google App Engine is a step along that path, and lets you see where application engines are headed.  For the first time, you can see that installing and configuring MySQL on a server and then renting space in a rack for the server will someday sound the same as someone talking about pulling the engine in his car and changing out the rings in the driveway.  I guess you could do that yourself, but why?  You still need to work in the soup of languages:  HTML, CSS, JavaScript, HTTP headers, Flash, Python, and more.   You still need to coordinate your tools for each language:  editor coloring, debugger, make system, test harness, code coverage, and documentation.  It does us good to keep our eyes on the App Engine we want.</p>
<p>So, let&#8217;s talk about Google App Engine:  what is does, how to write for it, where you would use it and not.</p>
<p>Google App Engine is fundamentally a deployment engine.  After you write your application, it provides that application out on the Internet.  It&#8217;s also very early technology.  It sort of supports Django (&#8216;jango&#8217; for those who talk; &#8216;d-jango&#8217; for those who read), but using the latest version runs up against its thousand file limit.  Fully half of the seventy posts a day on the mailing list are about deployment quotas or looking for workarounds to deployment limits.  You cannot run any long job that takes more than a few seconds.  Still, it&#8217;s free.</p>
<p>Writing for Google App Engine is much like writing for any other application engine.  You use the WSGI interface, which someone taught me is pronounced &#8216;whiskey&#8217;, that provides a mapping between the requested URLs and the classes to serve them.  You write a class that has methods to respond to HTTP messages like get and put.  Your codes spits out the HTML and whatever to respond.  Sometimes you trigger urlfetch, from urllib, of your own application like remote procedure calls to avoid hitting computation time request limits.  You store your data in the Google Base data store.</p>
<p>Google Base can be a problem.  The Google Base datastore is not a relational database.  It&#8217;s a great database for working data you collect from all over the web, like web pages or screen scraping, where you are working with massive amounts of data and some of it is always aging out.  It should never be used for accounting.  For example, you can&#8217;t just run a GBase query to update the total invoices for a month.  You need to walk through all the records.  If you update the date on an invoice and then retotal the invoices, you might get the wrong answer.  GBase doesn&#8217;t guarantee the invoices index is immediately updated.  It would probably work, but if you were to try running tests to see how often it fails you&#8217;d use up your quota and be locked out for a few days.</p>
<p>So where is Google App Engine the right choice?  First, it&#8217;s free.   It&#8217;s a good way of learning how to write for application servers.  There are some good tutorials and videos and off you go.  If your application needs a lot of bandwidth downloading from elsewhere on the internet, it&#8217;s probably a good choice.  So if you want to try out an idea that&#8217;s not for making money, go for it.</p>
<p>Where is Google App Engine the wrong choice?  If you are trying to make money, it&#8217;s right out.   First, the license includes clauses that require you to indemnify Google if the API infringes patents.  A Fortune 500 company won&#8217;t let you agree to that.  Second, its reliability wants to get up to five nine&#8217;s (.99999) but is hovering between one and two nines.  Third, it&#8217;s really early tech.  You can watch lots of  bugs get filed and occasionally fixed, but they are in the stage of getting it feature complete first.</p>
<p>In conclusion,  I want an auto-driving car and I want my great application engine.  Google App Engine is like getting a taxi.   A taxi does the driving, but I still need to know directions and road conditions, and I still get into car accidents.   With Google App Engine, I still need to know the whole stack of languages, my site still gets hacked, and it still goes down a lot.  But you can see the future in Google App Engine, and it may turn into something great.</p>
<p><em>[Clarifications and follow-ups for this article got a bit long.  I added some expansions on <a href="http://www.charlesmerriam.com/blog/?p=160">this blog post</a>.]</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.charlesmerriam.com/blog/2008/08/google-app-engine-7-minute-talk/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>KDE 4:  Crud and the Quest for &#8220;The One Last and True Windowing System&#8221;</title>
		<link>http://www.charlesmerriam.com/blog/2008/07/kde-4-crud-and-the-quest-for-the-one-last-and-true-windowing-system/</link>
		<comments>http://www.charlesmerriam.com/blog/2008/07/kde-4-crud-and-the-quest-for-the-one-last-and-true-windowing-system/#comments</comments>
		<pubDate>Fri, 25 Jul 2008 20:26:13 +0000</pubDate>
		<dc:creator>charles</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Reviews]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Write-up]]></category>

		<guid isPermaLink="false">http://www.charlesmerriam.com/blog/?p=145</guid>
		<description><![CDATA[80% of effects come from 20% of causes &#8212; Pareto Principle by Vilfredo Frederico Damaso Pareto, 1906 90% of Everything is Crud &#8211; Sturgeon&#8217;s Law by Theodore Sturgeon, 1956 100% of Everything is Crud &#8211; Linear extrapolation of above, 2006. There seems to have been a natural tendency for us to look at past as [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://kde.org"><img class="size-medium wp-image-146 aligncenter" title="klogo-official-oxygen" src="http://www.charlesmerriam.com/blog/wp-content/uploads/2008/07/klogo-official-oxygen.png" alt="" width="80" height="80" /></a></p>
<p><strong>80% of effects come from 20% of causes</strong><br />
<em> &#8212; Pareto Principle by Vilfredo Frederico Damaso Pareto, 1906</em></p>
<p><strong>90% of Everything is Crud</strong><br />
<em>&#8211; <a href="http://en.wikipedia.org/wiki/Sturgeon%27s_law">Sturgeon&#8217;s Law</a> by Theodore Sturgeon, 1956</em></p>
<p><strong>100% of Everything is Crud</strong><br />
<em>&#8211; Linear extrapolation of above, 2006.</em></p>
<p>There seems to have been a natural tendency for us to look at past as some magical time when quality mattered.   Really, only the pure quality of finished work survived.  We forget the uncountable steps towards quality.</p>
<p>In the world of desktop environments, the journey towards quality continues.  KDE 4.1 makes a step, following trends, and aiming to be The One Last and True Windowing System.</p>
<p><strong>Quality Steps and Missteps</strong></p>
<p>I installed Kubuntu with KDE 4 on my laptop, and am using it to write this post.   That it is written at all shows a minunum level of quality.  That the post starts with these quotes shows a maximum level.</p>
<p>I find immediate problems when installing.  The very first action, the &#8220;Read Me&#8221; during the LiveCD boot,<a href="http://www.charlesmerriam.com/blog/wp-content/uploads/2008/07/5.png"><img class="alignright size-medium wp-image-150" title="5" src="http://www.charlesmerriam.com/blog/wp-content/uploads/2008/07/5-300x225.png" alt="" width="300" height="225" /></a> comes up in a clipped and illegible font.  During partitioning the disks, the progress bar hangs at 0% for ten minutes.  The task bar lacks resizing and basic functionality.  The quick launcher, <a href="http://en.wikipedia.org/wiki/Katapult">Katapult</a>, disappeared.  A new program launcher experiment falls flat with some buttons activating by click and other by hovering the mouse.  Konquer still crashes.    I discover new bugs a few times per hour.  These are the the nits and bugs of a new system.</p>
<p>The subtle problems are the problems repeated from previous years:  the LILO boot system that unhelpfully refers to Vista as &#8220;longhorn&#8221; and Kubuntu as &#8220;generic Ubuntu core&#8221;; the cobbleware of screen layout that has fonts too big for buttons, text too wide for dialogs, and odd alignments; the usual flakiness with power and wireless management.  These problems persist for ages from expectation, difficulty, or blindness.</p>
<p>So quality is a step downward while the easy bugs are fixed.  Some nice features, like <a href="http://en.wikipedia.com/filelight">FileLight</a> <a href="http://www.charlesmerriam.com/blog/wp-content/uploads/2008/07/filelight-10.png"><img class="alignright size-medium wp-image-148" title="filelight-10" src="http://www.charlesmerriam.com/blog/wp-content/uploads/2008/07/filelight-10-300x277.png" alt="" width="300" height="277" /></a>are a definite step up that I expect every other distribution to copy soon.  KDE did buck the trend in releasing a quality downgrade.</p>
<p><strong>Trends in Window Managers </strong></p>
<p>KDE 4 follows the collective wisdom of other software competitors including GNOME, Sugar, Microsoft&#8217;s Windows line, and Apple&#8217;s OS X line.  It tries to be different just like everyone else.  It adds new functionality in pieces and parts.  The hodgepodge of bundling, or smush, that make up windowing systems includes GUI and interface candy, applications, and APIs.</p>
<p>Smush is not pejorative.  Open source swaps in and out competing components and the windowing system selects components under its seal of approval and delinates APIs outside its control.  Quality for each component is involved at several layers.  When the power management on my laptop fails to hibernate before powering off, I could file a bug with KDE, Ubuntu (link to shuttleworth), Debian, the Linux ACPI mailing list, hardware discovery, or just fix it myself.  When searching for a workaround, it could exist anywhere.</p>
<p>KDE is following the trend towards aggressively  cross platform deployment.   By using Qt 4 as it&#8217;s underlying graphics engine, KDE hopes to deploy on desktops (Linux, MS Windows, and OS/X), cellular phones, and some embedded devices.   It is currently hampered by Qt 4 having no LGPL or BSD license, requiring a special licensing cycle to deploy any commercial application.  The previous Qt 4 copyright holder, TrollTech needed this revenue to continue operations.  The new holder, Nokia, may free the code in order to encourage wider adoption and easier developer migration to its cellular phones.</p>
<p>KDE also follows the practice of wrapping more and more functionality into API layer plug-ins.  Rather than commit to a scripting language, <a href="http://kross.dipe.org/">Kross</a> wraps or interfaces to Python, Ruby and JavaScript.   Rather than commit to a multimedia engine, Phonon creates one more layer of indirection for a common interface to GStreamer, QuickTime, DirectShow, and others.  The new release switches many of the wrappers so now it is Phonon (multimedia), Solid (device integration), Plasma (a new desktop), Kross (scripting), DXS (application data updates), Decibel (human communications), and D-BUS replacing DCOP (application messaging).  It is unclear if &#8220;one more layer of indirection&#8221; will be the correct solution in the long run.</p>
<p>In the long run, of course, KDE hopes to birth &#8220;The One Last and True Windowing System.&#8221;</p>
<p><strong>The One Last and True Windowing System</strong></p>
<p><strong><em>Results 1 &#8211; 10 of about 1,040</em></strong><br />
&#8211;<em> Google search for <a href="http://www.google.com/search?q=&quot;one+api+to+rule+them+all&quot;">&#8220;One API to Rule Them All&#8221;</a></em></p>
<p>Windowing systems race towards the goals of full functionality, sweet abstractions, and wide deployment with the winner creating a work that will last decades.  Each release brings new experiments and implements growing standards.  Implementations trump ideas. Differing implementations get abstracted and merged.  Engineers have always raced towards sweet solutions.</p>
<p>Software does get finished.  We still use the C programming language after more than a third of a century.  The syntax, style, and assumptions are passed to new languages such as C++, Python and Ruby.  Other contenders failed.  Hardware architectures now handle pointer indirections, sequential arrays, and null terminated strings.  C goes through occasional updates and forks, but it endures.  Also enduring are the most of the Internet stack including TCP/IP, DNS/Bind, and packet switching; HTTP protocols, SQL, and many more.  These become the common parts upon which we solve new problems.  Many hope to finish writing the desktop software.</p>
<p>FreeDesktop.org gently pushes towards standardization by facilitating discussion.  It speeds the process of making compatible, then integrating, then merging competitng development that has become similar.  It&#8217;s influence on KDE is unmistakable.</p>
<p>So, will KDE give birth to the &#8220;One Last and True Windowing System&#8221; that lasts for decades?</p>
<p><strong>Conclusions </strong></p>
<p>KDE took a significant risk.  It&#8217;s adoption of Qt 4, dropping of DCOP, and making so many changes significantly hurt its quality.  On the other hand, it might provide a new level of functionality to catapult into the top three windowing systems.  Time will tell.  For people just wanting a desktop to work, stay away for six months.<span id="more-145"></span><!--more--><!--more--><!--more--><!--more--></p>
]]></content:encoded>
			<wfw:commentRss>http://www.charlesmerriam.com/blog/2008/07/kde-4-crud-and-the-quest-for-the-one-last-and-true-windowing-system/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fun with Programming a Technology Tree</title>
		<link>http://www.charlesmerriam.com/blog/2008/04/fun-with-programming-a-technology-tree/</link>
		<comments>http://www.charlesmerriam.com/blog/2008/04/fun-with-programming-a-technology-tree/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 19:00:04 +0000</pubDate>
		<dc:creator>charles</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[Write-up]]></category>
		<category><![CDATA[civ2]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[source]]></category>
		<category><![CDATA[technology tree]]></category>

		<guid isPermaLink="false">http://www.charlesmerriam.com/blog/?p=123</guid>
		<description><![CDATA[I spent over a day writing a silly Python program to read in a Civilization 2 Technology Tree. I learned: Python assert statements tend to fail silently during common misuse. Blogged about it. Suggested fixing it on the Py3k mailing list. Guido says there is a SyntaxWarning now. Google docs appears to use the python [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://www.civfanatics.com/civ2/downloads/poster/"><img class="aligncenter size-medium wp-image-127" title="civ2chart" src="http://www.charlesmerriam.com/blog/wp-content/uploads/2008/04/civ2chart-300x243.jpg" alt="Technology Tree for Civilization version 2" width="300" height="243" /></a></p>
<p>I spent over a day writing a silly Python program to read in a Civilization 2 Technology Tree.</p>
<p>I learned:</p>
<ul>
<li>Python assert statements tend to fail silently during common misuse.  Blogged about it.  Suggested fixing it on the Py3k mailing list.  Guido says there is a SyntaxWarning now.</li>
<li>Google docs appears to use the python csv module to export to csv.  Their spreadsheet works fairly well.  I like the auto-save/auto-versioning.</li>
<li>The csv package is pretty inflexible.   It cannot discover the dialect of comma-separated-vague file it is passed.  It works for, and is designed for, times when the export is either excel or Python.  The Dialects do allow you to set some other basic options.</li>
<li><a href="http://www.somethingaboutorange.com/mrl/projects/nose/">nose</a> is a great testing tool.  nose.tools confuses pylint because of its on-the-fly playing with __all__.  I should probably write a Wikipedia article on it.</li>
<li>Whenever debugging recursion, make a note both when calling the recursed function and when returning.  It makes digging through the log much easier.</li>
<li>Nothing tests your code like a large, real world, example.</li>
<li>The logging function rocks far less well.  I filed <a href="http://bugs.python.org/issue2684">bug</a> on it:  it picks up the wrong %(filename)s.  This bug has apparently been going back and forth for years.</li>
<li>Reading a correctly validated input file is about 10x the effort of reading an incorrectly validated one.</li>
<li>Testing code is fairly easy and a bit bulky.  It&#8217;s real cost is that it forces that 10x effort in validating the input in order to pass the tests.  I could get behind Test Driven Development.</li>
<li>The<a href="http://www.civfanatics.com/images/civ2/poster/civ2chart.jpg"> Civilization 2 Technology Tree</a> has five errors, including two &#8220;Destroyer&#8221; units and a bunch of redundant dependencies, such as Fusion Power doesn&#8217;t need to depend on Nuclear Power.</li>
<li>Sets in Python work well.</li>
<li>WordPress has syntax coloring plug-ins that work fairly well, and it can handle arbitrary files.</li>
<li>Programming is still fun.</li>
</ul>
<p>So, with no plans to do anything with this:</p>
<p><a href="http://www.charlesmerriam.com/blog/wp-content/uploads/2008/04/techpy.txt">tech.py</a> &#8212; This is Python code.  It loads the technology tree and doesn&#8217;t do anything with it.</p>
<p><a href="http://www.charlesmerriam.com/blog/wp-content/uploads/2008/04/civtech.csv">civtech.csv</a> &#8212; A CSV file with the <a href="http://www.civfanatics.com/images/civ2/poster/civ2chart.jpg">Civilization 2 technology tree</a></p>
<p><a href="http://spreadsheets.google.com/pub?key=p3clPOmjOp6gFMAiXDIfUIw">CivChart</a> &#8212; A GoogleDoc spreadsheet with that same technology tree</p>
<p><em>This post cleverly delayed for a few days to space out my postings. <img src='http://www.charlesmerriam.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.charlesmerriam.com/blog/2008/04/fun-with-programming-a-technology-tree/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python Assert Fails Silently?</title>
		<link>http://www.charlesmerriam.com/blog/2008/04/python-assert-fails-silently/</link>
		<comments>http://www.charlesmerriam.com/blog/2008/04/python-assert-fails-silently/#comments</comments>
		<pubDate>Thu, 24 Apr 2008 18:51:00 +0000</pubDate>
		<dc:creator>charles</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Idea]]></category>
		<category><![CDATA[Ideas]]></category>
		<category><![CDATA[assert]]></category>
		<category><![CDATA[assertions]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[python 3.0]]></category>
		<category><![CDATA[python 3K]]></category>

		<guid isPermaLink="false">http://www.charlesmerriam.com/blog/?p=119</guid>
		<description><![CDATA[Problem: Python assert statements are prone to silently fail in obvious misuse. Solution: Modify Python assert statement to &#8220;assert condition as message&#8221; Python usually does the right thing &#8482;. That is, usually a programmer&#8217;s code does what is expected without odd language gotcha&#8217;s. Here is one of the gotcha&#8217;s: def do_with_file(filename): assert(len(filename)&#62;0 and filename[0] &#60;&#62; [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://flickr.com/photos/baldheretic/240534018/"><img class="alignnone size-medium wp-image-120" title="python" src="http://www.charlesmerriam.com/blog/wp-content/uploads/2008/04/python.jpg" alt="" width="240" height="160" /></a></p>
<p><strong>Problem:</strong> Python assert statements are prone to silently fail in obvious misuse.</p>
<p><strong>Solution:</strong> Modify Python assert statement to &#8220;assert condition as message&#8221;</p>
<p>Python usually does the right thing &#8482;.  That is, usually a programmer&#8217;s code does what is expected without odd language gotcha&#8217;s.  Here is one of the gotcha&#8217;s:</p>
<pre lang="python">def do_with_file(filename):
    assert(len(filename)&gt;0 and filename[0] &lt;&gt; ' ', 'filename (%s) not valid' % filename)
    ...</pre>
<p>Seems reasonable?  Sorry, that assert is equivalent to:</p>
<pre lang="python">assert True</pre>
<p>because your parenthesis made a tuple.  You meant to type this:</p>
<pre lang="python">assert len(filename)&gt;0 and filename[0] &lt;&gt; ' ', 'filename (%s) not valid' % filename</pre>
<p>Python 3.0 should be modified to require this:</p>
<pre lang="python">assert len(filename)&gt;0 and filename[0] &lt;&gt; ' ' as 'filename (%s) not valid' % filename </pre>
<p>or just make assert a built_in function and, therefore, require the parenthesis.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charlesmerriam.com/blog/2008/04/python-assert-fails-silently/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>FavIcon integrated editor</title>
		<link>http://www.charlesmerriam.com/blog/2008/04/favicon-integrated-editor/</link>
		<comments>http://www.charlesmerriam.com/blog/2008/04/favicon-integrated-editor/#comments</comments>
		<pubDate>Wed, 16 Apr 2008 22:54:04 +0000</pubDate>
		<dc:creator>charles</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Idea]]></category>
		<category><![CDATA[Ideas]]></category>
		<category><![CDATA[Products]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[editor]]></category>
		<category><![CDATA[favicon]]></category>
		<category><![CDATA[icon editor]]></category>

		<guid isPermaLink="false">http://www.charlesmerriam.com/blog/?p=101</guid>
		<description><![CDATA[Problem: I want a web browser plug-in that can edit the FavIcon for my bookmarks. Solution: Build one. There exist dozens of online FavIcon editors on the web. The FavIcon is the small graphic in the corner of the address book; the one for this site looks like this .  Some tools, like FavIcon Picker 2 [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://flickr.com/photos/xerones/97565383/"><img class="aligncenter size-medium wp-image-112" title="icon" src="http://www.charlesmerriam.com/blog/wp-content/uploads/2008/04/icon.jpg" alt="" width="100" height="100" /></a></p>
<p><strong>Problem:</strong> I want a web browser plug-in that can edit the FavIcon for my bookmarks.</p>
<p><strong>Solution: </strong> Build one.</p>
<p>There exist dozens of online FavIcon editors on the web.  The FavIcon is the small graphic in the corner of the address book; the one for this site looks like this <img src="http://www.charlesmerriam.com/favicon.ico" alt="" />.    Some tools, like <a href="https://addons.mozilla.org/en-US/firefox/addon/3176">FavIcon Picker 2</a> let bookmarks be reduced to just the icon, making a compact tool bar of bookmarks.   Unfortunately, not every site has a favorite icon, and different services help on the same favorite icon.  For example, Google, Google (Linux) search, and Google Analytics have the same favicon.  I want to make my own icon as a minor variation of the single standard icon.  Alternately, I want to make dirt simple favicons for sites that have none.</p>
<p>My feature list for such a program would include:</p>
<ul>
<li>Take an existing favicon and alter the colors.  The red &#8220;G&#8221; might be search, the &#8220;blue&#8221; might be analytics.</li>
<li>Add a letter overlay onto existing favicons, so my &#8220;Google Linux&#8221; button has an &#8220;L&#8221; on it.</li>
<li>Create a one or two character favicon so that the cool Widgets site with no icon could get a &#8220;red Wi&#8221; favicon in my bookmarks.</li>
</ul>
<p>None of this is particularly odd or difficult.  It&#8217;s a matter of a GUI front end, some data files, and some shelling out to ImageMagick to do the actual work.  Hmm&#8230;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charlesmerriam.com/blog/2008/04/favicon-integrated-editor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing Python GUI Toolkits for Testability (for PyGTK et al)</title>
		<link>http://www.charlesmerriam.com/blog/2008/03/writing-python-gui-toolkits-for-testability-for-pygtk-et-al/</link>
		<comments>http://www.charlesmerriam.com/blog/2008/03/writing-python-gui-toolkits-for-testability-for-pygtk-et-al/#comments</comments>
		<pubDate>Thu, 27 Mar 2008 07:40:26 +0000</pubDate>
		<dc:creator>charles</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Idea]]></category>
		<category><![CDATA[Ideas]]></category>
		<category><![CDATA[gui testing]]></category>
		<category><![CDATA[pyGTK]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.charlesmerriam.com/blog/?p=106</guid>
		<description><![CDATA[Problem: Testing GUIs tends to be hard. Writing a reasonable test for GUIs usually involves contortions to find the correct widget and values. For example, a test might want to confirm that &#8220;the font is now bold for the third text field, named system_danger_level, in the hbox in the floating frame in the second panel [...]]]></description>
			<content:encoded><![CDATA[<p> <a href="http://flickr.com/photos/markuz/293476500/"></a></p>
<p style="text-align: center"><a href="http://flickr.com/photos/markuz/293476500/"><img src="http://www.charlesmerriam.com/blog/wp-content/uploads/2008/03/testing.thumbnail.jpg" alt="testing.jpg" /></a></p>
<p><strong>Problem:</strong>  Testing GUIs tends to be hard.</p>
<p>Writing a reasonable test for GUIs usually involves contortions to find the correct widget and values.  For example, a test might want to confirm that &#8220;the font is now bold for the third text field, named <em>system_danger_level</em>, in the hbox in the floating frame in the second panel in the third tab bar in the dialog box&#8221;.  Figuring out how to tell if the test passed is usually difficult.</p>
<p><strong>Solution:</strong>  Add a function in the GUI framework that returns a single large data structure for the state of the GUI.  Use standard Python programming to navigate it.</p>
<p>The test becomes:</p>
<p><em>assert(gobject.dump(&#8220;system_danger_level&#8221;)["font"]["style"] == &#8220;bold&#8221;) </em></p>
<p>This is one of my poorly researched ideas:  it came up while talking with Shandy before Mark Shuttleworth&#8217;s talk last night.  All GUI frameworks are inherently a bit crufty and hard to navigate.  On the other hand, the data types in Python are rich:  dictionaries, arrays, nested structures, etc.   While handing such a data structure to PyGTK to modify the GUI might require a lot of writing, asking PyGTK to disgorge such a data structure is far easier.</p>
<p>Consider adding it the the <a href="http://www.pygtk.org/docs/pygobject/gobject-functions.html">GObject functions</a>.  Call a new <em>gobject.dump_main_context()</em> and get a huge Python data structure back.  It might have lots of redundant methods of finding the same data.  For example, a tree of all the contexts or dialog boxes and the usual tree objects inside that are grabbed by tools like <a href="http://www.cs.umd.edu/~atif/GUITARWeb/gui_ripper.htm">Guitar&#8217;s GUI Ripper</a>.  It might also have a handy hash of object id&#8217;s and their associated sub-records, like an index into the big tree.</p>
<p>While some may decry the memory and time cost of creating this tree might have the legitimate wish for a second  function known simply as <em>gobject.dump()</em>.  It would take a single identifier tag and return a single object from that tag &#8216;downwards&#8217; in detail.  A well published heuristic would have it &#8220;do the right thing&#8221; when given a tag that exists in multiple places.<br />
This feels like a &#8220;implement it first and then see if its useful&#8221; type of hack.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charlesmerriam.com/blog/2008/03/writing-python-gui-toolkits-for-testability-for-pygtk-et-al/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rethinking the Font Chooser</title>
		<link>http://www.charlesmerriam.com/blog/2008/03/rethinking-the-font-chooser/</link>
		<comments>http://www.charlesmerriam.com/blog/2008/03/rethinking-the-font-chooser/#comments</comments>
		<pubDate>Fri, 21 Mar 2008 19:04:08 +0000</pubDate>
		<dc:creator>charles</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Idea]]></category>
		<category><![CDATA[Ideas]]></category>
		<category><![CDATA[fonts]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[typography]]></category>

		<guid isPermaLink="false">http://www.charlesmerriam.com/blog/?p=104</guid>
		<description><![CDATA[Problem: Font chooser are boxes cause more load as one has more fonts. Font choosing options have barely evolved from the very first days of the Lisa where a user could choose between *gasp* five fonts. Now, there are thousands of fonts and the font chooser boxes look the same. Solution: Visualize fonts spatially according [...]]]></description>
			<content:encoded><![CDATA[<p align="center"> <a href="http://flickr.com/photos/bright/84004836/" title="signs"><img src="http://www.charlesmerriam.com/blog/wp-content/uploads/2008/03/signs.jpg" alt="signs.jpg" /></a></p>
<p><strong>Problem:</strong>    Font chooser are boxes cause more load as one has more fonts.</p>
<p>Font choosing options have barely evolved from the very first days of the Lisa where a user could choose between *gasp* five fonts.   Now, there are thousands of fonts and the font chooser boxes look the same.</p>
<p><strong>Solution:</strong>    Visualize fonts spatially according to useful categoriztions</p>
<p>There exist various categorization methods for fonts:  technical, quantitative, typographical, and subjective.  Pick some within the list:  measured reading speed (quantitative), bitmap versus stroke based (technical), or rankings (subjective); then map the fonts onto a sphere,  fictional map (the isle of bitmaps), or plain old grid.   That way, a user can pick a font from among other fonts that share the sameessential characteristics, e.g., slow reading speed.</p>
<p>Ah, but were ideas code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charlesmerriam.com/blog/2008/03/rethinking-the-font-chooser/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

