<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>Let's discuss the matter further</title>
	
	<link>http://rhodesmill.org/brandon</link>
	<description>Thoughts of Brandon Craig Rhodes</description>
	<lastBuildDate>Tue, 15 Jun 2010 16:56:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/LetsDiscussTheMatterFurther" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="letsdiscussthematterfurther" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Changed rules for Picasa tag searches</title>
		<link>http://rhodesmill.org/brandon/2010/picasa-tag-searches/</link>
		<comments>http://rhodesmill.org/brandon/2010/picasa-tag-searches/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 16:56:09 +0000</pubDate>
		<dc:creator>Brandon Craig Rhodes</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Web Notes]]></category>

		<guid isPermaLink="false">http://rhodesmill.org/brandon/?p=360</guid>
		<description><![CDATA[Well, drat. Several images disappeared from the Our Fresh World green-building web site because Google changed their Picasa API recently — and I must not be subscribed to the proper mailing list or blog to have been warned ahead of time. Where are incompatible Google API tweaks announced? The site owner and his photographer use Picasa [...]]]></description>
			<content:encoded><![CDATA[<p>
  Well, drat.
</p>
<p>
  Several images disappeared from the
  <a href="http://www.ourfreshworld.com/">Our Fresh World</a>
  green-building web site
  because Google changed their Picasa API recently —
  and I must not be subscribed to the proper mailing list or blog
  to have been warned ahead of time.
  Where are incompatible Google API tweaks announced?
</p>
<div class="dropshadow alignright"> 
  <a><img border="0" src="http://rhodesmill.org/brandon/static/2010/solar-power.jpg"/></a>
</div> 
<p>
  The site owner and his photographer use
  <a href="http://picasaweb.google.com/">Picasa web albums</a>
  to upload, edit, and maintain their image collection.
  They simply give special tags to their favorite photos,
  and my application code then knows
  that it is supposed to display those photos on the web site.
  I almost used <a href="http://flickr.com/">Flickr</a>
  for this application,
  both because I am an avid Flickr user myself
  and because I consider its web interface more usable.
  But, perhaps predictably, Picasa had the much stronger search API —
  whereas you can either ask Flickr for the photos in a particular set,
  <i>or</i> ask for all of someone's photos that share a particular tag,
  Picasa lets you can combine the two queries
  and ask for only the photos that are in a particular set
  <i>and</i> that also share a specific tag.
  And since search is what attaches pictures to this web site,
  Picasa was my choice.
</p>
<p>
  All was going well,
  with each page getting populated by searches like:
</p>
<pre>

http://picasaweb.google.com/data/feed/api/user/<i>name</i><br/>?kind=photo&#038;tag=solar-power

</pre>
<p>
  Then I received an email from the site owner,
  complaining that many of the photographs had disappeared!
  After seeing some complaints in the Picasa forums
  about recent versions of the user interface
  treating certain “special characters” in tags as spaces instead,
  I suddenly wondered whether the hyphen in several of our tags
  (like the “solar-power” tag in the URL above)
  was the cause of our trouble.
  I adjusted my code so that this search became:
</p>
<pre>

http://picasaweb.google.com/…?kind=photo&#038;tag=solar+power

</pre>
<p>
  And, voilà, the images returned and were again visible!
  Does anyone know what forum or blog I should have been following
  to be informed of this critical change by Google?
  It is dismaying to have a site break in front of a customer
  when the very reason that I chose a Google product
  was because of their powerful API for integrating my application.
</p>]]></content:encoded>
			<wfw:commentRss>http://rhodesmill.org/brandon/2010/picasa-tag-searches/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Grok has book. Book good!</title>
		<link>http://rhodesmill.org/brandon/2010/grok-has-book-book-good/</link>
		<comments>http://rhodesmill.org/brandon/2010/grok-has-book-book-good/#comments</comments>
		<pubDate>Fri, 11 Jun 2010 02:32:52 +0000</pubDate>
		<dc:creator>Brandon Craig Rhodes</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Grok]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Zope]]></category>

		<guid isPermaLink="false">http://rhodesmill.org/brandon/?p=350</guid>
		<description><![CDATA[I little suspected the great chasm that lies between the simple act of agreeing to review a book, and the actual exercise of sitting down later to write the review. It feels quite pleasant, really, to jot off a positive reply to the publisher's polite question. One feels magnanimous for agreeing to help advance our [...]]]></description>
			<content:encoded><![CDATA[<p>
  I little suspected the great chasm that lies
  between the simple act of agreeing to review a book,
  and the actual exercise of sitting down later to write the review.
  It feels quite pleasant, really,
  to jot off a positive reply to the publisher's polite question.
  One feels magnanimous for agreeing to help advance our civilization
  by reviewing a book about Python,
  and for helping out the publisher in what,
  after all, are such hard economic times.
  It is fun when the free copy arrives,
  crisp and smartly bound.
</p>
<p>
  But then, eventually, one has to write the actual review.
</p>
<div class="dropshadow alignright"> 
  <a href="http://www.amazon.com/gp/product/1847197485?ie=UTF8&#038;tag=letsdisthemat-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=1847197485"><img border="0" src="http://rhodesmill.org/brandon/static/2010/grok-book.jpg"></a><img src="http://www.assoc-amazon.com/e/ir?t=letsdisthemat-20&#038;l=as2&#038;o=1&#038;a=1847197485" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
</div>
<p>
  And so,
  a full four months after that friendly email from Packt Publishing,
  it is time that I sit down
  and put together some thoughts
  about Carlos de la Guardia's first book,
  <a href="http://www.amazon.com/gp/product/1847197485?ie=UTF8&#038;tag=letsdisthemat-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=1847197485"
     >Grok 1.0 Web Development</a>.
  Carlos is a long-time veteran of the Zope and Plone communities,
  and <a href="http://grok.zope.org/">Grok</a>,
  of course,
  is the web framework
  that places a simple and agile convention-driven engine
  atop the otherwise notoriously XML-ridden Zope application framework.
  Grok is an important project,
  because it packages the technology of Python's oldest
  and most experienced community of web developers
  in a way that makes it easy to extend and use.
</p>
(...)<br/>Read the rest of <a href="http://rhodesmill.org/brandon/2010/grok-has-book-book-good/">Grok has book. Book good!</a> (814 words)</p>
]]></content:encoded>
			<wfw:commentRss>http://rhodesmill.org/brandon/2010/grok-has-book-book-good/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mounting Windows shares in Linux userspace</title>
		<link>http://rhodesmill.org/brandon/2010/mounting-windows-shares-in-linux-userspace/</link>
		<comments>http://rhodesmill.org/brandon/2010/mounting-windows-shares-in-linux-userspace/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 21:33:30 +0000</pubDate>
		<dc:creator>Brandon Craig Rhodes</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Emacs]]></category>

		<guid isPermaLink="false">http://rhodesmill.org/brandon/?p=341</guid>
		<description><![CDATA[A current project has forced me into the clunky world of Windows, to verify that a Python program compiles and runs there just like it runs under Linux. Instead of trying to port my entire development environment to Windows — which includes two decades of customizations and a small empire of tools like Emacs, pyflakes, and [...]]]></description>
			<content:encoded><![CDATA[<p>
  A current project has forced me into the clunky world of Windows,
  to verify that a Python program compiles and runs there
  just like it runs under Linux.
  Instead of trying to port my entire development environment to Windows —
  which includes two decades of customizations
  and a small empire of tools like
  <a href="http://www.gnu.org/software/emacs/"
     >Emacs</a>,
  <a href="http://divmod.org/trac/wiki/DivmodPyflakes"
     >pyflakes</a>, and
  <a href="http://rope.sourceforge.net/"
     >Rope</a> —
  I want to simply mount my Windows home directory under Linux
  so that I can run my normal editor and version control tools
  in a more familiar environment.
</p>
<p>
  I have worked out an elegant solution
  by combining <i>two</i> of the powerful user-space filesystems
  available through the <a href="http://fuse.sourceforge.net/">FUSE</a>
  mechanism in the Linux kernel.
  Let me take you through the story of how I put them together!
</p>
(...)<br/>Read the rest of <a href="http://rhodesmill.org/brandon/2010/mounting-windows-shares-in-linux-userspace/">Mounting Windows shares in Linux userspace</a> (1,264 words)</p>
]]></content:encoded>
			<wfw:commentRss>http://rhodesmill.org/brandon/2010/mounting-windows-shares-in-linux-userspace/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Python multiprocessing is different under Linux and Windows</title>
		<link>http://rhodesmill.org/brandon/2010/python-multiprocessing-linux-windows/</link>
		<comments>http://rhodesmill.org/brandon/2010/python-multiprocessing-linux-windows/#comments</comments>
		<pubDate>Fri, 14 May 2010 16:27:05 +0000</pubDate>
		<dc:creator>Brandon Craig Rhodes</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://rhodesmill.org/brandon/?p=333</guid>
		<description><![CDATA[One of the great recent advances in the Python Standard Library is the addition of the multiprocessing module, maintained by Jesse Noller who has also blogged and written about several other concurrency approaches for Python — Kamaelia, Circuits, and Stackless Python. I have wanted to try the multiprocessing module out for some time, and now have [...]]]></description>
			<content:encoded><![CDATA[<p>
One of the great recent advances in the Python Standard Library
is the addition of the
<a href="http://docs.python.org/library/multiprocessing.html"
   >multiprocessing</a> module,
maintained by <a href="http://jessenoller.com/">Jesse Noller</a>
who has also blogged and written
about several other concurrency approaches for Python —
<a href="http://jessenoller.com/2009/01/29/a-gentle-overview-of-kamaelia-or-its-axon-stupid/"
   >Kamaelia</a>,
<a href="http://jessenoller.com/2009/01/31/circuits-event-driven-components/"
   >Circuits</a>,
and
<a href="http://jessenoller.com/2009/02/23/stackless-you-got-your-coroutines-in-my-subroutines/"
   >Stackless</a> Python.
</p>
<p>
I have wanted to try the multiprocessing module out for some time,
and now have a consulting project that will really benefit from multiple processes:
they will let our application run third-party plugins
without having to worry that any bugs or indiscretions which they commit
might damage or hang our main server,
which can remain safe in another process.
</p>
<p>
First, one can only stand in awe at the achievement —
and the amount of work —
that the multiprocessing module represents.
I cannot imagine the time that it would have taken our team
to figure out all of the differences between Linux and Windows
when it comes to processes, shared memory, and concurrency mechanisms.
In fact, the approach we are taking might not even have been feasible
under those circumstances.
By figuring out how to get locks, queues, and shared data structures
all working cleanly on such different architectures,
the multiprocessing authors
save Python programmers out on the street like me
from reinventing a dozen wheels
when we need to support multi-platform concurrency.
</p>
<p>
Well, <i>almost.</i>
</p>
<p>
There is one rather startling difference
which the multiprocessing module does <i>not</i> hide:
the fact that while every Windows process must spin up
independently of the parent process that created it,
Linux supports the <i>fork(2)</i> system call
that creates a child processes already in possession
of exactly the same resources as its parent:
every data structure, open file, and database connection
that existed in the parent process
is still sitting there, open and ready to use, in the child.
Consider this small program:
</p>
<pre>
from multiprocessing import Process
f = None

def child():
    print f

if __name__ == '__main__':
    f = open('mp.py', 'r')                                                      
    p = Process(target=child)
    p.start()
    p.join()
</pre>
<p>
On Linux, the open file <tt>f</tt> keeps its value in the child process;
the child has inherited an open connection from its parent:
</p>
<pre>
$ python mp.py
&lt;open file 'mp.py', mode 'r' at 0xb7734ac8&gt;
</pre>
<p>
Under Windows, however, where the multiprocessing module
has to spawn a fresh copy of the Python interpreter
to which it gives special instructions
to just run the function <tt>f()</tt>,
the module is a clean slate without an open file inside:
</p>
<pre>
C:\Users\brandon\dev>python mp.py
None
</pre>
<p>
Now, my complaint is not exactly
that the multiprocessing documentation is misleading on this point;
under its section on
<a href="http://docs.python.org/library/multiprocessing.html#programming-guidelines"
   >Programming guidelines</a>,
it makes it quite clear that:
</p>
<blockquote>
On Unix a child process can make use of a shared resource created in a
parent process using a global resource. However, it is better to pass
the object as an argument to the constructor for the child process.
</blockquote>
<p>
I have no quarrel with this advice;
if I am careful to pass everything the child needs
in its list of arguments,
then I can be sure that my code will work under both Linux and Windows.
</p>
<p>
But I do wish that the multiprocessing module
provided more support for testing this condition
more rigorously under Linux.
In particular, I wish that there were some way of turning
the simple forking logic <i>off</i> —
of saying, “Yes, I know that Linux will let you create a child process
very simply using <i>fork(2)</i>, but for my sanity would you please
create the child process from scratch like you do under Windows so
that I can test whether my code accidentally depends on residual
state from the parent process that I did not see that I was using?”
I looked at the multiprocessing "forking.py" module
to see whether I could turn on the Windows-style process spawning
even from inside of Linux,
but the mechanism is chosen
by a bare module-level check of "sys.platform"
and if I overwrite that variable with 'win32'
the code then dies when it tries to import "msvcrt"
which is available only under Windows.
</p>
<p>
There is, thus, even in principle, no way
that I can test my multiprocessing application under Linux
which will give me any assurance that my child processes
are not accidentally taking advantage of data structures
and open connections left lying around by the parent process;
only by actually moving over to Windows itself
can I see how my child code really behaves on its own.
I have <a href="http://bugs.python.org/issue8713">created a feature request</a>
in the Python bug tracker to see whether this situation can be improved.
</p>
<p>
But even with this one inconvenience —
which is troubling me much less, now that I at least understand
why my application was behaving so differently under Windows —
the multiprocessing module is still a huge leap forwards
for Python programmers who need to run code
in heavyweight processes with all of the isolation and safety
that they provide.
Thanks again to Jesse and the multiprocessing team!
</p>]]></content:encoded>
			<wfw:commentRss>http://rhodesmill.org/brandon/2010/python-multiprocessing-linux-windows/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Sphinx + Mercurial = My favorite CMS</title>
		<link>http://rhodesmill.org/brandon/2010/sphinx-mercurial-cms/</link>
		<comments>http://rhodesmill.org/brandon/2010/sphinx-mercurial-cms/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 02:58:28 +0000</pubDate>
		<dc:creator>Brandon Craig Rhodes</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Document processing]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://rhodesmill.org/brandon/?p=318</guid>
		<description><![CDATA[Though I write and maintain some of the content for our Python Atlanta web site, updates and additional content often come in from other users. For example, our Plone interest group — headed up by Christopher Johnson — has their own page on our web site. And the information about our book club is both written and [...]]]></description>
			<content:encoded><![CDATA[<p>
Though I write and maintain some of the content for our <a href="http://pyatl.org/">Python Atlanta web site</a>, updates and additional content often come in from other users. For example, our Plone interest group — headed up by <a href="http://www.ifpeople.net/about/people/cjj">Christopher Johnson</a> — has their <a href="http://pyatl.org/plone">own page on our web site</a>. And the information about our <a href="http://pyatl.org/bookclub">book club</a> is both written and regularly updated by <a href="http://www.doughellmann.com/">Doug Hellmann</a>.
</p>
<div class="dropshadow alignright">
  <a href="http://pyatl.org/">
    <img src="http://rhodesmill.org/brandon/static/2010/pyatl-thumb.png"
         alt="Python Atlanta web site"
         width="240" height="135" />
  </a>
</div>
<p>
How can a collaborative site like ours best be edited and updated? Well, I would like to report some modest initial success with an experimental approach: I now maintain the site as a <a href="http://sphinx.pocoo.org/">Sphinx-powered</a> documentation system stored in a <a href="http://bitbucket.org/brandon/pyatl.org/">BitBucket repository</a> into which I pull changes made by my collaborators. The advantages are several.
</p>
<ul>
<li>The change management tools supported by traditional CMS systems, even at their best, seem somehow anemic when compared to the toolkit provided by a good DVCS like <a href="http://mercurial.selenic.com/">Mercurial</a>. Where, for example, does even a capable CMS like Plone provide anything like Mercurial's “backout” or “blame” commands?
</li>
<li>Markup as well-designed as <a href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> is not only a lot of fun to use, bit it also very cleanly separates content from design. Authors working in plain text tend to produce clean, readable content without the messy markup often associated with visual HTML editors, or, worse yet, the disaster that is Microsoft Word.
</li>
<li>Staging — a feature I find essential, but which seems missing from many default CMS configurations — occurs automatically! Each author can see locally how the site will look with their changes, and after doing a pull I can review the site's appearance on my laptop before finally deploying the new content to the production site.
</li>
</ul>
<p>
To top it all off, authors get to use their own editor-of-choice when making contributions, and we all get extra practice cloning and merging in my favorite DVCS. I am optimistic about this direction, but I will post again if we wind up hitting snags in the future. Finally, of course, feel free to clone our repository if you want to see how Sphinx looks when running a generic web site.
</p>]]></content:encoded>
			<wfw:commentRss>http://rhodesmill.org/brandon/2010/sphinx-mercurial-cms/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Ubuntu Python: raise an exception, import 190 modules</title>
		<link>http://rhodesmill.org/brandon/2010/ubuntu-exception-190-modules/</link>
		<comments>http://rhodesmill.org/brandon/2010/ubuntu-exception-190-modules/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 04:16:32 +0000</pubDate>
		<dc:creator>Brandon Craig Rhodes</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://rhodesmill.org/brandon/?p=301</guid>
		<description><![CDATA[Imagine my surprise, while writing my first PEP 302 compliant import hook this afternoon, to carefully watch “sys.modules” for the results of my import but see it suddenly grow by nearly two hundred modules! What on earth had I done wrong? Some quick experiments revealed that my only sin was having the temerity to raise an [...]]]></description>
			<content:encoded><![CDATA[<p>
Imagine my surprise, while writing my first
<a href="http://www.python.org/dev/peps/pep-0302/">PEP 302</a>
compliant import hook this afternoon,
to carefully watch “sys.modules” for the results of my import
but see it suddenly grow by nearly two hundred modules!
What on earth had I done wrong?
Some quick experiments revealed that my only sin
was having the temerity to raise an exception.
Let's try raising a simple NameError:
</p>
<pre>
>>> import sys
>>> len(sys.modules)
35
>>> foo
...
NameError: name 'foo' is not defined
>>> len(sys.modules)
225
</pre>
<p>
That's 190 extra modules — merely importing them takes around 60 ms on my laptop!
Where are they all coming from?
And how could an exception cause so many imports,
including such illustrious modules as “email”, “mimetools”, and “xml”?
</p>
<p>
After reading Ubuntu's “sitecustomize.py” file
and all of its consequences, the situation became clear.
Their <a href="https://wiki.ubuntu.com/Apport">apport</a>
crash-reporting subsystem instruments Python
with an exception hook that, when invoked,
discovers that my system says “enabled=0”
in my “/etc/default/apport” file
and so it undertakes no special crash logging.
But, on the way to loading the routine
that performs this simple check,
it performs two quite flagrant and unnecessary imports,
pulling in both “apt”
(that brings with it 83 packages)
and “apport”
(an additional 107 packages).
</p>
<p>
The solution?
I have removed the “python-apport” package,
along with the “ubuntuone-client” suite that depends on it.
After the uninstall, exceptions are — wonderfully enough —
not causing a <i>single</i> import of a new module!
Now, finally, I can continue writing my import hook in peace.
</p>]]></content:encoded>
			<wfw:commentRss>http://rhodesmill.org/brandon/2010/ubuntu-exception-190-modules/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>Opening tabs remotely in Google Chrome</title>
		<link>http://rhodesmill.org/brandon/2010/remote-tabs-google-chrome/</link>
		<comments>http://rhodesmill.org/brandon/2010/remote-tabs-google-chrome/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 04:07:06 +0000</pubDate>
		<dc:creator>Brandon Craig Rhodes</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://rhodesmill.org/brandon/?p=291</guid>
		<description><![CDATA[Now that I use Google Chrome almost exclusively, I miss the fact that a running Firefox instance could be controlled from the command line so that Emacs could call for a new tab when I clicked on a URL. It would run a command something like this: firefox -remote 'openURL(http://example.com/, new-tab)' But after a few [...]]]></description>
			<content:encoded><![CDATA[<p>
Now that I use
<a href="http://www.google.com/chrome">Google Chrome</a>
almost exclusively,
I miss the fact
that a running <a href="http://www.firefox.com">Firefox</a> instance
could be controlled from the command line so that Emacs could call for a new tab
when I clicked on a URL.
It would run a command something like this:
</p>
<pre>
firefox -remote 'openURL(http://example.com/, new-tab)'
</pre>
<p>
But after a few months of manually cutting and pasting URLs into Chrome —
which wasn't actually <i>that</i> bad,
since the address bar in Chrome is such a convenient and large target —
I decided that I needed a real solution.
After not finding anything like a <tt>-remote</tt> option,
I discovered that Chrome can at least be run
with a debugging port open:
</p>
<pre>
google-chrome --remote-shell-port=9222
</pre>
<p>
The protocol that Chrome speaks is primitive enough
that it was quick work to implement a small client in Python.
Rather than merely cutting and pasting its code here on my blog,
or even be satisfied with
<a href="http://bitbucket.org/brandon/chrome_remote_shell/"
   >making it available on bitbucket</a>,
I decided to place the code inside of a new Python package
and make it generally available on PyPI as <a href="http://pypi.python.org/pypi/chrome_remote_shell/"
   >chrome_remote_shell</a>.
</p>
<p>
Thanks to this simple package,
a four-line program (not counting the shebang and comment)
is now all that I need to ask Google Chrome to open a new tab:
</p>
<pre>
#!/usr/bin/env python
# Name this file "google-chrome-open-url"
import sys
import chrome_remote_shell
shell = chrome_remote_shell.open()
shell.open_url(sys.argv[-1])
</pre>
<p>
To teach Emacs to start using Google Chrome when I clicked on a link,
I only needed to supply it with two new settings:
</p>
<pre>
(setq browse-url-browser-function
      'browse-url-generic)
(setq browse-url-generic-program
      "google-chrome-open-url")  
</pre>
<p>
And now everything works.
I hope that these notes prove useful to someone else.
Enjoy!
</p>
]]></content:encoded>
			<wfw:commentRss>http://rhodesmill.org/brandon/2010/remote-tabs-google-chrome/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Leaving Python Magazine</title>
		<link>http://rhodesmill.org/brandon/2010/leaving-python-magazine/</link>
		<comments>http://rhodesmill.org/brandon/2010/leaving-python-magazine/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 03:04:44 +0000</pubDate>
		<dc:creator>Brandon Craig Rhodes</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://rhodesmill.org/brandon/?p=275</guid>
		<description><![CDATA[It was with regret that I tendered my resignation yesterday as the Editor-in-Chief of Python Magazine. While the publisher will keep producing the magazine by distributing PDFs on the web site, the transition to the new format has dragged on long enough — both for both myself and our customers — that I have run out of [...]]]></description>
			<content:encoded><![CDATA[<div class="dropshadow alignright">
  <a>
    <img src="http://rhodesmill.org/brandon/static/2010/pymag-logo.png"
         alt="Python Magazine logo"
         width="200" height="63" />
  </a>
</div>
<p>
It was with regret that I tendered my resignation yesterday
as the Editor-in-Chief of Python Magazine.
While the publisher will keep producing the magazine
by distributing PDFs on the web site,
the transition to the new format has dragged on long enough —
both for both myself and our customers —
that I have run out of enthusiasm.
My last responsibility
will be to shepherd the February and March issues
through the publishing process
and safely on to the PDF readers of our subscribers.
</p>
<p>
I hope that the authors featured in the October issue will forgive me
for not writing my usual blog post last year touting their achievements;
I had just received the sad news that the publisher
could no longer afford the rising costs
of printing and shipping Python Magazine,
and I did not want to further advertise the magazine
until its fate was certain one way or the other.
</p>
<p>
I have by no means been a perfect editor.
In particular,
the publisher hoped that I would get the magazine —
which was running eight weeks late —
back on schedule.
Instead, my bumbling first month as editor
made the magazine an additional week late,
and by the time I hit my stride in May it was another week behind.
Although the schedule then stabilized at a steady ten weeks late,
I never did manage to start reeling the fish back in.
The only metric, I suppose, which I can really claim to my credit
is that I oversaw a nineteen-fold increase
in the number of em-dashes in the magazine —
247 appeared over the course of 2009,
up from only 13 the year before!
</p>
<p>
I should express thanks to my co-workers:
Arbi, Emanuela, and Cathleen are smart, helpful, and professional,
and were patient with me as I learned the ropes.
Doug Hellmann gave me ample training as he handed over the reins,
and also supported the magazine later as an acquisitions editor.
Several associate editors performed solid reviews of incoming articles.
And, of course, the greatest privilege of being Editor-in-Chief
was to help such a wide array of voices from the Python community
find their way into print —
from Steve Holden,
the illustrious chair of the Python Software Foundation,
to young Meran Cambpell-Hood,
an eleven-year-old from New Zealand
who described using Python for the first time
to process data for her science fair project.
</p>
<div class="dropshadow alignright">
  <a href="http://pymag.phparch.com/c/issue/view/109">
    <img src="http://rhodesmill.org/brandon/static/2009/pymag-october.jpg"
         alt="Cover of October 2009 Python Magazine"
         width="200" height="260" />
  </a>
</div>
<p>
Which reminds me:
the authors from the October issue
never got their moment in the spotlight!
The article by <b>Meran Campbell-Hood</b> about her science fair
project was the most fun to edit,
but every single article was interesting and taught me something.
Steve Holden interviewed <b>James Tauber</b>
about the secrets of a successful Python start-up;
<b>Yusdi Santoso</b> finished his two-part series
on the Python program he wrote to produce the PDF
for the beautiful EuroPython brochure last year;
the original editor of Python Magazine, <b>Brian Jones</b>,
returned to talk about why he now tends
to choose Django for web projects rather than PHP;
and <b>Joe Amenta</b> introduced his "3to2" project,
which will help Python programmers
support their old Python 2 users while still moving ahead
with the transition to Python 3.
Finally, <b>Greg Newman</b> explained how to turn Emacs
into a powerful Python IDE,
and <b>Steve Holden</b> and myself
rounded out the issue with our usual editorializing.
</p>
<p>
With many of the rest of you,
I am eager to see the debut of the new
<a href="http://pythonmagazine.com/">Python Magazine web site</a>.
And I look forward to seeing everyone
at <a href="http://us.pycon.org/2010/">PyCon 2010</a>
in less than three weeks!
While I will not have the joy that I did last year
of walking the halls of PyCon as a newly-minted Editor-in-Chief,
able to make dreams come true
and grant the fame and fortune of being a published author,
I will at least enjoy being a developer among developers
in the best programming language community on Earth!
</p>]]></content:encoded>
			<wfw:commentRss>http://rhodesmill.org/brandon/2010/leaving-python-magazine/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>The September 2009 issue of Python Magazine</title>
		<link>http://rhodesmill.org/brandon/2009/pymag-september/</link>
		<comments>http://rhodesmill.org/brandon/2009/pymag-september/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 05:41:07 +0000</pubDate>
		<dc:creator>Brandon Craig Rhodes</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Document processing]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://rhodesmill.org/brandon/?p=266</guid>
		<description><![CDATA[The September issue of Python Magazine appeared on the web late last week and only now, as a new week has started, am I finally sitting down to announce it! The articles range from technically heavy development topics to high-level thoughts about the whole Python community, with plenty in between. I have to say that [...]]]></description>
			<content:encoded><![CDATA[<div class="dropshadow alignright">
  <a href="http://pymag.phparch.com/c/issue/view/107">
    <img src="http://rhodesmill.org/brandon/static/2009/pymag-september.jpg"
         alt="Cover of September 2009 Python Magazine"
         width="200" height="258" />
  </a>
</div>
<p>
  The <a href="http://pymag.phparch.com/c/issue/view/107"
         >September issue of Python Magazine</a>
  appeared on the web late last week
  and only now, as a new week has started,
  am I finally sitting down to announce it!
  The articles range from technically heavy development topics
  to high-level thoughts about the whole Python community,
  with plenty in between.
</p>
<p>
  I have to say that our prettiest article this month
  is “Using Python to Create Beautiful Documents” by Yusdi Santoso,
  who shares the basic secrets to document generation
  that he learned when building the
  <a href="http://www.europython.eu/">EuroPython 2009</a> brochure
  using a Python program.
  Traditional typesetting and computer typography
  were both interests of mine when I was growing up,
  so it was fun to read Yusdi's introduction to using
  <a href="http://www.reportlab.org/">ReportLab</a>
  to generate PDF documents.
  I look forward to his follow-up article
  that we will soon be publishing,
  on the specific techniques that he used in creating
  the EuroPython booklet.
</p>
<p>
  The other technical articles are an introduction
  to using <a href="http://www.w3.org/TR/soap/">SOAP</a> in Python;
  a guide to displaying objects in a Mac OS X GUI created with PyObjC;
  an article introducing Python's own built-in
  <a href="http://docs.python.org/library/tkinter.html">Tkinter</a>
  GUI toolkit;
  and a small excursion of my own
  that attempts to explain the popular “trick”
  (well, it really confused <i>me</i> the first time I saw it!)
  of defining a decorator using a pair of nested functions.
  I should confess that my own article
  contains what is probably this issue's biggest mistake,
  as pointed out quite promptly by alert reader Emanuel Woiski:
  in the code sample that is its whole crux of my example,
  I somehow managed to omit one of the most crucial lines,
  shown here in bold:
</p>
<pre>
def log(function):
    def log_wrapper(*args):
        print "called %s%s" % (
            function.__name__, tuple(args)
            )
        <b>return function(*args)</b>
    return log_wrapper
</pre>
<p>
  I suppose I will now need remedial cut-and-paste training of some sort.
</p>
<p>
  Finally, the issue is rounded out
  by three articles that move back from Python coding
  and step out to wider vantage points.
  Justin Lilly provides an excellent guide
  to customizing your Vim setup
  so that it becomes a powerful Python
  integrated development environment.
  Steve Holden muses about why diveristy is so difficult
  and reveals some of the recent goings-on
  surrounding the diversity statement
  that the Python Software Foundation has been working on.
  And my own editorial seeks to point any Python Magazine readers
  who do not yet have a strong connection with the wider community
  in the direction of greater engagement
  with the world of Python.
</p>
<p>
  All in all, I think the issue
  is a nice mix of fact, experience, and opinion.
  Please consider subscribing if you would like to hear more
  about what people are doing with Python, and how.
  I enjoy reading it; so might you.
</p>]]></content:encoded>
			<wfw:commentRss>http://rhodesmill.org/brandon/2009/pymag-september/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Google Earth and Middle-earth</title>
		<link>http://rhodesmill.org/brandon/2009/google-earth-and-middle-earth/</link>
		<comments>http://rhodesmill.org/brandon/2009/google-earth-and-middle-earth/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 04:11:21 +0000</pubDate>
		<dc:creator>Brandon Craig Rhodes</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://rhodesmill.org/brandon/?p=253</guid>
		<description><![CDATA[Importing a normal, rectangular map of Middle-earth as a Google Earth overlay is too narrow toward the north. I wanted to measure distances in Tolkien's Middle-earth. While a flat map distorts such measurements, it occured to me that Google Earth can correctly measure both lines and paths across the curved surface of the globe. I soon [...]]]></description>
			<content:encoded><![CDATA[<div class="caption" style="width: 100%;">
  <img src="http://rhodesmill.org/brandon/static/2009/google-middle-earth-distorted.jpg"
       alt="GetPaid for Plone logo"
       width="420" height="286" />
  <p style="padding-left: 3em; padding-right: 3em; text-align: center;">
  Importing a normal, rectangular map of Middle-earth
  as a Google Earth overlay is too narrow toward the north.
</p></div>
<p>
  I wanted to measure distances in Tolkien's Middle-earth.
  While a flat map distorts such measurements,
  it occured to me that Google Earth can correctly measure
  both lines and paths across the curved surface of the globe.
  I soon found excellent documentation for
  <a href="http://earth.google.com/userguide/v4/ug_imageoverlays.html"
     >using image overlays with Google Earth</a>,
  so I downloaded a map of Middle-earth
  and tried placing it on the globe.
</p>
<p>
  Imagine my disappointment when I saw the result shown in the above image!
  At first I made the mistake
  of not holding down the <tt>Shift</tt> key
  when resizing the image in Google Earth;
  the <tt>Shift</tt> key is absolutely critical
  for the image to maintain its aspect ratio
  as you stretch it to the right dimensions.
  But even after learning this habit,
  it was painfully clear that the Middle-earth map's projection
  was different from that expected by Google Earth:
  the map is far too narrow at the top.
</p>
<p>
  Obviously, it was time to pull out Python,
  my favorite programming language,
  and see whether the
  <a href="http://www.pythonware.com/products/pil/">Python Imaging Library</a>
  could help me make short work
  of converting a map from one projection to another.
</p>
(...)<br/>Read the rest of <a href="http://rhodesmill.org/brandon/2009/google-earth-and-middle-earth/">Google Earth and Middle-earth</a> (1,146 words)</p>
]]></content:encoded>
			<wfw:commentRss>http://rhodesmill.org/brandon/2009/google-earth-and-middle-earth/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
