<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Eric Moritz</title><link href="../." rel="alternate"></link><link href=".././feeds/index.atom.xml" rel="self"></link><id>../.</id><updated>2012-02-17T17:46:00Z</updated><entry><title>Learning Python Logging</title><link href=".././learning-python-logging.html" rel="alternate"></link><updated>2012-02-17T17:46:00Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2012-02-17:.././learning-python-logging.html/</id><summary type="html">&lt;p&gt;The Python logging module is often a source of confusion with
developers.  Often logging is the final thought in a project. When we
are finishing up a project, the last thing we want to do is sift
through the &lt;a href="http://docs.python.org/library/logging.html"&gt;logging
documentation&lt;/a&gt; to figure
logging out. It is a perpetual cycle that results in some very bad
code.&lt;/p&gt;
&lt;p&gt;I am going to assume that you have some familiarity with the Python
logging module and the concept of logging levels, so I will only
address concepts with the logging module that has been a source of
confusion in colleagues.&lt;/p&gt;
&lt;h1 id="how_python_logging_should_be_used_in_modules"&gt;How Python logging should be used in modules&lt;/h1&gt;
&lt;p&gt;The first source of confusion with the Python logging module is the
question of how to create a logger.  This is probably the easiest part
of Python logging.  Here's how you do it:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt;
&lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;That is basically it.  That code will create a logger based on the
module's fully qualified name. So if we have a module called
&lt;code&gt;mypackage.module1.module2&lt;/code&gt;, that will be the logger's name.&lt;/p&gt;
&lt;p&gt;Keep in mind that &lt;code&gt;__name__&lt;/code&gt; is the string &lt;code&gt;"__main__"&lt;/code&gt; if
your Python file is ran as a script.  Other than that, that is all you
need to do.&lt;/p&gt;
&lt;p&gt;You do not have to worry about logging levels, or handlers or anything
in your modules.  How your loggers are configured is an application
level setting. Your modules have no reason to worry about how to
configure loggers.&lt;/p&gt;
&lt;h1 id="logger_names"&gt;Logger names&lt;/h1&gt;
&lt;p&gt;An often overlooked fact about loggers is that logger names are
hierarchical.  That is why I choose to use the module name as the
logger name. The hierarchy starts with the root logger and descends
from there.&lt;/p&gt;
&lt;p&gt;The root logger can be accessed by calling:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;  &lt;span class="n"&gt;rootLogger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Configuring the root logger will cascade down to the other loggers:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;  &lt;span class="n"&gt;rootLogger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The same is true if you access a parent of any other logger:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;  &lt;span class="n"&gt;appLogger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;myapp&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;appLogger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;All &lt;code&gt;myapp.*&lt;/code&gt; loggers will have the level &lt;code&gt;INFO&lt;/code&gt; as their default.&lt;/p&gt;
&lt;p&gt;Let us say that there are the following loggers used in our application:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;redis.connection&lt;/li&gt;
&lt;li&gt;mysql.connection&lt;/li&gt;
&lt;li&gt;mysql.query&lt;/li&gt;
&lt;li&gt;myapp.models.polls&lt;/li&gt;
&lt;li&gt;myapp.models.questions&lt;/li&gt;
&lt;li&gt;myapp.models.articles&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If we only wanted connection errors from our databases, query debug
information from MySQL, and warnings from myapp's models; we could
configure it as so:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ERROR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;mysql.query&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;myapp.models&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WARNING&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;That is it.  This accomplishes what I described. We set the default
level to ERROR which causes "redis.connection" and "mysql.connection"
to only emit ERROR and EXCEPTION level messages. We set the
"mysql.query" logger to DEBUG to emit query debug messages. Finally we
set the "myapp.models" logger to WARNING.&lt;/p&gt;
&lt;h1 id="configuring_python_loggers"&gt;Configuring Python loggers&lt;/h1&gt;
&lt;p&gt;I just showed you how to configure the level of a logger
pragmatically. Where should that code exist?  If you answered, "In the
module", I want you to get up, find the nearest blunt object, and hit
yourself with it. Do you not remember me saying that logging
configuration is an application level configuration?&lt;/p&gt;
&lt;p&gt;Here is a hypothetical script that uses a Redis connection.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ericmoritz/blog/blob/master/example-code/learn-python-logging/import_presidents1.py"&gt;import_presidents1.py&lt;/a&gt;:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;csv&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;redis&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrictRedis&lt;/span&gt;

&lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;./presidents.csv&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StrictRedis&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;president:&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now, let us assume that the redis module used a "redis.connection"
logger that logs a DEBUG level message whenever the redis client needs
to reconnect to the server. Here is a &lt;a href="https://github.com/ericmoritz/blog/blob/master/example-code/learn-python-logging/redis.py"&gt;mock Redis client&lt;/a&gt;
for this example.&lt;/p&gt;
&lt;p&gt;When we run the code as it is, no connection messages will be printed.&lt;/p&gt;
&lt;p&gt;Now, let us say our connection is flaky and we have to reconnect to
Redis often:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ericmoritz/blog/blob/master/example-code/learn-python-logging/import_presidents2.py"&gt;import_presidents2.py&lt;/a&gt;:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;csv&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;redis&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrictRedis&lt;/span&gt;

&lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;./presidents.csv&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StrictRedis&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;president:&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c"&gt;# simulate a disconnect every 3 operations&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;We can configure the "redis.connection" logger to output the
connection messages by configuring our script like so:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ericmoritz/blog/blob/master/example-code/learn-python-logging/import_presidents3.py"&gt;import_presidents3.py&lt;/a&gt;:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;csv&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;redis&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrictRedis&lt;/span&gt;

&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;redis.connection&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;./presidents.csv&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StrictRedis&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;president:&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c"&gt;# simulate a disconnect every 3 operations&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;For simplicity, we could have replaced:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;redis.connection&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;with:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;basicConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;a href="http://docs.python.org/library/logging.html#logging.basicConfig"&gt;logging.basicConfig()&lt;/a&gt;
is a really handy function.  I find myself using &lt;code&gt;basicConfig()&lt;/code&gt; often
because most of the time I simply want to output to &lt;code&gt;stderr&lt;/code&gt; or to a
single file rather than wanting complex routing using Handlers.&lt;/p&gt;
&lt;h1 id="what_are_handlers_and_formatters"&gt;What are Handlers and Formatters?&lt;/h1&gt;
&lt;p&gt;Apart from Loggers, there are three classes that are used to configure
an application's loggers: logging.Handler, logging.Formatter, and
logging.Filter.&lt;/p&gt;
&lt;p&gt;A Handler defines how a message is handled.  For instance, there is a
&lt;a href="http://docs.python.org/library/logging.handlers.html#streamhandler"&gt;StreamHandler&lt;/a&gt;
that logs messages to stderr.&lt;/p&gt;
&lt;p&gt;There are 13 standard Handlers defined in the
&lt;a href="http://docs.python.org/library/logging.handlers.html"&gt;logging.handlers&lt;/a&gt; 
module that will send messages to files, syslog, HTTP servers,
sockets, what have you.&lt;/p&gt;
&lt;p&gt;A Formatter is exactly what it sounds like.  It formats a
LogRecord. That's pretty much it.&lt;/p&gt;
&lt;p&gt;A Filter filters a LogRecord.  I have never needed one, so I will let
you define your own use case for one.&lt;/p&gt;
&lt;p&gt;Let us change our presidential import script to log any exceptions
that occur when importing:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ericmoritz/blog/blob/master/example-code/learn-python-logging/import_presidents4.py"&gt;import_presidents4.py&lt;/a&gt;:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;config&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;csv&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;redis&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrictRedis&lt;/span&gt;

&lt;span class="c"&gt;# We do not want to use __name__ here because __name__ is &amp;quot;__main__&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;presidents.importer&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;./presidents.csv&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StrictRedis&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;president:&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="c"&gt;# simulate a disconnect every 3 operations&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c"&gt;# simulate a failure&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;37&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;crook.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;dang it.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Notice that we added "import config", this will let us separate
configuration from implementation.  For our little one-off script,
having a config.py module is overkill and only exists to prove a
point.&lt;/p&gt;
&lt;p&gt;Here's the contents of &lt;a href="https://github.com/ericmoritz/blog/blob/master/example-code/learn-python-logging/config.py"&gt;config.py&lt;/a&gt;:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FileHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;StreamHandler&lt;/span&gt;

&lt;span class="n"&gt;default_formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;\
   &lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;%(asctime)s&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;%(levelname)s&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;%(message)s&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;console_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StreamHandler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;console_handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_formatter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;error_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FileHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;error.log&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;error_handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ERROR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;error_handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_formatter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;console_handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error_handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;An alternative way to configure your application's logger is to use
the
&lt;a href="http://docs.python.org/library/logging.config.html#logging.config.fileConfig"&gt;logging.config.fileConfig&lt;/a&gt;
to configure the loggers using an INI file.&lt;/p&gt;
&lt;p&gt;Here is the equivalent INI file for the configuration we previously
described using Python code:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ericmoritz/blog/blob/master/example-code/learn-python-logging/logging.ini"&gt;logging.ini&lt;/a&gt;:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="k"&gt;[formatters]&lt;/span&gt;
&lt;span class="na"&gt;keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;default&lt;/span&gt;

&lt;span class="k"&gt;[formatter_default]&lt;/span&gt;
&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;%(asctime)s:%(levelname)s:%(message)s&lt;/span&gt;
&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;logging.Formatter&lt;/span&gt;

&lt;span class="k"&gt;[handlers]&lt;/span&gt;
&lt;span class="na"&gt;keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;console, error_file&lt;/span&gt;

&lt;span class="k"&gt;[handler_console]&lt;/span&gt;
&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;logging.StreamHandler&lt;/span&gt;
&lt;span class="na"&gt;formatter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;tuple()&lt;/span&gt;

&lt;span class="k"&gt;[handler_error_file]&lt;/span&gt;
&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;logging.FileHandler&lt;/span&gt;
&lt;span class="na"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;ERROR&lt;/span&gt;
&lt;span class="na"&gt;formatter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;(&amp;quot;error.log&amp;quot;, &amp;quot;w&amp;quot;)&lt;/span&gt;

&lt;span class="k"&gt;[loggers]&lt;/span&gt;
&lt;span class="na"&gt;keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;root&lt;/span&gt;

&lt;span class="k"&gt;[logger_root]&lt;/span&gt;
&lt;span class="na"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;DEBUG&lt;/span&gt;
&lt;span class="na"&gt;formatter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="na"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;console,error_file&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;To use this file, let us modify our config.py.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ericmoritz/blog/blob/master/example-code/learn-python-logging/config_ini.py"&gt;config_ini.py&lt;/a&gt;:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging.config&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os.path&lt;/span&gt;
&lt;span class="n"&gt;LOGGING_CONF&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__file__&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                          &lt;span class="s"&gt;&amp;quot;logging.ini&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fileConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LOGGING_CONF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Finally, here's the updated import script:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ericmoritz/blog/blob/master/example-code/learn-python-logging/import_presidents5.py"&gt;import_presidents5.py&lt;/a&gt;:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="nb"&gt;import&lt;/span&gt; &lt;span class="n"&gt;config_ini&lt;/span&gt;
&lt;span class="nb"&gt;import&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;
&lt;span class="nb"&gt;import&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;
&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;redis&lt;/span&gt; &lt;span class="nb"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StrictRedis&lt;/span&gt;

&lt;span class="c1"&gt;# We do not want to use __name__ here because __name__ is &amp;quot;__main__&amp;quot;&lt;/span&gt;
&lt;span class="nb"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;presidents.importer&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;try:&lt;/span&gt;
    &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;./presidents.csv&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StrictRedis&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;president:%s&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;%&lt;/span&gt; &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="c1"&gt;# simulate a disconnect every 3 operations&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="nv"&gt;%&lt;/span&gt; &lt;span class="nv"&gt;3&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;# simulate a failure&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;37&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Crook.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;except:&lt;/span&gt;
    &lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Dang it.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;For some people INI files leave a bad taste is their mouth.  If you do
not like the taste of INI files, you can also configure the loggers
using a dictionary or with Python code.  It is up to you.&lt;/p&gt;
&lt;p&gt;There we have it. Python 2's built-in logging module is one of those
warts of the standard library that goes against the "Zen of Python"
but once you learn the non-obvious way the designers intended to be
used it becomes simple.&lt;/p&gt;
&lt;p&gt;I hope this helps clear up Python's logging module for you.&lt;/p&gt;
&lt;p&gt;Links&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ericmoritz/blog/tree/master/example-code/learn-python-logging"&gt;Example Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://news.ycombinator.com/item?id=3612786"&gt;Hacker News Discussion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</summary><category term="python"></category><category term="logging"></category></entry><entry><title>Books every self-taught computer scientist should read</title><link href=".././books-every-self-taught-computer-scientist-should-read.html" rel="alternate"></link><updated>2012-02-15T11:16:00Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2012-02-15:.././books-every-self-taught-computer-scientist-should-read.html/</id><summary type="html">&lt;p&gt;There are three books that I believe that every self-taught computer
scientist should read.  These are books that I often recommend to
smart junior developers that learned their knowledge by doing instead
of schooling. These are books that will close the gap for people that
fall into the category of "or equivalent experience" on a job posting.&lt;/p&gt;
&lt;h1 id="kr"&gt;K&amp;amp;R&lt;/h1&gt;
&lt;p&gt;The first book is the venerable &lt;a href="http://amzn.to/zUOn2s"&gt;C Programming
Language&lt;/a&gt; book. This book was written by Brian
Kernighan (an original Unix hacker) and Dennis Ritchie (the creator of
C) and because of that, it is affectionately known as the K&amp;amp;R book.&lt;/p&gt;
&lt;p&gt;The K&amp;amp;R book is invaluable for self-taught computer scientists for a
number of reasons.  Firstly, C is arguably the Latin of modern
programming languages. C++, ObjectiveC, Java, Perl, Ruby and Python all have
their roots in C.&lt;/p&gt;
&lt;p&gt;Second, the K&amp;amp;R book is written by the designer of the language. I
read it early in my career and found it very easy to read despite
being a manual for a programming language.&lt;/p&gt;
&lt;p&gt;This book provides a comprehensive look at all aspects of the C
language; from basic statement structure to pointers and elementary
data structures. The topics discussed in this book will provide you
with a good foundation of programming that is often missed when you
learn to program to get the job done.&lt;/p&gt;
&lt;h1 id="mastering_algorithms_in_c"&gt;Mastering Algorithms in C&lt;/h1&gt;
&lt;p&gt;Where the K&amp;amp;R book leaves off, the &lt;a href="http://amzn.to/yIiWbR"&gt;Mastering Algorithms in
C&lt;/a&gt; book picks up. In this book you will learn
the about Big-O notation, analysis of algorithm, recursion
and fundamental data structures.&lt;/p&gt;
&lt;p&gt;The beauty of this book is that it demonstrates these topics a
practical way that appeals to the self-taught computer
scientist. Instead of discussing these topics in only abstract terms,
the author walks you through the implementation of algorithms and data
structures in C.&lt;/p&gt;
&lt;p&gt;With this book you will be introduced to five fundamental data
structures in computer science and their application: Linked Lists,
Sets, Hash Tables, Trees, and Graphs.&lt;/p&gt;
&lt;p&gt;Once you have a solid grasp of these structures you will be able to
model solutions in those terms without having to reinvent the
wheel.  Do you need to model the relationships between people?  That's
a graph.  Do you need to model a hierarchy of sections on a website?
That's a tree.&lt;/p&gt;
&lt;h1 id="the_little_schemer"&gt;The Little Schemer&lt;/h1&gt;
&lt;p&gt;After you have a grasp of basic data structures, it is time to visit
the book that had a significant impact on the way I solve harder
problems.  This modest, but potent book is &lt;a href="http://amzn.to/z2FOF7"&gt;The Little
Schemer&lt;/a&gt;.  In the world of computer books it's
nearly a pamphlet at 195 pages, but just like its language of choice,
Scheme, it is concise and powerful.&lt;/p&gt;
&lt;p&gt;This book is a step-by-step guide on how to think like a computer
scientist.  A step-by-step guide may sound dry and boring but this
book is surprisingly full of humor.  I believe the authors took a page
from Douglas Adams and Monty Python when they wrote this book.&lt;/p&gt;
&lt;p&gt;The beauty about this book is not just its humor.  The beauty is in
its compounding process of teaching hard problems by starting with a
simple idea and then building on that idea to lead you step-by-step
onto more complex, abstract algorithms.&lt;/p&gt;
&lt;p&gt;Before you know it, you will be done with this book, thinking like a
computer scientist and all the while having a lot of fun in the
process.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; The &lt;a href="http://news.ycombinator.com/item?id=3595599"&gt;Hacker News discussion&lt;/a&gt; about this article provides a number of
alternative books to my list.&lt;br /&gt;
&lt;/p&gt;
&lt;h1 id="book_links"&gt;Book Links&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://amzn.to/zUOn2s"&gt;C Programming Language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://amzn.to/yIiWbR"&gt;Mastering Algorithms in C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://amzn.to/z2FOF7"&gt;The Little Schemer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</summary><category term="programming"></category><category term="computer science"></category><category term="self-taught"></category><category term="learning"></category><category term="books"></category></entry><entry><title>Why REST?</title><link href=".././why-rest.html" rel="alternate"></link><updated>2010-10-06T01:42:52Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2010-10-06:.././why-rest.html/</id><summary type="html">&lt;div class="section" id="preface"&gt;
&lt;h2&gt;Preface&lt;/h2&gt;
&lt;p&gt;I have to say before you read this that I only have a theoritical
understanding of how a web service benefits for being RESTful.  Most
of the topics I have explored are actually explained in Roy Fieldings
&lt;a class="reference external" href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm"&gt;section on REST&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the future, I would like to explore and test the assumptions I have
made and come up with evidence of thier truthiness.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="id1"&gt;
&lt;h2&gt;Why REST?&lt;/h2&gt;
&lt;p&gt;RESTful web services have been talked about ad-nauseum for a decade.
In fact, REST felt like such a hipster's architecture that I pawned it
off as a fad and waited this long to only begin to understand it.
Prior to understanding a technology, I have to ask myself, &amp;quot;What
motivates people to use this technology over others?&amp;quot;.  I think I may
have figured it out.&lt;/p&gt;
&lt;p&gt;The key to benefit of REST is the fact that it lives within the
confines of HTTP/1.1. Within this world a RESTful web service benefits
from all the solutions already solved by the HTTP/1.1 spec. A brief
list of standard HTTP solutions that benefit RESTful web services are
a uniform interface, caching, asynchronous processing, and security.&lt;/p&gt;
&lt;p&gt;A RESTful web service, in particular a resource oriented RESTful web
service, starts with a list of URLs that resources live on.
Resources are basically entities that live inside your application.  A
few examples could be a Blog entry, a Forum post, a page hit.
These entities don't have to map directly to your applications
database, they could merely be logical resources, such as a page hit.&lt;/p&gt;
&lt;p&gt;When a client sends a resource to the server, the server will act on
that resource.  If it's a blog post, it would store the blog post. If
it's a logical resource like a page hit, the service would simply
increment a counter somewhere.&lt;/p&gt;
&lt;p&gt;Each resource has a limited number of verbs that can be done to that
resource.  The primary verbs are GET, POST, PUT and DELETE.  There are
inherent restrictions to what these verbs can do. GET never writes on
the server; whereas POST/PUT and DELETE always write.  Due to these
restrictions you can do some simple optimizations to your web service
to help it scale.&lt;/p&gt;
&lt;p&gt;One of the limitations of SQL is replication and it is a hard problem
to solve.  In the most basic SQL replication architecture you have a
master server and a number of slave servers.  The master is written to
and the slaves are read from.  If your web service abides by the
HTTP/1.1 read/write restrictions based on the HTTP method, you can
easily route your database connection to your read slaves on GET and
your write master on POST, PUT, and DELETE.  This would be a more
complex solution in a GET based RPC service because every GET to a URL
could potentially write to the server.  A special router would have to
be written that have to know which procedure writes and which reads.
You can gain the same benefit with a custom RPC if you support POST
and limit your writes to just POST methods.&lt;/p&gt;
&lt;p&gt;Another problem already solved by HTTP/1.1 is caching.  If you can
assume that a GET will always read and if you know when resource was
last changed, you can send the Last-Modified header with the
response. The client is then responsible for caching the content and
storing the Last-Modified date.  The client will now send the
If-Modified-Since header with each new request for that resource.  If
the resource has not been modified, the service will respond with a
&amp;quot;304 Not Modified&amp;quot; with no information.  The service is done.  All it
had to do is check if the resource has been modified since the client
last requested the content.  There are other cache headers such as
ETag and Cache-Expires, but I think Last-Modified is the simplest to
support.&lt;/p&gt;
&lt;p&gt;The beauty of your web service supporting HTTP/1.1 caching is that
browsers already support it.  All AJAX calls to your service will only
return content if it's changed.  This makes every web browser out
there a replicated node for your service!  Instant horizontal scaling,
how's that feel?&lt;/p&gt;
&lt;p&gt;However, you should not trust clients to cache your content, so you
should implement a server side caching layer in front of your web
service.  Varnish can sit in front of your service and serve all
cached content from memory. If you want to get really distributed, you
can load balance an expandable pool of nginx servers caching content
into a expandable pool of memcached servers that sit in front of your
web service.  If you always send a Last-Modified header, these super
fast asynchronous servers can serve up cached content until the
content is changed.&lt;/p&gt;
&lt;p&gt;Sometimes it takes a long time to process a write and one solution is
to make that request asynchronous.  HTTP/1.1 has a standard response
code for supporting this, &amp;quot;202 Accepted&amp;quot;.  This status code tells the
client, &amp;quot;I have your content, I will process it when I can&amp;quot;.  This
allows you to respond in a timely matter.  The client knows that it's
write is being worked on.  Using a &amp;quot;202 Accepted&amp;quot; response in
conjunction with a request with a Last-Modified header allows the
client to poll the service for new content and the service will only
work as hard as it has to get the Last-Modified value.&lt;/p&gt;
&lt;p&gt;An example of asynchronous processing might be implemented in a search
engine.  Let's say your search engine indexer is time consuming.  It
parses out keywords, does named entity extraction, and searches for
addresses to geocode.  This would be a lot of things to do in one HTTP
request. Don't worry HTTP/1.1 lets you tell the client you've queue it
up.  When a new piece of content needs to be index, the service would
queue the document and respond with a &amp;quot;202 Accepted&amp;quot; and the client
can move on. Eventually the search engine will index the content and
the new content will show up in the search engine.&lt;/p&gt;
&lt;p&gt;For security, HTTP/1.1 defines support username/password based
authentication and SSL encryption so any web service has the ability
to use these technologies.&lt;/p&gt;
&lt;p&gt;A RESTful web service also has the benefit of having a limited number
of actions that can act on a resource.  This simplifies authorization
and access control tremendously.  If you want to restrict a client
from writing to a resource you can forbid a client from doing a PUT,
POST or DELETE on the URL.  You can even set up an OAuth based system
external to the web service that allows users to grant authorization
to external applications to do things on their behalf.&lt;/p&gt;
&lt;p&gt;For instance, a blogging system's OAuth based system could define a
permission of &amp;quot;Add/Update blog entries&amp;quot;, and this permission would allow
&lt;cite&gt;PUT /blog/entry/:slug&lt;/cite&gt; resources and &lt;cite&gt;POST /blog/entry/&lt;/cite&gt;.  The web service
does not have to worry about authorizing access to that resource because
a layer between the client and the service handles that for it.&lt;/p&gt;
&lt;p&gt;These are small number of solutions that HTTP/1.1 provides web
services if they abide by a RESTful resource oriented architecture and
make use of the functionality that HTTP/1.1 has already defined for
you.&lt;/p&gt;
&lt;p&gt;There are a number of off the shelf products that can benefit RESTful
web services such as caching servers, load balancers, and
authentication frameworks. These solutions would have to be
implemented within your web service or within your service's
overloaded HTTP protocol. One example of this reimplementation is
SOAP's WS-* suite of specifications.  Reinventing the wheel is rampant
in the web development world and this is mainly due to ignorance of
existing solutions.  There is no reason to keep reimplementing
functionality solved by HTTP on top of HTTP.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="REST"></category><category term="programming"></category></entry><entry><title>Announcing django-viewtools</title><link href=".././announcing-django-viewtools.html" rel="alternate"></link><updated>2009-02-17T18:30:37Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2009-02-17:.././announcing-django-viewtools.html/</id><summary type="html">&lt;p&gt;Hi, I'm announcing a project I have called &lt;a class="reference external" href="https://launchpad.net/django-viewtools"&gt;django-viewtools&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;django-viewtools provides a management command to help in debugging and profiling views&lt;/p&gt;
&lt;div class="section" id="overview"&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;django-viewtools provides a number of management commands for
debugging views.&lt;/p&gt;
&lt;p&gt;There are a number of flags that can be used when calling the view&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;-d, --debug: This sets settings.DEBUG to True before calling the&lt;/dt&gt;
&lt;dd&gt;view. This allows you to retrieve the content from a view in
production when settings.DEBUG is on&lt;/dd&gt;
&lt;dt&gt;-n, --no-debug: This sets settings.DEBUG to False, handy to see what&lt;/dt&gt;
&lt;dd&gt;will happen if DEBUG is turned off.&lt;/dd&gt;
&lt;dt&gt;--pdb: This starts PDB before the request is handled. Great for when&lt;/dt&gt;
&lt;dd&gt;you have a traceback email and want to set a breakpoint where it
occurs.&lt;/dd&gt;
&lt;dt&gt;--pm: This fires up PDB's post_mortum when an error occurs in the&lt;/dt&gt;
&lt;dd&gt;process of calling a view.&lt;/dd&gt;
&lt;dt&gt;--profile: This dumps a hotshot profile file to the location specified&lt;/dt&gt;
&lt;dd&gt;for profiling the performance of a view.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;-q, --quiet: Don't output the response of the view&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;-m, --mute: Turn off output through stdout and stderr, handy for noisy&lt;/dt&gt;
&lt;dd&gt;views with print statements everywhere.&lt;/dd&gt;
&lt;/dl&gt;
&lt;div class="section" id="example"&gt;
&lt;h3&gt;Example&lt;/h3&gt;
&lt;p&gt;So you have a traceback that gives you the following&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;/home/eric/Projects/django/env/django-1.0.2/lib/python2.5/site-packages/viewtools/views.py&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;py_error&lt;/span&gt;
  &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;This is an error&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;An you don't know why it's happening. Even worse, it's only happening
on your production server.&lt;/p&gt;
&lt;p&gt;Before django-viewtools, you only had one option in this scenario,
edit your production code, put some print statements or forced
assertion errors to peek into the code to see the problem.&lt;/p&gt;
&lt;p&gt;django-viewtools makes things a lot easier&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;eric&lt;/span&gt;&lt;span class="nd"&gt;@knoxpy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Projects&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;projects&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;viewtooltest&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="o"&gt;./&lt;/span&gt;&lt;span class="n"&gt;manage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="n"&gt;viewtools&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;pdb&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;py_error&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;eric&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Projects&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;python2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;viewtools&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;management&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;commands&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;viewtools&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;135&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;call_view&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;eric&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Projects&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;python2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;viewtools&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;
 &lt;span class="n"&gt;Breakpoint&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;eric&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Projects&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;python2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;viewtools&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;eric&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Projects&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;python2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;viewtools&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;py_error&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;This is an error&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;
   &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;
   &lt;span class="mi"&gt;2&lt;/span&gt;
   &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;py_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;This is an error&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="mi"&gt;5&lt;/span&gt;
   &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;db_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;select * from asotuhaosetuhaosethuasote&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;EOF&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;
 &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;WSGIRequest&lt;/span&gt;
 &lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;QueryDict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;QueryDict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;COOKIES&lt;/span&gt;&lt;span class="p"&gt;:{},&lt;/span&gt;
 &lt;span class="n"&gt;META&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;CONTENT_TYPE&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;text/html; charset=utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;&amp;#39;HTTP_COOKIE&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SimpleCookie&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;&amp;#39;PATH_INFO&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;u&amp;#39;/py_error/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;&amp;#39;QUERY_STRING&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;&amp;#39;REQUEST_METHOD&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;GET&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;&amp;#39;SCRIPT_NAME&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;u&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;&amp;#39;SERVER_NAME&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;testserver&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;&amp;#39;SERVER_PORT&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;80&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;&amp;#39;SERVER_PROTOCOL&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;HTTP/1.1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;&amp;#39;wsgi.errors&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;cStringIO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StringO&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x10a68b8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;&amp;#39;wsgi.input&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FakePayload&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x10ec150&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;&amp;#39;wsgi.multiprocess&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;&amp;#39;wsgi.multithread&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;&amp;#39;wsgi.run_once&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;&amp;#39;wsgi.url_scheme&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;http&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s"&gt;&amp;#39;wsgi.version&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Isn't that just great? I can see all the local variables in the view.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</summary><category term="debugging"></category><category term="django"></category><category term="python"></category></entry><entry><title>Python Encodings and Unicode</title><link href=".././python-encodings-and-unicode.html" rel="alternate"></link><updated>2008-11-21T20:24:43Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-11-21:.././python-encodings-and-unicode.html/</id><summary type="html">&lt;p&gt;I am sure there has been a number of explanations on Unicode and Python
but I'm going to do a little write up for my own sake.&lt;/p&gt;
&lt;div class="section" id="byte-streams-vs-unicode-objects"&gt;
&lt;h2&gt;Byte Streams VS Unicode Objects&lt;/h2&gt;
&lt;p&gt;Let's start by defining what a string in Python is.  When you use the
string type what you're actually doing is storing a string of bytes.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;[&lt;/span&gt;  &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;][&lt;/span&gt;  &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;][&lt;/span&gt;  &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;abc&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;97&lt;/span&gt; &lt;span class="p"&gt;][&lt;/span&gt; &lt;span class="mi"&gt;98&lt;/span&gt; &lt;span class="p"&gt;][&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;abc&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With this example, the string &amp;quot;abc&amp;quot; is a string of the bytes, 97, 98, 99 in
the ASCII table.  A deficiency of Python 2.X is that by default it treats
every string as ASCII. Unfortunately ASCII is lowest common denominator of
Latin type character sets.&lt;/p&gt;
&lt;p&gt;ASCII is the first 127 characters of a number
of character mappings. Character mappings such as windows-1252
(aka Latin-1, aka cp1252) and UTF-8 both have the same first 127
characters. You're safe mixing string encodings when every byte value in
your string is lower that 127.  However it's really dangerous to make that
assumption.  More on that later.&lt;/p&gt;
&lt;p&gt;A problem arises when you mix encodings that have bytes in them that are
greater than 126.  Let's take another string encoded as windows-1252.
Character map windows-1252 is a 8-bit character map so there can be a total
of 256 characters in the table.  The first 127 match ASCII, the second 127
are extra characters that the windows-1252 encoding defines.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="n"&gt;windows&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1252&lt;/span&gt; &lt;span class="n"&gt;encoded&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;looks&lt;/span&gt; &lt;span class="n"&gt;like&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;97&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;98&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;abc–&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Windows-1252 is still a string of bytes but do you see that the last byte is
greater than 126.  If Python attempts to decode that byte stream as the
default encoding ASCII, it will throw an error.  Let's see what happens
when Python tries to decode that string.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;abc&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;chr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="nb"&gt;repr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="s"&gt;&amp;#39;abc&lt;/span&gt;&lt;span class="se"&gt;\x96&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;u&amp;quot;Hello&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="err"&gt;?&lt;/span&gt;
&lt;span class="ne"&gt;UnicodeDecodeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;ASCII&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;codec&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;t decode byte 0x96 in position 3: ordinal not in range(128)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let's take another string encoded as UTF-8&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="n"&gt;encoded&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;looks&lt;/span&gt; &lt;span class="n"&gt;like&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;97&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;98&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;226&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;147&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;abc–&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0x61&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0x62&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0x63&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mh"&gt;0xe2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mh"&gt;0x80&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mh"&gt;0x93&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;abc-&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you pull up your handy dandy Unicode character table, you'll see that an
en dash is Unicode codepoint 8211 (0x2013).  That value is greater than
the 127 max of ASCII.  Hell it's greater than the max value that 1 byte
can store. Since 8211 (0x2013) is actually two bytes UTF-8 has to do some
magic to tell the system there are three bytes needed to store one
character.  Again, let's see what happens when Python attempts to use the
default ASCII encoding on a UTF-8 encoded string that has characters
greater than 126.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;abc&lt;/span&gt;&lt;span class="se"&gt;\xe2\x80\x93&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="nb"&gt;repr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="s"&gt;&amp;#39;abc&lt;/span&gt;&lt;span class="se"&gt;\xe2\x80\x93&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;u&amp;quot;Hello&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="err"&gt;?&lt;/span&gt;
&lt;span class="ne"&gt;UnicodeDecodeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;ASCII&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;codec&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;t decode byte 0xe2 in position 3: ordinal not in range(128)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, Python always defaults to ASCII.  It hits that fourth byte
which has a decimal value of 226 that's greater than 126 so Python
raises an error.  This is the trouble with mixing encodings.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="decoding-byte-streams"&gt;
&lt;h2&gt;Decoding Byte Streams&lt;/h2&gt;
&lt;p&gt;The term decoding can be confusing when you first start learning about
Unicode in Python.  You decode byte streams to make Unicode objects and
encode Unicode objects into byte streams.&lt;/p&gt;
&lt;p&gt;Python has to know how to decode a byte stream to Unicode.  When you take
a byte stream, you call it's &amp;quot;decode&amp;quot; method to create a Unicode object
from it.&lt;/p&gt;
&lt;p&gt;Your best bet is to decode byte streams to Unicode as early as possible.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;abc&lt;/span&gt;&lt;span class="se"&gt;\xe2\x80\x93&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;unicode&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;abc&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;chr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;windows-1252&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;span class="n"&gt;abc&lt;/span&gt;&lt;span class="err"&gt;–&lt;/span&gt;&lt;span class="n"&gt;abc&lt;/span&gt;&lt;span class="err"&gt;–&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="encoding-unicode-to-byte-streams"&gt;
&lt;h2&gt;Encoding Unicode to byte streams&lt;/h2&gt;
&lt;p&gt;Unicode objects are an encoding agnostic representation of text.  You
can't simply output a Unicode object.  It has to be turned into a byte
string before it's outputted.  Python will be nice enough to do it for
you however Python defaults to ASCII when encoding a Unicode object to
a byte stream, this default behavior can be the source of many headaches.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;u&amp;quot;abc&lt;/span&gt;&lt;span class="se"&gt;\u2013&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;
&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="ne"&gt;UnicodeEncodeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;ascii&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;codec&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;t encode character u&amp;#39;&lt;/span&gt;\&lt;span class="n"&gt;u2013&lt;/span&gt;&lt;span class="s"&gt;&amp;#39; in position 3: ordinal not in range(128)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;abc&lt;/span&gt;&lt;span class="err"&gt;–&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="using-the-codecs-module"&gt;
&lt;h2&gt;Using the codecs module&lt;/h2&gt;
&lt;p&gt;The codecs module can help out a lot when ingesting byte streams.  You can
open files with an encoding defined and what you read from that file will
automatically be converted to Unicode objects.&lt;/p&gt;
&lt;p&gt;Try this&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;codecs&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;codecs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/tmp/utf-8.txt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;w&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\u2013&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What that did was take an Unicode object and write it out as a utf-8 file.
You can do the same in the other direction.&lt;/p&gt;
&lt;p&gt;Try this&lt;/p&gt;
&lt;!-- sourcecode
 python

&gt;&gt;&gt; import urllib, codecs
&gt;&gt;&gt; fh = open("/tmp/google-com.html", "w")
&gt;&gt;&gt; fh.write(urllib.urlopen(url).read()) # Download Google's homepage to a file
&gt;&gt;&gt; fh.close()
&gt;&gt;&gt; fh = codecs.open("/tmp/google-com.html", "r", "utf-8")
&gt;&gt;&gt; type(fh.read(1))
&lt;type 'unicode'&gt; --&gt;
&lt;p&gt;When reading data from a file codecs.open create a file object that will
automatically convert the utf-8 encoded file into a Unicode object.&lt;/p&gt;
&lt;p&gt;Let's take the previous example and use the urllib stream directly&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.google.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;codecs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getreader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;unicode&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Reader&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;encodings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utf_8&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StreamReader&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0xa6f890&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;One-liner version&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;codecs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getreader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.google.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You have to be careful with the codecs module.  Whatever you pass to it
must be a Unicode object otherwise it will try to automatically decode the
byte stream as ASCII&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;abc&lt;/span&gt;&lt;span class="se"&gt;\xe2\x80\x93&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt; &lt;span class="c"&gt;# our &amp;quot;abc-&amp;quot; utf-8 string&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;codecs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/tmp/foo.txt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;w&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;/usr/lib/python2.5/codecs.py&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;638&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;/usr/lib/python2.5/codecs.py&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;303&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt;
  &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;consumed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="ne"&gt;UnicodeDecodeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;ascii&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;codec&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;t decode byte 0xe2 in position 3: ordinal not in range(128)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Crap, there Python goes again, trying to decode everything as ASCII.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="problems-with-slicing-up-utf-8-byte-streams"&gt;
&lt;h2&gt;Problems with slicing up UTF-8 byte streams&lt;/h2&gt;
&lt;p&gt;Since an UTF-8 encoded string is just a list of bytes, len() and slicing do not work correctly.  Take our string from before&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;97&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;98&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;226&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;147&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;abc–&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now do the following&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;my_utf8&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;abc–&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_utf8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What? It looks like 4 chars, but len is saying 6. This is because len is counting bytes not characters.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="nb"&gt;repr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_utf8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="s"&gt;&amp;#39;abc&lt;/span&gt;&lt;span class="se"&gt;\xe2\x80\x93&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now let's try slice the string&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;my_utf8&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c"&gt;# Get the last char&lt;/span&gt;
&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\x93&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Crap, that's the last byte, not the last char.&lt;/p&gt;
&lt;p&gt;To slice up UTF-8 correctly, your best bet is to decode the byte stream to create a Unicode object from it.  Then you can manipulate, count, whatever safely.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;my_unicode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;my_utf8&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="nb"&gt;repr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_unicode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="s"&gt;u&amp;#39;abc&lt;/span&gt;&lt;span class="se"&gt;\u2013&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_unicode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;my_unicode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="err"&gt;–&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="when-python-automatically-encodes-decodes"&gt;
&lt;h2&gt;When Python automatically encodes/decodes&lt;/h2&gt;
&lt;p&gt;There are a number of cases when Python could throw an error when it tries to
automatically encode or decode as ascii.&lt;/p&gt;
&lt;p&gt;The first case is when it tries to concat unicode and string values together&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;u&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;u&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\u2019&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="ne"&gt;UnicodeDecodeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;ascii&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;codec&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;t decode byte 0xe2 in position 0:   ordinal not in range(128)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The same will happen when you try to join a list.  Python will automatically
decode strings to unicode when there are both strings and unicode objects in
the list&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s"&gt;u&amp;quot;This string&lt;/span&gt;&lt;span class="se"&gt;\u2019&lt;/span&gt;&lt;span class="s"&gt;s unicode&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;u&amp;quot;This string&lt;/span&gt;&lt;span class="se"&gt;\u2019&lt;/span&gt;&lt;span class="s"&gt;s utf-8&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="ne"&gt;UnicodeDecodeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;ascii&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;codec&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;t decode byte 0xe2 in position 11:  ordinal not in range(128)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or when trying to format a string&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;quot;This string&lt;/span&gt;&lt;span class="se"&gt;\u2019&lt;/span&gt;&lt;span class="s"&gt;s unicode&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;u&amp;quot;This string&lt;/span&gt;&lt;span class="se"&gt;\u2019&lt;/span&gt;&lt;span class="s"&gt;s  utf-8&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),)&lt;/span&gt;
&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="ne"&gt;UnicodeDecodeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;ascii&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;codec&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;t decode byte 0xe2 in position 11: ordinal not in range(128)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Basically when you are mixing unicode and byte strings together, you can
cause an error.&lt;/p&gt;
&lt;p&gt;Take for instance you're taking a utf-8 file and then adding some text to it
that is an unicode object.  There can be a UnicodeDecodeError&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;utf-8-sample.txt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;buffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;buffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;quot;This string&lt;/span&gt;&lt;span class="se"&gt;\u2019&lt;/span&gt;&lt;span class="s"&gt;s unicode&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="nb"&gt;repr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;This file&lt;/span&gt;&lt;span class="se"&gt;\xe2\x80\x99&lt;/span&gt;&lt;span class="s"&gt;s got utf-8 in it&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;u&amp;#39;This string&lt;/span&gt;&lt;span class="se"&gt;\u2019&lt;/span&gt;&lt;span class="s"&gt;s unicode&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="ne"&gt;UnicodeDecodeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;ascii&amp;#39;&lt;/span&gt; &lt;span class="n"&gt;codec&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;t decode byte 0xe2 in position 9: ordinal not in range(128)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can fix that by using the codecs module to load in the file as unicode&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;codecs&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;utf-8-sample.txt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;r&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;buffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="nb"&gt;repr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;This file&lt;/span&gt;&lt;span class="se"&gt;\u2019&lt;/span&gt;&lt;span class="s"&gt;s got utf-8 in it&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;u&amp;#39;This string&lt;/span&gt;&lt;span class="se"&gt;\u2019&lt;/span&gt;&lt;span class="s"&gt;s unicode&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;buffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;quot;This string&lt;/span&gt;&lt;span class="se"&gt;\u2019&lt;/span&gt;&lt;span class="s"&gt;s unicode&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="n"&gt;utf&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;

&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="nb"&gt;unicode&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, the stream produced by codecs.open automatically converted the
string to unicode when the data is read.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="best-practices"&gt;
&lt;h2&gt;Best Practices&lt;/h2&gt;
&lt;blockquote&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Decode First, Encode Last&lt;/li&gt;
&lt;li&gt;When in doubt, encode as utf-8&lt;/li&gt;
&lt;li&gt;Use codecs with unicode objects to simplify things&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;Decode First means whenever taking byte stream input, decode
that input to Unicode as early as possible.  This will help prevent issues
where len() and slice malfunctions with utf-8 byte streams.&lt;/p&gt;
&lt;p&gt;Encode last means only encode to byte streams when you're ready to output
the text to something.  That output could be a file, a database, a socket,
whatever.  Only encode the Unicode objects when you're done with
them.  Encode last also means, don't let Python encode your Unicode
objects for you.  Python will use ASCII and your programs will crash.&lt;/p&gt;
&lt;p&gt;When in doubt, encode as UTF-8 means this:  Since UTF-8 can handle any Unicode
character, your best bet is to use it as opposed to window-1252 or god
forbid ASCII.&lt;/p&gt;
&lt;p&gt;The codecs module help you skip steps when ingesting streams such as files
or sockets.  Without the tools provided by the codecs module you'll have to
read the content of the files into byte streams and then decode those
byte streams into Unicode objects.&lt;/p&gt;
&lt;p&gt;The codecs module lets you read the bytes in and decode the bytes on the
fly getting your text into unicode objects much simplier and with less
overhead.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="explaining-utf-8"&gt;
&lt;h2&gt;Explaining UTF-8&lt;/h2&gt;
&lt;p&gt;This final section will give you primer on UTF-8, you can ignore this
unless you're a super-geek.&lt;/p&gt;
&lt;p&gt;With UTF-8, any byte between 127 and 255 are special.  Those bytes tell the
system that the bytes following the current byte are part of a multi-byte
sequence.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;Our&lt;/span&gt; &lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="n"&gt;encoded&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;looks&lt;/span&gt; &lt;span class="n"&gt;like&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;97&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;98&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;226&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;147&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;abc–&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The last three bytes are a UTF-8 multi-byte sequence.  If you convert the
first of the three, 226 to binary you can see what it looks like.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="mi"&gt;11100010&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first three bits tell the system that it is starting a three byte
sequence that is 226, 128, 147&lt;/p&gt;
&lt;p&gt;So taking the full sequence bytes&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="mi"&gt;11100010&lt;/span&gt; &lt;span class="mi"&gt;10000000&lt;/span&gt; &lt;span class="mi"&gt;10010011&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then you apply the following mask for three byte sequences (described
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/UTF-8#Description"&gt;here&lt;/a&gt;)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="mi"&gt;1110&lt;/span&gt;&lt;span class="n"&gt;xxxx&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="n"&gt;xxxxxx&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="n"&gt;xxxxxx&lt;/span&gt;
&lt;span class="n"&gt;XXXX0010&lt;/span&gt; &lt;span class="n"&gt;XX000000&lt;/span&gt; &lt;span class="n"&gt;XX010011&lt;/span&gt; &lt;span class="n"&gt;Remove&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="mo"&gt;0010&lt;/span&gt;       &lt;span class="mo"&gt;000000&lt;/span&gt;   &lt;span class="mo"&gt;010011&lt;/span&gt; &lt;span class="n"&gt;Collapse&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;
&lt;span class="mo"&gt;00100000&lt;/span&gt; &lt;span class="mo"&gt;00010011&lt;/span&gt;          &lt;span class="n"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;Unicode&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="mh"&gt;0x2013&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8211&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;–&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is a basic primer on how UTF-8, refer to the UTF-8 Wikipedia page for
greater detail&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category></entry><entry><title>PDB and django.test.client</title><link href=".././pdb-and-djangotestclient.html" rel="alternate"></link><updated>2008-11-17T00:14:57Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-11-17:.././pdb-and-djangotestclient.html/</id><summary type="html">&lt;p&gt;So you have a site in production and someone called you up that there is a bug
on the site.  Your template designer is trying to make a change to a template
and the change is isn't showing up on the site.  You make the change on you
development server and the change takes effect.  What is going wrong?&lt;/p&gt;
&lt;p&gt;You can do a number of things:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;You can call your template designer an idiot and figure it's a problem between the chair and the keyboard&lt;/li&gt;
&lt;li&gt;You can spend hours trying to figure out how the development server and the production server differ and bang
your head against the closest hard object until you find it.&lt;/li&gt;
&lt;li&gt;You can be a bad boy or girl and start changing code on the production server&lt;/li&gt;
&lt;li&gt;Or, you can use PDB and django.test.client to keep from spending all your hard earned money on hard liquor.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;The url in question is the homepage.  We have a simple view, all it does is
load a template.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.http&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;
 &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.template&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;

 &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
     &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;index.html&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;First we'll look at the index.html template that loads the page:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&lt;/span&gt;Hi&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Welcome to my site, click on a link below to go somewhere&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
{% include &amp;quot;includes/navigation.html&amp;quot; %}
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Something is wrong with the include tag, it's not loading the correct template.
Taking a quick look in they site templates shows that the template exists.
What's going on!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;ls pdb_example_templates/includes/
navigation.html  navigation.HTML~
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ok, there's something &amp;quot;wrong&amp;quot; with the {% include %} tag.  A quick glance at
django/template/loader_tags.py shows that the ContantIncludeNode loads the
template on line 102.  We're going to drill down the stack to find where the
template is actually loaded.  Line 102 has get_template, get_template is
defined in django.template.loader.  Open that up and find the definition of
get_template. We see that get_template calls find_template_source.  That's
up on the top of django.template.loader on line 47.  We know that there
is something funky with the loading of the template so we have our starting
point for PDB.&lt;/p&gt;
&lt;p&gt;Let's SSH into the production server and start playing. First, what we need
to do is create a simple little script to call the view. Let's call it wtf.py:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.test.client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Since we're using &lt;em&gt;./manage.py shell&lt;/em&gt; for this, we can't just do ol'
&lt;em&gt;if __name__ == '__main__'&lt;/em&gt; trick to run the script so we create a main()
function to call from interactive mode.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pdb_example&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;manage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="n"&gt;shell&lt;/span&gt;
&lt;span class="n"&gt;Python&lt;/span&gt; &lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r251&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;54863&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Mar&lt;/span&gt;  &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="mi"&gt;2008&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mo"&gt;03&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;39&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;copyright&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;credits&amp;quot;&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;license&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;information&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;IPython&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;An&lt;/span&gt; &lt;span class="n"&gt;enhanced&lt;/span&gt; &lt;span class="n"&gt;Interactive&lt;/span&gt; &lt;span class="n"&gt;Python&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;?&lt;/span&gt;       &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Introduction&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;IPython&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;s features.&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;magic&lt;/span&gt;  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Information&lt;/span&gt; &lt;span class="n"&gt;about&lt;/span&gt; &lt;span class="n"&gt;IPython&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;s &amp;#39;&lt;/span&gt;&lt;span class="n"&gt;magic&lt;/span&gt;&lt;span class="s"&gt;&amp;#39; &lt;/span&gt;&lt;span class="si"&gt;% f&lt;/span&gt;&lt;span class="s"&gt;unctions.&lt;/span&gt;
&lt;span class="n"&gt;help&lt;/span&gt;    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Python&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;s own help system.&lt;/span&gt;
&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Details&lt;/span&gt; &lt;span class="n"&gt;about&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;object&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;also&lt;/span&gt; &lt;span class="n"&gt;works&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;??&lt;/span&gt; &lt;span class="n"&gt;prints&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;wtf&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;wtf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Hi&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Welcome&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;my&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;click&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt; &lt;span class="n"&gt;below&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;go&lt;/span&gt; &lt;span class="n"&gt;somewhere&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/blog/&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;My&lt;/span&gt; &lt;span class="n"&gt;Blog&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.flickr.com/photos/ericmoritz/&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;My&lt;/span&gt; &lt;span class="n"&gt;Photos&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ok our little script calls up the correct view and generates the incorrect
content, good.  Next step, get PDB into the mix.&lt;/p&gt;
&lt;p&gt;There are two ways of doing this, the python way and the ipython way.  I'll
do it the python way first for all you dummies that aren't using ipython yet
(what are you waiting for?).  Edit wtf.py and add &lt;em&gt;import pdb; pdb.set_trace()&lt;/em&gt;
right before the &lt;em&gt;c.get(&amp;quot;/&amp;quot;)&lt;/em&gt; line.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.test.client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pdb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;pdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_trace&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will drop you into pdb before the view is called so you can set a
breakpoint.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;find_template_source&lt;/em&gt; function does some module level caching stuff in
the beginning. The guts that we want is near the bottom on line 67.&lt;/p&gt;
&lt;p&gt;So let's fire up &lt;em&gt;manage.py shell&lt;/em&gt; and set a breakpoint.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pdb_example&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;manage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="n"&gt;shell&lt;/span&gt;
&lt;span class="n"&gt;Python&lt;/span&gt; &lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r251&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;54863&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Mar&lt;/span&gt;  &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="mi"&gt;2008&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mo"&gt;03&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;39&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;copyright&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;credits&amp;quot;&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;license&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;information&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;IPython&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;An&lt;/span&gt; &lt;span class="n"&gt;enhanced&lt;/span&gt; &lt;span class="n"&gt;Interactive&lt;/span&gt; &lt;span class="n"&gt;Python&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;?&lt;/span&gt;       &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Introduction&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;IPython&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;s features.&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;magic&lt;/span&gt;  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Information&lt;/span&gt; &lt;span class="n"&gt;about&lt;/span&gt; &lt;span class="n"&gt;IPython&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;s &amp;#39;&lt;/span&gt;&lt;span class="n"&gt;magic&lt;/span&gt;&lt;span class="s"&gt;&amp;#39; &lt;/span&gt;&lt;span class="si"&gt;% f&lt;/span&gt;&lt;span class="s"&gt;unctions.&lt;/span&gt;
&lt;span class="n"&gt;help&lt;/span&gt;    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Python&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;s own help system.&lt;/span&gt;
&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Details&lt;/span&gt; &lt;span class="n"&gt;about&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;object&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;also&lt;/span&gt; &lt;span class="n"&gt;works&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;??&lt;/span&gt; &lt;span class="n"&gt;prints&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;wtf&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;wtf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;eric&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;wtf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;
&lt;span class="n"&gt;Breakpoint&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;cont&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;find_template_source&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;template_source_loaders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;
 &lt;span class="mi"&gt;62&lt;/span&gt;                     &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;warnings&lt;/span&gt;
 &lt;span class="mi"&gt;63&lt;/span&gt;                     &lt;span class="n"&gt;warnings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Your TEMPLATE_LOADERS setting includes &lt;/span&gt;&lt;span class="si"&gt;%r&lt;/span&gt;&lt;span class="s"&gt;, but your Python installation doesn&amp;#39;t support that type of template loading. Consider removing that line from TEMPLATE_LOADERS.&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="mi"&gt;64&lt;/span&gt;                 &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="mi"&gt;65&lt;/span&gt;                     &lt;span class="n"&gt;loaders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="mi"&gt;66&lt;/span&gt;             &lt;span class="n"&gt;template_source_loaders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loaders&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="mi"&gt;67&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;     &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;template_source_loaders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="mi"&gt;68&lt;/span&gt;             &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="mi"&gt;69&lt;/span&gt;                 &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;display_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dirs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="mi"&gt;70&lt;/span&gt;                 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;make_origin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;display_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dirs&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
 &lt;span class="mi"&gt;71&lt;/span&gt;             &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;TemplateDoesNotExist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="mi"&gt;72&lt;/span&gt;                 &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;index.html&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Whoops, we're going to go through the load of every template and probably start
drinking.  Let's make our breakpoint more specific.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;clear&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;Deleted&lt;/span&gt; &lt;span class="n"&gt;breakpoint&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;includes/navigation.html&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;Breakpoint&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ok, now our breakpoint will only break if the name of the template being loaded
is called &lt;em&gt;includes/navigation.html&lt;/em&gt;. Let's continue.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;find_template_source&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;template_source_loaders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="s"&gt;u&amp;#39;includes/navigation.html&amp;#39;&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;
 &lt;span class="mi"&gt;62&lt;/span&gt;                     &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;warnings&lt;/span&gt;
 &lt;span class="mi"&gt;63&lt;/span&gt;                     &lt;span class="n"&gt;warnings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Your TEMPLATE_LOADERS setting includes &lt;/span&gt;&lt;span class="si"&gt;%r&lt;/span&gt;&lt;span class="s"&gt;, but your Python installation doesn&amp;#39;t support that type of template loading. Consider removing that line from TEMPLATE_LOADERS.&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="mi"&gt;64&lt;/span&gt;                 &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="mi"&gt;65&lt;/span&gt;                     &lt;span class="n"&gt;loaders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="mi"&gt;66&lt;/span&gt;             &lt;span class="n"&gt;template_source_loaders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loaders&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="mi"&gt;67&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;     &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;template_source_loaders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="mi"&gt;68&lt;/span&gt;             &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="mi"&gt;69&lt;/span&gt;                 &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;display_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dirs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="mi"&gt;70&lt;/span&gt;                 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;make_origin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;display_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dirs&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
 &lt;span class="mi"&gt;71&lt;/span&gt;             &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;TemplateDoesNotExist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="mi"&gt;72&lt;/span&gt;                 &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cool, we've successfully broke at the correct line with the correct template
name.  Let's walk through the code.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;68&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;find_template_source&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;69&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;find_template_source&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;display_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dirs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we're positioned right before the loader is called. Now we'll use the
&lt;em&gt;step&lt;/em&gt; command to step into that function.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt;
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;Call&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;loaders&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;app_directories&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;load_template_source&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;load_template_source&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;template_dirs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;
 &lt;span class="mi"&gt;40&lt;/span&gt;                 &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;safe_join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;template_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="mi"&gt;41&lt;/span&gt;             &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="mi"&gt;42&lt;/span&gt;                 &lt;span class="c"&gt;# The joined path was located outside of template_dir.&lt;/span&gt;
 &lt;span class="mi"&gt;43&lt;/span&gt;                 &lt;span class="k"&gt;pass&lt;/span&gt;
 &lt;span class="mi"&gt;44&lt;/span&gt;
 &lt;span class="mi"&gt;45&lt;/span&gt;  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;load_template_source&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;template_dirs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
 &lt;span class="mi"&gt;46&lt;/span&gt;         &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;get_template_sources&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;template_dirs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
 &lt;span class="mi"&gt;47&lt;/span&gt;             &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="mi"&gt;48&lt;/span&gt;                 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FILE_CHARSET&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="mi"&gt;49&lt;/span&gt;             &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;IOError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="mi"&gt;50&lt;/span&gt;                 &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We're now at the start of the &lt;em&gt;load_template_source&lt;/em&gt; function.  Let's walk
through this function to see if it finds a template.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;loaders&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;app_directories&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;load_template_source&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;get_template_sources&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;template_dirs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;loaders&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;app_directories&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;load_template_source&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="s"&gt;u&amp;#39;/home/eric/src/pdb_example/example/templates/includes/navigation.html&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ok, the first template it's trying to load is the template in our app's
templates folder.  This shouldn't work, so let's continue to verify that our
assumption is correct.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;loaders&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;app_directories&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;load_template_source&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FILE_CHARSET&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;Return&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;loaders&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;app_directories&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;load_template_source&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;&amp;lt;ul&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;...n&amp;lt;/ul&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;u&amp;#39;/home/...ion.html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FILE_CHARSET&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;versions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;find_template_source&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;make_origin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;display_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dirs&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;
 &lt;span class="mi"&gt;65&lt;/span&gt;                     &lt;span class="n"&gt;loaders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="mi"&gt;66&lt;/span&gt;             &lt;span class="n"&gt;template_source_loaders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loaders&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="mi"&gt;67&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;       &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;template_source_loaders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="mi"&gt;68&lt;/span&gt;             &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="mi"&gt;69&lt;/span&gt;                 &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;display_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dirs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="mi"&gt;70&lt;/span&gt;  &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;             &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;make_origin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;display_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dirs&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
 &lt;span class="mi"&gt;71&lt;/span&gt;             &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;TemplateDoesNotExist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="mi"&gt;72&lt;/span&gt;                 &lt;span class="k"&gt;pass&lt;/span&gt;
 &lt;span class="mi"&gt;73&lt;/span&gt;         &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;TemplateDoesNotExist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
 &lt;span class="mi"&gt;74&lt;/span&gt;
 &lt;span class="mi"&gt;75&lt;/span&gt;     &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template_name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="s"&gt;u&amp;#39;&amp;lt;ul&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;  &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/blog/&amp;quot;&amp;gt;My Blog&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;  &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;http://www.flickr.com/photos/ericmoritz/&amp;quot;&amp;gt;My Photos&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We've walked through the loader's function and have returned with a
success.  However, this is the app_directories loader, the site should of used
the filesystem loader first because the template designer has his own
set of templates that are outside of the django project code.&lt;/p&gt;
&lt;p&gt;Let's look at our TEMPLATE_LOADERS setting to see what's up&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# List of callables that know how to import templates from various sources.&lt;/span&gt;
&lt;span class="n"&gt;TEMPLATE_LOADERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.template.loaders.app_directories.load_template_source&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django.template.loaders.filesystem.load_template_source&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Doh!  Our loaders are backward.  Who did that?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;svn&lt;/span&gt; &lt;span class="n"&gt;blame&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="n"&gt;newman&lt;/span&gt; &lt;span class="n"&gt;TEMPLATE_LOADERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="n"&gt;newman&lt;/span&gt;     &lt;span class="s"&gt;&amp;#39;django.template.loaders.app_directories.load_template_source&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="n"&gt;newman&lt;/span&gt;     &lt;span class="s"&gt;&amp;#39;django.template.loaders.filesystem.load_template_source&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="n"&gt;newman&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Newman! Hang on, I have to go smack my other programmer in the back of the
head...&lt;/p&gt;
&lt;p&gt;Now to use pdb with ipython with all the benefits of ipython
(colors, tab completion, etc). There is a module &lt;a class="reference external" href="http://trac.gotcha.python-hosting.com/file/bubblenet/pythoncode/ipdb/ipdb/__init__.py?format=txt"&gt;here&lt;/a&gt;
that will help you out.  Just download that script as ipdb.py in the same
folder as wtf.py (or somewhere in sys.path)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl http://trac.gotcha.python-hosting.com/file/bubblenet/pythoncode/ipdb/ipdb/__init__.py?format&lt;span class="o"&gt;=&lt;/span&gt;txt &amp;gt; ipdb.py
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then change your code like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.test.client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;
  &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;ipdb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;ipdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_trace&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, there you have it.  How to use pdb and django.test.client to solve bugs
in production without editing the code and potentially disrupting service.&lt;/p&gt;
</summary><category term="debugging"></category><category term="django"></category><category term="pdb"></category><category term="python"></category></entry><entry><title>Find the number of days until next day of week</title><link href=".././find-the-number-of-days-until-next-day-of-week.html" rel="alternate"></link><updated>2008-07-10T23:03:29Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-07-10:.././find-the-number-of-days-until-next-day-of-week.html/</id><summary type="html">&lt;p&gt;I've had to figure this out before and I forgot it.  Here it is preserved&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;daysuntilnextdow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
     &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;Determine how many days until the next Day of week&lt;/span&gt;

&lt;span class="sd"&gt;     start: The day of the week to start from&lt;/span&gt;
&lt;span class="sd"&gt;     next: The day of the week to go to&lt;/span&gt;

&lt;span class="sd"&gt;     returns a number of days until the next day of week&lt;/span&gt;

&lt;span class="sd"&gt;     Note, start is inclusive, so if next is the same day,&lt;/span&gt;
&lt;span class="sd"&gt;     you will receive 0&lt;/span&gt;

&lt;span class="sd"&gt;     Example:&lt;/span&gt;

&lt;span class="sd"&gt;     &amp;gt;&amp;gt; start = 0 # Sunday&lt;/span&gt;
&lt;span class="sd"&gt;     &amp;gt;&amp;gt; next = 1 # Monday&lt;/span&gt;
&lt;span class="sd"&gt;     &amp;gt;&amp;gt; daysuntilnextdow(start, next)&lt;/span&gt;
&lt;span class="sd"&gt;     1&lt;/span&gt;
&lt;span class="sd"&gt;     &amp;gt;&amp;gt; start = 3 # Wednesday&lt;/span&gt;
&lt;span class="sd"&gt;     &amp;gt;&amp;gt; next = 0 # Sunday&lt;/span&gt;
&lt;span class="sd"&gt;     &amp;gt;&amp;gt; daysuntilnextdow(start, next)&lt;/span&gt;
&lt;span class="sd"&gt;     4&lt;/span&gt;
&lt;span class="sd"&gt;     &amp;gt;&amp;gt; start = 0 # Sunday&lt;/span&gt;
&lt;span class="sd"&gt;     &amp;gt;&amp;gt; next = 0 # Sunday&lt;/span&gt;
&lt;span class="sd"&gt;     &amp;gt;&amp;gt; daysuntilnextdow(start, next)&lt;/span&gt;
&lt;span class="sd"&gt;     0&lt;/span&gt;
&lt;span class="sd"&gt;     &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
</summary><category term="date"></category><category term="python"></category></entry><entry><title>Understanding PSQL's MVCC</title><link href=".././understanding-psqls-mvcc.html" rel="alternate"></link><updated>2008-06-18T16:40:54Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-06-18:.././understanding-psqls-mvcc.html/</id><summary type="html">&lt;div class="section" id="id1"&gt;
&lt;h2&gt;Understanding PSQL's MVCC&lt;/h2&gt;
&lt;p&gt;PostgresSQL implements something called &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Multiversion_concurrency_control"&gt;MVCC&lt;/a&gt;.  Which alleviates the need for a Read-Lock in many cases.
However when &lt;a class="reference external" href="http://www.hackermojo.com"&gt;Glenn Franxman&lt;/a&gt; and I were trying to figure out how this works we were having trouble understanding
it completely.&lt;/p&gt;
&lt;p&gt;If you ask about &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Multiversion_concurrency_control"&gt;MVCC&lt;/a&gt; in the #postgres irc channel on Freenode, they will direct you to the following three
links&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Multiversion_concurrency_control"&gt;http://en.wikipedia.org/wiki/Multiversion_concurrency_control&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.developer.com/net/vb/article.php/877181"&gt;http://www.developer.com/net/vb/article.php/877181&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.postgresql.org/docs/current/static/mvcc.html"&gt;http://www.postgresql.org/docs/current/static/mvcc.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;With SQL there are &lt;a class="reference external" href="http://www.postgresql.org/docs/current/static/transaction-iso.html#MVCC-ISOLEVEL-TABLE"&gt;four transaction isolation levels&lt;/a&gt;, unfortunately the Wikipedia &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Multiversion_concurrency_control"&gt;entry&lt;/a&gt; only describes one, serializable. So relying on
the Wikipedia documentation to describe how Postgres' opperates is not completely accurate.  I think that internally Postgres may operate the
way that the Wikipedia entry describes, but uses a write-lock to emulate a &amp;quot;Read Commit&amp;quot; isolation level to prevent the transaction abort that
would normally occur by one transaction writing and comitting data .
I don't know if that's true or not.&lt;/p&gt;
&lt;p&gt;Another confusing bit about Postgres is that Postgres only implements two levels, &amp;quot;Read Committed&amp;quot; and &amp;quot;Serializable&amp;quot; even though
you can set the other isolation levels.  In the documentation, the &lt;a class="reference external" href="http://www.postgresql.org/docs/current/static/transaction-iso.html#MVCC-ISOLEVEL-TABLE"&gt;four transaction isolation levels&lt;/a&gt; refers to the SQL standard
and not Postgres' actually functionality.&lt;/p&gt;
&lt;p&gt;So when you look at the &lt;a class="reference external" href="http://www.postgresql.org/docs/current/static/transaction-iso.html#MVCC-ISOLEVEL-TABLE"&gt;four transaction isolation levels&lt;/a&gt;, you'll notice that it says that a dirty
read is possible if you set the isolation level to &amp;quot;READ UNCOMMITTED&amp;quot;, however because &amp;quot;READ UNCOMMITTED&amp;quot; is the
same as &amp;quot;READ COMMITTED&amp;quot; internally in Postgres, you can never get a dirty read even if you set the isolation level
to READ UNCOMMITTED.  That's ok because, as the documentation states, &amp;quot;the four isolation levels only define which phenomena must not
happen, they do not define which phenomena must happen.&amp;quot;&lt;/p&gt;
&lt;p&gt;I'll run some examples of concurrent transaction to show you how the four levels act.&lt;/p&gt;
&lt;div class="section" id="read-committed"&gt;
&lt;h3&gt;Read Committed&lt;/h3&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="46%" /&gt;
&lt;col width="54%" /&gt;
&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;Transaction 1&lt;/td&gt;
&lt;td&gt;Transaction 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="k"&gt;ISOLATION&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;-#&lt;/span&gt; &lt;span class="k"&gt;READ&lt;/span&gt; &lt;span class="k"&gt;COMMITTED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="k"&gt;ISOLATION&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;-#&lt;/span&gt; &lt;span class="k"&gt;READ&lt;/span&gt; &lt;span class="k"&gt;COMMITTED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;update&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;update&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;-- 7&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="c1"&gt;-- blocked until the other commited&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section" id="read-uncommitted"&gt;
&lt;h3&gt;Read Uncommitted&lt;/h3&gt;
&lt;p&gt;With &lt;em&gt;Read Uncommited&lt;/em&gt; I observed the same behavior as &lt;em&gt;Read Commited&lt;/em&gt;.
This reflects the &lt;a class="reference external" href="http://www.postgresql.org/docs/current/static/transaction-iso.html"&gt;transaction documentation&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
But internally, there are only two distinct isolation levels, which correspond to the levels Read Committed
and Serializable. When you select the level Read Uncommitted you really get Read Committed, and when you select
Repeatable Read you really get Serializable, so the actual isolation level might be stricter than what you select.
&lt;/pre&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="46%" /&gt;
&lt;col width="54%" /&gt;
&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;Transaction 1&lt;/td&gt;
&lt;td&gt;Transaction 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="k"&gt;ISOLATION&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;-#&lt;/span&gt; &lt;span class="k"&gt;READ&lt;/span&gt; &lt;span class="k"&gt;UNCOMMITTED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="k"&gt;ISOLATION&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;-#&lt;/span&gt; &lt;span class="k"&gt;READ&lt;/span&gt; &lt;span class="k"&gt;UNCOMMITTED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;-- 1&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;-- 2.&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
 &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;update&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;update&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="c1"&gt;-- blocked until the other commited&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section" id="serializable"&gt;
&lt;h3&gt;SERIALIZABLE&lt;/h3&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="46%" /&gt;
&lt;col width="54%" /&gt;
&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;Transaction 1&lt;/td&gt;
&lt;td&gt;Transaction 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="k"&gt;ISOLATION&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;-#&lt;/span&gt; &lt;span class="k"&gt;SERIALIZABLE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="k"&gt;ISOLATION&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;-#&lt;/span&gt; &lt;span class="k"&gt;SERIALIZABLE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;update&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;update&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;ERROR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;could&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="n"&gt;serialize&lt;/span&gt; &lt;span class="k"&gt;access&lt;/span&gt; &lt;span class="n"&gt;due&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt;
&lt;span class="n"&gt;concurrent&lt;/span&gt; &lt;span class="k"&gt;update&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;ERROR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="k"&gt;current&lt;/span&gt; &lt;span class="n"&gt;transaction&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;aborted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;commands&lt;/span&gt;
&lt;span class="n"&gt;ignored&lt;/span&gt; &lt;span class="k"&gt;until&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;transaction&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;ROLLBACK&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section" id="repeatable-read"&gt;
&lt;h3&gt;Repeatable Read&lt;/h3&gt;
&lt;p&gt;Refering to the same paragraph in the &lt;a class="reference external" href="http://www.postgresql.org/docs/current/static/transaction-iso.html"&gt;transaction documentation&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
But internally, there are only two distinct isolation levels, which correspond to the levels Read Committed
and Serializable. When you select the level Read Uncommitted you really get Read Committed, and when you select
Repeatable Read you really get Serializable, so the actual isolation level might be stricter than what you select.
&amp;lt;http://www.postgresql.org/docs/current/static/transaction-iso.html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Repeatable Read&lt;/em&gt; is the same as Serializable.&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="46%" /&gt;
&lt;col width="54%" /&gt;
&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;Transaction 1&lt;/td&gt;
&lt;td&gt;Transaction 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="k"&gt;ISOLATION&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;-#&lt;/span&gt; &lt;span class="k"&gt;REPEATABLE&lt;/span&gt; &lt;span class="k"&gt;READ&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="k"&gt;ISOLATION&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;-#&lt;/span&gt; &lt;span class="k"&gt;REPEATABLE&lt;/span&gt; &lt;span class="k"&gt;READ&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;update&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;update&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;ERROR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;could&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="n"&gt;serialize&lt;/span&gt; &lt;span class="k"&gt;access&lt;/span&gt; &lt;span class="n"&gt;due&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt;
&lt;span class="n"&gt;concurrent&lt;/span&gt; &lt;span class="k"&gt;update&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;ERROR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="k"&gt;current&lt;/span&gt; &lt;span class="n"&gt;transaction&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;aborted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;commands&lt;/span&gt;
&lt;span class="n"&gt;ignored&lt;/span&gt; &lt;span class="k"&gt;until&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;transaction&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;ROLLBACK&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="what-is-possible-in-isolation-levels"&gt;
&lt;h2&gt;What is possible in Isolation Levels&lt;/h2&gt;
&lt;p&gt;So, in the &lt;a class="reference external" href="http://www.postgresql.org/docs/current/static/transaction-iso.html#MVCC-ISOLEVEL-TABLE"&gt;four transaction isolation levels&lt;/a&gt; table, it describes what is possible in the different
isolation levels.  Since I've demostrated that there are only two isolation levels in Postgresql.  I'll
demostrate the two read phenomena that could happen in both Serializable and Read Committed.&lt;/p&gt;
&lt;p&gt;Let me explain what those two phenomena are. Here is a good explanation of &lt;a class="reference external" href="http://www.adp-gmbh.ch/ora/misc/isolation_level.html"&gt;read phenomena&lt;/a&gt;.  I'm
just simply repeating what is stated at that link&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;Nonrepeatable Read&lt;/dt&gt;
&lt;dd&gt;S1 reads data which is later changed and commited by S2. If S1 reads the same data again (after S2's commit)
and finds it to have changed or to be deleted (according to S2's changes), this is called a non-repeatable
read. It is called non-repeatable because the same select statement doesn't return the same data
(within the same transaction).&lt;/dd&gt;
&lt;dt&gt;Phantom read&lt;/dt&gt;
&lt;dd&gt;S1 reads data (select) with a specific where condition. After this read, S2 inserts some data that meets
the S1's where condition and commits the inserted data. When S1 issues a select statement with the same
where condition, it finds new records. It is called phantom read because the new records seem to be of
phantom origin. A phantom read is thus a special case of a non-repeatable read.&lt;/dd&gt;
&lt;/dl&gt;
&lt;div class="section" id="read-committed-nonrepeatable-read-attempt"&gt;
&lt;h3&gt;Read Committed / Nonrepeatable Read Attempt&lt;/h3&gt;
&lt;p&gt;The SQL Standard says that with a Read Committed Isolation level, a &amp;quot;Nonrepeatable Read&amp;quot; is possible.
Here is my attempt in proving that assertion.&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="46%" /&gt;
&lt;col width="54%" /&gt;
&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;Transaction 1&lt;/td&gt;
&lt;td&gt;Transaction 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="k"&gt;ISOLATION&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;-#&lt;/span&gt; &lt;span class="k"&gt;READ&lt;/span&gt; &lt;span class="k"&gt;COMMITTED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="k"&gt;ISOLATION&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;-#&lt;/span&gt; &lt;span class="k"&gt;READ&lt;/span&gt; &lt;span class="k"&gt;COMMITTED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;update&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;--&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;--&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;p class="last"&gt;This is a Nonrepeatable Read. Because the data has
change while inside a transaction.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section" id="read-committed-phantom-read-attempt"&gt;
&lt;h3&gt;Read Committed / Phantom Read Attempt&lt;/h3&gt;
&lt;p&gt;The SQL Standard says that with a Read Committed Isolation level, a &amp;quot;Phantom Read&amp;quot; is possible.
Here is my attempt in proving that assertion.&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="46%" /&gt;
&lt;col width="54%" /&gt;
&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="k"&gt;ISOLATION&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;-#&lt;/span&gt; &lt;span class="k"&gt;READ&lt;/span&gt; &lt;span class="k"&gt;COMMITTED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="k"&gt;ISOLATION&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;-#&lt;/span&gt; &lt;span class="k"&gt;READ&lt;/span&gt; &lt;span class="k"&gt;COMMITTED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;
  &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;
   &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
 &lt;span class="c1"&gt;----+---&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;insert&lt;/span&gt; &lt;span class="k"&gt;into&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="k"&gt;values&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;
   &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
 &lt;span class="c1"&gt;----+---&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;p class="last"&gt;This is a phantom read because the row poofed into
existance inside the transaction when it didn't
exist before.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section" id="serializable-nonrepeatable-read-attempt"&gt;
&lt;h3&gt;Serializable / Nonrepeatable Read Attempt&lt;/h3&gt;
&lt;p&gt;The SQL Standard says that with a Serializable Isolation level, a &amp;quot;Nonrepeatable Read&amp;quot; is &lt;strong&gt;not possible&lt;/strong&gt;.
Here is my attempt in proving that assertion.&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="46%" /&gt;
&lt;col width="54%" /&gt;
&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;Transaction 1&lt;/td&gt;
&lt;td&gt;Transaction 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="k"&gt;ISOLATION&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;-#&lt;/span&gt; &lt;span class="k"&gt;SERIALIZABLE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="k"&gt;ISOLATION&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;-#&lt;/span&gt; &lt;span class="k"&gt;SERIALIZABLE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;update&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;--&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;--&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;p class="last"&gt;This is not a Nonrepeatable Read. Because the data
did not change while inside a transaction.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section" id="id2"&gt;
&lt;h3&gt;Read Committed / Phantom Read Attempt&lt;/h3&gt;
&lt;p&gt;The SQL Standard says that with a Read Committed Isolation level, a &amp;quot;Phantom Read&amp;quot; is possible.
Here is my attempt in proving that assertion.&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="46%" /&gt;
&lt;col width="54%" /&gt;
&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="k"&gt;ISOLATION&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;-#&lt;/span&gt; &lt;span class="k"&gt;READ&lt;/span&gt; &lt;span class="k"&gt;COMMITTED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TRANSACTION&lt;/span&gt; &lt;span class="k"&gt;ISOLATION&lt;/span&gt; &lt;span class="k"&gt;LEVEL&lt;/span&gt;
&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;-#&lt;/span&gt; &lt;span class="k"&gt;READ&lt;/span&gt; &lt;span class="k"&gt;COMMITTED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;
  &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;
   &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
 &lt;span class="c1"&gt;----+---&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;insert&lt;/span&gt; &lt;span class="k"&gt;into&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="k"&gt;values&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt;
   &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
 &lt;span class="c1"&gt;----+---&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div class="first last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;&lt;div class="first"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;mvcc_test&lt;/span&gt;&lt;span class="o"&gt;=#&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mvcc_test&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;span class="c1"&gt;----+---&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;p class="last"&gt;This is a phantom read because the new row did not
appear inside the transaction after it was commit in
the first transaction.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style="text-align: center;"&gt;
  &lt;object width="425" height="344" type="application/x-shockwave-flash" data="http://www.youtube.com/v/LVsFuScCUMg&amp;amp;hl=en"&gt;
   &lt;param name="movie" value="http://www.youtube.com/v/LVsFuScCUMg&amp;amp;hl=en" /&gt;

  &lt;embed src="http://www.youtube.com/v/LVsFuScCUMg&amp;amp;hl=en"  type="application/x-shockwave-flash" width="425" height="344" /&gt;&lt;/object&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
</summary><category term="django"></category><category term="postgresql"></category></entry><entry><title>Fun with APIs</title><link href=".././fun-with-apis.html" rel="alternate"></link><updated>2008-06-18T16:38:41Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-06-18:.././fun-with-apis.html/</id><summary type="html">&lt;p&gt;So, you're looking for a job you say... Need to brush up on your knowledge set... I've got the tool for you!&lt;/p&gt;
&lt;p&gt;career_chooser.py&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;urllib&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;re&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;cgi&lt;/span&gt;

&lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;USE YOUR OWN&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;http://api.indeed.com/apisearch?q=&lt;/span&gt;&lt;span class="se"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="se"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;&amp;amp;l=&amp;amp;start=0&amp;amp;limit=1&amp;amp;sort=&amp;amp;filter=on&amp;amp;latlong=off&amp;amp;key=&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;amp;format=xml&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result_count_re&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;r&amp;quot;&amp;lt;totalresults&amp;gt;(\d+)&amp;lt;/totalresults&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result_count_re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;display&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;count_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;%10d&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;spaces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;78&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count_str&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;%s%s&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot; &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;spaces&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;result_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Usage &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; [Query] [Query] ...&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:]:&lt;/span&gt;
    &lt;span class="n"&gt;result_list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="n"&gt;result_list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="n"&gt;result_list&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Try it out&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;C:                                                                       136105
Java:                                                                     89132
HTML:                                                                     87963
Assembly:                                                                 63423
XML:                                                                      62938
C%2B%2B:                                                                  60774
Javascript:                                                               42368
ASP:                                                                      42067
Perl:                                                                     35742
J2EE:                                                                     31609
Visual+Basic:                                                             28924
PHP:                                                                      17972
ADA:                                                                      11821
Struts:                                                                   11425
Python:                                                                   10416
COBOL:                                                                     6964
Ruby:                                                                      5439
Ruby+on+Rails:                                                             2515
FORTRAN:                                                                   2008
Zend:                                                                       270
Django:                                                                     228
CakePHP:                                                                    109
CodeIgniter:                                                                 31
JRuby:                                                                       30
&lt;/pre&gt;&lt;/div&gt;
</summary><category term="fun"></category><category term="python"></category></entry><entry><title>Template Tag Caveat</title><link href=".././template-tag-caveat.html" rel="alternate"></link><updated>2008-06-17T21:46:55Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-06-17:.././template-tag-caveat.html/</id><summary type="html">&lt;p&gt;In the Django template system.  There is a small caveat that you need to
recognize when developing your own template tags.&lt;/p&gt;
&lt;p&gt;When Django parses the Node tree it creates a template.Node instance for
each template tag in the template.  The node tree is just like our beloved
HTML DOM.&lt;/p&gt;
&lt;p&gt;So for instance take the following&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt; &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;2&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;3&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;4&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;5&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That turns into something like this&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt; &lt;span class="nt"&gt;&amp;lt;ul:Element&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;li:HTMLElement&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;li:HTMLElement&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;li:HTMLElement&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;li:HTMLElement&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;li:HTMLElement&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The indention shows that the li's are child nodes of the ul tag. Each li in a
different instance of an HTMLElement, each with their own state.&lt;/p&gt;
&lt;p&gt;So for a Django Template take the following&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;block&lt;/span&gt; &lt;span class="nv"&gt;content&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;   &lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;firstof&lt;/span&gt; &lt;span class="nv"&gt;var1&lt;/span&gt; &lt;span class="nv"&gt;var2&lt;/span&gt; &lt;span class="nv"&gt;var3&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;   &lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;firstof&lt;/span&gt; &lt;span class="nv"&gt;var1&lt;/span&gt; &lt;span class="nv"&gt;var2&lt;/span&gt; &lt;span class="nv"&gt;var3&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;   &lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;firstof&lt;/span&gt; &lt;span class="nv"&gt;var1&lt;/span&gt; &lt;span class="nv"&gt;var2&lt;/span&gt; &lt;span class="nv"&gt;var3&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;   &lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;firstof&lt;/span&gt; &lt;span class="nv"&gt;var1&lt;/span&gt; &lt;span class="nv"&gt;var2&lt;/span&gt; &lt;span class="nv"&gt;var3&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;endblock&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The node tree would look like this&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt; &lt;span class="nt"&gt;&amp;lt;BlockNode&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;FirstOfNode&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;FirstOfNode&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;FirstOfNode&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;FirstOfNode&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So we have a block node with four FirstOfNode instances&lt;/p&gt;
&lt;p&gt;In python this would translate roughly to&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt; &lt;span class="n"&gt;f1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FirstOfNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;f2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FirstOfNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;f3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FirstOfNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;f4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FirstOfNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;f1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="n"&gt;f2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="n"&gt;f3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="n"&gt;f4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Everything looks fine here.  Render is called once per node instance.&lt;/p&gt;
&lt;p&gt;Now, check this out&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;block&lt;/span&gt; &lt;span class="nv"&gt;content&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;   &lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;value_list&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;     &lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;repr&lt;/span&gt; &lt;span class="nv"&gt;obj&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;   &lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;endfor&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt; &lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;endblock&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The node tree that django builds would look something like this&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt; &lt;span class="nt"&gt;&amp;lt;BlockNode&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;ForNode&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;ReprNode&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now each node in that tree is it's own object instance with it's own
state.  This can be an issue if you don't realize one thing, each node
is persistent while the template is rendering.&lt;/p&gt;
&lt;p&gt;Let me write out how the template rendering of the a loop would look
in python with the ReprNode&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt; &lt;span class="n"&gt;repr_node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ReprNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;obj&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
     &lt;span class="n"&gt;repr_node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Can you tell what the problem?  We're calling the render method
on the same instance of the Node.&lt;/p&gt;
&lt;p&gt;Let's peek under the covers and look at ReprNode's definition&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReprNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
     &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;

     &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
         &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resolve_variable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

     &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do_repr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
         &lt;span class="n"&gt;tag_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split_contents&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ReprNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now look at what's going on.  self.obj is assumed to be the name of the
variable in the context.  That's fine when render is called once.  When render
called a second time, self.obj is now the actual value of obj from the context.
What happens when you try to resolve that?  You get a VariableDoesNotExist
error, uh oh!&lt;/p&gt;
&lt;p&gt;I made the assumption that render() is only called once.  You don't realize
that inside a for tag, the render method is called repeatedly.  This can cause
tons of issues.  If it wasn't a huge design change, Template Nodes should
probably be Static classes.&lt;/p&gt;
&lt;p&gt;I don't know if this is technically a bug in the Django templating system,
bad design, bad documentation, or just simply poor assumptions on my part, but
I came across this issue today and it took stepping through PDB to find the
problem with my custom template tag (the ReprNode was completely made up for
the example)&lt;/p&gt;
&lt;p&gt;Example code &amp;lt;&lt;a class="reference external" href="http://www.djangosnippets.org/snippets/811/"&gt;http://www.djangosnippets.org/snippets/811/&lt;/a&gt;&amp;gt;&lt;/p&gt;
</summary><category term="django"></category></entry><entry><title>iphone-3g</title><link href=".././iphone-3g.html" rel="alternate"></link><updated>2008-06-11T13:12:05Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-06-11:.././iphone-3g.html/</id><summary type="html">&lt;p&gt;What can I say about the iphone 3g that hasn't been said.  All I can say is I want one and I want to develop on it.&lt;/p&gt;
&lt;p&gt;The one thing that sold me was the true GPS support.  This thing is going to herald in the geotagging revolution that has been conspiring in dark rooms for a couple years now.&lt;/p&gt;
&lt;p&gt;Just like podcasting which hadn't taken off until iPods took over, the iphone is going to do the same for geotagging.&lt;/p&gt;
&lt;p&gt;We're going to be geotagging everything.  I'm anticipating some really awesome apps based on gps.&lt;/p&gt;
&lt;p&gt;Remember &lt;a class="reference external" href="http://www.dodgeball.com/"&gt;http://www.dodgeball.com/&lt;/a&gt;? Awesome idea.... Now think of dodgeball.com on the iphone with gps, a perfect idea.&lt;/p&gt;
&lt;ol class="upperalpha simple" start="5"&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ol&gt;
</summary><category term="gps"></category><category term="iphone"></category></entry><entry><title>appengine vs twitter part 2</title><link href=".././appengine-vs-twitter-part-2.html" rel="alternate"></link><updated>2008-05-21T16:54:48Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-05-21:.././appengine-vs-twitter-part-2.html/</id><summary type="html">&lt;p&gt;I've created a &lt;a class="reference external" href="https://launchpad.net/meow/"&gt;project&lt;/a&gt; in launchpad for &lt;a class="reference external" href="http://meow.appspot.com"&gt;Meow&lt;/a&gt;.  You can now submit bug reports and feature requests into launchpad.&lt;/p&gt;
&lt;p&gt;If your a &lt;a class="reference external" href="http://www.djangoproject.com"&gt;Django&lt;/a&gt; or &lt;a class="reference external" href="http://code.google.com/appengine/"&gt;Appengine&lt;/a&gt; hacker and want to help me out, simply branch the Meow code with bazaar and you can &amp;quot;bzr send&amp;quot; me patches.  I'll be happy to merge them if they're handy.&lt;/p&gt;
&lt;p&gt;There is now a code link on the bottom of every Meow page to get you to the launchpad page.&lt;/p&gt;
&lt;p&gt;Meow has also aquired the &lt;a class="reference external" href="http://www.fsf.org/licensing/licenses/agpl-3.0.html"&gt;Affero GPLv3&lt;/a&gt; license as well to protect it's open source nature on the web.  The AGPLv3 requires modified source code to be made available even if it's running behind a web server.&lt;/p&gt;
</summary><category term="appengine"></category><category term="django"></category></entry><entry><title>appengine vs twitter</title><link href=".././appengine-vs-twitter.html" rel="alternate"></link><updated>2008-05-20T03:17:11Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-05-20:.././appengine-vs-twitter.html/</id><summary type="html">&lt;p&gt;So &lt;a class="reference external" href="http://www.hackermojo.com/"&gt;Glenn Franxman&lt;/a&gt; was opining this afternoon about how &lt;a class="reference external" href="http://www.twitter.com"&gt;twitter&lt;/a&gt; is going to reach a point where they're going to grow to big and need to make money somehow.  He said that they're either going to have to throw ads everywhere or hope to be aquired.&lt;/p&gt;
&lt;p&gt;He thinks that they're like every startup in web 2.0 where they're hoping to be aquired by Google.&lt;/p&gt;
&lt;p&gt;I said to him, &amp;quot;Why would Google aquire them?   I could write twitter on &lt;a class="reference external" href="http://code.google.com/appengine/"&gt;google app engine&lt;/a&gt; in like 30 minutes.&amp;quot;&lt;/p&gt;
&lt;p&gt;Well it took me two hours to shoehorn Django into GAE and about an hour to get a working prototype.  It's far from complete, but it works.  I still have to integrate &lt;a class="reference external" href="http://www.textmarks.com"&gt;textmarks&lt;/a&gt; to enable SMS i/o, add following and replies, but it works.&lt;/p&gt;
&lt;p&gt;You can view the app at &lt;a class="reference external" href="http://meow.appspot.com/"&gt;http://meow.appspot.com/&lt;/a&gt;  and you can checkout the code at &lt;a class="reference external" href="https://launchpad.net/meow"&gt;https://launchpad.net/meow&lt;/a&gt;&lt;/p&gt;
</summary><category term="django"></category><category term="gae"></category><category term="google"></category><category term="twitter"></category></entry><entry><title>Experimenting</title><link href=".././experimenting.html" rel="alternate"></link><updated>2008-05-09T11:01:00Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-05-09:.././experimenting.html/</id><summary type="html">&lt;p&gt;I ran across &lt;a class="reference external" href="http://trac.hunch.se/smisk/"&gt;Smisk&lt;/a&gt; two days ago and though. &amp;quot;Hmm,  someone should write a wsgi adaptor for that&amp;quot;.&lt;/p&gt;
&lt;p&gt;Maybe an hour after I had that thought,  I started working on one.  It was pretty easy.  &lt;a class="reference external" href="http://trac.hunch.se/smisk/"&gt;Smisk&lt;/a&gt;'s classes seem to be inspired by &lt;a class="reference external" href="http://www.python.org/dev/peps/pep-0333/"&gt;WSGI&lt;/a&gt;, all the wsgi environment variables had a &lt;a class="reference external" href="http://trac.hunch.se/smisk/"&gt;Smisk&lt;/a&gt; equivilent.  So the adaptor was basically putting tab A in Slot B and Tab B is slot A, etc.&lt;/p&gt;
&lt;p&gt;If you noticed in my &lt;a class="reference external" href="http://del.icio.us/ericmoritz"&gt;del.icio.us feed&lt;/a&gt;.  I bookmarked &lt;a class="reference external" href="http://trac.hunch.se/smisk/"&gt;Smisk&lt;/a&gt; itself and three hours later, I bookmarked my launchpad branch of &lt;a class="reference external" href="https://code.launchpad.net/~ericmoritz/+junk/smisk-wsgi"&gt;smisk-wsgi&lt;/a&gt;.  Pretty cool.&lt;/p&gt;
&lt;p&gt;Fifteen hours later across the globe in Sweden, &lt;a class="reference external" href="http://trac.hunch.se/smisk/"&gt;Smisk&lt;/a&gt;'s project owner Rasmus Anderson, &lt;a class="reference external" href="http://hg.hunch.se/smisk/rev/0ddab23e8dc8"&gt;merged my code&lt;/a&gt; in with some changes.&lt;/p&gt;
&lt;p&gt;So in a total of 3 hours, something went from concept to reality thanks to &lt;a class="reference external" href="http://www.python.org"&gt;Python&lt;/a&gt;.  I don't think the quickness is a testimate to my mad hacking skills.  It's really a testimate to &lt;a class="reference external" href="http://www.python.org"&gt;Python&lt;/a&gt;'s agility.&lt;/p&gt;
&lt;p&gt;So what is &lt;a class="reference external" href="http://trac.hunch.se/smisk/"&gt;Smisk&lt;/a&gt; and why is it cool?   &lt;a class="reference external" href="http://trac.hunch.se/smisk/"&gt;Smisk&lt;/a&gt; is a low level web framework built in C but controled by Python.   Basically it's a &lt;a class="reference external" href="http://www.fastcgi.com/"&gt;fastcgi&lt;/a&gt; interface to Python with some really well thought out classes bolted on.&lt;/p&gt;
&lt;p&gt;What does the &lt;a class="reference external" href="http://www.python.org/dev/peps/pep-0333/"&gt;wsgi&lt;/a&gt; adapter get you?  It basically allows you to expose your &lt;a class="reference external" href="http://www.python.org/dev/peps/pep-0333/"&gt;wsgi&lt;/a&gt; based framework/app (&lt;a class="reference external" href="http://www.djangoproject.com"&gt;Django&lt;/a&gt;, &lt;a class="reference external" href="http://www.cherrypy.org"&gt;Cherrypy&lt;/a&gt;, etc) to &lt;a class="reference external" href="http://www.fastcgi.com/"&gt;fastcgi&lt;/a&gt; via C.  Now, what does that get you?  Well it gets you a faster &lt;a class="reference external" href="http://www.fastcgi.com/"&gt;fastcgi&lt;/a&gt; protocol (I think).&lt;/p&gt;
&lt;p&gt;Now, I don't have any quantifiable evidence if it's actually faster or not. Rasmus has some &lt;a class="reference external" href="http://trac.hunch.se/smisk/wiki/Performance"&gt;performance tests&lt;/a&gt; on the &lt;a class="reference external" href="http://trac.hunch.se/smisk/"&gt;Smisk&lt;/a&gt; wiki.  Logic would say it would be.  If it is faster,  it's probably in the range of miliseconds, so it's probably not something to lose sleep over.  Generally your application slows down due to database performance.&lt;/p&gt;
&lt;p&gt;Is the WSGI adaptor compliant?  For the most part.  I'm doing tests with the wsgiref's validator app.  There are some methods that we have to add to smisk's Stream class to make it valid.  That means C work, so I have to brush up on my skills, but it shouldn't be long.&lt;/p&gt;
&lt;p&gt;I'm currently running this blog on &lt;a class="reference external" href="http://www.djangoproject.com"&gt;Django&lt;/a&gt; on top of &lt;a class="reference external" href="http://trac.hunch.se/smisk/"&gt;Smisk&lt;/a&gt;.  I found some nasty bugs (causes segfaults on POST) that were in the Stream class, so I wouldn't recomend doing the same until Rasmus merges the &lt;a class="reference external" href="http://eric.themoritzfamily.com/upload/smisk.wsgi.patch"&gt;changes&lt;/a&gt; I sent him.&lt;/p&gt;
&lt;p&gt;Will this replace &lt;a class="reference external" href="http://www.saddi.com/software/flup/"&gt;flup&lt;/a&gt; as a &lt;a class="reference external" href="http://www.fastcgi.com/"&gt;fastcgi&lt;/a&gt; to &lt;a class="reference external" href="http://www.python.org/dev/peps/pep-0333/"&gt;wsgi&lt;/a&gt; adapter?  I doubt it at this point, &lt;a class="reference external" href="http://www.saddi.com/software/flup/"&gt;flup&lt;/a&gt; has some nice pooling features that would have to be built into &lt;a class="reference external" href="http://trac.hunch.se/smisk/"&gt;Smisk&lt;/a&gt; in order for &lt;a class="reference external" href="http://trac.hunch.se/smisk/"&gt;Smisk&lt;/a&gt; to have the flexibility of &lt;a class="reference external" href="http://www.saddi.com/software/flup/"&gt;flup&lt;/a&gt;.  I don't know if those features are in Rasmus' plans for &lt;a class="reference external" href="http://trac.hunch.se/smisk/"&gt;Smisk&lt;/a&gt; or not.&lt;/p&gt;
</summary><category term="django"></category><category term="programming"></category><category term="python"></category><category term="smisk"></category></entry><entry><title>is opensource really all that great for companies</title><link href=".././is-opensource-really-all-that-great-for-companies.html" rel="alternate"></link><updated>2008-04-29T17:14:33Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-04-29:.././is-opensource-really-all-that-great-for-companies.html/</id><summary type="html">&lt;p&gt;So I released my feedclowd code as open source and I needed to pick license.  The requirements I wanted in a license were this,  you may use the source code but if you modify that source code you must make your source code available.  In my ignorance, that's what I thought the GPL provided.&lt;/p&gt;
&lt;p&gt;Well after some discussion with numerous people, that's not the case.  What the GPL provides is that if someone takes your code and modifies it they only have to make that code available if they distribute the new code.&lt;/p&gt;
&lt;p&gt;This is a one way relationship.  The main benefit that a company could reap if their code is open sourced would be the fixes and enhancements that other programmers would make to the company's product.  If those modifications and enhancements are never distributed, the original creator of the source code may never have the opportunity of seeing those changes.&lt;/p&gt;
&lt;p&gt;This is a huge flaw with creating web systems that are rarely redistibuted.  If my company builds a CMS and makes it open source, everyone can use the product but they are not required to benefit my company in anyway.  Any benefit my company would reap would be soley in the kindness of others...&lt;/p&gt;</summary><category term="django"></category><category term="gpl"></category><category term="opensource"></category></entry><entry><title>feedclowd is now opensource</title><link href=".././feedclowd-is-now-opensource.html" rel="alternate"></link><updated>2008-04-25T20:17:01Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-04-25:.././feedclowd-is-now-opensource.html/</id><summary type="html">&lt;p&gt;I've finally made the application that drives www.feedclowd.com to be open source.&lt;/p&gt;
&lt;p&gt;Here's the official &lt;a href="http://www.feedclowd.com/blog/2008/04/25/django-feedclowd-now-opensource/"&gt;announcement&lt;/a&gt;&lt;/p&gt;</summary><category term="django"></category><category term="feedclowd"></category></entry><entry><title>feedclowd now in beta</title><link href=".././feedclowd-now-in-beta.html" rel="alternate"></link><updated>2008-04-21T17:16:03Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-04-21:.././feedclowd-now-in-beta.html/</id><summary type="html">&lt;p&gt;I just released my project as a public beta, &lt;a href="http://www.feedclowd.com"&gt;feedclowd&lt;/a&gt; It's a life aggregator were you can take all your feeds from all your social sites and combine them into one simple feed.&lt;/p&gt;</summary><category term="django"></category></entry><entry><title>Your own appengine, maybe not yet</title><link href=".././your-own-appengine-maybe-not-yet.html" rel="alternate"></link><updated>2008-04-08T23:14:28Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-04-08:.././your-own-appengine-maybe-not-yet.html/</id><summary type="html">&lt;p&gt;Well, I started looking at both Parallel Python and CouchDB.&lt;/p&gt;
&lt;p&gt;CouchDB still seems to be a viable replacement for the BigTable backend to datastore.  A GQL parser will have to be written to interface with Couch's views, but that's probably easy enough.&lt;/p&gt;
&lt;p&gt;After looking at PP (Parallel Python) a little more.  It's definitely not the correct solution.  PP only works with a limitted python scope.  You couldn't say, load all of Django inside of PP.&lt;/p&gt;
&lt;p&gt;The way that appengine works is simple CGI, this makes every request autonomous.  It doesn't need to know what machine it's running on. &lt;/p&gt;
&lt;p&gt;One possible implementation is to distribute your source code across all nodes.  With some kind of virtual hosting router and load balance system, you could make your own appengine on a small scale.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;mod_fastcgi on lighttpd allows you to load balance application servers inside of  lighttpd.  You could distribute fastcgi servers across all 20 app servers all with a pool of min_children/20.  So if you need at least 10 children you could have 1 app server per site per machine.  I'm not completely sure, but I don't think mod_fastcgi load balancing provides any fault tolerance.&lt;/p&gt;
&lt;p&gt;So the idea is to have each http request load balanced to each lighttpd server.  each lighttpd server load balances fastcgi among all the nodes.  Each fastcgi app server can access the couchdb cloud of all the nodes.&lt;/p&gt;</summary><category term="appengine"></category><category term="couchdb"></category><category term="diy"></category><category term="parellel"></category><category term="python"></category><category term="tahoe"></category></entry><entry><title>Your own appengine</title><link href=".././your-own-appengine.html" rel="alternate"></link><updated>2008-04-08T18:16:23Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-04-08:.././your-own-appengine.html/</id><summary type="html">&lt;p&gt;My main gripe with &lt;a href="http://code.google.com/appengine/"&gt;appengine&lt;/a&gt; is that while you're sticking your app on a lot of iron, it's pretty much stuck there forever because of the infrastructure.  Your app is not portable.  You can't just take it off of Google's iron and host it yourself. &lt;/p&gt;
&lt;p&gt;So, when I was listening to &lt;a href="http://www.youtube.com/watch?v=oG6Ac7d-Nx8"&gt;part 3&lt;/a&gt; of the google app engine intro, I heard him describe BigTable as a "a distributed, fault-tolerant and schema-free", I knew I heard that before.  I heard that from the &lt;a href="http://incubator.apache.org/couchdb/"&gt;CouchDB project&lt;/a&gt;.  I never saw a need for CouchDB, but it's looking interesting now.&lt;/p&gt;
&lt;p&gt;After looking at the SDK for appengine, the datastore interface is pretty simple, there's no reason it couldn't be implemented with CouchDB as the backend.  Giving you your own "distributed, fault-tolerant and schema-free" datastore.&lt;/p&gt;
&lt;p&gt;Also in  &lt;a href="http://www.youtube.com/watch?v=oG6Ac7d-Nx8"&gt;part 3&lt;/a&gt; that they run your python code on a low overhead, distributed, fault-tolerant infrastructure..  I knew I heard that before too. I heard it with the &lt;a href="http://www.parallelpython.com"&gt;Parallel Python&lt;/a&gt; project.&lt;/p&gt;
&lt;p&gt;Need a decentralized, fault-tolerant file system?  There's &lt;a href="http://allmydata.org/trac/tahoe"&gt;Tahoe&lt;/a&gt;.  Tahoo provides that too.&lt;/p&gt;
&lt;p&gt;So let's say you have 20 servers, a mix match of database, media and http servers.  Now instead of partitioning them to have their own roles, they become nodes in a cloud all handling http, appserving, media file serving and data storage.&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;If you create a webserver inside of parallel python that basically brokers requests for different sites to the parallel python cloud, a node in llpy then executes the request.  llpy may contact the couchdb cloud.  All using the power of the cloud.  Therefore if you have 22 sites and only 5 get heavy traffic, you don't have to waste the power of the other 17 machines on the slow sites.&lt;/p&gt;
&lt;p&gt;The appengine SDK looks like a start to create such a system.  The datastore modules provide a way to interface CouchDB.  Recreating the http brokering system with llpy shouldn't be that hard.&lt;/p&gt;
&lt;p&gt;And once the django community finds a way to work it's ORM onto Google's datastore api (which I know they will), implementing Django inside your own parellel python/couchdb appengine wouldn't be hard.&lt;/p&gt;
&lt;p&gt;Creating your own appengine wouldn't be for the average joe schmoe, It would be for big companies with some iron.&lt;/p&gt;</summary><category term="appengine"></category><category term="couchdb"></category><category term="django"></category><category term="parellel"></category><category term="python"></category><category term="tahoe"></category></entry><entry><title>My site is now on slicehost</title><link href=".././my-site-is-now-on-slicehost.html" rel="alternate"></link><updated>2008-04-08T17:01:31Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-04-08:.././my-site-is-now-on-slicehost.html/</id><summary type="html">&lt;p&gt;I just migrated my blog to slicehost because I finally got fed up with site5's janky django setup.&lt;/p&gt;
&lt;p&gt;I noticed that I broke my link to the django aggregrator when I moved my blog off wordpress and onto Django.  I tried to log into site5 to fix it and I got that damn &amp;quot;-bash: fork: Resource temporarily unavailable&amp;quot; error that prevents me from doing anything in my shell.&lt;/p&gt;
&lt;p&gt;I pulled my stuff off and stuck it on my slice.  I may get all kinds of errors, but we'll see.  Let me know if
DNS is still propagating so you may not see this.&lt;/p&gt;
</summary><category term="slicehost"></category></entry><entry><title>Google Apps Engine without Django colored glasses</title><link href=".././google-apps-engine-without-django-colored-glasses.html" rel="alternate"></link><updated>2008-04-08T15:22:22Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-04-08:.././google-apps-engine-without-django-colored-glasses.html/</id><summary type="html">&lt;p&gt;So after a day of mulling over GAE, I've come up with one conclusion.  For one-off apps, this is brilliant.  What Ruby and Rails did in it's heyday, this is going to do.  No need to figure out how to set up a web server or configure a database. Just write some python and blamo an application.&lt;/p&gt;
&lt;p&gt;This also blows Facebook applications out of the water.  With GAE, you get a full web framework, written on top of a real language.  You aren't forced to use FBML, you can use Django templates.  Tie in opensocial and you have a turn-key application platform.&lt;/p&gt;
&lt;p&gt;Now, I'm not sure that this is a viable solution to run a website on (what is a website anymore?), but writing a web application, it's brilliant.  Next up, Google Gears for appengine.&lt;/p&gt;</summary><category term="appengine"></category><category term="django"></category><category term="gae"></category><category term="python"></category></entry><entry><title>Google Apps Engine, wait what?!?</title><link href=".././google-apps-engine-wait-what.html" rel="alternate"></link><updated>2008-04-08T11:53:11Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-04-08:.././google-apps-engine-wait-what.html/</id><summary type="html">&lt;p&gt;So I saw a post to this last night and I thought, &amp;quot;Oh it's like &lt;a class="reference external" href="http://www.amazon.com/gp/browse.html?node=201590011"&gt;Amazon's EC2&lt;/a&gt; I won't ever need that&amp;quot;.&lt;/p&gt;
&lt;p&gt;Much to my surprise this morning, it's something I could really need.  It's a sandboxed distributed web framework.  No need for load balancing, hardware, whatever.&lt;/p&gt;
&lt;p&gt;The first thing I saw was it uses WSGI, my first thought, &amp;quot;Sweet Django can run on this.&amp;quot;  Which is true... sort-of.&lt;/p&gt;
&lt;p&gt;There are few limitations that will &lt;a class="reference external" href="http://code.google.com/appengine/docs/python/sandbox.html"&gt;drive Djangonistas crazy.&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First, there is no local file support.  You can't upload arbitrary files to the file system.  &lt;em&gt;BUT&lt;/em&gt;, you can store them in the datastore, so with Marty Alchin's filesystem backends, someone can write a  FileSystemBackend to support storing files into google's datastore&lt;/p&gt;
&lt;p&gt;Second, and the big one,  Django Model support.  At first I thought, &amp;quot;oh, GQL,  sweet a SQL-like language, we can just make a DBBackend in django to support it.&amp;quot;  Nope, for one, it's only supports Selects, and second, no joins.  So that's absolutely out of the question.&lt;/p&gt;
&lt;p&gt;There are other ways of interfacing Django models to google's datastore.  One way is to implement dbapi on top of the google db.models, but that's probably absolutely retarded.  We'd have to implement a sql parser and basically our own db engine.&lt;/p&gt;
&lt;p&gt;I haven't been following the queryset refactoring stuff, but hopefully it'll make this easier.  I'd like to see the Django ORM be less reliant on SQL.  I know the R in ORM is Relational, but I would be nice to be able to store and retrieve objects from different storage methods.&lt;/p&gt;
&lt;p&gt;I'm surprised that there wasn't more effort made to make the two frameworks work together.  From what I see, I can't see a reason to run Django on GAE.&lt;/p&gt;
&lt;p&gt;So what does Django have going for it.  a ORM, and a Templating System.  GAE requires you to use the Datastore API, so no ORM.  Templating system?  GAE implements &lt;a class="reference external" href="http://code.google.com/appengine/docs/gettingstarted/templates.html"&gt;Django templates&lt;/a&gt;  inside of webapp.  So no need for the Django Templating system.&lt;/p&gt;
&lt;p&gt;Django provides tons of contrib apps, and those are great but how many of them rely on models, probably quite a few.&lt;/p&gt;
&lt;p&gt;I don't see a reason why you'd really want to load the complete Django stack if you can't use probably 75% of Django.&lt;/p&gt;
&lt;p&gt;I am really surprised that they didn't do more work to integrate GAE with Django.  I'm sure Guido was working really closely with GAE and it's not like he doesn't know about Django.&lt;/p&gt;
&lt;p&gt;So here are benefits of GAE: First, you don't have to worry about hardware, it's all sitting on google's hardware being load balanced and distributed for you.  Don't have to worry about database optimization, again, it's all on google's hardware being load balanced and distributed.&lt;/p&gt;
&lt;p&gt;So here are the faults of GAE, First, if you build an application on GAE, it's not portable, you can't take your app, export the data, plug it into Apache via mod_wsgi and go.  You're app is completely tied to the App Engine. Second, conspiracy alarms go off, google has all your application's data to do what they want with it.&lt;/p&gt;
</summary><category term="django"></category><category term="python"></category></entry><entry><title>python interface to the mozilla DOM</title><link href=".././python-interface-to-the-mozilla-dom.html" rel="alternate"></link><updated>2008-02-08T14:39:38Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-02-08:.././python-interface-to-the-mozilla-dom.html/</id><summary type="html">&lt;p&gt;Glenn Franxman and I were brain storming on how to do unittesting with a real browser DOM with working javascript.  Basically everything accessible to the browser could be accessible to python&lt;/p&gt;
&lt;p&gt;I ran across this post: &lt;a class="reference external" href="http://ejohn.org/blog/bringing-the-browser-to-the-server/"&gt;http://ejohn.org/blog/bringing-the-browser-to-the-server/&lt;/a&gt; where he uses Rhino and a custom window library to mimic the interface of the window:
&lt;a class="reference external" href="http://jqueryjs.googlecode.com/svn/trunk/jquery/build/runtest/env.js"&gt;http://jqueryjs.googlecode.com/svn/trunk/jquery/build/runtest/env.js&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;He's using Rhino which is a java engine... It would suprise me if Spidermonkey, which as python bindings, would not work.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update&lt;/em&gt; the env.js library has bindings to java classes so it won't work... I'll have to create an interface to those.&lt;/p&gt;
</summary><category term="amazing"></category><category term="javascript"></category><category term="python"></category></entry><entry><title>Open Search</title><link href=".././open-search.html" rel="alternate"></link><updated>2008-02-05T11:28:01Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-02-05:.././open-search.html/</id><summary type="html">&lt;p&gt;With the invention of the opensearch specification, it has become super easy to create search plugins for Firefox 2.0+ and IE7.  Here's an example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;OpenSearchDescription&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://a9.com/-/spec/opensearch/1.1/&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ShortName&amp;gt;&amp;lt;/ShortName&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;Description&amp;gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;Image&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;16&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;16&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;image/x-icon&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/Image&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;Url&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text/html&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;get&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;template=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/OpenSearchDescription&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
</summary><category term="code"></category><category term="firefox"></category><category term="opensearch"></category></entry><entry><title>PreResolution follow up</title><link href=".././preresolution-follow-up.html" rel="alternate"></link><updated>2008-01-04T11:44:59Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-01-04:.././preresolution-follow-up.html/</id><summary type="html">&lt;p&gt;I've almost made it 4 days without a cigarette.  I'm pretty much off the nicotine gum, though I'm still carrying around a few pieces of gum in case of emergency.&lt;/p&gt;
&lt;p&gt;I am currently reading &amp;quot;Flatland&amp;quot; by E. A. Abbott, it's an interesting book.&lt;/p&gt;
&lt;p&gt;I haven't started exercising or the weekly meditation yet because my body is still recovering from the shock of not smoking anymore.  I anticipate starting that next week.  I plan on jogging Tuesday and Thursday and meditating on Wednesday.  We'll see how it goes, I'm not very eager to jog in the cold air.&lt;/p&gt;
</summary><category term="news"></category><category term="personal"></category></entry><entry><title>Donating Bandwidth to Neighbors</title><link href=".././donating-bandwidth-to-neighbors.html" rel="alternate"></link><updated>2008-01-02T00:14:57Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-01-02:.././donating-bandwidth-to-neighbors.html/</id><summary type="html">&lt;p&gt;My neighbors across the street don't have Internet access so I volunteered my WPA password to them so that they can use my Internet.  Today I decided to install a custom WRT54G firmware called &lt;a class="reference external" href="http://coova.org/wiki/index.php/CoovaAP"&gt;CoovaAP&lt;/a&gt; to turn my router into an open hotspot like you would see in hotels for my other neighbors to use.&lt;/p&gt;
&lt;p&gt;It was very easy to install and configure.  It uses &lt;a class="reference external" href="http://coova.org/wiki/index.php/CoovaChilli"&gt;CoovaChilli&lt;/a&gt; to create a captive portal to allow my neighbors create a user and log in.  It also separates my hardwired network from the wireless hotspot.&lt;/p&gt;
&lt;p&gt;I also installed &lt;a class="reference external" href="http://www.ipp2p.org/"&gt;ipp2p&lt;/a&gt; to block p2p traffic to keep the bandwidth usage down.  Besides everyone uses p2p for piracy anyway (Don't try to deny it).  Bittorrent is a great technology used for evil.  Don't get me started on Limewire...  Here's a &lt;a class="reference external" href="http://coova.org/wiki/index.php/CoovaAP/p2p_block"&gt;howto&lt;/a&gt; on installing ipp2p on Coova&lt;/p&gt;
</summary><category term="hotspot"></category><category term="linux"></category><category term="networking"></category><category term="news"></category></entry><entry><title>New Years preresolutions</title><link href=".././new-years-preresolutions.html" rel="alternate"></link><updated>2008-01-01T06:16:23Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2008-01-01:.././new-years-preresolutions.html/</id><summary type="html">&lt;p&gt;Ok, I'm not going call these resolutions, they just happen to be commitments I'm making on the first of the year :)&lt;/p&gt;
&lt;p&gt;There are three of them, each corresponding to mind, body, and soul.&lt;/p&gt;
&lt;div class="section" id="mind"&gt;
&lt;h2&gt;Mind&lt;/h2&gt;
&lt;p&gt;Read one book from the &lt;a class="reference external" href="http://www.gutenberg.org/"&gt;Project Gutenberg&lt;/a&gt; a month.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="body"&gt;
&lt;h2&gt;Body&lt;/h2&gt;
&lt;p&gt;This one is two phased.  First I'm quitting smoking,  I've already started on the gum.  That's just a means to make the second one easier.  The second one is to exercise more often.  I think I'm going to start by running once a week.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="soul"&gt;
&lt;h2&gt;Soul&lt;/h2&gt;
&lt;p&gt;Meditate at home once a week.  I already attend service at the local &lt;a class="reference external" href="http://www.lslk.org/"&gt;Buddhist center&lt;/a&gt; on Sundays which include a short meditation.  There just something about meditating in the privacy of your home that's makes it more fulfilling and intimate.&lt;/p&gt;
&lt;p&gt;Ok, that's it.  Let's see if I stick to them.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="news"></category></entry><entry><title>Registration now open</title><link href=".././registration-now-open.html" rel="alternate"></link><updated>2007-12-30T05:41:01Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2007-12-30:.././registration-now-open.html/</id><summary type="html">&lt;p&gt;I managed to get &lt;a class="reference external" href="http://code.google.com/p/django-registration/"&gt;django-registration&lt;/a&gt; installed now.  So you all can now create users.&lt;/p&gt;
&lt;p&gt;I'll get comments installed as soon as I get a chance.  I wanted to get the registration working first before allowing comment.&lt;/p&gt;
</summary><category term="django"></category><category term="news"></category></entry><entry><title>eric.themoritzfamily.com is now more Djangolicious</title><link href=".././ericthemoritzfamilycom-is-now-more-djangolicious.html" rel="alternate"></link><updated>2007-12-28T17:38:47Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2007-12-28:.././ericthemoritzfamilycom-is-now-more-djangolicious.html/</id><summary type="html">&lt;div class="section" id="now-running-on-django"&gt;
&lt;h2&gt;Now Running on Django&lt;/h2&gt;
&lt;p&gt;Thanks to this &lt;a class="reference external" href="http://forums.site5.com/showthread.php?t=10236"&gt;post&lt;/a&gt;, I was able to get Django running on &lt;a class="reference external" href="http://www.site5.com"&gt;Site5&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="just-two-days"&gt;
&lt;h2&gt;Just two days&lt;/h2&gt;
&lt;p&gt;Thanks to djangoprojects.com's blog application I was able to port my wordpress content to django and create some templates in just two days.  How do you like the new look?&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-diario"&gt;
&lt;h2&gt;django-diario&lt;/h2&gt;
&lt;p&gt;The next day I found &lt;a class="reference external" href="http://code.google.com/p/django-diario/"&gt;django-diario&lt;/a&gt; which is a simple blog application that seems to be actively developed.  I plan on following diario's tickets and sending some patches.  In fact I already sent one in.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="todo"&gt;
&lt;h2&gt;Todo&lt;/h2&gt;
&lt;p&gt;I'd like to enable freecomments in diario for the time being.  I'll be looking into django-registration to add users so that I can do proper comments.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="django"></category><category term="news"></category><category term="site5"></category></entry><entry><title>10+2*5 bash script</title><link href=".././1025-bash-script.html" rel="alternate"></link><updated>2007-09-14T01:35:30Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2007-09-14:.././1025-bash-script.html/</id><summary type="html">&lt;p&gt;I've been meaning to post this script for a while. It's a little bash
script that I wrote to switch xmms playlists using &lt;a class="reference external" href="http://www.43folders.com/2005/10/11/procrastination-hack-1025/"&gt;Merlin Mann's
10+2*5 procrastination hack&lt;/a&gt;. It's could well be the greatest bit of
code I've ever written.&lt;/p&gt;
&lt;p&gt;I've been using it for weeks now, it works for me. It may work for you
or it may not. It's real simple, you can probably figure out how to fix
it if it doesn't work for you. Post a comment if it's broken on your
system.&lt;/p&gt;
&lt;p&gt;The script itself: &lt;a class="reference external" href="http://eric.themoritzfamily.com/upload/tenplustwo/tenplustwotimer.sh"&gt;tenplustwotimer.sh&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A scripts that runs it in small xterm window: &lt;a class="reference external" href="http://eric.themoritzfamily.com/upload/tenplustwo/tenplustwowin.sh"&gt;tenplustwowin.sh&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My two playlists, one EBM stream (for work), one Jazz stream (for
break): &lt;a class="reference external" href="http://eric.themoritzfamily.com/upload/tenplustwo/tenplustwo_pls.tar.gz"&gt;tenplustwo_pls.tar.gz&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A quick tip, to change the playlist I usually just save over the ten.pls
or the two.pls and when the phase changes it'll load the new playlist.&lt;/p&gt;
&lt;p&gt;What's great about using playlists instead of urls directly to the
stream is I can plug in my GMINI 402 and make two playlists from the
mp3s and
listen to my own stuff.&lt;/p&gt;
</summary></entry><entry><title>Xubuntu Day 3</title><link href=".././xubuntu-day-3.html" rel="alternate"></link><updated>2007-08-02T19:42:53Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2007-08-02:.././xubuntu-day-3.html/</id><summary type="html">&lt;p&gt;So it's been three days since I started using XFCE flavored Ubuntu. It's
been a pretty lovely existence, but I have a few tips that's I've come
across&lt;/p&gt;
&lt;div class="section" id="notification-daemon"&gt;
&lt;h2&gt;Notification Daemon&lt;/h2&gt;
&lt;p&gt;Stock Xubuntu doesn't come with a notification daemon that works with
XFCE installed. So those little popups that rise out of the task bar in
Gnome don't rise anymore and I end up missing things like new IMs, new
mail notifications, etc. Unfortunately, there is not a package in the
repositories for the xfce friendly notification daemon so you'll have to
compile it yourself. Follow these &lt;a class="reference external" href="http://devilsadvocate-chs.blogspot.com/2006/11/libnotify-popups-on-xubuntu-xfce4.html"&gt;instructions&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="mail-notifications"&gt;
&lt;h2&gt;Mail Notifications&lt;/h2&gt;
&lt;p&gt;Since I'm running Xubuntu in VMWare and I need Outlook running so that
Activesync will sync appointments to my Blackjack, It's hard to know
when new emails come in. Luckly, our Exchange server here provides IMAP.
I could run Evolution and get my mail in XFCE, but why should I have two
mail clients running. So what I did was set up two Mail Watcher panel
Applets, one for my corporate email and one for my personal Google Apps
for Domains account.
Unfortunately I was missing emails yesterday because by default, all the
Mail Watcher applet does when new mail comes in is change the icon. This
is what prompted me to get the notification daemon working. Details on
how to tie Mail Watcher and Notifications together are &lt;a class="reference external" href="http://xubuntublog.wordpress.com/2007/04/27/email-notification/"&gt;here&lt;/a&gt;
By the way, I absolutely love &lt;a class="reference external" href="https://www.google.com/a/"&gt;Google Apps for Domains&lt;/a&gt;, it's
brilliant. I wrote a little mailto: handler script for my wife's laptop
so that when she clicks on mailto: links anywhere, it opens gmail. I'll
provide that script sometime, it's a little 10 line beauty.&lt;/p&gt;
&lt;p&gt;Powered by &lt;a class="reference external" href="http://scribefire.com/"&gt;ScribeFire&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
</summary></entry><entry><title>Watch out Eric's gone Xubuntu</title><link href=".././watch-out-erics-gone-xubuntu.html" rel="alternate"></link><updated>2007-07-31T02:30:13Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2007-07-31:.././watch-out-erics-gone-xubuntu.html/</id><summary type="html">&lt;p&gt;So I was installing Ubuntu onto my wife's puny laptop (400 mhz, 512 ram)
and I thought I'd try something different and install Kubuntu because
she complained that she didn't like Linux because it doesn't look like
XP.
I forgot how under powered her laptop was, Ubuntu ran fine on it before
she accidentally reformatted the drive by putting some forgotten Fedora
Core CD in it and kept clicking &amp;quot;OK&amp;quot;, trying to make it go away, but
Kubuntu ran dog slow. It was bad, windows were tearing, drives were
swapping, it was a computing nightmare. I started googling, &amp;quot;How to
Replace Kubuntu with Ubuntu&amp;quot;, and somehow I came across Xubuntu, which I
never gave the light of day because regular Ubuntu ran fine, and I was
unimpressed whenever I used XFCE.
On, this puny 400 mhz laptop, it runs pretty good, much better than
Gnome ran. So, when I got in to work today I decided to make the switch
to Xubuntu on my PC.
So I fired up VMWare (I run my linux install in VMWare because I can't
touch the internals of this PC) Ran, &amp;quot;sudo apt-get install
xubuntu-desktop&amp;quot;, reboot and wala, XFCE in all it's glory!
In VMWare, Ubuntu(Gnome) didn't run super fast. It was useable, but
switching windows was a little laggy. XFCE, works beautifully (not
perfect, but a lot better).
I didn't really lose functionality, because a desktop environment is a
desktop environment, they all do pretty much the same thing. I'm not
sure I'm all that crazy with Thunar and the loss of gnome-vfs, but I can
make due.
So all and all I think switching to Xubuntu (Zoo-bun-tu?) is a great
Idea. Why would I not want run a resource intensive desktop environment
when I can have the same experience with a lighter desktop. Duh. Seems
like a no brainer...
Eric.&lt;/p&gt;
&lt;p&gt;Powered by &lt;a class="reference external" href="http://scribefire.com/"&gt;ScribeFire&lt;/a&gt;.&lt;/p&gt;
</summary></entry><entry><title>The KISS approch to GTD project planning</title><link href=".././the-kiss-approch-to-gtd-project-planning.html" rel="alternate"></link><updated>2007-07-05T19:18:03Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2007-07-05:.././the-kiss-approch-to-gtd-project-planning.html/</id><summary type="html">&lt;p&gt;I've never really got how projects work in GTD. I understand how &amp;quot;Next
Actions Lists&amp;quot; worked, but never understood how multi-action projects
worked in with that. This is what I came up with it. I'm not sure if
this is how it's done in GTD or not.&lt;/p&gt;
&lt;p&gt;Let's start with how a project is defined in GTD. A project is a goal
that has multiple actions associated to it in order to reach completion.
From what I've read of GTD, you keep those actions on a separate list
than your &amp;quot;Next Actions&amp;quot; list. That's fine and dandy, but I never did
that because it seemed to be just one more list to keep.&lt;/p&gt;
&lt;p&gt;So what is this &amp;quot;Next Actions&amp;quot; list that I mentioned? Those familiar
with the GTD process know it to be a list of atomic actions. Atomic
actions are actions that cannot be broken up into subtasks. Since these
actions are the simplest actions you can perform, they are the easiest
to complete and it's easy to keep your work flowing smoothly.&lt;/p&gt;
&lt;p&gt;This morning I have a project that I need to work on. It's a project
that consists of a lot of subtasks of many different types (research,
programming, documenting, testing) When looking at this project as a
whole, it's overwhelming. I don't know where to start. So I thought,
&amp;quot;Let me start with the goal, &amp;quot;Write a PUSH service for a search engine&amp;quot;.
That is an action that could be simply added to my task list, but it's
not atomic. This action has many sub-actions, so therefore it's a
project, not a next action. I need to break this up into atomic next
actions. Anyone that knows how to factoring prime numbers, the process I
used is similar to that.&lt;/p&gt;
&lt;p&gt;So I started with the task:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Write a PUSH service for a search engine&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next I thought what actions are needed to accomplish that:&lt;/p&gt;
&lt;p&gt;1. Write a PUSH service for a search engine
1.1 Find out how to write a Mason template for the search engine system
1.2 Find out how to make it spit out XML
1.3 Write a template that will output the search results as XML&lt;/p&gt;
&lt;p&gt;Ok, actions, 1.1 and 1.2 seem to be atomic to me. There isn't much more
complexity to those actions. I could split it up further into, &amp;quot;1.1.1
Google for docs about Mason, 1.1.2 Read docs&amp;quot;... but let's not get
obsessive now. There has to be some limit to factoring an action.&lt;/p&gt;
&lt;p&gt;So 1.1 and 1.2 are atomic, groovy. Let's look at 1.3. I could say that
1.3 is atomic, it seems simple enough, but it really isn't. There are at
least two actions I need to do.&lt;/p&gt;
&lt;p&gt;1.3 Write a template that will output the search results as XML
1.3.1 Define the XML format that will be generated
1.3.2 Write Template&lt;/p&gt;
&lt;p&gt;There might be more that that, but I'll revisit 1.3 when I get to it.&lt;/p&gt;
&lt;p&gt;How does the &amp;quot;Next Action&amp;quot; list come into play? The Next Action list
acts as a filter to keep only one action of a project in view at a time.
So what I do is put, 1.1 on my next action list, when it's completed I
put 1.2 on there, then 1.3.1 (not 1.3 because it's not atomic), then
1.3.2. I never have more than one atomic action from a project list on
the next action list at a time.&lt;/p&gt;
&lt;p&gt;Having only one item from the project list keeps my mind focused on the
action at hand and not the whole project. I'm not tempted to look down
the list and imagine the mammoth project that the ten actions scattered
among the other actions represents. That's the point of GTD, keep the
mind focused on the simplest thing and at a time when the mind should be
focused on it.&lt;/p&gt;
&lt;p&gt;The other advantage of not having all a project's actions on my next
action list is my next action list isn't bloated by things I can not
take care of before the action before them is completed. The next action
list has to be a list of actions that any could be completed at this
moment. No action can be dependent on another action.&lt;/p&gt;
&lt;p&gt;Review:&lt;/p&gt;
&lt;p&gt;1. Determine a goal, factor that goal into atomic actions. This is your
project list.
2. Place only one action from the project list on your next action list
3. No action on your next action list can be dependent on another action&lt;/p&gt;
&lt;p&gt;Final tip for project lists: Keep your project list simple as well. If
your finding that your project has more that three levels, your project
goal may be too lofty. Split the first level into sub-projects. You
should never have to look at a single piece of paper and feel the world
collapse, something is wrong, simplify.&lt;/p&gt;
</summary></entry><entry><title>Satechi's Bluetooth A2DP/Handsfree FM Carkit</title><link href=".././satechis-bluetooth-a2dphandsfree-fm-carkit.html" rel="alternate"></link><updated>2007-06-19T20:29:07Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2007-06-19:.././satechis-bluetooth-a2dphandsfree-fm-carkit.html/</id><summary type="html">&lt;p&gt;I recently acquired a &lt;a class="reference external" href="http://satechi.com/Bluetooth-Stereo-A2DP-HandsFree-Fm-Transmitter/M/B000NVYVRO.htm"&gt;Satechi's A2DP/Handsfree FM Carkit&lt;/a&gt;. What it
does is provide both a &lt;a class="reference external" href="http://en.wikipedia.org/wiki/A2DP#Advanced_Audio_Distribution_Profile_.28A2DP.29"&gt;A2DP&lt;/a&gt; Bluetooth profile and a Handsfree profile
and transmits the bluetooth audio to your radio via FM. This was the
holy grail I've been looking for, streaming &lt;a class="reference external" href="http://www.shoutcast.com"&gt;shoutcast&lt;/a&gt; to my car
stereo.&lt;/p&gt;
&lt;p&gt;I don't have &lt;a class="reference external" href="http://en.wikipedia.org/wiki/3G"&gt;3G&lt;/a&gt; in Ft Myers, but in Miami this weekend I had all that
3G goodness to my disposal. I installed &lt;a class="reference external" href="http://www.smartphone-freeware.com/download-tcpmp-0-81rc-subtitles-plugin.html"&gt;TCPMP&lt;/a&gt; on my Samsung Blackjack
and fired up some &lt;a class="reference external" href="http://www.shoutcast.com/directory/index.phtml?s=ebm"&gt;EBM shoutcast streams&lt;/a&gt; like &lt;a class="reference external" href="http://biodustrial.com/"&gt;Bioindustral&lt;/a&gt; or &lt;a class="reference external" href="http://www.rantradio.com/"&gt;Rant
Radio&lt;/a&gt; and was cruising down`Biscayne Blvd`_ listening to some crazy
EBM/Sythpop, all streaming through the Internet on my phone!&lt;/p&gt;
&lt;p&gt;I personally love that kind of music but I'm not going to devote a
library of MP3s to it. The music is so different from my normal
listening habits that putting my PMP on shuffle with EBM mixed in with
&lt;a class="reference external" href="http://www.myspace.com/theagencyrock"&gt;&amp;quot;The Agency&amp;quot;&lt;/a&gt; or &lt;a class="reference external" href="http://www.hotwatermusic.com/"&gt;&amp;quot;Hot Water Music&amp;quot;&lt;/a&gt;, just wouldn't go. So I usually
get my EBM fix via shoutcast streams (It's great coding music).&lt;/p&gt;
&lt;p&gt;So the A2DP functionality is absolutely great. No wires, nice crisp
stereo sound. It's just great. The hands free... It works but, not
great. I have to turn down my radio to avoid echoing, but it works well
enough to: pause my music, take a call and tell them &amp;quot;I'm driving, I'll
call back&amp;quot; and start my music up again (that process is automatic on my
Blackjack by the way, just press the answer button). Frankly I don't
want to talk when I'm listening to some good music, but that's just me.&lt;/p&gt;
&lt;p&gt;The overall experience with this product is that it makes a great A2DP
to FM transmitter but a lousy hands free device. Fortunately I wanted it
for the A2DP and it works great, so I'm not that bummed about it. If you
want to send music from your phone to your stereo wirelessly, then this
is the one and only device for you.&lt;/p&gt;
</summary></entry><entry><title>How Beryl/XGL and Deskbar simplified my life</title><link href=".././how-berylxgl-and-deskbar-simplified-my-life.html" rel="alternate"></link><updated>2006-10-25T07:55:35Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2006-10-25:.././how-berylxgl-and-deskbar-simplified-my-life.html/</id><summary type="html">&lt;p&gt;&lt;a class="reference external" href="http://eric.themoritzfamily.com/wp-content/uploads/2006/10/Screenshot.png"&gt;|Screenshot of my simple gnome|&lt;/a&gt; Screenshot of my current desktop&lt;/p&gt;
&lt;p&gt;Yesterday I was playing with Gnome's basic layout and I decided because
&lt;a class="reference external" href="http://raphael.slinckx.net/deskbar/"&gt;Deskbar&lt;/a&gt; was so good at locating what I wanted that it was quicker to
use Deskbar than the standard Gnome application list. I decided to take
things farther and remove some key GUI standards from my screen because
I found that using alternative methods of accomplishing the same thing
were quicker.&lt;/p&gt;
&lt;div class="section" id="removed-the-application-menu"&gt;
&lt;h2&gt;Removed the Application Menu&lt;/h2&gt;
&lt;p&gt;First I removed the application menu in favor of using Deskbar. It's
much quicker to hit the Deskbar keyboard shortcut and type out &amp;quot;web&amp;quot; or
&amp;quot;mail&amp;quot; to launch Firefox or Evolution. The application menu is still
accessible by pressing Alt-F1. The benefit of ALT-F1 is that it opens
the menu where the cursor is. This reduces the amount of movement the
mouse has to do to accomplish the same thing. I'm also able to use the
arrow keys to choose an item in the application menu&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="replaced-the-run-dialog-with-deskbar-by-mapping-it-to-alt-f2"&gt;
&lt;h2&gt;Replaced the Run Dialog with Deskbar by Mapping it to Alt-F2&lt;/h2&gt;
&lt;p&gt;Normally the run dialog is mapped to the shortcut Alt-F2. Because
Deskbar includes the ability to run an application by the executable
name, there was a overlap of functionality between the run dialog and
Deskbar. Replacing the run dialog with Deskbar does not remove any
functionality. In fact Deskbar gives me more functionality.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="removed-the-standard-gnome-window-list"&gt;
&lt;h2&gt;Removed the Standard Gnome Window List&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="image::http://eric.themoritzfamily.com/wp-content/uploads/2006/10/Screenshot-1.png"&gt;|Example of the Scaling Plugin|&lt;/a&gt; Scaling Plugin&lt;/p&gt;
&lt;p&gt;I removed the standard Gnome Window List in favor of Beryl's Scale
plugin. Beryl's Scale functionality resembles OSX's Expose
functionality. Because the Scale plugin displays all the windows
currently open and unminimized at a keypress, I can quickly find the
window I want visually and select it either with the mouse or with the
arrow keys.&lt;/p&gt;
&lt;p&gt;The one flaw I had always found with the window list is once you get
more than five windows open, you can no longer see the window title and
easily identify the window you want. What also tends to happen is when I
have multiple windows open, the only thing I can see is the logo of the
window and no more. This makes it extremely difficult to find a window.&lt;/p&gt;
&lt;p&gt;Another problem is when I have multiple Gnome Terminal windows open. The
title bar with Gnome Terminal is usually the current directory I am
working in. Trying to find the window by the current working directory
is not enough to determine the correct window and I end up clicking a
number terminals before finding the correct one. Being able to see all
the windows currently open, I can see the terminal that resembles the
shell I'm looking for.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="change-my-perception-of-minimize"&gt;
&lt;h2&gt;Change My Perception of &amp;quot;Minimize&amp;quot;&lt;/h2&gt;
&lt;p&gt;Because I no longer have a window list in my panel, I can no longer
easily find windows that I've minimized. The solution I found to
alleviate this problem is to change my perception of what minimize is
used for.&lt;/p&gt;
&lt;p&gt;Instead of using minimize to put the window in the window list but not
on my screen I now think of it as hiding the window. To find the window,
I added the window selector applet to my main panel. That way I can find
the window I hid.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="fitts-law"&gt;
&lt;h2&gt;Fitts' law&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://blogs.msdn.com/jensenh/archive/2006/08/22/711808.aspx"&gt;Fitts law&lt;/a&gt; is a well know model in ergonomics and user interfaces.
Granted I'm not a usability expert by no means but I doubt you have to
be one to understand Fitts. This is an over simplification of the law,
but I'll try to explain it. When it applies to the mouse cursor, Fitts'
law says that the time to hit a target is related to the target's size
and the distance from the starting point.&lt;/p&gt;
&lt;p&gt;For instance moving the mouse from the center of the screen to a target
a hundred pixels to the right takes a certain amount of time. The size
of the target also plays a part because a large target is easier to put
the cursor on than a small target. With a small target you have to be
careful not to overshoot the target and therefore you have to slow down
when you get near the target.&lt;/p&gt;
&lt;p&gt;Another principle of Fitts' Law is if the target is in a location where
you cannot overshoot, you do not have to slow down to hit it regardless
of it's size. The target is thought to have an infinite size and
therefore it is easier and quicker to hit the bottom of the screen than
it is to hit a 64x64 size icon sitting 10 pixels from the bottom of the
screen. This principle is a key reason for Apple putting the menus for
applications on the top of the screen as opposed to within the window
like Windows/Gnome/KDE does.&lt;/p&gt;
&lt;p&gt;The key way to understand the application of Fitts law is to understand
that it only applies to one dimension at time. The distance is either
horizontal or vertical. Even though you may move the mouse diagonal to
reach a target there is actually two distances in play. You are both
moving the mouse horizontally and vertically when you move it
diagonally.&lt;/p&gt;
&lt;p&gt;How Fitts' Law is used on my desktop&lt;/p&gt;
&lt;p&gt;Though you can't see most of the applications of Fitts in the my
screenshot, it is used in a few places:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;The window selector panel applet that I use to locate hidden
(minimized) windows is located in the topp left. This gives window
selector icon infinite width and height because it's in the corner.
If I'm too low and continue to move the mouse cursor to the left past
the left edge of the screen the cursor will slide upwards into the
corner.&lt;/li&gt;
&lt;li&gt;The Scale plugin is activated by simply moving the cursor to anywhere
on bottom edge of the screen. This gives that target an infinite
height because the target is on the bottom and an infinite width
because it doesn't matter where on the bottom I hit. All I have to do
is fling the cursor to the bottom of the screen and I see all my
visible windows.&lt;/li&gt;
&lt;li&gt;Deskbar is on the top center of the screen. While I generally use the
shortcut to access Deskbar. Putting it on the top of the screen gives
it an infinite height. It is also in the center of the panel,
although this does not give it a infinate width, it substantially
increasses the ease of hitting the target. Having the deskbar applet
in the center makes the max distance horizontally no more than half
the screen minus the width of the Destbar applet. If the deskbar was
on the left or right side of the panel the max distance horizontally
would be the width of the screen minus the width of the deskbar
applet. I also made the width of the deskbar applet nearly 50% of the
screen. 90% of the time the cursor would be between the second
quarter and fourth quarter the of the screen. So the max distance
horizontally is essentially zero because more often than not I would
not have to move the cursor horizontally to get to the deskbar.
Moments when my cursor is within the 1st quarter or the 4th quarter
of the screen, the max distance my mouse would have to travel would
be a quarter of the screen.&lt;/li&gt;
&lt;li&gt;The Scaling plugin has the ability to display only windows from a
single application, all applications on the current virtual desktop,
and all windows. I've mapped the &amp;quot;Show all windows of a single
application&amp;quot; function to the top right of the screen so that it has
infinite width and height. This is good when I have multiple Firefox
windows open.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The Fitts Optimized Targets All Have Keyboards Shortcuts to reduce hand
movement
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;/p&gt;
&lt;p&gt;I am a Dvorak keyboard user and a huge fan of Ratpoison. The main goal
of both the Dvorak layout and Ratpoison is to reduce the movement of
your hands. It takes a lot of time, both physically and mentally to
switch from keyboard mode to mouse mode and vice-versa.&lt;/p&gt;
&lt;p&gt;While I probably use the keyboard more than the average joe, it's no
secret that we live in a point and click world. It's common for me to be
surfing the web and need to switch to another window. Hence the Fitts
optimized trigger for the scale plugin. It's also not uncommon for me to
be hacking away in Emacs and need to switch to another window. It would
be a waste of energy to move my hand from the keyboard, grab the mouse
and fling it to the bottom to see all the windows.&lt;/p&gt;
&lt;p&gt;To minimize the movement of my hand from the keyboard to the mouse and
back again, all areas of the screen that were chosen because they are
Fitts optimized to reduce mouse movement have a keyboard shortcut to
reduce hand movement.&lt;/p&gt;
&lt;p&gt;If I decide I want to choose another window while my hand is on the
mouse, I simply fling the cursor to the bottom and select the window
with the mouse cursor. If I have my fingers on the keyboard, I simple
hit F8 and use the arrow keys to select the window I want.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="decreased-the-importance-of-the-desktop"&gt;
&lt;h2&gt;Decreased the importance of the Desktop&lt;/h2&gt;
&lt;p&gt;Normally the Nautilus file browser is the central application when
interacting with the computer. I deactivate the icons on the desktop
with gconf . There are three reasons for me to do this. The first reason
is I wanted to use Nautilus like any other application. The second
reason is the desktop usually gets cluttered with files, the third
reason is that there is an easier way of accessing your files than
desktop icons.&lt;/p&gt;
&lt;p&gt;To prevent the clutter, I took a cue from Windows and OSX and created a
number of folders in my Desktop folder:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;strong&gt;Applications&lt;/strong&gt;, these are user installed applications that would
normally go in opt if installed system wide. Applications like
Songbird, Opera, Limewire go in here.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reference&lt;/strong&gt;, the idea for this folder was taken from &amp;quot;Getting
Things Done&amp;quot;. It holds all kinds of reference information, generally
saved documents that will need to be referenced later. I avoided
calling it the vague term, &amp;quot;Documents&amp;quot;, because a document could be
anything. The name &amp;quot;Reference&amp;quot; defines the purpose of these files.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Media&lt;/strong&gt;, obviously media files. This has subfolders to keep this
folder from getting cluttered&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Images&lt;/strong&gt;&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;strong&gt;Photos&lt;/strong&gt;, actual photos taken from my camera&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Illustrations&lt;/strong&gt;, Vector based images&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Backgrounds&lt;/strong&gt;, I seperate backgrounds from photos or
illustrations because backgrounds are generally novalties. The
name &amp;quot;Backgrounds&amp;quot; also describes the purpose of these files.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Novalites&lt;/strong&gt;, Images that completely pointless but funny&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Videos&lt;/strong&gt;&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;strong&gt;Movies&lt;/strong&gt;, Full length movies that I've ripped from DVDs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TV Episodes&lt;/strong&gt;, TV episodes that I've downloaded&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Novalties&lt;/strong&gt;, Novalties items like silly you tube videos of
people falling over or cats attacking cealing fans. Basically
mental junk food.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With these folders I've created bookmarks in Nautilus so that I can
easily access these folders from, the nautilus side bar, choose/save
file dialog or deskbar's &amp;quot;File and File Bookmarks&amp;quot; plugin.&lt;/p&gt;
&lt;p&gt;The reason why this is easier use than using the desktop for storing
files is that it's quicker to get to the files you need using deskbar.&lt;/p&gt;
&lt;p&gt;The normal way to access the desktop is that you need to either use the
show desktop icon, or use the beryl show desktop plugin. Once you get to
the desktop, if you keep all your stuff on the desktop, you're done, but
you have a cluttered desktop.&lt;/p&gt;
&lt;p&gt;If you keep all your stuff in sub folders of the desktop, you need first
locate the subfolder on the desktop, then locate the files in that
folder. It's a multistep process.&lt;/p&gt;
&lt;p&gt;Using Nautilus bookmarks and the &amp;quot;Find File and File Bookmarks&amp;quot; deskbar
applet is that to get to the subfolder that's on the desktop, it's a two
step process: Click on deskbar and type subfolder name. The normal way
would be: Show the desktop, locate the folder, open the folder. It may
seem like a one extra step, but the time it takes to locate the folder
takes longer to do than typing in the name. You could say that the old
method is two steps more because typing a name is so much quicker than
scanning the desktop for an icon&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="limitations"&gt;
&lt;h2&gt;Limitations&lt;/h2&gt;
&lt;p&gt;Although I think that this setup is great, and it's optimized allow me
to do many of my common tasks with very little effort and energy, there
are a few flaws. This set up is also only a day old and I'm sure I'll
find others. I'll append this section with any that I find.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Once the Gnome Volume Manager (the thing that monitors the system for
removable media) mounts a drive, I can not unmount the drive from
Nautilus. The only way that Gnome made it possible to unmount
removable media is by the desktop icon. I'm sure that there is a way
to umount a drive with some sort of panel applet but for the moment,
I simply run &amp;quot;pumount [mount point]&amp;quot; in the terminal.&lt;/li&gt;
&lt;li&gt;When deskbar hangs, I can no longer launch anything. The solution
I've found is to hit ALT-F1, open up the application menu, open
terminal, and kill deskbar.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</summary></entry><entry><title>Open Source Dental Software!</title><link href=".././open-source-dental-software.html" rel="alternate"></link><updated>2006-08-26T16:01:31Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2006-08-26:.././open-source-dental-software.html/</id><summary type="html">&lt;p&gt;I went to the dentist the other day and I noticed the app running on
their computer had the title, &amp;quot;Open Dental&amp;quot;. I thought, as I sat in the
dental chair. Is he using an open source dental app? Sure enough, he
was.
&lt;a class="reference external" href="http://www.open-dent.com/"&gt;read more&lt;/a&gt; | &lt;a class="reference external" href="http://digg.com/programming/Open_Source_Dental_Software"&gt;digg story&lt;/a&gt;&lt;/p&gt;
</summary></entry><entry><title>coastalbeat.com woot woot!</title><link href=".././coastalbeatcom-woot-woot.html" rel="alternate"></link><updated>2006-08-26T13:59:54Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2006-08-26:.././coastalbeatcom-woot-woot.html/</id><summary type="html">&lt;p&gt;So the past three days have been a blur. I got into work on Wednesday
with forty-eight hours of work and twenty-four hours to do it. I was not
letting the new site launch without the social app I've been writting
for the past week or two. After staying up twenty four hours I finally
finished the app and the site went live to the public. Check it out:
&lt;a class="reference external" href="http://www.coastalbeat.com/"&gt;http://www.coastalbeat.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I am very proud of this site. Finally something to work on that I can
really feel good about being involved with. Todd's design is awesome,Â
Ira and Tovin really busted their asses to get coastalbeat.com on the
stands and get content online.Â Levi put in some ungodly hours (I think
he has 300 skill points in endurance) to get it up.Â Props go out to all
those the helped out that I don't know about.Â Â I'm really proud of the
work we all did!
Check out my &lt;a class="reference external" href="http://www.coastalbeat.com/social/eric/"&gt;profile&lt;/a&gt;, I'm costalbeat's Tom! I think there's talks of
&amp;quot;&lt;a class="reference external" href="http://www.jinx.com/scripts/details.asp?affid=-1&amp;amp;productID=599"&gt;Eric is NOT my friend&lt;/a&gt;&amp;quot; and &amp;quot;&lt;a class="reference external" href="http://www.tshirthell.com/store/product.php?productid=601"&gt;Eric is my only friend&lt;/a&gt;&amp;quot; t-shirts.&lt;/p&gt;
</summary></entry><entry><title>RSS increases boredom.</title><link href=".././rss-increases-boredom.html" rel="alternate"></link><updated>2006-06-23T10:00:08Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2006-06-23:.././rss-increases-boredom.html/</id><summary type="html">&lt;p&gt;Remember back in the day when you could waste hours clicking on the net
finding information.Â It was fun, you felt like you were &amp;quot;surfing&amp;quot; the
net.Â Â I just finished reading my feeds on bloglines, going through the
links on digg.com, I even checked out slashdot to see artcles that I
read yesturday.Â Then I thought, now what.Â I don't know what to do
next.&lt;/p&gt;
&lt;p&gt;With RSS, everything gets aggregated into a personality-less list of
articles.Â After I go through all the artcles, I find myself wondering
what to do next.Â Wtih all this new &amp;quot;web 2.0&amp;quot; technology, are we losing
the personality of the net?&lt;/p&gt;
</summary></entry><entry><title>Test Tube Meat Nears Dinner Table</title><link href=".././test-tube-meat-nears-dinner-table.html" rel="alternate"></link><updated>2006-06-23T08:47:20Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2006-06-23:.././test-tube-meat-nears-dinner-table.html/</id><summary type="html">&lt;p&gt;If they can produce meat in vitro? For vegitarians like myself that
don't eat meat because animals have to die, would I eat it? I don't
know.&lt;/p&gt;
&lt;p&gt;It's an interesting quandery. I don't eat meat because mainly because of
the Buddhist belief that if we have had an infinate number of rebirths
then every being has once been our mother and that they are still our
mothers. Chewing on the flesh of my mother sounds absolutely discusting
to me.&lt;/p&gt;
&lt;p&gt;So if muscle tissue can be produced in a lab, it's not technically flesh
and definately not the flesh of another living being. Is it any less
discusting? I doubt it.&lt;/p&gt;
&lt;p&gt;I do eat veggie burgers which resemble meat, so I don't know what I
would think of eating something that is essentially flesh.&lt;/p&gt;
&lt;p&gt;I'll just have to wait and form an oppinion when this stuff is in the
market.
&lt;a class="reference external" href="http://www.wired.com/news/technology/0,71201-0.html"&gt;read more&lt;/a&gt; | &lt;a class="reference external" href="http://digg.com/science/"&gt;digg story&lt;/a&gt;&lt;/p&gt;
</summary></entry><entry><title>URGE and iTunes</title><link href=".././urge-and-itunes.html" rel="alternate"></link><updated>2006-06-20T09:30:18Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2006-06-20:.././urge-and-itunes.html/</id><summary type="html">&lt;p&gt;I got a chance to take a look at Vista Beta 2. While I'm not normally a
guy that likes MS products. At first glance, Vista looks good. I could
never forget what my wife said when I showed it to here, &amp;quot;That looks
like Linux&amp;quot;. What?&lt;/p&gt;
&lt;p&gt;Anyhow, this post is not about Vista, but a service that comes bundled
with Vista called, URGE. URGE is Microsoft's and MTV's joint venture
into the online music sales market. There is one good thing with the
service and a few flaws I see with the service.&lt;/p&gt;
&lt;p&gt;One of the good things with the service is that you can pay a flat rate
every month, $14.95 I believe, and download as much as you want. That
sounds like a deal to me. I see many music pirates going legit with such
a plan. I just hope they don't screw the pooch on this one and make the
songs expire after a month.&lt;/p&gt;
&lt;p&gt;And now for the problems I see. URGE is bundled with Vista. This
technique has proven a dangerous practice with Microsoft **cough IE
**. What I see happening is other music services will cry and say that
because URGE is preinstalled, it's hard to get customers.&lt;/p&gt;
&lt;p&gt;The second problem is that URGE doesn't work with iPods. It uses MS'
Play's for Sure DRM with works with just about every portable music
player I've seen except the iPod. I don't know if this was a great plan
on Microsoft's part to get all those pmp's out there to gang up on the
iPod, but all those iPod owners are gonna see that the iPod restricts
them to giving Apple money via the iTunes music store and that they have
no freedom of choice (i.e. Apples' Monopoly on iPod's money).&lt;/p&gt;
&lt;p&gt;While I don't think the second flaw is a flaw with URGE, but more a
revelation of Apple locking iPod owners to iTunes when legally
purchasing music. There will be two outcomes to this revelation. Apple
will open on their AAC DRM to others, so that other services can provide
music for the iPod. The other outcome will be that iPod's will provide
support for MS' Play's for Sure DRM. Both outcomes means a loss of
control for Apple.&lt;/p&gt;
&lt;p&gt;We'll see what happens, until the war of the DRM's begins, iPod owners
will be left in out of URGE's 14.95/mo unlimited downloads and will
either pay Mr. Jobs for their music or continue pirating.&lt;/p&gt;
</summary></entry><entry><title>A cool google map/wiki mash up</title><link href=".././a-cool-google-mapwiki-mash-up.html" rel="alternate"></link><updated>2006-05-29T04:55:31Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2006-05-29:.././a-cool-google-mapwiki-mash-up.html/</id><summary type="html">&lt;p&gt;I found this the other day, it's pretty cool. You can create a personal
map by clicking on the map and type in a description.
&lt;a class="reference external" href="http://www.gmapme.com"&gt;read more&lt;/a&gt; | &lt;a class="reference external" href="http://digg.com/technology/"&gt;digg story&lt;/a&gt;&lt;/p&gt;
</summary></entry><entry><title>Say F.U. to linux passwords</title><link href=".././say-fu-to-linux-passwords.html" rel="alternate"></link><updated>2006-05-16T02:19:19Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2006-05-16:.././say-fu-to-linux-passwords.html/</id><summary type="html">&lt;p&gt;I bought a 128 meg usb drive from radio shack because it was on
clearance and fit on my keychain. I was trying to find reasons to use it
and I found, pam_usb. PAM_USB allows you to store a dsa key on your
usb drive that, when plugged in (it doesn't have to be mounted, just
plugged in). Despite a scary description on the page, it was pretty easy
to install.
&lt;a class="reference external" href="http://www.pamusb.org/"&gt;read more&lt;/a&gt; | &lt;a class="reference external" href="http://digg.com/linux_unix/"&gt;digg story&lt;/a&gt;&lt;/p&gt;
</summary></entry><entry><title>Hong Kong's Symphony of Light (with video)</title><link href=".././hong-kongs-symphony-of-light-with-video.html" rel="alternate"></link><updated>2006-05-01T21:25:31Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2006-05-01:.././hong-kongs-symphony-of-light-with-video.html/</id><summary type="html">&lt;p&gt;Honk Kong lights up the skyline every night with this spectacular show
of syncronized lasers, leds and fireworks. Makes Epcot look lame.
&lt;a class="reference external" href="http://www.laservision.com.au/hongkong/"&gt;read more&lt;/a&gt; | &lt;a class="reference external" href="http://digg.com/hardware/"&gt;digg story&lt;/a&gt;&lt;/p&gt;
</summary></entry><entry><title>Budgeting</title><link href=".././budgeting.html" rel="alternate"></link><updated>2006-02-07T22:42:58Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2006-02-07:.././budgeting.html/</id><summary type="html">&lt;p&gt;When I was younger budgeting was easier. The reason it was easier
because I didn't use a bank account and I would simply put money in
designated envelopes. Life was simple.&lt;/p&gt;
&lt;p&gt;Now that I'm a responsible adult, I have a bank account and I rarely
have cash in my hands. The envelope idea doesn't work.&lt;/p&gt;
&lt;p&gt;Last night on my drive home from work I was day dreaming about how I
could budget like I used to in this age of bits and bytes. Budgeting on
a computer doesn't give that instant response of &amp;quot;Oh crap, I don't have
any cash for clothes left&amp;quot; as an empty envelope.&lt;/p&gt;
&lt;p&gt;The idea I came up with was using poker chips to represent the money
allocated for a particular catagory.&lt;/p&gt;
&lt;p&gt;I'm still pondering how I would want to store the chips so that it's
obvious how much is left. I want to easily gaze at each &amp;quot;envelope&amp;quot; and
see how much is left so that I can start to curb my spending when the
budget is low.&lt;/p&gt;
&lt;p&gt;I saw online that there are clear holders for chips that I would be able
to easily stack the chips in columns for each category. They usually
have 5 column (one for each chip color) but I think I might have more
categories than that so that may not be good. Using the holder also
means having to either buying the holder online or searching stores for
them.&lt;/p&gt;
&lt;p&gt;What I came up with for now is using ziplock bags instead of envilopes.
They're easy to aquire and they're clear. We'll see how well it works.&lt;/p&gt;
&lt;p&gt;I haven't implemented my idea as of yet, I'll let everyone know how well
it works.&lt;/p&gt;
</summary></entry><entry><title>Oh yeah. GMINI 402 baby.</title><link href=".././oh-yeah-gmini-402-baby.html" rel="alternate"></link><updated>2006-01-14T09:21:25Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2006-01-14:.././oh-yeah-gmini-402-baby.html/</id><summary type="html">&lt;p&gt;My wife got me a GMINI 402 for Christmas. I wanted to wait a few weeks
before actually writing about my experience with it. My first expression
when I opened the box was that it was smaller than I thought it would
be. It is a very nice size. The case of the device is metal which makes
it feel really solid.&lt;/p&gt;
&lt;div class="section" id="audio"&gt;
&lt;h2&gt;Audio&lt;/h2&gt;
&lt;p&gt;What is there to say, it's a mp3 player. It plays mp3s. I like the
ability to create playlists on the device. I can browse by artist and
press add and it adds all that artist's songs to the playlist.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="video"&gt;
&lt;h2&gt;Video&lt;/h2&gt;
&lt;p&gt;This is were the device shines. I thought before I bought the device
that I would have to transcode all my videos to mp4's but after a few
weeks of use, I've noticed that I usually can just download the video
and dump it on the device as long as it's an avi encoded as divx with
mp3 audio which is proving to be the most common format I've found. The
only time I have to reencode the video is if it's a mp4 quicktime file
(which is what ipods/psps play). Being able to download and drop the
file into the device is really nice.&lt;/p&gt;
&lt;p&gt;So far, I'm really impressed with the device.&lt;/p&gt;
&lt;/div&gt;
</summary></entry><entry><title>New Position at Naples Daily News</title><link href=".././new-position-at-naples-daily-news.html" rel="alternate"></link><updated>2005-11-29T09:05:50Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-11-29:.././new-position-at-naples-daily-news.html/</id><summary type="html">&lt;p&gt;One of the most respected and award-winning newspaper Web teams in the
world has moved to Florida and is looking for an experienced server-side
Web developer.&lt;/p&gt;
&lt;p&gt;NDN Productions -- the online and new media publishing division of the
Naples Daily News -- is looking for a full-time Python programmer to
develop Internet-based applications that cross from computers to mobile
phones to iPods to Sony PSPs.&lt;/p&gt;
&lt;p&gt;We strive for innovation and nimble development for sites that embrace
relational databases in ways they've rarely been used on the local level
coupled with broadband-centric multimedia content that all works
together in a platform-independent manner.&lt;/p&gt;
&lt;p&gt;In other words, we strive to build the kinds of Web sites and related
offshoots that you wish were in your hometown.&lt;/p&gt;
&lt;p&gt;We're big believers and contributors to the open-source community. Our
primary development platform is Python (mod_python) and PostgreSQL,
with a particular emphasis on using the Django infrastructure.&lt;/p&gt;
&lt;p&gt;That being said, we believe a solid background in Web application design
is more important than knowledge of a particular language or platform.
If you're a smart cookie and it shows, we know that you'll have no
problems picking up the tools we use.&lt;/p&gt;
&lt;p&gt;We embrace a highly creative, non-traditional work environment. We love
to work fast and have fun, with the time between having a great idea and
that idea being added to one of our sites being measured in days, if not
hours.&lt;/p&gt;
&lt;p&gt;Our salary is competitive, though not crazy huge, and our benefits
package is sweet.&lt;/p&gt;
&lt;p&gt;And because our agile and autonomous online team works under the
umbrella of one of the largest and most stabile diversified media
companies in the nation, you don't have to worry about your checks ever
bouncing. If you work with us, your mom and dad will be proud, and your
friends will be envious.&lt;/p&gt;
&lt;p&gt;So, if you learn things quickly, want to hang out with cool people and
build amazing Web content, than this is the place for you.&lt;/p&gt;
&lt;p&gt;We're an equal-opportunity employer. In fact, we even hire folks from
Missouri.&lt;/p&gt;
&lt;p&gt;So, contact Rob Curley at NDN Productions right now before one of your
buddies beats you to this great gig.&lt;/p&gt;
&lt;p&gt;Rob Curley
Director of New Media
NDN Productions/The Naples Daily News
E &amp;gt;&amp;gt; &lt;a class="reference external" href="mailto:nerds&amp;#64;bonitanews.com"&gt;nerds&amp;#64;bonitanews.com&lt;/a&gt;
P &amp;gt;&amp;gt; 239.435.347&lt;/p&gt;
</summary></entry><entry><title>Hey! You got some emo in my hair-band.</title><link href=".././hey-you-got-some-emo-in-my-hair-band.html" rel="alternate"></link><updated>2005-11-24T01:12:53Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-11-24:.././hey-you-got-some-emo-in-my-hair-band.html/</id><summary type="html">&lt;p&gt;I saw this band on MTV the other day, &lt;a class="reference external" href="http://www.coheedandcambria.com/"&gt;Coheed and Cambria&lt;/a&gt;. I'm really
digging their sound. It's like Rush if they decided to dive into 80's
hair metal. Many describe them as Emo Progressive rock. The lead singer
looks/sounds like the illegitimate son of the mother of the guy from
Counting Crows and the singer from Rush. Check them out.&lt;/p&gt;
</summary></entry><entry><title>We need a Django Developer</title><link href=".././we-need-a-django-developer.html" rel="alternate"></link><updated>2005-11-09T02:42:35Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-11-09:.././we-need-a-django-developer.html/</id><summary type="html">&lt;p&gt;There is now an opening at Naples Daily News for a new developer. If
anyone doesn't know what we're doing, let me fill you in.&lt;/p&gt;
&lt;p&gt;If you do a search for &amp;quot;Rob Curley&amp;quot; in Google you will notice that it'll
take 38 pages of Google before people stop talking about him. He
previously worked for &lt;a class="reference external" href="http://code.djangoproject.com/wiki/WorldOnline"&gt;World Online&lt;/a&gt; and helped propel them into New
Media stardom.&lt;/p&gt;
&lt;p&gt;Rob left Lawrence and has started making waves at Naples Daily News. It
is definitely the place to be if you want to win awards and become
famous.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.poynter.org"&gt;Poynter&lt;/a&gt;, which is the one of most prestigious journalism think tanks
in the country, this past month sent journalists to follow our work
during Hurricane Wilma because they wanted to see how &lt;a class="reference external" href="http://www.poynter.org/column.asp?id=68&amp;amp;aid=91058"&gt;we worked&lt;/a&gt;. CBS
also sent their reporters to Naples to cover us for the &lt;a class="reference external" href="http://www.bonitanews.com/mediagalleries/hurricane_wilma"&gt;Early Show&lt;/a&gt;.
We have just started and we already have the world's attention.&lt;/p&gt;
&lt;p&gt;I hope I'm not sounding pretentious but I'm very excited about the work
we've done and what we are going to do in the coming months. If there is
anyone out there that is interested in programming in Django full time
with one of the best New Media teams around, please let me know.&lt;/p&gt;
</summary></entry><entry><title>We survived.</title><link href=".././we-survived.html" rel="alternate"></link><updated>2005-11-06T20:03:53Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-11-06:.././we-survived.html/</id><summary type="html">&lt;p&gt;We finally got the our electric back since Hurricane Wilma. I just
wanted to let everyone know that we survived and we are safe. We
evaculated to Fort Lauderdale thinking that we'd be safer by putting 100
miles of land between us and were the hurricane makes landfall. If
anyone was watching this monster of a hurricane, Wilma was perdicted to
pass her eye directly over Naples, Fl. So prior to the Wilma's attack on
Florida, we thought that getting the hell out of dodge would be wise.&lt;/p&gt;
&lt;p&gt;Unfortunately, Fort Lauderdale was not ready for being raped by the
hurricane. We ended up getting stranded in Fort Lauderdale because no
gas stations were opened after the storm. Slowly stations opened but
with millions without power and millions using generators to watch tv
and have lights, chaos insued. There were/are miles of lines up to the
few stations opened. People waited in lines for hours. Some people were
unfortunate enough to wait in a line at a gas station that was never
going to open and they waited all day for gas and never got it. It was
insane. As far as I know, this is still happening.&lt;/p&gt;
&lt;p&gt;Because of the gas shortage, we were stranded in Fort Lauderdale. Our
friend owns a pizzaria and because they have a gas pizza oven they were
still being able to make pizza. So being stranded in Fort Lauderdale
wasn't all bad, we were getting hot meals, can't complain there. Someone
who came in for a hot pizza told he about how he drove to Fort Myers (a
little north of Naples) and filled up his truck and all his gas cans and
drove back.&lt;/p&gt;
&lt;p&gt;So, our friend came back from the restuarant and told us his master plan
of driving to Naples and grabbing as much gas as we could. By this time,
Naples was basically up and running aside from some residencial power
outages. Our car was on E so without gas, we were stranded in Fort
Lauderdale.&lt;/p&gt;
&lt;p&gt;Driving an hour and a half to Naples was much better than waiting in
line four hours for a chance to get gas, no guarntee at getting gas,
just for the chance the get gas. So my wife, our friend and I packed up
the baby, hopped in her car and drove to Naples.&lt;/p&gt;
&lt;p&gt;When we arrived in Naples, we gased up the car and searched for gas
cans. We had one flaw in our plan. We expected Naples to have gas cans
available to bring back to Fort Lauderdale to fill up our dry car. With
tens of thousands of residents without power, people needed gas cans to
keep their generators running. We drove to Super Walmart... No cans.. We
drove to Home Depot... No cans... We drove to Target... No cans...&lt;/p&gt;
&lt;p&gt;We drove to Lowes and finally we found six gas cans. We filled up the
cans and drove back to Fort Lauderdale. That night, we filled up our car
and drove home. It was quite an adventure.&lt;/p&gt;
</summary></entry><entry><title>Overwelmed by Web 2.0</title><link href=".././overwelmed-by-web-20.html" rel="alternate"></link><updated>2005-10-16T05:05:34Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-10-16:.././overwelmed-by-web-20.html/</id><summary type="html">&lt;p&gt;Prior to moving to Naples and taking the job at Naples Daily News, I was
kinda resisting the suite of &amp;quot;Web 2.0&amp;quot; technologies, Ajax, RSS,
Podcasting, etc.&lt;/p&gt;
&lt;p&gt;Sure I tried RSS, and I thought it was cool but I guess I never had a
decent client to collect the feeds. I thought it was a little involved
to collect the RSS sources. Firefox made it easy with their fandangled
little rss icon but Live bookmarks never seemed like the right interface
for RSS. I tried out Thunderbird's RSS feature. Again, a little involved
to find the feeds. I noticed that a coworker, Levi, used Bloglines, and
that was nice. Then I found &lt;a class="reference external" href="http://www.litefeeds.com"&gt;litefeeds&lt;/a&gt; which I really like primarily
for their cell phone interface. I'm starting to get a little overwelmed
by the shear volume of available RSS feeds. Which is good? So many, I
hardly have the time to find those I like...&lt;/p&gt;
&lt;p&gt;On Friday I upgraded &lt;a class="reference external" href="http://www.ubuntu.com"&gt;Ubuntu&lt;/a&gt; from Hoary Hedgehog to Breezy Badger...
Ok, oh my god, the best Linux distro eva'. Try it out, there's
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Live_CD"&gt;LiveCD's&lt;/a&gt;, no commitment needed.This isn't a post about Ubuntu, so let
me get back te the current topic. With the upgrade came the latest
version of &lt;a class="reference external" href="http://amarok.kde.org/"&gt;Amarok&lt;/a&gt;. No, this isn't that &lt;a class="reference external" href="http://www.omarosa.com/"&gt;annoying reality tv diva&lt;/a&gt;
from The Apprentise. This has to be the best audio player for Linux. If
you're using Linux, install this app. Even is you love Gnome and hate
KDE, install this app.&lt;/p&gt;
&lt;p&gt;So, anyhow, with the newest version of Amarok, you get podcast support.
Another one of those &amp;quot;Web 2.0&amp;quot; technologies I never got into. So today I
got my first taste of podcasts. It was fun, it tasted good. I downloaded
our new &lt;a class="reference external" href="http://www.bonitanews.com"&gt;Bonita News.com&lt;/a&gt; podcast and got to listen to Crunk Master Tim
sound all professional. I signed up to a few Buddhist themed podcasts,
the &amp;quot;Rock and Roll Geek&amp;quot; show, the &amp;quot;Keith and the Girl&amp;quot; podcast, so many
podcasts... Seems like anyone with a microphone has a podcast show. Who
has the time to listen to all those podcasts to become a fan of a few.&lt;/p&gt;
&lt;p&gt;If anyone is actually reading this thing, please post a few comments
about your favorite podcasts, blogs, rss feeds, etc. You'd make my &amp;quot;Web
2.0 life&amp;quot; easier.&lt;/p&gt;
</summary></entry><entry><title>Old and Busted: Bloglines, New Hotness: litefeeds</title><link href=".././old-and-busted-bloglines-new-hotness-litefeeds.html" rel="alternate"></link><updated>2005-10-09T00:08:45Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-10-09:.././old-and-busted-bloglines-new-hotness-litefeeds.html/</id><summary type="html">&lt;p&gt;Ever since I signed up for bloglines I kept thinking, &amp;quot;Man, RSS feeds
are perfect for cell-phones&amp;quot;. I flirted with the idea of creating a RSS
aggregator that outputted the content in xhtml-mp for my mobile browser.
Then I found &lt;a class="reference external" href="http://litefeeds.com"&gt;litefeeds&lt;/a&gt; and life is good.&lt;/p&gt;
&lt;p&gt;Litefeeds just like bloglines it's a web based RSS reader, but it has
one feature that Bloglines doesn't have, a j2me app for your cellphone.
What does that me to you? It means that you can get your feeds on your
java enabled phone. That's awesome.&lt;/p&gt;
&lt;p&gt;Other features: The ability to view images from users of flikr on your
phone, import from opml and therefore import from bloglines.&lt;/p&gt;
&lt;p&gt;Another cool feature, bloglines has this but it's infinately better on
your phone, it's the &amp;quot;clip it&amp;quot; function. What it does is save the
article into an online clipboard so that you can read it later. You can
do this on your phone, it's a minute detail that I'm very glad they
included it.&lt;/p&gt;
&lt;p&gt;Check it, let's say &lt;a class="reference external" href="http://www.lifehacker.com/"&gt;Life Hacker&lt;/a&gt;, which showcases useful apps and
sites, has an article reviewing an awesome application. I'm standing in
line at the DMV, I can't check out the application right at that moment,
but the article convinced me that this is &lt;strong&gt;the&lt;/strong&gt; killer app and I
&lt;strong&gt;need&lt;/strong&gt; to check it out. So, I clip it. When I get back home from DMV
hell, I can open up my laptop, bring up the site and get hip to that new
app. Awesome or what?&lt;/p&gt;
&lt;p&gt;There are a few features that I would add if I was in charge. One would
be displaying of images via an RSS' encloser tag so that I can get
Dilbert's feeds on my phone. If they can display flikr images on the
phone, there's no reason why we couldn't get that to work. Another
feature would be a &amp;quot;Add to litefeeds&amp;quot; type button for our blogs, MyYahoo
has it, Bloglines has it, no reason litefeeds shouldn't. A bookmarklet
would be nice too.&lt;/p&gt;
&lt;p&gt;Enjoy.&lt;/p&gt;
</summary></entry><entry><title>OK/Cancel</title><link href=".././okcancel.html" rel="alternate"></link><updated>2005-10-08T19:13:40Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-10-08:.././okcancel.html/</id><summary type="html">&lt;p&gt;I came across this really awesome comic strip for anyone who's in the
website making business. &lt;a class="reference external" href="http://www.ok-cancel.com/"&gt;Ok/Cancel&lt;/a&gt; It's funny because it's true.&lt;/p&gt;
</summary></entry><entry><title>Social Bookmarking</title><link href=".././social-bookmarking.html" rel="alternate"></link><updated>2005-10-08T12:26:37Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-10-08:.././social-bookmarking.html/</id><summary type="html">&lt;p&gt;So, I finally joined the social bookmarking craze. I've used &lt;a class="reference external" href="http://www.simpy.com"&gt;Simpy&lt;/a&gt;
before but I had some trouble with it. I finally got around to using
&lt;a class="reference external" href="http://del.icio.us"&gt;del.icio.us&lt;/a&gt; and so far I like it. I even added a Word Press plugin to
list my 10 most recent links. Enjoy.&lt;/p&gt;
</summary></entry><entry><title>Been busy</title><link href=".././been-busy.html" rel="alternate"></link><updated>2005-09-26T01:17:54Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-09-26:.././been-busy.html/</id><summary type="html">&lt;p&gt;Phew,... I've been busy, I've finally gotten a breather to update my
blog. Two weeks ago we launched`http://www.bonitanews.com`_. It is the
first Ellington/Django site launched outside of World Online. We're very
proud of it.&lt;/p&gt;
&lt;p&gt;Something else to be proud of, my son, &lt;a class="reference external" href="http://www.themoritzfamily.com/index.php?set_albumName=album01&amp;amp;option=com_gallery&amp;amp;Itemid=26&amp;amp;include=view_album.php"&gt;Aiden Jacob&lt;/a&gt;, was born on Sept.
8th. He is wonderfully healthy.&lt;/p&gt;
&lt;p&gt;Life is good here in Naples, Florida. I think we've finally acclimated
to the Neapolitan lifestyle.&lt;/p&gt;
&lt;p&gt;Be well.&lt;/p&gt;
</summary></entry><entry><title>All Hail the Flying Spaghetti Monster!</title><link href=".././all-hail-the-flying-spaghetti-monster.html" rel="alternate"></link><updated>2005-08-24T21:07:50Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-08-24:.././all-hail-the-flying-spaghetti-monster.html/</id><summary type="html">&lt;p&gt;Read &lt;a class="reference external" href="http://www2.ljworld.com/news/2005/aug/24/evolution_debate_creates_monster/?education"&gt;this&lt;/a&gt;&lt;/p&gt;
</summary></entry><entry><title>Naples Mindfulness Center</title><link href=".././naples-mindfulness-center.html" rel="alternate"></link><updated>2005-08-22T19:00:00Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-08-22:.././naples-mindfulness-center.html/</id><summary type="html">&lt;p&gt;Last night I went to my first Buddhist meditation class in Naples.
Anyone who has known me for an extended period of time or has browsed my
bookself knows that I am a practicing Buddhist. I've been studying
Buddhism for almost four years now. When I decided to take the job at
Naples Daily News, I looked into Buddhist groups in Naples and I was
saddened to find out that there is very little reputable Buddhist
organizations in Naples and the west coast in general.&lt;/p&gt;
&lt;p&gt;I found &lt;a class="reference external" href="http://www.naplesmindfulness.org/"&gt;The Naples Community of Mindfulness&lt;/a&gt; during my search. They
are students of &lt;a class="reference external" href="http://www.plumvillage.org/"&gt;Thich Nhat Hanh&lt;/a&gt;, who is a well respected and
accomplished Vietnamese Zen Master. Anyone who has browsed Barnes and
Nobels' Buddhist section has heard of Thich Nhat Hanh.&lt;/p&gt;
&lt;p&gt;The teacher, &lt;a class="reference external" href="http://www.naplesmindfulness.org/our_teacher.asp"&gt;Fred Eppsteiner&lt;/a&gt;, has studied under both Thich Nhat Hanh
and Tibetan teachers, which is very comforting to me because I've
studied under a Tibetan lineage and I'm completely oblivious of Zen's
practices. A Zen/Tibetan teacher would make the transition very nice. He
is also a psychotherapist, which will make things very interesting. I
like the fact that he has wisdom from both Eastern and Western mind
sciences. I'm sure he has much to offer. Unfortunately for me, he is on
vacation until the end of September.&lt;/p&gt;
&lt;p&gt;Last night, I attended their sunday night meditation class, the class
was very nice. The meditation room is styled in the minimalistic Zen
style therefore it wasn't as colorful as a Tibetan Gom-pa. I was happy
to see a Tibetan thangka of Manjushri, who I've always had an affinity
for. The people were very nice and welcoming. I was honestly afraid that
I would find to many Gucci-Buddhists in Naples but the people at this
class were very genuine praticioners. I'm very excited to experience
this new aspect of Buddhism.&lt;/p&gt;
</summary></entry><entry><title>National Weather Service XML Feed</title><link href=".././national-weather-service-xml-feed.html" rel="alternate"></link><updated>2005-08-19T19:33:51Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-08-19:.././national-weather-service-xml-feed.html/</id><summary type="html">&lt;p&gt;The national weather service now provides a &lt;a class="reference external" href="http://weather.gov/data/current_obs/"&gt;Current Weather
Conditions&lt;/a&gt; xml feed. It's really cool.&lt;/p&gt;
</summary></entry><entry><title>Back to Corporate</title><link href=".././back-to-corporate.html" rel="alternate"></link><updated>2005-08-12T18:22:21Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-08-12:.././back-to-corporate.html/</id><summary type="html">&lt;p&gt;To Celebrate my re-enter into Corporate life, I added a link category
called &amp;quot;Corporate Fun&amp;quot;. This is my request, comment to this posting with
all your favorite Corp links, jokes, or what have you.&lt;/p&gt;
</summary></entry><entry><title>Undocumented Django Wiki</title><link href=".././undocumented-django-wiki.html" rel="alternate"></link><updated>2005-08-11T01:41:31Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-08-11:.././undocumented-django-wiki.html/</id><summary type="html">&lt;p&gt;On Monday night before I left for Naples, I installed a &lt;a class="reference external" href="http://www.mediawiki.org/wiki/MediaWiki"&gt;Media Wiki&lt;/a&gt;
for &lt;a class="reference external" href="http://www.djangoproject.org"&gt;Django&lt;/a&gt;. You can find it located &lt;a class="reference external" href="http://eric.themoritzfamily.com/djangowiki"&gt;here&lt;/a&gt;. Feel free to contribute
if you have something cool to show everyone.&lt;/p&gt;
</summary></entry><entry><title>First Day at Naples Daily News</title><link href=".././first-day-at-naples-daily-news.html" rel="alternate"></link><updated>2005-08-10T10:59:55Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-08-10:.././first-day-at-naples-daily-news.html/</id><summary type="html">&lt;p&gt;I had to return to Naples Daily News for a meeting with the Corporate
folks. I woke up in the morning to find that my wife didn't pack my
Khakis. So I was a little annoyed because I would be under dressed. My
wife drove me to the NDN IT building and while I was waiting for Rob
Curley (my boss) to arrive, I kept noticing that I was the only one
wearing jeans. I felt like it was my first day of high school, checking
out what everyone is wearing.&lt;/p&gt;
&lt;p&gt;The meeting went well. I'm very excited about what is going to be
happening with Django and Ellington. What we are going to be doing with
the software is really going to show off the two systems.&lt;/p&gt;
&lt;p&gt;I had the opportunity to meet &lt;a class="reference external" href="http://www.jacobian.org/"&gt;Jacob Kaplan-Moss&lt;/a&gt;, who is one of the
developers working on the Django project at World Online. He's a really
cool guy. He gave me an overview of their Ellington system, which blew
me away. The simplistic structure of this large system just showed me
why I knew that Django was an amazing framework.&lt;/p&gt;
&lt;p&gt;Seeing Ellington in action proved to me that I have some big shoes to
fill. Well, it's a good thing I have large feet. Seriously, I'm
confidently that we're going to whoop some major ass with this stuff. I
wish I could go into more detail about what our intentions are but I'm
not sure what I'm allowed to say.&lt;/p&gt;
</summary></entry><entry><title>Left Handers day</title><link href=".././left-handers-day.html" rel="alternate"></link><updated>2005-08-05T00:41:20Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-08-05:.././left-handers-day.html/</id><summary type="html">&lt;p&gt;I'm moving on Aug 13th which is International Left Hander's day. Being
that I'm left handed, that must make it an auspicious day to move. So
lefties, celebrate International Left Hander's day by lending a hand and
helping me move :)&lt;/p&gt;
</summary></entry><entry><title>The Django Virus</title><link href=".././the-django-virus.html" rel="alternate"></link><updated>2005-08-03T22:47:02Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-08-03:.././the-django-virus.html/</id><summary type="html">&lt;p&gt;Well it looks like Django is going to be running in some high profile
places. With &lt;a class="reference external" href="http://www.holovaty.com/blog/archive/2005/08/03/0202"&gt;Adrian's announcement&lt;/a&gt; that he's going to be &lt;a class="reference external" href="http://www.poynter.org/column.asp?id=31&amp;amp;aid=86489"&gt;working for
the Washington Post&lt;/a&gt; soon and of course my announcement of me moving to
Naples to work for &lt;a class="reference external" href="http://www.naplesdailynews.com"&gt;Naples Daily News&lt;/a&gt; and therefore Naples Daily New's
parent, media giant &lt;a class="reference external" href="http://www.scripps.com/websites/index.shtml"&gt;Scripps&lt;/a&gt;. Django is going to have some really
impressive things to put on it's resume (take that Ruby on Rails j/k).&lt;/p&gt;
</summary></entry><entry><title>I'm moving to Naples, Fl...</title><link href=".././im-moving-to-naples-fl.html" rel="alternate"></link><updated>2005-08-03T02:22:25Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-08-03:.././im-moving-to-naples-fl.html/</id><summary type="html">&lt;p&gt;I am sooo moving to Naples, it's so beautiful there. No really, I'm
moving to Naples August 13th.&lt;/p&gt;
&lt;p&gt;I was in Naples this weekend interviewing for Naples Daily News. For
anyone that knows the history of Django, the code was developed at
&lt;a class="reference external" href="http://code.djangoproject.com/wiki/WorldOnline"&gt;World Online&lt;/a&gt;. The man that was in charge at World Online was a fellow
named, &lt;a class="reference external" href="http://www.robcurley.com"&gt;Rob Curley&lt;/a&gt;. Rob then &lt;a class="reference external" href="http://www.digitaledge.org/DigArtPage.cfm?AID=7083"&gt;came down&lt;/a&gt; to Naples with the intent to
kick ass, and that &lt;strong&gt;we&lt;/strong&gt; will.&lt;/p&gt;
&lt;p&gt;I'm the newest member of the Naple Daily News. My wife and I are moving
to a beautiful &lt;a class="reference external" href="http://www.aimco.com/AptSearch/PropShow.asp?PropertyID=039625"&gt;apartment&lt;/a&gt;. The apartment complex' grounds looks like a
park. There is a huge lake, tons of trees, two tennis courts, two pools,
a fitness center and this is the best, access by water to the bay. I'm
thinking about getting a couple kayaks so that I can drop then in the
river from my apartment. That sounds like lots of fun.&lt;/p&gt;
&lt;p&gt;Ok, so I have a new job working with &lt;a class="reference external" href="http://www.djangoproject.org"&gt;Django&lt;/a&gt;, the greatest thing for
web development since slice bread. Django is written in &lt;a class="reference external" href="http://www.python.com"&gt;Python&lt;/a&gt;, which
is the greatest thing for programming since slice bread. I'm working for
a New Media celebrity. I'm working with some of the best in the field.
I'm going to be living in a city were the local section of the newspaper
has to outsource to report about crime. I'm going to be living in an
apartment complex that is like looks like a park.&lt;/p&gt;
&lt;p&gt;Someone, please do not pinch me.&lt;/p&gt;
</summary></entry><entry><title>Greetings from Naples,Fl</title><link href=".././greetings-from-naplesfl.html" rel="alternate"></link><updated>2005-07-30T12:06:21Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-30:.././greetings-from-naplesfl.html/</id><summary type="html">&lt;p&gt;My wife and I are now in Naples, Fl. We are staying in a very nice
hotel. It's a Comfort Inn, but like everything I've seen of Naples, it's
very beautiful. It's the nicest Comfort Inn I've ever stayed in. I took
a few photos of the hotel room, I'll post those tommorrow. I want to
photograph the view from the window in the daylight. There are some
photos on our family blog, &lt;a class="reference external" href="http://www.themoritzfamily.com"&gt;http://www.themoritzfamily.com&lt;/a&gt;&lt;/p&gt;
</summary></entry><entry><title>Django Ajax and Dojo?</title><link href=".././django-ajax-and-dojo.html" rel="alternate"></link><updated>2005-07-29T22:21:40Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-29:.././django-ajax-and-dojo.html/</id><summary type="html">&lt;p&gt;The other day in the #django channel I was msg'd by Alex, a developer
for the &lt;a class="reference external" href="http://dojotoolkit.org/"&gt;Dojo Javascript toolkit&lt;/a&gt;. (Have anyone noticed that javascript
toolkits are popping up like crazy?). Well, Alex asked my, &amp;quot;Why are you
using prototype.js for Django Ajax&amp;quot;. I told him that I used it for some
other projects and it's simple. He told my to take a look at his
project.&lt;/p&gt;
&lt;p&gt;At first glance I thought, &amp;quot;Man, Dojo is much more than what Django Ajax
needs.&amp;quot; It looked over complicated and I just didn't want to get into
figuring out how this thing works. (It was probably late at night). All
I thought that Django Ajax needed was a simple ajax library. I told
Alex, &amp;quot;Dojo looks like overkill for my needs.&amp;quot; He responded by saying,
&amp;quot;This maybe true, but people are going to want this.&amp;quot; I thought he was
just trying to push his project. Man was I wrong...&lt;/p&gt;
&lt;p&gt;Today I took a second look at Dojo because MochiKit was released and it
had a reference to Dojo on their site. The other day I looked at this
page, &lt;a class="reference external" href="http://dojotoolkit.org/fast_widget_authoring.html"&gt;Fast Widget Authoring&lt;/a&gt;, but I didn't really read it because it
didn't think it pertained to DjAj's needs. Today I actually took the
time to the page and... Damn... This is cool shit!. The first thing I
thought was, &amp;quot;This looks a lot like how Django does things...&amp;quot;. Dojo
&lt;strong&gt;IS&lt;/strong&gt; for Javascript, what Django is for Python web development. This
is going to be big.&lt;/p&gt;
&lt;p&gt;If you read the article, you will see what Dojo does. Basically it
allows you to create packaged javascript components using html and css.
No more, innerHTML-String Splicing crap, no more DOM appendChild, blah,
blah, blah, well not as much anyhow.&lt;/p&gt;
&lt;p&gt;I'm going to be playing with Dojo a little and most likely integrate
Django Ajax with it. Happy Hacking...&lt;/p&gt;
</summary></entry><entry><title>For the Gamer Dorks out there...</title><link href=".././for-the-gamer-dorks-out-there.html" rel="alternate"></link><updated>2005-07-29T00:39:53Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-29:.././for-the-gamer-dorks-out-there.html/</id><summary type="html">&lt;p&gt;&lt;a class="reference external" href="http://www.vgcats.com/"&gt;http://www.vgcats.com/&lt;/a&gt;&lt;/p&gt;
</summary></entry><entry><title>Django, Dreamhost and FCGI</title><link href=".././django-dreamhost-and-fcgi.html" rel="alternate"></link><updated>2005-07-28T18:58:45Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-28:.././django-dreamhost-and-fcgi.html/</id><summary type="html">&lt;p&gt;There have been quite a few people in #django trying to get Django to
work with Dreamhost. Thanks to the work that Hugo has done and the folks
in the channel hacking away at the problem, the work has been posted on
the &lt;a class="reference external" href="http://wiki.dreamhost.com/index.php/Django"&gt;Dreamhost wiki&lt;/a&gt;. Maybe now I can get Site5 to get django up and
running on my server.&lt;/p&gt;
</summary></entry><entry><title>Stupid Windows Keymap</title><link href=".././stupid-windows-keymap.html" rel="alternate"></link><updated>2005-07-27T23:33:38Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-27:.././stupid-windows-keymap.html/</id><summary type="html">&lt;p&gt;I've been using the standard windows keyboard layout switcher to remap
my keyboard to dvorak. Unfortunately when I log into a machine through
remote desktop, the keymap of the machine is used and not my local
keymap settings. This is really dumb because I annoy all my non-djorak
coworkers because when they log into the same machine, I usually forget
to switch the mapping back to qwerty and they get aoeu instead of
asdf...&lt;/p&gt;
&lt;p&gt;I used a program called &lt;a class="reference external" href="http://webpages.charter.net/krumsick/"&gt;keytweak&lt;/a&gt; to remap my caplocks key to control,
which is very helpful because I use control much more than I use
capslock. I thought, &amp;quot;Hey, I can use keytweak to avoid annoying my
coworkers&amp;quot; it took some doing but I managed to remap all the keys. I
just feel sorry for the poor fellow that uses this computer if I ever
leave :)&lt;/p&gt;
&lt;p&gt;Another cool utility for emacs users is the &lt;a class="reference external" href="http://www.cam.hi-ho.ne.jp/oishi/indexen.html"&gt;XKeymacs&lt;/a&gt; program that
sets emacs keybindings for stuff like moving the cursor and copy and
paste (kill and yank).&lt;/p&gt;
</summary></entry><entry><title>Django, lighttpd and FCGI,  take two</title><link href=".././django-lighttpd-and-fcgi-take-two.html" rel="alternate"></link><updated>2005-07-27T19:13:06Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-27:.././django-lighttpd-and-fcgi-take-two.html/</id><summary type="html">&lt;p&gt;In case no one reads comments on my site, Hugo posted a comment about
his second way of getting Django to work with lighttpd and fcgi (you
mean people actually read my blog?) You can find that article &lt;a class="reference external" href="http://hugo.muensterland.org/2005/07/27/django-lighttpd-and-fcgi-second-take/"&gt;here.&lt;/a&gt;&lt;/p&gt;
</summary></entry><entry><title>Example Django Ajax app</title><link href=".././example-django-ajax-app.html" rel="alternate"></link><updated>2005-07-27T00:37:01Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-27:.././example-django-ajax-app.html/</id><summary type="html">&lt;p&gt;I created an example django ajax application in the svn repos. If anyone
is interested, the README.html should help you get that up and running.&lt;/p&gt;
&lt;p&gt;Still on the agenda is template tags to ease the use of django ajax for
those Javascript impaired&lt;/p&gt;
</summary></entry><entry><title>Running Django with FCGI and lighttpd</title><link href=".././running-django-with-fcgi-and-lighttpd.html" rel="alternate"></link><updated>2005-07-26T18:49:52Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-26:.././running-django-with-fcgi-and-lighttpd.html/</id><summary type="html">&lt;p&gt;Hugo's house of weblog horror has an article on how to get &lt;a class="reference external" href="http://hugo.muensterland.org/2005/07/26/running-django-with-fcgi-and-lighttpd/"&gt;Django
running with fcgi and lighttp.&lt;/a&gt; There are many in the #django IRC that
are waiting for someone to do this so I'm linking him in case they
missed his article.&lt;/p&gt;
</summary></entry><entry><title>Django RSS</title><link href=".././django-rss.html" rel="alternate"></link><updated>2005-07-26T03:19:25Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-26:.././django-rss.html/</id><summary type="html">&lt;p&gt;From what I can tell, turning on RSS is very easy. Basically you setup a
urlpattern like in
&lt;a class="reference external" href="http://code.djangoproject.com/svn/djangoproject.com/django_website/settings/urls/main.py"&gt;http://code.djangoproject.com/svn/djangoproject.com/django_website/settings/urls/main.py&lt;/a&gt;
and then make a module that is the same name as your settings module
that ends in _rss, like so:
&lt;a class="reference external" href="http://code.djangoproject.com/svn/djangoproject.com/django_website/settings/main_rss.py"&gt;http://code.djangoproject.com/svn/djangoproject.com/django_website/settings/main_rss.py&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Happy hacking!&lt;/p&gt;
</summary></entry><entry><title>django_ajax update</title><link href=".././django_ajax-update.html" rel="alternate"></link><updated>2005-07-26T02:15:26Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-26:.././django_ajax-update.html/</id><summary type="html">&lt;p&gt;From the reaction of the folks in the django irc channel, it seems that
my Django_Ajax library is a little advanced, everyone wants the power
of Ajax without having to write Javascript. I made the false assumption
that anyone messing with Ajax would know Javascript.&lt;/p&gt;
&lt;p&gt;After taking a look at what Ruby on Rails does with their ajax api, I'm
going to be writting, with the help of some of the folks in #django, a
templatetag library to rival ROR's ajax helper functions. It should
shape up nicely this coming week.&lt;/p&gt;
</summary></entry><entry><title>Javascript Name Clobbering</title><link href=".././javascript-name-clobbering.html" rel="alternate"></link><updated>2005-07-22T00:58:46Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-22:.././javascript-name-clobbering.html/</id><summary type="html">&lt;p&gt;I was working with two different javascript libraries today and ran into
the issue that brought about namespaces in other languages.&lt;/p&gt;
&lt;p&gt;Jsval has a class called Field. I wanted to use prototype.js and
openrico so... guess what, prototype.js, has the class Field also... So,
they stepped on each other toes. I renamed all the Field references is
Jsval (because prototype.js is a dependancy for many libraries) and then
wrote this &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Javascript_Namespaces"&gt;http://en.wikipedia.org/wiki/Javascript_Namespaces&lt;/a&gt; out of
frustration. Maybe someone will listen to me and use javascript
namespaces.&lt;/p&gt;
</summary></entry><entry><title>Pay no attention to the man behind the curtain..</title><link href=".././pay-no-attention-to-the-man-behind-the-curtain.html" rel="alternate"></link><updated>2005-07-20T19:04:16Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-20:.././pay-no-attention-to-the-man-behind-the-curtain.html/</id><summary type="html">&lt;p&gt;If anyone saw the django_ajax article that I accidentally posted to my
blog. Pay no attention to it. It does not exist (cue Jedi Mind Trick)&lt;/p&gt;
</summary></entry><entry><title>This is exactly what a blog should not be used for...</title><link href=".././this-is-exactly-what-a-blog-should-not-be-used-for.html" rel="alternate"></link><updated>2005-07-20T18:54:33Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-20:.././this-is-exactly-what-a-blog-should-not-be-used-for.html/</id><summary type="html">&lt;p&gt;Ack,... I ran out of sugar at work today. It's black coffee for me this
morning.&lt;/p&gt;
</summary></entry><entry><title>Django, Django, Django...</title><link href=".././django-django-django.html" rel="alternate"></link><updated>2005-07-18T01:28:36Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-18:.././django-django-django.html/</id><summary type="html">&lt;p&gt;This framework is so freakin' awesome.... They just enough documentation
on the site that you can actually get things running without much
effort.. I have to say, this is the coolest thing to come out in a long
time. You have a object-relational mapping system, obsessive SEO
support, a templating system and the coolest thing ever, automatic
administive interface! Oh not to mention it's freakin python! The best
scripting language ever. Go to &lt;a class="reference external" href="http://www.djangoproject.com/"&gt;here&lt;/a&gt; and check it out. NOW!&lt;/p&gt;
</summary></entry><entry><title>&amp;lt;lang_en&amp;gt;Silent Bob uses Wordpress.&amp;lt;/lang_en&amp;gt;&amp;lt;lang_eo&amp;gt;Silent Bob uzas &amp;quot;Wordpress&amp;quot;-on&amp;lt;/lang_eo&amp;gt;</title><link href=".././ltlang_engtsilent-bob-uses-wordpressltlang_engtltlang_eogtsilent-bob-uzas-quotwordpressquot-onltlang_eogt.html" rel="alternate"></link><updated>2005-07-15T08:06:10Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-15:.././ltlang_engtsilent-bob-uses-wordpressltlang_engtltlang_eogtsilent-bob-uzas-quotwordpressquot-onltlang_eogt.html/</id><summary type="html">&lt;p&gt;Kevin Smith (aka Silent Bob) uses Wordpress for his blog, &lt;a class="reference external" href="http://silentbobspeaks.com/"&gt;My Boring Ass
Life&lt;/a&gt;, tre bone!
Kevin Smith (aka Silent Bob) uzas &amp;quot;Wordpress&amp;quot;-on por lia blogo, &lt;a class="reference external" href="http://silentbobspeaks.com/"&gt;My
Boring Ass Life&lt;/a&gt;, tre bone!&lt;/p&gt;
</summary></entry><entry><title>&amp;lt;lang_en&amp;gt;Windows is easier than linux?&amp;lt;/lang_en&amp;gt;&amp;lt;lang_eo&amp;gt;Vindozo estas pli facila pli Linukso?&amp;lt;/lang</title><link href=".././ltlang_engtwindows-is-easier-than-linuxltlang_engtltlang_eogtvindozo-estas-pli-facila-pli-linuksoltlang.html" rel="alternate"></link><updated>2005-07-13T23:50:59Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-13:.././ltlang_engtwindows-is-easier-than-linuxltlang_engtltlang_eogtvindozo-estas-pli-facila-pli-linuksoltlang.html/</id><summary type="html">&lt;p&gt;Who said that Windows is easier than Linux? Today I tried to
plug in my SD Card reader into my work computer. At first it didn't
show up. I had to remove my network drive mappings in order for them to
show up. How stupid.&lt;/p&gt;
&lt;p&gt;When I plug in the card reader into my linux box, it appears instantly.
I didn't have to do anything. To think, I was afraid that it wasn't
going to work in Linux. Shesh&lt;/p&gt;
&lt;p&gt;Kiu diris ke Vindozo estas pli facila pli Linukso? Hodiaux mi
penis uzi mia SD memorkarton en mia komputilo labora. Komence, gxi ne
laboris. Mi havis fortiri mia retodurdiskojn por la memorkarto labori.
Tre muta.&lt;/p&gt;
&lt;p&gt;Kiam mi uzas la memorkarton kun Linukso, gxi laboras
senprokraste. Mi ne havas fari neniajxo. Pensi, mi timis ke gxi ne estis
ironta
labori en Linukso. sxisx.&lt;/p&gt;
</summary></entry><entry><title>&amp;lt;lang_en&amp;gt;Happy Birthday to me&amp;lt;/lang_en&amp;gt;&amp;lt;lang_eo&amp;gt;Felicxan Naskigxtagon por min&amp;lt;/lang_eo&amp;gt;</title><link href=".././ltlang_engthappy-birthday-to-meltlang_engtltlang_eogtfelicxan-naskigxtagon-por-minltlang_eogt.html" rel="alternate"></link><updated>2005-07-13T21:01:14Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-13:.././ltlang_engthappy-birthday-to-meltlang_engtltlang_eogtfelicxan-naskigxtagon-por-minltlang_eogt.html/</id><summary type="html">&lt;p&gt;Happy Birthday to me. Happy Unbirthday to all of you (except &lt;a class="reference external" href="http://www.theworldofstuff.com"&gt;Jordon&lt;/a&gt;,
Felicxan NaskiÄ?tagon por lin).
Felicxan Naskigxtagon por min. Felicxan MalNaskigxtagon por vi.&lt;/p&gt;
</summary></entry><entry><title>GPG Public Key</title><link href=".././gpg-public-key.html" rel="alternate"></link><updated>2005-07-13T04:16:39Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-13:.././gpg-public-key.html/</id><summary type="html">&lt;p&gt;A added my &lt;a class="reference external" href="http://www.gnupg.org/"&gt;GPG&lt;/a&gt; Public Key to the bottom of this page if anyone wants
to send encrypted/signed messages to me.&lt;/p&gt;
</summary></entry><entry><title>The Uncyclopedia</title><link href=".././the-uncyclopedia.html" rel="alternate"></link><updated>2005-07-13T02:23:58Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-13:.././the-uncyclopedia.html/</id><summary type="html">&lt;p&gt;Fans of Wikipedia will love this site, &lt;a class="reference external" href="http://uncyclopedia.org/"&gt;Uncyclopedia&lt;/a&gt;. It is like a
bizzaro-pedia, where everything on the wiki is wrong. It's a delightful
waste of time.&lt;/p&gt;
</summary></entry><entry><title>Finally a decent  Nintendo DS game</title><link href=".././finally-a-decent-nintendo-ds-game.html" rel="alternate"></link><updated>2005-07-10T10:57:37Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-10:.././finally-a-decent-nintendo-ds-game.html/</id><summary type="html">&lt;p&gt;Well I traded in Batman Begins because I beat it and there wasn't much
more to do with it. I looked around the Gamestop and I didn't really see
any XBox games that really interested me. I want to tryout Paper Mario
for the Gamecube but it was $10 more than the store credit I had for
Batman.&lt;/p&gt;
&lt;p&gt;While I was looking for a game, Gina was playing a game on the Nintendo
DS demos. I couldn't really find anything. I went over to see what Gina
was playing and it was &amp;quot;Kirby Canvas Curse&amp;quot;. I thought, &amp;quot;Oh great,
another 'Yoshi's Touch and Go' (A really bad game)&amp;quot;. After that we got
the clerk to help us find something.&lt;/p&gt;
&lt;p&gt;The clerk was helpful in helping me find some XBox games. He recomended
some first person shooters but frankly I've been playing FPSes since the
first Wolfenstein and I'm a little bored with that genre. Although XIII
was an awesome FPS. I recomend grabbing that if you haven't played it
yet. He then recommended one of the Mech series games and Buffy the
Vampire Slayer. I was willing to finally give a Mech game a try since
they have some hardcore fans and must be a something to that. The clerk
recommended Buffy, which is a third person action game, he said that it
was surpisingly a good game and he doesn't care for Buffy. So I said
what the hell (Maybe there is a Willow naked cheat j/k).&lt;/p&gt;
&lt;p&gt;While we were waiting in line, I thought I'd try out Kirby's Canvas
Curse to see if it was anything good. I played it for about two minutes
and then I put the other games back and grabbed a copy of Kirby.&lt;/p&gt;
&lt;p&gt;Kirby's Canvas Curse (KCC) is a very cool game. It's just like the other
Kirby games except the you don't control Kirby with the keypads, you
direct them with the stylus. At first it's seems like a really annoying
way the control the character, especially if you played Yoshi's Touch
and Go. However, this game got it right.&lt;/p&gt;
&lt;p&gt;Gameplay is like this. Kirby is a ball and he continuously moving. You
can draw lines and he will roll on the line in the direction that you
draw the line. It sounds simply but its really isn't, you have to
maneuver Kirby around all kinds of obsticles, block laser beems with you
lines, block those pesky cannon balls, etc. It makes it extremly
entertaining. Perhaps Yoshi's Touch and Go might of been this much fun
if it was longer and more inventive, however it was so short that it was
really nothing more than a puzzle game masked as a platformer.&lt;/p&gt;
&lt;p&gt;Oh course the usual Kirby abilities are in this game. It wouldn't be
Kirby without the cool ass power-ups. The Boss Levels aren't like the
other Kirby games where you just tediously battle it out with them. They
take the form of mini-games (A NDS specialty).&lt;/p&gt;
&lt;p&gt;There are three bosses that I'm aware of. The first is that annoying
Cloud guy that shoots lightning. He's a little more tame in this game,
however the mini game is the fun part. It's a Kirby version of Breakout.
instead of a paddle on the bottom, you draw you paddle to direct Kirby.
The object of the minigame is to clear each board of the enemies by
directing Kirby into them.&lt;/p&gt;
&lt;p&gt;The second is a race against the King Penguin guy, I can't remember his
name. You steer kirby by dragging his cart with the stylus and if you
steer him into food, his gets a boost. I don't really care for this one.&lt;/p&gt;
&lt;p&gt;The third boss is the Painter guy. What you have to do is recreate the
drawings he does before kirby walks from the left side of the screen to
the left.&lt;/p&gt;
&lt;p&gt;In the end, I think that this game is a great adaptation of the 2d Kirby
series to the NDS.&lt;/p&gt;
</summary></entry><entry><title>Some Buddhist Links</title><link href=".././some-buddhist-links.html" rel="alternate"></link><updated>2005-07-10T08:39:21Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-10:.././some-buddhist-links.html/</id><summary type="html">&lt;p&gt;I was writing a friend of mine about some good Buddhist links and I
thought I might share them with whoever is reading this Blog.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.tubtenkunga.org"&gt;http://www.tubtenkunga.org&lt;/a&gt; This is the website of the Buddhist Center
that I goto.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.thubtenchodron.org/"&gt;http://www.thubtenchodron.org/&lt;/a&gt; This is the website of a western nun
that writes a number of good books. Her site has a lot of resources&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.lamayeshe.org/"&gt;http://www.lamayeshe.org/&lt;/a&gt; This site has many free ebooks that you can
download.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.lamrim.com/"&gt;http://www.lamrim.com/&lt;/a&gt; This website has a lot of great Buddhis
teachings by some the great Tibetan teachers and Western monks and nuns.
Some good Western teachers there are: Ven Sarah Thresher, Ven Thubten
Chodron, and Ven Robina Courtin (I really like her). Generally the
people who look Western would be the easiest to understand because they
put thinks in a Western context.&lt;/p&gt;
</summary></entry><entry><title>Batman Begins The Video Game</title><link href=".././batman-begins-the-video-game.html" rel="alternate"></link><updated>2005-07-10T00:08:39Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-10:.././batman-begins-the-video-game.html/</id><summary type="html">&lt;p&gt;We saw Batman Begins in the theaters the day it came out and we both
thought it was the best batman movie ever. I don't know if my wife
thinks the movie was good because of the quality of the fact that her
boyfriend Christian Bale was batman. My only beef with the movie is the
Mr Bale's &amp;quot;Batman Voice&amp;quot; sounded really goofy.&lt;/p&gt;
&lt;p&gt;Anyhow, while I traded in some games at gamestop yesturday and saw
&amp;quot;Batman Begins&amp;quot;. I suspended my ban on movie games and picked it up. I
must say it was a good choice. The game is amazing. It was fun to play
and the graphics were simply amazing. The game wasn't hard but it wasn't
to easy that it was boring. I thought it was just plain fun.&lt;/p&gt;
&lt;p&gt;The game plays off the concept of fear. You have a fear meter that you
can increase by doing scary things. For instance you can hang from a
light fixture and throw one of those HF emitters that summon bats to
scare the snot out of your enemies.&lt;/p&gt;
&lt;p&gt;I beat it in about 4 hours or so. It's is not a long game, so I'd
recommend that you rent it. Gina even enjoyed watching me play it.&lt;/p&gt;
&lt;p&gt;So, if you are in the mood for a fun game, pick up this one.&lt;/p&gt;
</summary></entry><entry><title>I have bronchitis</title><link href=".././i-have-bronchitis.html" rel="alternate"></link><updated>2005-07-07T23:10:08Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-07:.././i-have-bronchitis.html/</id><summary type="html">&lt;p&gt;Last night the wife and I had to go to the hospital because we both got
sick. We went to Memorial Pembroke(don't go there) and sat for four
hours. We ended up leaving and going to Memorial West(go there). We were
admitted immediatly.&lt;/p&gt;
&lt;p&gt;At about 6am the doctor saw me. He diagnosed me with bronchitis. So, I'm
stuck at home again.&lt;/p&gt;
</summary></entry><entry><title>One reason I love Dvorak</title><link href=".././one-reason-i-love-dvorak.html" rel="alternate"></link><updated>2005-07-07T02:31:39Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-07:.././one-reason-i-love-dvorak.html/</id><summary type="html">&lt;p&gt;One reason why I love the &lt;a class="reference external" href="http://www.dvorak-keyboard.com/"&gt;Dvorak keyboard&lt;/a&gt; is that I can be sick as a
dog, sit in my chair like &lt;a class="reference external" href="http://www.hawking.org.uk/"&gt;Steven Hawkings&lt;/a&gt; and still be able to type
without much effort.&lt;/p&gt;
</summary></entry><entry><title>Kids... Don't try this at home...</title><link href=".././kids-dont-try-this-at-home.html" rel="alternate"></link><updated>2005-07-05T08:54:33Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-05:.././kids-dont-try-this-at-home.html/</id><summary type="html">&lt;p&gt;Well, the 4th of July for us was eventful. We went to a bbq at a friends
house in the afternoon. We swam, got crispy in the sun. It was fun.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image0" src="/upload/arsenal.jpg" /&gt;
Our Arsenal&lt;/p&gt;
&lt;p&gt;After the bbq, we went to my wife's parents house to light off
fireworks. We had the regular arsenal of fireworks. Roman Candles,
Bottle Rockets, Blackcats(firecrackers). We were in for a good time.&lt;/p&gt;
&lt;p&gt;We started off tame lighting bottle rockets from the bottle. When we got
bored of that we lit them while holding the bottle. When we got bored of
that we get a pipe and aimed them at trees.&lt;/p&gt;
&lt;p&gt;When we got bored of that we brought out the roman candles. First we
shot them up in the air. Then we shot them at a soda can. Next about 10
packs of firecrackers. Then we played Roman Candle Harry Potter....&lt;/p&gt;
&lt;p&gt;The point of Roman Candle Harry Potter is to act like wizards and shoot
2d8 fireballs at each other.&lt;/p&gt;
&lt;p&gt;Tell me, would you let this man shoot fireballs at you:&lt;/p&gt;
&lt;p&gt;&lt;img alt="image1" src="/upload/cardinal_sin.jpg" /&gt;
Cardinal Sin.&lt;/p&gt;
&lt;p&gt;At first it was fun. I shot one over his head. He shot one over mine. He
shot one to the left of me. I shot one to the left of him... Just not
that far left of him. Then he shot one very close to me. I dodged. Then
another, and another, oh the horror.... Then one hit my stomach.&lt;/p&gt;
&lt;p&gt;This is wait happens when you play Roman Candle Harry Potter:&lt;/p&gt;
&lt;p&gt;&lt;img alt="image2" src="/upload/shirt_hole.jpg" /&gt;
Burn in my shirt, about the size of a quater.&lt;/p&gt;
&lt;p&gt;Kids-- Don't play Roman Candle Harry Potter.&lt;/p&gt;
</summary></entry><entry><title>&amp;quot;Oh Crap, my steering wheel fell off&amp;quot;</title><link href=".././quotoh-crap-my-steering-wheel-fell-offquot.html" rel="alternate"></link><updated>2005-07-03T21:10:27Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-03:.././quotoh-crap-my-steering-wheel-fell-offquot.html/</id><summary type="html">&lt;p&gt;&lt;img alt="Chris." src="/upload/chris.jpg" /&gt;
Chris&lt;/p&gt;
&lt;p&gt;While I was in the middle of typing my previous post I heard a knock on
my door. When I answered the door, my friend Chris who lives across the
street from me asked, &amp;quot;Do you have a tap and die set?&amp;quot; For those that
don't know, A tap and die set is for making new threads on bolts and
nuts when they are stripped. Of course I didn't have one so I told him,
&amp;quot;No, I don't have one. Why what is stripped?&amp;quot;. He told me that his
steering wheel had fallen off his car and the stud that holds the wheel
on is completely stripped off. I went over to look at the stud and it
was completely stripped, there were no threads on it at all. I told him,
sure lets go to the store.&lt;/p&gt;
&lt;p&gt;When I was getting ready, I remembered that my dad had a tap and die set
in his garage. I called my dad an asked if I could borrow the set. He
was reluctant and suggested what we could do. Most of his suggestion
required getting the car to my dad's house to work on the car. We had no
idea how to get it over there aside from towing it.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Chris's shirt" src="/upload/chris_shirt.jpg" /&gt;
Chris' Shirt&lt;/p&gt;
&lt;p&gt;I had to go to the bank first so we went there first. On the way to the
bank we were joking around trying to think of ways to hold the wheel on
the stud to get it to my dads. I suggested duct tape. He suggested
welding. I told him, you know you could most likely hold the wheel on
the stud to get it there. The crazy bastard thought that was a great
idea.&lt;/p&gt;
&lt;p&gt;&lt;img alt="our trip" src="/upload/map.jpg" /&gt;
Our Trip&lt;/p&gt;
&lt;p&gt;The problem is that my parents live on the other side of town about 9
miles from where we live. 9 miles isn't far when you have a working
steering wheel but it's very long without one. So, we had to break the
news to his girlfriend that this might be the last day she will every
see him. She started freaking out, &amp;quot;You're going to die&amp;quot;, &amp;quot;You're
crazy&amp;quot;, &amp;quot;You better use your seat belt!&amp;quot;. Then we were off.&lt;/p&gt;
&lt;p&gt;I told him that we need to drive around the block to make sure he can
drive it. He takes off and I fallow behind him. We go around the corner
and he starts to swerve. He lost his steering wheel! He recovers and
continues around the block. I pull up beside him and he says, &amp;quot;Yeah, I'm
comfortable driving it.&amp;quot;, crazy bastard...&lt;/p&gt;
&lt;p&gt;We goes off, I drive infront of him and he's behind me. We drive down
our main street and he's ok. That's good, but we are not on I95 yet. We
get on I95. I'm constantly looking in my rear view every two minutes to
make sure he didn't lose it and drive off the road. A few times he
swerves a little and I think he's a gonner but he recovers and we make
it to my parents.&lt;/p&gt;
&lt;p&gt;He gets the car into my parents garage and about twenty minutes later,
he's done.&lt;/p&gt;
</summary></entry><entry><title>Deep Impact</title><link href=".././deep-impact.html" rel="alternate"></link><updated>2005-07-02T08:58:20Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-02:.././deep-impact.html/</id><summary type="html">&lt;p&gt;&lt;a class="reference external" href="http://www.npr.org/templates/story/story.php?storyId=4726136"&gt;This is amazing&lt;/a&gt;, Nasa is smashing one of their space craft into the
comet Tempel 1 in hopes to see what is inside it.&lt;/p&gt;
&lt;p&gt;I heard this on NPR this afternoon. They were interviewing a reporter
from &lt;a class="reference external" href="http://skyandtelescope.com/deepimpact"&gt;Sky and Telescope&lt;/a&gt;. Apparently if you live west of the
Mississippi River you will be able to see the impact on July 3rd at
around 10:53pm with your naked eye.&lt;/p&gt;
&lt;p&gt;It's a shame I'm on the east coast :'( the comet will be under the
horizon when impact is to occur. It would of been a damn good excuse to
dust off my ol' Meade ETX-70.&lt;/p&gt;
&lt;p&gt;All is not lost for us eastside geeks, however. The reporter at Sky and
Telescope said that we will be able to see the aftermath of the impact
on the Forth of July... yeah, ok, sure bud...&lt;/p&gt;
&lt;p&gt;All sarcasm aside, the &lt;a class="reference external" href="http://skyandtelescope.com/deepimpact"&gt;Article&lt;/a&gt; at Sky and Telescope gives westsiders
directions on how to locate the comet. For the eastside? There are also
links to several webcasts of the event at the end of the article.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.jackstargazer.com/"&gt;Keep Looking up!&lt;/a&gt;&lt;/p&gt;
</summary></entry><entry><title>My Host</title><link href=".././my-host.html" rel="alternate"></link><updated>2005-07-02T00:08:53Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-02:.././my-host.html/</id><summary type="html">&lt;p&gt;In my previous post, I told you about &lt;a class="reference external" href="http://www.themoritzfamily.com"&gt;my family's website&lt;/a&gt;. I forgot
to mention the hosting company that I'm using. The hosting company is
&lt;a class="reference external" href="http://www.site5.com"&gt;Site 5&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A coworker of mine told me about them, I've used them for a couple days
now and I am very impressed with the sophistication of the control panel
they are using. If you want web site hosting, their features are
amazing for the price. Check them out.&lt;/p&gt;
</summary></entry><entry><title>Just another blog</title><link href=".././just-another-blog.html" rel="alternate"></link><updated>2005-07-01T23:18:37Z</updated><author><name>Eric Moritz</name></author><id>tag:None,2005-07-01:.././just-another-blog.html/</id><summary type="html">&lt;p&gt;Just another blog, &lt;em&gt;nothing to see here&lt;/em&gt;...&lt;/p&gt;
&lt;p&gt;Ok, well this is my adventure into the blogosphere. I'm not sure where
I'm going with this blog, but after creating my new &lt;a class="reference external" href="http://www.themoritzfamily.com"&gt;family's website&lt;/a&gt;
I was given unlimited subdomains and the ability to use &lt;a class="reference external" href="http://netenberg.com/fantastico.php"&gt;Fantastico&lt;/a&gt; so
I had just had to create a personal blog.&lt;/p&gt;
&lt;p&gt;My friend Jordon at &lt;a class="reference external" href="http://www.theworldofstuff.com/"&gt;The World of Stuff&lt;/a&gt;, a fellow Esperantist (Saluton
Gxordono!) and Dvorak keyboad user, uses the blog software &lt;a class="reference external" href="http://wordpress.org/"&gt;Word
Press&lt;/a&gt;. I clicked a button in Fantasico and a moment later, &lt;em&gt;I had a
blog!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Generally the blog will be my forum for showcasing stuff that I find
interesting. Stuff about My wife, Computers, Linux, Programming,
Buddhism, Jazz, Chess, Punk/Ska (alright, I thinks that's enough
keywords to make the search engine robots happy :) )&lt;/p&gt;
&lt;p&gt;Well I hope you will enjoy my blog. I hope I enjoy it too :)&lt;/p&gt;
</summary></entry></feed>
