<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>I gotta have my orange juice. &#187; Python</title>
	<atom:link href="http://scottmoonen.com/category/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://scottmoonen.com</link>
	<description>Jesu, Juva</description>
	<lastBuildDate>Thu, 31 May 2012 16:33:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='scottmoonen.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/71456a1f4695cc8129f159ece0f7b3a1?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>I gotta have my orange juice. &#187; Python</title>
		<link>http://scottmoonen.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://scottmoonen.com/osd.xml" title="I gotta have my orange juice." />
	<atom:link rel='hub' href='http://scottmoonen.com/?pushpress=hub'/>
		<item>
		<title>My experience with Django and Rails</title>
		<link>http://scottmoonen.com/2009/01/09/my-experience-with-django-and-rails/</link>
		<comments>http://scottmoonen.com/2009/01/09/my-experience-with-django-and-rails/#comments</comments>
		<pubDate>Fri, 09 Jan 2009 05:59:38 +0000</pubDate>
		<dc:creator>Scott Moonen</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://blog.fullvalence.com/?p=48</guid>
		<description><![CDATA[I&#8217;ve had the opportunity to work on both Django and Rails frameworks recently as part of one project.  The core application for the church administrative tools that I am working on is written in Rails, while the church guest follow-up application that I am responsible for is written in Django.  Why two separate stacks?  GuestView [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=115&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had the opportunity to work on both <a href="http://www.djangoproject.com/">Django</a> and <a href="http://rubyonrails.org/">Rails</a> frameworks recently as part of one project.  The core application for the <a href="http://www.gospelsoftware.com/">church administrative tools</a> that I am working on is written in Rails, while the <a href="http://www.gospelsoftware.com/guestview">church guest follow-up application</a> that I am responsible for is written in Django.  Why two separate stacks?  <a href="http://www.gospelsoftware.com/guestview">GuestView</a> began its life independently from <a href="http://www.gospelsoftware.com/">Gospel Software</a>, and I chose Django there because of my familiarity with Python.  Three developers are sharing responsibility for the core of Gospel Software, however, and we chose Rails as the most reasonable <em>lingua franca</em>.</p>
<p>What follows are my personal opinions and observations.  These are mostly aesthetic or other value judgments, and I offer them simply for your consideration.</p>
<h2>Language</h2>
<p>I&#8217;ve used the <a href="http://python.org/">Python</a> programming language for a number of years and like it a lot.  I particularly enjoy its functional aspects, although lately I&#8217;ve become more of a fan of using <a href="http://docs.python.org/tutorial/datastructures.html#list-comprehensions">list comprehensions</a> and <a href="http://docs.python.org/tutorial/classes.html#generator-expressions">generator expressions</a> wherever possible compared to map() and filter() with lambdas.  Compared to Python, <a href="http://www.ruby-lang.org/en/">Ruby</a> has much more powerful functional capabilities, although some things don&#8217;t feel natural to me (Ruby&#8217;s design choice to not require parentheses to denote function invocation means that you must use .call to call a lambda, which feels clunky).  There are also some cases in Ruby where choosing one of several alternative forms of an expression can have a significant impact on your performance.  Lambdas seem particularly costly in Ruby as of version 1.8.</p>
<p>Overall I think the languages are fairly on par.  Right now I prefer Python for aesthetic rather than technical reasons.  As I grow in familiarity with Ruby, and as it matures and its performance improves I think I may eventually grow to prefer it.</p>
<h2>Object-Relational Mapping (ORM)</h2>
<p>The Django ORM is very powerful and you can express complicated queries very efficiently using it.  Django queries are not executed until they are actually used, so you can construct your queries piecemeal, which helps in writing readable code.  Django also allows you some flexibility with adding custom SQL to your queries, but for anything complicated I&#8217;ve found that I have to break down and write my own SQL.</p>
<p>Rails 2.1 introduced the ActiveRecord <a href="http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-finder-functionality">named_scope</a> functionality.  Prior to this Rails was significantly lacking compared to Django&#8217;s expressive power for query construction, but named_scope pretty much evens the playing field.  And for complicated queries, which you will surely face in any real-world project as you seek to tweak performance, ActiveRecord gives you a degree of control over your SQL that really puts Django to shame.</p>
<p>Both Django and Rails seem to have adequate support for <a href="http://www.postgresql.org/">PostgreSQL</a>, my database of choice.</p>
<h2>URLs</h2>
<p>Django lets you express your URLs using regular expressions; Rails accomplishes this using routes.   I personally prefer Django&#8217;s method, but both work well enough.</p>
<h2>Templates</h2>
<p>While Rails&#8217; Embedded Ruby allows you to include arbitrary code in your templates, Django&#8217;s template engine is much more spartan.  It provides ways of getting at variables passed to the template, including objects, dictionaries, lists, and even methods.  And it has some simle control structures, but not covering the full expressive power of Python.  I yearned for a more powerful template language in Django at first.  But I found over time that the discipline of  a simple template language was helpful to me, forcing me to move any complicated behaviors to the controller (or &#8220;view&#8221; as Django calls it) which was in most cases the right thing to do anyway.</p>
<p>There are still some areas where I think the Django template language is lacking.  However, there is an open-source alternative to the Django template engine that is similar but sufficiently more powerful to meet my needs: <a href="http://jinja.pocoo.org/2/">Jinja2</a>.</p>
<p>For me it is a toss-up between Embedded Ruby and Jinja2.</p>
<h2>Performance</h2>
<p>I suspect it&#8217;s common knowledge that Rails has a little ways to go in performance.  For our own purposes, I didn&#8217;t find too much difference in time measurements between Django and Rails.  However, Rails clearly has a much larger memory footprint than Django.</p>
<p>I was surprised to learn that even with a FastCGI or WSGI model, Django still opens and closes a database connection for each request.  While there may be technical reasons that the Django architecture requires this, it was still a surprise to me.  Django performance still seems on par with Rails in spite of this.  Interestingly, having Django use <a href="http://pgpool.projects.postgresql.org/">pgpool</a> to connect to PostgreSQL didn&#8217;t improve my performance at all, perhaps because my application and database are currently located on the same host.</p>
<h2>Console</h2>
<p>Both Django and Rails allow you to run a <a href="http://en.wikipedia.org/wiki/REPL">REPL</a> session for your application.  The Rails script/console command beats out Django hands-down, because Rails&#8217; internal magic automatically imports pretty much everything you need.  In Django you still need to import any models or framework modules before you can use them.</p>
<h2>Debugging</h2>
<p>The Rails built-in log is enabled out of the box and is very handy.  Django provides logging functionality but you have to do a little extra work to enable it.  Rails wins out on logging.  Django is better at in-browser rendering of exception tracebacks.  Overall the handiness its logging means a slight win for Rails here for me.</p>
<h2>Admin Application</h2>
<p>Django&#8217;s admin application is truly its crown jewel.  If you need a private admin interface to your web application, Django will give you a very attractive and powerful interface almost entirely for free.  I&#8217;m not aware of any equivalent for Rails that even comes close to this.</p>
<h2>Deployment</h2>
<p>I&#8217;ve deployed Django using FastCGI and Rails using Mongrel.  Right now I am using Nginx to proxy to Mongrel, and to connect directly to the Django FastCGI instance.  Neither Django nor Rails seems to have a unique advantage or disadvantage in deployment.</p>
<h2>Summary</h2>
<p>I&#8217;ve spent more cumulative time with Django than with Rails, so I feel subjectively more at home with Django.  If I were going to write a small toy project, I&#8217;d choose Django mainly for ease and efficiency.  In fact, I took this route for the <a href="http://www.groupsched.com/">meal and potluck scheduler application</a> that I recently wrote for <a href="http://code.google.com/appengine/">Google App Engine</a>.  GAE has many similarities with Django, and even allows you to run much of the Django stack on it.</p>
<p>However, for larger projects my current framework of choice is Rails.  With the named_scope functionality in Rails 2.1, ActiveRecord is finally on par with Django&#8217;s ORM.   And for any complicated queries ActiveRecord is superior to Django&#8217;s ORM.  While Django&#8217;s admin application is handy, I don&#8217;t make much use of it.  And while Rails falls slightly behind in performance and storage characteristics, I believe that Ruby and Rails will both continue to improve in this regard.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/smoonen.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/smoonen.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/smoonen.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/smoonen.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/smoonen.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/smoonen.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/smoonen.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/smoonen.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/smoonen.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/smoonen.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/smoonen.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/smoonen.wordpress.com/115/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/smoonen.wordpress.com/115/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/smoonen.wordpress.com/115/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=115&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scottmoonen.com/2009/01/09/my-experience-with-django-and-rails/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c801efd19dadd22c4f35d3f1f6ea1869?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">smoonen</media:title>
		</media:content>
	</item>
		<item>
		<title>SmugMug uploader</title>
		<link>http://scottmoonen.com/2008/12/01/smugmug-uploader/</link>
		<comments>http://scottmoonen.com/2008/12/01/smugmug-uploader/#comments</comments>
		<pubDate>Mon, 01 Dec 2008 20:33:56 +0000</pubDate>
		<dc:creator>Scott Moonen</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[gallery]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[picture]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[SmugMug]]></category>
		<category><![CDATA[upload]]></category>

		<guid isPermaLink="false">http://blog.fullvalence.com/?p=38</guid>
		<description><![CDATA[I&#8217;ve written a small Python script to upload pictures to a SmugMug gallery. I love SmugMug and use it extensively for family photos. I&#8217;m using this script for my personal use because it&#8217;s much simpler and much less of a resource hog than a browser-based uploader, and also because it was a fun exercise to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=113&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.smugmug.com/"><img style="border:0 none;float:right;margin:.5em;" src="http://cdn.smugmug.com/img/header/smugmug_black.png" alt="[SmugMug]" width="118" height="25" /></a>I&#8217;ve written a small Python script to upload pictures to a <a href="http://www.smugmug.com/">SmugMug</a> gallery.  I love SmugMug and use it extensively for family photos.  I&#8217;m using this script for my personal use because it&#8217;s much simpler and much less of a resource hog than a browser-based uploader, and also because it was a fun exercise to try out the <a href="http://wiki.smugmug.net/display/SmugMug/API">SmugMug API</a>.  You can run this script as follows to upload one or more files:</p>
<pre>python upload.py <em>gallery-name</em> <em>picture-file-name</em> . . .</pre>
<p>On Windows I&#8217;ve set up a desktop shortcut pointing to the script, and I can drag and drop a pile of picture files onto the icon and it will upload away.  I&#8217;ve tested it using both Python 2.5 using <a href="http://code.google.com/p/simplejson/">simplejson</a>, and also using Python 2.6 which has simplejson built in.  Earlier versions of Python may require you to change the import of hashlib to md5, and change the hashlib.md5() invocation to a md5.new() invocation.  You&#8217;ll also need to modify the script to contain your email address and SmugMug password, and obtain a <a href="http://smugmug.com/hack/apikeys">SmugMug API key</a> for your own development use, but this is a very painless process.  Here is the script:</p>
<p><pre class="brush: python;">
#!/usr/bin/python

##########
# Requirements: Python 2.6 or
#               simplejson from http://pypi.python.org/pypi/simplejson
##########

EMAIL='...'
PASSWORD='...'

##########
APIKEY='...'
API_VERSION='1.2.0'
API_URL='https://api.smugmug.com/hack/json/1.2.0/'
UPLOAD_URL='http://upload.smugmug.com/photos/xmlrawadd.mg'

import sys, re, urllib, urllib2, urlparse, hashlib, traceback, os.path
try    : import json
except : import simplejson as json

if len(sys.argv) &lt; 3 :
  print 'Usage:'
  print '  upload.py  album  picture1  [picture2  [...]]'
  print
  sys.exit(0)

album_name = sys.argv[1]
su_cookie  = None

def safe_geturl(request) :
  global su_cookie

  # Try up to three times
  for x in range(5) :
    try :
      response_obj = urllib2.urlopen(request)
      response = response_obj.read()
      result = json.loads(response)

      # Test for presence of _su cookie and consume it
      meta_info = response_obj.info()
      if meta_info.has_key('set-cookie') :
        match = re.search('(_su=\S+);', meta_info['set-cookie'])
        if match and match.group(1) != &quot;_su=deleted&quot; :
          su_cookie = match.group(1)
      if result['stat'] != 'ok' : raise Exception('Bad result code')
      return result
    except :
      if x &lt; 4 :
        print &quot;  ... failed, retrying&quot;
      else :
        print &quot;  ... failed, giving up&quot;
        print &quot;  Request was:&quot;
        print &quot;  &quot; + request.get_full_url()
        try :
          print &quot;  Response was:&quot;
          print response
        except :
          pass
        traceback.print_exc()
        #sys.stdin.readline()
        #sys.exit(1)
        return result

def smugmug_request(method, params) :
  global su_cookie

  paramstrings = [urllib.quote(key)+'='+urllib.quote(params[key]) for key in params]
  paramstrings += ['method=' + method]
  url = urlparse.urljoin(API_URL, '?' + '&amp;'.join(paramstrings))
  request = urllib2.Request(url)
  if su_cookie :
    request.add_header('Cookie', su_cookie)
  return safe_geturl(request)

result = smugmug_request('smugmug.login.withPassword',
                         {'APIKey'       : APIKEY,
                          'EmailAddress' : EMAIL,
                          'Password'     : PASSWORD})
session = result['Login']['Session']['id']

result = smugmug_request('smugmug.albums.get', {'SessionID' : session})
album_id = None
for album in result['Albums'] :
  if album['Title'] == album_name :
    album_id = album['id']
    break
if album_id is None :
  print 'That album does not exist'
  sys.exit(1)

for filename in sys.argv[2:] :
  data = open(filename, 'rb').read()
  print 'Uploading ' + filename
  upload_request = urllib2.Request(UPLOAD_URL,
                                   data,
                                   {'Content-Length'  : len(data),
                                    'Content-MD5'     : hashlib.md5(data).hexdigest(),
                                    'Content-Type'    : 'none',
                                    'X-Smug-SessionID': session,
                                    'X-Smug-Version'  : API_VERSION,
                                    'X-Smug-ResponseType' : 'JSON',
                                    'X-Smug-AlbumID'  : album_id,
                                    'X-Smug-FileName' : os.path.basename(filename) })
  result = safe_geturl(upload_request)
  if result['stat'] == 'ok' :
    print &quot;  ... successful&quot;

print 'Done'
# sys.stdin.readline()
</pre></p>
<p>I am donating this script to the public domain.  You are welcome to use and modify it as you please without conditions.  I&#8217;d appreciate hearing about your experience with this script or any changes and improvements you&#8217;ve made; please leave a comment.  Thanks!</p>
<p><strong>Update 2010-07-20</strong></p>
<p>Since I first posted this, I&#8217;ve updated it as follows:</p>
<ol>
<li>Add a Content-Type header of &#8216;none&#8217;.  This is to workaround a <a href="http://www.dgrin.com/showthread.php?p=1424518">bug in the SmugMug API</a>.</li>
<li>Use basename() to send only the file&#8217;s basename for X-Smug-FileName.</li>
<li>Rewrite safe_geturl() to loop up to five times if the upload attempt fails.  I&#8217;ve found that uploading is surprisingly unreliable, and re-attempting the upload generally works fine.
<li>Add a commented call to readline() at the end of the script.  In my case, I run my script by dragging files onto an icon on my Windows desktop, which causes it to run in a DOS window and vanish when done.  If you uncomment this line, it will wait for you to press Enter when it is done uploading.  You&#8217;ll be able to see any files that weren&#8217;t uploaded successfully.</li>
</ol>
<p><strong>Update 2010-11-28</strong></p>
<p>SmugMug made a recent change to their API&#8217;s login behavior which broke this script.  While the new login behavior is not documented in the API docs, the fix is apparently to <a href="http://dgrin.com/showthread.php?t=183759">use a session cookie along with the session ID</a>.  While it&#8217;s a bit of a kludge, I&#8217;ve updated the script above to save this cookie in a global variable and submit it on subsequent requests.</p>
<p><strong>Update 2011-06-24</strong></p>
<p>I&#8217;ve fixed a bug in the script causing it to wrongly report a failure for certain requests that don&#8217;t send back the session cookie. The fix involves testing whether a set-cookie header was returned before accessing the header.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/smoonen.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/smoonen.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/smoonen.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/smoonen.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/smoonen.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/smoonen.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/smoonen.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/smoonen.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/smoonen.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/smoonen.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/smoonen.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/smoonen.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/smoonen.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/smoonen.wordpress.com/113/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=113&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scottmoonen.com/2008/12/01/smugmug-uploader/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c801efd19dadd22c4f35d3f1f6ea1869?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">smoonen</media:title>
		</media:content>

		<media:content url="http://cdn.smugmug.com/img/header/smugmug_black.png" medium="image">
			<media:title type="html">[SmugMug]</media:title>
		</media:content>
	</item>
		<item>
		<title>Python generators &#8211; saving time and memory</title>
		<link>http://scottmoonen.com/2008/02/01/python-generators-saving-time-and-memory/</link>
		<comments>http://scottmoonen.com/2008/02/01/python-generators-saving-time-and-memory/#comments</comments>
		<pubDate>Fri, 01 Feb 2008 15:22:25 +0000</pubDate>
		<dc:creator>Scott Moonen</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[efficiency]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[footprint]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[generator]]></category>
		<category><![CDATA[generators]]></category>
		<category><![CDATA[iterator]]></category>
		<category><![CDATA[list]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[object]]></category>
		<category><![CDATA[return]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[time]]></category>
		<category><![CDATA[yield]]></category>

		<guid isPermaLink="false">http://blog.fullvalence.com/2008/02/01/python-generators-saving-time-and-memory/</guid>
		<description><![CDATA[Python version 2.2 introduced support for generator functions. A generator is a function that returns something kind of like a list. You can think of a generator as a function that gets to return more than once; each time it returns, it produces a new item in the list. Here is a simple example of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=100&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Python version 2.2 introduced support for <em>generator</em> functions.  A generator is a function that returns something kind of like a list.  You can think of a generator as a function that gets to return more than once; each time it returns, it produces a new item in the list.  Here is a simple example of a generator:</p>
<p><pre class="brush: python;">
def mygen() :
  print &quot;calling generator&quot;
  for x in [1, 2, 3, 4] :
    print &quot;yielding next value&quot;
    yield x

for item in mygen() :
  print item
</pre></p>
<p>This example prints the following:<br />
<pre class="brush: bash;">
calling generator
yielding next value
1
yielding next value
2
yielding next value
3
yielding next value
4
</pre></p>
<p>Instead of <tt>return</tt>, we used the <tt>yield</tt> statement inside our generator.  <tt>yield</tt> returns an item from the generator, but marks that point in the code so that we continue processing when we go back to the generator to fetch the next item in the pseudo-list.  Notice how the generator is only called once, but the yield points are interleaved with the print statements in the calling code.  Each time the generator needs to produce a new value, it picks up from the previous yield point.  When the generator reaches the end of the function, no more values are produced.  You cannot use <tt>return</tt> within a generator.</p>
<p>Let&#8217;s look at some code where the use of generators might help us.  The following code instantiates a list of objects and then creates HTML to display them.  We&#8217;ll assume the existence of a database API to execute queries and retrieve results:</p>
<p><pre class="brush: python;">
def get_objects() :
  result = []
  query = db_execute(&quot;...&quot;)
  row = query.fetchrow()
  while not row is None :
    result.append(MyObject(row))  # Build object from DB, append to result
    row = query.fetchrow()
  return result
. . .
for object in get_objects() :
  print object.getHTML()
</pre></p>
<p>This code creates the entire list of objects before it can print any of them.  There are two problems with this &#8212; first, there is a huge delay to create all of the objects before any progress is made in printing; this means that the user&#8217;s browser has no partial results to display.  Second, all of the objects must be held in memory at the same time; if there are many objects, this can cause significant overhead.</p>
<p>Generators allow us to attack both of these problems.  Since a generator produces items one at a time, on demand, it avoids both of these problems.  We don&#8217;t have to wait to construct all of the objects in the list before we use the first one.  And once we are done using an object, the Python garbage collector is now free to immediately clean it up.  Here&#8217;s how we might rewrite the above code to use generators:</p>
<p><pre class="brush: python;">
def get_objects() :
  query = db_execute(&quot;...&quot;)
  row = query.fetchrow()
  while not row is None :
    yield MyObject(row)    # Build object from DB, yield to caller
    row = query.fetchrow()
. . .
for object in get_objects() :
  print object.getHTML()
</pre></p>
<p>With a small change we have now significantly improved our code&#8217;s memory footprint &#8212; all of the objects do not need to be held in memory at the same time.  And we are now producing the output for each object as we create it, without needing to wait for all the objects to be instantiated first.  This is a significant improvement!</p>
<p>We can also build a chain of generators.  Let&#8217;s assume that we need to modify the code above to optionally display only those objects that have an &#8220;active&#8221; flag set.  Ordinarily, if we use Python&#8217;s <tt>filter</tt> function to accomplish this, it needs to create the entire list all at once. But if we use a generator to perform the filtering, then we can still keep our optimizations since we are only ever creating and filtering one object at a time.  Here&#8217;s an example:</p>
<p><pre class="brush: python;">
my_objs = get_objects()         # This returns a generator object

if display_active_only :
  def active_filter(objects) :  # A filtering generator
    for object in objects :
      if object.active :
        yield object

  my_objs = active_filter(my_objs)

for object in my_objs :
  print object.getHTML()
</pre></p>
<p>A generator function doesn&#8217;t produce a real list; instead, it produces a generator object that behaves like something called an <a href="http://docs.python.org/lib/typeiter.html">iterator</a>.  You can&#8217;t write either of the following statements for a generator or iterator:</p>
<p><pre class="brush: python;">
print len(get_objects())
print get_objects()[3]
</pre></p>
<p>The <tt>for</tt> statement is smart enough to traverse a generator, and it will probably be sufficient for your needs.  Perhaps you can get the count of objects by other means, such as executing an SQL COUNT request.  If you absolutely need to access a generator as a list, you can coerce it to a list as follows:</p>
<p><pre class="brush: python;">
objlist = list(get_objects())
</pre></p>
<p>But be aware that this removes all of the advantages that we&#8217;ve discussed here, since this causes all of the objects returned by the generator to be created at once and stored in the list.  If you find yourself needing to do this, you should consider rewriting your code so that you don&#8217;t need to do so.  Or perhaps generators aren&#8217;t the right solution for your particular problem.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/smoonen.wordpress.com/100/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/smoonen.wordpress.com/100/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/smoonen.wordpress.com/100/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/smoonen.wordpress.com/100/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/smoonen.wordpress.com/100/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/smoonen.wordpress.com/100/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/smoonen.wordpress.com/100/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/smoonen.wordpress.com/100/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/smoonen.wordpress.com/100/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/smoonen.wordpress.com/100/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/smoonen.wordpress.com/100/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/smoonen.wordpress.com/100/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/smoonen.wordpress.com/100/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/smoonen.wordpress.com/100/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/smoonen.wordpress.com/100/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/smoonen.wordpress.com/100/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=100&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scottmoonen.com/2008/02/01/python-generators-saving-time-and-memory/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c801efd19dadd22c4f35d3f1f6ea1869?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">smoonen</media:title>
		</media:content>
	</item>
		<item>
		<title>Python combinations</title>
		<link>http://scottmoonen.com/2007/09/01/python-combinations/</link>
		<comments>http://scottmoonen.com/2007/09/01/python-combinations/#comments</comments>
		<pubDate>Sun, 02 Sep 2007 00:25:50 +0000</pubDate>
		<dc:creator>Scott Moonen</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[choices]]></category>
		<category><![CDATA[combinations]]></category>
		<category><![CDATA[combinatorics]]></category>

		<guid isPermaLink="false">http://scottmoonen.com/?p=350</guid>
		<description><![CDATA[In September 2007, Brian Adkins posted a simple Logo program to print all possible combinations of lists of items, and asked for alternatives in other languages. He provided a Ruby alternative which would translate fairly easily into Python. For my own Python implementation I decided to try a completely different approach:<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=350&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In September 2007, <a href="http://lojic.com/blog/">Brian Adkins</a> posted <a href="http://lojic.com/blog/2007/08/31/logo-ruby-javascript/">a simple Logo program</a> to print all possible combinations of lists of items, and asked for alternatives in other languages.  He provided a Ruby alternative which would translate fairly easily into Python.  For my own Python implementation I decided to try a completely different approach:</p>
<p><pre class="brush: python;">
prod1   = lambda elem, vec : map(lambda x : elem+' '+x, vec)
xprod   = lambda vec1, vec2 : reduce(list.__add__, map(lambda elem : prod1(elem ,vec2), vec1))
choices = lambda x : '\n'.join(reduce(xprod, x))+'\n'

q = [['small', 'medium', 'large'],
     ['vanilla', 'ultra chocolate', 'lychee', 'rum raisin', 'ginger'],
     ['cone', 'cup']]

print choices(q),
</pre></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/smoonen.wordpress.com/350/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/smoonen.wordpress.com/350/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/smoonen.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/smoonen.wordpress.com/350/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/smoonen.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/smoonen.wordpress.com/350/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/smoonen.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/smoonen.wordpress.com/350/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/smoonen.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/smoonen.wordpress.com/350/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/smoonen.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/smoonen.wordpress.com/350/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/smoonen.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/smoonen.wordpress.com/350/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/smoonen.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/smoonen.wordpress.com/350/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=350&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scottmoonen.com/2007/09/01/python-combinations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c801efd19dadd22c4f35d3f1f6ea1869?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">smoonen</media:title>
		</media:content>
	</item>
		<item>
		<title>Functional Python</title>
		<link>http://scottmoonen.com/2005/06/09/functional-python/</link>
		<comments>http://scottmoonen.com/2005/06/09/functional-python/#comments</comments>
		<pubDate>Thu, 09 Jun 2005 12:13:18 +0000</pubDate>
		<dc:creator>Scott Moonen</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[function]]></category>
		<category><![CDATA[functional]]></category>
		<category><![CDATA[functional programming]]></category>
		<category><![CDATA[lambda]]></category>

		<guid isPermaLink="false">http://scottmoonen.com/?p=353</guid>
		<description><![CDATA[A friend of mine is learning Python and was curious about functional programming, so I have written this brief tutorial. Python isn&#8217;t a full-fledged functional language, but it supports some very useful functional idioms. It&#8217;s best to approach this tutorial by programming along at the Python interactive prompt. Try typing everything in to see what [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=353&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>A friend of mine is learning Python and was curious about functional programming, so I have written this brief tutorial.  Python isn&#8217;t a full-fledged functional language, but it supports some very useful functional idioms.</p>
<p>It&#8217;s best to approach this tutorial by programming along at the Python interactive prompt.  Try typing everything in to see what the results are.</p>
<h3>Introduction</h3>
<p>Imagine you have a list of numbers and want to filter out all even numbers:</p>
<p><pre class="brush: python;">
q = [1,2,5,6,8,12,15,17,20,23,24]

def is_even(x) :
  return x % 2 == 0

result = filter(is_even, q)
</pre></p>
<p>(Remember that the &#8220;%&#8221; operator is the modulus or remainder operator.  If the remainder when a number is divided by two is zero, then the number must be even.)</p>
<p>If we only use <tt>is_even</tt> once, it&#8217;s kind of annoying that we have to define it.  Wouldn&#8217;t it be nice if we could just define it inside of the call to <tt>filter</tt>?  We want to do something like &#8220;<tt>q = filter(x % 2 == 0, q)</tt>&#8220;, but that won&#8217;t quite work, since the &#8220;<tt>x % 2 == 0</tt>&#8221; is evaluated before the call to <tt>filter</tt>.  We want to pass a function to filter, not an expression.</p>
<p>We can do this using the <tt>lambda</tt> operator.  <tt>lambda</tt> allows you to create an unnamed throw-away function.  Try this:</p>
<p><pre class="brush: python;">
q = [1,2,5,6,8,12,15,17,20,23,24]
result = filter(lambda x : x % 2 == 0, q)
</pre></p>
<p><tt>lambda</tt> tells Python that a function follows.  Before the colon (:) you list the parameters of the function (in this case, only one, <em>x</em>).  After the colon you list what the function returns.  This function doesn&#8217;t have a name, and Python disposes of it as soon as <tt>filter</tt> is done with it.</p>
<p>You can, however, assign the function to a variable to give it a name.  The following two statements are identical:</p>
<p><pre class="brush: python;">
def is_odd(x) :
  return x % 2 == 1
 
is_odd = lambda x : x % 2 == 1
</pre></p>
<h3>map</h3>
<p>Here&#8217;s another example.  The <tt>map</tt> function applys a function to every item in a list, and returns the result.  This example adds 1 to every element in the list:</p>
<p><pre class="brush: python;">
result = map(lambda x : x + 1, [1,2,3,4,5])
</pre></p>
<p>(At this point, <tt>result</tt> holds <tt>[2,3,4,5,6]</tt>.)</p>
<p>The <tt>map</tt> function can also process more than one list at a time, provided they are the same length.  This allows you to do things like add all of the elements in a pair of lists.  Note that our lambda here has two parameters:</p>
<p><pre class="brush: python;">
result = map(lambda x,y : x+y, [1,2,3,4,5], [6,7,8,9,10])
</pre></p>
<p>(At this point, <tt>result</tt> holds <tt>[7, 9, 11, 13, 15]</tt>.)</p>
<h3>reduce</h3>
<p>Python also provides the <tt>reduce</tt> function.  This is a bit more complicated; you provide it a list and a function, and it reduces that list by applying the function to pairs of elements in the list.  An example is the best way to understand this.  Let&#8217;s say we want to find the sum of all the elements in a list:</p>
<p><pre class="brush: python;">
sum = reduce(lambda x,y : x+y, [1,2,3,4,5])
</pre></p>
<p><tt>reduce</tt> will first apply the function to 1,2, yielding 3.  It will then apply the function to 3,3 (the first 3 is the result of adding 1+2), yielding 6.  It will then apply the function to 6,4 (the 6 is the result of adding 3+3), yielding 10.  Finally, it will apply the function to 10,5, yielding 15.  The result stored in <tt>sum</tt> is 15.</p>
<p>Similarly, we can find the cumulative product of all items in a list.  The following example stores 120 (=1*2*3*4*5) in <tt>product</tt>:</p>
<p><pre class="brush: python;">
product = reduce(lambda x,y : x*y, [1,2,3,4,5])
</pre></p>
<h3>Conditionals</h3>
<p>Beginning in Python 2.5 you can even express conditions within your lambdas, using Python&#8217;s conditional expressions.  So, for example:</p>
<p><pre class="brush: python;">
reciprocals = map(lambda x : 1.0/x if x !=  0 else None, [0, 1, 2, 3, 4, 5])
</pre></p>
<p>At this point, <tt>reciprocals</tt> holds the list <tt>[None, 1.0, 0.5, 0.333..., 0.25, 0.2]</tt>.  The expression &#8220;1/x if x != 0 else None&#8221; is the conditional expression, and it is used to prevent division by zero.  If <em>x</em> is not 0, then the result is 1/x, but otherwise it is None.</p>
<h3>Background</h3>
<p>One of the advantages of lambda-functions is that they allow you to write very concise code.  A result of this, however, is that the code is dense with meaning, and it can be hard to read if you are not accustomed to functional programming.  In our first example, <tt>filter(is_even, q)</tt> was fairly easy to understand (fortunately, we chose a descriptive function name), while <tt>filter(lambda x : x % 2 == 0, q)</tt> takes a little longer to comprehend.</p>
<p>If you are a masochistic mathematical geek, you&#8217;ll probably enjoy this (I do).  If not, you might still prefer to break things into smaller pieces by defining all of your functions first and then using them by name.  That&#8217;s ok!  Functional programming isn&#8217;t for everyone.</p>
<p>Another advantage of functional programming is that it corresponds very closely to the mathematical notion of functions.  Note that our lambda-functions didn&#8217;t store any results into variables, or have any other sort of side effect.  Functions without side effects cause fewer bugs, because their behavior is deterministic (this is related to the dictum that you aren&#8217;t supposed to use global variables).  It is also much easier to mathematically prove that such functions do what you think they are doing.  (Note that it&#8217;s still possible to write a lambda function that has side effects, if the lambda function calls another function that has side effects; for example <tt>lambda x : sys.stdout.write(str(x))</tt> has the side effect of printing its parameter to the screen.)</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/smoonen.wordpress.com/353/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/smoonen.wordpress.com/353/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/smoonen.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/smoonen.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/smoonen.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/smoonen.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/smoonen.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/smoonen.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/smoonen.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/smoonen.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/smoonen.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/smoonen.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/smoonen.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/smoonen.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/smoonen.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/smoonen.wordpress.com/353/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=353&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scottmoonen.com/2005/06/09/functional-python/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c801efd19dadd22c4f35d3f1f6ea1869?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">smoonen</media:title>
		</media:content>
	</item>
		<item>
		<title>Python odd word problem</title>
		<link>http://scottmoonen.com/2004/11/10/python-odd-word-problem/</link>
		<comments>http://scottmoonen.com/2004/11/10/python-odd-word-problem/#comments</comments>
		<pubDate>Wed, 10 Nov 2004 10:36:31 +0000</pubDate>
		<dc:creator>Scott Moonen</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Dijkstra]]></category>
		<category><![CDATA[E. W. Dijkstra]]></category>

		<guid isPermaLink="false">http://scottmoonen.com/?p=347</guid>
		<description><![CDATA[I crafted this compact solution to Dijkstra&#8217;s OddWordProblem:<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=347&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I crafted this compact solution to Dijkstra&#8217;s <a href="http://c2.com/cgi/wiki?OddWordProblem">OddWordProblem</a>:</p>
<p><pre class="brush: python;">
from sys import stdin, stdout
def even(char) : stdout.write(char); return select(even, 0, &quot;&quot;);
def odd(char)  : q = select(odd, 0, &quot;&quot;); stdout.write(char); return q
def select(fn, skipspace, prefix) :
  char = stdin.read(1)
  if char.isspace() and skipspace : return select(fn, 1, prefix)
  elif char.isspace()             : return 0
  elif char.isalpha()             : stdout.write(prefix); return fn(char)
  elif char == &quot;.&quot;                : return 1
  else                            : raise &quot;Invalid input&quot;

if not select(even, 1, &quot;&quot;) :
while not select(odd, 1, &quot; &quot;) and not select(even, 1, &quot; &quot;) : pass
stdout.write(&quot;.&quot;)
</pre></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/smoonen.wordpress.com/347/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/smoonen.wordpress.com/347/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/smoonen.wordpress.com/347/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/smoonen.wordpress.com/347/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/smoonen.wordpress.com/347/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/smoonen.wordpress.com/347/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/smoonen.wordpress.com/347/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/smoonen.wordpress.com/347/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/smoonen.wordpress.com/347/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/smoonen.wordpress.com/347/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/smoonen.wordpress.com/347/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/smoonen.wordpress.com/347/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/smoonen.wordpress.com/347/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/smoonen.wordpress.com/347/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/smoonen.wordpress.com/347/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/smoonen.wordpress.com/347/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=347&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scottmoonen.com/2004/11/10/python-odd-word-problem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c801efd19dadd22c4f35d3f1f6ea1869?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">smoonen</media:title>
		</media:content>
	</item>
		<item>
		<title>Python list partition</title>
		<link>http://scottmoonen.com/2004/11/09/python-list-partition/</link>
		<comments>http://scottmoonen.com/2004/11/09/python-list-partition/#comments</comments>
		<pubDate>Tue, 09 Nov 2004 19:10:22 +0000</pubDate>
		<dc:creator>Scott Moonen</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[list]]></category>
		<category><![CDATA[partition]]></category>

		<guid isPermaLink="false">http://scottmoonen.com/?p=343</guid>
		<description><![CDATA[I came up with these simple solutions to RonJeffries&#8216; CodingProblem. The first uses Python 2.2’s generators, the second uses the functional idiom, and the third uses list comprehensions. The third is my favorite:<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=343&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I came up with these simple solutions to <a href="http://c2.com/cgi/wiki?RonJeffries">RonJeffries</a>&#8216; <a href="http://c2.com/cgi/wiki?CodingProblem">CodingProblem</a>.  The first uses Python 2.2’s generators, the second uses the functional idiom, and the third uses list comprehensions.  The third is my favorite:</p>
<p><pre class="brush: python;">
def split1(list, num) :
  for index in range(num) :
    yield list[index * len(list) / num:(index + 1) * len(list) / num]

def split2(list, num) :
  return map(lambda x: list[x * len(list) / num:(x+1) * len(list) / num], range(num))

def split3(list, num) :
  return [list[x*len(list)/num : (x+1)*len(list)/num] for x in range(num)]
</pre></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/smoonen.wordpress.com/343/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/smoonen.wordpress.com/343/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/smoonen.wordpress.com/343/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/smoonen.wordpress.com/343/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/smoonen.wordpress.com/343/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/smoonen.wordpress.com/343/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/smoonen.wordpress.com/343/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/smoonen.wordpress.com/343/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/smoonen.wordpress.com/343/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/smoonen.wordpress.com/343/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/smoonen.wordpress.com/343/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/smoonen.wordpress.com/343/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/smoonen.wordpress.com/343/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/smoonen.wordpress.com/343/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/smoonen.wordpress.com/343/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/smoonen.wordpress.com/343/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=343&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scottmoonen.com/2004/11/09/python-list-partition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c801efd19dadd22c4f35d3f1f6ea1869?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">smoonen</media:title>
		</media:content>
	</item>
		<item>
		<title>Python Timestamp Increment</title>
		<link>http://scottmoonen.com/2004/11/09/python-timestamp-increment/</link>
		<comments>http://scottmoonen.com/2004/11/09/python-timestamp-increment/#comments</comments>
		<pubDate>Tue, 09 Nov 2004 17:52:32 +0000</pubDate>
		<dc:creator>Scott Moonen</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[timestamp]]></category>

		<guid isPermaLink="false">http://scottmoonen.com/?p=339</guid>
		<description><![CDATA[I composed this concise solution to ncm&#8216;s &#8220;coding challenge&#8221; in November 2004. I&#8217;m not entirely satisfied with its elegance, but I&#8217;m pleased with its brevity. I further reduced this as follows, turning the carry function into a one-liner that computes the carry in-place (and also using builtins wherever possible). I’m much more satisfied with this [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=339&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I composed this concise solution to <a href="http://www.advogato.org/person/ncm/">ncm</a>&#8216;s &#8220;<a>coding challenge</a>&#8221; in November 2004.  I&#8217;m not entirely satisfied with its elegance, but I&#8217;m pleased with its brevity.</p>
<p><pre class="brush: python;">
def dateinc(s) :
  def carry(list, modulus) :
    if len(list) == 1 : return [list[0] // modulus[0], list[0] % modulus[0]]
    else              : q = carry(list[1:], modulus[1:]); return [(list[0] + q[0]) // modulus[0], (list[0] + q[0]) % modulus[0]] + q[1:]
  s = reduce(lambda x,y:x+y, map(lambda x : (x &gt;= '0' and x &lt;= '9') * x, s))
  result = map(lambda x,y:x+y, map(int,(s[0:4],s[4:6],s[6:8],s[8:10],s[10:12],s[12:14])),(0,-1,-1,0,0,1))
  modulus = [10000,12,[31,28,31,30,31,30,31,31,30,31,30,31][result[1]],24,60,60]
  if result[0] % 4 == 0 and (result[0] % 100 != 0 or result[0] % 400 == 0) :
    modulus[2] += 1                               # Account for leap day.
  result = carry(result, modulus)[1:]             # Carry the extra second.
  result[1:3] = map(lambda x:x+1, result[1:3])    # Readjust to 1-base.
  return reduce(lambda x,y:x+y, map(lambda x : (x &lt; 10) * '0' + str(x), result))
</pre></p>
<p>I further reduced this as follows, turning the carry function into a one-liner that computes the carry in-place (and also using builtins wherever possible). I’m much more satisfied with this solution.</p>
<p><pre class="brush: python;">
def dateinc(s) :
  s = reduce(lambda x,y:x.isdigit()*x+y.isdigit()*y, s)
  ans = map(int.__add__, map(int,(s[0:4],s[4:6],s[6:8],s[8:10],s[10:12],s[12:14])),(0,-1,-1,0,0,1))
  mod = [10000,12,[31,28,31,30,31,30,31,31,30,31,30,31][ans[1]],24,60,60]
  if ans[0] % 4 == 0 and (ans[0] % 100 != 0 or ans[0] % 400 == 0) : mod[2] += 1
  ans = map(lambda x:(ans[x] + reduce(int.__mul__, map(lambda y:ans[y]&gt;=mod[y]-1,range(x+1,len(ans))),x!=len(ans)-1)) % mod[x], range(len(ans)))
  ans[1:3] = map(int.__add__,ans[1:3],[1,1])      # Readjust to 1-base.
  return reduce(str.__add__, map(lambda x : (x &lt; 10) * '0' + str(x), ans))
</pre></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/smoonen.wordpress.com/339/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/smoonen.wordpress.com/339/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/smoonen.wordpress.com/339/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/smoonen.wordpress.com/339/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/smoonen.wordpress.com/339/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/smoonen.wordpress.com/339/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/smoonen.wordpress.com/339/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/smoonen.wordpress.com/339/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/smoonen.wordpress.com/339/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/smoonen.wordpress.com/339/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/smoonen.wordpress.com/339/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/smoonen.wordpress.com/339/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/smoonen.wordpress.com/339/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/smoonen.wordpress.com/339/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/smoonen.wordpress.com/339/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/smoonen.wordpress.com/339/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=339&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scottmoonen.com/2004/11/09/python-timestamp-increment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c801efd19dadd22c4f35d3f1f6ea1869?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">smoonen</media:title>
		</media:content>
	</item>
		<item>
		<title>Python persistence</title>
		<link>http://scottmoonen.com/2004/10/01/python-persistence/</link>
		<comments>http://scottmoonen.com/2004/10/01/python-persistence/#comments</comments>
		<pubDate>Fri, 01 Oct 2004 16:07:22 +0000</pubDate>
		<dc:creator>Scott Moonen</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[object store]]></category>
		<category><![CDATA[persistence]]></category>
		<category><![CDATA[prevalence]]></category>

		<guid isPermaLink="false">http://scottmoonen.com/?p=363</guid>
		<description><![CDATA[I&#8217;ve implemented a rudimentary persistent object store in Python. It is implemented as a Python extension module that implements a set of persistent types: strings, integers, floats, lists, and dictionaries. Each of these are backed by the persistent object store, which is implemented using a memory-mapped file. In addition, using a specially crafted Python base [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=363&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve implemented a rudimentary persistent object store in Python.  It is implemented as a Python extension module that implements a set of persistent types: strings, integers, floats, lists, and dictionaries.  Each of these are backed by the persistent object store, which is implemented using a memory-mapped file.</p>
<p>In addition, using a specially crafted Python base class for Python objects, Python objects may be stored in the object store (as dictionaries) and instantiated out of the object store.</p>
<p>The result is an persistent object graph (the root of which is a persistent dictionary) whose objects and attributes may be manipulated in-place using native Python syntax.  Rudimentary locking is provided so that multiple Python threads / processes may concurrently manipulate the object store.</p>
<h3>Details</h3>
<p>Some aspects of this system are:</p>
<ul>
<li>It is a Python extension module written in C and C++.</li>
<li>It is tested on Linux.  It will likely work on *BSD systems, though it is possible that the location of the mapped storage may need to be moved.</li>
<li>It is implemented in a hierarchical manner:
<ul>
<li>A <em>page manager</em> handles the allocation of 4kB pages within a memory-mapped file.  It is multi-process safe.  It is, in a sense, a glorified <tt>sbrk()</tt> for a memory-mapped file.</li>
<li>A <em>heap manager</em> abstracts the page manager&#8217;s services to manage the allocation and deallocation of arbitrary-sized storage segments within the memory-mapped file.  It is essentially a <tt>malloc()</tt> and <tt>free()</tt> for a memory-mapped file.  This is also multi-process safe.</li>
<li>An <em>object manager</em> manages five new base types (persistent int, float, string, list, and dictionary) backed by persistent storage, using the heap manager&#8217;s services.  It also provides rudimentary locking facilities for concurrency-safeness.</li>
<li>The <tt>persist</tt> Python extension uses the object manager&#8217;s services to implement persistent types that mimic the equivalent Python types.  Additionally, it has the ability to reinstantiate a Python object that was stored as a dictionary (using the appropriate Python base class).  The object manager&#8217;s locking facilities are made available for application usage.</li>
</ul>
</li>
<li>Only one file may be mapped at a time (because it is mapped to a fixed logical address).</li>
<li>It is available for use under the MIT license.  Contact me if you are interested in using it.</li>
</ul>
<h3>Examples</h3>
<p>Some examples of its use are a simple counter:</p>
<p><pre class="brush: python;">
import persist

root = persist.root()
root.lockExcl()
try :    root['x'] += 1                # Increment counter
except : root['x'] = 1                 # First pass; initialize
print &quot;Content-type: text/html\n&quot;
print &quot;&lt;p&gt;You are visitor &quot; + str(root['x']) + &quot; to visit this site!&lt;/p&gt;&quot;
root.unlock()
</pre></p>
<p>and rudimentary objects:</p>
<p><pre class="brush: python;">
import persist
from pbase import pbase

class person (pbase) :
  def __init__(self, name = &quot;&quot;, age = 0) :
    pbase.__init__(self)
    self.name = name
    self.age = age

  def printAge(self) :
    print &quot;&lt;p&gt;&quot; + self.name + &quot; is &quot; + str(self.age) + &quot; years old&lt;/p&gt;&quot;

root = persist.root()
root.lockExcl()

if not root.has_key('Joe') :            # First time through
  root['Joe'] = person('Joe', 27)
if not root.has_key('John') :           # First time through
  root['John'] = person(&quot;John&quot;, 29)

# On subsequent passes we will retrieve the objects stored on the first pass.

print &quot;Content-type: text/html\n&quot;
root['Joe'].printAge()
root['John'].printAge()

root.unlock()
</pre></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/smoonen.wordpress.com/363/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/smoonen.wordpress.com/363/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/smoonen.wordpress.com/363/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/smoonen.wordpress.com/363/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/smoonen.wordpress.com/363/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/smoonen.wordpress.com/363/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/smoonen.wordpress.com/363/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/smoonen.wordpress.com/363/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/smoonen.wordpress.com/363/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/smoonen.wordpress.com/363/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/smoonen.wordpress.com/363/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/smoonen.wordpress.com/363/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/smoonen.wordpress.com/363/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/smoonen.wordpress.com/363/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/smoonen.wordpress.com/363/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/smoonen.wordpress.com/363/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scottmoonen.com&#038;blog=9709237&#038;post=363&#038;subd=smoonen&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scottmoonen.com/2004/10/01/python-persistence/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/c801efd19dadd22c4f35d3f1f6ea1869?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">smoonen</media:title>
		</media:content>
	</item>
	</channel>
</rss>
