<?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>Wyatt Baldwin</title>
	<atom:link href="http://wyattbaldwin.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://wyattbaldwin.com</link>
	<description></description>
	<lastBuildDate>Wed, 11 Jan 2012 16:28:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>What I Learned from the apache.org Break-in</title>
		<link>http://wyattbaldwin.com/2010/04/14/what-i-learned-from-the-apache-org-break-in/</link>
		<comments>http://wyattbaldwin.com/2010/04/14/what-i-learned-from-the-apache-org-break-in/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 17:01:31 +0000</pubDate>
		<dc:creator>Wyatt</dc:creator>
				<category><![CDATA[planet python]]></category>

		<guid isPermaLink="false">http://wyattbaldwin.com/?p=409</guid>
		<description><![CDATA[Here&#8217;s my initial take-away after reading about the recent apache.org XSS-initiated break-in: If you&#8217;re going to allow caching of credentials (Subversion or otherwise) on a server, don&#8217;t use an account that shares credentials with any superuser account. Personally, I can&#8217;t &#8230; <a href="http://wyattbaldwin.com/2010/04/14/what-i-learned-from-the-apache-org-break-in/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s my initial take-away after reading about the recent apache.org XSS-initiated break-in:</p>
<ul>
<li>If you&#8217;re going to allow caching of credentials (Subversion or otherwise) on a server, don&#8217;t use an account that shares credentials with any superuser account. Personally, I can&#8217;t think of a good reason for these credentials to be cached in the first place (except on a development machine). As an aside, by default, Mercurial doesn&#8217;t do this; I suppose the fact that every &#8216;svn commit&#8217; is also a push makes this more &#8220;necessary&#8221; with Subversion.</li>
<li>If you have an organization-wide login (say a Windows login that is automatically sync&#8217;ed with Subversion, your enterprise RDBMS, and who knows what else[1]), <span style="text-decoration: line-through;">if at all possible</span> use a different  password on any server where you&#8217;ve got superuser access.</li>
<li>All superuser accounts on servers should have different passwords; at a minimum, if you use a common password for superuser accounts across servers, don&#8217;t use this password for other accounts.</li>
<li>Use Trac instead of Jira. [2]</li>
</ul>
<p>That&#8217;s a bare minimum; I&#8217;m still thinking about how vulnerable the organization I work for might be. Most of this probably seems obvious, but I&#8217;m betting that these and other less-than-best practices are extremely common.</p>
<p>&#8211;</p>
<p>Ref: <a title="Official Apache blog post about break-in" href="https://blogs.apache.org/infra/entry/apache_org_04_09_2010">https://blogs.apache.org/infra/entry/apache_org_04_09_2010</a></p>
<p>[1] This is a purely hypothetical scenario. <img src='http://wyattbaldwin.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>[2] Just kidding?</p>
]]></content:encoded>
			<wfw:commentRss>http://wyattbaldwin.com/2010/04/14/what-i-learned-from-the-apache-org-break-in/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eclipse for Python Web Development on Ubuntu</title>
		<link>http://wyattbaldwin.com/2009/06/29/eclipse-for-python-web-development-on-ubuntu/</link>
		<comments>http://wyattbaldwin.com/2009/06/29/eclipse-for-python-web-development-on-ubuntu/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 19:52:07 +0000</pubDate>
		<dc:creator>Wyatt</dc:creator>
				<category><![CDATA[planet python]]></category>

		<guid isPermaLink="false">http://wyattbaldwin.com/?p=308</guid>
		<description><![CDATA[Updated 14 July 2009 for Eclipse 3.5. Now using Aptana to install PyDev. Updated 5 March 2010 for Eclipse 3.5.2 and Subversion 1.6. Updated 20 July 2010 for Eclipse 3.6 Updated 1 August 2011 for Eclipse 3.7 and Aptana Studio &#8230; <a href="http://wyattbaldwin.com/2009/06/29/eclipse-for-python-web-development-on-ubuntu/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>Updated 14 July 2009 for Eclipse 3.5. Now using Aptana to install PyDev.</em></p>
<p><em>Updated 5 March 2010 for Eclipse 3.5.2 and Subversion 1.6.</em></p>
<p><em>Updated 20 July 2010 for Eclipse 3.6</em></p>
<p><em>Updated 1 August 2011 for Eclipse 3.7 and Aptana Studio 3<br />
</em></p>
<p><strong>Overview</strong></p>
<p>So, I think I&#8217;ve finally decided that I prefer Eclipse for Python Web development over NetBeans. (I prefer Wing IDE over both for straight Python development, but that&#8217;s another post.) Eclipse&#8217;s Python support, via PyDev, seems more advanced and NetBeans has some annoying issues. Eclipse also seems a bit snappier, at least on my machine (YMMV, blah blah).</p>
<p>Eclipse takes a bit more effort to set up, but once you&#8217;ve done it a couple times, it&#8217;s pretty straightforward. The hard part is keeping track of the links to the Eclipse update sites and remembering a few odd bits of configuration. This document gives details on installing Eclipse for Python Web development with Aptana, PyDev, and Subclipse.</p>
<p>The instructions here are Linux/Ubuntu-centric, but the instructions for getting to the Platform Binary&#8211;the smallest possible Eclipse download, as far as I can tell&#8211;are applicable to all platforms.</p>
<p><strong>Download Eclipse</strong></p>
<p>If you go to the Eclipse downloads page, you&#8217;ll see packages for Java and C++ along with some other options. If you&#8217;re doing ONLY Python development, you might wonder which version to download. These versions install cruft I don&#8217;t want or need. I finally found what I think is the smallest possible Eclipse package, the so-called Platform Runtime Library.</p>
<ul>
<li>Start here: <a title="Eclipse downloads" href="http://download.eclipse.org/eclipse/downloads/">eclipse project downloads</a>.</li>
<li>Find the Latest Release under Build Type in the Latest Downloads section and click the <a title="Eclipse 3.7 downloads" href="http://download.eclipse.org/eclipse/downloads/drops/R-3.7-201106131736/index.php">3.7 link</a> under Build Name.</li>
<li>Click <a title="Eclipse platform binary" href="http://download.eclipse.org/eclipse/downloads/drops/R-3.7-201106131736/index.php#PlatformRuntime">Platform Runtime Binary</a> in the left hand menu.</li>
<li>Choose for your OS by clicking one of the (http) links in the Download column; I chose <a href="http://download.eclipse.org/eclipse/downloads/drops/R-3.7-201106131736/download.php?dropFile=eclipse-platform-3.7-linux-gtk.tar.gz">Linux (x86/GTK 2)</a> for 32 bit Linux. Here&#8217;s the 64 bit version: <a href="http://download.eclipse.org/eclipse/downloads/drops/R-3.7-201106131736/download.php?dropFile=eclipse-platform-3.7-linux-gtk-x86_64.tar.gz">Linux (x86_64/GTK 2)</a>.</li>
<li>You still need to pick a mirror! I use the <a href="http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.7-201106131736/eclipse-platform-3.7-linux-gtk.tar.gz&amp;url=http://ftp.osuosl.org/pub/eclipse/eclipse/downloads/drops/R-3.7-201106131736/eclipse-platform-3.7-linux-gtk.tar.gz&amp;mirror_id=272">OSU Open Source Lab</a> link because it&#8217;s close to me and fast.</li>
<li>And finally, the download begins&#8230;</li>
</ul>
<p><strong>Install Eclipse</strong></p>
<p>Extract the downloaded package: <code>tar xvzf eclipse-platform-3.7-linux-gtk.tar.gz</code>. I rename the resulting eclipse directory to eclipse-3.6, move it to ~/.local,  and create a symlink in ~/.local/bin to the eclipse executable: <code>ln -s ~/.local/eclipse-3.7/eclipse ~/.local/bin/eclipse</code></p>
<p><strong>Configure Eclipse</strong></p>
<p>Edit ~/.local/eclipse-3.7/eclipse.ini. Find the line containing &#8220;-vmargs&#8221;. Add a new line directly below that: <code>-Djava.library.path=/usr/lib/jni</code>. Save and close. Fire up Eclipse.</p>
<p><strong>Install Aptana Studio<br />
</strong></p>
<ul>
<li>Help &gt; Install New Software&#8230; &gt; Add
<ul>
<li>Eclipse update URL: <a href="http://download.aptana.com/studio3/plugin/install">http://download.aptana.com/studio3/plugin/install</a></li>
</ul>
</li>
<li>Click OK, click the Aptana Studio checkbox, click Next, click Finish, wait&#8230;, click Yes to restart Eclipse</li>
</ul>
<p><strong>Install PyDev</strong></p>
<p>PyDev is installed as part of the Apatana Studio install.</p>
<p><strong>Install MercurialEclipse</strong></p>
<p>Eclipse update URL: <a href="http://cbes.javaforge.com/update">http://cbes.javaforge.com/update</a></p>
<p><strong>Install Subclipse</strong></p>
<p>Prerequisite: <code>sudo apt-get install libsvn-java</code></p>
<p>Eclipse update URL: <a href="http://subclipse.tigris.org/update_1.6.x">http://subclipse.tigris.org/update_1.6.x</a> (select all required items under Subclipse checkbox)</p>
]]></content:encoded>
			<wfw:commentRss>http://wyattbaldwin.com/2009/06/29/eclipse-for-python-web-development-on-ubuntu/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Supervisor now supports Python 2.6</title>
		<link>http://wyattbaldwin.com/2009/05/26/supervisor-now-supports-python-26/</link>
		<comments>http://wyattbaldwin.com/2009/05/26/supervisor-now-supports-python-26/#comments</comments>
		<pubDate>Tue, 26 May 2009 18:26:24 +0000</pubDate>
		<dc:creator>Wyatt</dc:creator>
				<category><![CDATA[planet python]]></category>

		<guid isPermaLink="false">http://wyattbaldwin.com/?p=317</guid>
		<description><![CDATA[I&#8217;ve been using Supervisor for a few months now to manage some app servers at work. Good stuff; solid. My only gripe with it was that it didn&#8217;t run properly under Python 2.6[1,2]. I had to install Python 2.5 just &#8230; <a href="http://wyattbaldwin.com/2009/05/26/supervisor-now-supports-python-26/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using Supervisor for a few months now to manage some app servers at <a href="http://trimet.org/">work</a>. Good stuff; solid. My only gripe with it was that it didn&#8217;t run properly under Python 2.6[1,2]. I had to install Python 2.5 just to run Supervisor, which isn&#8217;t a super big deal but is kind of annoying. The latest release, 3.0a7, fixes this by including a &#8220;patched version of Medusa to allow Supervisor to run on Python 2.6.&#8221;</p>
<p>Note: I had to <code>`wget http://dist.supervisord.org/supervisor-3.0a7.tar.gz`</code> and easy_install that due to a network timeout[3]. I assume that&#8217;s because Supervisor is super popular and everyone&#8217;s upgrading.</p>
<p>[1] It did run under 2.6 but issued an error when starting up.<br />
[2] This was due to changes in the Python 2.6 stdlib, not a problem with Supervisor itself.<br />
[3] Suggestion: If possible, remove link from PyPI to http://supervisord.org/ so easy_install doesn&#8217;t get stuck there.</p>
]]></content:encoded>
			<wfw:commentRss>http://wyattbaldwin.com/2009/05/26/supervisor-now-supports-python-26/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Implementation of Dijkstra&#8217;s Single-Source Shortest-Paths in JavaScript</title>
		<link>http://wyattbaldwin.com/2008/08/19/implementation-of-dijkstras-single-source-shortest-paths-in-javascript/</link>
		<comments>http://wyattbaldwin.com/2008/08/19/implementation-of-dijkstras-single-source-shortest-paths-in-javascript/#comments</comments>
		<pubDate>Tue, 19 Aug 2008 23:52:03 +0000</pubDate>
		<dc:creator>Wyatt</dc:creator>
				<category><![CDATA[planet python]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[dijkstra]]></category>
		<category><![CDATA[geek-fun]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://wyattbaldwin.com/?p=223</guid>
		<description><![CDATA[I&#8217;m working on a project where the client wants a cool sliding navigation effect. We&#8217;re implementing this with JavaScript/AJAX/DHTML. One of the constraints is that pages can only be reached via certain other pages. For example, if you&#8217;re on the &#8230; <a href="http://wyattbaldwin.com/2008/08/19/implementation-of-dijkstras-single-source-shortest-paths-in-javascript/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on a project where the client wants a cool sliding navigation effect. We&#8217;re implementing this with JavaScript/AJAX/DHTML.</p>
<p>One of the constraints is that pages can only be reached via certain other pages. For example, if you&#8217;re on the /portland/contact page and want to go to the /seattle/contact page, you&#8217;ll first slide up to /portland, then over to /seattle, then finally down to /seattle/contact.</p>
<p>After a while, it occurred to me that there were some similarities with another project I&#8217;ve been working on off and on for the last few years, <a href="http://bycycle.org/">byCycle.org</a>, which is a bicycle trip planner a la Google Maps.</p>
<p>I had written a Python version of Dijkstra&#8217;s Single-Source Shortest-Paths (SSSP) for <a href="http://bycycle.org/">byCycle.org</a>. That&#8217;s available on <a title="Dijkstar on Bitbucket" href="https://bitbucket.org/wyatt/dijkstar">Bitbucket as Dijkstar</a> (so named because it also <span style="text-decoration: line-through;">does</span> has the potential to do A*). I figured it wouldn&#8217;t be too hard to port the Python version to JavaScript, and it wasn&#8217;t.</p>
<p>There were a few snags, though. Most of it was just syntactic and semantic differences between the two languages. The biggest issue was that I use &#8220;heapq&#8220; in the Python version to maintain the costs to previously visited nodes in sorted order. JavaScript has no priority queue implementation that I could find, so I came up with a different solution that involves updating an Object (AKA hash) with costs to newly visited nodes and sorting the keys to pick the next node to visit. I&#8217;m assuming/hoping the underlying sort implementation is highly optimized.</p>
<p>Interestingly, I think I found at least one bug in the Python version, although I&#8217;ve been using that version for a couple years now with no known problems, so it must only be applicable in certain edge (no pun intended) cases (or maybe it&#8217;s due to some difference in the languages&#8211;need to take a closer look). I think the JS version came out cleaner, too.</p>
<p>If anyone&#8217;s interested, I&#8217;m releasing this under an MIT license. You can <a title="Dijkstra in JavaScript on Bitbucket" href="https://bitbucket.org/wyatt/dijkstra.js">get it from here</a>. <del>Note that it depends on the util module that you can <a title="Namespaces and classes in JavaScript" href="http://wyattbaldwin.com/code/util.js">get from here</a>. The util module contains some other Python-inspired JavaScript, in particular a couple of functions for generating namespaces and classes. I might write another post about that at some point.</del></p>
]]></content:encoded>
			<wfw:commentRss>http://wyattbaldwin.com/2008/08/19/implementation-of-dijkstras-single-source-shortest-paths-in-javascript/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>YUI TreeView with Ruby on Rails</title>
		<link>http://wyattbaldwin.com/2008/05/26/yui-treeview-with-ruby-on-rails/</link>
		<comments>http://wyattbaldwin.com/2008/05/26/yui-treeview-with-ruby-on-rails/#comments</comments>
		<pubDate>Tue, 27 May 2008 03:48:07 +0000</pubDate>
		<dc:creator>Wyatt</dc:creator>
				<category><![CDATA[dev]]></category>
		<category><![CDATA[acts_as_tree]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[yui]]></category>

		<guid isPermaLink="false">http://wyattbaldwin.com/?p=184</guid>
		<description><![CDATA[Here&#8217;s some code I&#8217;m using to generate a dynamic tree view using an acts_as_tree model with slug and title fields, the TreeView widget from YUI, and a Rails helper. I chopped out some of the code for clarity, so all &#8230; <a href="http://wyattbaldwin.com/2008/05/26/yui-treeview-with-ruby-on-rails/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s some code I&#8217;m using to generate a dynamic tree view using an acts_as_tree model with slug and title fields, the TreeView widget from YUI, and a Rails helper. I chopped out some of the code for clarity, so all this does is create a menu with the titles from the model, but the basic idea is there to expand on.</p>
<p><strong>Rails view/JavaScript</strong></p>
<pre>&lt;script type="text/javascript"&gt;
  var page_tree;
  page_tree_init = function () {
    page_tree = new YAHOO.widget.TreeView('page_tree');
    var root = page_tree.getRoot();
    &lt;% generate_page_nodes(@root) {} %&gt;
    page_tree.draw();
  };
  page_tree_init();
&lt;/script&gt;
</pre>
<p><strong>Ruby</strong></p>
<pre>def generate_page_nodes(node, &amp;block)
  parent = node.parent
  node_name = node.slug.gsub('-', '_')
  parent_node_name = parent.nil? ? 'root' : parent.slug.gsub('-', '_')
  js = &lt;&lt;-JS
    var #{node_name} = new YAHOO.widget.MenuNode('&lt;span class="node_title"&gt;#{node.title}&lt;/span&gt;',
                                                 #{parent_node_name});
  JS
  concat(js, block.binding)
  children = node.children
  children.each { |c| generate_page_nodes(c, &amp;block) } unless children.empty?
end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://wyattbaldwin.com/2008/05/26/yui-treeview-with-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Ruby on Rails&#8230; Revisited</title>
		<link>http://wyattbaldwin.com/2008/04/04/ruby-on-rails-revisited/</link>
		<comments>http://wyattbaldwin.com/2008/04/04/ruby-on-rails-revisited/#comments</comments>
		<pubDate>Sat, 05 Apr 2008 03:54:56 +0000</pubDate>
		<dc:creator>Wyatt</dc:creator>
				<category><![CDATA[dev]]></category>
		<category><![CDATA[planet python]]></category>
		<category><![CDATA[comparisons]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[grok]]></category>
		<category><![CDATA[pylons]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[web frameworks]]></category>
		<category><![CDATA[zope 3]]></category>

		<guid isPermaLink="false">http://wyattbaldwin.com/?p=130</guid>
		<description><![CDATA[Updated with links and a couple typo corrections. Update: It wasn&#8217;t long before the project got too complex on the back end (SOAP blech) for my limited Ruby knowledge. I switched it back to Python/Pylons and never looked back. The &#8230; <a href="http://wyattbaldwin.com/2008/04/04/ruby-on-rails-revisited/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>Updated with links and a couple typo corrections.</em></p>
<p><em>Update: It wasn&#8217;t long before the project got too complex on the back end</em><em> (SOAP blech) </em><em>for my limited Ruby knowledge. I switched it back to Python/<a title="Pylons Python Web Framework" href="http://pylonshq.com/">Pylons</a> and never looked back. The </em><em><a title="Pylons Python Web Framework" href="http://pylonshq.com/">Pylons</a></em><em> =&gt; Rails migration was straightforward. I guess I could have pushed through with Ruby/Rails, but with deadlines looming, it made more sense for me to go with what I knew best. Being familiar Python and its ecosystem was far more pertinent than the deficiency of any particular library. There&#8217;s probably another blog post or two in here&#8230;<br />
</em></p>
<p>I&#8217;ve been working on a fairly big Web site project lately. My partner and I initially decided to use <a title="Django Python Web Framework" href="http://www.djangoproject.com/">Django</a> to build the site, mainly because I&#8217;m a <a title="Python programming language" href="http://python.org/">Python</a> &#8220;expert&#8221; and Django is (apparently) the #1 Python Web framework. We were also lured by the easy admin interface.</p>
<p>After trying to use Django and not really enjoying it, I tried switching to <a title="Pylons Python Web Framework" href="http://pylonshq.com/">Pylons</a> because I&#8217;ve had a good amount of experience with it in the building of <a title="byCycle bicycle trip planner / route finder" href="http://bycycle.org/">byCycle.org</a>. It&#8217;s gone through two fairly major releases since then, and so have a bunch of the libraries that tend to get used with it, like <a title="SQLAlchemy Python database library" href="http://sqlalchemy.org/">SQLAlchemy</a>, <a title="Elixir Python Active Record library" href="http://elixir.ematia.de/trac/wiki">Elixir</a>, etc.</p>
<p>I was having a hard time with the Pylons docs, and so I ended screwing around with <a title="Grok Python Web framework" href="http://grok.zope.org/">Grok</a> (which actually looks fairly interesting) and even took a look at the <a title="Zope 3 Python Web framework" href="http://wiki.zope.org/zope3/Zope3Wiki">Zope 3</a> site. I&#8217;m sure Zope is really awesome or whatever, but it might as well suck. Every time I look at that site, I&#8217;m just like &#8220;WTF! This shit has been around for like five years!&#8221; Anyway, I might just not be smart enough for Zope.</p>
<p>This led us back toward Rails (even if <a title="Rails is a ghetto?" href="http://www.zedshaw.com/rants/rails_is_a_ghetto.html">it is a ghetto</a>). I used Rails a bit last year but never did anything too serious with it. Diving into it today was quite a pleasure. There are issues to be sure, but overall I&#8217;m enjoying it <em>by far</em> over any of the other options we had tried. I&#8217;m also enjoying learning/relearning Ruby.</p>
<p>If Pylons had good docs, we&#8217;d probably be using that.</p>
<p>So, I don&#8217;t know if this is a particularly useful post, since I didn&#8217;t get into much in the way of reasons (what, i have back this up?!). This subject&#8217;s been hashed and rehashed, but I just wanted (<em>needed</em>) to make a qualitative statement about my/our experience, which, of course, is purely personal.</p>
]]></content:encoded>
			<wfw:commentRss>http://wyattbaldwin.com/2008/04/04/ruby-on-rails-revisited/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Erlang Linked List Exercise</title>
		<link>http://wyattbaldwin.com/2007/08/07/erlang-linked-list-exercise/</link>
		<comments>http://wyattbaldwin.com/2007/08/07/erlang-linked-list-exercise/#comments</comments>
		<pubDate>Tue, 07 Aug 2007 22:04:39 +0000</pubDate>
		<dc:creator>Wyatt</dc:creator>
				<category><![CDATA[planet python]]></category>
		<category><![CDATA[adt]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://wyattbaldwin.com/2007/08/07/erlang-linked-list-exercise/</guid>
		<description><![CDATA[Yesterday, my copy of Programming Erlang arrived in the mail1. w00t! I’m already part way through chapter three. I don’t know what it is about this language – maybe it’s all hype and a passing fad – but I haven’t &#8230; <a href="http://wyattbaldwin.com/2007/08/07/erlang-linked-list-exercise/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Yesterday, my copy of <a href="http://www.pragmaticprogrammer.com/titles/jaerlang/">Programming Erlang</a> arrived in the mail<sup><a href="#fn1">1</a></sup>. w00t! I’m already part way through chapter three. I don’t know what it is about <a href="http://erlang.org/">this language</a> – maybe it’s all hype and a passing fad – but I haven’t been this interested in learning a new language since I started with Python over two and half years ago.</p>
<p>The day before yesterday, I took a shot at implementing a linked list in Erlang. I had one basic rule, which was that I wasn’t allowed to use the built in list type. Getting started was fairly difficult, but once I started to “get it” (e.g., pattern matching, recursion), the task got much easier.</p>
<p>Previously, I had only played around in the shell, so this is the first Erlang module I’ve written. Erlang modules are similar to Python modules, though to make functions available outside an Erlang module, they must be explicitly exported. I haven’t yet come across whether Erlang modules can be organized into packages, although I imagine there must be some kind of higher level system for organizing Erlang programs.</p>
<p><a href="http://blog.wyattbaldwin.com/2007/4/25/fun-with-python-bdd">Recently</a>, I did a similar exercise with Python as way to experiment with Behavior Driven Development. That version uses the familiar “destructive assignment” operation throughout. Erlang allows single assignment only, so I had to think about the problem in a different way. For example, an item can’t be appended to a list by manipulating a couple of object references as in Python—instead I used recursion to build up a new list.</p>
<p>After I get further into the book, it will be fun to come back to this implementation and see how it can be improved given a better understanding of the language. I’m also looking forward to exploring Concurrency Oriented Programming in depth. With Python, I tend to not think in terms of concurrency, though I’m sure I’ve got code that could be improved by using it.</p>
<p>Finally, here’s the code. It was written in Emacs, which has a nice Erlang mode. There are two other IDEs available, one based on Eclipse and the other on NetBeans.</p>
<p><code></code></p>
<pre>
-module(linkedlist).
-export([new/0,
     head/1,
     tail/1,
     append/2,
     nth/2,
     last/1,
     length/1,
     is_empty/1,
     main/0
    ]).

-record(list, {head, length=0}).
-record(item, {data, next}).

new() -&gt;
    #list{}.

new_item(Data) -&gt;
    #item{data=Data}.

head(List) -&gt;

    List#list.head.

tail(List) when List == #list{} -&gt;
    undefined;
tail(List) -&gt;
    Length = linkedlist:length(List) - 1,
    #list{head=next(head(List)), length=Length}.

append(Data, List) when List == #list{} -&gt;
    List#list{head=new_item(Data), length=1};
append(Data, List) -&gt;
    Item = append_item(Data, head(List)),
    NewLength = linkedlist:length(List) + 1,
    List#list{head=Item, length=NewLength}.

append_item(Data, Item) when Item#item.next == undefined -&gt;
    Item#item{next=new_item(Data)};
append_item(Data, Item) -&gt;

    Item#item{next=f(Data, next(Item))}.

next(Item) -&gt;
    Item#item.next.

% Get the Nth item from List
% N: Index of item to get
% List: List to get from
nth(N, List) when N &lt; 1 -&gt;
    undefined;
nth(N, List) -&gt;
    nth(N, 1, head(List)).

% N: Index of item to get
% I: Current index
% Item: #item in List corresponding to index I
nth(N, I, Item) when I == N -&gt;
    Item;
nth(N, I, Item) -&gt;

    nth(N, I + 1, next(Item)).

last(List) -&gt;
    nth(linkedlist:length(List), List).

length(List) -&gt;
    List#list.length.

is_empty(List) -&gt;
    List == new().

p() -&gt;
    io:format("\n").
p(Object) -&gt;
    erlang:display(Object).

main() -&gt;

    L = new(),
    test_list(L, "New list"),
    L1 = append(data1, L),
    test_list(L1, "List with one item"),
    L2 = append(data2, L1),
    test_list(L2, "List with two items"),
    L3 = append(data3, L2),
    test_list(L3, "List with three items"),
    ok.

test_list(List, Description) -&gt;
    io:format("~s~n", [Description]),
    Length = linkedlist:length(List),
    p({'list', List}),
    p({'head', head(List)}),
    p({'tail', tail(List)}),
    p({'first', nth(1, List)}),
    p({'nth', nth(Length, List)}),
    p({'last', last(List)}),
    p({'length', Length}),
    p({'is_empty', is_empty(List)}),
    p(),
    ok.</pre>
<p id="fn1"><sup>1</sup> A new blade and O-ring for my old-fashioned Oster blender came also. Double w00t!</p>
]]></content:encoded>
			<wfw:commentRss>http://wyattbaldwin.com/2007/08/07/erlang-linked-list-exercise/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Erlang for Python Programmers?</title>
		<link>http://wyattbaldwin.com/2007/08/03/erlang-for-python-programmers/</link>
		<comments>http://wyattbaldwin.com/2007/08/03/erlang-for-python-programmers/#comments</comments>
		<pubDate>Fri, 03 Aug 2007 23:33:25 +0000</pubDate>
		<dc:creator>Wyatt</dc:creator>
				<category><![CDATA[planet python]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://wyattbaldwin.com/2007/08/03/erlang-for-python-programmers/</guid>
		<description><![CDATA[I’ve been hearing about Erlang for several months now. It has seemed interesting, but up until recently I hadn’t felt any great need to look into it. Last week, however, my interest was piqued, and I spent much of the &#8230; <a href="http://wyattbaldwin.com/2007/08/03/erlang-for-python-programmers/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I’ve been hearing about <a href="http://erlang.org/">Erlang</a> for several months now. It has seemed interesting, but up until recently I hadn’t felt any great need to look into it.</p>
<p>Last week, however, my interest was piqued, and I spent much of the weekend reading about Erlang and playing around in its interactive shell. That continued into this week when I decided to buy <a href="http://www.pragmaticprogrammer.com/titles/jaerlang/">the new book</a>.</p>
<p>While I’ve been sitting around with “ants in my pants” waiting for the book to show up, I’ve been wondering if there’s an <em>Erlang for Python Programmers</em> tutorial floating around anywhere (I haven’t come across one yet). I’m thinking I might try to put something like that together. I think that will be an interesting challenge as there’s not necessarily an obvious one-to-one correspondence between the two languages.</p>
<p>Here’s how I initially learned about and got interested in Erlang:</p>
<ul>
<li>Blog articles via <a href="http://planetpython.org/">Planet Python</a> via Google Reader</li>
<li>Videos linked from the <a href="http://google-code-updates.blogspot.com/2007/07/weekly-google-code-roundup-for-july-23.html">Google Code Blog</a>: <a href="http://video.google.com/videoplay?docid=240707194662243675&amp;q=user%3A%22Google+engEDU%22&amp;total=333&amp;start=10&amp;num=10&amp;so=1&amp;type=search&amp;plindex=0">Erlang tech talk</a> and <a href="http://video.google.com/videoplay?docid=-5830318882717959520">Erlang: The Movie</a></li>
</ul>
<p>These things made it easier to get beyond the yeah-that-looks-neat stage and into the ok-what-the-hell-I’ll-give-it-a-try stage:</p>
<ul>
<li>It was easy to install with apt-get on Ubuntu (`sudo apt-get install erlang`)</li>
<li>It has an interactive shell (`erl`)</li>
<li>There’s good introductory documentation at <a href="http://erlang.org/">erlang.org</a></li>
</ul>
<p>Here’s what’s keeping me interested:</p>
<ul>
<li>It’s a functional language, which makes it more interesting in some ways than learning, say, Ruby—in fact, I wouldn’t really need to learn much to start using Ruby, whereas using Erlang will require new ways of thinking about program structure (in terms of functions and processes)</li>
<li>I like the term “Concurrency Oriented Programming”</li>
<li>It’s been used to build some massive real-world systems</li>
<li>There’s a <a href="http://erlyweb.org/">Web framework</a></li>
<li>It has a planet: <a href="http://www.planeterlang.org/">Planet Erlang</a></li>
<li>There’s <a href="http://www.pragmaticprogrammer.com/titles/jaerlang/">a recent book</a> by <a href="http://armstrongonsoftware.blogspot.com/">one of the original creators</a> of the language</li>
<li>It seems to be hot amongst alpha geeks, and I’m a wannabe alpha geek</li>
</ul>
<p>See <a href="http://erlang.org/">erlang.org</a> for pointers to more info.</p>
<p>Erlang is the first functional language I’ve really gotten into (for whatever reason), so regardless of whether I ever end up using it in the real world, the learning experience will be valuable.</p>
]]></content:encoded>
			<wfw:commentRss>http://wyattbaldwin.com/2007/08/03/erlang-for-python-programmers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fun With Python BDD</title>
		<link>http://wyattbaldwin.com/2007/04/25/fun-with-python-bdd/</link>
		<comments>http://wyattbaldwin.com/2007/04/25/fun-with-python-bdd/#comments</comments>
		<pubDate>Wed, 25 Apr 2007 17:59:01 +0000</pubDate>
		<dc:creator>Wyatt</dc:creator>
				<category><![CDATA[planet python]]></category>
		<category><![CDATA[bdd]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://wyattbaldwin.com/2007/04/25/fun-with-python-bdd/</guid>
		<description><![CDATA[I was testing my algorithm/data structures chops by implementing a Linked List from scratch using no reference material (not very difficult, I know), and I must say that using BDD was incredibly helpful. I’m calling it “BDD” instead of “TDD” &#8230; <a href="http://wyattbaldwin.com/2007/04/25/fun-with-python-bdd/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I was testing my algorithm/data structures chops by implementing a Linked List from scratch using no reference material (not very difficult, I know), and I must say that using <span class="caps">BDD</span> was incredibly helpful. I’m calling it “BDD” instead of “TDD” just because the test class names describe a context and the method names in the test classes are behavior-oriented, inspired by the style found on the <a href="http://rspec.rubyforge.org/">RSpec site</a>.</p>
<p>I didn’t write the tests/specs up front like you’re “supposed” to. Instead, I thought about what I was trying to do, came up with an initial idea for the implementation, started writing code, and then added a test to make sure I was on the right track. This worked out pretty well. I also used the tests during refactoring. Writing the tests first might have worked out better, but I can’t say for sure.</p>
<p>Now, for some real fun, implement a linked list based on <em>only</em> the test code below.</p>
<pre style="font-size: 4px">
class LinkedList(object):
    def __init__(self, *values):
        self._size = 0
        if values:
            for v in values:
                self.add(v)
        else:
            self.head = self.tail = None

    def is_empty(self):
        return len(self) == 0

    def add(self, val):
        node = Node(val)
        if self.is_empty():
            self.head = node
        else:
            self.tail.next = node
        self.tail = node
        self._size += 1

    def get(self, index, get_prev=False):
        if index &lt; 0:
            index = self._size + index
        if index &lt; 0 or index &gt;= self.length:
            raise IndexError
        prev = None
        for i, node in enumerate(self):
            if i == index:
                if get_prev:
                    return node, prev
                else:
                    return node
            prev = node

    def remove(self, index):
        node, prev = self.get(index, get_prev=True)
        if node is self.head:
            self.head = node.next
        else:
            prev.next = node.next
        self._size -= 1
        return node

    def pop(self):
        return self.remove(self.length - 1)

    def __len__(self):
        return self._size
    length = property(__len__)
    size = property(__len__)

    def __iter__(self):
        curr = self.head
        while curr is not None:
            yield curr
            curr = curr.next
        raise StopIteration

    def __str__(self):
        return ', '.join([str(node.value) for node in self])

class Node(object):
    def __init__(self, val, next=None):
        self.value = val
        self.next = next
</pre>
<pre>import unittest
class Test_A_New_Linked_List(unittest.TestCase):

    def test_given_no_values_should_be_empty(self):
        list_ = LinkedList()
        assert list_.is_empty()

    def test_given_no_values_should_have_size_0(self):
        list_ = LinkedList()
        assert list_.size == list_.length == 0

    def test_given_values_should_not_be_empty(self):
        list_ = LinkedList(1, 2, 3)
        assert not list_.is_empty()
        assert [node.value for node in list_] == [1, 2, 3]

    def test_given_4_values_should_have_size_4(self):
        list_ = LinkedList(1, '2', 3, '4th value')
        assert list_.size == 4

class Test_An_Empty_List(unittest.TestCase):

    def test_should_have_size_1_after_add(self):
        list_ = LinkedList()
        val = 15
        list_.add(val)
        assert list_.head.value == list_.tail.value == val
        assert len(list_) == list_.length == list_.size == 1

    def test_should_raise_an_index_error_on_get(self):
        list_ = LinkedList()
        self.assertRaises(IndexError, list_.get, 1)
        list_ = LinkedList(1, 2, 3)
        list_.remove(0); list_.remove(0); list_.remove(0)
        self.assertRaises(IndexError, list_.get, 0)

    def test_should_raise_an_index_error_on_remove(self):
        list_ = LinkedList()
        self.assertRaises(IndexError, list_.remove, 1)
        list_ = LinkedList(1, 2, 3)
        list_.remove(0); list_.remove(0); list_.remove(0)
        self.assertRaises(IndexError, list_.remove, 0)

    def test_should_raise_an_index_error_on_pop(self):
        list_ = LinkedList()
        self.assertRaises(IndexError, list_.pop)

class Test_A_Non_Empty_List(unittest.TestCase):

    def test_should_increase_its_size_by_1_on_add(self):
        list_ = LinkedList(1, 2, 4, 5)
        starting_size = list_.size
        list_.add(13)
        assert len(list_) == list_.length == list_.size == (starting_size + 1)

    def test_should_return_a_node_on_get(self):
        list_ = LinkedList(1, 2, '3rd value')
        node = list_.get(0)
        assert isinstance(node, Node)
        assert node.value == 1
        node = list_.get(1)
        assert isinstance(node, Node)
        assert node.value == 2
        node = list_.get(2)
        assert isinstance(node, Node)
        assert node.value == '3rd value'

    def test_should_decrease_its_size_by_1_on_remove(self):
        list_ = LinkedList(1, 2, 4, 5)
        starting_size = list_.size
        list_.remove(0)
        assert len(list_) == list_.length == list_.size == (starting_size - 1)

    def test_should_decrease_its_size_by_1_on_pop(self):
        list_ = LinkedList(1, 2, 4, 5)
        starting_size = list_.size
        list_.pop()
        assert len(list_) == list_.length == list_.size == (starting_size - 1)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://wyattbaldwin.com/2007/04/25/fun-with-python-bdd/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Google Maps Encoded Polylines</title>
		<link>http://wyattbaldwin.com/2007/04/19/google-maps-encoded-polylines/</link>
		<comments>http://wyattbaldwin.com/2007/04/19/google-maps-encoded-polylines/#comments</comments>
		<pubDate>Thu, 19 Apr 2007 15:19:03 +0000</pubDate>
		<dc:creator>Wyatt</dc:creator>
				<category><![CDATA[planet python]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[google maps]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://wyattbaldwin.com/2007/04/19/google-maps-encoded-polylines/</guid>
		<description><![CDATA[Update 6/30/07: Fixed links to glineenc.py so that it’s actually accessible. Update 7/15/08: Fixed links to glineenc.py again because of change to HTTPS on Trac site. Here’s some Python code (complete with unit and doc tests) for converting a series &#8230; <a href="http://wyattbaldwin.com/2007/04/19/google-maps-encoded-polylines/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em>Update 6/30/07: Fixed links to glineenc.py so that it’s actually accessible.</em><br />
<em>Update 7/15/08: Fixed links to glineenc.py again because of change to HTTPS on Trac site.</em></p>
<p><a title="Code on Bitbucket" href="https://bitbucket.org/wyatt/glineenc">Here’s some Python code</a> (complete with unit and doc tests) for converting a series of latitude/longitude points (i.e., a polyline) to the Base64 encoding that Google Maps understands. It’s particularly useful for long and/or complicated lines.</p>
<p>It’s based on the algorithm listed <a href="http://www.google.com/apis/maps/documentation/polylinealgorithm.html">here</a> and the JavaScript code <span style="text-decoration: line-through;"><a href="http://www.google.com/apis/maps/documentation/polyline.js">here</a></span> [page disappeared].</p>
<p><a href="http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/">This site</a> gives some more insight into it and has a pretty cool example of a fractal line <a href="http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/fractalLog5Log4.html">here</a>.</p>
<p>Here’s the code:</p>
<p><em>Previously, I had pasted the Python code right into this article, but I recently made a bunch of revisions and it was way too long. Here’s a link to the Bitbucket project instead:</em></p>
<p><a title="Code on Bitbucket" href="https://bitbucket.org/wyatt/glineenc">glineenc on Bitbucket</a></p>
<p>Please note that this code is still in somewhat of a rough state. I have plans to polish and package it up, but for now, I’m <a href="http://bycycle.org/">using it</a> as is and it’s <a href="http://bycycle.org/regions/portlandor/routes;find?s=longitude%3D-123.42041%2C%20latitude%3D45.769439&amp;e=longitude%3D-121.786194%2C%20latitude%3D44.957024&amp;pref=default">working quite well</a> (you’ll have to be patient to click that link as it takes ~20-30 seconds to generate the route, even though the line drawing itself is almost instantaneous).</p>
<p>JavaScript that uses results from `glineenc` looks something like this (assuming you’ve returned some <span class="caps">JSON</span>, say, with `encoded_points` and `encoded_lines` keys):</p>
<pre><code>
map.addOverlay(new GPolyline.fromEncoded({
  color: "#0000ff",
  weight: 4,
  opacity: 0.8,
  points: result.encoded_points,
  levels: result.encoded_levels,
  zoomFactor: 32,
  numLevels: 4
}));
</code></pre>
<p>`points` is the encoded lat/long points. `levels` indicates which zoom levels each point should displayed at; there is one character per point. See the links above for a more complete explanation.</p>
]]></content:encoded>
			<wfw:commentRss>http://wyattbaldwin.com/2007/04/19/google-maps-encoded-polylines/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

