« September 2009 | Main | November 2009 »

October 31, 2009

Santa Special - Trowbridge and Melksham to Swindon

Santa Claus will be on the "TransWilts" train from Trowbridge and Melksham to Swindon on Sunday, 6th December, organized by the Melksham Railway Development Group. Santa's been a regular visitor to the line in early December for a number of years, but this year he's extending his ride to start from Trowbridge and carry on back to there afterwards.

Tickets are for sale at both Trowbridge and Melksham Tourist Information Centres ... and numbers are limited as Santa wants to have plenty of time to talk to each young person. And our heartfelt thanks to First Great Western for arranging to strengthen the train that day (that means "making it longer" and not having a more robust floor!)

Trip details are in the poster that illustrated this article, and you can download a copy of the poster for printing too if you wish from here.


The details ...

Santa Train Christmas trip to Swindon by train to meet Santa Claus on Sunday 6th December 2009.

The Melksham Railway Development Group have arranged a trip for you to meet him on the train! Join them at Trowbridge Station for the 17:10 train and arrive back there at 19:10, or join them at Melksham station for the 17:20 train and arrive back there at 19:00.

The train travel to Swindon and back ... a 35 minute journey from Trowbridge / 25 minutes from Melksham, with a stop of about 40 minutes in Swindon, where you may remain on the train. Santa will be handing out presents to all the children, his helpers giving minced pies to the adults and there will be a beverage for everyone.

Adults - £9 (from Trowbridge) or £7 (from Melksham). Children 15 and under - £3 (from either).

The prices include travel, present and refreshment and tickets are ONLY available from the Tourist Information Centers in Melksham and Trowbridge.

Contacts - Sion Bretton (01225 700740) and Graham Ellis (01225 708225)

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


Related topics: via article database
More about Graham Ellis of Well House Consultants

How do I set up a constant in Python?

You may think of values like pi being a constant, but in Python they're really just another object that's defined in the namespace of the module from which they're loaded!

So ...

>>> import math
>>> math.pi
3.1415926535897931
>>> math.pi *= 4
>>> math.pi
12.566370614359172

You are fully entitled to think that what I have just done as an illustration would be dreadful in a real program - and I would agree with you 110%. I've done it to show you that in Python you do not have constants, you have variables that you are strongly advised not to change. You'll find that exacly the same behaviour happens with variables that look like python constants because they are capitalised:

>>> import re
>>> re.IGNORECASE
2
>>> re.IGNORECASE+=4
>>> re.IGNORECASE
6
>>>

Why does Python behave this way? Because it's a trusting language that's written for programmers who think a bit about what they're doing and don't overstape the mark with 'sillies'. This approach allows for a slimmer, sleaker language that is coded and operationally faster, without the need to have private, public, protected, final, abstract and interface keywords. These are all keywords which are around in languages like Java (mandatory) and recent PHP (optional in use) and when you think about it they're just policemen, there to enforce rules. But don't most of us stick to the rules most of the time anyhow, once we understand that they're good for us! A really clever thing about Python is the way the language was designed to encourage us to write good code without the need for policemen like P.C. John Private, Sergant Tom Protected and Inspector Bill Public; the languages's block inset system though you may hate it at first does lead to code that in naturally inset, and the language's structures of working on lists ensure that they are never going to be sparse (you should use a dictionary).

It's actually a very good idea in any programming language to set up a file of globals or constants for you application. Here's a Python example - let's see how we might use it first:

>>> from constant import *
>>> print "This page " + whc.COPYRIGHT
This page Copyright Well House Consultants Ltd, 2009
>>>

And what might it contain?

>>> dir (whc)
['COMPANY', 'COPYRIGHT', 'FREEPHONE', 'PHONE', 'VAT', '__doc__', '__module__']
>>>

And of course it contains a self-documenting test harness:

Dorothy-2:~ grahamellis$ python constant.py
COMPANY : Well House Consultants Ltd
COPYRIGHT : Copyright Well House Consultants Ltd, 2009
FREEPHONE : 0800 043 8225
PHONE : 01225 708225
VAT : 15
__doc__ : A file of values to be used as globals or constants
throughout our company's Python programs. By using this
file, you are able to change the VAT rate (which is 15%
as I write this in late 2009, but goes up to 17.5% on
the 1st January 2010 in ONE PLACE only
__module__ : __main__

The source code for our constant module may be found here

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


Related topics: via article database

Useful link: Python training

October 30, 2009

Finding text and what surrounds it - contextual grep

grep is a very useful tool for finding all the lines in a file (or series of files) that contain a particular string or match some other pattern / criteria. For example, I have a file that contains data for 52 staff members and I want to find who knows Lua ...

[trainee@melksham Download]$ grep Lua requests.xyz
lisa PHP Python Lua ASP Perl Java
graham Lua Perl Tcl/Tk
[trainee@melksham Download]$

But what if I want to see the context of my matches - to be given back not only the matched lines, but a few lines before and after the match to see what it relates too - "other nearby employees" in my example, but more commonly "the rest of the paragraph / example" in the case of text files. On Linux's grep, you can use the -A and -B options to specify the number of lines to display before and after each match, and the -C option if you want to show the same number before and after. Let's see that:

[trainee@melksham Download]$ grep -A2 -B1 Lua requests.xyz
kerry Perl Tcl/Tk Ruby MySQL
lisa PHP Python Lua ASP Perl Java
margaret XML Perl Ruby MySQL Tcl/Tk
nina Tcl/Tk Perl ASP Ruby
--
fred MySQL Perl Java XML
graham Lua Perl Tcl/Tk
harry PHP Python Java
ivan Ruby Java Perl Tcl/Tk MySQL
[trainee@melksham Download]$ grep -C3 Lua requests.xyz
iris Perl MySQL Java Tcl/Tk
jenny XML Perl Ruby ASP
kerry Perl Tcl/Tk Ruby MySQL
lisa PHP Python Lua ASP Perl Java
margaret XML Perl Ruby MySQL Tcl/Tk
nina Tcl/Tk Perl ASP Ruby
olivia MySQL Python ASP PHP
--
david Perl Tcl/Tk Java
ed Ruby Perl Java PHP
fred MySQL Perl Java XML
graham Lua Perl Tcl/Tk
harry PHP Python Java
ivan Ruby Java Perl Tcl/Tk MySQL
john PHP XML Java Perl
[trainee@melksham Download]$

If you're on a system that's got a version of grep that doesn't support these options, what can you do? Well - you could do worse that write a Perl script - in fact we've used the requirement for a contextual grep for an example on our Perl Programming course.

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


Related topics: via article database

Clustering on Tomcat

Subject: Clustering, using Apache http server (version 2.2.14 in my example) with mod_proxy_balancer as the front load splitter and Apache Tomcat 6.0.20 as the replicated application engine. [[Tip should also work for other recent 2.2.x and 6.0.x versions]]

Background

This is a follow on article from Load balancing with sticky sessions (httpd / Tomcat), where I looked at sharing out the application work between a number instances of Tomcat from an Apache http server (httpd) that did the bookkeeping. In a nutshell, the Apache http server sent new arrivals to a 'random' Tomcat, and then used sticky sessions so that - when a visitor came back for their subsequent visit in the same series of accesses - they would always talk to the same Tomcat and could continue their conversation with the server having full knowledge of the position to date.

The balancer alone is a good solution as far as it goes but:
• What happens if the Tomcat that has been stuck to goes out of service?
• What happens if you have such a lot of traffic that you need to replicate your httpd front end?
• What happens if your httpd fails?
• What is you don't actually want to use sessions, but still need what appears to be a single Tomcat?

One possible option to addressing some of these is to use the clustering capability of Tomcat, which I'll describe below. But you should first consider if you really need the extra step:
(a) can I accept that a session will be lost on the rare occasions that a Tomcat goes offline?
(b) is writing to a backend database going to preserve sufficient information anyway?
and if the answer to either is "yes", you probably do NOT need to cluster.

How does clustering work?

You run your web application on a series of identical (or rather "near identical" - the IP address will differ!) servers. With clustering turned on, each of the servers in the cluster is broadcasting (via multicast) any changes made in sessions, cookies, etc to any other listening cluster members on that same multicast address. So that when a visitor comes back for his / her next access, all the machines know what's been going on and can knowledgeably handle the request, even if the original machine isn't available.

You can turn clustering on in Apache Tomcat 6.0.20 simply by uncommenting the line in the default server.xml file that relates to it:
  <Cluster className = "org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
and restating your Tomcat. Older versions of Tomcat (such as 5.5) had a long configuration section listing the ports, replication time, IP addresses to use, trigger files all of which are important but none of which actually needs to be changed from default in the current release that's the target of this article.

Once you have turned clustering on (yes, it's now that simple), your machines will be communicating ... it's rather like starting a rumor in an office - before you know it, EVERYONE who's around has heard the rumor.

Clustering with the balancer

If you have already implemented balancing with sticky sessions (as covered in the preceeding article), turning on clustering will cause the data to be shared around. Most of the time the data passed around will not be used - it will ONLY form a backup of the session, to be used if the balancer is unable to reach the sticky machine because it has done down or been taken out of service.

With sticky sessions activated, even a second front-end Apache http server won't cause a switch from one Tomcat to another unless a fail-over occurs, as the jvmroute is a part of the cookie so either (any) of the httpd front ends will correctly forward to the original Tomcat. And if you have an intelligent hardware load balancer, that too will be able to forward consistently and the the clustering will remain merely as a backup.

If you disable sticky sessions on your balancer, the metrics will change. Forwarding will now be at shared to each of the Tomcats in the balanced group / cluster group (take care that all members of the balance group are included in the cluster!) and so the visitor will get to a differnt back end box each time. But that's now perfectly fine, as they're sharing the data between them so will all know about the originator.

Testing if your cluster is working

Ironically, clustering and balancing is designed to be transparent, so how do you test whether it's working?

My first simple 'trick' is to change the background colour of the pages returned from each cluster member so that "if it's orange it must be Holt" and "if it's blue it must be Chippenham" (our servers are names after local towns and villages!). Going a little further, you can edit your servlet / JSP to return the name of the current host. In Java, the following line:
  String myname = InetAddress.getLocalHost().getHostName();
will return you the local name of your computer, so that you can then echo the name.

On last Tuesday's course, I took our sample "Barman" script that remembers how many drinks you've had in a session (visit counter!) and extended it into a "Pub Watch" script, where each of the barman communicates with his colleagues in neighboring pubs to keep track of who's out on the town, and how much they have had to drink in each establishment.

If you click on the links in the previous paragraph, you can download the source code for "Barman" and "PubWatch" and try the code out for yourself. Using the balancer manage that I introduced at the end of yesterday's article, you can open and close individual pubs and see how their customers go elsewhere for their next drink, and you can turn sticky sessions off in the balancer and see how faithful customers will then hit the road and go to a different pub each time for their next drink.

Some notes on clustering

1. The machines in the cluster communicate through multicast, so must be on the same subnet.

2. It's a good idea for the subnet you use to have plenty of capacity if your environment is busy, and for it to be firmly behind a strong firewall from your own company's general user traffic, let alone the Internet

3. If you have multiple Tomcat clusters on the same subnet, you'll need to configure one of the clusters away from the default settings - otherwise they'll end up as being one big cluster (you'll find the word 'tribe' creaping in here!)

At present, we mention clustering on our public deploying apache httpd and Tomcat course. Only a small proportion of our delegate want to go 'that far', and for newcomers who hadn't done any web server work when they first came along a couple of days earlier, it would be just too much for the one session.

An extra day on the end of a Tomcat course, coverage in a private course, or a special session set up for the purpose ... all are possible to help you learn how clustering and balancing work. We'll have a network of computers set aside at our training centre for the purpose of setting up a test case, experimenting with configurations, seeing what happens when machines are switched on and off. Something you wouldn't dare so with your own production environment, and might be reluctant to do even on your development of test networks (that's even assuming that you do HAVE multiple machines at the development or test level).

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


Related topics: via article database

October 29, 2009

Load balancing with sticky sessions (httpd / Tomcat)

Subject: Load balancing with sticky sessions, using Apache http server (version 2.2.14 in my example) with mod_proxy_balancer as the front end balancer and Apache Tomcat 6.0.20 as the application engine. [[Tip should also work for other recent 2.2.x and 6.0.x versions]]

Background

When you have too many big requests for one Tomcat server to look after the compute for all of them, you can set up an Apache http server ("Apache httpd") to act as a switchboard for all incoming requests, farming them on to a whole series of Tomcats to do the real work. It's rather like having a receptionist at the hotel - we only have one on duty, but he / she has plenty of capacity to check the customers in, and deal with any follow up inquiries during their stay. The receptionist leaves them to get on in their rooms with watching the large TVs, having a relaxing shower, working, sleeping ... and wouldn't dream of actually doing those other things with them, nor would he/she have the time to do so.

When a new customer checks in, a 'random' available room can be allocated from the appropriate pool. But when follow up requests are made by a customer, they have to be applied to the right room. Jo Smith in room 210 will love a knock on his door at 05:00 to tell him that the taxi for Melinda and Robert Brown in room 218 has arrived! And so it is with httpd - initial requests can be passed to any appropriate system, but then follow up requests which are part of the same sequence must be forwarded to the same machine (((Possible exception - clustering - see following article))).

Using mod_proxy_balancer without maintaining state

Here's an example where requests to the url
  http://www.melkshamhotel.co.uk/manor/
will be passed on to a balancer called "robin", which will share out the traffic between two machines on its local subnet, running the web application there that's called "latmjdemo". If neither of these machines has a running Tomcat on it, then a third machine has been set up as a hot standby to take the traffic.

ProxyPass /manor/ balancer://robin/
# Two servers, sharing traffic (2 to 1 ratio)
# Third server is only used when neither of the others is available
<Proxy balancer://robin>
BalancerMember http://192.168.200.218:8880/latmjdemo loadfactor=10
BalancerMember http://192.168.200.210:8880/latmjdemo loadfactor=5
BalancerMember http://192.168.200.219:8880/latmjdemo status=+H
</Proxy>

That code works well, except that "state is not maintained". In hotel terms, our receptionist will provide it to a random room when asked for a follow up service. The scheme works well for 'single shot' requests, but fails where there's a whole series of pages involved such as in an online ordering system, where cookies will be involve. We need to tell our receptionist that a request isn't a new one - it's for the folks in room 218!

Maintaining state with mod_proxy_balancer

Your Java Servlet application that's running on Tomcat will almost certainly be using the built in session handling capacities within the code - we have examples here and here. Such applications will serve a cookie - in hotel terms, a room card - which the customer presents to the receptionist at each subsequent service request.

Then:

a) Each individual Tomcat needs to have a unique "jvmroute" set - there will be a line in the server.xml file that needs to be configure along the lines of:

<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm6">

b) The mod_proxy_balancer needs to be told which cookie is the one that's used for the sticky session, and which jvmroute has been used on which server in the balanced group. Here's a configuration sample:

ProxyPass /manor/ balancer://rednose/ stickysession=JSESSIONID|jsessionid
# Ensure that cookies get rewritten on their way back
ProxyPassReverseCookiePath /latmjdemo /manor
<Proxy balancer://rednose>
BalancerMember http://192.168.200.218:8880/latmjdemo/servlet loadfactor=10 route=jvm6
BalancerMember http://192.168.200.210:8880/latmjdemo/servlet loadfactor=10 route=jvm7
BalancerMember http://192.168.200.219:8880/latmjdemo/servlet loadfactor=10 route=jvm8
</Proxy>

These are working, tested examples. The Apache httpd mod_proxy_balancer manual is somewhat unclear with regard to the need for the route to be set (at both Tomcat and in the balancer) and indeed it could be (mis)read to imply that it isn't necessary to set the route - as id it has some large table of all the sessionids so that it knows which to forward to where. If you try to run balanced sticky sessions without the route, you'll fail - you'll be passed to what appears to be a random Tomcat each time, even if you have "stickysession" set in your ProxyPass.

Other Notes

1. With PHP, your session cookie does NOT by default include a "jvmroute" and you'll need to find a mechanism to add one. Mark Round has blogged about this here - a story that's beyond this Java based post, but we can help delegates work this out on our LAMP deployment course or on a one on one day if you already know the rest of the LAMP stuff!

2. You should ensure that you have code in your proxy configuration that prevents you being used as an open proxy ...

3. Under normal circumstances, sticky sessions are very hard indeed to test as you're looking to get virtually identical resources from each machine in the group. We have a test servlet here which reports on the server being hit by name, to help in debugging / tracking your session. (This same example will be used in my follow up article on clustering)

4. The balancer manager (part of mod_proxy_balancer) is a further useful monitoring tool. Turn it on as follows in the httpd configuration:

<Location /watch>
SetHandler balancer-manager
Order Deny,Allow
Deny from all
Allow from 192.168.200.
<Location>

5. There is a file containing various proxy configuration examples here, which we pulled in to our main httpd.conf via an include. You'll need to choose the bits you want - there are various conflicting proxies in there that will default to issuing warnings.

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


Related topics: via article database

Sample code with errors in it on our web site

Feedback is lifeblood ... ignore it at your peril, and remember that for each person who lets you know you have a problem, a further ten will have noticed and not said anything. From my mailbox:

> Your webpage
>
> http://www.wellho.net/resources/ex.php4?item=y105/locvar.py
>
> contains the following code ...
>
> [snip]
>
> which is erroneous.

I totally agree. It does generate an error in the last line. Why?

The immediate answer is that variables used within defined functions / methods in Python are local to those functions, and unless returned or declared global are NOT available outside in the calling code. When you think about it for a minute of two, this is an excellent default behavior as it means that you don't clutter up your main variable name space with internal names from other piece of code you have packaged into self-contained units. If your language uses "default global" which means that variables are shared unless you declare otherwise, you can end up with the most enormous problems when you come to build an application using code blocks (functions / methods / objects) from several sources and they have a variable name conflict. Perl's use strict pragma is an example of a language that is "default global" but has an addition to let you circumvent the problems it causes.

There is a second very different answer too if you are asking why we have erroneous code on our site. Many of the examples on the site come from our training courses, and were initially uploaded as a service to our delegates - so that they could try out the code after the course without the need to retype it. Some of the examples intentionally show the sort of things that generate error messages, and the notes for the course go through the "why" and "wherefore" of that - indeed, on of the most important things you learn on a programming course is how to 'read' the error messages - interpreting what they mean - so of necessity there will be failing examples in the notes, thus on our site.

Jxx's feedback is doubly useful - it alerted me to the fact that a page put up for a very good reason has now become much more visible, and that the explanation that was offered further on in the page:
>>> Remember that some of our examples show you how not to do things - check in your notes.
was far too well buried, and generic.

Rather than change an example which is there for good cause, and forms part of our Python Programming and learning to program in Python courses, I have added some comments to say that it shows how an error is generated, and why. Always good to comment your code ;-) and hopefully much clearer now. It will, though, need to be revised further in the near future to take accocunt of Python 3 ;-)

Jxx continued:

> I'm not trying to be a smart-ass since python is certainly not
> my best language but you really shouldn't have erroneous code
> advertising your expertise.

Totally agree (with the conclusion - he probably knows a lot more Python that he lets on!) - and "Thank you" letter sent. The page, if you would care to click here still illustrates the error, but now clearly explains why the code doesn't work. Which is what you want to learn on a training course.

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


Related topics: via article database

October 28, 2009

Pantomimes around Melksham - 2009/2010 season

There's a lot happening in Melksham and the surrounding area - have a look at the diary of events. Picture - Andy Pandy and Goldilocks make a couple at the end of last year's Melksham Comedy Club panto [report]

This year' pantomime season ...

Footlights present Aladdin at the Arc Theatre, Trowbridge, from 12th to 15th November. Adults £6.95, Concessions £5.95. [details]

The Whitley Players will be presenting The Snow Queen at the Whitley Reading Rooms, Middle Lane, Whitley on November 19 & 20 at 19:30 and November 21 at 14:30 and 19:30. Tickets from Smiths Stores, Top Lane, Whitley or via 01225 707106. Price £6 (£4 concessions). The Whitley Players' web site is here.

Egg present Around the World in 80 days at the Theater Royal, Bath, from 17th December to 16th January inclusive. [details]

The Trowbridge Players present Robin Hood And The Babes In The Wood at the Arc Theater, Trowbridge from Thursday, 14th January 2010 to Saturday, 23rd January 2010. Tickets are £8 (£6 concessions) - see here for booking details.

The Melksham Comedy Club presents Puss in Boots at the Melksham Assembly Hall from Wed 3rd February 2010 to Saturday 6th February 2010. See full details on their web site.

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


Related topics: via article database

October 27, 2009

Accidentally typed ci rather than vi?

You're using the Linux command line interface, you get distracted, and you type in ci. Oops - before you know it, you've lost your file ... at least it has disappeared from where you expected it to be:

[root@holt conf]# ci server.xml
server.xml,v <-- server.xml
enter description, terminated with single '.' or end of file:
NOTE: This is NOT the log message!
>>
initial revision: 1.1
done
[root@holt conf]#

What's happened IS recoverable. You have "Checked In" your file to the source code control system (have you come across SCCS and RCS?), and there's now a version controlled system with ,v on the end of the filename that has replaced your original.

To recover a copy of the original, you can "Check Out" your file with the co command:

[root@holt conf]# co server.xml
server.xml,v --> server.xml
revision 1.1
done
[root@holt conf]#

You may need to check the permissions on the file, and if you have specific line formats that are taken as revision control headers, they may have been updated but ... you have not lost your file!

RCS, SCCS, SubVersion, CVS and others are all revision control systems which allow you to keep numerous versions of a file, and to go back to old versions too. Checking out a file for edit allows it to be locked so that in a multi-developer environment, you have a mechanism available that avoid two people editing the same file at the same time ... with the edits of one being over-ridden by the other.

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


Related topics: via article database

October 26, 2009

How did I do THAT?

I had great fun putting together yesterday's blog about My train journey from Melksham, with a whole lot of images in the text rather than real words.

For my first tests, the images sat on the line like this: which starts to look really ugly once you 've added more that a couple of pictures - so I have fine tuned my "img" tags, adding in both align="middle" and "vspace=2" (and, yes, I know ... deprectation warning - should have used style!). I then added alt="what it is text" to provide a backdrop of desciptive text whould people use various browser facilities to read me properly.

But then I also wanted to provide me with a "just show me the friging text" option, so I wrapped my images in PHP tags:
< imagestart("tiny_bristol") ?>Bristol< imageend() ?>
and provided thos extra functions imagestart and imageend:

<?php function imagestart($wot) {
  return (($_REQUEST[txt]=="")?
  "<img src=http://www.wellho.net/pix/$wot.jpg align=middle vspace=2 alt=\""
  :"") ; }
function imageend() {
  return (($_REQUEST[txt]=="")?
  "\">"
  :""); } ?>

i
Notes

1. The reason to use functions should be glaringly obvious - it saves the need to keep repeating a messy piece of code. Write it once, debug it once, and have it used consistently. But why two functions? Ah - that's because I want to keep my ALT text outside the tags so that if I run the PHP function stripslashes on the text, I am left with the keywords correctly. That way, I can help blog feeds and our own other scripts which re-use the blog text or search through it such as this one to index / report the page properly too.

2. The $_REQUEST[txt] control is the quasi-form element that I am using to control whether the text is show in picture or text form. It's defaulting to pictures, but links on via
<a href="?txt=x">[here]</a>
to the plain text version and back via
<a href="?txt=">[here]</a>
to the version with pictures again.

3. In order to keep PHP code in my Movable Type (Moveabletype) database, I added code that uses functions such as ob_get_contents to my templates, and I've also ensured that .html URLs are parsed by the PHP interpretter. For details, see here and here

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


Related topics: via article database

October 25, 2009

By train ...

Want to see this in plain text? Click [here]

It can be done ...

I was invited to a meeting at The Sugar Loaf yesterday evening - that's a pub in St Mark's Road, Easton, Bristol - a couple of miles out from the City Centre. And I thought I might like to have a pint or two there, so driving was out, quite apart from the fact that I was meeting up with some rail campaigners and - well - you have to make the right impression, don't you!

But I live in Melksham, where the joke is that you look up a calendar to see when a train is running, rather than a timetable, as trains calling at the  station are so rare. However, I was in luck and so I walked from my street through the town centre to the station ... to catch my train at 14:55. It turns out that a calendar was a good idea, as the Saturday afternoon train usually runs 20 minutes later and had I missed it, the next one would have been 27 hours later.

The train was on time ... very comfortable, plenty of space. The conductress sold me my ticket and we chatted, and before we knew it we were in Chippenham where I left the train on its way to Swindon, and connected into the express for Bristol. Again, train on time, good seating and a chance to both relax and travel at the same time (I do feel it's so much better to arrive refreshed after a journey than to be all tense from fighting the traffic!). Bath came and went, and the final stop was Bristol Temple Meads.

Fifteen platforms. FIFTEEN! Where is the next train to Stapleton Road? Just leaving from the far side of the station ... as I lookup up timetables in the subway, I heard a diesel train's engines roar and, sure, that was it. But it turns our there's another one in 18 minutes, so I get onto the Avonmouth train and with a load of other we let the clock tick to just past four when we head out ... and a really quick run out to Stapleton Road, from where this train branches off onto the single track to Clifton Down, then on to Avonmouth.

OK - now here's an admission. I'm not used to stations with 4 different entrances to although the Sugar Loaf is very close to the station, it took me a while to find it. Rather longer than the part of my journey from Melksham to Chippenham actually.

You can view this report with text or pictures!


What was I doing in Bristol? I was meeting up with the "Friends of Bristol Suburban Railways", who have campaigned for a number of years for improved services on the Severn Beach line, for re-opening of freight lines such as the one to Portishead, to Thornbury, and the one from Filton to Avonmouth to passengers, and for new stations at places like Horfield, Saltford and Long Ashton. They've been part of some notable successes too - such as the major improvements that have happened on the line that serves Clifton Down, Avonmouth and Severn Beach ... with major service improvements. But things aren't static. In an effort to get even more trains on the limited line space from Bristol 'up North', there are threats of cutbacks on the "Severn Beach" line, and various suggestions too about cutting back the end of the branch. That would be a retrograde step - although the trains aren't exactly "nesting" - 'Nearly Every Seat Taken' at that far end, they contribute traffic to the inner section where they do "nest", and it's a question of making sure that the bean counters understand and don't do anything stupid.

I look at the steps taken in Bristol, on the Newquay branch, to Bicester and to other places and say "yes, it can be done". The people of Wiltshire took their eye off the ball from 2001 to 2005 - were lulled into a false sense of security with the increased service on the "TransWilts" that made it practical, usable and growing and they were too late when the SRA / DfT put through a specification for the next 10 years which was counting beans, and included a thumping great loophole which meant that the remaining trains were run at silly times that provide few return trip opportunities. Indeed - last night I had a choice between an hour's wait at Chippenham / a journey time from leaving Stapleton Road to getting back to Melksham of over 2 hours (with only 45 minutes actually on the move) or taking to the bus at Bath. Well - I met up with Sion on the train, and we changed over to the bus. Met up with Anne on there ... and I got back to Well House Manor an hour before originally planned ... and took over the wait for late checkins, delayed as they were driving down to us on the road. Perhaps that's another story, or perhaps there's a moral in there somewhere.

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


Related topics: via article database

October 24, 2009

Tcl - uplevel to run code at calling level

Tcl procs (they're Tcl's functions) can pass information back via the return command, and they can access data in the top level of code via the global commands. Incoming parameters can be passed in 'by name' so that any values altered within the proc are also altered in the calling code - there's an example here using the upvar command and another here.

A further facility - uplevel - allows you to run a command in the scope of the proc that called your code. It can be useful for setting an extra return value, but it's also a command that allows all sorts of horrors - so be careful. And remember that any variables that you reference in the uplevel command that are prefixed with a $ will be interpretted / substituted before the uplevel command is even run - so will be from the local scope. There's an example of uplevel in use here if you want to see what I mean!

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


Related topics: via article database

Useful link: Tcl training

Quick easy and dangerous - automated logins via Tcl / Expect

Let me start with a security warning. Passwords and firewalls are there to make it difficult for unauthorized users to get through / at systems, and if you write a script which automates passwords and multi-hop telnet and ssh logins to make it quick and easy for you to get over all the hurdles you are also making it easy for everyone else who has access to a copy of your script. In other words, use what I am about to show you with great care and keep the script if you embed passwords and save names in it with extreme care!

OK. Now let me spill the beans. If you want to automate a login process so that you get straight in to a remote system though what might be a difficult series of steps, you can do so using expect. Once logged in, you can use the interact command within expect to connect your keyboard and screen to the remote process and talk to it directly.

Let's make the connection:

spawn ssh -l accountname www.melkshamchamber.org.uk
expect_after {
   default {
     puts "Failed to connect"
     exit 1
     }
   }
expect "sword:" {send "abc123_not_really\r"}
expect "\$ " {send \r}
expect "\n"
 
puts "connected ...."

And then you can simply:

interact

Interact has a series of options / matching capabilities just like the expect command itself, though, and you can apply filters on what you type. There's an example here - automating ssh and with filters and further examples here (telnet) and here (telnet, filtering, logging, etc)

But let me finish as I started. A script that makes it trivially easy for YOU to log in also makes it trivially easy for anyone who has stolen your script to log in!

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


Related topics: via article database

Useful link: Tcl training

Using Tcl and Expect to automate repetitive jobs

If you're typing the same series of instructions into your computer time and time again, perhaps with predictable variations depending on the responses that you get, you should consider using Expect. Expect adds three extra major commands to the Tcl language:
spawn to start a process
send to send a (user input) to that process
expect to tell the program what to expect back.

There's a huge power in the expect command - you can have it wait for an exact string, a pattern (matched with directory style 'globbing' or regular expressions), or the first of several matches if you like. You can even spawn multiple processes and wait for any of them to respond with a match, and you can set up various fallbacks using expect_before and expect_after commands which let you trap any error messages that you get back in a common format without having to specify them all through the question and answer sequence.

However ... that's getting a bit advanced for an introduction. So let's have a look at a simple piece of code, as written on last week's Tcl Programming Course:

puts "This is a Tcl program"

OK - I started with that just to prove that this really IS Tcl running ;-). Then the spawn - expect - send sequence:

log_user 0
spawn ssh -l username www.wellho.net
expect "sword: "
send "xyzyxzxxw\r"
expect "3.2\$ "
send "tail -60 /home/wellho/logdir/filename.txt\r"
expect "3.2\$ "
set store $expect_out(buffer)
send "exit\r"

Some notes on that:

1. You'll run the code at first WITHOUT the log_user command; on your initial run, you'll want to see the interaction as it happens, so that you can debug it / fix any places where it hangs or times out.

2. You don't need to describe the full string you're expecting - just the end of it. The word "password" ends with "sword". However, you MUST add the ": " on the end of it if that is how the prompt ends so that the password isn't sent too early!

3. The \r means "carriage return" which is the key you press on your keyboard to send data. You do NOT send a new line (\n) when you press enter!

4. The expect_out array contains a great deal of interesting data after you've run an expect command, including the text that's been received since your last expect. Save it, use it!

As you get data back in you expect command, via the expect_out array, you can analyze it in Tcl. In the example above, where we saved the total response into a variable called store, we concluded the program with the following analysis:

set counter ""
foreach line [split $store \n] {
  set lastmin [lindex $line [expr [llength $line] -3]]
  regsub "," $lastmin "" load
  lappend counter $load }
puts $counter

And the result - because the log file that we read was a server log noting how busy our system was - is a list of loads every minute for the last hour:

0.21 0.18 0.19 0.27 0.30 0.23 0.12 0.62 0.44 0.17 0.36 0.13
0.17 0.13 0.19 0.29 0.31 0.42 0.58 0.47 0.30 0.22 0.30 0.45
0.33 0.58 0.71 0.33 0.25 0.48 0.22 0.40

The complete source of this example is available here

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


Related topics: via article database

Useful link: Tcl training

Exploring Old Railways

I've got a certain inquisitiveness about Industrial Archeology, an interest in transport with something of a current specialization in rail - so it's no surprise that I'll spot odd railway-like structures dotted around the countryside and wonder "what is/ was that?". The old water tower at Druid's Lodge set off learning about the Larkhill Military Light Railway - you can find pictures from Druid's Lodge, from Ratfyn Junction and from Larkhill elsewhere on our site (follow the links), together with comments from correspondents who have written after finding the pages.

Yesterday, I found myself heading back from Salisbury and not wanting to rush, and I decided to see if I could find some more signs of the railway which was built during the first world war, and only survived for a few years. North from Amesbury, past the A303, and it crossed over the road, probably on the level. And indeed, this gateway and track are almost certainly its former course where it dropped away towards the river, crossing over on a bridge to meet the main network.

But further exploration in this direction was forbidden - and this is very common with old railway lines. Much has reverted to private ownership (or in this case, it would appear, public ownership but not open to the public - ironic!) and that private ownership should be respected. Frankly, I have no business case for finding out more about this particular railway and I would reluctantly accept a desciption of "nosey" were it applied to me. But if it doesn't hurt anyone, why should I not be nosey? Were there a serious interest, no doubt I could find more about who is the contact for this land and write to ask if I might look ...

In contrast, across the road from the gate that was shut against me was a bridleway, leading onto a path that ran between two high hedges - almost level, gently curving through the countryside, giving me the clue that I was indeed ... and legitimately ... on the course of the old railway.

After the best part of a hundred years, little remains but the trackbed as a path. Indeed, I couldn't spot any artefacts and wouldn't have expected to do so. A few minutes looking around (less time than it is taking to write this item!) and we were on our way.

Many rail enthusiasts are all for retaining and preservation of the past at all costs. I'm not one of them; it was probably sensible for this line to be ripped up when its purpose was done. For sure, it would make an excellent tourist attraction today, adding a beautiful countryside run from the Countess Roundabout on the A303 up to Larkhill, where the line passed somewhere close to the Church of St Alban the Martyr (or perhaps that church was built over the trackbed?). But in general, preserved railways can be sad nostalgia - as I have commented before [link] - and they will progressively struggle more and more as their stock goes from old to ancient, and their band of enthusiasts ages beyond the point an which they can drive trains.

Here's - perhaps - a vision of rail for the future. Hedge End station was opened in 1990, to serve the population of the new-growing area there abouts. Services have risen to hourly, with passenger journeys rising year on year. A good local bus service integrates road and rail, and car parking is available at 2 pounds a day for those who don't wish to use the bus or are not on the bus route. And good footpaths take you to many of the closer houses too. I look at Hedge End, and I see much we can learn for Melksham - much positive. But that's a story for another day.

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


Related topics: via article database

October 23, 2009

split and join in tcl and expect

Split and join in most languages convert strings of text into arrays / lists / collections of other sorts. But in Tcl, all variables are held as strings, so are split and join actually needed?

If you're working with a collection of single words - no embedded spaces, no special characters, space delimited, then running split and join in Tcl will return you a string that's identical to the one you sent to them ... but if you do have special characters involved, it's another matter:

Dorothy-2:tcl grahamellis$ tclsh
% set places [list Calne Devizes Melksham Corsham Bradford-on-Avon]
Calne Devizes Melksham Corsham Bradford-on-Avon
% join $places
Calne Devizes Melksham Corsham Bradford-on-Avon
% split [join $places]
Calne Devizes Melksham Corsham Bradford-on-Avon
% Dorothy-2:tcl grahamellis$

but

Dorothy-2:tcl grahamellis$ tclsh
% set places [list "404, The Spa" {"Well House Manor"} Bristol]
{404, The Spa} {"Well House Manor"} Bristol
% join $places
404, The Spa "Well House Manor" Bristol
% split [join $places]
404, The Spa {"Well} House Manor\" Bristol
% Dorothy-2:tcl grahamellis$

Because they're so often 'null' in their effect, you should test any code that uses lists very carefully, and with special characters too when you're working in Tcl.

I've added an example from this week's Tcl course here, and there are further string manipulation examples here and here. A further example here shows a case of handling a string as a list where you don't need to use split or join.

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


Related topics: via article database

Useful link: Tcl training

A short form of if ... then ... else

There are so many times you want to say "if ... then ... else" to do no more than choose between the word "is" and "are", to say "child" or "children", or to say "may" or "may not" in your output. Using an if statement for that's a lot of code for a little job.

In most of the languages we teach (Perl, PHP, Python, Java, Ruby and C and C++), the ? ... : operator allows you to do a 'rapid fire' If and else ...

PHP, Perl

print (($n==1) ? "is" : "are") ;

Ruby

In Ruby, the operator is available and you can even embed it within a double quoted string ... (that's Ruby for you!)

method = miles < 3 ? "walk" : "ride"
or
print "That is a #{miles > 10 ? "LONG" : "short"} distance\n"

See Complete example source

Tcl, Tcl/Tk and Expect

Tcl is a command based language rather than an operator based one, so as you would expect the : and ? operator is not available everywhere - but you CAN use it within the expr command, or implicit expr deferred blocks - the conditions for if and while commands.

Here we are, checking under British licensing laws, whether we can sell you alcohol:

set mayyou [expr (($here > 17)?"may":"may not")]
puts "You $mayyou buy a drink"

The full source code is here. As even with Tcl, I could place the square bracketed expression for evaluation into my puts, but I've decided to keep it clear rather than concise.

Want to know more?

We provide training courses on all the languages I have mentioned - we offer scheduled public courses if you have just one or two delegates, and we can run private courses (and even do so at your own offices) if you have a larger group.

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


Related topics: via article database

October 22, 2009

Windows 7 and Open Source Programming

Windows 7 went on sale at midnight ... and at ten past, I got my first bulk sales email with a subject line Windows 7 out now - time for a new PC. Slight pity that the graphic on the top of the email still says "PC World Recommends Windows Vista Home Premium" ;-).

But - in all seriousness - how will Windows 7 effect our Open Source training? Not very much, I suspect; the languages we teach in are pretty portable these days - I was writing examples in Unix (Mac OSX), and my delegates were using Windows Vista and Fedora Linux yesterday, and even code such as Expect which used to be notorious for Windows problems was running cross platform. These days, the operating system become less and less relevant - an editor, and the language itself and (unless you write code that says "run this OS command") it will usually run. Google are soon to be bringing out an operating system too ... that will make life interesting, but won't be a show stopper in our business. And I expect I'll be able to report on Windows 7 and how Tcl, Lua, Python, Perl ... run under it in the near future. But I'm not rushing out to the shops today.

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


Related topics: via article database

Beyond the Pale

The other day, I used the term "beyond the pale" in conversation with some delegates, and as an afterthought commented - "I don't know where that saying comes from / originates". Well - they knew one origin at least!

It comes from Ireland ... the English aristocracy settled centuries gone by in the Dublin area, and spread out somewhat from there - but not all the way across the island. There was a certain boundary, rather beyond the current M50 motorway, I understand - a fence with pailings beyond which the land was regarded as wild country. And if people went out there ... they were Beyond the Pale

Illustration - Mellifont Abbey from A weekend in Ireland.

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


Related topics: via article database

What are Tcl lists?

In Tcl, all variables (except 'arrays') are held as strings of text - and that includes lists. A list is a string which is treated as a collection of individual words, space separated, and you can then select individual words by their word number.

And this means that if you have a simple, space separated file of data you can read in the data line by line and use commands like lindex to refer, item by item, to the components of that line without needing to recourse to splits or joins. There's an example that shows that truly simple (almost naive) approach here which I wrote on the public Tcl programming course I presented earlier this week. There's a further example of analyzing the log file and building up a list of the hosts served here - again a naive example (as adding arrays to the mix is helpful in this case).

Actually, lists are rather more sophisticated than the example shown above will lead you to believe - they're interpreted within Tcl by the same syntax analyzer that analyses your code (why not - it keeps the footprint down!) so that you can include spaces and other special characters in your list elements - using {} and \ protection just as you would on your data. Tools such as the list and split and join commands let you manipulate lists easily, even if the list members include 'specials'.

Here is a summary of the main list commands:

Creating and modifying lists
As well as creating lists from first principles, you can construct and modify lists using:
list - provides automatic quoting
lappend - adds second and subsequent arguments to list named as first argument
linsert - inserts elements into a list at a given index position, returns a new list
lreplace - replaces elements in a list (first argument) with index numbers in a range (second and third arguments) with subsequent arguments
split - splits a string into list elements and returns the list. If called with two arguments, the second argument is the separator character

Extracting information from a list
Information can be returned from lists using:
lindex - first parameter, the list; second parameter, the index number of the element to be returned
llength - returns the length of a list
join - merges the elements of a list, separating each with the second parameter
lsearch - search a list for a value

Manipulating lists to create other lists
concat - takes multiple lists as parameters and returns a single joined list
lrange - returns part of the incoming list, from start index number to end index number
lsort - sort an incoming list and return a new sorted list

(This table is from our course notes - all delegates get a copy of our course notes to take away with them - approx 60 pages per day of training. The source code of all the examples is available on our web site too.)

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


Related topics: via article database

Useful link: Tcl training

Tcl - catching an error before your program crashes

There are times when a Tcl command can fail because of the data being passed in to it ... and when it fails, it can do so with a spectacular crash! For example, the glob command which matches files to a pattern (Tcl's ls or dir if you like to think of it that way) can go 'belly up' if there are no files at all that match the pattern:

no files matched glob pattern "*.lua"
   while executing
"glob *.lua"
   invoked from within
"set file [glob *.lua]"
   (file "tcl/falls" line 15)

OOooops!

If you want your Tcl program to continue, even on an error, you should use the catch command and run the command that may fail within a deferred block that's passed in to it ... something like:

catch {glob *.lua} yikes.

It works like this:
• If the command WORKS, the result is put back into the yikes variable, and catch returns a true value, but
• if the command FAILS, an error message is put into the yikes variable, and catch returns a false value.

There's a code example here that illustrates catching (on glob) with testihng the conditionals. And further examples here (failing) and here (caught). There's also a further explanation on the blog here, and a demonstration of how catch can handle a failure to open a file here.

When you are first writing a piece of code - writing what's known as a 'proof of concept' or a 'spike solution', you may not be thinking about error handling too much. But it reallity such code testing / defensive coding against errors is VITAL. So we make certain that we cover catch and loads of associated subjects on our Tcl Programming courses.

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


Related topics: via article database

Useful link: Tcl training

Tcl - passing arrays and strings in and back out of procs

When you want to pass data INTO a proc in Tcl from a regular variable, you write the variable name with a $ in front of it in the code and the value is substituted. But this doesn't work if (a) you are passing an array (which cannot be expanded into a string or (b) you want to change the value in a variable, or pass a result back in it. So that's when you use upvar.

It works like this. You pass in the NAME of the variable that you want to set / change, and then you use upvar to say "the variable called harry in this proc is the same as the varaible named in the $text varaible passed in from the level above which is the same as the mytext variable in that calling code." (Clearly, the names I have used are examples, and from this piece of code:

proc dress {text} {
   upvar $text harry
   set harry "<h1>$harry</h1>"
   return [string length $harry]
   }
set mytext "Hello World"
set sz [dress mytext]
puts "$sz $mytext"

Here's a sample that shows how this runs:

Dorothy-2:oct09 grahamellis$ tclsh tcl/dresser
20 <h1>Hello World</h1>Dorothy-2:oct09 grahamellis$

When you start looking at the built in commands in Tcl itself, you'll see how significant this is ... so many of them take parameters from which you omit the $ character and that's a sure sign that the proc concerned does / will / might change the ingoing value. Examples that come to my mind include foreach, regsub, regexp, incr, and even set!

The example above is on our web site here. This is a subject that's not an obvious one when you first come to it, and there are all sorts of other nasty things you can do with upvar and uplevel and so we spend a good time explaining and trying it out on both our Tcl and Expect programming and our Learning to program in Tcl courses.

Further examples: here, here (passing back an array), and here.

Tcl offers further flexibility in proc (function) calls too - optional parameters are illustrated here, calling procs with a variable number of parameters here, using global variables (OK to use occasionally!) here and you can even use uplevel to run code in the level above - very specialised use, see example here

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


Related topics: via article database

Useful link: Tcl training

October 21, 2009

Melksham Town - asleep or awake?

I'm writing this early - before six in the morning - and already I've been around Melksham town as it starts to awaken for another day, dropping off a Melksham Chamber of Commerce Update Letter through the letterboxes of all the businesses. When I checked all their details for the town map a couple of months ago, I promised an update on various issues raise, and now is a good time both to sweep around with a final update on some of those, and to start a new and more active approach from The Chamber that we have long since planned.

Melksham is dark. But it's active. The town's three newsagents are setting up shop. And people are walking and cycling through the town, down to "The Avon" or Cooper Tires as they are now, for the start of their shift at six. It's when you see the steady and significant flow that you realize just how important jobs, and these jobs, are to the town.

Some businesses have easy to access letterboxes. And I was able to pop my newsletter through their doors in a matter of a few seconds. Some have instructions on their front doors - "please leave post in door to side", and I cheerfully complied. Others have no letter boxes that I could see, are behind gates, have blocked their letter boxes or are so dark that I would need a torch to find them. I've taken the view that such businesses aren't encouraging local people who want to drop off a letter for them to get in touch - "business on OUR terms - when we're here" is the approach - and I'm not going to take a substantial amount of "prime time" during the day going around and forcing myself upon them. If you just happen to be a town center business in Melksham and haven't received the Chamber's fly, please follow the link above, or get in touch if you would like a printed copy of the same thing ;-).

We're moving more and more to 24 hour businesses - I already have overnight training inquiries to answer, and the post and written word have so largely been taken over (or overtaken) by the Internet. Receiving a cheque for course payment by post is still quite common (although it may hit terminal decline if we have a postal strike) but more and more people pay us by BACS or credit / debit card - and although credit cards especially cost us a significant fee, it means we're "open all hours", and we're able to work from the Hotel, from home ... or from Fareham, Lymington, Cambridge, Horsham, Larne, or any other place that we're giving a course.

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


Related topics: via article database

October 20, 2009

Beauty in pictures

Top picture - Well House Manor

Bottom Picture - an orange pepper

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


Related topics: via article database

Tcl - a true interpretive, command based language

Tcl is a very different language to the others that I give courses on - it's a truly interpretive language who's structure is based on commands rather than operators and operands. Thank sounds a bit technical - so what does it really mean?

A Truly Interpretive language is interpreted each step along the way. You'll often be told that Perl, Python or Lua is interpreted but that's not really the case - they are "compile and run" languages where the source code is checked once, and an intermediate "Byte code" produced - a slower start to running a program with all that extra work to do ahead of time, but once it's running much faster as the lexical analyzer doesn't have to go "p-r-i-n-t ... oh that's a print" every time around a loop.

And a Command Based Language is one where every instruction starts with a command word - it means that code such as h = 12 isn't valid because that would be looking for a command called "h" with two parameters - an = sign and the string "1-2". This makes the source a little longer and clunkier, but the interpreter far smaller, and much easier for traditional engineers who only do a bit of programming to understand.

So really Tcl is very much closer to Shell Programming than the other so-called scripting languages. Not a problem to us - we cover Shell Programming in Bash briefly on our Linux basics course (and much more on private courses), and Korn Shell Programming on private courses

Footnotes - see here for details of Lua's compiler, and here to read more about how Python does it. Perl's byte code is discussed here, and Java's is widely used - it's the "class file" - and you'll find mentions all over our site - see here for example.

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


Related topics: via article database

Useful link: Tcl training

Python - how it saves on compile time

Python is interpreted every time you run the code ... or that's the simple first story you're told. But really it's not that simple ... and not that inefficient.

When you run a Python program, it is not interpreted line by line as you run it - it is interpreted all at once before it's run at all, and stored as "byte code" so that loops and methods don't need to be re-interpreted hundreds or thousands of times during a single execution ... the Python virtual machine (for that's what it is) simply comes back to the already-worked-out store.

It gets even more efficient when you come to modules that you load through from or import. Their virtual machine code is saves into files with the extension .pyc (or .pyo if you use the optimize option) and they are loaded directly without the need to recompile on future runs. A quick operating system check on file time stamps means that if you change your source file, it will be 'silently' recompiled and resaved.

Other languages which are described as 'scripting' languages use a similar technique. See here, for example, to see how Lua does it.

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


Related topics: via article database

Useful link: Python training

Luac - getting lua to start fast by precompiling

Luac is Lua's Compiler ... using "luac" you can turn your Lua program into a binary (executable) file. Covered on Installing Lua on our Lua Programming and Learning to program in Lua courses.

usage: luac [options] [filenames].
Available options are:
- process stdin
-l list
-o name output to file 'name' (default is "luac.out")
-p parse only
-s strip debug information
-v show version information
-- stop handling options

The output file isn't actually a binary for the processor you're running on - it's an intermediate bye code format that saves compile time each time you load your Lua program. So Lua still has to be installed on your system (not an issue - it's open source and a very flexible license) and once it's actually running, it's no quicker. Rather like having a car with the engine running ... the get away is quicker, so it's great for short journeys but on a long journey the few cycles saved starting and warming up are lost into insignificance!

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


Related topics: via article database

Useful link: Lua training

October 19, 2009

Mothers Day or Mothering Sunday?

For Americans living in the UK, there's a need to think ahead ... for Mothering Sunday in the UK is celebrated in March (so cards on sale from mid January!) and in the USA, Mother's Day is in early May. You'll get some very odd looks if you walk into a card shop just after Easter here in England and ask for a Mother's Day card ... and you'll need to be very lucky to find one accessible in the "try and sell it next year" draw.

Adding dates to our diary (here and here), I came across a page on a site that I've often found before - Woodlands Junior School in Kent - explaining the UK's mothering Sunday and who it's the middle Sunday of Lent (See here) whereas the USA version isn't based on the date or Easter, which is a study in itself!

The UK / European "Mothering Sunday" dates until 2016 are listed at present here and "Mother's Day" around the world - from Greece on 2nd Feb to 22nd Dec in Indonesia - here

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


Related topics: via article database

October 18, 2009

New Web Site for Melksham Chamber of Commerce

I'm going to "hit the button" this week ... a small, but very important new website for Melksham Chamber of Commerce and Industry and under their own domain name too!

http://www.melkshamchamber.org.uk/

The Chamber is a member of the Wessex Association of Chambers of Commerce - covering more that a dozen towns across the area, and we're delighted to be included on their web site and to work with them in things which are logically county wide ... or within the area for those that cover the old West Wilts region. But there are issues which are very particularly Melksham too. And that's why we need our own section of the web[site] too ... and to proudly say "This is Melksham".

Please click on my link above ... have a look at the site. Have a look at the current goings on with Countrywide who want to move their 35 to 40 jobs a hundred yards or so, and are being told that "it will harm the town centre". If you're interested in Melksham, please cast a vote too and tell me what you think - I'll be attending the planning meeting in about a week and I would love inputs.

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


Related topics: via article database

October 17, 2009

Cant connect to local MySQL server through socket /tmp/mysql.sock

Q Have you ever had the error message Can't connect to local MySQL server through socket '/tmp/mysql.sock' from your PHP program. It's one that I see quite often, but it doesn't seem all that well documented ... so what's the cause, and the cure?

A The error message seems to occur if you delete your MySQL installation and re-install - something we do very frequently during our training. You need to remember to delete the /etc/my.cnf ~/my.cnf and data and spool directories before you re-install if you want a clean start.

If you have the error message above and want a temporary fix, try connecting to "127.0.0.1" and you'll probably find it will work ;-)

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


Related topics: via article database

Useful link: MySQL training

October 16, 2009

Railway Arithmetic

1 + 1 = 1 If you have an early morning round trip out and back to a residential / suburb, and a similar evening round trip, you're just providing a single commute opportunity to the origin point of the train.

2 + 2.5 = 8 If you take the two round trips of the first example, and add two more round trips (plus - in my example - an extra single journey) you can increase the commute opportunities from one to eight (yes, 125% more trains - 700% more journey options).

How does this work? Let's see my example

Here is the current train service from Swindon and Chippenham to West Wiltshire (Melksham, Trowbridge and Westbury). With an arrival at Chippenham at 07:27 and a departure back home at 19:01, (Swindon 07:47 to 18:45) this gives just a single commute opportunity with 11 hours (far too long for most people) in Swindon, or 11.5 hours (also too long!!) in Chippenham.

Adding an an extra round trip at lunch time (using a train that sits idle in the sidings at Westbury for 2 hours at present), and an extra pair of trains in the late afternoon (swapping over trains which sit at Swindon for an hour, and are available at Westbury for an hour) ... and rerouting a morning Bristol to Swindon train to call additionally at Westbury, Trowbridge and Melksham, you're up from 4 to 9 single journeys on the line ... and from one to eight possible return trips ... and good, useful ones too!

Current:
Arr. 07:48, leave 18:45 - 11 hours

Suggested:
Arr. 07:48, leave 18:45 - 11 hours (useful for occasional long days)
Arr. 07:48, leave 16:45 - 9 hours (ideal length for daily work)
Arr. 09:48, leave 18:45 - 9 hours (ideal length for daily work)
Arr. 09:48, leave 16:45 - 7 hours (good for some shorter days work, also for days out shopping, etc)
Arr. 12:20, leave 18:45 - 6 hours (half day work / leisure / business option)
Arr. 07:48, leave 12:30 - 5 hours (half day work / leisure / business option)
Arr. 12:20, leave 16:46 - 4 hours (half day work / leisure / business option)
Arr. 09:48, leave 12:30 - 3 hours (half day work / leisure / business option)

That's a considerable gain from making better use of existing resources, isn't it? It's not going to be quite 'cost free' - as train crews are taking rest breaks at present during those longer layovers, and there may not be a crew around at all for the train that's parked up at Westbury over lunch.

It has been said that an ideal extra train would arrive into Chippenham and Swindon between 08:15 and 08:45 and leave back between 17:15 and 17:45 - and that would form a true commuter service. Indeed - I agree that WOULD be ideal. But the price to be paid would be five to ten times more than that of the option above - you would need an extra train, 3 or 4 crews (6 to 8 new staff) ... and the two nine hour commuter options, with the longer and shorter alternatives that people can use if they wish, are eminently sellable. These days, many more people ARE flexible in their hours, or working in places where they can routinely do a slightly earlier or slightly later turn.

The lunch time service gives really good part time opportunities, as well as good service for access to places like the Wiltshire Heritage Center in Chippenham which is currently impractical to access by rail from the rest of Wiltshire. Spend a morning, or an afternoon, or the whole day studying the resources there.

West Wiltshire to Chippenham and Swindon is one of the top 50 commutes in the South West - and it's almost exclusively done by car at the moment, with about an hour being taken from Trowbridge to Swindon. The bus takes 95 minutes, the train 35.


Let's look at another piece of arithmetic on this railway corridor - using the same service and the growing town of Melksham, currently 22,000 population, 1000 new houses authorized, 100 acres set aside for further development - so I would expect to see a population of around 32,000 by 2025.

Here's the present service with a very long day indeed to Chippenham and Swindon in one direction, and an impractically long day to Trowbridge / Salisbury / Southampton in the other. Long distance travel is ruled out for all but the most hardened - tourists and people going away on holiday simple don't want to leave home when it's still dark, nor have the worry of wondering if they will miss the ONLY train after a long journey back to the area.

Double the number of trains in the cheap way we propose, and the options blossom. I won't list them all but you'll see all the Chippenham and Swindon trips I mentioned above, plus new options to the south ... and services such as an 09:17 departure which would really help the town's visitors and leisure traffic, together with the services that arrive back at a quarter to and a quarter past five.

With extra services as outline, there's a marketable product. Form a Community Rail Partnership to help with the promotion, produce a proper timetable (try asking at Chippenham for a timetable of services, direct and indirect to Trowbridge, and see what they say!), provide good bus connections along the way ... and you'll end up with a useful, well used and supported service.

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


Related topics: via article database

Bright Eyes

Lisa pointed me at the upside down dogs website the other day ... and we had a chuckle. The picture besides this entry is sideways on, and I have entitled it "Bright Eyes".

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


Related topics: via article database

October 15, 2009

Lua examples - coroutines, error handling, objects, etc

I have presented a bespoke Lua course over the last three days ... and it has lead me to some interesting new examples which I'm sharing here.

Object Orientation is more a way of thinking and coding than a language feature in Lua - when you set up a piece of data / structure / object, you do so in a table, and you include in the table references to the functions that are to be called when you perform certain actions on that table. See here for a first example (which never the less shares some functionality between different types of data - polymorphism) and here for an example which also overrides various default methods through a metatable. The data these two sample programs use may be found here.

Coroutines provide the Lua programmer with the ability to have several functions active at the same time - akin to parallel processing or threading, if you like to think of it that way. A comparison is sometimes made to Python's generators, but with Lua coroutines you can easily have several active at the same time. This is a great way of storing "state" within a function - it saves messy parameter passing and globals, and it also saves really long blocks of code too. If you want an iterator - anything that you might say "give me the next ..." to, then it's probably best to use a coroutine. There's a new example showing coroutine basics here, and an example in which we have used several co-routines to process different steps in a process here.

If you open a file in Lua, you'll get a file handle back ... or nil if the file fails to open. But WHY did it fail to open? io.open actually returns a second value if the first one is nil - an error string. There's an example here.

During our courses, we set a number of practical exercises so that delegates can try things out, calling on the tutor to talk about the best way to design and implement a task if they wish, with regards to code readability and maintainability. Such as exercise is set here ... calling for the delegates to write a module to meet what is, in essence, a specification and test harness. My own sample answer, written after the delegates had come up with their own answers, is here

In Lua, functions are truely dynamic - you can load them then overwrite them, and you can even define them within conditionals so that they'll be defined in different ways depending on your data. Powerful but dangerous! There's a sample showing you the mechanism here ... and we discuss the pros and cons of using these techniques on our Lua Programming and Learning to program in Lua courses (the former for people with prior programming experience, the latter for those who have never programmed before).

A log file analysis program that I wrote about 2/3 of the way through the course pulled together all the common coding features you might use in a shortish piece of code - loading data from a file, extracting information from it, sorting and producing a formatted report.

And a final example shows how you can split a line of text using string.find and string.sub ... there are other ways (such as string.gfind) which make for shorter code - there's an example of string.gfind here where it is used for filter email addresses from a flow of data.

Please follow the links on this page to see the various source codes ... please have a look at our Lua courses if you want to learn more from us. Public courses run in Melksham, Wiltshire, England; if you have a group of people, we'll run a private course for you - either at our centre, or at your office almost anywhere in the world.

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


Related topics: via article database

Useful link: Lua training

October 14, 2009

For loops in Lua

As an old Fortran programmer, I remember that a for loop was given a start point, an end point and a step ... and they had to be whole numbers (integers). Lua's for loops can be used that way, but they can be used a lot more flexibly too.

From, to, step for loops

Th egood news is that Lua works in double precision floats throughout, so your from, to and step can be anything you like ... and the step can go forwards or backwards. There's an example here where I report Celsius to Fahrenheit conversions - any step you like. You'll also notice that I have specified whole numbers for the conversion factors and they work ... 9 / 5 gives a result of 1.8 in Lua, not an integer result of 1.

If you're a C, Perl, PHP or Java programmer, you'll be used to for loops where the condition (end point) is checked every time around ... so that if the end condition is chanced within the loop, it effects the number of times that the loop runs. That's not the case with Lua which, like Fortran, decides the number of times the loop will run even before the first iteration is started. See here for an example.

in for loops

If you use an in style for loop, you're looping through an iteration (a set) of values or value pairs. Commonly used functions to generate these iterations are pairs which goes thought EVERY pair of values in a table, ipairs which only goes through the INDEXED pairs (i.e. it starts at element one, then gives elements 2, 3, etc until it finds a missing index at which point in stops, ignoring names elements and elements which are numbered but not in sequence from the start) and string.gmatch which goes though all strings that match a pattern within an incoming longer string.

See here for examples of pairs and ipairs, and here for an example of string.gfind

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


Related topics: via article database

Useful link: Lua training

October 13, 2009

Dark to dark

I know that autumn is well here when I set out in the dark for a customer site at the start of the day ... and by the time I get to my hotel in the evening, it's dark as well. But there's a beauty in the rising sun over Salisbury plain, and I'm lucky to have a camera that captures some of the atmosphere.

Mists were rising from the river Avon above Salisbury, and a few streetlights from the northern suburbs twinkled through the trees.

This hotel has been here for six years "but the other wing and the lights are much newer" according to the general manager, who was out on the lawn with his deputy as I took this picture. Very interesting that he described his hotel - with a room rate of £69.95 - as a "budget hotel". I must give that some thought. But I will admit that the prices of some of the others around here, between Portsmouth and Southampton rather scared me off.

The rooms have what I need. Space. I can get on line. Comfortable bed. En suite. Quiet. Well stocked hospitality tray. And it's been a long day ... so I may go off and watch the TV; the only slight downer being that it's medium rather than large, and I need to carefully decide which buttons to press to avoid the pay section.

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


Related topics: via article database

October 12, 2009

Making executable binaries in Python (or Perl)

In a nutshell, translations of any of the scripting / semi-scripting languages into executables require the libraries that are included with the base distribution to be included with them, so they gain very little indeed in terms of efficiency or footprint; if the language uses dynamic memory allocation, it still needs that when compiled so you can't pull the application down to a fast and tiny single executable file, which is what most people who are asking this question are hoping for. Indeed, I spoke with the author of one of the major script to C converters and to paraphrase him, he wrote - "Graham - I wish I had never written that piece of code. It does exactly what was intended, but people assume it can do so much more that it's a support headache and I'm forever having to disappoint people"

A recent delegate writes ...

... I have discussed the possibility of migrating to Python for applications that we now developing, mostly in MATLAB. Being free resource Python is very attractive alternative to MATLAB. There was a question raised – is it possible to generate executable in Python? – based on Python source files?

Although no easy "make me a small binary" exists, there is a close alternative in Python if you are looking to avoid the need to distribute your source. Place the whole application in a .py file (let's call in application.py) and run it via an enclosing script that simply states
from application import *

At the first run, this will generate a file application.oyc (or application .pyo - optimised - if you run it with the -O option which eliminates asserts and make some other optimisations) and you can then distribute / embed based purely on the binary files.

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


Related topics: via article database

Useful links: Python training, Perl training

Gypsy says

Gypsy has asked me to point out following on from yesterday's entry that although she appeared in three out of the four family pictures (and was the ONLY one to appear multiple times, I noticed!), she did NOT appear in the picture with the food.

In all seriousness, she has settled down well since we adopted her as a rescue dog in the spring - her coat has become shiny, she gets on with the cat, she's very gentle if not always 100% obedient ... and she has changed our lives.

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


Related topics: via article database

October 11, 2009

Family Gathering at 404, The Spa

Yesterday's lunch was the first time in goodness know how long that the whole family living here abouts came together for dinner, so I'm going to make a very rare break from my 'norm' and post a family photo which they all knew I was taking. From left to right, my Dad, son Chris, his wife Delene, Tom who is the partner of daughter Kim. Then my wife Lisa, and our dog Gypsy.

I was on "front of house" and Lisa on "kitchen", though with odd helpful digressions both ways. The there was the autumn harvest of apples (we have a harvest of horse chestnuts too, but don't think they're edible), and Lisa did us proud with a pork roast, cooked in apple juice and served with apple sauces - and an apple cobbler pie crunch for desert.

"Never act with children or animals as they will steal the show" - I expect you've heard that said? Well - I say "never photograph animals - most pictures have to be scrapped as they look odd", and I've enhanced that saying to read "never try and photograph two animals together". It's taken a long time, but Gypsy the dog and Charlie the cat now get on quite well. Gypsy says hi to Charlie who arches her back for a grooms, but Gypsy sniffs her. And Charlie comes out into the garden to watch Gypsy exercise and be with us all. But it's been impossible to capture on camera so far, so you're seeing the best of a poor bunch here.

It's only fair that I should include my picture today too ... and here's one Lisa took (she does better with animals!) with me and Gypsy, in the garden.

Pictures in this article ... all taken at our HQ - "404". Delegates who came on Perl courses or Java courses prior to October 2006 may recognise the old training / conference room - now an office and meeting room which we very occasionally take over for a family meal; last one prior to today must have been Christmas 2007!

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


Related topics: via article database

Four aspects - Chamber, Transport, Courses and Hotel

Our main business is in Open Source computer training - reaching people how to program in Perl, PHP and Python, in Lua, Ruby and Tcl, and on related subjects such as the MySQL database and the Linux Operating system. You can find a full public course schedule (with links to detailed course descriptions) here, or you can find our about private courses at our training centre here and at your offices here.

So many of our delegates come a long way to our courses, and rather than have them head off in different directions to different hotels and B&Bs every night, we opened our own new hotel and training centre in 2006. It's become very popular with people who visit Melksham to see other businesses, and we do a healthy weekend / holiday trade with people visiting their relatives or touring our beautiful area. See here for our Well House Manor web site.

Until 2006, some 40% of our delegates arrived in Melksham by train, but in that year First Great Western removed all but two trains a day from the timetable ... and now it's just 4% of our delegates who arrive by train and the service is, frankly, an embarrassment. It's also rather silly that a town with a population of over 20,000 and a perfectly good railway has been slashed back in this way, forcing us onto overcrowded and slower roads which are less environmentally friendly. I started a campaign in 2005 (but AFTER the decision had been made to cancel most services) for an appropriate service, and that carries on to this day. We have moved from being considered to be a "basket case" in the early days to having a very high Benefit Cost Ratio in the latest reports for a service that runs as frequently as once an hour. See here for more details of the campaign and here for a wider area forum.

When we arrived in Melksham in 1999, we arrived quietly. Our customer base is countrywide / continent wide, and our footprint a small one, so it wasn't necessary of natural to make a big splash. However, our delegates bring business to Melksham, and we fell in love with the place. The hotel brings further natural local involvement, and the train campaign further involvement. Local politics, with the recent changes and economy, lead to a real need for Melksham's businesses to be supported and their case put and so we joined the Chamber of Commerce. And being around the town so much of the time, and happy to 'represent', I have been elected as the President of the Chamber.

All four of these aspects appear on this blog - "The Horse's Mouth" and in the archives too. Regular readers will look and see what happens on a daily basis and skip over articles that are not relevant, and our newsletter provides a general update every 2 months. But what about people arriving at our blog archives when using a search engine to find out about the Chamber of Commerce. Up until (roll of drums!) this morning, they've come to a page that has appeared to Chamber of Commerce content in an illogical training wrapper ... but no longer. The four logos you see on this page are now selected as appropriate for archived articles, and the top "soundbite" and menus are also tailored. How do we do it? Find out on our PHP techniques workshop.

Examples of each logo in use:

Weekend and Christmas specials at Well House Manor

Melksham's Public Transport and especially how limited it is on a Sunday

Making your Melksham business a destination (Chamber of Commerce)

Choosing your PHP course

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


Related topics: via article database

October 10, 2009

MySQL - efficiency and other topics

Following on from the last two days of MySQL training, you'll see a number of blog entries covering stored procedures, securing a mysql server, and exploring database requests in PHP.

Further technical diagrams can be found here ... including how to make your select queries efficient, table locking, storing of calculated results (in summary, don't!) and why server and client are shipped together. The diagram alongside this text shows how a query that joins two tables with around 10,000 records each may produce a temporary table internally with 90 million records if you write an inefficient joing, but just 10,000 temporary records with a very slight tuning of the SQL command.

MySQL is covered on our public public MySQL course, and its installation within a LAMP environment on deploying LAMP. Calling up MySQL databases from individual languages when you're programming is covered on the appropriate language course ... typically these course give only a brief overview of MySQL and also tell you how you use Sqlite, Oracle and other databases too.

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


Related topics: via article database

Useful link: MySQL training

MySQL stored procedures / their use on the web from PHP

Are there times when your PHP will pull a large result set back from MySQL, or have to make a large number of queries, just to further process the data into a relatively small dynamic section of a report? If so, why not have the MySQL do more of the work and return a much shorter, more processes results to the PHP? You can do this with an appropriate stored procedure.

On yesterday's MySQL course I wrote a series of stored procedure examples ... the "abc" of stored procedures, if you like - there are complete books on the topic! Let's see the results - follow the links if you want to see the code.

This is a very simple stored procedure ... a 'macro' that lets a simple query - call otc() embedded in your mysqli query method - run a more complex piece of SQL within the MySQL daemon.

See MySQL stored procedure definition and PHP source code

Rather than return just a single value, this example returns a complete table of results - in our PHP, we've loped through those results and displayed them in a browser.

See MySQL stored procedure definition and PHP source code

You'll want to pass a parameter into your stored procedures ... this example shows how ...

See MySQL stored procedure definition and PHP source code

Our final example in this set shows variables, conditionals, loops, a cursor and more ... we've passed back just a single value - kicked back to us by a rather different use of select to what you're used to.

See MySQL stored procedure definition and PHP source code

The data that we seeded the tables with is here, and the same data as a mysqldump file is here

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


Related topics: via article database

Useful links: PHP training, MySQL training

October 09, 2009

Learn about MySQL stored procedures

Current releases of MySQL include "stored procedures". What are they?

You may start by considering stored procedures to be "Macros" - a series of commands bunched together as one, or a complex command which is held within the MySQL daemon and called up by just a simple call. But they then go much further than that, with variables, conditionals, functions and loops ...

Let's set up and use a simple stored procedure:

mysql> DELIMITER !!!
mysql>
mysql> CREATE PROCEDURE orgtypecount() READS SQL DATA
    -> BEGIN
    -> SET @what = 'SELECT count(oid) from orgtype';
    -> PREPARE summat FROM @what;
    -> EXECUTE summat;
    -> END;
    ->
    -> !!!
Query OK, 0 rows affected (0.00 sec)
 
mysql>
mysql> DELIMITER ;

That's a procedure called "orgtypecount" which counts the number of rows in a table called "orgtype" which have a NOT NULL value in the oid column. But you don't have to type the full command in every time you run it now that it's a stored procedure:

mysql> call orgtypecount();
+------------+
| count(oid) |
+------------+
|          4 |
+------------+
1 row in set (0.00 sec)
 
Query OK, 0 rows affected (0.00 sec)
 
mysql>

Wasn't that easy ;-) ... well, as a starter it was, but stored procedures have a complete programming language to them. From a niche interest a while ago, they're becoming more important as time passes, and I'm now adding a handful of examples to our public MySQL course and I'm happy to go into further details on private courses.

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


Related topics: via article database

Useful link: MySQL training

Securing MySQL on a production server

There's a conumdrum for the authors / distributors of any open source server software that's likely to be used in a productions environment - should they send it out so that it's quick and easy to try but needs securing, or so that it's well secured but therefore calls for a bit more effort when you try it out.

The MySQL folks have always been "passed masters" at providing good distributions that install easily and test well ... but there have always been warnings about setting up passwords, getting rid of anonymous accounts and test databases, and limiting direct logins to localhost or a specific subnet.

These warnings remain, but in recent versions, the MySQL folks supply a script called mysql_secure_installation which takes you through each of the areas I have warned you about and lets you close the potential loopholes (some ARE just potential) on your to-be-production server.

Before you run the script, you should set up your path to include the MySQL binaries just installed:
  export PATH=/usr/local/mysql/bin:$PATH
  ./bin/mysql_secure_installation

and if you get "cannot connect to socket" messages, you should clean up / repeat the install, getting rid of the /var/lib/mysql directory before the reinstall!

What are the issues that the mysql secure installation deals with?

1. Setting the root password ensures that nobody can log into the MySQL root user without authentication (as shipped / unpacked, there is no root password set)

2. By default, a MySQL installation has an anonymous user, allowing anyone to log into MySQL without having to have a user account created for them. This account is limited in where it can log in from and what it can do, but never the less it should normally be removed.

3. Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. If your server is behind a firewall, this may be less of a concern, but if you do need root access to MySQL from a remote site, you've probably got an ssh access set up to the server too and you should use that and run the mysql client on the server.

4.By default, MySQL comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. If you've removed the anonymous user already, there's less of an issue here as the door is already closed, but it IS sensible to remove the test database. If you leave both anonymous access and the test database easily accessed, dangers include unauthorised people stuffing your discs with gobs of data you don't want, and then running slow queries on it.

Even if you go through this securing script when installing MySQL, you still need to continue to consider security at all times. A login account to MySQL with a password the same as the user account name, or a password held in plain test in a publicly readable file can compromise the whole system. And if your database can hold data submitted by users, you'll need to have an acceptable user policy and a system in place to enforce that AUP.

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


Related topics: via article database

Useful link: MySQL training

Potted MySQL installation

Putting MySQL onto a machine that may previously have had an install ... here's a summary of the commands we used yesterday. It's a useful checklist (reminders to get rid of old config files that could cause a new install to start with old data, for example) but you 'll need to adopt / adapt individual commands to deal with what you find on your system.

1. Backup / copy anything you want to keep!

2. Tidy up / remove previous installs

Kill any running daemons
Also /etc/my.cnf, ~/.my.cnf, /var/lib/mysql, /etc/init.d/mysql.server
cd /usr/local
rm mysql
rm -rf mysql-5.1.xx-linux-i686-icc-glibc23/

3. Fresh Install

[download / copy fresh distribution]
tar xf ~trainee/bristol/mysql-5.1.xx-linux-i686-icc-glibc23.tar.gz
ln -s mysql-5.1.xx-linux-i686-icc-glibc23 mysql
cd mysql
chown -R mysql.mysql .
./scripts/mysql_install_db --user=mysql
chown -R root .
chown -R mysql data
./bin/mysqld_safe --user=mysql &
export PATH=/usr/local/mysql/bin:$PATH
./bin/mysql_secure_installation
ps aux | grep mysql
mysql -uroot -pk645pfb -hlocalhost

4. Make permanent at reboot

cd /etc/init.d
cp /usr/local/mysql/support-files/mysql.server .
cd ../rc5.d
ln -s ../init.d/mysql.server S94mysqld
ln -s ../init.d/mysql.server K09mysqld

5. Create a user account and database

mysql -hlocalhost -p -uroot
grant all on twcrp.* to twcrp@"%" identified by "abc123" ;
create database twcrp;

(Yes, I am running our MySQL course at the moment!)

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


Related topics: via article database

Useful link: MySQL training

October 08, 2009

Contrasting Cambridge, Bristol and Wiltshire

When I'm in Cambridge, I try to stay as close as I can to where I'm working - and that's measured in driving minutes, rather that in miles. There are some places that are less than a mile apart as the crow files, but 20 minutes apart by road, with one way systems in place and uncrossed rivers and railways. I made note on Wednesday ... 12 minutes for a mile and a half ... an average speed of less that 8 m.p.h. and I wonder if it will get worse in a month's time when the guided busway opens and spews all its (err) guided buses onto the same road. There *is* a bus lane for part of the way. I passed in in 10 seconds of my 12 minutes.

To be fair to Cambridge, I have averaged just 11 m.p.h. in London before now, and a truly appalling 1.5 m.p.h as the crow flies from J19 of the M4 in Bristol to Great Stoke, behind Parkway Station.

So it was a joy to be able to drive home in the day light ... taking country roads as I got back to the area that I know well in Wiltshire and to see some of the autumn colour and move at a speed that the road, and not the other traffic, dictated.

This is a view of the lanes between Membury and Ramsbury, on the Berkshire / Wiltshire border - showing some of the lovely scenery in Wiltshire even on what was, weather wise, quite a nasty afternoon.

It's only 50 miles from Bristol to this lovely spot in the country. And only 100 miles from Cambridge. And there are lots of lovely spots like this for you to see if you visit us ;-)

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


Related topics: via article database

Variable storage - Perl, Tcl and Python compared

From Monday to Wednesday, I was teaching Python to a group of delegates at a company where I have previously taught Tcl and Expect and Perl. And this interesting diagram shows just what a contrast there is between the three languages right from the start - in terms of how data is stored into variables!

In Tcl, all data is stored a strings so the number 21 would be 2 bytes - the character 2 followed by the character 1.

In Perl, you have a much more 'traditional' model where the name of the variable - which has a leading $ - may be considered to be a direct label on the storage element

And in Python, everything is an object, so your variable name contains a reference to a location on the heap at which the data is stored.

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


Related topics: via article database

Useful links: Python training, Perl training, Tcl training

Not your cup of tea?

When I travel, I'll usually grab a sandwich or fish and chips of an evening, and eat in my room; there's no great thrill in sitting alone in a hotel restaurant and there's often something on the TV (more than five channels is nice, but still surprisingly uncommon), or work to be done online. But on occasions, I'll have something completely different (and when is that more appropriate that when giving a Python Course?

On Tuesday evening, I ventured into the Cambridge Continental Delicatessen - just across the road from the Hamilton Hotel which is my first choice in Cambridge. Now ... the food I bought wouldn't be everyone's cup of tea (indeed, there's no cup of tea there at all if you look - the drink was coconut milk from Thailand) but it made an interesting change. And the hotel wouldn't be everyone's cup of tea either - if you want a standard plastic hotel, spend twice the price and you'll find a standard chain with standard sized rooms. Both the Hotel and the Delicatessen are a very pleasant change, and both (here's where they really score!) make you very welcome - you feel they really value your business.

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


Related topics: via article database

October 07, 2009

Optional parameters to Python functions

Python functions (and methods) can be called with any number (0 or more) parameters, but the calling sequence must match the 'template' or 'function prototype' given when defining the function. Let's define a function:

def fred(a,b,c=3,d=4,e=5,f=6):
    print a,b,c,d,e,f

That function can be called with a minimum of two parameters, and a maximum of six. The mandatory ones are filled into variables called "a" and "b" and any others into "c", "d", "e" and "f". If there aren't enough values, then "f" will become 6, "e" will become 5, "d" will become 4 and "c" will become 3. In other words, values fill in from the beginning.

If you want to fill in some of the optional values, but not from the 'left', you can do so by specifying the name of the variable within the function and its value:

fred (1,2,10,20)
fred (1,2,10,e=20)
fred (1,2,10,f="shishcake",e=20)

Running that:

Dorothy-2:3 grahamellis$ python dxz2
1 2 10 20 5 6
1 2 10 4 20 6
1 2 10 4 20 shishcake
Dorothy-2:3 grahamellis$

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


Related topics: via article database

Useful link: Python training

October 06, 2009

Multiple returns from a function in Python

Convention states that you can call a function with many parameters, but you return just one.

There's some truth in that statement, but of course you can often return a collection - an array, list, hash, dictionary or other composite object.

Here's a Python example ... 3 parameters in and 2 return values:

def foo(fee,fi,fum):
   add = fee + fi + fum
   mul = fee * fi * fum
   return add,mul
 
smaller,larger = foo(10,20,30)
 
print larger,smaller

Runs as follows:

94:3 grahamellis$ python symi
6000 60
94:3 grahamellis$

The above is a demonstration from yesterday's Python Course ... a 'live' program would include documentation and comments, and would use some more descriptive variable names too!

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


Related topics: via article database

Useful link: Python training

October 05, 2009

Listening to The Minister

You've got to admire the guy - Paul Clark MP, Undersecretary of State, arrived at Saturday's TravelWatch South West meeting during the chairman's introduction. And he was the first speaker. Without visual aids - with just his name and role projected all the time - he spoke for 30 minutes without any of the gaffs we have seen at these meeting from previous ministerial visitors. His speech was long on statistics and impressive on all the money the government had spent on transport. And he talked about results, with many lines now having far better services that those they had a few years ago. And he talked too about planning journeys as a whole, across modes and bus rail interchanges. Of course, these latter rang very hollow indeed to those of us who had travelled from Melksham, which has had its train service reduced to 2 a day each way, and where the evening bus from Chippenham leaves the railway station at 20:24, just as you see the 20:25 train drawing in.

Paul then took three questions from the audience. He promised to "take on board" the request to relook at the growth rates used in the GWRUS, he sympathised with Torbay Council over their funding problems with concessionary bus passes, and he also confirmed that Cate Mack had an excellent point with regard to a huge increase in parking at an expanding Bristol Airport at a time that we should be looking to encourage greener ways of getting to the airport.

Then he took around of applause and dashed out for his train back to London to connect with a flight to Copenhagen.

As I say, you have to admire the guy. His stamina, his delivery, his clever handling of the questions such he didn't really answer anything but got in many more of his points. But I'm not terribly sure what I came away with. Well - I didn't write it down, but I know that 36 hours later I still remember that he represents Gillingham, has a majority there of 257, and joked about knowing every one of them personally.

Picture - Paul Clark fields Kate Mack's question.

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


Related topics: via article database

October 04, 2009

Wiltshire Unitary News - Chamber of Commerce Intelligence

In my role with Melksham Chamber of Commerce, a number of "nuggets" come my way - four recently relating to the new Wiltshire Unitary Authority and how things are changing / have changed.

1. Charity shops, which used to get 80% discount off the business rates on their premises in our area, now get 100% discount - in other words, they don't pay business rates at all. I support charities - especially ones that are doing a great deal of good for and within the local community. And I accept that there's a need to standardise across the new administrative area. But quite honestly, I think that even 80% was generous. A 100% discount removes the accountability from charities to be prudent in the premises they take on, and it lands their entire 'local bill' on businesses and householders. An already sloping playing field now suffers from an even steeper gradient, with business owners playing up a steeper hill.

2. On the brighter side, the county is now taking a more serious look at overall public transport provision, which has for so long seemed to be synonymous with "bus provision" across Wiltshire. To quote a comment on Corsham Area Board's web site: 17/09/2009   09:39:58 Wiltshire Council have a new team of transport planners, including several with rail experience and we are partnering with Mouchel's specialist rail team to explore how best the new Wiltshire Council can support this important mode in the future. We have set aside £100,000 this year to critically review the type and frequency of service we need, the economic case for these and the infrastructure requirements necessary, I hope this will enable us to provide a strong case for investment going forward. This is a hopeful step - a VERY hopeful step; it declares that we're looking forward and not relying on the status quo which has been in place for as long as I have been involved in public transport issues around here. link to full article

3. My thanks to Calne Chamber of Commerce for bringing to our attention a change in planning applications on listed buildings. There are many planning applications made, and it has long been the system that some 9 out of 10 are handled by paid council officers rather than being considered by elected members. However, there has always been the option of elected members "calling in" any application for discussion at council planning meetings. This right of calling in has now been removed from our elected representatives for applications relating to listed buildings (except 'full consent' applications). It means that there is no longer going to be democratic input into an element of the preservation of the heritage of our towns, with decisions being made by officials who are not answereable to the public.

4. I was delighted to hear that the new person responsible for Economic development was taking a look around Melksham last Wednesday as a part of his "learning in" to the job ... but at the same time concerned that his guide was to be an exert from our of town who has expressed his opposition to some local developments which enjoy overwhelming support from within Melksham. In order to ensure local input, I dropped a note to the guide outlining some of the points of local concern. A copy follows below, with names, etc deleted; I was / am concerned to have had the following included in the guide's reply" I would ask that you do not make contact with Xxxxx Xxxxxxxxxx at this stage as this visit is intended to be just a brief familiarization tour. At some time in the future Xxxxx may well want to undertake a more detailed study which would benefit from input from a wider range of participants. Hmmm ... Why do I get the distinct feeling that us locals are regarded as something of a nuisance here? (The emphasis on the word "may") is mine.


Dear Xxx,

I understand that you are going "Walkabout" in Melksham this Wednesday lunchtime with [snip]. I'm taking the liberty of dropping you this short note from the local perspective; I understand that [snip] is not yet familiar with the Melksham area, and I commend him on coming to take a look and start 'learning in'. I am slightly concerned at the lack of any local representative at the walkabout to answer any immediate questions ... may I help fill that gap by setting the scene?

Our mayor is proud to tell us at that at the outbreak of the second world war, Melksham has a higher proportion of its land given over industry than any other British town. Since that time the industry has shrunk, proportionately more than in other towns as it had further to fall, and Melksham now has some of the least affluent wards in the county. Recent figures indicate improvement in the poorest areas, but in reality a large element of that is caused by boundary changes. And you'll be aware of the recent announcement of up to 200 redundancies at Cooper Avon Tires, which is another blow to the town.

It's not all 'doom and gloom', though. We've got a major industrial area at Bowerhill, and there many companies who have been encouraged to come there and who are doing well, in addition to others who are struggling somewhat at present, often due more to market conditions in their industries than to their own management. And there are areas where we are developing and with Unitary support we can develop further.

I moved to Melksham about 10 years ago. Before then, Melksham was (to me) just a town that I passed by on the bypass; I had lived in a Wiltshire village for some 25 years, where little had changed for a generation, and the local people were just about starting to pass the time of day with me when I left. What a huge difference in Melksham! Melksham is a friendly, welcoming town. I can recall conversations shortly after I moved here ... "but I've only just arrived" said I, to which the response was "then welcome, and lets all work together for the town". You can see that spirit as you talk to people in the town, and you can see that spirit as you look at town development.

I went to the planning meeting at the very start of the year as which Asda asked for permission to build a new store. And it was notable how very much in favour the town was for the application; for sure, some of us had detailed questions to raise, but the store was overwhelmingly wanted and was passed. Taking another case - as I look out of my window as I write this letter, I can see traffic queueing at the temporary lights for the footpath works in associate with the new Melksham Oak school, and at times our home is vibrating as HGVs idle in the traffic jam. But - once concerns about the narrow footpath, etc, have been addressed, you won't find us being NIMBYs.

Some 100 acres of land are identified around Melksham for housing development through the RSS strategy - that's more than have been identified on other towns nearby, including the SSTCs such as Chippenham and Trowbridge - which as not all that much larger. Melksham is set to grow by around 50% in the next 15 years, and although the housing land seems earmarked, where the jobs / employment are to come from - and from a fairly low base - isn't so obvious. I'm certainly very concerned, as a representative of Melksham Chamber of Commerce and Industry, at the apparent "talking up" of opportunities in Salisbury, Trowbridge and Chippenham to what as times feels like the exclusion of the next tier of towns, of which Melksham is the largest. So I certainly applaud [snip]'s visit this week, and invite him to work with The Chamber, the Town Council, Melksham Without Council, and the other parties to ensure that Melksham develops as an equal with the other towns, rather than officially being a second rate dormitory and leaving those of us who love the place to have to fight for it on an uneven playing field.

Xxx, you mentioned the Riverside in Melksham and - indeed - that is one area to look at with [snip]. But it's only a start; there are other areas where the new Unitary Authority can step up and help soon. CountryWide - who have their most successful store in Melksham - are looking to move it less than 100 yards to a site that's where grain silos are to be demolished; it's something of a 'no brainer' that the town wants CountryWide to stay, but it might not be so with regards to the planning authorities. There is other works in progress, and plans too, which are important but would make for a very long introductory message.

There are other opportunities for the new Unitary authority to take some quite small steps that would make access so much easier and would help the authority to help us attract jobs on a more level playing field - and to help us retain those that exists. Such short term enablers include:

* A stretch of about 100 yards of road to link Bowerhill direct to the A350 / Semington bypass.

* Provision of an appropriate train service to Melksham Station. We currently have 2 trains a DAY each way ... Chippenham (50% larger) and Trowbridge (25% larger) each have 2 trains an HOUR each way. According to Network Rail's GWRUS, there is capacity for an hourly service and a BCR (benefit cost ration) of well over 2.0 in providing that service ...

I would very much welcome an opportunity to meet with [snip] during or after his initial walkabout, and also to co-ordinate development with everyone involved - [Snip] will not be wanting just my view or the Chamber's view, but the inputs of the various other concerned bodies, who I am copying on this email.

This is one town that want to work "with". How do we take it forward after Wednesday?

Graham

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


Related topics: via article database

Melksham Hotel Rooms - pictures

We have chosen to show pictures of ALL of the bedrooms at Well House Manor on the Well House Manor website. We're not unique in this, but it is not the common practise; for sure, we could have just selected our best room(s) but we know that some guests want to see where they will be staying ahead of time, not where they could be staying if they get lucky.

The room rate is £90.00 per night, double occupancy, including our superior continental breakfast. We don't have extra charges for internet, extra TV channels, teas and coffees, early arrival or late departure - it's a simple flat rate so you know what you are paying and there are no extra on departure. For single occupancy of any of the same rooms, the rate is just £80.00 per night.

We're also offering over this winter (October 2009 to February 2010 inclusive) a "Winter Weekend Special" - stay for two or more successive nights, including either a Saturday night or during the 20th December to 3rd January period, and we'll charge just £70.00 per room per night, including one or two breakfasts.

"You're a business hotel - are you open for other visitors too?". A regular question, and the answer in an emphatic "Yes, we are" ... we're open for business visitors, for tourists, for people visiting friends and relatives, and for course delegates.

Our facilities are geared up for the business traveller - each room has a large table, plenty of space to spread out, lots of power points. Swipe cards give you access to the hotel throughout the day and night without having to wake the proprietor. We encourage our guests to order food to be delivered for themselves and to use our breakfast room to eat in. Breakfast is a superior continental - Yoghurt, Actimel, Cereal, Fruit juice (we have our own orange and grapefruit squeezer that customers use) and fresh fruit .. that's just starters before I list breads, spreads, meats, cheeses, and so on. The business traveller doesn't want a cooked breakfast every day. And he may want his breakfast early, or quite late if he arrived long after everywhere else was closed ...

Those facilities also suit many groups of leisure guests - the people who are visiting family in the area and will have an unconventional pattern of coming and going, the people who are looking for a quiet weekend away in a slightly luxurious setting, the people who need crisp internet access (including a printer) as they continue to run their own business. And we have some extended capabilities too - tourist information, helping you plan what do do while you're with us such as taxi bookings, lifts, suggestions of where to eat. We do lack facilities for children (in fact we can't accept bookings for under 14s and we have no family rooms) but what some see as a disadvantage others see as a huge advantage; it does mean we can have an openly accessible fire in winter, and books and games and much more in our homely lounge area, for example.

Click on individual pictures (to the right) to see our rooms. To book on line through our secure server, click here for the weekend / Christmas special and here for other stays. If you prefer to book on the phone, plase call us directly on 01225 709638, or our freephone number which is 0800 043 8225.


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


Related topics: via article database

Serialization - storing and reloading objects

In most of the languages we teach, data is held in memory on a "heap" with a "symbol table" holding the names of the variables, where they are stored, and what type of information the (currently) contain. When you write simple variables out to a file (or the screen) functions like print or puts (Tcl) format the data in such a way that it's written out in useful form. There is, however, something of a problem when you try to do that with an object. Unless it has been told, your computer doesn't know how to display or save an object in a way appropriate for its later reuse.

Saving an object to disc for later reloading

The very term "heap" should give you a clue about something. If data is stored in "a heap" then it's not going to be all neat and tidy, is it ;-) ?? It will be held in a well defined structure that makes it accessible as necessary, but thet structure will include all sorts of memory address pointers. That means that if you just store a variable's content it won't be practical for another program to read it back later, because:
• you won't have saved the memory locations as well as the data, so the restoring program won't know what points where
• even if you had saved the memory locations, it's almost certain that when you come to restore the object there will be something else at those memory locations, or they will be within the address space of a different program.

There is often a solution provided - built in to the language - which provides you with a way of adding further information as you store your object so that you can restore it later. The generic term for this is serialisation - which means turning the object into a stream on bytes that can be stored in a serial fashion on a disc, or indeed sent down a serial connection such as a pipe to another process, or even over a network connection to another computer.

In PHP, you can provide a method called __serialize in your class definition which defines how an object should be formatted into a stream suitable for transfer over a serial line (where the name came from) of writing to disk, and a method called unserialize which reverses the process.

In Java, you state that your class implements serializable and that ensures that extra work is done within the class, and is stored. It's necessary to ensure that any classes which are used within the object are also serialisable. There's an example class (source code) here and the code that reads and writes objects to file here.

In Python, the pickle, cpickle and marshal modules all provide ways of serialising an unserialising data. There's more on that in a previous article

Cleaning up before you serialise

Where you have a complex object, it's likely that you'll have stored intermediate calculations within it. That's caching partly calculated results to avoid the need for repeated recalculation. But such intermediate data need not be stored, and may take up a lot of disc space, so you'll want to dump it before you save to disc or other serial stream.

In Java, you declare your variablse as transient if you don't want to save their contents as part of the object.

In PHP, the __sleep method which you can write performs a tidy up operation, and the __wakeup routine can be used on reload.

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


Related topics: via article database

October 03, 2009

Abstract classes, Interfaces, PHP and Java

Abstract classes, Interfaces, PHP and Java

Basics.

When you design code for a number of different similar type of thing (object types, classes) you don't start from scratch in each case - you define a base class which contains all the common code, and you then create subclasses by extending the original. You say that the subclass extends the base class, and you write the extension in a separate piece of source code. That way, you only have one set of fundamentals (i.e. one base class) to maintain into the future, and subclasses in which you only have to maintain the bits that are different in the subclass to the base class.

Two further steps.

1. Sometimes, you'll never actually want to create objects the are in the base class directly. My board example here shows a base class of "animal", but we never have just an animal ... we have a pet, a farm animal, a wild animal, a zoo animal, a mythical animal ... all of which are based on animals but have slight differences in some of the ways we handle them in our code. Indeed, for certain object behaviours (for example, if we call up the value of an object) there won't be common routines - they will always be in the subclasses; this lack of any method at all in the base class means that we can't actually create just an "animal" object, since it would be incomplete - there would be no way of getting back its value.

When you define an incomplete base class that you don't want people to initialize directly, and you want to require any subclass to provide one or more methods of a specific name, you can (PHP) or must (Java) declare that base class as abstract and you can (PHP) must (Java) also declare as abstract members all the things your subclasses are required to provide.

2. There will be times that you want all classes in a certain group that you create to have certain behaviours - certain methods - even through you don't want to inherit any underlying code at all from a base class. For example, you could have a whole lot of different types of objects being insurable, but no common code used for defining any of the data about that, such as terms and conditions and what the risks insured against are. If you want to use such a common way of talking to very different classes, you can (PHP) must (Java) declare an interface (like a skeleton class with no code, just a list of needed methods) and then say that your (sub)classes implement that interface.

Note:

Using Abstract classes and interfaces helps you to ensure that the subclasses that you write conform to the same API (application programmer interface) and thus allow you to process a whole series of objects of similar (but different) types through the same code - polymorphism. But you will see that I wrote "must" against Java and "may" against PHP. What's all that about?

In PHP, extra method definitions from abstract class and interface declarations only provide advise / a framework to the subclasses that use them - causing compile or run time errors if the subclasses haven't provided the extra code that is stated as being required. If you are programming in a large team with a PHP project, or the project is split between several coders who need to check up on each other's coding, they are a good idea ... my diagram has a "Sara" declaring an interface and a class to be abstract, so that she can help a "Pete" ensure that his subclasses are complete. But if Sara was writing all the classes on a small project, she may decide to save herself the extra coding, with the thought that the shorter code will be easier to follow later on. It's very much down to her analysis of the balanace of advantage.

Java, on the other hand, is heavily typed, and if you want to handle a number of objects of similar type through commonly named methods, it REQUIRES you to have them in a variable of the right type, and / or to cast them as appropriate. This additional enforcement by this particular language means that Sara wouldn't be allowed the option of saying "it's a small application / little cluster of classes and abstract declarations and interfaces are unnecessary bloat" as she could (and should) do on occasions in PHP ... no, in Java she must always use abstract and interfaces. And for the big systems that Java is used for these days, that's not a bad enforcement anyway.

Abstract classes and Interfaces are covered on our Object Oriented Programming in PHP day, and on our Java Bootcamp.

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


Related topics: via article database

Useful links: PHP training, Java training

October 02, 2009

Controlling, supressing, enabling PHP error messages

Q: "How can I suppress the PHP error messages?"
Q: "I get no error messages - how can I tell what is going wrong in my PHP"
Q: "Can I replace the PHP error messages with my own"

However PHP is configured, there is no satisfying everyone ... and it's a mystery to many people who install PHP code as to just how it handles errors. Let's find some answers.

First, a simple case of failing code ... as the file "jose.txt" does not exist.

<php
$fh = fopen("jose.txt","r");
print "Hello World";
?>

There are two possible results:
a) An error message from PHP, then the words "Hello World"
b) just the words "Hello World".
Which will it be?

If the php.ini file contains something like:
  error_reporting = E_ALL & ~E_NOTICE
then (unless overridden) you'll get the error message, but if it contains something like:
  error_reporting = 0
you'll get no reports (again .. unless overridden)

The setting in php.ini can be overridden by a directive to set the variable in the httpd.conf file, such as:
  php_value error_reporting -1
which will give you the error messages, or
  php_value error_reporting 0
which will supress reports.

These settings can be further overridden by settings in the .htaccess file - in the same format as the httpd.conf file, but for individual parts of the document tree.

Code changes which can effect the error handling

If the settings about don't provide what you want - if you want to turn standard error messages on and off in a script for different parts of the script, you can do that too:
  php_value error_reporting -1
will turn error reporting on (all error types) whatever is set in php.ini, httpd.conf and .htaccess files, and
  php_value error_reporting 0
will turn error reporting off.

For individual function calls in your code, a leading "@" character can be used to supress error reporting. So:
  $fh = fopen("jose.txt","r");
will generate error messages according to the settings I have described earlier, whereas
  $fh = @fopen("jose.txt","r");
will supress error messages whatever the earlier settings call for.

There are a lot of options there, aren't there? - but I have still not told you how to generate your own error message. The "trick" is that most functions return false if they fail, but another value (usually a true one) if they work correctly. So an @ to suppress the error message, and an if statement to wrap the function call ... and you can provide your own, hopefully more user friendly and application specific, message:

if (! ($fh = @fopen("jose.txt","r"))) {
        print "My own error message<br>";
        }

If you're interested in learning more about PHP coding, have a look at our PHP Programming course. If you're fine with PHP, but baffled by .htaccess, httpd.conf and php.ini ... have a look at our Linux Web Server course which covers the Apache HTTP Server running under Linux or Unix.

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


Related topics: via article database

Useful link: PHP training

October 01, 2009

Using print_r in PHP to explore mysql database requests

The print_r function in PHP lets you "print raw" the contents of a variable - great for debugging and far better that print which - if you pass it an array helpfully says Array

Embed your print_r into <pre> to </pre> tags ... so that you get a good display on your browser ... otherwise you'll end up with the spaces removed and a mess. Here's an example - showing the global $_SERVER array, and also the contents of a table that's been brought back to an array of arrays:

<pre><?php
# Show server variables
print_r($_SERVER);
print ("----------------------------\n");
mysql_connect("127.0.0.1","wellho","xxxxxx");
mysql_select_db("wellho");
$rr = mysql_query("select * from recent limit 15");
print_r($rr);
print ("----------------------------\n");
$stuff = array();
while ($nextrow = mysql_fetch_assoc($rr)) {
  array_push($stuff,$nextrow); }
print_r ($stuff);
?></pre>

Select here to see what you get when you run that code. Note how the mysql_query call just returns a resource handle, and you then have to use something like mysql_fetch_assoc to get the actual data back.

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


Related topics: via article database

Useful links: PHP training, MySQL training