<?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://blog.webworxshop.com/category/tips/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.webworxshop.com</link>
	<description>cat /dev/brain &#62; /dev/null</description>
	<lastBuildDate>Mon, 30 Aug 2010 08:17:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com" />
	<atom:link rel="hub" href="http://superfeedr.com/hubbub" />
			<item>
		<title>Playing with Python Generators</title>
		<link>http://blog.webworxshop.com/2010/08/30/playing-with-python-generators</link>
		<comments>http://blog.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[generator]]></category>
		<category><![CDATA[list comprehension]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.webworxshop.com/?p=266</guid>
		<description><![CDATA[Today I&#8217;ve been playing with generators in Python. 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 [...]]]></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>
]]></content:encoded>
			<wfw:commentRss>http://blog.webworxshop.com/2010/08/30/playing-with-python-generators/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Denting via Android Intents</title>
		<link>http://blog.webworxshop.com/2010/05/30/denting-via-android-intents</link>
		<comments>http://blog.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[identi.ca]]></category>
		<category><![CDATA[Intent]]></category>
		<category><![CDATA[Mustard]]></category>

		<guid isPermaLink="false">http://blog.webworxshop.com/?p=215</guid>
		<description><![CDATA[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 Mustard identi.ca client. It turns out it is, and here&#8217;s how you do it: Intent i = new Intent(Intent.ACTION_SEND); i.setType("text/plain"); [...]]]></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>
]]></content:encoded>
			<wfw:commentRss>http://blog.webworxshop.com/2010/05/30/denting-via-android-intents/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Online Filesystem Resizing with LVM</title>
		<link>http://blog.webworxshop.com/2009/10/10/online-filesystem-resizing-with-lvm</link>
		<comments>http://blog.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[linux]]></category>
		<category><![CDATA[LVM]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.webworxshop.com/?p=134</guid>
		<description><![CDATA[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>
]]></content:encoded>
			<wfw:commentRss>http://blog.webworxshop.com/2009/10/10/online-filesystem-resizing-with-lvm/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Quickly change Debian repositories</title>
		<link>http://blog.webworxshop.com/2009/06/03/quickly-change-debian-repositories</link>
		<comments>http://blog.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[python]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[UoA]]></category>

		<guid isPermaLink="false">http://blog.webworxshop.com/?p=82</guid>
		<description><![CDATA[Apt is awesome. Plain and simple. 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>
]]></content:encoded>
			<wfw:commentRss>http://blog.webworxshop.com/2009/06/03/quickly-change-debian-repositories/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Screen switching on the EeePC</title>
		<link>http://blog.webworxshop.com/2009/02/12/screen-switching-on-the-eeepc</link>
		<comments>http://blog.webworxshop.com/2009/02/12/screen-switching-on-the-eeepc#comments</comments>
		<pubDate>Thu, 12 Feb 2009 06:54:41 +0000</pubDate>
		<dc:creator>Rob Connolly</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[eeepc]]></category>
		<category><![CDATA[screen resolution]]></category>
		<category><![CDATA[xrandr]]></category>

		<guid isPermaLink="false">http://blog.webworxshop.com/?p=45</guid>
		<description><![CDATA[I spend a lot of time working on my EeePC 901 using it&#8217;s external monitor support, it&#8217;s great, I have this little netbook, but when I plug it in to an external monitor, keyboard and mouse it pretty much turns into a desktop PC. The only drawback I&#8217;ve found so far is that there was [...]]]></description>
			<content:encoded><![CDATA[<p>I spend a lot of time working on my EeePC 901 using it&#8217;s external monitor support, it&#8217;s great, I have this little netbook, but when I plug it in to an external monitor, keyboard and mouse it pretty much turns into a desktop PC. The only drawback I&#8217;ve found so far is that there was no way to switch between the monitors in Ubuntu without going through the Screen Resolution configuration dialog. That was until I decided it had annoyed me for long enough and got Googling.</p>
<p>I found <a href="http://www.thinkwiki.org/wiki/Xorg_RandR_1.2">this</a> page, which documents the Xrandr, which can be used to configure monitors and screen resolutions from the command line. Some of the code snippets on the page got me into writing a script, which could toggle between the displays and be assigned to a hot key. I also added a mode to switch back to the laptop screen when there is not external screen (just in case my external monitor dies as happened in the <a href="/2009/02/03/another-auckland-power-outage-means-go-home-early">power cut</a> the other day!).<span id="more-45"></span></p>
<p><code>#!/bin/sh<br />
# names of outputs<br />
EXTERNAL_OUTPUT="VGA"<br />
INTERNAL_OUTPUT="LVDS"<br />
# external and internal resolutions<br />
EXTERNAL_RESOLUTION="1024x768"<br />
INTERNAL_RESOLUTION="1024x600"<br />
# if the external output is disconnected, then switch back to internal output<br />
xrandr | grep $EXTERNAL_OUTPUT | grep 'disconnected'<br />
if [ $? -eq 0 ]; then<br />
# just check to make sure we aren't on internal output already<br />
xrandr | grep $INTERNAL_OUTPUT | grep $INTERNAL_RESOLUTION<br />
if [ $? -eq 1 ]; then<br />
xrandr --output $INTERNAL_OUTPUT --auto --output $EXTERNAL_OUTPUT --off<br />
fi<br />
exit 0<br />
fi<br />
# check to see whether the external output is active<br />
xrandr | grep $EXTERNAL_OUTPUT | grep $EXTERNAL_RESOLUTION<br />
if [ $? -eq 0 ]; then<br />
# yep, we're currently using the external output, so switch back to the internal output<br />
xrandr --output $INTERNAL_OUTPUT --auto --output $EXTERNAL_OUTPUT --off<br />
else<br />
# otherwise we want to change to the external output<br />
xrandr --output $INTERNAL_OUTPUT --off --output $EXTERNAL_OUTPUT --mode $EXTERNAL_RESOLUTION<br />
fi<br />
exit 0</code></p>
<p>I assigned this to the Fn-F5 key combination using <a href="apt:eee-control">eee-control</a>, which I already have running on my eeepc. The result is really nice switching between internal and external outputs, which solved my problem perfectly.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webworxshop.com/2009/02/12/screen-switching-on-the-eeepc/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
