<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>Endlessly Curious</title>
	
	<link>http://www.endlesslycurious.com</link>
	<description>Programming, Productivity &amp; Software Development.</description>
	<lastBuildDate>Fri, 17 Feb 2012 07:00:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/EndlesslyCurious" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="endlesslycurious" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Goodbye Vancouver.  Hej Stockholm!</title>
		<link>http://www.endlesslycurious.com/2012/02/17/goodbye-vancouver-hej-stockholm/</link>
		<comments>http://www.endlesslycurious.com/2012/02/17/goodbye-vancouver-hej-stockholm/#comments</comments>
		<pubDate>Fri, 17 Feb 2012 07:00:01 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Misc]]></category>

		<guid isPermaLink="false">http://www.endlesslycurious.com/?p=2996</guid>
		<description><![CDATA[At the start of February I moved from Vancouver, Canada to Stockholm, Sweden! Last year was a traumatic year for me with the death of my beloved wife Barbara to brain cancer in July.  As five of the six years we were married were spent in Vancouver there are many happy memories there but there [...]]]></description>
			<content:encoded><![CDATA[<p>At the start of February I moved from Vancouver, Canada to Stockholm, Sweden!</p>
<p><img class="alignleft size-full wp-image-3001" style="margin-right: 10px;" title="Traveller" src="http://www.endlesslycurious.com/wp-content/uploads/2012/02/Traveller.jpg" alt="" width="250" height="333" />Last year was a traumatic year for me with the death of my beloved wife Barbara to brain cancer in July.  As five of the six years we were married were spent in Vancouver there are many happy memories there but there are unpleasant memories too.</p>
<p>I felt it was time for a new adventure so the opportunity to work with the awesome folk at DICE on the Frostbite engine was an opportunity that I felt I&#8217;d regret if I didn&#8217;t give it a shot.  Plus I&#8217;d always wanted to learn another language, as something about thinking in multiple languages has always intrigued me.</p>
<p>Leaving the friends I&#8217;ve made  and the colleagues I&#8217;ve worked with in the five years I spent in Vancouver behind has been hard.  Yet exploring Stockholm and meeting new people has been interesting so far!</p>
<img src="http://feeds.feedburner.com/~r/EndlesslyCurious/~4/kbtFsZff_lk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.endlesslycurious.com/2012/02/17/goodbye-vancouver-hej-stockholm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Top posts of 2011</title>
		<link>http://www.endlesslycurious.com/2012/01/09/top-posts-of-2011/</link>
		<comments>http://www.endlesslycurious.com/2012/01/09/top-posts-of-2011/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 09:00:50 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Links]]></category>
		<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[links]]></category>
		<category><![CDATA[Lists]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.endlesslycurious.com/?p=2982</guid>
		<description><![CDATA[The top ten posts for 2011 according to Google Analytics were: Installing Python, MatPlotLib &#38; iPython on Snow Leopard. Finding duplicate files using Python. Getting started with Python. Praise for Python. Basic Graphing with MatPlotLib. Graphing real data with MatPlotLib. Extracting image EXIF data with Python. Python 2.7.1 Goodness. Running WordPress on Mac OS X [...]]]></description>
			<content:encoded><![CDATA[<p>The top ten posts for 2011 according to Google Analytics were:</p>
<ol>
<li><a title="Installing Python, MatPlotLib &amp; iPython on Snow Leopard" href="http://www.endlesslycurious.com/2011/04/06/installing-python-matplotlib-ipython-on-snow-leopard/">Installing Python, MatPlotLib &amp; iPython on Snow Leopard</a>.</li>
<li><a title="Finding duplicate files using Python" href="http://www.endlesslycurious.com/2011/06/01/finding-duplicate-files-using-python/">Finding duplicate files using Python</a>.</li>
<li><a title="Getting started with Python" href="http://www.endlesslycurious.com/2011/06/14/getting-started-with-python/">Getting started with Python</a>.</li>
<li><a title="Praise for Python" href="http://www.endlesslycurious.com/2011/05/02/praise-for-python/">Praise for Python</a>.</li>
<li><a title="Basic Graphing with MatPlotLib" href="http://www.endlesslycurious.com/2011/05/04/basic-graphing-with-matplotlib/">Basic Graphing with MatPlotLib</a>.</li>
<li><a title="Graphing real data with MatPlotLib" href="http://www.endlesslycurious.com/2011/05/06/graphing-real-data-with-matplotlib/">Graphing real data with MatPlotLib</a>.</li>
<li><a title="Extracting image EXIF data with Python" href="http://www.endlesslycurious.com/2011/05/11/extracting-image-exif-data-with-python/">Extracting image EXIF data with Python</a>.</li>
<li><a title="Python 2.7.1 Goodness" href="http://www.endlesslycurious.com/2011/06/10/python-2-7-1-goodness/">Python 2.7.1 Goodness</a>.</li>
<li><a title="Running WordPress on Mac OS X with XAMPP" href="http://www.endlesslycurious.com/2011/03/14/running-wordpress-on-mac-os-x-with-xampp/">Running WordPress on Mac OS X with XAMPP</a>.</li>
<li><a title="John Clease on Creativity" href="http://www.endlesslycurious.com/2011/03/10/john-cleese-on-creativity/">John Cleese on creativity</a>.</li>
</ol>
<p>Eight of the top ten are Python related, the top twenty is more diversified:</p>
<ol start="11">
<li><a title="Querying Reddit with Python" href="http://www.endlesslycurious.com/2011/11/30/querying-reddit-with-python/">Querying Reddit with Python</a>.</li>
<li><a title="Barbara" href="http://www.endlesslycurious.com/2011/08/22/barbara/">Barbara</a>.</li>
<li><a title="Processing Perforce command output with Python" href="http://www.endlesslycurious.com/2011/03/28/processing-perforce-command-output-with-python/">Processing Perforce command output with Python</a>.</li>
<li><a title="Downloading Wallpaper Images from Reddit with Python" href="http://www.endlesslycurious.com/2011/12/31/downloading-wallpaper-images-from-reddit-with-python/">Downloading wallpaper images from Reddit using Python</a>.</li>
<li><a title="Why Scrum fails..." href="http://www.endlesslycurious.com/2011/04/25/why-scrum-fails/">Why scrum fails</a>&#8230;</li>
<li><a title="Hacking Work Manifesto" href="http://www.endlesslycurious.com/2011/05/12/hacking-work-manifesto/">Hacking work manifesto</a>.</li>
<li><a title="The ascendancy of JSON" href="http://www.endlesslycurious.com/2011/05/20/the-ascendancy-of-json/">The ascendeancy of JSON</a>.</li>
<li><a title="Using Perforce Counters to control syncing" href="http://www.endlesslycurious.com/2011/03/24/using-perforce-counters-to-control-syncing/">Using Perforce counters to control syncing</a>.</li>
<li><a title="Why work doesn't happen at work." href="http://www.endlesslycurious.com/2011/05/03/why-work-doesnt-happen-at-work/">Why work doesn&#8217;t happen at work</a>.</li>
<li><a title="Small steps to big goals" href="http://www.endlesslycurious.com/2011/05/05/small-steps-to-big-goals/">Small steps to big goals</a>.</li>
</ol>
<p>On a personal note I hope 2012 will bring more posts and less personal tragedy..</p>
<img src="http://feeds.feedburner.com/~r/EndlesslyCurious/~4/QILPCoFcBLU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.endlesslycurious.com/2012/01/09/top-posts-of-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Organising photographs with Python</title>
		<link>http://www.endlesslycurious.com/2012/01/02/organising-photographs-with-python/</link>
		<comments>http://www.endlesslycurious.com/2012/01/02/organising-photographs-with-python/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 09:00:48 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.endlesslycurious.com/?p=2959</guid>
		<description><![CDATA[Previously I posted about extracting EXIF information from images using the Python Image Library (PIL).  The reason I was investigating how to do this was I wanted to programmatically reorganise my personal photograph collection from its current ad-hoc mess to something more structured. My goal was to use Python to extract the EXIF information from each [...]]]></description>
			<content:encoded><![CDATA[<p>Previously I <a title="Extracting Image EXIF data with Python" href="http://www.endlesslycurious.com/2011/05/11/extracting-image-exif-data-with-python/">posted</a> about extracting <a title="Wikipedia: EXIF" href="http://en.wikipedia.org/wiki/Exchangeable_image_file_format">EXIF</a> information from images using the <a title="Python Image Library (PIL)" href="http://www.pythonware.com/products/pil/">Python Image Library</a> (PIL).  The reason I was investigating how to do this was I wanted to programmatically reorganise my personal photograph collection from its current ad-hoc mess to something more structured.</p>
<p>My goal was to use Python to extract the EXIF information from each image file and use the creation time of each image as key to organise each image into the directory structure Year/Month/Day.  If an image file is missing EXIF data then the file&#8217;s creation time can be used instead via an option.</p>
<p>An example of running this script to reoranise the photos folder and leave the original files in place would be:</p>
<pre class="brush: bash; title: ; notranslate">
python PhotoShuffle.py -copy /Daniel/Pictures /Daniel/OrganisedPictures
</pre>
<p>You can also find the latest version on github at <a title="PhotoShuffle on GitHub" href="http://github.com/dpbrown/PhotoShuffle">github.com/dpbrown/PhotoShuffle</a>, the following is the current script:</p>
<pre class="brush: python; title: ; notranslate">
&quot;&quot;&quot;Scans a folder and builds a date sorted tree based on image creation time.&quot;&quot;&quot;

if __name__ == '__main__':
    from os import makedirs, listdir, rmdir
    from os.path import join as joinpath, exists, getmtime
    from datetime import datetime
    from shutil import move, copy2 as copy
    from ExifScan import scan_exif_data
    from argparse import ArgumentParser

    PARSER = ArgumentParser(description='Builds a date sorted tree of images.')
    PARSER.add_argument( 'orig', metavar='O', help='Source root directory.')
    PARSER.add_argument( 'dest', metavar='D',
                         help='Destination root directory' )
    PARSER.add_argument( '-filetime', action='store_true',
                         help='Use file time if missing EXIF' )
    PARSER.add_argument( '-copy', action='store_true',
                         help='Copy files instead of moving.' )
    ARGS = PARSER.parse_args()

    print 'Gathering &amp; processing EXIF data.'

    # Get creation time from EXIF data.
    DATA = scan_exif_data( ARGS.orig )

    # Process EXIF data.
    for r in DATA:
        info = r['exif']
        # precidence is DateTimeOriginal &gt; DateTime.
        if 'DateTimeOriginal' in info.keys():
            r['ftime'] = info['DateTimeOriginal']
        elif 'DateTime' in info.keys():
            r['ftime'] = info['DateTime']
        if 'ftime' in r.keys():
            r['ftime'] = datetime.strptime(r['ftime'],'%Y:%m:%d %H:%M:%S')
        elif ARGS.filetime == True:
            ctime = getmtime( joinpath( r['path'], r['name'] + r['ext'] ))
            r['ftime'] = datetime.fromtimestamp( ctime )

    # Remove any files without datetime info.
    DATA = [ f for f in DATA if 'ftime' in f.keys() ]

    # Generate new path YYYY/MM/DD/ using EXIF date.
    for r in DATA:
        r['newpath'] = joinpath( ARGS.dest, r['ftime'].strftime('%Y/%m/%d') )

    # Generate filenames per directory: 1 to n+1 (zero padded) with DDMMMYY.
    print 'Generating filenames.'
    for newdir in set( [ i['newpath'] for i in DATA ] ):
        files = [ r for r in DATA if r['newpath'] == newdir ]
        pad = len( str( len(files) ) )
        usednames = []
        for i in range( len(files) ):
            datestr = files[i]['ftime'].strftime('%d%b%Y')
            newname = '%0*d_%s' % (pad, i+1, datestr)
            j = i+1
            # if filename exists keep looking until it doesn't. Ugly!
            while ( exists( joinpath( newdir, newname + files[i]['ext'] ) ) or
                newname in usednames ):
                j += 1
                jpad = max( pad, len( str( j ) ) )
                newname = '%0*d_%s' % (jpad, j, datestr)
            usednames.append( newname )
            files[i]['newname'] = newname

    # Copy the files to their new locations, creating directories as requried.
    print 'Copying files.'
    for r in DATA:
        origfile = joinpath( r['path'], r['name'] + r['ext'] )
        newfile = joinpath( r['newpath'], r['newname'] + r['ext'] )
        if not exists( r['newpath'] ):
            makedirs( r['newpath'] )
        if not exists( newfile ):
            if ARGS.copy:
                print 'Copying '+ origfile +' to '+ newfile
                copy( origfile, newfile )
            else:
                print 'Moving '+ origfile +' to '+ newfile
                move( origfile, newfile )
        else:
            print newfile +' already exists!'

    if ARGS.copy:
        print 'Removing empty directories'
        DIRS = set( [ d['path'] for d in DATA ] )
        for d in DIRS:
            # if the directory is empty then delete it.
            if len( listdir( d ) ) == 0:
                print 'Deleting dir ' + d
                rmdir( d )
</pre>
<p>UPDATE: I tend to run my duplicate file script over image collections before I organise them to remove any duplicates.  You can find that script on github at <a href="github.com/dpbrown/Duplicate-Files" title="Duplicate Files Script">github.com/dpbrown/Duplicate-Files</a>.</p>
<img src="http://feeds.feedburner.com/~r/EndlesslyCurious/~4/bsWoBvwu5yU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.endlesslycurious.com/2012/01/02/organising-photographs-with-python/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Downloading Wallpaper Images from Reddit with Python</title>
		<link>http://www.endlesslycurious.com/2011/12/31/downloading-wallpaper-images-from-reddit-with-python/</link>
		<comments>http://www.endlesslycurious.com/2011/12/31/downloading-wallpaper-images-from-reddit-with-python/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 09:00:15 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.endlesslycurious.com/?p=2881</guid>
		<description><![CDATA[In my previous post I demonstrated how to query Reddit using Python and JOSN. My goal was a script to download the latest and greatest wallpapers off of image sub-reddits like wallpaper to keep my desktop wallpaper fresh and interesting. The main function of the script is to download any JPEG formatted image that listed [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://www.endlesslycurious.com/2011/11/30/querying-reddit-with-python/" title="Querying Reddit with Python">previous post</a> I demonstrated how to query Reddit using Python and JOSN.  My goal was a script to download the latest and greatest wallpapers off of image sub-reddits like <a href="http://www.reddit.com/r/wallpaper" title="Wallpaper sub-reddit">wallpaper</a> to keep my desktop wallpaper fresh and interesting.  The main function of the script is to download any JPEG formatted image that listed in the specified sub-reddit and download them to a folder.  </p>
<p>Allot of the script turned out to be managing URLs, handling exceptions and checking image types so that links to the most commonly encountered image repository: <a href="http://imgur.com/" title="Imgur">imgur</a> worked.  I opted to use the reddit hash id for each post as the filename for the downloaded JPEGs as this seems to be unique value, which means there are no collisions and its easy to programatically check if that item&#8217;s image has already been download or not.  Although using a hash value instead of the items text title doesn&#8217;t make the most memorable filenames..</p>
<p>The single most frustrating thing I encountered when writing this script is that I have yet to discover a programatic way to work out the URL for an image on Flickr given a Flickr page URL.  This is a real shame as Flickr is a really popular image hosting site with allot of great images.</p>
<p>An example of running the script to download images with a score greater than 50 from the wallpaper sub-reddit into a folder called wallpaper would be as follows:</p>
<pre class="brush: bash; title: ; notranslate">
python redditdownload.py wallpaper wallpaper -s 50
</pre>
<p>And to run the same query but only get any new images you don&#8217;t already have, run the following:</p>
<pre class="brush: bash; title: ; notranslate">
python redditdownload.py wallpaper wallpaper -s 50 -update
</pre>
<p>You can find the source code for this post (and the previous) on GitHub at <a href="http://github.com/dpbrown/RedditImageGrab" title="GitHub">github.com/dpbrown/RedditImageGrab</a> and the current source for the script is as follows:</p>
<pre class="brush: python; title: ; notranslate">
&quot;&quot;&quot;Download images from a reddit.com subreddit.&quot;&quot;&quot;

from urllib2 import urlopen, HTTPError, URLError
from httplib import InvalidURL
from argparse import ArgumentParser
from os.path import exists as pathexists, join as pathjoin
from os import mkdir
from reddit import getitems

if __name__ == &quot;__main__&quot;:
    PARSER = ArgumentParser( description='Downloads files with specified externsion from the specified subreddit.')
    PARSER.add_argument( 'reddit', metavar='r', help='Subreddit name.')
    PARSER.add_argument( 'dir', metavar='d', help='Dir to put downloaded files in.')
    PARSER.add_argument( '-last', metavar='l', default='', required=False, help='ID of the last downloaded file.')
    PARSER.add_argument( '-score', metavar='s', default='0', type=int, required=False, help='Minimum score of images to download.')
    PARSER.add_argument( '-num', metavar='n', default='0', type=int, required=False, help='Number of images to process.')
    PARSER.add_argument( '-update', default=False, action='store_true', required=False, help='Run until you encounter a file already downloaded.')
    ARGS = PARSER.parse_args()

    print 'Downloading images from &quot;%s&quot; subreddit' % (ARGS.reddit)

    ITEMS = getitems( ARGS.reddit, ARGS.last )
    N = D = E = S = F = 0
    FINISHED = False

    # Create the specified directory if it doesn't already exist.
    if not pathexists( ARGS.dir ):
        mkdir( ARGS.dir )

    while len(ITEMS) &gt; 0 and FINISHED == False:
        LAST = ''
        for ITEM in ITEMS:
            if ITEM['score'] &lt; ARGS.score:
                print '\tSCORE: %s has score of %s which is lower than required score of %s.' % (ITEM['id'],ITEM['score'],ARGS.score)
                S += 1
            else:
                FILENAME = pathjoin( ARGS.dir, '%s.jpg' % (ITEM['id'] ) )
                # Don't download files multiple times!
                if not pathexists( FILENAME ):
                    try:
                        if 'imgur.com' in ITEM['url']:
                            # Change .png to .jpg for imgur urls.
                            if ITEM['url'].endswith('.png'):
                                ITEM['url'] = ITEM['url'].replace('.png','.jpg')
                            # Add .jpg to imgur urls that are missing it.
                            elif '.jpg' not in ITEM['url']:
                                ITEM['url'] = '%s.jpg' % ITEM['url']
                            elif '.jpeg' not in ITEM['url']:
                                ITEM['url'] = '%s.jpg' % ITEM['url']

                        RESPONSE = urlopen( ITEM['url'] )
                        INFO = RESPONSE.info()

                        # Work out file type either from the response or the url.
                        if 'content-type' in INFO.keys():
                            FILETYPE = INFO['content-type']
                        elif ITEM['url'].endswith( 'jpg' ):
                            FILETYPE = 'image/jpeg'
                        elif ITEM['url'].endswith( 'jpeg' ):
                            FILETYPE = 'image/jpeg'
                        else:
                            FILETYPE = 'unknown'

                        # Only try to download jpeg images.
                        if FILETYPE == 'image/jpeg':
                            FILEDATA = RESPONSE.read()
                            FILE = open( FILENAME, 'wb')
                            FILE.write(FILEDATA)
                            FILE.close()
                            print '\tDownloaded %s to %s.' % (ITEM['url'],FILENAME)
                            D += 1
                        else:
                            print '\tWRONG FILE TYPE: %s has type: %s!' % (ITEM['url'],FILETYPE)
                            S += 1
                    except HTTPError as ERROR:
                            print '\tHTTP ERROR: Code %s for %s.' % (ERROR.code,ITEM['url'])
                            F += 1
                    except URLError as ERROR:
                            print '\tURL ERROR: %s!' % ITEM['url']
                            F += 1
                    except InvalidURL as ERROR:
                            print '\tInvalid URL: %s!' % ITEM['url']
                            F += 1
                else:
                    print '\tALREADY EXISTS: %s for %s already exists.' % (FILENAME,ITEM['url'])
                    E += 1
                    if ARGS.update == True:
                        print '\tUpdate complete, exiting.'
                        FINISHED = True
                        break
            LAST = ITEM['id']
            N += 1
            if ARGS.num &gt; 0 and N &gt;= ARGS.num:
                print '\t%d images attempted , exiting.' % N
                FINISHED = True
                break;
        ITEMS = getitems( ARGS.reddit, LAST )

    print 'Downloaded %d of %d (Skipped %d, Exists %d)' % (D, N, S, E)
</pre>
<img src="http://feeds.feedburner.com/~r/EndlesslyCurious/~4/bcsuheEZiaY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.endlesslycurious.com/2011/12/31/downloading-wallpaper-images-from-reddit-with-python/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Querying Reddit with Python</title>
		<link>http://www.endlesslycurious.com/2011/11/30/querying-reddit-with-python/</link>
		<comments>http://www.endlesslycurious.com/2011/11/30/querying-reddit-with-python/#comments</comments>
		<pubDate>Wed, 30 Nov 2011 09:00:12 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.endlesslycurious.com/?p=2856</guid>
		<description><![CDATA[I&#8217;ve long been a fan of reddit: which is a social news site where users can submit news, they can also comment and vote on submissions of other users.  Reddit provides a form of content filtration though subreddits which are specialized by topic e.g. the Python programming language. I thought it would be fun to figure out [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve long been a fan of <a title="Reddit" href="http://www.reddit.com/">reddit</a>: which is a social news site where users can submit news, they can also comment and vote on submissions of other users.  Reddit provides a form of content filtration though subreddits which are specialized by topic e.g. the Python programming language.</p>
<p>I thought it would be fun to figure out how to get the most recent items for a particular subreddit and the previous items for an item in a subreddit. Both these things turned out to be really simple using existing Python packages to query reddit and process the <a href="http://www.json.org/" title="JSON">JSON</a> formatted response.</p>
<pre class="brush: python; title: ; notranslate">
&quot;&quot;&quot;Return list of items from a sub-reddit of reddit.com.&quot;&quot;&quot;

from urllib2 import urlopen, HTTPError
from json import JSONDecoder

def getitems( subreddit, previd=''):
    &quot;&quot;&quot;Return list of items from a subreddit.&quot;&quot;&quot;
    url = 'http://www.reddit.com/r/%s.json' % subreddit
    # Get items after item with 'id' of previd.
    if previd != '':
        url = '%s?after=t3_%s' % (url, previd)
    try:
        json = urlopen( url ).read()
        data = JSONDecoder().decode( json )
        items = [ x['data'] for x in data['data']['children'] ]
    except HTTPError as ERROR:
        print '\tHTTP ERROR: Code %s for %s.' % (ERROR.code, url)
        items = []
    return items

if __name__ == &quot;__main__&quot;:

    print 'Recent items for Python.'
    ITEMS = getitems( 'python' )
    for ITEM in ITEMS:
        print '\t%s - %s' % (ITEM['title'], ITEM['url'])

    print 'Previous items for Python.'
    OLDITEMS = getitems( 'python', ITEMS[-1]['id'] )
    for ITEM in OLDITEMS:
        print '\t%s - %s' % (ITEM['title'], ITEM['url'])
</pre>
<p>In my <a href="http://www.endlesslycurious.com/2011/12/31/downloading-wallpaper-images-from-reddit-with-python/" title="Downloading Wallpaper Images from Reddit using Python">next post</a> I&#8217;ll detail what I used this script for..</p>
<img src="http://feeds.feedburner.com/~r/EndlesslyCurious/~4/tzZKKI9O9QU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.endlesslycurious.com/2011/11/30/querying-reddit-with-python/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Rands Test</title>
		<link>http://www.endlesslycurious.com/2011/10/14/the-rands-test/</link>
		<comments>http://www.endlesslycurious.com/2011/10/14/the-rands-test/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 16:32:52 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Communication]]></category>

		<guid isPermaLink="false">http://www.endlesslycurious.com/?p=2850</guid>
		<description><![CDATA[Rands has posted his own &#8216;Rands Test&#8216; in the style of Joel Spolsky&#8217;s famous &#8216;Joel Test&#8216; for telling if your company is screwed or not.  Rand&#8217;s test is focuses on communication while Joel&#8217;s original test focused on engineering: &#8220;There is a higher order goal at the intersection of the two questions The Rands Test intends [...]]]></description>
			<content:encoded><![CDATA[<p>Rands has posted his own &#8216;<a href="http://www.randsinrepose.com/archives/2011/10/11/the_rands_test.html">Rands Test</a>&#8216; in the style of Joel Spolsky&#8217;s famous &#8216;<a href="http://www.joelonsoftware.com/articles/fog0000000043.html">Joel Test</a>&#8216; for telling if your company is screwed or not.  Rand&#8217;s test is focuses on communication while Joel&#8217;s original test focused on engineering:</p>
<p style="padding-left: 30px;">&#8220;There is a higher order goal at the intersection of the two questions The Rands Test intends to answer: <em>Where am I?</em> and <em>What the hell is going on?</em> While understanding the answers to these questions will give you a good idea about the communication health of your company, the higher order goal is selfish.&#8221;</p>
<img src="http://feeds.feedburner.com/~r/EndlesslyCurious/~4/2V73EMO0j3M" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.endlesslycurious.com/2011/10/14/the-rands-test/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Steve Jobs 1955-2011</title>
		<link>http://www.endlesslycurious.com/2011/10/07/steve-jobs-1955-2011/</link>
		<comments>http://www.endlesslycurious.com/2011/10/07/steve-jobs-1955-2011/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 09:00:32 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://www.endlesslycurious.com/?p=2827</guid>
		<description><![CDATA[So passes a legend. It was impossible not to admire Steve Job&#8217;s ability to consistently produce products and companies that lead their marketplace. The following is Steve&#8217;s graduation speech at Stanford University. Having just lost my wife to cancer less than three months ago, my thoughts are with his family at this challenging time.]]></description>
			<content:encoded><![CDATA[<p>So passes a legend.  It was impossible not to admire Steve Job&#8217;s ability to consistently produce products and companies that lead their marketplace.  The following is Steve&#8217;s graduation speech at Stanford University.</p>
<p><object width="480" height="360"><param name="movie" value="http://www.youtube.com/v/UF8uR6Z6KLc?version=3&amp;hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/UF8uR6Z6KLc?version=3&amp;hl=en_US" type="application/x-shockwave-flash" width="420" height="315" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>Having just lost my wife to cancer less than three months ago, my thoughts are with his family at this challenging time.</p>
<img src="http://feeds.feedburner.com/~r/EndlesslyCurious/~4/si_f3yc6OhA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.endlesslycurious.com/2011/10/07/steve-jobs-1955-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why visualise data?</title>
		<link>http://www.endlesslycurious.com/2011/10/05/why-visualise-data/</link>
		<comments>http://www.endlesslycurious.com/2011/10/05/why-visualise-data/#comments</comments>
		<pubDate>Wed, 05 Oct 2011 19:13:51 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Visualisation]]></category>

		<guid isPermaLink="false">http://www.endlesslycurious.com/?p=2820</guid>
		<description><![CDATA[This excellent short video from Column Five really demonstrates the difference that even basic data visualization techniques can make.]]></description>
			<content:encoded><![CDATA[<p>This excellent short video from <a title="Column Five Media" href="http://columnfivemedia.com/">Column Five</a> really demonstrates the difference that even basic data visualization techniques can make.</p>
<p><iframe src="http://player.vimeo.com/video/29684853?title=0&amp;byline=0&amp;portrait=0" width="400" height="225" frameborder="0" webkitAllowFullScreen allowFullScreen></iframe></p>
<img src="http://feeds.feedburner.com/~r/EndlesslyCurious/~4/8_HSf-GTM48" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.endlesslycurious.com/2011/10/05/why-visualise-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Friday Linkage</title>
		<link>http://www.endlesslycurious.com/2011/09/23/friday-linkage-17/</link>
		<comments>http://www.endlesslycurious.com/2011/09/23/friday-linkage-17/#comments</comments>
		<pubDate>Fri, 23 Sep 2011 09:00:54 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Links]]></category>

		<guid isPermaLink="false">http://www.endlesslycurious.com/?p=2815</guid>
		<description><![CDATA[This weeks interesting links: Why Functional Programming Matters Not a new paper (1984!) but interesting take on the usefulness and potential scalability of functional languages. Learn you a Haskell for great good! An excellent online book for learning the Haskell functional programming language. How we Scrum A description of the scrum process at an indie game developer [...]]]></description>
			<content:encoded><![CDATA[<p>This weeks interesting links:</p>
<ul>
<li><a href="http://www.cse.chalmers.se/~rjmh/Papers/whyfp.html">Why Functional Programming Matters</a><br />
Not a new paper (1984!) but interesting take on the usefulness and potential scalability of functional languages.</li>
<li><a href="http://learnyouahaskell.com/">Learn you a Haskell for great good!</a><br />
An excellent online book for learning the Haskell functional programming language.</li>
<li><a href="http://altdevblogaday.com/2011/09/21/how-we-scrum/">How we Scrum</a><br />
A description of the scrum process at an indie game developer and how they&#8217;ve tailored it to their needs.</li>
<li><a href="http://maniacdev.com/2011/09/best-resources-in-ios-development-september-19th-2011/">Best resources for iOS programming</a><br />
A current summary of good online resources for programming Apple&#8217;s iOS devices (e.g. iPhone &amp; iPad).</li>
<li><a href="http://www.lightstalking.com/can-you-really-get-great-shots-with-a-point-and-shoot">Can you really get great shots with a point and shoot?</a><br />
Inspirational article about getting great photographs from compact point and shoot cameras rather than large, expensive DSLRs.</li>
<li><a href="http://daringfireball.net/2011/09/fall_event">The Fall Event</a><br />
Apple has ran a iPod music event every year in the fall until this year, this article speculates on what this means for the future of the iPod and on Apple&#8217;s changing priorities.</li>
</ul>
<img src="http://feeds.feedburner.com/~r/EndlesslyCurious/~4/Dt47-Gf8oCg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.endlesslycurious.com/2011/09/23/friday-linkage-17/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On taking initiative</title>
		<link>http://www.endlesslycurious.com/2011/09/20/on-taking-initiative/</link>
		<comments>http://www.endlesslycurious.com/2011/09/20/on-taking-initiative/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 09:00:55 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://www.endlesslycurious.com/?p=2806</guid>
		<description><![CDATA[As an engineer it is easy to complain about things that don&#8217;t work as well as they could, especially when you first encounter the issue. However the difference between an average engineer and a truly effective engineer is that effective engineers don&#8217;t just stop and complain about a problem, they will actively suggest and implement [...]]]></description>
			<content:encoded><![CDATA[<p>As an engineer it is easy to complain about things that don&#8217;t work as well as they could, especially when you first encounter the issue.</p>
<p>However the difference between an average engineer and a truly effective engineer is that effective engineers don&#8217;t just stop and complain about a problem, they will actively suggest and implement solutions to allow them to continue working.  This is especially apparent when it comes to repetitive manual tasks, I have witnessed so many people complain about tedious manual processes but then fail to automate the process!  So do not view a problem as a road block preventing further progress, instead view it as an unexpected opportunity to solve a problem and improve something.</p>
<p>A pleasant side effect of this proactive approach is that those that habitually remove problems when they encounter them are also building a reputation as a problem solver and someone who <em>gets things done</em>.  This reputation will dramatically increases the chances that they will be listened to when it comes to getting management buy in to solve a significant problem.</p>
<img src="http://feeds.feedburner.com/~r/EndlesslyCurious/~4/p3DidRU19HA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.endlesslycurious.com/2011/09/20/on-taking-initiative/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss><!-- Dynamic page generated in 0.236 seconds. --><!-- Cached page generated by WP-Super-Cache on 2012-02-22 05:16:06 -->

