<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-18720575</id><updated>2011-04-21T12:34:10.273-07:00</updated><title type='text'>Serpent Addiction</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://serpentaddiction.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://serpentaddiction.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jeff Bauer</name><uri>http://www.blogger.com/profile/17023308739087864427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='27' src='http://3.bp.blogspot.com/_Kk8bilu8bj0/S9ZK76GzerI/AAAAAAAAAF4/oI9gZSYn4as/S220/jeff_head.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-18720575.post-114030058258815108</id><published>2006-02-18T14:05:00.000-08:00</published><updated>2006-02-18T14:10:23.580-08:00</updated><title type='text'>python builtin inflation</title><content type='html'>There's some talk on python-dev about adding defaultdict.  One consequence of tinkering with Python is the number of builtins increase over time.  Here's my only-slightly-tongue-in-cheek proposal.  The total amount of builtins should be limited to a standard sized 80x24 xterm screen:&lt;br /&gt;&lt;br /&gt;Python 2.4.2 (#2, Sep 30 2005, 21:19:01)&lt;br /&gt;&gt;&gt;&gt; dir(__builtins__)&lt;br /&gt;['ArithmeticError', 'AssertionError', 'AttributeError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 'IOError', 'ImportError', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'OverflowWarning', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '__debug__', '__doc__', '__import__', '__name__', 'abs', 'apply', 'basestring', 'bool', 'buffer', 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'min', 'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']&lt;br /&gt;&gt;&gt;&gt;&lt;br /&gt;&lt;br /&gt;We've got a little room for futher expansion, but many more will have to come at the cost of removing others.  How did 'zip' ever get in there?  ;-)&lt;br /&gt;&lt;br /&gt;Interesting to compare with "classic" Python 1.52 ...&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; dir(__builtins__)&lt;br /&gt;['ArithmeticError', 'AssertionError', 'AttributeError', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'FloatingPointError', 'IOError', 'ImportError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplementedError', 'OSError', 'OverflowError', 'RuntimeError', 'StandardError', 'SyntaxError', 'SystemError', 'SystemExit', 'TypeError', 'ValueError', 'ZeroDivisionError', '__debug__', '__doc__', '__import__', '__name__', 'abs', 'apply', 'buffer', 'callable', 'chr', 'cmp', 'coerce', 'compile', 'complex', 'delattr', 'dir', 'divmod', 'eval', 'execfile', 'exit', 'filter', 'float', 'getattr', 'globals', 'hasattr', 'hash', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'len', 'list', 'locals', 'long', 'map', 'max', 'min', 'oct', 'open', 'ord', 'pow', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'round', 'setattr', 'slice', 'str', 'tuple', 'type', 'vars', 'xrange']&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18720575-114030058258815108?l=serpentaddiction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serpentaddiction.blogspot.com/feeds/114030058258815108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18720575&amp;postID=114030058258815108' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/114030058258815108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/114030058258815108'/><link rel='alternate' type='text/html' href='http://serpentaddiction.blogspot.com/2006/02/python-builtin-inflation.html' title='python builtin inflation'/><author><name>Jeff Bauer</name><uri>http://www.blogger.com/profile/17023308739087864427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='27' src='http://3.bp.blogspot.com/_Kk8bilu8bj0/S9ZK76GzerI/AAAAAAAAAF4/oI9gZSYn4as/S220/jeff_head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18720575.post-113778713739541160</id><published>2006-01-20T11:50:00.000-08:00</published><updated>2006-01-20T11:58:57.423-08:00</updated><title type='text'>It's not all fun and games</title><content type='html'>I'm wearing my sysadmin hat today.  Last night&lt;br /&gt;I started an upgrade for trajan (Debian Sarge).&lt;br /&gt;When I got in early this morning it wouldn't&lt;br /&gt;boot, just hung at "LI".  The usual panicky&lt;br /&gt;minutes before verifying that the nightly&lt;br /&gt;backups completed.&lt;br /&gt;&lt;br /&gt;Next, attempt to boot up on &lt;a href="http://www.knoppix-en.org"&gt;Knoppix&lt;/a&gt;&lt;br /&gt;and verify the filesystems are okay.&lt;br /&gt;&lt;br /&gt;I attempted to rebuild LILO (yes, I use GRUB&lt;br /&gt;for all the new installs):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# mount /dev/hda3 /mnt/hda3&lt;br /&gt;# chroot /mnt/hda3&lt;br /&gt;# /sbin/lilo&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But Knoppix won't write lilo to /dev/hda,&lt;br /&gt;even after I've given it write access.  This&lt;br /&gt;is one of the few times Knoppix has let me&lt;br /&gt;down.  Fortunately, I've got another Linux&lt;br /&gt;Rescue CD with the 2.4 kernel.  Booting up&lt;br /&gt;on it finally allows me to rebuild LILO.  My&lt;br /&gt;decision process was much more time consuming&lt;br /&gt;than appears above, but that was the general&lt;br /&gt;flow.  &lt;i&gt;Stupid Jeff:&lt;/i&gt;  I didn't have a rescue&lt;br /&gt;diskette built, at least not one that was&lt;br /&gt;readily available.  A boot diskette would have&lt;br /&gt;saved valuable time.&lt;br /&gt;&lt;br /&gt;Unfortunately there are now some residual&lt;br /&gt;problems from the upgrade.  Python spews some&lt;br /&gt;wierd linkage warnings (fixed by recompiling&lt;br /&gt;the source), but Apache won't allow any users&lt;br /&gt;to log on.&lt;br /&gt;&lt;br /&gt;An awful lot of cursing/head-scratching later&lt;br /&gt;reveals a couple of very obscure Apache bugs:&lt;br /&gt;&lt;br /&gt;The gist of the matter is that I must swap the&lt;br /&gt;order in which the following modules appear in&lt;br /&gt;the configuration.&lt;br /&gt;&lt;br /&gt;LoadModule auth_module /usr/lib/apache/1.3/mod_auth_ssl.so&lt;br /&gt;LoadModule apache_ssl_module /usr/lib/apache/1.3/libssl.so&lt;br /&gt;&lt;br /&gt;Also, I had to turn off SSLFakeBasicAuth, which&lt;br /&gt;was on by default.&lt;br /&gt;&lt;br /&gt;Quite a nerve-wracking morning.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18720575-113778713739541160?l=serpentaddiction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serpentaddiction.blogspot.com/feeds/113778713739541160/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18720575&amp;postID=113778713739541160' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113778713739541160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113778713739541160'/><link rel='alternate' type='text/html' href='http://serpentaddiction.blogspot.com/2006/01/its-not-all-fun-and-games.html' title='It&apos;s not all fun and games'/><author><name>Jeff Bauer</name><uri>http://www.blogger.com/profile/17023308739087864427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='27' src='http://3.bp.blogspot.com/_Kk8bilu8bj0/S9ZK76GzerI/AAAAAAAAAF4/oI9gZSYn4as/S220/jeff_head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18720575.post-113424061047061503</id><published>2005-12-10T10:39:00.000-08:00</published><updated>2005-12-12T08:22:16.400-08:00</updated><title type='text'>Twisted online API documentation is hopeless</title><content type='html'>There's an &lt;a href="http://www.amazon.com/exec/obidos/redirect?path=ASIN/0596100329&amp;link_code=as2&amp;camp=1789&amp;tag=fettignet-20&amp;creative=9325"&gt;outstanding book&lt;/a&gt; on &lt;a href="http://www.twistedmatrix.com"&gt;Twisted&lt;/a&gt; by &lt;a href="http:///www.fettig.net/weblog/"&gt;Abe Fettig&lt;/a&gt;.  I've been meaning to get down into the details of Twisted rather than devote all my time with Nevow.  The examples are clear and well-written, e.g.:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;from twisted.internet import reactor&lt;br /&gt;import time&lt;br /&gt;&lt;br /&gt;def printTime():&lt;br /&gt;    print "current time is", time.strftime("%H:%M:%S")&lt;br /&gt;&lt;br /&gt;def stopReactor():&lt;br /&gt;    print "stopping reactor"&lt;br /&gt;    reactor.stop()&lt;br /&gt;&lt;br /&gt;if __name__ == '__main__':&lt;br /&gt;    reactor.callLater(1, printTime)&lt;br /&gt;    reactor.callLater(2, printTime)&lt;br /&gt;    reactor.callLater(3, printTime)&lt;br /&gt;    reactor.callLater(4, printTime)&lt;br /&gt;    reactor.callLater(5, stopReactor)&lt;br /&gt;    print "running the reactor ..."&lt;br /&gt;    reactor.run()&lt;br /&gt;    print "reactor stopped"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;However, I next go to the twisted website to review the &lt;a href="http://twistedmatrix.com/documents/current/api/"&gt;reference API&lt;/a&gt;. Guess what?  There's &lt;b&gt;no entry&lt;/b&gt; tor &lt;i&gt;twisted.internet.reactor&lt;/i&gt;.  Reading the source reveals that &lt;i&gt;selectreactor&lt;/i&gt; is the default implementation of reactor.  It's pretty obvious that the parameter to the &lt;i&gt;callLater&lt;/i&gt; method are time (in seconds) and and argument-less function, but I'd like to review that in the API documentation.  &lt;br /&gt;&lt;br /&gt;The twisted.internet.selectreactor section lists no &lt;i&gt;callLater&lt;/i&gt; method. Grepping through the source reveals that it's implemented in four places, but the one I'm probably using is twisted.internet.base.  There's a reference in the docstring:  &lt;i&gt;"See twisted.internet.interfaces.IReactorTime.callLater."&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Okay, I can live with this, but it means the online API is a waste of time.  I'll simply have to read through the source code to learn anything useful about twisted.  The online API actually &lt;u&gt;slows down&lt;/u&gt; the discovery process.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Update:&lt;/i&gt;  Here's a line of Nevow code:&lt;br /&gt;&lt;pre&gt;request = inevow.IRequest(ctx)&lt;/pre&gt;&lt;br /&gt;Want know to what IRequest returns?  Check out the &lt;a href="http://divmod.org/users/exarkun/nevow-api/public/nevow.inevow-module.html"&gt;API docs&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18720575-113424061047061503?l=serpentaddiction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serpentaddiction.blogspot.com/feeds/113424061047061503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18720575&amp;postID=113424061047061503' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113424061047061503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113424061047061503'/><link rel='alternate' type='text/html' href='http://serpentaddiction.blogspot.com/2005/12/twisted-online-api-documentation-is.html' title='Twisted online API documentation is hopeless'/><author><name>Jeff Bauer</name><uri>http://www.blogger.com/profile/17023308739087864427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='27' src='http://3.bp.blogspot.com/_Kk8bilu8bj0/S9ZK76GzerI/AAAAAAAAAF4/oI9gZSYn4as/S220/jeff_head.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18720575.post-113399566631549669</id><published>2005-12-07T14:37:00.000-08:00</published><updated>2005-12-07T14:47:46.610-08:00</updated><title type='text'>Acroread on Unix</title><content type='html'>Adobe's &lt;a href="http://www.adobe.com/products/acrobat/readstep2.html"&gt;acroread&lt;/a&gt; is another non-GPL piece of software that I find useful for software development, since many specifications are now distributed in pdf format.  Unfortunately, too many spec sheets are still tied to the proprietary Microsoft Word format, for which the only remedy is &lt;a href="http://www.openoffice.org"&gt;OpenOffice.org&lt;/a&gt; or some of the various lightweight MS-Word readers.&lt;br /&gt;&lt;br /&gt;Acroread is a bit heavyweight for most viewing tasks, which is why &lt;a href="http://www.foolabs.com/xpdf/"&gt;xpdf&lt;/a&gt; is still my default pdf viewer.  But for certain kinds of documentation, such as 700+ page &lt;a href="http://www.cms.hhs.gov/hipaa/"&gt;HIPAA&lt;/a&gt; implementation guides, having acroread is indispensible with it's window tiles to aid navigation.&lt;br /&gt;&lt;br /&gt;Having acroread installed is useful for software development with *&lt;br /&gt;&lt;a href="http://www.reportlab.org"&gt;ReportLab&lt;/a&gt;.  It's handy to view the output of generated pdf files with two different renderers, though I also check the results on Windows as well.&lt;br /&gt;&lt;br /&gt;Acroread on Unix is much improved.  For a while it appeared that the Linux/Solaris versions were languishing behind the Windows versions.  Unix acroread has one feature not available on the Windows version. It can emit the Postscript to a file or stdout - useful for batch print jobs.&lt;br /&gt;&lt;br /&gt;Something new I just learned:  Compressed pdf files can be viewed with the &lt;b&gt;zxpdf&lt;/b&gt; command.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18720575-113399566631549669?l=serpentaddiction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serpentaddiction.blogspot.com/feeds/113399566631549669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18720575&amp;postID=113399566631549669' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113399566631549669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113399566631549669'/><link rel='alternate' type='text/html' href='http://serpentaddiction.blogspot.com/2005/12/acroread-on-unix.html' title='Acroread on Unix'/><author><name>Jeff Bauer</name><uri>http://www.blogger.com/profile/17023308739087864427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='27' src='http://3.bp.blogspot.com/_Kk8bilu8bj0/S9ZK76GzerI/AAAAAAAAAF4/oI9gZSYn4as/S220/jeff_head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18720575.post-113363402914179431</id><published>2005-12-03T10:03:00.000-08:00</published><updated>2005-12-03T10:20:29.280-08:00</updated><title type='text'>remote backups with Strongspace.com</title><content type='html'>I've been wanting to use an off-site backup process that was simple to administer, yet easy for non-techies to use.  &lt;a href="http://www.strongspace.com"&gt;Strongspace.com&lt;/a&gt; appears to fit the bill.  You basically sign up for a particular plan that gives you a specific amount of disk space and a number of users.  There's no signup fee and you can discontinue the service at any time.&lt;br /&gt;&lt;br /&gt;Strongspace works with &lt;b&gt;sftp/scp&lt;/b&gt; and &lt;b&gt;rsync+ssh&lt;/b&gt;.  For windows users, it can be accessed via &lt;a href="http://winscp.net/eng/index.php"&gt;WinScp&lt;/a&gt; or &lt;a href="http://filezilla.sourceforge.net/"&gt;Filezilla&lt;/a&gt;.  But for making convenient backups from Windows machines nothing beats an &lt;a href="http://samba.anu.edu.au/rsync/"&gt;rsync&lt;/a&gt; batch file linked to a desktop icon.  Even better, would be to schedule automatic backups.  The advantage with rsync is that after the initial backup, updates are generally very quick.&lt;br /&gt;&lt;br /&gt;The disadvantage with &lt;b&gt;rsync&lt;/b&gt; is that it's not an easy program for Windows users to install.  Fortunately, David Barrett has written an excellent &lt;a href="http://www.antidis.com/articles/2005/08/windows-rsync/"&gt;How-To&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;A typical rsync batch file entry will look like this:&lt;br /&gt;&lt;pre&gt;rsync -avz "/Documents and Settings/user/My Documents" myaccount@mydomain.strongspace.com:Documents&lt;/pre&gt;&lt;br /&gt;Backups are only half the story, however.  Eventually, there will come a day when the user needs to retrieve lost data.  This is where having a browseable backup site is handy.  For the user, retrieving a lost document is as simple as accessing her account on Strongspace.com.  No intervention from me is necessary.  Furthermore, the data can be retrieved from any other location, e.g. modifying a contract or spreadsheet while off-site.  It would certainly be possible to configure something like this internally, but it would be a hassle to maintain with limited advantages.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18720575-113363402914179431?l=serpentaddiction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serpentaddiction.blogspot.com/feeds/113363402914179431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18720575&amp;postID=113363402914179431' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113363402914179431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113363402914179431'/><link rel='alternate' type='text/html' href='http://serpentaddiction.blogspot.com/2005/12/remote-backups-with-strongspacecom.html' title='remote backups with Strongspace.com'/><author><name>Jeff Bauer</name><uri>http://www.blogger.com/profile/17023308739087864427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='27' src='http://3.bp.blogspot.com/_Kk8bilu8bj0/S9ZK76GzerI/AAAAAAAAAF4/oI9gZSYn4as/S220/jeff_head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18720575.post-113292488721809823</id><published>2005-11-25T05:10:00.000-08:00</published><updated>2005-11-25T17:35:11.293-08:00</updated><title type='text'>Thanksgiving</title><content type='html'>&lt;i&gt;"The miraculous thing about this country is that almost everybody has food, clothing, shelter, and extraordinary devices undreamed of until a moment ago in human history: radios, telephones, color televisions, cars, radios in their cars even enough dough to fly across the country once a year, if they plan ahead and stay over a Saturday.  I speak here not just of the great middle class."&lt;/i&gt;  &lt;a href="http://www.andrewtobias.com"&gt;Andrew Tobias&lt;/a&gt;, 1996&lt;br /&gt;&lt;br /&gt;Andrew talks about the material possessions, of which food, clothing, and shelter can only be taken for granted by most people in this country, but I'm certainly grateful for them.  Working in the healthcare field, I'm thankful for my health.  Also, my family and friends.&lt;br /&gt;&lt;br /&gt;But what I'm mostly thankful for today is free software.  Not just because it costs less, but the breadth and quality of open source software makes it a joy to work with computers.  So thanks to &lt;a href="http://www.python.org/~guido/"&gt;Guido van Rossum&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Linus_Torvalds"&gt;Linus Torvalds&lt;/a&gt;, and all the others who have dedicated contributed to free, high-quality software.&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org"&gt;PostgreSQL&lt;/a&gt; is pretty cool.  I'm now starting to use it in favor of &lt;a href="http://www.mysql.com"&gt;MySQL&lt;/a&gt;.  But I spent almost an hour today figuring out how to retrieve column names from a table.  Resulting SQL:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  SELECT attname FROM pg_class, pg_attribute WHERE relname='billcode' and &lt;br /&gt;    pg_class.oid=attrelid and attnum &gt; 0 ORDER BY attnum;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Anyone know of a better way?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18720575-113292488721809823?l=serpentaddiction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serpentaddiction.blogspot.com/feeds/113292488721809823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18720575&amp;postID=113292488721809823' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113292488721809823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113292488721809823'/><link rel='alternate' type='text/html' href='http://serpentaddiction.blogspot.com/2005/11/thanksgiving.html' title='Thanksgiving'/><author><name>Jeff Bauer</name><uri>http://www.blogger.com/profile/17023308739087864427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='27' src='http://3.bp.blogspot.com/_Kk8bilu8bj0/S9ZK76GzerI/AAAAAAAAAF4/oI9gZSYn4as/S220/jeff_head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18720575.post-113275644371937393</id><published>2005-11-23T06:12:00.000-08:00</published><updated>2005-11-23T06:34:03.730-08:00</updated><title type='text'>jEdit</title><content type='html'>A couple people whose opinions I respect have expressed admiration for &lt;a href="http://www.jedit.org"&gt;jEdit&lt;/a&gt;, a programmer's editor written in Java.&lt;br /&gt;&lt;br /&gt;Since Java is non-free software, it requires more than a simple apt-get command to install jEdit on my machine.  Fortunately, the Ubuntu &lt;a href="http://www.cs.cornell.edu/~djm/ubuntu/"&gt;How-To&lt;/a&gt; lists a fairly straightforward procedure to install the Java runtime.  I used to write quite a bit of code in Java.  It's interesting that I haven't had Java installed on my development machine in some time.&lt;br /&gt;&lt;br /&gt;A few minor tweaks later and jEdit is running.  It supports an large number of features, plug-ins, language support, etc.  You move the cursor around with the standard arrows, Home/End, PgUp/PgDn keys, which will make it easy for most Windows users.  As a touch typist, however, I prefer to keep my fingers on the keyboard - even moving my right hand to the arrow keys disrupts my speed and concentration.  It's certainly possible to remap keys to control-key combinations, but I dislike building special-purpose key configurations.  It's always a problem, when you move to another machine, even temporarily. The final negative is the memory required for jEdit.  For comparison:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;vi, Vim: 4.7MB&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;xemacs: 19.4MB&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;jEdit: &lt;b&gt;258MB&lt;/b&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Memory is getting cheaper, but I can run a dozen emacs sessions (or 50 vi sessions) for the cost of one running jEdit process.  I think this is the showstopper for me, though I'll continue to play with jEdit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18720575-113275644371937393?l=serpentaddiction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serpentaddiction.blogspot.com/feeds/113275644371937393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18720575&amp;postID=113275644371937393' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113275644371937393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113275644371937393'/><link rel='alternate' type='text/html' href='http://serpentaddiction.blogspot.com/2005/11/jedit.html' title='jEdit'/><author><name>Jeff Bauer</name><uri>http://www.blogger.com/profile/17023308739087864427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='27' src='http://3.bp.blogspot.com/_Kk8bilu8bj0/S9ZK76GzerI/AAAAAAAAAF4/oI9gZSYn4as/S220/jeff_head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18720575.post-113210550317297083</id><published>2005-11-15T17:32:00.000-08:00</published><updated>2005-11-15T17:53:06.210-08:00</updated><title type='text'>The high price of low-bandwidth data</title><content type='html'>The current situation with mobile phone communications is crazy.  In the U.S., it's relatively easy to send a short text message (&lt;a href="http://en.wikipedia.org/wiki/Short_message_service"&gt;SMS&lt;/a&gt;) to someone's cell phone via email, e.g.:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;T-Mobile: &lt;i&gt;phonenumber@&lt;/i&gt;tmomail.net&lt;br /&gt;&lt;li&gt;Cingular: &lt;i&gt;phonenumber@&lt;/i&gt;cingularme.com&lt;br /&gt;&lt;li&gt;Sprint: &lt;i&gt;phonenumber@&lt;/i&gt;messaging.sprintpcs.com&lt;br /&gt;&lt;li&gt;Verizon: &lt;i&gt;phonenumber@&lt;/i&gt;vtext.com&lt;br /&gt;&lt;li&gt;Nextel: &lt;i&gt;phonenumber@&lt;/i&gt;messaging.nextel.com &lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Apparently in Europe the carriers make sms-to-email more difficult.&lt;br /&gt;&lt;br /&gt;However in Euroland, they make it relatively easy to send outbound SMS messages from your cell phone to internet email accounts.  In the U.S., I couldn't find a single provider for sms-to-email delivery.  &lt;a href="http://www.t-mobile.com/"&gt;T-Mobile&lt;/a&gt; will allow me to send email (not SMS) to the internet, but I must first setup a POP server.  Since all I want is to send simple outbound messages via Python code, this seems like overkill.  I don't want or need inbound email.&lt;br /&gt;&lt;br /&gt;So my current round-trip scenario:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;server-to-phone:  send automated email to &lt;i&gt;phonenumber@&lt;/i&gt;tmomail.net&lt;br /&gt;  &lt;li&gt;phone-to-server:  send sms via &lt;a href="http://www.connectotel.com/sms"&gt;connectotel&lt;/a&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;a href="http://www.conectotel.com/sms"&gt;Connectotel&lt;/a&gt; is an free offshore sms-to-email gateway service.  Free is a bit of a misnomer, however, as each overseas message costs me $0.15.  Even domestic messages cost $0.05 each.&lt;br /&gt;&lt;br /&gt;There's something quite screwy in that my voicemail, which consumes orders of magnitude more transmission and storage, is free. I could easily spend over $50/month in SMS fees for less than 12K of data.&lt;br /&gt;&lt;br /&gt;Most of the time this is a non-issue since I'll be using my &lt;a href="http://serpentaddiction.blogspot.com/2005/11/success-with-swig.html"&gt;hacked bluetooth server&lt;/a&gt; for local data communications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18720575-113210550317297083?l=serpentaddiction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serpentaddiction.blogspot.com/feeds/113210550317297083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18720575&amp;postID=113210550317297083' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113210550317297083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113210550317297083'/><link rel='alternate' type='text/html' href='http://serpentaddiction.blogspot.com/2005/11/high-price-of-low-bandwidth-data.html' title='The high price of low-bandwidth data'/><author><name>Jeff Bauer</name><uri>http://www.blogger.com/profile/17023308739087864427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='27' src='http://3.bp.blogspot.com/_Kk8bilu8bj0/S9ZK76GzerI/AAAAAAAAAF4/oI9gZSYn4as/S220/jeff_head.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18720575.post-113191247309903552</id><published>2005-11-13T11:58:00.000-08:00</published><updated>2005-11-13T12:07:53.110-08:00</updated><title type='text'>svk vs. svn</title><content type='html'>&lt;a href="http://effbot.org"&gt;Fredik Lundh&lt;/a&gt; says "If you're using &lt;a href="http://subversion.tigris.org/"&gt;subversion&lt;/a&gt; for anything, you really want to use &lt;a href="http://svk.elixus.org"&gt;svk&lt;/a&gt; as a front-end, instead of svn."  I installed version 1.00 of svk via apt-get.  &lt;br /&gt;&lt;br /&gt;svk is written in &lt;a href="http://www.perl.com"&gt;Perl&lt;/a&gt; and I notice the command line response seems very sluggish.&lt;br /&gt;&lt;br /&gt;After creating a respository, I attempted to import a project.  No response.  A query to #svk chat confirms that it's failing silently.  The recommendation is that I upgrade to version 1.05, but I think I'll just pass for now.  Or maybe just just svk as a client for Subversion.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18720575-113191247309903552?l=serpentaddiction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serpentaddiction.blogspot.com/feeds/113191247309903552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18720575&amp;postID=113191247309903552' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113191247309903552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113191247309903552'/><link rel='alternate' type='text/html' href='http://serpentaddiction.blogspot.com/2005/11/svk-vs-svn.html' title='svk vs. svn'/><author><name>Jeff Bauer</name><uri>http://www.blogger.com/profile/17023308739087864427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='27' src='http://3.bp.blogspot.com/_Kk8bilu8bj0/S9ZK76GzerI/AAAAAAAAAF4/oI9gZSYn4as/S220/jeff_head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18720575.post-113189688164775127</id><published>2005-11-13T07:44:00.000-08:00</published><updated>2005-11-13T08:26:29.096-08:00</updated><title type='text'>Upgrading to Ubuntu Breezy / XEmacs</title><content type='html'>It's a rainy Sunday, a good time to upgrade my &lt;a href="http://www.ubuntulinux.org"&gt;Ubuntu&lt;/a&gt; desktop from Hoary 5.04 to Breezy 5.10.  A few hours later I'm frustrated.  The upgrade process gives me errors which I spend too much time resolving.  I have backups of /etc and /home/jbauer, but a system restore would not have been pleasant. I won't go into the details, but enough time spent on Ubuntu forums found the answers to most of my questions.  Upgrading is a task for the steel-willed, not nervous nellies such as myself.&lt;br /&gt;&lt;br /&gt;I prefer &lt;a href="http://www.xemacs.org"&gt;XEmacs&lt;/a&gt; to GNU/Emacs, though I could live with either.  One problem with running XEmacs from the command line is the annoying messages:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Warning: Missing charsets in String to FontSet conversion&lt;br /&gt;Warning: Missing charsets in String to FontSet conversion&lt;br /&gt;Warning: Unable to load any usable fontset&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;My LANG environment is en_US.UTF-8, so my short-term fix is to create a command line script, ~/bin/xe:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;LANG=C xemacs $* &amp;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18720575-113189688164775127?l=serpentaddiction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serpentaddiction.blogspot.com/feeds/113189688164775127/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18720575&amp;postID=113189688164775127' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113189688164775127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113189688164775127'/><link rel='alternate' type='text/html' href='http://serpentaddiction.blogspot.com/2005/11/upgrading-to-ubuntu-breezy-xemacs.html' title='Upgrading to Ubuntu Breezy / XEmacs'/><author><name>Jeff Bauer</name><uri>http://www.blogger.com/profile/17023308739087864427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='27' src='http://3.bp.blogspot.com/_Kk8bilu8bj0/S9ZK76GzerI/AAAAAAAAAF4/oI9gZSYn4as/S220/jeff_head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18720575.post-113173582471470272</id><published>2005-11-11T10:56:00.000-08:00</published><updated>2005-11-11T11:06:09.286-08:00</updated><title type='text'>Success with SWIG</title><content type='html'>It bothered me yesterday that I didn't get a Bluetooth server running with Python, so I had to go back to &lt;a href="http://www.swig.org"&gt;SWIG&lt;/a&gt;.  The &lt;a href="http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/"&gt;Pyrex&lt;/a&gt; framework is probably better for major projects, but SWIG wins out for write-once applications that won't require a lot of maintenance.&lt;br /&gt;&lt;br /&gt;My swig file, &lt;i&gt;pyobexserver.i&lt;/i&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    %module pyobexserver&lt;br /&gt;    %{&lt;br /&gt;    #include "openobex/obex.h"&lt;br /&gt;    %}&lt;br /&gt;    int get_my_file(char *outfile);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;From the Python interpreter:&lt;pre&gt;&lt;br /&gt;    &gt;&gt;&gt; from pyobexserver import get_my_file&lt;br /&gt;    &gt;&gt;&gt; get_my_file('/home/jbauer/nokia/files')&lt;br /&gt;    Waiting for connection...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What could be easier?  From downloading SWIG to running a functional program: 30 minutes.  I love &lt;a href="http://www.python.org"&gt;Python&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18720575-113173582471470272?l=serpentaddiction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serpentaddiction.blogspot.com/feeds/113173582471470272/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18720575&amp;postID=113173582471470272' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113173582471470272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113173582471470272'/><link rel='alternate' type='text/html' href='http://serpentaddiction.blogspot.com/2005/11/success-with-swig.html' title='Success with SWIG'/><author><name>Jeff Bauer</name><uri>http://www.blogger.com/profile/17023308739087864427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='27' src='http://3.bp.blogspot.com/_Kk8bilu8bj0/S9ZK76GzerI/AAAAAAAAAF4/oI9gZSYn4as/S220/jeff_head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18720575.post-113167090726526617</id><published>2005-11-10T16:43:00.000-08:00</published><updated>2005-11-10T17:13:36.673-08:00</updated><title type='text'>Subversion: status vs. update</title><content type='html'>Today I learned something important about svn status the hard way.  Prior to this project, I've only used the rudiments of &lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt;.  For most SourceForge projects, I would run &lt;i&gt;svn update&lt;/i&gt;.  The &lt;i&gt;svn status&lt;/i&gt; command displays all files that have been modified locally.  I assumed it compared changes against the repository.  So yesterday when I tried to commit some changes, I got an "Out of date" error message.  I had to copy my mods elsewhere, update, manually diff the files, then commit.  No big deal. I just didn't read the documentation closely enough.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.gnome.org/"&gt;Gnome&lt;/a&gt;: How do I get the properties of a program listed in my applications menu?  Most windowing systems do this with a right mouse click.  It's not obvious with gnome, so my workaround is to install the application on my panel, right-click, then remove it from the panel.  This is how I discovered the "Bluetooth File Sharing" application is actually &lt;a href="http://usefulinc.com/software/gnome-bluetooth"&gt;gnome-obex-server&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Speaking of gnome-obex-server (written in Python) and obexserver (written in C) -- they are incredibly limited pieces of software.  They both accept incoming files from &lt;a href="http://www.bluetooth.com/"&gt;bluetooth&lt;/a&gt; devices -- in my case pictures from my Nokia 6600 -- but give no option to choose where you want them saved.  The gnome-obex-server drops the files in your home directory, and obexserver puts everything in /tmp.  Another issue with obexserver -- it shuts down after it has received the first incoming file.  It's a simple matter to modify the code in obexserver, but both of these are &lt;a href="http://www.debian.org/"&gt;Debian&lt;/a&gt; distribution apps -- obexserver even has a man page.&lt;br /&gt;&lt;br /&gt;I looked into using &lt;a href="http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/"&gt;Pyrex&lt;/a&gt; to build a Python interface to the &lt;a href="http://triq.net/obex/"&gt;OBEX&lt;/a&gt; stuff.  Pyrex is an awesome piece of work, but I don't have time to wrap up all the OBEX C structures in a .pyx file.  There's a bit of a learning curve to get it right. Since the interface is so simple, I might SWIG it instead.  I shouldn't be wasting time on this anyway.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18720575-113167090726526617?l=serpentaddiction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serpentaddiction.blogspot.com/feeds/113167090726526617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18720575&amp;postID=113167090726526617' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113167090726526617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113167090726526617'/><link rel='alternate' type='text/html' href='http://serpentaddiction.blogspot.com/2005/11/subversion-status-vs-update.html' title='Subversion: status vs. update'/><author><name>Jeff Bauer</name><uri>http://www.blogger.com/profile/17023308739087864427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='27' src='http://3.bp.blogspot.com/_Kk8bilu8bj0/S9ZK76GzerI/AAAAAAAAAF4/oI9gZSYn4as/S220/jeff_head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18720575.post-113157721565357191</id><published>2005-11-09T14:38:00.000-08:00</published><updated>2005-11-09T15:05:00.566-08:00</updated><title type='text'>YAML vs. JSON</title><content type='html'>I have some information that doesn't quite fit into a relational database model, though it would be convenient to store it as such. Here's an example:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&gt;&gt;&gt; data = {'therapies': ['4'], 'inpatient_diagnoses': [('751.1', 'ATRESIA SMALL INTESTINE')], 'prior_conditions': ['3'], 'diagnoses_and_severity': [('879.2', 'OPN WND ANTERIOR ABDOMEN', '2'), ('751.1', 'ATRESIA SMALL INTESTINE', '4'), ('751.2', 'ATRESIA LARGE INTESTINE', '2')], 'race': ['6'], 'regimen_changed': '1', 'current_payment_sources': ['1'], 'overall_prognosis': '1', 'high_risk_factors': ['2','5'], 'inpatient_discharge_date': 2005-02-19, 'financial_factors': ['0'], 'rehab_prognosis': '1', 'inpatient_facilities': ['1'], 'changed_diagnoses': [('751.1', 'ATRESIA SMALL INTESTINE')], 'life_expectancy': '0'}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It's a combination of lists, strings, and associative arrays, supported by most modern languages. One goal is to keep the data human-readable, which precludes some kinds of binary serialization. The data could be represented as XML, but XML's just barely readable.&lt;br /&gt;&lt;br /&gt;Matt Goodall offered the following suggestions:&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.yaml.org/"&gt;YAML Ain't Markup Language (tm)&lt;br /&gt;  &lt;/a&gt;&lt;/li&gt;   &lt;li&gt;&lt;a href="http://www.crockford.com/JSON/index.html"&gt;JSON - &lt;b&gt;J&lt;/b&gt;ava&lt;b&gt;S&lt;/b&gt;cript &lt;b&gt;O&lt;/b&gt;bject &lt;b&gt;N&lt;/b&gt;otation&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; I recall playing with the Python version of YAML over a year ago. It was pretty cool, though slow, and not a complete implementation. There's a certain appeal to a Python programmer in representing data with whitespace. For example, an invoice:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;invoice: 34843&lt;br /&gt;date   : 2001-01-23&lt;br /&gt;bill-to: &amp;amp;id001&lt;br /&gt;    given  : Chris&lt;br /&gt;    family : Dumars&lt;br /&gt;    address:&lt;br /&gt;        lines: |&lt;br /&gt;            458 Walkman Dr.&lt;br /&gt;            Suite #292&lt;br /&gt;        city    : Royal Oak&lt;br /&gt;        state   : MI&lt;br /&gt;        postal  : 48046&lt;br /&gt;ship-to: *id001&lt;br /&gt;product:&lt;br /&gt;    - sku         : BL394D&lt;br /&gt;      quantity    : 4&lt;br /&gt;      description : Basketball&lt;br /&gt;      price       : 450.00&lt;br /&gt;    - sku         : BL4438H&lt;br /&gt;      quantity    : 1&lt;br /&gt;      description : Super Hoop&lt;br /&gt;      price       : 2392.00&lt;br /&gt;tax  : 251.42&lt;br /&gt;total: 4443.52&lt;br /&gt;comments:&lt;br /&gt;    Late afternoon is best.&lt;br /&gt;    Backup contact is Nancy&lt;br /&gt;    Billsmer @ 338-4338.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I couldn't google up an emacs mode for .yml files, but I'm sure someone must have written one by now. Ultimately though, I'd prefer to keep embedded newlines out of the field data, so I next looked at JSON.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&gt;&gt;&gt; import json&lt;br /&gt;&gt;&gt;&gt; s = json.write(data)  # data is returned as a string.&lt;br /&gt;&gt;&gt;&gt; d = json.read(s)      # converted back into a dictionary.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Pretty simple.&lt;br /&gt;&lt;br /&gt;JSON wins out over YAML for this project. It was dirt simple to round-trip the example data. Speed isn't much of an issue for this particular use of JSON and I like storing the data as TEXT rather than BLOB.&lt;br /&gt;&lt;br /&gt;There is also &lt;a href="http://json-rpc.org/"&gt;JSON-RPC&lt;/a&gt;, a remote procedure call protocol similar to &lt;a href="http://xmlrpc.com/" target="_blank"&gt;XML-RPC&lt;/a&gt;.  Interesting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18720575-113157721565357191?l=serpentaddiction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serpentaddiction.blogspot.com/feeds/113157721565357191/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18720575&amp;postID=113157721565357191' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113157721565357191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113157721565357191'/><link rel='alternate' type='text/html' href='http://serpentaddiction.blogspot.com/2005/11/yaml-vs-json.html' title='YAML vs. JSON'/><author><name>Jeff Bauer</name><uri>http://www.blogger.com/profile/17023308739087864427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='27' src='http://3.bp.blogspot.com/_Kk8bilu8bj0/S9ZK76GzerI/AAAAAAAAAF4/oI9gZSYn4as/S220/jeff_head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18720575.post-113140584147156297</id><published>2005-11-08T15:15:00.000-08:00</published><updated>2005-11-08T07:17:30.050-08:00</updated><title type='text'>Trac: Integrated SCM &amp; Project Management</title><content type='html'>After working on my current project I have a better&lt;br /&gt;appreciation for having issue tracking, a &lt;a href="http://wiki.org/wiki.cgi?WhatIsWiki"&gt;wiki&lt;/a&gt;, and the&lt;br /&gt;&lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt; revision control  system integrated into&lt;br /&gt;a complete package.&lt;br /&gt;&lt;br /&gt;If you're already familiar with cvs or Subversion, &lt;a href="http://www.edgewall.com/trac/"&gt;Trac&lt;/a&gt;&lt;br /&gt;is useful without having to learn a bunch of arcane&lt;br /&gt;commands.  It would be fairly easy for even a non-programmer&lt;br /&gt;to participating in a project managed with Trac.&lt;br /&gt;&lt;br /&gt;The Trac wiki isn't as robust as &lt;a href="http://moinmoin.wikiwikiweb.de/"&gt;MoinMoin&lt;/a&gt;, but the&lt;br /&gt;effortless integration with the ticket tracker&lt;br /&gt;is a pleasure to use.  Project members can&lt;br /&gt;be issued notifications via email or RSS for tickets&lt;br /&gt;that have issued, modified, or resolved.&lt;br /&gt;&lt;br /&gt;The source browser is also well integerated.  The&lt;br /&gt;current version of each code module has a link to&lt;br /&gt;the revision, which in turn displays all the other&lt;br /&gt;files that were committed as part of the revision.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18720575-113140584147156297?l=serpentaddiction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serpentaddiction.blogspot.com/feeds/113140584147156297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18720575&amp;postID=113140584147156297' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113140584147156297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113140584147156297'/><link rel='alternate' type='text/html' href='http://serpentaddiction.blogspot.com/2005/11/trac-integrated-scm-project-management.html' title='Trac: Integrated SCM &amp; Project Management'/><author><name>Jeff Bauer</name><uri>http://www.blogger.com/profile/17023308739087864427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='27' src='http://3.bp.blogspot.com/_Kk8bilu8bj0/S9ZK76GzerI/AAAAAAAAAF4/oI9gZSYn4as/S220/jeff_head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18720575.post-113135410207210395</id><published>2005-11-07T00:40:00.000-08:00</published><updated>2005-11-07T01:01:42.080-08:00</updated><title type='text'>Python for Series 60</title><content type='html'>Yesterday my Dad loaned me his USB bluetooth dongle. I put it on sulla, a linux box running Ubuntu 5.04. After the usual frustrations, I got my Nokia 6600 to communicate, sending files in each direction.&lt;br /&gt;&lt;br /&gt;At last year's &lt;a href="http://www.python.org/pycon/2005/"&gt;PyCon&lt;/a&gt; I met Jukka Laurila and Erik Smartt from Nokia who were demonstrating &lt;a href="http://www.postneo.com/postwiki/moin.cgi/PythonForSeries60"&gt;Python for the series 60 phones&lt;/a&gt;.Ever since then, I've been wanting to get Python running on my nokia 6600. With some help from the #pys60 channel, I was able to run the interpreter on the phone via bluetooth. Pretty cool.&lt;br /&gt;&lt;br /&gt;I spent too much time with bluetooth and not enough on learning &lt;a href="http://www.nevow.com"&gt;Nevow&lt;/a&gt;.  Today was unseasonably warm, so I got out on the bike for a couple hours despite wanting to spend more time on development projects.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18720575-113135410207210395?l=serpentaddiction.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://serpentaddiction.blogspot.com/feeds/113135410207210395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18720575&amp;postID=113135410207210395' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113135410207210395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18720575/posts/default/113135410207210395'/><link rel='alternate' type='text/html' href='http://serpentaddiction.blogspot.com/2005/11/python-for-series-60.html' title='Python for Series 60'/><author><name>Jeff Bauer</name><uri>http://www.blogger.com/profile/17023308739087864427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='27' src='http://3.bp.blogspot.com/_Kk8bilu8bj0/S9ZK76GzerI/AAAAAAAAAF4/oI9gZSYn4as/S220/jeff_head.jpg'/></author><thr:total>0</thr:total></entry></feed>
