<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
<title>Horse&apos;s Mouth</title>
<link rel="alternate" type="text/html" href="http://www.wellho.net/horse/" />
<modified>2013-05-18T09:59:16Z</modified>
<tagline>Musing, events and thoughts from Graham Ellis</tagline>
<id>tag:www.wellho.net,2013:/horse/1</id>
<generator url="http://www.movabletype.org/" version="3.01">Movable Type</generator>
<copyright>Copyright (c) 2013, gje</copyright>
<entry>
<title>Python Properties - how and why</title>
<link rel="alternate" type="text/html" href="http://www.wellho.net/archives/2013/05/index.html#004094" />
<modified>2013-05-18T09:59:16Z</modified>
<issued>2013-05-18T09:58:09Z</issued>
<id>tag:www.wellho.net,2013:/horse/1.4094</id>
<created>2013-05-18T09:58:09Z</created>
<summary type="text/plain">When you&apos;re being taught Object Oriented Programming, you&apos;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...</summary>
<author>
<name>gje</name>

<email>graham@wellho.net</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.wellho.net/horse/">
<![CDATA[<p><img src=http://www.wellho.net/pix/oxgoose.jpg align=right hspace=5>When you're being taught Object Oriented Programming, you'll usually be encouraged to access all the various elements within each object through <b>methods</b> rather than by going directly at the <b>variables</b> 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:</p>

<p><code>&nbsp;&nbsp;def setPubyear(self,year):<br />
&nbsp;&nbsp;&nbsp;&nbsp;self.pubyear = year<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;def getPubyear(self):<br />
&nbsp;&nbsp;&nbsp;&nbsp;return self.pubyear</code></p>

<p>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.</p>

<p>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 <b>property</b>. Here's how it works:</p>

<p>&bull; within your class, you declare that <code>variable name = property (getter, setter, deleter, doc) </code> 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.    </p>

<p>&bull; 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.</p>

<p>Example:</p>

<p>Defining a property:<br />
<code>&nbsp;&nbsp;author = property(lambda x:x._author , None)</code></p>

<p>Making use of that property:<br />
<code>&nbsp;&nbsp;print nineteen.author</code></p>

<p>Complete example - <a href=http://www.wellho.net/resources/ex.php?item=y112/ob1.py>[here]</a> 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<br clear=all></p>]]>

</content>
</entry>
<entry>
<title>More things to make sure that we do NOT do ...</title>
<link rel="alternate" type="text/html" href="http://www.wellho.net/archives/2013/05/index.html#004093" />
<modified>2013-05-18T09:08:26Z</modified>
<issued>2013-05-18T08:37:12Z</issued>
<id>tag:www.wellho.net,2013:/horse/1.4093</id>
<created>2013-05-18T08:37:12Z</created>
<summary type="text/plain">An addiiton to my note on my &quot;Oxford&quot; 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,...</summary>
<author>
<name>gje</name>

<email>graham@wellho.net</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.wellho.net/horse/">
<![CDATA[<p>An addiiton to my note on <a href=http://www.wellho.net/mouth/4091_A-reminder-of-why-we-opened-Well-House-Manor-for-our-customers.html>my "Oxford" Hotel</a> .. and confirmation of why we provide <a href=http://www.wellhousemanor.co.uk>Well House Manor</a> for our guests...</p>

<p>One loo, one showerroom between three rooms (the 4th in en Suite).  And when I took a shower, I noted:</p>

<p>* No loo in the bathroom.</p>

<center><img src=http://www.wellho.net/pix/hollyloo.jpg width=450></center>

<p>* 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.</p>

<p>* A shared shower mat for all guests</p>

<p>* Toilet and shower room doors bolt from inside, with no outside indication if they're engaged or not</p>

<p>* Black mould in the shower</p>

<p>* 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.</p>

<p>+ Good water flow, hot water, came through almost instantly too</p>

<p>And looking wider</p>

<p>* Thin walls</p>

<p>* Fire safety sign on floor, under fire extinguisher, wedged in by bookcase</p>

<center><img src=http://www.wellho.net/pix/hollyfire.jpg width=450></center>

<p>* No checkin to check address / gather any needed legal deatails</p>

<p>* Not matching hangers in wardrobe</p>

<center><img src=http://www.wellho.net/pix/hollyhangers.jpg width=450></center>

<p>* Fire door and automatic closer on bedroom but carpet pile stops the door closing automatically, and it must be dragged</p>

<p>* Single tiny cereal packet at breakfast - then the basket's taken away. Single butter pat. Nice butter, mind you.</p>

<p>* Lots of doors marked "private". No "knock for help" or call bell. A mobile phone number to call "if you need to reach us".</p>

<p>* "BBE July 2012" says the marmalade - in May 2013</p>

<p>+ Strong WiFi connection / easy connection (benchmarked to a tenth of what we have at Well House Manor, but it met my needs!)</p>

<p>+ Efficient payment - took my 50 pounds quickly by modern credit card machine</p>

<p><i>In summary...</i> 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.</p>]]>

</content>
</entry>
<entry>
<title>Identity in Python</title>
<link rel="alternate" type="text/html" href="http://www.wellho.net/archives/2013/05/index.html#004092" />
<modified>2013-05-18T08:59:45Z</modified>
<issued>2013-05-17T07:41:04Z</issued>
<id>tag:www.wellho.net,2013:/horse/1.4092</id>
<created>2013-05-17T07:41:04Z</created>
<summary type="text/plain">There&apos;s a differece between &quot;the same&quot;, &quot;equal&quot; and &quot;identical&quot;. I can have two identical 5p coins, but they&apos;re not the same coin. And I can have two coins which are not identical, but are equal in value. And when you&apos;re...</summary>
<author>
<name>gje</name>

<email>graham@wellho.net</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.wellho.net/horse/">
<![CDATA[<p>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:</p>

<p><code>&nbsp;&nbsp;>>> a = [10]<br />
&nbsp;&nbsp;>>> b = [10]<br />
&nbsp;&nbsp;>>> c = a<br />
&nbsp;&nbsp;>>> a == b<br />
&nbsp;&nbsp;True<br />
&nbsp;&nbsp;>>> a is b<br />
&nbsp;&nbsp;False<br />
&nbsp;&nbsp;>>> a is c<br />
&nbsp;&nbsp;True<br />
&nbsp;&nbsp;>>></code></p>

<p>a and b are different lists, but they contain identical information. c is another name for the list which is also called a.</p>

<p>The <b>==</b> operator tells you whether two variables (or expressions) contain equal values, whether or not they're the same actual object.</p>

<p>The <b>is</b> operator tells you whether two variable names point to the same object.</p>

<p>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 <b>is</b> ... if two immutable objects are identical, they'll be the same object. Thus:</p>

<p><code>&nbsp;&nbsp>>> a = 10<br />
&nbsp;&nbsp>>> b = 10<br />
&nbsp;&nbsp>>> c = a<br />
&nbsp;&nbsp>>> a == b<br />
&nbsp;&nbspTrue<br />
&nbsp;&nbsp>>> a is b<br />
&nbsp;&nbspTrue<br />
&nbsp;&nbsp>>> a is c<br />
&nbsp;&nbspTrue<br />
&nbsp;&nbsp>>></code></p>]]>

</content>
</entry>
<entry>
<title>A reminder of why we opened Well House Manor for our customers</title>
<link rel="alternate" type="text/html" href="http://www.wellho.net/archives/2013/05/index.html#004091" />
<modified>2013-05-18T08:58:40Z</modified>
<issued>2013-05-17T07:12:33Z</issued>
<id>tag:www.wellho.net,2013:/horse/1.4091</id>
<created>2013-05-17T07:12:33Z</created>
<summary type="text/plain"><![CDATA[Twenty years ago, I would have been happy with the B&amp;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...]]></summary>
<author>
<name>gje</name>

<email>graham@wellho.net</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.wellho.net/horse/">
<![CDATA[<p>Twenty years ago, I would have been happy with the B&amp;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 <a href=http://www.wellhousemanor.co.uk>Well House Manor</a> for our business guests... later extended to business guests of other local businesses, and now as a generally available hotel.</p>

<p>So - what are the issues that have changed?</p>

<p>Firstly, I prefer en-suite. Now I knew this was <i>not</i> 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 <s>bathroom</s> shower room.</p>

<p>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.</p>

<center><img src=http://www.wellho.net/pix/hollybed.jpg width=450></center>

<p>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. </p>

<center><img src=http://www.wellho.net/pix/hollykettle.jpg width=450></center>

<p>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.</p>

<p>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.</p>

<p>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".</p>

<p>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!</p>]]>

</content>
</entry>
<entry>
<title>Test Driven Development in Python - Customer Comes First</title>
<link rel="alternate" type="text/html" href="http://www.wellho.net/archives/2013/05/index.html#004090" />
<modified>2013-05-18T08:55:24Z</modified>
<issued>2013-05-16T05:46:48Z</issued>
<id>tag:www.wellho.net,2013:/horse/1.4090</id>
<created>2013-05-16T05:46:48Z</created>
<summary type="text/plain">The Customer comes first! When you&apos;re writing code, you should be thinking of your user. That may be your end user or - if you&apos;re writing a module or classes - that might be a fellow developer, set of developers...</summary>
<author>
<name>gje</name>

<email>graham@wellho.net</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.wellho.net/horse/">
<![CDATA[<p>The Customer comes first!</p>

<p>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 <i>important</i> 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 <b>Test Driven Development</b>.   </p>

<p>Writing the tests <i>first</i> 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.</p>

<p>Python coding has always encouraged redientary testing with <br />
<code>&nbsp;&nbsp;if __name__ == "__main__":</code><br />
but we can now go further - and we did on yesterday's <a href=http://www.wellho.net/course/yifull.html>Intermediate Python</a> course.</p>

<p>My first test code is <a href=http://www.wellho.net/resources/ex.php?item=y212/tdd_0 target=bob>[here]</a>. It's a simple exercise of an object, with the user having to check the results and ensure that they're as expected.</p>

<p>I extended that <a href=http://www.wellho.net/resources/ex.php?item=y212/tdd_1 target=bob>[here]</a>, testing multiple objects - but still a manual look through the results to ask "was that OK?"</p>

<p>Using <b>unittest</b> <a href=http://www.wellho.net/resources/ex.php?item=y212/tdd_2 target=bob>[here]</a>, I ran a series of tests and they come out with a neat report to show how they've done and</p>

<p>finally <a href=http://www.wellho.net/resources/ex.php?item=y212/tdd_3 target=bob>[here]</a> I ran a series of tests in severl test groups.  And indeed I can keep adding if I wish.</p>

<p>With all working tests, the final results are as short as</p>

<p><code>&nbsp;&nbsp;munchkin:yi grahamellis$ python tdd_3<br />
&nbsp;&nbsp;.....<br />
&nbsp;&nbsp;----------------------------------------------------------------------<br />
&nbsp;&nbsp;Ran 5 tests in 0.001s<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;OK<br />
&nbsp;&nbsp;munchkin:yi grahamellis$</code></p>

<p>which is really all I need.</p>

<p>With a failed test, you get a need log telling you where the issue lies:</p>

<p><code>&nbsp;&nbsp;munchkin:yi grahamellis$ python tdd_3<br />
&nbsp;&nbsp;F....<br />
&nbsp;&nbsp;======================================================================<br />
&nbsp;&nbsp;FAIL: testfinish (__main__.TestBusFunctions)<br />
&nbsp;&nbsp;----------------------------------------------------------------------<br />
&nbsp;&nbsp;Traceback (most recent call last):<br />
&nbsp;&nbsp;&nbsp;&nbsp;File "tdd_3", line 61, in testfinish<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.assertEqual(gam,"08:28")<br />
&nbsp;&nbsp;AssertionError: '08:27' != '08:28'<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;----------------------------------------------------------------------<br />
&nbsp;&nbsp;Ran 5 tests in 0.001s<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;FAILED (failures=1)<br />
&nbsp;&nbsp;munchkin:yi grahamellis$</code></p>

<p>The sample class I was testing through these examples is <a href=http://www.wellho.net/resources/ex.php?item=y212/transport.py>[here]</a>.   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.</p>]]>

</content>
</entry>
<entry>
<title>Quick and easy - showing Python data hander output via a browser</title>
<link rel="alternate" type="text/html" href="http://www.wellho.net/archives/2013/05/index.html#004089" />
<modified>2013-05-18T08:53:54Z</modified>
<issued>2013-05-15T20:17:13Z</issued>
<id>tag:www.wellho.net,2013:/horse/1.4089</id>
<created>2013-05-15T20:17:13Z</created>
<summary type="text/plain">From today&apos;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...</summary>
<author>
<name>gje</name>

<email>graham@wellho.net</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.wellho.net/horse/">
<![CDATA[<p>From today's intermediate Python course - a new example of how to very quickly present the results of running an application on the web - <a href=http://www.wellho.net/resources/ex.php?item=y202/pyhello>[here]</a>.</p>

<p>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.</p>

<p>My script starts:</p>

<p><code>&nbsp;&nbsp;#!/usr/bin/env python<br />
&nbsp;&nbsp;print "Content-type: text/html\n"</code></p>

<p>And that's to tell the Apache httpd web server that the script is written in Python, and that the output is HTML.</p>

<p>You also need to enable CGI in your httpd.conf file (or a file it includes) and set the file to be executable.</p>

<p>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 &lt;pre> tag pair.</p>

<p><code>&nbsp;&nbsp;print "&lt;pre>"<br />
&nbsp;&nbsp;<i>Output code goes here</i><br />
&nbsp;&nbsp;print "&lt;/pre>"</code></p>]]>

</content>
</entry>
<entry>
<title>Some tips and techniques for huge data handling in Python</title>
<link rel="alternate" type="text/html" href="http://www.wellho.net/archives/2013/05/index.html#004088" />
<modified>2013-05-18T08:53:11Z</modified>
<issued>2013-05-15T01:04:13Z</issued>
<id>tag:www.wellho.net,2013:/horse/1.4088</id>
<created>2013-05-15T01:04:13Z</created>
<summary type="text/plain">Python&apos;s an excellent tool for handling huge data sets and long-running programs, although some of the elements of the language that you&apos;ll use for such work aren&apos;t exactly things we teach on our Introduction to Python courses. Yesterday, however, I...</summary>
<author>
<name>gje</name>

<email>graham@wellho.net</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.wellho.net/horse/">
<![CDATA[<p>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 <a href=http://www.wellho.nec/course/ypfull.html>Introduction to Python</a> courses. Yesterday, however, I was teaching an <a href=http://www.wellho.net/course/yifull.html>Intermediate Python</a> course, and had a chance to cover a number of these things.</p>

<p>Some elements of note:</p>

<p>a) Progress logging to stderr:</p>

<p><code>&nbsp;&nbsp;tracey = sys.stderr</code></p>

<p>and </p>

<p><code>&nbsp;&nbsp;percent = 100.0 * counter / totalwork<br />
&nbsp;&nbsp;report = "Here we go ... {:8.2f}% of the way\r".format(percent)<br />
&nbsp;&nbsp;tracey.write(report)<br />
&nbsp;&nbsp;tracey.flush()</code></p>

<p>in my code. The output's to <b>stderr</b> rather than <b>stdout</b> 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.</p>

<p>b) Reprogramming of ^C</p>

<p><code>&nbsp;&nbsp;signal.signal(signal.SIGINT,sighandler)</code></p>

<p>which causes ^C to run a handler:</p>

<p><code>&nbsp;&nbsp;def sighandler(which, frame):<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;# This could be run at ANY point ... don't do much in here!<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;global interim<br />
&nbsp;&nbsp;&nbsp;&nbsp;interim = 1<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;# If ^C is pressed twice within a second, really do kill it!<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;now = time.time()<br />
&nbsp;&nbsp;&nbsp;&nbsp;sighandler.recent += 1<br />
&nbsp;&nbsp;&nbsp;&nbsp;if now - sighandler.recent &lt; 1:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sys.exit(0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;sighandler.recent = now</code></p>

<p>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 <i>have</i> added extra code to pick up ^C twice in a second - if someone's hammering the keyboard then, sure, let the program exit.</p>

<p>Complete source code <a href=http://www.wellho.net/resources/ex.php?item=y305/longjob>[here]</a>.</p>

<p><i>If you want ^C to generate an exception, see <a href=http://www.wellho.net/resources/ex.php4?item=y109/stopc>[here]</a>. That's not a suitable trap where we want to resume execution straight away, as exceptions jump out from a piece of trapping code</i></p>]]>

</content>
</entry>
<entry>
<title>Python network programming - new FTP and socket level examples</title>
<link rel="alternate" type="text/html" href="http://www.wellho.net/archives/2013/05/index.html#004087" />
<modified>2013-05-18T08:52:17Z</modified>
<issued>2013-05-14T17:31:48Z</issued>
<id>tag:www.wellho.net,2013:/horse/1.4087</id>
<created>2013-05-14T17:31:48Z</created>
<summary type="text/plain">These days, it&apos;s the exception rather than the rule to write low level network code within your applications - and during today&apos;s Intermediate Python course, I wrote an example showing an FTP connection to retrieve data using ftplib. The first...</summary>
<author>
<name>gje</name>

<email>graham@wellho.net</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.wellho.net/horse/">
<![CDATA[<p>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 <b>ftplib</b>. The first example is <a href=http://www.wellho.net/resources/ex.php?item=y303/ftpgrab>[here]</a> - grabbing a file, saving it locally via a callback.</p>

<p>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 <a href=http://www.wellho.net/resources/ex.php?item=y303/ftpthread>[here]</a>.</p>

<p>If you do need to program a socket directly, yes, you <i>can</i> do so.  I've revised / refreshed myself into that - <a href=http://www.wellho.net/resources/ex.php?item=y303/to_me>[here]</a> 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.</p>]]>

</content>
</entry>
<entry>
<title>Cacheing class for Python - using a local SQLite database as a key/value store</title>
<link rel="alternate" type="text/html" href="http://www.wellho.net/archives/2013/05/index.html#004086" />
<modified>2013-05-18T08:51:29Z</modified>
<issued>2013-05-14T07:02:15Z</issued>
<id>tag:www.wellho.net,2013:/horse/1.4086</id>
<created>2013-05-14T07:02:15Z</created>
<summary type="text/plain">Question from Tom: What did you have for lunch yesterday? Answer: A Sandwich, a piece of cake and some fruit. Question from Dick: What did you have for lunch yesterday? Answer: A Sandwich, a piece of cake and some fruit....</summary>
<author>
<name>gje</name>

<email>graham@wellho.net</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.wellho.net/horse/">
<![CDATA[<p>Question from Tom: What did you have for lunch yesterday?<br />
Answer: A Sandwich, a piece of cake and some fruit.</p>

<p>Question from Dick: What did you have for lunch yesterday?<br />
Answer: A Sandwich, a piece of cake and some fruit.</p>

<p>Question from Harry: What did you have for lunch yesterday?<br />
Answer: A Sandwich, a piece of cake and some fruit.</p>

<p>The answer's the same each time, no matter who asks, and it will remain the same for 24 hours no matter how many times is asked. And if working out the answer is quite a bit of work / involves getting someone else to remind you, then wouldn't it be better so remember the result and just replay it? That's the principle of <b>caching</b> an answer.</p>

<p>On yesterday's course, we were collecting a JSON object from a remote server, and doing so time and time again. That was inefficient use of the remote server, relatively slow, and an excellent demonstration case for caching the data returned which was originally called up for Tom, but is equally valid for Dick, Harry, Fiona, Betty, Susan and Bob. As a "control" case, the JSON loader example is <a href=http://www.wellho.net/resources/ex.php?item=y117/pyjson>[here]</a> and I wrote about it <a href=http://www.wellho.net/mouth/4085_JSON-from-Python-first-principles-easy-example.html>[here]</a>.</p>

<p>Principle of basic cacheing:<br />
&bull; ask if we already have the data locally<br />
&bull; if YES, supply the local copy<br />
&bull; if NO, read from the remote source and store a copy locally</p>

<p>I've added code (in Python) that caches our JSON object into a local file - <a href=http://www.wellho.net/resources/ex.php?item=y117/pyjson_with_cache>[here]</a> - into the control example.  There were a few bells and whistles required:</p>

<p>a) We had to see if the cached file actually existed (we checked how old it was) before we read it:</p>

<p><code>&nbsp;&nbsp;try:<br />
&nbsp;&nbsp;&nbsp;&nbsp;cachetime = os.path.getmtime("cachedrecord.txt")<br />
&nbsp;&nbsp;except:<br />
&nbsp;&nbsp;&nbsp;&nbsp;cachetime = 0</code></p>

<p>b) We had to check to see if we had data that was out of date (in the example, data may live for just 20 seconds)</p>

<p><code>&nbsp;&nbsp;if time.time() - cachetime > 20:</code></p>

<p>c) We had to handle the case of being unable to open the file to store the cached data:</p>

<p><code>&nbsp;&nbsp;try:<br />
&nbsp;&nbsp;&nbsp;&nbsp;fho = open("cachedrecord.txt","w")<br />
&nbsp;&nbsp;&nbsp;&nbsp;fho.write(stuff)<br />
&nbsp;&nbsp;&nbsp;&nbsp;fho.close()<br />
&nbsp;&nbsp;except:<br />
&nbsp;&nbsp;&nbsp;&nbsp;pass</code></p>

<p>But there are two things that could be improved in that code:<br />
&bull; We're only caching a single specific value and<br />
&bull; We've added the caching code within our main program class; it's a useful utility and should be its own class for reuse and support purposes!<br />
So during the <a href=http://www.wellho.net/course/yifull.html>Intermediate Python Course</a> we improved on it!</p>

<p>The refactored application is <a href=http://www.wellho.net/resources/ex.php?item=y113/pyjson_kvcache>[here]</a> ... and the cache code has been reduced to:</p>

<p><code>&nbsp;&nbsp;import kvcache<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;localstore = kvcache.kvcache("http://www.wellho.net/services/*.json")<br />
&nbsp;&nbsp;stuff = localstore.get("pix")</code></p>

<p><i>Yes - that's all I need in my application!</i>  Of course, all the hard work's done within the class, where I used an SQLite3 database to store and retreive multiple records based on a key - "pix" in my example, but the system can store and pull back based on any unique test string key.    The source code of the kvcache class is <a href=http://www.wellho.net/resources/ex.php?item=y113/kvcache.py>[here]</a>.</p>

<p>There are just two methods on the class:<br />
&bull; a constructor into which I pass the base URL (with a "*" for where the key is to be substituted in), and optionally a time to live (default 20 seconds) and a database file name for the class to use (defauly /tmp/mycache)<br />
&bull; a <b>get</b> method, which returns the record requested; pass in the key that you're looking for (substitute for the "*" in the URL in the constructor) and it will do the rest ... from setting up the database table, to pulling the record back, storing it based on key, checking timestamps, deleting the old record if it's expired.<br />
All in all, this is a "classic" demonstration of the use of a class; the complicated stuff is encapsulated in the class, and all the user has to do is make a couple of simple calls ...</p>

<p>We could refactor further - I could replace the storage engine in the class with <b>memcached</b> for example, allowing cached responses to be held in memory and shared between a number of servers. And the beauty of the OO approach is that <i>all my applications that use the kvcache should work without alteration</i> once my refactoring has been completed with the same API.<br />
</p>]]>

</content>
</entry>
<entry>
<title>JSON from Python - first principles, easy example</title>
<link rel="alternate" type="text/html" href="http://www.wellho.net/archives/2013/05/index.html#004085" />
<modified>2013-05-18T08:50:15Z</modified>
<issued>2013-05-13T18:53:37Z</issued>
<id>tag:www.wellho.net,2013:/horse/1.4085</id>
<created>2013-05-13T18:53:37Z</created>
<summary type="text/plain">Here&apos;s a short example of how to pick up a JSON feed from a URL in Python. All the examples I came across looked very complicated, so I thought I would write one that&apos;s really straightforward: Open a remote URL...</summary>
<author>
<name>gje</name>

<email>graham@wellho.net</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.wellho.net/horse/">
<![CDATA[<p>Here's a short example of how to pick up a JSON feed from a URL in Python. All the examples I came across looked very complicated, so I thought I would write one that's really straightforward:</p>

<p>Open a remote URL feed that provides a JSON object:</p>

<p><code>&nbsp;&nbsp;response = urllib2.urlopen('http://www.wellho.net/services/pix.json')</code></p>

<p>Read that object in:</p>

<p><code>&nbsp;&nbsp;stuff = response.read()</code></p>

<p>That'll give you a dict... and you can look at the keys:</p>

<p><code>&nbsp;&nbsp;for itemname in memory.keys():<br />
&nbsp;&nbsp;&nbsp;&nbsp;print itemname</code></p>

<p>... you can get at individual values:</p>

<p><code>&nbsp;&nbsp;toby = time.gmtime(memory["timedat"])<br />
&nbsp;&nbsp;print "This was generated at",memory["timedat"],time.strftime("%c",toby)</code></p>

<p><code>&nbsp;&nbsp;if memory["lookfor"]:<br />
&nbsp;&nbsp;&nbsp;&nbsp;print "Searching only for",memory["lookfor"]<br />
&nbsp;&nbsp;else:<br />
&nbsp;&nbsp;&nbsp;&nbsp;print "All available records requested"</code></p>

<p>... and you can look deeper into the structure if you like:</p>

<p><code>&nbsp;&nbsp;for record in memory["acc"]:<br />
&nbsp;&nbsp;&nbsp;&nbsp;print record["when"], record["which"]</code></p>

<p>Full code <a href=http://www.wellho.net/resources/ex.php?item=y117/pyjson>[here]</a>. More about urllib2, JSON from Pyton and lots of other subjects on our <a href=http://www.wellho.net/course/yifull.html>Intermediate Python Course</a></p>]]>

</content>
</entry>
<entry>
<title>New Pictures - Melksham Pack Horse Bridge</title>
<link rel="alternate" type="text/html" href="http://www.wellho.net/archives/2013/05/index.html#004084" />
<modified>2013-05-18T08:49:01Z</modified>
<issued>2013-05-12T08:58:11Z</issued>
<id>tag:www.wellho.net,2013:/horse/1.4084</id>
<created>2013-05-12T08:58:11Z</created>
<summary type="text/plain">Beautiful Spring Weekend. Yesterday, Gypsy and I walked the fields near Melksham down to the Pack Horse Bridge over the River Avon. The bridge used to be part of a major driving route, but these days it&apos;s become just a...</summary>
<author>
<name>gje</name>

<email>graham@wellho.net</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.wellho.net/horse/">
<![CDATA[<p>Beautiful Spring Weekend. Yesterday, Gypsy and I walked the fields near Melksham down to the Pack Horse Bridge over the River Avon.</p>

<p>The bridge used to be part of a major driving route, but these days it's become just a public footpath - off the Melksham to Holt road, across fields and over the railway line (<i>take care at the unprotected crossing</i> and over other fields down to the the water meadows.</p>

<center><img src=http://www.wellho.net/pix/m13_phb0.jpg width=450></center>
&nbsp;
<center><img src=http://www.wellho.net/pix/m13_phb1.jpg width=450></center>
&nbsp;
<center><img src=http://www.wellho.net/pix/m13_phb2.jpg width=450></center>
&nbsp;
<center><img src=http://www.wellho.net/pix/m13_phb3.jpg width=450></center>

<p>Beyond the river, if you take a right turn you'll walk beside the river for a while, then uphill to the little hamlet of Whaddon from where you can walk down Whaddon lane to the outskirts of Trowbridge at Hilperton. And there's a lovely circular walk along the Kennet and Avon Canal to Semington, then over fields and back to the Pack Horse Bridge. Scarcely a busy road - just one quiet lane, through beautiful countryside. If you're staying with us at Well House Manor, please ask for directions.<br />
</p>]]>

</content>
</entry>
<entry>
<title>Spring at Well House Manor - Teas and Coffees, Museum, Garden, Rooms</title>
<link rel="alternate" type="text/html" href="http://www.wellho.net/archives/2013/05/index.html#004083" />
<modified>2013-05-18T08:47:46Z</modified>
<issued>2013-05-11T19:40:58Z</issued>
<id>tag:www.wellho.net,2013:/horse/1.4083</id>
<created>2013-05-11T19:40:58Z</created>
<summary type="text/plain"><![CDATA[A beautiful spring day... though still a bit chilly. But the museum for Melksham is open every afternoon, and we're serving bean to cup coffee and cream teas inside and (currently for the more robust!) outside too. &nbsp; &nbsp; If...]]></summary>
<author>
<name>gje</name>

<email>graham@wellho.net</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.wellho.net/horse/">
<![CDATA[<p>A beautiful spring day... though still a bit chilly. But the museum for Melksham is open every afternoon, and we're serving bean to cup coffee and cream teas inside and (currently for the more robust!) outside too. </p>

<center><img src=http://www.wellho.net/pix/m13_shut.jpg width=450></center>
&nbsp;
<center><img src=http://www.wellho.net/pix/m13_foh.jpg width=450></center>
&nbsp;
<center><img src=http://www.wellho.net/pix/m13_front.jpg width=450></center>

<p>If you've got relatives coming to stay over the next few weeks, we've got good availability of rooms for most weekends - and Melksham is an excellent base from which to explore Wiltshire too.</p>]]>

</content>
</entry>
<entry>
<title>Training around the world - easy payment in pounds Sterling</title>
<link rel="alternate" type="text/html" href="http://www.wellho.net/archives/2013/05/index.html#004082" />
<modified>2013-05-11T13:21:20Z</modified>
<issued>2013-05-10T20:11:45Z</issued>
<id>tag:www.wellho.net,2013:/horse/1.4082</id>
<created>2013-05-10T20:11:45Z</created>
<summary type="text/plain">We&apos;ll train you in your own offices - whether they&apos;re close to our Melksham, UK base or far away. And that applies unless there are issues such as work permit, visa requirements or safety which mean that our tutor can&apos;t...</summary>
<author>
<name>gje</name>

<email>graham@wellho.net</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.wellho.net/horse/">
<![CDATA[<p>We'll train you in your own offices - whether they're close to our Melksham, UK base or far away. And that applies unless there are issues such as work permit, visa requirements or safety which mean that our tutor can't travel to you.</p>

<p>Historically, we have offered payment terms in Euros, US Dollars and GB pounds. But these days international money exchange and payment is much easier than it used to be, and customers now pay direct into our UK (pounds sterling) account without recent exception. We have therefore simplified our systems and our quotations are now purely in pounds. You'll find that the pound prices are (and always were) better for you that the prices we quoted in dollars or euro, simply because we no longer need to build in margins to allow for exchange rate fluctuations.</p>

<p>Each of our current fleet of delegate laptops is named after a location that I've traveled to as part of our training business - and I would love to visit any or all of them again. They're Albany, Brugges, Caerphilly, Dharan, Edinburgh, Frankfurt, Guadalajara, Helsinki, Izmir and Juneau!</p>]]>

</content>
</entry>
<entry>
<title>Pushing down the advertised price, pushing up the total price charged.</title>
<link rel="alternate" type="text/html" href="http://www.wellho.net/archives/2013/05/index.html#004081" />
<modified>2013-05-11T13:19:45Z</modified>
<issued>2013-05-08T19:24:53Z</issued>
<id>tag:www.wellho.net,2013:/horse/1.4081</id>
<created>2013-05-08T19:24:53Z</created>
<summary type="text/plain">The sign in lights outside this hotel says &quot;Rooms from 55 pounds&quot;. I&apos;ve prebooked and prepaid 69 per night (but then this *is* a London suburb), but I asked about the 55 pounds when I check in. Apparently, the rates...</summary>
<author>
<name>gje</name>

<email>graham@wellho.net</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.wellho.net/horse/">
<![CDATA[<p>The sign in lights outside this hotel says "Rooms from 55 pounds". I've prebooked and prepaid 69 per night (but then this *is* a London suburb), but I asked about the 55 pounds when I check in. Apparently, the rates vary and if you book fairly well ahead for a day that's not booking well, and not expected to book well, it may be offered to you. But advertised outside for tonight? No - it shouldn't be. The best you'll get as a walk in would be 74 machines.</p>

<p>I want to watch the TV, so I turn on then I have to select:<br />
&bull; Option 1 (default is 4 - special offer media package at 9.99)<br />
&bull; Option 8 (default is 5 - the same special offer media package; 1 at this menu would but you a pay movie<br />
&bull; Option 1 (Tv Channels)<br />
&bull; Option 1 (BBC One)</p>

<p>I have my own internet access. Without it, I could pay 5 pounds for an hour, or 9 pounds for 24 hours. But I would then learn that was only accessible in the lobby. It'll cost me 10 pounds for use in the room as well.</p>

<p>If I had forgotten anything at home, I could have bought a dental kit for a pound, a shaving kit for a pound, a sewing kit for a pound, and five pounds for a travel adapter.</p>

<p>Breakfast isn't included in my room rate. It will cost me 7.95 if I believe the information I was given when I booked. Or 8.95 if I believe the information in the lift.</p>

<p>I don't think I've spent any extras but I could so easily have had the odd pint of beer, a bit of breakfast, used the internet around the hotel, eaten a meal in (because it's rather windy out) and ended up spending 300 pounds for my three nights.</p>

<p><i>This experience is totally OPPOSITE to our policy at Well House Manor; no extras for breakfast, internet, teas and coffees - TV's free and there's no menu of costly add-ons to navigate to get to it;</i> granted, we're not just across the road from Elstree studios!</p>]]>

</content>
</entry>
<entry>
<title>Fancy a day at the seaside? Weymouth from Melksham</title>
<link rel="alternate" type="text/html" href="http://www.wellho.net/archives/2013/05/index.html#004080" />
<modified>2013-05-11T13:16:59Z</modified>
<issued>2013-05-06T11:15:55Z</issued>
<id>tag:www.wellho.net,2013:/horse/1.4080</id>
<created>2013-05-06T11:15:55Z</created>
<summary type="text/plain">Bank Holiday Monday - 27th May - is a rare opportunity to travel by train from Melksham to Weymouth for the day - prices are 16 pounds for an adult, or just 36 pounds for a group of 4 adults...</summary>
<author>
<name>gje</name>

<email>graham@wellho.net</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.wellho.net/horse/">
<![CDATA[<p>Bank Holiday Monday - 27th May - is a rare opportunity to travel by train from Melksham to Weymouth for the day - prices are 16 pounds for an adult, or just 36 pounds for a group of 4 adults and 4 children using a "Groupsave" ticket.</p>

<p><img src=http://www.wellho.net/pix/dress_r.jpg align=left hspace=5>The train at 09:01 from Melksham Station, and arrives in Weymouth at 11:03. Return from Weymouth is at 17:30, back into Melksham at 19:46.</p>

<p>Passengers joining at Melksham can buy their tickets on the train. A change of trains is necessary at Westbury. Free car parking available at Melksham Station.</p>

<p>A big "Thank you" to First Great Western, who are making the trains as long as the platforms allow, and supporting the Melksham Railway Development Group and the TransWilts Community Rail Partnership in publicising this opportunity. A representatives of both groups will be on the train.</p>

<center>---OOO---</center>

<p>Trains leave Melksham on Monday to Friday at 06:38 and 19:11 for Westbury, and 07:20 and 19:48 for Swindon. Saturday trains are at 09:20 and 15:21 to Swindon, and at 15:48 and 21:34 to Westbury. And on Sundays, trains leave at 17:25 and 19:53 for Swindon, and at 18:45 for Westbury. Services vary on Bank Holidays.</p>

<p>The TransWilts Community Rail Partnership encourages the use of the existing services by working together with the community, the rail industry and local businesses and government, and it works to promote an improvement in the service to a level appropriate for the journey requirements along the route. Such improvements will see Melksham served by a train every hour - alternately to Westbury and Swindon, giving hourly connections onwards to Bath, Bristol, and London.</p>

<p>The Melksham Railway Development Group promotes the use, marketing and improvement of facilities at services at Melksham in Wiltshire - a town of some 25,000 inhabitants, currently with very limited rail services and facilities.<br clear=all></p>]]>

</content>
</entry>

</feed>