Comments(0) | Print | Home
I was writing a macro to create an Index tab and couldn't find anything directly related to iterating through the Sheets collection. You can't hyperlink to a Chart tab nor does it have a Cells() method so the index entry processing needs to be different. Anyway, this code extract works for me. YKMV
Dim mySht as Object
For Each mySht In Application.Sheets
If mySht.Type = xlWorksheet Then
' Process a Worksheet tab
Else
' Process a Chart tab
End If
Next mySht
Comments(0) | Print | Home
I read about map my run and tried it. There was a lot of registering involved and the UI over Google maps seemed to move the map around too much as I moved the cursor to do a route.
I mentioned the site to a friend and she suggested Gmaps Pedometer. This site is much simpler: you plot a route, save it and it returns a URL. Just the simplicity I need to find out how far I walked my dog or to lay out a 5k lunchtime jog.
Comments(0) | Print | Home
I guess it had to happen sooner or later…I joined Facebook. Facebook disallowed Service. First I used Ecivres, then changed it to Serçice then I noticed my son had the right name so I sent an email got the correct last name.
I have “connected” with a couple of cousins that I haven’t seen since they were little kids.
Come on over and be my friend.
)
Comments(0) | Print | Home
The door springs broke on the old dishwasher and the door is so heavy that one side bracket cracked the side of the door. We bought a new one since this old one has lasted over twenty years.
I uncrated the new Maytag model and put it in the space where the old one was. Two problems: the hot water fitting is in a different place so that I either have to cut the copper pipe or, my preference, use a stainless steel flexible line. I note that there is already a union in that pipe so I must have lengthened it when I installed the old dishwasher.
The other problem is that the sound deadening package of plastic and rubber flanges require an opening of just 24 inches. I’ll have to do some shimming of the opening and the kick plate area.
I guess I’ll be washing dishes in the sink for a few more days more.
Comments(0) | Print | Home
I use rsync on my Unix boxes to archive or update directories on different host machines. Recently I have started using it to synchronize directories between my Windows boxes at work and at home (through the VPN) via the SAN drives. This works quite well, especially for files such as large Word documents as the format just seems to include new stuff in chunks so that the rsync algorithm need only update the changes. Using the -z compression switch also helps to speed the transfer.
I include a short file I’ll call rsync.sh. I run bash in cygwin and paste in the appropriate line. I keep the -n switch so that no action will take place initially and I’ll recognize whether the list of files to be transferred looks correct.
# remove -n to do the operation # home to work rsync -n -Cavz --stats /cygdrive/c/home/jservice/work/DIR /cygdrive/h/network/ # work to home rsync -n -Cavz --stats /cygdrive/h/network/DIR /cygdrive/c/home/jservice/work/ # network to desktop rsync -n -Cavz --stats /cygdrive/h/network/DIR /cygdrive/d/work/ # desktop to network rsync -n -Cavz --stats /cygdrive/d/work/DIR /cygdrive/h/network/
Comments(0) | Print | Home
At work I used VNC to connect from my desktop PC to another win2k box in a lab a floor and a building away. From that box I dialed out using PCanywhere to a win2k box in a transformer station near Sudbury.
Today it was a Terminal Services client through the VPN to a win2k server box. From there I used Putty as an SSH client to connect to a FreeBSD box. Then I ran screen on that.
Comments(0) | Print | Home
I spent almost a day trying to find out why my dialog in Borland C++ was closing with the press of an <Enter> or <Esc> key. When I set a break point I found those keys weren’t even being seen by the dialog. Finally after considerably searching I found that controls such as buttons have a Default property. If this is true then <Enter> or <Esc> will automatically press that button. Thanks for making this clear!
Comments(0) | Print | Home
Sheesh! I re-enabled comments and then went away on business for a week. Though I did have Internet at some of the hotels I discovered that MT-Blacklist didn’t work on the server. There were at least 800 comment spams added.
Finally, this weekend, I exported my entire blog. I wrote a Perl script to remove the offending comments and to close all commenting. I started to tediously delete all the old entries until I found that the Web Developer Toolbar for Firefox could automatically populate all the delete boxes.
So, the blog is renamed and all the comments are closed. Now you commentors will have to email jservice (at) gmail (dot) com if you would like me to add your comment.
Comments(0) | Print | Home
When this blog switched servers, the Email::Valid module was missing. Now I’ve put it back and comments can be made. (Will I regret this?)
Comments(0) | Print | Home
It doesn’t seem to turn on no mo'.
I didn’t use the mp3 part much; but, I miss listening to CBC Radio One while commuting to work already.
Comments(0) | Print | Home
I had a rather complicated view where I needed to duplicate each row and change one column in every other row. I came up with this function:
-- Function: numbers(count int4)
-- DROP FUNCTION numbers(count int4);
CREATE OR REPLACE FUNCTION numbers(count int4)
RETURNS SETOF int4 AS
$BODY$
BEGIN
-- Usage: select * from numbers(10)
-- returns a column of integers from 0 to 9
--
for i in 0 .. count - 1 loop
return next i ;
end loop ;
return ;
END ;
$BODY$
LANGUAGE 'plpgsql' IMMUTABLE;
To make 3 copies of each row of table I could use the following:
select * from mytable,numbers(3)
Comments(0) | Print | Home
An estimate for replacing tub, taps, wall tiles and adding floor tiles amounted to $5k! This didn’t include a new toilet, vanity or light fixtures. For about 1% of that amount I spent the weekend cleaning and epoxy painting the tub. Looks pretty good. Now I have to wait a few days while the paint cures and then re-caulk.
Comments(0) | Print | Home
A client provided an MS Access export of their asset database: a table of 330,000 rows by 77 columns. Good ol' Access felt these data needed over 2 Gbytes of storage. I exported the table as a CSV file, about 143 Mbytes and then imported it into PostgreSQL. It needed only 240 Mbytes or so. Queries are much faster than with Access, too. When I made a compressed backup (dump) of the table from PostgreSQL only a modest 7.9 Mbytes was required.
Comments(0) | Print | Home
Finnegan, our dog is wearing out our backyard. And we can’t let him out after a rain as he’s worn down the grass to the bare clayey soil. So, I’m partitioning off, with chain link fencing, part of the back yard and the west side yard for a dog run.
Yesterday it took me an afternoon and evening to put in 3 six inch by 27 to 30 inch holes. The middle hole was the “easiest” as there were no large rocks or roots. Just a thunk, scoop, thunk, scoop with the post hole digger. The first hole had several tree roots along the way and several larger stones to extract. Once I cut the forked tree root at the top of the third hole the thunking part wouldn’t work. I needed to use my 3 foot crowbar to “loosen” up an inch or so of clay and then use the post hole digger to extract this. This was all very laborious and time consuming. However, I doubt a power auger would have worked in our heavy clay.
Today I set the three poles in the three holes with quick setting post-hole concrete. I didn’t even need to stake the last pole vertical as the concrete had all ready set enough. For the other two poles I found my heavy pipe clamps laid on the ground were sufficient to hole the fence posts in place.
Comments(0) | Print | Home
I sifted the compost yesterday and, since there were no stones, I thought I would run the lumps (sticks, grass roots, pits, etc) that didn’t sift through the chipper / shredder (CS). However it has been raining a lot lately and there was enough sticky clay to gum up the works. Once I stopped the engine I couldn’t restart it. At least I have taken the guard off the CS before so it didn’t take me long to clean out the gunk. And, yes the lumps are smaller now and mixed up with weed and twig bits ready for some more composting action.
Comments(0) | Print | Home
My son’s server died so he had moved my home directories including this blog over to a different server. However, the set up and permissions for the cgis to run the blog updates weren’t set correctly. I have been just a tad too busy to solve the problems until tonight.
Comments(0) | Print | Home
I write a lot of Perl scripts that run periodically in the background through the so-called Task Scheduler. Each of these scripts appends to a log file and sends a one-liner to the next-to-useless Event Log to report the path to this log file. I redirect STDOUT and STDERR to the log file so that everthing gets set there. This all works fine using perl.exe but not with wperl.exe the “non console” version of perl.exe. Today I found out why.
In wperl.exe fileno(STDOUT) returns -1, an invalid file handle number. So, you have to close(STDOUT) and then open(STDOUT, “>>$log_file”). In perl.exe I would open(LOGFILE, “>>$log_file”) and then open(STDOUT, “>&LOGFILE”). Now I can run (w)perl scripts at user logon/off and system startup/shutdown events and still have some logs to look at if something goes awry.
Comments(0) | Print | Home
For the last four years I have been using an Excel spreadsheet to log the receipts for my wife’s music teaching business. In previous years I’d log each receipt with a code (ele - electricity bill, os - office supplies, etc), the date and the amount. Then I would sort this list of 200 - 300 items by code and date and confirm that I have each month’s utility bill. Each of those ranges I would name, sum them and name the sums: a lot of work, especially if I found another receipt or two.
This year I’m using DSUM and DCOUNT the “database like” functions of Excel. Now I don’t need to sort the receipts anymore. I just select on the codes to get the various sums. I also downloaded all 2005’s worth of chequing account transactions from my credit union in the form of a spreadsheet. Again I could use DSUM and DCOUNT to select and sum all the automatically deducted utility bills. After an afternoon (most of that was spent setting up the DSUM magic) and an evening’s work that part is done—a process that has taken me several weekends in the past.
Comments(0) | Print | Home
I wrote an ISO9000:2000 internal audit report which is basically a long table of section numbers from the standard, brief descriptions, a rating and my observations; especially if I rated the section UNSatisfactory. I used LATEX (LaTeX) to typeset the report and found that the \afterpage macro doesn’t work in \longtable. I usually use something like this on the title page:
\lhead{}\chead{}\rhead{\putlogo}
\afterpage{\chead{\MyTitle}}
After some head-scratching I came up with the following using the \ifthenelse macro to achieve the same effect. Now the header logic is inside the header itself.
\lhead{}\chead{%
\ifthenelse{\equal{1}{\thepage}}
{}
{\MyTitle}}\rhead{\putlogo}
Comments(0) | Print | Home
Through the This is True email list I found this standard scout knot site with animations.
The only missing knot was something with which to tie down your canoe to the car roof racks. The driver’s hitch, here or here would seem to be suitable though I use a simple overhand loop which, admittedly, gets very difficult to untie at the end of a couple of hundred kilometers. I don’t normally make New Year’s Resolutions; however, I might learn this knot…and the one I found for tying fishing line to a fish hook.
Comments(0) | Print | Home
Well, it seems I have either a) lost interest, b) lost time, c) found other things to do or d) all of the above with respect to this blog. My first post was way back on Feb. 25, 2002. Our dog, now almost one year old, accounts for b) and c) as well as becoming choir manager, and a) arises because, after walking the dog in the evening, I don’t feel much like spending another half an hour posting something.
Perhaps I should try posting just a sentence or fragment instead of paragraphs.
Anyway, my software find this week is Audacity. I decided to start digitizing choir concert tapes from years ago. I can record one side of a tape and then slice out the selections, creating mp3 files out of them. So far I have done one Bell’Arte Singers set of two tapes from Nov. 1998 and one Toronto Chamber Society concert from Nov. 1981. The TCS turned out all right. The BAS tapes have either been played too much or they weren’t recorded at a high enough level. Their sound is kind of rumbly and muddy. I tried the FFT filter from the Audacity library to cut out the low frequencies: less rumbly now but the vocal sounds still aren’t very clear.
As for the 1981 tape, I don’t have the program just the titles I wrote on the cover. Through the “miracle” of the Internet though, I can search for midis based on the titles and, from listening to those, I can determine the correct title and composer.
Comments(0) | Print | Home
I have an hourly scheduled set of commands that take between 15 and 20 minutes to complete on my work PC. I found out how to automatically start the cmd with the console minimized. Just recently I discovered how to get rid of the window entirely using Win32::GUI:
@perl -MWin32::GUI -e "$dos = Win32::GUI::GetPerlWindow() ; Win32::GUI::Hide($dos)"
Now I would like to find a or write a small NotifyIcon application to which other processes can talk and change either the icon or the tooltip in order to report the status of those processes running in the hidden console window.
Comments(0) | Print | Home
Hmmm, I forget a ~ yet again in my Perl code and spent quite a while trying to figure why a variable was empty. Sheesh!
# The following means assign $b the "success" of $_ =~ s/.dat// # whatever $_ is at this point $b = s/\.dat// ; # This is a regexp substitution: remove first occurrence # of ".dat" from $b. $b =~ s/\.dat// ;
Comments(0) | Print | Home
A colleague wanted to send out a mass email with attachments announcing a new piece of test equipment. I looked at a few packages and finally decided on Mail Merge Toolkit as having the necessary features to link a MS Word merge with email. Well, it came time to do it today and I find out the colleague uses Work 97 and this add-in only works for Word 2000 and above. Sigh. Since we are on a common domain he logged on to my machine and I tried the installation and merging using his account. Another sigh. He didn’t have admin rights so the install was incomplete. I had to log in as myself put him in the admin group and then get him to log in again. Finally I managed to send out the 131 emails with “glossy pdf” attachment.
It had to be done today because he is going on an extended vacation using up banked days until sometime next June we he officially retires. Me, I can only recall one or two years of the almost 30 when I might have banked a few days. I’m of the school where vacation is meant to be taken and enjoyed in the year that it is granted.
Comments(0) | Print | Home
This past weekend I added Google site search to the company website. This replaces the “so Twentieth Century” local search engine. Now the PDFiles and DOCuments are indexed, too.
Comments(0) | Print | Home
Comments(0) | Print | Home
The old windows were replaced last month; however, I hadn’t had the chance to take pictures until yesterday. My favourite is the large awning window in the kitchen. When we were cooking for 20 on Thanksgiving, I could cool off the kitchen with the ceiling fan and opening the window. The old window here was a sticky-side slider which we eventually gave up using.
“Siding” the kitchen window and living room window eliminates two more outside paint jobs. Though the thermostat has been switched to “heat” it hasn’t come on at all yet because these window insulate so much better than the old ones. These windows, as well as being low-E and better insulated, are also “self-clean”, too.
Comments(0) | Print | Home


I tried to print a page from one website, an IBM developer article I think, and, no matter how I shrunk it, part or all of some of the words in the right margin were cut off. This was in Firefox. I tried IE —same result. Since Opera is now free and I had recently installed it, I tried this browser. Success, all the paragraphs were displayed, however, I should have “print previewed” the whole document as Opera gave me 10 extra neatly numbered, URL titled, marked and dated blank pages!
Comments(0) | Print | Home
I wrote a script to format “per channel, hourly” statuses into an Excel spreadsheet and an html table using variously coloured boxes to show the status (good, fair, poor, no data, etc). It was easy enough to date the “past week” files with the current day-date in the file name. However, after a couple of months, there are a number of these daily files, each with 6 days worth of redundant data. Yesterday I wrote a small function to return the timestamp of the Saturday for the current week’s data. Now I will have only one weekly spreadsheet and html file per week showing that week’s status.
The Perl function is quite short:
# Index of date numbers returned by localtime.
%DATE_INDEX = (isdst => 8, yearday => 7, weekday => 6,
year => 5, month => 4, day => 3,
hours => 2, minutes => 1, seconds =>0) ;
$_ONE_HOUR = 60*60 ; # seconds/hour
$_ONE_DAY = 24 * $_ONE_HOUR ; # seconds/day
# ...
sub week_ending_time ($) {
# Given a serial time find the time on the next Saturday.
my $time = shift || time ;
# Add number of days until next Saturday.
$time + (6 - (gmtime($time))[$DATE_INDEX{weekday}])*$_ONE_DAY ;
}
I also wrote a PostgreSQL function equivalent:
CREATE OR REPLACE FUNCTION week_ending_date("timestamp")
RETURNS "timestamp" AS
$BODY$select date_trunc('day', $1) + (6-(date_part('dow', $1)) || ' days')::interval
$BODY$
LANGUAGE 'sql' VOLATILE;
Comments(0) | Print | Home
This Labour Day long weekend, at the end of my August vacation (except for being called in 5 days to work!), I wanted to clean up the garage. There are pieces of drywall and birch veneer particle board, for example, that have been moved (and re-moved) from my first house where my oldest son was born. I think that after 25 years, most of this stuff has got to go. That drywall was used to repair a wall in my older son’s nursery and the birch veneer particle board was used for kitchen cabinets in our first house. I’m not sure why I moved three 4' x 8' x 1½”sheets of styrofoam insulation from the last house or why I bought it in the first place. Anyway, I’ve cut it up to put out for recycling and and generated lots of bits of styrofoam chips to sweep up. Through experimentation, I found a hand saw works best. The serrated knife generated too many styrofoam bits and required more effort.
Tomorrow I’ll use my table saw or chop saw to cut the scraps of wood to length to bundle up for the garbage.
No pictures because a) I forgot to take one “before” and b) unless you were the one trying to find something in the junk, the picture wouldn’t tell the story.
Comments(0) | Print | Home
I had several ½” holes to drill into the brick in my house in order to “sturdy up” and “verticalize” the deck railings with some brackets. It took an hour to go in about ½” with my 3/8” 2-speed drill (a wedding present to me from my best man, btw). I brought out my other drill but it happened to fall off the railing and crack the handle. I considered this an omen: go out and buy yourself a hammer drill. So I did.
It took me about 15 minutes to do the four holes I required with that tool. I should have bought one years ago. For example, it took me most of the day to drill a 5/8” hole through the foundation wall of my previous house to add a new outside hose tap. I was swapping my two drills as one would get too hot to hold. I suspect that with a hammer drill it might have taken 15 minutes, tops.
Duct tape, “the handyman’s secret weapon,” fixed the drill’s handle.
Comments(0) | Print | Home
I hate being indispensable when I’m supposed to be on vacation!
First it was a power outage and then a drastic change in IP address from the infamous sympatico.ca prevented data getting through for a few days while I was canoing in Algonquin Park. I spent a day fixing this.
Then, coincidently, bad blocks appeared on the root partition of my server and it wouldn’t boot after yet another local power outage. So we purchased to new brand new hard drives. One of them I put in the old server and made the old disk a “slave.” Then I used the FreeBSD miniinst CD to install the OS on the new disk. Then I could rsync all of /usr from the old to the new drive. I also rsync'd /var/log, too. Finally I had to tweak the /etc files. Fortunately I had a backup copy as / was hosed on the old drive. The new and improved server worked fine once it was re-installed in the so-called DMZ at work. Thus ended the second day.
Today I “constructed” a backup server with that other new hard drive installed in another surplus office computer. This was somewhat slower install because, after I had installed the OS from the miniinst CD I had to bring over the rsync executable from the other server. Then I rsync'd /usr and /var/log over the network. As left this backup server will mirror the original server so that, hopefully, I’ll be able to swap if the original server dies. So endeth the third day.
I “pretended” I was on vacation by walking the dog first, picking up a coffee on the way, and coming in to work later wearing shorts and sandals. Oh well, this means three more vacation days later on.
Comments(0) | Print | Home
I wrote a trigger function today to “audit” a table of readings I’ll call
mydata which has new records automatically INSERTed by a
script. Occasionally there are “funny” entries which I have to manually fix up
using pgAdmin III's grid widget. However, I wanted some way of keeping
track of the old changes in a log table. So, I wrote this trigger function to generate an update query which would change the modified record back to the old one. The trigger fires on updates to the mydata table each time I edit a row.
CREATE OR REPLACE FUNCTION mydata_update()
RETURNS "trigger" AS
$BODY$BEGIN
-- Add an entry to mydata_log about the old data.
insert into mydata_log (date,channel,outer_channel,rdg_date,rdg_hour,comment)
values (OLD.reading_stamp,OLD.channel,OLD.outer_channel,OLD.rdg_date,OLD.rdg_hour,
-- Generate an SQL list values of not already in other fields of the log table
'UPDATE mydata SET '
|| 'reading = ' || OLD.reading
|| ',' || 'reading_diff = ' || OLD.reading_diff
|| ',' || 'reading_valid = ' || CASE WHEN OLD.rdg_valid THEN '''t''' ELSE '''f''' END
|| ',' || 'perl_time = ' || OLD.perl_time
-- quote the timestamp
|| ',' || 'modified = ' || '''' || OLD.modified || ''''
|| 'WHERE ' || 'id = ' || OLD.id
) ;
-- Set modified field to now.
NEW.modified := CURRENT_TIMESTAMP ;
-- Continue with the update
RETURN NEW ;
END ;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
Comments(0) | Print | Home
I had to display a matrix of data, about 100 channels vs several days of sampled hours where some channels have good data, some have partial data and others don’t have any data. These data items are hourly residential meter readings and it is important for the hardware guys to spot which meters are sending data and which aren’t. As I was parsing and finding this data with Perl, I realized I could use the Spreadsheet::WriteExcel module to format it. That way I could colour code the different categories of meter readings and hide rows of extra data or noise found in the original “transmission.” It is obvious from the red lines on the image that there are some problem channels.
Comments(0) | Print | Home
It looks like Rogers is blocking outgoing SMTP (port 25) traffic.
There goes my nice little FreeBSD server I used to help my fellow choir members send out messages to each other. I was the only one who had to maintain a list of 50 or so members and all the rest could send to everyone using just one email address.
Comments(0) | Print | Home
I have several PostgreSQL tables of readings in a database which all inherit from the same base table so that they all have the same columns. I wanted to define a function to return the maximum value of a particular column from an arbitrary table. The EXECUTE command doesn’t work because it doesn’t “trap” it’s output. After some Googling and reading, I finally came up with the answer using FOR-IN-EXECUTE:
CREATE OR REPLACE FUNCTION get_timestamp(text)
RETURNS "timestamp" AS
$BODY$DECLARE
max_ts timestamp ;
rec record ;
BEGIN
FOR rec IN EXECUTE 'SELECT max(reading_stamp) as mx FROM ' || quote_ident($1) LOOP
max_ts := rec.mx ;
END LOOP ;
RETURN max_ts;
END ;$BODY$
LANGUAGE 'plpgsql' VOLATILE;
Comments(0) | Print | Home
I run some Perl scripts from the Windows Scheduled Tasks control panel applet. I have always had the cmd window pop up while the script is running which can be quite annoying. Today I found how to suppress or at least minimize the window by adding the start command:
cmd /c start "My Task" /min c:\Perl\bin\Perl.exe c:\scripts\myperlscript.pl arg1 arg2
Now the cmd window appears very briefly and the perl process gets minimized to the task bar.
Comments(0) | Print | Home
I made a copy of a Perl module I’m developing so I could make it faster and test it thoroughly before I merged it with the production code. Today I merged the production and new and improved modules and discovered one tiny change I made for testing and sorting convenience: $hash{key_a}{ke_yb} to $hash{key_b}{key_a} would seriously “break” the main calling program. Fortunately I had checked in my old versions as I went so I could restore the previously working versions of the calling program and production module. It’s kind of depressing to do this on a Friday afternoon, though — especially since I’ll be tied up doing Health and Safety auditing next week.
I see that Chiang Mai, Thailand where my brother teaches, has about the same temperatures, low 20’s to high 30+, as we do.
Comments(0) | Print | Home
I needed to convert a timestamp (seconds, minutes, hours, day, month, last 2 digits of the year) into a BCD string of bytes. Here’s the Perl sub I came up with to do that:
sub bcd_timestamp_string (@) {
# Convert given time or local time to BCD bytes
my @time = @_ ;
join('', map {
pack('H*',sprintf('%02d',$_))
} @time) ;
}
Comments(0) | Print | Home
I was too tired to comment on the table I put up last night comparing four routes from work to a place near the transformer station I worked at last Wednesday. I already knew the way but I wanted to see what the web map sites said.

Both Google and Yahoo! suggest the same basic route through downtown Toronto. Perhaps those times (20 or 26 minutes) are realistic at 3 a.m; however, with traffic lights, street cars and traffic “calming” on a couple of streets I would probably allow an hour for this route. Mapquest recommends the route I usually take. Except for rush hour, I would probably allow just ½ an hour for this route. The Maporama route starts similarly to the Mapquest until this direction: Follow Don Valley Pky for 6 km, Turn left, follow Millwood Rd. I have an image of that left turn which seems to include a 30 m vertical climb as well.
I do like Maporama street maps because they include house numbers: just don’t ask for directions!
Comments(0) | Print | Home
| Yahoo! | Mapquest | Maporama | |
|---|---|---|---|
| 18 km, 20 mins | 18.2 km, 26 mins | 27.2 km, 25 minutes | 24.1 km, 18 min. |
|
1. Head northwest from Kipling Ave - go 1.2 km 2. Turn right onto the Dundas St. East ramp - go 0.1 km 3. Bear left at Dundas St W - go 3.9 km 4. Turn left at Scarlett Rd - go 0.1 km 5. Turn right at St Clair Ave W - go 8.8 km 6. Continue on St Clair Ave E - go 0.9 km 7. Turn left at Mt Pleasant Rd - go 0.4 km 8. Turn right at Moore Ave - go 1.5 km 9. Continue on Southvale Dr - go 0.8 km 10. Turn left at Laird Dr - go 0.3 km |
1. Start at 800 KIPLING AVE, ETOBICOKE going toward NORSEMAN ST - go 1.4 km 2. Turn right onto DUNDAS ST W toward DUNDAS ST. EAST - go 4.0 km 3. Turn left on SCARLETT RD - go 0.2 km 4. Turn right on ST CLAIR AVE - go 9.7 km 5. Turn left on MT PLEASANT RD - go 0.3 km 6. Turn right on MOORE AVE - go 1.6 km 7. MOORE AVE becomes SOUTHVALE DR - go 0.6 km 8. Continue on MILLWOOD RD - go 0.2 km 9. Turn left on LAIRD DR - go 0.3 km 10. Arrive at 86 LAIRD DR, E YORK |
1: Start out going SOUTH on KIPLING AVE toward JUTLAND RD. 1.0 miles 2: Take the GARDINER EXPWY. EAST ramp. 0.3 miles 3: Merge onto GARDINER EXPY COLLECTORS E. 1.2 miles 4: GARDINER EXPY COLLECTORS E becomes GARDINER EXPY E. 8.1 miles 5: Merge onto DON VALLEY PKWY N via the exit on the LEFT. 4.2 miles 6: Take the DON MILLS RD. SOUTH exit. 0.1 miles 7: Turn SLIGHT RIGHT onto DON MILLS RD. 0.2 miles 8: Turn RIGHT onto OCONNOR DR. 0.1 miles 9: Turn SLIGHT RIGHT onto DONLANDS AVE. 0.3 miles 10: DONLANDS AVE becomes MILLWOOD RD. 0.7 miles 11: Stay STRAIGHT to go onto LAIRD DR. 0.1 miles 12: End at 86 Laird Dr |
1 Follow Kipling Ave for 1.3 km 1.3 km 00h 01 2 Turn left, follow Gardiner Expy for 15.4 km 16.7 km 00h 12 3 Follow Don Valley Pky for 6 km 22.6 km 00h 16 4 Turn left, follow Millwood Rd for 1.2 km 23.8 km 00h 18 5 Follow Laird Dr for 236 m 24.1 km 00h 18 |
Comments(0) | Print | Home
There are about 8 Windows 2000 equipped PC’s at transformer stations about the province measuring GICs. I have fixed the software and upgraded some drivers to make them work better. However an older version of PC Anywhere would die under mysterious circumstances so that one couldn’t contact the machine anymore unless it happened to reboot. Many of these TSs are unmanned and remote so you can’t just call someone to press the reset button. Today I figured out one work-around that should have been used from the start. I added a new Scheduled Task to run once every ½ day:
net start "pcanywhere host service"
Either one of us a work has to drive out to the two remaining stations and upgrade the software or, perhaps, we can convince some travelling operator or service person to reset the machine so that we can call it again and add my work-around. Then we can download the software and driver upgrades at our leisure, so to speak. I’m not sure how PC Anywhere upgrades itself when you run setup over an old version of PC Anywhere though.
Comments(0) | Print | Home
A manager wanted to present a talk on our 50 home test trial we are doing in a town near here. The local utility’s AutoCAD drawing was unsuitable because of over[too much information]{TMI}. Instead, I saved a couple of the XXL images from Maporama. Though I prefer Google maps for finding my own way around, the maps are really a collection of small images so you have to use a screen capture to grab the whole map. Maporama also has a nice feature at higher zoom levels by annotating with street numbers. This made it easy to cross-reference with the utility’s AutoCAD drawing. Once I had the map images, I used dia to import the images, adjust them so they made a continuous map and then mark our test trial locations with text notations.
| Selected Netcraft toolbar page rankings | |
|---|---|
| Site | Rank |
| Work | 82,203 |
| This site | 270,763 |
| 1 | |
Comments(0) | Print | Home
There are still vestiges of DOS in Windows XP. I was merrily parsing several hundred 256k binary files in Perl with this script until it failed to read in the whole file one day. It got stuck on a cr-lf combination even though I was using a sysread call. I had (forgotten?) to use binmode FILE; right after I opened the file. Of course this is a NOP in every other type of Unix where text and binary files are treated just the same when reading raw bytes.
Comments(0) | Print | Home
I took a day off using up some lieu time and finished up the taxes for my younger son, myself and my wife. I’m looking forward to that refund already!
Comments(0) | Print | Home
My little MP3/WMA player, FM Tuner is now, effectively, a removable USB drive. I don’t need to use iRiver’s application anymore to load it up with music files for on the road. Right now it has the Handel’s Messiah choruses for parts 2 and 3 to re-familiarize myself for upcoming performances with a “pick up” Oakville choir and orchestra on April 13 and 15, 2005 at St. Andrew’s Church in Oakville.
Comments(0) | Print | Home
Finally all the immediate work FY2004-5 deadlines have been met:
All is not bliss, though, as there’s still income taxes to file, an internal quality audit to conduct and a bundle of transfer of technology information to be assembled for another client.
Comments(0) | Print | Home
My wife is back at work today after her March break. Thus I’m working at home so I can take the puppy out from his crate every so often. I just sent off a report I worked on yesterday and this morning to my boss. Though I’d love to run outside in the milder weather I think I only have an hour or so before the puppy needs to go out to do his “business.”
Today’s Firefox extension is a spell checker for textareas Spellbound. I can right click as I’m writing here and check the spelling.
Comments(2) | Print | Home
I create log files with a custom Perl module and I decided to investigate creating an emacs “mode” in which to view them so that it would emphasize the warnings, for example. I found a tutorial on how to create a custom mode. At the very bottom of the article was a much easier way: deriving from an existing mode. Here’s my “quickie” mode for viewing my log files:
;;;;;;;;;;;;;;;;;;;;;;;;;;; -*- Mode: Emacs-Lisp -*- ;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; jrrs-event-log-mode.el
;;
;; A mode to highlight parts of the log files I create with JRRS::eventlog.pm
;;
;; Author : James R.R. Service
;; Created On : Wed Mar 09 2005
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defconst elog-font-lock-keywords1
(list
'("\\<\\(info\\|debug\\)\\>" . font-lock-comment-face)
;; bring out embedded \n
'("\\\\n" . font-lock-constant-face)
;; Bring out today's date by using ` and , operators to eval before adding
;; to list.
`(, (concat "\\<" (format-time-string "%Y-%m-%d")
" [0-9][0-9]:[0-9][0-9]:[0-9][0-9]\\>")
. font-lock-function-name-face)
;; Emphasize WARN and DIE messages.
'("\\<\\(WARN\\|DIE\\)" . font-lock-keyword-face)))
(defvar elog-font-lock-keywords elog-font-lock-keywords1
"Highlight regexps for ELOG mode."
)
;; (setq elog-font-lock-keywords elog-font-lock-keywords1)
(define-derived-mode elog-mode fundamental-mode "ELOG"
"Major mode for view log files created by JRRS::eventlog.pm"
(set (make-local-variable 'font-lock-defaults) '(elog-font-lock-keywords))
)
(add-to-list 'auto-mode-alist '("\\.log\\'" . elog-mode))
(provide 'jrrs-event-log-mode)
Comments(0) | Print | Home
Bad temperature readings appear as 4’s or 31.5’s. But if the rdg_valid flag is already false or the reading is an 'a' or 'b' code I want to accept the row. I only want to reject the row if it is a 'T' reading outside of the range 4.5 to 31.
ALTER TABLE my_table
ADD CONSTRAINT temperature_in_range
CHECK (NOT rdg_valid
OR reading_type_code = 'a'
OR reading_type_code = 'b'
OR reading_type_code = 'T'
AND reading >= 4.5 AND reading <= 31);
Comments(0) | Print | Home
Today I replaced a bunch of Postgres database views like this:
CREATE OR REPLACE VIEW readings_last30d_daily_0 AS
SELECT rdg_date
, to_char(sum(reading_diff)/1000.,'FM999990.999') as kwh_per_day
FROM readings
WHERE channel = 0 and rdg_valid
AND reading_stamp between
(select max(reading_stamp) from readings
where channel = 0 and rdg_valid)
- interval '31 days'
AND (select max(reading_stamp) from readings
where channel = 0 and rdg_valid)
GROUP BY rdg_date ORDER BY rdg_date ;
with a function:
CREATE OR REPLACE FUNCTION readings_daily(text, int4)
RETURNS SETOF date_rdg AS
$BODY$ SELECT readings.rdg_date
, to_char(sum(readings.reading_diff)::numeric / 1000::numeric
, 'FM999990.999'::text) AS kwh_per_day
FROM readings
WHERE readings.channel = $2 AND readings.rdg_valid
AND readings.reading_stamp >=
(((SELECT max(readings.reading_stamp) AS max
FROM readings
WHERE readings.channel = $2
AND readings.rdg_valid)) - $1::interval)
AND readings.reading_stamp <=
(( SELECT max(readings.reading_stamp) AS max
FROM readings
WHERE readings.channel = $2 AND readings.rdg_valid))
GROUP BY readings.rdg_date
ORDER BY readings.rdg_date;$BODY$
LANGUAGE 'sql' VOLATILE;
Where SELECT * from readings_daily('31 days',0) gives me the same
rows of data. Some 15 views per table are replaced by one function. I now just
cross-reference those view names with SQL function calls in another table.
Comments(0) | Print | Home

Regarding that memory leak: I sent an email and called the technical support of the watchdog timer board manufacturer describing the problem. They were kind enough to send me the sources to the DLL and I compiled them. “How about them apples” — no more leaks.
Now I have to make sure that the new DLL is actually setting/resetting the hardware watchdog timer since I had problems trying to link the VC6 LIB file with the Borland C++ code.
Comments(0) | Print | Home

We got a couple of lithium AA batteries as part of a marketing promotion. I used one in our kitchen clock—should be good for a few years. I tried the other in my fm tuner/mp3 player. I have found its output voltage to be very sensitive to the cold. The other day it was in my jacket pocket in about -10°C weather and the device shut off because the battery was too low. When I turned it on later after it warmed up to room temperature the mp3 player said the battery was at full potential. I think I will have to switch back to an alkaline AA battery and use that lithium one for something else.
Comments(0) | Print | Home
I was “hired” at work to troubleshoot a problem with some hardware and controlling software running under win2k. There was a memory leak adding 4k to the main process every 10 seconds or so. Using the System Monitor “snap-in” and monitoring the process' “working set” I was able to view the memory leaking away. I traced it to the software (dll?) controlling a hardware reboot timer. After disabling this “feature” the program ran over lunch with nary another byte used. We brought the computer back from the transformer station relay for some remedial work and testing of the software and some other problems it has.
I have always enjoyed software troubleshooting.
Comments(0) | Print | Home

I thought this was common knowledge that you removed the masking tape immediately after painting or caulking; otherwise, the coating will dry and stick to the masking tape. A friend at work told me he tried caulking once using masking tape to make clean edges. He let things dry and then found the masking tape pulled up most of the caulking. Another used masking tape to protect the moulding while he painted the walls. Again, he let things dry and then ruined the edge of his paint job. I thought I must share this tip.
Comments(0) | Print | Home
My wife is making “Indian” flutes with the Grade 5’s. So far I’ve cut the ½ in PVC pipe to lengths and loaned my two electric drills to make the holes. Soon I’ll have to fabricate little ½ in x 1¼ in pieces to direct the air from one hole to another to give it that “flutey” sound. These parts will require me to use a router table to cut ¼ in grooves in PVC doorstop moulding. As I was at Rona to get the moulding, I looked at the tables and only found generic or mucho-expensive models. As I have had a Craftman router for several years I decided to look for one at Sears just down the road. I ended up buying the medium expensive model shown in the image. You gotta love those marketing images: they show a router table in a workshop with a few shavings but no router. I spent a relaxing half-hour or so assembling the table.
In the not so exciting department I had to replace some of the caulking around the main bathroom’s tub. We are thinking it is time to renovate because of the ugly tub and the bathroom’s rather bland decor. We aren’t sure whether it will be a shower cubicle or a complete bathtub enclosure this time around. I grew up in a house with only a bathtub so I’ve taken showers exclusively ever since I left home. I’m really not into tiling and I think it is difficult to achieve leak-proof results without a lot of skills, time and care. It will be time to look at bathroom furnishings in the next few weeks and start planning.
I’m tired: I increased the distance of my run by several kilometers. Unfortunately snow at about the freezing point starts to lose its hard-pack qualities. The valley trails are starting to become slushy in places. That last third was starting to feel like a real grind.
Comments(0) | Print | Home
I took a snapshot of the environment variables on my XP box at work and compared them with the home 2k box. Here was the difference:
2k box: COMSPEC=C:\WINDOWS\SYSTEM32\COMMAND.COM!!
XP box: COMSPEC=C:\WINDOWS\SYSTEM32\cmd.exe
When I installed 2000 in place of Me I guess the upgrade kept good ol' COMMAND.COM. I changed this and PostgreSQL installed “perfectly.” I’m not sure why the install used the COMSPEC variable but now I have something else to put on the checklist if an install fails.
I have several thousand hourly readings on each of several channels collected over the last couple of months stored in the database. Now I can use simple SELECT commands to aggregate say the sums of hourly readings/channel for each day or the last 48 hours of readings for a particular channel or the average daily sum of hourly readings/channel/day of the week. Lovely data mining!
Comments(0) | Print | Home

The newest version of PostgreSQL, my “favourite” database now has a “native” Windows port. This couldn’t have come at a better time at work as I need a “big” database for a project I’m involved with. Now I can develop the database on my Windows box and then move it out to the FreeBSD box on the Internet. I certainly couldn’t do that with Access!
Unfortunately it wouldn’t install on my home box because, just near the end, initdb fails and the log reports: creating template1 database in C:/Program Files/PostgreSQL/8.0/data/base/1 … Bad command or file name. I guess I’ll have to compare my home box environment settings to those at work to see what might be is screwing up the installation.
Comments(0) | Print | Home
Looks like I might have to hack up my old copy of Moveable Type again. Google suggests the “major” search engines won’t follow links containing the rel=“nofollow” attribute. This means that comment spammers will no longer have search engines coming to their sites from the junk they post as comments and/or trackback pings on popular blogs. Personally, I have found that using some Apache mod_rewrite rules has eliminated almost all of it.
Comments(0) | Print | Home
I tried Microsoft’s beta anti-Spyware
software
at work and at home yesterday. It seems to be pretty simple-minded about
filenames and directories. It found a file, cat.exe, in the
system32 directory and called it the Dutch Porn Dialer. Actually it’s a Windows port of the Unix cat command. It also called two expat.dll files spyware. These are an XML parsing library.
I think the software needs more work.
Comments(0) | Print | Home
Because I walk or run about 6 km each day I like to keep track of the weather. I was planning to web scrape Environment Canada’s website and create an RSS feed for myself. Then I discovered Forecast Fox. Now I can have the weather in the status bar. Neat!
Comments(0) | Print | Home

Today I bought a stud finder from the planet Zircon. It used to be a tedious process to find the drywall screws or nails using one of those small pivoting magnet thingys. Of course, now I ask myself why I didn’t buy a “finder” years ago.
I easily located the studs and screwed three standards using a 2 ft level to verticalize and a 4 ft level to horizontalize the brackets. On this hardware I placed a 16 in x 8 ft shelf about 12 in down from the ceiling so my wife can store boxes of stuff “up there” in her sewing room. I also bought a light aluminum step platform so she can reach said boxes.
The greatest part of the time I spent doing this job involved removing the Rubbermaid UPC labels and glue from the six pieces of shelf hardware.
Comments(0) | Print | Home
Our company is demonstrating a technique for AMR using the power lines. The novel aspect about this method is that the metering signals can transmit through transformers. Other technologies have to use additional equipment to “go around” those transformers. After a couple of weeks of data gathering for five house within a block of each other there’s some interesting statistics already. The highest energy house uses 4½ times more energy than the lowest one and the peak usage is 3.6 times higher. I’ll have to find out from the test co-ordinator why there’s such a difference: teenagers, electric water heater or heating, extensive outdoor Christmas light display, etc?
Comments(4) | Print | Home
# This isn't very explicit on the web so I thought I would show
# a short example of how to make an array of filehandles using
# the IO::File module.
use IO::File ;
my @fh ;
# Make 11 files with the numbers 0 to 10, 1 number per file.
foreach $file (0..10) {
$fh[$file] = new IO::File ">$file.txt" ;
# print $fh[$file] "$file\n" ; # This doesn't compile
print { $fh[$file] } "$file\n" ; # Inside a block it does
}
exit 0 ;
Comments(0) | Print | Home
You may recall (or perhaps I neglected to discuss it here) that I was having
a problem with the Perl script I used to synchronize our employee email
addresses from the LDAP directory to the SQL server database serving our Intranet web
site. One early morning it deleted half the names — probably something to
do with the domain controller server upgrade to Windows 2003. For some
reason the query wasn’t returning all the users in the directory
anymore. Part of the problem is that this list of names is also used to
establish the Intranet website content managers' permissions. It took me a
while to surf through the Google chaff to finally find an
article
on how to retrieve the information available in the Global Address List of
Exchange / Outlook. I culled the vbs script lines and added some of my
own changes:
' GEt the domain.
Dim rootDSE, domainObject
Set rootDSE=GetObject("LDAP://RootDSE")
domainContainer = rootDSE.Get("defaultNamingContext")
Set domainObject = GetObject("LDAP://" & domainContainer)
' Create a file for results.
Set fs = CreateObject ("Scripting.FileSystemObject")
Set userFile = fs.CreateTextFile (".\users.csv")
' Call the sub to do the work.
ExportUsers(domainObject)
Set oDomain = Nothing
MsgBox "Finished"
WScript.Quit
Sub ExportUsers(oObject)
Dim oUser
For Each oUser in oObject
Select Case oUser.Class
Case "user"
If oUser.mail <> "" then
userFile.Write oUser.displayName _
& "," & oUser.sAMAccountName _
& "," & oUser.userprincipalname _
& "," & oUser.sn _
& "," & oUser.department _
& "," & oUser.physicalDeliveryOfficeName _
& "," & oUser.telephoneNumber _
& "," & oUser.initials _
& "," & oUser.givenName _
& "," & oUser.mail
' for each email in oUser.proxyAddresses
' userFile.Write email & ","
' next
userFile.WriteLine ""
End if
Case "organizationalUnit" , "container"
If UsersinOU (oUser) Then
' If users in container call myself again.
ExportUsers(oUser)
End if
End select
Next
End Sub
Function UsersinOU (oObject)
' Are there users in the container?
Dim oUser
UsersinOU = False
for Each oUser in oObject
Select Case oUser.Class
Case "organizationalUnit" , "container"
UsersinOU = UsersinOU(oUser)
Case "user"
UsersinOU = True
End select
Next
End Function
Then I converted the vbs to a Perl script using the Win32::OLE module:
use Win32::OLE 'in' ;
sub last_error () {
my $last_error = Win32::OLE->LastError() ;
die $last_error if $last_error ;
}
sub has_users ($) ;
sub has_users ($) {
my $object = shift ;
my $result = 0 ;
foreach my $user (in $object) {
if ($user->{Class} =~ /^(organizationalUnit|container)$/) {
$result = has_users($user) ;
} elsif ($user->{Class} eq "user") {
$result = 1 ;
}
}
$result ;
}
sub export_users ($) ;
sub export_users ($) {
my $object = shift ;
foreach my $user (in $object) {
if ($user->{Class} eq "user") {
if ($user->{mail} ne '') {
print join(', ', map { "$_: $user->{$_}" } qw[mail displayName]),
"\n" ;
}
} elsif ($user->{Class} =~ /^(organizationalUnit|container)$/) {
export_users($user) if has_users($user) ;
}
}
}
my $rootDSE = Win32::OLE->GetObject("LDAP://RootDSE") ;
my $domain_container = $rootDSE->Get("defaultNamingContext") ;
my $domain_object = Win32::OLE->GetObject("LDAP://$domain_container") ;
_ddump [$domain_object], [qw[$domain_object]] ;
last_error ;
export_users($domain_object) ;
exit 0 ;
As I’m off to the OMEA conference tomorrow, though I’m not a music teacher, I’ll have to wait until Monday to change my script and restore those missing names.
Comments(0) | Print | Home
I have a server which accepts downloads from devices in the field and mails the results to me in an attachment. Outlook doesn’t provide a way to automatically detach and save them. Sometimes you look for stuff using Google and you find a heck a lot of chaff. Finally I discovered how to do this with a short VBA “script.” Outlook XP has a “run a script” action available for its rules but, again, it took a bit of searching to find out how to use it.
Attribute VB_Name = "SaveAttachments"
Option Explicit
' The "run script" check box in the Outlook Rules Wizard looks for subs with
' the Item As Outlook.MailItem argument.
Sub SaveAttachmentMessageRule(Item As Outlook.MailItem)
' save_dir must exist.
Const Save_dir = "c:\attachments\"
Const process_attachments_program = "C:\Perl\bin\perl.exe C:\bin\got-data.pl"
Const Ext = "txt"
Dim Filename As String
Dim Attach As Attachment
Dim i As Integer
i = 0
If Item.UnRead = True Then
For Each Attach In Item.Attachments
' Verify the attachment has the correct extension and is unread.
If Right(Attach.Filename, 3) = Ext Then
Filename = Save_dir & Attach.Filename
Attach.SaveAsFile Filename
i = i + 1
End If
Next Attach
' Mark as read.
Item.UnRead = False
End If
Set Attach = Nothing
If i > 0 Then
' Now process the saved attachment(s).
Shell process_attachments_program
End Sub
Though you can run an application from an Outlook rule it starts before the
run a script; hence, I use the Shell command to process the
attachment file. Note that you’ll have to change the “Security” settings to
enable macros. However, if you know how to use VBA then I would surmise you
know how to do this, too.
Comments(0) | Print | Home
In my /etc/hourly.local file I created to update awstats hourly, I added a Perl one-liner to look for comment spam attempts:
perl -ne 'print if /\b(POST|GET)\b/ && /mt-comments\.cgi/ && ! /(mysite|mysisterssite\ )\.com/' /home/myhomedir/logs/blog-access.log
On Nov. 20 there were 212 entries. Not all were comment spam attempts as some 'bots “cruise” the blog looking for open comments. All the rest were stopped with my suggested rewrite rules. It used to be that all those attempts would be clogging the MT activity log with MT-Blacklist comment denial or worse, sending me email about a bogus comment.
Comments(0) | Print | Home
Usually there’s dozens of blacklisted spam entries but at lunchtime today I added some mod_rewrite rules per the advice on some other blogs. Everything has been quiet since noon — only my sister and I logging in to our respective blogs. Here’s what I added to the httpd.conf file (change the site and domains to suit):
# Redirect clients who try to post comments directly.
RewriteEngine On
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} .mt-comments\.cgi*
# If the browser did not come from either of ours sites or
RewriteCond %{HTTP_REFERER} !.*(mysite|mysistersite)\.domain.* [OR]
# there's no agent.
RewriteCond %{HTTP_USER_AGENT} ^-$
# Redirect to an error message page.
RewriteRule (.*) /no-comment.html [R,L]
Comments(0) | Print | Home

The former little garden on the garage side of the walk is starting to fill with leaves giving me an idea. I had a long pile of shredded leaves and pine needles left over in the back behind the deck so I put a layer of this stuff along the edges of the walk from front to back. When I had excavated for the walk, I had piled the topsoil just behind the shrub. This pile provided just enough topsold to spread over the shredded material along the walkway edges. Therefore I used most of the mulch, removed the pile of topsoil and “finished” the sides of the walkway all at the same time. I also saved myself a few bucks by not having to order a cubic yard or two of triple mix for that purpose.
Comments(2) | Print | Home
I fiddled around with the colours and fonts on the site. There appears to be some colour “bleeding” with IE. Maybe I’ll fix it when I find an edit css tool like I got for Firefox.
Comments(0) | Print | Home
I changed the little thumbnail file: favicon.ico for the hubbo site.
Comments(0) | Print | Home
I have a host computer recently installed between between the two firewalls at work in the so-called DMZ. I use ssh to maintain it. It was getting tiresome to type in the password each time I rsync'd some files. It had been awhile since I set up authentication between hosts so a review of the man pages for ssh was called for. I used ssh-keygen -d dsa to generate a public and private key on the client Intranet host. I then appended the contents of ~/.ssh/id_dsa.pub to the file ~/.ssh/authorized_keys2 on the DMZ computer.
Comments(0) | Print | Home

In the last couple of weeks I have caught four mice in the garage. Now the traps appear undisturbed so perhaps the problem is gone for another year. BTW, I don’t use those clothes peg type traps: they are not as “snappy” as the kind in the image, but you don’t have to touch the dead critter, either.
Comments(0) | Print | Home

After doing some research and talking to other DIYs, I decided to hire someone to replace the torsion springs, one broken and one not, on our single car garage doors. The decision was easier when I found the invoice for the garage doors we had installed in 1990. That company is still in business so I figure they must be doing alright after 14 years. It was less than $250 and done the day after I called. I would still have to measure and buy the springs and then get a couple of tools, etc so it might have been another couple of weeks before I did it myself. Money well spent this time.
Comments(2) | Print | Home
I installed a javascript package that makes popup overlays on Saturday evening. I used them at work for a demo website with several large (image) maps and selectable houses. I needed little popups to display the house addresses. Through my web research I came across the overlibms package which seemed to be the best of the overlib clones.
It was quite easy to add to an MT blog. I added the following to my various index templates:
The second line specifies the styles names used in the popup that are found in your styles-site.css file.
Somewhere, just after the <body> tag, you add:
This initializes the “floating” div that overlib uses for its little popup box. Of course, I had to add a popup entry title to my calendar entries:
I also lightly hacked the mt/tmpl/cms/preview_entry.tmpl file in a similar fashion so that I can see my popups when I preview my entries. Now I find I might have to revise my TeXlike formatter so that I can embed html in those popups more easily.
Comments(0) | Print | Home
My wife and I finished laying down the pavers today. My estimates all seemed to have worked out: we have one layer of pavers left over which I can either use to make a step or hide the galvanized sheet I used to cover the opening under the front porch.
I rented a “brick splitter” to do the few cuts needed on the sideway walkway around the downspouts, window well and electrical service entrance. It also came in handy when my wife came to an impasse in the pattern-less pattern. She was using too many of the “twinkie” size. I cut one in half so she could plug up the twinkie run and start a new “twinky-less” pattern.
After using the brick splitter I know more about the sudden release of energy in earthquakes: You apply (enormous) pressure to the paver between two narrow knife-edge blades with a lever arrangement. Usually the paver splits suddenly with a sharp cracking sound and a sudden release in lever force. Another fun part of this job. Tomorrow’s fun includes sawing out a part of the driveway so I can set in the front pavers of the walkway, putting in the edging and sweeping sand in the cracks.

The torsion spring broke on the garage door of the side where we keep our car. So, now I am searching the Internet on the subject to determine whether or not this is a DIY project. Apparently it can be with a great deal of care. Perhaps I’ll phone around for repair estimates and time to complete versus the time and expense involved in trying to purchase the spring (not usually available at your typical home repair “supermarket”) and doing it myself.
Comments(0) | Print | Home
We (yes, my wife helped) laid out a skidful of pavers this afternoon and evening. We had trouble discerning what sort of pattern we should use with these 3 sizes of tumbled pavers:
So we went back to the garden centre to look again at the display.
We met the fellow who had laid the bricks in the display. He said there is no pattern and that you’ll drive yourself crazy if you try and make one. He suggested starting in a right-angled corner fixed by some objects you can’t change and move out diagonally from there. You try and lay the pavers so that they don’t end up having long “crack” lines. By the way, he called the smallest size a “twinky.” Sure enough, his system worked. We started out at the corner of the concrete porch and garage wall and spead out along the porch and down to the side of the house and another part jutting out towards the street. When I sat down on the porch it appears the front walk is tending to the right so that we’ll run out of prepared screenings' bed by the time we get to the far corner. I’ll have to straighten that out in the morning.
Anyway, once we discovered there is no pattern it’s a lot of fun the lay those pavers “randomly” and trying not to use too many twinkies. Yes, my wife has been very helpful. Her extensive experience in laying out quilt patterns has helped us tremendously.
Comments(0) | Print | Home
There are two skids and a section sitting on our boulevard: perhaps “a ton of bricks.” It looks like the lovely fall weather will continue to hold this Canadian Thanksgiving weekend and my walkways will start to look complete.
Comments(0) | Print | Home

Older son emailed me about an electrical problem at his house. It turned out he wired a ceiling fixture in parallel with a switch on the wall. When he screwed in a lightbulb, the radio plugged into the outlet operated by the switch turned on. He pulled out the outlet and switch and sent me a sketch of the wiring.
I sent him a possible solution tonight. The outlet is rewired to make it non-switched and the switch is re-wired so that it will interrupt the “hot” side to his ceiling light.
Comments(0) | Print | Home

I carted the rest of the limestone screenings from the front boulevard to then front walk. Next I leveled and hand-tamped the entire walkway (about 300 ft2). I used a 3 ft. and 4 ft screeding boards and did it “by eye.” Most of the time, when I checked with my level, I was either dead on or slightly sloping away from the house—just as it should be.
In the afternoon my wife and I went to the garden centre and looked at their paver and brick displays. We settled on the Unilock Antara pattern, of 3 different size “tumbled” pavers. We think that will look best because there won’t be a long pattern line to possibly screw up. I like the tumbledness because I can use the guillotine rather than the diamond saw. I asked about renting a gasoline-driven tamper: it was “free.” Of course, I’d spent over a grand for the pavers and edging.
Tamping was rather fun—something like driving a zamboni. The only problem was the exhaust diverter of the machine had rusted off so the tamping operation was rather fumy. Now the walkway seems to be as solid as concrete. I have a wheelbarrow load of screenings for “adjustments” and I will have to get a bag or two of “polymeric” sand to glue the bricks together once I’ve laid them next weekend.
Comments(0) | Print | Home
Now I’d better get to work excavating and putting down the gravel base…
Comments(0) | Print | Home
The client wanted the login to switch “web sites.” I’m using mod_auth to handle the login and, today, I used mod_rewrite, one of the more arcane modules, to rewrite the directory URL. I still need to set up a rewrite log to find out what it does. Sometimes the correct page comes out but image links are corrupted or the URL root index page comes out instead of subdirectory. It’s a work in progress. I didn’t check in the web site to my CVS directory on the drive I can access from home via VPN: so, no example .htaccess file yet.
In other news: I reserved a 6 yard3 waste disposal bin for the weekend. I expect I shall fill it to the top; unless the neighbour wants some of the topsoil.
Comments(0) | Print | Home
The mail client at work, Outlook, or as one guy calls it “Look Out!”, archives older messages on startup. Every so often a popup dialog says something like, “Auto archive failed see Deleted items folder for details.” Here’s the details:
Posted At: Wednesday, September 15, 2004 8:12 AM Posted To: Deleted Items Conversation: Archive Log. Subject: Archive Log. The operation failed. The operation failed.
So there. Now I know why. ;-)
Comments(3) | Print | Home
Just send email to:
j s e r v i c e a t g m a i l d o t c o m
and include your first and last names and where you live and I’ll send you a gmail invitation.
Comments(0) | Print | Home
Email sent to work is bouncing with an ominous message:
Delivery to the following recipient failed permanently:
some.one@our.company.com
Technical details of failure:
PERM_FAILURE: SMTP Error (state 10): 550 5.7.1 Unable to relay for some.one@our.company.com
According to this tip there’s a misconfiguration somewhere or a faulty permissions setting in the MS Exchange Server. I hope the IT people get this one fixed soon. Practically everything comes by email these days.
Comments(0) | Print | Home
p{It has been a year or two since I’ve had to carve holes in our heavy clay
soil but I needed to move a couple of daylilies from where the new walkway will
go.]
Yesterday I removed the grass from an area of the front sideyard to the west of the driveway and hedge. Today I transplated.
For each plant I dig a round hole about 24”in diameter using my handy garbage can lid template. For the top six inches or so of topsoil I sift it through frac{1}{2}”hardware cloth into the wheelbarrow and pick out the roots and stones. That 24”by 6”cylinder of soil (about 1.5 ft3) will usually fill the wheelbarrow (3 to 4 ft3 I guess). Then I pick away another few inches of the reddish clay and rocks which I usually throw out. I mix peat moss and compost into the wheelbarrow of soil using a small spade and then move some of it into a couple of five gallon pails so that I can use the wheelbarrow to transport the transplant. Digging one hole can take an hour or so depending on how stiff the clay is and how many rocks I have to pry out. At least at this location, I didn’t have to contend with any large roots.
Once the hole is dug and the soil prepared I take the wheelbarrow and large spade (the one where the handle goes right through the ferrule to the blade of the spade) over to the daylily. I found a couple of stretch (bungee) cords were handy at keeping the foliage out of the way while I inserted the spade several times all the way around the plant. Years ago I followed the tip to sharpen your spades: they go through clay and roots much easier that way. The clay soil has at least one advantage in that it sticks to the roots when you lift the root ball into the wheelbarrow. However that same clay makes that root ball very heavy. I did remember to bend at the knees and use my legs instead of my back to lift.
Back at the hole, I put in some prepared soil and nestled the root ball in the centre. Usually you want the top of the root ball to be slightly higher than the surrounding surface because it will sink somewhat when you tamp it down and water it. I fill and tamp prepared soil around the root ball until the hole is half full. The “moat” I fill with water and wait until it disappears. After that I top up the hole with soil and tamp down with my hands and then my feet. At this point I removed the stretch cords and then waterered the plant well with the watering can.
I have been using this transplanting method I learned from my Grandpa for probably 35 years. This method is a lot of work—especially in clay soil; however, I can’t recall ever losing a perennial, shrub or tree I have planted this way.
Comments(0) | Print | Home

I used “No More Nails,” basically a thick latex glue to attach the moulding to the walls. I did have to use a couple of finishing nails to put quarter round next to the tub as it wasn’t a straight surface or the quarter round may have been slightly warped. Today I masked the quarter round next to the tub and applied clear silicone caulk.
Speaking of caulk, I wasted more time this week trying to revive partly used tubes of silicone caulking. I finally ended up throwing out at least half a dozen used tubes.
In the close encounters of the thunderstorm kind department, I was putting a coat of latex paint on the quarter round I’d replaced around the sliding glass doors. Just as I finished, there was a lightning stroke so close by I could hear a spark gap type of sound immediately before the thunderclap. I high-tailed it inside. Fortunately the rain pounded the house from another direction (and we have a new roof!) so that coat of paint should be good.
Comments(0) | Print | Home
I replaced the rusty, old screws on the siding around two of the second storey windows with stainless steel screws. Those “chrome plated” screws only last a few years before rusting.
My knees were sore during my run today. I wonder if that had anything to do with standing on the ladder for a couple of hours?
Today’s image is brought to you from the “fire tower” cliff at Restoule Provincial Park.
Comments(0) | Print | Home
This was a tough one to diagnose because every time I used Outlook to send a message or expanded it from the taskbar I would get the new email messages. I finally tried reducing the Outlook polling interval to 5 minutes; but that still didn’t seem to pull in the new messages until I used Outlook. Finally I read an NTBuqtraq mail list message that pointed to XP SP2 as the cause of the problem. Somehow the so-called “Windows Firewall” prevented my office computer from getting notifications from the Exchange server about new email.
I applied the registry changes described in the article, OL2002: You Cannot Receive New E-mail Notifications in Environments That Use the Network Address Translation. These changes force the Outlook client to poll for new email messages.
Now I get those “Please fill out your timesheet” reminders as soon as they are sent instead of some indeterminate time in the future—A mixed blessing I’d say.
BTW, aside from this problem and having to open up the “Windows Firewall” to a few applications, these have been the only issues I have had with XP SP2.
Comments(0) | Print | Home
I had a little trouble with the mozex
extension in Firefox. Oh,
it would install just fine but it wouldn’t be listed in the
extensions. Therefore, you couldn’t double click on it and set the
application to say, edit textareas. After some searching on the Internet
where someone said you simply edit the userpref file, I found the
answer. You have to install the Show
Old Extensions extension. Now I can finally edit my blog entries in
emacs using
c:\usr\local\bin\gnuclientw.exe %t.
Comments(0) | Print | Home
Thanks to MT-Blacklist, 543 comments were rejected between 2004.08.10 20:30:31 and 2004.08.11 02:51:26 UTC(?). This selection of IPs from the rejections makes me thinks these are trojaned machines, especially the mil ones:
| IP | host |
|---|---|
| 198.26.120.13 | WCS2-MCPHERSON.NIPR.MIL |
| 80.58.3.235 | 80.58.3.235.proxycache.rima-tde.net |
| 12.36.104.2 | na |
| 198.26.118.37 | WCS2-MOFFETT.NIPR.MIL |
| 198.26.118.36 | WCS1-MOFFETT.NIPR.MIL |
| 210.240.188.81 | proxylib.ntctc.edu.tw |
| 24.216.53.52 | 24-216-53-52.charter.com |
| 208.24.115.221 | cedu221.centex-edu.net |
Comments(0) | Print | Home
I discovered Email::Valid a while ago and now I have finally added it as another defence against comment spammers. Basically Email::Valid checks if the domain part of the email address has an MX record, i.e., that the domain accepts email. When I get back from vacation I’ll have to look into migrating my blog to MySQL and then close all comments except for my most recent postings.
Of course this isn’t a panacea but most of the comment spam I have received recently, especially when I get a couple of hundred in a short time period, have randomly generated domains.
I inserted the following code in Jay Allen’s MTBlackList script file MTBlPost because it overrides MT::App::Comments::post. (N.B. One long string has been split with \.)
if ($email) {
require MT::Util;
if (my $fixed = MT::Util::is_valid_email($email)) {
$email = $fixed;
} else {
return $app->handle_error($app->translate(
"Invalid email address '[_1]'", $email));
}
# inserted code starts
require Email::Valid ;
unless (Email::Valid->address(-address => $email,
-mxcheck => 1)) {
$app->log('Comment denial on '.$blog->name.
": email $email has no MX record.") ;
return $app->handle_error($app->
translate("Email address '[_1]' is invalid: either the \
address is malformed or the given domain does not receive email.",
$email)) ;
}
# inserted code ends
}
Comments(0) | Print | Home
I have tried several of the extensions for the Mozilla and Firefox browsers. The most useful IMHO are the Googlebar, the adblocker and the clock in the status bar. I occasionally use the web developer tool bar, too.
Comments(0) | Print | Home
I have had a sendmail server running on my FreeBSD gateway/router box and connected through a cable modem to the Internet for several years. I maintain a list alias for our choir so that they need only send to one email address rather trying than to keep track of about 50 members who come and go and change email addresses. In the last year or so serveral members' email servers started to reject email from cable Internet addresses so I had to forward messages by hand. This kind of defeats the purpose as I had set this up to be completely automatic.
Just recently my son through his buddy got an additional subnet of static IP addresses for work. I let him use my gateway box as a test bed for IP in IP tunneling, the so-called gif interface in FreeBSD. Effectively I now have a third interface and Internet connection from my box with a static IP on my son’s subnet. Today I completed the last part of the goal by forcing sendmail to use this pseudo-interface. This was actually easy to do. The hard part was finding the arcane options in sendmail to do this. Anyway I added the following line to my hostname.mc file:
CLIENT_OPTIONS(`Port=smtp, Addr=10.1.2.3')
Of course the 10.1.2.3 is phony. I obtained a “free with ads” email address at mail.com as this was one mail server which was rejecting the choir emails. (Aside: mail.com’s 10MB offering looks pretty, pretty small compared to Yahoo!'s 100 and Google’s 1000.) Before I added the CLIENT_OPTIONS line I sent an email via the box and it was rejected by mail.com. After I put the change in and did a make cf install restart I sent another email. Success! Now the email doesn’t appear to come from a cable Internet address anymore. I think the next step will be to install something like GNU Mailman or Majordomo so that the choir can maintain their own email addresses and look in the archives for that rehearsal schedule they forgot to print.
Comments(0) | Print | Home
I finally got around to zoning out my modest internal network of two internal machines and an interface on the gateway/router. I chose 4146trapper.ca as the most appropriate domain for the purpose. The Windoze box I’m on right now has the oh-so-glamourous hostname of dhcp254.4146trapper.ca.
Comments(0) | Print | Home
This month’s electricity bill says we used an average of 22 kwh/day as opposed to 36 kwh/day in July '02. I attribute this to a) not as many hot days and therefore less A/C usage and b) avoiding using our dryer by air drying our towels and most of our clothes. The other bonus is that we stayed below the 750 kwh/month threshold so that we only paid the 4.7¢/kwh charge.
Comments(0) | Print | Home

Today’s project was to install an umbrella clothesline on the deck. The set came with a plastic sleeve with lid which is usually set in concrete in the ground. Instead I used my jig saw to cut a hole in the deck and attached the sleeve to the joist underneath. When the clotheline is removed and the lid is closed the assembly is flush with the deck.
The only difficult part was installing the brackets under the deck, only because I had to work on my back. I spread a blue, poly tarp on the ground and crawled underneath. There was just enough clearance for me to roll over if I made sure my hips were between joists. Transparent bins were handy for the nails, bolts, sockets, brackets, etc. I only had two other problems: the result of crawling under getting in position and then realizing I had forgotten something. It would have been great to have a kid around to ask to plug in the extension cord or bring me the bracket I’d left on top of the deck. I had to make at least two trips underneath because the first one involved attaching the brackets around the sleeva and C-clamping them to the joists. Then I had to go on deck, so to speak, to put in part of the clothesline pole and use a level to vertically align the sleeve in two directions.
There was a benefit being under the deck when the afternoon sun started to shine it on it — it was shady and definitely cooler.
Today’s exercise was a bicycle ride to the Square One to visit SportChek and get a brake pad for my Rollerblades. Eventually I was directed to the service desk at the back. The guy asked me how old my rollerblades were. I told him it didn’t matter — you are selling a model with the same brake design in your store right now. How short a lifespan do these things have anyway? Will I eventually have to buy chunks of rubber and carve my own?
Comments(0) | Print | Home
Via a long circuitous route I have built the firefox port on my work FreeBSD machine. This machine has been gradually updated over about three years. I use cvsup to keep the src and ports trees synchronized, and, every once in a while, I do a make world upgrade. So, there’s a lot of cruft in the ports stuff I have built over the years.
I decided to build firefox; however, this port has a rather large set of dependencies: XFree86-fontEncodings-4.3.0 XFree86-fontScalable-4.3.0 XFree86-libraries-4.3.0_7 atk-1.6.0 expat-1.95.7 fontconfig-2.2.3,1 freetype2-2.1.7_3 gettext-0.13.1_1 glib-2.4.2 gmake-3.80_2 gtk-2.4.3_1 hicolor-icon-theme-0.5 imake-4.3.0_2 intltool-0.31 jpeg-6b_3 lcms-1.13,1 libIDL-0.8.3_2 libXft-2.1.6 libiconv-1.9.1_3 libmng-1.0.7 libxml2-2.6.9 nspr-4.4.1_1 p5-XML-Parser-2.34_1 pango-1.4.0_1 perl-5.6.1_15 pkgconfig-0.15.0_1 png-1.2.5_5 python-2.1.3_5 shared-mime-info-0.14_3 tiff-3.6.1_1 zip-2.3_1|XFree86-fontEncodings-4.3.0 XFree86-fontScalable-4.3.0 XFree86-libraries-4.3.0_7 atk-1.6.0 expat-1.95.7 fontconfig-2.2.3,1 freetype2-2.1.7_3 gettext-0.13.1_1 glib-2.4.2 gtk-2.4.3_1 hicolor-icon-theme-0.5 imake-4.3.0_2 jpeg-6b_3 lcms-1.13,1 libIDL-0.8.3_2 libXft-2.1.6 libiconv-1.9.1_3 libmng-1.0.7 libxml2-2.6.9 nspr-4.4.1_1 pango-1.4.0_1 perl-5.6.1_15 pkgconfig-0.15.0_1 png-1.2.5_5 python-2.1.3_5 shared-mime-info-0.14_3 tiff-3.6.1_1
I built XFree86 v4 separately because xdm didn’t work when I upgraded some other X11 stuff separately.
I solved a shared-mime-info-0.14_3 port build failure by adding symlinks from giconv.h and libgiconv.* to their iconv equivalents.
The firefox build itself failed until I found and fixed a symlink. The symlink /usr/X11R6/include/gdx-pixbuf was pointing to /usr/X11R6/include/gdk-pixbuf-1.0/gdk-pixbuf instead of /usr/X11R6/include/gtk-2.0/gdk-pixbuf.
Rogers asked its customers to exchange their cable modems as the old ones will no longer function after the end of July. Once I swapped the cable modem I couldn’t get an IP address. Unlike the old modem this one enforces the number of IP addresses you are paying for. I thought I had been paying for two — apparently not. My son the on-line gamer doesn’t like going through my firewall. My server/gateway/router IP changed but now I only use it as an SMTP server. This blog is served from my son’s box at work.
I installed another ceiling fan today. This time in the computer room/study. Like the first installation, I had to mount the junction box to a horizontal joist. I used machine screws with hex heads so I could drive them into the stud at right angles with my socket wrench. This worked much better than using slanted screws. I also installed the “safety” hook first and then threaded the “safety” cable of the ceiling fan through the junction box and vapour barrier and hung it on that hook. In first installation, in my son’s bedroom, I put in the “safety” hook then I attached the junction box. I probably wasted an hour trying to “lasso” the hook with the “safety” cable via the hole in the top of the junction box.
Comments(0) | Print | Home
I installed WebWiz Forums software on our Intranet a while ago. Today I had a bit of time to set up a SQL server database and configure WebWiz to use it. Just possibly, I might be able to use the upload file features to permit a bit of data exchange between our company and some selected clients: test reports, chemical analyses and the like.
1351(!) comment spam items were automatically rejected overnight. I have received (useful) comments on two-year-old blog entries so I’m reluctant to close them.
Comments(0) | Print | Home
The email list I maintain on behalf of our choir has attacted some spam recently. Now I have to act as the spam filter instead of letting the mail server automatically send messages to everyone. It hardly seems worth it to install something like Spam Assassin for just one mailing list. Sigh.
Comments(1) | Print | Home
Tonight, neither the Reply nor Forward buttons are working. I even, horrors, tried MSIE, and they didn’t work there either. I suspect it must be a Javascript error because I get this in the JavaScript console window:
Error: LHCol_Init is not defined Source File: http://us.f115.mail.yahoo.com/ym/ShowLetter?... Line: 682
I hope they get this fixed soon.
Comments(0) | Print | Home
My Yahoo! Mail Plus account now has 2 Gigs of storage. Instead of deleting personal emails I should just put them in the “Archive.”
I was looking for a PDF to PNG converter program. I find the Irfanview interface quite convenient to scroll around even very large PNG images: much better than the Adobe reader does PDFs. I wanted to “section” a large PDF drawing and print parts of it. I remembered that GSview in combination with Ghostscript will read and view PDF files and it will also do the PDF to PNG conversion. So I successfully used Irfanview to crop and print parts of some large PNG files converted from PDF drawings. Very cool!
Version 0.9 of Mozilla’s Firefox browser just came out as did version 1.7 RC 3 of Mozilla last week.
The wisdom tooth is out and so is the freezing. I guess my jaw will be sore for a couple of days. Today’s menu will consist of soft foods: soup, yogurt, scrambled eggs and lots of fluids.
Comments(0) | Print | Home
This is what a bus shelter ad said underneath a picture of an older man. This struck me as a rather odd phrase. While I ran the rest of the way home, I wondered how these numbers could be similar?
Blood pressure is usually measured in millimeters of mercury or mm Hg and tire pressure is either measured in pounds per square inch (psi) or kiloPascals (kPa). The normal high BP reading is 120 mm Hg systolic. My car tires take 30 psi. Let’s do some numbers (using the Google calculator):
| 120 mm Hg | = | 2.32 psi |
| 120 mm Hg | = | 16 kPa |
| 30 psi | = | 1551 mm Hg |
| 120 kPa | = | 900 mm Hg |
Any way you slice the numbers, this man either has severely under-inflated tires or his blood is exploding out of every orifice.
Comments(0) | Print | Home
When I’m using Excel I miss some of my good ol' Perl functions. Today I wrote a variation of the join function. I call it join_ex a) because Excel has a join function and b) because I wanted to extend it and optionally not join empty elements or enclose the whole join_ex'd string with the join string. all_empty isn’t really a Perl function but I wanted a test so that I could join some cells some of which may be empty or to use another string, say “none,” if they were all empty.
Example usage:
join_ex(",",("a","b","","c"))
=> "a,b,,c"
join_ex(",",("a","b","","c"),True)
=> "a,b,c"
join_ex(",",("a","b","","c"),True,True)
=> ",a,b,c,"
all_empty(("a","b","","c"))
=> False
all_empty(("","","",""))
=> True
The VBA Module:
Attribute VB_Name = "PerlVBAFunctions" ' Jim Service' ' $Id: PerlVBAFunctions.bas,v 1.1 2004/06/10 13:35:15 servicej Exp $ ' ' Perl-like functions for VBA: ' joinex - join items with a string ' all_empty - true if all items empty Public Function join_ex(str As String, items, Optional ignore_empties As Boolean = False _ , Optional enclose_join As Boolean = False) As String ' ' This function works something like Perl's join function. Each of the items' ' values, where items may be an array of cells, e.g. (A1, F1, H1) or a range, ' e.g., (A1:H1) are concatenated with str between them. If ignore_empties is ' True then items with "" values are ignored. If enclose_join is True and ' some items have been joined then str is placed around the result. ' Dim result As String If items.Count = 0 Then ' Short circuit exit if no items were given. join_ex = "" Exit Function End If result = "" Dim i As Integer i = 1 Dim c For Each c In items If Not ignore_empties Or c.Value <> "" Then ' After the first item then insert str. If i > 1 Then result = result & str End If result = result & c.Value i = i + 1 End If Next If enclose_join And result <> "" Then result = str & result & str End If join_ex = result End Function Public Function all_empty(items) As Boolean ' Returns true only if all items' values are "" or items is empty. all_empty = True Dim c For Each c In items If c.Value <> "" Then all_empty = False Exit Function End If Next End Function
Comments(1) | Print | Home

Today was neighbourhood-junk-exchange a.k.a street sale day. I was looking for yard tools for my son’s soon-to-be-purchased house. Though I didn’t find anything for him, a neighbour down the street was selling his 5hp chipper/shredder because he was tired of storing it. I just had to try it out this afternoon: after I turned my compost piles, I had a pile of sticks and brush to chop. The machine is noisy but it works great. It even chops up pine cones into little bits if I feed a few at a time into the branch port rather than using the brush hopper. I had planned on buying an electric shredder but this is more powerful and I paid half the price for this apparently not used very much model.
Now I guess I’ll just throw out my electric vacuum-mulcher with the chipped plastic impeller blades. I had dissassebled it but found the impeller and motor shaft were one unit. I hadn’t gotten around to taking apart the motor. Even on the Internet I couldn’t locate parts for the unit. Besides it is those pine cones or the “cores” left by the red squirrels that break the impeller blades when I suck up a pile of leaves with those hidden inside.
Today’s weather was great for a 12 km run. The park and ravine paths are dry for the most part and the air was cool. Instead of wearing a hat, I now put sunscreen all over my head and wear a sleeveless top to avoid a “farmer’s tan.”
Comments(0) | Print | Home
Some ***hole spammed this blog with about 400+(!) comments — all pointing to the same site. It was easy enough to get rid of the offending comments via MT Blacklist. The other mildly annoying problem was purging the 400+ emails sent to my yahoo address, one per comment. The sheer volume of comment spam implies that there’s a script out there that does this dirty work. I updated my local blacklist from the master one.
Comments(3) | Print | Home

I finished putting in the laminate floor in our small (approx. 20 ft2) ensuite bathroom. Every board needed some sort of trimming.
Some observations:
Now “all” I have left to do is clean up the toilet, fit new accessories (flusher, toilet and tank bolts, etc) and re-install the toilet. I also have to cut, fit, finish and install baseboards (quaintly called skirting boards in the instructions) and quarter round and applying clear caulking around the toilet and the tub area.
Comments(0) | Print | Home
I bought a couple of ceiling fans, one for our younger son’s bedroom and one for ours. Today I took down the old light fixtures and wrestled out the ceiling junction boxes whose flanges were nailed to cross pieces. Perhaps those nailed JBs were strong enough to carry a ceiling fan; but, I didn’t install them. After much cussing and drywall dust I got the suckers out and then it was off to the lumber store for some replacements.
On the way I dropped off some empties at the new beer store just by the lumber store. I had to wait for 10 minutes while some lady bought $200 worth of “beer” clothes. Must be some party except she didn’t buy any beer!. While I was at the lumber store I also bought a couple of plastic covers to act as a vapour barrier. At the garden centre I found some small green fences to keep my lavender from flopping over on the miniature irises and some peony hoops.
Then it was another wifely errand to Wal-Mart to pick up some ribbon and safety pins for her upcoming school concert. Music director, costume designer, producer, the whole works…
After all these errands and making supper I only had time to install and secure the two JBs and clean up the mess. Actually, the fun part will be assembling and installing the fans themselves sometime this week.
Comments(0) | Print | Home
Hmmm, there are programming languages, APIs, and, sometimes they are both glommed together in a big gnarly mess. What might have taken me half a day in Perl with a couple of modules, one to web scrape and another to write Excel™ files, will take me considerably longer in VBA. Excel 2002 wins the prize for having the worst help system I’ve seen. You invoke it and it shrinks your Excel sheet in half and then it pops up the help window beside. The keyword help is almost useless as you try and thread your way through Range and Cells methods trying to do some seemingly simple task. At home I get more information “at my finger tips” from Excel 97. Anyway, I have managed to get my VBA routine working to gather one page of Environment Canada’s climate data. Now I have to scale it up to acquire and assemble several days', months' or years' worth of data.
Comments(0) | Print | Home
I installed and configured OpenWiki on the company Intranet site. Though there are all kinds of wiki software OpenWiki seemed to be the easiest to install and would work well with our present installation of SQL server. Now I just have to add a couple of FAQ’s and “release” it to the IT department to “play” with first of all.
Comments(0) | Print | Home
According to Chris Pratley MS Word has “property bags” so “reveal codes” won’t work. That is when you add bold-italic to a bunch of words in several places in a document that bold-italic property gets saved in one “bag.” Then, presumably each bunch of words points to this property “bag.” This probably explains why I have always been so annoyed with Word: especially for outlines, section, figure and table numbering. You might change one entry and, all of sudden, all the numbering changes, or styles, or fonts, or… Very aggravating. If I can, I use LATEX, usually via MikTeX. The PDF output is very nicely laid out. The section numbering nor the styles spontaneously change. And the text “source” files are relatively small.
Comments(0) | Print | Home
I missed having a regular expression function for Excel™ until I found a VBA script on Internet. It uses the so-called RegExp object. I have lightly edited the function and called it “s” in honour of Perl's s regexp operator and because Microsoft seems to have borrowed Perl’s RE syntax. To use it, you open the VB editor in Excel, create a new module and copy the following code. S will now be available to use in formulas, for example, . If =s(A1,"(\d+)","number$1")A1 contains "a box of 2300 toys" then the formula’s result will be "a box of number2300 toys" without the bold, of course. I have used s to add columns to large csv files where I need some extra columns based on permutations and substitutions of text in other columns. This can be very tedious and error prone without regular expressions.
Excel s Function
Function s(orig_text As String, _
match_pat As String, _
replace_pat As String, _
Optional instance As Variant) As Variant
Dim regex As Object, matches As Object, m As Object
Set regex = CreateObject("vbscript.regexp")
regex.Pattern = match_pat
regex.Global = True
If (IsMissing(instance)) Then
s = regex.Replace(orig_text, replace_pat)
ElseIf instance > 0 Then
Set matches = regex.Execute(orig_text)
If instance > matches.Count Then
s = orig_text 'matchnum out of bounds - do nothing
Else
Set m = matches.Item(instance - 1)
s = Left(orig_text, m.FirstIndex) & _
regex.Replace(m.Value, replace_pat) & _
Right(orig_text, Len(orig_text) - m.FirstIndex - m.Length)
End If
Else
s = CVErr(xlErrValue) 'invalid: instance <= 0
End If
End Function
Comments(0) | Print | Home
I’m getting a new gateway/router FreeBSD box ready to take place of the one with the flaky hard disk. I built a new kernel with firewall, natting and tweaked the various /etc files based on the old box’s settings. After rebooting I couldn’t get it to connect to the network even though the box got it’s initial IP address via DHCP. I fiddled with various settings in rc.conf and manually did various combinations of ifconfig and route but still there was “no route to host.” Finally I realized I had included the directive, options IPFILTER_DEFAULT_BLOCK in the kernel. This worked too well. I commented this out and used options IPFIREWALL_DEFAULT_TO_ACCEPT instead. Come to think of it, IPFILTER and IPFIREWALL might be prefixes to different sets of programs, namely ipfw and ipfilter. Well, it’s been a rainy and cool (4 or 5°C) day so that indoor activities were called for anyway.
Comments(0) | Print | Home
Bad byte bits on the old 200 MHz gateway/server hard disk hit the swap file. In Windows, it’s the blue screen; however, in Unix it’s the more prosaic kernel panic. Fortunately the data bytes are good so I have managed to transfer the blog contents to (one of ?) my son’s web server(s). I’ve been rather busy in the last few days and evenings so I haven’t been able to switch the sites as soon as I’d like. Enjoy … again.
Comments(0) | Print | Home
There’s a company MS Word™ form that everyone has to fill out and check boxes every time a potential job comes along. The two page document is only about 50k — small for a Word document. However, a colleague complained that when he printed it, the print file ballooned to three megabytes. It took me a while to find out why because the document is “protected” and you may only fill in the blanks and check the boxes. When I expanded the view to 500% I found that all the tables and frames were dotted lines. These lines get translated into little tiny filled boxes when printing to a postscript printer. Each of those tiny boxes becomes about 80 bytes of ascii characters in postscript.
I emailed the author and suggested he use light gray lines instead. The form will look the same and each line will be one long rectangle of, still just 80 bytes, not a zillion little 80 byte boxes. This modest change should save the company some gigabytes of excess traffic on the LAN and print spooler space.
Dotted line |
Solid gray line |
Comments(0) | Print | Home

I had been holding out upgrading from emacs 20 to 21 because my favourite fixed width font, 7×14b (or 7×14bold) wouldn’t display with the specifier I used in emacs 20. However emacs 21.3 was to good to pass up so I investigated and added the following fix to my startup elisp files.
(if (>= emacs-major-version 21)
(progn
(setq default-windows-font
(create-fontset-from-ascii-font “-*-7×14b-*-*”))
(set-fontset-font default-windows-font 'latin-iso8859-1
“-*-7×14b-*-*”)
(set-default-font default-windows-font)))
Why 7×14? On a 1280×1024 screen I can have two side by side 80 column x 62 row windows for writing source code or comparing files using ediff. You have to be a coder to appreciate. There’s too much “fluff” in today’s so-called IDE.
I probably have been using emacs for at least the past 10 years. There may be still one or two bug fixes in the elisp files with my name on them. My thanks to RMS for this “not just an editor but it’s a religion.”
Comments(0) | Print | Home
Today’s treadmill stats: #3 / 360 ↑ / 112 ↑ / 2.0% / 5.02 ↑ (10.04 km/h) / 12.1 ↑ / 78 / 49.
Though today’s outside weather was fine for running I had washed my running stuff this morning. I set the max. speed to 12.1 km/h (7.5 mph) which was pretty fast though I found if I lengthened my stride I could (just) keep up. Truth be told, I pressed pause a couple of times. While looking for something else I found the heart rate monitor for the treadmill (after I was done natch) so I’ll try a heart rate controlled routine next time.
Last night’s spreadsheet discovery was how to show formulas in MS Excel. This simple VBA function does the trick:
Function GetFormula(Cell) GetFormula = Cell.Formula End Function
Some of my expense calculations for the tax return combined some values (I use named ranges) and I wanted to show the formulas I used beside the calculated values.
Comments(0) | Print | Home
The xcopy command has been around since the ol' DOS days. Since Windows 95™ I’ve been using explorer to copy or move directories' of files. Today’s problem on a Windows 2000™ server was to copy some directories from one drive to another but preserve the permissions. However, just copying directories will inherit the permissions of the parent directory. I didn’t want to remove the old directories until I could confirm the web site and application worked solely from the new drive.
The solution I found was to use xcopy /O /T C:\dir X:\. This makes a tree of directories rooted at \dir on the X: drive with the same permissions as on C:. Next I could copy the subdirectories of C:\dir to X:\dir where they would inherit the xcopy'd permissions. If I had just copied C:\dir directly to X: using explorer then X:\dir would have inherited X:\'s permissions.
Comments(0) | Print | Home
I’ve been asked if we can support other browsers on the company website: specifically MSIE 5.2.3 on the Mac OS. I don’t own such a beast nor do any of my immediate colleagues so it would be difficult to test methinks. The logs report that 0.1% of the visitors use this OS/browser combination. So, for every 1,000 visitors with “standard” browsers I need to support that 1 person who has downloaded IE and installed it on his Mac? Yes, it is doable; however, I understand the CSS support is very quirky for that version of IE. However, this site seems to suggest that this browser should support most CSS specifications. I wonder where the problem is? I wonder if I can find a browser CSS test suite? Or will I have to make one based on our company’s web site?
Comments(2) | Print | Home
I installed a web application on behalf of a colleague. It didn’t work. There was an old DLL loaded by IIS which needed to be unloaded before the new DLL could be used. Here are roughly the steps required:
Unload button in the IIS properties for that web application.Comments(0) | Print | Home
I had installed a web app of asp scripts and a dll on behalf of a colleague. The opening login didn’t seem to work as no list of databases were displayed. I poked around the scripts and concluded that the ini file wasn’t being read. After a phone call and a couple of emails it was clear the “technical” guy (I hope he wasn’t the developer, too!) didn’t have a clue what the real problem was. He talked about ntfs permissions, missing entries in the ini file, etc. In a fit of inspiration I decided to try filemon on the web server and load the web page again. There it was in black and white: the dll was using the ini file from the directory of the old version of the program. This pointed to the fact that the program hadn’t been tested with two versions on the same box. I sent another email pointing out the ini file problem — we’ll see what the tech guy says about that.
Comments(0) | Print | Home
Sometimes you forget the little things. I wrote a Perl script and module to collect web logs on another Win2k server. The script is run each day by the so-called Scheduler service. If the script finds an error condition, it exits and sends a message to the Win2k Event Log; otherwise, it logs routine messages to a file. Today with Mail::sendmail I added the functionality of emailing myself what was written to that log file since I don’t always look at the Event logs on that server every day. The problem I had to solve was how to send the log file stuff no matter where the script exited. I looked on CPAN for a likely script and re-discovered the END{} block — stuff that gets executed at the, ah, end. Now the log entries will get emailed no matter whether the script exits normally or unusually. Of course, if it doesn’t execute at all then I won’t get an email.
Comments(0) | Print | Home
Sometimes, when I viewed my son’s site, certain images wouldn’t show up. They did on Firebird (now called Firefox) so it wasn’t the rendering engine. Today, I remembered the userContent.css file I had installed over a year ago. Now that I use Adblock I had forgotten about the other method of removing unsightly ad images. I commented out the stuff in the css file, restarted Mozilla and voilà the images are back on my son’s site. Now I have some work to do with Adblock to remove the banners that the css file used to block.
Comments(0) | Print | Home
Today’s clever idea was a “finding a needle in a hay stack” solution using Excel. For the last three years a particular requirement has been noted on, perhaps, a dozen or so projects. I had to find out which multi-year projects had been noted in the first two years but not on the third. As there are maybe a thousand on-going projects I used the MATCH function combined with the functions, NOT(ISNA()), to see if the noted project was in the list and conditional formatting to highlight the dozen or so matched entries for each year. Now it’s easy to page through the spreadsheet and see whether the highlight extends across all three years or not.
Comments(0) | Print | Home
Hmmm, it seems that as your blog creeps up in the search rankings then it becomes attractive to blog comment spammers. It’s a good thing I installed Jay Allen’s MT-Blacklist a while ago. I’m sure my readers don’t need any pr0n site URL’s or “new” ways to enlarge various parts of their anatomies. In fact I won’t even dignify their efforts by publishing what was blocked. Judging by the frequency of attempted postings this must have been an automated script or perhaps the poor soul at 61.11.26.134 has Parkinson’s disease and has trouble doing just one mouse click.
2004.02.02 09:15:14 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:15:30 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:15:41 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:15:48 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:16:03 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:16:18 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:16:32 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:16:43 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:16:51 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:17:04 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:17:18 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:17:28 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:17:45 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:17:55 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:18:03 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:18:13 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:18:23 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:18:31 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:18:42 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:18:50 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:19:00 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:19:08 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:19:23 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:19:34 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:19:56 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:20:06 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:20:17 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:20:33 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:20:50 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:21:04 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:21:14 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:21:25 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:21:43 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:21:50 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:21:58 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:22:18 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:22:25 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:22:33 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:22:43 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:22:54 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:23:02 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:23:15 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:23:23 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:23:36 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:23:47 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:23:57 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:24:11 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:24:25 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:24:36 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:24:43 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:24:54 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:25:16 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:25:24 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:25:32 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:25:43 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:25:55 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:26:03 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:26:14 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 09:26:28 61.11.26.134 MT-Blacklist comment denial ... 2004.02.02 23:05:02 82.76.136.19 MT-Blacklist comment denial ... 2004.02.02 23:08:13 82.76.136.19 MT-Blacklist comment denial ... 2004.02.02 23:08:52 82.76.136.19 MT-Blacklist comment denial ...
Comments(0) | Print | Home
In the learn-something-new-every-day department I learned how to access the company’s LDAP directory: first via a visual basic script, using M$ “Active Directory Provider” object, found on the Internet. I then converted the script to Perl because the Win32::OLE module provides similar functionality to VB script. I preferred not to use Net::LDAP because that would have meant installing extra modules on top of the “stock” Windows Perl.
What was the reason for doing this? Rightly, the company decided they only wanted to maintain one database of names, emails, locations, departments, etc. When the Intranet “portal” was set up a couple of years ago it added another employee database. Each employee had to be entered manually on a form — very tedious for the approximately 250 employees we have at the moment. Shortly, I’ll have an automatic, daily Perl script to transfer and update the Intranet database list from the LDAP directory.
my @printed_fields = qw(LastName FirstName Initials Email PhoneNum Location Title) ;
my @ldap_fields = qw(sn givenName initials mail telephoneNumber physicalDeliveryOfficeName title) ;
my $select_fields = join(',', @ldap_fields) ;
use Win32::OLE ;
my $LDAP_SERVER = "LDAP://ldap-server:389/dc=mycompany,dc=com" ;
my $obj_connection = Win32::OLE->new("ADODB.Connection")
or die "$me: can't create ADODB.Connection\n" ;
my $obj_command = Win32::OLE->new("ADODB.Command")
or die "$me: can't create ADODB.Command\n" ;
my $obj_recordset = Win32::OLE->new("ADODB.Recordset")
or die "$me: can't create ADODB.Recordset\n" ;
$obj_connection->{Provider} = ("ADsDSOObject") ;
$obj_connection->{ConnectionString} = "Active Directory Provider" ;
$obj_connection->Open() ;
$obj_command->{ActiveConnection} = $obj_connection ;
$obj_command->{CommandText} = "select $select_fields,objectClass from '$LDAP_SERVER' where objectClass='user' order by sn" ;
$obj_recordset = $obj_command->Execute()
or die "$me: can't execute $obj_command->{CommandText}\n" ;
print join(',', @printed_fields), "\n" ;
$obj_recordset->MoveFirst ;
while (! $obj_recordset->EOF) {
my %record = map {
$_ => $obj_recordset->Fields($_)->{Value} ;
} @ldap_fields ;
substr($record{initials},0,1) = '' ;
print join(",", map {
$record{$_} ;
} @ldap_fields),
"\n"
if $record{sn} && $record{givenName} && $record{mail} ;
$obj_recordset->MoveNext ;
}
$obj_recordset->Close ;
Comments(1) | Print | Home
Are all JSP slow? A contract developer at work implemented a set of java and jsp stuff to parse “B2B” SAP IDoc purchase orders to XML files. “Junk” in the description parts of the records sometimes cause the java parsing or the XML file parsing to fail. He keeps getting contracts to fix up his messes. In a day or so I whipped up a parsing script in Perl which takes just a few seconds, not the several wall-clock minutes, 41Mbytes of RAM and 98% CPU usage that the java application consumed.
The Ontario Colleges Application Centre also runs jsp pages. It took over an hour to submit an application on behalf of my younger son. 90% of that time was spent waiting for the next page to load. Perhaps their server(s) is overloaded because the deadline is Feb. 1 for the 2004/2005 school year. Still, I blame the java server(servlet) pages.
Comments(0) | Print | Home

One of the first things she did was attach a few pictures of 1600×1200 resolution, 500k+ jpeg images and send them to a small list I maintain for our choir members. Of course, since this email was over 7Mbytes in size it bounced or clogged the inboxes of almost every choir member. Methinks sympatico should have some confirmation in their email client:
“Are you sure you want to send this gargantuan email message? Over half of your recipients won’t be able to receive it because of their inbox limits and another quarter on dialup will need to have their phone line busy for a week while they download your message!”
I usually recommend that people download Irfanview, a freeware image viewer and “editor.” There may even be software provided with the digital camera. These newbie high-speed-digital persons should reduce the resolution (via Image | Resize/Resample in Irfanview) down to 640 × 480 or smaller. The recipients can always email back for a greater resolution image. Better yet, the large image can be posted in their webspace and they would just send a link and perhaps a small thumbnail limited to, I suggest, a maximum width or height of 200 pixels. Then, even dialup people can have a look.
Now I’m waiting for the next phase where the newbie will start sending long jokes and mpeg videos that I’ve been sent many times before.
Comments(0) | Print | Home
I have been reading a bit about hot-linking where one web site links to another’s images instead of making their own copies. I always copy the image and usually crop and resize it smaller as a side illustration. Then I got to thinking that maybe my site stats (1.75 Gb in December) might be inflated with hot-links. The birthday cake image or this one in particular seem to be quite popular. Anyway I got rid of the hot-links by adding the following code to the Apache web server httpd.conf file:
<Directory /usr/home/<user>/public_html/www/images/>
# Prevent links from external sites to images
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?my-site\.com/.*$ [NC]
RewriteRule \.(jpe?g|gif|bmp|png)$ - [F]
</Directory>
I’ll wait for a few days and see whether this makes any difference in the bytes transferred. Meanwhile, I guess there will be a few sites with broken links now.
)
Comments(0) | Print | Home
I have added the GeoURL button so that you can find out who’s near me. See the site for further details.
Comments(0) | Print | Home

I started this project to “renovate” the company web site way back at the beginning of the summer. The initial understanding and refactoring of the scripting took about a month. But through one thing and another it took quite awhile for the content to be written and management to review and approve the changes so I could upload the stuff. Eventually it all happened this week. I will be just too busy this weekend to do the changes so I stayed late at work tonight. Uploading the scripting and testing took about 3/4 of an hour, while roughly another two hours was spent uploading new menus, sections and content pages. Perhaps I’m fortunate that most of the staff have started their holidays by now. The complaints, if any, won’t be rolling in until 2004. We’ll also see what the search engines and web site statistics have to say about the new design.
Comments(1) | Print | Home
The so-called “Domain Registry of Canada” sent a “Domain Name Expiration Notice” to me. They don’t manage my domain — they just troll the whois databases and send these fake notices. Being a private individual (read “cheap”) I don’t want to pay for a stamp on the envelope. They don’t even have the guts to have a street address: just a P.O. box. What a great scam for a web server and a colour laser printer! Their web site (I won’t dignify their operation by even linking to it.) compares their prices with the two most expensive registrars they can find. Sure, and my Buick is cheaper than a Mercedes or a BMW. For the price they are charging I’d expect free hosting thrown in and not just DNS and email forwarding. The whois info on this company is interesting: a numbered company with no public contact info. What are they trying to hide?
Domain droc.ca
Organization 1446513 Ontario Limited o/a Domain Registry of Canada
Registrar Canadian Registry Services (1489099 Ontario Inc.)
Renewal Date 2004/08/08
Date approved 2003/08/28
Last changed 2003/08/28
Description Domain name registration has now been de-regulated. This means that you now have the
choice of who you wish to renew or purchase your domain name with, resulting in great savings for
the consumer. You can save up to $90.00 by renewing with the Domain Registry of Canada. Your
current registrar has been charging you the prices listed above for your domain name services. Visit our
site to review how much you’ll save by renewing your name with the Domain Registry of Canada,
Canada’s fastest growing Domain Registrar.
Registrar Number 322079
Registrant Number 323545
Domain Number 323545
DNS1
dns1.name-services.com
DNS2
dns2.name-services.com
DNS3
dns3.name-services.com
DNS4
dns4.name-services.com
Perhaps I’ll shred the notice and send them the confetti.
Comments(0) | Print | Home
Ever since I started to redesign/refactor the company web site I have been interested in menuing systems of all kinds. The site had a pop up javascript menu system which worked fine, I guess, until there were about forty pages in one category so that the menu filled the screen from top to bottom and still didn’t display all the choices. Now most of the links are on the content pages themselves and the menu choices have been pared down to just a few sub-categories so there’s no real need for a popup menu anymore.
I came across the “pureDOM explorer” just recently. It seems to do more of what I want. Here’s a simple example—just click on the links to expand the lists:
Without javascript or if it is disabled then you’ll see a set of nested lists. However with javascript enabled then these lists become expandable or contractable with mouse clicks. BTW, this example would have been much harder to compose without my TeXlike text formatting with braces instead of open and closed html tags.
Comments(2) | Print | Home

The IT department traded my desktop PC for a new one yesterday. I have roughly 5 times the processor speed and 6 times the disk space of my old one. And the noise — there isn’t any. That old Compaq monster had this aggravating, whiny fan noise. I had built a plywood shelf to put it underneath my desk to get the unit farther away from me. Now, that noise problem is gone.
The Dell OptiPlex GX270 (What the heck does “optiplex” mean?.) desktop machine comes with Windows XP Pro and the IT staff installed MS Office as well. I asked them to give me local admin rights so that I can install other software. Of course they warned me they would no longer “support” that PC. As if they ever did on the previous box! No, I’ll be looking after it.
Most of my usual software utilities works just fine on XP. I had a problem getting XP to talk to my FreeBSD Samba server. After reading the documentation and, realizing I have a firewall limiting which hosts can connect to that server, I could have the XP box self-authorize:
security = serverpassword server = %m
The other information I had forgotten to write down was how to use Tight VNC through an stunnel. Again I pieced together some web resources to find the answer. Now the Windows version of stunnel no longer needs to wrapped in a program like srvany. It can be an NT service (daemon in UNIX parlance) by itself.
After a bit of installing and “playing around,” I decided not to use the 15” LCD display as it is limited to a resolution of 1024×768. I need at least 1280×1024 so that I can have to two side by side 80 column x 50 row emacs editor windows. Fortunately I had a capable monitor lying around. I’ll have to call IT and have them open the lock and remove the too-cute LCD display.
I think almost all of my favourite utilities have been installed. I just need to install a “real” shell such as tcsh or perhaps use Cygwin instead. One severe limitation of Windows’ cmd.exe is that it can’t use UNC paths such as //otherserver/share/directory. I also need to install Visual C++ 6.0, the pre Dot Net MSDN CD and the service packs. I can hardly wait to the time the build for a large software project I refactored a couple of years ago.
Comments(1) | Print | Home
I have found yet another reason to prefer the Mozilla and Firebird web browers: Adblock. This adds an ad blocking tool to your browser. You click the button and a list of the images and scripts on the page pop up in a list. Though the use of regular expressions you can blow away a whole set of annoying ads. I especially enjoyed blocking those large flash ads that Yahoo! puts on the page when you have an empty folder.
Now I need to find an ad substituter. It would be something like a screensaver or wallpaper type of thing. Or maybe it could turn the ad space transparent so that your background would show through. Some of those html mass emails I subscribe to, now have a lot of empty space.
Comments(0) | Print | Home
My son upgraded his server FreeBSD sources but forgot to check the domain name server’s named.conf file: mergemaster merged it out of existence. Hubbo.com disappeared for awhile over the weekend. A gentle reminder this morning and we’re back on-line.
Comments(1) | Print | Home
An engineer claimed he went to the company site and found lots of broken links. He complained to the manager of IT and the VP - Sales and Marketing. The VP asked me, “What had I done to the company web site and why was that Flash intro still there?” I had done nothing — at least to the external web site. I didn’t think I had anyone’s approval to either work on it or copy the “new and improved” web site from its internal area to the external site.
It turned out the engineer was using <domain>.com rather than www.<domain>.com to navigate to the site. It may also have something to do with stale files in Internet Explorer’s cache. Anyway, the fix turned out to be quite easy to both prevent the Flash intro and to redirect the browser solely to the www.<domain>.com main Cold Fusion script. Everybody is happy for the time being.
Comments(0) | Print | Home
p{I maintain a FreeBSD box at work and, through cvsup, I get weekly updates to the source code. This week I did the whole “buildworld, buildkernel, installkernel, mergemaster -p, reboot, installworld, mergemaster and finally reboot” schtick with no apparent problems. Today I aimed my web browser at this box to look at some personal web pages and got back a “403” permission denied error. What could be wrong? There was nothing awry in the httpd-error.log file. After some investigation I found that my home directory had the permissions
Comments(0) | Print | Home
Every so often the subsidiary Samba daemons on my FreeBSD box dump core. This isn’t a problem because the main smbd daemon will respawn another. However, the core file itself would fill up my root volume causing some other programs not to work properly. It turns out the fix was relatively easy. I added the line:
ulimit -c 0
At the beginning of the startup file /usr/local/etc/rc.d/samba.sh to prevent the
generation of smbd is failing — that’s an investigation for another day.
Comments(0) | Print | Home
Here’s a list of items:
I want to try out a side box with text that floats around it. I want to use this for a variably-sized list of cross-reference links. Here’s the style I am using:
<style> div.rightbox { width: 20%; border: 1px solid blue; float: right; padding: 5px; margin-left: 5px; margin-bottom: 5px } </style>Comments(0) | Print | Home
I guess Adobe developers broke the rule: run your software on a machine that’s 100% slower than your customer’s. That way, you’ll be damn sure to make the application as speedy as possible. The Adobe Reader 6.0 isn’t. I browsed the internet and found that you could speed it up considerably by getting rid of the plugins in Program Files/Adobe/Acrobat 6.0/Reader/plug_ins you don’t need. Even after trimming the plugins, this version still has an annoying problem in Mozilla of taking many seconds to “release” itself when you close the tab showing a PDF file.
Comments(0) | Print | Home

My sister just joined the blogging community. She plans to talk about knitting of all things. I remember learning how to do it in my teens but I’ve long since forgotten. I wish her luck.
I wrote up a note to myself on the procedure for adding another person and their domain to my web server so that they can start blogging. Looks like I’ll have to refer to it real soon as my son tells me I have a cousin who’s intererested.
Comments(1) | Print | Home
Tonight I did the wizardly incantations to set up a moveable type blog for my sister on my humble 200 MHz web server box. She wants to share her “knitting knowledge.” Once my son sets up the DNS entries (and she’s posted something
) I’ll publish the URL here.
I also revised my TeXlike module because it was rampantly changing double quotes even in html tag attributes. Now I remove and save any html tags before I fix up the quoting, then I restore them again at the end.
Comments(0) | Print | Home
I wonder you call the state of being “lost in a formatting fog?”That is, you tweak your document, preview it, tweak again, over and over, because there’s some little table, or footer, or logo — something that’s just not quite right. Suddenly you realize you are half way into lunch hour or a couple of hours have gone by. Perhaps I’ll call it liffness.”Or I’ve wasted two hours liffing.
Comments(0) | Print | Home
Bummer, first the local net last night and now the cable net tonight. I phoned Rogers' toll-free line and waited tens of minutes. By that time my cable modem had synced again. That seemed to last only as long as I talked to the “technical”guy. The cable modem lost sync, I phoned again, waiting more tens' of minutes. (While on hold I sorted choir music from last Christmas. Most of it had been sorted but there were a few late arrivals to file in.) Wouldn’t you know it? By the time the tech guy answered, the cable modem had synced again. I asked for a refund. It’s only a buck and a bit but at least this sends a message about the service or lack thereof. The service usually is pretty good but they shouldn’t be “fixing”things in the evenings. And why is it that “tech”guys have to be so condescending? Not all of us use Windoze at the cable modem. My router/firewall is a FreeBSD box with ntp precision timing. The log files clearly show when the cable internet is down.
Comments(0) | Print | Home
My son told me the Internet was down. I went down to check the status of the FreeBSD router/firewall computer in the basement: behind the piles of unsorted or un-put-away choir music. The cable modem lights were OK, the network was slow with 21 computers on the cable segment according to arp -a. Two win2k boxes on the local network couldn’t get IP addresses via DHCP though I could see the traffic at the FreeBSD box. Turned out to be the hub — it had become a one-way device. Luckily I had another so I substituted. Our local net is up and running again.
Comments(0) | Print | Home
I maintain a small email alias list for our choir so that only me and the choir manager have to maintain a current list of everybody’s email addresses. Even though that alias address is pretty easy to remember, people still insist on adding to their email lists. Every once in a while, a PC gets infected and a virus starts replicating itself by sending copies to people on the mailing list. Today it’s the Swen virus — a particularly nasty one masquerading as a Microsoft update. Firstly Microsoft doesn’t send updates by email with exe attachments and secondly, you never open an exe attachment until you’ve virus scanned it. And then only after you’ve made sure your virus scanner is up-to-date.
Comments(0) | Print | Home
That’s how much it cost me to fix the futon frame. At a party some time (a long time?) ago my son and his friends exceeded the holding capacity of two of the rivets connecting the linkages on the futon frame. All I needed to fix the links was one 5/16”x 3/4”bolt and a 5/16”nut with nylon locknut insert and a 5/16”x 1 1/2”screw. Good as new: except for a gouge where the bent link had scraped the inside of the frame. Fortunately that part doesn’t show.
Comments(0) | Print | Home
Is our small consulting outfit now a Fortune 500 company with our very own computer worm infection? Yesterday, about 2:40 p.m.*, our Intranet at work was hit with the W32/Nachi.worm. Supposedly it is a “good”worm in that it gets rid of the nasty W32/Lovsan.worm.a a.k.a MSBlaster. But the “good”worm floods the network with pings and tries to download patches to correct the vulnerability which allowed the worm to install itself in the first place. My particular box was immune as I keep up with lastest security patches. However, most of my colleagues have “stock”Windows OS installs so that this worm spread like wildfire. By 10:00 a.m. this morning our Internet connection was unusable. As several of the IT staff are on vacation, the few remaining individuals are incredibly busy now travelling around to each PC in order to install a patch to eliminate this RPC vulnerability.
* The firewall on my FreeBSD box showed a sudden flurry of pings at this time.
Comments(0) | Print | Home
Well at least I’m fixin’ up the Intranet copy of the site. These web site kids (I presume they’re young anyway) write code like college class assignments. Instead of writing one CF menu template to be called by eight very small templates which just set some variable values: they copied the code eight times and made hard-coded string substitutions — Very messy and hard to change or test. So now I have a template to set up menus, and another to show index pages of links. Both are generated from database queries. This means I can have one or a hundred menus or indices using just one or two fully tested templates.
I have had two meetings, one with the VP - Sales and Marketing and the other with some sales and marketing types on what’s good or bad with the site. The latter meeting provided some useful suggestions. I’ve scheduled another meeting before I go on vacation next Tuesday to brief two VP’s on the suggestions and comments of the SM types. The one senior VP was in on the initial web site initiation and planning. Naturally none of the executives looked at the CF code. Of course, I’d much rather be coding than arranging meetings! Nevertheless, all these meetings will give me a greater appreciation for our choral singer vacation.
Comments(0) | Print | Home
I was away overnight visiting relatives east of Toronto and when I came back the IP of this box had been changed by those people at Mr. Roger’s hi-speed neighbourhood. I thought I had taken care of everything but I now know I need to change the hubbo.com slave entry in /etc/named/zone and restart named and to also flush the routing. I realized the latter after I had made a call to Colin at Roger’s technical help desk and we worked through some possibilites. Rebooting the modem didn’t work. Rebooting the box did and I think it was because of stale routing entries. Live and learn.
Comments(0) | Print | Home

In reviewing the company’s web site I discovered the outside contracter used SQL Server to save content pages. All their database tables are pretty simple really. In fact, I easily exported them to MS Access without any errors. All that raw power, so to speak, in the database is going to waste. I always thought triggers were a neat idea, that is, to do something whenever a row is inserted, updated or deleted. So I went to work: I added a new table to the Intranet copy of the company web site content page database which would contain content page ID’s and created, modified and access date-timestamps and counts. Then I created an on insert, update trigger for the content page table which would automatically update the created and/or modified times in the new table. This means that on the “real web site”I can create a new table and then add a trigger to the content page table without affecting or adding columns to the old table. I’ll also have to add a select statement to the script that displays content so that I can keep track of accesses and last access datetime-stamp independent of the web logs.
Comments(0) | Print | Home
I thought I would make a very small change to the company website — just change the 404 error (file not found) page email link which pointed to someone no longer working at the company. Silly me, I thought the staging server script code was the same as on the Internet web server so I made the little modification and uploaded it to the main server. Oops! The people who set up the site had embedded (30 times no less!) the username and password for the SQL server dynamic document lookup in that particular script on the Internet web site. Fortunately the home page was intact, the newly uploaded script just affected all the individual content pages showing an ODBC error of some sort. Of course this begs the question of why the script developers didn’t check for database errors in their CFML scripting. Anyway we called the web hosting company to restore the errant file. I couldn’t seem to read via ftp from the Internet site only write or upload. Turns out, way back when, our firewall only permitted passive mode ftp transfers so my environment had been set up to use only this method. I hadn’t noticed a problem until now: this provider requires active mode ftp transfers. That may be the reason I couldn’t read from the site. Suffice it say, the provider restored the script file. The company web site was back into full operation. I downloaded the entire website, checked it all in to CVS so that the whole thing is now properly backed up and under version control. Whew! I can sleep better tonight.
I have met some fine people that I only knew as talking heads at upper management presentations when we explained that there would be, ah, minor difficulties with the external website overnight. Management agrees that “something has to be done”about our web presence but there’s no budget for it. Oh well, I’ll proceed (very carefully) with some of the requested minor modifications until such time as I find billable work to do. Perhaps I’ll have time to mock up a “new and improved”website using open source tools such as Apache, PHP and PostgreSQL or MySQL.
No real harm done, just a humbling experience for yours truly.
Comments(0) | Print | Home
As I was low on work and my manager asked me if I might be interested (and perhaps I had a bout of temporary insanity
), it looks as if I might be looking after some technical issues with the company website. There seems to be lots of great content but a prospective client would have (does have) trouble “drilling down”to the service or expertise they might be looking for. So a navigation and accessibility retooling is in order. The question is: can I retain the existing tools for which the company paid serious money to do this? And of course there are a tonne of stakeholders who want it done tomorrow morning. Certainly a bit of challenge and stress keeps your mind and body sharp.
Comments(0) | Print | Home

I usually scan the sender and subject lines in the Bulk folder of my Yahoo email. Sometimes my son’s or my cousin-in-law’s jokes end up there. Can’t miss the humour. Today, there was a message from my father in there. Since it was in the SPAM folder, I knew it couldn’t be a personal note about his upcoming trip out our way. Instead, it was a poem and supposed e-mail petition from MADD. There were several hundred names. (I was thinking I could write a little web scraber app. in Perl and look up several thousand names from online phone directories and add them to the list.
)
A quick search on Google showed that the message is an urban legend dating back at least three years. Even MADD felt they to comment. If my Dad weren’t on the west coast and me on Lake Ontario I could show him how to use Google and save some embarassment; not to mention some net bandwidth.
Comments(0) | Print | Home

The “just the browser folks”at Mozilla released a new browser under a new name. It used to be Phoenix ‘ceptin’ there were some ™ or © issues. Now it’s the mouthful, “MozillaFirebird.'' I started using Phoenix to post to my weblog a couple of versions ago. I find it handy to use Mozilla to check up href’s and google troll for snazzy images and use Phoenix cum MozillaFirebird to do the previewing and posting.
Comments(0) | Print | Home

After I sent the re-worked M$ Word™ document to my project leader he called to say that Word complained the document had a macro. Was it a virus? Sheese, I’d forgotten I had typed in this VBA macro to erase the direct formatting and leave just the styles. However, when I tried to delete the macro (or edit it for that matter) I got the System Error &H80004500 message. I even rebooted the box and still got that message when I tried again. Finally I had to select the whole document (Ctrl-A) and copy it to a new one. Surprisingly (or maybe not
) it reduced the size of the document by 75%! What the heck was Word storing in the rest of it? Suffice it to say I sent the “new”document to my project leader. And I decided I would maintain a parallel version in LATEX using the MiKTEX distribution for Windows. Next time I’ll send the Word document together with a PDF file of the improved typeset version.
It’s nice to come back to my old friend LATEX — a proper typesetting program that I have been using on and off for several years.
Comments(0) | Print | Home
Usually I just browse the Slashdot main page and ocassionally click some links. Every so often, though, there’s an item I just know will generate lots of comments, some serious, most hilarious. This item points to a short bit of plain old html that crashes MSIE. Thanks to my
<html> <form> <input type crash> </form>
I sent this page (Caution: don’t go there if you are using Internet Explorer to view this page or, at the very least, save anything you need to before you do.) to my son before reading Slashdotter comments wherein I found it will crash Outlook, too, as it uses the same dll that IE uses to render html.
Comments(0) | Print | Home
I have never liked MS Word™ but a client (or least my project leader) says the guide should be issued in MS Word. I was ready to issue a revision when I noticed the section numbering was screwy. Those Heading styles and outline numbers all interact in a weird Word way. You think you have corrected it when all of sudden the sub headings of another section are misnumbered. I couldn’t find any way to get subsections of a Appendix A to be numbered A.1, A.2, etc without having the subsections of the main body suddenly being numbered A.1, A.2, … Finally after several hours of grief and a couple of crashes while trying to undo I got Word to number the main body properly and numbered the Appendix sections by hand. LATEX, a document preparation system, has always done a much better job for me. Even WordPerfect™ has handy counters you can use to manipulate section numbers. Searching the Internet was revealing. There are lots of sites with Word courses, tips, annoyances and tutorials. In one document I read:
Fixing broken links in Numbered Documents:
- Select all the text of the document
- Cut it (Ctrl-X)
- Delete all the outline-numbered styles
- Rebuild all the styles in the document using Format/Style Gallery twice
OR
- Rebuild all the styles in the document using Format/Style/Organizer/Copy of the outline numbered styles twice
- Once styles and schemes are in place, paste the text back into the document
- You may have to Ctrl+Q (Reset Paragraph) to remove manuallyapplied paragraph attributes on some paragraphs.
Seems like a lot of work to me. Perhaps I can still convince my project leader that the deliverable should be a PDF file instead. Then I can use other software to format the text.
Comments(0) | Print | Home
I have been illustrating my blog with images gathered from here and there on the web. In fact some of those images have been linked to by the web pages of others according to my web stats. I have found that Microsoft’s Photo Editor to be the easiest tool so far to make backgrounds transparent. There’s an arrow in the toolbar that you point to the background. They even provide a “fuzziness” setting so that you could, for example, make a sky of several shades of blue transparent. As you can see in the accompanying Help About box it appears this application didn’t come from Microsoft originally. It certainly isn’t as bloated or patronizing as Word seems to be.
Comments(0) | Print | Home

At lunch time I did a little tweaking on the script that grabs the latest weather and the Ontario electrical energy price. Strange: the observed weather time was an hour ahead. I looked for a bug in my code and then looked at the web site data. EC had advanced UTC, or GMT as it used to be known, by one hour. Funny, I though UTC was constant. Anyway I submitted a message in their contact form and they replied they were “working on it.”The fix in my perl script was simple enough: if their UTC time was greater than my computer’s UTC (I use NTP to keep my computer synchronized) then I subtract an hour from their “observed time.''
I decided that having the current reading in the middle of the trend graph was hard to interpret so I moved it to the right end, still retaining the lighter shade for the previous day’s values. I also decided it was convenient to cache the mtime of the script so that if I made modifications the script would automatically do a full update at the next interval. You’ll note that it’s the second week of April, below freezing and there’s snow. The average high temperature for this time of year should be 10°C or so. I’m done with winter now, thank-you. Let’s send our winter to the the arctic foxes.
Comments(0) | Print | Home
After many months somebody seems to have been monkeying around with the DHCP server and gave hubbo.com a new IP. So until I straighten this out and the new IP propagates, hubbo.com may be off for a day or so. As if you’d know since you wouldn’t be able to read this. Sigh!
Comments(0) | Print | Home
I have been playing with my WWW Data script trying to get the data looking “just right''. There are now little 24 hour trend charts generated by creating an ASCII ppm file and then using pnmtopng to create a graphics file that is loadable by most browsers. Each trend chart also has the daily min and max values. For awhile I had problems with updating the cache of 24 hourly values/quantity. It seems Perl won’t always automagically create nested references unless there’s an empty one there already. I also added a little bit of intelligence so that these web pages will only be loaded and parsed hourly even though the script may run more often than this. That is, the script keeps track of each web page’s CRC and the time it was accessed. Another 24 hours will go by before the little trend charts will be showing actual data. I had to preload them with bogus values in order to verify things were working. Oh and there’s a little cursor showing the current hour’s value and position in the chart.
Comments(0) | Print | Home
I decided to copy a data CD tonight and the software said it couldn’t find a CD burner. Well, I’ve read warnings that a Win2k upgrade from Me might have some bumps. “Repairing”the CD burner software didn’t work. I had to remove it and then re-install again plus at least a couple of re-boots in there. Finally a hour or two later I copied that CD. Windows™ is so much fun sometimes — like an evening of my life wasted watching install dialogs and screens.
My TEXlike text formatter seems to be working except for nuisance messages such as MT::App::CMS=HASH(0×836ed14) Use of uninitialized value in concatenation (.) or string at /usr/home/jservice/public_html/blog/mt/extlib/jrrs/TeXlike.pm line 78. In fact I have initialized everything so I suspect that somewhere in MT::App::CMS.pm there’s something uninitialized. Some day I’ll waste some more time looking for it.
Comments(0) | Print | Home
jrrs::TeXlike version 1.12. Documentation last updated Tue Feb 3 12:16:14 2009.
The latest version of Moveable Type supports plugins for blog entry formatting. I tried textile; however it wasn’t quite what I wanted but a step in the right direction. Using my favourite editor, which highlights matching {} easily I decided to created a plugin where the html tags resemble TEX macros — only they aren’t really macros. They just exchange the work of typing the second tag by adding a \ and two brace brackets. The regular expressions are pretty simple: they just go through the text and change the \tag{something} into <tag>something</tag>. What follows is a table of some of the patterns and their replacements. Of course this entire note itself was formatted via my TeXlike.pm plugin.
| TEX-Like Patterns | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Pattern | Result | ||||||||||||
| \strong{strong content} or strong{strong content} See note. |
strong content or strong content | ||||||||||||
| \div[commentary]{Using the commentary style...} p[align="right"]{This paragraph is right aligned.} | Using the commentary style…
This paragraph is right aligned. |
||||||||||||
| \href[http://www.moveabletype.org]{Moveable Type Link} | Moveable Type Link | ||||||||||||
|
\div[inner_table]
{
\table{
\tr{\th[colspan="3"]
{A sample table}}
\tr{\td{row 1, cell 1}
\td{row 1, cell 2}
\td{row 1, cell 3}}
tr{td{row 2, cell 1}
td{row 2, cell 2}
td{row 2, cell 3}}
\tr{\td{row 3, cell 1}
\td{row 3, cell 2}
\td{row 3, cell 3}}
}
}
Note: the leading \ is not required if the “word”proceeding the { is an html tag and it is on a “word boundary'', i.e., it follows whitespace or punctuation (Perl regular expression `\b'). |
|
||||||||||||
| \ol{ \li{Item one} \li{Item two} } |
|
||||||||||||
Include perl code <PerlCode>scalar localtime</PerlCode> or get this if your perl code is wrong: <PerlCode>scalar localtime(</PerlCode> |
Include perl code Tue Feb 3 12:16:14 2009 or get this if your perl code is wrong: syntax error at (eval 17) line 2, at EOF | ||||||||||||
| \'a \"o \'e \c{c} \^u \~n {\ss} | á ö é ç û ñ ß | ||||||||||||
| "This is double quoted". HTML tags are saved then double quotes are alternately set to ``and.'' Using the latter doubled single quotes will only work before a word and before whitespace respectively. Single quotes are somewhat similar: \`like this\' however if you use a single quote before a vowel the module will change it to an accented character so you n\`{}e\'{}ed to do this instead. Other typographic symbols include: ... -- --- \& \< \{\}\[\] | “This is double quoted”. HTML tags are saved then double quotes are alternately set to “and.” Using the latter doubled single quotes will only work before a word and before whitespace respectively. Single quotes are somewhat similar: ‘like this’ however if you use a single quote before a vowel the module will change it to an accented character so you n‘e’ed to do this instead. Other typographic symbols include: … – — & < {}[] | ||||||||||||
| \backslash \copyright \cent \registered \trademark | \ © ¢ ® ™ | ||||||||||||
| 10\degreesC -30\Fdegrees 273\degreesK 360 \degree | 10°C -30F° 273°K 360 ° | ||||||||||||
| \plusorminus 2x3 (times) 2\x3 (ecks) 2/3 2\/3 {1/2}, {1/4}, {3/4} | ± 2×3 (times) 2x3 (ecks) 2÷3 2/3 ½, ¼, ¾ | ||||||||||||
| TIACA{This Is A Cool Acronym} | TIACA | ||||||||||||
| Line one\\ Line two | Line one Line two | ||||||||||||
Comments(0) | Print | Home
In an effort to put off the receipt logging I need to do before I fill in the tax returns I added some caching to my WWW data script. Now there are arrows, ⇑ and ⇓, and a number to indicate the change from last hour to this one. Now I must really get back to the tax return data.
Comments(0) | Print | Home
I have made a couple changes to the site 1) a navigation bar to the archives and 2) a little table of data in the sidebar. This WWW Data table shows values extracted from the data of a couple of web sites whose data, in turn, change hourly. I also added a refresh meta tag so that the web page in your browser may automatically update, too.
I run a perl script from cron that generates this table in an html file. Whenever hubbo is accessed this file gets automagically included. The script doesn't use anything fancy except for a hash of hash of hashes (HOHOH) to express what web sites I want to access and what bits of data I would like to extract. Then, a generic loop does the extraction and output by processing this HOHOH. Of course you need an editor which does syntax highlighting of perl code and highlights matching braces, brackets and parentheses. I use emacs for the job. Now that the mechanism is in place, I'll have to look at other changing data nuggets on the web. Here's what the HOHOH looks like that generates the WWW data table:
my %url
= (weather =>
{url =>
'http://weatheroffice.ec.gc.ca/forecast/city_e.html?yyz',
title => "YYZ (Toronto) Weather",
# Hash of 'what' values and what was parsed from the web content.
result => {},
# Each rendered item is put here.
output => [],
# Order of items to be output. If it's not listed it isn't printed.
order => [qw(datetime temp wind windchill sun_rise_set forecast)],
data =>
# Items to parse from web content.
{temp =>
{
# Regular expression to find some values in the web content.
re => 'Temp.:.*?(-?\d+)(°C)',
# List of what will be assigned from parentheses in regular
# expression. These values should be unique for this url as they
# will be put in the {result} hash.
what => ['temp', 'units'],
# Anonymous sub that returns two strings, a label and a value string
# which renders the 'what' values.
render => sub ($)
{
# The value of $url{url_key}{result} is passed to the sub.
my $ref = shift ;
("Temperature", join_or_undef($ref->{temp}, "",
$ref->{temp}, $ref->{units})) ;
},
},
windchill => { re => 'WindChill.*?(-?\d+)\s*\<',
what => ['windchill'],
render => sub ($)
{
my $ref = shift ;
($ref->{windchill} ? "Wind chill" : '',
join_or_undef($ref->{windchill}, "",
$ref->{windchill},
$ref->{units})) ;
},
},
datetime => { re =>
'Observed on: (\d+)\s+(\w+)\.?\s+(\d+)\s+at\s+(\d+:\d+)',
what => ['day', 'month', 'year', 'time'],
render => sub ($)
{
my $ref = shift ;
("Observed time",
join_or_undef($ref->{month}, "",
scalar(localtime(str2time(join(" ",
$ref->{month},
$ref->{day},
$ref->{time},
$ref->{year},
"GMT")))))) ;
},
},
forecast => { re =>
'To(day|night) ..<.*?</strong>\s*([^<]+)',
what => [qw(ignore forecast)],
render => sub ($)
{
my $ref = shift ;
("Forecast",
join_or_undef($ref->{forecast}, "",
$ref->{forecast})) ;
},
},
sun_rise_set => { re =>
'Sunrise:.*?<strong>(\d+):(\d+).*Sunset:.*?<strong>(\d+):(\d+)',
what => ['risehr', 'risemin', 'sethr', 'setmin'],
render => sub ($)
{
my $ref = shift ;
my ($hr, $min) = ($ref->{sethr}, $ref->{setmin}) ;
# Calculate amount of daylight.
if ($ref->{setmin} < $ref->{risemin}) {
# Borrow from hours value.
$min += 60 ;
$hr-- ;
}
$hr -= $ref->{risehr} ;
$min -= $ref->{risemin} ;
("Sun rise/set",
join_or_undef($ref->{risehr}, "",
$ref->{risehr},
":", $ref->{risemin},
" - ", $ref->{sethr},
":", $ref->{setmin}),
"Daylight hours",
join_or_undef($hr, "", sprintf('%d:%02d',
$hr, $min))) ;
},
},
wind => { re =>
'Wind:.*<strong>([^<]+)<br>([^<]+)',
what => [qw(wind_dir wind_units)],
render => sub ($)
{
my $ref = shift ;
("Wind", join_or_undef($ref->{wind_dir}, " ",
$ref->{wind_dir},
$ref->{wind_units})) ;
},
},
},
},
imo =>
{url => 'http://www.iemo.com/imoweb/marketdata/marketToday.asp',
title => "Ontario Electricity Market",
result => {},
output => [],
order => [qw(datetime demand hourly_price)],
data =>
{ demand =>
{
re => 'Current Market Demand: .*\>\s*([,\d]+) MW',
what => ['demand'],
render => sub ($)
{
my $ref = shift ;
("Ontario demand", join_or_undef($ref->{demand}, " ",
$ref->{demand}, "MW")) ;
},
},
hourly_price =>
{
re => 'Current Hourly Price \(HOEP\): .*?(\$\d+\.\d+) /(\w+)',
what => [qw(hourly_price perEunit)],
render => sub ($)
{
my $ref = shift ;
(qq(Current <acronym title="hourly Ontario energy price">HOEP</acronym>),
join_or_undef($ref->{hourly_price}, "", $ref->{hourly_price},
" per ", $ref->{perEunit})) ;
},
},
datetime =>
{
re => 'at (\d+:\d+)\s*(\w\.\w\.) (\w+) (\w+) (\d+)',
what => [qw(time a_or_pm tz month day)],
render => sub ($)
{
my $ref = shift ;
("Datetime", join_or_undef($ref->{month}, " ",
$ref->{month}, $ref->{day},
$ref->{time}, $ref->{a_or_pm},
$ref->{tz})) ;
},
},
},
},
) ;
Comments(0) | Print | Home
I stayed up a little past my bedtime last night upgrading our “primary” (i.e. fastest) computer from Windows Me™ to Windows 2000™. I figured since my wife is away at her girlfriend's cottage for a few days for the March break holiday this would be as good a time as any. That way any problems would only inconvenience me. The upgrade wasn't quite as routine as our older PC as the video driver, ethernet driver and scanner are all newer than the win2k install disk I had. Before I installed the video driver software it harkened back to the days of Windows 3.1 and VGA mode. And, of course, I had no networking until the ethernet driver was installed. Now its just a matter of some settings' tweaking (e.g. moving Mozilla stuff from /Windows/Profiles/ … to /Documents and Settings/ …) and re-installing some software (e.g. AVG Anti-Virus).
Comments(0) | Print | Home

My client wanted a popup calendar instead of
typing a date on the command line so I obliged and put a thin wrapper around
the MFC “Month
Control”. Basically the user selected a date, pressed OK and the
little dialog printed a date to stdout . This worked fine on
Windows NT™, the OS my
client and I use. However, my esteemed project leader tried it on his
laptop, using Windows 2000™ and found it gave incorrect dates
usually several years in the future. I built the little application at home
on my Windows Me™ box and found that it, too, was giving the wrong
date. Fortunately I have the MFC sources and the windows SDK installed on my home box so I
did a little sleuthing. It turns out that Microsoft's implementation of
mktime?
doesn't care what you put in the hours, minutes or seconds fields. It
converts the lot to a number of seconds and does the same for the year,
month and day. So, if a large number gets passed in the hours field then the
time value will be rather far off than the date selected. In fact the month
control returns a SYSTEMTIME struct each of whose fields (year,
month, day, hours, minutes, seconds) is a WORD or two byte
(presumably unsigned) integer. So, if the hour value was the largest it
could be, i.e. 65536, this is roughly 7½ years! My guess is that
Windows NT zeros out the hour, minute and second values; whereas, Windows
2000 and Windows Me do not and random junk values are returned instead. My
work around was to use only the year, month and day values returned from the
month control. Why didn't I do this in the first place? Well the Visual C++
IDE suggested
I could use a CTime variable for the control's return
value. And how does this control initialize this value? It uses all
the fields of SYSTEMTIME and passes them to mktime
to initialize the CTime variable. Now I explicitly pass just
the year, month and day from the SYSTEMTIME result and zeros
for the hour, minute and second values. Ain't programming fun!
Comments(0) | Print | Home
I upgraded the Moveable Type Software to version 2.6+ and discovered “Text Formatting” plugins support. What does this mean? Well, bold and emphasized text, for example, can be entered thusly:
*bold* and _emphasized_
rather than like this:
<strong>bold</strong> and <em>emphasized</em>
A tip o' the toque to Brad Choate for this nifty module. This will speed up my blog composing as I won't have to remember opening and closing tags for run of the mill text.
Comments(0) | Print | Home

I use Mozilla or it's lighter weight cousin Phoenix to do most of my browsing except for the odd site which requires IE because they've used some M$ software to create the site. (The corporate intranet where I work is a big offender in this regard.) This web site described some ways to do some ad-blocking with css coding in the userContent.css. I used this file to solve a printing problem: At great expense (heh! heh!) I downloaded a driver from HP to do multiple pages/page and correct gray-scale shading at 600dpi with coloured documents on the Laserjet 5 Si/MX at work. One problem, though, is that trying to print pages from some sites will give very light lettering on a white background. Here's a userContent.css entry that will fix this:
@media print {
body { background: white ! important;
color: black ! important; } }
That is, when printing, the default background is white and the text colour is black, unless specifically overridden by the document. Works for me!
Comments(0) | Print | Home

For my birthday last week my family gave me a zippy CD writer (48x24x48x). My son offered to install it for me and I said where's the fun in that. The installation was no problem — I replaced the DVD-ROM since we have a DVD player now. However I found that the old CD writer was still just a shiny coaster maker. So, I yanked it out and now use the DVD ROM as the source for CD to CD copies. And, just now, I made a good copy of the Knoppix Linux on a CD. The next step is to back up the "user" files on my Windows Me box and then upgrade it to Win2k.
Comments(0) | Print | Home
I have become quite a fan of defining inserter (operator<<) methods for my C++ classes. Output becomes so simple just: os << instance_of_my_class. I rewrote my program logging to use an ogzstream class and custom inserters for "almost everything". When I run into problems I just have to add a short log statement and see the results. I would always run in to problems using the Visual C++ TRACE macros which use a printf type of format string. There's a (quite small) limit on the string buffer which causes an ASSERT if it overflows. And it isn't typesafe whereas with operator<< you can output almost anything and if the compiler can't find a << operator for a class it will complain. TRACE will merrily compile anything and then ASSERT or crash if the item isn't a CString or a simple type like int or double. The debug and logging macros I use are shown below. The CError::stream() and CError::gzlog() are static methods which define static variables internally so that I can do logging and stream formatting at any time during my program — even during static class variable initialization. In effect I'm using singletons.
// Usage: GLOBAL_MSG(FILE_LINE, fmt, arguments...) ;
#define FILE_LINE THIS_FILE, __LINE__
#define GLOBAL_MSG CError::global_msg
// Pre-format an inserter expression msg with a date-time stamp, a keyword,
// the source code file and the line number.
#define INSERTMSG(keyword,msg) \
CError::now() \
<< " " << keyword << " " \
<< CSplitPath::get_filename(THIS_FILE) \
<< ":" << __LINE__ \
<< " " << msg
// Usage: LOGMSG("result", "The result is " << result) ;
#define LOGMSG(keyword,msg) CError::gzlog() << INSERTMSG(keyword,msg) \
<< std::endl
//
#define POPUPMSG(x) CError::stream() << x ; \
CError::popup_msg(CError::stream().str().c_str(), 0, \
CSplitPath::get_filename(THIS_FILE).c_str(), __LINE__) ; \
CError::stream().str("")
#ifdef _DEBUG
// Fancy macros to generate debug or trace listing in the log file as well
// as a trace message. It is wrapped in a CCriticalSection because TRACEZ
// messages may come from different execution threads and the CError::stream()
// is shared among them. There are two std::endl, one to flush and send the
// line to the log file and the other to new line terminate the string.
//
// The if ... TRACEBUFSIZE works around a TRACE0 bug as TRACE0(string)
// resolves to AfxTrace("%s", string) and there's a 4096 character buffer
// limit which causes an assert if string is more than this number of
// characters.
//
// Arguments: (keyword,expression,inserter)
// keyword - a string e.g. "trace"
// expression - if (expression) is true send inserter to file and debug
// output otherwise just use TRACE0
// inserter - C++ << expression
//
// Usage: TRACEMSG("trace",1,"The value is " << value) ;
//
// Reasons:
// 1) You can't imbed inserters in function calls though I have tried. :-)
// 2) Uses TRACE0 so that no formatting is done. In some cases formatting
// may overflow whatever buffer visual C++ provides causing an assert
// which isn't related to the program.
// 3) Completely disappears when _DEBUG not defined.
# define TRACEBUFSIZE 230
# define TRACEMSG(keyword,logfile,x) do \
{ \
CriticalSectionLock cs_lock ; \
CError::stream() << INSERTMSG(keyword,x) ; \
if (logfile) \
{ \
CError::gzlog() << CError::stream().str() << std::endl ; \
} \
if (CError::stream().str().size() > TRACEBUFSIZE) \
{ \
std::string str(CError::stream().str(), 0, TRACEBUFSIZE) ; \
str += "...\n" ; \
TRACE0(str.c_str()) ; \
} \
else \
{ \
CError::stream() << std::endl ; \
TRACE0(CError::stream().str().c_str()) ; \
} \
CError::stream().str("") ; \
} while(0)
# define TRACEZ(x) TRACEMSG("trace",1,x)
// Trace with no file logging.
# define TRACENZ(x) TRACEMSG("trace",0,x)
# define TRACEIF(condition,x) if (condition) \
{ \
TRACEMSG("trace",1,x) ; \
}
# define TRACEIFELSE(condition,x,y) if (condition) \
{ \
TRACEMSG("trace",1,x) ; \
} else { \
TRACEMSG("trace",1,y) ; \
}
// Log info messages to trace output as well as log file.
# define INFOMSG(x) TRACEMSG("info",1,x)
# define WARN(x) TRACEMSG("WARN",1,x)
# if defined(ENABLE_VERBOSE) && ENABLE_VERBOSE
# define VERBOZE(x) TRACEMSG("verbose",1,x)
# else // ENABLE_VERBOSE
# define VERBOZE(x)
# endif // ENABLE_VERBOSE
#else // _DEBUG
// Some macros now cause their arguments to disappear and insert nothing.
# define TRACEZ(x)
# define TRACENZ(x)
# define INFOMSG(x) LOGMSG("info",x)
# define WARN(x) LOGMSG("WARN",x)
# define TRACEIF(condition,x)
# define TRACEIFELSE(condition,x,y)
# define TRACEMSG(keyword,x)
# define VERBOZE(x)
#endif // _DEBUG
#define GZLOG(x) INFOMSG(x)
Comments(0) | Print | Home
At work I used TrayMenu on my NT box. It's a little application which hides in the tray, actually it replaces the clock. Basically it pops up a menu of your desktop shortcuts among other things. It had a major annoyance that made tray minimized program icons disappear every so often. Annoying to me because I use another utility to "Minimize to Tray" several programs which create lots of windows such as MS Outlook and Emacs. I went to see if there was an update; however, it looks like the author didn't pay his domain name registration fee. Anyway I decided instead to populate my All Users/StartMenu and servicej/StartMenu with some of my desktop shortcuts, as it gives me the same functionality. I should have done this long ago. Using Emacs' dir-mode to mark several desktop shortcuts and copy them to the StartMenu made the task quite easy.
Comments(0) | Print | Home
Don't you just hate examining a problem, getting closer and closer to a solution when, blam!, you realized you had caused it with a very tiny configuration error. As a former part-time sysadmin, I had configured a particular Sun Solaris box to have two separate network interfaces: one for the Intranet and the other for a dedicated piece of simulation hardware. I had crafted a manual routing configuration script because the automatic Solaris solution would configure the routing for the wrong interface. This worked well for more than a couple of years. In the past year or more the IT function has been downsized and partly outsourced so those poor over-worked souls have been re-assigning subnets and IP addresses. They can tell at a glance whether a given IP address is for a "server", "workstation" or "printer". Anyway the symptom appeared to be that the Solaris box could ping any workstation on the Intranet but only certain workstations could ping it. Using tcpdump I found that the ping packets from the Solaris box weren't actually getting to some of the workstations. Unless you added some specific arguments to the ping command any old reply from the gateway, for example, would cause the Solaris box to say the workstation was "alive". Finally, after "hours" of work, I discovered the route command in my initialisation script was too restrictive on the Solaris box and excluded local Intranet connections to many workstations. Instead these would go to gateway which only handles connections to the Internet. In the "old" days the IP addresses of our department were pretty homogenous but now with new PC's and IP number policies this script had failed. Tomorrow I will have to log on the Solaris box and fix that little error.
I did discover one feature of the Solaris OS that it won't let you disturb an in-use existing (external) route. I remember several Oh-Oh's when I was playing around with my home FreeBSD box by connecting from work. A seemingly innocuous change to the routing or firewall configuration would suddenly break the connection. Then I would have to wait until I got home to fix it.
Comments(0) | Print | Home

That old enamel-on-steel sink in the main floor "powder room" was showing its age (about 22 years). I touched up one chip (with a different colour as those "standard" colours change over the years) and a couple of weeks later a new chip appeared. So I replaced it with a shiny white porcelain job yesterday. As I had previously replaced the taps and the drain it was just a matter of loosening a few nuts, taking out the old sink, cleaning the vanity cutout and plopping in the new one. It's not "perfectly" aligned with the cutout: to do that would have meant cutting off the old drain pipe and rebuilding a new one. The caulking provided with the sink hides the slight gap anyway. I have gone away from using silicone caulking. Though it seals nicely, it's a tedious job of scraping to clean it off when you replace something. Plumber's putty and mildew-resistant latex caulk are much easier to remove and probably seal just as well.
Sometime in the near future I will have to replace the sink in our ensuite for similar reasons However, I will also need to replace the old taps and drain, too — not just an afternoon's bit of work and a job for another vacation period.
Comments(0) | Print | Home

Comments(0) | Print | Home
My wife needed more rhythm sticks or clave for the children in her music classes who will be peforming in the up-coming "Holiday Season Concert" (can't call it Christmas nor can there be Christmas music, sheesh). Having the right set of power tools works wonders. I sliced up 24 6" lengths from the ¾" doweling with my chop saw. Then I clamped my belt sander into my Workmate and rounded off the 48 ends so no little fingers will get slivers. Et voilà — about ½ hours work and the job is done. As I am on vacation I might even hear those clave being struck together at the school concert next week.
Comments(0) | Print | Home
Comments(0) | Print | Home
"Works like a charm" as a former colleague used to say. I tested two 100-bulb strings and ran out of replacement bulbs, over a dozen "bum" ones at least! I made another trip to Rona (Walmart was sold out) to buy more replacements. My enthusiasm for putting up those outdoor lights has waned somewhat though. During the course of the day the temperature has plummeted from near 0°C this morning to -9°C this evening.
Comments(0) | Print | Home
A few weeks ago I replaced the ballast in the double 40W fluorescent light fixture in the laundry room because of its dim lighting. I also replaced the two old tubes. It worked initially but then only gave a quarter of the light its supposed to. Hard to tell the clean from the dirty laundry under those light conditions. Finally today I got out my digital multimeter, took out the tubes, and measured the voltage at the sockets. Over 300V between them at one end and about 150V between the sockets and the reflector — certainly enough voltage to light a couple of tubes. I changed one of the tubes and now its working. Suddenly I saw the light: now I realize that box of "econo-watt" tubes I bought were the source of my dimness problems. This may explain the seemingly shorter life of the ballasts, too. Now I resolve to buy "brand name" tubes on sale rather than a box of no-names.
Comments(0) | Print | Home
It used to be difficult to install stuff in a computer but the form factors, power, data connections, etc seem to have been pretty much standardized. My older son gave my younger son a CD burner for his birthday (18!) at the end of this week. I installed it last night in his computer. I had to take out the existing CD-ROM drive to find out whether it was a master or slave on that IDE channel. The tiny screws on the right side fell into a narrow channel in the case — it took me a while to slide them along and extract them with tweezers. When I put it back together I used the screwdriver with the magnetic bit so this wouldn't happen again. Anyway, my younger son reports that the CD burner works. I'll have to open up the case of my PC and try to determine why my burner only makes coasters unless I slow the process down to 4X or lower. Perhaps its the fault of running Windows Me so I should upgrade to Windows 2000.
Comments(0) | Print | Home
As you may or may not be aware I "blog" and preview with Mozilla, a very capable browser "suite" IMHO. Lately, the browser (only) part of Mozilla has been extracted and called Phoenix . Its claim to fame is that it starts up much faster and runs "cooler". I have found it so. Though it might not have all the fancy toolbars and plugins, it is ideal for firing up a quick connection to your blog when you don't have time for the Mozilla monster to start up and your not intent on general web browsing, too. You just want to jot down a note and post it. Like so.
Comments(0) | Print | Home
My large Ontario electricity market simulation would "hang" occasionally and I couldn't determine why. Sometimes I would be lucky and the program would hang while running with the debugger. All that would show when I "broke" into the program was that some DLLs were running including msjet40.dll. So, I figured it was an ODBC or MS Access database problem. Nope. Today I installed the program on another box and now it consistently hung. This was good as I could now finally track down the problem. What it boiled down to was an uninitialized class member variable. This variable was used in a Windows API call to Sleep(value). On my box apparently value was always small but on this other box it was a large number so the program was "sleeping" all the time at a certain point. It's disappointing that the debugger couldn't have given me this information. Anyway, it was quite satisfying to squash this bug.
Comments(1) | Print | Home
I have a Laserjet IIIp, now about 10 years old I guess, which I bought with a zippy 33 MHz PC (!). I don't use that PC but the Laserjet was working fine until recently when it showed a "52 Error". A little 'net surfing brought me to Fixyourprinter.com which diagnosed the error as a scanner motor problem. An 'net order and around $90 later I had a new scanner board and a CD video. (Aside: Canada Post charged a $5.00 handling fee and Canada Customs added PST and GST to the order. How nice!) I played the video this morning and followed the detailed screw-by-screw instructions. Now the laser printer is working again. As my wife has lots of stuff to print for her courses and teaching, she'll be glad to hear that.
Comments(0) | Print | Home
The edge of the low pressure system which used to be hurricane Isadore gave southern Ontario a good soaking today. It has been months since we have had a rain like that — at least during the day. Fortunately I have been so busy C++ coding at work this past couple of weeks, even through most of my lunch hours, I barely noticed the weather.
Speaking of coding, I am getting the knack of using C++ templates, the Standard Template Library (STL) and type-safe iostreams. There's some cool things (well at least for me) you do can do. These things include having "magic" static constants that automatically get read or written to an ODBC database connection, connections to several databases managed by one function with a static std::map variable, using std::auto_ptr's for automatic pointer deletion, templates for type-safe input and output. The large program I am working on used to have a hard-coded "tree of if statements" set of rules which created a 10,000 element linear programming (LP) matrix. This code was hard to understand and maintain especially if a particular rule had to be changed or there was an error in the output LP matrix. Now these rules are contained in a text file and I use the STL to create structures such as std::map, std::vector and std::set to process inputs and create the LP matrix. Perhaps, it is not quite as fast as the set of if statements but rule errors and changes are much easier to implement without a program recompilation.
Comments(0) | Print | Home
How about that. I had believed this myth but the explanation from this article makes more sense. If you've ever used a bicycle pump you know that it gets warm after awhile — probably the same phenomenum.
This one makes sense, which is why it's so pernicious. But it's still wrong.
Meteoroids are tiny bits of dust, rock, ice or metal that have the unfortunate luck of having their orbits intersect the Earth's. When they pass through our atmosphere, they are heated so ferociously that they glow (and at this point are called meteors), and are visible for hundreds of miles.
However, it is not friction that heats them. Think of it this way: a space shuttle's tiles are extremely delicate; they crumble easily in your hand. If they were heated by friction as the shuttle de-orbits and enters the atmosphere at Mach 25, the tiles would disintegrate. That's not a very good design characteristic.
In reality, it isn't friction, but ram pressure that heats the meteoroid. When a gas is compressed it gets hot, like when a bicycle pump is vigorously used to inflate a tire. A meteoroid, moving at 33,500 mph (15 kilometers a second) or more compresses the air in front of it violently. The air itself gets very hot, which is what heats the meteoroid. That's the fact, not friction.
Comments(2) | Print | Home
For debugging purposes I produce XML file "dumps" of some of the C++ class variables I have created used in a large program I'm developing at the moment. These files can be quite large but, because of the many redundant tags, they may be compressed down to 2% of their original size. I am using the zlib library in my program already and I looked for a way of using zlib with C++ streams. I discovered the gzstream library but, unfortunately, it wouldn't compile using Visual C++. When you try and compile gzstream.cpp (renamed from gzstream.C in the library) you get an "inappropriate or no default constructor found" type of error. After much head scratching and web research I finally found the clue while reading this article on Deriving the C++ Stream Buffer. gzstream has only been tested using the g++ compiler; so, looking in my handy cygwin distribution I discovered the prototypes in <iostream> don't use templates whereas the MS C++ compiler include files use them extensively.
What I found is that you can't derive a stream class using the typedefs std::istream or std::ostream. Instead you must use the actual types. So the original code extract from gzstream.h looked like this:
class igzstream : public gzstreambase, public std::istream {
public:
igzstream() : std::istream( &buf) {}
igzstream( const char* name, int open_mode = std::ios::in)
: gzstreambase( name, open_mode), std::istream( &buf) {}
gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }
void open( const char* name, int open_mode = std::ios::in) {
gzstreambase::open( name, open_mode);
}
};
class ogzstream : public gzstreambase, public std::ostream {
public:
ogzstream() : std::ostream( &buf) {}
ogzstream( const char* name, int mode = std::ios::out)
: gzstreambase( name, mode), std::ostream( &buf) {}
gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }
void open( const char* name, int open_mode = std::ios::out) {
gzstreambase::open( name, open_mode);
}
and the transformed code is now this:
class igzstream : public gzstreambase,
public std::basic_istream<char,
std::char_traits<char> > {
public:
igzstream() : std::basic_istream<char,
std::char_traits<char> >( &buf) {}
igzstream( const char* name, int open_mode = std::ios::in)
: gzstreambase( name, open_mode),
std::basic_istream<char,
std::char_traits<char> >( &buf) {}
gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }
void open( const char* name, int open_mode = std::ios::in) {
gzstreambase::open( name, open_mode);
}
};
class ogzstream : public gzstreambase,
public std::basic_ostream<char,
std::char_traits<char> > {
public:
ogzstream() : std::basic_ostream<char,
std::char_traits<char> >( &buf) {}
ogzstream( const char* name, int mode = std::ios::out)
: gzstreambase( name, mode),
std::basic_ostream<char,
std::char_traits<char> >(&buf) {}
gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }
void open( const char* name, int open_mode = std::ios::out) {
gzstreambase::open( name, open_mode);
}
which compiles using MS Visual C++. Now I can open an ogzstream stream and have my debugging XML output automatically compressed.
Comments(0) | Print | Home
Comments(0) | Print | Home
A few months ago I sent a colleague a note about the confluence.org web site where individuals send images and a story about their experiences in finding integer intersections of latitude and longitude. During travel from one location to another, Don and Peter realized that they might pass by a "confluence" on their way to the next site. As they explain they were lucky enough to find a logging road which intersected this confluence: no trek into the bug infested woods was necessary. Makes a mundane field trip all that more interesting.
Comments(0) | Print | Home
I have been reading Mark Pilgrim's 30 days to a more accessible weblog. One article mentionned the much deprecated javascript: attribute. I discovered that I still had javascript: cruft in my index file used to open an "add comments" box. By changing to combinations of onclick() and href links my readers, who don't (or won't) have javascript, may still comment on the articles and humour published here.
Comments(0) | Print | Home
I took the the network interface card (NIC) out of the win98 box to replace the dead NIC in my FreeBSD box acting as router and firewall for my home LAN. Today my son dropped off a new PCI bus NIC. First problem, it seems the floppy drive in the old win98 box doesn't work. I had to burn a CD with the floppy contents so that win98 could read the NIC drivers. Second problem, the "brain dead" part: win98 insists on reading the Windows 98 CD to copy all the dll's, drivers and exe files associated with a network card. They are all there folks. The old network card was using them. All that needed replacing was the actual NIC driver itself. Anyway, after pressing "Skip File" millions of times, the win98 box rebooted and the NIC card is finally installed and working. What would have taken 10 or 15 minutes in FreeBSD took an hour or two. This box needs reformatting because each reboot can be on the order of minutes. Someday soon I'll upgrade it to win2k.
Comments(0) | Print | Home
FAQ: Why do I receive an error message in WIN2K that says my password
must be at least 18,770 characters?
contributed by John Savill, http://www.windows2000faq.com
A. This error occurs when you're running Windows 2000 Service Pack 1 (SP1) and you connect to an MIT realm and select Change Password from the Security dialog box (Ctrl+Alt+Del). (An MIT realm is a Kerberos realm used for authentication in the same way that Win2K uses Kerberos 5 for authentication.) The full error you'll receive is "Your password must be at least 18,770 characters and cannot repeat any of your previous 30,689 passwords. Please type a different password. Type a password that meets these requirements in both text boxes."
To correct this problem, contact Microsoft Product Support Services (PSS) and request an updated msgina.dll file (version 5.0.2195.3351 or later).
Comments(0) | Print | Home
I decided to install the latest ISC dhcp software from the FreeBSD ports so I can serve IP addresses automatically to PCs on my local network. The install worked fine but I ran into a problem with the script dhcpd.sh in /usr/local/etc/rc.d. dhcpd would start but then stop once the script exited. The actual program /usr/local/sbin/dhcpd would work when I started it manually. After some experimention I found the -q switch to dhcpd would tell the program not send messages to stdout. So I modified dhcpd.sh:
dhcpd_options="-q" # -q required or dhcpd terminates when stdout closes
# at end of script
dhcpd_ifaces="ed0" # internal network interface
Now my Windows boxes automatically get assigned an IP address.
Comments(0) | Print | Home
I upgraded my blog software from version 2.0 to 2.11. The only minor glitch I found was that I forgot to execute mt-upgrade21.cgi. My category labels had disappeared. After a quick check of the MT web site I found the problem. I later tried to use mod_perl to speed things up but I get an error after logging in which seems to be a bug. I reported this to the MT support forums and we'll see what happens.
I decided to look at using mod_perl again to make the blog editing / comments part run faster. Still got errors complaining about missing modules not found in @INC, perl's library path. Aha, I said. Why don't I symlink the MT library into one of the "standard" library paths. So far this seems to work.
Comments(0) | Print | Home
I have added a link to today's electricity market page of the Independent Electricity Market Operator for Ontario. A colleague and I at Kinectrics have written software to simulate the Ontario electrical energy market for Ontario Power Generation. We are hoping to get more money this year to make some improvements. The software will enable OPG to make predictions on their electricity dispatch methods so as to maximize profit (obviously) and optimize their generators' usage profiles.
Comments(0) | Print | Home
Slashdot
recently posted a link to Professor Knuth's lecture in Munich last October entitled
href="http://www.ams.org/notices/200203/fea-knuth.pdf">All Questions Answered
. Several interesting points (ahem, at least to me :-) struck me when I read that
article.
I think letting users know that you welcome reports of errors is one important technique that could be used in the software industry. I think Microsoft should say, “You’ll get a check from Bill Gates every time you find an error.”Would Mr. G. be a billionaire?
Question: What are the five most important problems in computer science?
Knuth: I don’t like this “top ten” business. It’s the bottom ten that I like. I think you’ve got to go for the little things, the stones that make up the wall.
An interesting read if you are a fan of the man. I still use TeX / LaTeX on occasion. It still does far better tables than MS Word, IMHO.
Comments(0) | Print | Home
An old 200MHz x86 box running FreeBSD acts as gateway and firewall for my
home network. Today’s note discusses the firewall configuration script for
ipfw. One
problem I used to experience is that if I used ssh to connect to my
home box from work and tweaked an ipfw rule and then decided
to execute my ipfw script in
# From Xsession script let's redirect output to a file. Note that
# rc.network should be changed to /bin/sh ${firewall_script} rather than
# . ${firewall_script} so that the direction only occurs here.
for errfile in "/var/log/rc.ipfw.err" "/etc/rc.ipfw.err"
do
if ( cp /dev/null "$errfile" 2> /dev/null )
then
chmod 640 "$errfile"
exec > "$errfile" 2>&1
break
fi
done
Usually I can add or modify an ipfw rule remotely, test it and then
change
/bin/sh /etc/rc.ipfw
Then a quick check of
Comments(0) | Print | Home
My home gateway and my file server at work are both
FreeBSD boxes. I was fixing a
DNS*
problem on the work box and came across the queries category for the
logging keyword when I was reading the
named.conf
man page.
I added
logging {
category queries { default_syslog; default_debug; };
category db { default_syslog; default_debug; };
};
Copyright © 2002-2006 James (Jim) R. R. Service (@gmail.com - jservice)