Fascinating podcasts have emerged from the libre planet event.
Many mention the work done (in sprints thereat) to improve the floss manuals.
Here they are. Highly recommended.
http://en.flossmanuals.net/
Random musings on GNU+Linux. open source software, and Python. The main purpose of this blog is to archive (for myself) what I am learning about these wonderful technologies/communities
Friday, 12 June 2009
Monday, 11 May 2009
Saturday, 9 May 2009
Promote linux campaign
If I were involved in the marketing of Ubuntu... here is the advertising campaign I would run.
Setting - a school IT classroom
Music - Pink Floyd. "we don't need no education"
Theme - zombie kids being taught to use a popular word-processing application by (no names).
cool kid in the back of the classroom has a different desktop... what is it?
he's spinning the cube switching between all the killer apps. he winks to camera.
fade out...
ubuntu logo...
"because kids don't need no thought control"
Setting - a school IT classroom
Music - Pink Floyd. "we don't need no education"
Theme - zombie kids being taught to use a popular word-processing application by (no names).
cool kid in the back of the classroom has a different desktop... what is it?
he's spinning the cube switching between all the killer apps. he winks to camera.
fade out...
ubuntu logo...
"because kids don't need no thought control"
Thursday, 30 April 2009
openmolar update and a plea for sanity
2 weeks ago I switched off our commercially provided uber expensive crapware for the last time, and moved 100% to using my own solution "openMolar".
openMolar is a multi-client/single server application. Presently I have 2 linux clients, 3 windows clients running my software and a linux mysql server.
(I also have the full front-end and backend application running on my dell-mini9, but that's another story...)
The development of this application has been quite a trip, but proves that even someone with my limited coding skills can knock up a professional quality app using only open source tools.
And the bandwagon keeps on rolling.
Bryan Harris from the US and Mehmet nur Olcay from Turkey have joined in on the launchpad site, and are working on packaging the app for ubuntu and (more interestingly) Pardus linux. I look forward to making the code accessible for language translation purposes.

Richard Querin has again exceeded all expectations by providing an alternative logo focusing on the freedom aspect of the software. I intend to get some embroidered t-shirts for the practice staff to wear when we attend the British Dental Association Conference in 4 weeks time.
But before folks get too carried away, a reminder. This bandwagon needs the brakes applying somewhat.
My focus has always been (and will for the medium term at least) to have this software working in the practice.
The interest that is being shown from the dental profession and open source movement alike is quite humbling but a little frightening. It goes to show that there is demand for open source solutions, however, please let nobody be under the impression that this product is finished.
I am wary that if others take my code and push it out at this stage it could get it a reputation from which it will never recover. I am also fully aware that there are many companies who would love to see this project fail. I beg the open source community not to play a part in making this happen.
Here is a page of screenshots and explanations for those who would like to know more.
The project can be found on launchpad.
openMolar is a multi-client/single server application. Presently I have 2 linux clients, 3 windows clients running my software and a linux mysql server.
(I also have the full front-end and backend application running on my dell-mini9, but that's another story...)
The development of this application has been quite a trip, but proves that even someone with my limited coding skills can knock up a professional quality app using only open source tools.
And the bandwagon keeps on rolling.
Bryan Harris from the US and Mehmet nur Olcay from Turkey have joined in on the launchpad site, and are working on packaging the app for ubuntu and (more interestingly) Pardus linux. I look forward to making the code accessible for language translation purposes.

Richard Querin has again exceeded all expectations by providing an alternative logo focusing on the freedom aspect of the software. I intend to get some embroidered t-shirts for the practice staff to wear when we attend the British Dental Association Conference in 4 weeks time.
But before folks get too carried away, a reminder. This bandwagon needs the brakes applying somewhat.
My focus has always been (and will for the medium term at least) to have this software working in the practice.
The interest that is being shown from the dental profession and open source movement alike is quite humbling but a little frightening. It goes to show that there is demand for open source solutions, however, please let nobody be under the impression that this product is finished.
I am wary that if others take my code and push it out at this stage it could get it a reputation from which it will never recover. I am also fully aware that there are many companies who would love to see this project fail. I beg the open source community not to play a part in making this happen.
Here is a page of screenshots and explanations for those who would like to know more.
The project can be found on launchpad.
Thursday, 16 April 2009
logos, launchpad and bizarre experiences
Three things.
- I am overjoyed with Richard Querin's first draft of a logo for openMolar.

- My code is up on launchpad.net at http://launchpad.net/openmolar.
- The python versioning control system Bzr is working well. I hope. thanks to "thumper" in #launchpad on freenode for his guidance. I have made 3 pushes already. Awesome.
Wednesday, 8 April 2009
openmolar - new tarball

another test tarball for interested folks to install and try.
Still immature software, but a fair few new features.
Many thanks to all who sucessfully installed the 1st version despite a few errors in my README file!
Hopefully those bugs are now ironed out.
please note, you will need to refresh to the new database if you installed 0.0.3 version.
BTW - hopefully I will get the hang of bzr / launchpad for future releases... meantime, the tarball can be found HERE .
Sunday, 22 March 2009
two wee python lifesavers
filed under the "notes to self" category... if I forget these tips I'll googling for them... so let's put them on my random blog for now.
- This should be enabled by default in the standard python shell. http://blog.venthur.de/2008/07/06/tab-completion-in-pythons-interactive-mode/
- 'enscript' is a must have for printing code... and from the man page, is this suggestion from the developer himself - flags for printing code: gaudy header, two columns, landscape, code highlighting, 2-up printing.
~$enscript -G2rE -U2 main.py
if you have a long script, check it out... it's beautiful.
Thursday, 19 March 2009
openMolar - it's not a comic book reader.
I was a guest on the linux link tech show last night, I was my usual incoherent babbling self, but I had a great time.
If anyone is interested in seeing just how badly I write code, please download,play with, and scrutinise the openMolar software.
tarball (inlcuding an example database for March and April 2009) and a checksum for the paranoid can be found at
www.invernessrowingclub.co.uk/misc/openmolar

If anyone is interested in seeing just how badly I write code, please download,play with, and scrutinise the openMolar software.
tarball (inlcuding an example database for March and April 2009) and a checksum for the paranoid can be found at
www.invernessrowingclub.co.uk/misc/openmolar

Tuesday, 17 February 2009
Review - sansa clip ogg/mp3 player
With Linux cranks and the bad apples podcasts going to ogg only, I decided to invest in a new player.
The sansa clip seemed to fit the bill perfectly, for the following reasons.

but it turns out that this is the best damn player I've ever owned... and here's why.
That last feature sounds like a gimmick (or a discourtesy to the podcaster) however, I am enjoying it.
This morning, for example - it compressed lottalinuxlinks 106 down to MY commuting time, not Daves. Lynn didn't sound so sexy.. but kajarii did ;)
Battery Life could maybe be better... I have been spoilt by Sony players, having said that, battery life is perhaps the only thing to recommend Sony players.
The sansa clip seemed to fit the bill perfectly, for the following reasons.
- mounts as a drive, easy drag and drop of files
- plays ogg
- built in fm radio
- small
- cheap
- sexy

but it turns out that this is the best damn player I've ever owned... and here's why.
- It can delete tracks. Very useful. I need to do this, otherwise I forget what I've listened to.
- it can play tracks at an increased speed
That last feature sounds like a gimmick (or a discourtesy to the podcaster) however, I am enjoying it.
This morning, for example - it compressed lottalinuxlinks 106 down to MY commuting time, not Daves. Lynn didn't sound so sexy.. but kajarii did ;)
Battery Life could maybe be better... I have been spoilt by Sony players, having said that, battery life is perhaps the only thing to recommend Sony players.
Monday, 16 February 2009
dell mini ram trouble
Odd problem with my dell mini on Saturday. I needed to get a few packages up to ubuntu intrepid versions, and found that wasn't a trivial affair given the "lpia" archictecture that the pre-installed 'dellbuntu' insists upon.
I was installing dependencies, but they were still appearing to be missing. Very odd, so I decide to install the vanilla 32 bit Ubuntu8.10.
I partition the drive (ext2 with no swap) and stick in an 8.10 usb startup disk. Start the install and BOOM!! major problems at 27%. I get warnings that "source and destination files don't match".... "you probably have a dirty CD, or a damaged hard-drive".
Bummer - it has to be the hard-drive right? We all know these solid state drives are friable?
A quick google suggests several folks have had trouble with the dell mini drives, so I was 100% certain that was the problem.
Anyway... long story short, it turns out it wasn't that at all.
My RAM was hosed. memtest86 on the startup disk (which I tried on a whim whilst googling for SSD device checking software) found 40,000 errors at a very specific range of addresses.
So I popped in a different ram block, and voila! All is well. Ubuntu 8.10 was running flawlessly 20 minutes later.
On the off chance any ubuntu devs reading this.. it might be worth adding a line to the error dialog stating that the memory could be an issue as well as the more likely CD or hardrive cause.
Even more importantly, THANKYOU for having that memtest86 on the install media by default.. you saved me from ringing dell support (a fate worse than death methinks?)
I was installing dependencies, but they were still appearing to be missing. Very odd, so I decide to install the vanilla 32 bit Ubuntu8.10.
I partition the drive (ext2 with no swap) and stick in an 8.10 usb startup disk. Start the install and BOOM!! major problems at 27%. I get warnings that "source and destination files don't match".... "you probably have a dirty CD, or a damaged hard-drive".
Bummer - it has to be the hard-drive right? We all know these solid state drives are friable?
A quick google suggests several folks have had trouble with the dell mini drives, so I was 100% certain that was the problem.
Anyway... long story short, it turns out it wasn't that at all.
My RAM was hosed. memtest86 on the startup disk (which I tried on a whim whilst googling for SSD device checking software) found 40,000 errors at a very specific range of addresses.
So I popped in a different ram block, and voila! All is well. Ubuntu 8.10 was running flawlessly 20 minutes later.
On the off chance any ubuntu devs reading this.. it might be worth adding a line to the error dialog stating that the memory could be an issue as well as the more likely CD or hardrive cause.
Even more importantly, THANKYOU for having that memtest86 on the install media by default.. you saved me from ringing dell support (a fate worse than death methinks?)
Wednesday, 4 February 2009
Using binary data in python
For those who don't know, I am writing a python gui-frontend to an existing mysql database.
The original program that wrote out the data was written by an old-school C guy. Some of the data has been put into the tables in a "blob" format. Example
so when I read this table with the MySQLdb module (a third party module for python) I get a string like this.
You will note that this is packed with characters which need to be handled with care (understatement!)
So how to make sense of it?
One way is to use python's build in Struct module, which allows conversion between python and C types of variable.
after a bit of decoding.... I noticed the above is in chunks of 8 bytes, with /x00 at every 2,6,7 position. I also realise (by experiment) that the data contains 2 distinct unsigned doubles so the following code works for me.
which gives me the following output
and that makes more sense to me (just).
The original program that wrote out the data was written by an old-school C guy. Some of the data has been put into the tables in a "blob" format. Example
mysql> describe esttable;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| serialno | int(11) | NO | PRI | 0 | |
| data | blob | YES | | NULL | |
+----------+-------------+------+-----+---------+-------+
so when I read this table with the MySQLdb module (a third party module for python) I get a string like this.
import MySQLdb
db=MySQLdb.connect(host="localhost",user="myUser",passwd="myPassword",db="myDatabase")
Cursor=db.cursor()
Cursor.execute('select data from esttable where serialno=31599')
Cursor.fetchall()
(('\x01\x00o\x00\n\x0f\x00\x00\x04\x00\xc9\x00\x00\x00\x00\x00\x01\x00
\xe9\x03"\x0b\x00\x00\x02\x00\x87\x05@\x1f\x00\x00',),)
You will note that this is packed with characters which need to be handled with care (understatement!)
So how to make sense of it?
One way is to use python's build in Struct module, which allows conversion between python and C types of variable.
after a bit of decoding.... I noticed the above is in chunks of 8 bytes, with /x00 at every 2,6,7 position. I also realise (by experiment) that the data contains 2 distinct unsigned doubles so the following code works for me.
import struct
def blobToList(blob):
pythonlist=[]
i=0
for i in range(0,len(blob),8):
number=struct.unpack_from('b',blob,i)[0]
item=struct.unpack_from('H',blob,i+2)[0]
cost=struct.unpack_from('H',blob,i+4)[0]
pythonlist.append("%s %s $%d.%02d"%(number,item,cost/100,cost%100))
return pythonlist
if __name__=="__main__":
testdata ='\x01\x00o\x00\n\x0f\x00\x00\x04\x00\xc9\x00\x00\x00\x00\x00'
testdata+='\x01\x00\xe9\x03"\x0b\x00\x00\x02\x00\x87\x05@\x1f\x00\x00'
print blobToList(testdata)
which gives me the following output
['1 111 $38.50', '4 201 $0.00', '1 1001 $28.50', '2 1415 $80.00']
and that makes more sense to me (just).
Friday, 16 January 2009
Wikipedia for young minds
Another random idea inspired by real life.
Assuming there isn't (see picture)... wouldn't it be nice if there was a version of wikipedia aimed at kids under 12.
Same as wikipedia (and linking to it), but less verbose, simplified language, and guaranteed free of adult material?
Heck that would be a great resource for junior schools, teachers and parents alike.
Possible Names - "WikiJunior", "Junior Wikipedia", "PaedoPedia" (ok... one of the 1st 2)
Assuming there isn't (see picture)... wouldn't it be nice if there was a version of wikipedia aimed at kids under 12.
Same as wikipedia (and linking to it), but less verbose, simplified language, and guaranteed free of adult material?
Heck that would be a great resource for junior schools, teachers and parents alike.
Possible Names - "WikiJunior", "Junior Wikipedia", "PaedoPedia" (ok... one of the 1st 2)
Monday, 12 January 2009
Dell Mini-9 update DISASTER!
This post is about the dell-mini-9.
A netbook with pre-installed ubuntu 8.04. These machines use a separate repo for updates, (suffix http://dell-mini.archive.canonical,com) so would you expect the following to happen?
After weeks with no new packages for the standard dell-mini ubuntu repos, last night saw me pulling down 170MB.
(note - this is a vanilla ubuntu 8.04 dell-mini, first used in 'dec 08)
however, these upgrades have left me with several annoying issues.
1. an x-server update bust my uk keyboard layout. #~{}]["£ all moved around
2. New Firefox and/or WebFav packages wiped all my browser history/usernames/passwords AND removed all my add-ons. Furthermore I got an annoying "Yahoo" home page, default search and a task bar (the bloody screen is small enough, thanks)
Read again - I lost my homepage, all addons, history and bookmarks
3. the upgrading of lsb-base (3.2-4ubuntu1) to 3.2-4ubuntu1netbook1 meant that the mysql-server-5.0 wouldn't start, as I got an error about an unbound variable. Mysql is mission critical on this machine.
Anyway, I have smart friends on irc (thanks jlindsay and Peter64) and I am now fixed up again.
However, these machines are aimed at a broad spectrum of users who would be more inconvenienced than I.
For the sake of the ubuntu and gnu/linux community... please hold these upgrades back for further testing before unleashing them on new linux users.
A netbook with pre-installed ubuntu 8.04. These machines use a separate repo for updates, (suffix http://dell-mini.archive.canonical,com) so would you expect the following to happen?
After weeks with no new packages for the standard dell-mini ubuntu repos, last night saw me pulling down 170MB.
(note - this is a vanilla ubuntu 8.04 dell-mini, first used in 'dec 08)
however, these upgrades have left me with several annoying issues.
1. an x-server update bust my uk keyboard layout. #~{}]["£ all moved around
2. New Firefox and/or WebFav packages wiped all my browser history/usernames/passwords AND removed all my add-ons. Furthermore I got an annoying "Yahoo" home page, default search and a task bar (the bloody screen is small enough, thanks)
Read again - I lost my homepage, all addons, history and bookmarks
3. the upgrading of lsb-base (3.2-4ubuntu1) to 3.2-4ubuntu1netbook1 meant that the mysql-server-5.0 wouldn't start, as I got an error about an unbound variable. Mysql is mission critical on this machine.
Anyway, I have smart friends on irc (thanks jlindsay and Peter64) and I am now fixed up again.
However, these machines are aimed at a broad spectrum of users who would be more inconvenienced than I.
For the sake of the ubuntu and gnu/linux community... please hold these upgrades back for further testing before unleashing them on new linux users.
Sunday, 11 January 2009
Richard Querin - I love you!
Thanks to the linuxplanet.org aggregation, I have become a huge fan of Richard Querin's Work.
I am particulary grateful for his post about an easy way to CREATE YOUR OWN FONT.
Anyway, my 10 year old daughter followed this advice, and I noticed today that she has not only made such a font, but has tweaked it with fontforge (an apt-get away for us debian derivatives) and is now using it as her default application/Desktop/Window-Title and Document Font.
linux truly is flippin' awesome.
here is her desktop... (click image for a larger view)
I am particulary grateful for his post about an easy way to CREATE YOUR OWN FONT.
Anyway, my 10 year old daughter followed this advice, and I noticed today that she has not only made such a font, but has tweaked it with fontforge (an apt-get away for us debian derivatives) and is now using it as her default application/Desktop/Window-Title and Document Font.
linux truly is flippin' awesome.
here is her desktop... (click image for a larger view)
Thursday, 8 January 2009
Implementing a Custom Widget using pyqt4.
Pat from the linux link tech show (and others) have told me to stop whinging, and solve my own IT worries. I won't go over these again here, but scroll down for the full story.
So I dusted down all the programming manuals on the shelf and got to it, and I have to say, so far so good, I have spend many happy hours coding, and am REALLY enjoying the experience.
The tools - python and the qt4 toolkit, mysql, mysqldb, qt-designer and SPE (a wonderful python IDE)
Tomorrow, I have a meeting with a colleague, and I need to show him where I'm at. Thought I'd share here also. Here's a screenshot.

A thing of beauty IMHO!
Anyway, I was delighted how easy PyQt4 makes it to embed a custom widget. My little dental chart slotted into the tabPageWidget above is such a thing. The code is below for all to laugh at.
Note - if you have python and pyqt4 installed, this script will run as a top-level window, something ALL qt widgets are capable of doing. Very cool.
The chartWidget inherits from the QWidgetClass, but overwrites several methods, including the all-important paint method. So today I learned how to draw rectangles, rounded rectangles, lines and points again. QCanvas is like a big etch-a-sketch for nerds. Much Fun.
NOTE - this code borrows heavily from the "counters.py" example in chapter 11 of the pyqt4 book by Mark Summerfield.
So I dusted down all the programming manuals on the shelf and got to it, and I have to say, so far so good, I have spend many happy hours coding, and am REALLY enjoying the experience.
The tools - python and the qt4 toolkit, mysql, mysqldb, qt-designer and SPE (a wonderful python IDE)
Tomorrow, I have a meeting with a colleague, and I need to show him where I'm at. Thought I'd share here also. Here's a screenshot.

A thing of beauty IMHO!
Anyway, I was delighted how easy PyQt4 makes it to embed a custom widget. My little dental chart slotted into the tabPageWidget above is such a thing. The code is below for all to laugh at.
Note - if you have python and pyqt4 installed, this script will run as a top-level window, something ALL qt widgets are capable of doing. Very cool.
The chartWidget inherits from the QWidgetClass, but overwrites several methods, including the all-important paint method. So today I learned how to draw rectangles, rounded rectangles, lines and points again. QCanvas is like a big etch-a-sketch for nerds. Much Fun.
NOTE - this code borrows heavily from the "counters.py" example in chapter 11 of the pyqt4 book by Mark Summerfield.
#!/usr/bin/env python
from __future__ import division
from PyQt4 import QtGui,QtCore
class chartWidget(QtGui.QWidget):
'''a custom widget to show a standard UK dental chart - allows for user navigation with mouse and/or keyboard'''
def __init__(self, parent=None):
super(chartWidget,self).__init__(parent)
self.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Expanding))
self.grid = [[18,17,16,15,14,13,12,11,21,22,23,24,25,26,27,28],[48,47,46,45,44,43,42,41,31,32,33,34,35,36,37,38]]
self.selected = [0, 0]
self.setMinimumSize(self.minimumSizeHint())
def sizeHint(self):
return QtCore.QSize(600, 150)
def minimumSizeHint(self):
return QtCore.QSize(240, 80)
def mousePressEvent(self, event):
xOffset = self.width() / 16
yOffset = self.height() / 2
x= event.x()//xOffset
if event.y() < yOffset:
y = 0
else:
y = 1
self.selected = [x, y]
self.update()
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Left:
self.selected[0] = 15 if self.selected[0] == 0 else self.selected[0] - 1
elif event.key() == QtCore.Qt.Key_Right:
self.selected[0] = 0 if self.selected[0] == 15 else self.selected[0] + 1
elif event.key() == QtCore.Qt.Key_Up:
self.selected[1] = 1 if self.selected[1] == 0 else self.selected[1] - 1
elif event.key() == QtCore.Qt.Key_Down:
self.selected[1] = 0 if self.selected[1] == 1 else self.selected[1] + 1
self.update()
def paintEvent(self,event=None):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
midline=self.width()/100
midlineV=self.height()/20
xOffset = (self.width() - midline) / 16 #cell width
yOffset = (self.height() - midlineV) / 2 #cell height
painter.setPen(QtCore.Qt.red)
painter.drawLine(0,self.height()/2,self.width(),self.height()/2)
painter.drawLine(self.width()/2,0,self.width()/2,self.height())
for x in range(16):
if x>7:
midx=midline
else:
midx=0
for y in range(2):
cell = self.grid[y][x]
rect = QtCore.QRectF(x * xOffset + midx, y * yOffset+y*midlineV,xOffset, yOffset).adjusted(0.5, 0.5, -0.5, -0.5)
backTooth=False
color = QtGui.QColor("#ddddff")
if str(cell)[1] in ("8","7","6","5","4"): #molars
backTooth=True
painter.setPen(QtGui.QColor("black"))
painter.setBrush(color)
if backTooth:
outerRect=rect.adjusted(0,2,0,-2)
irw=outerRect.width()/4 #inner rectangle width
irh=outerRect.height()/4 #inner rectangle height
innerRect=rect.adjusted(irw,irh,-irw,-irh)
painter.drawRect(outerRect)
painter.drawRect(innerRect)
painter.drawLine(outerRect.topLeft(),innerRect.topLeft())
painter.drawLine(outerRect.topRight(),innerRect.topRight())
painter.drawLine(outerRect.bottomLeft(),innerRect.bottomLeft())
painter.drawLine(outerRect.bottomRight(),innerRect.bottomRight())
else:
outerRect=rect.adjusted(0,2,0,-2)
rw=outerRect.width()/3
rh=outerRect.height()/2.1
innerRect=rect.adjusted(rw,rh,-rw,-rh)
painter.drawRect(outerRect)
painter.drawRect(innerRect)
painter.drawLine(outerRect.topLeft(),innerRect.topLeft())
painter.drawLine(outerRect.topRight(),innerRect.topRight())
painter.drawLine(outerRect.bottomLeft(),innerRect.bottomLeft())
painter.drawLine(outerRect.bottomRight(),innerRect.bottomRight())
#draw a rectangle around the selected tooth, but don't overwrite the centre
if [x, y] == self.selected:
painter.setPen(QtGui.QPen(QtCore.Qt.blue, 3))
painter.setBrush(QtCore.Qt.transparent)
painter.drawRect(rect.adjusted(1,1,-1,-1))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
form = chartWidget()
form.show()
sys.exit(app.exec_())
Subscribe to:
Posts (Atom)