« November 2004 | Main | January 2005 »
December 31, 2004
Well House Consultants - review of 2004
It's been another busy and successful year for us - course, equipment and book upgrades have continued to keep our offerings right up to date, and we've attended Python, Perl, PHP, Linux and MySQL presentations given by the driving forces of the development in each case so that we know we're headed in our use and on our courses in the same direction that they're heading.
With business and times getting busier, we've simplified a few things; we prefer to be masters of some topics rather than trying to be "jack-of-all-trade". Public Java Programming courses have been dropped, and we're no longer maintaining the notes ourselves - they are available for download from our open training notes site if you want free Java training. We've also sold our London taxi cab which was great fun for station pickups, but harder to keep on the road than we might have wished. We'll still pick you up from the station if you attend a course, but the vehicle will be more comfortable and reliable.
We've already got plans to move gently forward and provide an even better service in 2005 - but I'm holding talk of this back until posts early in the new year. These quieter days between Christmas and the New Year are an excellent opportunity to relax a little, to get involved in our hobbies (oops - that's scripting and web site work!), and prepare for what seems set to be another busy year.
I want to add a personal vote of thanks here to Lisa - who's both my wife and my business partner. I can't find enough and adequate words to express my love and thanks to her in all her support (and also work) in both a personal and Well House Consultants capacity. Just to say that although you may not see her much if you come here on a course (as she prefers to be a backroom person), without her Well House Consultants wouldn't exist as it does today. Thank you, Lisa.
Posted by gje at 06:44 AM
More about Graham Ellis of Well House ConsultantsDecember 29, 2004
Introduction fees, bonuses, commissions, kickbacks
Do you get kickbacks?
The question was asked yesterday (yes, we answer emails and phones even on Bank holidays if we're around), from a trainee who was booking on the January Python course and was wanting suggestions for somewhere to stay.
The answer to his question is "no, we don't take kickbacks". The question was asked with a certain humour, but we were still a little suprised. In hindsight the question was reasonable enough - after all, agent's fees and introduction commissions are quite common in the accommodation business and almost the norm at certain training companies.
We don't receive any payments from any of the establishments on our Melksham Accommodation list. We are very much aware that we could gain a little more income that way, but we wish to remain unbiased and be able to add (and remove) places from our lists based solely on their suitability for our cutsomers, and the feedback we get from people who stay there.
Along the same lines, as a matter of policy we don't pay agents who wish to book people onto our courses. We have a single (good value) pricing structure, and everyone pays according to it. If an agent is providing a booking service onto one of our courses for his clients, then he's very welcome to charge his client for the service - the total cost to that client is likely to end up somewhat less than the cost of a course from a provider who "fattens" his prices to allow for kickback anyway!
Posted by gje at 08:28 AM
December 27, 2004
A Change is as good as a rest
This is the time of year that, for a few days, our training centre turns much more into a home - and that's not a difficult task as we "live above the shop".
On Christmas Eve, we celebrated Christmas for a gaggle of youngsters who couldn't be with us on Christmas day. Chicken dinners, presents under the tree, the inevitable quick trip to the 24 hour store for batteries, and friends and parents helping undo reluctant wrappers and helping the younger ones learn which toys were suitable for use where.
On Christmas Day, a less exuberant (but much enjoyed) Christmas for adult friends and family - and our first chance to try out the kitchen - fitting finished earlier this month. And it worked fabulously!
On Boxing day, we were all getting computer withdrawl symptoms ... and it turned into a normal working day. Well - not QUITE a normal working day, as I'll be telling you in a few days.
A great time to celebrate and be thankful for what we have. Good health, great friends, family and contacts. Jobs we enjoy. Space to do what we want, and enough of most things to meet our needs (and things can always be adjusted to ensure we continue to have enough of most things).
Posted by gje at 08:34 AM
December 23, 2004
Christmas break
For the next 10 days, I'm taking a Christmas break from Open Source training. A time with friends and family and recharging batteries ... although I'm sure that I'll be on line from time to time. Posts to "The Horse's Mouth" will be less frequent until the New Year - it's just not the season that most of you will be wanting to read this sort of thing - but I will check in to Opentalk at least once a day as usual and answer and questions that are posted there.
Thanks for your support in 2004. Have a great Christmas everyone!
Posted by gje at 07:17 AM
December 22, 2004
Review of the Autumn
This has been a very busy Autumn for Well House Consultants. In October, Lisa and I took a week away from presenting courses to attend a conferenece with speakers including the originators of Perl, PHP and MySQL ... yet still our October business level didn't dip. November was our best month ever, and every possible training day (right up to today) has been given over to training in December; after today, we're stopping training until the next (private) course on 4th January.
Rather like coming to the end of a long school term, there's a slight tiredness creeping in; last night, I elected to stop in a hotel only 60 miles from home to ensure that I'm in good shape and fresh for the last day of training in the year, whereas normally I might have commuted. And I'm glad I'm not doing a five full days for once. And yet - as soon as I get in front of a group of trainees what a pure pleasure it is to be able to introduce them to highlights and hidden gems in the subjects they're learning - help get them off to a flying start in the new year!
The three days this week (three one-day private sessions) have all been concerned, one way or another, with MySQL. On Monday, we were looking at complex joins and how to write them efficiently, and also how to design table structures to aid this - how to set up indexes, and whether some data denormalisation might be called for. Tuesday, the course covered Linux admin and backup procedures, and we included such topics as scheduling regular mysqldumps in order to ensure that the total system backups included good SQL information even if the system was live while backups were taken. Today (Wednesday) was a more general MySQL day - and overview of the topics covered on the public course, but with a group of 5 trainees it was much more effective for me to run a private course in Oxford.
Posted by gje at 07:49 PM
December 21, 2004
MySQL - Optimising Selects
If you're going to be doing a complex select in MySQL, how should you formulate it to make it run efficiently?
This sounds like a simple question, but is actually very complex!
Firstly, consider creating indexes on any columns that are likely to be used in the selection of joining of records; choose a UNIQUE INDEX if a field is known to be unique, and a FULLTEXT INDEX if you want to be able to quickly search a text field for a particular value. Use just an INDEX for non-unique fields. Here are some example commands that create indeexes:
create unique index piidindex on b_ptab (piid(5));
create index piidindex on b_btab (piid(5));
create fulltext index synindex on b_btab (synopsis);
Your data structure is now optimised to allow for selects searching on the indexed fields.
Secondly, when you specify your tables to be joined, try to specify the tables at the "heart" of the join operation first before the tables that tag data onto the structure; you may want to specify a STRAIGHT JOIN to force these tables to be read first.
Third, if you're selecting based on text word content
- use MATCH in preference to LIKE
- and use LIKE in preference to RLIKE
Using these techniques, a well written query can run thousands of times faster that a poor one. I'm writing this note on a laptop running MySQL and I ran a following query to join:
* A table of books
* A table of Authors
* A pivot table to link authors to books
* A table of book subject
* and a table of book publishers
Out of some 550 books (with a total of around 700 different authors), I selected the 53 records that included the word "focus" in their Synopsis, using the command:
select sql_no_cache title,fullname,b_btab.biid,b_atab.aiid,pvid,subject,pubname from b_btab, b_atab, b_pivot, b_stab, b_ptab where b_btab.biid = b_pivot.biid and b_atab.aiid = b_pivot.aiid and b_stab.biid = b_btab.biid and b_ptab.piid = b_btab.piid and match (synopsis) against ('focus');
and it took 0.02 seconds. The same join, without indexes and any optimisation, took 3 minutes and 18 seconds.
Posted by gje at 05:51 AM
December 20, 2004
MySQL - LEFT JOIN and RIGHT JOIN, INNER JOIN and OUTER JOIN
In a database such as MySQL, data is divided into a series of tables (the "why" is beyond what I'm writing today) which are then connected together in SELECT commands to generate the output required. I find when I'm running MySQL training, people often get confused between all the join flavours. Let me give you an example to see how it works.
If this isn't quite the question you're looking to have answered, we've got a MySQL IAQ (Infrequently Answered Questions that may help you. And if you want to learn how to make use of this in PHP, see here
First, some sample data:
Mr Brown, Person number 1, has a phone number 01225 708225
Miss Smith, Person number 2, has a phone number 01225 899360
Mr Pullen, Person number 3, has a phone number 01380 724040
and also:
Person number 1 is selling property number 1 - Old House Farm
Person number 3 is selling property number 2 - The Willows
Person number 3 is (also) selling property number 3 - Tall Trees
Person number 3 is (also) selling property number 4 - The Melksham Florist
Person number 4 is selling property number 5 - Dun Roamin.
mysql> select * from demo_people; +------------+--------------+------+ | name | phone | pid | +------------+--------------+------+ | Mr Brown | 01225 708225 | 1 | | Miss Smith | 01225 899360 | 2 | | Mr Pullen | 01380 724040 | 3 | +------------+--------------+------+ 3 rows in set (0.00 sec)mysql> select * from demo_property;
+------+------+----------------------+
| pid | spid | selling |
+------+------+----------------------+
| 1 | 1 | Old House Farm |
| 3 | 2 | The Willows |
| 3 | 3 | Tall Trees |
| 3 | 4 | The Melksham Florist |
| 4 | 5 | Dun Roamin |
+------+------+----------------------+
5 rows in set (0.00 sec)mysql>
If I do a regular JOIN (with none of the keywords INNER, OUTER, LEFT or RIGHT), then I get all records that match in the appropriate way in the two tables, and records in both incoming tables that do not match are not reported:
mysql> select name, phone, selling from demo_people join demo_property on demo_people.pid = demo_property.pid; +-----------+--------------+----------------------+ | name | phone | selling | +-----------+--------------+----------------------+ | Mr Brown | 01225 708225 | Old House Farm | | Mr Pullen | 01380 724040 | The Willows | | Mr Pullen | 01380 724040 | Tall Trees | | Mr Pullen | 01380 724040 | The Melksham Florist | +-----------+--------------+----------------------+ 4 rows in set (0.01 sec)mysql>
If I do a LEFT JOIN, I get all records that match in the same way and IN ADDITION I get an extra record for each unmatched record in the left table of the join - thus ensuring (in my example) that every PERSON gets a mention:
mysql> select name, phone, selling from demo_people left join demo_property on demo_people.pid = demo_property.pid; +------------+--------------+----------------------+ | name | phone | selling | +------------+--------------+----------------------+ | Mr Brown | 01225 708225 | Old House Farm | | Miss Smith | 01225 899360 | NULL | | Mr Pullen | 01380 724040 | The Willows | | Mr Pullen | 01380 724040 | Tall Trees | | Mr Pullen | 01380 724040 | The Melksham Florist | +------------+--------------+----------------------+ 5 rows in set (0.00 sec)mysql>
If I do a RIGHT JOIN, I get all the records that match and IN ADDITION I get an extra record for each unmatched record in the right table of the join - in my example, that means that each property gets a mention even if we don't have seller details:
mysql> select name, phone, selling from demo_people right join demo_property on demo_people.pid = demo_property.pid; +-----------+--------------+----------------------+ | name | phone | selling | +-----------+--------------+----------------------+ | Mr Brown | 01225 708225 | Old House Farm | | Mr Pullen | 01380 724040 | The Willows | | Mr Pullen | 01380 724040 | Tall Trees | | Mr Pullen | 01380 724040 | The Melksham Florist | | NULL | NULL | Dun Roamin | +-----------+--------------+----------------------+ 5 rows in set (0.00 sec)mysql>
An INNER JOIN does a full join, just like the first example, and the word OUTER may be added after the word LEFT or RIGHT in the last two examples - it's provided for ODBC compatibility and doesn't add an extra capabilities.
Extra link to three way join in solution centre (would have added that link in the comment except that it "spam trapped!
Posted by gje at 06:38 PM
December 19, 2004
Automatic service upgrades
Ever bought something ... only to discover shortly thereafter that a new model was launched the following month? Isn't that irritating in the extreme? When I attended sales training many, many years back I was taught "Don't sell futures - it makes people wait for the new product and means you miss this month's sales target". But it's poor rule - following it is too short term, and in the medium term you end up with dis-satisfied customers who don't recommend you to others because they don't trust you - however good your product.
In the services industry, there shouldn't be a worry about selling futures if good upgrade paths are provided. There are many who don't. Thought. Many years back, we bought 20Mb of web space at Totalweb, and a domain registration. Very reasonable 200 pounds per annum at the time, but gradually the price got out of line. Automatic upgrade offered? No. Made easy for us to tranfer the domain elsewhere? No - that was a long correspondence; as I recall, one form (which had to be faxed) got rejected because I had put a tick not a cross against the option I wanted! Another similar story outside the computing arena - a building society account which was used for long term savings and mysteriously slipped from a good interest rate to a dreadful one. Why DO certain suppliers work like this? Shouldn't they want to have their business thrive by having happy customers selling on for them?
We use a number of excellent service providers - who's products are updated to track the market.
Our main web site is at Hurricane Electric where we started off with (I think) 100 Mbytes of storage which stepped up to 1 Gbyte and just as that was getting tight it went up to 5 Gbytes. Traffic limit went up from 10Gb per month to 100Gb per month recently too. (And it turns out that the timing of that is exactly right for us.
Our internet connection is through TeleWest - using their blueyonder service. Starting from the initial 500Mbit connection offered, we twice chose to upgrade to 1Gb and 1.5Gb connections, at extra charge. Since then, they have increased the top connection speed to 3Gb and just recently to 4Gb - automatically, and at no additional charge.
I would be very reluctant to move our business away from either Blueyonder or Hurricane Electric, and I'm happy to be writing what is, in essence, and unsolicited testimonial for them.
Posted by gje at 06:44 AM
December 18, 2004
Signage
As I drove up the motorway to Liverpool a couple of weeks back, I pulled into a service area and followed the "cars ONLY" sign. Another route was marked "caravans ONLY", and I found myself visualling the scene on a summer Saturday as everyone uncouples their car / caravan combos, drives the car into one area and has the familiy drag the caravan into the other ...
Posted by gje at 04:34 PM
December 17, 2004
Railway train service, Melksham station
I never cease to be amazed at how little people know of the public transport that's available on their own doorstep.
* Melksham station closed in the 1960s. That seems to be pretty well know locally.
* It reopened in the 1980s, with a minimal service. Some people know this.
* In 2001, the service to Melksham Station was increased, and there are 10 trains every weekday. WHY OH WHY does this seem like a secret?
I'm not exactly setting off on a crusade to say "use your trains", but ... please do.
In the current timetable:
trains leave Melksham for Swindon via Chippenham at 05:52, 07:45, 13:25, 17:02 and 21:33.
(These trains originate from Frome / Westbury / Salisbury / Southampton)
trains arrive at Melksham from Swindon (via Chippenham) at 06:56, 09:12, 14:49, 18:09 and 22:37
(These trains carry on to Trowbridge / Westbury / Salisbury / Southampton)
Train times vary at the weekend - the first service does not run on Saturdays, and neither of the first two runs on Sunday.
If you're coming on a public course with Well House Consultants, let us know ahead of time and we can collect you from the station; there's a connection out of the 07:45 from Paddington at Swindon into the train that arrives at 09:12, and if you return on the 17:02 you'll get to Paddington for 18:40
Posted by gje at 08:58 AM
December 16, 2004
Linux - where to put swap space
Swap Space is used on Unix and Linux systems to provide additional pseudomemory resources. In other words, if you try to run so many processes that they won't all fit into memory at the same time, the operating system will swap them in and out of the swap space.
Swap space can be either disc partition(s) (a.k.a. slice(s)) dedicated to the task, and/or file(s) held within the file system. Although the operating system will attempt to swap as efficiently as possible, it does turn into a heavy resource burden sometimes and it's worth tuning your file system layout to take note of this:
a) Use Swap partitions rather than files (but files are great for a temporary expansion if you need it)
b) If you have multiple disc drives of the same speed, spread the swap area between them
c) If you have multiple disc drives of different speeds, put you swap space on the fastest
d) Keep the swap space in the middle of the disc / close to often used files to mimimise head movements
e) If you are using network drives, do NOT put any swap space onto a remote drive!
Posted by gje at 06:02 AM
Useful link: Linux training
December 15, 2004
Aladdin, or careful what you wish.
Have you heard of the Linux user called Aladdin? He came across a command called "alias" one day, and the manual told him that it would make his wishes come true - that options that he wanted to be default would be, and that he could even make up his own new commands.
Aladdin felt this was too good to be true, so he created a little alias called "hello" that echoed back "hello to you too". And it worked! Wow!
Now Aladdin had always wanted the rm command (the one that deletes files) to ask if he was sure, so he created an alias to do that ((it's quite easy - the -i option)). And, again, Wow!
But the Aladdin was deleting files and tidying up for the system administrator who was away on holiday in Skeggy, and there were whole big directories of spam that needed deleting. And Aladdin got really rather bored with typing in "Y" hundreds of time .... so his third use of the alias command was to undo what he had done with the second use.
And the moral is ... Aliases can be useful, but the operating system designers probably put rather more thought that you will have done into what's the default, and they probably got it just about right for most of us.
[Advert] Learn more about using Linux ... [/Advert]
Posted by gje at 05:48 AM
December 14, 2004
Coffee Standards
On the site on which I was working last week, there were two coffee machines, both Nescafe, both maintained by the company, and both with numeric keypads for drink selection. On one of them, 18 gave a black coffee and on the other 18 gave extra white coffee with lots of sugar. Isn't standardisation marvellous.
Posted by gje at 05:46 AM
December 13, 2004
Confession
Wednesday, 1st December - 9 a.m. ... waiting for the (single) student for our "Perl for Larger Projects" course. The booking had been made a good few months earlier, and shortly thereafter we had been notified of a delegate change, and also a company change as the booking organisation had been taken over. We weren't sure that our trainee was going arrive, but so busy have we been of late that we took the view "it will give us a chance to catch up on ... if we have a no-show" and - confession - there was an element in our minds that would have welcomed the opportunity to get some office work done. BUT - we have a "no cancel" policy and we were delighted when "Poppy" arrived.
Is it worth our while running a course with just one person on it? In the financial short term, no it isn't. But in the longer term it's totally worth it. Proven, time and time again.
About a year after we opened our training centre, a gentleman turned up for a course; I could have sworn that I had met him before, and it transpired that I had taught him a beginner course when I was in a previous capacity. He had booked an advanced course with that same organisation, but they had had no other takers and had cancelled the course ... failing to let him know. We used to regard that other organisation as a competitor, but no longer ... as we have grown, they seem to have shrunk. I don't think it's hard to see why, as we've had a great deal of follow up business from that Gent's employer even though we're located further away, and this isn't an isolated incident.
Our course material needs regular updates. Some updates are tiny, others less so - perhaps the replacement of examples, or even the writing of a new module to reflect the updated use of a language. One on one courses often provide the opportunity for us to stay a little off the published schedule (and/or to add material, as they can be paced to fit the one trainee) and try out new presentations. We encourage the trainee to come up with examples in his / her field of work and I'll often burn the midnight oil after a one-on-one day, writing up new work.
Advantage of running a course with just one person proven, too, in Poppy's case. It was justified straight away - an inspiration and great fun to teach. It's a little early to judge future business, and I think I made only minor changes to the notes (no - wait - I decided to add Packaging Modules into future public courses). But ... icing on the cake ... a beautiful reference on her journal. I'm touched, flattered. Thank you. And I'm very lucky to do what I do.
Posted by gje at 05:35 AM
December 12, 2004
Fish stocks
There's controvesy over plans to restrict fishing in the North and Irish seas - in what seems an annual round of cutting the fishing fleet and imposing strict quotas. I wonder how efficient and effecive such schemes are - I understand that up to 50% of the catch is thrown back dead as it's not the paricular fish that are wanted. Rather akin to a farmer breeding sheep and cattle, then killing all the lambs and throwing the carcasses away because the customers want beef this week.
In Melksham Forest, the chippy sells "Cat fish" which (on enquiry) is fish that can't be sold for human consumption but is legal for cats, and the pub offers a "bucket of fish trash" on its menu. Two small steps in the right direction, but we've a long way still to go - a sea change one might say.
Posted by gje at 04:04 AM
December 11, 2004
Programming in isolation
Since I got up this morning, I've been writing some thoughts / guidance on Perl standards (expect some much fuller links elsewhere on this website by the end of the weekend [update - see Perl Standards]). I've just come to a section where I'm saying "it's not just you as the coder - think of the user, the administrator, the maintainer and the tester too". This lead me back to thinking about a post I spotted earlier in the week (elsewhwere):
My name is Xxxxxxxx. I am citizen of ... I live in Townname, SN. I have just joined today. I am a uni professor. I am halfway through my Ph.D. I am very interested in spending some time in England ... I would like to know ... I want to ... I was wondering if it is true that ... I also wanted to know if there were any special considerations .... I ...
To protect privacy and copyright, and to prevent reader boredom, original post has been truncated but I have included EVERY SINGLE sentence start. Was is just me, or would you be put off by having every sentence start with "I". Does it show a certain - err - selfcentereddness? I wondered if the posting was a troll, but I came to the conclusion that it was probably a genuine post, written by someone who was rather inward looking to themself. It was agreeably surprising to find this morning, after a lot of thoughful follow ups, that the original poster had followed up with a one line reply. It started with "Thank you ..." which is much better ...
As programmers, it's very easy to get lost in looking inward at the software we're writing and not consider the wider picture of why we're writing it, for whom, and will be effected by the software though its life. We should think of all these other parties involved and, just once in a while, we'll get a pleasant surprise as we get more feedback and appreciation than we expected from the most unlikely source!
Posted by gje at 08:12 AM
December 10, 2004
Recent technical articles
I've written a number of technical articles over the last week or two. Rather than "flood" this diary, here are some links:
Connecting Apache httpd to Apache Tomcat
The principles and practise of file locking
Using Tcl to provide system testing
Portrait of the Author - PHP
Posted by gje at 03:52 AM
example of Tcl namespaces and packages
Packages in Tcl allow you to define a file of code that's going to be loaded as required at run time. Namespaces allow you to define a new set of variable and proc names that doesn't conflict with the variable and proc names in your main program - rather like giving all the variable and procs in part of your code a surname.
Although packages and namespaces are different facilities and technically not linked in any way, in practise they're often used together. I've often been asked for a simple example showing the mechanism of packages and namespaces working together ...
Here's a main program:
lappend auto_path /home/trainee/ltcl/bowbells
package require amerifruit 1.0
puts [usa::grapefruit]
Here's the file that defines the amerifruit package - it happens to be called florida.tcl in a directory called bowbells:
package provide amerifruit 1.0
namespace eval usa {
proc grapefruit {} {
puts "Big water melons"
}
}
The file bowbells/pkgIndex.tcl provides an index that links the amerifruit package to the florida.tcl file:
package ifneeded amerifruit 1.0 [list source [file join $dir florida.tcl]]
package ifneeded fruit 1.0 [list source [file join $dir clements.tcl]]
If you're worried about the syntax of this, don't be; it was genarated by the command
pkg_mkIndex . *.tcl
run in interactive mode in the bowbells directory
For further details and examples, see our training module on the subject
Posted by gje at 03:14 AM
Useful link: Tcl training
December 09, 2004
a comment on comments
You're very welcome indeed to add comments to this diary; if you're a new commenter, you may find that your message is "quarantined" for approval - a sad neccessity as we get dozens of automated submissions some days which are looking to advertise performance enhancing products, ways to reduce your interest payments, and other products and services which are totally irrelevant to the subject line.
Please don't be put off by the need to get approval - I'll approve and welcome almost any on-topic post even if the views expressed don't agree with mine. I have to say "almost" - it must be legal and decent, and I'm not going to provide a forum for personal attack ... and there may be a few other exclusions ...
At present (and for the foreseeable future) I read all comments. First and foremost because I'm interested, secondly because it's the vey least I can do if you've taken the trouble to contribute, and thirdly because your content is published under my URL and I want to know what's being published under my wing.
Do I answer your comments? SHOULD I answer your comments?
I'm told that commentators on blogs don't expect answers from the original poster to their comments. That's fine with me, in the sense that I shouldn't feel obligated to reply to everything - I make that commitment on Opentalk which is an "ask a question" forum, and I'm not making the same promise here - indeed, I'll often be happy to instigate a discussion / allow for feedback and let that feedback stand as a balance to what I wrote.
But ... I probably will tend to add comments myself, particularly where the commentor has written a long and well thought out follow up; these comments may be as simple as "thank you for adding that", they may be "I hadn't thought of that" or "thank you for correcting me". At times, a discussion may ensue and I'll look to contribute that discussion ... but I hope not take it over. I'm very conscious that I shouldn't always try for "the final word" ... seen too many forums / threads go down that line elsewhere ...
Footnote:If you come across this text in the archive, you might like to follow this link to take you to the page where you can contribute to any discussion!
Posted by gje at 05:19 AM
December 08, 2004
Tcl sandwich - lists in Tcl
In Tcl, a list is simply a string that's held in the same format (i.e. with the same delimiters and protection) as a series of parameters to a Tcl command. The split command (which does a great deal in languages such as Perl and PHP) really does little more than change the delimiters if need be, and add protective \ { and } characters - again only if need be.
Here's an example where we're splitting and manipulating the contents of a sandwich.
tcl>set sarnie "cheese, marmite, onion, pickle"
tcl>set d4 [split $sarnie ,]
tcl>set d4
cheese { marmite} { onion} { pickle}
At this point, the braces have been added to protect the space character which is part of the individual ingredient
tcl>foreach ingrid $d4 {
=>puts [string trim $ingrid]
=>}
cheese
marmite
onion
pickle
I used string trim to remove the space before printing each element out
Let's rejoin the ingredients into a string using the word "and" as the glue
tcl>set d5 [join $d4 " and "]
tcl>set d5
cheese and marmite and onion and pickle
or as an alternative, print it out sorted into the order of ingedients with my favourite first ;-)
tcl>lsort $d4
{ marmite} { onion} { pickle} cheese
tcl>
Posted by gje at 01:50 AM
Useful link: Tcl training
December 07, 2004
Network Camera
With web servers and networking capability now built into printers and broadband access boxes as well as computers, it was only a matter of time before a network webcam became available which doesn't need to be plugged straight into a computer. I've had "half an eye" open for such a device for a while - thinking that it must be technically possible. And on Sunday I spotted one on the shelf at our local PC World ....
It's a nice little camera from Linksys. Wireless and Cat5 connections. Powers up at IP address 192.168.1.115, so it can be spoken to (with a bit of temporary address changing!) from our network, and configured through its web server ... it's now on our network at 192.168.200.73, and configured to email us a few seconds of video clip if it detects movement.
All we have to do now is to work out how to view the .asf files that are coming into our Mac and Linux inboxes. It does seem a huge shame that Linksys (part of Cisco) are supplying a product without drivers even for OS X. A quick search of PHP's "Pear" and Perl's CPAN has drawn a blank so far ... but I have come across a formal specification of the file format. Perhaps my chance to write something as a contribution to one of those repositories? Or has anyone any experience with .asf -s ??
Posted by gje at 12:57 AM
December 06, 2004
Colour for access
Under disability discrimination legistlation, anyone who offers a service is required to make all reasonable efforts to provide an equality of service to anyone who suffers any form of disability; we've all seen wheelchair ramps and wide doors spring up on the High Street of late.
Every disabled person has slightly different requirements, so there's no quick aand easy answer to the question "how can I make my website more accessible / conform to the law". The concensus view is that two elements need to be considered: (a) font / size and (b) colour. With font and size, an option to provide a single large font page (even though very few words may be seen at once) is generally considered to fit the bill; for colour, I've seen examples that let web sites switch between black on white, yellow on dark blue, white on black and dark blue on yellow.
But the consensus view isn't ideal for everyone - indeed, there are as many different ideals as there are people. I've learnt today of research by the University of Bangor (that I need to follow up up) that shows that the ideal colours for someone who's dyslexic are black on light blue, or black on light green. Either light blue or light green on black is also very good. For some reason that's not yet understood, yellow on black and black on yellow is pretty dreadful ... as are black and red, and red and black. The frequently-seen blue on yellow and yellow on blue are great for some people, and horrendous for others. "There's a doctorate in researching that for someone" says one of my trainees on today's course, who was one of the subjects in the original Bangor study and continues to take an interest in their work.
Posted by gje at 06:08 PM
December 05, 2004
Too technical?
When I started writing the Horse's Mouth back in the summer, I wondered if I would find enough to say every day. I needn't have feared, as here I am, months later, not wondering what to write today but wondering what NOT to write!
Every day, I learn something in my job. Ranging from how you use Tcl to talk to Internet Explorer and Excel (yesterday), through a recipe to encourage workmen to complete the job in hand (previous day) and what paperwork is necessary to complete the sale of a narrow boat (the day before). None of these made it here as a full article. And sitting on my "I want to talk about" list remains a longer article on SQL injection, and overdue reply to David on a comment he made - goodness - nearly a week ago, and an explanation of how a photo I took appears in the Calendar of a Reading Civil Engineering company next year.
But perhaps at times I'm getting too technical. So for today, no further mention of work stuff. Just a look forward to the festive season of Christmas, and to a homeful of people around the tree on Christmas day. Young and old. Family and friends. Now that December's here, the corner is turned and I'm looking forward ... to spending some more time with these people and with others that we'll be meeting up with for a drink here, a meal there, and an outing somewhere else.
Posted by gje at 09:08 AM
December 04, 2004
Comparison Chart for Perl programmers - list functions
grep v map v sort
Most languages support lists and / or arrays - and that includes Perl. In Perl, though, you can use functions such as grep, map, sort and reverse to operate on lists as a whole rather than having to loop through members of the list cell by cell.
| function | desciption of action | element count | elements altered? | Output element order |
|---|---|---|---|---|
| grep | Filters incoming elements and copies those which match a criteria to the output list | "n" elements in, 0 to "n" elements out | outgoing elements are exact copies of incoming elements | outgoing elements are in same order as incoming elements |
| map | Performs an operation on each incoming element and writes the result to the output list | "n" elements in, "n" elements out | outgoing elements are the result of an operation on incoming elements | outgoing elements are in same order as incoming elements |
| sort | Re-orders the incoming elements and writes the result to the output list | "n" elements in, "n" elements out | outgoing elements are exact copies of incoming elements | outgoing elements are in a different order to the incoming elements |
| reverse | Writes the incoming elements to the output list in reverse order | "n" elements in, "n" elements out | outgoing elements are exact copies of incoming elements | outgoing elements are "back to front" from the incoming elements |
It's a common misconception that grep is used only to filter incoming members against a regular expression - it CAN be (and that's the most common use and how it got its name), but it can also be used to perform another task, based on each member of the incoming list in turn being put into $_. The following sample program shows two uses of grep and two of map to illustrate the comments just made and parts of the table above.
# antonia Perl XML PHP Tcl/Tk MySQL
# barbara Tcl/Tk ASP Ruby Java
# cherry Perl Java Ruby MySQL
open (FH,"requests.xyz") or die "No requests.xyz file\n";
@stuff = grep (/^.[aeiou]/,<FH>); # Only want lines with vowel as 2nd letter
@m1 = grep((split)>5,@stuff); # Filter to remove short lines
print @m1;
print "============================\n";
@m1 = map(uc,@m1); # Change all lines to all upper case
print @m1;
print "============================\n";
@m3 = map(length()."\n",@m1); # Produce a list of line lengths
print @m3;
I ran this against a test data file of 52 lines (I've pasted the first three lines into the sample code above) and here are the results - you'll see that the only lines left by grep are those which comprise over 5 space separated fields, and have a lower case vowel as the second letter.
[localhost:~/dplp] graham% perl nq
hazel PHP Python Perl Ruby ASP
leane PHP Python ASP Perl Java
margaret XML Perl Ruby MySQL Tcl/Tk
petra XML Tcl/Tk ASP Perl Ruby
xena Java Perl PHP ASP XML
barry Python XML Java Perl PHP
============================
HAZEL PHP PYTHON PERL RUBY ASP
LEANE PHP PYTHON ASP PERL JAVA
MARGARET XML PERL RUBY MYSQL TCL/TK
PETRA XML TCL/TK ASP PERL RUBY
XENA JAVA PERL PHP ASP XML
BARRY PYTHON XML JAVA PERL PHP
============================
31
31
36
31
28
31
[localhost:~/dplp] graham%
There are further examples of the use of functions such as grep (and push and pop and others too) available under our training note pages.
Posted by gje at 08:00 AM
Useful link: Perl training
December 03, 2004
Just provide a room and the students
I'm sitting, writing, in our training room and there are 9 laptops on the desks ready for the final day of Perl for Larger Projects. That's one laptop per trainee, some spares, a laptop off which we project course notes, and the system I'm writing from. Operating systems? A mixture of Unix, Linux and Windows so that the students can choose.
For both public and private courses, we provide a system for each trainee to use and a complete LAN too; at our offices, the LAN is connected to the Internet (with full 3Mbit access from all systems) but on site we run isolated - for security reasons, we don't want (or need) to connect inside your firewall. The system works well and is a delight to everyone - you "just provide the students" and we do the rest; you don't have to scramble about finding equipment or loading software, and we know what's on the systems and we can set up quickly and run an efficient course.
Over the past couple of years, though, some of our trainees have started bringing their own systems along, and they're welcomed on our network - we even have a page with full connection details on our web site. They can use their own data and programs for the course, they can grab copies of all our examples for the course off the course server, and at our offices they can check in with work via "the net" too.
Posted by gje at 07:46 AM
December 02, 2004
Perl - redo and last without a loop
Perl has next, last and redo commands which (by default) cause you to move on to the next iteration / exit from / repeat the same iteration of a loop.
Did you know that you can also label a block and then use them in a similar way in that block?
$c = 1;
$d = 4;
thyme:
{
$c++;
$e = 5;
redo thyme if ($c < 3);
$f = 6;
last thyme if ($e > 3);
$g = 7;
}
$h = 8;
print ("$c $d $e $f $g $h\n");
Result:
[localhost:~/dplp] graham% perl blocker
3 4 5 6 8
[localhost:~/dplp] graham%
Note - the "redo" lets you write a loop without there being any loop word used - dangerous unless you know what you're doing and almost as frowned upon as using a goto statement (of which Perl has three flavours!). See intermediate and advanced examples.
Posted by gje at 08:11 AM
Useful link: Perl training
Certification schemes
Should we offer certified training courses to agendas laid down by the likes of Sun, Adobe and Zend, or should we offer courses to our own agendas? There are arguments both ways, and we reconsider from time to time. I thought you might be interested in a (slightly long) item I wrote in response to a specific enquiry a few minutes ago (relating to PHP and the Zend certification)
We have given repeated consideration over a number of years to providing "official" training and taking part in "certification schemes" for some of the products on which we train, but haven't gone with any of them. Although it might help us to sell our courses in a few cases, we believe that we can do better offering our customers training to suit their need on the ground, rather than to pass an exam or to produce a "cookie-cutter" developer. A further issue is the conflict of interest created by us running a training course on which the attendee is provided with a certificate making him more easily able to move away from the employer who has paid for his training. There's more written on this topic elsewhere on our site and the text quoted on that page is actually relating to PHP certification from Zend ....
Of course, the fact that we write our own notes and set our own agenda means that we have to take especial care to ensure that we provide both what is right for the client, and what is going to be right to see him into the future too. We do this in a number of ways. Firstly, we do read extensively - the press, online, books, etc. Secondly, we undertake contract work ourselves and actually use the subjects that we teach. Thirdly, we listen to our trainees and their requirements; some of them get pretty advanced in specialist areas, others send more junior staff to us and already have senior (and very knowledgeable) PHP gurus on their staff. Fourthly, we review other training offerings on PHP to ensure that we're reasonably in line and not missing anything - although we don't simply duplicate their offerings of course! Examples that we've looked at within the last couple of months include several London courses - see my further comments. We've also looked at other offerings such as those from First Alternative, Oracle, Academy X and Media Training. Additionally although we're not offering the certification (with the cost and other implications), we have reviewed the agenda / program for it and have a copy of the study guide ISBN number 0-672-32709-0 which is for sale at bookstores, and is now available for reference during our course. I'm confident that our course provides good training which will meet the basic requirements of the exam which I understand can be sat independently at a Prometric centre if you so wish.
I have left what is, perhaps, the most important way we keep our course up to date until last. It's vital that I (as the tutor) understand not only the mechanisms of the language, but also the application and best practice, and the intent of the authors and developers. For that reason, I take "time out" to travel and listen to the originators and active people at the "sharp end". PHP was written by Rasmus Lerdorf, who now works for Yahoo in Toronto where it remains an active part of his interest and area of influence. He stopped off in southern Europe on his way to Japan in October, and I travelled there to attend some day-and-a-half of talks he gave - the only lectures he did on what was also a holiday stopover. What did I learn? Not the language, but the intended practice, a direction for the future so that I don't lead trainees up blind alleys, and answers to some nagging "why" questions that no-one else seemed to know the answers to. And I now pass on that knowledge during our courses ....
You've already seen how we run an "Open" web site - full details of our staff, our prices are published on line. We're proud of what we can offer. However, we also respect the privacy of our clients and don't publish a customer list. Occasionally, a customer will himself publish the fact that he's Well House Consultants trained and recommend us ... Oxford University, for example.
A longish answer here - I hope it helps fill you in, and helps you decide whether our PHP training course is the one you should choose.
Postscript. . We currently offer three different PHP / related courses:
Technology for PHP
PHP Programming
Object Oriented Programming in PHP
Of these three, the PHP programming is the relevant course for most trainees. We have servers running both PHP 4 and PHP 5 available on the course; at the present time, most live servers are running PHP4, and the course is suitable for both, encouraging you to write code for your current system but ensuring that it will also run on PHP5 (there is one specific compatibility issue in core PHP4 v 5, and a number of additions you'll want to be aware of).
Posted by gje at 07:35 AM
December 01, 2004
Please tell us
So often, I have said "if you like what we provide, tell your friends, if you don't, please tell us". That's not my original line, but it's good practice. And it's heartfelt too ...
Recently, we released about 500 pages (out of 3000) of our training notes under an Open Training Notes license on a sister site of this one - www.training-notes.co.uk - and I've pointed a few of our client sites at them. I woke this morning to learn that on one of these sites, a couple of teething problems have been reported and circulated on an internal mailing list. Now that's fine by me - but I do wish that the person / people who feel that there were issues had felt comfortable enough to let us know so that we could fix it!
By contrast ...
I received an email on Monday and it said " The engineer in me can't hold back from telling you that you've mis-spelt 'facsimile' in the footer on the wellho site - hope you can recover from the shock." To the person who wrote to me to let me know - a public THANK YOU. It's fixed in the development site, and will trickle through onto the live site as pages are updated.
Posted by gje at 09:39 AM