<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Coderholic</title>
	
	<link>http://www.coderholic.com</link>
	<description>Addicted to Development</description>
	<lastBuildDate>Tue, 31 Aug 2010 09:19:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/coderholic" /><feedburner:info uri="coderholic" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>coderholic</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Taking the leap: How I became a full time entrepreneur</title>
		<link>http://feedproxy.google.com/~r/coderholic/~3/4bjmAzCKrNQ/</link>
		<comments>http://www.coderholic.com/taking-the-leap-how-i-became-a-full-time-entrepreneur/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 11:29:23 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[startups]]></category>
		<category><![CDATA[entrepreneur]]></category>
		<category><![CDATA[geomium]]></category>
		<category><![CDATA[mendeley]]></category>
		<category><![CDATA[startup]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=776</guid>
		<description><![CDATA[I took the leap. I made the jump. As of almost a month ago I&#8217;m no longer an employee. I&#8217;m now an entrepreneur! That&#8217;s right, I&#8217;m now working full time on my startup Geomium. So how did it happen? Even at University I was making small steps towards it, working on my own interesting tech [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/sovietuk/486119799/" rel="no-follow"><img style="float: left; margin-right: 10px; margin-bottom: 5px; border: 1px solid gray;" src="http://www.coderholic.com/wp-content/uploads/jump1.jpg" alt="" /></a></p>
<p>I took the leap. I made the jump. As of almost a month ago I&#8217;m no longer an employee. I&#8217;m now an entrepreneur! That&#8217;s right, I&#8217;m now working full time on my startup <a href="http://geomium.com">Geomium</a>. So how did it happen?</p>
<p>Even at University I was making small steps towards it, working on my own interesting tech projects and doing freelance development work. When I started work as a developer for Siemens I kept this up, making sure I continued to read up about new and interesting technologies, and to write about it all for this blog and others.</p>
<p>A great part of working for such a large company was that they had a fantastic graduate development program. I got to go on courses about communication, presentation, and negotiation. There were even team building exercises where we got to go rock climbing and tackle assault courses! The whole time I was thinking &#8220;How could I apply these skills to my own business?&#8221;, and I got to take a lot from the program. Working for a large company certainly had its downsides though, and after I&#8217;d completed much of the graduate course and finished the project I was working on I knew it was time to move on.</p>
<p><strong>The Run Up</strong></p>
<p>I had a brief spell with a smaller company, and although I preferred the smaller company atmosphere I didn&#8217;t feel I was learning much. I needed a challenge! That&#8217;s when I moved moved to London to join <a href="http://www.mendeley.com">Mendeley</a>, a tech startup, as their second employee and first web developer. Who knew that a couple of years later that Mendeley would have over 40 employees in London and New York, and have won numerous awards?</p>
<p>Getting in early on meant that I really got to make a difference, and was able to play a critical role in making Mendeley what it is today. I found working for a startup so refreshing. Good ideas get worked on right away, there are no forms to fill in, or committees or procedures to get in the way. It requires hard work though. I remember the mad rush to get the first public beta of Mendeley ready, with several of us holed up in the office with vast amounts of Redbull. We ended up getting the first tube of the day home at around 6am, when most people were just getting up for work. Long hours, but lots of fun.</p>
<p>Mendeley not only gave me the chance to work on a large-scale high-traffic website, with all of the technical challenges that entails, but as the company grew I took on the role not only of technical lead, but also web team lead, so I got to learn first hand about managing teams, setting deadlines and targets, interviewing and recruiting people. It was an invaluable experience.</p>
<p>Being based in London also meant I could take advantage of its great tech scene. There are loads of monthly tech events, and annual conferences. I tried to attend as many of these as I could not only to keep up with the latest tech, but also to meet new people and to open myself up to more opportunities. It wasn&#8217;t through one of these meetups that I would eventually meet my co-founder though.</p>
<p><strong>The Jump</strong></p>
<p>Around a year ago I was browsing a freelance job site and came across a post from Michael Ferguson. The post sounded really interesting, so I got in touch. We first met at Costa Coffee, and spent at least an hour discussing not only Michael&#8217;s ideas for the project, but also about our backgrounds and interests. I think we almost immediately realised we were a good match, with complementary skill sets. By the time we&#8217;d finished our coffees we were both excited about moving forward with the project that would eventually become Geomium. At the time I thought it&#8217;d just be another interesting side project to work on though, little did I know that 12 months later I&#8217;d be leaving Mendeley to pursue it fulltime!</p>
<p>As the project progressed Geomium demanded more and more of my time. Not only on development, but also meetings with potential partners and investors, and going to events to try and get the word out. It was becoming clear that Geomium would soon need my full time commitment. It was at this point that I had to take the leap, and it was a time of mixed emotions. It was hugely exciting, but at the same time I was sad be leaving a company I&#8217;d cared so much about and put so much effort into for the previous couple of years. It was also scary to be leaving the relative security of employment, especially as I have a wife and baby to support. Fortunately my wife is hugely supportive, and just as excited about the opportunity as me. I took courage in the words of <a href="http://tom.preston-werner.com/2008/10/18/how-i-turned-down-300k.html">Tom Preston-Werner</a>:</p>
<blockquote><p>When I’m old and dying, I plan to look back on my life and say “wow, that was an adventure,” not “wow, I sure felt safe.”</p></blockquote>
<p>It certainly is going to be an adventure, but with hard work and dedication from Michael and I, and support from our family and friends, I&#8217;m sure we can make a success of it. So far things are going well. Geomium recently <a href="http://geomium.com/blog/post/geomium-battles-to-third-place-in-the-techcrunch-european-pitch-battle/">took third</a> in the TechCrunch summer pitch battle, and we&#8217;ve had some good write ups. It&#8217;s still early days though, there&#8217;s a whole lot still to do. The really hard work starts now!</p>
<img src="http://feeds.feedburner.com/~r/coderholic/~4/4bjmAzCKrNQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/taking-the-leap-how-i-became-a-full-time-entrepreneur/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.coderholic.com/taking-the-leap-how-i-became-a-full-time-entrepreneur/</feedburner:origLink></item>
		<item>
		<title>JavaScript: The Good Parts</title>
		<link>http://feedproxy.google.com/~r/coderholic/~3/62k7sJNuWkY/</link>
		<comments>http://www.coderholic.com/javascript-the-good-parts/#comments</comments>
		<pubDate>Sun, 18 Jul 2010 10:44:37 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[books]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[web dev]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=745</guid>
		<description><![CDATA[I&#8217;ve been a huge fan of Douglas Crockford and his articles about JavaScript for a long time. I often point people to his The World&#8217;s Most Misunderstood Programming Language article when I hear them complaining about the language. It&#8217;s taken me a couple of years to get around to reading his book, JavaScript: The Good [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://crockford.com/goodparts.gif" style="float: left; border: 1px solid grey; margin-right: 10px;"/> I&#8217;ve been a huge fan of Douglas Crockford and his <a href="http://javascript.crockford.com/">articles about JavaScript</a> for a long time. I often point people to his <a href="http://javascript.crockford.com/javascript.html">The World&#8217;s Most Misunderstood Programming Language</a> article when I hear them complaining about the language. It&#8217;s taken me a couple of years to get around to reading his book, <a href="http://www.amazon.co.uk/gp/product/0596517742?ie=UTF8&#038;tag=dowlingmeuk-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=0596517742">JavaScript: The Good Parts</a><img src="http://www.assoc-amazon.co.uk/e/ir?t=dowlingmeuk-21&#038;l=as2&#038;o=2&#038;a=0596517742" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />, but it exceeded all of my expectations.</p>
<p>Being an avid reader of his online stuff, and having watched various <a href="http://www.youtube.com/results?search_query=crockford+javascript&#038;aq=f">talks of his</a> I knew the book would be well written and informative, but I thought it&#8217;d probably just repeat much of what I&#8217;d already read, without providing much new information or insights. To a certain extent this was true, the book does reiterate what&#8217;s said in many of his online articles and talks, but the book is absolutely amazing for a different reason: <strong>The code examples</strong>.</p>
<p>The book is extremely succinct. There&#8217;s no padding, and very little dialog to join one section to the next. There is a common thread thoughout the book though, and that&#8217;s the code. Examples of good coding practices are repeated, and functions written in earlier chapters are often reused in later ones. So although the book appears to be presenting one feature at a time with a small code example you&#8217;re actually building up more and more complex javascript applications, and the book ends with a full JSON parser!</p>
<p>Crockford&#8217;s coding style seems to match his writing style: succinct and to the point. There&#8217;s some really great code in the book, that I think even non-JavaScript developers could appreciate. Here&#8217;s my favourite, from the chapter on regular expressions:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> parse_url <span style="color: #339933;">=</span> <span style="color: #009966; font-style: italic;">/^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> url <span style="color: #339933;">=</span> <span style="color: #3366CC;">'http://www.ora.com:80/goodparts?q#fragment'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> result <span style="color: #339933;">=</span> parse_url.<span style="color: #660066;">exec</span><span style="color: #009900;">&#40;</span>url<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> names <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'url'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'scheme'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'slash'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'host'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'port'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'path'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'query'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'hash'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> blanks <span style="color: #339933;">=</span> <span style="color: #3366CC;">'       '</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</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> names.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">+=</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    document.<span style="color: #660066;">writeln</span><span style="color: #009900;">&#40;</span>names<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">':'</span> <span style="color: #339933;">+</span> blanks.<span style="color: #660066;">substring</span><span style="color: #009900;">&#40;</span>names<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">length</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> result<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Which outputs:</p>

<div class="wp_syntax"><div class="code"><pre class="none" style="font-family:monospace;">url:    http://www.ora.com:80/goodparts?q#fragment
scheme: http
slash:  //
host:   www.ora.com
port:   80
path:   goodparts
query:  q
hash:   fragment</pre></div></div>

<p>I also love the explanations Crockford gives as to why he avoids using certain parts of JavaScript, and limits himself to a &#8220;good&#8221; subset of the language. He doesn&#8217;t simply say &#8220;This is bad and you shouldn&#8217;t use it&#8221;, it&#8217;s usually accompanied by a story about a time when Crockford had used that feature and got caught out, which is much more compelling.</p>
<p>I think it&#8217;s fair to say that <a href="http://www.amazon.co.uk/gp/product/0596517742?ie=UTF8&#038;tag=dowlingmeuk-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=0596517742">JavaScript: The Good Parts</a><img src="http://www.assoc-amazon.co.uk/e/ir?t=dowlingmeuk-21&#038;l=as2&#038;o=2&#038;a=0596517742" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> is one of my favourite programming books: It&#8217;s succinct, packed full of great code examples and best practices for writing maintainable and bug free code. It&#8217;s a fantastic JavaScript reference, but much of what the book talks about is relevant to programming in general. Highly recommended!</p>
<img src="http://feeds.feedburner.com/~r/coderholic/~4/62k7sJNuWkY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/javascript-the-good-parts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.coderholic.com/javascript-the-good-parts/</feedburner:origLink></item>
		<item>
		<title>How we built a startup in 54 hours</title>
		<link>http://feedproxy.google.com/~r/coderholic/~3/wdryj7ykr5k/</link>
		<comments>http://www.coderholic.com/how-we-built-a-startup-in-54-hours/#comments</comments>
		<pubDate>Sun, 13 Jun 2010 11:03:15 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[startups]]></category>
		<category><![CDATA[#swlondon]]></category>
		<category><![CDATA[date parsing]]></category>
		<category><![CDATA[london]]></category>
		<category><![CDATA[startup]]></category>
		<category><![CDATA[tweevents]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=703</guid>
		<description><![CDATA[Last weekend I attended the London Startup Weekend, a 54 hour event hosted at the IBM building on London&#8217;s Southbank. It was a fantastic event. I met loads of great people, had a lot of fun, and successfully launched a new website! Arianna, Pedro and Debbie have already written up great summaries of the event, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/weefz/4671279887/"><img border=0 style="float: right;" src="http://farm5.static.flickr.com/4036/4671279887_fe5d2b332f.jpg"/></a>Last weekend I attended the <a href="http://london.startupweekend.org/">London Startup Weekend</a>, a 54 hour event hosted at the IBM building on London&#8217;s Southbank. It was a fantastic event. I met loads of great people, had a lot of fun, and successfully launched a new website! <a href="http://arianna.posterous.com/my-thoughts-on-startup-weekend-london-swlondo">Arianna</a>, <a href="http://www.pedrosantos.me/08/some-thoughts-on-london-startupweekend-and-rags2riches">Pedro</a> and <a href="http://weefz.wordpress.com/2010/06/09/startup-weekend-london-writeup/">Debbie</a> have already written up great summaries of the event, so instead I&#8217;ll be focusing on how our team managed to build and launch our project, automatic event management for twitter.</p>
<p>After forming a group most of Friday evening and Saturday morning was spent discussing ideas around the original pitch of twitter calendar integration. We discussed a whole range of ideas including an event broker service, calendar availability widgets, and a twitter/google calendar mashup. It took until lunch time on Saturday to finalise our idea. We&#8217;d settled on a a service that would automatically work out the date of an event mentioned in a tweet and keep track of these events. There were now only 36 hours left!</p>
<p>I got straight to work on the code, using Django. I knew we&#8217;d need to pull in tweets and then analyse the dates. Using the <a href="http://code.google.com/p/python-twitter/">python-twitter</a> library I wrote a <a href="http://docs.djangoproject.com/en/dev/howto/custom-management-commands/">management command</a> to pull in all tweets containing some specific hashtags every minute.</p>
<p>The next stage was to work out a date from the tweets. A <a href="http://stackoverflow.com/questions/1495487/is-there-any-python-library-for-parsing-dates-and-times-from-a-natural-language">Stack Overflow question</a> suggested two options, <a href="http://code.google.com/p/parsedatetime/">parsedatetime</a> library, and some <a href="http://pyparsing.wikispaces.com/UnderDevelopment#toc0">pyparsing example code</a>. I tried the parsedatetime library first, and it gave some fairly good results right away. It wasn&#8217;t so good at more complicated dates though. I tried the pyparsing example, but unless given just the date string (eg. &#8220;Next week&#8221; instead of &#8220;See you next week&#8221;) failed to work out a date at all. I did briefly investigate using the <a href="http://www.nltk.org/">NLTK</a> to extract the date from a tweet, but worried about running out of time I gave up on investigating further and stuck with parsedatetime.</p>
<p>While I&#8217;d been busy programming <a href="http://twitter.com/guillaumedeM">Guillume</a> had come up with a great name for our service: tweevents. He&#8217;d then set about registering the domain name, setting up a <a href="http://twitter.com/tweevents_">twitter acccount</a> and <a href="http://www.facebook.com/pages/Tweevents/133447103335113?ref=ts">facebook fan page</a>. Once we had the name sorted I setup an online logo competition offering $25 to the winner, and an hour later we had our logo.</p>
<p><img src="http://www.tweevents.com/media/images/logo.png"/></p>
<p><a href="http://twitter.com/gtichy">Gabriel</a> worked hard overnight to produce some HTML/CSS for the site, so on Sunday morning I worked on integrating that into the Django project. We worked on adding features to the website, such as links to add events to your google calendar, hCalendar markup, and the ability to filter events by twitter username, and the rest of the day was spent putting a presentation together.</p>
<div style="width:425px" id="__ss_4487514"><object id="__sse4487514" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=tweevents4-100613083816-phpapp01&#038;stripped_title=tweevents" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse4487514" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=tweevents4-100613083816-phpapp01&#038;stripped_title=tweevents" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>
<p>So <a href="http://www.tweevents.com">tweevents</a> is now up and running. Within 54 hours we&#8217;d gone from a rough idea into a working website. The presentation we gave gives some details about what&#8217;s next from the business side, but there&#8217;s also some things I&#8217;d like to get done on the development side. Most importantly improved date parsing. I plan to give the <a href="http://labix.org/python-dateutil">python-dateutil</a> library a try, and failing that go back to look into NLTK in more detail. Guillume&#8217;s also working hard on improving the library we&#8217;re already using. Should none of the Python options work I&#8217;ve also come across some great date parsing libraries for other languges, such as <a href="http://www.rubyinside.com/chronic-natural-date-parsing-for-ruby-229.html">Chronic</a> for Ruby and <a href="http://www.datejs.com/">Datejs</a> for Javascript. A Rails or Node.js rewrite might be on the cards! There are also features that we could add, such as Facebook event creation, or filtering the list of events to just your twitter followers, or people you follow.</p>
<p>A huge thanks to <a href="http://twitter.com/damiensaunders">Damien</a>, <a href="http://twitter.com/digbyj">James</a> and <a href="http://twitter.com/peignoir">Franck</a> who organised and helped out at the event, and made it all so much fun. Of course, tweevents wouldn&#8217;t be much without the rest of the <a href="http://www.tweevents.com/about/">team</a>. Thanks also to my girlfriend, who was left on her own with our 2 month old daughter for the entire weekend!</p>
<img src="http://feeds.feedburner.com/~r/coderholic/~4/wdryj7ykr5k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/how-we-built-a-startup-in-54-hours/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.coderholic.com/how-we-built-a-startup-in-54-hours/</feedburner:origLink></item>
		<item>
		<title>FireEagle OAuth and Python2.5 Woes</title>
		<link>http://feedproxy.google.com/~r/coderholic/~3/FurKfrVeW5o/</link>
		<comments>http://www.coderholic.com/fireeagle-oauth-and-python2-5-woes/#comments</comments>
		<pubDate>Tue, 18 May 2010 20:34:10 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[oauth fireeagle python yahoo]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=691</guid>
		<description><![CDATA[Back in February I started work on integrating Yahoo&#8217;s FireEagle location service into Geomium and I ran into a problems with Python 2.5. Using Steve Marshall&#8217;s Python library the included test.py script was working perfectly with Python2.6, but when running with Python2.5 I&#8217;d get back an &#8220;Invalid OAuth signature error&#8221;. I posted the problem to [...]]]></description>
			<content:encoded><![CDATA[<p>Back in February I started work on integrating Yahoo&#8217;s <a href="http://fireeagle.yahoo.net/">FireEagle</a> location service into <a href="http://geomium.com">Geomium</a> and I ran into a problems with Python 2.5. Using <a href="http://github.com/SteveMarshall/fire-eagle-python-binding">Steve Marshall&#8217;s Python library</a> the included test.py script was working perfectly with Python2.6, but when running with Python2.5 I&#8217;d get back an &#8220;Invalid OAuth signature error&#8221;.</p>
<p>I posted the problem to the <a href="http://groups.google.com/group/oauth/browse_thread/thread/67fc9ca1e8fd750a/0953b6d5a3fd4b84?hl=en%CE%B9b6d5a3fd4b84&#038;pli=1">OAuth user group</a> but didn&#8217;t get any response. I got in touch with Yahoo. After quite a bit of back and forth we finally figured out the problem, which I&#8217;m posting here to try and save others from months of frustration!</p>
<p>The Yahoo guys noticed that with Python2.5 the HTTP host header was being sent through as as &#8220;fireeagle.yahooapis.com:443&#8243;, whereas 2.6 sends &#8220;fireeagle.yahooapis.com&#8221;. The inclusion of the port results in an invalid OAuth signature, because the signature is generated assuming the port isn&#8217;t included. I dug into the Python2.5 httplib code and came across this:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"> <span style="color: #ff4500;">813</span>    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">port</span> == HTTP_PORT:
 <span style="color: #ff4500;">814</span>        <span style="color: #008000;">self</span>.<span style="color: black;">putheader</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Host'</span>, host_enc<span style="color: black;">&#41;</span>
 <span style="color: #ff4500;">815</span>    <span style="color: #ff7700;font-weight:bold;">else</span>:
 <span style="color: #ff4500;">816</span>        <span style="color: #008000;">self</span>.<span style="color: black;">putheader</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Host'</span>, <span style="color: #483d8b;">&quot;%s:%s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>host_enc, <span style="color: #008000;">self</span>.<span style="color: black;">port</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>In Python 2.6 the comparison on line 813 is done with self.default_port instead of HTTP_PORT, which prevents the port from being added with HTTPS requests. I noticed that later on in the code that if you pass in your own host header it prevents one being created for you:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"> <span style="color: #ff4500;">875</span>     <span style="color: #ff7700;font-weight:bold;">def</span> _send_request<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, method, url, body, headers<span style="color: black;">&#41;</span>:
 <span style="color: #ff4500;">876</span>         <span style="color: #808080; font-style: italic;"># honour explicitly requested Host: and Accept-Encoding headers</span>
 <span style="color: #ff4500;">877</span>         header_names = <span style="color: #008000;">dict</span>.<span style="color: black;">fromkeys</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>k.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> k <span style="color: #ff7700;font-weight:bold;">in</span> headers<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
 <span style="color: #ff4500;">878</span>         skips = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
 <span style="color: #ff4500;">879</span>         <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #483d8b;">'host'</span> <span style="color: #ff7700;font-weight:bold;">in</span> header_names:
 <span style="color: #ff4500;">880</span>             skips<span style="color: black;">&#91;</span><span style="color: #483d8b;">'skip_host'</span><span style="color: black;">&#93;</span> = <span style="color: #ff4500;">1</span></pre></div></div>

<p>So the fix turns out to be really simple &#8211; explicitly set the http header. That&#8217;s exactly what I&#8217;ve done in my <a href="http://github.com/coderholic/fire-eagle-python-binding/">fork of the fireeagle library</a> (<a href="http://github.com/coderholic/fire-eagle-python-binding/commit/5586db6e984826bbda2b0f12144caab5a7d9a3de">see the fix</a>). I&#8217;ve also sent a push request, so hopefully this fix will make it back into the original library. Thanks to Arnab Nandi and Anand S from Yahoo for helping to debug things their end.</p>
<img src="http://feeds.feedburner.com/~r/coderholic/~4/FurKfrVeW5o" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/fireeagle-oauth-and-python2-5-woes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.coderholic.com/fireeagle-oauth-and-python2-5-woes/</feedburner:origLink></item>
		<item>
		<title>Rework Roundup</title>
		<link>http://feedproxy.google.com/~r/coderholic/~3/hB3sDPe1hJQ/</link>
		<comments>http://www.coderholic.com/rework-roundup/#comments</comments>
		<pubDate>Mon, 03 May 2010 13:09:23 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[books]]></category>
		<category><![CDATA[37signals]]></category>
		<category><![CDATA[book review]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[rework]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=685</guid>
		<description><![CDATA[37signals are the creators of the popular Ruby on Rails web framework and the people behind successful web applications such as basecamp and campfire. Their previous book Getting Real, about effecitive web application development, really resonated with me. When I heard that they were writing a new book, ReWork: Change the Way You Work Forever, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.co.uk/gp/product/0091929784?ie=UTF8&#038;tag=coderholic-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=0091929784"><img src="http://ecx.images-amazon.com/images/I/41ju6JBCJmL._SL110_.jpg" alt="ReWork Cover" style="float: left; border: none; margin-right: 10px; margin-bottom: 10px;"/></a></p>
<p>37signals are the creators of the popular Ruby on Rails web framework and the people behind successful web applications such as basecamp and campfire. Their previous book <a href="http://gettingreal.37signals.com/">Getting Real</a>, about effecitive web application development, really resonated with me.</p>
<p>When I heard that they were writing a new book, <a href="http://www.amazon.co.uk/gp/product/0091929784?ie=UTF8&#038;tag=coderholic-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=0091929784">ReWork: Change the Way You Work Forever</a><img src="http://www.assoc-amazon.co.uk/e/ir?t=coderholic-21&#038;l=as2&#038;o=2&#038;a=0091929784" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />, about &#8220;building, running and growing (or not growing) a business&#8221; the 37 signals way, I was excited. Especially as it arrived at a time when I&#8217;m working on my own <a href="http://geomium.com">startup</a>.</p>
<p>A week has passed since my copy arrived from Amazon, so I&#8217;ve had a change to read the book and write up some of my favourite points below.</p>
<p><b>Planning is guessing</b></p>
<blockquote><p>&#8220;Working without a plan may seem scary. But blindly following a plan that has no relationship to reality is even scarier&#8221;</p></blockquote>
<p>Don&#8217;t make long term plans, or at least don&#8217;t obsess over them if you do. I think the key point here is <em>be flexible</em>.</p>
<p><b>Start making something</b></p>
<blockquote><p>&#8220;Ideas are cheap and plentiful&#8230;the real question is how well you execute.&#8221;</p></blockquote>
<p>Coming up with cool ideas all day won&#8217;t get you anywhere. Starting something will. Even if it&#8217;s lame, you&#8217;ll learn something that&#8217;ll make the next attempt better.</p>
<p><b>Build half a product, not a half-assed product.</b></p>
<blockquote><p>&#8220;Getting to great starts by chopping out what&#8217;s merely good.&#8221;</p></blockquote>
<p>The classic 37 signals <a href="http://37signals.com/svn/posts/2106-you-can-always-do-less">do less</a> argument, about less being better, and bloat being bad.</p>
<p><b>Launch now</b></p>
<blockquote><p>&#8220;Stop imagining what&#8217;s going to work. Find out for real.&#8221;</p></blockquote>
<p>I&#8217;m also reminded of the Reid Hoffman principle here:</p>
<blockquote><p>&#8220;If you aren&#8217;t embarrassed by what you launch with, you waited too long to launch.&#8221;</p></blockquote>
<p><b>Good enough is fine</b></p>
<blockquote><p>&#8220;When good enough get the job done, go for it. It&#8217;s way better than wasting resources or, even worse, doing nothing because you can&#8217;t afford the complex solution.&#8221;</p></blockquote>
<p>I think the above rule is really a specific version of this one. Get something basic done first &#8211; worry about making it great later!</p>
<p><b>Pick a fight</b></p>
<blockquote><p>&#8220;Having an enemy gives you a great story to tell customers&#8230;They take sides. Passions are ignited.&#8221;</p></blockquote>
<p>This is certainly an approach that 37 Signals employ, and it seems to have worked well for them. OnStartups have a good article on <a href="http://onstartups.com/tabid/3339/bid/6727/Startups-and-The-Power-Of-Polarization.aspx">the power of polarization</a> which goes into more detail about this idea.</p>
<p><b>Don&#8217;t confuse enthusiam with priority</b></p>
<blockquote><p>&#8220;The enthusiasm you have for a new idea is not an accurate indicator of its true worth. What seems like a sure-fire hit right now often gets downgraded to &#8220;nice to have&#8221; by morning.&#8221;</p></blockquote>
<p>Don&#8217;t drop everything to start on your latest idea. You&#8217;ll constantly be chasing new ideas, and never finish any of your old ones which might be just as good, if not better.</p>
<p><b>Take a deep breath</b></p>
<blockquote><p>&#8220;When people complain, let things simmer for a while. Let them know you&#8217;re listening&#8230;but explain that you&#8217;re going to let it go for a while and see what happens. You&#8217;ll probbaly find that people will adjust eventually.&#8221;</p></blockquote>
<p>Every time Facebook change their privacy settings there is a huge uproar. When websites change their design you hear complaints. Changes aren&#8217;t always for the best, but there are some people complain no matter what. The advice given here is to wait a while for things to settle down before making any decisions based on the feedback.</p>
<p><b>Four-letter words</b></p>
<blockquote><p>&#8220;Need, must, can&#8217;t, easy, just, only and fast. There words get in the way of healthy communication. They are red flags that introduce animosity, torpedo good discussions, and cause projects to be late.&#8221;</p></blockquote>
<p>This is one of my favourite points in the book. I&#8217;ll certainly be making an effort to avoid these assumption-ridden words in the future!</p>
<p><b>Inspiration is perishable</b></p>
<blockquote><p>&#8220;Inspiration is a magical thing, a productivity multiplier, a motivator. But it won&#8217;t wait for you. Inspiration is a now thing. If it grabs you, grab it right back and put it to work.&#8221;</p></blockquote>
<p>So true. A great reason why you should <em>start making something</em> the second you feel inspired to do so.</p>
<p>They were my favourite points, but the book is filled with many more. If you&#8217;ve also read the book I&#8217;d love to know what you though and what your favourite parts were, either in the comments section or on <a href="http://twitter.com/coderholic">twitter</a>.</p>
<img src="http://feeds.feedburner.com/~r/coderholic/~4/hB3sDPe1hJQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/rework-roundup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.coderholic.com/rework-roundup/</feedburner:origLink></item>
		<item>
		<title>PHPUnit Command Line Code Coverage</title>
		<link>http://feedproxy.google.com/~r/coderholic/~3/9HT0lqybWlA/</link>
		<comments>http://www.coderholic.com/phpunit-command-line-code-coverage/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 21:40:33 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[scripts]]></category>
		<category><![CDATA[ci]]></category>
		<category><![CDATA[code coverage]]></category>
		<category><![CDATA[hudson]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpunit]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=663</guid>
		<description><![CDATA[I&#8217;m a big fan of unit testing, and for PHP projects I use PHPUnit. Combined with XDebug PHPUnit provides some great code coverage reporting options, including detailed HTML reports and a variety of different XML report options that work nicely with various different continuous integration servers and other tools. A feature I&#8217;ve often wanted, that [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a big fan of unit testing, and for PHP projects I use <a href="http://www.phpunit.de/">PHPUnit</a>. Combined with <a href="http://xdebug.org/">XDebug</a> PHPUnit provides some great code coverage reporting options, including detailed HTML reports and a variety of different XML report options that work nicely with various different continuous integration servers and other tools. </p>
<p>A feature I&#8217;ve often wanted, that is currently missing from PHPUnit, is a simple command line display of code coverage statistics when you&#8217;re running tests. If you&#8217;re trying to improve the code coverage of a specific test it isn&#8217;t practical to generate a full HTML report of the test every time you run it, and then check it in a browser. It would be much easier if the code coverage could be reported next to the success or failure message on the command line. </p>
<p>After a little bit of investigation into the different PHPUnit reports, and some git, awk, and sed hackery I came up with the following PHPUnit wrapper that does exactly what I was after. Once you&#8217;ve run a test, or collection of tests, it&#8217;ll display a list of files affected by the test and the code coverage for each file. The code for this script is below:</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>
<span style="color: #007800;">METRIC_FILE</span>=<span style="color: #ff0000;">&quot;/tmp/test-metrics.xml&quot;</span>
<span style="color: #666666; font-style: italic;"># Call PHPUnit will all provided command line arguments, and also generate a metrics file</span>
phpunit <span style="color: #660033;">--log-metrics</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$METRIC_FILE</span>&quot;</span> $<span style="color: #000000; font-weight: bold;">@</span>
<span style="color: #666666; font-style: italic;"># If phpunit exits with an error then exit here with the same error code</span>
<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: #660033;">-ne</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;">exit</span> <span style="color: #007800;">$?</span>
<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #666666; font-style: italic;"># Do some manipulation of the metrics file and output each file and the coverage for that file</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;*** SIMPLE COVERAGE REPORT ***&quot;</span>
<span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$METRIC_FILE</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #ff0000;">&quot;&lt;file&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $2 $10}'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span>
<span style="color: #ff0000;">&quot;s|<span style="color: #007800;">$PWD</span>||g&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #660033;">-F</span><span style="color: #000000; font-weight: bold;">\&quot;</span> <span style="color: #ff0000;">'{printf &quot;%-50s %.2f%\n&quot;, $2, $4}'</span>
<span style="color: #666666; font-style: italic;"># Cleanup</span>
<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$METRIC_FILE</span>&quot;</span></pre></div></div>

<p>I&#8217;ve place the script in /usr/bin/phpuc on my machine, and then I can invoke it like so:</p>
<pre>
$ phpcs tests/ExampleTest.xml

PHPUnit 3.3.16 by Sebastian Bergmann.

.........

Time: 0 seconds

OK (9 tests, 9 assertions)

Writing metrics report XML file, this may take a moment.
*** SIMPLE COVERAGE REPORT ***
Example.php                     89.37%
IncludedFile.php                 12.9%
</pre>
<p>Hopefully this will be something that&#8217;ll be built-in to PHPUnit in the future!</p>
<img src="http://feeds.feedburner.com/~r/coderholic/~4/9HT0lqybWlA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/phpunit-command-line-code-coverage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.coderholic.com/phpunit-command-line-code-coverage/</feedburner:origLink></item>
		<item>
		<title>PyWebShot – Generate website thumbnails using Python</title>
		<link>http://feedproxy.google.com/~r/coderholic/~3/lTIuSwM_i-Y/</link>
		<comments>http://www.coderholic.com/pywebshot-generate-website-thumbnails-using-python/#comments</comments>
		<pubDate>Sun, 11 Apr 2010 17:24:27 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[scripts]]></category>
		<category><![CDATA[python gtkmozembed screenshot pywebshot webkit2png]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=643</guid>
		<description><![CDATA[There have been lots of links to automatic website thumbnail generators on sites like reddit and hacker news today, including webkit2png and CutyCapt. Well it just so happens that a few weeks ago I wrote my own website thumbnail generator, and today I got around to putting it on GitHub. The code is based on [...]]]></description>
			<content:encoded><![CDATA[<p>There have been lots of links to automatic website thumbnail generators on sites like reddit and hacker news today, including <a href="http://www.paulhammond.org/webkit2png/">webkit2png</a> and <a href="http://cutycapt.sourceforge.net/">CutyCapt</a>. Well it just so happens that a few weeks ago I wrote my own website thumbnail generator, and today I got around to putting it on <a href="http://github.com/coderholic/PyWebShot">GitHub</a>.</p>
<p>The code is based on Matt Biddulph&#8217;s <a href="http://burtonini.com/computing/screenshot-tng.py">screenshot-tng</a> script, but heavily modified to be more user friendly and provide more options. It uses embedded mozilla for rendering, and therefore requires the <a href="http://www.mozilla.org/unix/gtk-embedding.html">python-gtkmozembed</a> package.</p>
<p>You can specify a resolution to take the screenshot at, and also a resolution for the thumbnail. When generating the thumbnail the aspect ratio will be preserved. You can also specify a delay, so that the screenshot is only taken so many seconds after loading the page. Here&#8217;s an example of running PyWebShot with 3 URLs, and the resulting images:</p>
<pre>
$ ./pywebshot.py -t 500x250 http://www.coderholic.com http://geomium.com/update/598/ http://jobs.plasis.co.uk
Loading http://www.coderholic.com... saved as www.coderholic.com.png
Loading http://geomium.com/update/598/... saved as geomium.com.update.598..png
Loading http://jobs.plasis.co.uk... saved as jobs.plasis.co.uk.png
</pre>
<p><img src="http://www.coderholic.com/wp-content/uploads/coderholic.com_.png"/></p>
<p><img src="http://www.coderholic.com/wp-content/uploads/geomium.com_.update.598..png"/></p>
<p><img src="http://www.coderholic.com/wp-content/uploads/jobs.plasis.co_.uk_.png"/></p>
<p>It you have a huge list of URLs you&#8217;d like to generate screenshots for you can put them all into a file and generate images for them all with the following command:</p>
<pre>
$ cat urls.txt | xargs ./pywebshot.py
</pre>
<p>For more details and the source code see the <a href="http://github.com/coderholic/PyWebShot">PyWebShot project page</a> on GitHub.</p>
<img src="http://feeds.feedburner.com/~r/coderholic/~4/lTIuSwM_i-Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/pywebshot-generate-website-thumbnails-using-python/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		<feedburner:origLink>http://www.coderholic.com/pywebshot-generate-website-thumbnails-using-python/</feedburner:origLink></item>
		<item>
		<title>The Acronym School of Software Design</title>
		<link>http://feedproxy.google.com/~r/coderholic/~3/bxbQRA1z4kU/</link>
		<comments>http://www.coderholic.com/the-acronym-school-of-software-design/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 11:33:52 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[software design]]></category>
		<category><![CDATA[dry]]></category>
		<category><![CDATA[kiss]]></category>
		<category><![CDATA[yagni]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=566</guid>
		<description><![CDATA[Well written software should be easy to use, test, maintain and understand. There are lots of software design principles and best practices that aim to help us achieve these goals (see Uncle Bob for great coverage of Object Oriented principles). While all of these design principles and practices will certainly help you to write better [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.coderholic.com/wp-content/uploads/180635570_345676005c_o.jpg" style="float: right; margin-left: 10px;"/><br />
Well written software should be easy to use, test, maintain and understand. There are lots of software design principles and best practices that aim to help us achieve these goals (see <a href="http://www.butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod">Uncle Bob</a> for great coverage of Object Oriented principles).</p>
<p>While all of these design principles and practices will certainly help you to write better software there are lots of them to learn, and lots to remember. When you actually sit down to write some code and you&#8217;re under pressure to get it finished as soon as possible some of the best practices can go by the way side. </p>
<p>Here are three acronyms that are simple to remember and will almost certainly help you to write better software. So whether you&#8217;re writing a small function, a class or a large module spare a few minutes to think about these acronyms and hopefully your software should end up being easier to use, test, maintain and understand as a result:</p>
<h3>DRY</h3>
<p>Don&#8217;t Repeat Yourself &#8211; The <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY principle</a> is about not repeating any logic or knowledge throughout your software, it&#8217;s about removing duplication. At the very least this means that repeated code should be moved into a function or class &#8211; <b>no copy and paste</b>! Taken to an extreme it means even things like a database schema and database interaction code should be generated from a single source. In their book <a href="http://www.amazon.co.uk/gp/product/020161622X?ie=UTF8&#038;tag=dowlingmeuk-21&#038;linkCode=as2&#038;camp=1634&#038;creative=19450&#038;creativeASIN=020161622X">The Pragmatic Programmer</a><img src="http://www.assoc-amazon.co.uk/e/ir?t=dowlingmeuk-21&#038;l=as2&#038;o=2&#038;a=020161622X" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />Andy Hunt and Dave Thomas recommend the use of code generators to help remove all duplication from a project.</p>
<p>With no duplication software becomes much easier to maintain. If something needs to be changed you know you&#8217;ll only need to change it in once place. It should also be easier to understand and test as a result.</p>
<h3>KISS</h3>
<p>Keep It Simple and Stupid &#8211; The <a href="http://en.wikipedia.org/wiki/KISS_principle">KISS principle</a> is about avoiding needless complexity, and keeping things as simple as possible. This doesn&#8217;t apply just to code, it can also apply to features. As 37Signals say in their free book <a href="http://gettingreal.37signals.com/toc.php">Getting Real</a>, which contains lots of suggestions for maximizing simplicity:</p>
<blockquote><p>&#8220;The key is to restate any hard problem that requires a lot of software into a simple problem that requires much less. You may not be solving exactly the same problem but that&#8217;s alright. Solving 80% of the original problem for 20% of the effort is a major win. The original problem is almost never so bad that it&#8217;s worth five times the effort to solve it.&#8221;</p></blockquote>
<p>Almost by definition simpler software should be easier to use, test, maintain and understand &#8211; so don&#8217;t forget KISS!</p>
<h3>YAGNI</h3>
<p>You Ain&#8217;t Gonna Need It &#8211; <a href="http://en.wikipedia.org/wiki/You_ain%27t_gonna_need_it">YAGNI</a> is about not writing code now for things that you think you might need in the future, because the chances are that you won&#8217;t, and even if you do the software you write now will likely be less than ideal for what you actually need in the future.</p>
<p>As a Software Engineer it&#8217;s easy to get carried away and think about generalized solutions to the problem you&#8217;re working on, or other ways in which your code can be used. This isn&#8217;t necessarily bad, and thinking about these issues can certainly aid maintainability and software reuse. The point of YAGNI though is that we shouldn&#8217;t actually write the code until we need it. Otherwise we have to maintain code that may never be used, and the time could better spent on other things.</p>
<img src="http://feeds.feedburner.com/~r/coderholic/~4/bxbQRA1z4kU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/the-acronym-school-of-software-design/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.coderholic.com/the-acronym-school-of-software-design/</feedburner:origLink></item>
		<item>
		<title>Clojure: 12 New Programming Languages Update 1</title>
		<link>http://feedproxy.google.com/~r/coderholic/~3/Yg4w7XHJBqc/</link>
		<comments>http://www.coderholic.com/clojure-12-new-programming-languages-update-1/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 10:25:08 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[scripts]]></category>
		<category><![CDATA[12in12]]></category>
		<category><![CDATA[clojure]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=588</guid>
		<description><![CDATA[At the start of the year I announced that I was setting myself the challenge of learning 12 new programming languages during 2010. That works out at a language a month, so seeing as it&#8217;s almost the end of March you might expect me to be wrapping up my third language. Unfortunately that isn&#8217;t the [...]]]></description>
			<content:encoded><![CDATA[<p>At the start of the year I announced that I was setting myself the challenge of learning <a href="http://www.coderholic.com/12-new-programming-languages-in-12-months/">12 new programming languages during 2010</a>. That works out at a language a month, so seeing as it&#8217;s almost the end of March you might expect me to be wrapping up my third language. Unfortunately that isn&#8217;t the case. I&#8217;m just about to move on to my second. I&#8217;m still optimistic I can achieve the target of 12 new languages this year though, so expect future updates to be more regular.</p>
<p><strong>Getting Starting with Clojure</strong></p>
<p>Getting up and running with Clojure was made easy to to the wealth of documentation. There&#8217;s a great <a href="http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started">getting started guide</a>, and a guide specifically for <a href="http://riddell.us/ClojureOnUbuntu.html">Clojure on Ubuntu</a>. In terms of programming environment there&#8217;s a round up of <a href="http://www.bestinclass.dk/index.php/2010/03/clojure-ides-the-grand-tour-getting-started/">Clojure IDEs</a>. I stuck to Vim, but I didn&#8217;t take it as far as <a href="http://writequit.org/blog/?p=386">this guide</a>, which describes turning Vim into a fairly comprehensive Clojure IDE. </p>
<p>Clojure has a <a href="http://clojure.org/repl_and_main">REPL</a>, which I always find makes learning a new language easier. When you want to find something out just type it in a see what the result is! The default REPL doesn&#8217;t support arrow navigation or pressing up to run previous commands though, so it can be a little frustrating. There are guides on <a href="http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started#Enhancing_Clojure_REPL_with_JLine">enhacing the REPL</a> with this functionality.</p>
<p>One of the first things I did was put together the following shell script which either runs the specified Clojure script, or gives you a REPL if no script was specified.</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: #007800;">CLOJURE_JAR</span>=<span style="color: #ff0000;">&quot;/opt/clojure-1.1.0/clojure.jar&quot;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span> 
        java <span style="color: #660033;">-jar</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${CLOJURE_JAR}</span>&quot;</span> 
<span style="color: #000000; font-weight: bold;">else</span>
        java <span style="color: #660033;">-jar</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${CLOJURE_JAR}</span>&quot;</span> <span style="color: #ff0000;">&quot;$@&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p><strong>Writing Code</strong></p>
<p>I decided to write a port scanner in Clojure, which would introduce me to command line argument handling, the network API, and parallelization. </p>
<p>One of the great things about Clojure is that despite being such a new language there is so much example code available on the web. I was able to find a <a href="http://travis-whitton.blogspot.com/2009/07/network-sweeping-with-clojure.html">Clojure network scanner</a> by Travis Whitton which detailed all of the network related code I&#8217;d need to my port scanner. Travis uses <a href="http://clojure.org/agents">Clojure&#8217;s agents</a> for parallelization, which is something else I borrowed from his script. I was amazed at how easy it was to parallelize the lookups. So much simpler than threading. If there is only one thing I take away from Clojure it&#8217;ll be its interesting approaches to parallelization.</p>
<p>So without further ado here is my Clojure port scanner:</p>

<div class="wp_syntax"><div class="code"><pre class="scheme" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>import '<span style="color: #66cc66;">&#40;</span>java.io IOException<span style="color: #66cc66;">&#41;</span>
        '<span style="color: #66cc66;">&#40;</span>java.net Socket<span style="color: #66cc66;">&#41;</span>
        '<span style="color: #66cc66;">&#40;</span>java.net InetSocketAddress<span style="color: #66cc66;">&#41;</span>
        '<span style="color: #66cc66;">&#40;</span>java.net SocketTimeoutException<span style="color: #66cc66;">&#41;</span>
        '<span style="color: #66cc66;">&#40;</span>java.net UnknownHostException<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">==</span> <span style="color: #66cc66;">&#40;</span>count <span style="color: #66cc66;">*</span>command<span style="color: #66cc66;">-</span>line<span style="color: #66cc66;">-</span>args<span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>def hostname <span style="color: #66cc66;">&#40;</span>first <span style="color: #66cc66;">*</span>command<span style="color: #66cc66;">-</span>line<span style="color: #66cc66;">-</span>args<span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>
    <span style="color: #66cc66;">&#40;</span>println <span style="color: #ff0000;">&quot;Usage: scanner &amp;lt;hostname&amp;gt;&quot;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>System<span style="color: #66cc66;">/</span>exit <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defn port<span style="color: #66cc66;">-</span>open? <span style="color: #66cc66;">&#91;</span>hostname port timeout<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sock<span style="color: #66cc66;">-</span>addr <span style="color: #66cc66;">&#40;</span>InetSocketAddress. hostname port<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>try
     <span style="color: #66cc66;">&#40;</span>with<span style="color: #66cc66;">-</span>open <span style="color: #66cc66;">&#91;</span>sock <span style="color: #66cc66;">&#40;</span>Socket.<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
       <span style="color: #66cc66;">&#40;</span>. sock connect sock<span style="color: #66cc66;">-</span>addr timeout<span style="color: #66cc66;">&#41;</span>
       port<span style="color: #66cc66;">&#41;</span>
     <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">catch</span> IOException <span style="color: #b1b100;">e</span> false<span style="color: #66cc66;">&#41;</span>
     <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">catch</span> SocketTimeoutException <span style="color: #b1b100;">e</span> false<span style="color: #66cc66;">&#41;</span>
     <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">catch</span> UnknownHostException <span style="color: #b1b100;">e</span> false<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
     	<span style="color: #66cc66;">&lt;</span>li<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&#40;</span>defn host<span style="color: #66cc66;">-</span>port<span style="color: #66cc66;">-</span>open? <span style="color: #66cc66;">&#91;</span>port<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>port<span style="color: #66cc66;">-</span>open? hostname port <span style="color: #cc66cc;">5000</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>def port<span style="color: #66cc66;">-</span><span style="color: #b1b100;">list</span> <span style="color: #66cc66;">&#40;</span>range <span style="color: #cc66cc;">1</span> <span style="color: #cc66cc;">1024</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>def agents <span style="color: #66cc66;">&#40;</span>for <span style="color: #66cc66;">&#91;</span>port port<span style="color: #66cc66;">-</span><span style="color: #b1b100;">list</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#40;</span>agent port<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>println <span style="color: #66cc66;">&#40;</span>str <span style="color: #ff0000;">&quot;Scanning &quot;</span> hostname <span style="color: #ff0000;">&quot;...&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>doseq <span style="color: #66cc66;">&#91;</span>agent agents<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>send<span style="color: #66cc66;">-</span>off agent host<span style="color: #66cc66;">-</span>port<span style="color: #66cc66;">-</span>open?<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>apply await agents<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>doseq <span style="color: #66cc66;">&#91;</span>port <span style="color: #66cc66;">&#40;</span>filter deref agents<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
       <span style="color: #66cc66;">&#40;</span>println <span style="color: #66cc66;">&#40;</span>str @port <span style="color: #ff0000;">&quot; is open&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>shutdown<span style="color: #66cc66;">-</span>agents<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>I&#8217;m sure it is far from an idiomatic solution, so any suggestions for improvement are welcome. Running the scanner with my bash script gives the following output:</p>
<pre>
$ ./clj.sh scanner
Usage: scanner &lt;hostname&gt;

$ ./clj.sh scanner github.com
Scanning github.com...
22 is open
80 is open
443 is open
</pre>
<p><strong>What&#8217;s next?</strong></p>
<p>I&#8217;ve barely scratched the surface of Clojure, but I&#8217;ve certainly become more aware of some of the concepts and idioms used by the language, which is what I was hoping for. I&#8217;ll be looking for more projects in the future where I can make use of it. For now though I need to move on to another language as part of my challenge. As I&#8217;m running behind I plan to go with one that I don&#8217;t think will be too unfamiliar, either Go or Fantom. I&#8217;ll keep you posted!</p>
<img src="http://feeds.feedburner.com/~r/coderholic/~4/Yg4w7XHJBqc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/clojure-12-new-programming-languages-update-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.coderholic.com/clojure-12-new-programming-languages-update-1/</feedburner:origLink></item>
		<item>
		<title>PostgreSQL for MySQL users</title>
		<link>http://feedproxy.google.com/~r/coderholic/~3/bwkKVS5f4bc/</link>
		<comments>http://www.coderholic.com/postgresql-for-mysql-users/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 16:54:17 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[geomium]]></category>
		<category><![CDATA[postgresql]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=567</guid>
		<description><![CDATA[I&#8217;ve been a long time user of MySQL, and despite having had some frustrations I&#8217;ve been pretty happy with MySQL. I&#8217;m comfortable with it, I know where its weaknesses lie and where it&#8217;s strong. I&#8217;ve never really had to look at alternatives. This all changed for a project that has been taking up all of [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been a long time user of MySQL, and despite having had <a href="http://forums.mysql.com/read.php?24,288330,288330#msg-288330">some frustrations</a> I&#8217;ve been pretty happy with MySQL. I&#8217;m comfortable with it, I know where its weaknesses lie and where it&#8217;s strong. I&#8217;ve never really had to look at alternatives.</p>
<p>This all changed for a project that has been taking up all of my spare time lately, <a href="http://www.geomium.com">Geomium</a>, a location-based communication tool. MySQL&#8217;s geospacial support is almost completely non-existant. PostgreSQL, on the other had, when combined with the <a href="http://postgis.refractions.net/">PostGIS</a> extension, has fantastic support. So PostgreSQL was what the project needed. I thought it&#8217;d be fairly easy to transition from MySQL to PostgresSQL but the command line clients of these two RDBMSes are very different. Here are some of the things I&#8217;ve learnt.</p>
<table width=100% border=1>
<tr>
<th>MySQL</th>
<th>PostgreSQL</th>
<th>Description</th>
</tr>
<tr>
<td>mysql -u&lt;user&gt; -p&lt;password &lt;database&gt;</td>
<td>psql -U&lt;user&gt; -P&lt;password&gt; &lt;database&gt;</td>
<td>Start command line client, and connect to &lt;database&gt;</td>
</tr>
<tr>
<td>SHOW DATABASES;</td>
<td>\l</td>
<td>Show available databases</td>
</tr>
<tr>
<td>SHOW TABLES;</td>
<td>\dt</td>
<td>Show available tables</td>
</tr>
<tr>
<td>USE &lt;database&gt;;</td>
<td>\c &lt;database&gt;</td>
<td>Connect to &lt;database&gt;</td>
</tr>
<tr>
<td>DESCRIBE &lt;table&gt;;</td>
<td>\dt &lt;table&gt;</td>
<td>Describe &lt;table&gt; structure</td>
</tr>
<tr>
<td>SHOW FULL PROCESSLIST;</td>
<td>SELECT * FROM pg_stat_activity;</td>
<td>Show all running queries</td>
</tr>
<tr>
<td>exit (or quit or \q)</td>
<td>\q</td>
<td>Quit the client</td>
</tr>
</table>
<p>A few other things to note: PostgreSQL only supports single quotes in queries not double quotes, so
<pre>SELECT * FROM table WHERE column = "value"</pre>
<p> would need to be rewritten as
<pre>SELECT * FROM table WHERE column = 'value'</pre>
<p>PostgreSQL also defaults to being case-sensitive, whereas MySQL defaults to case-insensitive, so you might want to modify your queries to something like
<pre>SELECT * FROM table WHERE lower(column) = 'value'</pre>
<p> although this can prevent an index on &#8220;column&#8221; from being used.</p>
<p>At first I thought PostgreSQL didn&#8217;t support some of the handy MySQL date functions (such as NOW() &#8211; INTERVAL 1 DAYS), but it turns out that it does support them, and more. It&#8217;s just fussier about the format. For details see the <a href="http://developer.postgresql.org/pgdocs/postgres/functions-datetime.html">datetime documentation</a>. </p>
<img src="http://feeds.feedburner.com/~r/coderholic/~4/bwkKVS5f4bc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/postgresql-for-mysql-users/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.coderholic.com/postgresql-for-mysql-users/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 0.317 seconds. --><!-- Cached page generated by WP-Super-Cache on 2010-09-06 17:57:56 -->
