Friday, June 17, 2011

Closed windows from a crashed Firefox: Dig [out of] your own grave and save!

Well, I don't know what happened. The Windows box went down for a reboot due to the usual bundle of patches for Windows bugs. Somewhere along the line, Firefox managed to close the window with all my (way too many) tabs, and when I rebooted, it opened up on the Mozilla homepage. Burn.

No problem, going to about:sessionrestore displays a list of... empty. Oh.

Ok then. A quick look in the profile dir (%APPDATA%\Mozilla\Firefox\Profiles\*.default) shows that the sessionstore.js and backup are over 4 megs in size - that looks promising. So I copy them and quit Firefox.
Inside sessionstore.js is a gigantic JSON string. Inside that, I find a closed tab (the session restore tab which I had given up on), with apparently another full JSON string in the #sessionData field. After decoding that, I find an empty list of windows, and a list of _closedWindows including my main window with many many tabs. Yay, I can just swap them then.

Here's a little program in Lua which might help resurrect your tabs/windows if something similar happens to you. It uses the very fast dkjson library (the whole read/decode/futz/encode/write process for a 4.5mb file takes about 1.25 seconds on my run-of-the-mill desktop using LuaJIT).

In this case, there was an open window with one closed tab containing an about:sessionrestore form...
  json = require('dkjson')

  print('Reading file...')
  local session = assert(io.open('sessionstore.js', 'r'))
  local session_data = session:read('*all')
  print('Parsing ('..#session_data..' bytes)...')
  local obj, pos, err = json.decode(session_data, 1, json.null)
  if err then error(err) end
  print('Success! table size: '..#obj, pos, err)

  -- I closed the session restore tab since the list was empty.
  -- Turns out it still had the closed window data, so
  -- we can extract that. You may have to change this.
  local data = obj.windows[1]._closedTabs[1].state.
      entries[1].formdata['#sessionData']

  -- parse it, swap open/closed windows
  local data_p = json.decode(data, 1, json.null)
  print('Decoded, swapping closed and open windows')
  local old_windows = data_p.windows
  data_p.windows = data_p._closedWindows
  data_p._closedWindows = old_windows

  print('Encoding')
  local outf = assert(io.open('sessionstore-rec-fixed.js', 'w'))
  outf:write(json.encode(data_p))
  outf:close()

In this case, the open windows had suddenly become closed windows... (this just happened now, the hell Aurora?)
  json = require('dkjson')
  print('Reading file...')
  local session = assert(io.open('sessionstore.js', 'r'))
  local session_data = session:read('*all')
  print('Parsing ('..#session_data..' bytes)...')
  local obj, pos, err = json.decode(session_data, 1, json.null)
  if err then error(err) end

  print('Success! table size: '..#obj, pos, err)
  print('Decoded, swapping closed and open windows')
  local old_windows = obj.windows
  obj.windows = obj._closedWindows
  obj._closedWindows = old_windows

  print('Encoding')
  local outf = assert(io.open('sessionstore-rec-fixed.js', 'w'))
  outf:write(json.encode(obj))
  outf:close()

Monday, March 28, 2011

Rachota... oh no you di'n't!

Started using Rachota a couple of days ago to keep track of how much time I'm spending on my research, which currently consists of reading a big stats book.

Clicked into the "Analytics" tab just now and was informed of the following:
* You don't categorize your tasks enough. Try to assign some keyword to as many tasks as you can. This helps to track how much time your projects consume.
* You seem to spend too much time on private tasks or off the computer. Either minimize working on private stuff or don't leave your computer often without measuring such activity.
* It looks like your tasks are either very short or too long. Try to consolidate the short ones or divide the complex tasks. This helps to identify where your time really goes.
* You don't prioritize your tasks correctly. Use different priorities to distinguish important tasks from the low priority ones. This helps to keep focus on your real objectives.
* You don't use regular tasks properly. This might indicate you often work on a task that is not set as regular or there is a regular task that in fact occurs very rarely.
* It seems you leave your tasks open forever. Instead, close it once you are done with each task in reality to make your daily ToDo list shorter. Or don't you really finish anything?


...

Tuesday, March 01, 2011

Pointing float

> =(1/0.1)
10
> =(1/(1-0.9))
10

> =math.ceil(1/0.1)
10
> =math.ceil(1/(1-0.9))
11

....FFFFFFFUUUUUUUUU

Monday, February 14, 2011

Gluap: an attempt at PushGP in Lua

Eventually got around to implementing a basic genetic programming system in Lua, using the subset of the Push 3.0 language as explained in the previous post.

The results on my amazingly simple test function () are not great so far, though. Some runs produce a good result, while others get stuck in bad local optima:

best program so far with fitness 4.7958315233127 (integer.dup integer.+)
...
best program so far with fitness 71.917763204878 (integer.dup 231 298 integer./ integer./ integer.+)
...
best program so far with fitness 772.44948974278 (true)

Some of this may be due to using parsimony pressure, which can prioritise suboptimal solutions that are shorter in length. I'll have to read the tome on GP that's sitting upstairs.

Also, I've only implemented very simplistic mutation so far; maybe crossover will work better?
Even for mutation, selecting from the Push 3.0 instruction set with a uniform probability might be bad, since there are so many weird EXEC and CODE instructions, which are probably less likely to be useful than the simple arithmetic and stack instructions like FLOAT.* and INTEGER.DUP.

Tuesday, February 08, 2011

Mini-side-procrastination-project: Gluap (PushGP in Lua)

Rather than procrastinate uselessly this week, I decided to implement a barebones interpreter and library for Push 3.0, a stack-based language intended for use in evolutionary computation. For me, that means genetic programming. Never having tried Forth, this will be the first stack-based language I've ever used... the idea is interesting, especially with the gimmicky exec and code stacks, bringing up all sorts of weird possibilities for code which evolves its own control flow.

The language du jour is Lua, which feels a bit like a mix between Ruby and Python and maybe Tcl, and has a ravishingly fast JITted interpiler called LuaJIT on most x86/x64 systems.

It's going to be a mess, but hopefully a fun mess. After a few hours' work, I've got it to the point where it can do... almost nothing! It can interpret programs that consist of single number literals, though...

Edit, 2 groggy hours later

Finally, it can parse and evaluate very simple Push programs like this:
local result =
gluap.eval_program '( 5 1.23 + (4) - 5.67 FLOAT.*)'
assert_equal(1, result.pop('integer'))
assert_equal(6.9741, result.pop('float'))

If I can find time on Wednesday, the rest of the basic logic (I haven't got beyond basic arithmetic instructions yet) and maybe the beginnings of actual GP... or sleep, whichever.

Edit, 1 day and not enough sleep later

Instead of sleeping, it was more fun to add to the interpreter so that it can now execute each of the Push 3.0 simple examples correctly, including such madness as "( ARG FLOAT.DEFINE EXEC.Y ( ARG FLOAT.* 1 INTEGER.- INTEGER.DUP 0 INTEGER.> EXEC.IF ( ) EXEC.POP ) )", in some 346 lines of clumsy Lua. However, there's an intimidatingly long "type dictionary" which contains a great number of instructions of varying confusingness. Meh, maybe I can leave most of them for now and get with the GP part.

Tuesday, January 18, 2011

Building LuaSocket for LuaJIT on Windows with MinGW. Oh my!

Lua is a lovely little language, somewhat minimalistic like Scheme, with a powerful and concise syntax somewhat like Ruby and Python, but it was never "batteries included", meaning that significant effort must be expended to accomplish some seemingly-trivial tasks.
Those defensive of Lua will counter that this is precisely the point of Lua - to be small and carry as few dependencies as possible. This may be true, but it's nice to offer some easily-installed extras, especially for basic tasks. It would be quite painful if everyone had to rewrite and link to C code just to get the time in milliseconds or open a socket.

Lua is very popular with the embedded and scripting crowd; especially game scripting, with WoW and a bunch of other games allowing users to write little Lua programs with some API to access game functions. Even NMap also allows Lua scripting now.

I'm interested in the use of Lua for more general programming tasks and projects, where re-using existing libraries is important to cut down on extra work. This is especially the case for Lua newbies like myself, and given the minimalism present in Lua's design and organisation, even quite trivial tasks require the use of external libraries.
One example of this is getting the current time in milliseconds - this is useful for writing simple benchmarking scripts, for example. Since Lua tries to stick almost exclusively (apart from some dynamic linking aspects, according to the canonical reference tome, PiL) to the ANSI C specification, you can't get access to time information at finer than per second resolution.

There is a networking library named LuaSocket which happens to provide such a function by calling into the standard C library:
require 'socket'
> =socket
table: 0x0026b680
> =socket.gettime
function: 0x0026ba18
> =socket.gettime()
1295358928.145

Rather than compile the library from source, which can be problematic - especially on Windows and double-especially for those not familiar with C - there are two promising software repository efforts for Lua: LuaRocks and LuaDist.

Unfortunately, neither of these managed to successfully install LuaSocket:
  • LuaDist failed to find anything at all on its repository - hopefully a temporary problem.

  • LuaRocks first failed outright due to wget not being present on my Windows system. After installing a Gnuwin port and copying it into the LuaRocks dir, some faffing about was required to have it use our network proxy, and it finally downloaded the appropriate .lua and prebuilt .dll files. The DLLs crash LuaJIT, the JITted interpiler I'm using.

Apparently the dynamic libraries provided by such extensions must be compiled against your interpreter's lua51.dll.

To get LuaRocks to use a network proxy, you must add an (undocumented) entry to the config.lua file:
proxy = "http://proxy:port"


Since the prebuilt DLLs didn't work, I tried to build luasocket from source, linking against LuaJIT's lua51.dll. For this, LuaRocks tried to use what I assume are Visual Studio commands:
...
Extracting luasocket-2.0.2\test\testclnt.lua
Extracting luasocket-2.0.2\test\testsrvr.lua
Extracting luasocket-2.0.2\test\testsupport.lua

Everything is Ok

Folders: 6
Files: 89
Size: 477216
Compressed: 552960
'msbuild' is not recognized as an internal or external command,
operable program or batch file.
cp: src/mime.dll: No such file or directory
cp: src/socket.dll: No such file or directory

Error: Build error: Failed building.


Oh well, it made a pretty decent effort. There was an option to install LuaRocks using the MinGW compiler toolchain, and to use LuaJIT as the interpreter. This crashed. So I tried to build LuaSocket from source myself, but was stymied because the provided Makefiles/solution files are for Linux or assume Visual Studio is available on Windows.

After an lengthy period of head-banging, the following Makefile (in luasocket's src dir) produced DLLs that work in LuaJIT for me (after calling mingw32-make, the resulting mime.dll and socket.dll can be moved into luajit-dir\mime\core.dll and lj-dir\socket\core.dll).

#------
# LuaSocket makefile configuration
#

#------
# Output file names
#
EXT=dll
SOCKET_V=2.0.2
MIME_V=1.0.2
SOCKET_SO=socket.$(EXT)
MIME_SO=mime.$(EXT)

CC="C:\MinGW\bin\mingw32-gcc.exe"
CINC=-I"C:\MinGW\include"

LD=$(CC)
LDFLAGS=-L "C:\MinGW\lib" -lmingw32 -lkernel32 -lcrtdll -lwsock32 -shared
CFLAGS= $(LUAINC) $(CINC) $(DEF) -pedantic -Wall -O2
#------
# Lua includes and libraries

LUAINC=-I"C:\Program Files\Lua\5.1\include"
LUADLL="C:\code\luajit2\lua51.dll"

SOCKET_OBJS:= \
luasocket.o \
timeout.o \
buffer.o \
io.o \
auxiliar.o \
options.o \
inet.o \
tcp.o \
udp.o \
except.o \
select.o \
wsocket.o

#------
# Modules belonging mime-core
#
#$(COMPAT)/compat-5.1.o \

MIME_OBJS:=\
mime.o

all: $(SOCKET_SO) $(MIME_SO)

$(SOCKET_SO): $(SOCKET_OBJS)
$(LD) -o $@ $(SOCKET_OBJS) $(LUADLL) $(LDFLAGS)

$(MIME_SO): $(MIME_OBJS)
$(LD) -o $@ $(MIME_OBJS) $(LUADLL) $(LDFLAGS)

#------
# List of dependencies
#
auxiliar.o: auxiliar.c auxiliar.h
buffer.o: buffer.c buffer.h io.h timeout.h
except.o: except.c except.h
inet.o: inet.c inet.h socket.h io.h timeout.h wsocket.h
io.o: io.c io.h timeout.h
luasocket.o: luasocket.c luasocket.h auxiliar.h except.h timeout.h \
buffer.h io.h inet.h socket.h wsocket.h tcp.h udp.h select.h
mime.o: mime.c mime.h
options.o: options.c auxiliar.h options.h socket.h io.h timeout.h \
wsocket.h inet.h
select.o: select.c socket.h io.h timeout.h wsocket.h select.h
tcp.o: tcp.c auxiliar.h socket.h io.h timeout.h wsocket.h inet.h \
options.h tcp.h buffer.h
timeout.o: timeout.c auxiliar.h timeout.h
udp.o: udp.c auxiliar.h socket.h io.h timeout.h wsocket.h inet.h \
options.h udp.h
wsocket.o: wsocket.c socket.h io.h timeout.h wsocket.h

clean: rm -f $(SOCKET_SO) $(SOCKET_OBJS)
rm -f $(MIME_SO) $(UNIX_SO) $(MIME_OBJS) $(UNIX_OBJS)
#------
# End of makefile configuration
#

I'm hopeful that LuaDist (if it's not defunct - the webpage is not encouraging) and LuaRocks will improve and become more useful on Windows systems soon. Hopefully the same process will be easier when I try it at home on my old Macbook... but argh, all of this just to get the time in milliseconds!

Monday, January 10, 2011

Minigotcha: escaping path strings for cmd.exe

There's a very handy plugin for (g)Vim called netrw, which provides the capability to edit files over ssh/scp/etc. To set it up with Putty on Windows, the suggested lines to add to $MYVIMRC were:
let g:netrw_cygwin = 0
let g:netrw_scp_cmd = "\"C:\\Program Files\\PuTTY\\pscp.exe\" -pw mypasswd "


I'm not sure why this worked for them and not me, but perhaps I'm using an older (or newer) version of netrw, or the cmd.exe behaves differently in Vista. In any case, it didn't work and gave the infuriating output of:
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.

This is annoying since the path for pscp is obviously escaped. However, it turns out that cmd.exe follows a slightly strange, arbitrary protocol for escaping space pathstrings - it uses another " character (ack, ugly and confusing... why? The argument is already in quotes...):
C:\Windows\system32\cmd.exe /c "C:\Program" Files\PuTTY\pscp.exe"

PuTTY Secure Copy client
Release 0.60

Okay then! So this works:
let g:netrw_scp_cmd ="\"C:\\Program\" Files\\PuTTY\\pscp.exe\""

Wednesday, December 08, 2010

Cancelling pending messages in Skype

How often are you chatting with someone in text on Skype when they log off, leaving messages in a send queue "waiting to be delivered"? How often does this happen, and the other party doesn't log on at the same time as you for days or weeks?

Well, it happens to me now and again. Sometimes you'll check the chat window with someone and see that it's waiting to send "Hey, I'll be a bit late this evening, maybe 9pm?", a month after the event? In many cases, you'd rather cancel the message rather than possibly confuse them when they receive it weeks later out of the blue.

Unfortunately, for some inexplicably stupid reason (or, more likely, no reason), Skype does not provide any method to cancel messages that are waiting to be sent, even though they're merely held offline on your local machine until Skype sees the other party online again. There is no technical reason whatsoever why these messages can't be deleted.

Since Skype doesn't do the job, you'll have to do it yourself. And luckily, it's not too difficult - it just requires one SQL statement to be executed on your local Skype database:

download a sqllite editor (http://sourceforge.net/projects/sqlitebrowser/)
exit skype
browse to: %AppData%\Skype
browse into your username directory
backup main.db <--- IMPORTANT!!!
run the sqllite editor
open main.db in sqllite editor
in the Execute SQL tab type the following commands:

--> (optional) this command will show you all of your unsent messages:
select author,identities,dialog_partner,body_xml from messages where sending_status = 1

--> this command will delete all unsent messages to a specific username:
delete from messages where dialog_partner = "username" and sending_status = 1

--> this command will delete all unsent messages:
delete from messages where sending_status = 1

Thursday, November 11, 2010

Miktex + LyX. Pixellated font?

My Miktex (2.7) install came without the "Computer Modern" vector font, and PDFs generated by LyX came with an awful bitmap version. There were two reasonably easy fixes:
  1. Go to Document->Settings...->Fonts and choose the Latin Modern variant for the three font families.

  2. Open the Miktex package manager, find the cm-super package and install it.

Both worked for me, but I stuck with the second option rather than make global changes to LyX default document settings.

Sunday, October 10, 2010

Alipay? Alibollox!

Taobao/Alipay are the Chinese equivalent of eBay and Paypal. To buy things, you have to set up an account with both services and register some kind of payment method - mostly Chinese banks, but Visa and Mastercard are apparently supported (although they didn't work for me).

There are a number of hideous, needless errors and usability mistakes on the Alipay site in particular:

  1. When entering your name, you must type it all in capitals. Why? You can automatically convert the string to uppercase if necessary in Javascript. No need to burden the user with this.

  2. You can't enter a phone number with more than 11 digits, it can't have a '+' symbol at the start, and it's validated as a Chinese mobile phone number (must have 13 or 18 at the start). The hell?

  3. The actual payment forms assume that the customer is using Internet Explorer and they're completely broken in Firefox. I'm using a Mac and even on my Vista box at work I use Firefox and Opera.

  4. After finally submitting the form (by using Firebug's console to fix some of the broken Javascript/DOM code: "form1 = document.forms[0]"), we get a page telling us there was a "payment failure" with error code -1, with the helpful message "没有定义的错误代码" meaning "the error code is undefined". Thanks for that.

What's most annoying are the problems that are so easy to fix: allow any phone number to be entered. Don't ask your users to type things in all caps. Don't assume your users are using Internet Explorer (or Windows) - that kind of nonsense should have been left in the 1990s!

Chinese websites and software often suffer from these problems. Everything appears to be written for Windows, even the web sites. Software doesn't declare what language it's written in and assumes the user has a Chinese version of Windows, forcing them to call the program through AppLocale (if they know how). If there's version of the software built for OS X or Linux, it will be binary only and either doesn't work at all or crashes constantly (QQ for Linux). Of course, you can't use an open-source program that tries to use that protocol because the servers detect and ban unofficial clients. Weak!

Another thing: about 99% of Chinese websites appear to be spammy search portals with hundreds of links and no useful content. Is there a way to search for useful content on Chinese sites and filter out all the useless portals?

Thursday, September 23, 2010

Eclipse: escape strings when pasting - off by default?

After a couple of years of occasionally having to paste a large multi-line string into Java source code and escape the hell out of it, I eventually searched for some kind of online tool to automatically do the job and quickly discovered that Eclipse automatically does this for you if a certain menu option is enabled (prefs->Java->Editor->Typing->"Escape text when pasting into a string literal").

So why on earth is this feature not enabled in Eclipse by default?

Tuesday, September 21, 2010

Integrity in snooker: empty pandering or meaningful measures?

When the John Higgins scandal erupted some months ago, I tried to keep an open mind and honestly hoped it was all a misunderstanding until I watched the video and heard some of the details of the case. It was very disturbing evidence, but even then I hoped for everything to turn out alright in the end, even if there was a good chance that he truly intended to carry out the promised match-fixing.

Flash forward a few months and Higgins' manager is banned from the sport for life (even though he had already resigned from his position on the WPBSA board) and Higgins gets a backdated six month ban and a £75,000 fine.
Then Barry Hearn, the recently-appointed chairman of World Snooker, appears on BBC2 today talking about the new anti-corruption unit being set up as a preventative - rather than curative - measure against betting fraud and match-fixing.

He was asked what role Higgins will have in this new light, and responded by basically saying that he would serve as an example to other players of how dangerous it is to give in to that temptation and appear to agree to dodgy deals without reporting them, especially now that there'll be some official, private channels for doing so. He also stated that Higgins made a silly mistake, by trusting people he shouldn't have, and was heavily punished and that £75,000 isn't pocket change.

That was a mistake, I think. For someone like Higgins, a backdated six-month ban and a £75,000 fine is chump change, especially when Hearn followed up those comments to assure of the seriousness of the new regime by saying "we're talking about lifetime bans here".
If we're talking about lifetime bans, Higgins got away very lightly and you should really acknowledge that. Why not just say something like "the case with Higgins could easily have ended up differently and he might have received a very lengthy or indefinite ban. But now we're drawing a line and making it very clear what you can and can't do, and specifying the penalties for breaking those rules"?

Another player, Quinten Hann, was handed an 8 year ban a while back, for agreeing to lose a match in the China Open. However, he resigned before the ban was decided, and never had a squeaky clean image to begin with. Also, his highest ranking was #14, where John Higgins has been #1 for a while and is one of the most consistent players in the game.
What if Higgins was a much lower-ranked player of less fame? Would he have been banned for longer (or even forever) and fined less?

What worries me is that much of the assurances about "hard measures" might be concerned more with convincing the public with tough-talking "draconian" plans than with actually stamping out corruption - that Higgins' real mistake was to get caught. But I'm still glad to see Higgins back in the game - it'd be such a shame for a master craftsman to be officially banned from his craft forever. I just hope that Hearn and the rest truly care about sport and its integrity rather than simply protecting the bottom line by telling the optimal story to the punters.




Oh and on a side note, I'm glad to read Hearn's comments on Ronnie O'Sullivan's odd attitude towards completing a 147 today: “I really don’t like to hear multi-millionaires talking about a few extra pounds for a 147 when that’s the game that’s given them their livelihood”.
Spot on, and a big "WTF Ronnie". Walking away from the table on a 140 break with the black on, or missing on purpose (which he very nearly did - the black nearly bounced off the table) would actually hurt the audience - remember Ken Doherty's missed black on a maximum attempt and the groans from the crowd, and try to imagine what it would be like if O'Sullivan missed one on purpose. I'd hate to be the guy giving post-match interviews with him - it seems like 15% of the time he enjoyed playing, 70% of the time he felt nothing, 80% of the time he says something really sad that makes you wonder if he hates the whole thing, himself, fans, other players etc.

But on the other hand, a 147 is still an amazing feat, even if it's slightly more common. The commentators seemed to only consider the case where there's no maximum break prize versus a £147,000 prize. Why not have a token but still half decent prize for a maximum - let's say £14,700 - which a) would not be sniffed at and b) would be separate from the high break prize, so that getting a 147 gets you a tangible reward. The amount isn't really important, as long as a maximum is distinguished from a high break of 145 or whatever.

Sunday, September 12, 2010

Screen magnifier and Orca screenreader stuck on at login screen (Ubuntu)

Although Linux has improved immensely in many respects over the years, there's still a chance of running into bizarre problems, either during install or in normal use.

A while ago I wiped the old Mandriva 2008 partition on my Acer Aspire 1705SMi, a 7 year old juggernaut of a laptop which was sitting in a drawer for a year or so.
The first problem was that the Ubuntu Live CD could not even boot properly, since as soon as it loaded the splash screen the video adapter (a NVidia GeForce FX Go5600) went slightly insane and produced a screen which looked like a garbled moire interference pattern. Rough shapes (maybe that's a dialog box...?) were visible but it was basically unusable.

Getting past that required editing the boot command line for the kernel at the GRUB prompt (hitting 'e', IIRC) and adding the "nomodeset" parameter. I also removed the "splash" parameter but this probably wasn't necessary. If something like this can happen, why not offer a nomodeset boot option on the boot menu, rather than forcing the user to edit the boot command line?
This got as far as a failed start of X and dropped back to the shell, where I was able to edit /etc/xorg.conf and start the installer.

So that was okay. The install worked nicely, although both suspend to RAM (sleep) and suspend to disk (hibernate) completely fail to resume, requiring a hard reboot. No change from ~2004 when I had to download a fixed version of the buggy Acer DSDT and install it at boot, as well as tinker with the kernel source (maybe, not sure if it was necessary). Surely those problems could have been fixed in the mainline kernel though - if it was fixable by a layman like myself before, why does it still not work out of the box?

Then a 2 year old demon managed to somehow enable Orca (a screenreader), a screen magnifier and dreadfully annoying "slow keys" by randomly clicking around (from her own user account), and things got really weird on the next reboot: the left half of the screen is normal, while the right half shows a magnified cursor and a load of garbage (maybe due to the old NVidia card being a pile of arse). Trying to type in a password to login seemed impossible at first, until I realised that I had to hold each key for about half a second before it would register. Ugh.

Anyway, after logging in I made sure that all of the accessibility tools were switched off in every preference menu on the GNOME desktop. Unfortunately this didn't really switch them off, even though the gconftool-2 program declared that they were successfully disabled.

After much googling (for once, not very helpful except to confirm that other people in similar situations have solved the problem by reformatting and re-installing Ubuntu, WHAT!) and grepping, I found another set of gconf XML configuration files in /var/lib/gdm/.gconf, even though you need to be root to access them.

Anyway, these global settings could be unset as follows:
$ sudo su
# cd /var/lib/gdm/.gconf
# gconftool-2 --direct --config-source xml:readwrite:. -s --type boolean /desktop/gnome/accessibility/keyboard/stickykeys_enable false
# gconftool-2 --direct --config-source xml:readwrite:. -s --type boolean /desktop/gnome/accessibility/keyboard/bouncekeys_enable false
# gconftool-2 --direct --config-source xml:readwrite:. -s --type boolean /desktop/gnome/accessibility/keyboard/slowkeys_enable false
# gconftool-2 --direct --config-source xml:readwrite:. -s --type boolean /desktop/gnome/applications/at/screen_magnifier_enabled false


Some of these problems may be due to the laptop having a poorly-designed BIOS/DSDT, so this post may sound like sour grapes. But a natural response from anyone who uses such a machine would be "but it works in Windows?" - and if it does, why shouldn't it work in Linux?

Tuesday, August 31, 2010

Parisian driving

(saving a comment I wrote on a boards.ie thread)

I thought we had some crappy driving here (in Ireland), but visiting Paris for a week really put things in perspective.

Firstly, if you're a pedestrian walking at a crossing, even if it's a signalled one with a green light in your favour, drivers will happily continue to fly around corners and barrel through the crossing. Get in their way and either get knocked down or beeped into deafness.

Secondly, remember that two-second clearance rule here? The TV safety ads suggest that when the car in front passes a point, you should be able to say "only a fool breaks the two second rule" before you pass the same point. In Paris it's "only a foo- ARGHHH!", with cars overtaking you (from any side) and diving into your lane after having barely cleared your car. This happens all the time. The cars behind don't even brake when it happens, so the tacit understanding seems to be a) one or two metres of clearance is an acceptable distance at 100kph and b) overtaking drivers will never have to suddenly brake while directly in front of my car. Weird.

The two and a half hour trip from Amboise back to Paris really made this clear: drivers will gladly overtake a bus and pull in front with about two metres' clearance. Not only that, but the bus driver starts to pull into the lane they just left, while they're still moving into our lane with two metres' clearance.
All of this is completely normal there.

And as probably everyone knows, parking there means gently (or not) backing into the car behind you, then forward into the next one, then back and forth repeatedly bashing the surrounding cars until your car is wedged into a space with two inches to spare on one side, with bumpers touching on one side. Almost every car's registration plate and bumper is dented, scratched or missing.

So I arrived back in Dublin airport thinking "I guess the standard over here isn't so bad really", just as a shitestain of a taxi driver in a silver Merc floored it as soon as the green man started to flash, as I was already running across the pedestrian crossing pushing a trolley full of bags which missed his car by about two inches as it screamed past me.
If that thing didn't have its own brakes, you were getting a heavy iron trolley in the rear left wing. I was sorely tempted to just let it happen too, but settled for a rapidly-shouted "my light's still green, you stupid fucking bastard!"

Sunday, August 22, 2010

Does the free software movement represent "true freedom"?

Someone commented on a Youtube video that:
Actually, free software represents freedom. The Open Source Movement just supports the benefits of source code being available. The Free Software Foundation supports true freedom."


To which my response was:

It doesn't support the freedom to sell software though, does it?

Almost all of the software I use is open-source, and I've made (miniscule) contributions to open-source software in the past, but I don't think it's fair to demonise those who wish to make money from writing software by selling it.

Stallman seems to characterise closed-source as unethical, but is it really wrong for someone to release a program without the source code so that they can profit a bit from their work?


I'd be interested to hear any insight from others on this issue. Free software provides some freedom, but obviously removes the freedom to sell that software, even by the author. As a big fan and user of free software, but also a programmer and tradesman, I recognise that other people may want to do programming as a living by selling their work (rather than doing unenjoyable coding tasks for a large financial company they dislike, say).
I don't see anything wrong with that, unless there are superior models that allow them to still get paid reasonably well for their work as well as allowing them to release as open source. For example, many open source project pages have a donation link which allows happy users to send any amount of money to the developer if they wish, but I'd expect that this isn't a hugely profitable source of income compared to selling the software (which would kind of require it being closed source or at least with a horrible restricted semi-free license).

Thoughts/enlightenments?

Friday, August 20, 2010

Why does Applescript suck so badly?

It's not like Apple is lacking developers or time or money or experience. Not only is the syntax for Applescript simultaneously verbose and vague, the API documentation sucks and the implementation appears to be buggy.
Not the language implementation per se, but the underlying hooks that allow it to do its job. For some reason, certain programs fail to respond to Applescript correctly, so scripts like the following don't work properly (and worse, the problem is sporadic):

tell application "Mnemosyne"
activate
end tell


Fine, maybe the Python wrapper for Mnemosyne is a bit dodge. But why should it matter?

In Windows there are free third party scripting/automation languages like AutoHotKey and AutoItScript. I've never had a problem bringing an application window into focus with them - why would you? Perhaps Applescript's hooks are at a higher level, while those of AutoIt etc operate on a low level Windows message scheme: instead of applications responding (or ignoring, or bolloxing up) Applescript requests, they simply receive normal window/GUI events, just like when a user is manually clicking and typing.

These Windows automation/scripting languages "just work" - you can assume that a window is just a window and if you can activate one by clicking or alt-tabbing to it, you can activate it via a script - and the syntax is simple and intuitive for most programmers (although AHK's is a bit ugly IIRC).

If they can do that, surely Apple can do much better than Applescript.



Addendum: It seems that you can't even move the mouse from Applescript, without installing extra 3rd party software. Boo-urns!

Addendum 2: Well, it's not giving me error -9874 anymore when trying to activate the window. Also it's become apparent that when activating the Mnemosyne window with a modal dialog open (the "Add cards" window), focus will be on the application's main window, unless the mouse cursor is hovering over the main window. This happens when you manually cmd-tab to the application. Very odd - perhaps the GUI event loop isn't processed properly until the mouse cursor is moved over the main window? Ah well. The rest of my diatribe stands (or crouches) though - I still dislike Applescript in more ways than one.

Tuesday, August 17, 2010

Why is speeding so commonplace?

The root problem seems more that people are expected to drive at least at the speed limit, if not over. When a driver travels at 3-5kph under the speed limit, following cars tend to overtake as soon as possible or get angry and start behaving dangerously. There are very large number of people out there who will consider you to be a lunatic for doing 48km/h with a 50km/h limit. In Dublin at least, a 50km/h limit is tacitly interpreted as a 60km/h limit, a 60 as an 80, etc.

And it's not purely a social problem; it starts in the Rules of the Road, which says things like:

You must progress at a speed and in a way that avoids interference with other motorway traffic.


Avoid driving too slowly

In normal road and traffic conditions, keep up with the pace of the traffic flow while obeying the speed limit. While you must keep a safe distance away from the vehicle in front, you should not drive so slowly that your vehicle unnecessarily blocks other road users. If you drive too slowly, you risk frustrating other drivers, which could lead to dangerous overtaking.


While it does remind you to obey the speed limit, this comes into conflict with the greater message here: "keep up with the pace". Since it seems like the majority of other road users are almost constantly speeding, this reinforces the notion that you should never travel below the speed limit, and if anything, increase speed to match traffic in front.

It's frustrating - if you're driving within a city, given the time spent in traffic or stopped at lights and the relatively short distance, it doesn't really matter if you travel at 45 or 55. But it's considered a greater crime to err on the low side. Why?

Thursday, August 05, 2010

Java verbosity again

(Repost of a comment I made somewhere on the topic of the verbosity of Java, and particularly its APIs)

The Reflection API is a fairly shocking example of the needless verbosity of Java. And I would consider the official API to be part of Java.

Here's a simplistic example in Java and Ruby, replacing characters in a string ("putty" => "puppy") first directly and then via reflective invocation:

// Java
String s = "putty";
System.out.println(s.replace('t', 'p'));
try {
Class c = s.getClass();
Method m = c.getMethod("replace", char.class, char.class);
System.out.println(m.invoke(s, 't', 'p'));
} catch (Exception e) {
e.printStackTrace();
}

# Ruby
s = "putty"
puts s.gsub("t", "p")
puts s.send("gsub", "t", "p")


This kind of verbosity is prevalent in Java's standard libraries, particularly when (anonymous) inner classes are involved. At the moment I'm struggling with "doPrivileged" blocks in some Java code which deals with sandboxing, and it is syntactically very unpleasant.

Ok, we could chain the Java calls together and knock some lines off, but it's still not nice:
try {
System.out.println(s.getClass().getMethod("replace", char.class, char.class).invoke(s, 't', 'p'));
} catch (Exception e) {
e.printStackTrace();
}

Tuesday, August 03, 2010

Ankimini audio on the iPod: can I hear it now?

Yes! But a small amount of manual muckery is required.

Here are the rough steps that I followed to get an Anki deck working with audio on my iPod Touch (2nd gen, on IOS4):
  1. Jailbreak the iPod. This was actually so easy that it will be hard to suppress an ear-to-ear grin. Just going to that link and opening a cleverly broken PDF file exploits a bug (presumably a stack smash) to execute arbitrary code and install Cydia. You don't even need to reboot the device! Very different from the iPhone OS 3 jailbreak that I used last time, but this will probably become impossible soon (until someone finds the next suitable vulnerability).

  2. Install Ankimini from the Cydia or Rock package managers. Easy peasy.

  3. Create or download the deck in Anki (desktop). Get your deck working on a desktop machine as normal, then sync it with an online account.

  4. Sync your deck in Ankimini. This should be straightforward.

  5. Copy across the media files. From my Mac, the command to do so was scp -r ~/Documents/Anki/deckname.media/ mobile@ipod_ip_address:~/.anki

I then stopped and started Anki via an SBSettings button, but I don't think this step is necessary. Now I can learn and listen to spoken Chinese in "dead time" (i.e. when I'm on a bus or taking a shite). Brilliant!

On a related note, I would like to try the new AnkiMobile, but it's just a bit too expensive for me at the moment. I think the developer may be pricing himself out of the market - you don't see (proportionally) many iPhone applications that cost €20. At an uneducated, not-thought-through guess, I'd wager that more than twice as many people would buy the program if the price was halved. Hopefully it works out anyway, after the tremendous work he's put into Anki.

Thursday, July 29, 2010

Abuse of software patents (what else are they good for?)

Check out the Wikipedia entry for Vistaprint (emphasis added):

The company recognizes that developing and protecting its intellectual property creates additional value in the company, and acts as a business moat to deter competitors. So far, Vistaprint has secured 15 issued patents and has applied for almost 40 more.

The company has described its objective as a "minefield of patents" and has been active in pursuing companies that it considers to be infringing on those patents."


If you think that's an unfairly exaggerated statement, check out the interview* with Wendy Cebula, then Executive Vice President and Chief Operating Officer (now President of the North American unit) of VistaPrint (emphasis added in italics):
VistaPrint has always placed a strong focus on getting patents. Which one or two would you classify to be the most important?
We really look at patents as a portfolio approach. As different competitors may choose to enter the market in different ways, our strategy is to create a minefield of patents that would be difficult for anyone to navigate. That being said, our patents around our studio design technology, which is one of the ones we are defending right now in the public, and in our back-end aggregation and our bridge are two that have been issued and that are public that we believe that are very important to us. There are others pending that, clearly, we are excited about as well.

If that's not clear evidence that patent systems, and especially software patent systems, are purposely abused to stifle competition, then what is?



* Note that the interview was taken down - I had to find it in the Internet Archive snapshot from 2008. Interesting...