« November 2008 | Main | January 2009 »

December 31, 2008

Review of 2008

The last day, of the last month. So a good day to look back to 2008.

On the training side, it's been "steady as she goes".

Our public courses (link to 2009 schedule) have been running all year at Well House Manor. New courses in Lua Programming and a more advanced PHP techniques Workshop were added to the schedule, and have been well received in their initial runs.

Private courses at Well House Manor have been run for a number of organisations and individuals, ranging from Java Bootcamps through to tailored versions of our Linux, Apache, MySQL and PHP / Perl Deployment course with all sort of other topics from Tomcat to Soap to basic programming techniques in between.

On site courses seem to have been closer to home than in previous years; a possible course in Malaysia came to nothing, for example. But I would like to thank customers in London, Norwich, Cambridge, Bristol, Nottingham, Milton Keynes and Liverpool amongst others for having me come and present training to them at their offices. See here for details of how such courses are run, and for pricing information.

Most of the delegates on our Melksham courses have stayed at our hotel (those who have not stayed being the 10 to 20% of delegates who live locally, or who have friends and relatives nearby), and that's meant that our courses have continued to be a complete learning experience and not just daytime classes and wasted evenings.

It's been the second complete year of Well House Manor

... and we've found ourselves filling something of a niche for business visitors to the town who are looking for a quite place to stay, where they can both relax and work and can come and go as they please - early arrivals off overnight flights from the USA don't worry us, nor late ones off the last flight into Bristol.

In 2007, with a newly opened business, the hotel had quiet weeks between courses but in 2008 we've seen a much higher room occupancy during those periods - and we've made a number of very good friends who come and stay when they're working in the area.

Moving from a business development to a continuing business situation, we've found that we've been getting increasingly more efficient in how we work at the Hotel. Some tasks such as the laundry which were initially outsourced have been brought in house without the need to add extra staff, and indeed a couple of the staff who helped us in the early setup days (and who were very good in that development role) have chosen to move on to take up other opportunities, and we have been able to absorb their ongoing work into existing schedules, all be it with some overtime and re-arrangement.

And more generally

I'm going to describe it as a year of quiet consolidation on the personal side too, with no major events to report. I've continued to be somewhat active in the community and with the campaign for improved public transport - especially rail - to our town. We had strong flags that we were likely to achieve something of a more sensible service that the current one, but the opportunity floundered once again and I have to say that the more cynical part of me wonders if the various organisations concerned have a policy of raising hopes and torpedoing them in the hope that campaigners will give up.

With local business organisations, the Federation of Small Businesses, North and West Wilts Branch has gone from bad to worse. You can find over a dozen articles I have written here if you're a member. A small handful of people in the organisation's elected and paid roles do themselves great credit, and it's been a pleasure to work with them, but I have better things to do in 2009 and you'll find few new reports from me about the absurd goings on because I simply won't be there.

Melksham's Chamber of Commerce and Industry also got itself into a pickle, and split between the Chamber on one hand and the town centre traders on the other, a number of years ago - before Lisa and I were around. Over the years since then, though, the Chamber has gently ticked along and - with the Wessex Association of Chambers - looks after business contacts and interests at a more local level in a way that the FSB totally fails (and isn't mandated!) to do, town by town and county by county. Lisa and I have been on the committee for a couple of years, and I was honoured to be elected to the role of President last month. You can find Chamber articles here and in this case there will be an ongoing flow in 2009. Indeed - there will be a lot happening and a lot for me to say, but as a representative of the Chamber of Commerce and not purely in a personal role - so I'm holding back until we meet up in the new year and I can go forward with a continued view or Melksham.

And on the personal side

The public domain of this review and forum really isn't the place to tell you about family life and disclose all those personal secrets; the years slow down some of the more mature ones of us, and some of the younger ones continue to bloom to fill roles and life's tasks over and above what the could have done 12 or 24 months ago. A trip with Lisa in September to Carlisle, Pennsylvania, to visit family and to attend her 35 years on school reunion, showed how this group of 400 has spread - some locally, some around the world. Some remain fit and healthy, other have had hips replaced and other medical issues, one or two are seriously ill and a some have passed away. And there are mother and fathers, grandmother and grandfathers, and I think we even met the odd "great".

Lisa and I continue to be "empty nesters" here at 404, The Spa, in Melksham and yet with family close by, and we hope to see other closely related, but geographically more distant, family here next year. And we continue to be naturally comfortable as a couple; everyone has there ups and downs (and I know I frustrate Lisa mightily at times!) but you'll find us here next year. And the year after. And the year after. I'm looking for words - and words fail me when they're REALLY important - to describe just how much Lisa means to me; how much I love her. How much I admire and care. So perhaps I had better just leave it with that as my sign off for 2008.

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

More about Graham Ellis of Well House Consultants

December 30, 2008

LinkedIn - Thrice Asked, and joined.

I admit it - I was something of a cynic when I got my first invite to join LinkedIn; I saw it as yet another idea / directory and felt that - although I should be networking - there's a limit to the number of profiles I can maintain, and to the amount of information I should put out there to fade, gently, out of date. But LinkedIn references keep coming up and a handful of people have invited me to join.

When telling the story of how we decided to write our first course at Well House Consultants (it was a Perl course), I describe how I told the first person who asked "look - that's a piece of free software, so who's going to pay for a course?". I told the second person that we weren't offering such a course. And to the third person I said "I keep telling people - there's no demand" ... and a bolt from the blue told me that there WAS a demand - I had three people proving it. Twelve years later, I can tell you that for every three people who ask you about a product that you don't advertise, there will be another thirty who are interested in the product but wouldn't even THINK of asking. And so we wrote our first course ... and Well House Consultants has move from being a £100 'shell' company to something much bigger - training courses, a hotel, meeting rooms, with an operation that's open from 06:30 to 22:00 through the week and a team of staff.

So ... when LinkedIn came up again (it's rather more than three times now!) this morning, I jumped in - took the plunge and entered my details. It does strike me as a system with excellent potential for keeping in touch / getting back in touch with long lost contacts, and for finding new people with whom we share aims and views, with whom we can exchange information, and perhaps work with or train to our mutual benefit.

If YOU are already a LinkedIn member, please visit my public page and feel free to contact me / add me to your connections. I'm not going to start sending round whole loads of invites to everyone in my mail box (I have the uneasy feeling that this would be too closely akin to spamming!) ... but I would welcome a build up of some connections.

If you are NOT already a LinkedIn member, you can still visit that public page, and you'll find you're getting invited to join, like I have just done. And I've joined at the free level; I expect I'll stick to that, but ... who knows, this may turn out to be the one in a hundred of those connections that becomes rather more.

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

December 29, 2008

Background to the TransWilts Train Fiasco

Management Summary - TransWilts Train service, linking largest Wiltshire population centres, growing rapidly but cut back to just 2 trains a day.

This is Article 1 of a series of 3.
Article 1 - Background to the TransWilts Train Fiasco
Article 2 - How much does a train service actually cost?
Article 3 - Why hasn't the fiasco been put right?

Have you ever tried to find out how much it costs to run a train service? In spite of the fact that the main purpose of railways these days is to provide a passenger travel service for you and me (the taxpayer), it's remarkably hard for you and me (the taxpayer) to find out what it actually costs. And just when you think you're starting to get somewhere / understand it, something changes of some other spanner gets throws in the works.

Let's take the case of the TransWilts line, linking Swindon to the four largest urban areas in Wiltshire - Salisbury, Trowbridge, Melksham and Chippenham. Growing at between 10% and 35% per annum, compound, from 2001 to 2006 it was never the less cut back to just 2 trips per day from 2007, with those trips running in what has been described as "marginal time" - in other words, at a time of day when the trains are spare from other lines. Yes, you can read that as "severely offpeak and totally inappropriate as far as passengers are concerned" if you like!

Since Summer 2005, Save The Train, The Melksham Railway Development Group, The West Wilts Rail User's Group, The First Great Western Coffeeshop, More Train, Less Strain, Travel Watch South West, Canber ... as well as many other more broadly focused organisations ... have been campaigning for the return of an appropriate service. And, yes, the first stages of this campaign were to spread awareness of the issue, and to define appropriate.

A quarter past six in the morning, and a quarter to seven at night, and nothing else, isn't an appropriate service. Everyone agrees with that; you will find some who say "may as well not run the trains at all" and - short term - that would might save First Great Western a little money in reduced crew hours and on payments to Network Rail for track access. But it would be largely a paper saving; the trains, crews, and track would still be there are would still be maintained and - in my view - keeping the current service as a base is sensible.

Who do we ask "what is appropriate"? We could try asking the man in the street. And he'll come up with anything from "no trains" to "every 15 minutes" depending on his personal view and narrow experience, largely influenced by marketing campaigns by all and sundry. Asking questions such as "what would cause you to use the train, and how much" is much more fruitful in terms of getting a real answer, though even there, statisticians will tell you that there's a need to debias the data given.

Better to ask the experts - but who are they? You have the Local Transport Authority (Wiltshire County Council), the Train Operating Company (First Great Western) and the Department for Transport as the overseeing / controlling authorities. And you have other major players such as Government Office South West and Network Rail who - although they are not controlling - have major inputs and (in the case of Network Rail at least) could effectively shunt any scheme into a siding if they were so minded.

The experts - the LTA, FGW and the DfT - come up with an "appropriate service" definition of a train every hour or two. Yes, I have written that somewhat vaguely as there's a spread of service levels involved - very largely depending on how far you look ahead, with all the major towns on the line growing very fast in the next 20 years. And by "very fast", I mean over 50%. Melksham to rise from 23,000 to over 30,000. Chippenham to become the current size of the City of Salisbury ...

But stepping up from a service run with zero trains (the train that's used for the marginal service is borrowed off the Stroud Valley line, serving the Labour constituencies in Swindon, Stroud and Gloucester, when they have through London services instead at those times!) to one that runs every hour and requires three trains to do that would be a huge leap, and would provide capacity early. Far better to add a single train 'set' to the current inappropriate service, at a third of the cost but - if carefully timed - gaining far more that one third of the potential income.

I started my article with a picture of a grape and a melon, and that provides a good comparison between the two options that we're looking at. The "grape" is much smaller that the melon, but much richer in goodness, gram for gram or pound for pound ... and this article is being written as a follow up to a campaigner on a related transport issue who asked me why on earth figures between 100k per annum and 800k per annum were all being quoted to him. (And if HE is confused about the pricing, pity the "Man on the Train"!).

Move forward to part 2 to see my "grape" and "melon" train pricing comparison

Article 1 - Background to the TransWilts Train Fiasco
Article 2 - How much does a train service actually cost?
Article 3 - Why hasn't the fiasco been put right?

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

How much does a train service actually cost

Management Summary - TransWilts Train service, linking largest Wiltshire population centres, growing rapidly but cut back to just 2 trains a day.

This is Article 2 of a series of 3.
Article 1 - Background to the TransWilts Train Fiasco
Article 2 - How much does a train service actually cost?
Article 3 - Why hasn't the fiasco been put right?

Here is my answer - slightly trimmed, written to a fellow transport campaigner and republished here as being in the general interest of the campaign and of ensuring that the answer is available somewhere in the public domain.


I'm following up on your email of a couple of days ago with regard to the pricing of a train service on the TransWilts line and how much / if a subsidy would be required. Figures ranging from under 100k per annum to nearly 3/4 of a million pounds have been quoted, and you (and you're not alone) are puzzled by how such different figures can be stated for what appears to be the same service. But it isn't - you're comparing a "grape" with a "melon"!

The Melon

Wiltshire (County) Council have presented a case to the Department for Transport that states that an hourly service on the TransWilts line would be appropriate. (Contact / Author - Xxxxx Xxxxxxx). Such a service, running on a single track railway most of the way from Chippenham to Trowbridge, and serving Swindon and Salisbury at its extremes, would require 3 trains.

The Grape

On current predictions, the hourly service is a good medium term goal. However, major service improvements which meet many of the requirements can be achieved with a single train running at approximately 3 hourly intervals, in addition to the two round trips which area already in the line and which would become part of the practical service as - in conjunction with additional trips - they would provide excellent out and back travel options currently missing.

On pricing quoted

The cost of providing a single train on the line, with crews and all charges, is around 800,000 pounds per annum.

With 125,000 journeys per annum (historic figure from when 5 trains per day were running, just before First cut them) at an average fare of 4 pounds per journey, that's an income of 500,000. And we could anticipate that with a service of 6 trains per day ("the grape"), a similar loading would be achieved. The usage had grown (5 year average) at between 10% and 35% compound (different measures) and even taking the lowest of these figures, you're looking at an extra 60% of traffic in five years.

An annual figure of between 100,000 and 125,000 pounds subsidy required from Wiltshire Council to First was quoted to me (at a meeting called by planning staff from those organisations, called by them) in February 2008. Under "Chatham House Rules", I cannot quote names, but you would probably be very familiar with them. It was explained to me that a half of that sum was actually to compensate for a loss of income from the earmarked train which is currently running a service that's competing with SWT between Salisbury and Southampton, generating First 60k of extra income under the ORCATS tradeoff system, basically money "grabbed" from SWT for passengers carried on the hourly SWT service.

At a further meeting three months later (different FGW players, same Council representative) a new figure of 300,000 pounds was presented, with an explanation that costs - such as fuel - had risen rapidly and a more cautious approach had to be taken. It was also explained that - contrary to expectation - passengers from Warminster, Westbury and Trowbridge to Chippenham and Swindon who had used the previous service had transferred to the route via Bath, in spite of a change of trains, and extended journey, overcrowding, and reliability issues. So the through business could not be counted in the way it was a few months earlier when looking at extra income the service would generate.

Comments on this pricing

a) Fuel costs have now reduced again, so I don't know where the 300k stands

b) Prices / figures quoted are 2008.

c) The fares on the line are significantly LOWER per mile than on most other train services; an increase of 20% above inflation would be sellable to users / future users with little loss of traffic and would provide an extra income of 100,000 (first year)

d) With a 10% compound growth rate and even assuming NO ABOVE INFLATION PRICE RISES, the income at 2008 prices in five years would be 800,000 per annum - in other words, you would have a break-even service even at these lowest recorded growth rates.

e) Trowbridge and Chippenham are both set to grow dramatically under the Regional Spatial Strategy - an extra 5000 homes in each of them. In Melksham, a further 750 homes are currently under way, and the site of the George Ward school, close to the station, will be redeveloped with around a further 250. (and that's just short term for Melksham).

On pricing the hourly service option

I have not seen the pricing details of this to the extent that I have seen the pricing option for the more limited option that has had consensus agreement as being the next step from the DfT, Network Rail, First and The County.

Cost-wise, logic says that you're looking at 2.4 million per annum, and the 800k subsidy quoted implies a farebox income of 1.6 million, equating to 400k journeys per annum. This sounds feasible in a year or two with good publicity. Other advantages of this scheme would include:

a) Half-hourly service Westbury to Salisbury, as identified by the County Council / expert reports produced for them.

b) Good service for the Dilton Marsh side of Westbury, where housing development is approaching the station and a direct hourly service to both Salisbury and Swindon, and to Bath and Bristol with a change of train, would encourage the new area to be public-transport based rather than car based

c) Significant transfer of journeys along the Salisbury / Warminster / Trowbridge / Melksham / Chippenham / Swindon corridor from road to rail would reduce road conjestion and consequent delays along the corridor. The road is already overcrowded and otherwise unsuitable in parts, to the extent that major expenditure has been proposed for its improvement.


Move on to part 3 to learn just why even the simpler and lower cost option hasn't been implemented - why it's like "pulling teeth" to get a sensible resolution to a currently nonsensical service.

Article 1 - Background to the TransWilts Train Fiasco
Article 2 - How much does a train service actually cost?
Article 3 - Why hasn't the fiasco been put right?

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

Why hasnt the fiasco been put right

Management Summary - TransWilts Train service, linking largest Wiltshire population centres, growing rapidly but cut back to just 2 trains a day.

This is Article 3 of a series of 3.
Article 1 - Background to the TransWilts Train Fiasco
Article 2 - How much does a train service actually cost?
Article 3 - Why hasn't the fiasco been put right?

I have been asked the following question on a number of occasions:

"If the service that you're backing really IS appropriate, surely it would have been part of the original service specified by the Department for Transport, and even if they had got it wrong it would have been corrected by now ...". I wish!

The current level of service was specified by a body called the SRA - the Strategic Rail Authority - in their dying days; heavily pushed towards a franchise system that maximised profit payable to The Treasury, they took unduly pessimistic growth and traffic figures for smaller lines, and in the particular case of the TransWilts that was a double tragedy as service improvements shortly before their surveys had started a spectacular (up to 35% per annum) growth but at the point of th surveys this hadn't been fully translated into passenger numbers. The triple tragedy is that it WAS translated into some pretty busy trains in the years between the stats being gathered and the new "reduced" service introduction.

As a result of the SRA specification and competitive bids by three companies, won by the First group, one sixth of the income from all rail fares in the South West over the 10 years of the franchise has to be paid to the government - in effect a tax on the traveller. And also, in effect, a raising of the profit threshold that much be made by the average train service. Quite simply, the SRA specification and the way that First chose to bid it has raised the bar so high that it doesn't make sense for First to run services that make only a small operational profit - they need a big profit. Emotively, I could compare it to The SRA setting up a system where they award the nice cushy job to the person who's prepared to pay the most protection money.

First's problems in serving the passenger first (!) are not limited to the need to pay crippling financial sums to the treasury (and, be warned, they kick in much more in 2009, then 2010!). They also have to lease the trains they run from a handful or organisations - the RoSCOs - who bought them from British Rail at privatisation and now, in a growing rail market, are sitting on a scarce commodity for which they can charge a very profitable price. Progressively tougher health, safety and access issues also add a further - and very significant burden; it's always tough to argue against safety improvements, but we now have the absurd situation where rail projects are lost on safety costs, and pushing traffic onto the much LESS safe roads. Oh - and First also have to ensure that they make enough money to pay their shareholders; at their AGM, they proudly state that they're improving dividend payments by 10% per annum ... and that money comes from their passengers and is NOT being spent on improving the service / keeping feeder service running as it would have been in the past.

I mentioned that the SRA had gone, didn't I? Their operation was taken over directly by the Department for Transport (Rail), who you'll see I've commented on earlier. There are largely the same staff in place (so you're not going to find that they'll say "The SRA got it wrong" as they would be admitting to their own errors) - civil servants who are largely guided by the politics of their Labour ministers. Since the summer of 2005 alone, we've had Alastair Darling, Douglas Alexander, Ruth Kelly and (now) Geoff Hoon as the Cabinet Minister at the Department. And we've had Derek Twigg, Tom Harris and (now) Andrew Adonis as the minister for Rail. All very bright people who have done well for themselves, yet little very limited prior transport skills and in many cases not even elected by people who's rail service they control (it always strikes me as undemocratic that a Minister for Rail often represents a Scottish seat, or sits in The Lords, when the Department only controls rail service in England, having devolved the Welsh and Scotch systems to their local parliaments!).

Let's look at Wiltshire County Council - the third key player. The council ceases to exist on 1st April, and is replaced by a Unitary Authority - with all the same people in charge, but taking over district councils. At present, they're busy spending 12 million on new IT systems, and jostling each other for the new jobs in the new authority. The council has a reputation for being "anti-rail", and that reputation is not helped by their view that it is for government and not them (even though they are the Local Transport Authority) to subsidise rail. The question has been asked of them "if it's not your job to tune government dictat of local conditions, what IS you job?" ... pointing out to them examples in Cornawll, Devon, Bristol, Hampshire ... but the question has been met with a deafening silence. Rail improvements - at a tidy price - would lessen the case for road improvements along the corridor, and one or two key elected representatives who hold sway over all of Wiltshire are very determined indeed to get those other schemes through, so will always look to kick plans into the long grass. A report to be commissioned last MAY to review the service hasn't even been awarded yet as far as I can tell. By the time it reports, it will be too late for the December 2009 service. And I believe that this is a calculated delay, wrapped up in the sweetener of "we have to be careful how we spend money" ...

Look at Wiltshire Council, at First and at the Department for Transport, and the position that the system has put them in, and it's little wonder that the grossly inappropriate service that was sneaked into the SRA document hasn't been changed to something more appropriate.

Indeed - what IS a miracle is that the service shown here was drawn up (by First), validated (by Network Rail), and accepted and encouraged as sensible approach (by the DtT and Wiltshire Council). There are very good people working at all of those organisations, and I applaud their work.

The story is an ongoing one. "Keep at it ... you'll get it in a year or two" said one of our professional contacts in the summer, just after we had lost the December opportunity. Yes - the campaign will keep on going, and the objective achieved. But the "you" who will get it won't be me or the other campaigners; the people who get their service will be the people of Wiltshire, and the people who visit this lovely county.

Article 1 - Background to the TransWilts Train Fiasco
Article 2 - How much does a train service actually cost?
Article 3 - Why hasn't the fiasco been put right?

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

December 28, 2008

Best source to learn Java (or Perl or PHP or Python)

An impossible question - there is no best way - yet it's one that I'm asked from time to time. [["Hello. I'm doing a b.tech. My friends like ur site very much. Plz help us in Java programming - plz tell me about the best source to learn Java"]]

So do I answer such questions, and if so, how? Firstly - YES - I make a point of answering emails which are written individually; although there may not be an immediate business point in doing so, you never know when you'll come across this person again, or who he / she may recommend you to. "Treat others as you would like to be treated yourself" ... but this is a personal comment, and digressing from the theme of the subject line.

When you're looking to learn, you are putting the filling in a sandwich - between what you already know, and what you want of need to know, and in order to establish your training requirements, you should think about those two points.

Beginning Point ... have you any prior experience (from a "learning a programming language" view point, that means asking if you have programmed before, and if so whether you've just dabbled, or if you're an experienced code. And it also means asking whether or not you have experience in a similar language, or if any experience is in something very different. You might even have made some attempts to study the language that you're asking me about and have failed to grasp it, or some specific issues, or you might be looking for more advanced training only.

Ending Point Are you learning with a specific job role in mind? For a particular project that you want to undertake as a hobby, as part of an academic program (i.e. to pass an exam) after which you'll make little use of your skill? And if you're heading for a specific job role, which are the important aspects of the subject - are you learning for a code maintenance role, for a specification role, or for something in between?

Logistics and Economics How long do you have - are you looking for something short and sharp, or a learning program that will last over a considerable period? Are you able to arrange your schedule to be available at certain times, and are you able to travel to specific locations? Are they nearby? And you'll need time, determination and commitment to learn, but there's something of a tradeoff between these three and money (and time is money if you're learning in a work situation. a little money will buy you a book, and rather more money will buy you a course.

Learning Methods. Some of us learn best with our peers, and others learn best alone. Some can read from a screen, and others from a book. Some need to "get away" to concentrate on learning, and others can learn with the office hubbub, the screaming child, or the railway announcer telling us that the next station is Pontypridd.

So with all of these variables, it was impossible for me to say to my correspondent "the best way to learn Java IS ..."; I could only suggest that he listened carefully to the advise of lecturers on his B Tech course (who, after all, should know many of the answers above!) and followed a few of our links to help with backup. I also pointed him towards:

Our own Java training notes which are available for download from:
http://www.training-notes.co.uk/java.html

Resources classified by subject - starting (for Java) at:
http://www.wellho.net/resources/J601.html

And there are many resources on our main web site at
http://www.wellho.net/

There is a very wide variety of books - and we list about 50 at:
http://www.wellho.net/booktopic/Java.html


Did I recommend our training courses, then?. No, I didn't. Even from the short enquiry, I read that my correspondent is undertaking an academic course already, where a second thread of learning would probably confuse rather than clarify. I also noted that English, in which we teach our courses, wasn't his mother tongue and that one of our courses would be frustrating for him, for the tutor, and for other delegates on the course. Finally, I noted from his email address that he lives half a world away, and it just wouldn't make sense for his to come all this way. Courses are NOT for everyone, and where there's multiple reasons they don't fit, I won't sell them - that would be a dis-service to everyone!

But I suppose I should finish off, dear reader, with some links to our courses; if you're fluent in English, and time is of the essence in your learning of Java or Perl or PHP or Python ... then they may very well be the best source to learn.

Python CoursesPerl CoursesPHP CoursesJava Courses

See here or here for sandwich making instructions

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


Useful links: Python training, Perl training, PHP training, Java training

December 27, 2008

Index Card System for Game Characters in PHP

A couple of days ago, I received a request for a PHP demonstration in which the web site owner could enter a character's name in a game, and something about the character, and have that information stored as a web page for later reference under the character's name.

It's easy enough to write a basic program - in fact I have written one and put the source here. Security is quite another matter, as it's also very easy to write such an application that will leave you open to injection attacks and all sorts of nasties (which is why my example checks our Well House Consultants staff cookie, so that we can update the page but you can't, Mr Joe Public).

There are also the questions like "how do I edit the data, then" and "How do I attach an image", "How do I delete a card", "How do I sort and search" .... none of which I was asked ;-) ... They're all perfectly do-able, and in fact we cover such things on our PHP Programming course and our PHP Techniques Workshop which I'm looking forward to running again in the new year.

Further links - Data Entry page (locked down, I'm afraid!) and Card Index.

Note - if you keep data about real people (or perhaps even the characters that they play in a game) on a system like this, and especially if it's public facing, you need to be aware of legal issues such as the UK's Data Protection Act.

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


Useful link: PHP training

December 26, 2008

Making our things easier to find

The gap from end-of-training a week before Christmas to start-of-training in the new year is a chance to catch up on some non-urgent, but never the less important things; catching up with family and on the personal side, as a starter (and that's somewhat away from this blog) but also with things like search engine placement.

Those of you who read this after being on a PHP course - or one of our other public courses - may have heard me describe who getting a good web site placement is rather like driving a gigantic oil tanker. You put what feels like a lot of effort in for a very long time, turning what feels like a stupidly silly little propeller and slowly - oh SO slowly - the propeller starts to move the ship forward. And my goodness me - you had better be careful that you're running it in the right direction because turning will take an awful lot of effort later on!

And you do need to keep turning that propeller to - there's a daily "twist" here, and I try to update a handful of other pages most days too. And at times it's worthwhile doing a more radical update. That sometimes needs research, and that's one of these non-urgent issues that I've plugged away at for a few hours today.

If you have a look here you'll see s scruffy page of mixed up links. And if you fill a word into the field on the form there, you'll see a selection of other links. Does it look good? No - it doesn't, but it's not intended to - it's my research, where I'm looking at the relative ranking of our pages; that's something you can now report to the search engines via a sitemap file, and I'm working on algorithms to classify the best part of 10,000 URLs automatically.

This work is ongoing, and it will be so for a while. As a subsidiary effect, it will help me monitor the usage, fade in and fade out of popularity of our pages, but you probably won't see it much, nor hear much more about it. Come to think of it, when you travel on the local bus you're not often aware of where it's fuelled and how it's serviced, and when you stay at our hotel you probably don't think about where the laundry's done ... so you're probably not too concerned at our SEO algorithms - just that you can find what you need here on our web site.

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

December 25, 2008

Christmas Survivors

There's a genre of TV shows - the post-catastrophe ones - where small group(s) of people from many walks of life are all that are left after some event. Be it from a world-shattering physical disaster, a virus or an aircraft crash, we see and learn about people and how they learn about each other, mix, meld, and fight in amongst the lonest, quietest of environments - a backdrop of empty beaches or abandoned cities with no-one to be seen.

There's something about Christmas day. I was up and about (and out) before first light. And I was just about the only one. Hardly a vehicle moving (just me at first, as I drove up to Bowerhill, then just the occasional vehicle venturing along the usually-busy roads, as if exploring and looking for some supply, some friendly group, or to avoid some nasty gang as if in one of those "Survivor" films.

The garage, usually bustling from 06:00 through to 22:00, was switched off. And my automatic check for traffic as I walked across the entrance was more habit than necessary; but many was the safe clue - there's not been some major overnight catastrophe and everyone was tucked up safely at home. Places are shut and not vandalised. Lights remain on. And at The Manor, Chris had breakfast prepared for our over-half-full hotel. And The Internet is working too.

Look carefully, and you see signs that Santa and his helpers have been around during the night; I'm suspecting that Rudolf has something of a red nose this morning, and that Santa will be nursing the most massive headache after drinking all those glasses of sherry.

Will we survive Christmas? Of course we will - in fact we'll thrive. Because so many things change at Christmas, it can be a time of tension and events and happenings, but it can also be a time of mending bridges, and of taking just those few extra minutes to be with friends, with family - of if not able to be with them, to think, remember how you care for them.

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

December 24, 2008

-

Happy Christmas!





Guess who's around tonight!

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

December 23, 2008

PHP - Parse error: syntax error, unexpected $end ...

Have you ever had an irritating PHP message that says "parse error" or "syntax" error and little else - and points to $end / the last line of your PHP file which is (a) perfectly ok and (b) probably HTML anyway? Something like this:

Dorothy:~ grahamellis$ php floppy
 
Parse error: syntax error, unexpected $end in /Users/grahamellis/floppy on line 56
Dorothy:~ grahamellis$

The problem is very likely to be a missing close brace - } - in other words, an if or while, a function or class or something similar isn't completed.

How do you find out just where the problem lies in what could be a big file?

a) Think about what you have just changed since you last ran the PHP - that will give you immediate pointers

b) If you're using an editor such as vi, my personal trick is to add in an extra } at the end of my code, then use the % command to find the matching bracket; it may not be exactly the problem one, but it's a good pointer to the area of concern in the code.

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


Useful link: PHP training

December 22, 2008

Why are cooks bad tempered?

I've heard it said that cooks are bad tempered because they spend all of their time creating art in food, just to have it destroyed when it's eaten ...

Odd comment.

Odd opposite.

I served breakfast this morning (hey, the first Monday in *months* I wasn't training, and they say a change is as good as a rest!). And here's how the breakfast table ended up.

Am I bad tempered and disappointed at having my setup destroyed? No - quite the reverse, I'm delighted that my customers were very happy with their breakfast, did an "Oliver Twist" and asked for more that we were happy to provide ... and will be staying with us again next year when they're in town again.

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

December 21, 2008

Images for Christmas

For just the winter holiday season, we'll be changing the image in our page header at seven minutes after five each morning. Will we be up at that time, then? Well - we might be but to make it consistent, we're using a crontab job on the server.

This is the regular image ...

And this is the image that we're showing today ...

I have to admit that after 30th December, this post is going to look a trifle boring. If you want to click here, here and here, you'll see the images for the holiday season. And here are the crontab lines ... as examples.

7 5 18,21,24,27,30 12 * cp /home/(dirname)/tdv.jpg /home/(dirname)/WHClogoBW.jpg
7 5 19,22,25,28 12 * cp /home/(dirname)/tsc.jpg /home/(dirname)/WHClogoBW.jpg
7 5 20,23,26,29 12 * cp /home/(dirname)/tho.jpg /home/(dirname)/WHClogoBW.jpg
7 5 31 12 * cp /home/(dirname)/WHClogoRegular.jpg /home/(dirname)/WHClogoBW.jpg

The first three lines rotate the images from 18th to 30th December each year, and the final line switches it back on New Year's Eve.

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

December 20, 2008

How to avoid duplicating web page maintainance

How do you move from a web site with a single static page to a web site with a thousand pages (URLs) without multiplying your maintainance work by a thousand? Such is the critical importance of being able to do this that there are many schemes available - many solutions - and virtually every site that's more than a single shop front window uses them. Here are some of the techniques:

Scripted Content Generation Where a program that's run whenever [part of] the web site is updated regenerates the individual static .html files.

Site Management Programs Where a static .html page is generated by a program that a content provider submits.

Style Sheets Where the look and feel that's been developed for one page is carried across many others.

Include Files Where a page is held on the server in "HTML++" - that's html with extra bits such as SSI, PHP, ASP, JSP, Mason, Rails which are interpreted by the server before it's passed to the browser allowing a single piece of content to be maintained for insertion in many pages

URL rewriting Where a whole number of apparently different static .html pages are actually served by a single page or program that produces a response based in part on the name of the page to be served.

Under the Apache httpd web server, URL rewriting is performed by mod_rewrite. See mod_rewrite for newcomers for further details of this (that's really the second part of this article)

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

mod_rewrite for newcomers

What is mod_rewrite?

It's an Apache httpd (web server) module that takes user's requests for pages and diverts them to a resource of a different name (and perhaps type). Why might we want to do this? See previous article for some reasons and alternatives

Here's a simple example of a rewrite rule:

RewriteRule ^train_running.html$ running.html

And that tells the web server to divert requests to train_running.html to running.html instead. We've used rewrite rules as simple as this one to divert links that people have kindly made to our site - but got wrong - to the correct resource:

RewriteRule ^5704.html$ J704.html

But there's much more to mod_rewrite than that as you'll see if you look at the official manual. Actually, there's so much more that I'll give you some further examples - each taken from our web site.

When reading these examples, please bear in mind that you can place them in your httpd.conf main Apache Configuration file if you wish them to propagate through the whole of your site, or in an individual .htaccess file in the directories to which you wish them to apply. Your server administrator has the ability to enable / disable .htaccess, and what may and may not be placed in it

One final introductory note - the incoming URL is specified in the form or a regular expression (a pattern). At its most basic, most characters match one for one to the URL but there are a number of "specials" such as anchors ^ and $ that mean "starting with" and "ending with", character groups such as . which means "any character" and counts such as * which means "0 or more of the preceding item". Round brackets have multiple meanings within regular expressions; you'll see them in my examples below, used to capture parts of the incoming URL to substitute it into the rewritten one. We offer a day's course on Regular Expressions.

Collapsing a whole directory of web pages to a single script

RewriteRule ^(.*)\.html$ /share/index.php?pagename=$1

All requests that end in .html in the area that the .htaccess or httpd.conf file controls are to be passed on to a single PHP script in the /share/ directory called index.php. The name of the page that was passed in to this PHP script is to be placed in a request parameter called pagename.

This is the mechanism we use in our "wiki" ... where (after validation to avoid injection attacks), the following SQL query is run:

mysql_query("select * from sharedata where pagename = '$_REQUEST[pagename]'");

and the fields from the database are used to populate a single template.

Taking all .htm and .html files and passing them on, including GET data filled in to forms

^(.*)\.htm 8.php?pagename=index&sharename=$1&%{QUERY_STRING}

This is an extended example of passing all .htm (and .html) URLs in a directory on to a single script, with various parameters being passed in too, and any data that was submitted via the GET method appended on to the end. Note that by leaving off the $ on the pattern for the incoming URL, you're able to overcome any ".htm or .html" issues. We do the same thing for .php / .php3 / .php4 / .php5 ...

Diverting the home page of a directory

RewriteRule ^$ 8.php?pagename=index&sharename=index&%{QUERY_STRING}

The Regular expression here is "start with and ends right away", so that's a request for a directory rather than anything in a directory.

Referring image requests on to a database via a program

RewriteRule ^(.*)\.jpg /pix/feeder.php?image=$1&%{QUERY_STRING}

All .jpg requests are passed on to a PHP script, with the image name passed in as a parameter. Why do we do this?

• it saves a directory with a large number of pictures getting cluttered
• it allows us to monitor where images are loaded from (the referer) so highlighting any images hotlinked from other web sites
• it allows us to generate dynamic images (for example, this diagram of current train cancellations on First Great Western ;-) )
• it allows us to feed out low res or high res alternatives
• it allows us t maintain image data with the image
• and it allows us to use selected URLs to generate a random image.

Handling a special case - something NOT to rewrite

RewriteRule ^rooms.html rooms.html?%{QUERY_STRING} [L]

Where you have a whole directory / pattern being rewritten and you want to make exceptions, you can do so. In this example, there really is a file called rooms.html that you want to serve! The [L] modifier means "Last" and instructs the httpd web server that it should skip the following rules if this rule has been applied - very useful indeed in preventing some utterly confusing situations!

Rewriting that calls up a page from another server

RewriteRule ^info.php http://www.wellho.info/ [L,P]

This example - with a complete URL in the target position and a [P] modifier, proxies (see mod_proxy) the request on to a different URL on a different computer. Your web server actually becomes a client as it retrieves the page from the other system, and in turn it passes it back to your client. So the following two links will return the same .html source:

http://www.wellho.net/demo/info.php
http://www.wellho.info/

Indeed they do return the same source, but you'll need to be very careful indeed of any site-relative links, references to style sheets and images, etc - but mod_proxy is a story for another day!

Other directives in mod_rewrite

As well as RewriteRule directives, you'll also need to make use of a RewriteEngine directive to turn the facility on. The RewriteCond directive allows you to apply a condition to the following RewriteRule, and the RewriteLog allows you to produce a log file of rewrite requests. You can use a RewriteMap directive to call in a separate file of mappings, and that can even include random proxy forwards; what sounds (at first) like a crazy idea actually provides a neat way of spreading your processor load on heavy web based applications around a number of servers - there's a complete example here of forwarding Java requests from Apache httpd to multiple instances of Tomcat.

We cover the configuration of Apache httpd on our Linux Web Server course ... and there's a lot more that you can do other than just mod_rewrite!

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

End of Training, 2008

Yesterday was the end of training for 2008 - the final Perl on the Web course for the year ran, and we're into our low / quiet season ... for training IS seasonal, with a low season from mid December through to mid January, from where business picks up and we'll be "all hands on deck" again by Valentine's. Why the slow pick-up in the new year? For many people, Christmas and the New Year is the target they're working towards, and they don't plan ahead to the next working year until that new year actually arrives, and then there's the average lead time of some 6 to 8 weeks between thinking about and actually taking a course. Yet, this year, we'll be moving into the new year with a healthier booking list than has been typical in the past. So - what will 2009 bring?

I stopped on the way home last night from dropping Dad off in Devizes and took some pictures. And - with our local Woollies closing down, with MFI gone, I mused as to how our High Streets and trading parks will be by this time next year. This is Somerfield in Devizes; Morrisons, Sainsbury, Lidl and Tesco all compete with them in a town that's considerably smaller than Melksham and that's a story that's repeated across the country. Can they all survive? The logic says "people will always need food", but perhaps we will see a shake-out with some mergers and closures - and is that a bad thing if the more efficient stores are left? Where would we be today if we hadn't grasped the nettle of the petrol engine but had stuck with steam?

The banking sector has been rocked (or "derocked" if you thing of Northern Rock) this year from global Tsunami to localised eruptions which have sent out distant shock waves. Some of the banks have been seen to have had practises and policies that were unwise to put it mildly, where others (such as HSBC) have fared much better - but even with HSBC, there's been to many issues in the sector that they haven't exactly got away without some major injuries. And when a bank's customers are sick, it makes the banks sick too. Will 2009 bring more back door nationalisation of the banks? Do we really need quite so many competing front doors on the streets of our towns, let alone so many on line deals from Iceland to The Netherlands to the Isle of Man?

On Teletext last night (we fell asleep with the TV on!), I saw that a survey showed that more than 70% of people surveyed didn't believe in the Nativity, and that lack of belief group included quite a lot of people who declared themselves to be Christians. Whence The Church in 2009? I don't know; I severely lack knowledge and fore site in this area. One part of me looks at the numbers of already-retired churches surplus to requirements and wonders if more will join them. And the other part of me wonders if more people in hard economic times will turn to Religion, and which religious communities will be ready to welcome and support them. I have little doubt that the buildings themselves will remain - most are listed buildings, and one of the things that seems to flourish whatever the state of the country is rules and bureaucracy!

But amongst the quietening of the High Steets shops and services, and perhaps of other walks of life too, there remain shoots of growth. Melksham Oak Community School is well under way, and due to open in less that 2 years, on the outskirts of the town. And Trowbridge, Chippenham and Melksham are all set to grow by over 35% in the next 16 years. Perhaps the recession and the thinning out of the tireder old services will clear the ground for the new - public transport that's appropriate enough for people to want to use it. Cars which - for the remaining journeys - are no longer build as gas-guzzlers that have built in obsolescence after two years (at least in the eye of the driver) and can last for 5 or 10. And more activities which actually cut the needs for some of the excesses - like that silly daily hour commuting! [BBC piece - Londoners commute 225 hours a year on average]

Well House Manor - Hotel Rooms still available over Christmas and the New Year, and at delegate rate for past trainees. Well House Consultants - book now for our 2009 public courses

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

December 19, 2008

Small Print

From an email just received:

This message and any associated files, is intended only for the purpose of conveying SEASONS GREETINGS to the individual or entity (gosh that's rude - ENTITY!!!) to which it is addressed and does not contain information that is confidential, subject to copyright or legal privilege, constitutes a trade secret or otherwise protected by other legal rules. If you are not the intended recipient it doesn't matter and you are hereby notified that we wish you a MERRY CHRISTMAS AND A HAPPY NEW YEAR and any use, perusal, dissemination, copying or distribution of this message, or files associated with this message, is strictly encouraged. If you received this message in error then we also wish you a MERRY CHRISTMAS AND A HAPPY NEW YEAR and there is absolutely no need to notify us immediately by e-mail, fax or telephone, or destroy the original message. Thank you.

Thank You Colin ... I guess that means that you're happy for me to give you a 'plug' too .... your contact details are T: 0845 094 3558 E: design@chdesign.co.uk W: www.chdesign.co.uk and it's been a delight to work with you in lots of different roles in 2008, and we look forward to more in 2009. Have a great Christmas!

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

December 18, 2008

Whisky - Setting and reading cookies from Perl

Fancy a Whisky - if you click on this link, our barman will choose a glass of whisky at random for you, and give it you on the house. Once you're hooked and secured as a customer, he'll sell you further glasses of the same whisky, remembering how many you've had and which is 'your' tipple. Just keep following the link and see him keep count (and keep sober) as you get successively more inebriated!

It's done through a Perl script which sets up cookies which are submitted to our server at each subsequent call to the page. In fact, the example is an old one that I dredged up to demonstrate this afternoon - Cookies in Perl from first principles. You can see the source code here and the course details for next year here. With Christmas being celebrated a week today, this is my final course of 2008!

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


Useful link: Perl training

Copyright of Training Notes and Web Site

Q: "How can I use your training notes?"

On one hand, we invest a lot of time and money writing training notes, and we need to recoup that investment - did you realise that it's commonly accepted that every 1 hour of new training material in our industry requires 10 hours of preparation?. But on the other hand, we want those notes to be used (and available for easy use too) by our customers ... and to give something back to the community too by releasing some training notes, and other technical articles, for more general use. It's a fine line to draw!

Printed Notes

Our printed notes all state the following:

Notice of Rights

All rights reserved. No part of this manual, including interior design, may be reproduced or translated into any language in any form, or transmitted in any form or by any means electronic, mechanical, photocopying, recording or otherwise, without prior written permission of Well House Consultants except in the case of brief quotations embodied in critical articles and reviews. For more information on getting permission for reprints and excerpts, contact Graham Ellis at Well House Consultants.

This manual is subject to the condition that it shall not, by way of trade or otherwise, be lent, sold, hired out or otherwise circulated without the publisher's prior consent, incomplete nor in any form of binding or cover other than in which it is published and without a similar condition including this condition being imposed on the subsequent receiver.

Notice of Liability

All brand names and product names used in this book are trade names, service marks, trademarks or registered trademarks of their respective owners. Well House Consultants is not associated with any product or vendor in this book and where such designations appear in this book, and Well House Consultants was aware of a trademark claim, the designations have been appropriately capitalised. Well House Consultants cannot attest to the accuracy of this information and use of a term should not be regarded as affecting the validity of any trademark or service mark.

The information in this book is distributed on an "as is" basis, without warranty. Whilst every precaution has been taken in the preparation of this manual, neither the author nor Well House Consultants assumes responsibility for errors or omissions, nor shall be liable to any person or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly by the instructions contained in this book or by the computer software and hardware products described herein.

And what does that mean?

Firstly, that they ARE 'just' training notes, and that many of the examples will be showing proof of concept or learning examples - so it's up to the person who makes use of them to ensure they're correct, relevant and secure for his or her own use.

Secondly, that although our customers are very welcome to use the notes, they really shouldn't start taking copies (especially of just parts of them, missing the above statements!) ... and they certainly shouldn't start circulating them widely or in ways that we haven't approved.

Electronic Notes

We do not publish all of our notes in electronic form, but some of them are available under three different arrangements.

a) For trainees who have difficulty using paper notes, we provide on a case by case basis individual (watermarked) copies of the notes for the courses they attend, for their own use.

b) We provide our entire Java course (and some other training modules too) under an Open Training Notes License. The download site for these is at http://www.training-notes.co.uk/.

c) Potential customers occasionally ask to see a sample of our notes prior to booking their first course, and for such customers we have placed a sample chapter from each major subject we teach here in our download centre. These samples are subject to our usual web site copyright rules which you will find here.

For these latter items (case (c)), and for everything else on this site which is not a special case as listed above, the copyright statement starts:

Material on this web site is Copyright 2008, Well House Consultants Ltd. You may view and print the material for your own personal use, or for your use in your employment EXCLUDING the training of others for any form of financial gain, direct or indirect. You may not save any information from this page in electronic form (save for storage in caches, proxies, and backups thereof), nor copy nor modify the information in any way without our prior written consent.

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

December 17, 2008

Nuclear Physics comes to our web site

One of the major projects that we'll be undertaking in the near future is aimed at improving the findability of information on our site - you shouldn't need to know that you need a blog article dated 2nd Feb 2007 to find about the difference between a comparator and comparable in Java, nor to look up on page /resources/Q907.html to find out about object oriented design - there should be an easier way.

And what better way than to actually use an Object Oriented approach where each of the "Pieces of Content" on the web site can be accessed through the same API (Application Programmer Interface)? Then - whether it's on The Horse's Mouth Blog, in the longer articles of the solution centre, part of a course description or somewhere in the Forum you should be able to find it by keyword or description, and further more have a ranked list of other pieces of content ("poc"s) that may also be relevant offered to you, irrespective of the particular subclass that they belong to.

On yesterday's Perl for larger Projects course, which covers Object Orientation in Perl as one of its key subjects, I took my "poc" project as an example and came up with something of a concept test / spike solution for the first algorithms that we may use. Starting with a series of function calls, we moved on to an object oriented example, showing off most of the features of Perl's OO model - all the "usual OO stuff", plus autoloaders, exporters and the rest. I've added the full series of examples written on to our web site ... so you can look at the source of each stage if you wish; it made an excellent teaching tool:

1. Use of a package
2. Encapsulate code, and add strict checking
3. Adding OO notations
4. AUTOLOAD
5. A list of objects
6. Setters and Getters
7. Inherited classes, and an Exporter
8. and 9. The final demo - the test program to go with ... the Perl module and the two classes

So where does the nuclear physics come in? Well - I've chosen to define an initial ranking for each piece of content, and a "halflife" - the number of days in which it decays to having just a half of its initial significance, as per the decay of a radioactive isotope. Here's the algorithm if you're interesed:
  sub getrank {
  my ($current) = @_;
  my $now = time();
  my $age_in_days = ($now - $current->{otime}) / 3600 / 24;
  my $decaysteps = $age_in_days / $current->{halflife};
  $decaysteps < 0 and $decaysteps = 0; # future content!
  my $decayfactor = 0.5 ** $decaysteps;
  my $rank = sprintf("%.2f",$current->{orank} * $decayfactor);
  return $rank; }

but of course that's going to be encapsulated within the class and "Joe Public" visiting our site - our even our content providers - will be gloriously unaware of the mathematics!


No - the general visitor will be much more interested in the titles and ranking of the pages, as illustrated by running our test program:

Dorothy:plpw grahamellis$ perl poctest
The Vet who liked horse meat
rank is 15.00 down from 15
Copyright, Well House Consultants
 
MySQL left join - howto
rank is 73.82 down from 95
Copyright, Well House Consultants
 
Contacts at Well House Consultants
rank is 95.00 down from 95
Copyright, Well House Consultants
 
Perl for Deep Sea Divers
rank is 50.00 down from 50
Copyright, Well House Consultants
 
95.00 - Contacts at Well House Consultants
73.82 - MySQL left join - howto
50.00 - Perl for Deep Sea Divers
15.00 - The Vet who liked horse meat
Attributes supported - comment halflife orank otime author title
Dorothy:plpw grahamellis$

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

Blame Culture

Why is it that people can't admit to making mistakes, but rather want to shift the blame on to someone else even when the responsibility should lie on their, or their company's shoulders?

This came to my mind this morning as I have a handful of particularly frustrating incidents over the past couple of days, with a very famous coffee supply company - one with a 300 year history - making aggressive phone calls for the umpteenth time to chase up late payment of a bill which was paid, in full, within 3 days of them submitting it. Has to be our fault that they screwed up the paperwork, blaming us first for non payment, then the move when that excuse was blown out the water, then having nothing to say when it was pointed out we had already had a similar call after their move, emailed and written to confirm, and they hadn't even been polite enough to reply. Even after 300 years, I am sorely tempted to find a new supplier.

The reason another company hasn't paid our invoices for course run in October is because we hadn't changed the company name on the invoice to them when they took over another company and added three letters to their combined name. That was 2 weeks ago and we have resubmitted with those extra magical letters, but the guy there's not answering emails nor returning calls, so I smell more problems.

And it's particularly frustrating at times to ask xxx "when was yyy last done" and to be told that zzz should have done it, even though it's clearly not been done for quite a while and xxx has signed off on having done it very recently indeed.

I guess that when people feel defensive and insecure, it's the most natural thing in the world for them to look to shift the blame onto others when asked. The immediate problem is that is makes them look all the more silly and gives me (as it would give any customer or business contact) all the more reason to mistrust them and in reality make their position all the more, truly, insecure. Whereas the occasional (or even a bit more than occasional) "oops - sorry about that", with a correction and a feeling that a lesson had been learned, would have turned a negative situation into one that had a positive outcome.

Sadly (and I shouldn't be sad in the run up to Christmas!), I know that I have to take steps as a "relationship manager" at work not to back anyone into a situation where an error must be admitted, but rather to do and ask things in such a way that they can get whatever it is sorted, without taking blame themselves, putting the blame on others ... and hopefully in such a way that the same issue won't occur again and again. And there are things that I know I have to get a little frustrated about, and simply let go.

There's an article on blame culture here ... worth a read. I am not blameless, but neither am I an expert /psychologist and I really wish that I could cut out the crap of all the time the blame culture wastes across the people we deal with and get on with the real job, with joy and efficiently.

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

December 16, 2008

Perl substitute - the e modifier

Here's a graphic illustration of the use of the "e" for "execute" modifier used on the end of substitute operation in Perl.

The "s" for substitute allows you to replace a matched pattern with a STRING in which you can use special references like \1 or $1 for the first matched substring. If you want it to replace the matched pattern with the RESULT OF RUNNING CODE, you should add that extra e on the end.

In this example, the $emma variable ends up containing a corrupted email address which actually includes some code, whereas (with the "e"), the $emily variable results in a correct email address with the section before the "@" pushed to lower case.

$emma = 'Graham@wellho.net';
$emily = 'Graham@wellho.net';
 
$emma =~ s/(\w+)@/lc($1)."@"/;
$emily =~ s/(\w+)@/lc($1)."@"/e;
 
print ("$emma\n$emily\n");
 
__END__
 
Dorothy:plpw grahamellis$ perl swithe
lc(Graham)."@"wellho.net
graham@wellho.net
Dorothy:plpw grahamellis$

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


Useful link: Perl training

December 15, 2008

Variable Types in Perl

In Perl, you have "autovivification" where variables are created when they have a values set in them, without the need to declare them. Some authorities will tell you that they are also "autotyped" in that Perl knows what to store in them automatically too, and to some extent that's true ... but the leading character is also important in at least some of the type decisions.

$ - a scalar, to hold an integer, a float, a string, a reference or a regular expression
@ - a list, to hold an ordered (referenced by counter) collection of scalars
% - a hash, to hold an unordered (reference by scalar key) collection of scalars
& - code, to hold a sub or method
No initial letter - a file handle - to hold the structure through which a file is accessed
* - a typeglob, used occasionally to handle a grouping of one of each of the above

Earlier today, I put together an example that sets up one of each variable type ...

$abc = "text"; # Scalar variable - string, number, reference or regex
@def = (1,4.5,"hello",$abc,\$abc); # List variable - a number of scalars
%ghi = (Wales => "Rugby", England => "Cricket"); # Hash variable - keyed scalars
sub jkl {print "Hello Wurld\n"; } ; # Code variable - named piece of code
open (MNO,">demo.gunk"); # File handle variable - for file reference
*pqr = *abc; # Typeglob - one of each of the above

and then makes use of it, or (in the case of lists, hashes and typeglobs) the scalars within:

print "$pqr ... \n"; # Same as $abc
print MNO "This is filed\n"; # To file - not seen on output
print (jkl,"\n"); # Runs jkl code, also prints "1" - its return value
print $ghi{Wales},"\n"; # Printing from a hash - note curlies
print $def[1],"\n"; # Printing from a list - note squares
print $abc,"\n"; # Straightforeward printing of a scalar!

See Full source code of example - and here are the results:

Dorothy:plpw grahamellis$ perl vartypedemo
text ...
Hello Wurld
1
Rugby
4.5
text

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


Useful link: Perl training

December 14, 2008

Summary - Apache httpd build on Linux

As a regular user:

1002 tar xzf httpd-2.2.10.tar.gz
1003 cd httpd-2.2.10
1004 ./configure --prefix=/usr/local/apache_2.2.10 \
   --enable-rewrite --enable-so --enable-proxy \
   --enable-proxy-http --enable-proxy-ajp \
   --enable-proxy-balancer
1005 make
1006 pwd
1007 su -

As the administrator:

1001 cd /home/trainee/httpd-2.2.10
1002 make install
1006 cd /usr/local/apache_2.2.10/
1009 ./bin/apachectl start

The numbers given in the example above are the history numbers taken from a recent install.

If you are deploying a LAMP system, you would follow this with:

A MySQL installation
A PHP Installation

Notes

a) The options selected in the above example build an httpd suitable for the later installation of PHP, and with mod_proxy connectors allowing it to talk to Tomcat to run Java applications

b) Directory names and locations given are examples

c) You may need to close down a previous installation of httpd before you start this one.

d) Configuration will be necessary in addition to the above steps, which will simply give you a bare web server with a single page that says "It works"

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


Useful link: Linux training

Forwarding session and cookie requests from httpd to Tomcat

If you're using mod_proxy to forward requests that use sessions to other servers, you need to ensure that the cookies get correctly rewritten as they're sent to the browser for setting, in order to reflect the URL of the customer facing server rather than the back end server.

Here's an example where we have forwarded all requests to our front facing server for a web application called /henry to a back end server on our internal network at 192.168.200.218, on port 5050, to a web application called /latmjdemo.

ProxyRequests Off
<Proxy *>
  Order deny,allow
  Allow from all
</Proxy>
ProxyPass /henry http://192.168.200.218:5050/latmjdemo
ProxyPassReverse /henry http://192.168.200.218:5050/latmjdemo
ProxyPassReverseCookiePath /latmjdemo /henry

The ProxyPassReverse is required in order for redirect URLs (such as the sort you generate if you leave the trailing slash off a directory request), and the ProxyPassReverseCookiePath is required in order to allow the back end server to correctly set cookies in the user's browser.

Here's an example of a test page that we've accessed via an httpd process running on 192.168.200.215, which has called up a session / cookie based application running on Tomcat on 192.168.200.218 - the configuration file above is off 192.168.200.215

The source code for that .jsp page may be found here. Example written in answer to a training customer's query / during a practical session. See course details.

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

Port and Glasses

I don't expect you've seen my picture with TCP port numbers coming out of my head very often, have you? In fact this may be the first picture of me in glasses that I've published here. That's not a vanity thing - just that it's only been over the course of this year that I've had to join the majority of people of my age and start wearing the things.

What are the port numbers all about? It's a characteristic of Tomcat that it can be set up to accept connections on a number of different ports, and in a number of different protocols, all at the same time - and this is something that we do on the Apache Tomcat Course that we run every couple of months. Last week, I set up ...
• Port 5008 as the shutdown port
• Port 5050 as my regular http connector
• Port 5009 for ajp connections (mod_jk or mod_proxy_ajp accessors)
• Port 5052 for proxies httpd connections (mod_proxy_http)
... and that's fairly typical. Even though our clients are often interested in having their Tomcatted websites accessible via https (secure protocol), such traffic is probably going to be fronted via Apache http. After all, if an organisation is going to start using the secure https protocol between two servers sitting in the same rack, or even on the same box (usually how they are run!), they either don't fully understand what they're doing, or they are paranoid!

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

Christmas scenes and events

Melksham's Market Square hosts a Christmas Tree each year, and there are lights on the Town Hall. Although it's still a fortnight to the big day, Christmas Parties are in full swing ... indeed, both Lisa and I were out last Thursday evening, and we hosted an event at Well House Manor the following morning.

How many people can I prepare breakfast for? Well - it was twenty on Friday, and I could probably have coped with twice that number if we had the space. Tables laid out ahead of time and a buffet style service allow us to achieve with a small team what would have taken a big team, and a lot of worry, just three years ago. I can recall being asked "how much notice do you need for an lunch event for a dozen people", and thinking to myself that we've probably got sufficient resources on hand to do it on demand if we're not otherwise tied up.

But sometimes it's nice to let others do the cooking, and so it was that the most enjoyable meal I had this week was at "The Magpies" ... a slow roast pork which was quite extraordinary; I could have eaten two portions, except that I might have been somewhat uncomfortable afterwards - much more in my line than the inevitable December turkey

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

Server - Service - Engine - Host, Tomcat

A Tomcat Server can run one or more Services. Each Service comprises a number of Connectors and an Engine, which contains one or more Hosts.

You connect to a Tomcat Server via an appropriate connector, which defines the port number, the protocol, and various other connection parameters, and within the Tomcat server information is generated for the particular host (domain) that you're serving.

Q: Why would you want multiple services?

A: So that you can use a single copy of Tomcat to serve different hosts in different ways.

The top diagram shows you a server with five connectors and a single service, accessing 3 hosts. Any of the five connectors can access any of the five hosts, so you've a total of fifteen different routes to the data.

The lower diagram shows, again, 5 connectors and 3 hosts - but this time two of the connectors access a service who's engine looks after just one host, and the other three connectors access a second service that looks after two hosts. Result? Just ( 2 x 1 + 3 x 2) = 8 different routes to data.

Why might this be useful? Let's say that the single host with two connectors provided internet-accessible http and https services, and the other two hosts were accessible via ajp and http proxies, together wish a second http port for testing. And that's all you wanted - no crossovers, but also no need to run two complete Tomcats!

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

URL rewriting with front and back servers

If you ask someone to double a number, they'll come back to you and tell you twice the number you gave them - give the "3" and they'll say "6". But if you tell them to double the number every time they handle it, but refer it to someone else for them to validate it, you'll get "12" back. Since they will double it each time they pass it on. And if the person they validated it with also doubles it, you'll get "24".

If you're calling up a web page from a Tomcat Server that's running an application behind an Httpd server, you need to make sure that your URLs don't get rewritten two or three times in this fashion - but rather they get processed each step along the way in such a fashion that the report back to the browser is the correct one. Using httpd's mod_proxy it is especially easy to get the rewriting wrong, though.

The diagram here shows each of the three steps where URL re-writing may happen with mod_proxy:
1. On the way in through httpd, as set up by the ProxyPass directive
2. At Tomcat, as defined by the proxyName and proxyPort attributes of the <Connector>
3. On the way back through httpd, as per the ProxyPassReverse directive

My own suggestion is to KISS ("Keep is Simple, Stupid!"). Leave off proxyName and proxyPort attributes on the Tomcat Connector, and have the ProxyPass and ProxyPassReverse set to be equal but opposite.

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

December 13, 2008

mod_proxy_ajp and mod_proxy_balancer examples

One of the major enhancements in release 2.2 of Apache httpd is the addition of the mod_proxy_ajp and mod_proxy_balancer modules to the standard distribution. Gone are the days of needing to build special modules such as Jserv, jk, jk2 and warp to have httpd act as a "front" to a Java (Tomcat) server - the module you need is already there.

Proxy forwarding to a Java Server

Here's an example of a proxied request from Apache httpd on to a server (probably Apache Tomcat) that's running the ajp protocol on port 5090:

ProxyPass /harry ajp://192.168.200.215:5090/latmjdemo
ProxyPassReverse /harry ajp://192.168.200.215:5090/latmjdemo

That's code to be added to the end of your httpd.conf file!

Proxy forwarding to a group of Java Servers

It gets even better ... mod_proxy_balancer lets you define a group of Java servers which you can forward your traffic on to - ideal on a busy site where the background task that's running in Java is a resource hog and needs to be shared between systems. Here's an example of what you would add to httpd.conf:

<Proxy balancer://catbox>
BalancerMember ajp://192.168.200.215:5090/latmjdemo
BalancerMember ajp://192.168.200.214:5009/latmjdemo
</Proxy>
ProxyPass /prince balancer://catbox/

In this example, any references to the web resources on the server under the /prince directory will be forwarded to one of two other machines, on port 5090, and will be directed to the "latmjdemo" web application on there.

On our private Apache Tomcat course yesterday (based on / extended from our public course), we set up exactly this; although a production system would have identical applications on the two servers, we altered the background colour on one of them and it was fascinating to watch different delegates, and different reloads, coming up in either green or white.

More flexibility in forwarding to a group of Servers

The example above uses the default "round robin" scheduler - but there are other facilities available too to help you tune your forwarding. Here's a further example:

<Proxy balancer://kennel>
BalancerMember ajp://192.168.200.219:5009/latmjdemo loadfactor=1
BalancerMember ajp://192.168.200.218:5009/latmjdemo loadfactor=3
BalancerMember ajp://192.168.200.215:5009/latmjdemo status=+h
ProxySet lbmethod=bytraffic
ProxySet stickysession=JSESSIONID
</Proxy>
ProxyPass /corgi balancer://kennel/

In this example, we are forwarding to 2 systems, in a ratio of 1 : 3 and we're allocating traffic based on the traffic quantities coming back from each server rather than the number of requests (so queries that generate a lot of traffic count for more). An extra machine has been designated as "hot swap" if neither of the others is available. Once a visitor is allocated to a particular machine for his forward, he'll continue to be forwarded to that same system while his JSESSIONID cookie remains live.

Some other notes about mod_proxy and family in Apache 2.2:

• ProxyPassMatch is available, which lets you specify a pattern (Regular Expression) for your forwarding - for example, if you wanted to forward all you image requests to an image server:
ProxyPassMatch ^/(.*\.jpg)$ http://images.wellho.net/$1

• mod_rewrite IS aware of mod_proxy_balancer, so that you can rewrite your requests as we do in many parts of our site, and then forward them on to other systems through an appropriate balancer.

• As from Apache 2.2.9, ProxyPassReverse is also mod_proxy_balancer aware.

Further reading ... There's a very good paper by Jim Jagielski - here - on these and more extra facilities. Documentation for mod_proxy_balancer is here, and there's a good description of reverse proxies here.

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

Predictive Load Balancing - PHP and / or Java

Load Balancing Algorithms - the standard offerings

How do you share out the requests when you're load balancing? The computer (or other device) that's sharing out the load needs to make a decision as to where it should forward each request, and there are a number of different option commonly available.

a) Round Robin / shared by number of requests. In the simplest example of "Round Robin" sharing, each system in sequence gets the next request. If you had three back end computers called "Duncan", "Wilfred" and "Nick", then Duncan would get first turn, Wilfred the second, Nick the third, and the baton would pass back to Duncan again.

b) Shared by traffic. With this algorithm, requests are forwarded to the system that's returned the least data in the very recent past - thus allowing back end systems which have only been passing small amounts of data back (due to easy requests) to be more heavily loaded.

c) Shared by queue length. In this case, the number of connections currently being forwarded is monitored, and new requests are forwarded to machines which have the shorter queue. Rather like looking for the shortest checkout line in the supermarket!

Each of these algorithms may be overridden by "sticky sessions", where the second and subsequent request of a series from the same client is passed on to the same server that was originally chosen for the first request, even if that server's not the 'quietest' or 'next'. So that once one particular back end server is dealing with a multi-page task (such as an airline booking), the main client can back in touch again and easily continue where it left off. We all do this 'in real life' - having got to speak with someone over the phone about a particular issue, we ask for the same person again when we call back rather than having to start explaining from the beginning again.

Further overrides of the basic scheme are possible, with requests being distributes to the more powerful computers in a back end group (or machines that don't have too much else going on) in greater quantity than to the slower or otherwise-loaded systems.

But even with these overrides, it's going to be rare for any of these algorithms to give you an ideal traffic balance. They'll tend to be based on recent historic data rather that the "here and now" and predicted loading. Taking my supermarket comparison, NONE of the algorithms I have described above actually looks at the baskets of the customers waiting in the queue and forecasts ahead as to how long each of the items there will take, even though that's exactly what we do in our local Tesco.

Predictive Load Balancing

What do I mean by "predictive load balancing"? I'll start with an example. Let's say that I'm deploying a journey planning application. Most journey requests are for quite short distances or for main artery journeys with few intermediate 'nodes', and can be handled quite quickly. But there's going to be the occasional awkward one - Melksham to Maentwrog or Cosham to Campbelltown, which will put a disproportionate load on the server.

By "predictive balancing", I mean noticing these occasional heavy requests even before they are processed, and then cutting right back on the following requests to that server until they are completed. But how do I identify, on the front end load balancer computer, which there requests are? The incoming parameters - the place names - certainly won't give any hint on the front end server unless there's substantial work done there which rather defeats the whole objective of spreading the load by balancing.

What's needed is feedback. If each backend task signals to the front end (perhaps by adding a record into a database) the expected job length, once it has established it in the backend, then the front end can make forwarding decisions based on the lowest predicted workload.

Here's some proof of concept code to show you how that could work:

<?php
 
# Back end task ...
 
$myname = "duncan"; # To be changed to server name in each instance
 
# Get me a random number (1 to 9) to indicate size of task
$tasksize = 10 - floor(pow(rand(1,9999),.25));
 
# Tell the front end server how long it will take
list($usec, $sec) = explode(" ", microtime());
$ts = ((float)$usec + (float)$sec);
mysql_pconnect("frontend","trainee","abc123");
mysql_select_db("test");
mysql_query("insert into actives (size, name, ts) ".
   "values ($tasksize, '$myname', $ts)");
 
# Something to represent loading ("application goes here")
sleep($tasksize);
 
# Cancel the load from the front end server
mysql_query("delete from actives where ts = $ts and name = '$myname'");
 
?>

and the front end code to choose which machine should do the work:

<?php
 
# Front end task 
 
$servers = array("wilfred","duncan","nick");
 
# Look for current loadings
 
$current = array();
mysql_pconnect("frontend","trainee","abc123");
mysql_select_db("test");
$qs = mysql_query("select size, name from actives");
while ($row = mysql_fetch_assoc($qs)) {
   $current[$row[name]] += $row[size];
   }
 
# Sort loadings and get lightest
asort ($current);
$inorder = array_keys($current);
$target = $inorder[0];
 
# Run the request on the appropriate backend
$result = file_get_contents
   ("http://$target/action.php?$_SERVER[QUERY_STRING]");
print $result;
?>

Although these concept codes are written in PHP, they are equally applicable to Java and other languages - indeed, you might choose to use a PHP or Perl front end running on Apache httpd to call up a number of backends running in Java on Apache Tomcat.

Note that code provided here does not rely on any particular Apache module to forward packets (except perhaps that you may have installed PHP as a module!) - with mod_jk, mod_rewrite and mod_proxy, which are generalised forwarders / balancers you don't have the opportunity to place application specific load forecasts into the decision process, which is the extra that my example has provided.

The code / example above came as a result of a private training course during which we set up multiple load balanced servers and discussed customer's specific needs. Our more general Deploying Apache httpd and Tomcat course covers the more common aspects of web server deployment, including a brief look at the issues of clustering and balancing, but if you would like to set up a sachem such as the one above, you really need a private course or an extra "1 on 1 day" after the public course.

Links:
Full back end source code
Full front end source code

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


Useful links: PHP training, Java training

December 12, 2008

Getting hold of the wrong end of the stick

I got an email on Tuesday that I would describe as aggressive in its approach, accusing me of libelling various people, and demanding that I remove that material from my site.

Getting hold of the wrong end of the stickProblem was ... the retired senior business man had got hold of the wrong end of the stick. I hadn't even heard of the people I was accused of libelling, and a quick look into the facts of the case lead me to an obscure link from a previous article here to a site that's nothing to do with me, and about which I even said "I cannot, of course, confirm that the information on this other site is correct". It wasn't even the page that I linked to that contains the material that is considered inappropriate - you actually have to follow links to other pages to find it.

With such a senior figure, who had copied his email to a solicitor and also to a senior member of a local business organisation in North and West Wilts, I had to take the matter seriously and this lead me to thinking Can a web content provider responsible for the content of sites that he links to?

Views on this appear to differ - with the Gent in question contending that a web site owner IS responsible for what he links to (and sending me the URL of his own site which, when you look around it has no outside links) taking one view, and nearly everyone else taking the opposite view. My goodness - where would Google be if they could not provide links to external sites?

I have advised the gentleman in question that he has got the wrong of the stick in attributing the content of that other site to me, and given him contact details from that other site and from the domain registrar's site so that he can take the matter up directly with them. And it has been suggested to him by the other kind folks he copied in that he's attempting to shoot the messenger. That should be another cue for a photograph to illustrate a proverb, but shooting the messenger can get very messy, but messengers are often useful people to have around and you don't want to go round shooting them just for a picture - you never know when they could be useful to you, alive, later.

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

Quick Summary - PHP installation

For Course Delegates - a quick reminder of the crucial commands. The numbers alongside the commands are just the history numbers!

As your regular user:

1012 tar xzf bristol/php-5.2.5.tar.gz
1013 cd php-5.2.5/
1015 vi INSTALL
1027 ./configure --with-apxs2=/usr/local/httpd_2.2.10/bin/apxs --with-mysql=/usr/local/mysql
1028 make
1030 make test

Then as root:

1001 cd /home/trainee/php-5.2.5
1002 make install
1004 cp php.ini-dist /usr/local/lib/php.ini
1006 cd /usr/local/httpd_2.2.10/conf/
1007 vi httpd.conf
1008 cd ..
1009 ./bin/apachectl stop
1010 ./bin/apachectl start

In that vi ... add to end of httpd.conf:

AddType application/x-httpd-php .php .phtml
AddType application/x-httpd-php-source .phps

To test ... add something like
  It is the year <?php print(date("Y")) ; ?> !!
to an existing web page, change it to a .php, and check that it runs

Notes

a) Apache httpd needs to be built first and with --enable-so option (big catch this one if you have installed Apache hhtpd and simply followed the Apache httpd instructions!)

b) MySQL needs to be unpacked too, to provide header files

c) Directory names and release numbers are the ones I was using yesterday - they'll vary for your own systems of course!

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


Useful link: PHP training

December 11, 2008

Summary of MySQL installation on a Linux system

The critical steps of deleting an old copy of MySQL, and installing and starting up a nice new clean one!

(the numbers are my "history number" - I did a lot of ls-ing and vi-ing in between!)

1001 cd /usr/local
1004 rm -rf mysql-5.1.24-rc-linux-i686-icc-glibc23/
1006 rm mysql
1009 tar xzf /home/trainee/bristol/mysql-5.1.24-rc-linux-i686-icc-glibc23.tar.gz
1013 ln -s mysql-5.1.24-rc-linux-i686-icc-glibc23 mysql
1014 cd mysql
1016 vi INSTALL-BINARY
1017 chown -R mysql.mysql .
1019 scripts/mysql_install_db --user=mysql
1021 chown -R root .
1022 chown -R mysql data
1024 bin/mysqld_safe --user=mysql &

Notes:

a) There may be a need to shut the Ole Daemon down first.

b) Beware files /etc/my.cnf and /root/.my.cnf which may exist from a previous install and have the database parameters and directories set to goodness only knows where

c) I HAVE DESTROYED ALL THE DATA that was being held in the previous database (but then I have a good backup, yah?)

d) I need to go on and set up the password and accounts for the database. It's left wide open with the base install - but not as wide as it used to be

e) To make it reload on reboot, the mysql.server script that's supplied with the download should be put into /etc/init.d, with appropriate links from rc5.d or rc3.d

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


Useful link: Linux training

Lidl opens in Melksham

Now here's an odd morning for you; in my recently elected role of President of Melksham Chamber of Commerce and Industry, I was invited to attend - "in chains" no less - the opening of the new Lidl store that re-extends the Town Centre across the river Avon. And indeed I was very happy to do so; Melksham is a growing town, and it can't grow in just houses and hairdressers and charity shops. For sure, other traders in what could be regarded as similar businesses, such as Aldi and Sainsbury's many not be quite so "very happy".

A week ago, the place looked like a construction site when I drove past, but an incredible amount of work has been done in the seven days. And at 07:30, the Mayor, the Town Crier, representatives of the District Council and myself to represent The Chamber met outside in a cold car park, dodging around the last-minute line-painters. And we were shown around the store; I don't think I have ever seen so clean, nor so completely stocked, a supermarket. Nice to see the "we have passed the VAT reduction" signs up, and (frankly) slightly amusing to see prices crossed out and replaced by lower ones on some lines - I know that the law lets them do that across stores, but they haven't been selling these things at higher prices here in Melksham.

It wasn't the first time I've been to Lidl - in fact Santa's minced pies for the train 10 days ago came from their Devizes branch - but I was impressed by how much larger the Melksham store is, how much more accessible is the car park too. I note that the entrance and edit have been arranged off the one way system so that the easier entrance is from the bypass, and the easiest exit in that direction too, with a "round the loop" needed to access from / to the town centre.

At twenty to eight, a new team of staff were being briefed around the till area - a great circle with final introductions and last minute instructions; the new store manager concentrating on this while our "VIP" party was shown around by the acquisition and opening team - I'm sure a scenario that they've repeated many times in the past and hope to many times in the future.

And so to an opening ceremony. A welcome by the Town Crier including "God save the Queen" even though she hadn't made it (did anyone think to invite her?). Kind words from the Lidl folks about how welcoming Melksham has been. And an introduction, a "thank you for the confidence in the town", and a best wishes from the Mayor, who apparently used to go to Boddington's Barbers almost exactly where we were standing, and remembered the Temperance Hotel just over the way. And - being Christmas, the store was opened by cutting a tinsel strip across the door and in flooded the crowds - there must have been 40 or 50 people waiting, even at 08:00. It always seems odd to me that people will queue for things like store openings, but clearly they knew what they were there for. Even while the official party was being photographed by the press, the first sale - a digital camera - left the store.

Picture - the local press (Matt) interview the new store manager (Scott) ... who should be joining The Chamber ;-)

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

December 10, 2008

Learning to Program in C

From my inbox

Q: I need to learn to program in the C language, but have never programmed before. Can you help me?

And my outbox (modified to make the answer generally applicable)

A: Yes - but my answer will be a long one ...

Looking back a number of years, C was very much a mainstream language that was widely taught, and it was often the first language that people learned, so that there was a wide variety of courses available, including some styled as "Learning to program in C" which were intended for those with no prior programming experience. These days, however, C has become more of a niche. Other languages have come along, such as Perl and PHP, Java and Python, and similar which are much more efficient in terms of programmer's time taken to do a particular task, and they have rather taken over. Better to write in a morning in Perl what would take you a week in C.

However, Perl itself (and these other languages) are actually written in C, so the language itself hasn't gone away at all and remains a critical part of modern computing. And there are some applications - such as embedded systems / specialist devices / high throughput and real time code for which the other high(er) level languages are not applicable. In other words, C won't and can't die and still has a vital place for a certain segment of specialist users. So these days, you'll find that most of the people who come newly to C will have already programmed in other languages, and they are the people that most providers of C courses are now catering for.

As you may have seen from our web site, we provide training in a number of languages, and the question "but which course can I take as I've never programmed before" is NOT a new one. Yet by providing a second series of courses on each of the more niche topics, we would thin out course sizes so that they would be below a minimum practical number of delegates to make a viable business out of it. However, I can offer you a solution.

The next C programming course - WITH pre-requisites - runs on 19th and 20th January 2009. I will be running extra days on 17th and 18th (yes, Saturday and Sunday) to cover off many of the basics of programming, with particular reference to C, to prepare you for the Monday / Tuesday course. You will be one of very few on those 2 extra days, and we could run the Saturday starting at lunchtime, and an extended day on the Sunday, so that at least you wouldn't have to travel down on the Friday night. For pricing, we would treat it as a 4 day course - so you would be looking at 1100 pounds + VAT (or 1340 + VAT if you include a hotel room).

I *have* run "learning to program in ....." courses before, and indeed have various note modules that I would use for the extra two days. I'm confident that we could do a good job for you is this proposal suits. I will caution you that many people take easily to programming, but others find it quite a daunting task, so I can't offer you a guarantee that you'll make a great programmer as a result of the course. I can guarantee that you'll have a very effective start, though. And you'll need to practise and learn more even after the course ... programmers are always learning even years and years "in" - but that learning can be from books, the web and practical experience once you're over the initial hurdle.

If you come back to this article in the archives, and have missed the dates quoted, you might like to note that we run the C Programming Course mentioned a number of times through the year. I can't always extend back to the two prior days, but sometimes I can ... if you're interested, please ask!

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

December 09, 2008

Training Passports - booking a training program

The question of "Training Passports", where a delegate can take a number of different courses over a period of time, isn't a new one to me ... but it really wasn't appropriate for us to offer such a product in our early days. With a sprinkling of niche courses, it was highly unlikely that we could offer the sort of "pick and mix" that the typical delegate retraining for a new role would need. However, slowly things have changed and we DO now offer a wide range of courses that inter-relate to each other.

So I please to announce that, YES, we can offer you a Training Passport.

* Purchase 6 or more days of training for a delegate
* Delegate can choose any suitable courses / dates from our schedule
* £1500.00 for 6 days, add £200.00 for each extra day

The courses are to be taken within 15 months of initial order and payment, and each place is subject to our usual terms and conditions for public courses.

Let's see an example - for someone who's done some programming before and has put together a static web site, but now needs to get in deeper with an interactive site using databases ...

PHP Programming 4 days from 2nd February 2009
Object Oriented PHP 1 day on 6th February 2009
Linux Basics 1 day on 23rd February 2009
MySQL 2 days from 26th March 2009
PHP Techniques Workshop 2 days from 6th April 2009

That's 10 days of training ... under the passport scheme, total cost £2300.00 if 10 days are purchased at the same time, as opposed to £3000.00 for individual bookings for each course. All prices quoted in this article exclude VAT. Hotel rooms are available at our training centre - Well House Manor at the VAT inclusive delegate rate of £70 per night - to be paid at each stay.

Training passports must be booked ahead of time and paid for in full before completion of the first course. Should you wish to cut short a passport program for any reason, we will refund you the difference between the list prices of the courses taken and the fee paid, or allow you to transfer the credit to another delegate's passport.

Everyone is an individual ... so please email me - graham@wellho.net with your individual training needs.

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

December 08, 2008

Frosty Morning, foggy evening

A frosty morning here in Melksham. This is actually yesterday's picture - taken in our garden with the Christmas berries and the haw frost - headed for Bath and the Christmas Market

A long day - back on a delayed evening bus (25 minutes late from Bath - good Ole First!) that dropped us at the end of our road long after day, as it headed on to Devizes and the remote Easterton.

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

Bath Christmas Market

We went down into Bath on the bus yesterday ... intending just to do a cinema trip, but the day was lovely and we had a look around the Christmas market.

Food and Drink stalls mixed in with stalls selling Christmas nicknacks, which extended around the cathedral and up to the market hall.

See here for further pictures.

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

December 07, 2008

2009 - Hotel, Meeting, Training Course prices

Well House Manor / Well House Consultants - prices for 2009 (valid from December 2008)

Bedrooms / Overnight

These prices are inclusive of VAT, at the new rate or 15%

Bedroom, Double Occupancy. 90 pounds per night
Includes continental breakfast for 2, internet access, all facilities of public areas including unlimited soft drinks, etc.

Bedroom, Single Occupancy. 80 pounds per night
Includes continental breakfast for 1, internet access, all facilities of public areas including unlimited soft drinks, etc.

Bedroom, Delegate or Contract rate. 70 pounds per night
Includes continental breakfast for 1 or 2, internet access, all facilities of public areas including unlimited soft drinks, etc.
This rate is available for delegates on courses or at other meetings or events at Well House Manor, guests booked and guaranteed by contract clients, and members of Melksham Chamber of Commerce.

Rooms are available from 3 p.m. on your day of arrival until 11 a.m. on your day of departure (please let us know if you would like to arrive early of leave a little later, and we'll do our best to help)

See hotelterms for full terms and conditions

Training / Meeting / Event rooms

These prices are inclusive of VAT, currently at the new rate or 15%

The "Wilts"

190 pounds (08:30 to 17:30)
120 pounds (08:30 to 12:30)
120 pounds (13:30 to 17:30)
80 pound (18:30 to 22:00)

Include drinks and light refreshments for up to 10 people per session

The "Berks"

90 pounds (08:30 to 17:30)
60 pounds (08:30 to 12:30)
60 pounds (13:30 to 17:30)
40 pound (18:30 to 22:00)

Include drinks and light refreshments for up to 5 people per session

The "Berks" is available at one half of these rates if booked for use at the same time as the Wilts. For example, "Wilts" + "Berks" all day = 235 pounds. At this combined rate, we include drinks and light refreshments for up to 12.

Extra Delegate rate - drinks / light refreshments / conference resources - 5 pounds (half day), 8 pounds (all day).

Lunch for meetings / conferences - 12 pounds per head (cold) or 15 pounds per head (hot). Both include mains and desert; choice of two menus in each case. Lunch is usually served in the "Whitworth" dining area, but may be served in-room with prior arrangement.

See eventterms for full terms and conditions.

Public Training Course Prices

One day course - 350 pounds, plus 250 pounds per additional day. This price does NOT include VAT. Delegates who wish to stay may do so at the 70.00 VAT inclusive delegate rate, or add 60.00 per night (before VAT) to the price of the course.

Second and subsequent delegates booked on the same course at the same time pay 250.00 per day (plus 60 per night stayed) - i.e. a discount of 100 pounds.

Training Courses may also be booked / paid in Euros (450 first day, 350 each subsequent day, 75 per room night, all + VAT) and US Dollars (550 first day, 450 each subsequent day, 90 per room night, all + VAT).

See courseterms for full course terms and conditions, our course schedule for dates of upcoming public courses, and here for details of our training centre and other aspects of public courses.

Private Training Course Prices at Well House Manor

900 pounds (or 1125 euros or 1350 dollars) - first day
800 pounds (or 1000 euros or 1200 dollars) - second day
plus 50 pounds (or 65 euros or 75 dollars) per delegate per day

These prices are quoted for a non-residential course at Well House Manor and are VAT exclusive. Add 60 pounds (or 75 euros or 90 dollars) (+VAT) per room per night for residential courses.

See courseterms for full course terms and conditions, our diary for current date availability, and here for details of our training centre and other aspects of private courses run there.

Private Training Course Prices on customer site

900 pounds (or 1125 euros or 1350 dollars) - first day
800 pounds (or 1000 euros or 1200 dollars) - second day
plus 80 pounds (or 100 euros or 120 dollars) per delegate per day

Plus tutor's travel costs and expenses, which are quoted based on a mileage rate, daily hotel and subsistence costs (if staying away), and flight / ferry costs if appropriate. Enter your postcode (UK, Canada, Australia), county (Ireland), zip code (USA), Country (rest of world) for an on-site quote: .

Please note that due to visa and other regulations, and the safety of our own staff, we may not be able to train in some countries. For countries that we are only asked to train in rarely, we take decisions on a case by case basis. See here for a full country listing.

VAT rules are complex, but broadly we add VAT in the UK, we ask you for your VAT number for other countries in Europe and with that we can then charge you VAT exclusive, and courses presented outside the EU are not subject to VAT.

We have a minimum course duration for on site courses of 2 days in the UK, 3 days elsewhere in Europe, and 4 days if further from our base. The minimum number of delegates is 4 in the UK, 5 elsewhere in Europe, and 6 if further from our base.

See courseterms for full course terms and conditions, our diary for current date availability, and here for details of on site private courses.

General Notes

Prices for 2009 are broadly unchanged from our 2007 and 2008 prices - exceptions are that we have slightly reduced a some of our VAT inclusive prices to reflect the lower VAT rate - not across the board, though, to avoid awkward pricing quotes. Prices in Euros and Dollars are substantially lower than they have been, due to the weakness of the pound against these currencies.

Increasing road congestion and travel time has lead us to add an extra night's hotel stay to courses in the following postcode areas for 2009: BH - Bournemouth, BN - Brighton, CH - Chester, CW - Crewe, L - Liverpool, M - Manchester, ME - Medway, SK - Stockport and WA - Warrington. This ensures that your tutor will continue to be fresh and give a good course from beginning to end!

It is our intention to hold the prices in pounds throughout 2009, although we reserve the right to change the prices we quote at any time. At present, quotations are valid for acceptance up to 31st March 2009. Prices in Euros and US Dollars are subject to revision if there is a further substantial change in exchange rates.

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

Melksham Oak Secondary School, Melksham, Wiltshire

Melksham is growing, with 750 new homes approved, to be constructed in the very near future - just over the back, behind our home. And there's a new secondary school already being built, to be known as "Melksham Oak" and replacing the George Ward, which is tired and worn out. "Melksham Oak" is going to be just a few hundred yards down the road from us Access from the town will be either the A365 from "The Spa" Roundabout - which hasn't got a footpath - or along the cul-de-sac in front of our home, carrying on along a path to join the main road.

You can probably imagine me saying "Not In My Back Yard", but actually I'm not - even thought the construction crane is clearly visible from our lounge. For Melksham will benefit from growing, and it does deserve a new school and other new facilities too - much better for it to grow and be a vibrant town than to moulder slowly away as some poor backwater - and that IS a danger we need to guard against with the new Wiltshire Council seeming having an orchestrated marketing line of "Salisbury, Trowbridge and Chippenham" even before they officially exist.

But although I'm not a NIMBE, I do share concerns that have been expressed with regard to access to the school. For sure, it's opposite the big new extension to the Bowerhill area, but only a small proportion of the pupils will walk in from there - the rest have to go through this narrow gullet on the A365, and I can anticipate some pretty big increases in traffic at school time, but perhaps I'm being too much the profit of doom - we'll see; this may just be a minor issue after all.

Yesterday, I walked along the road up to "The Oak" and took a few pictures; some accompany this article, and others may be found here.

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

December 06, 2008

Team changes at Well House - looking forward

When people leave a job where they were in a customer facing role, it's usual for them to quietly disappear from the scene with as little as possible said to the customers. I can understand why that's the convention, but I'm going to do rather the opposite here and write a little piece to say "Thank you" to Leah and Christine for all they have done for us, to wish them all the very best for the future, and to tell our customers who are reading this article about how we're moving forward.

It was as recent as summer, 2006 that we took over "The Old Manor". A B&B, much used by our delegates, it had become progressively more run down as the former owner looked to sell it to developers who were very keen to knock it down and build between 20 and 25 accommodation units on the site ... plans which had been rejected after a great deal of planning activity and at least one contested planning application which was rejected.

It was, then, only natural that the place was in need of a great deal of attention, and doing that work was a doubly tough task as we needed to keep the training business firing, throughout the works and initial period after we opened, on all cylinders. And it's no small thanks to Christine and Leah - and many others too - that we were able to do so.

Two years later, and the place - now known as Well House Manor - is well established. With Leah working largely behind the scenes on setting up 'systems', and Christine pounding the pavements and helping to raise awareness and to sell rooms and events to local businesses, we've moved in the 24 months or so since our first course at the new centre from a hotel and venue where, apart from our delegates, to a bustling venue where at times it seems that there are customers everywhere - and we love it!

Yet having invested all that hard work in putting systems into place and in raising the visibility, the workload for the development people naturally drops off rather; one systems are written and in place, they should have a good few years of care and maintainance (only) that needs to be done on them, and once we're well know to (and established with) local businesses and visitors to the area, that hard pounding of the pavement becomes inexorably modified to a much smaller - but never the less important - role in maintaining customer relationships with people who have, by now, largely become friends. And this changing workload and these changing needs mean that the people who were filling the old roles as we grew to make best use of our resources are not necessarily going to be the best people (or the happiest of staff) in roles which of necessity have changed.

Both Leah and Christine have chosen to leave us, but on the very best of terms and it doesn't really feel as if they're gone. Indeed - Leah was back in to help us out for a few hours yesterday (A quite exceptional day ... starting with breakfast for 25, a course to give, and all five rooms checking out and to "turn over", and one of our regular team out due to a bereavement) and will almost certainly be back and using our training rooms for her exciting new project that I'll be telling ou about in due course, and Christine popped it too, to return a few things and she stopped for a chat, and look forward to Christmas and some things she has happening. Also concerned to make sure that some things have been passed over smoothly.

So ... let me tell you about the key, customer facing people you'll find on our team as we move forward into 2009. I (Graham) remain as the trainer; I'll be running the courses, answering the technical emails ... but also looking after customers as and when I'm around at "The Manor" and generally keeping an overseer's eye on things. Starting in the mornings, Sharon will be serving breakfasts, doing rooms, and keeping the housekeeping and consumables inventory side of the hotel running. Chris, from early afternoon until final check-in, will also be doing elements of the hotel work, HR, looking after maintenance and the less routine inventory issues - and also continuing to provide me with "back room services" so that I know that the systems and web site will be running for me when I start a course. At our HQ, up the road at 404, The Spa, Lisa continues to look after the admin, books, bookings, and a wide raft of other things. And Sarah, with us for only a couple of shifts a week but never the less a crucial team member, helps us take up holiday, weekend and extra manning needs. See Staff page for more about each of us.

With the new, more compact team we've all got to work effectively and efficiently, but I know that we can and do. With such a wide range of tasks, we're crosstraining ... Chris can turn his hand to most roles, Sharon can pick up the phone and do an excellent job of taking a booking when Lisa's engaged on another call, and I know that I can leave the hotel in Sarah's hands with a number of time-critical jobs to be done, and they will be done.

It's all rather exciting, and I for one am looking forward to Christmas, and beyond Christmas to the New Year and a busy, but fun 2009 with role filled, very capably, by someone who's really enjoying that role. After all - if we enjoy our roles, then our customers will enjoy being with us.


Our phone numbers:

for Training - 01225 708225
for Hotel and Meeting Rooms - 01225 709638
(or use our freephone 0800 043 8225)
fax line: 01225 707126

Our web sites:

for Training - http://www.wellho.net
for Hotel and Meetings - http://www.wellhousemanor.co.uk

also: secure HOTEL booking page
and: secure COURSE booking page

Our email addresses are:

graham@wellho.net, lisa@wellho.net, etc ... but if you have a general enquiry or you're writing non-specifically, please use info@wellho.net and your email will be automatically routed to them most appropriate person who's on duty.

Postal addresses:

404, The Spa, Melksham SN12 6QL (HQ / correspondence)
Well House Manor, 48 Spa Road, Melksham, SN12 7NY (Hotel, Training)

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

Flash (client) to PHP (server) - example

Hidden deep in our website, there's an example of a Flash / Flex / Actionscript that runs in the browser, but contacts the server when certain information is required. In fact, it's so deeply hidden that I had trouble finding the links for some of yesterday's delegates:

An overview of Flash / Flex / Actionscipt

A demonstration of a Flash button which, when pressed, interacts with a PHP program on the server

An index of all the various pieces of code used in this demo with links to all the source code.

I'm also adding (to this page which is unashamedly a bit of a link farm) a link to AMFPHP. AMFPHP is an open-source PHP implementation of the Action Message Format(AMF) which is used primarily to exchange data between an Adobe Flash application and a database, using a Remote Procedure Call. Another alternative is WebOrb - of which both community and commercial versions are available.

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


Useful link: PHP training

Introduction to Object Oriented Programming

"Object Oriented Programming" is a whole new philosophy for programmers who have been writing short scripts for years, and it can be quite frightening to learn with all these new buzzwords like "overriding", "encapsulation" and "polymorphism" creeping in. It's a beautiful concept and a lovely approach, though .. but one that's at its most effective on projects and tasks that are more than just a few code lines - in other words, it's at its most effective on those larger jobs which are the very ones that we don't do as practicals on a course because of all the time such an extended exercise would take.

However ... I have found good ways to "teach OO" - and indeed I have given two separate courses in the last week that have covered the subject. On Thursday, I was teaching OO in Perl and on Friday, OO in PHP. And - the week after next - I'll be teaching Perl for Larger Projects - a public course that covers the subject for a further group.

The Background to OO

Newcomers to OO start here

When you're programming, you're dealing with data - and probably a number of different types of data. And there are a certain number of things that you can do with each type of data.

For example, you could be writing a program that deals with animals. You can load in (somehow) the data relating to an animal. You can set its weight. You can read its weight. You can set and read its age. And if you know its breed and age, with appropriate background knowledge you can work out the proportion of the way it is through its expected life. But you can't (for example) work out its data transmission rate, nor know it' Mastercard number, as such things don't apply to animals.

In Object Oriented Programming, you'll write a series of named pieces of code that deal with each particular type of data - for an animal, following on with our example, you would write a piece of code that actually creates the necessary structures within your program to hold the data for an animal, named pieces of code to set values (if you chose not to set them only as you created the structures), and named pieces of code to get information back out. You might also write a piece of code to deal with closing down the structures when you were finished with them - if (for example) data changes stored only in memory had to be saved to your disc.

One of the great beauties of OO programming is that you can clearly define your specification for a data type ("class") and write all the code for that class in a separate file which can be tested, maintained and extended as a unit on its own away from the main application code. That means that your "animal code" can then be shared between a whole lot of different applications that relate to animals, and yet only the person who wrote the class needs to understand its internals. And all the people who use the code only need to understand how to call it, and what it returns.

Here's a sample Perl program - from Thursday - that USES a couple of classes, but without any knowledge of how they work internally.

use animal;
 
$rover = new animal("Rover",9,7);
$boots = new animal("Blue",14,6);
$george = new human("Joe the Plumber",42);
 
$boots->setage(12);
$boots->setfurcolour("grey");
 
@group = ($rover, $boots, $george) ;
 
foreach $life(@group) {
  $ea1 = $life -> geteage();
  $ag = $life -> getage();
  $a1 = $life -> getname();
  print "We have $a1 aged $ea1 in essence and $ag in truth\n";
}

And here are the results that produced:

Dorothy:ppcsrd08 grahamellis$ perl annie
We have Rover aged 63 in essence and 9 in truth
We have Blue aged 72 in essence and 12 in truth
We have Joe the Plumber aged 42 in essence and 42 in truth
Dorothy:ppcsrd08 grahamellis$

You'll notice that - as well as animals - my example has used a human. So I have two different types of objects in my list (@group). And yet when I call code such as geteage and getname there's only a single line involved, and not a big switch and case structure. This is because you're starting to see a further advantage of a well designed OO program - the ability for it to run a different piece of code depending on the class of object that's passed in. Or (describing that another way), if you have two geteage methods - one for a human and another for an animal - the program itself will be able to work out which one to use on each particular object it's called on. Neat, isn't it? This ability is known as Polymorphism.

Looking a little further behind the scenes, a human isn't all THAT different to an animal, and it would be a great shame to have to duplicate code. So in this example, our class of animal is used as the basis for our class of human, and in fact the only extra code I had to write for a human was that code which changes when I start looking at a human as a specific type of animal. In a larger example, this means that I've not got to duplicate thousands of lines of code, but rather I can write just a handful of new blocks of code to override those from the base class. In the OO lingo, this is known as inheritance.

If you would like to see a complete source code example in PHP, look here for a demonstration I wrote during yesterday.

Learning OO Programming

Hopefully, the article above has given you a little insight into the world of Object Orientation ... but there's far, far more to it than I can write in an article such as this, and it's something that you'll need to try out for yourself and learn; for some people "book learning" can be very effective, but for others a training course is a far easier way to get them over the initial hurdle. I suspect you can see the advert coming ... ;-)

We cover OO languages and principles behind them on a lot of our public courses:
Perl for Larger Projects
OO Programming in PHP
Lua Programming
Programming in Python
Ruby Programming
C++ Programming
These courses last from 1 to 3 days, and include other related subjects with the languages concerned as appropriate. By that, I mean that a language such as Python is ALL OO, so the subject is covered in our general Python course, but with a language such as PHP, OO is something that's not needed by everyone so we have a single extra day for that course, which you can take in addition to the general PHP course if you wish.

All public courses are run at our Melksham, Wiltshire, UK, hotel and training centre. Our current schedule may be found here We can also run private courses there (or on your site) if you wish.

For private courses, we can also cover Object Orientation in Java, and we can train you on [Incr-Tcl] - Tcl's OO extension.

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

December 05, 2008

Preventing ^C stopping / killing a program - Perl

Here's a demonstration - in Perl - that shows you how to avoid a ^C (Control C) dropping you straight out of a program.

Have you ever accidentally hit ^C in the wrong window and terminated a long-running process just before it finished ... well, by setting $SIG{INT} to the address of a sub you want to run, you can divert the signal in Perl. The example code here simulates a long running process with a loop of 60 short sleeps (naps?) ...

$SIG{"INT"} = \&nowayjose;
 
$| = 1;
 
for (1..60){
  print "dot";
  sleep 1;
 
  if ($rq) {
    exit if (time() - $recent < 4) ;
    print "\nNah\n";
    $rq = 0;
    $recent = time();
    }
  }
 
sub nowayjose {
  $rq = 1;
  }

You'll note that all my extra "sub" does is set a flag so that the interrupt can be nicely handled at the end of the loop, that the handler turns the interrupt flag back off, and that I've written the program so that a second ^C within 4 seconds WILL cause it to exit.

As an afterthought ... if you disable ^C completely (i.e. if you don't use the 4 second trick), how will you get out of the program? Well ... you'll still be able to suspend it with ^Z then kill it with kill %1, or you'll be able to find its process id and use a kill -9

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


Useful link: Perl training

December 04, 2008

Making it all worthwhile

I know that a lot of people use our resources ... and that very few of them get in touch. That's only natural - it's very rare for me to send a "thank you" to an author.

So I was really touched to find the following in my email this morning:


To Graham Ellis,
 
Just e-mailing to say thanks for the great and easy to understand php image upload form at http://www.wellho.net/solutions/...database-retreive.html! It was really really helpful and prevented me having to "reinvent the wheel" in a way.
 
I haven't used it for any public site, it's just within the back end of a website I'm creating to let certain people in my team upload images to the website. I'll be adjusting it a bit for my own purposes but it was a great start :)
 
Thanks again for your great and helpful image upload code!
Patrick

Thank you, Patrick - you've given me a golden start to the day. (reproduced with permission)

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

Flurinci knows Raby Lae PHP and Jeve

Three more Perl Programming examples for you ...

Use of $" to produce csv data
Efficient code with map and grep
Use of implicit loop and print (-p switch)

... All from the Topicalisation and Special Variable module of our Learning to Program in Perl course.

Puzzled by the subject line? - It's a sample of output from the third or the examples. Have a look at the code and see how.

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


Useful link: PHP training

Romeo and Julie

Romeo wants to take his girlfriend Julie out to The Jolly Judge tomorrow night, but Julie's Dad (who really doesn't approve of young Romeo) has shut her in her room on the first floor of their home, which as you can see is on the top of a substantial mound.

Being a resourceful lad, Romeo is going to nip down to his local B & Q Store and nick a couple of ladders (it's this habit of his of nicking things that has put Julie's Dad off him, by the way) to get her out.

Your task ... if you're on our Perl Course ... is to write a program to help Romeo work out how long the two ladders he'll need will be:

• The mount is 12 metres tall, and there's a good grounding about 5 metres away from the base

• the window of Julie's room is 4 metres up from the ground, but Dad has placed a line of holly bushes just under Julie's window, so Romeo is going to have to foot the ladder 3 metres out.

The algorithm you need is:
   $ladlen = sqrt($w * $w + $h * $h);
and you're asked to write that in a separate sub / in a separate file, so that you can easily re-use the same code later if you need too (since Romeo is a bit of a jack-the-lad by all accounts, it would be a shame to write code just for him rather than have it available for re-use, wouldn't it?)

There's a sample answer - source code of the main program here, and you can find the file that contains the sub here. If you ARE here because you're a Perl programmer, do have a look at the source which is rather thoroughly commented - and contains examples of things like my v our, package definition, and the use of the wantarray function.

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

December 03, 2008

Progress Bar Techniques - Perl

Have you ever sat there and wondered "is this program nearly done ... is it still running ... how is it getting on" and wished you had a progress bar. But then have you ever watched a jerky progress bar and felt that it's more fiction than fact?

We were discussing these aspects on today's private Perl Programming Course (though on our public schedule, this topic is left until Perl for Larger Projects). And we came to the conclusion that progress bars, when carefully implemented, are an excellent idea. So how do you carefully implement them in Perl?

Here is a sample program that I wrote:

select STDERR;
$| = 1;
for (1..14) {
   sleep 1;
   $sofar = $_/14;
   printf "At %4.2f of 1.0\r",$sofar;
   }
print "\n";
$| = 0;
select STDOUT;

And here is a LONG set of notes on a very short program!

Firstly ... the "sleep" represents the work being done and the calculation of "$sofar" represents the calculation of progress so far; it's designed to be awkward and come up with a number that's sometimes a long decimal and at other times is short.

Notes ...

1. The output of the progress bar is to STDERR and not to STDOUT; this is done so that any redirection to file doesn't cause the progress bar data to be dumperd into the file as well, but rather to remain on the screen

2. I've used $| to set autoflush mode so that the progress data is actually output and isn't simply buffered. Normally, Perl buffers up to a \n character but we haven't used any of those right up to the end of the script, so without the setting of $| we would see no report until a sudden flush.

3. \r has been used to return the cursor to the start of the current line rather that to the next line - that way, one progress report overwrites the previous one repeatedly, rather than having them scroll down the screen

4. We've used printf for our output, and used fixed width fields which are plenty long enough for values that are going to be displayed. This means that the line length will NOT change as the program runs, so won't leave "droppings" at the right hand end when a shorter line is displayed over a longer one.

5. There's an indication of just what number we're going up to with our progress bar; we indicate (for example) 0.42 of 1.0 to clearly show that we're 42% of the way through and not just 4.2% or even 0.42%.

And - but it's not explicitly illustrated in this program - I advocate that you should NOT complete one phase of a program that shows a progress bar for that phase, then go onto another section that has its own progress bar ... progress should be reported as to how you're doing through the complete job. I don't know about you, but I have had some VERY frustrating experiences where a long-waited progress bar has finished and joy has turned to dismay as another bar has appeared for some further phase that I didn't even know existed ...

Source code of the example - here

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


Useful link: Perl training

Transition

We're moving from Autumn to Winter; the picture with the bright leaves on the trees is less than a month old, but it seems like an age ago. The bare tree was taken at Wilcot on Saturday. And this morning I was scraping ice off the car here in Cambridge.

Back to Melksham tomorrow night ... Friday is a Object Oriented Programming in PHP course at Well House Manor

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

December 02, 2008

Perl Socket Programming Examples

It's always a pleasure to run private courses - for when a questions that's a little bit away from the normal comes up, I can take time to provide a full answer and demonstration without fear of loosing delegates from other companies who have no interest. And so it was today - I have two examples, plus an old favourite.

Firstly, my customers told me that they'll be running a number of other programs / commands from within Perl, and wish to use Perl as the "puppeteer" - writing to and reading from those other processes even as they run. Choosing ping as an example program to run from within Perl, opened a demonstration process on a pipe and then read from that pipe. See Source code

Then, I was asked about (and got involved) in socket programming. The first example, with it all in a single program, got a little long ... so I refactored into a structured program, which makes it much easier to follow. See both the main program source code and the code of the subs that I used

Finally, they say "the old ones are the best", don't they? I so often write a demonstration to show context - how a list referred to in different ways can be output as all the elements jammed together, with the elements spaced out, or as just the number of elements in the list. Today's demonstration has its source code here on our site.

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


Useful link: Perl training

Out of memory during array extend - Perl

Use a hash if you want a sparse list in Perl!

If you set up a list in Perl and don't fill all the members from zero up, that's OK but all the missing elements will actually use up some memory as they'll point to an "undef" value. So this happens:

Dorothy:ppcsrd08 grahamellis$ perl
$num[1223776336] = 0;
Out of memory during array extend at - line 2.
Dorothy:ppcsrd08 grahamellis$

That's attempting to create over 1 billion members of a list ... which would take an awful lot of memory.

You can, however, use a hash instead:

Dorothy:ppcsrd08 grahamellis$ perl
$num{1223776336} = 0;
Dorothy:ppcsrd08 grahamellis$

In a hash you name rather than number your elements ... but an element can be named with any scalar, thus allowing to produce a sparse collection - one in which you don't have to predefine a whole lot of keys in order to reach the one that you need.

Lists are written with square brackets - [ and ] - round each member, but members of a hash are written with curly braces - { and }. If you refer to the whole of a list, use the "@" character, but if you refer to the whole of a hash, use a "%".

You can learn a lot more about lists and hashes on our Perl Programming Course ... I'm teaching a private variant this week in Cambridge with some extra topics such as a little bit of socket programming ... see the next post ...

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


Useful link: Perl training

Why I remember East Grafton

There are certain places that bring a poignant reminder to me when I drive through them - and one of those is the village of East Grafton, near Hungerford in Wiltshire. We passed through there on Saturday - for the first time in years - on a winter's drive around some of the parts of Wiltshire that are further from where we live.

"Who sold you THAT" ... I can remember the sentence, and the furrour it caused, when Jim Longmead, a field service engineer with Tektronix, question what one of our sales team had sold to a customer. Jim had a reputation for calling a spade a spade - for not mincing his words, even when perhaps he should have done so ... and for having a bit of a grumble when asked to do something. But that grumble was just a front - and Jim had a heart of gold.

I joined Tektronix as a very junior member of the team in 1976 - providing the software support over a side range of products, to compliment both the team of 5 or 6 hardware service engineers, and a dozen or so salesmen. And however busy he was, Jim would always find the time to help me with some issue or other - a little grump as was his way, then help over, above and beyond.

As the company grew, Jim moved "out West" and indeed so did I - the East Grafton link is because that's where he lived and we would meet there occasionally when doing a join visit; I have become one of those 'dreaded' salesmen, and he was the one who was going round installing, maintaining, and occasionally fixing the products that I had sold. I felt privileged to have him on my 'patch' and I think he enjoyed having a saleman who was a little more technical than most, and could ensure that most of the orders were actually right for the job.

Jim was out at Rolls Royce in Filton one day, dealing with some equipment that I had probably installed, when he had a brain haemorrhage and passed away "even before he hit the ground ...."


Other pictures from Saturday - a grey day, so "record" shots really ... East Grafton, Great Bedwyn, Little Bedwyn and Wilcot

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

Quietly putting prices up

At 7 a.m. yesterday morning, I stopped at Welcome Break's South Mimms Service area on my way to Cambridge; I'm particularly watching for price changes with the VAT drop - to see if we can continue to pass on savings, or if our various suppliers have quietly put their prices up, forcing us to do so once we get fresh stock.

<rant>

Muffin and Coffee ... £2.99. Hmm - signs a bit dusty; doesn't look like they have changed. My VAT receipt duly says 15% ... so that means that the base price has gone up - Welcome Break are pocketing the Chancellors's reduction and not passing it on.

And when I asked ... what a web of misleading information.

"We haven't put our prices up" says the young lady on the till. "Look - if you're VAT registered you can still claim back 39p"

"Our prices haven't changed for years"

"What you have bought would have cost you more if you had bought the two items separately"

"We have 24 sites - we can't change the prices all at once" (yes, but you changed the VAT!)

"It's been the weekend - we can't get staff at the weekend to do it"

Oh ... and just one honest answer that started with "Don't quote me but ...", so I won't quote it, nor give you any clue as to which employee it was who came over and had a quiet chat ...

</rant>

Wouldn't it have been nice to have been given a nice, honest "we haven't changed our prices [yet]. We're keeping the extra money and not passing it on". I might not have approved, but I would have respected the business decision.

Following on during yesterday, I bought Fish and Chips from a corner chippie, and booked into a small hotel. Both appear to left their gross prices unchanged and used the VAT reduction as a quiet way to put prices up by a couple of percent. Perhaps the government is more clever than we thought and that the real reason for the VAT reduction was to allow the retailer who is at the final stage of the supply chain to increase his margins in these hard times, and to put a brake on potential price deflation. This behaviour of our suppliers does make me question our own decision to hand back the difference to our customers - in some areas it may need to be a short-lived gesture on the proportion of our business in which we buy in and are just a part of the supply chain.

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

December 01, 2008

It must be nearly Christmas

Crowds waiting to join the "Santa Special" at Melksham; on the train with Santa, and Longford Road, Melksham - the Christmas lights. All pictures taken on the evening of 30.11.2008.

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