Apache

Downloads

Links to software I've written.

WikklyText


WikklyText is a TiddlyWiki-compatible wikitext engine written in Python. It can be used both as a Drupal plug-in, as well as for creating standalone (X)HTML documents.

Read more at the WikklyText Homepage

boodebr library


The boodebr library is a collection of lower level modules that I've written here and there and finally collected together in a package. It has modules for JSON/XML pickling, configuration files, pysqlite, and other useful utilities.

Read more at the boodebr library wiki

pyconfig


Written in WikklyText.

Notes on installing Cygwin

These are my notes to document my Cygwin setup. This is certainly not the only way to install Cygwin. For brevity, I've used my personal folder names below, i.e. c:\frank, c:\frank\Run Periodically. There is nothing special about these names; adjust them to suit your preference.

  • Download setup.exe. Save to c:\Frank\Run Periodically\cygwin-setup.exe
  • Run cygwin-setup.exe:
    • Select "Install from Internet"
    • Set "root directory" to c:\frank\cygwin
    • Set "Install for All Users"
    • Set "Default text file type" to "Unix/binary"
    • Set Local Package Directory to c:\frank\Run Periodically
  • Add these packages to the default install:
    • rxvt, unzip, zip, zsh
  • From My Computer -> Properties -> Advanced -> Environment Variables, make a new variable HOME=c:\frank

rxvt

Think twice about this ...
Command-line applications that require interactive input will freeze when running under rxvt due to rxvt using ptys and normal apps not understanding them. A better solution is to run zsh in a "DOS box" as shown below.
Make a shortcut on the desktop to c:\Frank\cygwin\bin\rxvt.exe:
  • Set the Target to:
    C:\Frank\cygwin\bin\rxvt.exe 
         -fg white -bg black +sr -sl 2000 
         -fn "-*-courier new-medium-r-*-*-*-15-*-*-*-*-*-*" 
         -e /usr/bin/zsh
  • Set Start in to c:\frank

zsh in a "DOS box"


To run zsh in a "DOS box", make a shortcut on the desktop to c:\Frank\cygwin\bin\zsh.exe:
  • Set Start in to c:\frank
  • "DOS boxes" are not resizable on-the-fly, however you can set a larger size by clicking "Layout" and adjust the Window Size. Make sure the Screen Buffer width is equal to the Window size width you set so there isn't a horizontal scroll bar.
  • Set the Screen Buffer height to a large value (e.g. 1000) to enable a large scrollback buffer.
  • From the "Options" tab, turn on "QuickEdit mode". This allows copy & paste editing to/from the window:
    • To copy: Highlight text in window and right-click to copy to clipboard.
    • To paste: Copy text from somewhere into the clipboard. Right-click to paste.

Voila! 99% of the benefits of rxvt and you can also run interactive apps.

Keyboard + zsh


Some nice keybindings for your .zshrc, known to work at least in a DOS box:
# make DEL work inside a DOS box
bindkey "\e[3~" delete-char
# HOME/END key (BTW, you can capture keycodes with Ctrl+V+key)
bindkey "\e[1~" beginning-of-line
bindkey "\e[4~" end-of-line
Reference: ZSH on Dos/Windows

Text editors


Set your text editor to save files in Unix ("\n") format rather than DOS/Windows ("\r\n") format. This will save you headaches when writing shell scripts that fail to run because of \r characters.

Written in WikklyText.

The Python Tourist #2: Taking Exception

Exception handling in Python is a tremendously useful feature. I grew up on C programming, where, to write a really "correct" program, it seems like you have to spend half your code on mundane error checking.
for(i=0; i<NR; ++i) {
    result = do_thing_1();
    if (result < 0) {
        if (result == IO_ERROR) {
             /* handle error */
        }
        else if (result == API_ERROR) {
            /* handle error */
        }
        else {
            /* handle unknown error */
        }
    }
    result = do_thing_2();
    
    /* sigh ... I have to code another huge error block ... */
    ...

/* finally, the loop ends! */    
}


True, C++ has exception handling, but if you are calling standard C-library functions, then you have to go back to the mundane way.

Rewriting the above mess into an equivalent Python block gives:
try:
    # uninterrupted program logic here, no need to break up
    # the natural flow with error checking
    for i in range(NR):
        do_thing_1()
        do_thing_2()
    
# errors can all be handled out-of-line    
except IOERROR:
    # handle IO error
except API_ERROR:
    # handle API error
except:
    # handle unknown error
    # ** be careful here -- keep reading! **


Notice that I wrote "be careful here" under the last except clause. The "be careful" part is what I want to cover in this article. The topics I'm going to cover are:
  1. Globally catching unhandled errors.
  2. Catching exceptions, with details.
  3. Catching multiple exceptions.
  4. When it is bad/good to use "bare" exceptions.
Written in WikklyText.

The Python Tourist #1: Passing Mutable Objects as Default Args

Many modern languages allow for default function arguments. Default arguments can be a great thing - they allow you to use sensible defaults for the common cases, without taking away the power to add more functionality as needed. You can arbitrarily expand a function definition without breaking existing code by providing sensible defaults for the new parameters.

Here is a fun example of how Python will bite you if you try to use a mutable object (like a list, dict, or object instance) as a default argument. The following is an example function I'm trying to write ...

# OK, now I am *INTENDING* to write a routine to do the following:
#
#    Append an item to a list, returning the list.
#    If no list is passed, a new list is created.
#
# Here is my first attempt at implementation ...
def add_item(item, the_list = []):    
    the_list.append(item)
    return the_list


At first glance this appears to do what is intended. If the user doesn't pass a list to append items to, then a new list is started. Or at least that appears to be what will happen.
Written in WikklyText.

Having Drupal live in a subdirectory

The easiest way to install Drupal is to have it live in the root of your webserver. However, I don't like doing that, because I have other top-level directories under my webroot, and I don't want to clutter up the root with the Drupal files. Having Drupal in a subdirectory makes maintenance a lot easier (IMO, of course).

For reference, my webserver is set up like this:

  • boodebr.org root = /var/htdocs/boodebr
  • Drupal root = /var/htdocs/boodebr/main
  • boodebr.org is an Apache VirtualHost (the real root is /var/htdocs).

I have to do three things to set it up the way I want:

  1. Redirect visitors from http://boodebr.org to http://boodebr.org/main
  2. Tell Drupal that it is living under "/main" and not under "/"
  3. Tweak the Apache httpd.conf so that URL rewriting will work under the VirtualHost.
Syndicate content