« June 2009 | Main | August 2009 »
July 31, 2009
What are closures in Lua?
When you're writing a sort routine, passing in "a" and "b" to be compared, how do you access other data that's needed in association with a and b? If - for example - a and b are keys to a hash or dictionary or associative array, and you want to sort based on the values in that array? You could make your hash global (or rely on the global default in Perl or Lua) but that is a poor solution - messy and unmaintainable.
Lua uses the concept of a closure - in Lua, variables that are local to a function are also available in functions that are defined within that function i.e. within nested definitions, or 'within the outer closure'.
Here's an example:
function postman(thistable)
function psord(a,b)
if thistable[a] < thistable[b] then
return true
end
return false
end
local keys = {}
for k,_ in pairs(thistable) do
keys[#keys+1] = k
end
table.sort(keys,psord)
rs = ""
for k,v in ipairs(keys) do
rs = rs .. k .. " " .. v .. " at no. ".. thistable[v].."\n"
end
return rs
end
deliveries = {John = 4, Jim = 10, Jean = 7, Joanna = 3, Jo = 9}
hegoes = postman(deliveries)
io.write (hegoes)
You'll notice that "thistable" is a local (parameter) to postman, but never the less can be accessed from within psord ... which is a pleasant surprise if you're converting from other languages.
Running the code, I get
1 Joanna at no. 3
2 John at no. 4
3 Jean at no. 7
4 Jo at no. 9
5 Jim at no. 10
Source of the example here
Posted by gje at 02:06 PM | Comments (0)
Related topics: via article database
More about Graham Ellis of Well House Consultants
Useful link: Lua training
July 30, 2009
Floor to ceiling
From floor to ceiling, this is a new training room this week. And from floor to ceiling, it is eventful. Heavy overnight Mexican rain had seeped into the building, leaving a centimetre of standing water at the slightly lower end of the room where my tutor's area / projection wall is located (I thought it was going to be "paddling in Lua" but a lady with a mop appeared!). And the ceiling above my translator's head was being painted during the course. But we all stuck in and got down to what is a very tiring, but very rewarding day. I took the opportunity of clicking a few snaps to share.







"A picture paints a thousand words" ... I'm not going to label up those individual pictures here within the blog!
Posted by gje at 12:15 PM | Comments (0)
Related topics: via article database
Learning to write high quality code in Lua
What a wonderful opportunity this week - to train delegates in Lua programming (and Lua, byte for byte, is perhaps the best value language that I train in) but also to be in on the early stages of a project where it's not just a question of training on the language itself, but also in helping provoke thoughts with regards to the best way to make use of the language in the application. I was happy - no, let's say "delighted" to step into one of the siderooms at the end of the class and find the team leaders discussing programming standards and techniques, to the extent that they're planning a further course on the subject. Good for them - I'm sure that such a course will repay its cost many times over! They asked me if I was interested in presenting - yes, interested, but I don't have the materials, the knowledge in some of the areas, and they would do far better with a more local tutor who could come back in for a morning every couple of months to review progress with individuals.
I have, as is my normal practise, been writing code examples 'on the fly' during the course ... and on one of those I wrote today, I asked for a critical review from my delegates. In the culture, where everyone is so polite, I had to trigger the discussion - "I can see at least three things that I haven't done, which I should have done to make this into a high quality piece of code". And then they started to pick up my faults - (most of which were deliberate!)
• My code was uncommented throughout its body, meaning that it would be very hard to follow later, even by the original author.
• Variables within functions (at least I HAD structured my code into functions!) were not all declared as local - like Perl, Lua's variable are default global. And that means the a reuse of the function later could lead to some odd and hard-to-find bugs due to name conflicts
• The indentation of my code was erratic, again making it hard to read
• My functions, which would have been useful in other applications of the same data, were in the same file as my main program, meaning that without re-engineering my code could not be shared.
• Variable naming wasn't standard or consistent ... and we had already seen during the course how inconsistent variable naming slows down maintenance coding as the maintainer has to keep looking back to find out what variables were called, and what spellings and capitalisation were used.
• The output from my program was just a set of results - it didn't label the results in any way. So that means that a copy of the output given as a report to a manager would have needed extra work to document it to make it of any practical use
• There was no header block stating what the field was, which version, who maintained it, what it required. Once again, that makes it very hard to maintain.
• No user documentation ...
Our next Lua Programming course starts on 10th August 2009 in Melksham, UK. If you have missed that date, the course description page will give further dates - usually scheduled 9 to 18 months ahead. And if you're looking for a course for a group of delegates, we can arrange a private course at our centre or a on site course at your offices for you. And as you'll see from the blogs I am writing this week, that can be in the UK, or further afield ... look back and you'll read of courses in the USA, Saudi Arabia, Germany, Ireland, the Netherlands, Slovenia, Finland ... and this week Mexico.
I believe in teaching NOT ONLY the mechanisms of a programming language, BUT ALSO how that language should be well written - both in terms of the specifics for the language and in general computing terms!. If asked to teach "just the mechanisms of the language" on a private course, I would probably refuse, insisting on adding at least a few words to encourage good practise.
Posted by gje at 11:55 AM | Comments (0)
Related topics: via article database
Useful link: Lua training
July 29, 2009
Lua training class in Spanish
"Can't wait to hear how you're getting on". "Keeping an eye on your blog". A couple of messages from folks wondering how I'm getting on with my Lua course in Guadalajara, Mexico, this week.
The answer will be brief. I'm enjoying the course, the delegates are getting a lot from it (THAT is the important bit), but I'm exhausted at the end of the day because there's so much different and there is more adrenalin and less autopilot than usual.
The group size is around 30 ... an during practical sessions, I'm rushing around. And I'm having to be pulled off topic far less - almost being cruel and saying "I WILL answer but for everyone", and making sure that I do so later. The translation service is interesting to work with; my words are being translated as I say them, and are fed back in Spanish into my headset so that I know when to slow down. 1 word in English seems to become 3 in Spanish. And I have to restate any questions I'm asked so that the whole audience knows what I am answering. I have to admire the lady doing the translations - her multitasking is excellent, and she's coping pretty well with while as a keyword that must not be translated, and while in conversation that must be!
The training room is new ... the network not connected ... no whiteboard and just a flipchart that is too small for everyone to see. No aircon. One loo (and that didn't fill at one stage, so I had to ask for a bucket!) between 33 of us, and I have the Mexican equivalent of Delhi Belly. And the hosts are - well - falling over themselves to be helpful and hospitable, to the extent that it's overpowering.
But - hey - I am enjoying the course, the challenge, the subject. Lovely group - I knew this one would be different when I took it on, and it sure is. But in spite of my few grumps, I'm glad I took it on. It is working very well!.
Posted by gje at 01:03 PM | Comments (0)
Related topics: via article database
Useful link: Lua training
July 28, 2009
A new place in pictures
Perhaps this is the "picture postcard" that you'll expect to see from a trip far from the UK - and indeed, it's a picture taken in Guadalajara yesterday, as I took an easier day that usual to recover from the jetlag, catch up on some sleep, and also went across to the place I'll be training to meet the folks and check that everything is on order. With a group of around 30 delegates, and with a translation service converting my English into Spanish, this is not a 'run of the mill course'. Most of the delegates are a new intake who only started work yesterday (and I sat and observed body language and interaction as they were taking through things like where to park in the neighbourhood), with a major part of the company's project being to upskill people, sponsored by the Mexican government, rather than the final products. The training room is also new; it was nearing completion yesterday - painting and carpetting still being done in the breakout rooms, computers covered in plastic and being started / having Lua installed. So this will be an "opening course" for the room - hopefully there will be few or no major teething troubles, but I know that the networking will be limited.
Another picture?
That's an image at random from the ones that I have uploaded (so I am presenting my HTML to cope with horizontal and vertical) which will change each time you come back. In some circumstances, I am caching to avoid too many reloads to a simple refresh may not illustrate the changes. But there are pictures of the area, the suburb we are situated in, the hotel room (you may wonder - I do this routinely to let us compare / look for ideas that we should or should not, must or must not borrow!), and a couple of the place and people where I'll be.
If you want to link to see each of the images (outside our own tight knit group, I don't expect many will) see here here here here here here here here here here here here here here and here. Phew!
Posted by gje at 10:28 AM | Comments (0)
Related topics: via article database
July 27, 2009
Breakfast in Mexico
The Mexican Buffet Breakfast ... I look and I learn from hotels that I say in and ask "would this work in Melksham". OK - the food was lovely this morning. The price compares very favourably with a Premier Inn breakfast, where the buffet does not include ... Nachos, Cactus, Beef Burritos, Beef Tongue, Spicy Sausage, Plantains and Refried beans (those things shown on my plate), nor the scrambled eggs and chicken pancakes that I didn't have room for this morning.
I'll probably eat at the buffet again tomorrow - I hope they still have the spicy trip broth that was there, but I noticed too late, and the Mexican Omelettes which I could be tempted by.
But some things DO transfer to Melksham. At Well House Manor we trialled (and were unimpressed) by the premade 'fresh' fruit salads that are available in the trade, and took a decision a while back to make ours truly fresh. We have a breakfast meeting every Friday and (it seems) no matter how much fruit salad we make (on site, ourselves), there is always the "Oliver factor" of "May we have more". And here in Mexico, they too have a fruit salad - truly fresh - prepared just a show while ahead and not shipped in, in bulk, in sealed containers.
Posted by gje at 03:18 PM | Comments (0)
Related topics: via article database
Melksham to Mexico for the week
I am starting my day with a short item ... but you may look at the time aand think have a funny definition of "start". But I'm in Guadalajara, Jalisco, Mexico - I arrived here yesterday from London, a lunchtime (UK time) flight of over 11 hours to Mexico City, and an ongoing connection to Guadalajara which got me clear of the baggage hall ten minutes shy of midnight (local time) - that is 6 a.m. UK time. A VERY welcome sight as I came through to the public area at the airport was a sign with my name on it, and one of the delegates on the Lua Course that I'll be teaching standing behind it, with his car in the parking structure across the way. I was in the hotel by midnight-30.
I am tempted to write something of a travelogue, but it was frankly something of a standard journey made by countless millions, written up by hundreds, and many of them doing a far more interesting job than I. I suspect it was my longest ever scheduled flight, and the three hour scheduled layover followed by a further hour's flight has left me very glad that I'm taking today 'quiet' - to type, relax, recover. Actually, I took the opportunity of the flight to skim-read a couple of the Lua texts, and I expect I'll be writing up and playing about with some of the ways of presenting certain Lua topics during today. My class will be a record 30 delegates (that's by special negotiation, but can be done!) so I need to be fresh and on the ball.
But I will add that I noted a friendliness of the staff at Mexico City and Guadalajara airports, and at the hotel, which with my customer service hat on I say "we should learn from that" in the UK. As a newcomer who doesn't speak Spanish (project - work out a few common words - later today) I was so open to being treated in the way that I see happen on some occasions in the UK - but actually, here, it was a model. I felt like a welcome visitor even at customs and immigration, and not just someone who had to be processed and was giving them more to do.
What could I see of Guadalajara in the dark, as we drove in? Well - very little, and as ever I'm working so any chance to see the sights / be in the pretty and tourist parts will be be an unexpected bonus. But I did note a dual carriageway we drove down, slip roads and parallel roads off the side to service local businesses, very much in the way that will be familiar to those of you who have driven extensively in the USA - town and city business areas. The businesses were shut and boarded and didn't look at their best (neither did I at midnight) and it was quiet, and went on and on. Looking a hundred yards up the side streets, though, they were lined with cars and trucks (white van / 4wd type not 44 tonners) and very clearly the "strip" was backed by the residences. All very low to the ground; a spread out city, and where the this housing spread up to alongside the main drag, it is very clearly more 'township' than 'suburb'.
It's 7 ... and there will be a breakfast buffet available. Mexicana offered actually quite nice food for us in cattle class yesterday, but in quite small quantities and now that I think about it I didn't really have anything substantial after we had left Irish airspace. Off for brekkies, and I had said "short post" I think!
Posted by gje at 12:51 PM | Comments (0)
Related topics: via article database
July 26, 2009
Hot Tap at West Wilts Show
The West Wilts Show at Trowbridge concluded at 5 p.m. yesterday ... and yesterday was the day that we saw the children and their parents, in addition to the more limited range of people who had been able to come along during the working and school week on Thursday and Friday. Which was rather good, as much of the show and entertainment is for the children.
Here are "Hot Tap" in the Melksham tent (and, yes, those three rapt faces above were watching them) - four tap dance shows during the show. It's at time like this than I get reminded that there is a community out there who are not on line - at this point I would normally be adding a link to Caroline Wilkinson's site, which would tell you about her classes in Southwick, Trowbridge, Melksham and Semington ... but she's not got one, so the best I can do is to say taht "If you're looking to get into shape / have fun at the same time, call her on 01225 752030" from her publicity blurb (and put up here with her permission!
.
I have a lot more pictures to post of the show ... but I'm travelling today; you'll find out to where in a day or two. Watch this space!
Posted by gje at 06:13 AM | Comments (0)
Related topics: via article database
July 25, 2009
Extracting real data from an exported file in PHP or Perl
"Just give me the data". Where there's a requirement to take data from another program into a Perl or PHP script, it's often easier simply to take the data in a format that it's offered / exported from that other program and use code in Perl or PHP to make appropriate use of that data. The alternative of getting the data supplier to do all sorts of manipulation is, frankly, more trouble than it's worth.
Lisa has passed me a data flow - a dump of all the Melksham retail businesses - from the map she's been working on and is being shown at the West Wilts Show today. It's good, it contains what I need, but it's formatted with the map in mind rather than with the data meaning ("how it should look" rather than "what it means"). Now I could ask for it in XML ;-) ... of I could use Perl or PHP and their powerful text handlers. I have chose to do the latter.
Here is the main "what's this line" decision code - in PHP:
if (ereg("^ ",$record)) { # MAIN HEADER
elseif (count($els) == 1) { # SUB HEAD
elseif (count($els) == 2 and ereg("^[1-9]",$els[1])) { # OUT OF TOWN on map
elseif (count($els) == 2) { # OUT OF TOWN LOCATION not on map
elseif (count($els) == 3) { # IN TOWN LOCATION
else { # ERROR
and here is the formatted list of Melksham retailers I have produced from it. The source code is here. The next stage is going to be to produce listings by area ... as I have the data in my PHP code now, that will be easy. And I know that I need to put a good look and feel onto it!
You can download the map from here.
Posted by gje at 07:22 AM | Comments (0)
Related topics: via article database
Useful links: Perl training, PHP training
July 24, 2009
Turning potential customers away
I want happy customers ... which is why I turned down a golden booking opportunity a few minutes ago.
"Have you got a single room for tonight". Err - all of our rooms are double / twin, but we routinely let them as singles ... and we have rooms tonight, but we're full tomorrow night so it would be a good fit. But we're not just a bed for the night; I explain this, and that our pricing reflects the services we offer. "Oh - I was playing Golf in the area, and I've decided to have a drink with me mates and stop over - thank you for your help anyway" says my caller "I'm just looking for somewhere to sleep", and the phone conversation ends cheerfully on both sides.
I'm very happy to take fairly late bookings - phone calls that start with "we were looking to stay in Melksham - have found your number and we are in our car NOW looking at a grain silo, can you guide us" [last weekend] to people simply walking in during the afternoon - "have you got a room" [Wednesday] - both cheerfully and happily accommodated. But once it gets well into the evening, enquirers tend not to be well suited to Well House Manor. They are typically looking for a room, a single bed, and not much more. But we offer much more. And if we take the business, they end resentful of what they have paid for something that was far more than they wanted, and we're more likely to end up with a room that has not been respected in its use by that resentment.
I hope our gentleman found himself a bed; I can't imagine he would have a problem on a Friday night. I hope he enjoyed his drink - heck, if he ended up at the King's Arms or the Pear Tree he could simply roll upstairs. And if he goes for another round of golf tomorrow, he'll not be thinking how he was stung in Melksham. And I'll have a good night's sleep, secure in the knowledge that - whilst we are not full - we have a comfortable group of happy customers in.
Now - I need to print out a bus timetable, as some of our guests are going to Bath tomorrow; they asked about Park and Ride, but they're better advised to leave their car at Well House Manor and catch the 272 or 273, right outside our gate, into the City. Heck - we are "Melksham park and ride for Bath" as far as our guests are concerned, and withe the bonus of evening services back that you don't get at the conventional park and ride too!
Posted by gje at 11:45 PM | Comments (0)
Related topics: via article database
July 23, 2009
See us at the West Wilts Show
The West Wilts show runs today (Thursday, 23rd July) and Friday and Saturday in Trowbridge. We will be in the "Melksham" tent - covering Well House Manor hotel, Well House Consultants courses, the Train Service Improvement Campaign, the Melksham Map, the Chamber of Commerce ... all on an 18 foot stand.
Do pop in and see us if you're in the area. Or if not, have a look at the web sites / pages that we have set up via here
We may be in a tent, but we'll be online, broadband!
Posted by gje at 07:17 AM | Comments (0)
Related topics: via article database
July 22, 2009
Mistaken identity?
I asked who I was logged in as yesterday ... and I got two different answers:
[melksham ~]# who am i
trainee pts/1 2009-07-21 13:16 (192.168.200.80)
[melksham ~]# whoami
root
[melksham ~]#
When you log in to a Unix or a Linux box, you give an account name (and password, I hope!) and you're given a user account name / identity. Or so you think - but really you have two identities, your real and your effective id. If you use a command such as su to get a new identity, your effective id changes, but not your real id ... and that's what had happened with the report above.
There is a good reason for this ... the difference between real and effective ids is used within programs too - operating system programs such as the passwd program. On one hand, users cannot possibly be allowed to write from their normal accounts to the file that contains encoded passwords - think of the security risk, yet on the other hand they must write to that file if they're going to be changing their password. The conundrum is neatly overcome by having the passwd program set up with a setuid bit, which means that while you're running it, you have an effective root id while your real id remains as the user you logged in as.
We tell you more about su and why you should always run su - on our Linux Admin Introduction.
Posted by gje at 05:52 AM | Comments (0)
Related topics: via article database
July 21, 2009
What does x on a linux directory mean?
Trick question (I don't ask too many, I hope ... and those that I do ask are designed to be thought provoking):
What does the x bit in permission strings mean?
Most delegates who've done a bit of Unix or Linux before will tell me it's the exexcutable bit - says whether a file can be run as a program direct from the command line, and for a plain file they are correct. But for a directory, it means Access of should I say Axess?
One a directory, the r setting still means "readable" but without the x set on, I can only read the file names - I cannot access the full details of each file, nor can I delve deeper into the directory.
To illustrate this, I temporarily turns the "x" off on one of my directories and did some directory listings:
[trainee@easterton ~]$ chmod a-x dbn
[trainee@easterton ~]$ ls dbn
dbn/ac_20090716 dbn/mediawiki-1.14.0.tar.gz
dbn/apache-tomcat-5.5.27.tar.gz dbn/mysql-5.1.34-linux-i686-glibc23.tar.gz
dbn/httpd-2.2.11.tar.gz dbn/palace_of_westminster.jpg
dbn/jdk-6u14-linux-i586.bin dbn/php-5.2.9.tar.gz
dbn/latmjdemo.war dbn/somewhere_else
dbn/mediawiki-1.13.5.tar.gz
[trainee@easterton ~]$ ls -l dbn
total 0
?--------- ? ? ? ? ? dbn/ac_20090716
?--------- ? ? ? ? ? dbn/apache-tomcat-5.5.27.tar.gz
?--------- ? ? ? ? ? dbn/httpd-2.2.11.tar.gz
?--------- ? ? ? ? ? dbn/jdk-6u14-linux-i586.bin
?--------- ? ? ? ? ? dbn/latmjdemo.war
?--------- ? ? ? ? ? dbn/mediawiki-1.13.5.tar.gz
?--------- ? ? ? ? ? dbn/mediawiki-1.14.0.tar.gz
?--------- ? ? ? ? ? dbn/mysql-5.1.34-linux-i686-glibc23.tar.gz
?--------- ? ? ? ? ? dbn/palace_of_westminster.jpg
?--------- ? ? ? ? ? dbn/php-5.2.9.tar.gz
?--------- ? ? ? ? ? dbn/somewhere_else
and as you can see, you're able to see what's there, but not do much more.
Is this used / useful? There are places within the operating system that you'll find one just one of r and x on a directory, but advise for newcomers on our Linux Basics course is that - for a directory - you should normally treat them as a pair.
Posted by gje at 03:40 PM | Comments (0)
Related topics: via article database
Useful link: Linux training
July 20, 2009
How much space does my directory take - Linux
The index card in the library for "War and Peace" takes a lot less space that the book itself, and so it is when you ask Linux or Unix "how much space is taken in this directory" ... you'll be told how big each of the files are, and how big the index table for each subrirectory is. Here's an example from today's course, one of our training machines:
[trainee@easterton ~]$ ls -l
total 1224
drwxrwxr-x 4 trainee apache 4096 May 18 11:52 build
drwxrwxr-x 2 trainee apache 4096 Jun 4 11:56 dbn
drwxr-xr-x 2 trainee apache 4096 Jun 12 14:21 Desktop
-rwxr-xr-x 1 trainee apache 55 May 26 11:20 ls
drwxr-xr-x 3 trainee apache 4096 May 26 12:09 ppl
drwxr-x--- 2 trainee apache 4096 Jun 12 14:22 richard
-rw-r----- 1 trainee apache 81920 Jun 12 14:22 richard.tar
drwxr-x--- 3 trainee apache 4096 Jun 4 16:29 tombuild
-rw-r--r-- 1 trainee apache 22186 May 21 19:55 transwilts2009.odt
-rw-r--r-- 1 trainee apache 785849 May 21 19:55 transwilts_2009.pdf
-rw-r--r-- 1 trainee apache 313556 May 21 19:57 transwilts2009.pdf
drwxrwxr-x 4 trainee apache 4096 May 18 11:22 website
So that's telling me that the total size is 1224 Kbytes (just over 1 Mbyte) with most of the space in the file transwilts_2009.pdf. And there are 7 directories that are 4096 bytes each ... Yes, but that's the directory entry size. Let's dig deeper:
[trainee@easterton ~]$ du -sk *
211020 build
243080 dbn
12 Desktop
4 ls
60348 ppl
152 richard
84 richard.tar
60352 tombuild
24 transwilts2009.odt
772 transwilts_2009.pdf
312 transwilts2009.pdf
461424 website
Once again, you see that the transwilts_2009.pdf file is 772k ... but the grand total has rocketed from just over 1 Mbyte to 461 Mbytes ... because we're now looking within each directory. They're not 4096 bytes each - that's just the index card. The website directory (as an example) is 461 Mbytes alone.
Courses - Linux Admin Introduction and LAMP deployment for folks who have to look after we servers.
Posted by gje at 03:30 PM | Comments (0)
Related topics: via article database
Useful link: Linux training
July 19, 2009
Melksham Carnival Parade - the people
Carnival is all about people ... people in the carnival, and people watching the carnival.

Melksham Carnival and Party in the Park, 18th July 2009.
Posted by gje at 09:25 AM | Comments (0)
Related topics: via article database
Standing on the corner, Melksham Carnival
Yesterday was Melksham's "Party in the Park" and Carnival ... the Carnival Parade running from the car park of Cooper Avon Tires at about 6 p.m., looping through the town centre, with a variety of walking groups and floats.
On days like this, Well House Manor is ideally placed as we're close enough to the town centre for it to be very easily accessed (and with plenty of parking for our guests and selves) but just far enough out for for our road to remain open.
So there I was at about a quarter past six ... "Standing on the corner, watching all the girls [and boys] go by" (Words and music by Frank Loesser).









Most of our guests had checked in earlier in the day - we are as flexible as possible with our 3 p.m. checkin, and we welcome "Saturday night only" guests. I think some had gone out to the Party in the Park and Carnival. Others had gone to Bath for the afternoon - it's only 12 miles away. And the final couple of the late afternoon / evening arrived at around parade time.
Posted by gje at 08:31 AM | Comments (0)
Related topics: via article database
July 18, 2009
Variable scope - what is it, and how does it Ruby?
Variables have different "scopes" - in other words, a name that is allocated to a piece of computer memory and subsequently used to refer to that memory may be 'know about" to your program only within a very small area, or much more widely. It's the same IRL ("In Real Life") - consider you, Dad, Graham and Graham Ellis, all of which are names by which I am known, but in different scopes. You is a very temporary variable name which can be reallocated throughout a process ... as people get on a bus, the "you" of "Where would you like a ticket to varies every few seconds. Dad varies from context to context, and there can be lots of dads all on that same bus. But there is probably just one Graham Ellis there. This scoping, and the need for uniqueness, is a key element to programming ... and it's often something that newcomers to coding take a while to get their head around.
The first whiteboard photograph with this article (Fig 1 ;-) ) shows how you define the scope of your variables in Ruby. Variables that are just bare words (i.e. don't have any special character starting them) are local to the function / method in which the name is used. That's like their family, and like referring to someone as "Bill" or "Kylie". There will be different Bills and Berts and Kylies in other families just up the road, but you just wait until Bill brings home another Kylie - the girl up the road - and you have a recipe for confusion around the dinner table. ((Does anyone still sit down for dinner??)). Variables that start with an @ character are object variables - they apply across all pieces of code that can be run on a particular object, and variables that start with two @ characters are class variables that apply to all objects of a certain type. I have another picture to show that:
A number of buses and trains. Each has a destinations, and a departure time and those vary ... so you are looking at a different memory location for each destination, and a single @ character. But if you ask how many pieces of transport you have defined, there's just a single answer across the class as a whole, and in Ruby you indicate that using @@ rather than @. And both of these variable type are wider ranging than local variables which apply only in a single block of code and are released when that block has finished running, rather than being retained between one method and another.
You'll here terms like "instance variables", "dynamic variables" and "object variables" used too for the @ type, and "static variables" or "class variables" used for the @@ type too, depending on who you're talking to and about which programming language - moving away from Ruby, the same concept but a different syntax and varied nomenclature is used for other languages - you'll find if you come on a Perl, PHP, Python, C, Java, Lua or Tcl course that I'll still talking about scope.
The final variables that I showed in my initial diagram start with a $. They are global variables - available anywhere through the code. Now you might think it would be a good idea to make heavy use of these but emphatically it is NOT. It's all very well to use them to pass things around in smaller bits of code / scripts, but if more than a tiny proportion of your variables are scoped in this way, you make yourself a major maintainance problem as your program grows, and it becomes very hard to reuse the same code in several programs as the combining of useful bits of logic is likely to require a lot of patching of global variables on their way in and out of each piece of logic, and perhaps the dramatic updating of one or other piece of logic when you discover that both have used $result or $current.
There is an example that uses local, object and class variables here (that's the example I was writing when I put these diagrams on the board during last week's Ruby Course). Running that code you get:
Dorothy-2:pics grahamellis$ ruby d4_5
Swindon - 2 vehicles. option 1 of 4
Chippenham - 1 vehicles. option 2 of 4
Westbury - 2 vehicles. option 3 of 4
Bath - 1 vehicles. option 4 of 4
Dorothy-2:pics grahamellis$
A variety of different destinations within each object (Swindon, Chippenham, Westbury and Bath) held in a variable that starts with at @ ... and a single value for the number of pieces of public transport defined [4] in a variable that starts @@.
Posted by gje at 11:41 PM | Comments (0)
Related topics: via article database
Useful link: Ruby training
July 17, 2009
The dog is not in trouble
"I know I put my papers somewhere" I said to Lisa [wife], and Gypsy [dog] goes off and whimpers in the corner, looking very guilty.
So had she [dog] taken the papers and chewed them? That wasn't the case - she had heard the word "no" (or rather "know") in what I said, and had taken it that she was being told off for something.
We heard words and take them in context - they mean different things depending on the rest of the sentence surrounding them. "We don't subsidise lunches" could mean 'as a matter of policy we will never pay part of the cost of your lunch', or it could mean 'as it happens, we don't at the moment make any payment towards your lunch in our canteen'. And - taken out of context - this is an awfully good way of manipulating a message (or a naughty way, depending on your print of view).
It may surprise newcomers to programming that context also comes in to computer languages - a simple ^ (caret character) means different things in different places, and it's far from unique in having different meanings,
print "Say something: "
saying = gets.chop
puts "That starts with W" if saying =~ /^W/
puts "That contains a character which is not a letter" if saying =~ /[^A-Za-z]/
print 160 ^ 54, " shows the bitwise exclusive or operator\n"
So that's "Starts With" or "Anything Except" or "Either but not Both depending on what else is written around it. The example I have given is in Ruby, but the three meanings are the same in many other languages - thank goodness for that consistency, at least!
Running that code ...
Dorothy-2:jul09 grahamellis$ ruby csdp
Say something: Wicked
That starts with W
150 shows the bitwise exclusive or operator
Dorothy-2:jul09 grahamellis$ ruby csdp
Say something: Sweet Summer Sunshine
That contains a character which is not a letter
150 shows the bitwise exclusive or operator
Dorothy-2:jul09 grahamellis$
Some languages such as Perl make a very heavy use of context - if I write @abc, I could be referring to all the elements of a list, to the length of the list, or to the list expanded into a string. See article on context in Perl.
While checking this article, Google found me a rather nice Ruby Quick Reference - enjoy!
Posted by gje at 07:58 PM | Comments (0)
Related topics: via article database
July 16, 2009
Can you learn to program in 4 days?
"New to programming" on Monday Morning ... and understanding a program that reads and analyses a web access log file, reporting back on remote hosts that visited us and stayed for between one and five minutes by the end of Thursday. That's a good advert for Ruby - and a good advert for our Learning to Program in Ruby course, and a good advert for Ruby too!
I have added the program that I wrote, with delegate help, here (that's the source for you). The program - even after such a short time with the language - was already revealing useful information from the data about the metrics of visitors too our web site.
Have a look at the example to see Ruby code for quite complex structures (a hash of arrays of objects, no less), directory handling, formatting output, regular expression work, and much more.
I have files the source code, ironically, under "Introduction to Ruby". It's not the first thing you would write, but it's certainly an example of what you can do very quickly with the language ... and its OO structure and maintainability shines through. Some of the more awkward time handling algorithms are encapsulated and reused, and the code to identify which records are automata (spiders and other robots), which are web site attacks, and which are real users is all held in one small area too.
Posted by gje at 04:13 PM | Comments (0)
Related topics: via article database
Regular Expressions in Ruby
Ruby has a wide variety of string handling methods, and a very strong regular expression engine. In one of the example I wrote today ([link] Regular Expression Example in Ruby) I've included a primer on the elements of a Ruby Regular expression as well as sample source code - showing you how you can match things like email addresses and postcode, and how you can extract the information from different parts of the matches too.
Other new Ruby string handling examples:
[link] Using a string as a collection
[link] Formatted printing in Ruby - printf sprintf and %
[link] Running a piped command via backquotes
Posted by gje at 04:01 PM | Comments (0)
Related topics: via article database
Useful link: Ruby training
Object Orientation in Ruby - intermediate examples
It's when you teach object orientation - the fully Monty, including inheritance, static and dynamic methods and variables, and so on - to a complete novice to programming and that person finds it's one of the easiest parts of the course that you realise:
a) Just how many bad ole habits us ancient structure programmers have gotten ourselves into and ...
b) What an excellent and natural Object system languages like Ruby have. T hat's as compared to C++ with a bevy of files, Java with so much security it obscures the simplicity, or Perl with so many options and so much ability to sidestep objects. (Python has a similar, and great, philosophy too)
Here are the 'second level' examples from today - not the basic object stuff, which you'll find if you look back a couple of days.
[link] Single class example for extension by inheritance
[link] Object and Class variables (dynamic and static)
[link] Static Method in Ruby
[link] Inheritance in Ruby
Posted by gje at 03:52 PM | Comments (0)
Related topics: via article database
Useful link: Ruby training
Collection objects (array and hash) in Ruby
Ruby has two collection objects - Arrays (where you access elements based on their numeric position) and hashes (where you can access elements based on a key, rarely numeric). That's similar in all but name to many other languages, although the names may be different (arrays or lists; hashes or dictionaries or associative arrays!). We covered many of the basics on yesterday's learning to program in Ruby course - and here are the sample programs I wrote as an illustration during the Arrays and Hashes section:
[link] Arrays, and iterating through them
[link] Array methods such as grep
[link] Simulated table (an array of arrays)
[link] Set up a hash and use it
[link] Simple but practical hash example
[link] Count the number of visits from each IP address (Includes how to sort a hash - or rather the keys - based on the values the hash contains in Ruby)
Posted by gje at 05:31 AM | Comments (0)
Related topics: via article database
Useful link: Ruby training
Opening and reading files - the ruby fundamentals
Once you've noted that File.new doesn't create a new file, but rather (default) opens an existing one for read ... you'll find Ruby's file handling interface easy to use. The new methof returns a file handle object - a sort of buffer that sits between the file and your program - and each time you run the gets method on it, you'll get the next line back. Once you hit the end of the file, you'll get a nil result which you can check for, and you're then supposed to close the file.
Once you've hit the end of the file, further calls to gets will simply return nil again; if you want to re-read the data, you'll have to open the file again, or use a rewind method. Of course, you could read the whole file into an array with readlines and then iterate through it a lot of times without going back to the disc, and that's going to be much quicker unless the file is huge.
The File class also has a number of methods like exists and size which allow you to check a file status even without opening it
[link] Iterating through a file, and file output.
[link] Test file to see if it exists prior to opening.
You can also open another process and handle that as it it were a file:
[link] Reading from another process
Examples written yesterday during our Learning to program in Ruby Course. Similar principles apply across many of the langauges we teach with just the deatil and syntax varying, and we can also run "Learning to program in ..." courses in Python, Lua, PHP, ....
Posted by gje at 05:20 AM | Comments (0)
Related topics: via article database
Useful link: Ruby training
July 15, 2009
pre-Inaugural briefing - Melksham Community Area Partnership
14th July, Semington Village Hall - the sort of inaugural meeting of the Melksham Community Area Partnership (see about CAPs and about Wiltshire's new structures).
I wondered why Semington Village Hall for a "Melksham" meeting - Semington Village has been made an awkward place to drive to due to road restrictions forcing visitors from Melksham to drive all around the Semington bypass and approach from the other end, and it seemed odd for a Melksham meeting. It became clearer.
Joanna, on short term contract to the council, explained what the Community Area Partnership was, handed out questionnaires with about a dozen statements about CAPs and asked us to choose "True", "False" or "Don't Know" - a good way to set the subject / theme and get the discussion running. And she introduced Laura who assists these partnerships throughout the authority area, and Abbi who is a council officer, with a role to support the Melksham Area Board.
Many of the 40 or so faces at the meeting were very familiar to me, and deeply involved in local politics - so knew what an CAP was. But many of us did not / could only make educated guesses, and so this priming was a healthy introduction, and lead to animated discussions through the evening.
At the end of the meeting, a roadmap for the formation of the Melksham CAP was drawn. 8 of the people present volunteered to form an initial steering group with a view to setting up the structure of the CAP and constitution, prior to a further meeting at which CAP steering group members would probably be elected, with the CAP (in whatever form it turns out to exist) then starting to function (or not). It was very interesting to see that even after a lukewarm reception to the idea, the 'usual culprits' quickly volunteered for the posts, sensing a powerful role on offer, whereas the more targeted / single issue / ordinary people present were left rather bemused by the whole process. Some excellent speakers who would have brought a breath of fresh air failed to come forward. I am not going to publish the notes I made listing the 8, but please feel free to email me if you want to know; officially, I guess, I should tell you to ask Laura, or Abbi.
What are the major issues of concern that came up.
1. That the country parishes will be swamped by Melksham Town. Villages of 300 or 400 people feel that their voice won't be heard fairly with the 21,000 of Melksham. Yet I would speculate that the county already spends more per member of its rural population on roads, on transport subsidy, on refuse collection ... than it does on its majority urban population. If everyone feel it's unfair, it's probably about right!
2. That the CAP will not be truly independent of the Area Board. Members of the area board seem to be under the impression that they can require cases to be made for expenditure by the CAP - "it won't be a problem if they do good work" said a current Area Board Councillor. But I worry about the area board withholding funding or making it awkward if it feels the CAP is not doing good work, or if it wants to spend money on non-CAP projects. I am also concerned of a conflict of interests if people are active on the CAP steering committee (with voting rights) AND are on the Area Board (with voting rights). There is already one such case and apparently (as anyone can be on the CAP), it's within the rules.
3. That some communities in the area are not naturally Melksham based and feel out of place. Poulshot look naturally to Devizes ... Steeple Ashton is 5km from Trowbridge, but 8km from Melksham and has direct public transport to Trowbridge - but not to Melksham (change at Trowbridge!) Are the people in these places really going to want to be on the Melksham CAP, and are the people who look naturally to Melksham as their centre really going to want to put money into Poulshot to Devizes issues?
4. That true consultations will not happen and it will just be "he who shouts loudest who gets heard"? With just a few people talking, a fear was expressed that the CAP could get taken over by a few vocal voices.
5. That the CAP will add another layer between residents and their councillors and area board, thus the councillors will not be so much in touch.
6. That there is no forum for cross-boundary matters. One gentleman was talking about public transport services, and it seems the CAP isn't going to be great for that - nor for other things shared over a wider area. I felt rather sorry for him being shushed by the chair, without an adequate alternative representation being presented. (Some readers who know me will be aware of my own public transport concerns - getting people around within the Melksham Board Area and to and from Melksham to help the whole economy of the place. I did not know the gent, and felt it best to keep my own concerns / case to myself in the Semington meeting, rather looking at other avenues.
7. That consultations inputs will be filed rather than being acted on with due weight. The role is to advise, suggest and plan. But it seemed clear that there is no guarantee (and I wonder what the expectation is) that what results will be given due weight. Past personal experience is that there are a lot of hidden agendas around in Wiltshire, and CAP consultations are another golden opportunity for a "we consulted" box to be ticked, without any consideration being given of the results.
8. That the CAP will conflict with the Parish Councils / Town Council. They should work together but with different boundaries / people, who knows?
9. That only the officially recognised bodies will get involved with the CAP Invites to the meeting had gone out to "160 organisations on our lists" (and it was good that 40 attended and 40 apologised for absence). But I would love to have had the meeting mentioned via editorial in the local papers, for example. I wonder who is on the official list. Chamber of Commerce IS, it seems. None of the rail campaign groups that I am involved with - and which are well known to people at council - was.
10. That the CAP will run amuck spending taxpayer's money like there's no tomorrow and have to be bailed out by the authority. This fear was expressed at Area Board level, with memories of Melksham First which may be biased memories. It may well be that the purpose of this fear was the start of an area board v CAP power play.
11. That the CAP area board will disregard all minorities, even including significant ones who's position should be considered.
I'm sorry that list looks so negative ... but let's take it as being careful to list out some of the pitfalls to be avoided; I chose personally not to put my name forward for the initial steering group. I was at the meeting by invite to represent Melksham Chamber of Commerce and did not feel it was my place without going to committee to put me / us forward for this body. Had I been there in a personal or other organisation committee basis or on dual invite, I might have taken a different view. But also - I am no expert at waste disposal, health and so many other topics that effect the area, nor am I a great organiser, so there are other things I can do with my time which are more suited.
There is an opportunity in the area board. And there are some excellent people on the steering group who could make an excellent job of the cards they have been dealt. They deserve our support and encouragement - I hope to be able to attend the formal launch of the formed body and to offer it appropriate support. Who knows - if the organisation ends up with specialist groups looking after areas with which I am concerned, I may find myself deeper involved. Just as the parishes fear being swamped by the town of Melksham, so the town of Melksham fears being swamped by the 'big three' of Salisbury, Chippenham and Trowbridge - the mantra that Council Officials seem to echo at county wide meetings on subjects from Budget to Tourism, from Policing to Development, and from connectivity to waste disposal. A strong CAP could ensure a fairer hearing for all, and I hope it works.
Footnote - why was the meeting in Semington? I don't know, but I'm guessing that it was a message to the parishes from whoever chose the venue to symbolically make them the more welcome.
[b]Update - December 2009[/b]. The inaugral AGM took place on 20th November, and I stood for / was acceped for the steering group for the next year. [report]. the first meeting of this steering group took place on 9th December; I have chosen NOT to file a report yet on my blog.
Posted by gje at 07:03 PM | Comments (0)
Related topics: via article database
Wiltshire Community Area Partnerships
A few days ago, I wrote about all the new structures at Wiltshire Council; I was having trouble working out what they all did, and I don't think I am the only one having trouble understanding it. (See that article). I got stuck at "Community Partnerships" or "Community Area Partnerships" which seemed to be missing from the various official body lists.
Well ... I sorted it out last night, when I attended a meeting that (it turned out) was to launch the setup of the Melksham Community Area Partnership. And it should work like this:
The County is split into 18 Area Board - groups of around half a dozen councillors who look after their own patches, dealing with more local issues themselves and coordinating the inputs from there area to full council. It is proposed that each Area Board should have a Community Area Partnership associated with it - the role of the CAP being to involve and consult with the community in the area, and to feed back those views to the area board with the purpose of helping to set and steer the agenda.
Everyone who lives in, works in, or otherwise has a legitimate interest in an Area is considered to be a member of their local Community Area partnership, although many people will be inactive and perhaps oblivious to the fact that they're even a member. It's completely up to each area how they set up their CAP, within some very general guidelines, and around 38k of the area board's funding is to be made available to them, of which up to a fifth can be on admin. CAPs have already been setup in many areas - Melksham is one of the last, although few of the recent ones associated with the new Unitary setup have been going long enough for them to have a track record to report.
Typically, a CAP will have a steering committee of around 8 to 16 members who will meet from time to time, channel information to and from the area board, community members and community organisations. They must be formalised to the extent of having a constitution, but the intent overall is that they should be as free as possible to represent the community - they are intended (according to Joanna who was running the meeting) to be independent of the area board. And this independence and local delegation is, we were told, a key factor in why Wiltshire's Unitary bid was accepted.
Melksham's Area Board (and therefore Community Area Partnership) includes Melksham Town, and the parishes of Melksham Without, Atworth, Broughton Gifford, Semington, Seend, Great Hinton, Keevil, Bulkington, Poulshot and Steeple Ashton. The six councillors are Jonathon Seed (Conservative, Summerham and Seend) who chairs the board, plus the five "Melksham" councillors - town and without - listed here. Rod Eaton (also Conservative) is deputy chair of the board.
The stuff above is more or less 'official' ... now would you like to know about the meeting, which will be much more personal views and heresy? I'll add that on in the next 'tranche' in a short while. Added - see here
Update - December 2009. The inaugral AGM took place on 20th November, and I stood for / was acceped for the steering group for the next year. [report]. the first meeting of this steering group took place on 9th December; I have chosen NOT to file a report yet on my blog.
Posted by gje at 05:28 PM | Comments (0)
Related topics: via article database
Learning to program in Ruby - examples of the programming basics
We so often overlook the basics of programming, and yet they are so fundamental to good code - understanding things like how widely variables can be seen (also known as variable scope), what happens when you divide two numbers (do you get a decimal result or is the remainder thrown away), and how do you name a block of code and re-use it to avoid having to duplicate code and later maintainance work.
On yesterday's Ruby course, I produced a series of example of many of the basics and I have uploaded them on to our web site for you to take a look through if you wish. I have tried to avoid the temptation of "I'll just add something to show xxx" in these examples - the wood should not get lost in the trees!
[link] Prompt, read from user, calculate, output in Ruby
[link] Use of intermediate variables
[link] Use of intermediate variables - alternative
[link] Easier output formatting
[link] Calculations within double quotes
[link] if, elsif and else illustrated
[link] while, until and for loops - comparison
[link] finding extreme values from a collection
[link] Summing a collection
[link] Putting common code in a name block (function)
[link] Define class, create and use instances of it
[link] Use of 'self' in Ruby
[link] Calling program to access class in another file ...
[link] ... and that sample class in its own file
We offer two public Ruby courses - Learning to program in Ruby for newcomers to programming, and Ruby Programming for those with prior programming experience in another language. Public courses run at our Well House Manor training centre in Melksham, Wiltshire, England. These are niche courses - we offer residential facilities to full hotel standard, and can help with delegates travel arrangements too.
Posted by gje at 07:40 AM | Comments (0)
Related topics: via article database
Useful link: Ruby training
July 14, 2009
New to programming? It is natural (but needless) for you to be nervous
Yesterday, I ran the introductory day at the start of our Learning to Program in Ruby course.
Delegates come to us to learn a programming language with two different backgrounds - "I have programmed before in xxxxx and now I need to learn QWERTY" (the converters) and "what is this programming thing all about anyway" (the newcomers). The newcomers are typically nervous at their lack of knowledge, overawed by the people they'll meet who they feel are going to be much more clever, and worried about not 'getting it' in the new world of programming.
If - as a programmer - you're reading this, you'll know that the newcomers should not be nervous. The newcomer is no less bright - just less practised, and can and will pick up programming if they have an aptitude. The convertors were newcomers once, and understand very well indeed what the newcomer is going through - and want to help that newcomer. And the teacher (who was also a newcomer once) gets an immense satisfaction from helping the newcomer start from zero, and pick up some of the basic concepts and start plugging them together into usable, and then useful programs.
Don't get me wrong - the hardest courses to teach are the "complete novice" ones, but they are also so much more rewarding. I tend to end up writing brand new example code, showing the individuals on the course not only WHAT a program looks like but HOW it is reached. And each individual finds different things easy and difficult, so the examples vary every time.
The other great thing? "Get 'em early and they don't get bad habits". My "learning to program" days show not only the mechanism of programming and how it applies in a certain language, but also what is good and what is bad ... I can teach people that they should comment their code well, that they should plan what they're doing, that they should write and test in stages, that testing is important and that if they find themselves copying and pasting code they should be structuring their code ... all of which go towards making code which will be easy to maintain, which will run consistently and which will tend to be more reusable and more reliable.
During yesterday, I developed a number of examples and I have added them to our web resources this morning. Some are dinky little examples to show the basic features and principles, others are somewhat longer to say "yes - we are headed to a wonderful destination here, even though we don't arrive until later in the week". And they also say "you, dear newcomer, will see how the things you learn on the first day are going to be an integral part of your live applications".
Here are those examples:
[link] First use of variables and calculations
[link] Simplest practical program - read from user, calculate, output result
[link] An example with a loop, showing how you should plan and document your code
[link] Naming a block of code - adding in structure and re-usability, and a first introduction to local variables and why that is a good thing
And some of the demonstrations of "where are we going with this ..."
[link] Read through a file and report on all lines matching a pattern, with management summary at the end
[link] Finding and matching various lines and keeping several counts
[link] Analysis of a large data file (web access log) which reports on the pattern of matching for the last 24 hours.
At the end of the day ... the final example produced some really useful results for me; I have wondered about the pattern of accesses to our servers over a 24 hour period, and this little program give me a profile for one day, and I can go on and extend it later ... no doubt I will be doing so, when I get the time (a.k.a. a month of Sundays!)
Posted by gje at 08:23 AM | Comments (0)
Related topics: via article database
July 13, 2009
Great new diagrams for our notes ... Python releases
When training, I project onto a white wall ... and I draw onto the projected image, and add extra notes and diagrams around the side too - after all, the whole wall is a whiteboard. Some of the diagrams and slides that I'll come up with are new / unique for an individual course, and I end up photographing the whiteboard or parts of it, and so do my delegates.
And I also photograph the board ....
Here's a sample diagram, showing how Python has gone through a series of updates. At version 2.3, "new style classes" were added to correct some (frankly) quite small issues - at least as far as the regular user was concerned - in the OO model / specification. And "old style classes" were retained, and still are up to release 2.6 and 2.7.
But there are other things that need(ed) changing, and without being held back by the need for ongoing source code compatibility, and so along came Python 3.0 ... now Python 3.1 ... which breaks some source code compatibility things. In Python 3.0, you can only use new style classes, print is a function which changes its syntax oh so slightly, and there are some other things. So I drew a strong read cross on the line from Python 2 to Python 3 ... but then a green line bypassing that cross to show there IS a way - an automated program - to make the change.
Posted by gje at 08:39 AM | Comments (0)
Related topics: via article database
Useful link: Python training
July 12, 2009
Strings as collections in Python
In Python, I can treat a string as a collection of characters and iterate through it without the need to do any sort of conversion on it, or muck about with "substr" ...
breakfast = "Croissants and toast"
for letter in breakfast:
print "Give me a ",letter
print "and we have",breakfast
Dorothy-2:py grahamellis$ python sar2
Give me a C
Give me a r
Give me a o
Give me a i
Give me a s
Give me a s
Give me a a
Give me a n
Give me a t
Give me a s
Give me a
Give me a a
Give me a n
Give me a d
Give me a
Give me a t
Give me a o
Give me a a
Give me a s
Give me a t
and we have Croissants and toast
Dorothy-2:py grahamellis$
Posted by gje at 05:30 PM | Comments (0)
Related topics: via article database
Useful link: Python training
Everyone is in the customer relations business
It's so important that everyone who represents a business represents it well - from 'The Boss' right through to the weekend help. The thought has struck me this weekend - not because of our own business (where I hope that every single one of us is fairly well on the ball) but because of various places I have been in to - unusually - over the last couple of days, while working the weekend myself.
At lunchtime yesterday, at one of our favourite cafes, the reception wasn't welcoming - it was merely polite. I felt the staff on duty would have much preferred to have being nearly empty than to have to serve customers. A call to a local taxi company we use was answered merely "hello", causing me to wonder if I had dialled the right number followed by "is that the taxi" and "oh yeah, I'll get my wife" (and they were too busy to do one of the journeys we needed). And I walked out of a third place - a 7 day, morning to late operation in the town, because the customers were queueing out the door and I knew I would have wasted half an hour waiting.
I know our staff read this (and in the fast moving tourist business we have ex-staff too, some of whom may read it) and I am not for a moment suggesting that I have seen any of the present crew dropping those clangers - well, yes, we all do from time to time, but this weekend has really brought it home as to how prevalent it is.
This weekend, the course I was giving was to a guy I had never met before. But he knew of us before he booked - because his colleagues have been singing our praises. It's three years since I trained them, (see blog) half a world away and a different culture. And that repeat business is cherished. Will there be more? "See you in Dharhan" I said as I dropped him off at Trowbridge station and - do you know what - I think it's quite likely that I will!
Posted by gje at 05:18 PM | Comments (0)
Related topics: via article database
Checking robots.txt from Python
The robots.txt file - which well behaved automata check to see whether they are welcome on a web site - has two directives in its base specification ' User-Agent and DisAllow. You will find some other directives used, and you will find some sites who have a robots.txt file that has blank lines after the User-Agent line, even though (in the specification) the block for a user agent ends at a blank line. These rules, and web master's lack of knowledge of the detail, mean that some sites don't have their robots exclusion file as effective as they would wish.
I have written a very short Python example here which reads a robots.txt file via http protocol, and analyses it to report on the active User-Agent and Disallow lines - not only as a sample program on today's Python Course, but also to allow me to do a quick sanity check of robots.txt files.
Features of this Python example include ...
• Checking the number of command line parameters
• Connecting to a remote web resource and reading it as it it was a file
• Use of exceptions
Posted by gje at 02:00 PM | Comments (0)
Related topics: via article database
Useful link: Python training
Python - using exceptions to set a fallback
In Python, you should use exceptions to catch error conditions such as files that you're unable to open, broken network connections, and user inputs which give a problem - it's all very well putting traditional checks in your code, but you'll be well advised to use try and catch as well for additional security.
You can also use exceptions as a safety net to set the fallback value for a variable if it hasn't otherwise been defined, as in this example:
# Lots of code that SHOULD set "status" variable ...
try:
print status
except NameError:
status = "OK"
print status
print "Code carries on, status is ",status
With multiple except clauses, Python can handle different errors in different ways - if you're going to use this facility, list the most specific exceptions first, as Python will use whichever one matches first.
Note that in Python, you can also raise your own exceptions too - and you are strongly advised to do so when you want to return an 'error' from a function rather than a value. For example, you should raise an exception in a function that returns the number of children someone has, but the function cannot determine a result - it should NOT return a cardinal or special value such as 99 or -1 as that would make the calling code and handling of the results more complex (and, one day, someone MIGHT be a sperm donor and have fathered 99 children!)
Posted by gje at 11:44 AM | Comments (0)
Related topics: via article database
Useful link: Python training
Creating and iterating through Python lists
In Python, you create lists by putting a series of values in square brackets - and the program creates a list with that number of elements. You can change an element by referring to the element by number in square brackets, remembering that Python starts counting at 0. Unlike Perl, you can't extend a list simply by referring to a number above the current range (very prone to programming errors), but you can use the append or extend methods to add extra elements on the end (flexible, whilst encouraging good coding practise).
places = ["London","Melksham","Farnborough"]
places[1] = "A Beautiful old town in Wiltshire"
# Use the append method to extend a list
places.append("Hastings")
places.append("Dungeness")
When you want to iterate through all the elements of a list, there are a number of ways of doing so and the most straightforward is for loop as follows ... although in this case you don't even get the index number, so if the position of each value is important you'll want to use one of the following alternatives.
# Quick and easy - but unable to get at posn no
for place in places:
print place
You can list individual places and loop through positions numbers - but that isn't extensible. Better to use a range function to get a list of position numbers of (in the case of a long list) xrange which is an iterator - returning one value at a time and not stuffing memory with a large intermediate list.
# Not extensible
for posn in [0,1,2]:
print posn,places[posn]
# Extensible BUT intermediate list may get long
for posn in range(len(places)):
print posn,places[posn]
# Extensible and uses an iterator
for posn in xrange(len(places)):
print posn,places[posn]
Python 3 (actually 3.1) has now been released, and in Python 3 there are some slight syntax changes. print is now a function so you would add brackets around the parameters, and you would always use range rather than xrange as it will automatically convert to an iterator for you.
Why am I still using a Python 2 example? Because the recommended upgrade route is to keep maintaining code in Python 2 until all the platforms that you run on have been converted, using the automated converter while you are supporting both. And because most of the delegates on our Leaning to program in Python and Python Programming courses are following that approach. We have both versions available during the course, and we ensure that delegates leave with a knowledge of the conversion process without switching back and forth all through the course and leading to confusion.
The example above is taken from the Python course I am running this weekend - more normally, the course runs during the week, with the next available dates in mid August. As one of the delegates who is booked on that next course wrote about our update strategy "Aha, perfect ... I was told that I should concentrate on python 2.x as python 3.x has an awful lot of changes and all our existing scripts would have to be updated."
Posted by gje at 07:07 AM | Comments (0)
Related topics: via article database
Useful link: Python training
July 11, 2009
Understanding the new local government structure in Wiltshire
Government is bound to be complex, but I have this uneasy feeling that two layers of local government that I didn't understand have been replaced by one layer (and a sub-layer) that are almost as complex ... and which I think Joe Public still may not understand.
You can download this diagram (full size / .pdf) from here on the Wiltshire Council's web site. But, complex though it appears, it doesn't seem to cover all the local bodies. So I have added tried to put some of into context below.
• The layers of Government
1. Parish / Town Councils (253)
1a. Area boards (come under the Unitary Authority, but cover 18 separate geographic areas in the county)
2. Unitary Authority
Wiltshire Council
Wiltshire Council Cabinet
Wiltshire Council Committees
Wiltshire Assembly
Wiltshire Coordinating Group
Thematic Delivery Partnerships
Wiltshire Public Service Board
Community Partnerships
Citizens Panels
Wiltshire Council Scrutiny
Council Departments and Officers
Wiltshire Strategic Board (related - not just part of council?)
3. Regional
Our region covers an area of 23,829 square kilometres including Cornwall, Devon, Dorset, Gloucestershire, Somerset, Wiltshire and the Isles of Scilly, and represents a population of almost five million people.
The South West Regional Assembly was abolished on 13th May 2009, powers to:
Strategic Leaders board of (41) South West Councils
Also at the regional level - Government Offices South West
4. Central Government (9 regions)
(No, I am not going to try to explain that one, or the following ones!)
5. European Government (27 member states)
6. Worldwide groupings to whom we sign up
(e.g. United Nations, International Court of Human Rights)
• The major bodies at Unitary level
Wiltshire Council 98 elected members, each of whom represents a geographic area across the county. Councillors are listed here and there are full council meetings from time to time, but in practise most of the decisions are delegates to commitees, cabinet, other bodies, or made by the controlling party group or the county's officers.
Wiltshire Council Cabinet A grouping of senior elected members from the governing party who provide the political lead for the council on a day to day basis. Drill Deeper.
Wiltshire Council Committees Smaller groups of councillors to whom powers are delegated by the main council. There are 7 committees with specific functions covering the whole area, plus planning committees which cover parts of the area. Drill deeper here.
Wiltshire Assembly The Assembly met for the first time in October 2008, and meets twice a year. "It aims to be the main place where Wiltshire organisations come together to decide what needs to happen in order for Wiltshire to build a bright future for itself." See here for further details.
Wiltshire Coordinating Group The Wiltshire Coordinating Group is a small action focused working group which will bring issues together to assist the Wiltshire Assembly to develop, update, and coordinate delivery of the Wiltshire Sustainable Community Strategy. Drill deeper here.
Thematic Delivery Partnerships "Responsible for delivering significant action and developing strategy to achieve the ambitions in the Local agreement for Wiltshire". Drill deeper here
Wiltshire Public Service Board Brings together key public sector organisations that allocate significant resources to Wiltshire and are held accountable by government. The membership is largely comprised of elected Members and Chairmen who have the authority to commit resources on behalf of their organisation, supported by key officers. Drill deeper here
Community Partnerships (Community AREA partnerships?) I am still working this one out as to whether or not it is a formal setup, or a generic name for some other groups. Update - they "represent the community to the area board" - see here
Citizens Panels Panels of local citizens (sometimes specific demographic groups) within the county who are surveyed concerning various issues, with the reports from those surverys being published. Drill Deeper.
Wiltshire Council Scrutiny There are five scrutiny bodies who oversee the work of other bodies in the council - drill deeper here.
Area Boards Area boards are formed of the elected councillors for a geographic area (who can vote) and of other local area 'notables' who can attend on an advisory level. They have a limited local budget, and are intended to give the local areas an influence over what is done within an area up to the Unitary level. ASee here for further details.
Council Departments and Officers The organisation of the employed staff who operate the day to day services and are charged with implementing the policies of the council and its cabinet. See here to drill in deeper.
Wiltshire Strategic Board The Wiltshire Strategic Board (WiSB) is the key overarching, multi-agency partnership for the County. It is encouraged by government to set out its vision for the future of Wiltshire, and the broad actions that will make a reality of this vision, in a document called a community strategy. Drill deeper here.
• Listings of individual organisations / committees
Wiltshire Parishes:
Aldbourne, Alderbury, All Cannings, Allington, Alton Barnes, Alvediston, Amesbury, Ansty, Ashton Keynes, Atworth, Avebury, Barford St Martin, Baydon, Beechingstoke, Berwick Bassett and Winterbourne Monkton, Berwick St James, Berwick St John, Berwick St Leonard, Biddestone, Bishops Cannings, Bishopstone, Bishopstrow, Bowerchalke, Box, Boyton, Bradford on Avon, Bratton, Braydon, Bremhill, Brinkworth, Britford, Broad Chalke, Broad Hinton and Winterbourne Bassett Parish Council, Broad Town, Brokenborough, Bromham, Broughton Gifford, Bulford, Bulkington, Burbage , Burcombe, Buttermere, Calne, Calne Without, Castle Combe, Chapmanslade, Charlton, Charlton St Peter and Wilsford, Cherhill, Cheverell Magna, Chicklade, Chilmark, Chilton Foliat, Chippenham, Chippenham Without, Chirton, Chitterne, Cholderton, Christian Malford, Chute, Chute Forest, Clarendon Park, Clyffe Pypard, Codford, Colerne, Collingbourne Ducis, Collingbourne Kingston, Compton Bassett, Compton Chamberlayne, Coombe Bissett and Hornington, Corsham, Corsley, Coulston, Cricklade, Crudwell, Dauntsey, Devizes, Dilton Marsh, Dinton, Donhead St Andrew, Donhead St Mary, Downton, Durnford, Durrington, East Kennet, East Knoyle, Easterton, Easton Grey, Easton Royal, Ebbesbourne Wake, Edington, Enford, Erlestoke, Etchilhampton, Everleigh, Figheldean, Firsdown, Fittleton, Fonthill Bishop, Fonthill Gifford, Fovant, Froxfield, Fyfield and West Overton, Grafton, Great Bedwyn, Great Hinton, Great Somerford, Great Wishford, Grimstead, Grittleton, Ham, Hankerton, Heddington, Heytesbury, Imber and Knook, Heywood, Hilmarton, Hilperton, Hindon, Holt, Horningsham, Hullavington, Idmiston, Keevil, Kilmington, Kington Langley, Kington St Michael, Lacock, Landford, Langley Burrell, Latton, Laverstock, Lea and Cleverton, Leigh, Limpley Stoke, Little Bedwyn, Little Cheverell, Little Somerford, Longbridge Deverill and Crockerton, Luckington, Ludgershall, Lydiard Millicent, Lydiard Tregoz, Lyneham and Bradenstoke, Maiden Bradley with Yarnfield, Malmesbury,Malmesbury Without, Manningford, Marden, Market Lavington, Marlborough, Marston, Marston Meysey, Melksham, Melksham Without, Mere, Mildenhall, Milston, Milton Lilbourne, Minety, Monkton Farleigh, Netheravon, Netherhampton, Nettleton, Newton Tony, North Bradley, North Newnton, North Wraxall, Norton Bavant, Norton and Foxley, Oaksey, Odstock, Ogbourne St Andrew, Ogbourne St George, Orcheston, Patney, Pewsey, Pitton and Farley, Potterne, Poulshot, Preshute, Purton, Quidhampton, Ramsbury and Axford, Redlynch, Roundway, Rowde, Rushall, Salisbury City Council, Savernake, Seagry, Sedgehill and Semley, Seend, Semington, Shalbourne, Sherrington, Sherston, Shrewton, Sopworth, South Newton, South Wraxall, Southwick, Stanton St Bernard, Stanton St. Quinton, Stapleford, Staverton, Steeple Ashton, Steeple Langford, Stert, Stockton, Stourton with Gasper, Stratford Tony, Sutton Benger, Sutton Mandeville, Sutton Veny, Swallowcliffe, Teffont, Tidcombe and Fosbury, Tidworth, Tilshead, Tisbury, Tockenham, Tollard Royal, Trowbridge, Upavon, Upper Deverills, Upton Lovell, Upton Scudamore, Urchfont, Warminster, West Ashton, West Dean, West Knoyle, West Lavington, West Tisbury, Westbury, Westwood, Whiteparish, Wilcot and Huish, Wilsford cum Lake, Wilton, Wingfield, Winsley, Winterbourne, Winterbourne Stoke, Winterslow, Woodborough, Woodford, Wootton Bassett, Wootton Rivers, Worton, Wylye, Yatton Keynell and Zeals
Wiltshire Area Boards:
Calne, Chippenham, Corsham, Malmesbury, Marlborough, Wootton Bassett, Bradford on Avon, Devizes, Melksham, Pewsey, Trowbridge, Westbury, Amesbury, Salisbury, Southern Wiltshire, South West Wiltshire, Tidworth and Warminster
Council Committees:
Standards Committee, Audit Comittee, Stategic Planning Comittee, Area Planning Comittee, Staffing Policy Comittee, Officer appointments Committee and Pension fund committee.
Thematic Delivery Partnerships:
The Wiltshire Strategic Economic Partnership, The Wiltshire’s Children and Young People’s Trust Board, The Community Safety Partnership, The Housing Partnership , The Resilient Communities Partnership, The Transport Partnership, The Wiltshire Environmental Alliance and The Health and Wellbeing Partnership Board
Posted by gje at 07:03 AM | Comments (0)
Related topics: via article database
July 10, 2009
First courses for 2010
Can you believe that the schools haven't yet broken up for the summer holidays (except in Scotland) ... yet I am scheduling the first provisional dates for each of our courses for 2010 - six to nine months ahead.
Our customers need to plan well in advance - to budget, to schedule, and to know what will be available when. Booking are already open for these courses, and although I have said the dates are provisional, each course will be fixed and guaranteed to run once even a single booking is confirmed.
The weeks of 11th January 2010 and 8th March 2010 are "options" weeks - set aside for training on the more niche topics; in each of those weeks we will run whichever course is the first to take a booking - so if you want to learn a subject, please call us to get in soon.
Please follow this link for dates for the rest of 2009, and for updates to the 2010 schedule in due course
| January 2010 | |
Deploying Apache and Tomcat [Link] | Thursday 7 January 2010 and Friday 8 January 2010 |
Learning to program in Lua [Link] | Monday 11 January 2010 to Thursday 14 January 2010 |
Learning to Program in Ruby [Link] | Monday 11 January 2010 to Thursday 14 January 2010 |
Learning to Program in C [Link] | Monday 11 January 2010 to Wednesday 13 January 2010 |
Learning to program in C++ [Link] | Monday 11 January 2010 to Friday 15 January 2010 |
Lua Programming [Link] | Tuesday 12 January 2010 to Thursday 14 January 2010 |
Programming in C [Link] | Tuesday 12 January 2010 and Wednesday 13 January 2010 |
C and C++ Programming [Link] | Tuesday 12 January 2010 to Friday 15 January 2010 |
Ruby Programming [Link] | Tuesday 12 January 2010 to Thursday 14 January 2010 |
C++ for C Programmers [Link] | Thursday 14 January 2010 and Friday 15 January 2010 |
Learning to Program in Python [Link] | Sunday 17 January 2010 to Wednesday 20 January 2010 |
Python Programming [Link] | Monday 18 January 2010 to Wednesday 20 January 2010 |
PHP Techniques [Link] | Thursday 21 January 2010 and Friday 22 January 2010 |
February 2010 | |
Learning to program in PHP [Link] | Sunday 7 February 2010 to Thursday 11 February 2010 |
PHP Programming [Link] | Monday 8 February 2010 to Thursday 11 February 2010 |
Object Oriented programming with PHP [Link] | Friday 12 February 2010 |
Deploying LAMP - Linux, Apache, MySQL Perl / PHP / Python [Link] | Monday 15 February 2010 to Thursday 18 February 2010 |
Linux Basics [Link] | Monday 15 February 2010 |
Linux Administration [Link] | Tuesday 16 February 2010 |
Linux Web Server [Link] | Wednesday 17 February 2010 and Thursday 18 February 2010 |
Learning to Program in Java [Link] | Monday 22 February 2010 to Friday 26 February 2010 |
Java Bootcamp [Link] | Tuesday 23 February 2010 to Friday 26 February 2010 |
March 2010 | |
Learning to Program in Perl / Perl Programming [Link] | Monday 1 March 2010 to Friday 5 March 2010 |
Learning to program in Perl / Perl Programming [Link] | Monday 1 March 2010 to Friday 5 March 2010 |
Learning to Program in Tcl [Link] | Sunday 7 March 2010 to Wednesday 10 March 2010 |
Perl for Larger Projects [Link] | Monday 8 March 2010 to Wednesday 10 March 2010 |
Tcl Programming [Link] | Monday 8 March 2010 to Wednesday 10 March 2010 |
The MySQL Relational database [Link] | Thursday 11 March 2010 and Friday 12 March 2010 |
Using Perl on the Web [Link] | Thursday 11 March 2010 and Friday 12 March 2010 |
Tcl - the Tk Toolkit [Link] | Thursday 11 March 2010 and Friday 12 March 2010 |
Regular Expressions [Link] | Friday 12 March 2010 |
The prices we will be charging in 2010 have not yet been fixed, but we charge only the price that was quoted when you book - so if we have to raise prices, that won't apply to 2009 bookers.
Course agendas may change slightly ... the technologies that we teach to develop over the years, and our courses are adjusted regulary to ensure they remain current.
Posted by gje at 05:46 PM | Comments (0)
Related topics: via article database
Python classes / courses - what version do we train on?
Usually, the release number of a programming language that's used on a 'first level' course doesn't make a big difference as the changes tend to be quite minor - after all, languages cannot change much for who would develop e piece of code using a syntax that was likely to go out of date? But that's not the case between Python 2 and Python 3, where there were / are distinct changes. For our courses, we're currently 'in transit'
As part of the introduction at the start of the course, I explain a little about the releases and listen to where the delegates are in the changeover. I then present the course as appropriate. Examples in Python 2 and Python 3 will both be available, and delegates will have the choice of which to use during practicals.
Why have we not switched every course to the latest version?
Changes are NOT so large that we need to run two courses.
There is a lot of existing Python 2 code to be maintained, so lots of people still need to know about that
It is recommended that you carry on coding in Python 2.6 until all your target systems have been upgraded, using the 2 to 3 converter each time you're installing on Python 3. So there's a lot of coding still going on using 2.6 syntax!
Our next Python courses:
Learning to program in Python - for those with no prior programming - starts 16th August 2009
Python Programming - for those with no prior programming - starts 17th August 2009
If you have missed those dates, click on the link to the course description pages and you'll see the forthcoming dates
Posted by gje at 03:31 PM | Comments (0)
Related topics: via article database
Useful link: Python training
Who is Marc Schneider of Multilingual Search Engine Optimization Inc
We give training courses in English. Do we really want to encourage enquiries that bring us sales leads for Lua, Ruby or Python courses that would have to be presented in Chinese, German, Spanish or Japanese? No, we don't - it is a dis-service to everyone concerned if we appear to offer something we cannot deliver.
So the unsolicited commercial emails that I receive from "Dr Marc Schneider" with monotonous regularity, suggesting that we use his services to promote our sites in non-English searches, are selling me a service that would actually be very bad for our business. Dr Schneider is correct in stating that we don't come out very well in non-English searches - he's very correct - that's by design!
It seems that we're not the only ones to be bugged by Dr Marc - he's bulk emailing, so he's (by my definition) a spammer. And when you read what others have written, you'll find there's more than meets the eye there. Bill Hartzer writes and Brian at "seonj" writes for example, as well as earlier comments I made.
I have placed samples of his emails here, here and here so that you can compare the text (and also to help people who are researching him via searches).
I find it very interesting too that his own sites have a very low ranking ... search for "Marc Schneider" and you get all sorts of other people who share his name - only when you add "spam" does he come up prominently. I wouldn't order a smart suit from a man dressed in rags, nor a high quality restaurant meal from someone eating pot noodles, so why on earth should I buy search engine placement from Marc Schneider of Multilingual Search Engine Optimization Inc - or is it March Schneider of optimization?
Posted by gje at 09:58 AM | Comments (0)
Related topics: via article database
July 09, 2009
Debugging multipage (session based) PHP applications
PHP's print_r function allows you to dump out the contents of a variable - and that includes more complex variables like arrays containing other arrays, objects, etc ... in a human (programmer!) readable form. By default, the output string is directly sent to the browser, but with a second parameter that's a true value, it is returned to you for further processing.
Here's an example of print_r's output being decorated to allow for special characters and to retain the spacing so that it can be displayed via the browser:
<?php print ("<pre>".htmlspecialchars(print_r($_SESSION,1))."</pre>"); ?>
And here is a sample of that running in our session demonstration:

(run the demonstration here with that extra trace line now added; you'll find that our wrapper is maintaining your session history too, but that's another story!)
This is a particularly useful facility to use if you're debugging a multipage application and want to see how the data is passed from one page to another.
Remember - if you alter the PHP script that's running a multipage application, you'll probably need to delete the session cookie too ... otherwise you will have changed the program but your testing would continue with the old data!
Posted by gje at 07:56 AM | Comments (0)
Related topics: via article database
Useful link: PHP training
July 08, 2009
PHP preg functions - examples and comparision
preg_match('%CheckUpdateTime(.*?)Main content end%s',$stuff,$gotten);
preg_match_all('%(<td class="destination">.*?)</tr>%s',$gotten[1],$service);
foreach ($service[1] as $train) {
$teapot = preg_split('%</td>%',$train);
foreach ($teapot as $element) {
$el = preg_replace('%\s+%',' ',trim(strip_tags($element)));
print "$el\n";
}
print "-----------\n";
}
For this week's course, I have been doing some quite complex data extraction in PHP ... and the example code above uses a number of the major PHP regular expression functions,
Firstly, PHP has an "ereg" family using POSIX regular expressions, and a "preg" family using Perl style. I have used the latter - a little harder to understand at first, but more powerful and stated to be quicker. You may as well take the bull by the horns if you're jumping in!
preg_match creates an array - the whole matched string in the first element, and parts that match bracketed sections of the regular expression in the second (number 1!) and subsequent elements.
preg_match_all works like preg_match but creates a whole array for each element. Slightly surprisingly, the first array within the array is all the full strings, the second array is all the fist matches, etc.
The return values from preg_match and preg_match_all are simply reports of success and not the matched parts, which are in the named array passed in as the third parameter.
preg_split throws away each occurrence of a matching string and returns, as an array, the unmatching string sections in between
preg_replace takes an incoming string and replaces all matches to a particular pattern with an alternative string.
See full source of the example above, which pulls back data from Transport for London and tells you about the next departures from your local tube station!
Posted by gje at 11:04 PM | Comments (0)
Related topics: via article database
Useful link: PHP training
July 07, 2009
Three recent questions on Tomcat Convertors
Can mod_proxy receive a request in one protocol and forward it in another?
mod_proxy (in httpd 2.2.x at least) is capable of protocol conversion - at least from http to ajp. https to http, and https to ajp should also work. mod_proxy_connect provides the capability of onward connection via https according to the manual. It is not a facility I have used personally, as the requirement for a secure connection between two local machines on the same subnet is not common when compared to external secure connections. See:
http://httpd.apache.org/docs/2.2/mod/mod_proxy.html
What is ajp 1.4 protocol?
I have taken a look at "ajp 1.4 protocol". The commonly used protocol / current standard is 1.3, but there are a (very few references around to 1.4. As an educated guess, the 1.4 proposal which included some sort of negotiated content system, was dropped.
The Tomcat project page includes details of the ajp 1.3 protocol:
http://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html
but there are no similar pages for ajp 1.4 - see:
http://tomcat.apache.org/connectors-doc/
What is the "accept count" on a connector, what is its default value, and what should I set it to?
According to the documentation, the default acceptcount (the number of connections that can be help waiting in a queue) is 10. Usual recommendation is that the acceptCount be set to the same value as the maximum connections to allow for there to be one connection waiting for each one being processed, although with the throttling at the httpd rather than the tomcat level in most installations, this could be a moot point.
Posted by gje at 08:36 AM | Comments (0)
Related topics: via article database
Monitoring and loading tools for testing Apache Tomcat
The following monitoring and loading tools can be used to test Apache Tomcat and are all Open Source. This comparative summary includes a link to more details of each of these resources.
ab - ApacheBench. Part of the standard Apache httpd download - a good but basic soak test where you can see how your servers respond to traffic of a particular type from a single source. Good for looking at 'denial of service' type attacks; too basic for typical loading tests.
Example run from command line
ab -n 2000 -c 30 http://192.168.200.215:8080/whm_course/demo.jsp
That's calling for a page to be loaded 2,000 times - with a concurrency of 30 (in other words for there to be 30 connections all at the same time, simulating visits from 30 different places.
jmeter. Open source, part of Apache jakarka. You set up a number (minimum one) of testing machines to generate traffic to the server. You then run a GUI tool on one of the testing machines to gather in the results and process them - into graphic, text report or log forms.
Jmeter allow much more realistic traffic simulation than ab, but is much more complex to set up - people struggle at their first use. We have a sample first demonstration on our web site at:
http://www.wellho.net/mouth/2082_Jmeter-a-first-test-case.html
jconsole. A way of looking inside the jvm and seeing resource use, splitting the heap down to the various generations if need be. Unlike jmeter and ab, this is not a load tester - it adds no load; rather it is a tool for examining a running system.
Example:
http://www.wellho.net/mouth/2080_Using-ApacheBench-and-jconsole-to-test-and-monitor-Tomcat.html
Tomcat Manager. By providing a "manager" role in Tomcat, you can enable the manager, allowing the control of individual web applications (stop, start, etc) rather than having to stop and start all web applications on the same tomcat instance at the same time.
Sample file:
http://www.wellho.net/resources/ex.php4?item=a652/tomcat-users.course.xml
It is also possible to control the logins to the manager using accounts held in databases - there is a sample in the shipped server.xml file.
The Tomcat Manager is listed in this section because it also provides management information with regards to the internal operations of Tomcat and the jvm.
Posted by gje at 08:30 AM | Comments (0)
Related topics: via article database
July 06, 2009
Dogs Trust, Dog Show, Newbury





We were invited back to the dog show open day at The Dog's Trust near Newbury, from where we adopted Gypsy a few months ago. Yes - I know the real reason to invite everyone back was for them to make money, but it was never the less a good day's outing. I suppose I should have expected a lot of dogs at a Dog show!
Gypsy won none of the formal prizes - but it's the taking part that's important. She did win the heart of the owner of Fudge the Staffie, who would have taken her home given half a chance (we refused a swap ;-) ), and she was clearly remembered - very affectionately - by the staff who were there; good to have them coming over and saying "hello" to her amongst all the canines.
Lisa has just Skyped me to let me know that Gypsy is in the doghouse for chewing a book of invoices ... but overall, she's settled in very well. Charlie [cat] is accepting her more and more, and although I wouldn't yet say "friendship" Charlie is getting more tolerant. Lisa and I are getting used to pushing a dog out of the way when we want to settle down, or lifting one off the bed.
Were you expecting a technical blog - oops - they have been a bit thin for the last few days. Tomorrow?
Posted by gje at 06:10 PM | Comments (0)
Related topics: via article database
July 05, 2009
Wiltshire - a chance to improve life for everybody
Lisa and I were discussing the way that democracy has been effected by the Internet ... on one hand, more access to data, and on the other hand more professional control by the 'powers that be' - unelected / appointed officers who see this extra data access as (frankly) a bit of a nuisance. Some take the attitude that they know best, and that members of the public don't know what they're talking about and call for impractical things to be done. Which is a great shame, because some members of the public do have innovative ideas and suggestions which can and could be helpful.
On a few occasions, I've attended or submitted inputs to consultations where I have felt that my inputs (and the inputs of all the other people who have put thought into what they would say, and spent time and money saying it) provide the consultation runners with the ability to tick a box that says "we are democratic - we have consulted". Would it be possible that I have an unduly cynical view and public input really is considered? I would hope so, but I don't see how the public has any substantive input when the "consultation" is done after decisions are made and there are just a few tiny things that could be changed (Wiltshire budget meetings!), nor how the public's view is truely canvassed when they are asked to make a multiple choice selection from a limited set of options - so limited that the only options on offer are those which suit the canvasser's paymaster. I can recall a travel and transport meeting in Trowbridge where the audience was split into table groups and half the groups (mine included) refused to place an order of importance to the options given, on the grounds that important alternatives had been ignored.
So it has been a great pleasure already this year to see several decisions made which take the public (consultation) views into account. I refer to the decision to give permission for Asda to build a new supermarket in Melksham - something which I believe has much more in favour of it than against, and to the decision to refuse permission of the Westbury Eastern Bypass, where I have great sympathy with the people of Westbury who live alongside the current road, but also extreme disquiet that the solution offered would have been expensive and limited in its effects - some of which would have been to encourage congestion elsewhere.
With the change from a County Council to a Unitary Council, we saw little immediate change save for replacement of 99% of the signs (even though I could swear that I remember an FAQ Answer that said they new authority would not spend a lot of money on an immediate re-branding!) and that was potentially because it was the same old faces in the same old roles through April and May and into June. But now there is an opportunity - and this is an opportunity that was "sold" to us by the people who suggested Unitary - to move forward with a system fit for the next 30 years, rather than one that was good for the 1970s and 1980s.
Here is the old logo, and motto / sound bite:


(I had some trouble finding one of these that hadn't been replaced, and it seems that the new motto / sound bite has been so heavily sold that most people have already forgotten the old one)
And here is the new one:

I would like to thank the team that has put in so much effort for Wiltshire in the past, and also to welcome the newcomers to the team who have a golden opportunity to go forward with both the old and the new motto's in their work. I sincerely hope that they will be Improving life in Wiltshire and remember that Wiltshire is a place Where everybody Matters ... and that includes the rich and the poor, the businesses and the individuals, the healthy and the sick, the urban (the majority of the population of the county now lives in towns with a population of 8000 or more) and the rural, the private transport user and the transport user who cannot (or does not wish) to use private transport, the local voter, the youngsters, the tourists, and the people who work in the county but live outside.
Posted by gje at 09:16 AM | Comments (0)
Related topics: via article database
Sipping at York
I took so many pictures that capture York last week, and I want to share them. But - let's face it - readers who randomly come across a web page because they're searching for a resource want to sip rather than guzzle these personal snaps. So here are a random three:



And if you want a little more than a sip, refresh the page or visit it again at so
me other time. There are ten possible images in each position.
Want to know how we do this? It's on our ull.html>PHP Techniques Workshop.
Update - see here for all of the pictures in the slide show, briefly labelled.
Posted by gje at 07:28 AM | Comments (0)
Related topics: via article database
July 04, 2009
Westbury Bypass Refused - looking forward
The report of The Public Enquiry into the proposed Westbury Bypass was published a couple of days ago, together with the Secretary of State's decision based on that report. As someone who attended the enquiry briefly and made a statement, I have received a copy of the various papers from the Department for Transport, and from the Department for Communities and Local Government.
In summary, the enquiry recommended that the planning application by Wiltshire (County) Council be refused, and the Secretary of state agreed with that recommendation. Formally "He hereby refuses planning permission for the construction of a new single carriageway road with a climbing lane over part of the route, roundabout junctions, associated infrastructure and works in accordance with application number W.07.09002 dated 14th February 2007."
The covering letters and reports are in two sections - those relating to the Department for Transport and those relating to the Department for communities and local government. They are online:
Transport:
letter - http://www.gos.gov.uk/nestore/docs/transport/laos/westbury_ltr.pdf
report - http://www.gos.gov.uk/nestore/docs/transport/laos/westbury_report.pdf
Local Government:
letter - http://www.communities.gov.uk/documents/planning-callins/pdf/1271537
report - http://www.communities.gov.uk/documents/planning-callins/pdf/westburybypassreport.pdf
Public Enquiries such as this have tended to come down on the side of the official authorities who propose them in the past; such authorities have the full time team to present an excellent, logical case, the access to expertise, and access to taxpayer's money to fund the presentation of the case. They are the Goliaths at such enquiries. Organisations who oppose do not have access to the official funding, and are very much on their back foot through the procedure as they have to be reactive rather than pro-active, prepared for any "curved ball" which the proposing authority throws at them, and within their own funding. They are the Davids.
So the result is a bit of a surprise ... I'm not sure what proportion of such enquires recommend a rejection of major proposals into which so much time and public money has gone (millions of pounds that could have bought a train service for many years) ... but it's certainly something of a surprise. It is important to study the reasons given (summary), but it is doubly important now to look forward, and say what can and should we be doing for transport flows in this corridor, now with the changed metrics brought about by the refusal.
Local (i.e. council tax payer's) funding of the rejected bypass would have accounted for some 10% of the scheme's cost. We may now have a golden opportunity to look at how that money saved can be used, never the less, to meet the objectives of improved journey times through Wiltshire by both private and public transport, and reduced traffic levels through Westbury and elsewhere resulting in an improved environments there.
One such scheme is an appropriate passenger train service on the parallel railway - see here; that should be enhanced by better integration of different transport modes, which can be done at very little cost (and in some cases cost saving) ... encouraging people to use public transport where they can with a carrot rather than with a stick, in so doing reducing the number of vehicles using the current road network, leaving it clearer for those journeys for which there is no sensible alternative than private motor vehicles.
Posted by gje at 10:48 AM | Comments (0)
Related topics: via article database
July 03, 2009
winmail.dat enclosure ... reading on an Apple
I use an Apple Mac ... run OSX ... and I have that problem of how to deal with applications data files. I have become a passed master at Word documents and Excel spread sheets! How about an attached file winmail.dat?
winmail.dat is used by thing like Microsoft Outlook ... so you can easily read it if you have Microsoft Outlook too. But I haven't.
Solution? TNEF's Enough from http://www.joshjacob.com/macdev/tnef/.
Drag and drop (sorry - this is a Mac world solution!) your winmail.dat file onto the application, and it'll be revealed to be a container like a tar or zip of stuffit file with loads of other files held in it. Click on the one you want (sorry - this is a Mac solution!) and you can get at that individual component.
Posted by gje at 06:47 PM | Comments (0)
Related topics: via article database
July 02, 2009
Travelling












Six trains ... a bus ... four walks ... and a day's work too. Still - as you can see from above, a wide variety of places!
Posted by gje at 10:44 PM | Comments (0)
Related topics: via article database
July 01, 2009
A chance to do the tourist thing
Just occasionally, work takes me to exactly the right place at exactly the right time ... and so it was this evening when after a good day's work I had a chance to let my hair down, join the leisure visitors, and have a look around York ... with some lovely lighting effects

Point of arrival in York

River

Maltings Pub

City Centre

Geese

Wall

Minster

A Pie and Pint to finish the day
Posted by gje at 09:36 PM | Comments (0)
Related topics: via article database