<?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>Coderholic &#187; python</title>
	<atom:link href="http://www.coderholic.com/category/programming/python/feed/" rel="self" type="application/rss+xml" />
	<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>
		<item>
		<title>How we built a startup in 54 hours</title>
		<link>http://www.coderholic.com/how-we-built-a-startup-in-54-hours/</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>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/how-we-built-a-startup-in-54-hours/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>FireEagle OAuth and Python2.5 Woes</title>
		<link>http://www.coderholic.com/fireeagle-oauth-and-python2-5-woes/</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>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/fireeagle-oauth-and-python2-5-woes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PyWebShot &#8211; Generate website thumbnails using Python</title>
		<link>http://www.coderholic.com/pywebshot-generate-website-thumbnails-using-python/</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>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/pywebshot-generate-website-thumbnails-using-python/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>8 Reasons Why You Should Try Django</title>
		<link>http://www.coderholic.com/8-reasons-why-you-should-try-django/</link>
		<comments>http://www.coderholic.com/8-reasons-why-you-should-try-django/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 22:14:36 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[web dev]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=336</guid>
		<description><![CDATA[I have been using Python for quite a few years, but mostly for writing one off sysadmin scripts, command line utilities, and of course PyRadio. Most of my web development work has been done with PHP. The language gets a lot of bad press, some deserved and some not so much. I&#8217;ve had my own [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-505 aligncenter" title="django" src="http://www.coderholic.com/wp-content/uploads/django1.png" alt="django" width="500" height="228" /></p>
<p>I have been using Python for quite a few years, but mostly for writing one off sysadmin scripts, command line utilities, and of course <a href="http://www.coderholic.com/pyradio">PyRadio</a>. Most of my web development work has been done with PHP. The language gets a lot of bad press, some deserved and some not so much. I&#8217;ve had my own <a href="http://www.coderholic.com/beware-phps-split/">gripes</a>, but all-in-all I&#8217;ve been fairly happy with PHP.</p>
<p>Several months ago, though, I thought I&#8217;d give <a href="http://www.djangoproject.com/">Django</a> a try, a python based web framework. I was completely blown away!  Compared to the PHP frameworks I&#8217;d worked with, such as <a href="http://cakephp.org/">Cake</a>, it was just so much more of a pleasure to work with. So here are 8 reasons why you should give Django a try yourself if you haven&#8217;t already. You won&#8217;t be disappointed!</p>
<p><strong>1. Great Documentation</strong></p>
<p>The Django documentation is well written, extremely comprehensive, and up to date. The <a href="http://docs.djangoproject.com/en/">official documentation</a> contains details API references, loads of relevant examples, and tutorials for those getting started. If that isn&#8217;t enough there&#8217;s also a whole <a href="http://www.djangobook.com/">book</a> that&#8217;s available for free online.</p>
<p><strong>2. It&#8217;s Python</strong></p>
<p>The fact that it&#8217;s Python is a huge plus point for me. It&#8217;s a great language that doesn&#8217;t suffer from many of the well documented inconsistencies that PHP does, and includes some nice features such as decorators and first-class functions. Going back to PHP you soon start to miss the little things, such as the ability to assign <a href="http://diveintopython.org/native_data_types/declaring_variables.html#odbchelper.multiassign">multiple values at once</a>, and the simplicity of <a href="http://diveintopython.org/native_data_types/lists.html#odbchelper.list.slice">slicing lists</a>.</p>
<p><strong>3. The ORM</strong></p>
<p>Django&#8217;s object relational mapper completely abstracts away the database, meaning you don&#8217;t need to worry about your database schema or constructing SQL queries. If you&#8217;re using to writing SQL queries then the <a href="http://docs.djangoproject.com/en/dev/ref/models/querysets/">QuerySet</a> API takes a little getting used to, but it&#8217;s really worth the effort. Projects like <a href="http://south.aeracode.org/">South</a> make the ORM even more powerful, allowing you to make schema changes and data migrations automatically.</p>
<p><strong>4. Built in Development Server</strong></p>
<p>Where PHP really shines is on its ease of deployment. Setting up a local development server can be a bit of a pain though, especially if you&#8217;re working on several different sites. Django comes with a built in development server though, so you can be up and running within minutes! From your project&#8217;s root directory you just do</p>
<pre>./manage.py runserver</pre>
<p>and access your django website from http://localhost:8000 &#8211; awesome!</p>
<p><strong>5. The Admin Interface</strong></p>
<p>Django&#8217;s built-in admin interface is practically a full blown CMS, allowing you to add, delete or update your data. It&#8217;s pretty much all automatic, but it&#8217;s also fairly configuration. See the <a href="http://docs.djangoproject.com/en/dev/intro/tutorial02/">documentation</a> to see what it can do!</p>
<p><strong>6. Reusable Applications</strong></p>
<p>Django projects are broken up into &#8220;applications&#8221;, and there are lots of existing reusable applications that you can use for your own projects, such as those for <a href="http://code.google.com/p/django-registration/">user registration</a>, <a href="http://github.com/flashingpumpkin/django-socialregistration">facebook integration</a>, <a href="http://github.com/nathanborror/django-basic-apps">blogging</a>, and <a href="http://github.com/search?langOverride=&amp;language=&amp;q=django&amp;repo=&amp;start_value=2&amp;type=Repositories&amp;x=13&amp;y=19">many many more</a>.</p>
<p>Existing applications are great, but the whole project/application distinction also forces you to think about your own project structure and therefore more likely to make reusable components that you can use in more of your own projects, or even share for others to use.</p>
<p><strong>7</strong><strong>. Templates</strong></p>
<p>I&#8217;ve always been a bit dubious about the merits of PHP template engines such as Smarty. The Django template layer is great though. The inheritance model works well, and the restrictive language really forces you to have a very clean separation of presentation and logic.</p>
<p><strong>8</strong><strong>. Forms</strong></p>
<p>I usually find dealing with user input one of the most boring parts of web development. It takes time to get it right, and its repetitive. The Django Form API really simplifies things. You can define your form class, include and validation rules, and simply add a few lines to your template and few lines to your view and you&#8217;re done!</p>
<hr/>
<p>So those are my 8 reasons why you should give django a go. If you&#8217;re already a django user let me know if you have any points to add!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/8-reasons-why-you-should-try-django/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Parsing CSV data in Python</title>
		<link>http://www.coderholic.com/parsing-csv-data-in-python/</link>
		<comments>http://www.coderholic.com/parsing-csv-data-in-python/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 21:19:51 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=310</guid>
		<description><![CDATA[Python provides the csv module for parsing comma separated value files. It allows you to iterate over each line in a csv file and gives you a list of items on that row. For example, given the following csv data: id, name, date 0, name, 2009-01-01 1, another name, 2009-02-01 You&#8217;d end up with something [...]]]></description>
			<content:encoded><![CDATA[<p>Python provides the <a href="http://docs.python.org/library/csv.html">csv module</a> for parsing comma separated value files. It allows you to iterate over each line in a csv file and gives you a list of items on that row. For example, given the following csv data:</p>
<pre>
id, name, date
0, name, 2009-01-01
1, another name, 2009-02-01
</pre>
<p>You&#8217;d end up with something like:</p>
<pre>
["id", "name", "date"],
["0", "name", "2009-01-01"],
["1", "another name", "2009-02-01"]
</pre>
<p>In some situations it is nice to have a dictionary of keys and values though, so that instead of a simple list of columns we end up with:</p>
<pre>
{"id": "0", "name": "name", "date": "2009-01-01"},
{"id": "1", "name": "another name", "date": "2009-02-01"}
</pre>
<p>This would allow us to refer to fields by name rather than position in the list. Do you really want to remember that date is in position 2? And what happens if the input data changes, and a new column is added between name and date? If we&#8217;re referring to columns by position then we&#8217;ll have to change our existing code, but by referring to it by name we won&#8217;t have to change anything.</p>
<p>It turns out this is pretty easy to achieve, in only a few lines of python:</p>
<pre name="code" class="python">
import csv
data = csv.reader(open('data.csv'))
# Read the column names from the first line of the file
fields = data.next()
for row in data:
        # Zip together the field names and values
	items = zip(fields, row)
	item = {}
        # Add the value to our dictionary
	for (name, value) in items:
		item[name] = value.strip()
</pre>
<p>The csv module allows you to specify a delimiter, so if your data separated you just need to make a single change:</p>
<pre name="code" class="python">
data = csv.reader(open('data.tsv'), delimiter='\t')
</pre>
<p><strong>Update</strong></p>
<p>Thanks to several people for mentioning <a href="http://docs.python.org/library/csv.html#csv.DictReader">csv.DictReader</a>, which does exactly what I&#8217;ve mentioned here. Having a look at the code it does something very similar, but also takes into account rows of different length, ignores empty columns, and uses the method Tim mentioned in the comments for creating the dictionary:</p>
<pre name="code" class="python">
    # From csv.py
    def next(self):
        if self.line_num == 0:
            # Used only for its side effect.
            self.fieldnames
        row = self.reader.next()
        self.line_num = self.reader.line_num

        # unlike the basic reader, we prefer not to return blanks,
        # because we will typically wind up with a dict full of None
        # values
        while row == []:
            row = self.reader.next()
        d = dict(zip(self.fieldnames, row))
        lf = len(self.fieldnames)
        lr = len(row)
        if lf < lr:
            d[self.restkey] = row[lf:]
        elif lf > lr:
            for key in self.fieldnames[lr:]:
                d[key] = self.restval
        return d
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/parsing-csv-data-in-python/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>PyRadio 0.2 Released</title>
		<link>http://www.coderholic.com/pyradio-02-released/</link>
		<comments>http://www.coderholic.com/pyradio-02-released/#comments</comments>
		<pubDate>Fri, 12 Jun 2009 16:51:36 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=269</guid>
		<description><![CDATA[PyRadio 0.2, the curses based Internet radio player which I develop, is now available! Changes since the last release include: External radio stations file Page up/down to move up and down 5 stations at a time The selected station remains highlighted when you move about Volume up/down keys Additional radio stations The latest code available [...]]]></description>
			<content:encoded><![CDATA[<div style="float: right; padding: 10px;"><a href="http://www.coderholic.com/wp-content/uploads/pyradio.png"><img class="aligncenter size-thumbnail wp-image-100" title="pyradio" src="http://www.coderholic.com/wp-content/uploads/pyradio-150x150.png" border="0" alt="" width="150" height="150" /></a></div>
<p><a href="http://www.coderholic.com/pyradio">PyRadio 0.2</a>, the curses based Internet radio player which I develop, is now available! </p>
<p>Changes since the <a href="http://www.coderholic.com/pyradio-01-released/">last release</a> include:</p>
<ul>
<li>External radio stations file</li>
<li>Page up/down to move up and down 5 stations at a time</li>
<li>The selected station remains highlighted when you move about</li>
<li>Volume up/down keys</li>
<li>Additional radio stations</li>
</ul>
<p>The latest code available via <a href="http://github.com/coderholic/pyradio/tree/master">GitHub</a>, and you can download the 0.2 release from the <a href="http://www.coderholic.com/pyradio">project page</a>.</p>
<p>Thanks to everyone who left feedback and suggestions about the 0.1 release!</p>
<p>If you find any bugs or would like to request any features then please leave a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/pyradio-02-released/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Batch Image Processing with Python</title>
		<link>http://www.coderholic.com/batch-image-processing-with-python/</link>
		<comments>http://www.coderholic.com/batch-image-processing-with-python/#comments</comments>
		<pubDate>Sat, 15 Nov 2008 14:42:04 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[image processing]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.dowling.me.uk/blog/?p=23</guid>
		<description><![CDATA[If you want to make changes to a single image, such as resizing or converting from one file format to another, then you&#8217;ll probably load up the image in an editor and manually make the required changes. This approach is great for a single image, but it doesn&#8217;t really scale past more than a few [...]]]></description>
			<content:encoded><![CDATA[<p>If you want to make changes to a single image, such as resizing or converting from one file format to another, then you&#8217;ll probably load up the image in an editor and manually make the required changes. This approach is great for a single image, but it doesn&#8217;t really scale past more than a few images, at which point it becomes time consuming, not to mention boring!</p>
<p>This is where Python and the <a href="http://www.pythonware.com/products/pil/">Python Imaging Library</a> (or PIL) come in, allowing you to write scripts that process images in batch. The <a href="http://www.coderholic.com/png2gif/">PNG2GIF</a> converter I wrote back in August is just one example of batch image processing using Python and PIL. In this post I&#8217;m going to explore some other uses, and provide lots of example code.</p>
<p><strong>Batch Processing</strong></p>
<p>No matter what processing we want to do on our images the script outline will be the same: loop over all provided arguments, and perform the processing. The code to do this is shown below:</p>
<pre name="code" class="python">
#!/usr/bin/env python
import sys
import Image

# Loop through all provided arguments
for i in range(1, len(sys.argv)):
	try:
		# Attempt to open an image file
		filepath = sys.argv[i]
		image = Image.open(filepath)
	except IOError, e:
		# Report error, and then skip to the next argument
		print "Problem opening", filepath, ":", e
		continue

	# Perform operations on the image here
</pre>
<p>This will allow our script to be called in all of the following ways:</p>
<blockquote><p>
batch_process.py image.gif<br />
batch_process.py image1.png image2.gif image3.jpg<br />
batch_process.py *.png<br />
batch_process.py image1.gif, *.png
</p></blockquote>
<p><strong>Processing</strong></p>
<p>With the help of PIL the image processing is really simple. Below is a collection of just some of the operations we could perform. For more details see the <a href="http://www.pythonware.com/library/pil/handbook/image.htm">PIL documentation</a>.</p>
<pre name="code" class="python">
# Resize an image
image = image.resize((width, height), Image.ANTIALIAS) 

# Convert to greyscale
image = image.convert('L')

# Blur
image = image.filter(ImageFilter.BLUR)

# Sharpen
image = image.filter(ImageFilter.SHARPEN)
</pre>
<p><strong>Saving</strong></p>
<p>Once we&#8217;ve processed the image we need to save the changes. In some instances we might just want to save over the original filename. If that&#8217;s the case we can just call the save method of image with its original filename. If we want to save the file under a different name, or as a different filetype we need to do a little more work:</p>
<pre name="code" class="python">
	# Split our original filename into name and extension
	(name, extension) = os.path.splitext(filepath)

	# Save with "_changed" added to the filename
	image.save(name + '_changed' + extension)

	# Save the image as a JPG
	image.save(name + '.jpg')
</pre>
<p>Notice in the last example how PIL takes care of the conversion to JPG for us. All we do is provide the file extension and PIL does the rest for us.</p>
<p><strong>A Complete Example</strong></p>
<p>Each of the steps above can easily be put together to create a batch image processing script. Below is a complete script which creates thumbnails of all provided images, and saves them as PNG images, not matter what their original format:</p>
<pre name="code" class="python">
#!/usr/bin/env python
# Batch thumbnail generation script using PIL

import sys
import os.path
import Image

thumbnail_size = (28, 28)

# Loop through all provided arguments
for i in range(1, len(sys.argv)):
	try:
		# Attempt to open an image file
		filepath = sys.argv[i]
		image = Image.open(filepath)
	except IOError, e:
		# Report error, and then skip to the next argument
		print "Problem opening", filepath, ":", e
		continue

	# Resize the image
	image = image.resize(thumbnail_size, Image.ANTIALIAS)

	# Split our original filename into name and extension
	(name, extension) = os.path.splitext(filepath)

	# Save the thumbnail as "(original_name)_thumb.png"
	image.save(name + '_thumb.png')
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/batch-image-processing-with-python/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>PyRadio 0.1 Released</title>
		<link>http://www.coderholic.com/pyradio-01-released/</link>
		<comments>http://www.coderholic.com/pyradio-01-released/#comments</comments>
		<pubDate>Thu, 23 Oct 2008 18:03:56 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=102</guid>
		<description><![CDATA[PyRadio 0.1 is now available! PyRadio is a curses based Internet radio player that makes it really simple to play music via the console. It&#8217;s written in Python, and uses mplayer for the media playback. The full source code is available via GitHub. I use Amarok for managing my media collection, and it comes with [...]]]></description>
			<content:encoded><![CDATA[<div style="float:right; padding: 10px;"><a href="http://www.coderholic.com/wp-content/uploads/pyradio.png"><img class="alignnone size-thumbnail wp-image-100" title="pyradio" src="http://www.coderholic.com/wp-content/uploads/pyradio-150x150.png" border="0" alt="" width="150" height="150" /></a></div>
<p><a href="http://www.coderholic.com/pyradio">PyRadio 0.1</a> is now available! PyRadio is a curses based Internet radio player that makes it really simple to play music via the console. It&#8217;s written in Python, and uses mplayer for the media playback. The full source code is available via <a href="http://github.com/coderholic/pyradio/tree/master">GitHub</a>.</p>
<p>I use <a href="http://amarok.kde.org/">Amarok</a> for managing my media collection, and it comes with excellent support for Internet radio. However, Amarok can be fairly resource intensive. That&#8217;s why I developed this extremely lightweight console based radio player to make it easy to listen to music without slowing my system down.</p>
<p>For the next release I&#8217;m planning to support easy addition and removal of radio stations. Currently you have to edit the actual code if you want to do that. If anyone finds this app useful and would like to request a feature then feel free to leave a comment, either here or on the <a href="http://www.coderholic.com/pyradio">PyRadio project page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/pyradio-01-released/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>10 Free Python Programming Books</title>
		<link>http://www.coderholic.com/free-python-programming-books/</link>
		<comments>http://www.coderholic.com/free-python-programming-books/#comments</comments>
		<pubDate>Sat, 23 Aug 2008 15:18:00 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[books]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=75</guid>
		<description><![CDATA[Below is a collection of 10 great Python programming books that are available online in full, completely free of charge: Dive into Python This is a fantastic book that is also available in print. It covers everything, from installing Python and the language&#8217;s syntax, right up to web services and unit testing. This is a [...]]]></description>
			<content:encoded><![CDATA[<p>Below is a collection of 10 great Python programming books that are available online in full, completely free of charge:</p>
<p><strong><a href="http://www.diveintopython.org/">Dive into Python</a></strong></p>
<p><a href="http://www.amazon.co.uk/gp/offer-listing/1590593561?ie=UTF8&amp;tag=coderholic-21&amp;linkCode=am2&amp;camp=1634&amp;creative=6738&amp;creativeASIN=1590593561"><img class="alignnone size-medium wp-image-76" style="float: left; margin-right: 5px; border:none;" title="diveintopython" src="http://www.coderholic.com/wp-content/uploads/2008/08/diveintopython.jpg" alt="" width="89" height="110" /></a></p>
<p>This is a fantastic book that is also <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.co.uk%2FDive-Into-Python-Mark-Pilgrim%2Fdp%2F1590593561%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1219497763%26sr%3D8-1&amp;tag=coderholic-20&amp;linkCode=ur2&amp;camp=1789&amp;creative=9325">available in print</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.com/e/ir?t=coderholic-20&amp;l=ur2&amp;o=1" border="0" alt="" width="1" height="1" />. It covers everything, from installing Python and the language&#8217;s syntax, right up to web services and <a href="http://site.typemock.com">unit testing</a>. This is a good book to learn from, but it&#8217;s also excellent to use a reference. I frequently find myself visiting the site! If you only read one book on this list make it this one.</p>
<p><a href="http://www.amazon.co.uk/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.co.uk%2FPython-Standard-Library-Nutshell-Handbooks%2Fdp%2F0596000960%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1219502286%26sr%3D8-1&amp;tag=coderholic-21&amp;linkCode=ur2&amp;camp=1634&amp;creative=6738"></a></p>
<p><strong style="clear: left;"><a href="http://www.pythonware.com/library/tkinter/introduction/index.htm">An Introduction to Tkinter</a></strong></p>
<p>Tkinter is a popular cross-platform Python GUI toolkit, and this book provides a good introduction with lots of examples. If you want to learn GUI development with Python then this book is a great place to start.</p>
<p><strong><a href="http://openbookproject.net//thinkCSpy/">How to think like a Computer Scientist</a></strong></p>
<p>This book uses Python to explain some Computer Science principals. It is full of examples, and each chapter has a collection of exercises for the reader to perform.</p>
<p><a href="http://effbot.org/librarybook/"><strong>The Standard Python Library</strong></a></p>
<p><a href="http://www.amazon.co.uk/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.co.uk%2FPython-Standard-Library-Nutshell-Handbooks%2Fdp%2F0596000960%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1219502286%26sr%3D8-1&amp;tag=coderholic-21&amp;linkCode=ur2&amp;camp=1634&amp;creative=6738"><img class="alignnone size-medium wp-image-78" style="border: none; margin-right: 5px; float: left;" title="stdlib" src="http://www.coderholic.com/wp-content/uploads/2008/08/stdlib.jpg" alt="" width="89" height="117" /></a></p>
<p><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.co.uk/e/ir?t=coderholic-21&amp;l=ur2&amp;o=2" border="0" alt="" width="1" height="1" /><br />
This book provides a detailed description and usage examples for all of the modules in Python&#8217;s standard library. This fantastic reference is <a href="http://www.amazon.co.uk/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.co.uk%2FPython-Standard-Library-Nutshell-Handbooks%2Fdp%2F0596000960%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1219502286%26sr%3D8-1&amp;tag=coderholic-21&amp;linkCode=ur2&amp;camp=1634&amp;creative=6738">available in print</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.co.uk/e/ir?t=coderholic-21&amp;l=ur2&amp;o=2" border="0" alt="" width="1" height="1" />.</p>
<p style="clear: left;"><strong><a href="http://pythonbook.coffeeghost.net/book1/index.html">Invent Your Own Computer Games with Python</a></strong></p>
<p>This book is aimed at novice programmers who are interested in writing simple computer games. Each chapter describes a different game and goes through the stages of design and development. A great book for beginners, but the book lacks more advanced content and doesn&#8217;t include any information about Python game development libraries such as <a href="http://www.pygame.org/news.html">PyGame</a>.</p>
<p><strong><a href="http://www.djangobook.com/en/1.0/">The Django Book</a></strong></p>
<p><a href="http://www.amazon.co.uk/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.co.uk%2FPro-Django-Development-Done-Right%2Fdp%2F1590597257%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1219500025%26sr%3D1-2&amp;tag=coderholic-21&amp;linkCode=ur2&amp;camp=1634&amp;creative=6738"><img class="alignnone size-medium wp-image-77" style="float: left; margin-right: 5px; border: none;" title="django" src="http://www.coderholic.com/wp-content/uploads/2008/08/django.jpg" alt="" width="84" height="110" /><br />
</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.co.uk/e/ir?t=coderholic-21&amp;l=ur2&amp;o=2" border="0" alt="" width="1" height="1" /><br />
Django is a Python web framework (similar to Ruby&#8217;s <a href="http://www.rubyonrails.org/">Rails</a>) which &#8220;encourages rapid development and clean, pragmatic design&#8221;. This book covers the framework in detail, and is a great place to start if you&#8217;re thinking about creating a dynamic website using Python. This book is also <a href="http://www.amazon.co.uk/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.co.uk%2FPro-Django-Development-Done-Right%2Fdp%2F1590597257%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1219500025%26sr%3D1-2&amp;tag=coderholic-21&amp;linkCode=ur2&amp;camp=1634&amp;creative=6738">available in print</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.co.uk/e/ir?t=coderholic-21&amp;l=ur2&amp;o=2" border="0" alt="" width="1" height="1" /></p>
<p><strong style="clear: left;"><a href="http://pylonsbook.com/">The Pylons Book</a></strong></p>
<p><a href="http://www.amazon.co.uk/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.co.uk%2FDefinitive-Guide-Pylons%2Fdp%2F1590599349%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1219499879%26sr%3D8-1&amp;tag=coderholic-21&amp;linkCode=ur2&amp;camp=1634&amp;creative=6738"></a></p>
<p><a href="http://www.amazon.co.uk/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.co.uk%2FDefinitive-Guide-Pylons%2Fdp%2F1590599349%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1219499879%26sr%3D8-1&amp;tag=coderholic-21&amp;linkCode=ur2&amp;camp=1634&amp;creative=6738"><img class="alignnone size-medium wp-image-78" style="border: none; margin-right: 5px; float: left;" title="stdlib" src="http://www.coderholic.com/wp-content/uploads/2008/08/pylons.jpg" alt="" width="89" height="117" /></a></p>
<p><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.co.uk/e/ir?t=coderholic-21&amp;l=ur2&amp;o=2" border="0" alt="" width="1" height="1" /></p>
<p>Pylons is another Python web framework. The book is structured in a very similar way to the Django book, and is worth reading if you&#8217;re looking for an alternative framework. This book is <a href="http://www.amazon.co.uk/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.co.uk%2FDefinitive-Guide-Pylons%2Fdp%2F1590599349%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1219499879%26sr%3D8-1&amp;tag=coderholic-21&amp;linkCode=ur2&amp;camp=1634&amp;creative=6738">available in print</a><img style="border:none !important; margin:0px !important;" src="http://www.assoc-amazon.co.uk/e/ir?t=coderholic-21&amp;l=ur2&amp;o=2" border="0" alt="" width="1" height="1" /> too.</p>
<p style="clear: left;"><strong><a href="http://www.brpreiss.com/books/opus7/html/">Data Structures and Algorithms with Object-Oriented Design Patterns in Python</a></strong></p>
<p>This book provides a thorough introduction to data structures and algorithms using Python. This is definitely not a book for those wishing to learn Python. However, if you want to learn about data structures and algorithms, or you just wish to learn about their implementation in Python, I can&#8217;t recommend this book enough.</p>
<p><strong><a href="http://homepage.mac.com/s_lott/books/python/pythonbook-2.5.html">Building Skills in Python</a></strong></p>
<p>This book consists of 42 chapters, each packed full of exercises designed to help you build Python programming skills. The book &#8220;includes six projects from straight-forward to sophisticated that will help     solidify your Python skills&#8221;. A great book for those that already know Python, but would like to become more proficient.</p>
<p><a href="http://homepage.mac.com/s_lott/books/oodesign.html"><strong>Building Skills in OO Design</strong></a></p>
<p>Written by the same author as the book above, this book follows the same format. This book focuses on object-oriented application design (using Python, of course) to help you to develop better programs.</p>
<p><strong>More free books&#8230;</strong></p>
<p>Above are just some examples of the books that you can find online. Back in January I posted a list of <a href="http://www.coderholic.com/free-computer-science-books/">free computer science books</a>, and I&#8217;ve managed to find lots more since then! I&#8217;ll post about them soon, so be sure to subscribe to my <a href="http://feeds.feedburner.com/coderholic">RSS feed</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/free-python-programming-books/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>PNG2GIF: Convert PNG images to GIF</title>
		<link>http://www.coderholic.com/png2gif/</link>
		<comments>http://www.coderholic.com/png2gif/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 20:45:16 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[image processing]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://www.coderholic.com/?p=72</guid>
		<description><![CDATA[The PNG image file format is vastly superior to GIF, supporting many more colours and better transparency. IE6, however, doesn&#8217;t support PNG transparency without the use of a browser specific hack. Therefore the easiest way to display partly transparent images across multiple browser without the use of a hack is to use a GIF image [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://en.wikipedia.org/wiki/Portable_Network_Graphics">PNG</a> image file format is vastly superior to <a href="http://en.wikipedia.org/wiki/GIF">GIF</a>, supporting many more colours and better transparency. IE6, however, doesn&#8217;t support PNG transparency without the use of a browser specific hack. Therefore the easiest way to display partly transparent images across multiple browser without the use of a hack is to use a GIF image instead.</p>
<p>The excellent set of free and widely used <a href="http://www.famfamfam.com/lab/icons/silk/">silk icons</a> from <a href="http://www.famfamfam.com">FAMFAMFAM</a> come as a set of over 700 PNG images, and I frequently found myself converting a few icons from PNG to GIF for a web project. Converting more than one or two images at a time quickly gets boring, so I created a Python command line utility, based on the code at <a href="http://nadiana.com/pil-tips-converting-png-gif">Nadia Alramli&#8217;s blog</a>, to perform the conversion automatically.</p>
<p>Creating GIF files from all the PNG images in the current directory becomes as simple as:</p>
<pre>png2gif *.png</pre>
<p>If you want to create the GIF images, and delete the PNG images then:</p>
<pre>png2gif -r *.png</pre>
<p>And if you&#8217;d like to output the GIF images to a different directory then:</p>
<pre>png2gif -o gifImages/ *.png</pre>
<p>To view a full list of supported options you can run png2gif with -h, which shows:</p>
<pre>Usage: png2gif [OPTIONS] &lt;files&gt;

Convert PNG images to GIF format

Options:
-h, --help            show this help message and exit
-o OUTPUTDIR, --outputdir=OUTPUTDIR
Set the output directory in which to put the GIF
images. Defaults to the current directory
-t THRESHOLD, --threshold=THRESHOLD
Set the transparency threshold. Defaults to 0
-r, --replace         Delete the PNG files after converting them to GIF
-v, --verbose         Verbose output</pre>
<p>You can download the utility here: <a href="http://www.coderholic.com/wp-content/uploads/2008/08/png2gif">png2gif</a></p>
<p>And you can also download the <a href="http://www.coderholic.com/wp-content/uploads/2008/08/silk-gif.zip">silk icons in GIF format</a>, as converted by PNG2GIF.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coderholic.com/png2gif/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
