<?xml version="1.0" encoding="utf-8"?>
<!-- generator="Kukkaisvoima version 9" -->
<rss version="2.0"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
>
<channel>
<atom:link href="http://www.nickcoleman.org/blog/index.cgi/feed" rel="self" />
<title>Nick Coleman: python</title>
<link>http://www.nickcoleman.org/blog/index.cgi</link>
<description>Nick Coleman blog</description>
<pubDate>Thu, 23 Sep 2010 09:30:00 -0700</pubDate>
<lastBuildDate>Thu, 23 Sep 2010 09:30:00 -0700</lastBuildDate>
<generator>http://23.fi/kukkaisvoima/</generator>
<language>en</language>
<item>
<title>Tip: Dictionary Substitution With Python's print
</title>
<link>http://www.nickcoleman.org/blog/index.cgi?post=pythonprintform%21201009230930%21programming%2Cpython</link>
<comments>http://www.nickcoleman.org/blog/index.cgi?post=pythonprintform%21201009230930%21programming%2Cpython#comments</comments>
<pubDate>Thu, 23 Sep 2010 09:30:00 -0700</pubDate>
<dc:creator>Nick</dc:creator>
<category>programming</category>
<category>python</category>
<guid isPermaLink="true">http://www.nickcoleman.org/blog/index.cgi?post=pythonprintform%21201009230930%21programming%2Cpython/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[
<p>
You have no doubt been using python's print statement for yonks and are
pretty familiar with it.  You know that you can use  <code>%</code>,
the string formatting or interpolation operator. Most people use the
standard formatting types of %s, %d, and so on.  I have recently changed
to using the less common dictionary mapping and here I go through the
benefits and why I changed.
<p>
Briefly, <code>%</code> is the operator that allows you to do C style <a
href="http://www.nickcoleman.org/axs/ax.pl?http://linux.die.net/man/3/sprintf">sprintf</a>
operations.  If you don't know them, they let you substitute values into
a string, like this:
<code class="code"> print "%s is the time" % "now" </code>
which give the result "now is the time".  The '%s' is an indicator to
insert a string here, and the string to insert is in the second part of
the expression, the 'now'.  There are many other types of formatted
insertions: int, float, scientific and so on as well as string.
<p>
If you do any sort of web programming, you use the <code>print</code>
statement a <em>lot</em>.  After all, the purpose of your program is to
generate HTML for the web server to serve up to your users, and you make
the HTML by outputting strings using <code>print</code>.
<p>
If your coding is anything like mine, you start off by using lots and
lots of print statements, just to get the ball rolling and getting some
sort of output.  Often the prints are interspersed with a bunch of
calculation statements , creating a bit of a jumble.  Later, I go back
and refactor the block to bring all the calcs to one place and all the
prints to one place, then try and consolidate them to reduce the number
of statements. (Although the server does do some caching to reduce the
IO between server and app, it still makes sense to give your input to
the server in as few statements as possible.)  In particular, I try to
move print statements around so I can consolidate them into big blocks
of """ ... """.  This has two benefits: it reduces the number of print
statements, and, perhaps more importantly, I can more easily see the
structure of the HTML since I can format the tags so they appear in
logical blocks rather than spread over one long line.
<p>
By the way, while doing this I discovered that <code>print """ ...
"""</code> can use the <code>%</code> operator too.  I didn't know that
and assumed for some reason that you could use it only for "normal"
print statements.  That was quite a discovery and made generating the
HTML much easier, both to create and debug. So now I can write <code
class="code">print """ ... %s """ % "now"</code> and I get the correctly
formatted substitution in my output.
<p>
However, using substitution in large blocks of HTML becomes cumbersome.
Say you want to insert a new value in the middle of a block of HTML.
You now have to count the parameters and hope you are inserting in
the correct place: <code class="code">print """ 
&lt;h1&gt; some word %s inserted&lt;/h1&gt; 
  &lt;p&gt;another word %s inserted&lt;/p&gt;
  &lt;p&gt;another word %s inserted&lt;/p&gt; 
  &lt;p&gt;another word %s inserted&lt;/p&gt; 
  &lt;p&gt;another word %s inserted&lt;/p&gt;
  &lt;p&gt;another word %s inserted&lt;/p&gt; 
  &lt;p&gt;final word %s inserted&lt;/p&gt; 
""" % ('now', 'is', 'the', 'time',  'all', 'good', 'men')</code>Tricky.
Especially when you come to maintain it six months later.
<p>
I've intentionally made a mistake in the above example (the values are
missing the word 'for' in the start of the well known phrase "now is the
time for all good men to come to the aid of their party").  How would
you fix it?  First you need to work through the %s's to figure how where
to insert the extra %s, then you would need to count through the
substitution values to figure out where to add the new value of 'for'.
Very easy to make a mistake, and a pain to actually do.
<p>
Aside: it's probably not really an issue when you're dealing with
multiple print statements.  Each print probably has a substitution list
of only a few values.  But once you have consolidated print statements,
as in this use case of writing HTML, each print may have a dozen or more
substitutions.  That's when it gets tricky.
<p>
There is a better way to do string formatting and that is to use a
dictionary.  Many python people don't use this, if they are anything
like me, because the doc page does a pretty poor job of explaining it,
at least in terms of why you would want to.  The docs show the syntax,
but not an example of its benefits. We will come to the benefits in a
second.
<p>
This is how you use a dictionary instead of a tuple of values.  Create a
dictionary (called <code>phrase</code> in this example) with all the values and keys
to represent them.  It's not much extra work; the
values fall out when you are doing the calculations to generate them and
it is a simple matter to put them in a dictionary at that time.  Then,
in the print statement, use the keys to insert the values from the
dictionary.  Here's the dictionary: 
<code class="code">phrase = {
'word1': 'now', 
'word2': 'is', 
'word3': 'the', 
'word4': 'time', 
'word5': 'for', 
'word6': 'all',
'word7': 'good', 
'word8': 'men', 
'word9': 'to', 
'word10': 'come',
'word11': 'to', 
'word12': 'the', 
'word13': 'aid',
...}</code>
Not a great choice of key names, but I don't want to get bogged down in
details. I want to make the example clear, so I chose the key to reflect
the word's position within the phrase. (In actuality, you would choose
key names that reflect the purpose of the variable, such 'name' or
'email'.)
<p>
Here's the print statement:
<code class="code">print """
&lt;h1&gt;some word %(word1)s inserted &lt;/h1&gt; 
  &lt;p&gt; another word %(word2)s inserted&lt;/p&gt; 
  &lt;p&gt;another word %(word3)s inserted&lt;/p&gt; 
  &lt;p&gt;another word %(word4)s inserted&lt;/p&gt;
  &lt;p&gt;another word %(word5)s inserted&lt;/p&gt; 
  &lt;p&gt;another word %(word6)s inserted&lt;/p&gt; 
  &lt;p&gt;final word %(word7)s inserted&lt;/p&gt; 
""" % phrase</code>
Notice the change: the value's key is placed between parentheses
that are between the '%' and the indicator 's'.
<p>
Some points: the key is specified between parentheses placed in between
the substitution operator '%' and the substitution type 's' <small>(or
d, f, g, etc)</small>; the key is <em>not</em> stringified, but typed as
it appears in the dictionary without the enclosing ''; and finally you
need only to specify the dictionary name at the end of the print
statement.
<p>
You can see this is very easy to maintain.  If I want to insert a value,
I don't need to count any values to make sure I'm specifying the correct
one in the correct place, I just specify it by key name. It's much
harder to get wrong.  
<p>
An added benefit is that there is (unintuitively) less typing since you
specify only key names, not like <code>dictionary[key]</code>.
<p>
Finally, and this is the real kicker, the number of keys in the
dictionary <strong>doesn't have to be the same</strong> as the number of
substitutions.  This is great; it is such a benefit that even by itself
it means that a dictionary is much better than using parameter
substitution.  With "normal" substitution, the tuple has to  have the
same number of items as there are substitutions (unless you can slice
the tuple), and the values have to be in the order that you want to use
them (rather than unordered).  You have to have a one-to-one match
between each %s and 'value'. You can't have too few values (obviously),
but you also can't have too many, which is annoying sometimes when
working with tuples and lists.  With a dictionary, you can pre-compute
any number of values and just pick off the ones you need.
<p>
So what? Say you are generating a &lt;form&gt; which is re-using values
from a previous POST, and that the form is quite complex with about 30
different elements ranging from textboxes, drop-down lists to radio
buttons.  If you use "normal" %s substitution, the print statements
become very complex and it becomes hard to maintain and change.  (I had
real life experience of this when making my <a
href="http://www.nickcoleman.org/axs/ax.pl?/ephem/">ephemeris</a>.)  Instead, store all the values
in a dictionary and recall them by using their key name, and you will
find maintenance of the form becomes a snap.
<p>
I hope this gives you a real life example of the benefits of using a
dictionary in string formatting.  I find it both better and easier to
use for anything involving intermixed calculations and print.
<p>
]]></content:encoded>
<wfw:commentRss>http://www.nickcoleman.org/blog/index.cgi?post=pythonprintform%21201009230930%21programming%2Cpython/feed/</wfw:commentRss>
</item>
<item>
<title>Python Learning Books
</title>
<link>http://www.nickcoleman.org/blog/index.cgi?post=python%21201007071205%21programming%2Cpython</link>
<comments>http://www.nickcoleman.org/blog/index.cgi?post=python%21201007071205%21programming%2Cpython#comments</comments>
<pubDate>Wed, 07 Jul 2010 12:05:00 -0700</pubDate>
<dc:creator>Nick</dc:creator>
<category>programming</category>
<category>python</category>
<guid isPermaLink="true">http://www.nickcoleman.org/blog/index.cgi?post=python%21201007071205%21programming%2Cpython/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[
<p>
I've been spending the last couple of months teaching myself <a
href="http://www.nickcoleman.org/axs/ax.pl?http://www.python.org">Python</a> properly.  I already
had some basic knowledge of it, enough to do, say, some tasks equivalent
to Bash shell scripting, but I knew I didn't know the language
properly. I thought I would jot down some of the references and texts I
found useful.
<p>
If you know any programming language at all, you will find Python easy.
Its syntax is natural and clear.  If you have formal programming skills,
and by that I mean that you can program in another language fairly
proficiently, you will find that Python has an elegance that delights;
it is a beautiful language.  On top of that, it has object-oriented
features, data-oriented features, and some <a
href="http://www.nickcoleman.org/axs/ax.pl?http://en.wikipedia.org/wiki/Functional_programming"></a>functional
programming</a> features.  As well, it has the rapid development
facility of any scripted language, and yet it is fast.  
<p>
On to texts.  I read a great deal and already have several hundred
books, so I now intentionally limit my book-spending budget.  I found
that this wasn't a hinderance here, though.   There are some excellent
texts online that are free.  Please bear in mind that I was not looking
for beginner books since I am a programmer; I was looking for books that
assume some programming experience.  I found three particularly useful:
<ul>
<li> <a href="http://www.nickcoleman.org/axs/ax.pl?http://diveintopython.org/">Dive Into
Python</a> by Mark Pilgrim.</li>
<li> <a
href="http://www.nickcoleman.org/axs/ax.pl?http://homepage.mac.com/s_lott/books/python.html">Building
Skills In Python</a> by Steven Lott.</li>
<li> <a
href="http://www.nickcoleman.org/axs/ax.pl?http://www.mindview.net/Books/TIPython">Thinking In
Python</a> by Bruce Eckel of <i>Thinking in C++</i> and <i>Thinking in
Java</i> fame.</li>
</ul>
<p>
These three complement each other by covering slightly different ground.
<p>
<i>Dive Into Python</i> covers Python in several chapters, going from
simple features to advanced features.  It is brief, but comprehensive.
I think of it as a primer.  The latter chapters become more specific to
certain tasks such as xml processing, using the http module, and so on.
There is a lot of detail without much verbiage, which I quite like.
Skills are built by following examples that build up on previous ones in
each chapter.
<p>
<i>Building Skills in Python</i> is a very comprehensive text.  This
one is more like a text book that you would use in a university or
college course on Python.  It seems to cover the full gamut of
Python, as far as I can tell.  There is a number of exercises at
the end of each chapter, useful for testing your skills.  The exercises
intentionally are not particularly easy and are more like a mini-project
than a one-or-two sentence answer.  I suspect the author doesn't
expect you to do each one.
<p>
The text can be searched and the source can be viewed.  This is now my
reference book.
<p>
<i>Thinking In Python</i> is different to the other two, and from
Eckel's <i>Thinking in C++ Vol 1</i>.  It is more like Eckel's
<i>Thinking in C++ Vol 2</i> in that is more about design patterns and
less about teaching the language.  I'm yet to finish this one so I'll
leave it at that for now and come back later.
<p>
A newcomer will benefit from both of the first two books.  I would start
with <i>Dive Into Python</i> first then, when the content becomes a little too
specific for your needs, which will happen after several chapters, switch
to <i>Building Skills In Python</i>.  That should give you a good
grounding.
<p>
<p>
]]></content:encoded>
<wfw:commentRss>http://www.nickcoleman.org/blog/index.cgi?post=python%21201007071205%21programming%2Cpython/feed/</wfw:commentRss>
</item>
<item>
<title>Easy Charts and Graphs -- Use Google's Visualization API
</title>
<link>http://www.nickcoleman.org/blog/index.cgi?post=chartsandgraphsbygoogle%21201002040825%21software%2Cpython%2Cinternet</link>
<comments>http://www.nickcoleman.org/blog/index.cgi?post=chartsandgraphsbygoogle%21201002040825%21software%2Cpython%2Cinternet#comments</comments>
<pubDate>Thu, 04 Feb 2010 08:25:00 -0700</pubDate>
<dc:creator>Nick</dc:creator>
<category>software</category>
<category>python</category>
<category>internet</category>
<guid isPermaLink="true">http://www.nickcoleman.org/blog/index.cgi?post=chartsandgraphsbygoogle%21201002040825%21software%2Cpython%2Cinternet/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[
<p>
Have you sometimes wanted to make a quick graph or a pie chart to
display on your website?  Decided it was too hard for the amount of
effort and given up?  There is a very simple solution that is remarkably
easy.  You can use Google's Visualization API to create the graphs for you with just a
few lines of code.
<p>
Here is a screen shot of a very simple pie chart.  Note the extra
features such as a slice that pops out to identify it, a pop up with
more information, and sorted columns in the table.  These features come with it,
you don't need to do anything.
<div class="image"><img src="http://www.nickcoleman.org/blog/images/googlegraph.png" alt="google graph
example" /></div>
<p>
The image shows a pie chart and a table.  You can show either or both
plus several other types of graphs. I think it looks professional and neat.
<p>
The graphs are generated using javascript and ajax, and the browser will go and
load the Google javascript (which I guess could cause a small delay,
though on my site it is less than a second).  <a href="http://www.nickcoleman.org/blog/static/google_vis.html">Here </a> is the actual
page from which the screen shot was taken.  You will notice it is quite
quick in practical terms. Try clicking on one of the wedges, one of the
coloured index icons and a column header.
<p>
Here is the code that produced this display:
<p>
<pre><code>
<p>
&lt;html&gt;
  &lt;head&gt;
    &lt;!--Load the AJAX API--&gt;
    &lt;script type="text/javascript" src="http://www.google.com/jsapi"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;
    
      // Load the Visualization API and the piechart package.
      google.load('visualization', '1', {'packages':['piechart', 'table']});
      
      // Set a callback to run when the Google Visualization API is loaded.
      google.setOnLoadCallback(drawChart);
      
      // Callback that creates and populates a data table, 
      // instantiates the pie chart, passes in the data and
      // draws it.
      function drawChart() {
<p>
      // Create our data table.
        var data = new google.visualization.DataTable();
        data.addColumn('string', 'Task');
        data.addColumn('number', 'Hours per Day');
        data.addRows([
          ['Work', 11],
          ['Eat', 2],
          ['Commute', 2],
          ['Watch TV', 2],
          ['Sleep', 7]
        ]);
<p>
        // Instantiate and draw our chart, passing in some options.
        var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
        chart.draw(data, {width: 400, height: 240, is3D: true, title: 'My Daily Activities'});
	var table = new google.visualization.Table(document.getElementById('table_div'));
	table.draw(data );
      }
    &lt;/script&gt;
  &lt;/head&gt;
<p>
  &lt;body&gt;
    &lt;!--Div that will hold the pie chart--&gt;
    &lt;div id="chart_div"&gt;&lt;/div&gt;
    &lt;div id="table_div"&gt;&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
<p>
</code></pre>
<p>
It might look a fair bit more than the few lines of code I mentioned
above, but take out the comments and notice that 5 lines are the data
itself.  Twelve lines of code generate everything.  Most of it is template stuff and you provide only a few
parameters yourself like table type, column headings and so on.  You can see
that all of it goes in the &lt;head&gt; section, with just a couple of
&lt;div&gt; tags in the body.
<h4>Parameters</h4>
The parameters you set to control the display are the chart type, the
column and row names, the data, the chart's title, width and height, and
the &lt;div&gt; section to display the chart in the body of your page.
<p>
The chart <b>type</b> is set when you load the vizualization api itself.
You specify an array of packages; here I've chosen pie chart and table.
<p>
The <b>column names</b> are set when you add a column of data.  Then
you add the <b>rows</b> of data and there are several ways to do this.  The
simplest is to place it in an array.  Just note that this means
your data will be viewable in the source.  For simple charts this may
not matter, and you can get the data externally in which case it
won't show up. 
<p>
The <b>title</b>, <b>width</b> and <b>height</b> are set when you draw
the chart.
<p>
Finally, the chart is displayed in a <b>&lt;div&gt;</b> section that you specified
when you created the chart.
<p>
The point is that it is extremely simple and you don't need to know any
javascript at all.
<h4>More</h4>
Once you've made up one graph, you've pretty much made any others you
might want later.  You only need to copy the html file and edit the
headings, etc.  Cut and paste the data and you are done.  Simple.
<p>
The API can draw a range of different chart types such as pie, horizontal bar,
vertical columns, lines, scatter plots, and even images like piles of money.
You can also get the API to show minimum and maximums, averages, aggregators
(similar to SQL aggregators), and get the data from an external source
like a Google spreadsheet or a javascript file instead of hard
coding it into the source code of the chart's page. If you are a bit more advanced and know python,
you can use a python module to talk directly to the API and
generate everything within python.
<p>
Google's visualization documentation starts <a
href="http://www.nickcoleman.org/axs/ax.pl?http://code.google.com/apis/visualization/">here</a>, and the
docs for graphs are <a
href="http://www.nickcoleman.org/axs/ax.pl?http://code.google.com/apis/visualization/documentation/using_overview.html#preparedata">here</a>.
While you are there, check out the <a href="http://www.nickcoleman.org/axs/ax.pl?http://code.google.com/apis/ajax/playground/?type=visualization">Interactive Samples</a> section to see how the different
graph types can be used.
<p>
<h4>Sweet Spot</h4>
Finally, I offer this as a sort of after-dinner mint, one extra
visualization from Google.  The API provides a <b>tag cloud</b> gadget that you
can easily plug in to your blog or cms.  I personally am not a huge fan
of tag clouds.  To my eyes they look like a good way of obfuscating data
in a mass of competing visuals.  However, if you want one and can't be
bothered/don't know how to implement one yourself, check out a couple of
offerings of <a
href="http://www.nickcoleman.org/axs/ax.pl?http://code.google.com/apis/visualization/documentation/gadgetgallery.html">
Google's</a>.  They are straighforward to implement and look the goods.
<p>
]]></content:encoded>
<wfw:commentRss>http://www.nickcoleman.org/blog/index.cgi?post=chartsandgraphsbygoogle%21201002040825%21software%2Cpython%2Cinternet/feed/</wfw:commentRss>
</item>
<item>
<title>Kukkaisvoima Blogging Software
</title>
<link>http://www.nickcoleman.org/blog/index.cgi?post=kukkaisvoima%21200912201044%21python%2Csoftware%2Cblogging</link>
<comments>http://www.nickcoleman.org/blog/index.cgi?post=kukkaisvoima%21200912201044%21python%2Csoftware%2Cblogging#comments</comments>
<pubDate>Sun, 20 Dec 2009 10:44:00 -0700</pubDate>
<dc:creator>Nick</dc:creator>
<category>python</category>
<category>software</category>
<category>blogging</category>
<guid isPermaLink="true">http://www.nickcoleman.org/blog/index.cgi?post=kukkaisvoima%21200912201044%21python%2Csoftware%2Cblogging/</guid>
<description><![CDATA[ 
 [...]]]></description>
<content:encoded><![CDATA[
<p>
I wanted a simple light-weight personal blogging tool that lets me write in flat files.
Like many <a
href="http://www.nickcoleman.org/axs/ax.pl?http://utcc.utoronto.ca/~cks/space/blog/web/BrowsersMakeBadEditorsII">others</a>,
I very much dislike editing text in a browser, especially anything more than a
few lines.  Browsers seem so overloaded with junk and javascript nowadays
that their response time has crept up to several tenths of a second, very frustrating for a
touch-typist who needs response times of around a tenth to catch
errors <small><sup><a href="#fn1" id="back1">1</a></sup></small>.  So, this tool needed to work with flat
files that I could edit in vim and easily transfer up to the blog host.
<p>
As well, it needed to be light-weight.  I can't see my blog ever running to more
than a few hundred entries per year max.  Tools like Wordpress et al are too heavy
for me, in the sense that their processing slows things down by comparison.
<p>
Python would be good, I prefer it to PHP.  I really like it, it is a great language.
<p>
Also, I wanted some simple things like categories and comments, and search would
be nice too.
<p>
Originally, I had tried pyblosxom, but I found the lack of documentation
frustrating.  I put a few days into it and got the core working and a couple
of plugins.  Eventually though,  I gave up after two days of unsuccessfully
trying to get the comments plugin to work.  Plus, I couldn't get the logging to
work so I couldn't debug the problem.  I decided that almost a week's worth of
time was enough.  
<p>
(To be "sort of" fair to pyblosxom, they <i>are</i> in the middle of a version
upgrade, which means older plugins are broken and docs are behind the pace.
That doesn't solve my immediate need though, so pyblosxom is out for me. And,
really, I don't get the whole "I'd rather be programming" thing.  I write docs
as I go, they form the application's specifications<sup><a href="#fn2"
name="back2">2</a></sup>.)
<p>
All of which motivated me to look for something else, which led me
to <a
href="http://www.nickcoleman.org/axs/ax.pl?http://23.fi/kukkaisvoima/">Kukkaisvoima</a>, for which I'm grateful.
I downloaded and installed Kukkaisvoima  on my local machine.  It is
very useful for my needs: a light-weight simple blogging tool for flat files,
written in Python, with comments and categories.  The archive and search are a nice bonus.
<p>
<h4>Kukkaisvoima in a nutshell</h4>
Kukkaisvoima uses simple text files for posts.  The first line is the headline and everything
else is text.  HTML is allowed, which is useful for links and images.  It
requires you to use a &lt;p&gt; tag to start a new paragraph.
<p>
The text file's name is used to generate the post's date and categories.  For
example, the file name for this entry (now changed, so it won't work as a link) is
"kukkaisvoima:2009-12-20:python,software,blogging.txt", which kukkaisvoima tokenises
into three parts separated by a ':'; the first is (presumably) not used
internally, the second is used to generate the post's date, and the third is a
comma-separated list of categories for this post.  Simple and effective.
<p>
Kukkaisvoima automatically shows in the sidebar a list of categories, month archives, and a
search box.
<p>
Each post can have comments or they can be disabled globally, but not for
individual posts.  There is very limited checking on comments: required
username and email, a simple question-and-answer check for a live person (no
captcha or akismet), and html tags are stripped from the comment's text.
IP addresses are not logged.  There is no database engine, so SQL injection
is not a problem.
<p>
<h4>My Modifications</h4>
Kukkaisvoima has no docs apart from a simple README, so am I about to complain as I
did for pyblosxom?  No.  It's ok because the program logic is very simple to
follow.  It's all clear and concise, self-documenting really.  Meaningful
function names help a lot, don't they :).  I had no trouble to find my way
around the code, unlike pyblosxom which was confusing to me.   
<p>
I modified it a little to suit my needs, which is not a criticism. We all have
our own idea of what we need and how important they are.
<p>
The main things I wanted to implement were:  recording the IP address of
people making comments; removing the need for &lt;p&gt; tags to signify a new
paragraph when writing a blog entry; and removing the need for a date token
in the blog text's filename.  Fairly minor stuff, except I really wanted to
record the IP address, it was a priority for me.
<p>
The IP address turned out to be quite easy once I realised that, like PHP,
Python has it in the external environment.  I added a hidden attribute to the
comment form that recorded os.environ['REMOTE_ADDR'], and added attributes
for it to the appropriate classes and functions.  In the comments display
function, I print it out with the least-significant octet displayed as .xxx,
for privacy.  (It's still recorded in full, just not displayed.)
<p>
The tags thing was easy too.  I added a line to the display function that
checked for a newline at the start of the line, and replaced the line with "&lt;p&gt;\n".  Now I
simply put a blank line in the text, and the html renderer adds a &lt;p&gt; tag.
(I really don't like writing HTML when I'm in the middle of writing text. It
interupts the flow.)
<p>
My next change will be to the file name tokenising, to remove the need for the
date in the file name.  For my needs, I'm happy to use os.stat.CTIME to
generate the post's date.  
<p>
I also made some minor format changes: the date display uses a strtime()
format; date appears directly under the headline rather than with the
comments; IP address for each comment; and some spacing and colour changes in
the CSS.
<p>
In the CSS, I did change many px attributes to either % or em.  I have a
wide-screen laptop and fixed-size px meant the columns were quite narrow
compared to the screen's real estate.  Again, thanks to the clear relationship
between divs in the html and the css, it was very easy to find which classes
and ids needed to be changed.  
<p>
All in all, it has been a great learning experience.  I have brushed up on my
Python and my CSS understanding.  The author deserves kudos for making the
codebase clear and logical with easily understood relationships.
<p>
Oh, it's Finnish for "flower power" according to google translate.
<p>
<hr>
<div id="footnote">
<a href="#back1" id="fn1">[1]</a>  I change <a href="http://www.nickcoleman.org/axs/ax.pl?http://www.gnu.org/software/screen">screen's</a>
keystroke timeout to less than 100 msecs, otherwise I'm constantly tripping up in vim.
<p>
<a href="#back2" name="fn2">[2]</a>  You won't be surprised to hear I like
Eiffel and the self-documenting design-by-contract philosophy. <a href="#back1">&#8593;</a>
</div>
]]></content:encoded>
<wfw:commentRss>http://www.nickcoleman.org/blog/index.cgi?post=kukkaisvoima%21200912201044%21python%2Csoftware%2Cblogging/feed/</wfw:commentRss>
</item>
</channel>
</rss>

