« March 2007 | Main | May 2007 »

April 30, 2007

Emailing as HTML (Web Page) - PHP example

If you want to send an email as HTML, you can do so by adding a content-type header.

<?php
 
$content = <<< EMC
<h1>Hello World</h1>an HTML email
Shwoing how the content can be sent
as a web page.
EMC;
 
$extras = "From: Graham Ellis \n";
$extras .= "Reply-to: Graham Ellis \n";
mail("graham@sheepbingo.co.uk","Web page in HTML Demo (control)",
$content,$extras);
 
$extras .= "Content-type: text/html\n";
mail("graham@sheepbingo.co.uk","Web page in HTML Demo (working)",
$content,$extras);
 
?>

Without the extra line, the email views like so:

But with it, I got

A whole host of extra considerations here - you might light to look at multipart emails (the sort that use several types in the same transmission - giving users the option of viewing as plain text - example). You need to consider how your recipients spam filters differently handle HTML to plain text emails, and indeed whether what you're sending is really necessary or could be considered to be spam.

Edit / note added - It's been pointed out to me that I mis-spelled the word "showing" and then compounded the problem by putting up a screen capture with the word mis-spelt. I'm allowing myself to take the view that showing a typing error in both the source and the resut isn't ENTIRELY bad as it confirms that the screen capture really are the result of my sources!

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


Related topics: via article database
More about Graham Ellis of Well House Consultants
Useful link: PHP training

April 29, 2007

Moving out some of the web site bloat

A late-night post ... the weekend has slipped away from us with a huge variety of things to catch up on, and a major new project on our web site. The update that we brought in over the new year has been working reasonably, but has been showing signs of "bloat" - too much, too complex to the detriment of the site from a customer perspective. So much of the weekend was spent cleaning and simplifying templates, and I'm hoping that pages uploaded over the next week or two will be cleaner, more navigable, will make better use of the available screen estate for real content ... and will be all together a more pleasant experience.

We're a small team, each will our own role in the company that only has the website as a small part of the total. Browser-specific adjustments that must all interact through the site would be all well and good with a big team (and perhaps necessary if we were in a highly competitive market with online selling and look making a huge impact) but there are other ways - "KISS" or Keep it Simple, Stupid ... which I think was the story of an earlier blog. My target for the update should be that you can find things like that earlier KISS post with great ease, view it nicely and print it out.

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


Related topics: via article database

April 28, 2007

Leaning tower of Cheeser

I know, I know - it's a dreadful put on the "Leaning Tower of Pisa" but I couldn't resist posting up Lisa's breakfast.

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


Related topics: via article database

Back button - ensuring order are not submitted twice (PHP)

Ensuring that forms aren't "double submitted" is critically important on certain automated data entry applications - the classic example being an absolute need NOT to allow your user to place an order twice if he / she uses the "back" button and presses submit again.

I came across an article on a Java forum talking about redirect after Post, but I can't say that I'm thrilled. An over-complex solution and there's much easier ways of doing it in PHP (and in Java and other languages too!).

Almost inevitably, on line ordering systems are going to comprise a number of pages where you select your product(s) and then, as a final operation, confirm your order.

In PHP, you should use the $_SESSION superglobal to maintain the state of each individual user as he / she goes through your site, starting each operation that updates the embryonic order with a call to session_start. By default, values WILL be stored between pages in this super-global and the back button will leave the order-in-progress (a.k.a. the shopping cart) in tact - and that's ideal because you'll not want your customers to loose their selected products if they commit the 'crime' of doing a back.

But when one of your users selects the "yes, confirm my order" button or the equivalent, you DO want to prevent a step backwards resurrecting the data. There are two ways of doing this. The easiest is to do a session_destroy which eliminates the content of the shopping cart from the session when it's confirmed - the rest of your submit code for that page will have emailed the order confirmation, added the necessary information to your table of to-be-filled orders, and so on. The alternative way (if you don't want to loose the whole session - perhaps you want to leave your user logged in, for example) is to selectively clear the vital variables such as the cart-to-date form $_SESSION when the order is placed.

We have an example of this approach on our web site - try it out here and see the source code of the main application here. You'll note that this is part of a demonstration of the "four layer model" for major applications (you can write appliactions in PHP that have the beauty of A Picasso, or ones that look like the dog's dinner) - but that's a story for another entry.

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


Related topics: via article database

Useful link: PHP training

April 27, 2007

Extended Credit request - train in June and be paid in September

Payment terms: "Payment will be made within 60 days of the end of the month in which they are received" says an order that's been passed to me for clearance. Those terms look like a return to the bad old days - should we accept them, we'll complete a course in the first few days of June, and invoice that month. The 60 days will start on 1st July, and payment will be cleared into our bank account on or by Monday, 3rd September. The "end of the month" trick adds, in effect, up to a further 30 days until the bill is paid.

Terms such as these, on what's quite a substantial order, used to be quite common. These days, with improved electronic systems they're totally un-necessary as far as company's administrations are concerned, and they represent bully-boy tactics by a huge multinational looking to use their suppliers as cheap bankers by providing them with what is, in effect, three months of interest-free overdraft.

What are our options? We could simply roll over and accept, and put the cost of not having the money for the period down as a "cost of sale". We could look to re-negotiate with the company's system, but what's the chance of their ivory-towered managers allowing more reasonable terms? And if they did on paper, would they really happen? And would it jeopardise future business? How about us requoting at a price that includes an appropriate interest charge?

"The surcharge of 10 pounds may be deduced if you pay within 10 days". So says a footnote on a bill that's also been brought to my attention (for other reasons), and it's tempting - so tempting - to start invoicing companies such as our 90-day friends with such a surcharge. But I fear that it would complicate our systems and administration where we wouldn't know how much to put through the accounts until it actually came in, and I can imagine a lot of confusion and a lot of resentment being caused in our particular line of business. We could set up an alternative "if you want 90 days" price structure, but then so many companies overrun our 28 day terms and need chasing - would we backcharge them? The whole thing is one of those silly nightmares that any business selling to other businesses or on credit faces.

I have no magic wand. No solution. Policy set, decision made, but only the experience of what happens will test the case. At the moment the jury's out.

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


Related topics: via article database

Grand Central Station

"Grand Central Station" answered the voice on the other end of the phone, with an American accent. Had I mis-dialled, or was I really looking for train times out of New York? No - this was a call I made into the office and Lisa, who moved from the USA 10 years ago next January, had recognised my number on caller ID - at least I hope she had recognised it and doesn't answer that way to everyone - and she was indicating that it was a busy day!

And, indeed, it sounds like it *has* been like a station for these last few days, with comings and goings at all hours. But also, Grand Central station is apt rather than Penn Central Station. For Grand Central Station is largely a commuter flow station - a place for regulars travelling 50 or 100 miles up State rather than occasional travellers who may pass through two or three times in a lifetime. And we are starting to see a flow of regulars - the conference room every 2 months for a partner's meeting, an overnight bedroom with a painfully early breakfast for Ms xxx visiting a company at Bowerhill, and "do you have the same room available next week" from this week's new guests.

Stepping back through some photos from this time last year, I came across some of the conference room at "404" - our headquarters - and I'm reminded that we have not two but three training rooms. And we're using 'em too ... MySQL last month, Perl just coming up ... in "the Conference Room" at 404.

 
Conference Room
404, The Spa
The Wilts
Well House Manor
The Berks
Well House Manor
 
7 Persons 15 Persons4 PersonsMaximum Class size
25 Persons50 Persons20 PersonsMaximum Theatre size
8 Persons24 Persons8 PersonsMaximum Breakout size

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


Related topics: via article database

April 26, 2007

A better alternative to cutting and pasting code

If you're new to coding, you'll be so concerned to be writing code that works that you may not take a look at coding technique. Your nose will be so close to the grindstone as you work that you won't take the time to look and ask "Do I need to keep grinding anyway?"

If you find yourself writing a piece of code and thinking "surely someone has done this before", they probably have, and the code is probably available to you - either as a standard PHP function of in resource libraries such as the PEAR and PECL. ((See footnote for other languages))

If you find yourself cutting and pasting part of your code, then STOP! - you should be turning that code into a function! "But I need to change a few things in the copy" I hear you saying. Maybe you do - and you have just identified those parts of the function code that will need to be passed in to it as parameters.

I wrote the text above in relation to PHP, but the same thing applies in almost every language.

In Perl, you write your shared code in a sub, and look on the CPAN resource library.

In Python, you write your shared code using a def, and look in the cheeseshop resource library.

In Java and C++ you write a method, in C a function, and in Tcl you write a proc. As I recall, in Fortran it's a subroutine or a function, and you may also come across words like macros and procedures ...

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


Related topics: via article database

Cheddleton, Staffordshire

An evening walk beside the canal.

In the fading halflight of early evening, it's hard to capture in a picture the quiet beauty and tranquillity of the canal at Cheddleton, where the Churnet Valley runs between the hills on the edge of the Staffordshire moorlands. But I thank goodness that this canal was re-opened 30 years ago, and that the railway up the valley does - at least - have a tourist service on summer weekends.

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


Related topics: via article database

April 25, 2007

A contrast in room rates and facilities

This week is another great opportunity for me to see how others do it. Efficient, regular, reasonable-standard chain hotels usually 'do' me when I'm away training, with no need to research ahead, but here in Leek there aren't any of the 'regulars' so I've stayed at the Peak Weavers for one night, at 50 pounds, and I'm the Garden House, at 26 pounds a night, for the rest of the time as the PW was full. Both are 'bargain' compared to hotels in our neck of the woods; in Bath, the average price of a room is 114.00 per night and we're a bargain compared to that at 80.00 single, and 95.00 double.

So - what do you get for your money? What's best value?

At 26 pounds, my room is very new, very clean ... and very small. It's one of those rooms that's a single because you couldn't actually fit a double bed in, and that has a folding louvre door on the en-suite because there isn't actually the room for a regular door to open either in or out. The shower is a "60cm" tray not a "90cm", and I have to duck at all times. And yet whilst I might appear to be being slightly critical, I really don't mind; I expect to get, actually, less than I have at the rate I'm paying. Apart from the noise of the rain on the roof during the night (I'm in the attic), it's quiet, and there's enough parking for me have not yet been blocked in. I should add - I have seen one of the double rooms - lovely, and of good size and headroom

At 50 pounds, my room had also been redone since my last visit when I happened to have been in the same room. The bed was double, the place much more spacious and yet ... really the extra space hadn't been taken advantage of. "Help - where can I put my computer" thought I, and it turned out to be best-ish perched on the bedside table, with the coffee tray moved over to the top of the low chest of draws beside the TV. But - nicely don't and shouldn't grumble. The shower and bath, with a pathetic water flow, leave me wishing for something a little more vigorous.

At 80 pounds, all of our rooms are probably bigger that the 26 pound room and the 50 pound room put together. And - conscious of the business traveller they do have good desks, plenty of power points (no need to scrabble behind the bed, not to plug each thing that needs charging up in sequentially through the night). Showers / baths have fitted heads, excellent strong water flow, and the TVs are bigun's with 26" screens that your laptop can connect to.


The Garden House, Cheddleton


The Peak Weavers, Leek

If I'm back in Leek again, where would I stay? I have to say, irrespective of price and room size, at the Garden House. And it comes down to the welcome / the friendliness of mine host and hostess. The "Peak Weaver's" is probably the more technically correct, with the somewhat stand-offish approach that could easily be mistanken for snobbishness. But "The Garden House", where some people might find the more friendly approach over breakfast to be a little intrusive (yes, I could have given 'lay off' signals!) suited me, and I learnt all about my host and hostess's other jobs and how they have taken on and grown the place in the last couple of years.

I started talking about the week being an opportunity to sample and indeed it is. And a chance to learn. It convinces me that we have many things right (and a good job too as it would be too later to change certain things at this point). We have had discussions about how much / little we should interact with the customers at breakfast, and it leaves me convinced that the "join in" is right. The Garden House, where I am much happier, has a single long table just as we do, and I met with Tom who's a Geordie working at the local meat processing plant for the week; contrast that to the other three blokes at the Peak Weavers who - well - I haven't a clue what they were doing in Leek, I only know that they got down before me and had all the newspapers.

And - from our businees view point - I remain convinced that real coffee 24 hours a day, unlimited wired and wireless internet access, large screen TVs with freeview and a willingness to accept credit cards are all right. Paying a third of our rates, I naturally expect to get only a small proportion of what we offer; actually, I think I'm doing fine and well for my personal needs.

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


Related topics: via article database

April 24, 2007

HTML - example of a simple web page

After a series of advanced courses over the last few weeks, it's really great to be back to basics for a week ... with HTML and simple PHP scripts being the target - training for an organisation who are using PHP to web enable some admin tasks on their intranet.

Back to basics with HTML ...

1. Directives to the browser on how to format are written as tags - <xxx> through to </xxx> as the close tag.

1a. Alternative - open and close in one - <xxx />

1b. Attributes can be set in open tags - <xxx yyy="zzz">

Attributes ought be in quotes (but sometimes we forget), and tag and attribute names really should all be lower case these days.

1c. Tags must be "well" nested - i.e. if you open "a" then "b", you must close "b" before "a".

2. All text outside tags displays 'as is' except for new line characters and multiple white spaces, which become single white spaces. Use <br /> for a line break.

2a. If you want an & or < character, use &amp; or &lt; - there are plenty of others such as &copy; for a copyright symbol.

3. Overall page structure - surrounding <html> to </html> tags, with <head> and <body> sections within.

4. Code to be run on the SERVER to be enclosed in <?php to ?> tag (breaks nromal rule) and this code to generate valid HTML.

Example:

<html>
<head>
<title>Staying at hotels in Leek</title>
</head>
<body>
<h1>The Peak Weaver's</h1>
This is some HTML. I find it <u>hard to know</u> what
to say when I'm doing a demo!<br /><br />
<Copyright>, &amp; me, <?php print(date("Y")); ?>.<hr />
What a wonderful way of writing text documents!<br />
Please see <a href=smith.html>the chap on my left</a> if
you want the StevEbay stuff. If you want to search,
try <a href=http://www.google.com/>Google</a><hr />
<form action=esq.php>
Your height <input type=text name=high><br />
Your weight <input name=heavy><br />
<input type=submit>
</form>
</body>
</html>

That's just the basics ... there's so much more about links, forms, Javascript, Style sheets ... but the above is a "Hello World" page of first examples. See it run here

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


Related topics: via article database

April 22, 2007

It can take more that one plus one to get two.

I was running a C++ course yesterday (yes, a Saturday!) and among the topics we covered was the overloading of operators. In languages such as C++ and Python, you can re-define what operators such as "+" do when you add objects together, and the course example I used was adding two enclosing cubes - boxes - where the resulting box to contain both the input boxes is sized as:
The LARGER of the two X values
The LARGER of the two Y values and
The SUM of the two Z values.
Think about it - stacking two cubes on top of each other.

Odd things happen with addition in real life too. With staff at the hotel now going off on their summer holidays, we need not just one person (plus the manager) but two who can perform each job. And that adds a whole new "can of worms" - procedures to ensure that jobs are documented and done consistently - things that Martin and I take for granted and do automatically each morning have to documented and checked. It's a darned site harder that just saying 1 + 1 = 2!

Please feel free to browse "Breakfast in 5 Stages" ... part 1, part 2, part 3,, parts 4 and 5 ... a new writing that I'm sure is NOT going to turn into a best seller, by Graham Ellis and other Well House staff.

Other pictures/pages added recently ... Heddington, Lacock as a film set and Random pictures of Well House Manor and Wiltshire

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


Related topics: via article database

Private Java Course - A customer's pictures

It's great to see customers coming on our courses and posting pictures up in public on places like Flickr ... especially when the pictures turn out to be better than mine.

Here are a some thumbnails that will link you to the images of a private Java course we ran a month or two back at Well House Manor


Rob - many thanks for putting thos picture on line and in public - Graham

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


Related topics: via article database

Useful link: Java training

April 21, 2007

Speed Networking - a great evening and how we arranged it

What an excellent evening! Our Speed Networking evening, organised on behalf of the Federation of Small Businesses, drew in around a dozen inividual and a coupe of pairs with a disparate range of products to sell, and a wide variety of requirements to meet - some by using other's products and services.

Seated at either side of what was (in theory) a single long table, each person moved one seat left every five minutes thus meeting every other person they passed. And when they went back down the other side of the table, we had engineered it so that they met the people they had missed on the way up.

Six meetings, then 5 5-minute presentations on aspects of individual's interests and businesses, and a further six meetings ... everyone felt that the two hours was excellently spend and went away with at least one (and in most cases several) excellent new contacts.


It worked in Melksham ... and it would would in Matlock, Mexborough, Mitcham, Moreton and Mumbles too. So let me share my algorithms / organisation scripts.

1. To set up a sheet to hand to each delegate as he / she arrives:

Delagate Number:

2. To set up a sheet to place at each seat around the table (seats 1, 3, 5, 7, down one side, opposite them seats 2, 4, 6, 8 etc):

Delagate Number: Total delegates attending:

(We need to know the total number of delegates to adjust the algorithm for an odd or an even number of attendees. With an odd number, one "speeder" sits out each time, and with an even number, one remains in a particular chair all evening to provide the "offset" on the way back and ensure that different people are met)

3. To provide the organiser's matrix:

Total Delegates:


"Speed networking in Melksham on behalf of the FSB"

Other Speed Networking articles

Advertising, setup, planning

The event itself and planning sheets

Background, pictures

Direct link to seat script

Direct link to Matrix script



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

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


Related topics: via article database

April 20, 2007

Two by One by Wiltshire

Four pictures of Wiltshire at a 2:1 aspect ratio ... all taken in the last few days.

Trowbridge, Marlborough Downs, Devizes and Kingsdown Golf Club

We love in a lovely county. No hotel availability for the Mayday bank holiday Friday, but if you fancy a long weekend in this lovely area we have space on most other weekends. See here

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


Related topics: via article database

April 19, 2007

Pointers in C

I know when I'm giving a C Programming course that I'll come to the section on pointers and I'll have to slow right down - those extra * and & characters take a little explaining and getting used to.

Here are the key points.

A variable declared with a * in front of it holds a reference to (i.e. the address of) another variable. The type of the OTHER variable is stated inthe declaration. Thus: float *boat; declares a variable called boat that holds an ADDRESS, and at that address you'll find a float variable.

A reference to a variable preceeded with an & calls up the ADDRESS of a variable rather than its contents - so it's suitable for assigning to a variable of the type described in the previous paragraph.

And a reference to a variable preceeded with an * calls up the CONTENTS of the address pointed to by the variable - in effect it's the opposite of &.

Example:

int main(int argc, char ** argv) {
 
  int bill = 25; /* hold int */
  int ben = 43;
 
  int *fpotmen; /* holds POINTER TO an int */
 
  fpotmen = &bill; /* ADDRESS OF bill */
 
  *fpotmen = 65 - *fpotmen;
  printf("Retires in %d years\n",*fpotmen); /* CONTENTS OF fpotmen */
 
  fpotmen = &ben; /* ADDRESS OF ben */
 
  *fpotmen = 65 - *fpotmen;
  printf("Retires in %d years\n",*fpotmen); /* CONTENTS OF fpotmen */
 
}

WHY?

Because you can assign lots of different variable addresses in turn to a single pointer variable, teh use common code to process a whole lot (array) of data. You'll note that I've illustrated this in the example above by exactly duplicating two of the lines of code, though in a real life application I would prefer not to duplicate but rather to write them into a separate function.

Let's run that code and see when Bill and Ben retire ...

[trainee@daffodil cxx]$ gcc -o panda panda.c
[trainee@daffodil cxx]$ ./panda
Retires in 40 years
Retires in 22 years
[trainee@daffodil cxx]$

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


Related topics: via article database

As I came back from Tesco

Early morning mist over the fields near Trowbridge - this morning just before 6

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


Related topics: via article database

April 18, 2007

Object Oriented Model - a summary of changes from PHP4 to PHP5

What are the differences between the Object Oriented model in PHP5 and PHP4?

Firstly (and the reason the release number jumped) is that assignments copy references in PHP5 (which is regarded as correct OO behaviour) but they duplicate or clone the object in PHP4. This may sound a bit obtuse, but:
* if you duplicate an object and then change one of the copies, you do NOT effect the data refered to by the other name (PHP4 behaviour)
* if you copy by reference (PHP5 behaviour, in effect giving the object a second name) and then change one of the "copies", you effect both as there one and the same.
In effect, it's the difference between letting someone share a piece of paper with you and both writing on it (PHP5), and taking a photocopy to give to someone then each writing on your own sheet (PHP4).

The second major difference is that PHP5 lets you use a whole lot of RESTRICTING keywords in your definitions of classes and methods. You can declare that functions and member variables are:
* private - i.e. only visible inside the class
* protected - i.e. only visible in the class or its subclasses
* final - i.e. cannot be overridden by / in subclasses
And you can declare classes to be
* abstract - i.e. MUST be subclassed with specific extra methods
* to implement an interface - i.e. MUST define certain methods

None of these new keywords adds new capabilities, apart from the capability of restricting, so why are they there? To allow the designer / author of a class to limit the externally available elements leading to a crisper, easier to documuent and maintain API (application programmer interface), in the long term interest of maintainable PHP code in substantial applications. If you want a member to be public, you can still use the var keyword of PHP4, although you're really encouraged to use the public keyword that means the same thing and, you'll note, does NOT restrict.

Thirdly, in PHP5 you can name your constructor method __construct rather than have it as a function with the same name as the class, and you can use a parent:: notation to call up methods in the base class is you wish to. In this way, you no longer need to code the name of the class, nor its relationship to other classes, internally - once again making for easier code modification and use later. PHP5 also has a __destruct method which is run to clean away objects when you're finished with them.

Other additions at PHP 5 to the OO model include
* A static keyword to let you define class / static / unbound members
* An autolaod method called if a class is missing at run time
* An __clone method if you really want to duplicate an object
* An __toString method that lets you define what's printed out when you print or echo an object variable
* Exceptions, Reflection classes, constants, interceptors ....

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


Related topics: via article database

Useful link: PHP training

April 17, 2007

Course, right place, right time

Courses tend to be in the right place at the wrong time to look around at pretty places, or in the wrong place (nothing much to see) at the right time of year. But just ocasionally, I do have an opportunity to wander out of my hotel and look around at some lovely places ...

Last night in Hereford ... and I have put more pictures in our wiki here

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


Related topics: via article database

April 16, 2007

Gordon Dodge, R.I.P.

Gordon Dodge, who helped fight such long odds to get Melksham station re-opened in 1985 - and won - passed away yesterday. My deepest sympathy goes to his wife Audrey and family who have lost a remarkable husband and father.

When I started the "Save the Train" campaign 2 summers ago, Gordon welcomed this upstart into the fold of campaigning for the retention of an appropriate service under the harsh new Greater Western Franchise which puts profit ahead of passengers - and I am very VERY grateful for that. The Melksham Rail Development Group, and the West Wilts Rail User Group (he was Vice Chairman of both) could so easily have taken umbrage at the newcomer, but instead I was welcomed and we worked well together.

It didn't take me long to realise that Gordon was far more active in both groups that his "vice chairman" role implied. A Friend of Melksham Station, Gordon tended the flowers, even though he had to carry the water in his car from home (their being no tap at the station), and last year planted the beds in First Group's colours, even though he shared our disquiet as to what they were doing to our service. That was Gordon for you - welcoming, generous and quietly active.

Gordon Dodge (standing behind Santa) organised the "Santa Special" train trips from Melksham to Swindon in early December each year.

Gordon talked about working at "The Avon" in Melksham, and work in the print shop there. It sounded very much like he loved his work, and when he retired he took further work as a pallbearer, working for our local undertakers. Some of the tales he had to tell ... but never at the expense of anyone, I note (as I don't think he had an ounce of that in him!) had us enthralled.

Still very much an active supporter, Gordon came along to our train meeting early last month - he wasn't feeling (or looking) well, but he was very much an ACTIVE supporter. We were shocked to hear that he was in hospital a week or two later, and we visited him in there. He knew / we knew that there was no certainty that he would pull through, but still we talked of trains, and future, and how we hoped we would be able to arrange a special this summer to Weymouth, and that he would be able to join us on the first day of an appropriate service this coming December.

Gordon's worked for both the local undertakers, and so he's pretty much aware of what'll go on - indeed, he was talking the other week of planning his own funeral and had some very specific ideas. I only heard of his passing a few hours ago, so I can't pass on the details yet - but I will do so.

And I think it would be a good memorial to Gordon is we COULD run a seaside special this summer. And it would be a GREAT memorial if we could get that appropriate service back for the town that he loved, through the station he cherished.

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


Related topics: via article database

April 15, 2007

Helsinki - what comes naturally

Even when it's sweltering in England, it's quite cold in Helsinki and everyone was heavily clothed - I suspect that there was a hot water bottle (and perhaps an iPod too) under that hat.

So perhaps it's as an educational aid to the locals that statues such as this may be found in the local park (or perhaps it's the Nordic way - see Viglandsparkin, Oslo).

The reindeer may look on and wonder about this strange new world ...

... but I am glad to see that the Finns have taken the education further ... I particularly liked the "beware Children" sign behind this sculpture.

I've put up more (and more conventional!) pictures of Helsinki on our wiki - here here and here.

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


Related topics: via article database

Turning objects into something you can store - Pickling (Python)

If you're working with objects in an OO language and you want to transfer them to another computer ... or simple save them from the current application for reloading into that application or another one on the same computer later on, you need to serialize the objects.

Data within OO programming languages is stored in the heap and as its name implies, the heap isn't neat - there's pointers and information all over the place, and even if you save an object correctly into a file of database, without extra information you probably couldn't read it back in as the memory locations and addresses used internally probably wouldn't be available in the next program. Serialization is the process that adds the extra information you'll need

Python's cPickle module allows you to serialise an object. The dumps method writes any object to a string, and the loads method reads the object back from a string. The reloading program does need to have imported any modules that were used within the dumped object, of course. If you want to write objects straight to a file, you can use the dump method instead, and reload using the load method.

Source code examples:
Picking
Unpickling
Class of objects to be stored / recovered

Note also the marshal module, which allows you to dump and restore simple objects, and the pickle module which is written in pure Python rather than a mixture of C and Python. Marshal is OK for simple objects (perhaps its a bit more efficient sometimes) but you should only use pickle rather then cPickle if there's a chance of cPickle not being available.

The term "shelving" is often used in association with pickling. Objects picled can be stored in strings, files, databases ... and the shelve module allows you to use an anydbm 'simple' database for the purpose. Personal choice, though - MySQL, but remember not to store objects for the long term as an upgrade / change to the internals of a class may render pickled object unloadable.

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


Related topics: via article database

Useful link: Python training

Python decorators - wrapping a method call in extra code

Would you like to add an extra set of wrappers around a series of function of method calls - perhaps to add a profiler or logger to your application? These are examples of the things you can do with Python's decorators, introduced (with the syntax I'll show you below) in Python 2.4.

Here's a class of object that I've defined called "User". The only difference from regular code is the @logger line that's been added before each definition to ask for it to be wrapped in (decorated) with something called logger.

class User:
    @logger
    def __init__(self,username,email):
        self.uname = username
        self.email = email
    @logger
    def getemail(self):
        return self.email
    @logger
    def getname(self):
        return self.uname

And here's the code of a test application that uses that class:

team = []
team.append(User("Lisa","lisa@wellho.net"))
team.append(User("Leah","leah@wellho.net"))
team.append(User("Christine","christine@wellho.net"))
for member in team:
    print "Team member",member.getname(),\
        "has email",member.getemail()

The results when I run (with the correct version of Python, of course!) are very much as you would expect:

Dorothy:~/ grahamellis$ /usr/local/bin/python dec01 (Python 2.5)
Team member Lisa has email lisa@wellho.net
Team member Leah has email leah@wellho.net
Team member Christine has email christine@wellho.net
Dorothy:~/ grahamellis$ python dec01 (Python 2.3)
  File "dec01", line 21
    @logger
    ^
SyntaxError: invalid syntax
Dorothy:~/ grahamellis$

However ... there's an extra log file that was generated by the code in the decorator -

***__init__ <function __init__ at 0x650f0>
(<__main__.User instance at 0x66620>, 'Lisa', 'lisa@wellho.net'){}
 
***__init__ <function __init__ at 0x650f0>
(<__main__.User instance at 0x66670>, 'Leah', 'leah@wellho.net'){}
 
***__init__ <function __init__ at 0x650f0>
(<__main__.User instance at 0x66698>, 'Christine', 'christine@wellho.net'){}
 
***getname <function getname at 0x651f0>
(<__main__.User instance at 0x66620>,){}
 
***getemail <function getemail at 0x65170>
(<__main__.User instance at 0x66620>,){}
 
***getname <function getname at 0x651f0>
(<__main__.User instance at 0x66670>,){}
 
***getemail <function getemail at 0x65170>
(<__main__.User instance at 0x66670>,){}
 
***getname <function getname at 0x651f0>
(<__main__.User instance at 0x66698>,){}
 
***getemail <function getemail at 0x65170>
(<__main__.User instance at 0x66698>,){}

The final piece of the jigsaw is the decorator itself - loaded in the top of the test source file in my example (full source code listing here but more often in its own separate module.

def logger(f, name=None):
    # if logger.fhwr isn't defined and open ...
    try: 
       if logger.fhwr:
          pass
    except:
       # ... open it 
       logger.fhwr = open("log.txt","w")
    if name is None:
        name = f.func_name
    def wrapped(*args, **kwargs):
        logger.fhwr.write("***"+name+" "+str(f)+"\n"\
+str(args)+str(kwargs)+"\n\n")
        result = f(*args, **kwargs)
        return result
    wrapped.__doc__ = f.__doc__
    return wrapped

That's not a piece of "first day Python", with exceptions to check on the existance of a variable, names containing code blocks, and references to a number of interbal variables - but it will provide you with an excellent springboard from which you can start using decorators. Have you even said to yourself "I wish I could put all my function calls through this extra filter ....? Well - now you can - it's a Python decorator!

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


Related topics: via article database

Useful link: Python training

April 14, 2007

A picture (mostly in words) of Helsinki

It's a while - a long while - since I wrote a travalogue of one of my journeys - things have gone from busy to mad to manic over the past year and that's hardly a suprise - in the last year we have bought a house, refurbished it into a high quality hotel, planned all the rooms, staffing, systems, opening and operations ... and still kept courses running (an income flow to gelp finance the expansion) with little or no dropping off.

However, I sit now on a Finnair flight from Helsinki back to Heathrow with a camera - up there in the rack above my head - stuffed with pictures taken on a Friday evening and Saturday morning in the Finnish capital and there's some wonderful material there that I want to link together and share.

Is Finland a part of Europe, or a part of the East? It's both. It was a territory of Russia before it broke away during the last Century, but now it very much looks like - and looks to - Europe. Working in a near-central suburb, visiting the home of one of the people I was training, walking around the City centre I felt we could have been in a city in the Netherlands, Belgium, Germany or Austria. Not really Scandinavian. Certainly not - now - Russian. "Look Graham - the only thing we really had and retain in common is the Vodka" says one of my contacts.

Is Finland ancient or modern? It's modern. Very little dates back more than 100 years - a handful of historic buildings, perhaps, but that's about it. Some architecture from the early part of the last century, but the majority less - far less - than that. And yet there's an underlying ancient or old fashioned element - you'll find the haze of smoke in a restaurant, see parcels laying around unattended, be able to use luggage lockers at the main station and see children out on their own - things that modern society elsewhere has moved on from with safety and security issues. And you can buy bear meat, elk, reindeer ... and reindeer skins. The ancient still shows through, all be it for a tourist show at times.

Over 95% of Finns have mobile phones. And the electronics isn't just up to date - it seems to be very much in the future. "Where do you recommend we eat?" I asked my hosts, and they directed me to eat.fi - not just a directory of places to eat but a conprehensive one with reviews, with opening times and maps shown, and with the map updating through the day to show you where is open, where closed, and even where is open but closing in the next hour.

Public transport is good, efficient, and cheap to use. Maps and diagrams of routes are clear and the ticketing system is simple. My chances to sample were limited, but the Metro (underground) wasn't overcrowded and seem to be running to a correct schedule. The bus turned up and ran when we expected it, the trams looked like on time, and the trains were running in and out of the central station like worker ants, silent, smooth and fast. No doubt they *do* have service incidents, but I saw no evidence of any.

"How do I find out how to get to xxxx?" - another question of my hosts for I am an inquisitve (a.k.a. nosey) guest. "Just pop your location into your GPS system and it will give you the walking route to the appropriate public transport, the timetable, change information, and your walking route at the end too". True integration - perhaps Finland is THE most developed country in the world as far as this is concerned.

"The people make the country". Polite, happy to help, and happy to help the visit / tourist honestly. The lady at the airport wanted to be sure of where we were going to ensure that we were able to import what we were buying, and she wanted to be sure that I knew that it was reindeer liver that I had, and not the regular meat. Good for her, and thank you. The clerks at the hotel, when the wired internet didn't work on the first evening, gave us wireless access for the wired price (I'm not sure why Wifi is normally 3 times the wired price, mind you!).

Finland is a country of water - we saw that as we flew out with a lake and island patchwork visible from the plane until we reached the Baltic. And yet we got a distorted view in Helsinki. Perhaps time would have allowed us to see a more realistic view on the ground ... perhaps this is a city to return to some time; the evidence of other things to see that I come back with is scant, but it's a friendly people and - perhaps some time when we've wound back from manic to mad to merely busy, we'll take a summer fortnight to revisit Helsinki, and take side visits to St Petersburg and Tallin too.

I've put further pictures of Helsinki here - night, here - day and here.

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


Related topics: via article database

__new__ v __init__ - python constructor alternatives?

The constructor you'll normally override (and call when you create an object) in Python is called __init__, but there is also a method called __new__ available to the class author.

Here's a code sample showing three classes with a mixture of different constructors.

class A(object):
  def __new__(cls, *args, **kwds):
    print "one"
    print "A.__new__", args, kwds
    return object.__new__(B, *args, **kwds)
  def __init__(cls, *args, **kwds):
    print "two"
    print "A.__init__", args, kwds
class B(object):
  def __new__(cls, *args, **kwds):
    print "three"
    print cls
    print B
    print "B.__new__", args, kwds
    return object.__new__(cls, *args, **kwds)
  def __init__(cls, *args, **kwds):
    print "four"
    print "B.__init__", args, kwds
class C(object):
  def __init__(cls, *args, **kwds):
    print "five"
    print "C.__init__", args, kwds
print C()
print "====================="
print A()
print "====================="
print B()

And here's the result of running that code:

40:~/ndfi grahamellis$ python newvinit
five
C.__init__ () {}
<__main__.C object at 0x6fc10>
=====================
one
A.__new__ () {}
<__main__.B object at 0x6fc10>
=====================
three
<class '__main__.B'>
<class '__main__.B'>
B.__new__ () {}
four
B.__init__ () {}
<__main__.B object at 0x6fc10>
40:~/ndfi grahamellis$

In class C, there's only an __init__ so that's run. Class A has both, and so the __new__ take precedence. In class B, the __new__ takes precendence but it makes an apparent recursive call that's been diverted to __init__ as something of a safeguard - for illustrative purposes, this one!

When would you use __new__?

1. When you want you constructor to return an object of a different type to the class in which it is defined. For example, you have a class "animal" with subclasses "farmanimal" and "pet" and you want the animal cosntructor to be able to examine the data passed in to it and return an animal ... OR a farmanimal OR a pet depending on that data.

2. It has been suggested that experienced base class programmers override __new__ to discourage programmers who subclass them from overwriting their constructors. Personally, I would suggest that a good training course is better than this form of security through obscurity.

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


Related topics: via article database

Useful link: Python training

April 13, 2007

Using a list of keys and a list of values to make a dictionary in Python - zip

If you have two lists in Python and you want to use them as the keys and values of a dictionary, you might be interested on Python's zip function. It's NOT the use of zip as we know it for file compression - rather it's used to interlace (combine) elements of two lists into a list of lists.

Here's an example - two lists

names = ["Jesus","Marc","Michal","Graham"]
places = ["Spain","USA","Poland","UK"]

Combine them with zip and you get a list of 2 element lists which you can turn into a dictionary:

combo = zip(names,places)
who = dict(combo)

Here's the result:

{'Michal': 'Poland', 'Marc': 'USA', 'Graham': 'UK', 'Jesus': 'Spain'}

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


Related topics: via article database

Useful link: Python training

April 12, 2007

Python dictionary for quick look ups

Using a dictionary in Python, you can avoid the need for a loop in your program to search out elements in a collection. Suppose, for example, you have a list of people and a list of their countries of origin, you could look up individuals like this:

names = ["Jesus","Marc","Michal","Graham"]
places = ["Spain","USA","Poland","UK"]
for x in range(len(names)):
  if names[x] == "Marc": print places[x]
  if names[x] == "Graham": print places[x]

But with a dictionary, it is both easier and faster:

who = {"Jesus":"Spain", "Marc":"USA", "Michal":"Poland","Graham":"UK"}
print who["Michal"]
print who["Jesus"]

In effect, a dictionary is a database table with two columns ...

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


Related topics: via article database

Useful link: Python training

April 11, 2007

A course in Helsinki

Greetings from Helsinki, Finland, where I'm running a Python course. After a late arrival last night and a busy course (10 bright delegates) I feel tired, but inquisitive enough to have a brief look around in the last light of day.

A modern city - this is the area I'm staying in, a couple of stops on the Metro from the town centre

And one of the few (?) older buildings - a city museum on the main central square, outside the railway station.

The maps shows water all around, and Finland is said to be very much a country of water; perhaps I'll get a chance to see some of that over the next couple of days ... or perhaps not, as a business and training trip is very much a business and training trip, and with the best will in the world any opportunities to explore new places much be looked upon as unexpected bonuses.

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


Related topics: via article database

April 10, 2007

Planters in the Spring

Christine and Jane (not to forget Ed) have done us proud in transforming a building site into a hotel garden. It's been a big task with major areas to be re-turfed, the debris of ages cleared, new beds installed, and the rawness of the site transformed into the pleasant place that you'll want to stay when you're in Melksham.

Ongoing garden works by Nigel, keeping the place in trim especially in the current grass-growing season - and we have a LOT of grass.

The planters to the left and right of the front door struck me as beautiful in the halflight of dawn this morning, and I couldn't resist adding in the pictures. Quite an interesting technical challenge - to use natural light, flash, or a mixture? Which of the hundreds of settings on the digital camera to use? Both of my experiments look effective in their own way - but then I've got some of the beauties of spring to work with right on my doorstep, so it really wasn't that hard even for an amateur photographer like myself.

Technical note The UPPER picture was taken with flash, just after dawn when there was also low natural light available to provide the skylight to the read and, in effect, the silhouettes of the trees. The LOWER picture was taken earlier. Flash was NOT used, but the camera was set to make best use of available light, and the light from our entrance porch was illuminating the flowers.

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


Related topics: via article database

A strong team broadens the professional coverage

At the very tail end of last month, we ran a MySQL course back in the old training centre rather that at Well House Manor - quite simply, we're getting busier with external bookings as well as our own courses, and now that we have three conference rooms we can mix and match as appropriate. The "Old 'un" still works well and we've now got enough furniture and equipment to book fully.

That day, I was giving the MySQL at "404" and Lisa was downstairs there in "Command Central". Christine, Leah and Martin [alphabetic order!] were on their own at "The Manor" - something we consciously let happen so that they can take on the roles and responsibilities. It's both staff development in their interests and broading out who can do what in Lisa's and mine.

So - in shortly Lisa and I head up to Finland to run a course up there, and to see the Friday evening nightline in Helsinki. There's hotel bookings ... there's people around, and we feel confident that issues that come up will be dealt with and the place will be in safe hands.

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


Related topics: via article database

April 09, 2007

Python GTK - Widget, Packing, Event and Feedback example

Python has a variety of GUIs available ... one of which, GTK, has been getting much more popular of late. As is common with many of the GUIs in Pyton and other languages, you'll typically write an application as follows:

Within the GUI, each widget must be defined, packed into the appropriate piece of Geometry, and shown (and the box and window containers also need to be shown) and - there you are - a simple GUI.

As you use the GUI, you'll want to provide your user with feedback by altering the text on labels, buttons, and making other widget changes. Slightly surprisingly, you define all the possible actions early on then have your events trigger them as callback functions

The authors of GUI documentation always seem to start with a very very simple "hello world" example, then leap off into some quite extravagant further example, when all you (the programmer) want is a few buttons to perform tasks (and change to show what you've done). Of course, I do know why they make them complicated as they've got dozens of events, scores of widgets and hundreds of facilities they would love you to use.

But I'm going to break from convention today and point you in the direction of a simple Python Gtk example that starts like this:

showing the basic elements of a window, a box, and a couple of widgets. Events are defined on the first two buttons that change the text and the quit button is (!!) programmed to quit the GUI.

As you run the GUI, you'll see the display counting up the number of times each button is pressed: - thus completing that vital feedback element that you'll need in every GUI but never seems to be described in the manual until a footnote in chapter 5 or 6.

Complete (commented!) source code is here where you'll find further examples as well.

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


Related topics: via article database

Useful link: Python training

April 08, 2007

Overcrowded trains around Bristol

A Bank Holiday trip to Bristol yesterday, with our local train company providing a service that wasn't substantial enough to meet the customer demand. Temperatures raised, passengers denied access, already-late trains delayed further as people tried to get in and out at each stop.


The 08:46 from Weymouth - 40 minutes late by Bristol

Really great to have an opportunity and space in Bristol before the return trip


The 16:30 from Cardiff - over 30 minutes late by Trowbridge

Any yet, in spite of all the problems, train really IS the way to travel.

Further reports for anyone following the train story - here and here.

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


Related topics: via article database

The Holiday - unlikely romantic comedy?

Last night, we watched "The Holiday" - a romantic comedy with Cameron Diaz, Kate Winslet and a couple of blokes that I didn't find quite so fetching. The premise was that both the young ladies (one in the USA and the other in the UK) had come to the end of relationships and were unhappy and distinctly OFF men in the run up to a holiday season. Both looked to getting away for a fortnight and they came across each other's places (San Franciso and the countryside near Godalming) on a holiday home swap web site. Can you believe - off they went and swapped homes. Travelling on their own to an unknown land for a vacation, to get away?

The Cameron Diaz woman ends up in a remote cottage, freezing, minimal wood fires and is nearly turning straight around when a guy called Graham turns up the worse for wear from alcohol on her doorstep; explains he's the other woman's brother and persuades her to let him stay the night. Romance follows, but it seems that Graham has others in his life which in time turn our to be two young daughters he's been left with. I guess the rest of that half of the plot is pretty predictable.

And I haven't told you the half of the improbabilities! Pretty far fetched from real life? Curiously not ... Lisa and I found ourselves spotting a number of parallels ... not everything you'll appreciate as I've never owned a house in Godalming ... but we do rather feel that the main parts of our story have been nicked.

In the film, the story ended with both couples (because the girl who went to LA found romance too) back at Graham's place, with his daughters too, for the happiest new year of their lives. Questions had been left hanging about "damned geography" - how things might work out for the future. But there, I can add a happy conclusion for you. Lisa and I have known each other for over 10 years now. Been married for 8. Stronger than even; I love her, couldn't do without her, and can't imagine life without. We're enjoying working on "and they lived happily every after".

Happy Easter, Lisa. Happy Easter, everyone!

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


Related topics: via article database

April 07, 2007

Wiltshire Circles

Wiltshire is a county of historic circles at an architectural scale. Most famous is Stonehenge and the other stone circle at Avebury. Less famous is Woodhenge ... and yesterday I can across another circle, much more temporary and in a different material:

The view from our bedroom window!

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


Related topics: via article database

April 06, 2007

Buffering output - why it is done and issues raised in Tcl, Perl, Python and PHP

When you go to board a plane at Heathrow, do the ground staff admit the passengers one at a time, ensuring that each is seated before the next boards, and sealing and re-opening the main doors between each? What a stupid and inefficient system that would be!!

The same thing applies when you're programming - outputs that you THINK that you're printing directly to screen, to file, to pipe, or (via a socket) to a process on another machine may in fact be waiting in the lounge - buffered - to be output with greater efficiency in a single block.

Should you wish to read from a newly written resource, then, you might have to wait. In the majority of cases it would not be a problem. Language libraries are usually built with a number of checkpoints at which data is "flushed" even if buffers aren't full. Such flushes commonly occur:
a) When a new line is generated (keep screen up to date)
b) When an input is about to be read (so that prompts can be seen!)
c) When the buffer reaches 4k of data
d) When the file handle is closed
e) When the program exits
and these account for most, but not all, of the cases the programmer needs to be aware of.

"But not all" I wrote. Here are some common exceptions:

In Tcl, the fconfigure command gives you channel by channel control. By default, flushing happens line by line (and so NOT when you're about to do a read) and this means you'll want to flush stdout after outputting a prompt with puts -nonewline. Otherwise, the prompt is only issued on the screen AFTER you've answered the question. [example]

In Perl, output is similarly flushed at new line, and in addition it is flushed at read. Good - no need for Tcl's flush. However, if you're generating a progress bar - either a series of dots or a line that's being overwritten time and again, then you'll need to flush. Have a look at autoflush and have a look at the special variable $| (that's dollar-pipe). Neither of these flushes itself - rather they add an extra flush at the end of each print. See
[/example].

Python has a similar arrangement to Perl, so it's quite rare that you need to flush the screen output - but again you DO need to do so with a progress bar. [example].

I describe PHP as being a "batch" or "batchlet" language - at least in its intended web use. So it doesn't have the interactive buffering issues associated with keyboard-to-screen in most uses. Actually, you have rather the opposite problem sometimes. In PHP, if you try to call the header function, or anything else that could effect the headers (even session_start can do it) after you have generated some output, you'll get an error message like Warning: Cannot modify header information - headers already sent by .... There *is* an ob_start function to turn ON output buffering but, really, best programming practise is to generate your headers early!

There are PHP examples broken here and working here. They include links to source.

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


Related topics: via article database

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

April 05, 2007

Government pressure on me to shut up after I make the papers

Well ... the Government's response to my petition for an appropriate train service made the front page of the Western Daily Press yesterday (article) under the headline "Blair Snubs Rail Misery". And we also got coverage in the Bath Chronicle, the Wiltshire Times and the Wiltshire Gazette and Herald. The Spar shop / garage next door started giving me very funny looks as I keep coming in for more newspapers!

The response to the petition was disappointing - very disappointing. After all the hard word work, five year old figures and demonstrably wrong, pessimistic, forecasts are regurgitated. The Civil servants know they're incorrect, damn it - and they know that the current service schedules are not appropriate. I can tell you this because I have spent a long time, on the phone in person, to 'Whitehall'. And to compound the disappointment, some "bright spark" has read the request for an appropriate service to mean a return to the old pre-December situation. No - I'm no Luddite and the petition was no request to step back in time - quite the reverse; it was a request to look forward. I agree with the Government response that the service should not revert to what it was - it should develop forward to meet the need. You'll note:
* Compound growth between 8% and 35% per annum over 5 years
* West Wilts towns to grow by 50% over the next 30 years
* Increasing road congestion making the car commute less practical
* Cheaper trains perhaps for hire (to reduce cost)
* Environmental issues ...

But the $64,000 question is how we take this dreadful response from the Prime Minister's office and, never the less, work forward with the other forces that we know are there to a positive conclusion. And how we tie that in with support from the local transport authority (Wiltshire CC) and others around such as Somerset and Swindon to everyone's benefit.

So yesterday evening concluded with a most interesting call from a supporter / insider with a political "nose", warning me off criticising the Government too hard on their response. "He's trying to shut you up as the Government don't like this publicity" suggest Lisa and, yes, that's a big part of it. But at the same time, we DO have to work with these people - Glaswegian Ministers who don't even look after trains in Scotland - until the next general election in perhaps 2009 or 2010. My purpose is not to score political points with a political football of the railway service. It's to have provided an appropriate service. So, in spite of the idiosyncrasies of the system and the distortions it brings, I'll work on with Tom Harris (DfT) , Alison Forster (FGW), Fleur de Rhe_Philipe (Wiltshire) for the joint aims. They can ALL come out as winners, and the travelling public can come out as winners too!

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


Related topics: via article database

April 04, 2007

Function / method parameters with * and ** in Python

In Python, you can define a function with optional parameters; if you specify a single * in front of a parameter, then that will be a tuple of all remaining unnamed values. And if you specify two *s in front of a parameter, that will be a dictionary of all remaining named parameters.

Let's see an example:

def demo(first, second, *third, **fourth):
  print "first",first
  print "second",second
  print "third",third
  print "fourth",fourth
  print
 
demo(1,2,3,4,5,6,7)
 
demo(5,6,7,8,aa=9,bb=11,cc=44)

When I run that, I get

C:\gje>python onetwo.py
first 1
second 2
third (3, 4, 5, 6, 7)
fourth {}
 
first 5
second 6
third (7, 8)
fourth {'aa': 9, 'cc': 44, 'bb': 11}
 
C:\gje>

Note that * and ** parameters must be the last parameters in a function definition, and if you're going to use both of them you put the ** at the very end, after the *.

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


Related topics: via article database

Useful link: Python training

April 03, 2007

B-2-B Networking, 20th April. Useful for YOUR business?

On Friday April 20th [2007], we're organising a business to business networking event in Melksham on behalf of the Federation of Small Businesses.

This is a golden opportunity for businesses in the West and North Wilts areas (Melksham, Chippenham, Trowbridge, Westbury, Bradford-on-Avon, Corsham, Warminster and Box) and Bath to meet up and establish new links.

I've been to a number of networking events in the past. I've made some very useful contacts. And I've met some charming people with whom I have nothing in common - and sometimes spoken to them for quite a while, perhaps missing out on other good contacts. So we're going for a "Speed networking" approach where every business meets every other business - but just for a few minutes.

Bring along ...
* Plenty of business cards and some of your literature
* Notepad and pen
* A one minute synopsis of who you are, and what's your business

Arrive from 18:30 onwards (snacks, beverages and a tour of Well House Mnaor). We'll be starting SHARP at 19:00 on Friday, 20th April ... please email me - graham@wellho.net if you would like to book a place or would like further information.


* 5 minute presentations - open to FSB members only; we have just one or two openings remaining.


The following information goes a little deeper into the arrangement of the meetings and is provided for technical interest only

Speed Networking and Speed Dating

Managing the meetings

We're setting up a speed networking event at Well House Manor in a couple of weeks and it turns out that the published algorithms for speed dating aren't suitable - on speed dating you meet all the players on the other team (and not those on your own), but with speed networking we want to to meet everyone.

How will be do it? Imagine a long table with people seated all up one side and back down the other, meeting across the table:

1 meets 7
2 meets 6
3 meets 5
4 sits out

We've got an odd number of people in this example (7) so one person is unpaired and sits out at each step.

At the end of the first meeting, each person moves 1 seat to his/her right:

7 meets 6
1 meets 5
2 meets 4
3 sits out

and the same action repeats after each meeting

6 meets 5
7 meets 4
1 meets 3
2 sits out
5 meets 4
6 meets 3
7 meets 2
1 sits out
4 meets 3
5 meets 2
6 meets 1
7 sits out
3 meets 2
4 meets 1
5 meets 7
6 sits out
2 meets 1
3 meets 7
4 meets 6
5 sits out

So No. 1 meets, in order, 7, 5, 3, gets a break, 6, 4, 2.

If we had an even number of people in our example, the final person (number 8) would take a seat opposite opposite the person who was sitting out in the previous example, and would remain in that seat throughout.

Suggestions for participants

Bring business cards, notepad and pen, and some introductory literature

Prepare a 1 minute introduction (or sheet with bullet points) to include who you are, and what your company can provide.

Arrive EARLY - once we've started the "Round Robin" sessions, it's not practical for us to break other attendees into the matrix.

Turn your mobile phone OFF.

Enjoy your evening - make some good contacts!

Speed Networking articles

Advertising, setup, planning

The event itself and planning sheets

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


Related topics: via article database

April 02, 2007

Well House Manor, Melksham, Art Gallery

Now online at .... http://www.wellhousemanor.co.uk/art.html

Each bedroom at our business hotel has individual canvas prints taken in and around Melksham. You can look round all of the bedrooms in the gallery, and other pictures in the hotel too.

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


Related topics: via article database

MySQL - Password security (authentication protocol)

Ever had this message?

bash> mysql -h www.weekendinwiltshire.co.uk -u weekend -p
Enter password: ******
Client does not support authentication protocol requested by server; consider upgrading MySQL client

The MySQL login password / security model changed between MySQL version 4.0 and version 4.1. In MySQL 4.0 (and prior) there were security risks that related to the password being intercepted between clients and the server, which were fixed with a new protocol from MySQL 4.1.

  1. Client programs built with the old (4.0 and prior) libraries cannot connect to new servers (4.1 and later) by default.
  2. The error message suggests that you upgrade your client programs - i.e. rebuild them with the new libraries or (in the case of clients such as mysql and mysqladmin) download fresh copies.
  3. If you are unable to upgrade your client (e.g. if it's commercial software or is provided to you as part of a shared / ISP service) you can instruct recent versions of MySQL to accept old-style passwords for specific accounts.

Here's the MySQL instruction that you'll need to set the old password mode for a particular account ...You will, though, have to run the actual command to set it from a new style client:

SET PASSWORD FOR "wwweb"@"localhost" = OLD_PASSWORD("paddington") ;

This issue of out-of-date clients is particularly relevant to PHP installations, where you're using an older version of PHP on a web server to contact a new MySQL - perhaps running on a different host. In the past, PHP shipped with the MySQL drivers but a new, and tighter, open source license applied to recent versions of MySQL precludes the shipping of parts of MySQL with PHP. The easiest solution is to download and install MySQL before you download and install PHP, and to ensure that you use PHP installation switches to pull in the mysql or mysqli functions as required, together with the appropriate drivers already installed with MySQL.

Further discussions on the MySQL upgrade here and more detail of the password hashing in MySQL here.

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


Related topics: via article database

Useful link: MySQL training

Science Museum - larger exhibits / store, Wroughton, Swindon

I remember the Science Museum in London from many happy and interesting visits as a child. Did you know that they also have a big place in Wiltshire - on the old RAF Wroughton - where some 18,000 to 20,000 exhibits that won't fit in to the London premises are stored.

Four hangars on the aerodrome are open - occasionally - to the public, or for organised groups. Two of them are given over to aircraft exhibits such as the Comet (which would fill the whole aircraft hall at South Kensington) and a third contains a wide variety of other transport vehicles - cars, buses, industrial, agricultural - as seen in the picture above. My thanks to Peter Goodearl for permission to use the picture above (not one of mine for once!) - and he has an excellent gallery of pictures here.

The Science Museum has updated its own site and many links to information about Wroughton ("Swindon") are now broken - but if you want to know more about when it's open [this link works at present].

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


Related topics: via article database

April 01, 2007

Golfing, Wiltshire (near Melksham)

With some of the loveliest countryside in Southern England, where better to enjoy a short golfing break than in Wiltshire. Choose between courses as contrasting as the North Wilts Golf club on the flank of the Marlborough Downs and the more gentle Lafarge course at Westbury, nestling under the White Horse, or between the Kingsdown Club overlooking the Avon Valley above Box and the Erlestoke Sands course on the approach to the Vale of Pewsey. All of those - and the others listed below too - are within 10 miles of Well House Manor, where we'll be delighted to offer you quiet, luxurious accommodation.

Bowood Chippenham / Calne, 6890 yard, Par 72

Whitley Melksham, 6200 yard, Par 66

Kingsdown Box, 6445 yard, Par 72

North Wilts Devizes / Calne, 6414 yard, SSS 71

Erlestoke Sands Devizes / Westbury, 6759 yards, SSS 72

Cumberwell Park Trowbridge / Bradford-on-Avon, 6435 yard, Par 71

Lafarge Westbury, 9 hole course.

West Wilts Warminster, 5754 yard, par 70

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


Related topics: via article database

Avon Vale hunt at the Point to Point

The law which makes hunting with dogs illegal has now been in force for over a year, and controversy still rages. And I'm NOT going to get involved in the law, its rights, wrongs, and loopholes on "The Horse's Mouth". But I am going to share some pictures taken at Larkhill point to point races yesterday, of the Avon Vale Hunt who sponsored the day and brought their hounds along. No hunting - just running the dogs out on the course between races, and mingling with the crowds.

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


Related topics: via article database

A day at the races

Larkhill, near Amesbury, on the blowy last day of March - point to point racing with the Avon Vale hunt.


Place your bets, please


Sheltering from a squal in the car


Awaiting the start of the race


Crossing the winning line


Returning to the winner's enclosure


Animals wait to be won at the fairground attractions between races

A fun and varied day. Point to Point racing takes place at Larkhill and at the Barbary Castle, both within about 30 miles of Melksham, and there are full race courses nearby at Salisbury and Bath.

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


Related topics: via article database