What can be improved in Windows 7? Add app store

August 20th, 2010

I bought a pentium su4100 based netbook recently. It comes with Windows 7, and I must say it is a refreshing change to just be able to run games without spending 3 days full-time trying to tweak the wine configuration to try to get something passably working…

And Windows 7 works generally rather well I feel. Hasn’t crashed on me once yet. Microsoft produces a free real-time virus and malware scanner now.

So, what is there left to improve in Windows 7 for future versions of Windows? Off-the-top-of-my-head, I came up with two things:
- make other things become built-in, available at no extra cost, eg Office
- add an application store, a one-stop shop to buy everything, including everything currently available from Steam, battle.net, and so on
– no more need to wonder whether something one is downloading is legitimate or not
– downloads would be easy and secure by default, ie make sure they use https and so on
– could provide an option to either buy software outright, or lease it for an hour, 24 hours, a month, or whatever
– or whatever is done for applications in the iPhone app store, which seems to be very successful

I suppose that if everything were made available through an appstore, then that would be a great whitelist for 99% of end-users, and all other applications could be entirely banned from running, eliminating a lot of viruses, rootkits and so on.

Converting CantoFish dictionary for stardict

April 11th, 2010

Stardict is an awesome dictionary utility for linux, with several dictionaries available for mandarin.

I started to learn cantonese recently, and I couldnt find any stardict dictionaries for cantonese.

There is a plugin for Firefox called Cantofish which uses the dictionary data from CantoDict, and adsotrans.

Unfortunately, for some reason CantoFish doesnt run on my machine.

And also, stardict’s mouse-over translation is really awesome.

So I took a look at converting Cantofish’s dictionary into stardict format, which turned out to be pretty easy.

Cantofish’s dictionary is in the firefox profile, in extensions/cantofish@cantofish.net/chrome/content/canto.dat

As far as I know, this data is available under the GPL, or possibly under a non-commercial attribution license (eg adso).

canto.dat is a tab separated text file, which is really easy to read. I was pleasantly surprised by this!

Then, stardict dictionaries can be created using tabfile, which is in stardict-tools, from an appropriate tab-separated file.

I used the following script to convert canto.dat into an input file for tabfile, and then the rest is easy:

#!/usr/bin/python

import sys
import os
import string

def go( cantopath, outpath ):
	print cantopath
	cantofd = open( cantopath, "r" )
	outfd = open( outpath, "w")
	firstline = True
	for line in cantofd.readlines():
		if not firstline:
			line = line.strip()
			#print line
			cantocharacters = line.split(" ")[0]
			#print cantocharacters
			cantopronunciation = line.split("[")[1].split("]")[0].strip()
			#print cantopronunciation
			trans = string.join( line.split("]")[2:],' ').replace('/', '\n').strip().replace('\n', '\\n')
			#print trans
			outfd.write( cantocharacters + '\t' + cantopronunciation + '\\n' + trans + '\n' )
		firstline = False
	outfd.close()
	cantofd.close()

go( sys.argv[1], sys.argv[2] )

The script expects the path of canto.dat as the first argument, and the name of the output file as the second.

Then you can just process the output using tabfile, and copy the resulting files into an appropriate subfolder of /usr/share/stardict/dic/dic.

Finally, Karmic kernel no longer panics on my eeepc

April 8th, 2010

Finally, nearly six months after release, the latest Karmic kernel has not panicked in over a week now. It generally panicked whenever I turned off my rt2860sta wifi on my eeepc 901, or every few times I did so. It seems like the 2.6.31-20-generic kernel has the relevant patches applied to it.

Created a test web page for my web site

April 5th, 2010

To make it easy to check whether my website is functioning, I built a python webpage to download each sub-site, and check it contains some appropriate text, and display the result.

The test page is here:

web site test page

The source code is something like:

def checksite(sitename, url, checktext):
   serverrequesthandle = urllib.urlopen(url, None )
   serverrequestarray = serverrequesthandle.readlines()
   serverrequeststring = (''.join( serverrequestarray )).decode('utf-8')
   result = sitename + u': '
   if serverrequeststring.find(checktext) > -1:
      result = result + '<font color="green">OK</font>'
   else:
      result = result + '<font color="red">FAIL</font>'
   return result

   result = u""

   try:
      result = result + checksite(u'techblog', "http://hughperkins.com/techblog", u'Hugh Perkins') + u'<br />'
      result = result + checksite(u'writerblog', "http://manageddreams.com/writerblog", u'Hugh Perkins') + u'<br />'
      # etc ...

Hmmm, idea: maybe I could wrap this up in a website itself, and let people register their own sites in it? I guess this probably exists somewhere, but maybe for a ridiculous price, so there could be an opportunity to make something similar, but ad-supported?

Python, jinja, print and unicode…

April 5th, 2010

This took me a while to figure out…

I wanted to display some Chinese characters in Jinja, in Python.

The problem was I would get errors like:

  • UnicodeDecodeError: ‘ascii’ codec can’t decode byte
  • UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position

I figured it was going to be one of those errors which needs lots of reading to figure out the answer, but, once you know the answer, the actual tweaks to the code are minimal; and that was the case for me.

Ultimately, this page from diveintopython.org turned out to be pretty helpful for me.

First, what was I doing? I had something like the following code:

sometext = gettextfromsomewhere() # eg by downloading a web-page
env = jinja2.Environment(loader=jinja2.PackageLoader('jinjaapplication', 'templates'))
template = env.get_template('mypage.html')
print template.render( sometext = sometext )

sometext was the result of using urllib to download a webpage. The webpage contained Chinese characters, encoded as utf-8.

Logically I felt sometext would be also utf-8 encoded unicode, which is half-right.

I tried all sorts of things like converting sometext to unicode using unicode(), decode, encode and so on, but it still would not work.

Ultimately, I feel there were a key concepts I needed in order to fix the problem were:

  • print doesn’t seem to be unicode-aware
  • decode and encode; str vs unicode

A biggie for me was that print does not seem to unicode aware. print seems to be geared up simply for outputing bytes, byte by byte.

print expects not a unicode object, but a plain old ‘str’, containing the unicode characters converted into plain old bytes.

Converting a unicode string into an appropriate str is easy once one knows how, but fairly counter-intuitive I felt. It can be done like this:

print someunicodestring.encode('utf-8')

I felt calling this ‘encode’ was counter-intuitive, since we’re changing away from utf-8, I felt, but I suppose one way of thinking about it is that we are changing from utf-8 into some sort of coded bytes.

This was half the solution, and the biggest part for me.

The other half is figuring out how to deal with the incoming string from the downloaded website. The incoming string is a ‘str’, and it actually contains the chinese characters in utf-8, only they are being stored byte by byte as a str, rather than stored character by character as a unicode object.

To convert from the utf-8 str to a utf-8 unicode object is the reverse of printing. We can do simply:

sometext = gettextfromsomewhere().decode('utf-8')

The ‘decode’ function takes the str, which is a byte array, albeit in utf-8 encoding, and converts it into a unicode array, ie each value is a single character. I think. Anyway, it works :-P

So, the full solution needed two things:

  • convert the incoming utf-8 str into utf-8 unicode using decode(‘utf-8′)
  • convert the unicode coming from jinja back into a utf-8 str, ready for printing, using encode(‘utf-8′)
sometext = gettextfromsomewhere().decode('utf-8') # eg by downloading a web-page
env = jinja2.Environment(loader=jinja2.PackageLoader('jinjaapplication', 'templates'))
template = env.get_template('mypage.html')
print template.render( sometext = sometext ).encode('utf-8')

… and this seems to work perfectly.

Dreamhost upgraded to 64-bit, debian 4

April 4th, 2010

Dreamhost has upgraded itself to 64-bit servers, running debian 4.

Python is 2.4 by default, and 2.5 is available, by running ‘python2.4′ instead of just ‘python’.

I moved my old ‘local’ directory to ‘_local’ and recreated it. For now, I’m just using the built-in php, rather than building my own. I still seem able to log in to my blog using openid so I guess thats ok. I reinstalled python virtualenv, so I could install sqlalchemy and so on, so that http://manageddreams.com/ailaddergrid is working again now.

Edit: getfacl is still unavailable :-/ Also, debian 4 sounds a little old, considering that 5 has been out for ages now. Anyway… better than debian 3 :-P

Ubuntu on eeepc: re-enabling sound and mouse after iffy suspend

February 27th, 2010

Ubuntu: sometimes after a suspend or two, I lose sound. Sometimes the mouse stops working.

Solution: rmmod the appropriate driver, then re-modprobe it.

For mouse, on my computer:

sudo rmmod psmouse
sudo modprobe psmouse

(on Ubuntu Karmic, on an eeepc 901).

For sound, its a bit trickier, but it’s something like:

pulseaudio -k
sudo rmmod snd_hda_intel
sudo modprobe snd_hda_intel
pulseaudio -D

.. with maybe a couple of extra rmmod’s first, in order to remove snd_pcm, perhaps also snd_timer, maybe snd.

Python script to learn Chinese tones

January 28th, 2010

I wrote a script to learn to distinguish between the Chinese tones. It’s not very useful without the corresponding multimedia (ie: recordings I got my gf to make), but maybe with script in hand, others can easily make their own such multimedia?

The script plays a sound, eg ‘dianhua’, then presents two possibilities for the user to choose between, eg the dianhua meaning ‘stippled painting’, or the dianhua meaning ‘telephone’.

There are three parts to the script:
- testdiff.py : the script, in Python
- testdiff.xml: configuration file, where you specify each test, the sounds for each test, and a corresponding text description
- the sound files, in a subdirectory ‘sounds’

Sample configuration file:

<root>
<tests>
<test>
<choice sound="几点.mp3" text="几点 jī diăn (what time is it?)" />
<choice sound="机电.mp3" text="机电 jī diàn (electrical machine)" />
</test>
<test>
<choice sound="忌惮.mp3" text="忌惮 jì dàn (fear)" />
<choice sound="鸡蛋.mp3" text="鸡蛋 jī dàn (egg)" />
</test>
</tests>
</root>

testdiff.py python script, gpl v2:

#!/usr/bin/python

# Copyright Hugh Perkins 2010
# hughperkins@gmail.com http://manageddreams.com
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
#  more details.
#
# You should have received a copy of the GNU General Public License along
# with this program in the file licence.txt; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-
# 1307 USA
# You can find the licence also on the web at:
# http://www.opensource.org/licenses/gpl-license.php
#
# ======================================================================================
#

import sys
import os
from elementtree.ElementTree import ElementTree
import random
import subprocess
import time

def playSound( soundfilepath ):
	popen2 = subprocess.Popen(['playsound',soundfilepath], stdout=subprocess.PIPE)
	popen2.wait()

def runTest():
	print "Next test:"

	config = ElementTree(file='testdiff.xml')
	numtests = 0
	for test in config.findall('/tests/test'):
		numtests = numtests + 1

	testnum = random.randint(0, numtests - 1 )

	chosentest = None
	numtests = 0
	for test in config.findall('/tests/test'):
		if numtests == testnum:
			chosentest = test
		numtests = numtests + 1

	numchoices = 0
	for choice in chosentest.findall('choice'):
		numchoices = numchoices + 1

	testchoice = random.randint(0, numchoices - 1 )

	numchoices = 0
	for choice in chosentest.findall('choice'):
		#print str(numchoices) + ' ' + choice.get('text')
		if testchoice == numchoices:
			soundfilepath = 'sounds/' + choice.get('sound')
			choicetext = choice.get('text')
		numchoices = numchoices + 1

	playSound(soundfilepath)

	numchoices = 0
	for choice in chosentest.findall('choice'):
		print str(numchoices) + ' ' + choice.get('text')
		numchoices = numchoices + 1

	gotchoice = False
	while not gotchoice:
		print "Your choice? ('r' to repeat sound)"

		userchoice = sys.stdin.readline().strip().lower()
		if userchoice == str(testchoice):
			gotchoice = True
			print "Yes! : " + choicetext
			print ""
			playSound(soundfilepath)
		elif userchoice == 'r':
			playSound(soundfilepath)
		else:
			gotchoice = True
			print "In fact: " + choicetext
			print ""
			playSound(soundfilepath)
			done = False
			while not done:
				print 'r to replay correct answer, b to play both, n for next'
				userchoice = sys.stdin.readline().strip().lower()
				if userchoice == 'r':
					playSound(soundfilepath)
				if userchoice == 'b':
					for choice in chosentest.findall('choice'):
						print choice.get('text')
						soundfilepath = 'sounds/' + choice.get('sound')
						playSound(soundfilepath)
				elif userchoice == 'n':
					done = True

while True:
	runTest()
	time.sleep(1)

I might turn it into a webpage, and try to generate some ad-revenue, but most likely I won’t :-P

Note that the code above is pretty dreadful, but it works, which is the goal, since I want to one day be able to hear the difference in the tones in Chinese.

(PS if you ask me nicely, and I know you, I might consider providing you with some of the corresponding multimedia, but I’m not that keen on just plastering my gf’s voice all over the web, what with ‘my voice is my password’ becoming more popular and so on….)

Debian: fixed x-fonts on my installation

January 28th, 2010

Just a minor detail really, but after installing debian squeeze using debootstrap, my x-fonts were really ugly.

It turns out that an appropriate way to clean them up was:
- install ttf-bitstream-vera, and set the system fonts to use this font
- in ‘appearance’ set ‘subpixel smoothing’, ‘slight’ hinting
- personally I use 10-point fonts, and 96dpi, which seems to give a reasonable compromise between information density, and readability, on an Eeepc 901, for me

Idea: artificial heart

January 25th, 2010

It seems to me that the basic technology of pumping heart around that the heart does is not actually that hard?

Of course, it needs to be fairly reliable, but that is what redundancy is for: just have two or three of them.

Another issue: how to maintain the hearts as and when they break down. Potential solution: have a flap, a door, that opens on the front of one’s chest, so that one can access the various hearts. Sort of like the electrical panel in one’s house.

Another issue: power… pumping blood around probably needs a *lot* of power. How much? Probably should check that. I feel that mobile phone batteries could probably deliver a fair amount of power. Give each of the two or three redundant hearts its own battery, and then there is redundance. Just open the panel to swap in and out a fresh one.

What about if someone forgets to charge up the batteries?

Initially, an alarm could sound to warn them, then as the battery becomes lower, the heart could slow down, ultimately slowing down to a rate just enough to prevent the person dieing, but they might collapse to the street, unable to move, effectively forcing them to be given medical treatment, ie replacement of batteries. This seems to me to be a better option than just stopping the heart after the batteries have been completely emptied!

Wouldn’t it be easy to murder someone by simply taking out the batteries? Sure, but it’s easy to murder someone anyway by just pressing on their windpipe, or slipping a knife into their heart, and yet generally we manage to survive 24 hours a day without such incidents impinging on our lives.

I suppose one issue to consider would be making the heart faster during fast exercise. A couple of thoughts:
- one could of course make the heart sensitive to adrenaline, but that’s complicated, maybe expensive, I don’t know how easy this is?
- otherwise, one could just make the heart go constantly the same speed. if someone does too much exercise, they’ll feel faint, but they’re not going to die from feeling faint, though they might collapse, probably workable
- and, one could just add the ability to control manually the speed of the heart. One button for faster one for slower.

Right, after writing this, I’ve googled and found a wikipedia article about artificial hearts.

It seems they exist. The concepts above do not seem to be being applied though:
- the hearts are only implanted singly, with no redundance
- they are not considered a permanent solution to heart failure
- power supply is from external packs via a transduction coil, which is fine I suppose
- there is no way to easily slot in and out a new heart when the old one breaks down