<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="http://nedbatchelder.com/rssfull2html.xslt" media="screen" ?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns="http://purl.org/rss/1.0/">
	<channel rdf:about="http://nedbatchelder.com//blog">
		<title>Ned Batchelder's blog</title>
		<link>http://nedbatchelder.com/blog</link>
		<description>Ned Batchelder's personal blog.</description>
		<dc:language>en-US</dc:language>
		<image rdf:resource="http://nedbatchelder.com/pix/rss-banner.gif"/>
		<items>
			<rdf:Seq>
				<rdf:li resource="http://nedbatchelder.com/blog/201008/global_django_requests.html"/><rdf:li resource="http://nedbatchelder.com/blog/201008/coveragepy_v34_beta_1.html"/><rdf:li resource="http://nedbatchelder.com/blog/201008/entrepreneurship.html"/><rdf:li resource="http://nedbatchelder.com/blog/201008/django_superuser_login_trapdoor.html"/><rdf:li resource="http://nedbatchelder.com/blog/201007/better_error_messages.html"/><rdf:li resource="http://nedbatchelder.com/blog/201007/whitespace_in_ruby_and_searching_for_code.html"/><rdf:li resource="http://nedbatchelder.com/blog/201007/making_peace_with_autism_in_korean.html"/><rdf:li resource="http://nedbatchelder.com/blog/201007/installing_python_packages_from_windows_installers_into.html"/><rdf:li resource="http://nedbatchelder.com/blog/201007/zach_anner.html"/><rdf:li resource="http://nedbatchelder.com/blog/201007/recent_tweets.html"/>
			</rdf:Seq>
		</items>
	</channel>
	<image rdf:about="http://nedbatchelder.com/pix/rss-banner.gif">
		<title>Ned Batchelder's blog</title>
		<link>http://nedbatchelder.com/blog</link>
		<url>http://nedbatchelder.com/pix/rss-banner.gif</url>
	</image>
	
	<item rdf:about="http://nedbatchelder.com/blog/201008/global_django_requests.html">
		<title>Global Django requests</title>
		<link>http://nedbatchelder.com/blog/201008/global_django_requests.html</link>
		
		<dc:date>2010-08-28T17:09:50-04:00</dc:date>
		<dc:creator>Ned Batchelder</dc:creator>
		<description><![CDATA[<p>As my Django sites get larger and larger, there inevitably comes a point
where I want access to the current request from deep inside some function
that doesn't have the request object.  The latest reason was that I wanted
a model class helper to have access to the session so it could access some
debug flags.</p><p>The first option for making this work was to pass the request object 
through two or three layers of code that otherwise didn't need a request.
This meant changing the signature and callers of the two or three functions,
which felt messy.  The prospect of it made me unhappy.</p><p>The second option was to create a way for any code invoked as part of a
request to get access to the request, even if it weren't passed to it
explicitly.  I think of this as a global request object.
</p><p>Of course, there isn't really a single global request object, since there
can be many threads, each of which is handling a separate request.  We need
a way to associate the request with a thread, and then to get the request
for our thread.  This middleware does the job nicely:</p><blockquote class="code"><tt><span class="p_word">from</span><span class="p_default">&#160;</span><span class="p_identifier">django</span><span class="p_operator">.</span><span class="p_identifier">utils</span><span class="p_operator">.</span><span class="p_identifier">thread_support</span><span class="p_default">&#160;</span><span class="p_word">import</span><span class="p_default">&#160;</span><span class="p_identifier">currentThread</span><br/>
<span class="p_identifier">_requests</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_operator">{}</span><br/>
<br/>
<span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">get_request</span><span class="p_operator">():</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">return</span><span class="p_default">&#160;</span><span class="p_identifier">_requests</span><span class="p_operator">[</span><span class="p_identifier">currentThread</span><span class="p_operator">()]</span><br/>
<br/>
<span class="p_word">class</span><span class="p_default">&#160;</span><span class="p_classname">GlobalRequestMiddleware</span><span class="p_operator">(</span><span class="p_identifier">object</span><span class="p_operator">):</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">process_request</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">request</span><span class="p_operator">):</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">_requests</span><span class="p_operator">[</span><span class="p_identifier">currentThread</span><span class="p_operator">()]</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">request</span><br/>
</tt></blockquote><p>I didn't write this code, I got it from 
<a class="offsite" href="http://stackoverflow.com/questions/653735/django-forms-set-an-initial-value-to-request-user/1233143#1233143">here</a> and 
<a class="offsite" href="http://bitbucket.org/vanschelven/global_request_middleware/src/df173c616e32/global_request_middleware/__init__.py">here</a>,
not sure who wrote it first.  I'm also not sure why Django provides its
own currentThread function when the Python standard module threading provides
thread locals to acheive the same effect.</p><p>There's another way to get a global request object, but you probably won't
like it:</p><blockquote class="code"><tt><span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">get_request</span><span class="p_operator">():</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_tripledouble">"""Walk&#160;up&#160;the&#160;stack,&#160;return&#160;the&#160;nearest&#160;first&#160;argument&#160;named&#160;"request"."""</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_identifier">frame</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_word">None</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">try</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">for</span><span class="p_default">&#160;</span><span class="p_identifier">f</span><span class="p_default">&#160;</span><span class="p_word">in</span><span class="p_default">&#160;</span><span class="p_identifier">inspect</span><span class="p_operator">.</span><span class="p_identifier">stack</span><span class="p_operator">()[</span><span class="p_number">1</span><span class="p_operator">:]:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">frame</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">f</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">]</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">code</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">frame</span><span class="p_operator">.</span><span class="p_identifier">f_code</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">if</span><span class="p_default">&#160;</span><span class="p_identifier">code</span><span class="p_operator">.</span><span class="p_identifier">co_varnames</span><span class="p_default">&#160;</span><span class="p_word">and</span><span class="p_default">&#160;</span><span class="p_identifier">code</span><span class="p_operator">.</span><span class="p_identifier">co_varnames</span><span class="p_operator">[</span><span class="p_number">0</span><span class="p_operator">]</span><span class="p_default">&#160;</span><span class="p_operator">==</span><span class="p_default">&#160;</span><span class="p_string">"request"</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">return</span><span class="p_default">&#160;</span><span class="p_identifier">frame</span><span class="p_operator">.</span><span class="p_identifier">f_locals</span><span class="p_operator">[</span><span class="p_character">'request'</span><span class="p_operator">]</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">finally</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">del</span><span class="p_default">&#160;</span><span class="p_identifier">frame</span><br/>
</tt></blockquote><p>This function looks at the stack frames of all of its callers, looking for
one with a first argument named "request".  If found, it returns the value.
The problem with this function is that it can be fooled, and will return
the "request" it finds regardless of its type.</p><p>In its defense: GlobalRequestMiddleware requires more machinery, and adds
a tiny tax to every request.  If your need for the global request object
is rare, the frame-based get_request() may be better for you.  Also, it's
a (nasty) technique that can be adapted to other situations.</p>
]]></description>
	</item>
	
	<item rdf:about="http://nedbatchelder.com/blog/201008/coveragepy_v34_beta_1.html">
		<title>Coverage.py v3.4 beta 1</title>
		<link>http://nedbatchelder.com/blog/201008/coveragepy_v34_beta_1.html</link>
		
		<dc:date>2010-08-21T14:43:49-04:00</dc:date>
		<dc:creator>Ned Batchelder</dc:creator>
		<description><![CDATA[<p><a class="offsite" href="http://pypi.python.org/pypi/coverage">Coverage.py v3.4 beta 1 </a>
is available now.  3.4 brings improved source code specification.
The --omit and --include switches have changed in an incompatible way, taking
file patterns rather than prefixes, and a new --source switch specifies 
directories or modules to measure.  Details are in the new page about
<a class="offsite" href="http://nedbatchelder.com/code/coverage/beta/source.html">specifying source files</a>
in the coverage.py docs.  These changes should help people focus
coverage.py on the code they really want to measure.
</p><p>In addition, a few bug fixes have helped in this area: Jinja templates and
doctest bodies are no longer measured, since they produced errors during 
reporting anyway.</p><p>One other notable change: coverage.py used to report the number of statements,
and the number of executed statements.  Now instead of executed statements,
it reports missed statements.  This is a better indicator of how well your code
is covered, because it's clear what the goal is: zero missed statements.</p><p>Give this version a try.  There have been lots of 
<a class="offsite" href="http://bitbucket.org/ned/coveragepy/src/c0af9a0b5c4d/CHANGES.txt">changes</a>.
Also, I hate to admit it: but this version has broken my own coverage
measurement of coverage.py itself, and I haven't figured out why yet...</p>
]]></description>
	</item>
	
	<item rdf:about="http://nedbatchelder.com/blog/201008/entrepreneurship.html">
		<title>Entrepreneurship</title>
		<link>http://nedbatchelder.com/blog/201008/entrepreneurship.html</link>
		
		<dc:date>2010-08-17T08:16:57-04:00</dc:date>
		<dc:creator>Ned Batchelder</dc:creator>
		<description><![CDATA[<p>After posting Alain De Botton's <a href="http://nedbatchelder.com/blog/201006/fragmented_biscuit_making.html">quote about meaningful work</a>,
I read his book <a class="offsite" href="http://www.alaindebotton.com/work">The Joys and Sorrows of Work</a>.  It was an interesting
read, but ultimately a bit empty.  He described a number of unusual
working environments, but managed not to get a single worker's words
or thoughts onto the page.  Mostly what he describes are the factual
landscape, his own reactions to what he sees, and way too much about
his own difficulties traveling.
</p><p>But he is a thoughtful observer, and a good writer.  After watching 
inventors pitch futilely to investors, he summed up the dynamics of venture 
capital thus:
</p><blockquote><div><p>
Then again, there was a certain heroic beauty in the exuberant destruction of
both capital and hope entailed by the entrepreneurs' activities.  Money
patiently accumulated through decades of unremarkable work would, in a rush of
optimism inspired by a flattering business plan, be handed over to a
momentarily convincing chief executive, who would hasten to set the pyre alight
in a brief, brilliant and largely inconsequential blaze.  
</p></div></blockquote><p>A bit cynical, but spot on.</p>
]]></description>
	</item>
	
	<item rdf:about="http://nedbatchelder.com/blog/201008/django_superuser_login_trapdoor.html">
		<title>Django superuser login trapdoor</title>
		<link>http://nedbatchelder.com/blog/201008/django_superuser_login_trapdoor.html</link>
		
		<dc:date>2010-08-13T22:28:46-04:00</dc:date>
		<dc:creator>Ned Batchelder</dc:creator>
		<description><![CDATA[<p>I added an admin trapdoor login to a project the other day.  This is the
technique where a superuser can log in to a site as any other user.  My
preferred way to do this is to <a class="offsite" href="http://nedbatchelder.com/blog/200905/log_in_as_a_user.html">use
the standard login form in a clever way</a>: enter the desired user's
name as the username, and both your superuser name and superuser password
into the password field.
</p><p>But this project was modern enough that I could use a 
<a class="offsite" href="http://docs.djangoproject.com/en/1.2/topics/auth/#authentication-backends">Django authentication backend</a>
to get the job done:</p><blockquote class="code"><tt><span class="p_word">from</span><span class="p_default">&#160;</span><span class="p_identifier">django</span><span class="p_operator">.</span><span class="p_identifier">contrib</span><span class="p_operator">.</span><span class="p_identifier">auth</span><span class="p_default">&#160;</span><span class="p_word">import</span><span class="p_default">&#160;</span><span class="p_identifier">login</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">authenticate</span><br/>
<span class="p_word">from</span><span class="p_default">&#160;</span><span class="p_identifier">django</span><span class="p_operator">.</span><span class="p_identifier">contrib</span><span class="p_operator">.</span><span class="p_identifier">auth</span><span class="p_operator">.</span><span class="p_identifier">models</span><span class="p_default">&#160;</span><span class="p_word">import</span><span class="p_default">&#160;</span><span class="p_identifier">User</span><br/>
<br/>
<span class="p_commentline">#&#160;So&#160;I&#160;can&#160;invoked&#160;authenticate&#160;recursively&#160;below</span><br/>
<span class="p_identifier">django_authenticate</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">authenticate</span><br/>
<br/>
<span class="p_word">class</span><span class="p_default">&#160;</span><span class="p_classname">SuperuserLoginAuthenticationBackend</span><span class="p_operator">(</span><span class="p_identifier">object</span><span class="p_operator">):</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_tripledouble">"""&#160;Let&#160;superusers&#160;login&#160;as&#160;regular&#160;users.&#160;"""</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">authenticate</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">username</span><span class="p_operator">=</span><span class="p_word">None</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">password</span><span class="p_operator">=</span><span class="p_word">None</span><span class="p_operator">):</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">try</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">user</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">User</span><span class="p_operator">.</span><span class="p_identifier">objects</span><span class="p_operator">.</span><span class="p_identifier">get</span><span class="p_operator">(</span><span class="p_identifier">username</span><span class="p_operator">=</span><span class="p_identifier">username</span><span class="p_operator">)</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">except</span><span class="p_default">&#160;</span><span class="p_identifier">User</span><span class="p_operator">.</span><span class="p_identifier">DoesNotExist</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">return</span><span class="p_default">&#160;</span><span class="p_word">None</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_commentline">#&#160;The&#160;password&#160;should&#160;be&#160;name/password</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">if</span><span class="p_default">&#160;</span><span class="p_string">"@"</span><span class="p_default">&#160;</span><span class="p_word">not</span><span class="p_default">&#160;</span><span class="p_word">in</span><span class="p_default">&#160;</span><span class="p_identifier">password</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">return</span><span class="p_default">&#160;</span><span class="p_word">None</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">supername</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">superpass</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">password</span><span class="p_operator">.</span><span class="p_identifier">split</span><span class="p_operator">(</span><span class="p_string">"@"</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_number">1</span><span class="p_operator">)</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">superuser</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">django_authenticate</span><span class="p_operator">(</span><span class="p_identifier">username</span><span class="p_operator">=</span><span class="p_identifier">supername</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">password</span><span class="p_operator">=</span><span class="p_identifier">superpass</span><span class="p_operator">)</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">if</span><span class="p_default">&#160;</span><span class="p_identifier">superuser</span><span class="p_default">&#160;</span><span class="p_word">and</span><span class="p_default">&#160;</span><span class="p_identifier">superuser</span><span class="p_operator">.</span><span class="p_identifier">is_superuser</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">return</span><span class="p_default">&#160;</span><span class="p_identifier">user</span><br/>
<br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">get_user</span><span class="p_operator">(</span><span class="p_identifier">self</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">user_id</span><span class="p_operator">):</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">try</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">return</span><span class="p_default">&#160;</span><span class="p_identifier">User</span><span class="p_operator">.</span><span class="p_identifier">objects</span><span class="p_operator">.</span><span class="p_identifier">get</span><span class="p_operator">(</span><span class="p_identifier">pk</span><span class="p_operator">=</span><span class="p_identifier">user_id</span><span class="p_operator">)</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">except</span><span class="p_default">&#160;</span><span class="p_identifier">User</span><span class="p_operator">.</span><span class="p_identifier">DoesNotExist</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">return</span><span class="p_default">&#160;</span><span class="p_word">None</span><br/>
</tt></blockquote><p>Very nice.</p>
]]></description>
	</item>
	
	<item rdf:about="http://nedbatchelder.com/blog/201007/better_error_messages.html">
		<title>Better error messages</title>
		<link>http://nedbatchelder.com/blog/201007/better_error_messages.html</link>
		
		<dc:date>2010-07-28T08:56:16-04:00</dc:date>
		<dc:creator>Ned Batchelder</dc:creator>
		<description><![CDATA[<p>A simple piece of advice: If you are throwing an exception (or logging an
error) about a value being incorrect in some way, include the value itself.
It will make it so much easier for the poor sap who has to figure out why the
exception is happening.
</p><p>I found myself in this situation, this code throwing an exception:</p><blockquote class="code"><tt><span class="p_word">if</span><span class="p_default">&#160;</span><span class="p_word">not</span><span class="p_default">&#160;</span><span class="p_identifier">isinstance</span><span class="p_operator">(</span><span class="p_identifier">key</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">str</span><span class="p_operator">):</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">raise</span><span class="p_default">&#160;</span><span class="p_identifier">Client</span><span class="p_operator">.</span><span class="p_identifier">MemcachedStringEncodingError</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_operator">(</span><span class="p_string">"Keys&#160;must&#160;be&#160;str()'s,&#160;not"</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_string">"unicode.&#160;&#160;Convert&#160;your&#160;unicode&#160;strings&#160;using&#160;"</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_string">"mystring.encode(charset)!"</span><span class="p_operator">)</span><span class="p_default">&#160;</span><br/>
</tt></blockquote><p>There are a few things wrong with this message, the first being that the
multi-line string concatenation is missing a space, so the message actually has
the word "notunicode" in it.  Why are we so sure the wrong value is Unicode in
the first place?  And of course, it should include the actual value:
</p><blockquote class="code"><tt><span class="p_word">if</span><span class="p_default">&#160;</span><span class="p_word">not</span><span class="p_default">&#160;</span><span class="p_identifier">isinstance</span><span class="p_operator">(</span><span class="p_identifier">key</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">str</span><span class="p_operator">):</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">raise</span><span class="p_default">&#160;</span><span class="p_identifier">Client</span><span class="p_operator">.</span><span class="p_identifier">MemcachedStringEncodingError</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_operator">(</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_string">"Keys&#160;must&#160;be&#160;str()'s:&#160;%r"</span><span class="p_default">&#160;</span><span class="p_operator">%</span><span class="p_default">&#160;</span><span class="p_identifier">key</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_operator">)</span><br/>
</tt></blockquote><p>If you want to be paranoid, you can limit the amount of repr text that
will appear in the message:</p><blockquote class="code"><tt><span class="p_word">if</span><span class="p_default">&#160;</span><span class="p_word">not</span><span class="p_default">&#160;</span><span class="p_identifier">isinstance</span><span class="p_operator">(</span><span class="p_identifier">key</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">str</span><span class="p_operator">):</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">raise</span><span class="p_default">&#160;</span><span class="p_identifier">Client</span><span class="p_operator">.</span><span class="p_identifier">MemcachedStringEncodingError</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_operator">(</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_string">"Keys&#160;must&#160;be&#160;str()'s:&#160;%.60r"</span><span class="p_default">&#160;</span><span class="p_operator">%</span><span class="p_default">&#160;</span><span class="p_identifier">key</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_operator">)</span><br/>
</tt></blockquote><p>If you are really paranoid, you're worried that getting the repr of your
unknown object could itself throw an exception:</p><blockquote class="code"><tt><span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">safe_repr</span><span class="p_operator">(</span><span class="p_identifier">o</span><span class="p_operator">):</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">try</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">return</span><span class="p_default">&#160;</span><span class="p_identifier">repr</span><span class="p_operator">(</span><span class="p_identifier">o</span><span class="p_operator">)</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">except</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">return</span><span class="p_default">&#160;</span><span class="p_string">"??norepr?"</span><br/>
<br/>
<span class="p_operator">...</span><br/>
<br/>
<span class="p_word">if</span><span class="p_default">&#160;</span><span class="p_word">not</span><span class="p_default">&#160;</span><span class="p_identifier">isinstance</span><span class="p_operator">(</span><span class="p_identifier">key</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">str</span><span class="p_operator">):</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">raise</span><span class="p_default">&#160;</span><span class="p_identifier">Client</span><span class="p_operator">.</span><span class="p_identifier">MemcachedStringEncodingError</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_operator">(</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_string">"Keys&#160;must&#160;be&#160;str()'s:&#160;%.60s"</span><span class="p_default">&#160;</span><span class="p_operator">%</span><span class="p_default">&#160;</span><span class="p_identifier">safe_repr</span><span class="p_operator">(</span><span class="p_identifier">key</span><span class="p_operator">)</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_operator">)</span><br/>
</tt></blockquote><p>or even:</p><blockquote class="code"><tt><span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">safe_repr</span><span class="p_operator">(</span><span class="p_identifier">o</span><span class="p_operator">):</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">try</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">return</span><span class="p_default">&#160;</span><span class="p_identifier">repr</span><span class="p_operator">(</span><span class="p_identifier">o</span><span class="p_operator">)</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">except</span><span class="p_default">&#160;</span><span class="p_identifier">Exception</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">e</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">return</span><span class="p_default">&#160;</span><span class="p_string">"??norepr&#160;(%s)?"</span><span class="p_default">&#160;</span><span class="p_operator">%</span><span class="p_default">&#160;</span><span class="p_identifier">e</span><br/>
</tt></blockquote><p>Good error handling is always a pain, but it's worth it when things start
hitting the fan and you have to figure out what's going on.</p>
]]></description>
	</item>
	
	<item rdf:about="http://nedbatchelder.com/blog/201007/whitespace_in_ruby_and_searching_for_code.html">
		<title>Whitespace in Ruby and searching for code</title>
		<link>http://nedbatchelder.com/blog/201007/whitespace_in_ruby_and_searching_for_code.html</link>
		
		<dc:date>2010-07-27T07:40:33-04:00</dc:date>
		<dc:creator>Ned Batchelder</dc:creator>
		<description><![CDATA[<p>Armin's post about <a class="offsite" href="http://lucumr.pocoo.org/2008/7/1/whitespace-sensitivity">Whitespace sensitivity</a>
in Ruby piqued my interest.  It points out that in Ruby, <span class="codeword">foo[42]</span>
is different than <span class="codeword">foo [42]</span> and that <span class="codeword">foo/bar</span>
is the same as <span class="codeword">foo / bar</span> but different than <span class="codeword">foo /bar</span>.
</p><p>So I wanted to learn more about Ruby, and looked at a bunch of tutorials,
finally ending up at Mitch Fincher's <a class="offsite" href="http://www.fincher.org/tips/Languages/Ruby/">Ruby Tutorial with Code Samples</a>,
which had the right breezy pace with no, "a variable is like a box for your numbers" stuff in it.</p><p>But I had originally gotten to Mitch's page from a Google search for
<a class="offsite" href="http://www.google.com/search?q=ruby%20puts%20gets">ruby puts gets</a>.
If you try it, you'll see that when you get to Mitch's page, a small box appears
near the top, saying,</p><blockquote class="box">Welcome. You seem to have come here from a search engine. Your search words (ruby puts gets) are highlighted on this page for your reading pleasure.</blockquote><p>I thought "nice,"  then I thought, "that looks familiar," then I realized it
was almost exactly the box that appears at the top of my pages when you visit
from a search engine (try it: <a class="offsite" href="http://www.google.com/search?q=batchelder+white+house+adventure">batchelder white house adventure</a>).
In fact, it used the same colors.  I looked at his page, and it used near-verbatim
copies of my three Javascript files, though a few years ago I consolidated them
into one.</p><p>I was amused, and wondered where else the code is being used.  But the search
engines are smart enough not to index comments in Javascript files, or names of
Javascript files referenced in HTML pages, unless there's some tricky syntax I
don't know about.
</p><p>PS: about whitespace sensitivity: I've decided that phrase means a programming
language needs tokens consisting of only whitespace in order to be parsed
properly.  Python and Ruby are whitespace-sensitive, and C is not, for example.
</p>
]]></description>
	</item>
	
	<item rdf:about="http://nedbatchelder.com/blog/201007/making_peace_with_autism_in_korean.html">
		<title>Making Peace with Autism in Korean</title>
		<link>http://nedbatchelder.com/blog/201007/making_peace_with_autism_in_korean.html</link>
		
		<dc:date>2010-07-18T10:06:50-04:00</dc:date>
		<dc:creator>Ned Batchelder</dc:creator>
		<description><![CDATA[<p>My wife's book <a class="offsite" href="http://susansenator.com/makingpeace.html">Making Peace with Autism</a>
is now available in Korean:
<a class="offsite" href="http://hakjisa.co.kr/book/book01.php?page=&amp;ptype=view&amp;bcode=P02057">자폐아 가정의 좌충우돌 성장 이야기</a>.
</p><p align="center"><a href="http://hakjisa.co.kr/book/book01.php?page=&amp;ptype=view&amp;bcode=P02057"><img src="http://nedbatchelder.com/pix/mpwa_kr.jpg" alt="Making Peace with Autism in Korean" width="306" height="450"></a></p><p>The publishing business is a strange place.  The first we knew the book was
being translated into Korean was when a box of the books was delivered to our
doorstep.  Apparently there was also an entry in the latest sales statement from
the publisher, but those things are completely indecipherable, so we didn't notice.
</p><p>The Korean culture also seems to value cute more than we Americans do: the
book is full of cartoony decorations. I guess that chipper salaryman on the
cover is me!
</p>
]]></description>
	</item>
	
	<item rdf:about="http://nedbatchelder.com/blog/201007/installing_python_packages_from_windows_installers_into.html">
		<title>Installing Python packages from Windows installers into virtualenv</title>
		<link>http://nedbatchelder.com/blog/201007/installing_python_packages_from_windows_installers_into.html</link>
		
		<dc:date>2010-07-17T16:47:00-04:00</dc:date>
		<dc:creator>Ned Batchelder</dc:creator>
		<description><![CDATA[<p>I'm a recent convert to <a class="offsite" href="http://pypi.python.org/pypi/virtualenv">virtualenv</a>,
it's a great way to maintain a number of different Python installations so that
you can install packages for one project without it polluting the environment
for all your projects.
</p><p>I also work on Windows, which can be a pain.  In particular, many interesting
Python packages involve compiling extensions, which is not always easy, and
especially not easy on Windows.  So I'm glad when package authors provide pre-built
binaries for Windows.  These are typically delivered as .exe Windows installers.
</p><p>Here's the problem: these installers know to look in the registry to find the
Python installation.  There are many things developers dislike about Windows,
and the registry is often at the top of the list.  One of the bad things about
it is that it encourages a mindset of their being one of everything.  Starting
with the concept of "one registry", it seeps into the whole culture of Windows,
invading even to Python, which cannot abide more than one installation of a
major release.</p><p>So when running a Windows package installer, it will find <em>the</em> Python 2.6
installation in the registry, and that's the only option you've got for where
the code is going to go.  Your nice isolated virtualenvs are completely out of
the picture.</p><p>I asked on Stack Overflow <a class="offsite" href="http://stackoverflow.com/questions/3271590/can-i-install-python-windows-packages-into-virtualenvs">if
there's a way to install Windows package installers into virtualenvs</a>, and
didn't get the answers I wanted.</p><p>So I decided the best approach was to change the registry, install my package,
then change the registry back.  I adapted <a class="offsite" href="http://effbot.org/zone/python-register.htm">a classic script
to register Python installations</a>, to create what I've called the_python.py:</p><blockquote class="code"><tt><span class="p_commentline">#&#160;script&#160;to&#160;register&#160;Python&#160;2.0&#160;or&#160;later&#160;for&#160;use&#160;with&#160;win32all</span><br/>
<span class="p_commentline">#&#160;and&#160;other&#160;extensions&#160;that&#160;require&#160;Python&#160;registry&#160;settings</span><br/>
<span class="p_commentline">#</span><br/>
<span class="p_commentline">#&#160;Adapted&#160;by&#160;Ned&#160;Batchelder&#160;from&#160;a&#160;script</span><br/>
<span class="p_commentline">#&#160;written&#160;by&#160;Joakim&#160;Low&#160;for&#160;Secret&#160;Labs&#160;AB&#160;/&#160;PythonWare</span><br/>
<span class="p_commentline">#</span><br/>
<span class="p_commentline">#&#160;source:</span><br/>
<span class="p_commentline">#&#160;<a href="http://www.pythonware.com/products/works/articles/regpy20.htm">http://www.pythonware.com/products/works/articles/regpy20.htm</a></span><br/>
<br/>
<span class="p_word">import</span><span class="p_default">&#160;</span><span class="p_identifier">sys</span><br/>
<br/>
<span class="p_word">from</span><span class="p_default">&#160;</span><span class="p_identifier">_winreg</span><span class="p_default">&#160;</span><span class="p_word">import</span><span class="p_default">&#160;</span><span class="p_operator">*</span><br/>
<br/>
<span class="p_commentline">#&#160;tweak&#160;as&#160;necessary</span><br/>
<span class="p_identifier">version</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">sys</span><span class="p_operator">.</span><span class="p_identifier">version</span><span class="p_operator">[:</span><span class="p_number">3</span><span class="p_operator">]</span><br/>
<span class="p_identifier">installpath</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">sys</span><span class="p_operator">.</span><span class="p_identifier">prefix</span><br/>
<br/>
<span class="p_identifier">regpath</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_string">"SOFTWARE\\Python\\Pythoncore\\%s\\"</span><span class="p_default">&#160;</span><span class="p_operator">%</span><span class="p_default">&#160;</span><span class="p_operator">(</span><span class="p_identifier">version</span><span class="p_operator">)</span><br/>
<span class="p_identifier">installkey</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_string">"InstallPath"</span><br/>
<span class="p_identifier">pythonkey</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_string">"PythonPath"</span><br/>
<span class="p_identifier">pythonpath</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_string">"%s;%s\\Lib\\;%s\\DLLs\\"</span><span class="p_default">&#160;</span><span class="p_operator">%</span><span class="p_default">&#160;</span><span class="p_operator">(</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_identifier">installpath</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">installpath</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">installpath</span><br/>
<span class="p_operator">)</span><br/>
<br/>
<span class="p_word">def</span><span class="p_default">&#160;</span><span class="p_defname">RegisterPy</span><span class="p_operator">():</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">try</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">reg</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">OpenKey</span><span class="p_operator">(</span><span class="p_identifier">HKEY_LOCAL_MACHINE</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">regpath</span><span class="p_operator">)</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">except</span><span class="p_default">&#160;</span><span class="p_identifier">EnvironmentError</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">try</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_identifier">reg</span><span class="p_default">&#160;</span><span class="p_operator">=</span><span class="p_default">&#160;</span><span class="p_identifier">CreateKey</span><span class="p_operator">(</span><span class="p_identifier">HKEY_LOCAL_MACHINE</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">regpath</span><span class="p_operator">)</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">except</span><span class="p_default">&#160;</span><span class="p_identifier">Exception</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">e</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">print</span><span class="p_default">&#160;</span><span class="p_string">"***&#160;Unable&#160;to&#160;register:&#160;%s"</span><span class="p_default">&#160;</span><span class="p_operator">%</span><span class="p_default">&#160;</span><span class="p_identifier">e</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</span><span class="p_word">return</span><br/>
<br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_identifier">SetValue</span><span class="p_operator">(</span><span class="p_identifier">reg</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">installkey</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">REG_SZ</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">installpath</span><span class="p_operator">)</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_identifier">SetValue</span><span class="p_operator">(</span><span class="p_identifier">reg</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">pythonkey</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">REG_SZ</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">pythonpath</span><span class="p_operator">)</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_identifier">CloseKey</span><span class="p_operator">(</span><span class="p_identifier">reg</span><span class="p_operator">)</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_word">print</span><span class="p_default">&#160;</span><span class="p_string">"---&#160;Python&#160;%s&#160;at&#160;%s&#160;is&#160;now&#160;registered!"</span><span class="p_default">&#160;</span><span class="p_operator">%</span><span class="p_default">&#160;</span><span class="p_operator">(</span><span class="p_identifier">version</span><span class="p_operator">,</span><span class="p_default">&#160;</span><span class="p_identifier">installpath</span><span class="p_operator">)</span><br/>
<br/>
<span class="p_word">if</span><span class="p_default">&#160;</span><span class="p_identifier">__name__</span><span class="p_default">&#160;</span><span class="p_operator">==</span><span class="p_default">&#160;</span><span class="p_string">"__main__"</span><span class="p_operator">:</span><br/>
<span class="p_default">&#160;&#160;&#160;&#160;</span><span class="p_identifier">RegisterPy</span><span class="p_operator">()</span><br/>
</tt></blockquote><p>Use your desired Python to run this script, and it will be entered into the
registry as <em>the</em> Python.  When you run your Windows package installer,
it will go into your virtualenv.  Don't forget to run it again at the end to
put things back the way they were.</p>
]]></description>
	</item>
	
	<item rdf:about="http://nedbatchelder.com/blog/201007/zach_anner.html">
		<title>Zach Anner</title>
		<link>http://nedbatchelder.com/blog/201007/zach_anner.html</link>
		
		<dc:date>2010-07-16T18:26:13-04:00</dc:date>
		<dc:creator>Ned Batchelder</dc:creator>
		<description><![CDATA[<p>Zach Anner is a funny guy, who happens to have cerebral palsy, as Zach puts it,
"the sexiest of the palsies".  He submitted a video to
<a class="offsite" href="http://myown.oprah.com/audition/index.html?request=finalists">Oprah's Search for the next TV star</a>:
</p><p align="center"><object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/T_35KKa3b1c&amp;amp;hl=en_US&amp;amp;fs=1"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/T_35KKa3b1c&amp;amp;hl=en_US&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object></p><p>He ended up with 2.5 million votes:</p><p align="center"><object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/bG0_rnkRiM8&amp;amp;hl=en_US&amp;amp;fs=1"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/bG0_rnkRiM8&amp;amp;hl=en_US&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object></p><p>I really like Zach's humor because it doesn't avoid his disability, and it
isn't just about his disability.  It's about funny Zach and the funny world,
and Zach's cerebral palsy is part of it, but just a part.  He strikes just the
right balance, and he's got a great attitude.  Watch him train for the 2011
Austin marathon:</p><p align="center"><object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/sQAG_xOmwXI&amp;amp;hl=en_US&amp;amp;fs=1"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/sQAG_xOmwXI&amp;amp;hl=en_US&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object></p><p>He has more stuff with <a class="offsite" href="http://larkthebeard.com/">Lark the Beard</a>.
I hope he goes far.</p>
]]></description>
	</item>
	
	<item rdf:about="http://nedbatchelder.com/blog/201007/recent_tweets.html">
		<title>Recent tweets</title>
		<link>http://nedbatchelder.com/blog/201007/recent_tweets.html</link>
		
		<dc:date>2010-07-05T21:21:34-04:00</dc:date>
		<dc:creator>Ned Batchelder</dc:creator>
		<description><![CDATA[<p class="quick">
		¶  <span class="tweet">RT <a class="user" href="http://www.twitter.com/catherinedevlin">@catherinedevlin</a>: I am so moving to France. Castle under construction w/ 100% historical technology. <a class="offsite" href="http://tinyurl.com/3acrbve">http://tinyurl.com/3acrbve</a> <a class="date" href="http://twitter.com/nedbat/status/17532972964">(Jul 02)</a></span></p><p class="quick">
		¶  <span class="tweet">Awesome and sweet.. RT <a class="user" href="http://www.twitter.com/sgalineau">@sgalineau</a>: <a class="offsite" href="http://www.youtube.com/watch?v=-CVYOCMpJRY">http://www.youtube.com/watch?v=-CVYOCMpJRY</a> <a class="hashtag" href="http://www.twitter.com/#search?q=%23classic">#classic</a> <a class="hashtag" href="http://www.twitter.com/#search?q=%23starwars">#starwars</a> (via <a class="user" href="http://www.twitter.com/bcongdon">@bcongdon</a>) <a class="date" href="http://twitter.com/nedbat/status/17285527075">(Jun 28)</a></span></p><p class="quick">
		¶  <span class="tweet">Not often you get bitingly mean graphic design humor: RT <a class="user" href="http://www.twitter.com/jackschofield">@jackschofield</a>: Missing cat poster story <a class="offsite" href="http://www.27bslash6.com/missy.html">http://www.27bslash6.com/missy.html</a> [Cat lovers beware] <a class="date" href="http://twitter.com/nedbat/status/16974048262">(Jun 25)</a></span></p><p class="quick">
		¶  <span class="tweet">Tons of recreational math stuff! Sadly, no RSS: <a class="offsite" href="http://www.mathpuzzle.com/">http://www.mathpuzzle.com/</a> <a class="date" href="http://twitter.com/nedbat/status/16580782182">(Jun 20)</a></span></p><p class="quick">
		¶  <span class="tweet">The Omnificent English Dictionary In Limerick Form: <a class="offsite" href="http://www.oedilf.com.">http://www.oedilf.com.</a> Really. <a class="date" href="http://twitter.com/nedbat/status/16580113991">(Jun 20)</a></span></p><p class="quick">
		¶  <span class="tweet">iPad + autism = win! <a class="offsite" href="http://www.blogher.com/ipad-nearmiracle-my-son-autism">http://www.blogher.com/ipad-nearmiracle-my-son-autism</a> <a class="date" href="http://twitter.com/nedbat/status/16436738676">(Jun 18)</a></span></p><p class="quick">
		¶  <span class="tweet">About time we took a hard look at couch architecture: <a class="offsite" href="http://blog.buildllc.com/2010/04/couch-cushion-architecture-a-critical-analysis/">http://blog.buildllc.com/2010/04/couch-cushion-architecture-a-critical-analysis/</a> lol. <a class="date" href="http://twitter.com/nedbat/status/15786464717">(Jun 09)</a></span></p><p class="quick">
		¶  <span class="tweet">Pretty, in a geometry/typography kind of way: <a class="offsite" href="http://www.flickr.com/photos/quasimondo/4644498892/in/photostream/">http://www.flickr.com/photos/quasimondo/4644498892/in/photostream/</a> See the paintings in the stream too. <a class="date" href="http://twitter.com/nedbat/status/15514683980">(Jun 05)</a></span></p><p class="quick">
		¶  <span class="tweet">RT <a class="user" href="http://www.twitter.com/sgalineau">@sgalineau</a>: Once in a while Smashing Mag surprises: Arabic, East Asian and Indic calligraphy &amp; writing systems <a class="offsite" href="http://www.smashingmagazine.com/2010/05/18/the-beauty-of-typography-writing-systems-and-calligraphy-of-the-world/">http://www.smashingmagazine.com/2010/05/18/the-beauty-of-typography-writing-systems-and-calligraphy-of-the-world/</a> <a class="hashtag" href="http://www.twitter.com/#search?q=%23i18n">#i18n</a> <a class="date" href="http://twitter.com/nedbat/status/14971715248">(May 29)</a></span></p>
]]></description>
	</item>
	
</rdf:RDF>
