May 21, 2013
Melksham Chamber of Commerce - Report for AGM, 21st May 2013
What an eventful year! On the development of Melksham for the future, progress has been substantial on the Campus project, and the canal has moved forward. Big new businesses such as Herman Miller and Castle Combe International are moving to town, and smaller businesses are setting up and / or moving to town too, such as a South West Coffee and Melksham Chiropracters. And although our town has some empty units, that's rather more a healthy set of opportunities which are being taken up by businesses that a town needs and uses in the second decade of the 21st Century rather than a sign of shrinkage and cutbacks.
The town's growing too - with new housing being built - and occupied - to the east of the town, and with further proposals both adjoining that, and on the old George Ward school site too. Melksham's a great place to live, and it's good to see others sharing that view. With average household side reduced by 10% over the last decade, there's been (and continues to be) a need for newbuild as well as replacement housing to counter any decline.
The Town Team and the Melksham Independent Traders, have been working hard to encourage people to use town centre retail businesses - special mention for Hayley Spencer. I attended the recent MITA networking evening - a useful catchup with some of the movers and shakers, and I welcome the election of one of the traders onto the town council.
The is - as ever - a shortage of volunteers to help with projects within the community, and for the future of that community, and that's especially the case for business operators and employees. Who are the very groups of people for whom the Chambers of Commerce exist. That's been an issue for many, many years and lead to the formation of the Wessex Association of Chambers of Commerce some twenty plus years ago, provinging centralised services from an office in Trowbridge. The Wessex Association has stood us in good stead for many years, but changing technologies and the resultant change in work patterns have given us the opportunity and motivation to move forward to a new model that's going to see us through the next 20 years.
Part of these changes are the removal of the needed for fixed landline, fax machine, photocopier and typewriter for a secretary, and we've taken the opportunity of the rearrangement to appoint a local secretary for the Chamber who is reachable by email, and who acts in a similar way for the local rail partnership, Community Area Partnership and others. Now only is there a greater synergy between the various groups in the town than between the chambers of different towns, but it also means that our secretary has his finger on the pulse of the town as a whole, to the mutual practical benefit of the organisations involved and their members. Many thanks to Phil McMullen for his initiation of this role, and taking it through its initial year. Thanks also to Colin Harrison for his continued work in the roles of Chair and on the accounts through these changing times.
The Wessex Association is now offering an enhanced membership package to businesses, including HR and legal helplines, tax investigation insurance, electronic marketing to members throughout the whole area of 18 chambers to which it's expanded, and much more. The last year has seen this offering move from a seed of an idea through to an implemented plant, and the package offered is an excellent one for many businesses; I comment it to you. However, there are certain businesses (Well House Consultants happens to be one of them) for whom the new association member package doesn't offer the gains that it needs for the higher price. And for such members, and for other businesses wishing to join the Chamber but with the same issues, the Melksham Chamber has introduced a local membership. This is in common with many other Chambers with whom we're in touch, though it's not universal across the Wessex area, highlighting the independence and difference of our towns.
We welcome new businesses - as association or local members as appropriate to them, and look forward to the chamber flourishing under these new structures. We're already seeing something of a renaissance, with the March meeting (focus on town centre and opportunities offered by the campus) and April meeting (focus on tourism, looking at VisitWiltshire in particular) both very well attended and lively. More "specials" are planned for the future - in fact we want to make every meeting special, so that people go away having networked, learned, and been motivated.
Earlier this month, local election in Wiltshire changed the largest party on the Town Council from Conservative to Liberal Democrat, and removed the Conservative's overall majority on the Area Board. Across Wiltshire as a whole, there is still an overall Conservative majority in council, but even there portfolios have changed hands - in some cases to newcomers, and in other cases back to previous incumbent. And already we're seeing the effects of new brooms, ranging from changes (mid-project!) to the Campus team, questions over the future of the Community Area Partnership, and an option for spending public transport improvement monies from the Department for Transport on existing heavily used stations, even though the funding was awared on the basis of the TransWilts line and Melksham in particular.
We've invited all three newcomers to the Melksham Area Board to our meeting tonight. As I write, we have one acceptance, one apology, and one member from whom we've yet to hear. We need to all inform one another and keep our activities joined up for the greater common good - after all, there's so much to do, and so much we agree on that transcends party politics and so much we can achieve.
An honourable mention for ... other things on the agenda, but not making the full report, such as
Hall and Woodhouse
Blue Plaque
Transport - LSTF and GW Franchises
Wilts and Berks Canal / Membership
Core strategy and neighbourhood plans
Business Services
Christmas Lights support
Posted by gje at 08:57 AM
| Comments (0)
More about Graham Ellis of Well House Consultants
Related topics: via article database
May 20, 2013
Perl design patterns example
For short programs, just a few lines of code in a single block do an excellent job. As the program size increases, some sort of structure such as named blocks of code (sub, def, function, proc, lambda, ...) becomes logical. And as the code grows further, you should consider splitting out logic relating to a particular data type into a class of methods, with each class having its own test harness.
There's a parallel here in real life writing - a tweet is a single block. Posts to social media such as facebook will be a series of paragraphs. And technical artcles will be a series of linked pages.
Python - being an object oriented language - is designed around the larger coding model. And that larger coding model is very common in these days of shared code between a lot of smaller projects; that's why Python is especially popular. But you can also write excellent Object Oriented code in Perl to conform to the same principles, and give you the same benefits of unit testability and code re-usability. And that's something we cover on our Perl for Larger Projects course which is running this week.
Yesterday, we covered OO as implemented in Perl, statring from first principles. And during the day I built up to a complete example - [here] - showing object definition and inheritance, and moving on to look at patterns for generic property accessors through get and set methods, and also through the autoloader. The example also includes factory and comparator design patterns which you're welcome to look at, copy, adopt ... or come on the course next time to learn in more depth.
Posted by gje at 11:14 PM
| Comments (0)
Useful link: Perl training
Related topics: via article database
May 19, 2013
Django - first steps - Updated
What is Django / What is a Web Framwork?
Many web applications have the same elements - a look and feel (the view, logic that works with the data, usually in a database (the model), something to handle incoming URLs and run the appropriate piece of logic (a router) and bespoke glue in the middle that takes the inputs, accesses the model / databases, fills in the view template, and returns the result to the user (the controller).
These are such repeating elements that a number of Web Frameworks have been written to provide all the standard stuff for you to tailor. An Object Oriented language (such as PHP, Ruby or Python) allows the web framework provider to provide a structure that's going to support a null (do-nothing) application, iin which the web developer can override the skeleton methods to provide functionallity. And components and helpers can provide extra handlers underneath the web developer's code to provide tasks that will be similar across applications.
Frameworks that I'm currently working with ...
• Zend (using PHP as the programming language)
• CodeIgniter (using PHP as the programming language)
• Rails (using Ruby as the programming language)
• Django (using Python as the programming language)
and they're all good. Which to choose? It depends on your metrics, on the programming languages you alrady know, perhaps on your server and company policy. There are whole article in that discussion. But here's we're going to look at Django.
This article is going to start off from a first Django application - "Hello Django World" - and expand it to cover most of the major elements you'll use in a typical Django application.
Planning
Let's plan our target application first - so that we know where we're headed as we write our Django based application.
Story 1: For this example, I'm going to take a hotel in Melksham, Wiltshire, and write a project that's a resource for guests. Within that project, we'll write an application for day out visits that are availabe from the hotel. We'll store the information in a database, and we'll have it searchable.
Story 2: We'll go on and add an administration capabiity to allow for new days out to be added.
Story 3: Then we'll add a user review / rank / comment capability.
Hello Django World
Let's start with Story 0 - building our project (guest) and our application (visit) within it, providing a route from our URL to the application, and initially an index page therein.
1. Check Django Installation:
trainee@brugges:~$ python -c "import django; print(django.get_version())"
1.5.1
trainee@brugges:~$
2. Create the project:
create the project ... cd to where you want to create the project, then:
trainee@brugges:~$ django-admin.py startproject guest
trainee@brugges:~$
and see what you've got:
trainee@brugges:~$ ls -R1 guest
guest:
guest
manage.py
guest/guest:
__init__.py
settings.py
urls.py
wsgi.py
trainee@brugges:~$
3. Start the server and see what you've got:
trainee@brugges:~$ cd guest
trainee@brugges:~/guest$ python manage.py runserver 0.0.0.0:1025
Validating models...
0 errors found
May 19, 2013 - 06:12:20
Django version 1.5.1, using settings 'guest.settings'
Development server is running at http://0.0.0.0:1025/
Quit the server with CONTROL-C.
Browse to your IP address ... you should see
and you'll see a log line in the window that you're running the server from:
[19/May/2013 06:12:51] "GET / HTTP/1.1" 200 1956
Once that's tested, ^C (Control - C) in that window will stop the server.
4. Add in your application.
trainee@brugges:~/guest$ python manage.py startapp visit
trainee@brugges:~/guest$
And see what you've done.
trainee@brugges:~/guest$ ls -R1 ../guest
../guest:
guest
manage.py
visit
../guest/guest:
__init__.py
__init__.pyc
settings.py
settings.pyc
urls.py
urls.pyc
wsgi.py
wsgi.pyc
../guest/visit:
__init__.py
models.py
tests.py
views.py
trainee@brugges:~/guest$
In order to access that application, you need to add a route in urls.py. Within url_patterns:
url(r'^visits/$','visit.views.index'),
url(r'^visits/index\.html?$','visit.views.index'),
And within settings.py, you need to add the installed application:
INSTALLED_APPS = (
'visit',
And finally, you need to add your controller (confusingly known as your view) in visit/views.py
# Create your views here.
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello Django")
Run the server again:
trainee@brugges:~/guest$ python manage.py runserver 0.0.0.0:1025
go to visits/ and you should see your "hello" page:
Try index.htm and index.html and you should see the same thing. Try a different page on the same server / in the same application, and you'll see a "not found".
If you've any other errors, various exceptions will be flagged. Check carefully and get them sorted out before you go on to the next stage!
Breaking out your view from the controller class
You've now got your "Hello World" working, but that's just a starter. You really don't want to generate your HTML from within your Python - rather you want a separte look and feel file. Let's write a template, and call it firsttemplate.htp in a template subdirectory - so we now have:
trainee@brugges:~/guest$ ls -1R
.:
guest
manage.py
visit
./guest:
__init__.py
__init__.pyc
settings.py
settings.pyc
urls.py
urls.pyc
wsgi.py
wsgi.pyc
./visit:
__init__.py
__init__.pyc
models.py
models.pyc
templates
tests.py
views.py
views.pyc
./visit/templates:
firsttemplate.htp
Here's the template I used:
trainee@brugges:~/guest$ cat visit/templates/firsttemplate.htp
<html>
<head>
<title>First Template - Django Demonstration</title>
</head>
<body>
<h1>My Django Application - Mk 1</h1>
The current time is {{ timenowis }}<br /><br />
Copyright and other stuff will be needed too
</body>
</html>
Let's call that template into our view:
from django.http import HttpResponse
from django.template import Context, loader
def index(request):
t = loader.get_template('firsttemplate.htp')
dynamics = Context({ 'timenowis':'lunchtime'})
return HttpResponse(t.render(dynamics))
Here is what I get when I run that:
And you'll notice how I passed data though from the controller to the view via the Context object.
Breaking out the changing section of the page from the generic template
Although an application (or indeed a project) will share a single look and feel, there will usually be a common shell around each page - and using the DRY philosophy of Python and Django, you'll want to move that shared part of the template out into a separate file.
So - how are we going to do that?
1. We'll put the dynamic section of the content in its own template file:
{% extends "visitbase.htp" %}
{% block maincontent %}
<hr />
<i>This is the index page for the </i><b>Visit</b><i> application</i>
<hr />
{% endblock %}
You'll note that we've defined this as a block, and stated that when we render the page it will be include within the visitbase.htp look and feel profile - which is the common surround we'll be sharing all through the application.
Here's that visitbase.htp file:
<html>
<head>
<title>Django Demonstration Template</title>
</head>
<body>
<h1>This headline is shared by all pages within this application</h1>
The current time is {{ timenowis }}<br /><br />
{% block maincontent %} [Default if no matching block] {% endblock %}
<br />Copyright and other stuff will be needed too
</body>
</html>
And note the use of block again - this time to say where the enclosure goes.
I've also taken the opportunity here to simplify my controller - combining the loader, the complex completion and the HttpResponse constructor into a single helper (shortcut) method that's provided by Django calls render_to_response.
from django.shortcuts import render_to_response
def index(request):
dynamics = Context({ 'timenowis':'lunchtime'})
return render_to_response('indextemplate.htp',dynamics)

We've still not completed story 0 - we have no data nor model yet, but we do have a router, a controller and a view system running within Django. Probably a good point at which to say we've finished story 0, and take a look at our structure and files.
trainee@brugges:~/guest$ ls -R1 ../guest
../guest:
guest
manage.py
visit
../guest/guest:
__init__.py
__init__.pyc
settings.py
settings.pyc
urls.py
urls.pyc
wsgi.py
wsgi.pyc
../guest/visit:
__init__.py
__init__.pyc
models.py
models.pyc
templates
tests.py
views.py
views.pyc
../guest/visit/templates:
firsttemplate.htp
indextemplate.htp
visitbase.htp
trainee@brugges:~/guest$
This example is for Django version 1.5.1 ... dictory structures were slightly different under previous versions. As I write, 1.5.1 is current, with 1.6 under test and early release; 1.5.1 is best for new production code.
Files used (modified by edit) in the above example:
firsttemplate.htp - first (all in one) template
indextemplate.htp included templare for index page
visitbase.htp - overall application template
urls.py - Router
settings.py - Configuration
views.py - Controller
Posted by gje at 05:44 PM
| Comments (0)
Related topics: via article database
May 18, 2013
Python Properties - how and why
When you're being taught Object Oriented Programming, you'll usually be encouraged to access all the various elements within each object through methods rather than by going directly at the variables that hold propoerties within the object directly. And yet this will often result (depending on the language) in you having to write a whole series of short property accessor functions. Here's an example of the sort of thing that I mean in Python:
def setPubyear(self,year):
self.pubyear = year
def getPubyear(self):
return self.pubyear
The reason you're taught (and I, too, teach) the use of methods rather than direct variable access is because it gives you a far greater flexibility later on. Hard coding variable names within objects into applications makes those variables a part of the API (Application Program Interface) and the provider of the class is then constrained in future enhancements. And that's a double constraint, because there's no intermediate code layer in which features that may become necessary (capitalisation, space trimming, logging access etc) can be added. In other words - by directly accessing variables, you're building up a potential update and maintenance problem.
But wouldn't it be nice in the application to be able to access properties / attributes of an object as if they were simple variables, rather than having to use the extended syntax of calling setter and getter methods? Well - in Python you can, using a property. Here's how it works:
• within your class, you declare that variable name = property (getter, setter, deleter, doc) where getter, setter and deleter are the methods to run when a property is called up. You'll always need to provide a getter (otherwise there's little point in trying to define a property), but the other parameters are optional.
• within your application, you access the property as if it was a variable within the object, but within the class it gets diverted to the code.
Example:
Defining a property:
author = property(lambda x:x._author , None)
Making use of that property:
print nineteen.author
Complete example - [here] from the course I've been giving in Oxford for the last couple of days. And that gives me an excuse to illustrate my post with a picture I took when walking into the location at which I was training along the River Thames
Posted by gje at 09:58 AM
| Comments (0)
Useful link: Python training
Related topics: via article database
More things to make sure that we do NOT do ...
An addiiton to my note on my "Oxford" Hotel .. and confirmation of why we provide Well House Manor for our guests...
One loo, one showerroom between three rooms (the 4th in en Suite). And when I took a shower, I noted:
* No loo in the bathroom.

* Going to the separate loo on the way to the bathroom... no hooks or table to put towel/clothes on while using loo - had to use floor.
* A shared shower mat for all guests
* Toilet and shower room doors bolt from inside, with no outside indication if they're engaged or not
* Black mould in the shower
* Shower head very loose - you have to jiggle with it when the water's on to get it to play over you rather than down the wall.
+ Good water flow, hot water, came through almost instantly too
And looking wider
* Thin walls
* Fire safety sign on floor, under fire extinguisher, wedged in by bookcase

* No checkin to check address / gather any needed legal deatails
* Not matching hangers in wardrobe

* Fire door and automatic closer on bedroom but carpet pile stops the door closing automatically, and it must be dragged
* Single tiny cereal packet at breakfast - then the basket's taken away. Single butter pat. Nice butter, mind you.
* Lots of doors marked "private". No "knock for help" or call bell. A mobile phone number to call "if you need to reach us".
* "BBE July 2012" says the marmalade - in May 2013
+ Strong WiFi connection / easy connection (benchmarked to a tenth of what we have at Well House Manor, but it met my needs!)
+ Efficient payment - took my 50 pounds quickly by modern credit card machine
In summary... I can put up with a lot of the limitations if made to feel welcome - but here I felt that my primary purpose was to provide an income. So much could be done at so little outlay... but then they were full, so why bother - there will be plenty more mugs along to pay them their fifty quid.
Posted by gje at 08:37 AM
| Comments (0)
Related topics: via article database
May 17, 2013
Identity in Python
There's a differece between "the same", "equal" and "identical". I can have two identical 5p coins, but they're not the same coin. And I can have two coins which are not identical, but are equal in value. And when you're checking for equality in a program, you should know which you're looking at. Take a look at this in Python:
>>> a = [10]
>>> b = [10]
>>> c = a
>>> a == b
True
>>> a is b
False
>>> a is c
True
>>>
a and b are different lists, but they contain identical information. c is another name for the list which is also called a.
The == operator tells you whether two variables (or expressions) contain equal values, whether or not they're the same actual object.
The is operator tells you whether two variable names point to the same object.
A list (as used above) is a mutable object - something that can be changed within itself. Integers, floats, strings and tuples are immutable - in other words if you want to change something, you need to create a new replacement object. And in Python, identical immutable objects are stored only once for efficiency - so you'll find a different set of results from using is ... if two immutable objects are identical, they'll be the same object. Thus:
 >>> a = 10
 >>> b = 10
 >>> c = a
 >>> a == b
 True
 >>> a is b
 True
 >>> a is c
 True
 >>>
Posted by gje at 07:41 AM
| Comments (0)
Useful link: Python training
Related topics: via article database
A reminder of why we opened Well House Manor for our customers
Twenty years ago, I would have been happy with the B&B I'm writing from. The room's clean and recently decorated, the bed's comfortable and the traffic noise from outside is bearable. But, alas, times have moved on and these days people want more - indeed that's exactly why we opened Well House Manor for our business guests... later extended to business guests of other local businesses, and now as a generally available hotel.
So - what are the issues that have changed?
Firstly, I prefer en-suite. Now I knew this was not when I booked it, but I still expected a wash basin in the room. Tough, there isn't one. And - worse - the single shared loo doesn't have a washbasin either; the only wash and water available is in the single shared bathroom shower room.
Secondly, I like a bit of space. This room's a single. And it's a single because that's all that could fit between the door and the wall. There's no room for a bedside table, so in order to put something aside, it's down to the floor or up and across to the little "dresser/desk" which is very suitable for smaller people.

Thirdly, I welcome a welcome tray and, yes there is one (queue for water at the shower room). And I would love to be able to plug it in. I'm able to do so, provided that I unplug either my laptop or the TV, but the kettle must remain and boil on the floor because the built-in cable isn't long enough to reach up to the dresser.

Fourthly, the description of the location is "Oxford". Postal address, maybe but it turns out that it's on a very long street and is beyond even the ring road. Bit of an issue as I left my car where I'm working and walked here due to the traffic issues of the City. An enquiry of where there's a nearby place to eat tells me to go to Summertown - that's a mile and a half, and advises me to get the bus if I don't want to walk.
Fifthly, the welcome was "a la seaside landlady". Not "did you have a good journey", but "I'm glad you got here [at last] because we're going out". And that was at around 18:30, when I had booked for arrival between 18:00 and 19:00.
In the 1990s, this would have been fine - the sort of place where First Alternative delegates used to stay when I was training for them in Harwell. But times have moved on, everyone (or nearly everyone) has upped their game and although it's clean (and does offer WiFi) it's fallen behind - and behind to the degree of being "sorry - I wouldn't stay again".
The price I'm paying? The same as I paid for a hotel about half a mile from Paddington station last week, which overlooked a London Square and was just round the corner to Bayswater. And that was en-suite. Mind you - the London place is exceedingly good value!
Posted by gje at 07:12 AM
| Comments (0)
Related topics: via article database
May 16, 2013
Test Driven Development in Python - Customer Comes First
The Customer comes first!
When you're writing code, you should be thinking of your user. That may be your end user or - if you're writing a module or classes - that might be a fellow developer, set of developers or even yourself. Whichever it is, the important thing is to get it right for them. It needs to be well specified, robust, well tested - and that's why you're encouraged to use Test Driven Development.
Writing the tests first helps you ensure that you're providing the right product. It helps you ensure that each of the elements work. And it lets you use testing tools which allow you to build up, rerun and retest time and time again with correlated results. How many times have I written code, come back to it years later and added something in the process breaking an obscure but important feature? With test driven development, and unit test tools, I can now build up test procedures and have an ever-growing validation set. That way, features won't get left behind.
Python coding has always encouraged redientary testing with
if __name__ == "__main__":
but we can now go further - and we did on yesterday's Intermediate Python course.
My first test code is [here]. It's a simple exercise of an object, with the user having to check the results and ensure that they're as expected.
I extended that [here], testing multiple objects - but still a manual look through the results to ask "was that OK?"
Using unittest [here], I ran a series of tests and they come out with a neat report to show how they've done and
finally [here] I ran a series of tests in severl test groups. And indeed I can keep adding if I wish.
With all working tests, the final results are as short as
munchkin:yi grahamellis$ python tdd_3
.....
----------------------------------------------------------------------
Ran 5 tests in 0.001s
OK
munchkin:yi grahamellis$
which is really all I need.
With a failed test, you get a need log telling you where the issue lies:
munchkin:yi grahamellis$ python tdd_3
F....
======================================================================
FAIL: testfinish (__main__.TestBusFunctions)
----------------------------------------------------------------------
Traceback (most recent call last):
File "tdd_3", line 61, in testfinish
self.assertEqual(gam,"08:28")
AssertionError: '08:27' != '08:28'
----------------------------------------------------------------------
Ran 5 tests in 0.001s
FAILED (failures=1)
munchkin:yi grahamellis$
The sample class I was testing through these examples is [here]. You'll note that it's independent of the tests in that there's noting at all that changes in the class for it to be run under the test harness.
Posted by gje at 05:46 AM
| Comments (0)
Useful link: Python training
Related topics: via article database
May 15, 2013
Quick and easy - showing Python data hander output via a browser
From today's intermediate Python course - a new example of how to very quickly present the results of running an application on the web - [here].
The objective was to provide an almost-trivial way of letting results be viewed via a remote browser. No forms, no validation needed, no formatting of the plain text output. I used the oldfashioned common gateway interface.
My script starts:
#!/usr/bin/env python
print "Content-type: text/html\n"
And that's to tell the Apache httpd web server that the script is written in Python, and that the output is HTML.
You also need to enable CGI in your httpd.conf file (or a file it includes) and set the file to be executable.
In order to have the code that normally prints the results to file / stdout in a fixed width font, you'll want to put it within a preformatted style, or <pre> tag pair.
print "<pre>"
Output code goes here
print "</pre>"
Posted by gje at 08:17 PM
| Comments (0)
Useful link: Python training
Related topics: via article database
Some tips and techniques for huge data handling in Python
Python's an excellent tool for handling huge data sets and long-running programs, although some of the elements of the language that you'll use for such work aren't exactly things we teach on our Introduction to Python courses. Yesterday, however, I was teaching an Intermediate Python course, and had a chance to cover a number of these things.
Some elements of note:
a) Progress logging to stderr:
tracey = sys.stderr
and
percent = 100.0 * counter / totalwork
report = "Here we go ... {:8.2f}% of the way\r".format(percent)
tracey.write(report)
tracey.flush()
in my code. The output's to stderr rather than stdout so that it won't be redirected to file if there's any redirection done with >. It's output using \r rather than \n to ensure that reports overwrite one another, and I've added a flush so that the output doesn't hang around in buffers but is displayed straight away, even though there are no newlines (\n)s.
b) Reprogramming of ^C
signal.signal(signal.SIGINT,sighandler)
which causes ^C to run a handler:
def sighandler(which, frame):
# This could be run at ANY point ... don't do much in here!
global interim
interim = 1
# If ^C is pressed twice within a second, really do kill it!
now = time.time()
sighandler.recent += 1
if now - sighandler.recent < 1:
sys.exit(0)
sighandler.recent = now
I've tried to do as little as possible in this handler, as the code could be called a just about any time. It tries to do little more than set a flag to indicate that an interim report is to be produced at an appropriate point. However, I have added extra code to pick up ^C twice in a second - if someone's hammering the keyboard then, sure, let the program exit.
Complete source code [here].
If you want ^C to generate an exception, see [here]. That's not a suitable trap where we want to resume execution straight away, as exceptions jump out from a piece of trapping code
Posted by gje at 01:04 AM
| Comments (0)
Useful link: Python training
Related topics: via article database
May 14, 2013
Python network programming - new FTP and socket level examples
These days, it's the exception rather than the rule to write low level network code within your applications - and during today's Intermediate Python course, I wrote an example showing an FTP connection to retrieve data using ftplib. The first example is [here] - grabbing a file, saving it locally via a callback.
A second version, using a thread to allow the FTP connection to be running while the main program is getting on with something else, is [here].
If you do need to program a socket directly, yes, you can do so. I've revised / refreshed myself into that - [here] is a demonstration from first principles of picking up a header from a web server. Lots of extra checking to do really, but the examples show the principles and you can build from there.
Posted by gje at 05:31 PM
| Comments (0)
Useful link: Python training
Related topics: via article database
