« April 2009 | Main | June 2009 »
May 31, 2009
Monitoring and Tuning your MySQL installation
How much memory does MySQL occupy? Is it efficient / does it need more memory? Can I tune it?
All good questions ... and to make the most of any answers, there's something you'll need to know first about the structure of MySQL. It runs as a series of daemon processes / services, each of which has a size associated with it, and there are also various buffers that are shared by those processes. So its memory footprint is effected by the size of global buffers, by the size of buffers in each thread, and by the number of threads. Changing the size of a global buffer by a megabyte only changes the overall footprint by a megabyte ... but changing the size of a thread buffer changes it in each thread, so if you have 20 threads running, then a change of 1Mb changes the overall memory usage by 20Mb. And limiting the number of threads / closing down threads that have completed quickly can be very significant indeed on systems which are tight for memory.
There is little point in having huge buffers if you're only using part of them - and you can see how you're doing with the MySQL command show status. This will report on the status of the last operation performed, so that you can run a statement and see how it did. Surprisingly, you may find that increasing buffer sizes beyond a certain point actually reduces performance; the most likely cause of this is that there's extra (pointless!) memory to be handled, and / or you're slowing your system down by increasing swapping.
OK - so what are the buffers?
MySQL buffers
(Sample data shown is from a show status on our server)
General ... and global:
• key_buffer_size (default 16 Mb)
| Key_blocks_unused | 5348 |
| Key_blocks_used | 3535 |
Especially used with MyISAM tables.
• innodb_buffer_pool_size (default 8 Mb)
| Innodb_buffer_pool_pages_data | 19 |
| Innodb_buffer_pool_pages_dirty | 0 |
| Innodb_buffer_pool_pages_flushed | 0 |
| Innodb_buffer_pool_pages_free | 493 |
| Innodb_buffer_pool_pages_latched | 0 |
| Innodb_buffer_pool_pages_misc | 0 |
| Innodb_buffer_pool_pages_total | 512 |
Used with innodb tables.
(Note - if you keep half your data in MyISAM and half in InnoDb, you're likely to need two quite substantial sets of buffers - it's possible that you could do better sticking to one table type or the other. You'll see that on my system, we have a big pool that's virtually empty and I'm tempted to cut it to 2 Mbytes ... not that 6 Mbytes is hugely important these days!)
• innodb_additional_memory_pool_size
• innodb_log_buffer_size
• query_cache_size
| Qcache_free_blocks | 0 |
| Qcache_free_memory | 0 |
| Qcache_hits | 0 |
| Qcache_inserts | 0 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 0 |
| Qcache_queries_in_cache | 0 |
| Qcache_total_blocks | 0 |
These only apply if you have query caching switched on
General ... per thread
• read_buffer_size (default 128k)
Note that for nested queries, MySQL may allocate more than one read_buffer per thread.
• sort_buffer_size (default 2 Mb)
So cutting the sort buffer to 1 Mb if you have 20 threads running will save 20 Mb of memory
• read_rnd_buffer_size
• tmp_table_size
Specials ... per thread
• bulk_insert_buffer_size
• myisam_sort_buffer_size
Changing the defaults
use /etc/my.cnf ... add in extra lines in the [mysqld] section.
Many of the values are now dynamic - i.e. they can be changed on a running system. And there are extra controls too, over and above the buffer sizes, which you should not overlook:
max_user_connections (default 0)
connect_timeout (was 5 now 10)
wait_timeout (default 28800)
There is a full list of the system variables here in the MySQL documentation
How do I find out what's going on?
If you have tuning issues ...
You can do immediate tests as to what settings your server is tuning with using mysql --help from the command line. And within the mysql stand alone program, you can run individual commands then do a show status to see how they did.
Individual logging is available for all queries, or (if you would like them filtered) just for slow queries, and can be set via flags in my.cnf:
log = /var/log/mysql/mysql.log
log-slow-queries=/usr/local/logs/mysql_slow
Remembering that logging itself may have a (slight?) effect on performance, and you'll need to ensure that crontab jobs cycle the log files if you leave then running over a long period.
Keeping track of the number of MySQL threads over a longer period, I run a crontab job regularly through the day which includes the following .. it's in Perl:
open (LOGFILE,">>/usr/local/logs/webserver");
$run_mysql = `ps aux | grep -c mysql`;
$run_httpd = `ps aux | grep -c httpd`;
print LOGFILE "Mysql - $run_mysql";
print LOGFILE "httpd - $run_httpd";
and I also add a datestamp to the file, so that I can correlate the results back with my web (and other) logs if I need to.
Individual queries can also need attention - have a look at explain to see how you can ask MySQL what it's doing, and have a look at indexes (short case study and introduction to optimising selects via indexes)to ensure that you're not reading through big tables time and time again.
This really is the most enormous subject ... and the answers to improving MySQL performance will vary for everyone, based on the footprint of your use of the server and how much resources you have available. In fact, I'm in danger of writing a whole book here ;-). But remember
• Study / benchmark before you change settings
• Look at individual thread sizes, then global buffers
• Don't overlook the number of threads you have running and for how long
• And remember to optimise your queries too.
Further Reading
Here are some links away from this site. I make no secret that I use these pages - once you've seen the overview above, they'll fill you in much more and so I'll leave you in the capable writings of the "MySQL Performance Blog" folks.
What to tune after installation
Posted by gje at 07:11 AM | Comments (0)
Related topics: via article database
More about Graham Ellis of Well House Consultants
Useful link: MySQL training
May 30, 2009
A beautiful coastline
I'm home ... after a very long drive indeed. And glad to be home. But truely thankful for the opportunity to train in Northern Ireland, and to have had the time to spend a day looking around before my return ferry.
Yesterday (though it feels a lot longer ago) I cut directly across from the Carrickfergus area in which I was staying to Portrush on the Nothern coast, then trickled down the coast road to catch my ferry back from Larne. So - adding to pictures from previous days, I can offer you pictures from
I'm very much aware that I missed a lot of places along the way. Frankly, I got entralled by The Giant's Causeway, captivated by Ballycastle, and had to hasten down the coast missing out Cushendun and Cushendall, Carnlough and Glenarm, Balleygalley and Larne in order to catch the "European Causeway" at 16:30 to Cairnryan. "Haste ye back" they say, and I have good reason. And I hope I can take the family, discover more, and show them the joys of Portrush, Bushmills, and Carrickefergus.
Anyone want a Perl course in Belfast, or PHP in Antrim, or Java in Coleraine?
Posted by gje at 08:46 PM | Comments (0)
Related topics: via article database
May 29, 2009
North Antrim Coast - a jewel thats well worth a visit
I've lived my whole life in the British Isles, and I've made a point of looking round wherever I travel - yet on this little group of islands there are still gems for me to find and take my breath away. And I've found one of those gems - or rather a whole string of them - along the north Antrim coast today.
My prior experience of Northern Ireland was close to zero, so I decided to take a late ferry rather than an early one back from Larne today, and spend the day touring - and I'm very glad to have done so. In fact, I exhausted myself do much that I've stopped off at a road side hotel rather than risk driving half through the night to get home - "better late but alive!". And I'll be back with memories.
Pictures are still to be cropped, places described - that will come in the next few days, so I'm just posting this one image as a taster of what's to come.
Posted by gje at 10:12 PM | Comments (0)
Related topics: via article database
Spot the odd one out







Many of the lampposts here in Northern Ireland are decorated with signs extolling you to vote as your first preference for "X" or "Y" in the European Parliament elections, which happen next week - a far cry from the subdued interest which we have seen for the South West seats in England.
In many ways I say "I wish we had that level of interest in Wiltshire". But I can't help feeling that the big interest is in past caused by the troubles that Northern Ireland went through in the last 40 years which, although faded, has left its mark and still the occasional spark. The news here is full of a man killed by what appears to be a sectarian mob in Coleraine, and of a parade re-routed / curtailed in the area as a result. And watching party election broadcasts and hearing a candidate interviewed on radio Ulster, there is still clearly a pain at what has happened here in the recent past, with some working together, but some remaining resolute in their refusal to work with those with whom they were at war a few years ago.
On second thoughts, perhaps I'm very happy that we don't have the same level of interest in the upcoming elections in Wiltshire if the way to achieve them had been to go through what Northern Ireland is still coming out of. The scars remain, and the price paid was clearly terrible.
Posted by gje at 06:35 AM | Comments (0)
Related topics: via article database
An evening walk in Carrickfergus
![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
![]() | ![]() | ![]() |
With so many pictures, made sparkling by gorgeous weather, I didn't know which to post. So here's a montage; please click on any of the images to see it rather larger!
Further pictures ... Carrickfergus and Islandmagee
Posted by gje at 05:58 AM | Comments (0)
Related topics: via article database
May 28, 2009
Images in a database? How big is a database? (MySQL)
The discussion came up yesterday as to whether images should be stored in plain files or in a database, with one of my delegates saying that he had been strongly advised against a database.
That advise is typically going to be correct for a handful of images ... but when you get on to thousands in a single 'directory', the directory structure of operating systems is not best set up to serve all the individual files and a database solution is the best. The database solution also allows you to hold descriptions and other information easily with the images.
"So how big is your image database?" Well - there's just over 4000 images in it, and I guessed that the disc space occupied was about a quarter of a gigabyte on the server. As my data is stored using MyISAM tables, I was able to take a look in the evening and see that my estimate was remarkable close:
-rw-rw---- 1 mysql mysql 8674 2009-03-09 17:24 im_library.frm
-rw-rw---- 1 mysql mysql 243813840 2009-05-27 21:23 im_library.MYD
-rw-rw---- 1 mysql mysql 158720 2009-05-27 21:23 im_library.MYI
All the images from the database are 'fed' via a PHP script which initially checks for a 'real' file and if it finds it, saves it into the database keyed by the file name, and deletes the real file - so it's very easy to add images. My regular database backup backs up all my images. And mod_rewrite is used to send all requests ending in .jpg to the script.
Posted by gje at 07:58 AM | Comments (0)
Related topics: via article database
Useful link: MySQL training
May 27, 2009
Always use su with minus. And where do programs come from?
When you're using the su command to do systems admin work as route, you should always add the - options (minus sign on its own) to start a new root environment too. This means that the PATH that executable files are found from is replaced (amongst other things) - so you can find things like ifconfig automatically, and you'll not get caught by any 'Trojans' set up for you within the account from which you have su'd.
Here's an example of the problem - I've set up a nasty script called "ls" in the current user's home directory, and altered his path to look at current directory first:
[trainee@easterton ~]$ su
Password:
[root@easterton trainee]# ls
Your disc has been scrubbed clean!
[root@easterton trainee]#
oops! Run with su - there's more to do as you have to change back to the source directory - BUT you don't get caught by the nasty ls script (which was just an echo for my demo!)
[trainee@easterton ~]$ pwd
/home/trainee
[trainee@easterton ~]$ su -
Password:
[root@easterton ~]# cd ~trainee
[root@easterton trainee]# ls
build Desktop transwilts2009.odt transwilts2009.pdf
dbn ls transwilts_2009.pdf website
[root@easterton trainee]#
This diagram shows where executable files are commonly loaded from on a Linux / Unix system. Directories called bin are for regular user accessible programs, with those which are intended for the system administrator being in sbin. There's nothing to stop a regular user who knows about a system command from running it, but most of these programs will reject requests for anything more that information enquiries if they're run by none-root users.
Why 3 directories of each name? Those at the top level are programs which are needed early in the system boot up procedure. Those in /usr are the majority of operating systems commands (not needed at early boot stage) and those in /usr/local - if any - will be the locally added / installed extra software that your local admin has added to the base system.
Posted by gje at 07:15 AM | Comments (0)
Related topics: via article database
May 26, 2009
Bright Colours
I was struck by the brightenss of colours this early evening in Whitehead and Carrickfergus - I'm going to let the pictures speak for themselves.


But let's not forget the brightness of natural colours too - the vibrant greens taken on Island Magee, just a few minutes earlier, nor the power of black and white as taken at the old Almeshouses in Carrickfergus.


Posted by gje at 08:23 PM | Comments (0)
Related topics: via article database
Running straight from the jar, but not from a tar
Why can you run applications in Java straight from the jar, but you'll never find mainstream applications extracting their code from a tar file? It all comes down to the different indexing structure.
A tar file was originally designed as a "tape archive". So it's a sequential file that contains file name, file length, file data for the first file, then the same thing for the second file, for the third file, and so on. It means that when a tape is written, you have a high data integrity even on a device that doesn't have random access facilities, as there's no need to store statistics about a file once it's been added, nor to look them up right at the start or end of writing the file which may - on a multiuser system - have changed. But it does mean that if you want to read back something from a "tar" file you have to look at each header block in turn until you find what you need.
By contrast, a jar file [same format as zip] contains all the data at the start of the jar, then an index of where each object starts and ends at the end of the file. Which means you can very quickly read the list of contents ("Manifest") and jump to what you need even in a huge file - but it does require random access.
You may ask why the list of contents for a jar is at the end. That's so that a jar file can be updated / have things added to it without having to rewrite the whole file - adding a new file is as simple as reading the old manifest, adding the new file's data starting where the manifest used to start, and then writing an updated manifest.
Posted by gje at 07:36 PM | Comments (0)
Related topics: via article database
England, Scotland, Northern Ireland
Yesterday I travelled from Melksham to Northern Ireland - a course to give this week. And with equipment to bring, I came on the ferry. Plenty of routes to choose, and I chose to drive up through England (picture is taken at Tebay in the Lake District) and the on through Galloway. With boats being none too frequent, a Bank Holiday Monday, and a drive that the AA told me should take 7.5 hours, I left home early to miss the crowds and to ensure that I had a "margin" ... and used that margin to take a look around in Galloway.
My map showed tome 100 miles of A75 from Gretna to Stranraer - and it was a typical 2 way trunk road, busy and with heavies even on the Bank Holiday on there way to Ireland, so I cut off and followed the more scenic and much quieter A712 through the forest. [more pictures]. And even then I was in good time at Cairnryan and took some more snaps
Carrickfergus is just 16 miles from Larne and is a pretty town beside Belfast Lough. Having spent to long driving and travelling, it was lovely to get out and have a brief look around in the evening. There are yet more pictures here and - as you might expect (or not, if you read something I wrote last week) - I left the best till last. Do have a look at them; I'll be telling you more about my trip to Northern Ireland during the week,
Posted by gje at 06:52 AM | Comments (0)
Related topics: via article database
May 25, 2009
Improving the structure of your early PHP programs
When you first coded in PHP, you probably wrote a different script to handle each form in a series - it's the natural way when you're early in the learning process, but it can lead to repeated code that's hard to follow, and some really horrid complicated conditionals.
On Saturday and Sunday, I demonstrated the restructuring of a "classic" series of scripts into a more robust, more efficient, and more maintainable piece of code - all in a single application (and in a single file in this case). Duplicate code was removed, variables in the session simplified, and by using a "current page number" scheme, a whole host of complex conditionals got shrunk out of existence. I can't publish the final code (as the code on which it was based, thus my derivative, isn't my copyright) but I can talk about it ... and I can point you to a sample of a similar structure - its here
Plan out your application. If you want a system into which people have to log in, or you don't want then to start halfway through, you'll write a single piece of code. Start off your design with a state diagram, showing (in circles) each of the pages that the user may see, then linking them with lines which represent the actual program chunks (your PHP isn't the stuff in the circles - it's the lines BETWEEN them!)
Write the code all in a single top level file - i.e. at a single URL. The code will have a $_SESSION variable which holds the current page so that it knows what to run, and each time the page is called up the actions performed will be:
• a) Validate form inputs / finish up from previous page
• b) Prepare for next page
• c) Complete the template for the next page, send it out
With a small demonstration such as the one we did over the weekend, all the code and even the template can go in a single file - however, as the application grows and as you want to reuse code in other applications you'll want to split it into four files / logical groups:
• 1. The Template for the response page (easily edited with Dreamweaver or similar)
• 2. Web helper routines to help with generation of sticky forms, handling user inputs which include awkward characters such as ' " and <, etc
• 3. "Business" or program logic which relates to the application and calculations and validations that it needs
• 4. Top level code - i.e. the two switch statements that control the whole program's operation.
With a still larger system (let's say you get up to 20 or 30 pages!), you can then load business logic from multiple files, using a 'just in time' technique which will be efficient, rather that loading all the code for every page each time.
Although a 'normal' computer program runs from top to bottom, a web application written as I have described above will run a number of times ... and the way it is structure means that some of the code that's further down the file will be run before code that's higher up, but on a later page. The note in green on the board says "Confusing" - which it might be for the first half hour. Once you're used to it, it's great.
Posted by gje at 07:06 PM | Comments (0)
Related topics: via article database
Useful link: PHP training
On the road, at a Service area thats a cut above the others

I (and everyone else) are much more prone to post <rant> than <praise> ... so here for a change is one of the latter. An early start this morning - 04:45 from home - and a stop at 09:00 on the motorway north at Tebay. Breakfast, email check, and I'll be carrying on in a few minutes. As service areas go, I prefer this one. I REALLY prefer it. Why?
• Setting - see picture of breakfast table!
• Not sales-pushy - you can get to the loo without going past all the trade stands
• Staff who have a smile not a scowl
• usually cleaner, quite spacious
• easy to get online (now with free Wifi, although I happen to be on mobile broadband at the moment
Posted by gje at 09:41 AM | Comments (0)
Related topics: via article database
May 24, 2009
New Example - cacheing results in PHP for faster loading
Here's an example from the last couple of days which is fully my own work, so I can share!
I was analysing a big data flow - yesterday's web log file in this case - and it was rather harsh on the server. No big shock about that - the log file's around 40Mbytes per day and I didn't have it in anything other than a normal text file. But it was rather silly to analyse it every time as the data only changes once every 24 hours.
Solution - let it run slowly the first time it's used after the log files are cycled, but then store the results in a cache and replay it from there each time. A user won't notice the first hit being slow if he can then call up other variants of the page at the blink of an eye!
You can try the code here (separate window) and chances are it will be very fast for you, as someone else will probably have been there recently. If not, the first time it will be slow then it will be fast. Full source code is available here.
Salient points:
1.
if (filemtime("ac_20090522") > @filemtime("cache_0.txt")) {
"is the log file newer that any cache." In the live demo, I have changed the code slightly to pick up yesterday's data every time. Note the "@" to suppress the warning message from filemtime if the cache file doesn't exit
2.
$fho = fopen("cache_0.txt","w");
fputs($fho,"$lines<%%>$result1<%%>$result2<%%>$result3\n");
fclose($fho);
}
# ------------- End of Code to set up cache --------------
"save the results to the cache". All the work of analysis has been done and the data for all the reports that might be called up for the next day is dumped into a file and then ...
3.
$parts = explode("<%%>",file_get_contents("cache_0.txt"));
"read back all the results from the cache". Note that I have NOT added a conditional - even if the cache file has just been generated, I let my code re-read it. Really I did that for testing purposes, but there's no harm in calling it back as - remember - reading the cache is FAST.
4.
Don't forget to make the cache file writable by the PHP!
Posted by gje at 07:17 PM | Comments (0)
Related topics: via article database
Useful link: PHP training
A two day gap - first time in five years?
A very busy few days (if you wonder why it's the first time in five years that I have gone two days without posting here!). Friday was last minute preparations for a very important rail meeting in Swindon - senior level, lots of important players. That's yet to be written up and I've got to report back to various folks who I was representing before I can say much here.
Saturday and Sunday was a two day 'hobby' course - taking PHP and presenting it for the leisure / hobby market. I took a customer's example code, and reformed it over the two days from functioning but buggy, repetitive and hard to maintain and showed how it could be structured into a neater, cleaner, piece of code that was easy to enhance. Then I added a short messaging / chat and news and update element to the code, taking advantage of the ease with which it can now be enhanced to do something very spectacular, very quickly. Unfortunately, I can't share the code with you as the example even at the end contains some customer elements, and I wasn't able to obtain permission to publish it here.
Tomorrow, I'm sure I will post, even though I'll be on the road all day. Watch this space to see where I end up.
Posted by gje at 07:05 PM | Comments (0)
Related topics: via article database
May 21, 2009
Melksham Business Map - Chamber of Commerce, Tourist Information and Town Council
Melksham has a wonderful array of retailers in the town ... but many of them are not obviously located and not well known. The three local bodies are putting together a map showing the town, and where all the businesses are located ... and I have spend several hours each day this week walking round the town and finding new gems.
An A0 (1189 x 841) mm copy will be displayed at Leekes store on the outskirts of the town, the Tourist Information centre will have a copy, and there will be others in handout form too. Entry onto the map for the businesses is completely free ... and the criterion for being shown is that you much be a business that welcomes walk-in trade. I've been testing out that 'measure' at a number of places and nearly everyone has been very receptive indeed.
If you would like to see a larger copy of the map, you can link to it here - it's still in draft form, so it's intentionally still too small to read. You SHOULD be able to read the instruction to email me if you want to check / change / edit your entry. Cutoff date is 15th June ... but changes can be submitted after that date for the second or subsequent edition
Posted by gje at 05:29 PM | Comments (0)
Related topics: via article database
Excellent product, excruciating customer service. 3 Mobile Broadband
Should I shout, or whisper? An excellent product, but a dreadful company to deal with. I ordered a mobile broadband connection and router to go with it on 11th April and here we are - 21st May - with it just working. Not exactly technical problems - I knew exactly what I wanted as it was a repeat of the order I had placed 2 months earlier, and been so impressed that I have given that original to my Dad. Should I tell you the company. They're not called "One", they're not called "Two" ... I won't name them, but I'll let you guess.
Order placed for a USB modem, SIM card, and Wireless Router on 11th April. "Interesting" discussion with sales rep at the time, who insisted that I could not have the "25% less for existing 3 customers" deal because the terms and conditions that should have been available through a broken link stated that it was excluded from certain packages such as the one I wanted. Either he didn't know his products, or he got upset with me and decided to make my life a misery, because he sent a modem stick by a different manufacturer that (later) turned out to be incompatible with the router ... I thought it very interesting at the time that he needed my credit card details twice, once for each part of the order. He also told me that the two parts would be delivered separately.
USB stick duly arrived; I was surprised to see a different model number on it, but never mind. I put it aside to wait for the router. But no router, so about a week after placing the order I phone to enquire. To be told that my credit card had been refused for the router and that I must have missed /spamtrapped the email telling me. They suggested I order again, so I phoned in and did so.
Once again, a week, and ten days, went past. No router. By this time, I had borrowed the router and his stick back from Dad as was going away on business and needed the facilities. Sorting out the mobile broadband access had to go onto the back burner ... which I came back to about a fortnight ago. I decided to try to use the stick modem on the only computer it stated it was directly compatible with in my network - running OSX, and one that the other stick modem had worked perfectly in.
"Plug and Play". Wrong - plug it in, Icon for a disc drive comes up, and disappears again 2 seconds later. Try it a few times, hoping to click on disc drive. Cutting a long story short - it's not plug and play. If you have had certain other devices in use in the past on that USB port, they can conflict. Ah - but you try finding someone in technical support who can tell you this gem. Eventually, I did, and the dear gentlemen (to whom I'm very grateful - compliments to the offshore call centre staff in this case!) also told me that the modem supplied would not work with the router when I eventually got it. He wrote notes onto his system so that anyone else I spoke with later would be quickly up to speed. But he couldn't arrange the necessary swap - so I was to call the part of the company from which I bought it.
So I phoned, and explained my predicament. Of course, I had to explain it from the beginning because the computer in India wasn't actually linked to the sales department's computer in Scotland ... but eventually I got my message through. "But you only have two weeks from receiving something to reject it or ask for a swap" I was told. Err - the second part of the order wasn't even completed within the two weeks, so how on earth was I expected to know it was wrong - in fact I still didn't have the router. "Nothing I can do - I'll get a manager to call you tomorrow".
Call never came (can't say I was surprised) so a further few days went by, and I made a further call along the same lines. And the same long explanation. And the same "I'll get a manager to call you" ... and this time, he actually did, and (after a long explanation ...) agreed to set up the swap. Now - what about the modem - "I'll put you through to re-order" says he.
"We've stopped doing those" says the lady I spoke to. "But I have ordered one twice and it's a necessary part of the setup I require". "I can't help that - you can't expect to be able to order something in May just because we offered it for sale in April. It's discontinued". Now I really wanted to find a solution, but I asked if I could return the parts of the package that had been shipped. "No - you are far in excess of the 14 days" she said. So was there somewhere else I could get the router. "You could try going into our local branch in your high street and seeing if they have any left" she said, and told me that she had no way of checking for such stock levels on her system.
I asked for a customer service email address, or to speak with someone with whom I could take it further. Apparently, neither were available, but I could send a letter to an address in Glasgow. I ruefully wondered (and still do) whether the address I was given really would reach someone who understood customer service, or whether the letter box dumps straight into a refuse sack ...
But, storm clouds brewing and what looked like a 2 year contract for something that would be of limited use (and thoughts of calling in Esther or Watchdog), and the pieces fell into place.
A google search found me a third party supplier of the router ... 5 quid cheaper, ordered online with no question of my card being rejected (I think that was standard excuse no. 1, and not what really happened), and the router arrived.
The modem swap was actually made (I'm not one to shout about a correct delivery normally, as it should be what happens every time - but I've made an exception here!) and I swapped the SIM card over.
And with a few minutes of setting up, I am configured and it's online.
But what a hassle - a month and 10 days, speaking to perhaps a dozen people, at least half a day on the telephone - all to order and receive "another one just like the one I bought 2 months ago. Superb product. Shame about the company's customer service!
Link - The router - my previous technical article
Posted by gje at 02:22 PM | Comments (0)
Related topics: via article database
Copy writing - allowing for the cut
Act 1 is boring, and sets the scene. Act 2 fills in the plot. In act 3, all the pieces come together and the show was a rising climactic conclusion. And the audience leaves the theatre in a buzz, thrilled and remembering a great evening.
The model works well for training courses and presentations where the audience is largely captive too, but it doesn't work for written pieces where there's no commitment to stay.
Consider theses requests - fairly typical of what I might get from Lisa, from the press, and from others:
• Write me an article on .... to fill [[this space]].
• Can you give me something - about 100 to 200 words.
• We want our web page to tell people about ...
With an audience uncommitted to stay around, the climax / point should be reached early, not late, so that the point has been made ... and it's not a huge loss if the reader doesn't go any further or the rest doesn't get printed.
Illustrative example. You can stop reading now if you wish - all I'm going to do hereafter is to fill in the detail!
Here's an example of this - a piece of text that I have written to include in a Chamber of Commerce advertorial for a presentation I'll be doing on 23rd June.
| If your business relies on passing trade, then you have a dependency on other nearby businesses for your own success. But if you are a destination business, with customers who will make a special journey or diversion to reach you, then you can cut that dependency and succeed irrespective of how others about you are getting along. Well House Consultants opened a training centre for specialised IT courses in Melksham in 2000 - a "destination business". In 2006, they added a hotel for their delegates - and also for other Melksham business visitors, and for leisure guests too. Graham Ellis, Director of Well House Consultants, will talk about how his company makes the hotel business a 'destination' one too, and how the company makes both of its businesses online destinations for remote selling. You may stop reading here OR .... "As President of the Melksham Chamber of Commerce, I have visited most of the shops in the Town Centre" says Graham "and I am struck by the difference between the businesses who are bright and bubbly, and those who are bemoaning the loss of trade since Woolworth left a hole in the High Street". You have had the story better filled in by here |
You can stop reading here too!
Editorial staff on newspapers don't have a huge amount of time, and it's very helpful to them to have articles provided in such a way that they can easily trim at any one of the possible cut-off points and still have a valid article ... providing your material in such as way gives you a better chance of getting it published, and published close to the format you would like. The use of a quote as a did above is, I am told, another excellent way of getting them to leave segments unaltered as the can't change what someone said.
From a web presence viewpoint, the 'top load' techniques works well too. Have you ever heard the term "above the fold", which means that your story should be visible, including its key point, before the user has to scroll.
You can stop reading here too!
Search engines / blog consolidators also precise the text by displaying on the first paragraph or two to give people a taster, so the point really needs to be made within that taster!
Here's some text - from my own recent blog entries - and I'll let you see just how much you get from the start of each article.
I have a requirement on my plate at present to write a piece of code for a customer that recognises cross reference codes within a document and turns them into links. And what makes the task quite difficult is that the referer .... Cynics will say that you "get nowt for nowt in this life" ... and indeed that see .... Let's say we're writing an accounts system, for example ... we have a base class tha .... |
For readers STILL here, lets give some onward links and references, should we? If we're looking to generate maximum response, the onward contacts should go at the top. If we're looking to filter out to just the 'very interested indeed' good prospects, put 'em down here.
If you want to look at more thought provoking, effective marketing of this sort, why not come along to the Chamber of Commerce lunch on 23rd June 2009 where I will be talking on a related subject (£10.00 for Chamber of Commerce members, £15.00 for guests - 12 midday at The Refa Balti House, Melksham. Price includes lunch). Book or let me know via our ask the tutor page (email for other opportunities - graham@wellho.net. And if you want to learn more in general on copy writing, I have found some very interesting sources including this blog.
Posted by gje at 07:38 AM | Comments (0)
Related topics: via article database
May 20, 2009
RT @brento - a valuable source for the twitter newbie
So I'm new(ish) on Twitter ... what do those @ symbols and things like RT and OT mean? Brent Ozar explains in his blog, and also tells us why people follow and why people don't follow. OK - I'm learning here; I know I'm doing some things that may discourage a proportion of followers. But then, I'm not feeling that I'm in a general "does the world love me" popularity contest ...
I like his background image ... white with a column image / avatar on the left hand side. You may see a case of "imitation is the sincerest form of flattery" at some point.
Posted by gje at 06:15 AM | Comments (0)
Related topics: via article database
Useful link: Lua training
May 19, 2009
How you are (re)presented at an exhibition
I congratulate Trowbridge Chamber of Commerce on their Business to Business event ... which I attended this morning. The Trowbridge Civic Centre packed with booths - a chance to re-make old acquaintances, network, and meet some new faces. And also a chance to look at how others present themselves, to learn what to do from some of them ... and (regrettably) what NOT to do from many of the others.
The exhibition had been open less than an hour ... and the marketing had been 'front loaded' to encourage people to come at the beginning - and yet these two stands had no customers on them. Why not? Probably because there was no-one representing the company on the stand either! If I was a manager at Travail, I don't think I would have been pleased that my staff had left the booth unmanned ... as an outsider, I see a supreme irony in a Recruitment Agency who's own staff walk off (or appeared to have walked off) the job ... but then with some 40 branches, the managers can't be everywhere.
As ever, there were the well staffed booths where the staff were more intent on talking with each other than to visitors walking by and looking at what they had on their stands. There were the booths where a single salesman was standing to defend the entrance to his space, fearful that someone would board and ask a question. And there were the booths where the sale team went into their routine, or allowed themselves to be lead, without even asking their visitor who he / she was, or what he / she was interested in ... I see such things, and they're common to many shows, and I don't know whether to laugh or cry.
But in fact I'm going to celebrate; scattered amongst the stands were some which were staffed by people who listened, who engaged in a dialogue, and who I look forward ... perhaps ... to meeting in the future. As a business to business event, I now know something of what they offer ... I have some cards, some names, some possible contacts; nothing earth-shattering but good background. And the listeners also know of training course and a hotel just up the way in Melksham, even if "we always use the Harington's in Bath because ...". And there were / are a handful of particularly impressive people who really put the contact / customer first.
A final thought - isn't it notable that I've talked about the staff and the interaction, and not mentioned their products? There were a number of stands which to some extent competed with one another. Guess which ones I would be inclined to do business with!
Posted by gje at 08:45 PM | Comments (0)
Related topics: via article database
Matching disparate referencing systems (MediaWiki, PHP, also Tcl)
Yes, we are Well House CONSULTANTS and do a bit of specialist coding ...
I have a requirement on my plate at present to write a piece of code for a customer that recognises cross reference codes within a document and turns them into links. And what makes the task quite difficult is that the references come from all sorts of different original sources, with varied formats some of which might even be identifiable in two ways.
We'll be using a regular expression based identification system, but how to make such a scheme logical, easy to follow, and easy to maintain in the future as new references and exceptions to the general rules get added? Well to start with, I'll be using the bunching technique I described last week to make individual regular expression easier to read, and to avoid the need to keep repeating subsection bundles of special characters. But there will be more to it ...
Spring, Summer, Autumn
Most of the cross reference codes will conform to a pattern, or a series of patterns, which can be identified fairly easily. I'll describe these as "summer" expressions, as that's the time of year that most people go on holiday, that places are crowded, and there's a maximum of facilities available for them.
For those who don't manage to catch the summer, there are autumn holidays - fewer people around, and special cases for those who have missed out on the summer; I'm going to describe a series of autumn matches for those references which have been missed by the main filters
Some of the URLs that form special references include an embedded main (summer) reference in them ... so that handling of them can't wait until the Autumn. So for this reason, we'll also provide early-bird spring holidays (or regular expressions) to ensure that it's the proper complete reference that's handled, rather than the embedded mainstream one.
And finally ... I understand there are special cases. We'll call those "snowdrops" - we'll allow them to be individually marked up within documents by the document provider, and they'll be extracted / handled ahead of spring.
A new idea? No - there's nothing much new in this world ... you'll see a similar concept used within expect, with the expect, expect_before and expect_after commands. "Look out for xxx, failing that yyy, failing that zzz". Tcl may be mature but it's still an inspiration!
Posted by gje at 09:08 AM | Comments (0)
Related topics: via article database
Useful links: PHP training, Tcl training
May 18, 2009
Camera to record where a picture was taken
Have you ever looked around your picture libraries for a picture of a particular place? I've just been doing so, and suggested to a delegate that cameras should have GPS systems on them. Apparently some do, so it's now just a question of getting the camera to use the latitude and longitude in the file name, as well as the date and time.
Posted by gje at 06:48 PM | Comments (0)
Related topics: via article database
May 17, 2009
Are we IITT (Institute of IT Training) members?
I'm a great believer in "Raising the standards of professionalism in training" - that's the byline of the Institute of IT Training - so when they approached us about becoming a certified member, I listened carefully.
Cynics will say that you "get nowt for nowt in this life" ... and indeed that seems to be the case with the IITT. Their sales rep who I spoke with wrote of an annual fee of over two thousand pounds, and looking around their web site and others associated with it, I would also need to spend 100 pounds or so on annual membership for myself, around 1400 pounds on a course to prepare me for an assessment, and 250 pounds on that assessment. So that's approaching 4000 pounds, two thirds of which isn't a one off payment but an annual expense. That's before you consider the cost of my time / being out of the office and not generating other business for a week. All in all, I estimate that to go for the scheme would cost 35 to 45 pounds per training day that I give.
Is it worth it? What would we get? What would our customers get?
Our delegates would get something, but not a lot. Reviewing the list of topics assessed by the IITT, I feel confident that most are considered already in what we can do - and our feedback confirms this. But there is always scope for improvement. Link - what is assessed Link - learner types used in that assessment
New booking contacts would get re-assurance, knowing that they were booking with a member of a professional organisation. Whether that would be real or imagined, I don't know - especially since we already subcontract training for a number of the IITT registered companies ... and we know of others who's business practises such as course cancellation that we do not agree with, and where we set a higher standard of customer service.
We might gain some business. The salesman looking to sell the IITT membership to me suggested that 80% of companies who book training look for IITT membership before they book. Hmmm - that seems a very high figure to me - indeed curiously high as I can't recall anyone actually asking me ...
I have concluded, then, that it would be excellent to raise the standards of professionalism in training. But I'm unconvinced that joining the IITT would make a significant difference in our case, and certainly not enough difference to justify the cost. Of course, it would be very nice to be invited to plush "Trainer of the year" award ceremonies, but personally that's not the sort of motivation I need - I'm motivated by happy delegates and seeing and hearing how well people progress with what they taught them, and having them come back on other courses and sent their colleagues.
I wrote to the IITT's salesman to tell him that the concept is a great one, but the implementation method and cost don't fit well with us. He didn't even bother to acknowledge my letter, which at least confirmed in my mind that my decision was the right one.
Clearly the views on this page are my own personal ones, and their relevance or otherwise has been evaluated based on our own customer base and needs, and the contacts I have had with them. You may have a different metric / experience
The IITT is a subsidiary of the National Computing Centre Ltd, and its web site is at www.iitt.org.uk
A random selection of trainer evaluation criteria ...
• How well did the trainer use the prescribed training aids during the session?
• How well did the trainer handle questions?
• To what extent did the trainer display anti-discriminatory best practice?
The selection shown here will change each time you reload the page. We've implemented this in PHP. If you want to learn how to make dynamic widgets in your page, have a look at our PHP courses. Start here - no prior programming knowledge or here - prior programming knowledge (not PHP) or here - if you know some PHP already.
Posted by gje at 09:32 AM | Comments (0)
Related topics: via article database
An FAQ on the Apache httpd and Apache Tomcat web servers, and on using them together
Both Apache httpd and Apache Tomcat are popular web servers - and most people who use Tomcat 'front' it with httpd. We run an Apache httpd course (under Linux / Unix) and also a combined httpd and Tomcat course so we're very familiar with those "Frequently Asked Questions" that everyone wants to have answered, but seem missing (or obfuscated) in the documentation!
This article is a listing of almost 100 postings that I have made over the last few years in answer to questions raised on courses. They are sorted as follows:
1. Questions about using the servers together [jump]
2. Questions about Apache httpd [jump]
3. Questions about Tomcat [jump]
4. Questions about the http protocol [jump]
Questions that refer to both httpd AND Tomcat, and their use together
B [1006] Apache httpd and Apache Tomcat together tips
B [1121] Sharing the load with Apache httpd and perhaps Tomcat
B [1265] Apache, Tomcat, Jakarta, httpd, web server - what are they?
B [1377] Load Balancing with Apache mod_jk (httpd/Tomcat)
B [1383] Monitoring mod_jk and how it is load balancing
B [1564] Default file (MiMe types) for Apache httpd and Apache Tomcat
B [1762] WEB-INF (Tomcat) and .htaccess (httpd)
B [1766] Diagrams to show you how - Tomcat, Java, PHP
B [1767] mod_proxy and mod_proxy_ajp - httpd
B [1938] Predictive Load Balancing - PHP and / or Java
B [1939] mod_proxy_ajp and mod_proxy_balancer examples
B [1944] Forwarding session and cookie requests from httpd to Tomcat
B [1993] Load Balancing - Hardware or Software?
B [2016] Apache httpd and Apache Tomcat miscellany
B [2038] Sticky Sessions with mod_jk (httpd to Tomcat)
B [2041] httpd, Tomcat and PHP course enhancements
B [2060] Database connection Pooling, SSL, and command line deployment - httpd and Tomcat
B [2062] Virtual hosting and mod_proxy forwarding of different domains (httpd)
B [2077] Why put Apache httpd in front of Apache Tomcat
B [2102] What do people think of our Apache httpd / Tomcat course?
B [436] Linking Apache httpd to Apache Tomcat
B [631] Apache httpd to Tomcat - jk v proxy
B [907] Browser -> httpd -> Tomcat -> MySQL. Restarting.
B [934] Clustering, load balancing, mod_rewrite and mod_proxy
Questions that refer to Apache httpd
H [1009] Passing GET parameters through Apache mod_rewrite
H [1080] httpd.conf or .htaccess?
H [1095] Apache httpd , browser, MySQL and MySQL client downloads
H [1207] Simple but effective use of mod_rewrite (Apache httpd)
H [1376] Choosing between mod_proxy and mod_rewrite
H [1381] Using a MySQL database to control mod_rewrite via PHP
H [1449] Upgrade Mac OSX to Leopard, Web Server Apache httpd config lost
H [1551] Which modules are loaded in my Apache httpd
H [1619] User and Group settings for Apache httpd web server
H [1687] Virtual Hosting on Apache httpd - a primer example
H [1688] cannot restore segment prot after reloc message - PHP / httpd
H [1707] Configuring Apache httpd
H [1731] Apache httpd, MySQL, PHP - installation procedure
H [1761] Logging Cookies with the Apache httpd web server
H [1768] What is built in to this httpd and PHP?
H [1945] Summary - Apache httpd build on Linux
H [1954] mod_rewrite for newcomers
H [2054] Tuning httpd / the supermarket checkout comparison
H [2063] Internal Dummy Connections on Apache httpd
H [2096] Where is my new Apache httpd installed
H [523] Apache httpd release 2.2
H [526] Apache httpd - serving web documents from different directories
H [660] Stopping and restarting Apache httpd cleanly
H [662] An unhelpful error message from Apache httpd
H [853] To list a directory under httpd on a web server, or not?
Questions that refer to Apache Tomcat
T [1049] Java 6, Apache Tomcat 6.
T [1370] Apache Tomcat Performance Tuning
T [1552] Extra public classes in deploying Apache httpd and Tomcat
T [1553] Automatic startup and shutdown of Tomcat
T [1718] Increasing Java Virtual Machine memory for Tomcat
T [1771] More HowTo diagrams - MySQL, Tomcat and Java
T [1899] Virtual Hosting under Tomcat - an example
T [1941] Server - Service - Engine - Host, Tomcat
T [1994] tomcat-users.xml; what a difference a space made
T [1996] Advise before my Apache / Tomcat course
T [2034] Through Snow and Flood to Linux and Tomcat
T [2036] Java Tag Libraries / how they work / Tomcat Deployment
T [2058] Invoker and cgi servlets on Tomcat 6
T [2059] Sharing the load between servers - httpd and Tomcat
T [2061] Tomcat 6 - Annotated Sample Configuration Files
T [2080] Using ApacheBench and jconsole to test and monitor Tomcat
T [2088] Changing the 404 - file not found - page in Tomcat
T [2184] Choosing the right version of Java and Tomcat
T [465] Changing Tomcat's web.xml and reloading a web application
T [498] Why is Tomcat called Tomcat?
T [49] Business is the predominant user of Tomcat, Perl and Tcl
T [837] Tomcat - Shutdown port
Questions that refer to the http protocol
P [1378] Etag in http headers - what is it?
P [1503] Web page (http) error status 405
P [1549] http, https and ajp - comparison and choice
Go to ...
Questions about using the servers together [jump]
Questions about Apache httpd [jump]
Questions about Tomcat [jump]
Questions about the http protocol [jump]
Posted by gje at 07:40 AM | Comments (0)
Related topics: via article database
May 16, 2009
Abstract Classes - Java
In Java you can write a class from scratch, or you can write one class based on another, using the 'extends' keyword and providing only the methods that change in the new class from the base class, plus any extras.
Let's say we're writing an accounts system, for example ... we have a base class that's a "line entry" and we have subclasses for "employee", "regularevent","capitalcost" and "course" ... then we can write four subclasses, and we'll never instantise (create) just a lineentry. The getcost method will differ for the employee and regularevent classes, as they are time dependent, whereas the capitalcost and course class methods return the same value irrespective of the time. So there needs to be a getcost method in each subclass.
But I want an array of lineentrys ... and I need to be able to call getcost on each of them and have it run a different (polymorphic) method. Solution - I define lineentry as an abstract class - i.e. one who's definition isn't complete and so the constructor cannot be called directly - and define the getcost method as abstract.
As an extra, if getcost is to be a different piece of code in various groups of subclasses, I can introduce extra intermediate abstract classes to ensure that each peice of code only has to be written once - this is shown in the diagram.
Posted by gje at 05:26 PM | Comments (0)
Related topics: via article database
Useful link: Java training
Choosing the right version of Java and Tomcat
Java is described as being a portable language. But that only means that the 'runnable' class files are fairly portable - you must download and install the correct Java Virtual Machine / Java Runtime Environment / Java Development Kit for your computer / operating system / needs.
This diagram shows you the choices you make in deciding which version is right for you.
• Which Distribution do you need - Sun's? IBM's? The Gnu version? Typically, Sun's version is the one we use, as we're heavily into the Tomcat container. The Gnu version is nice / unusual in that it lets you generate native executables.
• Do you need the full Java Development Kit which includes the compiler (if you're running JSPs on Tomcat, or developing code yourself, you do), or is just a Java Runtime Environment - the java engine plus all the standard classes that almost all code uses - sufficient? You can also download just a Java Virtual Machine - the core engine - but that's not much use without the supporting classes
• Micro edition (suitable for generating code to run on tiny devices), Standard Edition (a typical, middle of the road setup for client workstations), or Enterprise Edition (including all the server stuff). Surprisingly, for a simple Tomcat server setup, the Standard Edition is enough as the servlet-api which is in the enterprise edition is ALL you would need from the enterprise edition ... and it's included in the Tomcat distribution anyway.
• Download for the correct processor chip set. Although Java class files are portable, the underlying virtual machine is not - it's written in C and is compiled up for a particular processor
• Download for the correct operating system. As the code of the JVM is in C, and makes system calls, you need to have the version that's right for your operating system. If you download a Linux version and try and run it on Windows it won't work - even if you got everything else right - since the OS calls will be missing!
• And finally, you will need to download an appropriate release of Java. "Latest is best" may be your automatic reaction, but if you are compiling applets that will run in your user's browser, that may not be the case since you need to be able to generate class files that will be compatible with the JVMs that your users will have installed in their browsers. You can do yourself a huge dis-service by providing an applet that will ONLY work in the very latest browser releases because it uses new facilities that most people haven't yet upgraded to!
If you're installing Tomcat, you'll need to have Java installed - and you'll need the right version of Java to go with your Tomcat. Firstly - get the correct chip and OS version, and note that you'll want the Java Development Kit (JDK) and at least the standard edition of Java. Then choose your version.
• Tomcat 6 requires Java 1.6 (a.k.a Java 6). In the future, that will probably read "Java 6 or later".
• Tomcat 5.5 requires Java 1.5 (a.k.a. Java 5) or later
• Tomcat 5.0 requires Java 1.4 (a.k.a. Java 2 1.4) or later
If you must use Tomcat 5.5 with Java 1.4, there's an extra download available that will let you patch your Java and run that combination ... but Java 1.4 is getting old and the need for that patch is fading fast.
Posted by gje at 07:47 AM | Comments (0)
Related topics: via article database
Useful link: Java training
Servlet life cycle, and Java Servlet variable scope
If you write a 'traditional' program and run it ... then it is cleared from memory when you finish running it. It does its job then exits. And so it is with a java program that you run from the command line under the java command.
But if you're running a web server, where lots of users all call up the same page, you've got a different requirement / scenario. You really don't want a piece of code to keep dropping out of memory to be reloaded yet again a few milliseconds later as your next user comes along, as that would be hugely inefficient. So on a web server, when running Java, you may use the servlet approach.
A Servlet is loaded into a container (we provide training on the Tomcat container) and remains loaded - i.e. running as a daemon on service. Each time a user submits a GET request to the web server / servlet (i.e. follows a link to the URL that points to the servlet, or sends a default setup form to it), the doGet method is run which processes a request object into a response object. And each time the user POSTs to the servlet's URL, the doPost method is used to convert a request to a response.
When you're writing the class ("code") for a Java Servlet, then, you need to be very careful that you don't have one user leave behind variables / settings which the next user could pick up. On rare occasions, this "global scope" IS useful - for example to hold the highest bid so far for an item in an auction - but more usually, you'll want to use a "session scope" where a separate set of variables / settings are used for each user as they mover from page to page, adding things to their shopping cart. They you'll also have "local scope" - variables that are only used within an individual request.
Global scope variables may be defined as statics within the servlet class as a whole, session scope variables within a session object, and local variables within the methods of the servlet.
Init and finalise on my diagram show methods used to initialise a servlet when it's first loaded into the container, and used to flush it out when it's no longer needed after a long period of inactivity
Posted by gje at 07:31 AM | Comments (0)
Related topics: via article database
Useful link: Java training
May 15, 2009
What Linux run level am I in?
Linux / Unix systems have a "run level" that they're in ...
0 - halted
1 - single user
2 - multiuser (client)
3 - full multiuser
5 - full multiuser with X windows running
6 - reboot
How do I find out what run level a system is in at the moment? - a question asked on today's Java course (OK - it was over lunch and we were a bit a lot off topic ...)
1. The runlevel command tells you what run level you are in
2. The who -r command also tells you the run level, together with some other information.
Here's a machine which is in full multiuser mode, running as a server:
[trainee@melksham ~]$ /sbin/runlevel
N 3
[trainee@melksham ~]$ who -r
run-level 3 2009-05-15 09:28 last=S
[trainee@melksham ~]$
And here's one which is in full multiuser mode and has the windows system running too ...
[trainee@easterton ~]$ /sbin/runlevel
N 5
[trainee@easterton ~]$ who -r
run-level 5 2009-05-15 15:04 last=S
[trainee@easterton ~]$
Notes:
1. The runlevel command is intended for administrators only, so is in the sbin directory which is not on the normal user's path. However, the command is purely information so is available to all users who know where to find it.
2. The default run level of a system can be changed by updating the /etc/inittab file ... the line
id:5:initdefault:
will bring the system up into run state 5 on startup / reboot. Change the 5 to a 3 if you want the machine to start / reboot into run state 3
3. It is strongly recommended that you do not run your web servers in run state 5 ... I have had instances on a course where delegates have complained about a slow server, and they have been amazed when I have walked up to a 'spare' machine, moved the mouse around, and asked if the performance has improved. They have been even more amazed to be able to confirm that it HAS made a difference. What had happened? The system was running a screen saver in X Windows ... and it was eating up all the cpu resource in keeping an "atlantis" display of 3D whales and sharks swimming around the screen. Moving the mouse cancelled the screen saver ... and released the resources back to the server
4. Rather obviously, runlevel cannot report that a machine is in run state 0!
Posted by gje at 04:45 PM | Comments (0)
Related topics: via article database
Useful link: Linux training
May 14, 2009
You cannot please all of the people all of the time
In my role with the Melksham Chamber of Commerce, I take an interest in the business activities in the town, and the various factors that inspire and concern our shop owners.
At the tail end of last year, Bath Road was closed for a period and the shopkeepers were pretty upset about it - talking of how it was driving business away from them at a time they were struggling anyway, and the Chamber worked with the council to reduce the length of the closure, and to get the road re-opened as quickly as possible.
At lunchtime today, I was in a business in the narrow central section (quit e near to the vacated Wollies), and the business owner was saying how great it would be if the section in front of her premises was to be pedestrianised. And feeling a heavy lorry rumble by, and seeing the people squeezed on the pavement, I have to agree with that sentiment too.
Posted by gje at 04:20 PM | Comments (0)
Related topics: via article database
May 13, 2009
Patterns in numbers - room occupancy
I have often spotted patterns in the room numbers we have occupied - describing a night where 1, 3 and 5 are occupied but 2 and 4 are not as "odd" for example, and I have been surprised at how often the let combination allows me to come up with some such form of wording. I woke ... dawn is early at the moment ... and wondered just how many of the occupancy patterns could be met be a short description. And what better way to generate the pattern than a Python program ;-)
nrooms = 5
for room in range (2 ** nrooms):
print "occupied:",
for df in range(nrooms):
pw = 2 ** df
if room / pw % 2 == 1:
print df+1,
print
And the results?
occupied: "empty"
occupied: 1 "singular"
occupied: 2
occupied: 1 2 "bottoms"
occupied: 3 "one in the middle"
occupied: 1 3
occupied: 2 3
occupied: 1 2 3 "lowers"
occupied: 4 "factosisable"
occupied: 1 4 "squares"
occupied: 2 4 "even"
occupied: 1 2 4 "powers of 2"
occupied: 3 4
occupied: 1 3 4
occupied: 2 3 4 "middles"
occupied: 1 2 3 4 "top missing"
occupied: 5 "just the top"
occupied: 1 5 "extreme"
occupied: 2 5
occupied: 1 2 5
occupied: 3 5
occupied: 1 3 5 "odd"
occupied: 2 3 5 "prime"
occupied: 1 2 3 5 "Fibonacci"
occupied: 4 5 "tops"
occupied: 1 4 5
occupied: 2 4 5
occupied: 1 2 4 5 "hole in th middle"
occupied: 3 4 5 "uppers"
occupied: 1 3 4 5
occupied: 2 3 4 5 "non-singular"
occupied: 1 2 3 4 5 "full"
Hmm .. the majority (but not all) do describe to a pattern!
Posted by gje at 06:31 AM | Comments (0)
Related topics: via article database
May 12, 2009
Offers that I can refuse
Three business proposals I received in my email this lunchtime ... I'm going to pass on all three, but I enjoy reading about some of the incredible things I get invited to do!
| 12th May 2009 Dear Sir/Madam, I would like to know whether you have any part time business offer for me as I'm based in India and if you have any plans to expand your market in India kindly do let me know. Awaiting your reply at the earliest. | A very good day to you. Please kindly go through the attachment below and get back to me only if you are interested to work with me because I have determined to live for posterity. Looking forward to your urgent reply. | Dear Webmaster, I have visited your site www.wellho.net and found it quite impressive. I am dealing with a site which is based on the same theme of yours and looking for high quality related sites who can give me link backs. My site is having a PR of 3 and if you will give me a link back then definitely our site will also get benefited. This would be a win situation for both of us and I would really appreciate if you add my site with this information: Link Details: Title: Cheap Flights to Turkey URL: www.[deleted].org.uk/flights/ Description: Cheap Flights to Turkey: Amazing Late Flight Deals to Fantastic Turkish Holiday Resorts for the brits: Icmeler, Marmaris, Bodrum, and Antalya. Thanks & Regards |
Posted by gje at 02:37 PM | Comments (0)
Related topics: via article database
Melksham Candidates for Wiltshire Unitary Election
[update] - Results added at bottom of this entry.
I'm looking ahead with interest to the forthcoming Unitary elections for Wiltshire Council, where the new council will be about twice the size of the old one (in terms of elected members), but with the elimination of the districts there will be fewer people elected by local voters to look after their interests, and there's potentially a bit of a scramble for 'good' seats in the new organisation.
Melksham has five wards, each single member ... "North Without", "North", "Central", "South" and "South Without" and at lunchtime today I visited the town hall (to get a list of candidates for 3 seats) and the offices of the Without Parish Council - just across the Market Place - for the other two. Here is the candidate list (E & O E)
North Without
David Bolwell - Lib
Gregory Coombes - Lab
Mark Clifford - Con
North
Andrew Clayton - Lib
Rod Eaton - Con
Margaret White - Lab
Central
Philip Alford - Con
Steve Petty - Lib
Jo Sibley - Lab
South
Jon Hubbard - Lib
Jane McGee - Lab
Richard Wiltshire - Con
South Without
P Carter - UKIP
M Kennedy - BNP
M Sankey - Independent
Louise Smith - Lab
Terri Welch - Lib
Roy While - Con
Elections take place on 4th June. There are some excellent people standing ... and some who I wouldn't rank quite so highly. In at least one ward, there are difficult choices and there are going to be some good people who don't make it. I'm not going to post any individual support here, but I do find it interesting to see who's in support of decent local provision such as an appropriate rail service (see here), and who supported it last year (see here) but hasn't signed up again this year for some reason.
For the division of Melksham Without North
Details for 2009 election
Results finalised at 15:50 - Candidates for Melksham Without North Candidate Party Votes
BOLWELL David John Liberal Democrats 536 (33.7%)
COOMBES Gregory Anthony Labour Party 126 (7.9%)
GRIFFITHS Mark Rupert (Elected) Conservative Party 906 (56.9%)
Turnout and statistics Turnout 46.4%
Spoiled votes 24
For the division of Melksham North
Details for 2009 election
Results finalised at 15:31 - Candidates for Melksham North Candidate Party Votes
CLAYTON Andrew Robert Barnett Liberal Democrats 425 (40.7%)
EATON Rod (Elected) Conservative Party 535 (51.2%)
WHITE Margaret Ethel Labour Party 66 (6.3%)
Turnout and statistics Turnout 31.5%
Spoiled votes 18
For the division of Melksham Central
Details for 2009 election
Results finalised at 16:04 - Candidates for Melksham Central Candidate Party Votes
ALFORD Philip Conservative Party 534 (43.8%)
PETTY Steve (Elected) Liberal Democrats 554 (45.4%)
SIBLEY Jo Labour Party 110 (9%)
Turnout and statistics Turnout 32.7%
Spoiled votes 21
For the division of Melksham South
Details for 2009 election
Results finalised at 15:47 - Candidates for Melksham South Candidate Party Votes
HUBBARD Jon (Elected) Liberal Democrats 1117 (63.9%)
MCGEE James Labour Party 87 (5%)
WILTSHIRE Richard Conservative Party 536 (30.7%)
Turnout and statistics Turnout 44.2%
Spoiled votes 8
For the division of Melksham Without South
Details for 2009 election
Results finalised at 15:51 - Candidates for Melksham Without South Candidate Party Votes
CARTER Paul Robert UK Independence Party 162 (11.7%)
KENNEDY Mark British National Party 92 (6.7%)
SANKEY Michael Independent 116 (8.4%)
SMITH Louise Anne Labour Party 73 (5.3%)
WELCH Terri Liberal Democrats 361 (26.2%)
WHILE Roy Sidney (Elected) Conservative Party 571 (41.4%)
Turnout and statistics Turnout 37.3%
Spoiled votes 5
Posted by gje at 01:39 PM | Comments (0)
Related topics: via article database
Preventing forum spam - checks at sign up
You may have seen the IP lookup tool we have on our front page (if not, bookmark http://www.wellho.net and it's the bottom right link) which I use extensively to find out a little bit more about addresses that catch my interest - be they generating unusual traffic on our web site, scouring are pages in a "very interested" way, or signing up for a forum.
I told you about projecthoneypot and stopforumspam recently (here) and I have just added the following code to my front page tool which incorporates the summary of a stopforumspam report (they provide a nice api) within the tool.
$spammer = file_get_contents("http://www.stopforumspam.com/api?ip=$fip");
if (ereg("<appears>yes<appears>",$spammer)) {
ereg("<frequency>([[:digit:]]+)<frequency>",$spammer,$rs);
$spamreport = "$rs[1] report".(($rs[1]>0)?"s - ":" - ");
$spamreport .= "<a href=http://www.stopforumspam.com/".
"ipcheck/$fip target=exfull>more<a>";
} else {
$spamreport = "Clear";
}
(the incoming IP address for this code should be in the $fip variable, and should have been checked for format / cleaned up by the time you use the code snippet above!)
Try it here:
I have not found an automated API on projecthoneypot ... but a URL of the form http://www.projecthoneypot.org/ip_194.8.75.145 gives a result which includes the string "We don't have data on this IP currently" if the IP looks clear to them.
Posted by gje at 07:10 AM | Comments (0)
Related topics: via article database
Balloon Journey in Wiltshire
Three years ago, just before we opened Well House Manor, Lisa and I watches as the Triumph Balloon took off from the Green in Devizes ... and on Sunday night we watched that same balloon land in the field behind our house.
![]() | ||||||||||||||
![]() | ||||||||||||||
![]() | ||||||||||||||
![]() | ||||||||||||||
![]() | ||||||||||||||
![]() | ||||||||||||||
One of the Devizes pictures hangs in the lounge at Well House Manor, and there are pictures of Frome and Mere and Longleat in the breakfast room. The bedrooms all feature local shots of Melksham - see the artwork here
Posted by gje at 02:06 AM | Comments (0)
Related topics: via article database
May 11, 2009
Melksham in pictures
I'm following up a huge batch of technical posts with a reminder of what a great place Melksham is to live in and to visit. Pictures here all taken during the first 10 days of May 2009, in Melksham.
Young leaves on the trees, on the footpath that runs behind Laburnum Drive, Beech Avenue and Larch Close. Ironically, there is no "Oak Road" in the areas!
Melksham House, now the Cooper Avon Tires Sports and Social Club, is a magnificent old building in the heart of the town, with a long and interesting history
Stalls at the Melksham Food and Drink Festival in the grounds of Melksham House. With eating out experiences, local produce, cookery demonstrations and more, this special week provided Melksham with something a little out of the ordinary.
Surprisingly, it's quite ordinary for us to see hot air balloons overhead, and to have them land in the field behind the Spa Houses on a calm spring and summer evening.
And, talking of the Spa Houses, here is one of them. They make a magnificent site on the outskirts of the town, and remind us of the days when Melksham was going to rival Bath with people coming to take the waters.
There days, it's a much more gentle / quieter town - with some very attractive modern housing and facilities, as well as the older stuff. Picture - just of Campion Drive
And we even have our own nature reserve at Conigre Mead - running into the Riverside walk, again close to the town centre.
When we moved to Melksham in 1999, we really didn't know the place and it was something of a shot in the dark. Now we wouldn't want to leave.
Posted by gje at 07:23 AM | Comments (0)
Related topics: via article database
Application design in PHP - multiple step processes
When you're putting together a multiple step process in PHP (and that could be anything from a forum to an ordering system), you should bare in mind that each of the program elements will be the 'intermediate' step that takes you from one display to the next ... and that you can't be sure when page "X" has been completed that the next page to be presented really WILL be page "Y" - after all, if the user has failed to enter his password correctly on page "X" you'll want to redisplay it ...
... so here, in principle, is how your code should look. Your application will pick up form data and any existing information from the user's session, then "finish" processing from those inputs. Part of that finishing process will be making the decision as to what page to move onto next, so after finishing from page "X" the code will prepare for page "Y", or page "X" again perhaps. Upon completion of those preparations, the (newly updated) session is saved away, and a template for the new page completed.
Rather than store all the code associated with such a multipage application in one file / logical area, we'll usually split it up. The top level code goes into one file, the "business logic" - code to do the actual application work - into another. A third file contains the "web helpers" - routines which handle the forms, sticky fields, web principles, etc. And a fourth file contains a template - what the web page presented will actually look like.
By splitting the code in this way, it becomes easier to maintain as it's in sensible sized chunks. It also allows for elements to be reused in other areas of the web site / application - for example, a template might be shared right across a site, web helpers across many sites, and the business logic may be used offline as well as on the web. Finally, the division principle allows each section to be independently looked after by experts in that section - you need staff who are masters at each individual trade rather than staff who can dabble a bit in all areas.
If you have heard about MVC ("Model View Controller") parts of what I have written may sound very familiar indeed ... and that is no accident!
We have a sample 'shell' of an application that goes through a multistep process using these principle and you can run it here. Source code is here (top level), here (business logic), here (web helpers) and here (template).
This subject is taught briefly on our learning to program in PHP and PHP programming courses, and much more fully covered during our PHP techniques workshop
Posted by gje at 06:31 AM | Comments (0)
Related topics: via article database
Useful link: PHP training
Basic OO principles
Object Oriented Programming is often described as "data driven", but what does that mean?
For delegates who have been on my Object Oriented courses, I'm reproducing here is a diagram that I develop on the board during the course. And I'm reproducing it with some reluctance, as it's the very development of this diagram - the way the lines go in and it builds up - that help me describe the basic OO principles so powerfully and create "lightbulb moments" for many of our delegates.
Courses that include coverage of the principles of Object Oriented coding include:
Object Oriented Programming in PHP
Perl for larger Projects
Learning to program in Python and Python Programming
Ruby Programming and Learning to Program in Ruby
Java Bootcamp and Learning to program in Java
Lua Programming and Learning to program in Lua
Just a little about the diagram ...
When you're designing a program on OO principles, you think about the data first. Say (for example) you are writing a suite of programs to sell articles of clothing, then you'll think first about an article of clothing - what do you need to know / store about each garment, how do you set up a garment in your program, and what pieces of code do you need to set, manipulate and retrieve that information?
Thinking about the data and the accessors needed will lead you towards the specification of a group of pieces of code that work on that data, which you can discuss with your colleagues and work out what's needed now, and what may be needed in the future.
You can then write a program - a test harness - which will both help you validate your design, and will also allow you to test the code that deals with garments when you have written it.
Well thought through, these design methods allow you to come up with a clean, maintainable, extensible design which naturally offers the programmer who calls you code only facilities that will properly work on this type of data, and also offers a natural separation of the internals of how a garment is made and "works" from how it is used. That's the most natural thing in the world - after all, have you ever thought about how those shoes that you're wearing while reading this article were made?
The OO world has its own language - words like "class", "object", "method", "instance" and "constructor" to describe elements of the principles I have described above. Such single word descriptions are both a blessing and a curse - they're very helpful in discussing code with people who know what they mean, but the tend to obscure the OO principles and just how effective they are from newcomers. Some of these words are on the diagram above in a reddish colour ... and you'll see fully how they fit in place when I welcome you on one of the courses listed above ... or on our C / C++ courses which also cover it in the C++ element, but which I forgot to list earlier.
Posted by gje at 06:05 AM | Comments (0)
Related topics: via article database
PHP4 v PHP5 - Object Model Difference
In PHP, there was a major change in the object model between version 4 and version 5. This code here - incredibly - runs differently on the two versions and what happens when you assign an object to another variable has changed.
In PHP 4, the object being assigned is duplicated, so that if you change the original object after doing the assignment, then look up a property in the copy, you'll be given the value that you started with
In PHP 5, the new variable is just an extra name (an alias, if you like) for the original variable, so that if you change the original object after doing the assignment, in reality you're changing both. So that when you look up a property in the copy, you'll be given the value that you have just set in the original
This (and other entries this morning) are taken from the board examples I wrote during last Friday's Object Oriented Programming in PHP course. Each day during training, I'll draw dozens of diagrams to help delegates understand what's going on, and when asked I'm happy to document and publish some of them here. Bookings on our public courses are open - in other words, we'll accept bookings and welcome delegates who want to learn what we teach from any company or organisation, contractors, and private individuals. The prerequisites?
• A desire to learn
• A good understanding of the language in which the course is presented
• For advanced courses - enough technical background / prior knowledge to be able to gain from the course (and to not hold up other delegates)
There's a full list of our public courses for the rest of the year at http://www.wellho.net/course/index.html - we have beginner and advanced course in PHP ... and also Linux, Java, Perl, Python, MySQL, Lua, C, Tcl, C++ and Ruby.
Posted by gje at 05:47 AM | Comments (0)
Related topics: via article database
Useful link: PHP training
Cleaning up redundant objects
In Object Oriented Design, you'll find that there's a piece of code you can add to your classes called the destructor method ... which you don't usually call explicitly in your code.
When a variable goes "out of scope" and is no longer available to your code , it is marked for destruction so that any cleanups can be done, and the memory reused.
An object can also be released / marked for destruction by an action as simple as an assignment of a different value to the same name - in this example, [PHP], $a=1; might render a big old object no longer available to your code.
You'll notice that I've said that objects are MARKED FOR destruction, rather than actually being destroyed, when no longer accessible. The actual destruction is likely to be done some time later - in bulk when the application needs to get the memory back, or is about to exit (each remaining object's destructor is always run just before the program exits). Irritating though it is that the destructors don't run straight off, it's also a huge efficiency gain for them to be run in bulk / blocks.
Posted by gje at 05:24 AM | Comments (0)
Related topics: via article database
Designing a heirarcy of classes - getting inheritance right
You friend Will has written a class to handle management information about articles. It's great as far as it goes, but you want to add extra stuff to it, so you persuade Will to give you a copy. He's a nice guy, he does so ... but then a month later he tells you he's added a lot more code and you're forced to make a lot of changes to your derivative work ... and so is Jane, to whom you had in turn passed a copy of the code. Far, far better to write the code to OO principles, in which you simply write a file that describes the changes and can be automatically applied when you get Will's update. But this requires careful class design.
Here are some of the principles involved ...
From a class of "article", I have specified three derived classes - blog article, web published article and metro article. The blog article in turn is split into published and draft, and the draft is further split into withdrawn and future. In each case of inheritance, the class on which the new class is based is known as the "base class" and the newly created class is known as the "sub class" ... and we call this extending a class. This might sound back to front at first, but when you consider that you extend the code to create a class that will be more specific and have fewer members, it starts to make sense.
A base class of film contains a lot of methods and data .. but we have had to subclass it to "blockbuster" and "cinema" for our "getcost" method ... since you pay per person at the cinema, but per film hired from Blockbuster - a different algorithm demanding a different (but related) class
In order to minimise the amount of code you need, you should put common code as near to the root of the tree as possible. In this specification example, you'll see that I have put "gettext" into the base article class, as it's common over most of the subclasses. I have then added a separate "gettext" method into my draft brog article class, as that works on different principles. This replacement technique is overloading
Where there's no obvious way to overload a class, the addition of an intermediate class in the hierarchy - even if it's an object typel you'll never create - can help you out. In this example, I wanted a "getvet" method that applied to classes farm and pet, and a different one that applied to classes mythical and wild. But I didn't want to write either piece of code twice. The solution was to use an intermediate ("abstract") class .. and have one of the pieces of code in the base class, and the other in the abstract class.
Posted by gje at 04:54 AM | Comments (0)
Related topics: via article database
When should I use OO techniques?
We have two friends. They're married. She's a keen advocate of Object Oriented Programming and he can't stand the approach. So take them to the pub, buy them a couple of drinks each, mention OO programming and watch the feathers fly ;-)
Seriously, Object Oriented Programming has its place - and there are places it should not be used. Along the base of this diagram you'll find the size of application from tiny to huge, and on the left axis is the easy of writing - from trivial to impossible. The orange line represents "single block" code, the blue line is structured coding, and the black line is object oriented.
• With a single block of code, you can start coding very quickly and easily, but you'll rapidly find that it gets impractical to manage what you're doing. Like writing an article with no paragraphs.
• Structured coding is like writing a short story - there's a bit of an overhead, but the text is broken into paragraphs and it's easy enough to write and maintain up to a certain point.
• And with Object Oriented programming, you can compare with a complete book. There's considerable overhead in the initial setup, but the scheme is expandable far beyond the small and medium sized application - it works really well for something substantial in size
Which of our friends is 'right' in their argument? They both are - she writes parts of large systems, and he writes short system administration utilities.
Posted by gje at 04:37 AM | Comments (0)
Related topics: via article database
May 10, 2009
In honour of the photograph, I present ... a walk from Reybridge to Lacock












A walk from Reybridge to Lacock where William Henry Fox Talbot took the first reversal process photograph. 2 miles beside the river, across fields, past the abbey, through the village and back via the paths. Some free parking is available roadside at Reybridge at the start and end of the walk. There are no facilities at Reybridge, but there are plenty at Lacock about halfway through the walk.
If you would like to do this walk as part of your weekend away in Wiltshire, where better to stay that our hotel - Well House Manor. We will give you directions, loan you a map for the walk, and point you in the direction of the quiet charms of Melksham, and Caen Hill, Avebury, Westbury, Holt and Bath.
Posted by gje at 06:24 PM | Comments (0)
Related topics: via article database
Watching the tele

Posted by gje at 06:04 PM | Comments (0)
Related topics: via article database
Crossrefering documents with uniqueness and inconsistency issues - PHP proof of concept demo
The cross-referencing of documents - where one document contains a human readable reference to another - is very common. And so is the requirement to convert those cross-references into a appropriate links.
The Example
Let's say that I have chunks of data of up to 160k, relating to up to 4000 images, as output from some sort of search. Some of data lines have reference codes ("see also" stuff) attached to them. And I want to come up with a table of the "see also"s There can be several attached to a single line of data, and the formatting is inconsistent because it's manually updated. And a "see also" reference can occur a number of times. Sound like s**t loads of potential problems?
Here is some sample data:
train.jpg A train pulls in to Melksham Station
eiders.jpg Eider ducks (BIRD 15/025/35)
diffdir.jpg A view full of terns (BIRD 15/44.3/19)
pufffly.jpg Puffin in flight (BIRD 33/23/33)
puffnests.jpg Puffins nesting (BIRD 33/23/ 33)
gullery.jpg Gulls nesting at Vik (BIRD 44/32/123)
yern2.jpg A tern searches for food ( BIRD 15/44/19)
DSC08354a.jpg Santa at Melksham Station (PERS 43/22/12)
DSC08379.jpg Father Christmas at Melksham (PERS 43/022/12)
leveepics.jpg Lisa snaps up California (PERS 36/26/36)
avbr6.jpg Ascending a lower lock
newb_2.jpg Gypsy and Graham (ANIM 33/23/77) (PERS 12/73/17)
newb_3.jpg Gypsy (ANIM 33/23/77)
avbr4.jpg Lower down the locks at Caen Hill
avbr1.jpg Avebury Church
And I want to get a table of all the cross-referenced subjects (e.g. PERS 43/22/12 - Santa Claus) and all the data lines that each relates to.
The Solution
I have written a "proof of concept" program in PHP which analyses my data in the format above and produces a table of each reference, with a link to the image that it refers to.
The principle of how it works is as follows ...
The PHP program reads the data source record by record, and finds any references within each record. Each reference is canonicalised (reduced to a standard form for consistency) and stored into an associative array of results, so that we can spot non-unique references instantly and deal with them.
Once we have parsed the whole data source, all we need to do is to sort the array of references, and loop through the output to display it.
It sounds and IS simple ... but the first time you do something like this you have to be very careful to use the correct, efficient technique to deal with the uniqueness and irregularity of manual input issues.
Full data file: here
Source code of example: here
Run the example: here
Come and learn about it on this course which runs here
Posted by gje at 12:11 PM | Comments (0)
Related topics: via article database
Useful link: PHP training
Making Regular Expressions easy to read and maintain
Have you ever seen a long regular expression made up of so many special characters that you can't read or maintain it very easily? Something like
/\(\s*([A-Z]{4})\s+(\d+(?:\.\d*)?)\s*\/\s*(\d+(?:\.\d*)?)\s*\/\s*(\d+(?:\.\d*)?)\s*\)/
We offer a Regular Expression Course that will help you understand things like this more easily ... and also help you write them in what I believe is an easier-to-maintain way:
# A 4 letter word in capitals, to be captured
$word4c = '\s*([A-Z]{4})\s*';
# White Space
$spaces = '\s+';
# A number - may have a decimal point and digits thereafter, to be captured
$floatc = '\s*(\d+(?:\.\d*)?)\s*';
!\( $word4c $spaces $floatc / $floatc / $floatc \)!x
Although the coding of this example is longer, I have set up a series of intermediate variables that has avoided the need for me to repeat complex patterns. And those same intermediate variables can be used in other matches to similar data, avoid the need for repeated logic. "Why is it when people are so proud of their skill in removing duplicated code by writing functions, they often go and spoil the whole thing by repeating the same regular expression or printf format many many times" I ask myself!
Posted by gje at 08:30 AM | Comments (0)
Related topics: via article database
May 09, 2009
Updating my public profile - Graham Ellis
It's when delegates start asking me how old the picture of me in the back of the training notes is that I realise I should update my picture from time to time - not that people choose the person to teach their PHP course based on a photo of the tutor.
The picture on the right is me, taken on 27th April 2009, in our back garden. I haven't changed much since then, although some of the blossom on the tree may have blown away. And I'm still good to train you in Lua.
You may spot a bit of advertising / networking going on in this post. I think that blatant might be the word you're looking for!. So I'll add in a link to our Java courses, including Apache Tomcat deployment for good measure ;-).
Seriously, though, people don't walk up the street in Melksham, see hotel, and think "I'll just pop in there and ask if they do a Perl Course" and so much of our sales and marketing has to be done by networking. The majority of our business comes through recommendations (which is great - we provide an ongoing informal free support service to our customers so that they are helped, and we are not forgotten), with a significant minority reaching us though web searches and thinking "that could be what I'm looking for" ... then getting in touch.
Networking has moved on, and so much of it is moving across to the social networking sites ... and business networking sites too. Please have a look at any of the following that you're on ... and let's network. If you're a newcomer who has just found me via a search, email me too (graham@wellho.net) so that I can know to expect your invite.
LinkedIn ... http://www.linkedin.com/pub/10/709/aa8
Twitter ... http://twitter.com/wellho
Facebook ... http://www.facebook.com/people/Graham-Ellis/814747093
My own cv site ... http://www.grahamellis.co.uk/
Blog ... http://www.wellho.net/horse
And my public training course schedule is here
Posted by gje at 07:05 PM | Comments (0)
Related topics: via article database
CATALINA_OPTS v JAVA_OPTS - What is the difference?
There are two environment variables - CATALINA_OPTS and JAVA_OPTS - which are both used in the catalina.sh startup and shutdown script for Tomcat. They are described in comments within that file as:
(optional) Java runtime options used when the "start", "stop" or "run" command is executed [JAVA_OPTS]
and
(optional) Java runtime options used when the "start" or "run" command is executed [CATALINA_OPTS]
So why are there two different variables? And what's the difference?
Firstly, anything specified in EITHER variable is passed, identically, to the command that starts up Tomcat - the "start" or "run" command - but only values set in JAVA_OPTS are passed to the "stop" command. That probably doesn't make any difference to how Tomcat runs in practise as it only effects the end of a run, not the start.
The second difference is more subtle. Other applications may also use JAVA_OPTS, but only Tomcat will use CATALINA_OPTS. So if you're setting environment variables for use only by Tomcat, you'll be best advised to use CATALINA_OPTS, whereas if you're setting environment variables to be used by other java applications as well, such as by JBoss, you should put your settings in JAVA_OPTS.
"OK - so that's the difference. Give me some examples of what can go in there!"
You can increase heap memory available to the JVM - see here
You can open remote monitoring ports so that Jconsole on another system can watch how your Tomcat is running - see here
You can add in a -server to switch from the client (quicker start, slower running) JVM to the server (slower starting, quicker running) JVM.
You can increase java thread stack size using the -Xss option (same way to specify amount of memory as in -Xms and -Xmx as described in the "increase heap memory" link above.
Posted by gje at 04:52 PM | Comments (0)
Related topics: via article database
Useful link: Java training
Admins thoughts on banning a member from a forum
I took the decision to ban a member from a forum I help look after yesterday. Sometimes the administrators and moderators of such forums get accused (and sometime it's a correct accusation, but usually not) of being 'trigger happy' ... so for anyone reading this who uses forums, you might be interested at my thoughts out of that particular public eye. I am aware that a member or two from 'that place' may read this - even the banned person, so even here I am showing a little reserve!
I always feel that having to impose a ban is something of a failure ... and it's the first one imposed at xxxx since lsat August [this written the following May].
I don't actually mind people posting things that don't show them up in a very good light (as yyyyyyy was doing) ... and indeed I may turn round to someone who's not aware just how much of a twit (s)he comes across as and gently tell her/him. But where there's a significant risk of messing about with personal messages, spam/flood posting, posting against copyright / privacy / decency or other laws or rules, or significantly mucking up existing threads (which (s)he threatened), then it has to be "ban".
The ban imposed in this case never expires automatically. But - were I to receive an email / explanation / justification / apology / moderator message telling me I have overstepped, it could be reversed. Unlikely in this particular case, but never say "never". But let me tell you a story ...
I am minded of a time I was moderator on another forum - looking after the "Travel and Transport" board on http://talk.uk-yankee.com. One of our posters there displayed a childishness of posting, short sentences, and a bizareness of what she said had happened to her and a strange view of life that made us very wary of her. She said she had come to the UK for a week's holiday, USA passport (so no visa needed) but been turned back at the airport and told to get a Visa before she came back. And we wondered what was going on - certainly there was a less than sympathetic tone on the moderator's board.
Slowly, the story crept out. It turns out that she was blind, and having to use a special input device. And had other health issues too so that she obviously didn't have the mobility the rest of us had. And didn't even admit / want to comment on these things - there was just something in posts that eventually gave us the clue. Perhaps the immigration officer at Gatwick had thought she was coming to the UK to get treated on the NHS - perhaps he thought it odd that she was travelling alone, in that condition, and wasn't well set up to answer the officer's questions - I don't know.
But I do know that we then accepted her postings (which would have driven language pedants wYLde) and offered better, more tuned suggestions too - and that she contributed more. The brave lady went to the Los Angeles Consultate, got her visa, and came back to the UK.
The UK-Yankee forum is a bit of a transient place - people come along when they have "transatlantic issues" and as those issues are resolved, they fade away. I don't know what happened to zzzzz - but I do know that I was amongst a group of people just about to close the door to someone who turned out to be utterly valid, and probably twice as brave as any of the rest of us. And it's a lesson I don't think I'll ever forget.
Posted by gje at 02:43 PM | Comments (0)
Related topics: via article database
May 08, 2009
Get it right ... if it goes wrong, it takes so much effort to sort out!
When things go wrong, it gets very expensive and time consuming indeed to sort them out ... something that I was reminded of in a "personal message" I have just sent to a member of our Coffee Shop Forum. I wrote:
"My first priority where something is posted which could have legal implications for the forum is to clear it up; in doing so, I must reduce [usually eliminate] any liability that I as forum owner may have from it. My second priority is to implement any emergency actions that might be necessary to stop an immediate recurrence. My third priority is to post any necessary explanation to stop the whole membership wondering "what's going on here". My fourth to deal with aggrieved parties (if indeed anyone is feeling aggrieved), and finally (fifth) is to resolve the matter with the person / people who overstepped whatever mark it was ... which is where I now am. It all takes an awful lot of time when I could be doing other more fruitful / enjoyable things"
We have had something of a turnover of staff at Well House Manor since we opened. I think a lot (most ?) of that is simply the industry we're in with the hotel, with a transient workforce moving on - and it's partly because the jobs with us are a bit unusual in some ways (subject for another day!). But I'm very conscious indeed of just how sponging of extra resources it is to have a team member for whom everything seems to go wrong. We now have an excellent current team ... things go wrong from time to time for everyone, for sure, but I no longer feel the need to have a full set of work clothes to hand, 24 x 7, "just in case".
Yet another example ... I was training people this week who do technical support and the message 'we always have trouble with xxx software' came across. Ah - but talk it through and 95% of the user base was happy and not having trouble - it was just the 5% (perhaps those for whom the product wasn't really suitable!) were using 95% of the support resource.
And so getting it right first time is so important. I will always double check payments being put through. Make sure that I have a spare computer with me on courses "just in case" - far better to have to use a backup than be left with something to sort out later.
Posted by gje at 10:18 PM | Comments (0)
Related topics: via article database
May 07, 2009
PHP - getclass v instanceof
It should be very rare that you want to say "what type of object is this?" in PHP - or in any OO language; that's because with a correctly implemented class structure, you should have polymorphic effects that cause your code to perform the correct operation whatever object type you run in on. However - I said "rare" not "never"
The getclass method tells you what class a PHP object is a member of. Whereas the instanceof operator tells you if an object is a member of a class. Does that sound similar? Yes - but there is a subtle difference.
Let's say that $abc is a dog. That is what "getclass" will tell me. And instanceof will return me true if I ask whether $abc is a dog. but if a dog extends an animal, and implements insurable, then instanceof will also confirm that - yes - $abc IS animal and, yes, $abc is insurable.
In other words, getclass tells you a specific class name, whereas instanceof will confirm whether or not an object is a member of a whole series of base classes and interfaces, as well as the specific class in which it was constructed.
Posted by gje at 07:21 PM | Comments (0)
Related topics: via article database
Useful links: PHP training, Tcl training
May 06, 2009
A long day to guess where
It's only quarter to eight in the evening ... but I'm exhausted to sleep - probably due to the quarter past five start from home this morning. Perhaps that was crazy, but for on site course between 150 and 200 miles from home, I'm torn - to travel out the night before, have the hassle of unloading all the kit into a hotel and then loading it back in the morning for the final drive to the destination ... or the alternative early start. And that's the one that won.
So - where am I? I started from home at 05:15 and stopped after 149 mile at 07:43 for breakfast. I carried on again at 08:10 and had a further 34 miles to travel, which took the best part of an hour - the very last 8 miles taking a half of that hour.
I'm now in my hotel room ... the picture was taken during a short walk, during which a takeaway meal was collected and brought back in. The room overlooks the busiest railway line I think I've seen in an age, with services and colours from a veritable glut of operators. I expect I'll sleep through.
Posted by gje at 07:36 PM | Comments (0)
Related topics: via article database
May 05, 2009
On the roof of a Melksham Spa House
Over the weekend, we have been working (with far more skilled friends) to get our home / office at "404" linked to the hotel at "48" via a directional wifi setup. Not quite there yet due to ground clutter, but we will be. And it gave us the excuse to go up onto the roof at 404, which is 4 stories tall. Here's the view from the roof, looking towards the hotel and town.
A new view of our front garden, and showing just how narrow the houses are.
Although the roofs look flat from below, they're actually double pitched; some such as ours are slate, others are tiles. I'm not sure at the original material, but they were built some 200 years ago so that is lost in time.
If you should need a reminder of what those houses look like from below, this is it and you can see more here
Posted by gje at 10:26 AM | Comments (0)
Related topics: via article database
May 04, 2009
From the 51773 family
Having a dog around has brought all sorts of extra paraphernalia into the house - from leads and a rubber Frisbee through to water bowls and stair gates (and other things in between). And closely examining a bag that is in the kitchen (!) I saw this text on it.
Now we had firmly been reminded when Gypsy came to us that we needed to be aware of nature's call and to clear up after her, and some of the stuff we have is some little black bags that allow us to poop scoop. But for the big bag that I've pictured above to be in the kitchen was - well - a bit of a shocker.
Standing back, I took another look:
Ah yes - that does look to rather more understandable (though I am not sure why it is upside down.
Did you spot an odd title on this page ... if I should ever forget my surname, I can type 51773 into a calculator, turn it upside down, and it will remind me. I do have much more of a head for numbers than names, so it's a neat trick. Are there any other names that can be done with?
Posted by gje at 06:17 PM | Comments (0)
Related topics: via article database
Stopping forum spam - control of the signup process
On all the forums that I look after, I now run code so that everyone who wants to sign up has to pass a Captcha test where he / she is required to retype a word (that excludes automata), and even then there's a requirement for me or another administrator to accept the signup, based on information such as the email address entered and the user name requested (and I get a little more information too!)
Some signups are blindingly obvious that they should be accepted. Others are equally blindingly wrong, and rejected without further ado. And then there are those in between - where there is some elements that make the sign up request a bit suspicious, but other elements that look 100% sensible - and that's where we end up doing further research. Two projects that I have just come across to help my investigations are projecthoneypot and stopforumspam - and certainly they provide good further evidence (and I encourage the projects).
Yet even then, there can be a question mark over some signups. If I'm in doubt (but thinking that there's a strong chance of a signup being genuine), I'll send a friendly email and see what sort of answer I get back - quite openly saying "that's an interest choice of user name - is it your real name", and starting to chat about the person's interest in the subject. I recall doing this with a signup request from Japan for the First Great Western CoffeeShop and getting a very nice email back concerning how upset my correspondent was with public transport from Heathrow to somewhere in Devon when he visited his family there ... "genuine". But there are also numerous occasions where there's no answer ... "gotcha"!
Posted by gje at 01:10 PM | Comments (0)
Related topics: via article database
May 03, 2009
No subject or title?
There are times that I write a post here then - something of an afterthought - have to come up with a clever title ...
Why should everything have a title, or a subject line? I came across this post on the First Great Western Coffee Shop - image by Chris from Nailsea, who has given me permission to reuse it here. The post has started all sorts of arguments like "aren't all notices polite" and "it should be passengers and not customers", but it struck me that in fact the title / subject line add absolutely nothing at all and the notice would have been cleaner, and shorter without that bold line at the top.
Posted by gje at 04:56 PM | Comments (0)
Related topics: via article database
May 02, 2009
Bean Classes in Java and Java Database Connections
A class is a bean if it has a constructor that takes no parameters, and if it has methods that start with "get" to read properties, and "set" to set properties. And it's a good idea (!) if the letter after the word get or set is a capital, as this will let it be used within JSP tag libraries. Bean classes may have other methods too ... it's just that they won't be accessible through the bean interface.
Here's an example of using JDBC to connect to a MySQL database ... from within the code of a bean. Although Java has manager support to connect to databases, it doesn't include the actual support for any specific database - you need to go and download separate packages of classes for that. "How frustrating" you may say (you would be right!) but it means that the Java folks can look after the Java, the database folks can look after the databases, and when a database is updated the user doesn't have to wait for the next release of Java before he can use the new facilities. It also avoids huge arguments in the community about what should (and should not) be included as a standard driver.
So the database manager as shipped is rather like building a hotel without guests, and the individual drivers you load are like the guests. You need the hotel for the guests, but until you have guests it's really not fulfilling any sensible purpose.
Once the classes are there, how does the connectivity work? Here are the steps that we used in the example show here, written during yesterday's course:
Class.forName("xxxx").newInstance();
where xxxx is the driver class
Loads in the driver class into the driver manager
Connection cnamedb = driverManager.getConnection("yyyy");
where yyyy is a pseudoURL which describes the connection
Log in to the appropriate database
Statement bdstate = cnamedb.createStatement();
Get ready to perform an access (query) to the database
ResultSet dbresult = bdstate.executeQuery("zzzz");
where zzzz is the SQL query to be run
Run the actual query - or rather start it, and return an object that will let you iterate through the result
while (dbresult.next()) { Value = dbresult.getString("wwww"); }
where wwww is the field (column) that you want
Extract the data that you want from each row in turn. ... you can now add your code to process the Value variable further ...
Java Database Connections are also covered on our Java Bootcamp and Learning to Program in Java courses.
Posted by gje at 08:25 AM | Comments (0)
Related topics: via article database
Useful link: Java training
Class Loading and Variable Conversion in Java
"Where did you get THAT from?" Ever heard that question? I've asked it of Java sometimes, in wondering where a Java virtual machine has found a class from ... and it's not always obvious.
When loading a class, Java looks at each location given in the CLASSPATH in turn ... and if there are import directives in the code, it will also look in the specified subdirectory offset from each member of the classpath. So in this example, there are three places to look on the CLASSPATH (two directory structures and a .jar file) and for each of them it will look in the specified place, and also at two other places which are imported within them - making a possible 9 locations where it might find the Bicycle class.
You can always get the contents of a pint bottle into a litre bottle, but only SOMETIMES can you get the contents of a litre bottle into a pint one (those some times being if the litre bottle is only half full or less!).
It's the same with variables ... a float can always go into an integer, but an integer may loose something if it goes into a float.
Java automatically does conversions where it's certain that nothing will be lost (coercion), but if something might be lost, it makes the programmer say "yes, I AM sure" by using a cast.
Posted by gje at 07:52 AM | Comments (0)
Related topics: via article database
Useful link: Java training
May 01, 2009
My four feet!
OK - there has been quite a number of technical entries here tonight as I've been writing up some different diagrams I used during the course for these last days. So I thought I would make my last post of the day to show you my four feet ... and least I think they're mine. I recognize two of them but the other two ...
Ah yes - I knew I had seen them somewhere before!
Posted by gje at 08:47 PM | Comments (0)
Related topics: via article database
What is a JSP tag library?
Java programming is very different to writing HTML - web page authors expect a tag based language ... so why not provide one that provides some Java functionality? That's what tag libraries do. My slide shows a piece of Java program - defining a variable and calling a constructor; it's a pretty common thing to code and only two elements change - the name of the class and the name of the object created. And - because the java language and also the compiled class far format are published - geeks with enough knowledge could work out the class file data from the source code.
Using a tag library, a different way is chosen to specify the two things that vary - they're specified as attributes to a tag (and the tag type is used to select which standard profile is required). In that way, all the vital information that is needed to define the Java functionality is actually included within the tag, and there's no Java source code left at all!
A JSP is a web page in which Java is embedded within HTML, with the server processing it and sending only pure HTML to the browser. Using tage libraries, some (or all) of that Java can be replaced by tags which are much quicker to interpret, much more familiar-looking to the web developer, and will be set up to offer a restricted range of options only so they'll be more secure and less error prone.
Posted by gje at 08:29 PM | Comments (0)
Related topics: via article database
Routers, Firewalls and multilayer servers
We only have one IP address at Well House Manor, but lots of computers. How does that work?
Internally, all our machines are on 192.168.200.xxx network but the router re-writes those to our single IP address on output, and for traffic where the client is at our place (that's most traffic such as web browsers and FTP clients) it remembers who has opened which particular connection so that replies can be written back correctly.
Accesses to any servers that we run locally are slightly more problematic; incoming traffic of a particular type can only be routed to one machine ... and indeed we have one machine set up as the default destination for all types of traffic / ports (this machine is known as a DMZ or demilitarised zone) and care needs to be taken of the security on it. Then we make exceptions - the diagram showing how all traffic on TCP port 80 (web service) is routed to our web server, and traffic for printing is routed to a printer.
By using a single instance of httpd, fronting a number of machines running Tomcat, you can have a single web server that's targeted for all traffic that then distributes it to other services. This distribution is done by httpd via mod_proxy_balancer, mod_rewrite or mod_jk (and there are some other historic ways too).
As well as allowing traffic to be sent to a single machine, this approach also means that the main servers - running Tomcat - can be hidden behind a firewall and the high level of protection only need be applied to the httpd machine.
One of the issues of splitting traffic between a number of back end servers is that you have to make sure that sessions are continued properly - it's no good having a user start his work on machine "X" then get transferred to machine "Y" if machine "Y" isn't even aware of what he has done on "X".
There are a number of solutions to this issue, including the inclusion of a cookie in the initial response to instruct the user's browser to ask for the same machine next time (we do this in real life - "I was talking to Mavis about it ... can you put me through to her again please"). This diagram shows another approach - how the parallel machines can all co-ordinate via another machine behind them - perhaps running a database such as MySQL, or perhaps even another instance of Tomcat.
Posted by gje at 08:18 PM | Comments (0)
Related topics: via article database
Routing Network Traffic - Proxies, Redirects and DNS
If you point a domain at web server "X" when it's really hosted on web server "Y", you can either have web server "X" forward the request as a proxy, or you can have server "X" instruct the browser to try "Y" instead ... that's a redirect.
Which is best? A proxy forward hides server "Y" from the browser, but if server "X" has limited bandwidth it will use some of it up. The extra step will also be marginally slower. However, a redirect requires the browser to make a second request of a new server, and server "Y" will not be transparent to the browser.
When you visit a new web site, you'll call up a page based on the domain name ... however, the domain name does NOT tell the structure of the internet how traffic should be routes to the site as it's not based on the network structure - an IP address is required. So the Domain Name Service (DNS) is used to convert the domain name into an IP address, which does reflect the structure.
It works like this - your system (in the imserve.com domain in the example shown here) contacts its DNS server, which knows about DNS servers for its parent and child domains. So it can ask the .com server, which can ask the root server, which can ask .net, which can ask .wellho.net ... and the IP address then gets passed back doen the chain. Having completed that shenanigans, the original machine caches the IP address to save it the bother next time, and uses the IP address directly.
Posted by gje at 08:02 PM | Comments (0)
Related topics: via article database
Variable scope in Java Servlets and other web applications
How long does a variable last? When you set a variable in a Java Servlet (a Java programming that's running on a web server in a container such as Tomcat), the variable may ...
• be local to the block of code it's in, and be lost when that block has been completed
• be present only for the current request and response - in other words, only be available for a single browser call to the web server
• be present through a whole series of requests and responses made by an individual user in a linked series of operations
• be omnipresent within an application.
These are the possible variable scopes.
Let's see examples of them - let's say you are writing an online auction site (I know Ebay has done it already, by the way).
• the current top price of an item is an example of a global, omnipresent value
• your login details will be present through a whole series of requests and reponses, so that you can make a number of bids without having to give your information every time
• the information that you filled in on a form will be present throughout the running of a single request / response
• a whole series of temporary variables will be created and released as the server looks through its files to find any similar items you may wish to bid for, and generates a table of information about them.
During today's "Java on the Web" training, I wrote an example that shows each of the four scopes [source code]. The example is much simpler than an auction site - each user may simply enter a series of numbers, and the application keeps a running total for each user. It also tracks the most recent value entered by anyone, and the number of new sessions that have been started.
• The number of sessions and latest value entered are (in Java terms) static class variables (peeps and latest if you look at the code) as they last for the whole life of the web application and are omnipotent. I have described them being at Application level
• The running total for each user is (in Java terms) a session variable, as it lasts for the user's individual session, but each user has his/her own variable of this sort - if you look at the code, the example is called runtot. Unsurprisingly, I have described these variables as being at a Session or User level
• The request and response objects (inp and outp in my example) which are passed into the doGet and doPost methods are what I have described as being at an Iteration level
• finally .. variables declared within blocks of code (such as aok and dim1) could be very temporary indeed, reused time after time, and are at a local code level.
Why is scope important? Because you can loose vital information, or corrupt one user's data with another's, if you get it wrong. If everyone had a Session variable for the top bid to date, then everyone would win the auction. If an iteration variable that the user entered was stored in the session, then errors would not be automatically corrected. And if credit card details were kept at an application level not a session or user level, then the last person to enter his card details would be charged for everyone's purchases.
Posted by gje at 05:43 PM | Comments (0)
Related topics: via article database
Useful link: Java training
A very easy JSP (Java Server Page)
"Can you give me an easy first example" ... a common question on a course and - yes, I usually can. And so can other tutors. But then they go on and add things to make them complicated. So here is a really easy JSP example!
JSP is what I call an "HTML++ language" ... you write the HTML of the web page and you embed, within it, extra code of a sort that the browser wouldn't understand. Then you add a filter on your web server telling it to identify these extra codes (tags) and perform the instructions they contain.
Here is the HTML++ code ...
<% int wide = 5; int deep = 3;
int spaces = wellho.Utils.mully(wide, deep); %>
<html>
<head>
<title>Laptops I have poured coffee over</title>
</head>
<body>
<h1>This is my web page</h1>
You have room for
<%= spaces %> laptops
<hr>
Copyright etc
</body>
</html>
... and here is the result of running it, as received by my browser ...
<html>
<head>
<title>Laptops I have poured coffee over</title>
</head>
<body>
<h1>This is my web page</h1>
You have room for
13 laptops
<hr>
Copyright etc
</body>
</html>
The original code from <% to %> is Java statements that the web server runs, and the code from <%= to %> is a Java expression which is worked out, cast to a string, and output.
To complete the example, I chose to call a method in another java class (wellho.Utils.mully) to perform my calculations - it's representative of the work that goes on (business logic) behing my web page. Here's the source code that defined it:
package wellho;
public class Utils {
public static int mully(int dis, int dat) {
int wesult = dis * dat -2;
return wesult;
}
}
We've just scheduled - at short notice - two extra Java courses for May. Learning to program in Java from 11th and Java Bootcamp which starts a day later for those with prior programming experience. As this is a very late offering, you could twist my arm to give you five days for the price of four, or four days for the price of three. And the groups size will be 'just a handful' so there will be a superb tutor to student ratio to ensure that every delegate gets a lot from the course.
Posted by gje at 05:01 PM | Comments (0)
Related topics: via article database
Useful link: Java training














