Luke Plant's home page (Posts about Software projects)https://lukeplant.me.uk/blog/categories/software-projects.xml2023-11-11T20:15:30ZLuke PlantNikolaFamily Fortuneshttps://lukeplant.me.uk/blog/posts/family-fortunes/2011-05-13T13:57:27+01:002011-05-13T13:57:27+01:00Luke Plant<p>A quick Family Fortunes game</p><p>Yesterday I needed to play Family Fortunes (a.k.a. Family Feud) at our church youth group. Our church doesn't have internet connection, so I needed something that would work offline.</p>
<p>There were quite a few versions you could download – for a fee. But as well as the price, getting the computer to do it all is often not so much fun as something with humans more in control, and you're limited to what the computer can do – not easy to fix when you type something in wrong.</p>
<p>So in the end, with a couple of hours to go before the club started, I reckoned I could code up a simple implementation of the score board in a web browser. I scraped some questions from <a class="reference external" href="http://www.pub-quiz.net/Family-Fortunes-quiz.htm">here</a>, used a bit of Python to parse and convert to JSON, then used jQuery and HTML5 audio to get <a class="reference external" href="https://lukeplant.me.uk/familyfortunes/">something that works pretty well</a> for our purposes and doesn't need an internet connection.</p>
<p>Usage and source code on <a class="reference external" href="https://github.com/spookylukey/familyfortunes">GitHub</a>. In brief:</p>
<ul class="simple">
<li><p>n - next question</p></li>
<li><p>p - previous</p></li>
<li><p>1-5 - correct answer</p></li>
<li><p>x - wrong answer</p></li>
</ul>
<p>We set up my laptop as the screen, with some speakers for increased volume, and one of the other leaders used a USB keyboard to control it and decide on correct answers, while I was the game show host. It ended up being pretty fun, and I can imagine re-using on a church holiday etc, with a projector perhaps.</p>
<p>I was also impressed by just how much you can do in a browser these days, with so little time and effort. Recently the brilliant <a class="reference external" href="http://code.google.com/p/flot/">flot</a> library made me realise the same thing – more and more, web development is beating desktop development in terms of APIs, speed of development, ease of development, and even the performance of the result. I very quickly produced a great set of graphs gathering some stats on a website — both attractive and interactive – and realised that even with many of the easiest charting solutions for the desktop, I would not have been able to produce anything like the results.</p>Bible memorisation web apphttps://lukeplant.me.uk/blog/posts/bible-memorisation-web-app/2008-04-01T23:59:12+01:002008-04-01T23:59:12+01:00Luke Plant<p>I created a system and web app to help me organise my Bible memorisation. And I rant a bit Django and web.py.</p><p>EDIT 2012:</p>
<p>Nearly four years later, I've created a much more complete <a class="reference external" href="https://learnscripture.net/">Bible
memorization service - LearnScripture.net</a>.</p>
<p>The rest of this post is left for the sake of history. What used to be there
at <a class="reference external" href="https://lukeplant.me.uk/bibleverses/">https://lukeplant.me.uk/bibleverses/</a> now redirects to learnscipture.net</p>
<hr class="docutils">
<p>I recently decided to get more serious about memorising parts of the Bible.
I've found I can learn one a day fairly easily, with the right system, and
realised I needed two things:</p>
<ul class="simple">
<li><p>A system for ensuring I have a good coverage of topics.</p></li>
<li><p>A method for keeping track of what I have memorised so far</p></li>
</ul>
<p>It is now just about ready for public consumption, so I present my:</p>
<p><a class="reference external" href="https://lukeplant.me.uk/bibleverses/index.html">Bible Memorisation Schemes</a></p>
<p>It should be fairly self explanatory. (read: I haven't had time to write
any help yet). At the most basic level, it is a set of pages with verse
lists. But if you register and log in, check boxes appear which you can use
to indicate verses you have already learnt, and this data is stored on the
server.</p>
<section id="details">
<h2>Details</h2>
<p>I solved the first of my two aims with a set of <a class="reference external" href="http://www.yaml.org/">YAML</a>
documents that define sets of verses and a hierarchy of topics, along with some
Python scripts that combine them (into pages on <a class="reference external" href="https://lukeplant.me.uk/blog/posts/personal-wiki-and-desktop-integration/">my personal wiki</a> first of, and now into an
<a class="reference external" href="https://lukeplant.me.uk/bibleverses/topics.html">HTML version</a>), allowing me
to see what I'm missing.</p>
<p>YAML proves to be very convenient for this type of thing: you can use search and
replace to do changes to more than one area, and can easily add new
functionality. For example, the <a class="reference external" href="http://hg.lukeplant.me.uk/python/luke/file/tip/lukeplant_me_uk/bibleverses/yaml/BibleMemorisationSchemeYaml?style=gitweb">scheme definitions</a> are perfectly readable in English, but exceptional easy
to turn into nice data structures in Python to manipulate the data. The Python
scripts generate the actual schemes, which makes it very easy to add new verses
and still have schemes that are balanced and varied (or focused, if that's what
your scheme definition says).</p>
<p>The web app is written in Python, using CGI. (It is a very basic app, which
talks only JSON, and uses just two database tables—so I didn't want to rely
on a heavy framework that would have special hosting requirements). I started
using <a class="reference external" href="http://webpy.org/">web.py</a> at first, but had two problems with it:</p>
<ul>
<li><p>For an AJAX CGI app, it is much too heavyweight, as "hello world" on
my server took about 1.2 seconds due to everything that was being
imported.</p></li>
<li><p>Frankly, I thought it sucked. I have been spoilt by the lovely design
of Django. web.py really has a different niche to Django, but given
<a class="reference external" href="http://www.aaronsw.com/weblog/rewritingreddit">Aaron's dismissiveness of Django's API design</a> I was expecting he
would have learnt more from it, such as:</p>
<ul>
<li><p>Views are functions. Using classes which have 'GET' and 'POST'
methods may seem like a good idea, but often it isn't due to the
duplication between the two responses. Going from a function based system
to a class based system is very easy (just implement
<code class="docutils literal">SomeBaseClassForViews.__call__()</code>). But going the other way around is
ugly.</p></li>
<li><p>View functions simply take request objects and return response
objects. In web.py, parts of the request path are passed into the
function, as in Django, but you have to call <code class="docutils literal">web.input()</code> to get query
data and posted data (where <code class="docutils literal">web</code> is a module, not an object passed
in). But, even worse, you call web.header() to write headers, while the
body of the response is '<code class="docutils literal">print</code>'ed out (or returned as a string in
version 0.3). This is horrible.</p>
<p>With Django's method, you can do amazing things like the
<a class="reference external" href="http://www.djangoproject.com/documentation/authentication/#the-login-required-decorator">@login_required decorator</a> (it is very cool -- seamlessly persists any posted
data, passing it along to the view once the user has successfully logged in
[EDIT - see comment below]). And the implementation is robust and
straightforward, not magical (though not completely simple either, due to the
nature of the case). You can also do cache control decorators, and write a
<a class="reference external" href="https://lukeplant.me.uk/resources/djangovalidator/">validator middleware</a>
etc. This is simply from following standard good programming practice, in
which side effects are avoided where possible, and function outputs depend
only on inputs.</p>
</li>
</ul>
<p>Some of Aaron Swartz's design decisions just niggled me too. It is
claimed that "web.py lets you write web apps in Python", but to me it
seems more like something which is reminiscent of Python, but sloppier.
Take for instance the definition of URLs. If it had been this:</p>
<div class="code"><pre class="code python"><a id="rest_code_c015811a1a394e628730b33b4f10f3d4-1" name="rest_code_c015811a1a394e628730b33b4f10f3d4-1" href="https://lukeplant.me.uk/blog/posts/bible-memorisation-web-app/#rest_code_c015811a1a394e628730b33b4f10f3d4-1"></a><span class="n">urls</span> <span class="o">=</span> <span class="p">[</span>
<a id="rest_code_c015811a1a394e628730b33b4f10f3d4-2" name="rest_code_c015811a1a394e628730b33b4f10f3d4-2" href="https://lukeplant.me.uk/blog/posts/bible-memorisation-web-app/#rest_code_c015811a1a394e628730b33b4f10f3d4-2"></a> <span class="p">(</span><span class="s1">'/(.*)'</span><span class="p">,</span> <span class="s1">'hello'</span><span class="p">)</span>
<a id="rest_code_c015811a1a394e628730b33b4f10f3d4-3" name="rest_code_c015811a1a394e628730b33b4f10f3d4-3" href="https://lukeplant.me.uk/blog/posts/bible-memorisation-web-app/#rest_code_c015811a1a394e628730b33b4f10f3d4-3"></a><span class="p">]</span>
</pre></div>
<p>...I would have understood it straight away. Instead, I stared at
this for a while:</p>
<div class="code"><pre class="code python"><a id="rest_code_f15950e79b1c423e8362541b4e6efe82-1" name="rest_code_f15950e79b1c423e8362541b4e6efe82-1" href="https://lukeplant.me.uk/blog/posts/bible-memorisation-web-app/#rest_code_f15950e79b1c423e8362541b4e6efe82-1"></a><span class="n">urls</span> <span class="o">=</span> <span class="p">(</span>
<a id="rest_code_f15950e79b1c423e8362541b4e6efe82-2" name="rest_code_f15950e79b1c423e8362541b4e6efe82-2" href="https://lukeplant.me.uk/blog/posts/bible-memorisation-web-app/#rest_code_f15950e79b1c423e8362541b4e6efe82-2"></a> <span class="s1">'/(.*)'</span><span class="p">,</span> <span class="s1">'hello'</span>
<a id="rest_code_f15950e79b1c423e8362541b4e6efe82-3" name="rest_code_f15950e79b1c423e8362541b4e6efe82-3" href="https://lukeplant.me.uk/blog/posts/bible-memorisation-web-app/#rest_code_f15950e79b1c423e8362541b4e6efe82-3"></a> <span class="p">)</span>
</pre></div>
<p>...and eventually found that the explanation is <a class="reference external" href="http://webpy.org/faq">it'd be a lot more
typing</a> to do it the sensible way. I guess
readability doesn't count for anything.</p>
</li>
</ul>
<p>So anyway, I happily ditched web.py, wrote my own Django-inspired mini framework
that does just what I need, and fixed my performance problem (the 'framework' is
in <a class="reference external" href="http://hg.lukeplant.me.uk/python/luke/file/tip/lukeplant_me_uk/bibleverses/web/cgi-bin/lib/bibleverses/webutils.py?style=gitweb">webutils.py</a>,
see the <a class="reference external" href="http://hg.lukeplant.me.uk/python/luke/file/tip/lukeplant_me_uk/bibleverses/web/cgi-bin/lib/bibleverses/views.py?style=gitweb">views.py</a>
file for example usage. Most of it was developed using TDD, which turned out to
be a big timesaver – it's just so quick to make big changes and be sure you
haven't broken anything.</p>
<p>Anyway, it has been a nice little project, and I'm hoping that it will
actually prove useful to me and others!</p>
</section>Django validator updatedhttps://lukeplant.me.uk/blog/posts/django-validator-updated/2007-04-18T14:26:26+01:002007-04-18T14:26:26+01:00Luke Plant<p>I've updated my `validator app <https:></https:>`_ to latest Django trunk and finally done a release.</p><p>I've updated my <a class="reference external" href="https://lukeplant.me.uk/resources/djangovalidator/">validator app</a> to latest Django trunk
and finally done a release. (It's a small but very useful Django app that does
HTML validation of all outgoing pages, logging errors)</p>
<p>I've also added a small feature – the app detects duplicate error messages for
the same URL, so you no longer get the same page cluttering up the list of
validation failures.</p>Updated validator and CsrfMiddlewarehttps://lukeplant.me.uk/blog/posts/updated-validator-and-csrfmiddleware/2005-12-14T23:45:01Z2005-12-14T23:45:01ZLuke Plant<p>I've released some small updates to my 'Django validator app' and 'CsrfMiddleware'...</p><p>I've released some small updates to my 'Django validator app' and
'CsrfMiddleware'. The main changes are:</p>
<ul class="simple">
<li><p>added a setup.py to both of them, after working out how these work
and a lot of fiddling around.</p></li>
<li><p>added support for mod_python to the validator app (thanks nesh)</p></li>
<li><p>added a setting to allow the validator to ignore certain paths.</p></li>
</ul>
<p>Get them here:</p>
<ul class="simple">
<li><p><a class="reference external" href="https://lukeplant.me.uk/resources/djangovalidator/">Django Validator</a></p></li>
<li><p><a class="reference external" href="https://lukeplant.me.uk/resources/csrfmiddleware/">CsrfMiddleware</a></p></li>
</ul>
<p>I've also discovered that my CsrfMiddleware is currently number 6 in a google
search for <code class="docutils literal">Cross Site Request Forgery</code>, which is rather pleasing, or
perhaps it just tells you how little there is on the web about this exploit.</p>My blog codehttps://lukeplant.me.uk/blog/posts/my-blog-code/2005-02-16T13:15:21Z2005-02-16T13:15:21ZLuke Plant<p>Source code for my new blog is now available</p><p>If anyone's interested, you can get the <a class="reference external" href="https://lukeplant.me.uk/downloads/lukesblogcode-2005-02-15.tar.gz">code for my blog</a> here. I've put it together pretty
quickly - I've just packaged everything from my own directories that you need
for it to work without error, plus a README. If you actually wanted to use it
you'd need to replace at least the main page template and customise the others
and the CSS. You could remove some things completely (like my blogroll and
related functions).</p>
<p>It's licensed under the MIT license, so you can do pretty much anything with it.
As it is, it might be useful for anyone with some PHP knowledge who wants a
simple but powerful blog. It's got admin functions for managing posts, comments
and categories (quite basic looking at the moment, but they do the job). The
design is fairly clean so adding features to it should be pretty easy.</p>
<p>I'll try and add some more code comments (which are rather lacking at the
moment), and I'll also be doing a few quick articles on the methods I've used,
which are a more important product of what I've learnt than the blog software
itself.</p>
<hr class="docutils">
<p>Update: See <a class="reference external" href="https://lukeplant.me.uk/blog/posts/my-blog-code/websitecode.html">Website code</a> for a new version of the code.</p>CodeExporter 1.0https://lukeplant.me.uk/blog/posts/codeexporter-1-0/2004-07-20T19:30:18+01:002004-07-20T19:30:18+01:00Luke Plant<p>New version of CodeExporter, ironing out the first bug I've found in ages, so it's probably pretty mature now, and has helped me out lots already.</p><p>New version of CodeExporter, ironing out the first bug I've found in ages, so
it's probably pretty mature now, and has helped me out lots already. <a class="reference external" href="https://lukeplant.me.uk/codeexporter.html">Get it
here.</a></p>CodeExporter 0.2https://lukeplant.me.uk/blog/posts/codeexporter-0-2/2004-05-18T00:48:39+01:002004-05-18T00:48:39+01:00Luke Plant<p>Uploaded release 0.2 of CodeExporter, the only difference being that the modules are no longer password protected, so you can get at the code.</p><p>Uploaded release 0.2 of CodeExporter, the only difference being that the modules are no longer password protected, so you can get at the code.</p>VBA moduleshttps://lukeplant.me.uk/blog/posts/vba-modules/2004-05-18T00:13:41+01:002004-05-18T00:13:41+01:00Luke Plant<p>I uploaded a public release of some VBA modules I use.</p><p>I uploaded a public release of some VBA modules I use, <a class="reference external" href="https://lukeplant.me.uk/vbamodules.html">download here</a>.</p>