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)

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.

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)

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.


#!/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_())