<?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>Probably Programming</title>
	<atom:link href="http://probablyprogramming.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://probablyprogramming.com</link>
	<description>It&#039;s what I&#039;m doing, and what posts on this blog are about.</description>
	<lastBuildDate>Wed, 10 Feb 2010 02:03:42 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Comic-Fu</title>
		<link>http://probablyprogramming.com/2010/02/09/comic-fu/</link>
		<comments>http://probablyprogramming.com/2010/02/09/comic-fu/#comments</comments>
		<pubDate>Tue, 09 Feb 2010 23:42:21 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[500 Programming Languages]]></category>
		<category><![CDATA[Entertainment]]></category>
		<category><![CDATA[Comic-Fu]]></category>
		<category><![CDATA[GIMP]]></category>
		<category><![CDATA[scheme]]></category>

		<guid isPermaLink="false">http://probablyprogramming.com/?p=634</guid>
		<description><![CDATA[

Angie has been slaving away working on Company-Y lately, and I think it&#8217;s coming along quite nicely.

Yesterday I decided to give her a break by helping with the coloring of the latest page &#8220;I love it when a plan comes together&#8221;, and I realized that the coloring process could be greatly sped up if we [...]]]></description>
			<content:encoded><![CDATA[<div><a class="postimage" href="http://probablyprogramming.com/2010/02/09/comic-fu"><img src="http://probablyprogramming.com/wp-content/uploads/2010/02/plancomestogether.png" alt="saveplace" title="I love it when a plan comes together!" height="252" width="425"/></a></div>

<p>Angie has been slaving away working on <a href="http://company-y.com">Company-Y</a> lately, and I think it&#8217;s coming along quite nicely.</p>

<p>Yesterday I decided to give her a break by helping with the coloring of the latest page <a href="http://company-y.com/2010/02/08/i-love-it-when-a-plan-comes-together/">&#8220;I love it when a plan comes together&#8221;</a>, and I realized that the coloring process could be greatly sped up if we could simply flood fill the various areas, rather than having to draw around the outline of the area before flood filling it.</p>

<p>The comic is drawn in The GIMP. The lines are drawn on an transparent layer, and then the coloring is done on another layer below, so as not to mess up the lines. Since there are no boundaries on the lower layer, flood filling doesn&#8217;t work.</p>

<p>So I tossed together a quick TinyLisp add-on which takes the current layer, duplicates it, thresholds on alpha level (gets rid of any pixels that aren&#8217;t within a certain opacity level), and puts the new layer below the current one. After that, flood filling can be done in the lower layer without any issues related to the antialiased/feathered edges of the lines.</p>

<p>It&#8217;s a fairly simple script, though it took me a while to get it all working correctly (why the heck do all the GIMP built-ins return lists, making me have to (car &#8230;) everywhere, instead of just the primitives?)</p>

<p>Anyway, I was inspired, and came up with some ideas for some more time-saving add-ons to write, so I&#8217;ve started a <a href="http://github.com/pib/Comic-Fu">Comic-Fu project at GitHub</a></p>

<p>If you want to install it, simply download <a href="http://github.com/pib/Comic-Fu/raw/master/make-fillable.scm">make-fillable.scm</a> and put it into your .gimp-2.6/scripts directory. It should then be in the Filters->Comic-Fu menu the next time you start up the GIMP.</p>

<p>p.s. I&#8217;m totally counting this as one of my programs for my 500 Programming Languages thing. I&#8217;ll do a write-up of TinyScheme at a later point. </p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fprobablyprogramming.com%2F2010%2F02%2F09%2Fcomic-fu%2F';
  addthis_title  = 'Comic-Fu';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://probablyprogramming.com/2010/02/09/comic-fu/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>⚃ Rolling Dice with JS and Unicode ⚂</title>
		<link>http://probablyprogramming.com/2010/01/06/rolling-dice-with-js-and-unicode/</link>
		<comments>http://probablyprogramming.com/2010/01/06/rolling-dice-with-js-and-unicode/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 03:53:48 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[dice]]></category>
		<category><![CDATA[Unicode]]></category>

		<guid isPermaLink="false">http://probablyprogramming.com/?p=619</guid>
		<description><![CDATA[I recently discovered the unicode xscreensaver hack, and have had it running on my secondary monitor for the heck of it. I found out that there are dice face symbols, and I was inspired to do something with them.

So, I made a simple Unicode-dice roller in JavaScript. I know the same thing could be done [...]]]></description>
			<content:encoded><![CDATA[<p>I recently discovered the <a href="http://blog.spang.cc/posts/configuring_Gnome_screensaver_for_unicode-screensaver/">unicode xscreensaver hack</a>, and have had it running on my secondary monitor for the heck of it. I found out that there are dice face symbols, and I was inspired to do something with them.</p>

<p>So, I made a simple Unicode-dice roller in JavaScript. I know the same thing could be done in JS, but this way you can roll some numbers to paste into Twitter or something, if you feel like it.</p>

<script type="text/javascript">
function roll(n) {
    var dice = ['\u2680', '\u2681', '\u2682', '\u2683', '\u2684', '\u2685'];
    var results = '';
    for (var i=0; i<n ; i++) {
        results += dice[Math.floor(Math.random()*6)] + ' ';
    }
    return results;
}

function doRoll(countElem, resultElem) {
    document.getElementById(resultElem).innerHTML = 
        roll(parseInt(document.getElementById(countElem).value));
}
</script>

<p>Enter number of Dice to roll:<br /><input type="text" id="dice-roll-number" value="4" />
<input type="button" onclick="doRoll('dice-roll-number', 'dice-roll-result')" value="Roll!" /></p>

<p>Result: <span style="font-size: 64px; line-height: normal" id="dice-roll-result">&nbsp;</span></p>

<p>The code is extremely simple, calling Math.floor on the result of Math.random n times, then using a small table of the codepoints from U+2680 to U+2685 to build a string.</p>

<p>Here is the code for anyone interested:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #003366; font-weight: bold;">function</span> roll<span style="color: #009900;">&#40;</span>n<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> dice <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\u</span>2680'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\u</span>2681'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\u</span>2682'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\u</span>2683'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\u</span>2684'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\u</span>2685'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> results <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>n<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        results <span style="color: #339933;">+=</span> dice<span style="color: #009900;">&#91;</span>Math.<span style="color: #660066;">floor</span><span style="color: #009900;">&#40;</span>Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span><span style="color: #CC0000;">6</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">' '</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">return</span> results<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> doRoll<span style="color: #009900;">&#40;</span>countElem<span style="color: #339933;">,</span> resultElem<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span>resultElem<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> 
        roll<span style="color: #009900;">&#40;</span>parseInt<span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span>countElem<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">value</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span>
&nbsp;
Enter number of Dice to roll:&lt;br&gt;&lt;input type=&quot;text&quot; id=&quot;dice-roll-number&quot; /&gt;
&lt;input type=&quot;button&quot; onclick=&quot;doRoll('dice-roll-number', 'dice-roll-result')&quot; value=&quot;Roll!&quot; /&gt;
&nbsp;
Result: &lt;span style=&quot;font-size: 64px; line-height: normal&quot; id=&quot;dice-roll-result&quot;&gt;&lt;/span&gt;</pre></div></div>

<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fprobablyprogramming.com%2F2010%2F01%2F06%2Frolling-dice-with-js-and-unicode%2F';
  addthis_title  = '%E2%9A%83+Rolling+Dice+with+JS+and+Unicode+%E2%9A%82';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
</n></script>]]></content:encoded>
			<wfw:commentRss>http://probablyprogramming.com/2010/01/06/rolling-dice-with-js-and-unicode/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>A save your place bookmarklet</title>
		<link>http://probablyprogramming.com/2009/12/01/save-your-place-bookmarklet/</link>
		<comments>http://probablyprogramming.com/2009/12/01/save-your-place-bookmarklet/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 07:10:38 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[Entertainment]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[bookmarklets]]></category>

		<guid isPermaLink="false">http://probablyprogramming.com/?p=594</guid>
		<description><![CDATA[

(image source)

I read a lot of web comics, and one of the things that happens when reading through the archives of a comic is that I lose my place in the history, so when I come back, I have to spend a lot of time searching to find where I left off.

I wrote this simple [...]]]></description>
			<content:encoded><![CDATA[<div><a class="postimage" href="http://probablyprogramming.com/2009/12/01/save-your-place-bookmarklet/"><img src="http://probablyprogramming.com/wp-content/uploads/2009/12/saveplace.jpg" alt="saveplace" title="saveplace" width="425" height="252" /></a></div>

<div class="attribution"><a title="Some rights reserved" href="http://creativecommons.org/licenses/by/2.0/deed.en"><img alt="cc icon attribution" src="http://probablyprogramming.com/wp-content/uploads/2008/02/cc_icon_attribution_small.gif"/></a>(<a href="http://www.flickr.com/photos/chitrasudar/2756691008/">image source</a>)</div>

<p>I read a lot of web comics, and one of the things that happens when reading through the archives of a comic is that I lose my place in the history, so when I come back, I have to spend a lot of time searching to find where I left off.</p>

<p>I wrote this simple set of bookmarklets to help me in this situation. The &#8220;save place&#8221; bookmarklet stuffs the current URL into a cookie (cookies are per site, so there will be one cookie for each site you use this on), and the &#8220;restore place&#8221; bookmarklet takes the URL out of the cookie (if it exists) and loads that page. The &#8220;clear place&#8221; bookmarklet clears the cookie.</p>

<p>To use them, just drag the bookmarklets to your bookmark toolbar, or right-click on them and select &#8220;bookmark this link&#8221;.</p>

<p><a href="javascript:(function(){var date = new Date();document.cookie='ppdc_saved_location='+escape(document.location)+'; expires='+date.setTime(date.getTime()+22896000000)+'; path=/'})()">Save Place</a> | <a href="javascript:void(document.location=(function(){var ca=document.cookie.split(';');for(var i=0;i<ca.length;i++){var c=ca[i];while(c.charAt(0)==' ')c=c.substring(1,c.length);if(c.indexOf('ppdc_saved_location=')==0)return unescape(c.substring(20,c.length));}return document.location;})())">Restore Place</a> | <a href="javascript:void(document.cookie='ppdc_saved_location=; expires=-1; path=/')">Clear Place</a></p>

<p>For those who are interested, here&#8217;s the code in function form:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> savePlace<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> date <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    document.<span style="color: #660066;">cookie</span><span style="color: #339933;">=</span><span style="color: #3366CC;">'ppdc_saved_location='</span><span style="color: #339933;">+</span>escape<span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">location</span><span style="color: #009900;">&#41;</span>
        <span style="color: #339933;">+</span><span style="color: #3366CC;">'; expires='</span><span style="color: #339933;">+</span>date.<span style="color: #660066;">setTime</span><span style="color: #009900;">&#40;</span>date.<span style="color: #660066;">getTime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #CC0000;">22896000000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #3366CC;">'; path=/'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> restorePlace<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    document.<span style="color: #660066;">location</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #003366; font-weight: bold;">var</span> ca <span style="color: #339933;">=</span> document.<span style="color: #660066;">cookie</span>.<span style="color: #660066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">';'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&lt;</span>ca.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
             <span style="color: #003366; font-weight: bold;">var</span> c<span style="color: #339933;">=</span>ca<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
             <span style="color: #000066; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>c.<span style="color: #660066;">charAt</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">==</span><span style="color: #3366CC;">' '</span><span style="color: #009900;">&#41;</span> c <span style="color: #339933;">=</span> c.<span style="color: #660066;">substring</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span>c.<span style="color: #660066;">length</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
             <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>c.<span style="color: #660066;">indexOf</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'ppdc_saved_location='</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> 
                 <span style="color: #000066; font-weight: bold;">return</span> unescape<span style="color: #009900;">&#40;</span>c.<span style="color: #660066;">substring</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">20</span><span style="color: #339933;">,</span>c.<span style="color: #660066;">length</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #009900;">&#125;</span>
         <span style="color: #000066; font-weight: bold;">return</span> document.<span style="color: #660066;">location</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> clearPlace<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    document.<span style="color: #660066;">cookie</span><span style="color: #339933;">=</span><span style="color: #3366CC;">'ppdc_saved_location=; expires=-1; path=/'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>


<p>I based my code off the <a href="http://www.quirksmode.org/js/cookies.html">createCookie and readCookie functions from QuirksMode</a></p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fprobablyprogramming.com%2F2009%2F12%2F01%2Fsave-your-place-bookmarklet%2F';
  addthis_title  = 'A+save+your+place+bookmarklet';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://probablyprogramming.com/2009/12/01/save-your-place-bookmarklet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fun with bookmarklets and CSS3 transforms</title>
		<link>http://probablyprogramming.com/2009/11/26/fun-with-bookmarklets-and-css3-transforms/</link>
		<comments>http://probablyprogramming.com/2009/11/26/fun-with-bookmarklets-and-css3-transforms/#comments</comments>
		<pubDate>Thu, 26 Nov 2009 05:52:04 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[bookmarklets]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[transform]]></category>

		<guid isPermaLink="false">http://probablyprogramming.com/?p=562</guid>
		<description><![CDATA[

I recently read about the CSS transform property, and I was inspired to give it a try in a fun and mostly useless way.

After a bit of fidding, I present to you the &#8220;Rotate!&#8221; bookmarklet (click it several times if it doesn&#8217;t work the first time):

Rotate!

Simply drag the above link to your bookmarks toolbar, and [...]]]></description>
			<content:encoded><![CDATA[<p><a class="postimage" href="http://probablyprogramming.com/2009/11/26/fun-with-bookmarklets-and-css3-transforms"><img src="http://probablyprogramming.com/wp-content/uploads/2009/11/transformcrop.png" alt="Transform!" title="Transform!" width="425" height="252"  /></a></p>

<p>I recently read about the <a href="http://www.w3.org/TR/css3-2d-transforms/#transform-property">CSS transform property</a>, and I was inspired to give it a try in a fun and mostly useless way.</p>

<p>After a bit of fidding, I present to you the &#8220;Rotate!&#8221; bookmarklet (click it several times if it doesn&#8217;t work the first time):</p>

<p><a href="javascript:(function() {var ds = document.getElementsByTagName('div');var d = ds[Math.round(Math.random()*ds.length)];function transform(r) {d.style.transform=d.style['WebkitTransform']=d.style['MozTransform']='rotate(' + r + 'deg)';setTimeout(function() {transform(++r % 360);}, 100);}transform(1);})()">Rotate!</a></p>

<p>Simply drag the above link to your bookmarks toolbar, and whenever you get bored with a webpage, click that link, and see what happens!</p>

<p>The code is pretty simple. It just gets a list of all the divs on the page, picks one of them at random, and starts rotating it. Click it multiple times, and it will rotate multiple times.</p>

<p>Here&#8217;s the code, formatted for your viewing pleasure:</p>


<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> ds <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'div'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> d <span style="color: #339933;">=</span> ds<span style="color: #009900;">&#91;</span>Math.<span style="color: #660066;">round</span><span style="color: #009900;">&#40;</span>Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span>ds.<span style="color: #660066;">length</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">function</span> rotateHeaders<span style="color: #009900;">&#40;</span>r<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    d.<span style="color: #660066;">style</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'WebkitTransform'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> d.<span style="color: #660066;">style</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'MozTransform'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'rotate('</span> <span style="color: #339933;">+</span> r <span style="color: #339933;">+</span> <span style="color: #3366CC;">'deg)'</span><span style="color: #339933;">;</span>
    setTimeout<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>rotateHeaders<span style="color: #009900;">&#40;</span><span style="color: #339933;">++</span>r <span style="color: #339933;">%</span> <span style="color: #CC0000;">360</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  rotateHeaders<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></pre></div></div>


<p>Unfortuneately, this only works in Firefox and Webkit-based browsers at the moment..wait, no, that&#8217;s pretty much ok. You IE folks out there are used to things not working in your browser by now.</p>

<p>With a couple small changes, you can make it scale instead: <a href="javascript:(function() {var ds = document.getElementsByTagName('div');var d = ds[Math.round(Math.random()*ds.length)];function transform(r) {d.style.transform=d.style['WebkitTransform']=d.style['MozTransform']='scale(' + r + ')';setTimeout(function() {transform(++r % 10);}, 100);}transform(1);})()">Scale!</a></p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fprobablyprogramming.com%2F2009%2F11%2F26%2Ffun-with-bookmarklets-and-css3-transforms%2F';
  addthis_title  = 'Fun+with+bookmarklets+and+CSS3+transforms';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://probablyprogramming.com/2009/11/26/fun-with-bookmarklets-and-css3-transforms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Simple Lisp Parser in Python</title>
		<link>http://probablyprogramming.com/2009/11/23/a-simple-lisp-parser-in-python/</link>
		<comments>http://probablyprogramming.com/2009/11/23/a-simple-lisp-parser-in-python/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 07:59:15 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[Programming Languages]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[parser]]></category>
		<category><![CDATA[sexp]]></category>

		<guid isPermaLink="false">http://probablyprogramming.com/?p=545</guid>
		<description><![CDATA[A managed to sneak in a little time recently and write a simple Lisp s-expression parser in Python.

I started out with a version that just understands parentheses, atoms, and strings, but it was just a couple of extra lines to add in support for the quote &#8220;operator&#8221;, that I went ahead and threw that in [...]]]></description>
			<content:encoded><![CDATA[<p>A managed to sneak in a little time recently and write a simple <a href="http://en.wikipedia.org/wiki/Sexp">Lisp s-expression</a> parser in Python.</p>

<p>I started out with a version that just understands parentheses, atoms, and strings, but it was just a couple of extra lines to add in support for the quote &#8220;operator&#8221;, that I went ahead and threw that in there, too.</p>

<p>I&#8217;ll go ahead and go through it bit-by-bit here, though I think it&#8217;s pretty straightforward.</p>


<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">string</span> <span style="color: #ff7700;font-weight:bold;">import</span> whitespace
&nbsp;
atom_end = <span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'()&quot;<span style="color: #000099; font-weight: bold;">\'</span>'</span><span style="color: black;">&#41;</span> | <span style="color: #008000;">set</span><span style="color: black;">&#40;</span>whitespace<span style="color: black;">&#41;</span></pre></div></div>


<p>When any of these things are encountered while reading an atom, the atom should be ended. This means no need for whitespace betwen an atom and opening or closing parentheses or quotes.</p>


<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> parse<span style="color: black;">&#40;</span>sexp<span style="color: black;">&#41;</span>:
    stack, i, length = <span style="color: black;">&#91;</span><span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>, <span style="color: #ff4500;">0</span>, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>sexp<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">while</span> i <span style="color: #66cc66;">&lt;</span> length:</pre></div></div>


<p>Rather than write this recursively, I am using a list as a stack and a simple while-loop to go through the contents of the string. I start with an empty list on the stack, which will hold the entire parsed sexp when the parsing is done.</p>


<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">        c = sexp<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span>
        reading = <span style="color: #008000;">type</span><span style="color: black;">&#40;</span>stack<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre></div></div>


<p>Each character is put into c and the type of the current item being read is checked. Rather than using some variable to keep track of the current state of the parser, I just used a distinct Python type for each of the possible lisp types to be read: a list for a list, a string for a string, and a string inside a tuple for an atom. Using this system, I just have to check what type the top element in the stack is, and I&#8217;ll know what I&#8217;m currently reading.</p>


<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">        <span style="color: #ff7700;font-weight:bold;">if</span> reading == <span style="color: #008000;">list</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span>   c == <span style="color: #483d8b;">'('</span>: stack.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">elif</span> c == <span style="color: #483d8b;">')'</span>: 
                stack<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>stack.<span style="color: black;">pop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> stack<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> == <span style="color: black;">&#40;</span><span style="color: #483d8b;">'quote'</span>,<span style="color: black;">&#41;</span>: stack<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>stack.<span style="color: black;">pop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">elif</span> c == <span style="color: #483d8b;">'&quot;'</span>: stack.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">elif</span> c == <span style="color: #483d8b;">&quot;'&quot;</span>: stack.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'quote'</span>,<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">elif</span> c <span style="color: #ff7700;font-weight:bold;">in</span> whitespace: <span style="color: #ff7700;font-weight:bold;">pass</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>: stack.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>c,<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>


<p>When reading a list:</p>

<ul>
<li>If an opening parenthesis is encountered, add a new list to the stack</li>
<li>If a closing parenthesis is encountered, take the list from the top of the stack and append it to the next list down in the stack. Check if the last thing read was a quote, and if so, add this list as the parameter to the quote call.</li>
<li>If an opening double-quote is encountered, add an empty string to the stack.</li>
<li>If a single-quote is found, add a list with a quote symbol at the beginning of it.</li>
<li>If c is whitespace, ignore it.</li>
<li>Otherwise, start an atom with whatever other character was found.</li>
</ul>


<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">        <span style="color: #ff7700;font-weight:bold;">elif</span> reading == <span style="color: #008000;">str</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span>   c == <span style="color: #483d8b;">'&quot;'</span>: 
                stack<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>stack.<span style="color: black;">pop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> stack<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> == <span style="color: black;">&#40;</span><span style="color: #483d8b;">'quote'</span>,<span style="color: black;">&#41;</span>: stack<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>stack.<span style="color: black;">pop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">elif</span> c == <span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\\</span>'</span>: 
                i += <span style="color: #ff4500;">1</span>
                stack<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> += sexp<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>: stack<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> += c</pre></div></div>


<p>When reading a string:</p>

<ul>
<li>If a closing double-quote is found, end the string, and check for a previous quote call like above (it doesn&#8217;t really make sense to quote a string, but this isn&#8217;t really the place to check for that, is it?)</li>
<li>If a backslash is found, put whatever the following character is in the string. This is a simplistic way to at least allow double-quotes to be escaped, but I don&#8217;t have anything allowing for more complex escape-strings in here yet.</li>
<li>Anything else, add to the string.</li>
</ul>


<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">        <span style="color: #ff7700;font-weight:bold;">elif</span> reading == <span style="color: #008000;">tuple</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span>   c <span style="color: #ff7700;font-weight:bold;">in</span> atom_end: 
                atom = stack.<span style="color: black;">pop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> atom<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">isdigit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>: stack<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #008000;">eval</span><span style="color: black;">&#40;</span>atom<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">else</span>: stack<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>atom<span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">if</span> stack<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> == <span style="color: black;">&#40;</span><span style="color: #483d8b;">'quote'</span>,<span style="color: black;">&#41;</span>: stack<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>stack.<span style="color: black;">pop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
                <span style="color: #ff7700;font-weight:bold;">continue</span>
            <span style="color: #ff7700;font-weight:bold;">else</span>: stack<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>stack<span style="color: black;">&#91;</span>-<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> + c<span style="color: black;">&#41;</span>,<span style="color: black;">&#41;</span></pre></div></div>


<p>When reading an atom:</p>

<ul>
<li>If the end of the atom has been reached, check if the atom is a number (this code just assumes that if the first character of the atom is numeric, that it&#8217;s a number). If it is, I cheat and use eval to get its value, if it&#8217;s not, I leave the atom as a tuple-wrapped string.</li>
<li>Anything else, add as a character to the atom.</li>
</ul>


<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">        i += <span style="color: #ff4500;">1</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> stack.<span style="color: black;">pop</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>


<p>At the end here, I just take whatever&#8217;s on top of the stack (which should be the only thing on the stack if a proper s-expression was passed in), and return that.</p>

<p>I&#8217;m going to continue working on and improving this parser, for use in another project of mine, so I will be adding more functionality.</p>

<p>I was thinking of doing a s-expression to Python bytecode compiler, but someone already wrote one, and they even took the name I was going to use: <a href="http://pypi.python.org/pypi/sexpy">sexpy</a>.</p>

<p>I think the first thing I&#8217;ll be adding is the capability for the parser to yield sub-sexps so the entire thing doesn&#8217;t need to be parsed in one go before returning anything. Another thing I&#8217;ll most likely add is some checking for invalid sexps, something I left out for clarity in my initial version.</p>

<p>For those who are interested, here&#8217;s the <a href="http://gist.github.com/240957">complete version of sexp.py</a></p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fprobablyprogramming.com%2F2009%2F11%2F23%2Fa-simple-lisp-parser-in-python%2F';
  addthis_title  = 'A+Simple+Lisp+Parser+in+Python';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://probablyprogramming.com/2009/11/23/a-simple-lisp-parser-in-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IE7 Requires type=&#8221;submit&#8221; for &lt;button&gt; elements</title>
		<link>http://probablyprogramming.com/2009/10/30/ie7-requires-typesubmit-for-button-elements/</link>
		<comments>http://probablyprogramming.com/2009/10/30/ie7-requires-typesubmit-for-button-elements/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 23:32:31 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[button]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[nonstandard]]></category>
		<category><![CDATA[type]]></category>

		<guid isPermaLink="false">http://probablyprogramming.com/?p=549</guid>
		<description><![CDATA[If you don&#8217;t specify type=&#8221;submit&#8221; for a &#60;button&#62; element, IE7 (and probably IE6,  too) will do nothing when that button is clicked (well, unless you have an onclick handler on that element, of course).

The W3C HTML standard states that the default for a &#60;button&#62; element should be &#8220;submit&#8221;, but if you want it to [...]]]></description>
			<content:encoded><![CDATA[<p>If you don&#8217;t specify <strong>type=&#8221;submit&#8221;</strong> for a <code>&lt;button&gt;</code> element, IE7 (and probably IE6,  too) <strong>will do nothing</strong> when that button is clicked (well, unless you have an onclick handler on that element, of course).</p>

<p>The <a href="http://www.w3.org/TR/1999/REC-html401-19991224/">W3C HTML standard</a> states that the default for a <code>&lt;button&gt;</code> element should be &#8220;submit&#8221;, but if you want it to work with IE7 or earlier, <strong>you&#8217;ll have to be explicit</strong> about it.</p>

<p>I lost some precious time on this fun bug. I was doing some form validation via the great <a href="http://bassistance.de/jquery-plugins/jquery-plugin-validation/">jQuery Validation plugin</a> and for some reason, the form wasn&#8217;t validation in any IE earlier than IE 8. </p>

<p>Of course, since it&#8217;s such a pain to debug IE, I had a heckuva time figuring out the source of the bug, because I just assumed it was some weird JavaScript quirk, and didn&#8217;t even consider that it could be something as simple as a &#8220;missing&#8221; element attribute.</p>

<p>Ah well. Hopefully this will help somebody else avoid the same problem.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fprobablyprogramming.com%2F2009%2F10%2F30%2Fie7-requires-typesubmit-for-button-elements%2F';
  addthis_title  = 'IE7+Requires+type%3D%26%238221%3Bsubmit%26%238221%3B+for+%26lt%3Bbutton%26gt%3B+elements';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://probablyprogramming.com/2009/10/30/ie7-requires-typesubmit-for-button-elements/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Walking Journal: 45 miles, starting a Twitter client chain</title>
		<link>http://probablyprogramming.com/2009/09/25/starting-a-twitter-client-chain/</link>
		<comments>http://probablyprogramming.com/2009/09/25/starting-a-twitter-client-chain/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 08:37:22 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Walking Journal]]></category>
		<category><![CDATA[chain]]></category>
		<category><![CDATA[continuous deployment]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[twitter client]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://probablyprogramming.com/?p=533</guid>
		<description><![CDATA[I&#8217;ve been neglecting both walking and posting on here, though I&#8217;ve neglected posting more, obviously.

I&#8217;ve been very busy with work and side projects and my house trying to fall apart on me, so I&#8217;ve been out of free time lately.

Anyway, my total is now up to 45 miles of walking. Not too much more than [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been neglecting both walking and posting on here, though I&#8217;ve neglected posting more, obviously.</p>

<p>I&#8217;ve been very busy with work and side projects and my house trying to fall apart on me, so I&#8217;ve been out of free time lately.</p>

<p>Anyway, my total is now up to 45 miles of walking. Not too much more than last time, really. I&#8217;ve gone on some walks around the neighborhood with Angie, and I&#8217;m not counting them, mostly because I don&#8217;t know how long they are, really.</p>

<p>I decided I wanted to start a &#8220;chain,&#8221; where every day I do something to work toward a goal I&#8217;ve set for myself (yes, I mean other than the walking, though that can be a chain as well).</p>

<p>Fortunately enough for me, I found <a href="http://dontbreakthechain.com/">Don&#8217;t Break The Chain</a>, where you can keep track of one or more &#8220;chains&#8221; of things you want to do every day.</p>

<h3>The Twitter Client Chain</h3>

<p>So I&#8217;m creating a web-based Twitter client, as a project for me to try out all the different techniques and technologies that I want to use, but don&#8217;t have the chance to work with as much as I&#8217;d like during my day job. Also, ideally, it will at some point become a supplementary source of income. </p>

<p>That&#8217;s a quite a way off until I have more free time in a month or two, but for now, I will satisfy myself with making some small amount of progress on it each day (hopefully).</p>

<p>I&#8217;m writing this client in Erlang, using the awesome <a href="http://nitrogenproject.com/">Nitrogen web framework</a> with the equally awesome <a href="http://code.google.com/p/mochiweb/">MochiWeb web server</a>. My goals for this project include using <a href="http://c2.com/cgi/wiki?TestDrivenDevelopment">test driven development</a> and <a href="http://timothyfitz.wordpress.com/2009/02/10/continuous-deployment-at-imvu-doing-the-impossible-fifty-times-a-day/">continuous deployment</a> and fully embracing the mantra of <a href="http://www.google.com/search?q=release%20early%2C%20release%20often">&#8220;release early, release often&#8221;</a>.</p>

<p>The plan is to have something up and running on a server as soon as possible. By something, I mean even less than a full-featured twitter client. But as soon as something is up, I can start getting feedback, and see what I should work on next. If I&#8217;m creating a product for users, there&#8217;s no use in developing what I want.</p>

<p>I need to develop what my users want.</p>

<p>I started this chain up about a week ago, and broke it after the first day. Now I&#8217;m trying again.</p>

<h4>Tests and pre-commit hooks</h4>

<p>During my previous, one-day chain, I managed to get a test harness (using the <a href="http://svn.process-one.net/contribs/trunk/eunit/doc/overview-summary.html">EUnit Erlang unit test framework</a>) set up which will find any modules ending with _tests, stopping at the first error.</p>

<p>At the moment, I have a shell script which runs the tests. When it starts to take too long, I will switch over to an Erlang module which loops through, so I don&#8217;t get the startup times of the Erlang interpreter for each test. Or if anyone knows an easier way (perhaps there&#8217;s already a module that does that somewhere?).</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> modfile <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">ls</span> ebin<span style="color: #000000; font-weight: bold;">/*</span>_tests.beam<span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #000000; font-weight: bold;">do</span>
    <span style="color: #007800;">mod</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">basename</span> <span style="color: #007800;">$modfile</span> .beam<span style="color: #000000; font-weight: bold;">`</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> Running <span style="color: #007800;">$mod</span>:
    erl <span style="color: #660033;">-noshell</span> <span style="color: #660033;">-pa</span> .<span style="color: #000000; font-weight: bold;">/</span>ebin <span style="color: #660033;">-s</span> runtest main <span style="color: #800000;">${mod%.*}</span>
    <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$?</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">||</span> <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
<span style="color: #000000; font-weight: bold;">done</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$mod</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">||</span> <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span></pre></div></div>


<p>The runtest module consists of the following:</p>


<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>runtest<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>main<span style="color: #014ea4;">/</span><span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">main</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Mod</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #186895;">case</span> <span style="color: #ff4e18;">eunit</span>:<span style="color: #ff3c00;">test</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Mod</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">of</span>
        error <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff3c00;">halt</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff9600;">1</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
        <span style="color: #45b3e6;">_</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff4e18;">init</span>:<span style="color: #ff3c00;">stop</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">.</span></pre></div></div>


<p>It&#8217;s all kind of thrown together, but the point is incremental improvement, so I&#8217;ll get back to it when/if I need to. Like I said, there&#8217;s probably something else out there that will do a better job at this than I did.</p>

<p>So, today, my &#8220;chain link&#8221; was partially taking that script and setting it up to run from the GIT pre-commit script, and partially writing this blog post.</p>

<p>Getting it set up to run as a pre-commit script just involved making sure it returns non-zero whenever there is a test error (or if no tests were run, which happens when make hasn&#8217;t been run yet).</p>

<p>The pre-commit script itself (placed in .git/hooks/pre-commit and set executable) is pretty simple:</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
.<span style="color: #000000; font-weight: bold;">/</span>tests.sh
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$?</span> <span style="color: #000000; font-weight: bold;">!</span>= <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;====================================&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot; Commit stopped due to test failure&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;====================================&quot;</span>
        <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>


<script src="http://dontbreakthechain.com/share_js/pib/last-four/29377" type="text/javascript" charset="utf-8"></script>

<p>Chain length: 1!</p>

<h4>What&#8217;s next?</h4>

<p>Next up, I&#8217;m acutally going to start on the meat of the project. Since I haven&#8217;t fully decided on what GUI library I want to use, nor what GUI testing framework I want to use, I&#8217;m going to start on the backend with code to manage user login info and queries (timeline searches, DMs, etc.).</p>

<p>I&#8217;ve got some great ideas (I think) on ways to enhance the way people have conversations over Twitter (and eventually other mediums), so you can be sure that there will be more posts about this in the future.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fprobablyprogramming.com%2F2009%2F09%2F25%2Fstarting-a-twitter-client-chain%2F';
  addthis_title  = 'Walking+Journal%3A+45+miles%2C+starting+a+Twitter+client+chain';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://probablyprogramming.com/2009/09/25/starting-a-twitter-client-chain/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Walking Journal: 9 miles, thunderstorm, etc.</title>
		<link>http://probablyprogramming.com/2009/08/27/walking-journal-9-miles-thunderstorm-etc/</link>
		<comments>http://probablyprogramming.com/2009/08/27/walking-journal-9-miles-thunderstorm-etc/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 05:08:45 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[Walking Journal]]></category>
		<category><![CDATA[journal]]></category>
		<category><![CDATA[lightning]]></category>
		<category><![CDATA[thunderstorm]]></category>
		<category><![CDATA[walking]]></category>

		<guid isPermaLink="false">http://probablyprogramming.com/?p=526</guid>
		<description><![CDATA[

I walked at least 4 miles today. I&#8217;m not sure if I got too far over that, though, because a thunderstorm came through and killed the power before I could look at the exact amount on the treadmill. The last time I looked it was 4, so I&#8217;ll count it as that.

Thunderstorm

I was excited when [...]]]></description>
			<content:encoded><![CDATA[<p><a class="postimage" href="http://physicsdiet.com/Public.aspx?u=pib"><img src="http://probablyprogramming.com/wp-content/uploads/2009/08/weight-2009-08-26-2-300x225.png" alt="weight-2009-08-26-2" title="weight-2009-08-26-2" width="300" height="225" class="aligncenter size-medium wp-image-527" /></a></p>

<p>I walked at least 4 miles today. I&#8217;m not sure if I got too far over that, though, because a thunderstorm came through and killed the power before I could look at the exact amount on the treadmill. The last time I looked it was 4, so I&#8217;ll count it as that.</p>

<h3>Thunderstorm</h3>

<p>I was excited when I first saw the clouds rolling in, because we haven&#8217;t gotten a good rain for <em>months</em> now, and our lawn (as I mentioned in my last entry) is getting pretty brown.</p>

<p>However, when lightning started striking across the street from me, I started to get a little worried. That, and the fact that my wall-mounted monitor was swaying back and forth. Fun fact: speakers make a nice crackly noise when lighting strikes close by.</p>

<p>I don&#8217;t think I&#8217;d seen lightning strike before. It was quite a sight to see. A bright flash, then a sort of green glow and a halo of sparks that drifted slowly away from the strike point. And it happened in the same place, three times in a row, a few minutes in between. &#8220;Never strikes the same place twice&#8221; my ass!</p>

<p>After the storm had passed, we went outside to see how bad the damage was. Our South and street facing section of fence had been blown over into our yard, all of the fence posts simply snapped off. It takes a pretty strong wind to break a healthy 4&#215;4, I think. We also lost the corrugated plastic roofing over half our back patio, and worst of all, the planter box with my ginger plants in it got blown over! Three out of four of the plants seem to be okay, but one of them got snapped off at the base of the stalk. We also found some roofing shingles in the back yard, so we&#8217;ll probably need to take a look at the roof when it&#8217;s light outside.</p>

<p>We were lucky compared to some neighbors. One guy down the street got a huge tree (somewhere around 3 feet in diameter) through the roof of his station wagon, and partway through his PT Cruiser (it hit the station wagon first, so that took the brunt of the damage). He seemed in relatively good spirits despite the damage, telling us that he was going to  convert the station wagon into some sort of el Camino-type thing by cutting the damaged back half of the roof off. Perhaps all the beer he and his friend were drinking was helping him to stay in a good mood about it.</p>

<h3>500 languages slowdown</h3>

<p>I&#8217;ve been very busy with work and personal projects recently, and so I haven&#8217;t had much time for the 500 programming language project. I started learning about <a href="http://programming.nu/">Nu, a lispy, interpreted, object-oriented language built in objective-c</a>. I got the interpreter compiled and working on my 64-bit Ubuntu machine, which took more work than I would have liked due to the fact that most of the development of Nu takes place on Macs. Anyway, there&#8217;s a <a href="http://github.com/timburks/nunja/tree/master">webserver for Nu, called Nunja</a> and a <a href="http://github.com/timburks/numarkdown/tree/master">Nu markdown processor</a>, so I was thinking I&#8217;d write a simple blog engine as my Nu program. Nu is looking like a really interesting programming language so far, so it might be one I come back and spend some more time on.</p>

<p>But as I was saying, I haven&#8217;t had as much free time lately, so the posts have slowed down. Don&#8217;t let that fool you, though. I haven&#8217;t given up on the challenge, I&#8217;ve just accepted that it might be a while before I can be pumping out 5 languages a week. And it might, in fact, take me more than the 2 years I was originally thinking (dreaming) that it would take.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fprobablyprogramming.com%2F2009%2F08%2F27%2Fwalking-journal-9-miles-thunderstorm-etc%2F';
  addthis_title  = 'Walking+Journal%3A+9+miles%2C+thunderstorm%2C+etc.';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://probablyprogramming.com/2009/08/27/walking-journal-9-miles-thunderstorm-etc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Walking Journal: 5 Miles</title>
		<link>http://probablyprogramming.com/2009/08/26/walking-journal-5-miles/</link>
		<comments>http://probablyprogramming.com/2009/08/26/walking-journal-5-miles/#comments</comments>
		<pubDate>Wed, 26 Aug 2009 06:48:21 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[Walking Journal]]></category>
		<category><![CDATA[journal]]></category>
		<category><![CDATA[schoolchildren]]></category>
		<category><![CDATA[teeth]]></category>
		<category><![CDATA[walking]]></category>

		<guid isPermaLink="false">http://probablyprogramming.com/?p=515</guid>
		<description><![CDATA[

I&#8217;m starting a walking journal, to keep track of how far I walk each
day, and to give me something to post about more frequently. Despite
the fact that most of my posts on here are Probably about Programming,
this is still, in fact, a personal blog, so I think posting personal
things on here pretty much makes sense [...]]]></description>
			<content:encoded><![CDATA[<p><a class="postimage" href="http://probablyprogramming.com/wp-content/uploads/2009/08/weight-2009-08-26.png"><img src="http://probablyprogramming.com/wp-content/uploads/2009/08/weight-2009-08-26-300x225.png" alt="weight-2009-08-26" title="weight-2009-08-26" width="300" height="225" class="aligncenter size-medium wp-image-519" /></a></p>

<p>I&#8217;m starting a walking journal, to keep track of how far I walk each
day, and to give me something to post about more frequently. Despite
the fact that most of my posts on here are Probably about Programming,
this is still, in fact, a personal blog, so I think posting personal
things on here pretty much makes sense to me.</p>

<p>I&#8217;ll also use the walking journal as an actual journal, to talk about things other than walking. I can justify this by noting that I will, most likely be writing a lot of the journal while walking, so the name still works. I wrote most of this one while walking, so it works!</p>

<h3>Walking journal</h3>

<p>I&#8217;ve walked 5 miles since deciding to start this morning, so that&#8217;s a good start, I suppose.</p>

<p>Perhaps I&#8217;ll do a <a href="http://100milestoachumby.blogspot.com/"><del>100</del>200 miles to a chumby</a>-style thing with this. Though
I have an advantage with <a href="http://www.flickr.com/photos/pib/2893071653/">my walking desk</a>, because I can walk and be
working at the same time. If I walked during my entire workday, I&#8217;d be
able to get 16 or so miles a day without a problem, and I&#8217;d have 100
miles in no time <img src='http://probablyprogramming.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> , so maybe I&#8217;ll make my goal about losing weight
instead of a specific distance. 20 pounds to a <a href="http://openpandora.org">Pandora</a>?</p>

<p>I&#8217;ve redoubled my efforts at weight loss, and I&#8217;ve started both walking daily and tracking my weight again.</p>

<p>You can join in on the fun and track my progress on <a href="http://physicsdiet.com/Public.aspx?u=pib">my Physics Diet profile</a></p>

<p>It looks like I&#8217;ve been slowly on an upward gain, but it&#8217;s just because I weighed myself before dinner, rather than before breakfast as I always did before, and it filled in the blanks since February, since I haven&#8217;t weighed myself since then. I&#8217;ve actually been holding pretty steady in weight, I think, so it&#8217;ll be good to break through this plateau and get my weight lower.</p>

<h3>School&#8217;s started again in Round Rock</h3>

<p>School is back in session. I guess no more sleeping in since the
children gather outside our bedroom window in the morning to wait for
the bus.</p>

<p>On the plus side, I can once again go out on my front lawn in a bathrobe and yell at those &#8220;damn kids&#8221; to &#8220;get off my lawn!&#8221;</p>

<p>I could have done that during the summer, but I would have looked a little silly when all that was out there was dead grass.</p>

<h3>Teeth are expensive</h3>

<p>I had a 9am (super early for me) dentist appointment today to get an
impression for a crown taken. Good god these teeth are costing me a
lot of money. </p>

<p>I&#8217;ve used up all my COBRA dental insurance from my last
job, and from what I hear it&#8217;s nearly impossible to get private dental
insurance, so it&#8217;s going to all be out-of-pocket from now on. </p>

<p>Since
with my current job I&#8217;m technically a &#8220;private contractor,&#8221; because
they have no offices in the US, they are just paying me what would
cover insurance (though it might not cover personal insurance after my
COBRA is over). </p>

<p>Perhaps the way to go is really personal insurance in
the sense that I will put away that same money every month in case of
medical emergency.</p>

<p>Or I could just have all my teeth removed and switch to an all-liquid diet. I&#8217;m sure Angie would love having a toothless 25-year-old husband. For sure.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fprobablyprogramming.com%2F2009%2F08%2F26%2Fwalking-journal-5-miles%2F';
  addthis_title  = 'Walking+Journal%3A+5+Miles';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://probablyprogramming.com/2009/08/26/walking-journal-5-miles/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Live List of the Most Popular Twitter Clients</title>
		<link>http://probablyprogramming.com/2009/08/21/live-list-of-the-most-popular-twitter-clients/</link>
		<comments>http://probablyprogramming.com/2009/08/21/live-list-of-the-most-popular-twitter-clients/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 14:36:06 +0000</pubDate>
		<dc:creator>pib</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://probablyprogramming.com/?p=510</guid>
		<description><![CDATA[I just put up a live list of the most popular Twitter clients. The contents of that page are updated every 60 seconds (the length of time twitter caches their public timeline).

For some reason I woke up at 7 this morning, unable to get back to sleep, and I was randomly wondering how many Twitter [...]]]></description>
			<content:encoded><![CDATA[<p>I just put up a <a href="http://probablyprogramming.com/twitter_clients.html">live list of the most popular Twitter clients</a>. The contents of that page are updated every 60 seconds (the length of time twitter caches their public timeline).</p>

<p>For some reason I woke up at 7 this morning, unable to get back to sleep, and I was randomly wondering how many Twitter clients were out there, and which were the most popular. So I decided to find out.</p>

<p>After a bit of hacking around, I came up with the following Python script:</p>


<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">urllib</span> <span style="color: #ff7700;font-weight:bold;">import</span> urlopen
<span style="color: #ff7700;font-weight:bold;">from</span> contextlib <span style="color: #ff7700;font-weight:bold;">import</span> closing
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">pickle</span>
<span style="color: #ff7700;font-weight:bold;">import</span> json
&nbsp;
<span style="color: #ff7700;font-weight:bold;">try</span>:
    clientlist = <span style="color: #dc143c;">pickle</span>.<span style="color: black;">load</span><span style="color: black;">&#40;</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'clientlist.pickle'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">except</span>:
    clientlist = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">with</span> closing<span style="color: black;">&#40;</span>urlopen<span style="color: black;">&#40;</span><span style="color: #483d8b;">'http://twitter.com/statuses/public_timeline.json'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">as</span> f:
    json_str = f.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
tweets = json.<span style="color: black;">loads</span><span style="color: black;">&#40;</span>json_str<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> tweet <span style="color: #ff7700;font-weight:bold;">in</span> tweets:
    source = tweet<span style="color: black;">&#91;</span><span style="color: #483d8b;">'source'</span><span style="color: black;">&#93;</span>
    clientlist<span style="color: black;">&#91;</span>source<span style="color: black;">&#93;</span> = clientlist.<span style="color: black;">get</span><span style="color: black;">&#40;</span>source, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span> + <span style="color: #ff4500;">1</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">with</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'clientlist.pickle'</span>, <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">as</span> f:
    <span style="color: #dc143c;">pickle</span>.<span style="color: black;">dump</span><span style="color: black;">&#40;</span>clientlist, f<span style="color: black;">&#41;</span>
&nbsp;
total = <span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">for</span> count <span style="color: #ff7700;font-weight:bold;">in</span> clientlist.<span style="color: black;">itervalues</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    total += count
&nbsp;
<span style="color: #ff7700;font-weight:bold;">with</span> <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'clientlist.html'</span>, <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">as</span> f:
    f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&lt;html&gt;&lt;head&gt;&lt;title&gt;Twitter Client list&lt;/title&gt;&lt;/head&gt;&lt;body&gt;'</span><span style="color: black;">&#41;</span>
    f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'&lt;h1&gt;Twitter Client Popularity&lt;/h1&gt;'</span>,
                     <span style="color: #483d8b;">'&lt;div style=&quot;float: left; margin-right: 20px;&quot;&gt;Out of &lt;em&gt;'</span>, <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>total<span style="color: black;">&#41;</span>, 
                     <span style="color: #483d8b;">'&lt;/em&gt; Twitter messages, the following were the clients used.'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Client&lt;/th&gt;&lt;th&gt;Tweet Count&lt;/th&gt;&lt;th&gt;% of total&lt;/th&gt;&lt;/thead&gt;&lt;tbody&gt;'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: black;">&#40;</span>link, count<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">sorted</span><span style="color: black;">&#40;</span>clientlist.<span style="color: black;">iteritems</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, key=<span style="color: #ff7700;font-weight:bold;">lambda</span> item: item<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, reverse=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>:
        f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'&lt;tr&gt;&lt;td&gt;'</span>, link, <span style="color: #483d8b;">'&lt;/td&gt;&lt;td&gt;'</span>, <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>count<span style="color: black;">&#41;</span>, <span style="color: #483d8b;">'&lt;/td&gt;&lt;td&gt;'</span>, 
                         <span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #008000;">round</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">100.0</span> <span style="color: #66cc66;">*</span> count / total, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">'&lt;/td&gt;'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;'</span><span style="color: black;">&#41;</span>
&nbsp;
    f.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&lt;/body&gt;&lt;/html&gt;'</span><span style="color: black;">&#41;</span></pre></div></div>


<p>The script writes out a pickle file with the list of counts for each client, so multiple runs will generate a cumulative result (don&#8217;t run it more than once every 60 seconds, or you will add the same results in more than once). </p>

<p>It then writes out an .html file with a nice sorted list of the most common Twitter clients (well, all the twitter clients it&#8217;s seen, sorted by most common first).</p>

<p>I&#8217;ve set up a cron job on this server to update the file linked to above every minute, so as time goes on the list will become a more and more accurate representation of what people are using to tweet.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fprobablyprogramming.com%2F2009%2F08%2F21%2Flive-list-of-the-most-popular-twitter-clients%2F';
  addthis_title  = 'Live+List+of+the+Most+Popular+Twitter+Clients';
  addthis_pub    = 'misterpib';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://probablyprogramming.com/2009/08/21/live-list-of-the-most-popular-twitter-clients/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
