Language Comparisons
I won't be the last (or the first) person to point to Paul Prescod's comparison of Python and Lisp but if you haven't read it yet may I heartily recommend it to you.
A wise and valued colleague once suggested to me that good programmers should learn a new language every year. That way they can absorb all of the good, and bad, points in the language and improve their skills.
I'm personally running at about one language every ten years, but the discussion between Paul's Prescod and Graham has got me resolved to spread my wings a little. As soon as I've pared down my to-do list a little I think its time to explore scheme and maybe even squeak. If it doesn't make me a better person I'll let you know.
This is not a tech news site, but ...
This is cool. When I worked in a defunct dot com (before it was defunct) the limiting factor for our VoIP network was that there had to be a piece of our kit at each end of every call. ENUM solves that dilemma by making any internet connected entity addressable.
Which, to the unitiated, means you will be able to call me (eventually) by dialling "phone.halfcooked.com"
Vim
Today's top Vim tip. To escape special characters in vi you prefixed them with ^v (that is ctrl-v to all of you Windows users ;-) This doesn't work in Vim because ctrl-v is the now ubiqituous short cut for 'paste'. To escape a special character in Vim use ^q (ctrl-q). Sweet. As an example, if you have an SQL select statement and you would like each column in the select clause on a separate line, just type :s/, /,<ctrl-q><ctrl-m>/g and Bob will be your Auntie's live in lover.
Oh, and to be fair to the emacsen I almost installed it that other editor on my machine at work today. When you finally get to the download page at http://www.xemacs.org/ (hint, it is at the stunningly obvious URL of http://ftp.xemacs.org/pub/xemacs/binaries/wind32/installshield/) the Windows installer is 23.3Mb - do you have any idea how long that takes to download over a 56k line? Maybe another time.
A Slight Diversion
I'd just like to take a break from our scheduled coverage to wish Mark Pilgrim a happy 29.5 birthday. Keep up the good work Mark, but twenty nine and a half? Really.
Solving Problems by Displacement
This is an interesting technique I learnt a long time ago. So long, in fact, I can't remember when I picked it up. It goes something along the lines of, when trying to solve a problem, don't pick at it, go and do something else. What then happens is that your self conscious goes to work and before you know it a solution can present itself to you almost fully formed. At the very least you come back to your problem a little more objectively and are able to tell the wood from the trees or look at it a little differently and maybe a fresh angle is all you need.
After my last post I headed for the local swimming pool and followed the black line for a while. During one of my laps I found myself thinking that maybe I was asking the wrong question. And I was. The question was not "How do I emulate NVL like functionality in databases that don't support it?" It should have been "Where do I enforce these kind of rules?" The answer, of course, is not in the database layer, but in the application (or business object) layer we build on top of the database layer.
In my years spent developing Oracle solutions I have always enforced as many business rules in the database as possible. This is because the vast majority of applications I have worked with have been developed in tools like Oracle Developer where the developer writes lots of SQL. But in this case that won't be true. Anyone writing code for the application will go through the object model which I craft on top of the database, because all of the code will be in Python and frankly its much easier to write a bit of Python than try and figure out my relational data model and write some SQL.
This isn't foolproof, but its certainly good enough. The result of this is that my object layer will worry about complex features of attributes, and the database classes will only have to worry about persisting the information in the right data type. So my new code for the insert I mentioned in my previous post, and which will work with Oracle, MySQL and Gadfly, will beINSERT INTO stock_prices
( symbol, price_date, price )
VALUES
( '%s', '%s', %0.3f )
Multi Vendor SQL
I'm developing some software. "Gosh" I hear you say, "that is original for someone who claims to be a programmer". Well it is, but I am going to do it anyway.
I'm doing this for a number of reasons, not least of which is to stress the PythonCard prototype framework. Because of my previously expressed interest in storage (particular of the transparent nature) I'm also trying to write my code in a vendor-neutral fashion so that my application can work with a number of different databases. This is not as easy as it sounds.
For the time being I am limiting myself to Oracle, MySQL and Gadfly. Its the last one that will be the hardest work, as Gadfly only supports a limited subset of the functionality which you would expect from a fully fledged RDBMS. But I am getting ahead of myself here.
This isn't going to be a nice, perfectly worked out, tutorial. Rather this will be a series of posts sharing my successes and frustrations. I will point out interesting things I found out on my journey of adventure, and hopefully share some cool code with you as well.
Our first cab off the rank is delving into the differences between different dialects of SQL. Rather than work them out myself and print them here, its best to re-use. That article on www.oreilly.com is a treasure trove for cross database developers.
Faced with the choice of writing different back-end modules for each of the databases I wish to support or using a framework I have chosen to use a framework. I'm going to be using the zdc application, part of the weblib framework originally developed by Michal Wallace. I shall also be liberally borrowing from the Bulldozer framework currently under development by Patrick O'Brien. If you want a gentle introduction to the object-relational mapping framework, wander on by to webAppWorkshop and tell them that I sent you.
If you have recovered from the linkfest then consider our first problem, NULLs. I wrote my first bunch of code directly for Oracle, before getting bitten by the mutli platform bug. So here is a sample statement;INSERT INTO stock_prices
( symbol, price_date, price)
VALUES
( '%s', nvl(to_date('%s', 'DD-MON-YYYY'), trunc(sysdate)), %0.3f)Nice code, eh? Well it won't work in MySQL or Gadfly. Our first problem is the use of the NVL. This is a standard Oracle function meaning 'null values'. If the first argument (our passed in date value) is NULL it substitutes the second value (the current system date). NVL is great, it is part of one of the first rules every Oracle programmer learns; "Don't forget your NVLs"
Well, I can't use it. Nor for that matter can I use sysdate, to_date (Gadfly doesn't have a date data type) or the format mask 'DD-MON-YYYY'. I don't want to build my own date class, but I'm going to have to think about this one.
First though, I'm going to bash around with NULLs and NVL. Hopefully the next post will contain a nice simple answer. Then again ...
Headings in Blogger
Dorothea asks if you can give posts a title in Blogger. The simple answer is no.
So how do I do it then? Firstly, I stripped almost all of the markup from around the post in my template. But I was forced to include <p> tags inside the <blockquote> tags to make the page valid XHTML.
So at the beginning of each post in Blogger I type </p><h4>a witty and pithy title</h4><p> and Bob is your aunties live in lover.
Now I'm going to try and communicate this information to Dorothea via referer logs, failing that I may have to send an email later today <0.5 wink>
<edit>Of course, if I had perused my own archives the answer was already there. Is duplication a bad thing? Or am I just revising the information in this post? Who knows, but I should probably get back to posting about Python.</edit>
Couldn't Resist
According to Mark Pilgrim I'm confident in my HTML markup skills. Well, thats not good enough I want to be an arrogant snob as well. There, that feels better.
Now all I need to do is figure out how to ping weblogs.com whenever I post and I can be part of his next statistical analysis.
More CSS
Definitely the last change, until I make the next one.
I have added support for the cite, acronym and abbr html tags. Inspired by Mark Pilgrim and the always amusing Stavros the Wonder Chicken any item with an underline will now have a little tool tip to show you what it means. This is achieved quite easily in my style sheet (and yours too if you want) with these two simple entries;acronym, abbr, cite {
font-style: normal;
}
acronym[title], abbr[title], cite[title] {
border-bottom: 1px dotted black;
cursor: help;
}Thanks for the help guys.
One last change. As I am now putting the archives of this blog in their own directory on the server they were not rendering with my style sheet. This was because I had a relative link in my template rather than an absolute one. I've now changed this and hopefully every page should render in this awfully nice green tone. It looks especially good on my electromagnetically damaged monitor at work, the closest metaphor I can use is probably "bogey green". Nice.
Result!
.
I thank you. Of course, not everything is perfect, (and don't even go near the archives) but this is a good start.
The final step was to find a way to put post titles (as above) in this blog. Blogger doesn't currently have a way to title posts. I used to just put the first line in <strong> tags, but have recently switched to using <h4> as this arguably more correct HTML, and gives me more control over presentation via my stylesheet.
This presents a problem when you generate content from Blogger because the template really needs each post to be enclosed in <p> tags.
Once I had solved all of my other validation problems I was still stuck with this one. The compromise I have reached with myself is to have a blank line before each post. This is done by putting a closing </p> tag before the opening <h4> tag. I couldn't come up with another way to ensure my post headers were valid so I've stuck with this one. To see what I do just view the source of this page.
Oh, and the eagle eyed will have spotted the links to my stylesheet and Blogger template in the previous paragraphs.
Most of my validation problems were caused by the "Convert Line Breaks" flag in Blogger.
When this is set, each carriage return is translated to <br> tag and each blank line is converted to a <p> tag. This is not valid XHTML and the validator stringently objects to their presence. I've turned that flag off now, so we are getting there.
Success!. Well almost. The front page validates as strict XHTML, but this page stumbles a bit. Well, alright, a lot.
Hmm, time to open the bonnet and have a bit of a fiddle. I think I will need to add some new items to my style sheet.
Transition to CSS and XHTML
Now I've definitely done it. I've just uploaded a new style sheet and blogger template. Wish me luck as I press the button.
Well, now I've gone and done it. I reviewed my to do list today and top of the list (after languishing at number three for a couple of months) is to rebuild this web site and blog.
Specifically, I'm going all xhtml and css on you. Rather than document my toings and froings here though, I'll just point you at the places where I'm getting my information from.
The tutorial is being carried out by Dorothea Salo who is remolding AKMA's Random Thoughts with support and encouragement from Jonathon Delacour and Mark Pilgrim.
Changes will (hopefully) be made here in an orderly fashion, but until I say so, consider the "under construction" sign to be flashing. Oh, and when I'm done here, I'm off to my other site. But thats going to be a rather bigger job I fancy.
There is a new version of Gadfly available at SourceForge. Excellent.
Hot Off the Presses
PythonCard is a GUI construction kit for building cross-platform desktop applications on Windows, Mac OS X, and Linux.
Release 0.6.6 includes 30 sample applications, new additions include a source code editor and a sample for creating flat file databases. This release also supports the new wxPython 2.3.3 preview for Mac OS X.
All the information you need about PythonCard can be found on the project web page at: http://pythoncard.sourceforge.net/
The installation instructions and walkthroughs are available on the main documentation page: http://pythoncard.sourceforge.net/documentation.html
You can download the latest release at: http://sourceforge.net/project/showfiles.php?group_id=19015
For a list of some of the samples that have been built with PythonCard and screenshots of them in action go to: http://pythoncard.sourceforge.net/samples.html
A description of each sample is included in the readme.txt file in each sample directory.
The kind people at SourceForge host the project: http://sourceforge.net/projects/pythoncard/
If you want to get involved the main contact point is the Mailing list: http://lists.sourceforge.net/lists/listinfo/pythoncard-users
PythonCard requires Python 2.1.x or later and wxPython 2.3.2.1 or later. wxPython can be downloaded at http://www.wxpython.org/
Reasons I Choose Python
Number one in an occasional series.
Java makes a lot of fuss about a lot of things that Python just does, without any fuss. - Ian Bicking on c.l.p
Whilst you are there, read the whole thread, its quite interesting. Then go and read the exceptionally good J2EE training materials courtesy of MassLight inc.. If you are still confused about J2EE then welcome to my world and say hello to Python.
Seamless Persistent Storage
There is a new release of PythonCard coming out this week, lots of interesting new goodies ...
Meanwhile I'm struggling with a way to come up with transparent persistent storage in an easy to use desktop development environment. The existing flatfileDatabase sample is my starting point. In it Kevin takes a Model-View-Controller approach to storing fairly standard address records in a text file. The storage approach is fairly forceful, it simply saves the current record when you navigate out of it, but it should prove an interesting test bed for integrating other storage mechanisms. Top of my heap are shelve and MySQL. What I need to do is implement a generic storage mechanism. Inspired by the contents of weblib and bdoz how is this for a first stab at a super class definition;
class Storage:
def open(self):
"Initialise this storage object"
pass
def store(self, table, **row):
"Store an item"
pass
def fetch(self, table, id):
"Fetch an item by its key"
pass
def find(self, table, where):
"Find an item by a non-key value"
pass
def delete(self, table, id):
"Remove an item permanently"
pass
def _insert(self, table, **row):
raise NotImplementedError
def _update(self, table, **row):
raise NotImplementedError
The stored items would be passed arounds as dictionaries I think. This makes interfacing with ZODB and shelve quite easy and is quite analagous for us RDBMS types. I think I will let this kick around in my subconscious for a bit before I actually get off my bum and try and implement it.
Radio Userland on notice
I've got another blog in Radio Userland. I haven't been able to post to it (apart from one notable exception) for the last couple of weeks.
Well I am now putting it on an official death watch. I am going to dual post to this blog and to 99% of Gargoyles for the next couple of weeks. Any posts that do not go through to there will be echoed here. If progress continues as it has for the last couple of weeks then I will have to abandon it and stick with dear old blogger. I'll let you know how it goes.
Dual Booting
Its good to see that I'm not alone. Mark Pilgrim is having the same problem dual booting as I am. The other issue he doesn't note is that file permissions on vfat volumes are a little arbitrary.
Its not surprising given that Windows and Unix have such different schemes, but it is a little annoying that when you mount a Windows device (vfat drive) under Linux that all of the files on it appear to belong to root.
Eating your own dog food
In an attempt to prove the software I'm helping to develop I am testing out the textRouter sample from PythonCard.
Architecture of a laptop
I'm also trying to get to grips with basic CGI scripting in Apache, but more on that later. What I have discovered is that I have an Apache server running on my laptop and I didn't even know it. Rather than constantly updating and then copying files to my hosting provider (the lovely people at cornerhost) I thought I could work on them locally and only put them up when they work. It would save me from RSI caused by firing up ftp every couple of minutes.
I downloaded a web server and installed it. When I fired it up it told me that something was already listening on port 80. When I delved further I got an Oracle help screen. A-ha, I thought I've got Oracle 8.1.6 running on this machine, it must have some sort of http server built in. Sure enough it does, Apache.
Cue much slapping of forehead and cursing of Redwood Shores. So I can not only test my html and CGI scripts out locally, but I don't need to install any more software to do so. Its just a shame that I make my living using Oracle software and hadn't realised this was the case - woops.
For the curious, if you just want to use the Oracle/Apache set up out of the box and you have Oracle 8i (or above) installed on a machine near you, stick your html files in $ORACLE_HOME/Apache/Apache/htdocs and your CGI scripts in $ORACLE_HOME/Apache/Apache/cgi-bin
Oh, and whilst I'm here - Verisign you are bad people.
A Digression HP and Compaq have merged. Big deal. But this piece at the Register is probably the most cogent analysis of the merger to date. Oh, and they object to the completely meaningless management speak almost as much as I do. Going to market, indeed.
Now we are into uncharted territory. I am moving this blog (and my whole domain) to a new hosting provider. Anything exciting I find will, of course, be shared here. I'm hoping it all goes smoothly, and if that is the case this is the last you will hear on the topic.
Today I've managed to make Mozilla look nice on KDE. Its not as simple as it sounds as it doesn't act like a native application. The window borders conform to whatever desktop set up you have, but the button, menu and associated text items use a really ugly and quite large font. I spent ages going through the preferences dialog to no effect. Then a random Google picked up a vein of useful information. You change the look and feel of your browser window using cascading style sheets. For more information see the Customizing Mozilla page. Of course, this being Mozilla there isn't a definitive list of the options and what they will affect so experimentation is the key. For the curious, just to get rid of the hideous font in the application, just create a file called userChrome.css in the directory $HOME/.mozilla/
/ /chrome. Mine simply contains a comment and then; * { font-family: "Helvetica" !important; font-size: 12px; }
From this post on Slashdot, taken from the OpenOffice.org frequently asked questions; Q. Is OpenOffice.org 1.0 100% Microsoft Office file compatible? A. As Microsoft rarely publish their file specifications, no-one can answer that question. However, there are plenty of users who regularly edit and exchange documents, spreadsheets, etc with Microsoft Office users without any problems. Indeed, some users claim they've seen bigger compatibility problems moving between versions of Microsoft's own products. Q. I've just saved a file from Microsoft Office in OpenOffice.org format, and it's much smaller - yet it hasn't lost anything? A. Good, isn't it? Q. Has this suite got that annoying paperclip? A. No. Never has, never will. No. No! Made me chuckle anyway.