« December 2007 | Main | February 2008 »

January 31, 2008

Just one thing let the service down - but that is my memory

A good, lively bustling breakfast room at the Premier Inn in Nottingham this morning. I admire Duncan's introduction and interaction with customers - noting that he took special care to go back and look after a gentleman who was on his known, clearly new to the culture, and could (and did) benefit from an extra little bit of TLC. The croissants were fresh, there was plenty of coffee on tap, and a kitchen order was taken well - not smartly, but in reasonable time.

And I waited.

Breakfasts came out and staff appeared comfortably busy but, looking around, a lot of unserved tables. Emma came around to clear some plates, and - unusually for me - I asked if breakfast would be with me soon; she scurried off into the kitchen and came back to say that they cook it fresh, and I was now top of the stack. When I inquired if it generally took as long, she admitted that had a rush at in the kitchen, and one one chef instead of the two booked.

Top of the stack I may have been, but several other brekkies came out before mine, eventually, appeared while I hot steadily more antsy, and when I did get it, I felt cheated that I really didn't have the proper time to enjoy it.

Time can be of the essence in the morning, and the best of service and the best of intents ruined by just one slip up such as this timing. And I wasn't being awkward - I had a train to catch, and phoning up the station and asking them to hold the train for me was NOT an option.

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

More about Graham Ellis of Well House Consultants

January 30, 2008

Nottingham - just text!

I'm in Nottingham - giving a Tcl course - for a few days. No pictures yet - sorry. Firstly, I arrived at the venue in a rush (that's another term for a car that has got seriously held up in the traffic) and left in the dark. Secondly, I left the vital cable to link camera to computer beside the bed at home (why, oh why, are there so many different cable standards?). Which will probably have you wondering why on earth the cable was in the bedroom, so perhaps I had better not go on about it ;-).

At Well House Manor, we encourage our guests who use the dining room when they bring in their own food, and there's no-one else around, to clear their plates onto the tray rack. No notices to the effect, but we find that people do it naturally anyway. There is indeed much more of a "clear yourself" culture these days than there ever was in my youth - the American chains such as McD and KFC seem to have brought in the practice.

There are two signs in the training room I'm in. Please leave this room in the state you expect to find it says one, and Please leave this facility in the state you would wish to find it says the other. Tiny difference of words, but for anyone who hasn't got any faith in the tidying ability of other users of the room ... the most enormous difference in meaning!

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

January 29, 2008

Ive just received an email from myself. Should I be worried?

A friend writes ...

Dear Graham, I have just received an e-mail claiming to be from my own address with the above title. Should I be concerned?

Short answer - no, you shouldn't be concerned. But this does occur from time to time, and I know that it does concern people, so it's worthy of a fuller answer.

People want to reach you be email with their sales and marketing message - "SPAM" or unsolicited but commercial email it's called. And not only do they want to reach you, but they also want you to open and read their emails. So they'll go to whatever lengths they can in these days where the majority of emails are spams to try and get theirs through to you.

Do you ever copy yourself on an email? Do you ever receive an email from a close friend? I know I do, and indeed I may have (not telling!) a "white list" set up to allow those emails in through my filters. Now it's easy - VERY easy - so falsify the name of the sender in an email, and that's usually what has happened in these cases. Simple as that!

If you have an email client that allows you to see full headers, you'll probably find that the "from" IP addresses of the email that was supposed to be from you is completely different to yours, and you can totally disregard it.

Where a problem DOES occur with this sort of thing is where some low-life decides to use your email address to send out a huge series of SPAMs; you're liable to see a flood of bounced emails turning up in your inbox as if you had sent them - even though you have not. I've had up to 100 a minute ...

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

January 28, 2008

Paging Martin Noke, who petitions for more trains from Trowbridge to Swindon

Update, 2nd Feb 08 - see base of article

It was about a year ago that I ran a petition on the Prime Minister's web site, calling upon Tony Blair (our then Prime Minister) to provide an appropriate train service from Westbury to Swindon, and other routes which are operated using the same fleet of trains. You can see it here with the 1700 + signatories that we got - the highest number of signatures on a domestic public transport issue up to that point, which wasn't at all bad for a petition run for the minimum period of three weeks, and without any organisation behind it. It showed the strength of the case and I was delighted to have the names of MPs, MEPs, councilors and other notable people on it - people who have to think longer and harder about signing it that those of us who are not in the public eye.

Here's an admission - I didn't know what I was letting myself in for when I put the petition up. I had an idea, but I didn't realise the enormity of exposure, nor fully the responsibility I was taking on. Fortunately, I checked my working very carefully indeed and came up with what I believed to be a case that was sensible and practical and that everyone could unite behind, and I knew (and was know) to enough people with an interest to make the whole thing get significant support.

Yesterday, a good friend and fellow campaigner pointed me at a new petition which states We the undersigned petition the Prime Minister to Create a rail franchise to provide a hourly direct train service between Trowbridge and Swindon.. I applaud the quest for an hourly service - I do believe that a service of about this level (if serving the intermediate stations at Chippenham and Melksham too - thus taking in 4 of the 5 largest centers of population in Wiltshire) is appropriate. And it would need to follow on to Westbury - that's just 5 minutes - for connectional and operational reasons. But I have a number of reservations.

• I don't (yet, I hope) know the petition originator - a Martin Noke - and inquiries yesterday afternoon failed to find a backup website or publicity backing up his quest with supporting documentation. I think I have come across most campaigners who are working in parallel with us, so this one comes from left field. If it's a good petition and he's looking to achieve a large number of signatures then I would have expected to at least have known the name .. Martin - if you're reading this, please get in touch at least.

• The period of the petition runs for is 9 months, which means that any outcome and answer probably wouldn't be acted upon in timetable changes until December 2009 - such are railway timescales.

• The call for a new franchise to be created worries me; Government policy is to have quite large franchises these days (Island Line is merged, as even is Wessex Trains) so I fear that the service requirement and the patent obviousness of its use could get lost under the "change the system for us" element of the request.

• The text goes on to add that "There are currently only three passenger trains a day running between Trowbridge [snip] Swindon". Alas, there are just 2 trains each way (total of 4 single trips if you like) scheduled from Monday to Saturday - although there ARE three single trips on a Sunday. The choice of the wording makes the petition text (at first glance) look erroneous.

This posting is - unusually - an attempt to reach a person. I do not normally publish names, but Martin has chosen to thrust himself to public attention so I am fully justified in repeating his name - "Martin Noke" - and asking that he (or anyone who knows him) might like to get in touch. Where it goes from there, I don't know - the save the train and Coffee Shop may be able to work "with", or even help, or we may decide that he has a political agenda based on a fresh franchise, and we can then differentiate our causes to the mutual benefit of both.

Full text of Martin's "more details": There are currently only three passenger trains a day running between Trowbridge which is the county town of Wiltshire and Swindon which is the county's largest population centre. No additional track investment will be required. A regular train service would have a significant impact upon road congestion in the area.

I completely agree that a regular hourly service would have a significant effect on road congestion. And on the economy of the area too, with direct public transport times from Trowbridge to Swindon cut from around an hour and a half on the No 49 express bus to around 35 minutes. Martin, I hope that everyone can work together to achieve this level of service or something closer to it than we have at the moment. My email is graham@wellho.net, my phone is 01225 708225!

Update - 2nd Feb

I have now come across not one but two "Martin Noke"s in Wiltshire. One has kindly replied to an email I sent him letting me know he's not my man. I don't have an email for the other (but I do have an 01373 phone no.) and I have left a message inviting him to get in touch. However, further research suggests the petition has been running for 3 months already.

I believe that the petition is flawed in that it calls for a very specific mechanism which is totally contrary to government policy to be used to reach a very sensible objective, and the petitioner is not actively pressing it forward. So ... I will NOT be signing it (and that is my recommendation to others too) nor give it the oxygen of publicity, which is why I am following up with an obscure update here, NOT adding a link for once, and keeping my fingers crossed that it will quietly fade away.

Anyone who happens upon this ... lots of other campaign stuff for this service around. Have a look at West Wilts Rail User Group, Melksham Railway Development Group, Save the Train and the First Great Western coffeeshop

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

January 27, 2008

Evening drive across the roof of Wiltshire

A crisp winter's day ... and a shopping trip to Swindon. A late afternoon drive back over the Marlborough Downs.

In Devizes, the pond by the green - the Crammer - shimmered as the light went down, with trees silhouetted against the sky.

Caen Hill Locks on the canal run through the town, and as we left after dropping Dad off, we could just make out the waters running under Prison Bridge with its sawtooth shape railings which - I'm sure - have something of a history.

And in the last gasp of sunlight, away in the distance the stack of the Westbury Cement works belched its characteristic steam out over the countryside

I wouldn't want to live anywhere but Wiltshire.

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

January 26, 2008

Terms and Conditions - Hotel, England - plain English

With our hotel getting busier every month, and with advertising in place to fill rooms at weekends and holidays when our training courses are not in full swing, it seems a good time to update our terms and conditions.

On one hand, I wanted to cover almost every eventuality, but on the other hand I wanted the text to be easily read and understood - in plain English, with the sections all logically arranged so that people can easily find what they're looking for ... and when they do find it, I want them to be able to understand it, and to consider it fair. I really dislike the "small print" philosophy that many people seem to adopt, especially when they print in mid-grey on a slightly lighter grey background!

See what you think of ours - this should open in a separate window for you:

Well House Manor - terms and conditions

One of the other aspects of a set of terms and conditions is a need for our staff to understand them, and also for our staff to know the reasons behind them. So the page that you may just have looked at if you clicked on that link above needs some additional "behind the counter" comments for our own team. I've provided that via our Wiki system - indeed that's where the terms and conditions are maintained. If you have a look at them, you'll see

Hotel terms and conditions

but our staff, logged in via their passwords, will see additional comments in blue:

Hotel terms and conditions / staff comments

Some of the elements of our terms and conditions will vary significantly from those for other accommodations - our approach is to provide a home from home for the businessman visiting the area, or for the discerning tourist. And we feel that the best way to do that is not to have a cash till at every corner looking to take more money, nor a set of rules that force extra expenditure on our guests over and above the base room rate. So "bring in your own food" and "invite your contacts in for a complimentary coffee" wouldn't suit other establishments. Having said that, readers are welcome to grab our ideas if they wish - but make sure they suit your needs, and please provide a link back to Well House Manor along these lines:

With thanks to Well House Manor, Melksham

P.S. If you're a hotelier who would like to see all that blue text that explains the reasons "behind", please send me an email ... graham@wellho.net

Posted by gje at 09:01 AM | Comments (0)

Flipping images on your web page

Are you seeing this picture the right way up, or upside down?

If you're seeing it the right way up, you're using Mozilla, Firefox, Safari, Netscape or almost any other browser ... except Internet Explorer. With Internet Explorer, it might be up side down!

This is no "failure" on the part of some versions of Internet Explorer - it's just that the img tag in Internet Explorer allows style="Filter:FlipV" to flip an image vertical, whereas that tag isn't defined for other browser. Best avoid it, I think!

I came across a need to flip an image the other day ... which is why my research lead me to that discovery; in most situations, I would simply have used PhotoShop to invert the image but as the image in question was a dynamic feed from a webcam, that option wasn't open to me.

Let's see what I can do ...

Yep, that's better (and, yes, PHP again ;-) source code )

and Yet more pictures!

Posted by gje at 12:52 AM | Comments (0)

January 25, 2008

Downloading data for use in Excel (from PHP / MySQL)

Requirement: To allow a visitor to your web site to click on a link that downloads data from the server into a Microsoft Excel spreadhseet.

Solutions - I'm going to offer you two:

a) To send the output as a text file - delimited by tabs between columns, and with new lines for each new line. Add appropriate content type headers (such as octet-stream) to save the file to local disc rather than displaying it, and pass back a file name with a .xls extension to provide direction to the operating system as to how to handle the file. In most environments, Excel will do the import for you.

I have written an example that does this, grabbing data from one of our MySQL databases that logs web site traffic Run the example or see the source of the example

or b) To send the output as an HTML table, in which case Excel will interpret the rows and columns of the tables as its data cells. I've written an example of this too - using an alternative content type to show the flexibility that's available. And I have also put a formula into one of the cells so that you can get excel to fill in the extra boxes for you.

This example just populates a spread sheet with some numbers as a "proof of concept" but it's still a series of useful pointers, I hope. You can Run the example or see the source code

You'll notice in the source code of both examples that I've added in extra headers in my response to ensure that the browser doesn't cache the results - that's done to make sure that you get a fresh download each time you run the scripts, rather than being given stored old data.

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


Useful link: PHP training

January 24, 2008

Python - formatting objects

If you're going to be printing out objects from within Python, simply provide an __str__ method in the class and it will do all the work for you. Indeed - why not create classes and objects for straightforward objects such as people's names ... then you can call up the formatter for them very easily and have it defined just once in your code.

class person:
  def __init__(this,name):
    this.name=name
  def __str__(this):
    return "%-12s" % this.name
 
people = ["John","George","Paul","Esmerelda","Jo","Petal"]
plist = []
 
for current in people:
  plist.append(person(current))
 
for j in range(len(plist)):
  print plist[j],j

running that:

Dorothy:py08 grahamellis$ python names
John         0
George       1
Paul         2
Esmerelda    3
Jo           4
Petal        5
Dorothy:py08 grahamellis$

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


Useful link: Python training

January 23, 2008

Pictures you can use - for free - from our library

Here are some random images from our site ...

... randomly provided for a good cause. I've been bugged (I admit it!) by people who help themselves to our images and bandwidth without even asking and without even providing a link back and I put together a page at http://www.wellho.info to help persuade them to register. Now that means "watermarking" rogue pages - described in a previous post - but also providing a carrot at that page to show them some of the other images we have here ...

Use these pictures, use almost any of our pictures for non-commercial purposes (you'll see more detailed conditions and library links on the "info" page), provide a link, and it's a win for everyone!

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

January 22, 2008

Keeping staff up to date on hotel room status

Communication - communication of the immediate status of hotel rooms, of events that have happened out of the norm, of the reasons behind each of our terms and conditions, and much more is all a vital part of running our hotel - and it's not made easier by the fact that we are (and must be) run be a varied team who are at work at various times between 6:30 in the morning to midnight. Add to that the need to keep our HQ / booking office in touch with the hotel / conference / training centre itself.

We're an internet company .... so we do much of it on line, so what better system to use than a web-based one for these components? I've put a demonstration you can try here if you wish to see our new immediate availability display. The display looks like this:

and, yes, it's very simple - but we can click a room from "let" to "requiring service" when a guest checks our, back to "open" when it has been serviced so that the front desk knows, and leave "awaited" flags on rooms with checkins pending so that we know exactly where we stand right through the night ... and I can even check a 2 a.m. and see if that last guest actually showed up in the end!

Note to staff - you'll see the display on the main staff resource link page. Note to others - please feel free to follow that link; you will NOT see the room status but you will find other useful tools that we have, each exposed as much as our security and the security of our guests allows

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

January 21, 2008

Autovivification - the magic appearance of variables in Perl

Here's a one line perl program that does nothing but set up a variable ... except that it does a lot!

$p[7]{john}{paul}[9] = 1;
 
__END__
 
A list called @p. Elements 0 to 6 are null, and element 7
is a reference to a hash ...
 
That hash contains a single member, key is "john" and the
values it holds is a reference to another hash ...
 
THAT hash contains a single member with a key of "paul" and
it contains a reference to a list ...
 
And that list has elements 0 to 8 being null, and element
nine containing the value 1.
 
AND THAT WAS ALL DONE AUTOMATICALLY by Perl's Autovivification
capability!!

If you assign to a variable in Perl and it does not already exist, the Perl creates it dynamically - and that implies that it also creates all the other necessary structures as well. My oneliner above took 10 lines to describe in plain English!

This is both powerful and dangerous. Something as simple as

$phone[1225708225] = 1;

will give you "out of memory" as a list of over one billion elements is calledup. But do remember that

$phone{1225708225} = 1;

will create a hash with just one member, and THAT is what you should use for data with sparsely distributed numeric keys

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


Useful link: Perl training

January 20, 2008

Perl, PHP or Python? No - Perl AND PHP AND Python!

"Which language is best for xxx task" I am often asked. And I'll listen to the questioner's description of his application, his background, and the sort of support he'll have at his place of coding before coming up with a suggestion. Never would I suggest he learn all three.

And yet, today, I found myself with a little task to do - it took me no more that a few minutes - and I used all three languages without even thinking about it.

The task. A 900 Mbyte web log file - recording all the traffic from the last year at our First Great Western Customer Forum and a requirement to get some information out of it about the geographic spread of the visitors.

1. A little bit of PERL (the Practical Extraction and Reporting Language) to pull all the different IP addresses that have visited the site out of the file.

#!/usr/bin/perl -na
$counter{$F[0]}++;
END {
@hl = sort keys %counter;
print $#hl+1," unique hosts\n";
foreach $ak(@hl) {
  print "$ak $counter{$ak}\n";
}}


2. A PHP script - as we have the PHP / MaxMind routines easily accessible - to add the country of origin for each visitor to the data (that's right - PHP running from the command line!)

<?php
include("../../include/stdphp.v8");
print "never mind!\n";
foreach (file("uniquehosts") as $line) {
  $lns = explode(" ",$line);
  $coco = getcountry($lns[0]);
  if (ereg("...",$coco[id])) {
  print "$coco[id] $line"; } else {
  print "XXX $line"; }
}
?>

3. Another piece of Perl to count the number of visiting IP addresses from each country

while (<DATA>) {
  ($c,$ip,$k) = split;
  $byc{$c}++;
  $byk{$c}+= $k;
}
foreach $co(sort {$byc{$b} <=> $byc{$a}} keys %byc) {
  print "$byc{$co} $co\n";
}

__END__
XXX 116.122.81.28 32
XXX 116.199.208.54 7
XXX 116.214.24.78 34
etc

4. and finally Interactive Python in place of a calculator to do some final statistical arithmetic on the results.

OK - I'll admit it; I got caught miscoding once by the different format of foreach in Perl and PHP, but otherwise it all worked pretty well. If you want to see the information extracted by this process, look here. And, no, I'm not really proud of the beauty of my code; written to fulfill a quick one-off hacking job.

If you think I've not given Python a fair run above, you're right. But then I have been using it all day as a notepad as I do my final personal tax calculations, with all the additions keyed in so I can go back and check my sums as I may need to over the next few days. That's code and numbers that I won't be sharing here, of course!

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


Useful links: Python training, Perl training, PHP training

January 19, 2008

Summer Ball at Bowood - Saturday 12th July 2008

I'm giving a "plug" this morning for a Summer Ball which will be held at Bowood Golf and Country Club on Saturday, 12th July 2008. The local branch of the Federation of Small Businesses (FSB) has organised such an event for many years, and it's always been a sell out.

The arrangements take an incredibly long time, with the booking for one year being made before the noise from the previous year's event has even subsided, but this year the outgoing committee of the local FSB branch found itself unable, for reasons outside of its own control that I have mentioned elsewhere, to take those initial steps. Yet that commitee has many, many business friends who would not want to be disappointed, and we have amongst our numbers several people who organise hospitality on a regular basis. So - independent, and not for profit, we have started the Ball rolling.

How does YOUR diary look for 12th July? There's a whole lot about the ball here [link] including entertainment details, menu, prices and booking information. I've prepared the page and I'm hosting it without charge, Marion Mortimer is "fronting" the early admin and booking again not-for-profit and we'll have a whale of a time.

---OOO---

"How to survive in adversity" is the title of a book I once picked up to read on a transatlantic flight, and I remember some of the tidbits from it from time to time. Some people have a personal philosophy that says "take what life throws at you and grumble", others say "take what life throws and survive it the best you can" and a third approach - the one I attempt to follow - which says "take what life throws at you and use it to everyone's advantage". Yes - I try to be part of the every cloud has a silver lining brigade. And it has stood me well - VERY well - over the years. Well House Consultants grew from an adverse situation and the thought "what can I do about this?" - from a £100.00 shell company with me as the only member of the team to where we are today.

The Summer Ball can do the same. It's independent, and it's intended as a social event for business people in Wiltshire. It's not tied to the Federation of Small businesses ... but the organisers WILL welcome the FSB's new committee on board. And the local Chambers of Commerce, Institute of Directors, and other business groups. It promises to be a very interesting evening - fun and fruitful for us all.

---OOO---

Newly indexed images on this site ... page 1, page 2, page 3, page 4, page 5, page 6 and page 7. See here if you would like to link to any of these images from your own site. See here to search our images and here to see which of our images are the most viewed.

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

January 18, 2008

Buses from Well House Manor, Melksham, to Bath

If you're staying with us at Well House Manor in Melksham, there's an excellent bus service from right outside the Hotel which you can use to get to Bath for the day ... or for the evening.

In the morning, customers can catch the bus at 07:40, 09:20 or 10:20 (there are earlier and later services), and for an evening in Bath, services as 15:20, 16:55 and 17:55 (also 18:52 from the town centre) are convenient - journey time being about half an hour.

Return buses leave from Bath for Melksham in the afternoon at 14:32, 15:32, 16:32 and 17:45, and in the evening at 18:20, 20:20 and 23:00. All stop in the town centre which is just five minutes walk from us, and the majority carry on to stop right outside Well House Manor (service X72)

Bath is said to be the most expensive town in the UK for hotel rooms - although we provide what are probably the best rooms in Melksham, our prices are still significantly lower than the AVERAGE for Bath!

See Bath and more of Bath.
See Well House Manor - on this site and the hotel's own site

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

January 17, 2008

Handling Binary data (.gif file example) in Perl

Perl is very good for handling binary data - it can do things you can't do with other utilities and scripting languages, and things that are very much harder to do in C - that's because C's strings are null terminated and in the case on binary strings, there may be an embedded null anywhere.

Finding good examples is a bit tricky. And that's because binary data tends to come with long and involved specifications. However, a .gif image file has the height and width of the image encoded into the 7th to 10th bytes of the file, so that does make a reasonable example

# Find all files ending in ".gif" in current directory
@files = glob("*.gif");
print ("@files\n");
 
# Handle each of them in turn
foreach $picture(@files) {
        # If we can't open a file, PANIC!
        open (FH,$picture) or die ("couldn't open $picture\n");
 
        # Read first 10 bytes into $stuff
        read (FH,$stuff,10) ;
 
# Use "v" as the most significant byte is last - little endian
# Not "n" which is the other way round - big endian
        # skip 6 bytes, the pick up 2 x 2-byte integers
        # (see the manual for unpack - v means 2 byte integer ;-) )
        ($wide,$high) = unpack("x6vv",$stuff);
 
        # With a .gif file, these two numbers are the image size!
        print "$picture - $wide x $high\n\n";
 
        }

I've put plenty of comments into that code ... good practice ... and so there's not much need for extra detailed description here. But I should add that there's a pack function that's the opposite of unpack if you want to reform binary data, and you can output binary data using the regular print function - nothing special at all is needed.

Yes - it's Perl, yes the code is that short, and when you know the language really well you can write it REALLY quickly!

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


Useful link: Perl training

January 16, 2008

Extracting information from a file of records

Here's a very common application ...

You file a file of data records, and you want to parse the file handing the data record by record. Each record has a series of space delimited fields, most of which are no interest to you what so ever ...

And a template for a solution in Perl.

open (FH,--put file name here in quote--) or --handle error--
while ($report = <FH>) {
# Using list slices of anonymous lists to extract data
# $report = ("192.168.200.67 e-w-f graham mac 2005 17 Tiger mucky");
($cpuname,$yop) = (split(/\s+/,$report))[1,4];
print "$yop - $cpuname\n"; }

I dare say you were expecting a long example there, but in Perl I've done the whole thing in just six lines - and two of THEM are comments. The trick comes in the use of anonymous list slices:

(split(/\s+/,$report))[1,4];

"Take the string in $report. Divide it into a series of chunks, delimted at white space. But I'm only interested in returned fields 2 and 5 (i.e. numbers 1 and 4 because we start counting at zero).

Taking the data sample line I've included in my program sample, just the host computer name and the year of purchase are returned. No need for me to throw away explicitly the fields I don't want, and using
($cpuname,$yop) =
I can even assign each returned element to an appropriate scalar.

I might not do Perl as much as I used to , but I'm sure enjoying presenting the Perl Course this week!

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

January 15, 2008

How not to write Perl?

You can write a piece of code that resembles a Picasso ... or a piece of code that resembles a dog's dinner ... in Perl. And, rush job yesterday, I wanted to analyse a web access log file and find the number of unique visiting hosts listed. Here's what I came up with:

open (FH,"t09");
while (<FH>) {
  ($j)=split;
  $k{$j}++;
}
@s = keys(%k);
print @s+0,"\n";
foreach $host(sort {$k{$a} <=> $k{$b}} @s) {
  print "$k{$host} $host\n";
}

VERY quick. And VERY dirty, but it works:

[root@p15161732 logs]# perl t09d
291
1 84.16.235.40
1 62.31.153.127
1 86.6.163.203
1 213.40.135.44
[etc]
17 74.6.8.73
25 86.164.206.136
28 194.83.245.226
32 86.151.173.104
55 217.44.22.70
77 82.46.84.146
302 82.33.81.221
[root@p15161732 logs]#

So that's 291 unique hosts, and also some stats on who they are / the distribution of hits.

Why do I question whether or not this is good Perl? Because it will be VERY HARD to maintain later on. Variable names are not descriptive. No comments. No data validation. No checking to see if the input file actually exists. No report on the output as to what it is. No copyright statement / author notes. And that's just or starters.

For a one off - strictly a one off - these things probably don't matter; after all, Perl is the PRACTICAL extraction and reporting language and it did a very practical job of extracting what I needed here!

Learn Perl
The web page I was analysing

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


Useful link: Perl training

January 14, 2008

Comments on proposed Asda Superstore for Melksham

I welcome the proposal in principle but - oh dear - what a poor application in terms of traffic, in terms of safe access by anything other than private car, and what a lost opportunity to provide decent access if it were to be accepted in its current form.

Please have a look at my draft - following - let me know any inputs directly by email in the next 24 hours, then I need to submit this. It is "unfortunate" that the application was lodged just before Christmas as it has meant that so many people have been away during the public consultation period!

LINK to Draft Public Feedback

Update I have revised the draft - many thanks for many emailed inputs - and the link above will now take you to the sumission to be made

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

Ongoing Image Copyright Issues, PHP and MySQL solutions

I actually want to encourage people to use my images ... but to do so with permission, which usually means something as simple as a link back you our page which works out for everyone's benefit. A lot of people ask, but some don't seem to know that they should!

I've added an ability to "watermark" images into my image database script so that I can do things like this:

if (eregi("vwvortex",$_SERVER[HTTP_REFERER]) and eregi('mounthill',$filename)) { $error =
2; }

and follow that up with some of PHP / GD's excellent image routines to produce a result like:

I don't think some people realise just how risky it is linking from another site ... I could have put up a dramatically different picture there if I had wanted to!

Actually, I'm going to be very nice about this - just ask for a link back. The page linked to is intentionally one with a very short URL to make it even easier - http://www.wellho.info


Update - 17th January I'm clearly not the only one who feels strongly that permission should be sought before an image is used. "I Stole this image. Next time I'll have the decency to use my own bandwidth when I steal" says an image here ... a page I went to this morning as a result of a number of visits from their site. You may have guessed ... another of the images is one of ours!

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


Useful link: PHP training

January 13, 2008

Script to present commonly used images - PHP

"What are the most popular pages in your picture library, and where are they used from?" An interesting question and I could analyze raw web logs to find out the answers. However, most of our images are managed by a script that retains extra information such as an image title, and uses are logged ... so a simple PHP script will do the job admirably!

<?php
$most = fopen("../picfeed.txt","r");
 
while ($line = fgets($most,4096)) {
   $parts = explode(" ",$line);
   $counter[$parts[0]]++;
   }
 
arsort($counter);
$v = 0;
foreach (array_keys($counter) as $pname) {
   $html .= "$v: <img src=http://www.wellho.net/pix/$pname.jpg><br />";
   if (++$v > 10) break;
   }
?>
<html>
<head><title>Our most viewed pictures</title></head>
<body><h1>Most Viewed Pictures</h1>
Here are our most viewed pictures:<br>
<?= $html ?>
</body></html>

If you want to see our most popular images - dynamically - there's a link to that script running here. There's also an alternative version showing counts, tables of most popular referrers, and which allows you to page through the pictures page by page. You can run that alternative script here or here to show only images loaded by references from other sites and you can see the source code here. Passwords changed, of course.

Oh - <advert> I'll teach you how to do this on our PHP course! </advert>

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


Useful link: PHP training

January 12, 2008

Flooding by Asda-s proposed new supermarket

It's been raining heavily over the last couple of days and, once again, the river has burst its banks to for what we call Lake Melksham. The corner by "Countrywide Farmers" is flooded yet again ...

This is the site where Asda have their planning application in to build a store - something I've written about in the past and will be writing about again, no doubt, in the future; I note with a wry smile at the moment that one of the boxes they did NOT tick on their application was that the area is free from flooding.

Just downriver, there were even two men in a boat ...

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

Web page (http) error status 405

Running his first Java Servlet today, one of my delegates reported an HTTP status 405 from his code when he tried to browse to it. A new one on me ... I am used to a good number of other return codes, but hadn't seen this before.

It turns out that the cause was the lack of an appropriate doGet method in the Servlet class; in my delegate's case he had provided a doGet but with the wrong type of parameters, so instead of providing a method that Tomcat could call up he had provided what was, in effect, an internally available method only. I was able to reproduce the error later for the purpose of this note by simply mis-spelling doGet as doget ... Capital G to lower case g.

Wrong:

public void doget ( HttpServletRequest request,
   HttpServletResponse response )
   throws ServletException, IOException {

Right:

public void doGet ( HttpServletRequest request,
   HttpServletResponse response )
   throws ServletException, IOException {

Here are some other common 400 series errors we come across, and their typical causes to help you troubleshoot:

400 - Bad request

Typically this is caused by a user writing his own web client (for example using Web 2 techniques) and so making an illegal instruction call to the server

403 - Forbidden

A file exists on the server that is mapped to the URL that was given, but that file is not readable by the web server process. Typically, this error occurs when the web site administrator is uploading a file via FTP or copying it into place and gets the file permissions or ownership wrong.

404 - Not Found

The most common of the lot. The request was valid, but doesn't point to anything which exists on the server. It could be that the user (at the browser) has mistyped a URL, it could be that there's a broken link on a web page pointing at thin air, and it could be that a file that should exist on the server doesn't, or has been accidentally deleted. You will also get a lot of 404 errors in your server logs relating to malicious software that's poking around looking for holes in your security!

401 - Unauthorized

The page exists, but the user has failed to enter a correct user name and passwordd to access it. See .htpasswd in the Apache documentation.

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

January 11, 2008

Java, sorting, ArrayList example, generics

A Java ArrayList holds an ordered sequence of items like an array, but there are differences:

1. An ArrayList has no fixed size but can be extended by adding elements later
2. An ArrayList can only hold objects (not primitives)
3. ArrayList elements are addressed by methods and not by square bracket notation.

Here's an example from yesterday - showing a typical use of an ArrayList; I was reading a file but didn't know how many lines it contained, so an ArrayList gave me the flexibility I needed.

import java.io.*;
import java.util.*;
 
public class Pesort {
 
public static void main (String [] args) throws Exception {
 
   // Following line up to Java 1.4 then gives warnings
   //ArrayList Stuff = new ArrayList();
 
   // OR following line from Java 1.5;
   // this specifies that the ArrayList is to contain Strings
 
   ArrayList <String> Stuff = new ArrayList<String>();
 
   // Above lines show use of "Generics" - compare to
   // Templates in C++
 
   BufferedReader Source = new BufferedReader(
      new FileReader("../request.txt"));
 
   System.out.println("---------- UnSorted");
 
   while (Source.ready() ) {
      String Line = Source.readLine();   
      System.out.println(Line);
      Stuff.add(Line);
      }
 
   System.out.println("---------- Alphabetic Sort");
   
   Collections.sort(Stuff);
 
   Iterator stepper = Stuff.iterator();
   while (stepper.hasNext()) {
      String current = (String)stepper.next();
      System.out.println(current);
      }
   
 
   System.out.println("---------- Sort by line length");
 
   Collections.sort(Stuff, new byLineLength());
 
   stepper = Stuff.iterator();
   while (stepper.hasNext()) {
      String current = (String)stepper.next();
      System.out.println(current);
      }
   }
 
}

Here are the results from running that program:


[trainee@snowdrop java08]$ java Pesort
---------- UnSorted
antonia Perl XML PHP Tcl/Tk MySQL
barbara Tcl/Tk ASP Ruby Java
cherry Perl Java Ruby MySQL
delia XML PHP Java ASP
florence Ruby PHP Java ASP
gloria XML Perl Tcl/Tk MySQL
zoe Ruby ASP Perl PHP
adam Tcl/Tk Perl Python MySQL
barry Python XML Java Perl PHP
charles Perl Ruby MySQL Tcl/Tk
ed Ruby Perl Java PHP
fred MySQL Perl Java XML
graham Java Perl Tcl/Tk
harry PHP Python Java
ivan Ruby Java Perl Tcl/Tk MySQL
victor Ruby Perl Tcl/Tk MySQL
william Ruby Perl PHP
xavier PHP Java Perl
yuri XML PHP Perl Tcl/Tk
zachary MySQL Java Tcl/Tk
---------- Alphabetic Sort
adam Tcl/Tk Perl Python MySQL
antonia Perl XML PHP Tcl/Tk MySQL
barbara Tcl/Tk ASP Ruby Java
barry Python XML Java Perl PHP
charles Perl Ruby MySQL Tcl/Tk
cherry Perl Java Ruby MySQL
delia XML PHP Java ASP
ed Ruby Perl Java PHP
florence Ruby PHP Java ASP
fred MySQL Perl Java XML
gloria XML Perl Tcl/Tk MySQL
graham Java Perl Tcl/Tk
harry PHP Python Java
ivan Ruby Java Perl Tcl/Tk MySQL
victor Ruby Perl Tcl/Tk MySQL
william Ruby Perl PHP
xavier PHP Java Perl
yuri XML PHP Perl Tcl/Tk
zachary MySQL Java Tcl/Tk
zoe Ruby ASP Perl PHP
---------- Sort by line length
xavier PHP Java Perl
ed Ruby Perl Java PHP
harry PHP Python Java
william Ruby Perl PHP
zoe Ruby ASP Perl PHP
delia XML PHP Java ASP
graham Java Perl Tcl/Tk
fred MySQL Perl Java XML
yuri XML PHP Perl Tcl/Tk
zachary MySQL Java Tcl/Tk
florence Ruby PHP Java ASP
cherry Perl Java Ruby MySQL
barbara Tcl/Tk ASP Ruby Java
gloria XML Perl Tcl/Tk MySQL
adam Tcl/Tk Perl Python MySQL
victor Ruby Perl Tcl/Tk MySQL
barry Python XML Java Perl PHP
charles Perl Ruby MySQL Tcl/Tk
ivan Ruby Java Perl Tcl/Tk MySQL
antonia Perl XML PHP Tcl/Tk MySQL
[trainee@snowdrop java08]$

And here is the comparator class that I wrote for my non-standard sort. Using a comparator class, the programmer can provide a method which is used internally by the sort method to compare two items and return an integer - negative, nought or positive - to indicate if the first object comes first in sequence, the objects have the same tank, or it comes second.

public class byLineLength implements java.util.Comparator {
 public int compare(Object boy, Object girl) {
  int sdif = ((String)boy).length() - ((String)girl).length();
  return sdif;
 }
}

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


Useful link: Java training

January 10, 2008

Java - using super to call a method in the parent class

If you're writing a Java class in which you override a method from the base class, can you still make use of that base class method in your new code? Yes, you can. You want the super call.

Here's an example - I had a base class called Shape which overrides the toString method. And I was then writing a Rectangle class in which I wanted a further enhanced toString method. So here it is - firstly running toString from Shape and then adding some extra text.

public String toString() {
String firstbit = super.toString();
String result = firstbit + " Rectangle " + width + " by " + height;
return result;
}

The toString method in Java is defined for all Objects as the method which converts the object into a printable string - so that if you ask for an object to be printed this is how it will be formatted. It's a method that all classes that you write will inherit - either from Object or from other classes if you define inheritance yourself, and it is very often overridden at many levels.

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


Useful link: Java training

First Class Java. First step and moving forward.

Java is an Object Oriented language that's great for medium size through large to huge systems. Which means that it's not usually the best approach for short applications ... of the size that one typically uses as examples on a training course. So examples that I produce show mechanisms and extensibility rather than practical use in themselves. ((Put another way - why use a system of directory and file management, a.k.a. packages and classes, when you've only got one or two files!))

So here - for anyone who gets presented with a large Java project to maintain - is a very short "hello Java objects" example that shows a single class, nothing complicated, called from a single simple test program.

public class HotelBooking {
 
        int duration;
        int occupancy;
        boolean onCourse;
        String GuestName;
 
        public HotelBooking(int numberNights, int numberGuests,
                                boolean delegate, String LeadName) {
                duration = numberNights;
                occupancy = numberGuests;
                onCourse = delegate;
                GuestName = LeadName;
        }
 
        public float getcost() {
                if (onCourse) {
                        return 70.5f * duration;
                        }
                if (occupancy == 1) {
                        return 80.0f * duration;
                        }
                return 95.0f * duration;
        }
 
        public String getname() {
                return GuestName;
                }
 
}

And here's the test program:

public class TestHotel {
 
public static void main (String [] args) {
 
 
        HotelBooking Steve = new HotelBooking(3,1,true,"Steve Sunshine");
        HotelBooking Nick = new HotelBooking(1,1,false,"Nick Night");
 
        float costone = Steve.getcost();
        float costtwo = Nick.getcost();
 
        String nameone = Steve.getname();
        String nametwo = Nick.getname();
 
        System.out.print(nameone + " " );
        System.out.println(costone);
 
        System.out.print(nametwo + " " );
        System.out.println(costtwo);
 
        }
 
}

I run that and I get

[trainee@snowdrop bkp]$ java TestHotel
Steve Sunshine 211.5
Nick Night 80.0
[trainee@snowdrop bkp]$

But of course there's a lot more to Java than that!.

I went on to enhance my examples to include several different methods to create hotel bookings (overloading), to specifiy that some variables are private, to add in arrays of objects, and to place my HotelBooking class into a package of its own so that it can leater be easily bundled with a whole series of other classes.

And then you move on to saying that "I have a booking - but it's not a normal one; it differs because it's in association with an event". Rather than duplicate the code for a regular booking, which would mean that there was thereafter double the maintainance, in Java you'll describe the event booking as extending the regular booking and you'll only supply the extra functionallity and changed coding.

You can then extend classes in a number of different ways, giving you a whole alternative series of different booking types ... which you can hold in an array or something similar, and you'll rapidly find that you have a powerful application coming together, easy to maintain as the code for each piece of logic is only there once, and easy to enhance as you can very easily add in extra subclasses.

Why a Java example today? Because I was teaching a Java Bootcamp yesterday! And I'll be running another Bootcamp, and also an extended Java Programing for the Web at the end of next month.

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


Useful link: Java training

January 09, 2008

Climate change, renewable resources and paper v plastic

Climate change. End of supplies of fossil fuel. Carbon footprint. Expense of road building. Cost of time lost in travel. Just what effect are we having on our planet - where are we headed and how many of the changes that we see in the climate are natural variations and parts of a natural cycle or just typical variations, and how many are man made? I don't know the answers!

I have listened to comments that a major trunk road built to bypass Westbury would be good for 20 years, but would then provide a magnificent cycle path in the post-oil era. And I have listened to comments that say that our effect on the environment is a pinprick and that the earth will naturally balance for it. Both, I fear, are extreme views.

I find myself as an uneducated but thoughtful member of the public thinking

• I don't know who is right and who is wrong in what they say.
• I don't know which of the views put is complete and unbiased
• I don't know which facts I am told are proven and which are guesses

There's a move to have Melksham become a plastic bag free zone at the moment - lead by an ardent campaigner who feels it's the right and proper thing that we should do. And there are others who suggest that plastic bags are actually very efficient to produce compared to paper bags, can be reused much more, and actually help within landfill by retaining the methane for later energy production rather than wasting it in an adverse carbon way. And I sit bemused on the side lines!

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

January 08, 2008

Java is a dynamic language .... (and comparison)

Many older programmers are used to setting up an array of a fixed size and saying "that's fixed" ... for the duration of the program, if not for all time until the application is recompiled.

Languages such as C gave us malloc, calloc and realloc (and things have progress on somewhat in C++) to let us dynamically set up arrays, and languages like Perl and Python have move on to lists which are totally different structures. PHP uses the word "array" but really they are lists!

An array (in computer science terms) is defined as sequential memory locations and so by definition if you run off the end of it, you're going to be "out of bounds" and something nasty will happen. A list is defined as a series of items linked on to each other in sequence, which can be extended later.

What about Java?

Java uses arrays. However, they can be dynamically allocated so that the size can be controlled at run time, and all Java arrays are objects which means that you can re-allocate a name that you've already used to a new block of memory or another differing array as your program runs - thus getting a far more dynamic effect.

Example?


Let's calculate a result that processes an array to produce a new and longer array many times over.

Initialization and setup:

int [] previous, current;
previous = new int[0];

The names current and previous are set up in the first line, but with no particular size. Then previous is set to an empty array with no elements, basically to keep the compiler happy.

Let's now run the iteration loop:

for (int k=0; k<rows; k++) {
current = new int[previous.length+1];

We're going through the loop as many times as necessary, setting up the current row to be one longer than the previous.

At this point, calculations to generate current from previous!

Finally, set "previous" to be the array named in "current". The old previous will be lost and the memory released collected up in due course by the garbage collector, and we can run around the loop again to calculate the next row.

previous = current;
}

This "moving up" is cheap - we're only moving up a reference or pointer - a single memory address - and not what could be a major piece of storage. We're renaming a town, not building a complete new one if you like!

There's a complete program example here which shows Pascal's triangle being generated with this dynamic technique.

For even greater flexibility, see java.lang.util

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


Useful link: Java training

January 07, 2008

Training Season Starts again!

I'm glad that our business isn't heavily seasonal - tourist places like Longleat have a heavy summer and a barren winter, and The Christmas Shop must, surely, be heading for a quiet few months.

But we are - slightly - seasonal; we have a quiet three weeks where no-one wants to learn Perl or PHP (or even Python!) from mid December until the 12 days of Christmas are over. Well - we're there now, we've caught up on much work behind the scenes, we've turned the lights back on,and we're ready for the next 11 month season. The Programme is published on our main site

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

January 06, 2008

PHP / Web 2 logging

It' gone quiet here for 48 hours, hasn't it? The final run up to the first week of courses for the new year and we've been catching up with everything from cleaning blinds to updating web cam systems and ironing out final issues and catching up on other paperwork. Lots of good background and not too much to show you until it creeps gently in.

Oh - did I show you this one:
http://www.savethetrain.org.uk/running.php
which is using web2 technologies to keep a log of certain updating resources.

Not much special to show you in how it works - just plain Ole PHP.

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


Useful link: PHP training

January 04, 2008

Single login and single threaded models - Java and PHP

On Apache Tomcat courses, I find myself explaining "single login" models and on some Java courses I explain single threaded models. In both cases, there are times that newcomers to the technologies ask "does it matter".

Answer - for a small and quiet application suite, probably not - but as the application suite grows, a single login to cover all applications is a boon to your users, and in contrast the single threaded model should be avoided as it will limit traffic - keeping users waiting at the "starting gate" until the previous visitor to the application has completed his current interaction.

We have developed a number of applications for internal use here at Well House Consultants and Well House Manor over the years that rely on staff members logging in to get [full] use of the application code, and I am in process of applying a single login model to them retrospectively ... since they're internal, I'm afraid I can't publish log in details to give you a demonstration, but I can give you some pointers.

• 1. We're noting logins at the start of each of the applications via a common set of PHP functions that we have written and include in each application:
pwtest to see if the user is already logged in, and return account info
pwcheck to check if a user name and password pair are valid
pwlogin to log a user in
pwlogout to log a user out
 
• 2. On the exit from each application, any session is destroyed but the longer term login cookie is retained
 
• 3. On the user selecting a general logout button, session cookies for all applications grouped under the single login facility are destroyed in order to avoid any security holes being left open.
 
• 4. Cookies for the single common login are specifically set up for the root directory or any folder below it so that they will be seen by all the sharing applications, and are initially configured to allow a user to remain logged in for a period of rather longer that a regular session, but not for months or years!

What applications are we serving with the system so far?

Our Staff Resources Front Page (where extra links are provided for staff who are logged in)

Our hotel room availability page (if you're not logged in, you just get a room status report and an invitation to book. When logged in, we can see details of room allocation right down to the staff member on duty being given a checklist of anticipated arrival times!)

Our new incident book system through which we report anything from breakages to notes of customer preferences between ourselves - the public facing pages are read only, and only show items we have chosen to mark "public".

Our wiki (sample page) that is extensively used for both internal and customer facing pages that change frequently.

Our traffic monitor (last 5 minutes) and most popular pages (last 24 hours) reports reveal more information to logged in staff

And our security monitor page - when logged in suitably, certain team members can view the web cams. If not logged in, You'll see a display of some static photographs instead.

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


Useful links: PHP training, Java training

January 03, 2008

A time to update pictures

Time to change a few picture ... with the replacement of our fleet of training laptops with bigger, better machines over the New Year, the pictures illustrating our courses were all out of date! What better opportunity to use a series of picture from last August, taken on the journey up beside the Hudson River from New York to Albany to a Python course ...

These images are all quarter size - if you browse through our course descriptions from here, you'll come across them all in their full glory!

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

January 02, 2008

Comparison - cellpadding versus cellspacing

What's the difference between cellpadding and cellspacing in a table cell?

Cellpadding adds space all around a table cell - so if you set cellpadding to 2 pixels, you're adding 4 pixels between the data in neighboring cells. But cellspacing controls the space between the cells, so specifying 2 will add just two pixels between the cells.

You'll also find that if you have your background colour for a cell set to a different colour to the background, it will effect your cellpadding but NOT your cellspacing.

Perhaps an example would help?

Cellpadding = 2 and Cellspacing = 0

 StartsDuration
Regular Expressions Mon, 7 Jan 08 1 day
The MySQL Database Thu, 24 Jan 08 2 days
PHP Programming Mon, 4 Feb 08 4 days
Object Oriented PHP Fri, 8 Feb 08 1 day
Linux Web Server Thu, 27 Mar 08 2 days
Technology for PHP Mon, 7 Apr 08 1 day

Cellspacing = 2 and Cellpadding = 0

 StartsDuration
Regular Expressions Mon, 7 Jan 08 1 day
The MySQL Database Thu, 24 Jan 08 2 days
PHP Programming Mon, 4 Feb 08 4 days
Object Oriented PHP Fri, 8 Feb 08 1 day
Linux Web Server Thu, 27 Mar 08 2 days
Technology for PHP Mon, 7 Apr 08 1 day

Both Cellspacing and Cellpadding = 0

 StartsDuration
Regular Expressions Mon, 7 Jan 08 1 day
The MySQL Database Thu, 24 Jan 08 2 days
PHP Programming Mon, 4 Feb 08 4 days
Object Oriented PHP Fri, 8 Feb 08 1 day
Linux Web Server Thu, 27 Mar 08 2 days
Technology for PHP Mon, 7 Apr 08 1 day

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

January 01, 2008

Well House Consultants Training and Hotel - 2008 news

A Happy New Year everyone!

2007 was a busy year for us - our busiest yet - with our public courses, private courses at Well House Manor and on site private courses all thriving - and we start the new year with a busy schedule with a few places available on most courses. Our business hotel enjoyed an excellent first year too, with many returning guests and "booking by recommendation" becoming something of the norm.

So I'm not messing with a winning formula this New Year's day with any big announcements for 2008. But I would like to tell you of a few refinements and updates which will help us move towards results - for our customers as well as ourselves - that are as good (or even better) in 2008 than they were in 2007.

• Computer Equipment

We have a new fleet of laptops that will be available for delegates to use on ALL of our courses - public and private - in the UK and Western Europe. We're finding that an increasing proportion (but not the majority) of our delegates prefer to use their own laptops in place of, or in addition to ours, and they'll continue to be welcome to do so throughout 2008 - connecting in to our networks and making use of our servers and internet connection as required.

• Software

Delegate's laptops are running Windows Vista, with Cygwin installed to provide a Linux look and feel. For users who prefer to work in a full Linux / Unix environment, they're dual boot ... with a choice of Novell SuSE, Red Hat Fedora or Ubuntu distributions. We also have Apple laptops running Mac OS X.

The subjects we teach - especially the programming languages - don't actually change all that quickly. You wouldn't want them to - after all, you want to safeguard your code development, don't you? So we have loaded our systems with the latest generally available releases, with significant older versions also to hand where they are still in common use. Major new generally available releases will be loaded through the year, but we do not track minor releases where they make little difference to the subject being taught.

• Course Subjects

We have run Java courses for many years, but with the wide variety of other providers available for public courses in this field, and our own setup being designed to handle niche subjects, we have been running private courses only on Java for the last year or two. However, many of our customers want to return to us to learn Java and - taking the most appropriate of our modules - we are introducing the following two public courses:

Java Bootcamp - An intesnse 4 day introduction to programming in Java.
Java Programming for the web - 5 days covering the "bootcamp" schedule plus databases, servlets and JSP

Java-related (for staff who will be deploying Java applications written by others) we continue to offer Deploying Apache httpd and Tomcat which is a two day course, and a five day course for users running Tomcat on Unix or Linux systems and new to those operating systems too - "Deploying Java applications on Linux and Unix".

But Java is just a very small part of our business! Our "bread and butter" programming courses are in Perl, PHP, Tcl/Tk and Python. Outside the programming area, our other courses include Linux and Web server topics and the MySQL database. To complete the list, less frequent courses are offered on C anc C++ and on Ruby

• How the courses run

We continue to run courses in three ways - public courses at our training centre (schedule), private courses at our centre (great for groups of 3 to 8 trainees) and on site which is ideal for a larger group of up to about 12.

We still write and maintain all of our material (and that's NOT about to change) and the course is presented by one of the people instrumental in that writing and maintenance - and who is a full time employee (and that's not about to change EITHER!) Group sizes on our public courses are limited to 8 delegates to ensure that everyone has plenty of time for questions, and more than enough access to the tutor if they need extra help. That's something else that won't be changing!

Delegates are welcome to attend our public courses on a residential or non residential basis. As most delegates choose to stay with us (and a lot of the others say "I wish I had known / how good your rooms are"), we are now listing the public course prices showing residential first ... it adds £60.00 per night for bed, breakfast, a room to what has been described as 4 star quality, unlimited soft drinks and coffee, unlimited internet access ... which we feel is a real bargain. And it means that you can continue practicals in the evening if you wish, socialize with other delegates, and save yourself the need to commute to our training centre.

On private courses on site, all you need to provide is a room and the students, and we'll do the rest - equipment (UK / Europe only) , notes, projector, tutor all arriving about an hour before the course starts on the first morning.

• Hotel

Well House Manor has become a popular overnight stop for visitors to Melksham coming to meetings as local businesses in the area. Our high quality rooms, bundled breakfast, internet access, etc, price us out of the "cheap bed for the night" market - but then that's not a market we ever intended to service, and before the lull over Christmas we were getting full on at least a weekly basis.

"Making business a pleasure" is our motto on the business hotel side, to which I might add "quiet quality". No major announcements here, but do note that if you want an early breakfast or a lift to or from the local station, or advise on what's what locally, we're happy to oblige.

• Events

At Well House Manor, we let our training and meeting rooms out to other companies and organisations - from training sessions, to interviews, through committee meetings to customer presentation sessions. We've been surprised as the widely differing range of uses our facilities have been put to - with groups sizes from 2 to 50! Please get in touch to let us know about your requirements and we can advise accordingly.

• Prices

We review our prices, annually, on 1st January. But they don't inevitably go up year on year, and this New Year's day (2008 in case anyone find an archived copy in years to come) I'm delighted to announce that we've held all of our prices, save for the expenses we charge when running a private on site course - these particular items are priced to reflect costs such as fuel and the cost of us staying away, both of which have risen sharply.

So that means:

Hotel rooms - double occupancy £95.00, single occupancy £80.00
These are the rates per night, including breakfast, internet access and VAT.

1 day course - £410.00 (residential), £350.00 (day delegate)
2 day course - £720.00 (residential), £600.00 (day delegate)
3 day course - £1030.00 (residential), £850.00 (day delegate)
4 day course - £1340.00 (residential), £1100.00 (day delegate)
5 day course - £1650.00 (residential), £1350.00 (day delegate)
A second and subsequent delegate booked on the same course (running same dates, same purchase order) attracts a discount of £100.00. These course prices do NOT include VAT.

 

For private courses at Well House Manor, we have a pricing matrix available, and if you would like a quotation for a private course on your site, please enter your postcode (UK), county (Ireland), country (rest of Europe) or zip code (USA) here:
 

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

Apple Mac Operating System OS X - code names and version numbers

Which is the more recent? Panther or Jaguar? Is Tiger current or has it been replaced by Puma? If you get confused by these code names for Mac OS X versions ... here's a convenient table that may help you.

ReleaseCodenameRelease Date
10.0CheetahMarch 2001
10.1PumaSeptember 2001
10.2JaguarAugust 2002
10.3PantherOctober 2003
10.4TigerApril 2005
10.5LeopardOctober 2007

Mac OS X is Apple's Unix based operating system featuring a superb desktop; it's very fully featured, user friendly and GUI based ... but at the same time provides excellent access to the underlying Unix for those who require it.

We have Apple Mac computers available for your use on our Perl, Python, Tcl, Tk and Expect, MySQL and other training courses ... for you to use in place of (or in addition to) computers running Microsoft's Windows Vista or Linux. You'll find that we actually rather like the Macs - our tutor will be using one as his demonstration and projection system on most courses!

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