« April 2007 | Main | June 2007 »

May 31, 2007

A lot has happened in a year

It's a year ago to this day that we completed on the purchase of No. 48, Spa Road, Melksham which had been running for a number of years as "The Old Manor" B&B.

A lot has changed in a year!

We undertook a major upgrade and refurbishment in the first four months turning a tired but lovely old building in a high quality hotel for our delegates.

We had a "running in" period for the following four month, with our doors open to students attending our courses so that we could iron out any little glitches.

And for the past four months, we're been welcoming other business visitors to Melksham too ... many of who are already becoming regulars or recommending us to their colleagues and friends.

 
"The Old Manor", 2006 and Well House Manor, 2007 - Outside
 
 
"The Old Manor", 2006 and Well House Manor, 2007 - The Wilts training room
 
 
"The Old Manor", 2006 and Well House Manor, 2007 - Bedroom 5

A year on - from an empty property a year ago tonight, we have the majority of our rooms occupied. And rooms taken / booked right through next week. Guests newly checked have put their head around the door of the larger training / conference room room (the "Wilts") and said how much they like the rooms, and have given me a general idea of when they would like breakfast. I went through the various eating options in the town with them, and estimated how long their drive up to Devizes will take when they check out in the morning.

Well House Manor is open to guests staying in Melksham on business during the week, or visiting friends, familiy and touring Wiltshire at the weekend. All rooms are now en-suite with full business facilities including large work desks, flat screen TVs with 50 channels, and wired and wireless internet access. All this, and a continental breakfast is available at £80.00 per room (single occupancy) or £95.00 per room (double occupancy) per night. Booking number - 01225 709638.


Posted by gje at 06:37 PM | Comments (0)

More about Graham Ellis of Well House Consultants

May 30, 2007

PHP header() function - uses and new restrictions

PHP's header function allows you to change the headers on your returned content so that (examples)

• The browser receives not HTML but plain text, a .jpg image or a file to save locally
   example: header ('Content-type: Application/Octet-stream');

• You can change a "404" missing reponse code into a "200" - good.
   example: header("HTTP/1.1 200 OK");

• You can send out cache instructions
   example: header("cache-control: no-store");

• you can sent out a save file name if you're saving the file.
   example: header ('Content-Disposition: attachment; filename="hello.txt"');

However, up until PHP 4.4.2 / PHP 5.1.2 it was prone to injection attacks. If you used a variable within the parameter and your user could set that variable to include a new line character, he could add in any other header at all.

As from the releases above, you should send separate header directives if you want to set multiple headers as PHP has been altered to take care of the potential security issue and is not backwards compatible over this.

There's an example in our "database download to local CSV file" demonstration with required to set both a content-type and a content-disposition. Have a look at the source code in which I have commented out the old and replaced it by the new. The old was producing a message like:
Warning: Header may not contain more than a single header, new line detected. in C:\Domains[part of URL removed]testsite\phpcsv\phptocsv1.php on line 30

Note also with the header function - you may ONLY call it before your PHP script has sent out any content to the browser. This means that it must be in a block of PHP that comes at the very top of your script (no blank lines or spaces before the initial <?php please). See also the ob_start function which, however, I dislike.

Posted by gje at 05:27 AM | Comments (0)


Useful link: PHP training

May 29, 2007

Where did the Bank Holiday go?

Where did the Bank Holiday go? You'll have seen my comments about the model railway exhibition that was so good that I visited on 2 days; it must be 25 years since I was involved with any modelling and it was wonderful to see the sort of thing that's available these days and being done. A pleasure too to talk with enthusiasts, but I'm not tempted to get deeply involved in a hobby that I've not got the dexterity to do a good job, nor the time. "600 manhours" one exhibitor told me about a small part of his project, and others talked of a choice between the wife and the trains (from which, clearly, the trains had won). Instead, I'll plough a smaller number of hours into continuing with the 1:1 scale (full size!) train issues.

A wet Sunday morning saw me having a look around at the new Spencer's Gate development - with specific reference to the protected route / road to the railway stations. See here for pictures. That page needs maps / diagrams adding in!

Over the past year or so, we've added lots of course demonstrations here on our main web site so that people can try out our code, linking down from individual modules. The search engines have kindly indexed these pages which means, alas, that visitors sometimes arrive at a demonstration's output without links to tell them where to find out more. I've added a "wrapper" around the demonstrations now so that you'll be linked back to the source code and other similar examples - see (for example) our how different are two words? demo. And I've tidied up the demo index page too.

Further little changes include an update to the Melksham Resources Index, to the clock page and to the site search algorithm to give more weight to pages that include the search term in the title or page name.

Ah - having written this, I do feel that I've achieved something over the wet bank holiday ;-).

Posted by gje at 11:25 AM | Comments (0)

May 28, 2007

Meet other local businesses in Melksham



Update - 22nd June 2007 We're now fully booked for Thursday, 28th June, but will run another event in the Autumn (Tuesday 16th October 2007) for another group of up to 20 Melksham businesses. It won't be the same old faces each time either, as we'll only be taking a maximum of 5 "repeat" bookings, and (for events further in the future) no-one three times in sucession

Who? For Melksham (i.e. SN12) businesses
What? Speed Networking to meet other local businesses
Where? Well House Manor, 48 Spa Road, Melksham, SN12 7NY
When? Thursday, 28th June 2007 - arrive from 18:00 to 18:15

I still learn something every day ... and on a recent day I picked up "Who, What, Where, When" as the main headlines for publicising an event.

I'm also surprised every day by just how MUCH is available here in Melksham; we much prefer to work with local contacts and suppliers, and know that many other businesses feel the same way - and some don't know about us. "I searched on Google for a solution and your site was the second site i looked at, I was surprised when I saw you were based at Spa road!" says an email I have received with afternoon from someone in King Street who was searching the whole world wide web for a technical answer.

If you would like to meet other local businesses in Melksham for your mutual profitable benefit, please get in touch. This event isn't the first we've organised from here, but IS the first for just the Melksham area. I'm sure it won't be the last, mind you - if you come across this in the archives, please ask!.

Detail

A speed networking event to give YOUR Melksham based business a chance to meet other local businesses. 5 minutes with each of 19 other businesses lets you learn what's available locally and see
if you might be able to work together for your mutual advantage.

Then exchange contact details and that ALL you need to do on the evening - move on to the next business and follow up later.

For Melksham (SN12 - Melksham, Beanacre, Whitley, Atworth, Broughton Gifford, Seend and Sells Green)

Tea, coffee and soft drinks on arrival. Light buffet during the break. You'll be away by 21:00. 15 pounds per seat (20 pounds if you send two delegates seated together).

18:00 to 18:15 arrival
18:15 to 18:30 Introduction
18:30 to 19:30 9 x networks of 5 minutes + 1.5 min turnover
19:30 to 20:00 light buffet
20:00 to 21:00 9 x networks

Contact:

Christine Sivier, Events Co-ordinator, Well House Consultants.
email: christine@wellho.net
phone: 01225 709638

Posted by gje at 05:08 PM | Comments (0)

May 27, 2007

Simple but effective use of mod_rewrite (Apache httpd)

[Index under mod_rewrite tutorial]

Do you want a single 'intelligent' web page to provide the content for tens or hundreds of URLs so that you don't have to write each similar page individually? Do you want to set up your server so that it will take any requests for ".htm" files and turn them into ".html"s? Do you want to rename a page, but still leave the old name in place too for anyone who has bookmarked it or linked to it?

If you're using the Apache httpd web server (and 70% of domains do use it!), then mod_rewrite is the tool you need to implement these functions. But alas, mod_rewrite is so flexible it's hard to know where to start, even with the reference manual to hand!

How do I rename a page but leave the old name in place?

RewriteEngine On
RewriteRule ^oldplace/oldname\.html$ newplace/newname.html

This is an example from the top level directory (document root) .htaccess file, redirecting references to oldname.html in the oldplace directory to newname.html in the newplace directory.

* You can add as many rewrite rules like this as you like - no need to turn the engine on every time

* The path names you give should be relative to the directory in which the .htaccess file is located.

* The old name is a REGULAR EXPRESSION - the ^ and $ mean "starting with" and "ends with" and I've added them in this example to avoid any risk of matching a url that INCLUDES the text pattern. The \ in front of the . means "I really want a dot" as by default a dot matches any character at all.

How do I accept .htm extensions as well as .html?

RewriteEngine On
RewriteRule ^(.*)\.htm$ $1.html

Literally "Anything that ends in .html is to be replaced by the same thing ending in .html"

How do I point all the .html URLs in a directory at a single intelligent page?

RewriteEngine On
RewriteRule ^(.*)\.html$ action.php?pagename=$1&%{QUERY_STRING}

This forwards ANY URL with a .html extension in the current of lower directories to a page called action.php, with a parameter called "pagename" that will contain the name of the page called.

Many, many pages on our web site use code similar to this - our wiki is comprised of pages that are generated from a MySQL database by a single script every time, and even the image library isn't individual files - in that case, we have a rewrite rule that points .jpg requests at a script. What might appear to be 28 different style sheets are really just one ...

Where do I configure mod_rewrite?

1. You place any OVERALL settings in the Apache httpd configuration file httpd.conf (in the case of SuSE Linux, or other tailored configurations, you might place the settings in a file that's included from httpd.conf

2. Any changes / additions your want to set DIRECTORY BY DIRECTORY should be placed in a file called .htaccess in each individual directory. The settings you make will then apply to that directory and anything below it unless overridden in another .htaccess file.

Extra Notes?

If you have several rewrite rules that match, you may find that your URL is rewriten multiple times. If you add [L] onto the end of a rewrite rule, it means "Last" so that mod_rewrite will stop at that point and not try to make further changes to the current URL.

If you add [P] (or [L,P]) onto the end of a rewrite rule, you'll make the new URL a proxy request; this means that you can redirect to a URL on another server, which your server will call up by pretending to be a client (browser).

You can also specify rewrite conditions and much more - once you're familiair with the techniques listed above you should probably go on and learn the ins and outs of them from the manual which you'll find much more readable.

Notes for PHP Programmers

If you are writing a script that need to know its own name, and you call it via mod_rewrite, which variable name contains the original URL called for, and which the rewritten one?

$PHP_SELF is the rewritten name
$_SERVER[REDIRECT_URL] is the original name
$_SERVER[REQUEST_URI] is the original name WITH get parameters

Posted by gje at 05:48 PM | Comments (0)

Where and When - can you place the picture?

Do you recognise the location? Or perhaps the part of the country? Can you tell when this picture was taken - is it recent, or from many years ago?

The picture was taken yesterday - 26th May 2007. In Wiltshire too. Melksham. To be precise, at the Christie Miller sports centre on Bowerhill. It's a model - but a very realistic one - at a scale of 1:76.

In my youth, I used to enjoy railway modelling - and put a huge amount of time into it. Not that I was (or am) particularly good with my hands - I certainly don't have the ability, not the patience, to produce something of exhibition quality. But I fondly remember hours working on what might have been at Swanage and Lulworth, and what might have been at Ullapool. Studied down to the history of the proposals that were made for lines but that were never built.

Living now in "Great Western Territory" and having a fondness for Melksham, there's a temptation to get sucked in to doing *something* on Melksham. The substantial station of the mid 1900s shrank to closure in 1966, re-opening with a "halt" type platform in 1985 and a spluttering service since. So there's scope for anything from a substantial setup to a single track. But information is lacking and (at least for modern times) appropriate stock hard to find. I *am* going to say "watch this space". Not for anything huge, not for anything that's so realistic that you would have to do a double-take if you saw a picture. But I am tempted to set up a few yards of track, a model of the current station, and be able to run one or two representation trains - old and new, through it.

[More from TrainWest.]

Posted by gje at 10:21 AM | Comments (0)

May 26, 2007

Arrival and Departure experiences - another hotel

Running a hotel for our trainees (and other business customers) on one hand, and staying in hotels regularly while away on business on the other hand gives me a rare chance to see closely what goes on from both sides, in depth. And it's a great chance to learn for our own hotel - to take the best ideas and use them as appropriate on one hand, and to take the worst experiences and say "why did that happen" and make sure it doesn't happen to our customers.

Some notes from the last two nights, spent at the Holiday Inn at Histon, near Cambridge. And I'm going to highlight the arrival and departure experiences.

Arrival. After a LONG day, I didn't want to have to wait in line behind 20 tourists checking in, each of whom had their passports being photocopied. Yet their money is good income for the hotel too, who are left with something of a conundrum as to how to handle the situation. I'll simply record an "open verdict" on what should have been done, and note that it's a situation that will not occur with us, in consideration of our small size.

However ... when I get to the front of the line, my checking form is showing a room rate 19 pounds per night higher than the room rate I selected on line, and I'm asked to provide a credit card and enter my pin to authorise a figure 50% highere again. We get it sorted - apparently the room rate is 38 pounds more for the first night that the second but it's just the first night shown.

Part of the arrival experience is finding my way to the room and getting on line; I seemed to have the longest walk in the hotel (and poorly signed), and found I had a smoking room. Hmm - I know I had, as a late booking, only been able to express a preference for non, but a "sorry couldn't do" would have been nice from the checkin clerk. Online easily enough, but the 15 pounds a day just a few minutes after trying to push my room rate up by 20 made me feel that profit must come before customers here. The well laid out welcome tray, the thankfully large work desk, and the power points above the desk didn't completely clear the feeling, and the fact that I had to negotiate 4 buttons on my TV remote to find the free TV, when I could have been watching adult movies in just two click, confirmed my view.

Departure. "I think I should try their breakfast" I thought to myself on my last morning - advertised as a great way to start the day in my room but with no mention of price, I kinda guessed it might not be cheap. It was 13.75. Buffet, but excellent buffet; multiple citrus fruit, wide, wide range of traditional breakfast, and a note to ask for smoked haddock, kippers or porridge. Although we can't match in range, we DO match in quality and indeed we exceed. No real juice - no FRESH croissants and bread, and one of the precut grapefurit bowls was going slighly rancid. It re-iterated for me the ingredient QUALITY that we go for, and how important it is for it to be fresh.

I was dreading checkout - that long line of people patiently waiting to pay as I had come in for breakfast, so I was attacted by the "checkout over breakfast" offer on which I took the hotel up. My initial enquiry of the hostess as to whether I could re-access my room having checked out lead to an answer that I couldn't understand as she struggled with English, but in a few minutes one of the front of house team turned up with my bill, assured me I could get back in, and completed the procedure. Fast, painless, recommended. As they don't seem to have a hands-free credit card machine, my card had to be taken around the back and a chit to sign was produced.

I think we could do the same. For sure, if a guest asks for us to check them out while they're at breakfast we're already set up so that we could do so. Perhaps it's something we should make a bigger deal of?

Posted by gje at 07:38 AM | Comments (0)

May 25, 2007

Spot the difference

Two views of the river in Cambridge ... from almost the same spot, but do they tell different stories?



See more pictures of Cambridge where I have been these last few days

Posted by gje at 08:56 PM | Comments (0)

May 24, 2007

A Fresh horse

For all the hundreds and thousands of pictures that I've taken, there are many occasions that I think "I would like a picture of xxxx that illustrates yyyy" and find that I've not got one. I think it was my fifth entry on 'The Horse's Mouth' where I talked about looking for a picture of a donkey ...

I was looking for a picture of a horse last weekend - for the header page of the archive for this blog, and again found I had nothing appropriate. But staying in Cambridge last night, and out for a walk, I came across this longhaired old nag and, within a few minutes, I have the pictures I need. The Blog archive page is here

Whilst I was taking these pictures, my longhaired friend introduced some of his pals. And I found myself wondering which of these other horses could be used to represent which other members of our team ...

Posted by gje at 07:08 PM | Comments (0)

Returning multiple values from a function (Perl, PHP, Python)

Function in PHP and Python and subs in Perl can only return one "thing" - one item, one object. But all three languages allow that returned item to be a collection - in other words, a composite. And all three languages provide a very easy way of breaking the returned structure down into a series of individual variables.

Python Example returning a tuple

# Returning a tuple from a function
def doingit(v):
  a = v+10
  b= v*20
  c = 56/v
  return c,a,b; # returns a tuple
# function call will return a tuple (into z)
z = doingit(7)
# This syntax splits the tuple out into a
# series of individual variables (w, l and k)
w,l,k = doingit(7)
# Show that it has worked as expected
print w, l, k
print z

PHP Example returning into the list function

<?php
function maykit() {
  $rv = array("4","15");
  array_push($rv,"William");
  return $rv;
  }
list($fno,$sno,$name) = maykit();
print "We have $fno and $sno for $name\n";
?>

Perl Example Saving the returned values to a list

sub sistance {
  my @n;
  $n[0] = 4;
  $n[1] = 17;
  $n[2] = 23;
  return @n;
  }
($first,$second,$third) = sistance();
print "We have $first and $second and $third\n";

In each case, the techniques shown above should be used when you want to return multiple values in strong preference to global variables - your code will be much more modular and easy to maintain if you follow the approach shown.

Posted by gje at 06:39 PM | Comments (0)


Useful links: Python training, Perl training, PHP training

May 23, 2007

No switch in Python

Question There's no switch statement in Python. Why not?

(Poor) Answer Because there's no need .. you can use a series of if and elif statments. And we can't do it in Python because there isn't a label syntax that would be needed for case.

Better Answer If you come to write some code where a switch would be your natural choice in another language, then you would probably do far better to be using a set of polymorphic methods on various types of objects in Python.

What you might do without objects (a poor switch replacement):

if type == "local":
  name = "localhost"
elif type == "file":
  name = namevar
else:
  name = geturl()

What you would write with classes local, file and remote predefined:

name = current.getname()

Posted by gje at 06:09 PM | Comments (0)


Useful link: Python training

May 22, 2007

Training information - England, Scotland, Wales and Ireland

When you choose yor training with us, you have a choice between having us come to you (that's typically the best option for a large group), or coming to us for a private course (ideal for a handful of delegates) or for places on a public course (if you want to place just one of two delegates.

To provide illustrative examples of how the logistics and pricing work out, we've a series of pages for each country in the British Isles (and some further afield too) that give specific details ... newly updated, and with images to represent the county. But what image?

For courses in and delegates from England, we have a picture of the river Wye as it flows through Hereford.

For courses in and delegates from Ireland, I've chosen - at the moment - a picture or Trim Castle. We give a lot of training in Ireland, but haven't taken many recent pictures - I'm slightly unhappy with using a ruin as the "typical picture" and may change this in due course.

For courses in and delegates from Scotland, the choice is a picture of Oban. Truly beautiful as are so many placed in Scotland ... although my last 2 or 3 visits in the winter have been to short days with little chance to capture that beauty on film

And for courses in and delegates from Wales it's Caerphilly Castle - taken during a course I gave nearby last Autumn; a lovely evening's stroll into the own from my hotel on the outskirts

Posted by gje at 11:23 AM | Comments (0)

Testing for one of a list of values.

Question [PHP] When you have a string of conditions in an 'if' clause and one side of the conditional expression is the same in each condition, is there any shortcut to avoid writing out every expression in full. For examples, rather than writing
if(($name!='Lisa')&&($name!='Leah')&&($name!='Christine')) {
can I write
if($name!=('Lisa'||'Leah'||'Christine')) {

Answer The short answer is "no - you must write it all out if you're using the != operator". In Perl 6 (different language) you WILL have a shortened syntax for this sort of thing but that's highly unusual. But lets' take a wider look at other alternatives.

In php you could write
if (!ereg ('^(Lisa|Leah|Christine)$,$name)) { ....
although that would be slighly less efficient at run time.

I do worry about hardcoding data such as people's names into a program. When Lisa decides she now wants to be called by a different name, or when Chloe joins the team, you're back to the code! Your code would be more maintainable if you had an array of names in a separate file. You could compromise with something like:
$people = array("Hermione","Bob","Sally");
if (in_array($name,$people)) { ...

[i]Note[/i] - if you're reading your data into $name from a MySQL database, the INoperator used in a WHERE clause will allow you to filter your data before it ever reaches your PHP variables,

Posted by gje at 08:21 AM | Comments (0)

May 21, 2007

From Web to Web 2

"How do these technologies relate to Web 2?" asked one of my customers last week as we studied Apache httpd and Apache Tomcat. And of course that's followed up by the need to answer the question "What is Web 2".

Initial web sites - "Web 1" if you like - were discreet information sources provided by a web site owner, with connectivity to other resources made via the web site visitor's browser. In other words, each web site had:
* Information supplied by a single provider
* Isolated from other sites in terms of data provision
* Typically, a series of non-interactive pages.

Moving on to "Web 2", we have:
* Information supplied by multiple providers - blogs, forums, message boards, wikis, etc ("social software")
* Data provision across between sites - such as Google ads, RSS feeds and others
* Interactive and tailored pages to meet individual requirements.

The technologies are very much the established ones that are served by Apache httpd and Apache Tomcat anyway (and Web 2 means different things to different people!) so the answer to my initial questioner is really "You're already looking at Web 2". Well - you certainly are on our sites; not all of the web 2 technologies, of course; we have no incoming RSS feeds, Google Ads, SOAP or AJAX. But we do have social software, data provision from sites such as the European Central Bank, and interactive pages that will tailor the site to make it work better for what YOU require and for US to maintain.

Here are some old fashioned links: O'Reilly - the originators of the term "Web 2" and Wikipedia on Web 2. Oh - wait - even those aren't QUITE so old fashioned, are they? Wikipedia is very much Web 2 ;-)

Posted by gje at 12:18 PM | Comments (0)

Back off home with our best wishes

Tyler and Alyssa - [step]son and Daughter-in-law - left yesterday morning to return to Florida at the end of their honeymoon here. Theirs is such a whole different way of life and attitude. Here, they seemed rather like fish out of water. I felt frustrated in not giving them a magic time - on my terms, but perhaps it was on theirs. I wish them well, confirm that they're very similar people who seem well matched - and hope things work out well for them back in their home country.

Tyler and Alyssa pictured here with Lisa at Pewsey Wharf on Saturday - seeing a little of Wiltshire.

Posted by gje at 06:39 AM | Comments (0)

May 20, 2007

The last tree to leaf

Last summer and autumn, we had a great deal of tree work done at Well House Manor - catching up on years of neglect, clearing leylandia that had become a source of friction between the previous owner and her neighbours, and clearing the way for an improved entrance, driveway and parking. In the end, only one mature deciduous tree was lost - and that was a very old and mis-shapen specimen that would have only lasted another few years.

One of the other trees, close to the new driveway, would be fine (we were assured). However, this spring all other trees came into leaf and it remained bare. Look at the left of the picture above, taken early in May, and you'll see what I mean.

But I'm happy to report that in the last week or two, it's sprung back to life.

Another week, and we'll be celebrating a year of owning "Well House Manor". What a long way we have come in that time!

Posted by gje at 02:15 PM | Comments (0)

Regular Express Primer

Over the years I've been teaching people about Regular Expressions, I've learnt what does and doesn't work in such tuition. A casual question I saw yesterday got me writing, and I've just posted up a new technical article to the solution centre - see here (it will open in a separate window).

It's amazing - truly amazing - how often there's a code requirement to say "does this look like that" and that's exactly what regular expressions do. In fact, I added an extra markup facility to the solution centre as I was writing the article as I wanted an extra way to emphasise and - guess what - the methodolgy I used was a regular expression!

There are full tables of Regular Expression elements on our web site too - see here as a starter, and we even offer regular expression mousemats for sale at, of course, a very reasonable cost!

Posted by gje at 12:58 PM | Comments (0)

May 19, 2007

Drawing hands on a clock face - PHP

Would you like to draw clock face hands on to an image (such as the one shown here, with the time in UK when you called the page up!)? It's easier than you think using PHP's GD module.

Instead of supplying a fixed image in your <img> tag, provide the URL of a PHP script that reads an image and adds the hands - like I've done to the left here. I've even provided the source code - here so you can do something similar if you wish!

This very example is also used on our site clock which generates one image per minute ... and it will be a long time before we have all the images we need without using the PHP "cheat" I've introduced on this page.

Posted by gje at 12:04 PM | Comments (0)


Useful link: PHP training

Dangerous Dogs and Hotel Marketing

It's dangerous to make a law based on a single case, or even on just a couple of cases brought to attention in a very short time span. We saw this with the "Dangerous Dogs" act of 1991 which was a rushed piece of legislation and has come into some disrepute. In January 2007, it was still coming up as an unpopular piece of law in a public (radio) poll.

In a similar vein, making snap decisions to set company policy, or changing the web site based on individual inputs, is a risky business with a chance of dealing with one issue but, in the hurry, creating another. So my decision on Friday morning to add pricing information for courses with hotel accommodation included in addition to the prices without overnight accommodation was not totally made in response to a delegate saying "I wish I had known you had rooms here" as he grumbled about a leaky room in a hotel just up the road that cost him twice what he would have paid us ... no, it was a much more considered decision that it might have appeared based on not one but a small handful of incidents, and a growing comfort that our accommodation product is quite exceptional.

Weighting against the change is the desire not to be too pushy - not to oversell, and also the fact that we need to allow some of our big corporate customers to book course and hotel under separate cover, even though it may cost them more and may result in their delegates NOT staying with everyone else on the course (a disadvantage, this, in terms of them loosing a great deal of the benefits of peer interaction out of course hours). And also against the change is the need for us to be ultra-clear on VAT since training courses are normally quoted without, and hotels with.

Have a look at one of our course descriptions now updated ... and you'll see how we've introduced the options as clearly as possible. I hope we'll have cut the small handful of incidents - and I do hope to have made Lisa's job of seeing whether or not delegates will be staying with us that much easier.

Posted by gje at 11:31 AM | Comments (0)

May 18, 2007

What are WEB-INF and META-INF directories?

If you're looking at a web application on your Tomcat server you'll see all the files that you would expect - things like an index.html (or perhaps an index.jsp), images, and perhaps style sheets, a robots.txt and a favicon.ico. You'll also see a WEB-INF directory, and perhaps a META-INF directory that are unbrowsable. What are they?

The META-INF directories related to .jar files ... they contain the manifest (list of contents) of a jar and are created when you write a jar file. Then when you unpack it, the directory appears. Web applications, held in .war files, are just special cases of .jars. You should (in theory) be able to safely delete your META-INF directory and content from an installed web application.

The WEB-INF directory contains a heirarcy in which you'll find the necessary configuration information for your web application, and all the class files for your servlets and classes that are called up by your JSPs (Java Server Pages). The WEB-INF directory is a vital component of your web application, which will not run without it!

Posted by gje at 05:24 PM | Comments (0)

Smart English Output - via PHP and Perl ? : operator

It's smart to have your program say "there IS in stock" or "there ARE 2 in stock" ... but if you write your code using an "if" and "else" type structure it can become quite verbose.

The ? ... : operator - available in many languages including C, Perl and PHP - allows you to write a single "if,else" line in a much shorter form:

{condition} ? {value if true} : {value if false}

Here's an subtle example of this operator in use - an image from our pricing for a two day public course:

where you'll note "room" and "rooms". The code, where $ns is a variable containing the number of students:

$rlet = ($ns==1) ? "":"s";
$pricing[$ns] .= "<b>With hotel room$rlet<b><br>";

Posted by gje at 08:25 AM | Comments (0)


Useful links: Perl training, PHP training

May 17, 2007

Save the Forum - A regular clean sweep

With many visitors and a great deal of exposure, our Save The Train web site gets the attention of unwelcome content providers - people who will come on to our forum or blog and post articles and comments that are way off topic. Why do they do it? Primarily to sell their pharmaceutical products, loans, betting schemes to the search engines - to get themselves ranking on our good name and popularity. Unfortunately, such posts also dilute our content, lower our ranking and at times shock and offend some of our readers. How to "solve" the problem [on the forum]?

We COULD go for a manually authorised signup procedure and (at the levels we're looking at) the three moderators of the forum could cope with this. But it adds an extra hurdle into the loop for newcomers and it's likely to put them off having to wait, perhaps a few hours, before they can make their first post.

We COULD use a captcha scheme where the new arrival has to retype a series of letters - great against the "autobots" but more and more of these signups are made by paid workers in low-wage parts of the world - kids there doing it for minimal pocket money.

We COULD add a filter in to refuse messages as they're posted which match a pattern that we want to reject - but the posters would know straight away that their payload had not been placed, and would be flagged to look for alternatives.

So what's the solution? There's no "100% solution" that I know of, but I have implemented a "clean sweep" systems that goes around the boards from time to time, deleting posts which conform to certain criteria. It's run automatically under "crontab" so there no need for any interaction of my / our administrator's part. It's been tuned to err on the side of saftey - in other words, any genuine newcomer is highly unlikely to have his / her first post killed. And it means that our board-spammers leave thinking that they have successfully delivered their payload.

If anyone would like to use the algorithm on their own board ... here's my SQL that finds the rogue posts. It would, mind you, need individual tuning.
select id_msg, smf_messages.id_member, posts, totalTimeLoggedIn, membername from smf_messages left join smf_members on smf_messages.id_member = smf_members.id_member where posts < 2 and (body like "%[url%[url%" or body like "%href%href%" ) and body not like "%train%" and body not like "%wilts%" and body not like "%station%" and body not like "%swindon%" and id_msg > 5000 order by id_msg

Disadvantages?
* A few spam messages make it through and still need manual deletes
* Users will see occasional recent spams before they are deleted
* The "latest post" for each board isn't recalculated; a good clue to us "in the know" that we have trapped a spam post, but perhaps a "bug" to users
* Rare chance of deleting a genuine post.

Posted by gje at 11:37 PM | Comments (1)

May 16, 2007

Meet, greet and welcome

Picture ... Lisa waits at Heathrow to greet son Tyler, yesterday morning. Tyler has lived (contrary to our desire) with his natural father in Florida for these past years, and we have seen him for holidays and high days - always too short a time to spend together, always too few visits always too little time to enjoy, and certainly far from enough time to impart enough experiences of life and education.

A few months back, Tyler announced he was getting married (at 18) to a young lady that we knew only a very little of and had never met. He gave her a good sales pitch, and had demonstrated that this wasn't a quick fling running up substantial phone bills (for us to pay) back to her (more than his flight cost!) the Christmas before last.

The wedding was Sunday. And on Monday, Tyler and Alyssa left Miami for a week's honeymoon and meet-the-family trip to the UK ... thus Lisa pictured at the airport on Tuesday morning.

You can imagine the nerves, the trepidation, the natural concern. And I can imagine too that Alyssa would be somewhat nervous about what SHE was walking in to at Heathrow.

But I have to say, she's a really nice girl. We all get on well, had a fun day (straight to Alton Towers - that's another story) and perhaps she really is the right one for him and perhaps they are fortunate to have found each other so early.

I took the opportunity, waiting in line for a rollercoaster, to ask a few questions of Alyssa about herself that were pushy beyond my usual bounds. And, no, I'm not going to tell the world the answers. But I did find ... some similarities, some surprisingly identical answers to those that Lisa would have given.

It's also to see the couple together and arm in arm and clearly very much a couple. They'll have some struggles and tough times - they've not got an easy work and support system in Florida and they perhaps need to get some qualifications. But I do wish them all the very best, offer them our family support and hope they have many, many happy years together.

Posted by gje at 08:13 AM | Comments (0)

May 15, 2007

What shape is your shake?

Modern digital technology allows some quite amazing dark-scene photography ... but even these days there are still limits. Alton Towers, earlier today ... see the shape of my camera shake. As you'll see from the picture, I made three attempts and this is the best of the 3 ....

Two other pictures taken inside at the Towers:

Posted by gje at 11:00 PM | Comments (0)

May 14, 2007

Updating a page strictly every minute (PHP, Perl)

For the Clock exercise that I mentioned in my last entry, I need to update the page once a minute. Exactly once a minute. At the start of the minute.

I'm using client pull, where the browser asks for the next page - so my basic request is:
<meta http-equiv="refresh" content="60; url=/clock/now.php">
but that will neither refresh at the start of the minute, nor be exact - with update times and delays taken into account, a handful of times in each hour will be missed out (I know this - I tried it) as the 60 seconds starts from the time the new page is received, not from the previous page.

So I have adjusted the time as follows:
$togo = 61 - date("s");
if ($togo < 15) $togo = 15;

to calculate how long before we trigger - it's going to trigger 1 second into the next minute, and will be selfcorrecting to allow for page transmission times. The business with the "15" is to ensure that initial pages display for at least 15 seconds, even if - by rights - they should be refreshed quicker. That will help avoid an irritating refresh. And the client pull instruction becomes:
<meta http-equiv="refresh" content="<?= $togo ?>; url=/clock/now.php">

The example above is "Client Pull". There's also a complete "Server Push" example, written in Perl, using the same algorithm available for you here

Posted by gje at 02:11 PM | Comments (0)


Useful links: Perl training, PHP training

Two new pages / sites

There's a lot of interesting clocks and other timepieces around and I've started to gather a few up. Well - one thing leads to another and we're got an embryonic clock page together - showing the UK time at the moment, and where we have them an appropriate picture of a timepiece. See the current time (in a new window).. At the moment you'll get all sorts of different holding pictures when we have nothing specific available but in time, no doubt, you'll start seeing the fillers only rarely.

Another new web site is that of the Melksham Railway Development Group; it's been a while coming, but they've now registered their domain and I've put up a first holding page for them.

Posted by gje at 01:13 PM | Comments (0)

May 13, 2007

Themes for the web site

This is one of the pictures that I've used to illustrate the various themes on the new-look website. It's quite an easy one, I'm sure, for you to associate with area of our site, but some of the others are much more obscure.

A somewhat less obvious picture, this one! It's a steam engine in action on the "Waverly" running between Oban and Iona off the West Coast of Scotland. and - somehow - it's been associated with one of the subjects that we teach.

If you want to find out about all the themes, there's a page of excuses and lame justifications here.

Posted by gje at 02:12 PM | Comments (0)

Finding resources - some pointers

We have resources - huge resources - available on this site, and regular readers will know I've been updating much of the navigation over the past week or three. Just updates ... our resource indexes for individual topics ... here are some starters: The Well House Manor project, general non-technical items and Welll House Consultants resources.

For technical readers, topics are indexes technology by technology - Linux / LAMP / Web Servers, PHP, Python, Tcl, Perl, MySQL, the Web, C anc C++, Ruby and topics on several technologies.

Posted by gje at 11:31 AM | Comments (0)

May 11, 2007

Improving searches - from OR to AND?

There's a search box on the top of all our regular pages - put a word in there, submit the form, and you'll be offered a selection of appropriate pages ... and if there's nothing relevant, you'll be offered nearby spellings. Try a search for Ireland and a search for Irelond.

Search for multiple words, and our search box (until 30 minutes ago) would find you the top pages for each of those two words. Word xxxx OR word yyyy. But that's been becoming less than ideal. As our site grows, users who call for multiple words no longer want to be presented with the top pages for each of them - they want priority to be given to pages that match word xxxx AND word yyyy. The new algorithm is in - try deleting cookie or python printf.

But our server has already forgotten the instructions it had until 30 minutes ago, so now it'll work rather better (far from perfect - search algorithms are a law unto themselves) if you try any of the suggestions in this item ... or your own:

Search for:

Posted by gje at 08:30 AM | Comments (0)

May 10, 2007

Painting a masterpiece in PHP

In PHP, you can write a program that looks like a Rembrandt, or one that makes the dog's dinner look tidy. It's not only the mechanism of the language you need to learn to do a good job, but how to apply it.

This week, on my public PHP course, I have a group which is very IT professional in background, and very much concerned with writing good code efficiently, with easy maintainabiliy, enhancability, and element re-use across projects. So rather that use my mores standard "here is a program to ...", I've been writing new examples with a different twist as I go.

It's easy enough to code a box on a form to echo back what was on the previous form. But remember the user may enter all sorts of special characters that you need to deal with. And remember you need to do this multiple times. And remember that you need to be able to re-present the same form if the fields aren't correctly filled. And remember you would like to reuse near-identical logic on the next page. You're looking for nicely structured code - the Rembrandt not the dinner!
• Make good use of functions.
• Have common error handling logic.
• Put everything that varies into a single specification.
• Save the common code into an include file.
• Use good error messages.


I've put the example I finished with last night up on line - the source code is here and you can run it here. There ARE things still to be done ... - the error messages are common at the moment, and it's all in one file rather than using an include (a good way to do it for initial testing, after all!)

Posted by gje at 07:46 AM | Comments (0)


Useful link: PHP training

May 09, 2007

Good Programming practise - where to initialise variables

It's a good idea to initialise your variables directly before you use them for the first time if you're going to use them as accumulators.

By accumulator I mean that you're going to write assignments such as:
  $n += 4; # Perl
  incr notepad; # Tcl
  lappend flcodes [lindex $line 0] ; # Another Tcl example
  $html .= $nextline; # PHP
  sofar = sofar + thistime; # Ruby
  zed += ecs; // C++
  ping = ping + "pong"; /* Java */
  build = build + house(); # Python

which take the current value of a variable, modify it based on some other input, and resave it to the same location.

In Perl, fail to initialise a variable and it will be assumed to be empty (normally a good assumption) and the same applies in PHP - except that in older versions of PHP (Prior to 4.1) or if REGISTER GLOBALS is set, it will be filled from any incoming form if it has the same name as a form element. These are usually benign behaviours, so why the advise in this article??

You SHOULD always initialise (initialize) accumulator variables in PHP in case they're used with REGISTER GLOBALS on, as failure to do so renders you open to an injection attack by knowledgabe users. And you'll see a great deal of code that initialises some (or all) variables at the start. I'm going one step further - I'm advocating proximity initialisation

Scenario. You write a piece of code that analyses a directory. Or the contents of a file. Or loops through an array. You test it, and it works well. In fact, it works so well that you put it into a loop to analyse a whole series of directories / files / arrays and it falls over. Why? It could be because an accumulator variable hadn't been reset within the newly added loop.

By adopting proximity initialisation as your coding standard, you can laregly prevent debris rollover from a previous iteration of your newly added loop - although you do need to careful of things like static variables in functions (PHP) too.

Footnote: In Java, Tcl (in most cases, but not with the append and lappend commands, and in Python the language will itself insist on variable initialisation although it won't force you into proximity inialisation. In C and C++, an uninitialised varaible's value often cannot be guaranteed, and many interesting intermittent bugs that take an age to be fixed have been caused by this feature.

Posted by gje at 07:19 AM | Comments (0)

May 08, 2007

Conjugation

"I am, you are, he is ...". The conjugation of verbs is something which I remember from Latin and French classes at school with, it must be said, a degree of distaste. I never was one for languages.

"I am amply proportioned, you are well built, he is fat ...". A number of jests have been made over the years concerning conjugation and the different views we take of ourself, the person we are talking to and third parties. And many a true work is spoken in jest.

"I care, you care, they care ...". Such similarity. I care that we produce an excellent product - strive for perfection, but appreciate that (TQM style - another topic) fitness for purpose is the initial goal. And that means thet the "you" our customer care too. We've put a great deal of effort into providing rooms that are out of the ordinary, and we're rewarded by our customers showing a similar care for the rooms - they're rarely left "trashed" and more often than not they're tidied! "They care"? Our staff - both permanent and casual / emergency - care too. They'lll do their darnest to help you, our customer and us. To care, a regular verb. To be celebrated in that it means that naturally everyone cares together and the whole thing works. I, for one, much appreciate it even though I may not show it at busy times like the last few weeks!

Posted by gje at 03:13 PM | Comments (0)

May 07, 2007

Sizing sheets and other domestic issues

There's a great deal to be said for mucking in with all the jobs done within the company from time to time, and today Lisa and I have been turning bedrooms around - the wedding group gone, and two checkins tonight with three more arriving tomorrow - a full hotel again. Good to see how the rooms are standing up to the use they're getting, to spot the odd snags that need fixing, and some of the things that could be done to make the job so much easier.

Multiple choice question - how do you tell a clean King sheet from a clean super King sheet?

Possible answers:

1. From the pile on which it was stored

2. By a coloured spot or mark on the corner

3. By the stitching

4. By weighing it

5. By unfolding it to see if it fits ... changing 5 rooms and with the right amount of linen, chances are you'll have roughly what you need.

Answer (1) should be good ... except for Lisa who gets piles of clean sheets back from "flat out ironing". (2) and (3) don't work, and I was finding (5) more that a little frustrating.

A superking sheet weights 750 grams
A King sheet weights 590 grams
A singe sheet weights 450 grams
when returned neat and folded from cleaning (there might be slight differences due to a change in humidity, but there's plenty of margin for such fluctuations to be ignored). A new use, today, for the postal scales ... we should probably get something more specific for general use.

Posted by gje at 06:59 PM | Comments (0)

May 06, 2007

Ducking stool for Melksham?

There are times that there's a clash between the look and feel of a web site, and the need for functionallity - for it to operate correcly in all circumstances. Of course, both are key elements - a web site must work correctly for it to be useful, and it must attract and retain the visitor, and help the visitor through the various steps.

My wife Lisa is our "look and feel" guru. I'm the one who does the programming and gets the thing to operate and - perhaps you can imagine - there are times that we take a different view or approach to what is (or turns out to be,inthe end) the same desire. There are times when I feel (and I know Lisa does too) that a ducking stool in Melksham could be a useful threat ... but then I have to admit (after another day of working on web pages) thatsome of them are looking very much better and we end up sharing a late nite pizza and watching the tail end of the snooker.

(Picture - Christchurch, Dorset)

Posted by gje at 11:33 PM | Comments (0)

May 05, 2007

Sorting out for a site map

It's only when someone says "let's add a site map" that you realise justy how much old "stuff" there is to exclude, and how many different automated directories you have on a web site - or rather that's what I have found ... so it's been a long day "knife and fork"ing though directories and databases! You'll find enough done for me to have activates the new "Site Map" link on our newly updated paged - you might like to try out the image page and the horse's mouth archive page to see what's been going on.

Come to think of it ... I did do a few other things today. We had wedding guests overnight last night - the wedding was yesterday, they arrived at lunchtime, changed, and headed off to the ceremony in the afternoon. And they were down for quite a late breakfast this morning (of course, I didn't know their timing so was there early. Actually, it turned out that one of the couples was the bride and groom ... I wish I had known to at least arrange a card, but there had been a loss of communication somewhere and I understood the opposite. Lovely couple. We wish them all the best.

I also took a break after the party had left to go to the Melksham Spring festival - a walk up there and, a lovely afternoon, so a walk back too via Conigre Mead Nature Reserve and the cemetary. I'm still discovering some lovely spots in the town - the picture that illustrates this paragraph is Melksham,and there are more pictures in the same vicinity here. And on my way back in, I grabbed a picture of The West End - really the "local" for Well House Manor.

I wonder what tomorrow will bring - only 90 minutes to wait and see!

Posted by gje at 10:31 PM | Comments (0)

May 04, 2007

A pu that got me into trouble

If you're a regular visitor to the Well House Consultants web site, you may have noticed subtle changes over the last couple of days; the "Version 7" web site that we introduced at the new year wasn't up to the standard we had hoped and rather than making incremental changes, I've swept new profiles through in the background. Actually, it's been a good proof of the techniques we use that I've been able to do so much, and so fast.

I've also have a good proof / confirmation that I should take frequent backups while I work. In a tired moment yesterday evening, a put when I should have done a get during an FTP transfer meant that I overwrote my Version 8 pivotal templates with the old Version 7 ones that I'm working so hard to replace.

Anyway - an hour or two of reworking had me up and running again (and, yes, I HAVE backups this time) and the site's there for you to enjoy. Printing is improved. Navigation is improved. Resizing the window is much improved. And it looks good too. Odd "holes" cropping up - with the freedom for the width to vary, some pages that looked great narrow look less great when wide ... but I'm sure I'll get to most of those and fix them as I spot them.

Posted by gje at 04:23 PM | Comments (1)

May 03, 2007

Local elections - choosing who to vote for

It's election morning - we're voting for Parish Councillors (for Melksham Without Parish Council) where we can choose up to 10 of 11, and for West Wilts District Council where we can vote for 3 out of 10.

For perhaps the first time, I feel that I really know a number of the candidates - that I can make a decision based on some knowledge of how they operate, rather than on party ticket and on how their pictures look. Some of them promise help and come through very well with that, others profess to that help but them seem to go no further than that - though at times it's hard to know if they're doing anything in the background.

At District Council Level the question of "Party Ticket" is an interesting one; should I ignore or strongly consider the actions of parties in power at national or county level when I vote for their local candidates? Or is it useful to have an elected member from the same party that's in power as that gives us a politician with an extra lever via the party machine that has certainly opened a few doors in recent years? Even if I disagree with many of the policies? Should I consider national and county policies of parties that are NOT in power at that level? Should I (answer - NO) use my votes to express my view on Iraq and party support for it?

We have a number of good candidates for the District Council and I am - I think - decided on 2 out of my 3 votes. There are a number of good candidates for my "third" ... so there are bound to be a number of candidates who I would like to be in a District position who won't be. I wish them all personally "Good Luck" and admire them for taking on a role and responsibilities that I would not want (indeed, I refused an approach which would have placed me on the list) and I look forward to working with them for the ongoing future of West Wiltshire.

The Parish Council where we vote for up to 10 candidates out of 11 seems - with those figures - to be akin to a vote AGAINST one individual. With such a large voting area - it's the majority of Melksham Without in a single ward - the idea of local voting for the representative for "your street" seems to have gone out of the window. I'm somewhat in favour of proportional Represenentation and multi-member wards but the 3-member district is good and the 10-member parish is at least 5 members too far. The (very) local guy will, for sure, be one I support. The jury's out on the one who used his position (and parish council letterhead) to pontificate about public services in South Devon - a well intentioned loose canon that, regretably, caused a major "Friendly fire" incident.

And the whole business of Melksham being split into two parishes disenfranchised 6000 of the population (those of us in Melksham Without) from Town decisions. It's perhaps an illogical grouping of areas. We know that major changes are coming up in local government in the next few years with removal of one tier, so these will possibly be the last elections at District or Parish level. We might end up with a County Council (the level we're not voting for today), then a Community Council, to include ALL of Melksham and the surrounding area for which it's "Home Town". If Done right, that could be sensible, But what a big IF.

Posted by gje at 04:36 AM | Comments (0)

May 02, 2007

Installing Tcl and Expect on Solaris 10 - a checklist

Hot off the presses from the last couple of days - a check list (and a couple of "Gotcha" notes) concerning the installation of Tcl and Expect on a Solaris 10 system, compiling from scratch were possible.

You'll need a C Compiler

We used gcc (the Gnu C compiler) and we installed it from Sun standard packages - you can't compile the C compiler yourself, of course, in the first instance as you need a working compiler to do it ...

The following three packages are needed:

SUNWgccruntime
SUNWgcc
SUNWbinutilities

For the following operations:

a) add /usr/sfw/bin, /usr/local/bin and /usr/ccs/bin to your path, and export
b) set the CC environment variable to the value gcc and export it.

Installing Tcl

1. From a .tar.gz download ... ungzip and untar, cd to the directory created and the unix subdirectory therein.

2. Run ./configure which works out HOW the build should be done

3. Run make which does the build in the work directory

4. Run make test to check that the build worked

(at this point you need to become root, and get back to the same directory)

5. Run make install to install the Tcl program in place (you'll find it as /usr/local/bin/tclsh8.4

(at this point revert to ordinary user

Installing Expect

1. From a .tar.gz download ... unzip, unta, cd to the directory created.

2. Run ./configure --with-tcl=/xxx/yyy/tclzzz/unix - that path is tha path to the copy level of the Tcl build wherever you put that - the directory that contains the Tcl Configuration file.

3. Run make expect which does the build of expect in the work directory

(at this point you need to become root, and get back to the same directory)

4. Run make install to install the expect program in place (you'll find it as /usr/local/bin/expect

(at this point revert to ordinary user

Notes

1. If the make test reports network / socket errors and you're not properly network connected, that's not a problem.

2. Our sample build did NOT include the Tk GUI toolkit. Warnings generated during the build of Expect telling us it could not build expectk could be ignored.

3. If you get error messages from /usr/ccs/bin/as they you haven't installed the SUNWbinutilities properly, or your PATH is in the wrong order.

4. If you're using Tcl version 8.5a6 and you get fatal error messages about TCL_REG_BOSONLY build, you have a version of Expect that's not compatible directly with that Tcl, in which various elements were moved around include files. Best solution (as I write) is to step back 1 level with the Tcl.

5. My sample notes used Tcl 8.4.14 and Expect 5.42 on a "recent" Solaris 10 (built No. 0106).

6. Installs are all to default /usr/local/bin directory. Options at ./configure time allow you to change this.

Posted by gje at 03:36 PM | Comments (0)


Useful link: Tcl training

Cheat Sheet / Check list for Expect maintainers

Programming in Expect can be very different (and more challenging) than conventional programming. Rather than write code (structured, if you like) through a series of events, you'll do better to start off with a co-operation diagram of the process that you want to automate [[For the newcomer, Expect is a language / system that lets you automate the running of command line based programs that require user interaction, with Expect acting rather like a puppeteer in pulling the strings and watching the responses ofthe target program.]]

As you'll want to store, analyse and make decisions based on the outputs from your manipulation of the target program, Expect is usually built in top of the Tcl language which provides a rich array of facilities ... and the three most fundamental additional commands are:

spawn to start a controlled process
send to send text to that controlled process
expect to wait for a response from that controlled process.

There are many other commands available too - and each of the three I mentioned has an interesting array of options associated with it.

The question arose yesterday - "What do I need to know to look at / debug / maintain Expect scripts that have been written by others and I maintain / what are the common issues and pitfalls". Now THERE is an interesting question to help me clear my mind. What did I come up with?

1. Know the fundamentals of Tcl - that it's a command based language and what thet implies, and understand the difference between "...", (...), [....] and {....}. Know when to use a $ character in front of a variable name, and when NOT to.

2. Understand the significance of spaces, new lines and blocking with { and }.

Then for debug / specifics on Expect:

a) be aware of the "--" option on many commands (the option to end all other options) - what it is and what it means.

b) be aware of different line teminators \r and \n for carriage return and new line / line feed.

c) remember that you much "expect" to receive an echo of what you send

d) When expecting a glob or regular expression, look for a clear end value and try to avoid wild cards on the end - they are a recipe for complexity as you don't know where your inputs will get trimmed at each expect

e) Beware cardinal values. Someone is going to have computers called "ping" and "pong" and if you're automating ping that could give some issues.

f) Remember to wait for trailing spaces on prompts if they're issued by the program you're automating

g) If the program that you're automating is upgraded, you MUST retest your expect script and you can "expect" it to need updating if the user interface has changed AT ALL. One change from a lower case to a capital letter in a prompt might be all that it takes.

h) You may need to wait on turn-around for some programs (expect can send very quickly once it recieves a trigger - far faster than a human user), and you have "-s" and "-h" - slow and human - optiond for the send command if you need them.

i) If your program stutters (goes one protocol exchange every 10 seconds), it's probably got out of sync and the expected strings are not being received - so it's timing out.

j) Remember the log_user command which lets you add a debugging trace onto the screen (other options too)

k) You can control multiple spawned processes if you manage the spawn_id, and you can wait on multiple processes using the -i option to expect.

And finally, buy a hard hat to protet yourself against brickbats that I EXPECT your colleagues will throw at you when they hear all the dreadful puns you unintentially drop.

We run Tcl courses that include Expect - there's a public course several times a year, and private courses can be arranged too. In practise, the Expect element is either vital (to around 30% of delegates) or of little interest (around 70%) and we tailor the courses as need be for the particular groups, running extra sessions on the public courses as appropriate. We're also happy (please email) to provide help / assistance / support / consultancy days on Expect.

Posted by gje at 07:46 AM | Comments (0)

May day 2007 in pictures

Yesterday - May Day 2007 - was one of those long days which generated so much to say - techical and otherwise - that I don't know where to start (and so, it seems, I'm making the problem worse by going on about it). Early morning at "404" and "The Manor" getting ready for the day .... a day's consultancy work helping to install Tcl and Expect on a Solaris 10 system in Bournemouth (we don't "just" train - we keep our hand in too!), and an evening where I felt so enclosed from offices and computers that I wanted to get our and walk ... and it's lovely here in Christchurch.


The area is beautiful - rivers running down to the sea, old streets and ruins that have moved from "eyesore" to "historic", and a warm, plamy climate.


From young to old, everyone out enjoying themselves.

Many, many more pictures ... I'm (ah!) not quite sure how best to use them - but it you've a couple of minutes you might like to see some of the best here.

Posted by gje at 06:56 AM | Comments (1)

May 01, 2007

Traffic light control for horses

Pedestrian lights are very common, and you'll find quite a few cycle lights around. But have you even come across lights specifically for horses to cross the road?

The control panel, situated high up (at horse - or rather rider - level) carefully explains that red means "stop" and green means "go". interestingly, red and green aren't the ideal choice of colours due to around 8% of the male population being red-green colour blind, and indeed WHITE was the 'stop' colour in the very early days of the railways. "Not such a big problem as you might have thought -the countryside was very dark in those days" said a book I read many years ago. Does anyone know what proportions of horses are colour blind?

Posted by gje at 05:50 AM | Comments (0)

Smoking, or no? The law insists we spell out the obvious

We're a non-smoking hotel, and our headquarters / second training centre is non smoking too. There's never been any change in that status, there's never been an issue with people who don't realise, and there's only been one occasion that I'm aware of that guests have smoked in their rooms.

And we don't have any no-smoking signs up - not even discreet ones. No need. A lack of ash trays, a sweet smell, computer equipment all around, and light carperts and deor that's not tar-stained give the direction and lead. So why is the "Nanny State" insisting, under penalty of large fines, that we MUST display no smoking signs at the entrance after 1st July - the date after which smoking is banned in all such public places as ours with minimal exceptions?

We WILL put up those signs to conform to the law. But, frankly, we don't expect they will change our staff or guests attitude / behaviour in any way what so ever; if they can (and do) obey a smoking ban that we impose, why on earth would they even think of flouting it once it gets the weight of law behind it, and why on earth do they need extra reminders?

Posted by gje at 05:33 AM | Comments (0)