<?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>Blogging to Nowhere &#187; Tips</title>
	<atom:link href="http://webworxshop.com/category/tips/feed" rel="self" type="application/rss+xml" />
	<link>http://webworxshop.com</link>
	<description>cat /dev/brain &#62; /dev/null</description>
	<lastBuildDate>Sat, 05 May 2012 21:57:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com" />
	<atom:link rel="hub" href="http://superfeedr.com/hubbub" />
			<item>
		<title>Using Android WebViews</title>
		<link>http://webworxshop.com/2011/03/10/using-android-webviews</link>
		<comments>http://webworxshop.com/2011/03/10/using-android-webviews#comments</comments>
		<pubDate>Wed, 09 Mar 2011 19:00:33 +0000</pubDate>
		<dc:creator>Rob Connolly</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[foss]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[SwallowCatcher]]></category>

		<guid isPermaLink="false">http://blog.webworxshop.com/?p=557</guid>
		<description><![CDATA[<p>Recently I&#8217;ve been working on show notes support for <a href="http://blog.webworxshop.com/projects/swallowcatcher">SwallowCatcher</a>. Since most podcast feeds include their show notes in the feed as embedded HTML I decided to render this HTML to display the show notes. This turned out to be ridiculously simple thanks to Android&#8217;s <a href="http://developer.android.com/reference/android/webkit/WebView.html">WebView</a> class. The API for rendering arbitrary HTML [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I&#8217;ve been working on show notes support for <a href="http://blog.webworxshop.com/projects/swallowcatcher">SwallowCatcher</a>. Since most podcast feeds include their show notes in the feed as embedded HTML I decided to render this HTML to display the show notes. This turned out to be ridiculously simple thanks to Android&#8217;s <a href="http://developer.android.com/reference/android/webkit/WebView.html">WebView</a> class. The API for rendering arbitrary HTML within your app is almost Pythonic in its simplicity. However, there are a couple of gotchas which caught me out, so I decided to cover them here.</p>
<p>I started out by creating a new Activity class and a layout XML file for it. The layout XML was taken almost directly from the Android <a href="http://developer.android.com/guide/webapps/webview.html">WebView Tutorial</a> page:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;WebView</span>  <span style="color: #000066;">xmlns:android</span>=<span style="color: #ff0000;">&quot;http://schemas.android.com/apk/res/android&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:id</span>=<span style="color: #ff0000;">&quot;@+id/shownotes&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:layout_width</span>=<span style="color: #ff0000;">&quot;fill_parent&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:layout_height</span>=<span style="color: #ff0000;">&quot;fill_parent&quot;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>In my Activity class the XML is loaded as normal. We also need to import the WebView class and the URLEncoder class. Additionally, the UnsupportedEncodingException class is required:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.webkit.WebView</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.net.URLEncoder</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.UnsupportedEncodingException</span><span style="color: #339933;">;</span></pre></div></div>

<p>Next, we need to encode the text in the correct format. Weirdly, WebView requires that the text is URL escaped, but without spaces converted to &#8216;+&#8217; symbols. I used URLEncoder to encode my content then replaced the &#8216;+&#8217; symbols with spaces. This probably isn&#8217;t perfect, but for my purposes it works.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #003399;">String</span> text <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;Content goes here!&lt;/body&gt;&lt;/html&gt;&quot;</span><span style="color: #339933;">;</span>
text <span style="color: #339933;">=</span> <span style="color: #003399;">URLEncoder</span>.<span style="color: #006633;">encode</span><span style="color: #009900;">&#40;</span>text, <span style="color: #0000ff;">&quot;utf-8&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
text <span style="color: #339933;">=</span> text.<span style="color: #006633;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'+'</span>, <span style="color: #0000ff;">' '</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Finally, we find the WebView from the XML and tell it to load the string as its content:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">WebView web <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>WebView<span style="color: #009900;">&#41;</span>findViewById<span style="color: #009900;">&#40;</span>R.<span style="color: #006633;">id</span>.<span style="color: #006633;">shownotes</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
web.<span style="color: #006633;">loadData</span><span style="color: #009900;">&#40;</span>text, <span style="color: #0000ff;">&quot;text/html&quot;</span>, <span style="color: #0000ff;">&quot;utf-8&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>All the above is encased in a try..catch statement for UnsupportedEncodingException, just in case the URLEncoder has a fit. That&#8217;s pretty much it. In SwallowCatcher the <a href="http://gitorious.org/swallowcatcher/swallowcatcher/blobs/master/src/com/webworxshop/swallowcatcher/ShowNotesActivity.java">ShowNotesActivity</a> is 56 lines, including all the verbose Java imports and bootstrapping and loading the content from the database via <a href="http://ormlite.sourceforge.net/">ORMLite</a>. </p>
<p>As a wise action hero (and ex-Jedi) once said, &#8220;I love it when a plan comes together&#8221;.</p>
 <p><a href="http://webworxshop.com/?flattrss_redirect&amp;id=557&amp;md5=e7c2d893c144f9ec607d2eb352f7c46b" title="Flattr" target="_blank"><img src="http://blog.webworxshop.com/wp-content/plugins/flattrss/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://webworxshop.com/2011/03/10/using-android-webviews/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=robconnolly&amp;popout=1&amp;url=http%3A%2F%2Fwebworxshop.com%2F2011%2F03%2F10%2Fusing-android-webviews&amp;language=en_GB&amp;category=text&amp;title=Using+Android+WebViews&amp;description=Recently+I%26%238217%3Bve+been+working+on+show+notes+support+for+SwallowCatcher.+Since+most+podcast+feeds+include+their+show+notes+in+the+feed+as+embedded+HTML+I+decided+to+render+this+HTML...&amp;tags=Android%2Cfoss%2Cjava%2CSwallowCatcher%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Quick QR Code Generation</title>
		<link>http://webworxshop.com/2011/03/09/quick-qr-code-generation</link>
		<comments>http://webworxshop.com/2011/03/09/quick-qr-code-generation#comments</comments>
		<pubDate>Tue, 08 Mar 2011 22:58:22 +0000</pubDate>
		<dc:creator>Rob Connolly</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[awesome]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[Fedora]]></category>
		<category><![CDATA[foss]]></category>
		<category><![CDATA[qrcode]]></category>

		<guid isPermaLink="false">http://blog.webworxshop.com/?p=552</guid>
		<description><![CDATA[<p><a href="https://secure.wikimedia.org/wikipedia/en/wiki/QR_Code">QR Codes</a> are a really easy way to share information between your desktop or laptop and a smartphone, which don&#8217;t have the privacy issues inherent in Google&#8217;s <a href="https://code.google.com/p/chrometophone/">Chrome To Phone</a>. The excellent FOSS <a href="http://code.google.com/p/zxing/">Barcode Scanner</a> app for Android makes scanning these codes and opening the scanned data a breeze. However, generating them [...]]]></description>
			<content:encoded><![CDATA[<p><a href="https://secure.wikimedia.org/wikipedia/en/wiki/QR_Code">QR Codes</a> are a really easy way to share information between your desktop or laptop and a smartphone, which don&#8217;t have the privacy issues inherent in Google&#8217;s <a href="https://code.google.com/p/chrometophone/">Chrome To Phone</a>. The excellent FOSS <a href="http://code.google.com/p/zxing/">Barcode Scanner</a> app for Android makes scanning these codes and opening the scanned data a breeze. However, generating them on the desktop can be a bit of a pain. There are several websites, browser addons and APIs for generating these codes, but up until now I haven&#8217;t found anything really quick and easy.</p>
<p>That is until today, when I discovered the &#8216;qrencode&#8217; utility. Qrencode does exactly what it says on the tin. It takes some text, encodes it as a QR Code and writes the result as a PNG file. It&#8217;s a simple command line tool, which opens up awesome scripting possibilities. </p>
<p>My use case is simply to send the URL of a web page that I&#8217;m viewing on my desktop to my phone, via QR Code. I found that qrencode was quite happy to write its output to stdout, which meant I could display the result directly using ImageMagick&#8217;s &#8216;display&#8217; command, e.g:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ qrencode http:<span style="color: #000000; font-weight: bold;">//</span>blog.webworxshop.com <span style="color: #660033;">-o</span> - <span style="color: #000000; font-weight: bold;">|</span> display</pre></div></div>

<p>You&#8217;ll notice that by default the QR Code is quite small. We can fix this by increasing the block size:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ qrencode http:<span style="color: #000000; font-weight: bold;">//</span>blog.webworxshop.com <span style="color: #660033;">-s</span> <span style="color: #000000;">10</span> <span style="color: #660033;">-o</span> - <span style="color: #000000; font-weight: bold;">|</span> display</pre></div></div>

<p>Next, I wanted to automatically pull the text to encode from somewhere to save typing &#8211; the clipboard was an ideal candidate. Enter &#8216;xclip&#8217;. Xclip is a command line utility to read and write from/to the X system&#8217;s built in clipboard. I used bash&#8217;s backtick command substitution to grab text from the clipboard and encode it:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ qrencode <span style="color: #000000; font-weight: bold;">`</span>xclip -o<span style="color: #000000; font-weight: bold;">`</span> <span style="color: #660033;">-s</span> <span style="color: #000000;">10</span> <span style="color: #660033;">-o</span> - <span style="color: #000000; font-weight: bold;">|</span> display</pre></div></div>

<p>And there you have it, a simple one line command to generate and display a QR Code from the contents of the clipboard. I created a bash script containing the command and assigned it to a keyboard shortcut in Gnome (Ctrl-Shift-Q), so that sharing URLs to my phone is as simple as selecting the text in the location bar and hitting Ctrl-C followed by Ctrl-Shift-Q.</p>
<p>If you want to give this a try, you&#8217;ll need to install the utilities discussed, in Fedora these can be installed with:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> yum <span style="color: #c20cb9; font-weight: bold;">install</span> qrencode xclip ImageMagick</pre></div></div>

<p>Enjoy!</p>
 <p><a href="http://webworxshop.com/?flattrss_redirect&amp;id=552&amp;md5=d83e1c544fe3e8d5e3a6824b95c0ec6c" title="Flattr" target="_blank"><img src="http://blog.webworxshop.com/wp-content/plugins/flattrss/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://webworxshop.com/2011/03/09/quick-qr-code-generation/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=robconnolly&amp;popout=1&amp;url=http%3A%2F%2Fwebworxshop.com%2F2011%2F03%2F09%2Fquick-qr-code-generation&amp;language=en_GB&amp;category=text&amp;title=Quick+QR+Code+Generation&amp;description=QR+Codes+are+a+really+easy+way+to+share+information+between+your+desktop+or+laptop+and+a+smartphone%2C+which+don%26%238217%3Bt+have+the+privacy+issues+inherent+in+Google%26%238217%3Bs+Chrome+To+Phone....&amp;tags=Android%2Cawesome%2Cbash%2CFedora%2Cfoss%2Cqrcode%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Unofficial Python Module of the Week #2: configobj</title>
		<link>http://webworxshop.com/2011/02/07/unofficial-python-module-of-the-week-2-configobj</link>
		<comments>http://webworxshop.com/2011/02/07/unofficial-python-module-of-the-week-2-configobj#comments</comments>
		<pubDate>Mon, 07 Feb 2011 02:23:07 +0000</pubDate>
		<dc:creator>Rob Connolly</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[configobj]]></category>
		<category><![CDATA[foss]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[upmotw]]></category>

		<guid isPermaLink="false">http://blog.webworxshop.com/?p=522</guid>
		<description><![CDATA[<p>Welcome to our third instalment of interesting Python modules. Unfortunately I&#8217;m a bit late with this section this week &#8211; in fact its next week already! The fourth instalment should be along towards the end of the week thus catching me up.</p> <p>Today we&#8217;re going to cover something which isn&#8217;t in the standard library, but [...]]]></description>
			<content:encoded><![CDATA[<p>Welcome to our third instalment of interesting Python modules. Unfortunately I&#8217;m a bit late with this section this week &#8211; in fact its <em>next</em> week already! The fourth instalment should be along towards the end of the week thus catching me up.</p>
<p>Today we&#8217;re going to cover something which isn&#8217;t in the standard library, but is nonetheless very useful. The module is <a href="http://www.voidspace.org.uk/python/configobj.html">configobj</a> which is used for reading from and writing to INI style configuration files files. A simple INI file is shown below:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #000099;">item1</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> value</span>
<span style="color: #000099;">item2</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> value2</span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span> section1 <span style="">&#93;</span></span>
<span style="color: #000099;">item1</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> value</span>
&nbsp;
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span><span style="">&#91;</span> subsection <span style="">&#93;</span><span style="">&#93;</span></span>
<span style="color: #000099;">item1</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> value</span></pre></div></div>

<p>In the above we can see the simple use of items, values sections and subsection. Subsections can be nested down as far a you want, but I don&#8217;t think most applications will need many more than two or three levels.</p>
<p><strong>Installation</strong></p>
<p>As this module isn&#8217;t in the standard library, we need to install it. On most Linux distros it should be in the package repositories, for example on Fedora 14:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> yum <span style="color: #c20cb9; font-weight: bold;">install</span> python-configobj</pre></div></div>

<p>Windows and Mac users can install from PyPi by following the <a href="http://www.voidspace.org.uk/python/configobj.html#installing">instructions</a> on the homepage.</p>
<p><strong>Basic Usage</strong></p>
<p>Reading from a configuration file with configobj couldn&#8217;t really be any simpler:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> configobj
config = configob.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span>filename<span style="color: black;">&#41;</span>
myoption = config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'item1'</span><span style="color: black;">&#93;</span>
mysectionoption = config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'section1'</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'item1'</span><span style="color: black;">&#93;</span>
mysubsectionoption = config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'section1'</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'subsection'</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'item1'</span><span style="color: black;">&#93;</span></pre></div></div>

<p>Basically, all you need to do is open a ConfigObj object by passing it a filename, then you just read from it as if its a dictionary object. Sections and subsections appear as nested dictionaries. Writing to the file is just as simple:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> configobj
config = configob.<span style="color: black;">ConfigObj</span><span style="color: black;">&#40;</span>filename<span style="color: black;">&#41;</span>
config<span style="color: black;">&#91;</span><span style="color: #483d8b;">'newoption'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'new stuff'</span>
config.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>No surprises here, you just write to it as if it were a dictionary. All you have to do it call the write() method when you&#8217;ve finished, in order to sync everything to disk.</p>
<p>That&#8217;s pretty much it for basic usage. There is much more you can do with configobj, including advanced stuff like validation of configuration files. Check out the <a href="http://www.voidspace.org.uk/python/configobj.html">documentation</a> for more info.</p>
 <p><a href="http://webworxshop.com/?flattrss_redirect&amp;id=522&amp;md5=446f568352a6df7a758ed067502cfe4b" title="Flattr" target="_blank"><img src="http://blog.webworxshop.com/wp-content/plugins/flattrss/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://webworxshop.com/2011/02/07/unofficial-python-module-of-the-week-2-configobj/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=robconnolly&amp;popout=1&amp;url=http%3A%2F%2Fwebworxshop.com%2F2011%2F02%2F07%2Funofficial-python-module-of-the-week-2-configobj&amp;language=en_GB&amp;category=text&amp;title=Unofficial+Python+Module+of+the+Week+%232%3A+configobj&amp;description=Welcome+to+our+third+instalment+of+interesting+Python+modules.+Unfortunately+I%26%238217%3Bm+a+bit+late+with+this+section+this+week+%26%238211%3B+in+fact+its+next+week+already%21+The+fourth+instalment+should...&amp;tags=configobj%2Cfoss%2Cpython%2Cupmotw%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Unofficial Python Module of the Week #1: shelve</title>
		<link>http://webworxshop.com/2011/01/28/unofficial-python-module-of-the-week-1-shelve</link>
		<comments>http://webworxshop.com/2011/01/28/unofficial-python-module-of-the-week-1-shelve#comments</comments>
		<pubDate>Thu, 27 Jan 2011 21:06:17 +0000</pubDate>
		<dc:creator>Rob Connolly</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[foss]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[shelve]]></category>
		<category><![CDATA[upmotw]]></category>

		<guid isPermaLink="false">http://blog.webworxshop.com/?p=494</guid>
		<description><![CDATA[<p>Here we are, the second Unofficial Python Module of the Week. Yes, the second &#8211; we started from zero (obviously!). This week we are covering the shelve module. Shelve provides you with a very simple Python object store. You can use it where you need quick persistent storage of objects between program runs, it&#8217;s much [...]]]></description>
			<content:encoded><![CDATA[<p>Here we are, the second Unofficial Python Module of the Week. Yes, the second &#8211; we started from zero (obviously!). This week we are covering the shelve module. Shelve provides you with a very simple Python object store. You can use it where you need quick persistent storage of objects between program runs, it&#8217;s much less overhead than using a database &#8211; even SQLite. Anyway, lets dive straight into it:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">shelve</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> shelf = <span style="color: #dc143c;">shelve</span>.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;myshelf.db&quot;</span>, writeback=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Here we import the shelve module (its in the standard library, so there&#8217;s no installation required). Then we open our persistent object store, supplying the filename that we want to store the objects in and the writeback parameter, which allows mutable objects to be stored more conveniently (otherwise they are only written when an assignment is performed). The writeback parameter also causes data to be cached in memory, which can be quite memory intensive, so you should call shelf.sync() every so on to flush everything to disk.</p>
<p>You can store anything that can be handled by the Python pickle module in a shelf:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> shelf<span style="color: black;">&#91;</span><span style="color: #483d8b;">'thedict'</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'one'</span>: <span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'two'</span>: <span style="color: #ff4500;">2</span>, <span style="color: #483d8b;">'three'</span>: <span style="color: #ff4500;">3</span><span style="color: black;">&#125;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> shelf.<span style="color: black;">sync</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>As you can see, using a shelf is just like using a dictionary. The only real limit is that the keys must be strings. You can also read back values from the shelf as with a dictionary:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>shelf<span style="color: black;">&#91;</span><span style="color: #483d8b;">'thedict'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#123;</span><span style="color: #483d8b;">'one'</span>: <span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'two'</span>: <span style="color: #ff4500;">2</span>, <span style="color: #483d8b;">'three'</span>: <span style="color: #ff4500;">3</span><span style="color: black;">&#125;</span></pre></div></div>

<p>That&#8217;s just about it, just remember to close the shelf when you&#8217;re finished with it:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> shelf.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>If you want to find out more have a look at the official <a href="http://docs.python.org/library/shelve.html">Python docs for shelve</a> and <a href="http://www.doughellmann.com/PyMOTW/shelve/index.html">Doug Hellmann&#8217;s PyMOTW posting on the subject</a>.</p>
 <p><a href="http://webworxshop.com/?flattrss_redirect&amp;id=494&amp;md5=e18e4bf391c877fa1f5cd8df20ff844f" title="Flattr" target="_blank"><img src="http://blog.webworxshop.com/wp-content/plugins/flattrss/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://webworxshop.com/2011/01/28/unofficial-python-module-of-the-week-1-shelve/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=robconnolly&amp;popout=1&amp;url=http%3A%2F%2Fwebworxshop.com%2F2011%2F01%2F28%2Funofficial-python-module-of-the-week-1-shelve&amp;language=en_GB&amp;category=text&amp;title=Unofficial+Python+Module+of+the+Week+%231%3A+shelve&amp;description=Here+we+are%2C+the+second+Unofficial+Python+Module+of+the+Week.+Yes%2C+the+second+%26%238211%3B+we+started+from+zero+%28obviously%21%29.+This+week+we+are+covering+the+shelve+module.+Shelve+provides...&amp;tags=foss%2Cpython%2Cshelve%2Cupmotw%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Unofficial Python Module of the Week #0: argparse</title>
		<link>http://webworxshop.com/2011/01/20/python-module-of-the-week-0-argparse</link>
		<comments>http://webworxshop.com/2011/01/20/python-module-of-the-week-0-argparse#comments</comments>
		<pubDate>Wed, 19 Jan 2011 19:00:19 +0000</pubDate>
		<dc:creator>Rob Connolly</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[argparse]]></category>
		<category><![CDATA[awesome]]></category>
		<category><![CDATA[foss]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[upmotw]]></category>

		<guid isPermaLink="false">http://blog.webworxshop.com/?p=437</guid>
		<description><![CDATA[<p>[EDIT: This series has been renamed so as not to conflict with Doug Hellman's excellent Python Module of the Week series. See UPMotW #1 for details]</p> <p>I&#8217;m going to try something different today. This is going to be the first in a series (hopefully once weekly) of Python Modules of the Week. This has probably [...]]]></description>
			<content:encoded><![CDATA[<p><em>[EDIT: This series has been renamed so as not to conflict with Doug Hellman's excellent Python Module of the Week series. See UPMotW #1 for details]</em></p>
<p><em>I&#8217;m going to try something different today. This is going to be the first in a series (hopefully once weekly) of Python Modules of the Week. This has probably been done to death elsewhere, but I&#8217;m using it as an opportunity to learn some</em> <em>more Python</em> <em>and to cement some of these modules in my mind.</em></p>
<p><a href="http://docs.python.org/library/argparse.html">Argparse</a> is a Python module for processing command line arguments. It&#8217;s new in version 2.7 and is designed to replace the <a href="http://docs.python.org/library/optparse.html">Optparse</a> module. I&#8217;m not sure what the rationale for the change was as the two modules look very similar to me. However, it suffices to say that you should use argparse in all new code.</p>
<p>The main class of argparse is called ArgumentParser, it allows you to add arguments to your program and parse the provided arguments at runtime:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #dc143c;">parser</span> = argparse.<span style="color: black;">ArgumentParser</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">parser</span>.<span style="color: black;">add_argument</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;-v&quot;</span>, <span style="color: #483d8b;">&quot;--verbose&quot;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># a flag type argument</span>
<span style="color: #dc143c;">parser</span>.<span style="color: black;">add_argument</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;value&quot;</span>, <span style="color: #008000;">type</span>=<span style="color: #008000;">int</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># an integer positional argument</span>
...
<span style="color: black;">args</span> = <span style="color: #dc143c;">parser</span>.<span style="color: black;">parse_args</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># parse the args from sys.argv</span>
<span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">&#40;</span>args.<span style="color: black;">value</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># arguments accessed as data members</span></pre></td></tr></table></div>

<p>You can also add meta-data such as help and descriptions to your arguments via keyword arguments to many of the methods. Take a look at the <a href="http://docs.python.org/library/argparse.html">module documentation</a> for examples. Once nice thing is that when you provide this data, argparse automatically generates the -h and &#8211;help flags and populates them with nicely formatted help output using the info you provide.</p>
<p>The argument parsing provided by argparse allows you to create some very complex command line interfaces to your scripts. I especially like the <a href="http://docs.python.org/library/argparse.html#sub-commands">sub-commands</a> framework, which allows each sub-command to exist as its own separate entity with its own options and help information. To create an argument parser with a sub-command is just a few lines:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #dc143c;">parser</span> = argparse.<span style="color: black;">ArgumentParser</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
subcommands = <span style="color: #dc143c;">parser</span>.<span style="color: black;">add_subparsers</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
mysubcommand = subcommands.<span style="color: black;">add_parser</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'mysubcommand'</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Of course,each sub-command is an ArgumentParser in its own right, so you can add all the options that you normally would, including command line flags, positional arguments and help information. Also each sub-command will be listed in the help and will also have its own help page which can be accessed via:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>pyprog.py subcommand <span style="color: #660033;">--help</span></pre></td></tr></table></div>

<p>All in all, this is a very useful Python module to know about. Its ease of use and the number of things it &#8216;just takes care of&#8217; make it a pleasure to use. Hopefully it&#8217;ll have you writing nice command line interfaces to all those hacked together scripts that are currently controlled by commenting bits of them in and out!</p>
 <p><a href="http://webworxshop.com/?flattrss_redirect&amp;id=437&amp;md5=91c03113256d93a0dc851c4079a5dbb4" title="Flattr" target="_blank"><img src="http://blog.webworxshop.com/wp-content/plugins/flattrss/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://webworxshop.com/2011/01/20/python-module-of-the-week-0-argparse/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=robconnolly&amp;popout=1&amp;url=http%3A%2F%2Fwebworxshop.com%2F2011%2F01%2F20%2Fpython-module-of-the-week-0-argparse&amp;language=en_GB&amp;category=text&amp;title=Unofficial+Python+Module+of+the+Week+%230%3A+argparse&amp;description=%5BEDIT%3A+This+series+has+been+renamed+so+as+not+to+conflict+with+Doug+Hellman%27s+excellent+Python+Module+of+the+Week+series.+See+UPMotW+%231+for+details%5D+I%26%238217%3Bm+going+to+try...&amp;tags=argparse%2Cawesome%2Cfoss%2Cpython%2Cupmotw%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Calculating Alcohol By Volume in Python on Android</title>
		<link>http://webworxshop.com/2011/01/12/calculating-alcohol-by-volume-in-python-on-android</link>
		<comments>http://webworxshop.com/2011/01/12/calculating-alcohol-by-volume-in-python-on-android#comments</comments>
		<pubDate>Wed, 12 Jan 2011 02:14:22 +0000</pubDate>
		<dc:creator>Rob Connolly</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[abv]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[foss]]></category>
		<category><![CDATA[homebrew]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[specific gravity]]></category>

		<guid isPermaLink="false">http://blog.webworxshop.com/?p=359</guid>
		<description><![CDATA[<p>Wow, I just managed to combine three of my favourite things in a single title! Recently, I&#8217;ve been getting further into home brewing, with a book I received as a Christmas present (<a href="http://thenile.co.nz/books/Roy-Elkins/Home-Brewed-Beers-and-Stouts/9781854861238/">Home Brewed Beers and Stouts, by C.J.J. Berry</a>). Since I&#8217;d never actually measured the <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Abv">Alcohol By Volume</a> (ABV) of my beer [...]]]></description>
			<content:encoded><![CDATA[<p>Wow, I just managed to combine three of my favourite things in a single title! Recently, I&#8217;ve been getting further into home brewing, with a book I received as a Christmas present (<a href="http://thenile.co.nz/books/Roy-Elkins/Home-Brewed-Beers-and-Stouts/9781854861238/">Home Brewed Beers and Stouts, by C.J.J. Berry</a>). Since I&#8217;d never actually measured the <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Abv">Alcohol By Volume</a> (ABV) of my beer I decided to write some Python code to automate the process. The simple modules I came up with work from the command line and also on Android phones via <a href="https://code.google.com/p/android-scripting/">SL4A</a>, which makes them very useful when doing quick measurements.</p>
<p>Measuring ABV involves taking <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Abv">Specific Gravity</a> (SG) measurements at the start and end of fermentation, adjusting them for temperature and pushing them into a simple formula. The SG measurements are taken with a <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Hydrometer">Hydrometer</a>, which is supposed to read at 20C (hence the need to adjust for other temperatures).</p>
<p>The temperature adjustment is done via a simple table (which I took from the book). In the script I used <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Linear_interpolation">Linear Interpolation</a>, to adapt it for values which weren&#8217;t available in the table. Initially I used the numpy.interp() function. However, I found that numpy isn&#8217;t present in SL4A and that installing it would be a pain since it is a C module which would need cross compiling for Android.</p>
<p>I therefore wrote my own interp() function, which keeps the same interface:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> interp<span style="color: black;">&#40;</span>x, xp, fp<span style="color: black;">&#41;</span>:
    i = <span style="color: #ff4500;">0</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> p <span style="color: #ff7700;font-weight:bold;">in</span> xp:
        <span style="color: #ff7700;font-weight:bold;">if</span> p <span style="color: #66cc66;">&gt;</span> x:
            i = xp.<span style="color: black;">index</span><span style="color: black;">&#40;</span>p<span style="color: black;">&#41;</span> - <span style="color: #ff4500;">1</span>
            <span style="color: #ff7700;font-weight:bold;">break</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>x - xp<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">*</span>fp<span style="color: black;">&#91;</span>i+<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> + <span style="color: black;">&#40;</span>xp<span style="color: black;">&#91;</span>i+<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> - x<span style="color: black;">&#41;</span><span style="color: #66cc66;">*</span>fp<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> / <span style="color: black;">&#40;</span>xp<span style="color: black;">&#91;</span>i+<span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> - xp<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>I split up the code into two separate modules, sg.py (which just does specific gravity adjustment) and abv.py (which does ABV calualation). Splitting the code up enables me to take SG measurements and adjust based on temperature, without doing a full ABV measurement. In sg.py the reverse adjusted SG is what you would need to read from the hydrometer at the specified temperature, in order to achieve the adjusted reading you specified.</p>
<p>Since the calculations are fairly trivial the main bulk of the code is in the user interfaces. I implemented a simple command line interface which either takes arguments from the command line, or prompts the user via the python input() function. I also use the SL4A API to implement a simple UI for Android, basically the user is prompted for each quantity by a dialog box.</p>
<p>Anyway, there&#8217;s not much else to say, except that <a href="http://gitorious.org/python-tools">I&#8217;ve put the code up on Gitorious</a> for anyone who wants it (it&#8217;s licenced <a href="http://www.gnu.org/licenses/agpl-3.0.html">AGPL</a>). The code is in a git repository for useful Python scripts I&#8217;ve written, right now it&#8217;s the only thing there, but I&#8217;m going to track down some of the scripts I&#8217;ve written over the years and add them too &#8211; I might even get a few blog posts out of some of them!</p>
 <p><a href="http://webworxshop.com/?flattrss_redirect&amp;id=359&amp;md5=87f7a5d11cfe2ba7b01b675dc7ce6731" title="Flattr" target="_blank"><img src="http://blog.webworxshop.com/wp-content/plugins/flattrss/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://webworxshop.com/2011/01/12/calculating-alcohol-by-volume-in-python-on-android/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=robconnolly&amp;popout=1&amp;url=http%3A%2F%2Fwebworxshop.com%2F2011%2F01%2F12%2Fcalculating-alcohol-by-volume-in-python-on-android&amp;language=en_GB&amp;category=text&amp;title=Calculating+Alcohol+By+Volume+in+Python+on+Android&amp;description=Wow%2C+I+just+managed+to+combine+three+of+my+favourite+things+in+a+single+title%21+Recently%2C+I%26%238217%3Bve+been+getting+further+into+home+brewing%2C+with+a+book+I+received+as+a...&amp;tags=abv%2CAndroid%2Cfoss%2Chomebrew%2Cpython%2Cspecific+gravity%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Playing with Python Generators</title>
		<link>http://webworxshop.com/2010/08/30/playing-with-python-generators</link>
		<comments>http://webworxshop.com/2010/08/30/playing-with-python-generators#comments</comments>
		<pubDate>Mon, 30 Aug 2010 08:12:55 +0000</pubDate>
		<dc:creator>Rob Connolly</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[awesome]]></category>
		<category><![CDATA[foss]]></category>
		<category><![CDATA[generator]]></category>
		<category><![CDATA[list comprehension]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.webworxshop.com/?p=266</guid>
		<description><![CDATA[<p>Today I&#8217;ve been playing with <a href="http://docs.python.org/tutorial/classes.html#generators">generators</a> in <a href="http://python.org">Python</a>. I have to say they are yet another awesome Python feature! They give you a very cool and efficient way to store some state within a function, this is useful if you&#8217;re trying to do something like generating a sequence, which you would otherwise need [...]]]></description>
			<content:encoded><![CDATA[<p>Today I&#8217;ve been playing with <a href="http://docs.python.org/tutorial/classes.html#generators">generators</a> in <a href="http://python.org">Python</a>. I have to say they are yet another awesome Python feature! They give you a very cool and efficient way to store some state within a function, this is useful if you&#8217;re trying to do something like generating a sequence, which you would otherwise need a class for. I&#8217;m going to go over a couple of quick examples here in order to demonstrate what generators are and what you can do with them.</p>
<p><em>Side note: You need Python 2.4 or above to use generators, you&#8217;ll probably have this anyway, but it might pay to check before wondering why this stuff doesn&#8217;t work.</em></p>
<p><strong>A Quick Introduction</strong></p>
<p>At it&#8217;s heart a generator is a function which can return a value several times within it&#8217;s body. Each time the function is called it resumes from where it terminated in the previous call, with all it&#8217;s internal state intact (i.e. variables are held between calls). In Python a generator is defined by creating a function which uses the &#8216;yield&#8217; keyword. Each time that a yield is hit the function will return the specified value. Let&#8217;s start with an example which defines a generator implementation of the built-in &#8216;range&#8217; function:</p>
<p><code>def genrange(start, end):<br />
&nbsp;&nbsp;&nbsp;&nbsp;i = start<br />
&nbsp;&nbsp;&nbsp;&nbsp;while i &lt; end:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield i<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i += 1</code></p>
<p>As you can see this is incredibly simple and behaves in the same way as the standard range function. The only difference is that when the generator method is called it will return a generator object rather than a value (in contrast to range, which will return a list of values in the range). These generator objects are iteratable so calling the &#8216;next&#8217; method on the object will run your code and return the next yielded value. Because the generator object is iteratable, the way in which you are likely to use it should look familiar:</p>
<p><code>for i in genrange(0, 10):<br />
&nbsp;&nbsp;&nbsp;&nbsp;print i</code></p>
<p>If you want to go ahead and create a list from the sequence as you generate it, you can use a <a href="http://www.secnetix.de/olli/Python/list_comprehensions.hawk">list comprehension</a>, like so:</p>
<p><code>l = [i for i in genrange(0, 10)]</code></p>
<p>Of course, as hist comprehensions can be much more complicated than this you can use it to achieve more than just creating the equivalent list as calling the built-in range function. For example, you could filter the output elements according to some criteria, or call a method on each element returned.</p>
<p><strong>A Trade Off</strong></p>
<p>Although the above example is incredibly simple, it presents an interesting trade off between memory use and the speed of iteration through the &#8216;list&#8217;. The trade off exists because you could just build the list of elements in a separate function and then iterate through it. This is a perfectly valid approach but if there are a large number of elements you will use a significant quantity of memory to store the list. You are also more likely to double handle the data, unless you are building the list up over a period of time. Using a generator in this case is likely to be more efficient, as you are just creating the elements as you need them, so only storing a minimal amount of data at any one time.</p>
<p>The other side of the trade off is performance. If the process that produces your iterative data is computationally expensive, it makes no sense to calculate more values than you will need. So if you have a data processing loop, that can potentially exit early (i.e. before reaching the end of the &#8216;list&#8217;) a generator will be more efficient. But equally, if you require a tight loop which iterates quickly, you would want to pre-compute the values.</p>
<p>When considering using generators you should weigh up these factors and think which method is going to be most efficient for your situation. I think in a lot of cases, you will end up coming down in favour of the generator solution.</p>
<p><strong>Another Example (Dan Brown is going to love me)</strong></p>
<p>I&#8217;m going to leave you with another quick example, namely a very efficient way of generating Fibonacci numbers using a generator. Without further ado:</p>
<p><code>def fibonacci():<br />
&nbsp;&nbsp;&nbsp;&nbsp;p1 = 0<br />
&nbsp;&nbsp;&nbsp;&nbsp;p2 = 1<br />
&nbsp;&nbsp;&nbsp;&nbsp;while True:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f = p1 + p2<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p2 = p1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p1 = f<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield f</code></p>
<p>There you go, easy. Many other Fibonacci implementations use a recursive method, which is horribly inefficient. Most other implementations will require either a class to store persistent data in, or the use of static variables, both of which are more tricky to handle from a programming point of view.</p>
<p>Well that&#8217;s it. I think I&#8217;ve demonstrated that generators are pretty cool. The examples I&#8217;ve presented are very simplistic, but I&#8217;m sure you can think of awesome uses for them. Go forth and code!</p>
 <p><a href="http://webworxshop.com/?flattrss_redirect&amp;id=266&amp;md5=72107822bf78f0db240c0292d84185a1" title="Flattr" target="_blank"><img src="http://blog.webworxshop.com/wp-content/plugins/flattrss/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://webworxshop.com/2010/08/30/playing-with-python-generators/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=robconnolly&amp;popout=1&amp;url=http%3A%2F%2Fwebworxshop.com%2F2010%2F08%2F30%2Fplaying-with-python-generators&amp;language=en_GB&amp;category=text&amp;title=Playing+with+Python+Generators&amp;description=Today+I%26%238217%3Bve+been+playing+with+generators+in+Python.+I+have+to+say+they+are+yet+another+awesome+Python+feature%21+They+give+you+a+very+cool+and+efficient+way+to+store...&amp;tags=awesome%2Cfoss%2Cgenerator%2Clist+comprehension%2Cpython%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Denting via Android Intents</title>
		<link>http://webworxshop.com/2010/05/30/denting-via-android-intents</link>
		<comments>http://webworxshop.com/2010/05/30/denting-via-android-intents#comments</comments>
		<pubDate>Sun, 30 May 2010 01:01:36 +0000</pubDate>
		<dc:creator>Rob Connolly</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[awesome]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[foss]]></category>
		<category><![CDATA[identi.ca]]></category>
		<category><![CDATA[Intent]]></category>
		<category><![CDATA[Mustard]]></category>

		<guid isPermaLink="false">http://blog.webworxshop.com/?p=215</guid>
		<description><![CDATA[<p>This is just a quick post to share something cool that I was playing with the other day. I was wondering if it was possible to send a message from an Android application via the <a href="http://mustard.macno.org">Mustard</a> <a href="http://identi.ca">identi.ca</a> client. It turns out it is, and here&#8217;s how you do it:</p> <p>Intent i = new [...]]]></description>
			<content:encoded><![CDATA[<p>This is just a quick post to share something cool that I was playing with the other day. I was wondering if it was possible to send a message from an Android application via the <a href="http://mustard.macno.org">Mustard</a> <a href="http://identi.ca">identi.ca</a> client. It turns out it is, and here&#8217;s how you do it:</p>
<p><code>Intent i = new Intent(Intent.ACTION_SEND);<br />
i.setType("text/plain");<br />
i.putExtra(Intent.EXTRA_TEXT, "Testing intents on android");<br />
startActivity(i);</code></p>
<p>These four lines of code hook into a key feature of the Android platform: Intents. The intent system is a neat way of communicating via apps and enables different apps to integrate together without knowing about each other specifically.</p>
<p>In this case, we are sending the ACTION_SEND intent, which Mustard is set up to handle. We set the mime-type of the message to &#8216;text/plain&#8217; and put the contents of our message into the EXTRA_TEXT field. We then start the intent, and we&#8217;re done!</p>
<p>When the intent is started Android presents the user with a list of all the possible applications which can handle the ACTION_SEND intent. In my case this is Email, Gmail, Messaging and Mustard, when I select  mustard the new message screen pops up and is populated with my message content. Hitting send posts the message and returns control to my app. Neat!</p>
<p>There are probably a whole host of ways you can integrate your apps with other apps on the phone using the intents system, I guess it&#8217;s just a matter of knowing what intents are received by each app and what they do.</p>
<p>Thanks to <a href="http://identi.ca/macno">@macno</a> (main developer of Mustard) and <a href="http://identi.ca/bugabundo">@bugabundo</a> on identi.ca for their help working this out!</p>
<p>Anyway, I hope someone finds this useful. This is the first time I&#8217;ve posted about Android development, but I&#8217;ll hopefully write more about it in the future. Bye for now!</p>
 <p><a href="http://webworxshop.com/?flattrss_redirect&amp;id=215&amp;md5=3173eabccfd10fb41128a9c0bce6b90a" title="Flattr" target="_blank"><img src="http://blog.webworxshop.com/wp-content/plugins/flattrss/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://webworxshop.com/2010/05/30/denting-via-android-intents/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=robconnolly&amp;popout=1&amp;url=http%3A%2F%2Fwebworxshop.com%2F2010%2F05%2F30%2Fdenting-via-android-intents&amp;language=en_GB&amp;category=text&amp;title=Denting+via+Android+Intents&amp;description=This+is+just+a+quick+post+to+share+something+cool+that+I+was+playing+with+the+other+day.+I+was+wondering+if+it+was+possible+to+send+a+message+from...&amp;tags=Android%2Cawesome%2CDevelopment%2Cfoss%2Cidenti.ca%2CIntent%2CMustard%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Online Filesystem Resizing with LVM</title>
		<link>http://webworxshop.com/2009/10/10/online-filesystem-resizing-with-lvm</link>
		<comments>http://webworxshop.com/2009/10/10/online-filesystem-resizing-with-lvm#comments</comments>
		<pubDate>Fri, 09 Oct 2009 23:45:27 +0000</pubDate>
		<dc:creator>Rob Connolly</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[crunchbang]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[ext4]]></category>
		<category><![CDATA[foss]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[LVM]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.webworxshop.com/?p=134</guid>
		<description><![CDATA[<p>I use LVM on my main desktop machine. This is awesome because it allows me to dynamically allocate space to partitions as I choose, however I always forget how to do a resize, so I&#8217;m going to write it down here. This isn&#8217;t going to be a full LVM tutorial (there&#8217;s plenty of material out [...]]]></description>
			<content:encoded><![CDATA[<p>I use LVM on my main desktop machine. This is awesome because it allows me to dynamically allocate space to partitions as I choose, however I always forget how to do a resize, so I&#8217;m going to write it down here. This isn&#8217;t going to be a full LVM tutorial (there&#8217;s plenty of material out there for that), although maybe that&#8217;s an idea for the future.</p>
<p>The following commands will resize an ext2, ext3, or ext4 filesystem running on LVM while it is mounted:</p>
<p><code>$ sudo lvresize -L +XXG &lt;path to fs device&gt;</code><br />
<code>$ sudo resize2fs &lt;path to fs device&gt;</code></p>
<p>In the above command you need to replace XX with the number of GB you want the filesystem to grow by and &lt;path to fs device&gt; by the device node (typically /dev/mapper/something).</p>
<p>An there you have it, done! Obviously there is a huge amount more you can do with the two tools above, take a look at their man pages for more info.</p>
<p>Hopefully this post will save me from having to work out how to do this every time!</p>
 <p><a href="http://webworxshop.com/?flattrss_redirect&amp;id=134&amp;md5=359c7a4e80be394bc6359315f52b0228" title="Flattr" target="_blank"><img src="http://blog.webworxshop.com/wp-content/plugins/flattrss/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://webworxshop.com/2009/10/10/online-filesystem-resizing-with-lvm/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=robconnolly&amp;popout=1&amp;url=http%3A%2F%2Fwebworxshop.com%2F2009%2F10%2F10%2Fonline-filesystem-resizing-with-lvm&amp;language=en_GB&amp;category=text&amp;title=Online+Filesystem+Resizing+with+LVM&amp;description=I+use+LVM+on+my+main+desktop+machine.+This+is+awesome+because+it+allows+me+to+dynamically+allocate+space+to+partitions+as+I+choose%2C+however+I+always+forget+how+to...&amp;tags=crunchbang%2Cdebian%2Cext4%2Cfoss%2Clinux%2CLVM%2Cubuntu%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Quickly change Debian repositories</title>
		<link>http://webworxshop.com/2009/06/03/quickly-change-debian-repositories</link>
		<comments>http://webworxshop.com/2009/06/03/quickly-change-debian-repositories#comments</comments>
		<pubDate>Wed, 03 Jun 2009 08:30:30 +0000</pubDate>
		<dc:creator>Rob Connolly</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[apt]]></category>
		<category><![CDATA[awesome]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[foss]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[UoA]]></category>

		<guid isPermaLink="false">http://blog.webworxshop.com/?p=82</guid>
		<description><![CDATA[<p>Apt is awesome. Plain and simple.</p> <p>But it is kinda static. By this I mean it&#8217;s not particularly suited to environments where things change frequently. For example, we have a local mirror at uni, which of course it much faster than using the external Ubuntu or Debian ones, however as this is only available from [...]]]></description>
			<content:encoded><![CDATA[<p>Apt is awesome. Plain and simple.</p>
<p>But it is kinda static. By this I mean it&#8217;s not particularly suited to environments where things change frequently. For example, we have a local mirror at uni, which of course it much faster than using the external Ubuntu or Debian ones, however as this is only available from internal University of Auckland IP addresses I would have to change my /etc/apt/sources.list file if I wanted to install something from home.</p>
<p>Today I knocked together a quick Python script to fix this, all it does is basically manipulate a symlink which points to the real /etc/apt/sources.list file, but I thought I&#8217;d share it anyway:<span id="more-82"></span></p>
<p><code>#!/usr/bin/env python<br />
import sys, os<br />
def usage():<br />
print "Usage: %s " % (sys.argv[0],)<br />
def main(argv):<br />
if argv[1] != None:<br />
sources_path = "/etc/apt/sources.list.%s" % (argv[1],)<br />
if os.path.exists(sources_path):<br />
os.unlink("/etc/apt/sources.list")<br />
os.symlink(sources_path, "/etc/apt/sources.list")<br />
print "SUCCESS: Don't for get to run 'sudo apt-get update'"<br />
return 0<br />
else:<br />
print "ERROR: Unknown repository set '%s'" % (argv[1],)<br />
usage()<br />
else:<br />
usage()<br />
return 1<br />
if __name__ == '__main__':<br />
sys.exit(main(sys.argv))</code></p>
<p>Unfortunately wordpress screwed with my formatting there (which kinda matters in a python script) so here is the file (<a href="http://blog.webworxshop.com/wp-content/uploads/2009/06/repo-switch.py">repo-switch.py</a>). You&#8217;ll need to download it and put it somewhere in your $PATH. Then make it execuatable:</p>
<p><code>chmod +x repo-switch.py</code></p>
<p>The next step is to set up your lists of repositories. Each list will have a suffix which the script will use to identify it. First I copied my main repositories (for the NZ Ubuntu mirrors):</p>
<p><code>sudo cp /etc/apt/sources.list /etc/apt/sources.list.nz</code></p>
<p>Obviously replace &#8216;nz&#8217; with a suffix of your choice. Then I dropped the list of repos for the local mirror into another file (in my case /etc/apt/sources.list.ece). You can set up as many different sets as you like, but I only need two.</p>
<p>Next step is to practice switching between them:</p>
<p><code>sudo repo-switch.py nz</code></p>
<p>&#8230;sets apt to use the file /etc/apt/sources.list.nz by changing /etc/apt.sources.list to a symlink pointing to the relevant place. Calling the script again with a different set (e.g. &#8216;ece&#8217; in my case) will set it up to use one of your other sets.</p>
<p>Obviously, you&#8217;ll need to run &#8216;sudo apt-get update&#8217; each time to make apt work with the new repos, but I added a line to the script to remind you!</p>
<p>Magic!</p>
 <p><a href="http://webworxshop.com/?flattrss_redirect&amp;id=82&amp;md5=87f40cd2f29019d072a9d6f502100aea" title="Flattr" target="_blank"><img src="http://blog.webworxshop.com/wp-content/plugins/flattrss/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://webworxshop.com/2009/06/03/quickly-change-debian-repositories/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="https://flattr.com/submit/auto?user_id=robconnolly&amp;popout=1&amp;url=http%3A%2F%2Fwebworxshop.com%2F2009%2F06%2F03%2Fquickly-change-debian-repositories&amp;language=en_GB&amp;category=text&amp;title=Quickly+change+Debian+repositories&amp;description=Apt+is+awesome.+Plain+and+simple.+But+it+is+kinda+static.+By+this+I+mean+it%26%238217%3Bs+not+particularly+suited+to+environments+where+things+change+frequently.+For+example%2C+we+have+a...&amp;tags=apt%2Cawesome%2Cdebian%2Cfoss%2Cpython%2Cubuntu%2CUoA%2Cblog" type="text/html" />
	</item>
	</channel>
</rss>

