« November 2010 | Main | January 2011 »
December 31, 2010
Perl, Python, PHP, Lua, Linux, and more - and business hotel too. Menu for 2011
Whar are our plans for 2011? "Steady as she goes", I think - a gentle year of building on all we've achieved in the past year, and all that has developed in the last six months. Our hotel at Well House Manor in Melksham provides high quality accommodation for delegates on our public Open Source courses - in a wide range of subjects from Apache to Ruby, C and C++ to Tcl, through Linux and Lua, MySQL and Perl, Python and PHP! And we welcome other visitors to Melksham too - business visitors who need a room, good facilities, spacious workspace in a quite environment, and a blisteringly fast internet connection. Late checkins, early breakfast, colour copier and printer and (of course!) bean to cup coffee.
Our public courses - held in our "Wilts" training room - are limited to eight delegates. That's so that every delegate gets the tutor's time that he or she needs, and that specialist courses can be run well for a wide range of delegate, with everyone benefiting from them. To help this along, the courses in all of the programming languages we teach start at two levels - there are courses titled "learning to program" for those who are new to programming, and other courses for those with good prior experience. And we encourage you to email us (info@wellho.net) or call us (01225 708225) to check that you book the course that's right for you!. We write our own notes, present our own courses - so we know our subjects really well. And that means we can advise you on how the topic will apply to you, and tailor the presentation to meet your needs. We can provide a laptop for you to use during the course - but you are just as welcome to bring your own so that you'll be learning a new skill, but from your own familiar desktop.
But we're not just business. Melksham is set in the beautiful county of Wiltshire, and tourists coming to see Lacock (4 miles), Devizes (6 miles), Corsham (also 6 miles), Avebury and Silbury Hill (10 miles), Bath (12 miles), the White Horses, Longleat, Stonehenge ... are welcomed guests. As are visitors and exhibitors to TrainWest which runs at Melksham each year,to the Town Crier's competition, to the Party in the Park and the Melksham Carnival ... and visitors in town for friend's and relative's christenings, anniversaries and weddings.
Many of our hotel guest come back time and again. Many of our delegates come recommended by colleagues, and we have a saying "come as a student, leave as a friend". We look forward to welcoming back many familiar faces in 2011, and to meeting many new faces from some very familiar organisations.
Posted by gje at 08:45 PM | Comments (0)
Related topics: via article database
More about Graham Ellis of Well House Consultants
Useful links: Python training, Linux training, Lua training, Perl training, PHP training
December 30, 2010
Transwilts Link - both Wiltshire and beyond
Here's a personal list. Places I've traveled to this year - and they're all places that have not been purely for pleasure. Acton. Antrim. Avebury. Bank (London). Bath. Belfast. Birkenhead. Bradford-on-Avon. Bristol. Bristol Airport. Cambridge. Chippenham. Devizes. Dublin. Glasgow. Heathrow Airport. Henley-on-Thames. Horsham. Lacock. Lymington. Melksham. Norwich. Nurnberg. Oxford. Plymouth. Poole. Portsmouth. Radstock. Reading. Salisbury. Southampton. Southampton Airport. Stonehenge. Swanwick. Sway. Swindon. Taunton. Trowbridge. Warminster. Washington (DC). Westbury. Yeovil. The list is illustrative of the very wide range of journeys that people make - and that's where it's not just me making the journey - lots of people travel. I've welcomed people here from places as wide ranging as Llandrindod Wells to Greenwich, Chicago to Kuala Lumpur, and Chatteris to Motherwell.
Why the list? To show just how wide ranging the travel requirements can be for each of us individually. So that means there's a need for travel and transport systems to be able to provide for a disparate range of journeys - realistically with many of them involving changes of mode and connections along the way. And with good information too about the options available, how much each costs, and how to arrange it. More of my journeys that I would like have been made by car - it's the most flexible, often the fastest end to end, and there are few timing limits. BUT it burns up a lot of fuel (not green!), it can be tiring and enraging, it wastes time as I can't do things I want to (like read) as I travel, it can be expensive, and I've got to work out what to do with the car at the far end. And of course I'm fortunate enough to be fit enough to have a driving license, and well off enough to afford to run a car.
We're oft told that "Wiltshire is a rural county", and I've oft wondered what that means. The majority of the land area in Wiltshire is fields and woods - countryside - that's for starters. You'll find bats and badgers, foxes and deer, rats and other rodents ... but they don't need to travel. Staggeringly, over 70% of the population of Wiltshire live in the towns and City (and the percentage is higher if you include Swindon, which is postally still in Wiltshire). And if you look at travel-to-work, travel-to-shop, travel-to-learn, travel-to-healthcare, you'll find that the vast majority of journeys of over a mile are going to end in an urban area. Taking the under-30% of village and hamlet dwellers, you'll find a fair proportion of them in "strip development" villages that ribbon major roads - the Sells Greens, Potternes, Beanacres, Atworths and Semingtons of the county - so perhaps only 1 in 10 journey ends is where a car, taxi or other demand-responsive system is the only option. So ... "Wiltshire is a Rural County" really means "look we mustn't overlook this minority access issue that doesn't apply within cities", but it doesn't wash as a reason for NOT supporting transport within an urban area, and interurban.
Where am I headed? That for the future we need to ensure that we have a properly integrated transport system, within and without Wiltshire. The world does not stop at Salisbury in the south, nor at Swindon in the North. We need to be looking at Links - TransWilts and beyond. Look at the congestion maps, look at the time that bus services take, and the logical backbone becomes the "TransWilts" railway line ... but it's only the backbone. The backbone needs arms and legs attached to it - so we're looking not so much at "TransWilts" but at "TransWilts Link", with the majority of journeys being made not on just a train on the Swindon to Salisbury line, but beyond as well.
Here's the first of several - first draft - "TransWilts Link" maps. This one is showing rail connections that are logically useful as a part of journeys that involve the TransWilts.
On this diagram WE NEED TO ADD ... other airport connections (Bristol, Cardiff, Heathrow via Reading Railair link) ... ferry connections (Weymouth, Poole, Lymington, Southampton and Portsmouth).
Which lines and stations to include is very disputable; I've taken an educated guess at ... here are some thoughts:
My intent is to show connections / journeys / stations that would be most popular off the TransWilts trains. Tempted (but resisted) lines to Exmouth, Barnstaple, Henley, Marlow, etc ... realistically not a huge number of through journeys / potential relative to a complex map. Or could thay be added in faded grey?
For consideration on the diagram ...
1. Move Swindon towards Didcot?
2. Add Gillingham, Sherborne, Honiton, Axminster ...
3. Add Cosham?
4. Split Exeter and Portsmouth
5. Add Ashchurch, Worcester (x2), Malvern Link and Gt Malvern
6. Add Winchester
7. Extra stations on Reading - Gatwick?
8. Oldfield Park and Keynsham?
9. Stations between Pen Mill and Dorchester?
10. "To mid / North wales" from Newport?
11. More in the Thames Valley?
12. Weston and Avonmouth / Severn Beach?
Note - Solid black - core TransWilts Link
Yellow and black - some through services
Yellow - connections
I'm really not sure how vital ferries are - I was shocked as to how poor the links were and how few passengers there were at Poole, Portsmouth, Birkenhaed and Belfast in the last few months and wonder if we push those as a major selling point we're showing that we're a bit out of date. Discussion Point. To Channel Islands / Isle or Wight - different matter?
Coach Links - Cardiff, Bristol and Heathrow Airports
Bus Links - out of area ... Minehead, Stonehenge, Portland, Swanage
Click on the maps to see them larger!
Here is a connection map - "version 0.9" if you like, as it's an early illustrative sketch - for Chippenham. The railway's shown in black, and there are think black lines from the station to places in walking distance for the typical traveler, and thicker blue lines for connecting bus services. Services shown are as at present and I've indicated those which are through the day / reasonable frequent.
Highlighted in yellow are major toens for which Chippenham is the railhead - that's Corsham, Malmesbury and Calne. It could be argued that I should have extended the Lacock line to Melksham, and branched off from Bowood to Devizes. There's also teh question as to whether the Calne line should carry on to Lyneham and Wootton Bassett.
Red markers show leisure / tourist spots. Areas of the town are also show circled - Rowden, Monkton Park, Cepen Park, Pewsham and Bumper's Farm.
Redrawn / printed with finer type as per the diagram above, further information could be added to this diagram; in the future, routes and links to information could usefully be added too
Posted by gje at 02:57 PM | Comments (0)
Related topics: via article database
Trowbridge and Melksham to Chippenham - more roadworks, even slower journey over the winter
I understand that Wessex Water are going to be replacing a water main in Beanacre from mid January until mid March, and that will disrupt traffic on the A350 - the major road which links Trowbridge and Melksham to Chippenham and the rest of the country via the M4. I didn't have to look back very far through my archives to find a picture of a previous jam in Beanacre - indeed we joke at times about the number of times there seem to be roadworks on the A350 between the Melksham and Chippenham.
For access northwards from Trowbridge, the A350 is by far the best route ... the alternatives of the A36 take you through very congested parts of Bath, via the A363 you do through the centre of Bradford-on-Avon, and via the A361 you'll have to pass the oft-jammed inner relief road in Devizes.
On previous occasions where there has been single alternate line traffic, road works in Beanacre have caused major tailbacks and delays to drivers of up to 30 minutes. And there's little point (speedwise) in taking the bus as it uses the A350 too!
There could be a good alternative ... there's a perfectly good railway line from Trowbridge (and Melksham) to Chippenham - and with the bonus that it runs on to Swindon too, which is another congestion and parking black spot. Problem is - as I write - that there are ony two trains each way per day - from Trowbridge at 07:07 and 19:37 (Melksham - 10 minutes later) returning from Swindon at 06:16 and 18:44 (Chippenham about 15 minutes later).
On these occasional trains, the journey time from Trowbridge to Swindon is about 35 minutes. By bus, the direct service via Devizes takes just over 90 minutes. If you drive a car, it will normally take 50 to 55 minutes, but that could be quite a bit longer for the next 2 or 3 months. It would make such huge sense for there to be a train service worthy of the name, now wouldn't it? See [here].
For any of the more technical types amongst you, this diagram on the left shows the congestion map published by the Department for Transport about 3 years ago, onto which I have superimposed the route of the railway line.
It's my understanding that this map shows a typical / averaged out measure of congestion - in other words, this is the sort of busyness that you'll find the majority of the time when there are not roadworks to distort the view. It's also my understanding that the provision of an appropriate train service would cost around the same amount of money (per annum) as 50 yards of high standard, but single carriageway, road ... and with good loadings on those trains, most of that money would be pulled back via fares anyway
Posted by gje at 07:54 AM | Comments (0)
Related topics: via article database
December 29, 2010
Public and private courses - subjects available for 2011
Sorting through old manuals, it struck me just how many tailored courses we've given over the years. Tailoring a course to suit customer needs is really very easy for us - all of our courses are modular, and when we're running a single customer / private course, we prefer to top and tail the course to meet the client's need, rather than just providing the best set from our repertoire. I doubt whether the following list is complete (and I know it doesn't even hint at some topics like Django and wxPython as they've not made the headline banner!) but is does give you an idea of our scope. If you have a requirement that you think we may be able to help with, please contact me via email (graham@wellho.net) or through our [contact form] and I'll be delighted to advise you / provide a more detailed course spec to meet your needs.
Curricula which will be running as public courses in 2011 are shown in the list with an [information] link. Follow that link for details of course content and scheduled dates to January 2010
• Languages of the web - Which Technology?
• Getting Public Sector Data online
• Fundamentals of Web Design
• Learning to program in Perl (Public course - [information])
• Perl Programming (Public course - [information])
• Introduction to Perl Programming for Developers
• Introduction to Perl Programming
• Perl Advanced Network Application
• Perl Basics
• Using Perl on the Web (Public course - [information])
• Using Perl on the Web through CGI.pm
• Perl Extras
• Perl for Larger Projects (Public course - [information])
• Perl Bootcamp
• Java Technology
• The Java Language
• Custom Java Advanced
• Java Advanced
• MySQL and Java - the middle layer
• Java Programming part 1
• Java Programming part 2
• Name services and J2EE
• Java Programming
• Java and MySQL for Web Server
• Using Java on the Web
• Java Programming for the Web
• Learning to Program in Java (Public course - [information])
• Java Bootcamp (Public course - [information])
• Java Extra
• Complete Java
• Professional Java
• Technology background for Tcl/Tk
• Learning to Program in Tcl (Public course - [information])
• Tcl Programming (Public course - [information])
• Tcl and Expect Programming
• Tcl Basics
• Tcl/Tk Programming
• Tcl - the Tk Toolkit (Public course - [information])
• Learning to program in Python (Public course - [information])
• An Introduction to Python
• Python Programming (Public course - [information])
• Python for Beginners
• Python Intermediate
• Introduction to Python Programming
• Technology for PHP
• Object Oriented Programming with PHP (Public course - [information])
• Object Oriented Programming in PHP
• Learning to program in PHP (Public course - [information])
• PHP Programming (Public course - [information])
• PHP Techniques (Public course - [information])
• Beginning PHP - weekend course / hobby / club / leisure users
• Intermediate PHP - weekend course / hobby / club / leisure users
• Object Oriented Programming in C++
• Programming in C (Public course - [information])
• C and C++ Programming (Public course - [information])
• C++ Programming for C Programmers (Public course - [information])
• Learning to program in C (Public course - [information])
• Learning to program in C++ (Public course - [information])
• Learning to program in Ruby (Public course - [information])
• Ruby Programming (Public course - [information])
• Introduction to Rails
• Ruby on Rails (Public course - [information])
• Learning to program in Lua (Public course - [information])
• Lua Programming (Public course - [information])
• Deploying LAMP (Public course - [information])
• Deploying LAMP (Volume 1)
• Deploying LAMP (Volume 2)
• Deploying LAMP - Linux, Apache, MySQL, Perl/PHP
• Deploying Apache and Tomcat (Public course - [information])
• Deploying Tomcat
• Tomcat and connectors to httpd
• LAMP Deployment
• Linux Basics (Public course - [information])
• Linux Bootcamp
• Linux and Apache Httpd
• Linux Web Server (Public course - [information])
• Linux Administration
• Linux Admin Overview (Public course - [information])
• Linux Basics and Administration
• Deploying Java Applications on Linux
• Deploying Web Applications under Linux (Volume 1)
• Deploying Web Applications under Linux (Volume 2)
• Deploying Java Applications under Tomcat / Linux / Unix
• Korn Shell Programming ([more info])
• Unix, Linux and Korn Shell
• Regular Expressions (Public course - [information])
• The MySQL Relational Database
• MySQL (Public course - [information])
• Cascading Style Sheets ([more info])
For 2011 ... prices remain unchanged from 2010. £350.00 (first day) the £250.00 (each subsequent day) for a place on a public course. Rooms available for public course delegates at our Melksham hotel - £60.00 per room per night, including breakfast. Private courses start from £950.00; examples - 2 day course for 10 delegates £174.00 per delegate per day (Bristol, England) - 5 day course for 12 delegates £168.00 per delegate per day (Glasgow, Scotland) and that includes all travel and setup costs for the tutor. Prices quotes are exclusive of VAT. Private courses are also available in Ireland and (in English) on the European Mainland.
Posted by gje at 05:12 PM | Comments (0)
Related topics: via article database
December 28, 2010
TransWilts Link - Days out from Swindon to Weymouth?
Fancy a day trip to Weymouth? Over the past few days, I've been looking at possible timetables for an improved "TransWilts" service - with a particular view to connections beyond the area. Call it "TransWilts Link" if you like. There was a very great deal going on in the five weeks before Christmas - see the speech by Duncan Hames (our MP) in parliament on 21st December ([here]) as an example, and there's a lot going on for the next five weeks too.
The draft timetable proposal from 2009, with some minor amendments to fit in with recent minor amendments to other services, is back on the table. And the GOCO proposal - for open access services from Yeovil via Oxford to the Midlands is also alive ;-) - see [here]. Working together, these proposals would make a significant move - taking us about halfway from where we are towards the appropriate service that's got such a good BCR (benefit / cost ratio) in the GWRUS (Route Utilisation Strategy.
| Swindon | 08:20 |
| Chippenham | 08:36 |
| Melksham | 08:45 |
| via "Heart of Wessex" to | |
| Yeovil | 09:54 |
| Dorchester | 10:26 |
| Weymouth | 10:42 |
| Weymouth | 17:56 |
| Dorchester | 18:09 |
| Yeovil | 18:44 |
| via "Heart of Wessex" to | |
| Melksham | 19:49 |
| Chippenham | 20:02 |
| Swindon | 20:19 |
I think that looks rather good - and it's just the first of many, many such options!
Update - June 2011. I have revisited and updated this page. We have a SUMMER SUNDAY service, very much along the lines suggested, and in runs on 3rd and 17th to 28th August. The trains will be through trains and I have altered the train times shown (by no more than 15 minutes) to mirror the actual new timetable. I'm not a great lover of going back and changing historic blogs, but have done so in this case to avoid confusion and people arriving at the station just after the train has left.
Posted by gje at 11:22 AM | Comments (0)
Related topics: via article database
December 27, 2010
The days after Christmas

The period between Christmas and the New Year is a quiet one for business - and it gives us a chance to catch up on a few lot of things, and to recharge our batteries too. Picture, earlier today, Lisa and Graham getting mixed up between work and play, and Gypsy asking which of us is going to take her out.
From previous messages, you may be aware that we have network connections both sides of the bed ... but they've slipped into disuse as we're now running wireless. But we have invested in a couple of extra power supplies for our laptops so that we can plug in and charge up any time / ovenight.
The white of Christmas is turning into a brown and green as the snow melts, there's signs of a thaw in our frozen drains, and come the morning I'll be tacking piles of housework, paperwork, and writing.
Posted by gje at 10:40 PM | Comments (0)
Related topics: via article database
December 26, 2010
A weighty decision
We like to keep the computers that we use for training - both the machines that we use for presenting courses, and the machines that our delegates use during courses - up to date. And that means that every couple of years we renew our fleet - pensioning off machines which in truth probably still have plenty of life left in them, and superseding them with models that will take us forward with a "wow" factor over the coming years.
When Well House Consultants bought its first fleet of systems - 10 years ago this year - we were amongst the first to elect to use laptops rather than desktop systems. Yes - they were more expensive per system, but it allowed us to train on site much more easily, and to save on shipping and hotel costs. And it also left more delegate's desk space free for book, manuals, and notes ... not to mention allowing a far better view of the tutor for everyone, rather than skulking behind a cpu box and screen. We've continued to use laptops - the "sea mammal" series, the Indian Cuisine series, the days of the week, the flowers and (currently) the Wiltshire towns series - and the formula has stood the test of time. But it's looking a little long in the tooth now - a little "me also" - so what should we do for the future?
More and more delegates have their own laptops. They want to use them during courses and (unless we're doing security / Linux Admin / Server Admin) it's good and sensible for them to do so. And to facilitate that, we provide DNS and DHCP servers to connect them in, with broadband routing so they're on line at all times. Gone are the "stand alone" days, and even when we're on site, we're usually on line through the mobile phone (3G) network. So do we need to provide all the computers? And what do we need to provide?
Let's say I'm traveling onsite with the current fleet, to train 8 delegate. If I'm carrying enough computers for 1-per-person, plus a couple of spares, that's 25Kgs of computers and 4Kgs of power supplies. Looking back 6 months, add to that two MacBook Pros (17") for my own use and that added a further 7Kgs. Then add in a projector, multiways, mice and manuals for each delegate - for a 3 day course, each manual may weigh 800 grams (250 pages), so that's altogether an extra 10Kgs. Network hub, cables, reference manuals - say another 8kgs and all told you're looking at 54kgs. Which is rather too heavy to fly, and even too heavy to go by train.
Let's see how we can change that; let's think about carrying smaller 'netbook' computers for delegates who wish to use our equipment, and let's continue the move to MacBook Air's for my own systems. Let's rely on wireless networking throughout too.
• Netbooks, including spares - 14kgs + 3kgs of power supplies
• MacBook Airs - 2.5kgs
• Projector, multiway, mice, manuals - still 10kgs
• Reference books, etc - 5 kgs
So we're down to 35kgs - there may still be some further small reductions, but we're not considering compromising the quality of the paper we use for the manual, nor the ability for us to provide machines for each delegate. What we are doing is using current (in some cases state of the art) technology to provide better resources, (which will cost us more), but then to save on travel and transport hassle and costs.
Historic Note - "First Alternative" [link] days up to summer 2000
Sun SparcStation 5 - c.p.u. box 10kgs (I have just weighed one!)
Sony Triniton Monitor - around 30kgs (Too heavy to get out of the loft!)
Keyboard, cables, etc - say 2kgs
I used to travel in a "people mover" with a wide rangs of Sun Kit - Sun 3/50, 3/60, IPC, IPX, SparcStation 1 and 5 - up to 42 Kgs per unit; perhaps an average of 30 Kgs - giving a total weight of 8 systems (we never carried a spare in case of failure; too expensive!) of 240kgs. Add to that networking equipment and multiways (10kgs), viewfoil projector (5kgs), viewfoils(5kgs), manuals (7kgs - yes; they were smaller and on think paper) - and you've a total weight of some 270kgs.
The image accompanying this article shows the relative size od a SparcStation 5, a laptop of about the size of the ones we use, and my MacBook Air which is even smaller that the netbooks that we're considering. Click on the image to enlarge it ...
Posted by gje at 04:37 PM | Comments (0)
Related topics: via article database
My First Christmas
Proud Grandfather is allowed to publish pictures of Granddaughter occasionally, even though this blog is really about hotels, open source, Melksham, trains, and other similar topics.
Click on the image to see her larger, in another window
Delene, Chris and Aeryn came around yesterday afternoon; Aeryn's just seven weeks old, so it's her first Christmas!
Posted by gje at 01:02 PM | Comments (0)
Related topics: via article database
Hotel and Training Course prices - the effect of the VAT rise on 4th January 2011
Our training course rates for 2011 will remain (net) unaltered from 2010 - although the VAT increase from 17.5% to 20% means that invoice totals will rise slightly. Most of our customers can reclaim VAT. Hotel rates - quoted inclusive of VAT - rise slightly to reflect the extra tax - £85.00 double room as single occupancy, £95.00 double room / double occupancy, and £72.00 delegate rate. All rates include superior continental breakfast.
We are ... doubtful ... as to whether British commerce and industry as a whole will simply amend their prices to reflect the new VAT rate, or whether a whole lot of them will take advantage of the need to change prices to sneak in a rise in the next (pre-tax) price too, leading to inflationary pressures. So our formal quotation pages will only tell you that our new prices are valid for bookings confirmed by 31st March. I really hope that I can extend them at that point to June, September and then the end of the year, but at this point there is an unpredictability, and no need to make a decision we could regret.
It's at times like this that I'm really thankful that our website is largely parametrized, and that I've been able to make the changes in just a few placed to have the show up all through the sites. You should find prices correct and consistent for 2011 across the board at our main sites ...
Well House Manor, home page - [here]
Well House Manor, room by room - [here]
(and the change is reflected by template into the rest of the site!)
Secure hotel bookings - [here]
Well House Consultants, Company Details - [here]
Well House Consultants, staff reference page - [here] - we see more detail when logged in!
Secure course bookings - [here]
As always, the "devil is in the detail", and there is talk of prices in our Wiki, and I have mentioned them quite often in the blog. So I've ended up taking much longer that the work above took in order to make sure that people don't get old prices offered to them appearing to be current, while at the same time maintaining the archive nature of many of the blog articles - and that required individual updates at times!
Here are links to just *some* of the pages I have updated this morning:
• Bargain return visits for past delegates - [here]
• A Friendly hotel - [here]
• Previous VAT change effects - [here]
• Hotel prices for a new decade (2010) - [here]
• Customer review - [here]
• Do we have a night porter - [here]
• Comparison of our training to other suppliers - [here]
• Pictures of hotel rooms - [here]
• Winter Weekend Special - [here]
• Prices as they were in 2009 - [here]
• How we handle phone calls - [here] (really a staff page)
• How we handle walkins - [here] (really a staff page)
Posted by gje at 12:15 PM | Comments (0)
Related topics: via article database
Buckets
"What is a bucket?" ... A question asked during a recent programming course, and probably not one to answer along the lines of "an open topped plastic or metal receptacle to catch, hold or transport water, sand or other materials." In programming terms, a bucket is a software unit of memory allocation, often on the heap - very much more that a bit or a byte. [OK - perhaps I had better explain "heap" too!]
Programs need to dynamically allocate memory to store data as they run - for as a program is written, the programmer won't know how much data may be used in due course through the program at any one time. So the variable storage memory is usually arranged into a symbol table which holds the names of the variables currently in use, and an address where the values associated with may be found, and a heap which is where the actual values are held. The heap can grow in size as the program runs, so that there's no need in modern languages to code with limits and fixed sizes, and heap memory can also be released (when a variable isn't needed any more or has shrunk in size) for re-use by other variables. [Due to operating system constraints, the heap can't usually shrink].
If all this clever heap 'stuff' was done by allocating memory on a byte by byte basis, more space and time would be taken up administering the memory use than doing the actual work, so the allocation is typically done using larger units - and each of these larger units is called a bucket
You rarely see bucket allocation details, even as a programmer - it's too low level. But one of the places that you can see it is within Perl's hashes - if you refer to a hash in a scalar context, you'll get a result like
3/8
which means that the hash has 8 buckets allocated to it, and of those three are currently occupied with data. It's also interesting to watch as a perl hash grows, and see the hashtable being resizes as it gets almost full, with the number of buckets allocated being doubled and redoubled ...
for ($k=1; $k<4000; $k++) {
$fing{$k} = $k + 55;
print ("$k - ",($n = %fing),"\n");
}
gives the following results:
1 - 1/8
2 - 2/8
3 - 3/8
4 - 3/8
5 - 4/8
6 - 5/8
7 - 6/8
8 - 7/16
9 - 8/16
10 - 9/16
11 - 10/16
12 - 10/16
13 - 10/16
14 - 11/16
15 - 11/16
16 - 14/32
17 - 14/32
18 - 15/32
Finally, it's interesting to note a considerable increase in the number of buckets occupied each time the size of the hash is increased, indicative of the use of a longer hash key as the size of the hash table increases.
This code - in a complete example - is available [here]. The image is adapted from Free Clipart Now - "a large collection of high quality, public domain clipart graphics for presentations, web pages, documents, emails...".
Posted by gje at 08:22 AM | Comments (0)
Related topics: via article database
Adventure with references to lists and lists of references
I remember an old game I used to play on DEC 10 (and VAX and PDP-11) computers - the original adventure game, perhaps ([see here]) which was pure text / instruction based and you traveled North, South, East and West through the colossal cave. And there was one are - the maze - where you could get rather lost between a little maze of twisting passages, little maze of twisty passages, little twisty maze of passages, maze of little twisting passages, maze of little twisty passages, maze of twisting little passages, maze of twisty little passages, twisting little maze of passages, twisting maze of little passages, twisty little maze of passages and a twisty maze of little passages!
And I was reminded about that the other day when I was differentiating in Perl between a list of scalars, a list of references to scalars, and a reference to a list of scalars.
A series of scalars - held in a collections that's ordered (numbered from 0 upwards and sortable) is a list in Perl ... and you can create a list of scalars using round brackets:
@numbers = (10,20,30,40);
If you want to hold pointers / references / addresses of scalars rather than the scalars themselves in a list, you'll add an extra \ character:
@again = \(10,20,30,40);
In Perl terms, that looks like a single pointer to the list but it's not - it's an exception to the usual syntax, and it returns a whole list of pointers.
If you're really looking for a single pointer to a whole list, you'll use square brackets:
$further = [10,20,30,40];
So ...
A list of scalars (@numbers):
10 20 30 40
A list of references to scalars (@again):
SCALAR(0x100800f20) SCALAR(0x100800f30) SCALAR(0x100800f40) SCALAR(0x100800f50)
and a reference to a list (of scalars, but we can't tell that from the output) ($further):
ARRAY(0x10082c270)
There's an extended example - showing how hashes and references to hashes and context fits in too - [here].
Posted by gje at 07:32 AM | Comments (0)
Related topics: via article database
December 25, 2010
Catering in Syracuse, the Saigon Cafe, stolen images and Christmas
It was - indeed - a lovely buffet that we laid on at our old training centre in 2005 during a Perl course. So we took a picture of it, and included it in our slide show. Other, too, loved the picture and "hotlinked" it from our site into their various Plurks, to the extent that we were getting up to 10,000 downloads a day. (See [here]).
Hotlinking is a pretty crude way of stealing an image - it's visible to the owner of the site from whom the picture is stolen, and it becomes very obvious if the traffic levels are significant and the host site is a highly specialized one like ours. A much more (I'm choosing my words carefully) disguised way of using someone else's image is to save a copy onto your own site - for your site won't show up in the original site's log each time someone visits your page. And re-hosting also means that the original site is no longer able to delete / amend the image with a knock-on effect onto your page. Note that if the image is copyrighted, which the buffet lunch picture is, taking a copy and pretending it is your own is also theft - just a harder theft to trace. Or so I thought ...
I've come across a site called "Tineye" - at http://www.tineye.com/ - which offers a reverse image search. And it seems to be rather clever (much more clever than I would be) in that it can pick up duplicates from all sorts of places that it's crawled, even if they have been somewhat manipulated. I wonder what I can find for that buffet lunch ...
Click on any image to have it open, original size, in a new window. Follow any of the sites I've mentioned and you should link to the page - though they will change over time I expect!
From fibromyowgia.wordpress.com - a health meal for people with a medical condition, with the picture being used as illustrative material for a personal page. I'm not too fussed about such a (mis)use - just wish the folks had bothered to read our copyright page and get in touch as described [here].
From www.tiffanyscatering.com. Now this is very naughty, Tiffany's Catering Company of Syracuse, New York State, are using our picture and suggesting that its the sort of thing they provide. In the UK, I think they would be breaking the Trade Descriptions act as well as having stolen the image, and we have certainly never been called up from Melksham to serve lunch upstate New York!
From www2.dinhduong.com.vn. Oh gosh - not in English (nor French nor German); the clue is in the .vn (Vietnam) top level domain. But that's clearly a Well House Consultants Vintage Buffet Lunch again!
From www.canteen.yoyo.pl. ... and another ... this time from Poland. Nice clear use of the image, not distorted by size or recoloured!
From www.sodahead.com. A forum entry this time; I'm not totally happy that we may be seen to be supporting the forum message, but it's Christmas and I'm going to let this one and all the others pass ... but just beware of how stolen images are so commonly traced these days.
From www.vietbalo.vn/ And we have a second site from Vietnam - this one appearing to be much more professional, and even showing a seasonal message (I didn't know they had snow in Vietnam, nor that Santa came to call on a sleigh!)
Do I want to read the message that's being written alongside my picture? Too right I do! I understand a little American ;-) ... so I can see what Tiffany's Catering Company are doing ... but I don't understand Vietnamese. Google Translate to the rescue! It's at translate.google.com and you can pass in a URL and get the page translated between a wide variety of languages - not perfectly, but you can get the drift of what's being said.
Here is a rather better translation from Vietnamese to English - probably better because the original text may have been in Queen's Vietnamese (Chairman's Vietnamese? VBC Vietnamese?) and ... what do we have. They're using my image to sell the French buffet at the Saignon Cafe, Sheraton Hotel, in Ho Chi Minh City. Then they add the word "illustrative" to as if to say "this isn't really what you get!
You may have noticed that one of the earlier illustrations had a copyright on it. So - am I breaking copyright rules here by reproducing these pages - am I standing in a greenhouse and throwing stones? I don't believe that I am - the copyright in each of the buffet pictures above is mine, and around it I'm just showing a little decoration to put it into teh context for critical review, which is very much within the rules.
Ah - the Polish one, translated into English. Now - I admit it - I'm amused. The idea is that you can eat as much of a virtual buffet as you like, and you won't put any weight on. You can use this site to send a virtual cake - or other food gift - to anyone, without any fear that you'll end up being responsible for them putting on weight.
Christmas is a lot about food; I'm posting this late on Christmas eve to give myself time to prepare breakfast (hotel) and dinner (home) tomorrow - and that will be real rather than virtual food (so we can and possible will overdo it!). Please ... do feel free to have a look around the virtual world of our website, which like the Polish buffet is free and won't harm you however long you stay. But - if you ARE reading this on Christmas - spend some time with your family. If you happen to be alone today, and in Melksham, knock on our door / ring our bell. We'll have food to spare, and no-one should be alone at Christmas.
Happy Christmas, everyone!
Posted by gje at 12:07 AM | Comments (0)
Related topics: via article database
December 24, 2010
Thank you - and Happy Christmas
A personal, big, THANK YOU to all of our customers, and all our staff, for everything they've done for Well House this year, and a very happy Christmas to one and all.
A business wouldn't function without customers ... and it wouldn't be such a pleasure to run without such great customers. Almost without exception, our customers make it a pleasure to get up in the morning, to prepare you breakfast, to teach you, and to welcome you in the evenings after your journeys to Melksham. And you make it so easy for us to keep enthusiastically busy by being our ambassadors - by telling people about what we do and how we do it - both in hotel and training course terms. A significant proportion of our customers come to us on the recommendation of other customers - and that's something we really appreciate, and for which I cannot say "Thank You" often enough.
A business wouldn't function without excellent staff either ... and that's where Lisa and I owe a huge "Thank you" to the team. You - Rachel and Sarah, Kim, Heather and Ann, Chris and Phil - ALL - are appreciated much, much more than I may sometimes say. Without exception, everyone is 'looking out' for the customer - looking to give the best possible service and value and make all of our visitors totally at ease and totally welcome. And, again without exception, Lisa and I know that we can place customers, and "The Manor" or "404" too, into your capable hands and know that you'll take good care of them - considering not only the immediate actions to be taken, but also the effect of those actions on the rest of the team and the business. I'm really proud of you.
It's Christmas Eve, and being a business-to-business operation for the most part, we're looking forward to a quiet Christmas and New Year. There *will* be somebody around much of the time to answer emails and telephone, check guests in, etc, but most of the team will be taking a well earned rest. We're busy again from checkin time on January 2nd, and we look forward to welcoming delegates for the C and C++ course that first week, and hotel guests who'll be working at Bowerhill and Hampton Park in Melkhsam once business visits start up again in the new year.
So - have a Merry Christmas, and a Happy New Year - you've earned it. Lisa and I look forward to welcoming you, and to working with you, in 2011.
Posted by gje at 08:08 AM | Comments (0)
Related topics: via article database
AND and OR operators - what is the difference between logical and bitwise varieties?
Many modern programming languages have two operators for "or" and two for "and" - described as "bitwise" and "logical" operators. And you need to choose the right one in the right circumstances ... otherwise your code won't behave quite as you expect.
Bitwise OR takes the internal bit pattern of the two expressions / variables passed into it, and combines them bit by bit, setting a true (1) bit on the output if either of the incoming bits in the corresponding position is true. For example - illustrated with integers on a 32 bit system:
00000000000000000000000000010111 is 23 in binary (internal) format
00000000000000000000000001000011 is 67 in binary (internal) format
Bitwise "or" gives
00000000000000000000000001010111 which is 87 in binary (internal) format
Logical OR looks at each of the two incoming expressions as a whole, and if either of them is considered to be "true" in the language you're using, it returns a true result. But if both of the incoming expressions / variables are considered to be false, then a false result is returned.
99 times in 100, you'll want to use the logical OR rather than the bitwise OR in your code. "If the temperature is under 0 degrees OR if it is snowing" is a logical decision, for example - and most code requirements that combine conditions are comparisons like that. Uses of bitwise OR include setting up of masks (such as with file locking or selecting channels in Perl, and with regular expression modifiers in Python), and if you're doing low level computer graphics work, where a 32 bit byte may represent 32 pixels in a frame buffer, and you want to turn on extra bits as you draw a vector / fill an area on an image you're generating.
There is a similar differentiation bitwise AND and logical AND ... and it's with these that you can get badly burned if you use the wrong one. Consider 23 and 64 ...
• Logically, the result is TRUE
• Bitwise, there are NO bits set in both number, so the result is 0 which is usually FALSE (when misused in a logical context)
The really nasty snare here is that with most inputs, a bitwise and will return a true, lulling you into a false sense of security as you test your code.
In Perl, you have the following bitwise operators:
| bitwise OR
& bitwise AND
^ bitwise exclusive OR (XOR)
~ bitwise NOT (compliment)
<< bitwise left shift
>> bitwise right shift
and you have the following logical operators:
&& logical AND
|| logical or
and also logical AND
or also logical or
! logical not
and you'll find it's very similar in other languages such as C, C++ and PHP. There's an example of each of them in code, and sample output too, in our programs directory - [here].
With Python (which I might describe as a "post modern language", you only have a single operator for "or" and a single operator for "and" - they are | and &. The object type to the left of the operator determines if you're calling for a bitwise or logical operation.
Posted by gje at 06:50 AM | Comments (0)
Related topics: via article database
December 23, 2010
The week before Christmas
The canal at Devizes earlier today as we passed through. You'll see from the ice that we weren't passing through by boat, nor was anyone else
From the Perl for larger projects training course - a diagram to illustrate the problem of "diamond relationships". This is where a module "a" loads a module "b" and a module "c" and BOTH of those try to load module "d". This would lead to horrible double definition messages if it was allowed to proceed, but Perl's use operation looks at the %INC hash when asked to load a module, and only loads it if it's not already been done.
We're doing a whole load of inventory control work at Well House Manor - our hotel - and we couldn't find a picture of Elm Farm Yogurts online. Solution - take one ourselves.
Even in the snow, there have been lots of comings and goings by train at Melksham this week ... and at this time of year, all of our trains are in the dark. This is Tuesday's 19:47 to Swindon - 7 people on the platform, and a class 150 train in the old "Silverlink" colours from a different time and a different part of the country.
Some of the old equipment that's use to add atmosphere in the outlet centre in Swindon - yes, it was Christmas shopping day today!
Just some varied pictures from the last few days. A brief - and excellent - bite to eat "al Kitchen" with Kim this evening, and an early night; I'll be looking to hit the 24 hour supermarket VERY early in the morning for food supplies. It really feels like Christmas!
Posted by gje at 07:42 PM | Comments (0)
Related topics: via article database
Looking ahead and behind in Regular Expressions - double matching
Look-ahead and look-behind are a way of "double matching" in a regular expression. If you're at a certain point in the match and you think "the next bit should conform to xxx and at the same time it should conform to yyy" then you can describe xxx via a look-ahead, and follow that with matching yyy in the usual way.
Using Perl syntax for this example:
$journey =~ /\w+(?=\w+,)ing.on/;
This says ... ""I'm looking for word characters. They are to be followed by more word characters ending in a comma. They are also to be followed (a second match against the same part in the incoming string) by "ing?on" where "?" is any one character.""
You can look ahead and look behind. And you can negate the result too. That's actually much more useful that the positive look ahead - allowing you to exclude special cases:
$journey =~ /\w+(?!ingt)ing.on/;
Which says ... ""NOT ingt but ing[somethingelse]on"".
There's example of all four possibilities (lookahead, lookbehind, positive and negative in each case) in a new example - written as a follow up to a question on yesterday's Perl for Larger Projects course - source code [here]. It's been quite the season for lookahead / lookbehind - there are other new examples in Python [here] and [here].
Are these facilities useful? Yes - on some occasions they can be, but there are often better alternatives. If you look at my simple examples, the same thing could be achieved in a much more straightforward way using more commonly understood regular expression elements, which will be easier for people less into the depths of regular expressions to support. And it's often very much the case that two simple regular expression matches are better (faster, easier to maintain) that one complicated and obtuse one.
Posted by gje at 08:17 AM | Comments (0)
Related topics: via article database
December 22, 2010
Perl - database access - DBD, DBI and DBIx modules
Perl's DBI module provides an excellent link from SQL databases to Perl, and the assorted DBD modules that fit underneath it allow it to operate well for a whole lot of different databases. But they are only excellent as far as they go - for the SQL statements have to be generated in your application code, rather than keeping the database instructions clear of your code. Enter the DBIx module, which provides an interface from Perl language variables to database tables. Using DBIx (which calls DBI then DBD internally), you can extract the SQL from the application and generate it, encapsulated, within the DBIx classes.
The diagram shows - in the top line - how you need to code both your application and your SQL to application translation if you do not use DBIx. In contrast, the bottom line shows how you only need to code your application if you use DBIx.
I've started with a "Control" example - showing direct access to an SQLite database through DBI and DBD - source code [here] (and there's an older version using MySQL [here]). You'll note if you look at this code that it's quite short, but contains all sorts of SQL statements.
My second example uses DBIx. Look at this:
my $schema = D2::Main->connect('dbi:SQLite:d2_test.sqlite');
my @teamadditions = ( ["Tom", 5], ["Jerry", 6]);
$schema->populate('People', [ [qw/name pid/], @teamadditions ]);
Those three lines of application code ... which contain no SQL ... add two rows to an SQL table using DBIx. The source code (with two use statements to complete it!) may be found [here].
The "magic" of DBIx is in one of those uses - that pulls in separate datatype definitions:
package D2::Main;
use base qw/DBIx::Class::Schema/;
__PACKAGE__->load_namespaces;
1;
Which in turn pull in the table definition:
package D2::Main::Result::People;
use base qw/DBIx::Class::Core/;
__PACKAGE__->table('people');
__PACKAGE__->add_columns(qw/ pid name /);
__PACKAGE__->set_primary_key('pid');
1;
(You can download these two files [here] and [here])
The final file for this application - which sets up the database and some initial test data - is [here].
You'll find sample outputs from the programs, and details of how to run it, in the first file - and it's a straightforward and complete DBIx example; I'll go so far as to say it's the simplest I've seen around as the examples in the official documentation show off a lot more facilities - but set the hurdle far higher for you when you first want to try DBIx.
I have allowed myself to add further complexity (generating selects with joined tables, sorting my output, etc) in my third example. Once you've tried the example above, have a look at this set of files:
SQL to set up the tables - [here].
The main application, showing two examples of data extraction - [here]. INCLUDES SAMPLE RUN and DOCUMENTATION
The model loader - [here].
Defining a table of computers (and how it relates to a people table) - [here].
Defining a table of people (and how it relates to a computers table) - [here].
Once you get the hand of DBIx, it's a nice way to help keep the model layer in its own compartment, though you still need to know SQL subjects such as database normalization to come up with good designs. We're covering Perl to Database interfaces on this week's Perl for Larger Projects course, and we also cover it briefly on the more introductory Perl Programming Course. The DBD and DBI modules are usable by people who are quite new to Perl; some of the DBIx data structures, though, are rather ambitious for the first week - easy to use once you know them, but perhaps not too easy to learn.
Posted by gje at 02:58 AM | Comments (0)
Related topics: via article database
Useful link: Perl training
December 21, 2010
Learning Object Orientation in Perl through bananas and perhaps Moose
Perl has the most incredbible range of OO facilities (though at times it's overfeatured and a bit old fashioned / tricky to use). So yesterday I wrote a whole series of examples ... and then went on to explore Moose - a module which adds extra keywords and lets you define your classes in a shorter and somewhat more conventional way. See [here] for the moose series - this post introduces the standard facilities in a series of examples.
Bananas.
Our supplier for the hotel provides three types - best bananas, large bananas and small bananas ... "best" are priced per kg, "large" per fruit, and "small" per bunch ... which makes life interesting when we do stock controls and start looking at supply usage, but it did provide a very useful example for yesterday ...
Here are the examples
Setting up a package of hash references - [source]
How to bless the references and thus turn them into objects - [source] - First practical example
Notifying the caller of where errors are triggered in his code via carp, croak and confess - [source]
Use of the caller function to examine the stack frames - [source]
Base class, subclasses, inheritance - [source] First example that shows how we do polymorphism in Perl
How we can use the Universal superclass to find out what our object is / what it can do - [source] can lead to poor class design!
A factory method to construct objects indirectly - [source]
Perl 5's OO facilities are covered on our Perl for Larger Projects course - where we cover OO principles too as necessary. Moose can be introduced on private courses (it's a bit of an interim thing prior to Perl 6 though), or if you're on the public course let me know you would like to cover it and I'll run an extra session one evening.
Posted by gje at 08:18 AM | Comments (0)
Related topics: via article database
Useful link: Perl training
December 20, 2010
Making Perl class definitions more conventional and shorter
Perl 5's object oriented capabilities are excellent - but often a little longwinded, and quite easy to get wrong. Moose sells itself as "postmodern object system for Perl 5 that takes the tedium out of writing object-oriented Perl"; it's available for download from the CPAN under same license as Perl itself, and provides a good solution for certain groups of people. There does, however, seem a lack of "start here" examples ... so I've added a few to the web site.
Simplest Moose class - setting up an automatic constructor with two properties - [source].
Adding default values - [source].
Using Moose to check data types - [source].
Calling automatically generated functions, and with read only and read-write settings - [source] This is the first practical example as it sets up the access to properties via methods rather than direct variable access
Inheritance (using the extends keyword) and roles (i.e. interfaces / the requires keyword) in Moose - [source].
Getters, setters and defaults in Moose - [source].
Additional functionality - adding a second method with the after keyword - [source].
Would I use Moose on a project? If there were many classes to be written, and I was writing from scratch I might well give it some careful thought. It is just a wrapper around a blessed hash, but sometimes the wrapping can make all of the difference!
Posted by gje at 09:16 PM | Comments (0)
Related topics: via article database
Useful link: Perl training
Contrast in pictures
I need to learn a bit more about some of the special settings on my camera ... and to re-train myself to think "settings" as I take pictures; at present, I just snap away with either the regular setup, or "available light" which gives me nighttime pictures that would have been regarded as miracles just a few years ago - in the days when we used a crude system of silver based chemical to record our images. Pictures such as the one I took at Melksham Station for yesterday's article ([here]) would have been impossible - the moving people being just blurs, and the picture of the presents hanging in the tree would have required a tripod which (as I took the picture from the road) would have been risking life, limb, and the rage of drivers.
But although there are some marvelous things I've done with the camera, at present (my own lack of knowledge?) I struggle with contrasty situations like Gypsy in the snow. I *have* tried changing contrast levels with Gimp - but they reveal that the black truly is black - there's nothing there. (See also my "Testing on Animals" post).
No animals were harmed in the production of this article - in fact Gypsy loves playing in the snow!
Posted by gje at 05:42 AM | Comments (0)
Related topics: via article database
December 19, 2010
The Christmas Season has arrived
Remember that song - "It's beginning to look a lot like Christmas". Well - in many ways it feels like it's already the Christmas holiday. There's snow on the ground, traffic is quieter, and it's bitterly cold. Phones are quieter (that's largely because we've changed our phone company and our number is no longer being sold to thousands of salesmen!), lights are up, and Santa has already been seen on the train and in town. I went out shopping for some food supplies to build up some stock for the next fortnight yesterday, and found Lidl surprisingly quiet; something to do with the snow keeping people at home, I suspect - I know from a phone call that Dad's not been out for a couple of days - unusual for him - and he warns us that the drive up to his house is treacherous (that's not new, mind you - you skid on leaf mould in the autumn there too!)
This coming week we *are* running a course - Perl for Larger Projects. Systems are already set up, and I did a station run to pick up a delegate a few hours ago; fridge is set for breakfast, and it's going to be a fun (and I rather suspect busy) week. We're hunkered down for three good days, although I *will* be out of town - up to Swindon - on Wednesday evening, weather allowing, for a pre-christmas meetup of some of our First Great Western Coffee Shop regulars. A strategic decision has already been taken to leave Melksham by car that evening even though it's a public transport gathering. The only train from Melksham would get up there after the group had moved on from the meeting point, and the bus 'connections' at Chippenham would leave us hanging around there on the return for up to 80 minutes. Yes - I'm a great fan of public transport (and would love to let my hair down and have a pint), but without properly integrated services, the opportunity is denied me.
I'm expecting to be surprising busy on the rail / public transport side over Christmas too - there appears to be windows of opportunity and political will that's a considerable improvement [note British understatement] of what's been there up to this point. In fact, I'm feeling rather overawed by the prospect, but at the same time thinking that we may just end up with all our ducks in a row at the same time, and that will open the combination lock so that - next year - Santa can open our new service, and we'll be able to get back from Swindon to Melksham when we want - even those of us who aren't fortunate enough to have our own private cars, or the health to be able to drive one of them.
Posted by gje at 10:47 PM | Comments (0)
Related topics: via article database
December 18, 2010
Setting your user_agent in PHP - telling back servers who you are
If your web page pulls information in from other sites, you'll be turning your web server into a client (browser) to those other sites - and just as your web server can identify the type of browser it's answering via the $_SERVER[HTTP_USER_AGENT] variable, so can the remote server.
The default user agent setting that PHP sends out is an empty string - it does not identify itself - and that will sometimes cause the server it's contacting to provide a limited response, or even (as I have see in one case) send back code 403 "Forbidden"s. So it's not a good idea to leave this default if you're contacting a wide range of web sites - for example if you're writing a crawler.
PHP's user_agent parameter can be set outside your application via lines in the httpd.conf file (for the whole of your site), or within a .htaccess file (for all applications in and below a specific web site directory). You can also set it on a "per application" basis within the application - for example:
ini_set("user_agent","Well House Robot - see http://www.wellho.net");
If you shouldn't use the default, then what should you use? I would suggest that you strongly and proudly announce your robot / site, and give anyone who finds you in their log files a link through which they learn who you are, and why you are on their site. And you should - of course - respect their robots.txt file too [see here].
It's also possible for you to set the user_agent to the same string that would be used by a browser - in other words, it's possible for you to pretend to be Chrome, Firefox or Explorer. If you are writing a script to test a site automatically and with permission of the site owner, then go ahead and do this - but if you pretend to be a browser you're not when visiting lots of other people's site, some of them may get rather upset with you - in effect, you'll be considered to be forging a browser's signature.
There's an example of each type of user agent string in use, and how it appeared in the log files on our server when I ran it, [here].
Posted by gje at 09:40 PM | Comments (0)
Related topics: via article database
Useful link: PHP training
How many toilet rolls - hotel inventory and useage
Running Well House Manor, we buy a lot of hotel supplies - ranging from sheets and towels when they are to be replaced, through guest soaps and toilet rolls, salt, sugar and jams which are ordered from time to time, to weekly or twice weekly orders such as fruit and fresh products and ultimately the daily paper. And we need to keep track of this expenditure and where it all goes. Lisa's been working on a database extension over the last few days to bring these figures closer to our finger tips - to tell us what's worth worrying about, and what is such a small player in the game that it shouldn't be at the top of our attention list.
It turns out that the algorithms are surprisingly complex. Consider the following purchases on file:
1/3/10 240
4/4/10 360
5/6/10 360
12/8/10 240
7/9/10 240
9/10/10 360
At first glance, that's 1800 purchased over a 222 day period - 8.1 units used per day. But hang on a moment ...
• there were probably some in stock on 1st March
• the 360 purchased on 9th October won't be used until .. an indefinite date thereafter
• there will be stock left at the end of the period
So I really don't trust that 8.1 per day figure.
A true algorithm would take the numbers above, add in the number in stock on 1st March, subtract the number in stock today, and then divide by the number of days from 1st March. But that would meaning saving the stock level immediatly prior to all purchases, and also doing a stock count whenever we want o look at the figures. This seems rather a lot of work for a fine adjustment.
The algorithm I've come up with - which should even out over time - assumes that stock levels are [roughly] the same each time an order is placed - so we've used 240 in the 34 days from 1st March to 4th April, and so on. So the running calculation is made by adding up the numbers purchased on each occasion except the last, calculating the number of days from the first to the last order, and dividing one by the other. The results (from this Perl program - see [source]) are like this:
wizard:dec10 graham$ perl toiletrolls.pl
Over 222 days, 1440 were consumed
That's 6.48648648648649 per day
wizard:dec10 graham$
which is rather over-accurate, but much truer to the figures.
Posted by gje at 07:06 PM | Comments (0)
Related topics: via article database
December 17, 2010
wxPython geometry - BoxSizer example
Rather than manually position each of your widgets in a window in wxPython, you can use a Sizer; there are various type of GridSizer that let you define rows and columns of widgets, and there's a BoxSizer which lets you set up either a single row or a single column. Here's a single column example.
Components are created using regular wxPython widget constructors, and then we use the Add method on the BoxSizer to add them to the column. When all the components have been added, we set the sizer in the current wx.Frame, and then use the Fit method to adjust the frame to provide just enough space for the Sizer.
As buttons are pressed - playing a "take away" game in our example - the text label are changed to provide the full GUI feedback; thus you're seeing widget defintions, placement and events all in the one demo. We've also used parameters such as wx.EXPAND to fill the buttons to the width of the window, and as we Added each component we specified a weight with it, so that when I expanded the window each of the widget's areas expands in proportion (the ratio is 1:1:1:1:1:2 between the five buttons are the text area). Full source code [here].
This example has been kept short and easy so that you can learn from it / see what's happening. As the requirements of the GUI become more sophisticated, you can 'nest' sizers within sizers, and by doing so you're limited only by your ingenuity.
Posted by gje at 08:33 PM | Comments (0)
Related topics: via article database
Useful link: Python training
How do regular expressions work / Regular Expression diagrams
If you want to help yourself work out what a regular expression means, you can draw a regular expression matching flow chart such as this one. I've taken the regular expression .*@.* - a very basic "it might be an email address" filter - and sketched out how the regular expression engine actually matches.
Start from the left hand line, and you'll see that the first line leads into the *, and there are two lines leading out. Where there are two lines out of a symbol on these diagrams, the regular expression engine tries the uppermost branch first and only goes on to the lower branch if the upper branch leads it to a dead end. At each and every decision point, the current state of the match is saved away so that the engine can regress as far as need be.
Let's take the example string "graham@wellho.net" and see how that matches ...
a) The lefthand .* loop matches g - r - a - h - a - m - @ - w - e - l - l - h - o - . - n - e - t
b) There are no more characters for the upper branch, so the engine trys the lower brranch where it looks for at @ symbol - which it failes to find because it's an the end of the string. So it keep regressing ... t - e - n - . - o - h - l - l - e - w - @ until it can match
c) The @ now matches
d) The righthand .* loop matches w - e - l - l - h - o - . - n - e - t
e) There are no more characters for the upper branch, so the engine advances down the lower branch and finds that the match is completed, so it returns a success.
Regular expression diagrams such as this can be a big help in seeing what and how matching is done, and it will also help you appreciate where matching is efficient and where it's going to use a very great deal of resources going forward and regressing backward. To help you, here are some of the basic component diagrams for other counts:
Upper diagram - '.+' - one or more characters, greedy match. Lower diagram - '.+?' - one or more characters, sparse match
Upper diagram - '.?' - zero or one characters, greedy match. Lower diagram - '.??' - zero or one characters, sparse match
Upper diagram - '.*' - zero or more characters, greedy match. Lower diagram - '.*?' - zero or more characters, sparse match
Sparse and Greedy matching is covered in more detail [here] and there's a source code demonstration of the difference that it makes [here].
Posted by gje at 02:58 PM | Comments (0)
Related topics: via article database
Matching to a string - what if it matches in many possible ways?
If you're looking to match and capture part of a string that matches your pattern, you have to be very careful to ensure that you match the correct part of the incoming string. If - for example - I were to ask you what 3 digit numbers the text "I live at 404 and my phone number is 708225" contains, you would naturally reply "404", but there are more three digit numbers there - 404, 708, 082, 822 and 225. And if I were to ask you for all numbers of 3 or more digits, you would add 7082 0822 8225 70822 08225 and 708225 to that list. This is unimportant when you ask "does this string contain some numbers of 3 or more digits", but it is critically important when you then say "what are those numbers because I want to process them".
So what are the rules for making selections in regular expressions? They default to:
• Leftmost starting point and then
• Longest possible match
and then if global / multiple matches are found, it will look for non-overlapping ones.
So ... looking in
I live at 404 and my phone number is 708225
for a number of three or more digits, a regular expression system would find
404
and if it was told to do a global match it would find
404 and 708225
These defaults are sensible - they provide what you want in 95% of cases, and they apply to the following counts:
* (zero or more)
? (zero or one)
+ (one or more)
{3,6} (from 3 to 6)
(3,} (3 or more)
and this is known as "greedy matching" because it will grab as many characters as possible.
But there are a few occasions where greedy matching is not what you want. Look at this XML:
<grand>Aeryn</grand><grand>Zyliana</grand>
with a greedy match to <(.*)> , you'll get a single capture:
grand>Aeryn</grand><grand>Zyliana</grand
whereas you're likely to be wanting to match each of the tag elements:
grand, /grand, grand and /grand
You can achieve this though sparse matching, adding an extra ? after the count - thus:
* (zero or more, as few as possible)
? (zero or one, preferably one rather that zero)
+ (one or more, as few as possible)
{3,6} (from 3 to 6, as few as possible)
(3,} (3 or more, as few as possible)
That's "sparse" v "greedy" but there's one further element to consider - the .* that I'be used in the regular expression examples, and what it actually means ...
You'll often find you're told that the dot (".") matches any character, but that's not quite true by default; the dot usually matches any character except a new line. That exception is written into the default regular expression engines to stop the sequence ".*" running on from one line to another within a multiline string, and that's a good default, but not always what you want to do. In Perl / PHP [preg style], you can use an "s" modifier - it stands for single line mode - to specify that you truely want the dot to match absolutely any character. In Python, you'll normall do it by adding the re.DOTALL flag onto the end of your regular expression compile.
The principles in this article apply across almost all of the regular expression implementations; I've chosen to add an example in Python on to our web site to illustrate them - source code and sample output is [here]
Posted by gje at 10:04 AM | Comments (0)
Related topics: via article database
Python regular expressions - repeating, splitting, lookahead and lookbehind
If you're looking for part of a string that's repeated again later in the string, you can capture the first occurrence and then use a back reference (\1, \2 etc) to refer to "same again". In Python, you can also name the element that you want to repeat - examples [here].
If you have a number of fields on a line, rather than look to identify each field with a match, you'll often find it easier to match the separator - and you can do this in many languages with a function or method called split. In Python, there are two different split methods - one is a method on a string object and splits at an exact (literal) string, and the other is a method on a regular expression, and that one splits at a pattern. Beware - the calling sequences are different between the two splits - they are not polymorphic. See example [here].
Regular expressions can easily become very long and complex and have sections that repeat themselves ... so you should remember that if you find yourself repeating something there has to be an easier way!. In the case of regular expressions, you can often build up your regular expression as a string from a number of elements (which you can reuse), meaning that only the component elements actually appear in your source. If you want to see what I mean, there's a source code example [here].
In a regular expression, you match from left to right and each time you specify an individual character or a character from a group, you move on along the regular expression. Occasionally - VERY occasionally - you want to say "is this followed by" but NOT move on, giving you the opportunity to match the same part of the incoming string against two different patterns, and continue on only of it matches both of them. You may also want to do the same thing but continue on only if the upcoming text fails to match a pattern - this is known as negative lookeahead and turns out to be more useful that positive lookahead. I've added a source code example onto our site for negative lookahead - it's [here] - where we're looking for town names that end in "ing?on", but we're using negative lookahead to exclude specifically "ington".
As well as lookahead, many regular expression handlers offer lookbehind and I've added a negative lookbehind examples [here]. Again - you'll only find occasional good uses for lookbehind.
We provide some coverage of Python regular expressions on our regular public Python courses. More advanced / specialized topics such as lookahead are covered on our Regular Expressions day. Note that if you're on one of our main Python courses and would like an introduction to some of the more advanced features, I can easily be persuaded to take you through some of them after the course finishes one day so that you don't need to come back for the "Regex Special" ...
Posted by gje at 06:56 AM | Comments (0)
Related topics: via article database
Useful link: Python training
December 16, 2010
Melksham - two many councils?
I've only lived in Melksham for ten years - so I may be asking a very delicate question that's steeped in history - but can anyone tell me why we have separate councils for Melksham Town and Melksham Without? The various parts of Melksham rely on one another to make a complete community - with the town's shops providing retail outlets for Berryfield and Beanacre, and with Melksham Without's businesses at Bowerhill providing employment form many people who live in the Town - directly or indirectly. The majority of the new developments to the East of Melksham are within Melksham Without, yet these houses will naturally look to shops and schools and other services within the town itself.
Most other nearly towns - including those slightly larger than Melksham - have a single town council for the whole community. This strikes me as eminently sensible - not only do you have a single administration (rather than two) to fund, but also that single administration covers all the community-level facilities rather than having a distorted (town centre) or distorted (industry) catchment and view. Perhaps there is scope for some merging for efficiency's sake here ... and that would release resources for providing better service for the whole of Melksham.
Having a single body for the area would also reduce confusion which can be quite damaging; only yesterday, I came across the question "why Melksham - it's a town of just 14000 people" for the umpteenth time ... when the true natural community is more like 24000
Inputs welcome - and I'll add them here; email graham at wellho.net
Follow up from John Glover, on Melksham Without Parish Council, and posted here with his permission:
Graham,
Not at all!
We represent different communities. Bowerhill, along with all the other settlements is a village, and has been kept separate from Melksham Town by Wiltshire Council, (previously WCC), in its planning policies, and confirmed at Public Enquiries.
One of the more interesting aspects of your diatribe, talks of efficiencies. I suggest you look at the relative Council Tax levels between the two councils, the numbers of staff, and what they spend their precept on. Which of the councils has a budget problem and which does not.
Perhaps you would care to attend one of our meetings and compare it with the town. Given the continuous sniping between their councillors in the newspapers, you would not be surprised at the political nature of Town Council business. This is not reflected in the Parish business, and long may it continue to reflect what is best for the public, not the party.
JohnGlover
MWPC.
And a follow up from me ...
John - Lisa and I attended the annual Melksham Without Parish Council Public meeting last week ... that's after I got your follow up, but before I had a chance to add it. And it was in general a good meeting; we hadn't known what to expect - first time we had been to one of these.
I appreciate that the two present councils are like chalk and cheese. Perhaps a linkage would allow the one with the better practices to have those practices expanded to cover the other - in fact why not take the best from both? I really question whether the current state of each should be a significant factor in the selection of logical community areas / groupings for the next decade or two.
P.S. I would question "diatribe". I don't think it was - a diatribe is "a bitter, sharply abusive denunciation, attack, or criticism:" and I was just asking "why"? Nothing bitter, nothing that was intended to be abusive or attacking .... nor critical. Just asking "why" ;-)
Posted by gje at 03:25 PM | Comments (0)
Related topics: via article database
Making the most of critical emails - reading behind the scene
You can't please 100% of the people 100% of the time. So if you have a public facing website with anything like a reasonable number of visitors (we had accesses from over 16,000 different IP addresses in the last 24 hours), you're bound to have a few visitors who aren't totally delighted with what the see. The majority of them will just click away, so you won't be aware of their concerns and indeed your log files will show them identically to people who land at exactly the page they want and are delighted with what they learn - they tend to just click away too! So when someone takes the trouble to send you an email, you read it with great care; it could be the tip of an iceberg.
| UGH!!!!! I am sure you are a bright person, but to say you are not a fan of frames and also to prove it by not using them shows a great deal of ignorance. Your website like 99.999% of all websites fail to use frames effectively and by doing so cause the visitor to spend a great deal of time scrolling up and down. How stupid. So I have to scroll down to view the entire article but then I want to check out other things on your site and I have to scroll up to the top to find the menu. How stupid. Or even more annoying is the jumping div element that some goofy programmers employ to move the menu as the user scrolls. It is not that difficult, put the menu in a frame so it stays visible and use another frame for the content. There is zero lose of functionality and a million percent improvement in usability. But because very few teachers/trainers are bright enough to espouse the virtues of frames they are rarely used. It would be like Microsoft making all the menus in Word, Excel, PowerPoint, etc. scroll off the screen as the user expands their document. How stupid would that be?!?! Just as exceedingly stupid as having one big body element with everything in it so your menu disappears when the visitor scrolls down to view other elements of your site. But that is what most sites do why because nobody knows how to use frames. In general programmers are good at writing code but the really suck at developing usable sites. This is proven time and time again by the annoying implementation of flash or other popping, whirling, spinning or other crap like that displayed on numerous sites. Vince |
Well - that's a strong view, isn't it? I've previously written a "When to use Frames" article, and I would love to use them much more - but there are all sorts of issues with bookmarking, search engine placement, printing, complexity, alignment [and their deprecation in HTML 5 - thanks for the email to remind me, Ted!]... which have discouraged me in the past and will continue to do so into the future. I agree there would be gains from their use, but there would be losses too and, overall, the losses would probably outweigh they gains. We certainly wouldn't gain enough to justify the work to be done to make it happen.
But something doesn't quite add up about Vince's email. He's saying that only 1 in 100,000 web sites gets it right. Whilst we're not afraid to be different, we would have to think very carefully before adopting a scheme that so few others use. And he goes on to talk about jumping menus, and irritating flash elements which we certainly don't have on our site. So I think his email - though perhaps not a widely circulated spam - is a "form letter" that he's written once and sent to many.
Log files are very useful to retrace specific visits to a web site, and I decided to have a look and see whether "our Vince" had visited our site before sending his email to us. And indeed he had. He had arrived at 03:07 - via a google search for "PHP Frames" and spent six minutes reading our "Using Frames in PHP" page - which is a HowTo guide with complete example source that's runnable. He then ran the demonstration, changing the frame content 16 times before leaving the site at 03:20. His email is timestamped 35 minutes later, so either that's how long he took to write it, or he was off researching other sites who he felt might benefit from his comments.
All very curious - and a really interesting piece of detective work which I have quite enjoyed. I'm left wondering "what is his purpose in writing in this way" - no links in the email, no offer to sell his services to add frames to our site, not even a URL to go and look at. So - just as he had found us through Google, I decided to see what footprint he had there ... and I found that he's posted reviews of various products in the past ...
| Horrible I purchase the ER33C after reading a lot of reviews and all I can say is there are a lot of people that are satisfied with poor performance. The ER33C is VERY uncomfortable with ALL of the supplied tips. I modified the gray tip and it was sort of comfortable but not great. The most common complaint I have read is that the mike slips down away from your mouth and you cannot be heard. I found this to be the case and moments after moving the mike up near your mouth it would slip down again. The reason is because of a poor placement of the cord which tugs on the boom pulling it down and could easily be rectified by Etymotic. ... |
| Horrible I purchased a pair of the Bose Tri-Port headphones and all I can say is they are the worst headphones I have ever used! I got these because they supposedly had superior bass response. Not only is the bass very poor but in general the sound is very poor. For $90 I was expecting to be blown away and raving about how good they are but that is FAR from reality. The $5 replacements at Wal-Mart would be better. ... |
| When I saw this phone I liked it instantly. The size and feel are great and it looks slick too. One of the main reasons I was looking for a new phone, particularly a Nokia, was due to my dissatisfaction with the Motorola Q9h; or more specifically the Microsoft operating system. Not only did every application respond slowly but the phone frequently rebooted it self and froze. Anyway, the E71 looked like it was going to be everything I wanted ... But now that I have owned this phone for a while I am a little disappointed by: Goes on to list over 10 "design flaws" in the strong and colourful language you've already seen ... |
There are a couple of other reviews too of a similar ilk, but I think my quotes above are more than sufficient to set the scene. I wasn't able to find any generally positive posts to help redress the balance.
Conclusion. Vincent Terpe, online from Michigan USA, has actually performed a useful service for us in triggering me to think again about our frames strategy - but my view remains that our site would loose more than it would gain by having changes made in this area. He's also given me a fascinating case study to look at and research - seeing how our log site analysis tools stack up when looking at a specific visitor, and how that visitor can easily be researched a little further. And he's reminded me to look at and thing of the person and the motive when judging apparently aggressive and critical emails. Actually I've quite enjoyed the last hour of research too, and because so much of his critical work is already in the public domain at his own hand, this is an unusual case in that I feel free to share it here.
Posted by gje at 10:20 AM | Comments (0)
Related topics: via article database
December 15, 2010
Sizers (geometry control) in a wxPython GUI - a first example
In all GUI (Graphic User Interfaces), you define components / widgets, you define how they're laid out, and you define what's to happen when an even occurs, such as a button is pressed. All this definition can take quite a lot oflines of code, and it's not uncommon to find even 'simple' examples in the textbooks that are over a page long.
So today, I set out to write a really simple GUI in wxPython and make it as short as possible while showing
• Creation of components
• AUTOMATED component layout
• Handling of events on those components.
Here it is - 19 lines / 586 bytes:
import wx
class MyGrid(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None,-1,"First Sizer Demo")
grid = wx.GridSizer(rows=2, cols=2, hgap=20, vgap=30)
cellname = ("Angie","Babs","Cindy","Debbie-Alexandra")
for cell in range(len(cellname)):
current = wx.Button(self,cell+10,cellname[cell])
grid.Add(current,0,0)
self.Bind(wx.EVT_BUTTON,self.OnClick,current)
self.SetSizer(grid)
self.Fit()
def OnClick(self,event):
print event.GetId()
if event.GetId() == 11:
self.Destroy()
app = wx.PySimpleApp()
MyGrid().Show()
app.MainLoop()
COMMENTED source available [here]
My decision to automate the layout of the components is a significant one; I had the option of defining each of them by pixel position, but although that's more straightforward for your very first wxPython GUI, it also leads to longer and far less flexible code, and I recommend that you should use a Sizer in all but the most exceptional of circumstances. Of course, the example above just starts to touch on Sizers - you can choose from:
GridSizer (where rows and columns each have the same width and height)
FlexGridSizer (where each row and column is individually dimensioned)
GridBagSizer (where rows and colums are individually dimensioned, and you can have a widget spanning several rows and / or columns)
BoxSizer (where you have a single row or single column of widgets)
and you can nest sizers within sizers to give far greater flexibility - "almost any layout you like"
Going further, widgets won't always fill cells in your sizer, and you have a range of control as to the gravity of the widgets - whether they rise to the top of the call, fall to the bottom, or float in the middle. And you can also control whether the widgets expand to fill the cell, or are surrounded by background. If you look at the illustration at the top of this article, you'll see that the default is that the widgets gravitate to the top left of the cell.
Python has several GUIs available - but wxPython is perhaps the most popular, and we include a brief introduction in our Python Programming and Learning to program in Python courses. If you're going to be making heavy use of the wx GUI, and you're new to GUI programming, please ask us to extent the course by a day (which we can do for even one delegate) to introduce you to the wonderful art of designing and writing GUIs!
Posted by gje at 06:00 PM | Comments (0)
Related topics: via article database
Useful link: Python training
December 14, 2010
Object Oriented Programming for Structured Programmers - conversion training
I've been programming for many years; I started off with languages like Fortran and quickly learned that it's a good idea to split the code into named chunks - which were known as FUNCTIONs and SUBROUTINEs. This means that parts of a program can be tested named chunk by named chunk, that chunks can be re-used, and can be shared between programs. And that's a good system for medium sized programs, but as they grow further (especially where a program has to cope with numerous similar data types), it begins to creak a bit, with lots of "if, elseif, elseif, elseif, else" type structures and large numbers of named blocks of code with similar names that will find the capacity of ... a sphere, a cube, a jug, a cup ... and woe betide you if you call the wrong named block of code in the wrong circumstances.
Of course, us "old programmers" are very much aware of these issues, and we design and code defensively to deal with them. But - for the larger programs, and for programs that handle lots of similar data types - there is a better approach. And that's Object Oriented programming. But it's a big step from "structured coding" to "Object Oriented Programming" and for the old hacks it means stepping back to school and learning new techniques. And the introduction to the new world of OO isn't helped by the most enormous heap of new jargon that's been introduced with it to represent some of the concepts and implementation elements.
One of the most rewarding single-day courses that we give is Object Oriented Programming in PHP course - and it's so rewarding because we help some very smart and very experienced programmers make the crossing from structured coding to OO coding - something that many of them have struggled with for a very long time. Having - at one time - been a pure structured programmer myself, I have "been there" and I have "worn the T Shirt" so I know exactly the issues that need to be addressed, and we address them without initial reference to all the jargon that accompanies OO. After the initial session, we'll say "this is a class ... this is an object" so that delegates do leave with a good appreciation of the new lingo - but they've had it gently introduced to them, not rammed down their throats from the start.
Object Orientation is applicable in many languages these days. So when I got a request "can you help me pick up the principles of OO" general terms, I jumped at the opportunity. I chose Python as my main language of demonstration; experienced programmers can pick up the basics of variable, conditionals and loops very quickly, and the OO demonstrattions during the day can be neatly written in just one or two files (in contrast to the much higher number I would have used in a language such as C++)
Outcome of day? A great success!
Demonstrations from the day
... two types of thing and a list that contains a mixture of them ... [source]
... two types again, but this time sharing a whole lot of common logic rather than having it repeated ... [source]
... how to compare two things - which is 'greater'? ... [source]
... comparing whole lists of things - which is 'greatest'? ... [source]
I was also asked to write a program using the structured idiom [in Python] and convert it to an object oriented idiom. I kinda refused - it's NOT a question of converting, but of starting from the beginning, and designing the application differently. But I did let myself write the code twice - once each way.
The data is [here] - it's railway stock on the British network, with diesel and electrical multiple units each listed carriage by carriage, individual locomotive hauled carriages listed one per line, and coaches for high speed trains done in the same way. Then there are some 'specials' - the flywheel powered cars on the Stourbridge Town line, and the Isle of Wight trains, which don't quite conform to standard rules. ((I do have the complete file if you come on the course - ALL the stock - but can't publish it here because of copyright issues!))
... the sample codes, structured ... [source]
... sample code, using an OO approach ... [source]
Object Oriented princiles REALLY need to be taught ... the examples above may show you a little, but you will learn 50 times more if you let me show you how these examples are written - the logic behind the logic. Please get in touch via our [help page] and we can set up a one-on-one day (for just a regular course price!) or come out on site if there's a large group of you. The language I'll use won't necessarily be Python - if you know Perl already, we'll use that; for C programmers, we'll look at OO via C++, and so on.
Outline of the day
Prerequisites (which can be covered in an extra 90 minute session the previous evening for experienced programmers in other languages):
To know a little about in the target language ...
variables
calculations
conditionals
loops
functions (definition and use)
Input and output
How to add comments to a program
How to run a program
On the day:
"Single Block, Structured, Object Oriented"
Then ... an explanation of OO, and of how you do a job in an OO way. The tutor will NOT start by using all these words that are part of the OO Jargon, but by the end of the day you'll see where each of them fits in.
Class, Object, Method
Constructor, Destructor
Properties or Attributes
Static and Dynamic
Muttable and Immutable
Associated Objects
Inheritanace
Subclasses, Base classes and Extended Classes
Overloading and overriding; Polymorphism
Overloading Operators
Public, Protected, Package, Private
Multiple Inheritance, Interfaces and Mixins
Transient and Serialisation
Exceptions
The demonstration will be done by taking some example data, and handling it using the approach of Object Orientation. A second demonstration will use a signifcant file of real data, showing the delegates how the principles demonstrated earlier make for real gains as the data volume and complexity increases, but you do not want to program to have a similar increase in its complexity.
Philosophy of OO Design
Design Patterns
Singleton Pattern
Factory Methods
Unified Modelling Language
Extreme Programming
What makes a programming language OO?
Things from some other code that should not happen in OO:
"What is this"
Switch
Direct access
Wrong sort of operation / wrong sort of data
Repeated code
Cardinal Values
Posted by gje at 03:09 PM | Comments (0)
Related topics: via article database
December 12, 2010
Can you trust the big brand names?
I tread with great care if I post criticism of "big names" as I don't want big guns turned on me (yes, I'm vain enough to imagine that this may be being read;-) ). But here are a couple of example of what I consider to be appalling advertising, over the last few days, from big names mis-selling their product - the facts simply don't match the adverts in my opinion, and I feel badly let down. Names not quoted, but you can probably guess!
| I don't have cover, can you send a tradesman if I have an emergency now? Yes. If you have an emergency at home right now, call 0800 197 4184 for immediate assistance. How long will I have to wait before someone comes out in an emergency? We aim to have a tradesman at your home within 4 hours of your call. Where there is a need for faster service we aim to be with you within 2 hours. |
So why - when I contact them (as a longstanding member for 10+ years) - am I still waiting in freezing a house with central heating boiler and hot water out of service some 60 hours after my call?
| Thank you for this year and for next. This year,as a way of sayng thank you, we've offered our customers a little extra help ... We've given our current account customers access to better deals .. |
So why - if they're doing so much more to provide extra help - have they shut down their Melksham branch with an additional requirement placed on customers to visit Trowbridge or Chippenham for certain transactions?
And why - when a customer wants to transfer a mortgage to a company that's remained in the town - are they imposing thousands of pounds of penalties?
With big brand names, I expect to may somewhat more for a product that's probably not the very best - but I do expect it to be consistent, reliable, and to do what it says in the blurb. Perhaps I'm naive; perhaps these two companies have got the size they are by selling more than they can deliver, and pocketing or speculating with the profit.
Posted by gje at 09:11 PM | Comments (0)
Related topics: via article database
December 11, 2010
Python - fresh examples from recent courses
During courses, I write a lot of examples in front of delegates so that the get to see both a program to perform a certain task and how that solution was reached - after all, they'll be expected to modify and write programs after the course, and just showing them the final result would only be telling them a half of the story.
At the end of the course, these new programs are often useful for the delegates who attended, but not necessarily publishable to the wider world. They may lack comments, they may contain personal data, and they may have had 'side' demonstrations added into them which would make no sense to anyone who wasn't there. So I tidy up the examples, and add more comments too, before I public the useful ones. "Doesn't that take a long time?" someone asked me the other week. Yes - it does, but these new examples provide fresh alternative insights into how things are done, and build into a useful library.
I've been pretty full of cold / flu (?) for the last two weeks ... only firing on two cylinders rather than four ... so I've combined the extra examples from the Python course in Bristol (the week before last) and the public Python course from this week just concluded into a single post. All of the examples have additional descriptive comments - click on the [source] links to havea look.
Printing out several values in the same print statement. You can provide a comma separated list of variables / expressions to a print statement, and Python will print them out one after another, with a space between them. If you want to suppress the space, you'll need to join the expressions together and the easiest way is often to connect them as strings using the "+" operator. [source]
Conditionals in Python - conditions may be written without brackets, and the block of code that goes with the condition is inset rather than being surrounded by { to } or some other sort of delimiter. [source]
There's also an example (which I have placed in our "algorithms folder" - Q110 - which shows how we count the number of occurrences of a specific event within a loop. See [source]
Y105 - functions, modules and packages
A fresh demonstration of variable scope in Python - [source]
How xrange rather than range, and xreadlines rather than readlines, allow for efficient handling of large quantities of data without the need to store it all in memory - [source]
Calls to functions in another module (loaded from a separate file) - [source]
Setting up Unicode text strings in Python - [source]
Raw and regular strings - [source]
Checking the type of data entered - [source]
Search and find, search and replace, and search and replace with the result of running code on what was found - [source]
Exceptions to trap user errors - with a counter, so that if the user exceeds a certain number of erroneous inputs, the program exits - [source]
Reading from a remote URL ... with exception handling to trap the issue of the remote resource not being available [source]
Efficient programming to use huge amounts of data - example tests on 1Gbyte of text data records - [source]
Finding how much disc space is free from withing a Python program - using a wrapper to limit the OS dependent section to a set of functions isolated from the main code, which remains common. [source]
Sourcing data from a file using a "just in time" function so that no large intermediate list is produced [source]
Y111 - More on collections and sequences
Counting the number of times each visitor comes to a web site via a dictionary, then producing a sorted list. You're not able to sort a dictionary, but you can sort a list of the keys and then step through each of the keys in that sorted order. This example is also interesting in that it uses quite a complex sort function - it sorts firstly by the length of the IP address. If that doesn't tell records apart, it sorts by the number of visits from the IP address, and if there still isn't any distinction it sorts by the IP address itself. All of which is far longer to describe than to code - see [source].
A "classic" demonstration - two slightly different types of people, with a lot of common (shared) code in a base class, and with differences defined in an extended class. A test program that uses that data, through Polymorphism to avoid the need for lots of conditional code, and also avoid the need for lots of repeated code - [source]. Sample data for that application is [here]
There's also a seasonal variation on the theme, with Christmas, Easter and Groundhog Day characters ... see [source]
Posted by gje at 08:09 AM | Comments (0)
Related topics: via article database
Useful link: Python training
December 09, 2010
XML handling in Python - SAX, DOM and XSLT examples
XML is the "eXtensible Markup Language" ... a set of rules to which a language must adhere, rather than a complete language definition - you need to add other elements such as a DTD or Schema to complete the definition of a language that conforms to an XML standard.
How do you process XML, then?
There are three common ways.
a) You can use a SAX parser. SAX is the Simple API for XML. With a SAX parser, you pass the data through a handler which extracts pertinent information as it's passed through - so this is ideally suited to extracting a few very specific bits of information from what is potentially a huge data flow.
b) You can use DOM (the Domain Object Model). Here, you read data into a structure in memory and can process it within that structure. Because XML tags can be nested, you'll end up with nested structures in memory, with the result that you'll probably find yourself writing recursive code
c) XSLT - X Stylesheet Language Transforms - are a way of defining how a file of XSLT is transformed into some other format. XSLT is a programming language itself.
Can we use SAX, DOM, or XSLT in Python?
Yes - you can use any of them. There are many classes supplied with Python, and others which are easy to download. I've uploaded some recent demonstrations - firstly, there's some XML that I've used [here] ... with sample processing of that in Python via SAX [here] and in Python via DOM [here].
There's an example (using different data) with XSLT [here] - and you'll note that the XSLT example is much shorter. That's because a lot of the work has been transferred to the XSLT code (see [here]). The XML for that last example is also available - [here].
Posted by gje at 05:11 PM | Comments (0)
Related topics: via article database
Useful link: Python training
December 08, 2010
wxPython - simple example to add GUI to a server log file analysis
On our Python courses, we briefly introduce the various GUIs (Graphic User Interfaces), and where we have delegate(s) with an interest in one particular GUI, we'll spend a little longer on examples within a GUI. If delegates need to go deeper into GUI programming, we can provide an extra one day course on request - typically, we'll run that at a later date to ensure that the folks have good chance to practice the basics.
A GUI application (whether using TkInter, wxPython, or PyQt ...) is structured to run as follows:
a) Define the component parts of the GUI ("the widgets")
b) Define how they are laid out ("the geometry")
c) Define what's to be done when the user does something ("the event handlers")
d) Display the GUI
e) Enter a loop where the code waits for an event, and when it gets one it processes it
In wxPython, the widgets, geometry and event handlers are defined within a wx.Panel, which in built into a wx.Frame for display. The event handlers then call user defined methods to process events, which in turn call methods which are loaded from other modules / files / classes to perform the business logic (i.e. "real work") behind the GUI.
There's a complete example, written to illustrate this linkage to business logic, [here]; in this particular case it's all in the one single file so that it's easy for you to cut and paste and run the whole example. You'll need some web server log files, and in the example they're named to start ac_201... , to try the code out. If you run your own web server, you should have plenty of data ... either "common" or "combined" Apache log file format will work in this program; if you don't, there's a sample log file on our server at http://www.wellho.net/data/ac_20100322.xyz
Posted by gje at 11:22 PM | Comments (0)
Related topics: via article database
Useful link: Python training
December 07, 2010
Santa Special - rather more special than usual - December 2010
Headline
First Great Western provided an intercity 125 train last Sunday on the 17:05 from Westbury to Swindon. This train formed the Santa Special trip organised by the Melksham Railway Development Group - with 80 adults and children joining the train at Melksham for the ride to Swindon and back. Santa Claus, and the Melksham Town Crier, both found time in their busy schedules to join us on the train, and a great time was had by all.
On the way back from Swindon, we all got to ride in First Class, and Santa came through the train with presents for all of the young people in the party - lots of smiling faces, and a great time had by all. We left the train at Melksham; Santa stayed on through to Westbury, where he had parked his sleigh.
What was special?
This was the very first time (to our knowledge) that an intercity 125 (also known as an HST) has stopped at Melksham, certainly to pick up or drop off passengers. It's something that wasn't possible prior to the provision of "selective door opening" on these trains a couple of years ago, but since then it is something we have asked FGW to consider for special trips. There have still been technical concerns, at it's great to confirm they have been overcome.
This is more significant that just special train / events, though - it means that when there are engineering works that cause the HSTs to be diverted via Melksham, there's no longer any need to cancel the local services (and this will be more important if and when we get the local service improved) - just stop one of the expresses, which have to go slowly round the curve here anyway.
Note that the 18:19 (Sunday) from Swindon, on which we travelled back, is a service that's provided by First Great Western in excess of the government's minimum level specification - it was added to the timetable after requests from the Melksham Railway Development Group and the Save the Train Campaign - our thanks to First Great Western for their continued provision of this service; it's quite a success - we've had to reduce the number of Santa tickets sold this year due to fears of overcrowding.
Background
See newsletter handed out on train - http://www.transwilts.org.uk/twnews_01_mkm.pdf
Posted by gje at 09:45 AM | Comments (0)
Related topics: via article database
December 04, 2010
TransWilts Rail News ... Melksham (Santa Special) Edition ... 5th December 2010
The TransWilts railway line links Salisbury, Trowbridge, Chippenham and Swindon ... via Warminster, Dilton Marsh, Warminster and Melksham. Trains are sparse on the section from Trowbridge via Melksham to Swindon - just 2 each way a day - and various groups such as Save The Train, the Melksham Railway Development Group, the West Wilts Rail Users Group, supported by many other organizations and people including elected representatives - have pressed for a review of the service level to work out what's appropriate, then to see how we can work toward regaining, and retaining, that higher service level if that were to be the outcome of the review.
And an appropriate service is ... an hourly train in each direction. As long ago as July 2004, the Jacobs consultancy recommended a train every 2 hours through the day, but that was on a conservative growth estimate. That was also before Wiltshire became a unitary county, tying Chippenham much more closely to Trowbridge and Salisbury. It was before the rapid growth planned for (and now underway) in Trowbridge, Chippenham and Melksham (the 2nd, 3rd and 4th largest urban areas in Wiltshire). It was before we were all concerned about the possibility of Global warning. And it was before we were concerned about ever-rising petrol prices, parking charges and road congestion. More recent work - from Wiltshire Council, and from Network Rail (2010 GWRUS) have concluded that an hourly service is appropriate, and have given it a significant benefit to cost ratio - in other words, the cost of providing the service will be more than met (actually it will be met several times over) by benefits brought to the area.
But how do we translate this very positive analysis into a real service? It requires a lot of organizations, with some very different structures and goals, to work together, and to do so under a regulatory framework that throws up some startling anomalies that are counter productive. But there are some very good - really excellent - people in most of the organizations concerned who understand 'the system' and are working closer and closer together to move towards a much better service. It's unlikely that we'll see an immediate jump to an hourly service, but following on from a meeting within the last fortnight, I'm much more optimistic at the prospect of a service increase to six round trips a day. This would include a true peak service, and other service which would match travel flow requirements - in other words, it's a nice looking, practical timetable.
You'll here less of "Save the Train" and more of the "TransWilts Community Rail Partnership" (TWCRP) in coming years. "Save the Train" is a campaigning group which (if needed) will irritate players to take note - email campaigns and the like; that job is largely done, and the Partnership is all about the Rail industry, Government at various levels, Politicians, Financial Experts, and the Community having a forum to set common goals; such partnerships are tried and tested - indeed, we're working very closely with the Heart of Wessex Partnership who have helped their line achieve 173% growth; we thank them for their help and being able to learn from them.
The Community Rail Partnership is about the current service, and the facilities at the stations too. If you came on the Santa trip last year as well as this, you'll have noticed that there's a new electronic information point at Melksham station that (at last) gives us a visual live train departure indicator. There's been an extra stop inserted into a service at Dilton Marsh, and printed timetables produced for that station. The departure of the Saturday morning train from Westbury to Swindon has been delayed by a few minutes so that Salisbury passengers can get a good connection up to Chippenham and Swindon. And indeed, the Sunday evening train from Swindon to Westbury that Santa will travel on is in addition to the government's specification for the service; an empty train became a passenger service after we suggested that it should.
Have you heard the saying "a pet is not just for Christmas"? Well - this railway is not just for the Santa Special. It's for all year. There are trains from Melksham at 06:45 and 07:15 each Monday to Friday morning, and return service arriving at 19:15 and 19:45, and you can visit / do a day's work in places as diverse as London, Swindon, Bristol, Salisbury and Southampton. On Saturday, a morning train at 09:15 will take you or connect you to Swindon, Bristol, Oxford, London or further afield ... you can arrive back mid-afternoon, or mid-evening, and the cost may be surprisingly low - the total train fare for 4 adults and 4 children ("Groupsave 4 / Off Peak Day return") for a trip to Oxford would be £28.40 (2010 prices), and parking at Melksham station is free. The Sunday trains are good for evening journeys from or to the town, letting you get home after a weekend away, or travel away the night before if you're going to be working away.
Things take a long time to change in the rail industry, cost a lot of money, but can bring a lot of benefits. "Add an extra 0 on the end" said a cynic, who in all truth wasn't far out. So you won't have an extra train for this Christmas, even thought the case is clear. But if we all work together, and with your support, perhaps we'll have one for next Christmas.
-- Graham Ellis
Vice Chair, Melksham Railway Development Group (who have organized the Santa trip)
Some useful links:
http://www.firstgreatwestern.co.uk First Great Western - current train operators
http://www.transwilts.org.uk TransWilts CRP / line introduction
http://www.firstgreatwestern.info/coffeeshop Our Rail discussion Forum
http://www.savethetrain.org.uk Save the Train - a great deal of material
http://www.twcrp.org.uk/community/index.php Working group forums - most requires login to read / contribute
Posted by gje at 09:21 PM | Comments (0)
Related topics: via article database
December 02, 2010
Royal Wedding. How William and Catherine have changed our schedule
April 29th, 2011 ... will you be watching the Royal Wedding, or would you prefer to be learning about mod_proxy_balancer linking the Apache httpd server to Apache Tomcat on one of our "Tomcat Courses?". We rather suspect that most of our customers would prefer to be in front of the TV ... or if they object on principle to the Royal Wedding, be making the most of their extra day of holiday.
The week of 25th April becomes a very short week - starting with Easter Monday and ending with the wedding ... and I have moved course that were scheduled then to the weeks of 4th April and 9th May ... and as a result of a request for an earlier Lua course, I'm moved the 4th April course on that subject to 28th February; happy to do so, as the effect of the Royal Wedding change was to overload the 4th April week. April and May are always difficult times to schedule, with so many of the weeks shortened and days leading up to - and after - them being distinctly hard to sell.
So ...
Learning to Program in Lua - from 28th February [link]
Lua Programming - from 1st March [link]
Regular Expressions - 4th March [link]
Learning to Program in Ruby - from 4th April [link]
Ruby Programming - from 5th April [link]
Ruby on Rails day - 8th April [link]
PHP Techniques (an advanced 2 day course) - from 26th April [linki]
Perl for Larger Projects (advanced 3 day course) - from 26th April [link]
MySQL relational database (2 day course) - from 27th April [link]
(The week will be an "options" week - we offer a handful of specialized courses, and whichever is the first to take a booking is the one that we run. See [here])
Learning to program in Tcl - from 8th May [link]
Tcl Programming - from 9th May [link]
The Apache Http Server and Tomcat - from 12th May [link]
Remember - that's just four weeks of next year - there are lots of other courses too. We're starting straight back in January with C and C++. Linux Courses run the second week in January, and then we have a PHP course in the third week. In February, we're teaching Java and Python. The next Perl courses - after the ones still scheduled in the lead up to Christmas - are in March.
P.S. I Wish Catherine (Kate) and William a great wedding day, and a long and happy life together.
Posted by gje at 11:25 AM | Comments (0)
Related topics: via article database
Perl 6 - significantly nearer, and Rakudo looks very good
There's been a longstanding jest that says "You'll have Perl 6 for Christmas" but goes on to add "but of course we won't tell you which Christmas."
Christmas may have arrived early this year ... for this morning I downloaded Rakudo Star - the November 2010 release that's been out for about a week ... according to Github 200 people had got there before me, so perhaps I'm still a bit leading edge. The Rakudo team describe it as "a useful and usable distribution of Perl 6" ... I haven't thrown enough at it yet to be sure but first impressions are that their claims are valid.
Rakudo Star unpacked, and built easily from source on my Mac (MacBook Pro with Developer's Xcode, running OS X 10.6.4) ... in a nutshell:
cd /usr/local
sudo tar xf ~/Downloads/rakudo-star-2010.11.tar
sudo chown -R graham rakudo-star-2010.11
cd rakudo-star-2010.11/
perl Configure.pl --gen-parrot
make
make install
cd /usr/local
sudo ln -s /usr/local/rakudo-star-2010.11 perl6
and into my ~/.bash_profile file add
export PATH=/usr/local/perl6:$PATH
then (in a window that's freshly creates to check the new path ...)
wizard:dec10 graham$ perl6
> print "Hello World\n";
Hello World
> exit
wizard:dec10 graham$
(Goodness - it's nice to have the interactive shell come up like that)
Let's try a real (Perl 5) program and - yes - that's going to throw up the compatibility issues:
sub ladder {
$plen = sqrt($_[0] ** 2 + $_[1] ** 2);
}
print "Hello World\n";
$moat = ladder(5,12);
$building = ladder(3,4);
print "Ladder lengths needed are $moat and $building\n";
wizard:dec10 graham$ perl oldperl.pl
Hello World
Ladder lengths needed are 13 and 5
wizard:dec10 graham$
but
wizard:dec10 graham$ perl6 oldperl.pl
===SORRY!===
Symbol '$plen' not predeclared in ladder (oldperl.pl:3)
wizard:dec10 graham$
And - straight away - you see the first "fix" - variables are no longer default global, even without the "use strict;". Thank Goodness!
Let's rewrite that code, but pull in another of the Perl 6 new features - named parameters:
sub ladder($width, $height) {
my $plen;
$plen = sqrt($width ** 2 + $height ** 2);
}
print "Hello World\n";
my $moat = ladder(5,12);
my $building = ladder(3,4);
print "Ladder lengths needed are $moat and $building\n";
Of course, that fails with Perl 5:
wizard:dec10 graham$ perl newperl.pl
Malformed prototype for main::ladder: $width,$height at newperl.pl line 8.
wizard:dec10 graham$
but it runs sweetly on Rakudo Star:
wizard:dec10 graham$ perl6 newperl.pl
Hello World
Ladder lengths needed are 13 and 5
wizard:dec10 graham$
There's a second of the big potential criticisms of Perl 5 wiped out - Wow!
Now - you should NOT consider that Rakudo Star is Perl 6.0.0 or anything like that - there are still some features to be tested and implemented; they're listed in more detail at http://rakudo.org/announce/rakudo-star/2010.11, but it is an excellent step and something that's becoming very practical indeed to start using. And I have to say I have been very impressed this morning - it downloaded, unpacked, compiled, ran my little tests flawlessly.
The Mac I used is the presentation machine. So Perl 6 (Rakudo Star) will be available for use on forthcoming courses. That's not to say that we'll switch straight over - we will NOT - but we will be able to add flesh to an introductory talk about Perl 6 by running it, and we'll be able to delve in deeper as and if our delegates require / request us to do so.
I think I'm going to have a good Christmas this year (although I may be slightly inseparable from my keyboard) ... and I go forward with a new spring in my step; it now looks much more likely that Perl will still be one of our major training language even in 2020.
Now if you'll excuse me, I'm off to play with the samples, and write a lot more code of my own.
The 'story' behind this application / sample program is told [here] (and that also tells you why there's a picture of Edinburgh Castle illustrating the article)
The Perl 5 source of the example above is [here]
The Perl 6 source of the example above is [here]
Posted by gje at 07:52 AM | Comments (0)
Related topics: via article database
Useful link: Perl training
December 01, 2010
Python through the Snow
Welcome to December ... just over three weeks to Christmas, and at this time of year I would usually be scrambling back through the archives for last year's pictures to add festive snow to some of my articles. But this year is different; the snow has come early, and it seems has caught everyone by surprise (hey - it usually does!). Here's a picture from yesterday morning - the predawn train calling at Melksham at 07:17 on its way up to Chippenham, where I changed ...
Cars, people, pushchairs all fighting their way through the light sprinkling of snow in Chippenham, still predawn (or first light) as I changed to head down to Bristol ...
I took the flow with the crowds out of Temple Meads, and walked across the City Centre - I was presenting a private Python Course in one of the high rise offices just below the hill that's Clifton ... and it gave me a chance to look at a few of the scenes I don't often see
I was agreeably surprised how quiet the actual city centre's roads were, even at that time of the morning - and I'll put my journeys to Bristol to give this course in the big success bracket. But, alas, the return journeys were so slow, with over an hour to "kill" on the journey - a course finishing at 5, but the train with a connection from Bristol not leaving until 6.30 - that's an hour later that ideal. And I wasn't the only one making that Melksham to Bristol journey yesterday morning - the barriers at Bristol rejected my (perfectly valid) ticket telling me to seek assistance, and in amongst those crowds another person who had joined the train at Melksham was going through the same thing. And I find it vaguely like I'm being accused of not having the right tickets when the barriers reject me; I can't help wondering is this puts other people off too.
And here's an interesting thought. There were between 40 and 50 people on the train from Melksham when it got to Chippenham, but only about 15 on the way back. What happened to those other people? Perhaps if there was an evening train at a true peak hour return time it would do much better ... it would certainly encourage me to use the train for days in Bristol!
Posted by gje at 06:23 PM | Comments (0)
Related topics: via article database
Useful link: Python training