Monday, April 22, 2013

Keeping OS X Awake

Wake up and smell the coffee...

OS X 10.8 has quite an agressive sleep strategy. Quite often, when writing programs for the Enigmatic Code site, I need to stop my laptop sleeping while it runs a program to generate a solution to one of the problems.

I found out last year about the caffeinate command in OS X, which stops the system from sleeping while a command is running. So I often use something like this:
time caffeinate pypy enigma82.py 6

if I want to leave my laptop running something when I'm out, or overnight (and know how long it took).

But what happens if a program has been running for a while and you forgot caffeinate it before you started? You don't want to kill it off and lose all the work it's done, just so you can restart it under caffeinate.

Well the answer is simple, just write a quick Python¹ program to monitor the process you are interested in, and caffeinate that instead.

Here's my quick Python program - I called it pid-exists - it just monitors a process (using the pid specified as the command line argument), until it disappears, and then exits itself.
import sys
import os
import time

PID = int(sys.argv[1])

while True:
  try:
    os.kill(PID, 0)
  except OSError:
    break
  time.sleep(10)

Then you caffeinate that instead. For example:
caffeinate pid-exists 57905

will stop the laptop from sleeping while the process while pid 57905 is active. Once the process 57905 terminates then so will the pid-exists process and the parent caffeinate process and the laptop will go back to it's normal sleep strategy.

Note: On OS X 10.11 you can now just use:
caffeinate -w <pid>
to keep the computer awake while process <pid> is running.

───
¹ Other scripting languages are available.

Wednesday, April 10, 2013

Sliding Puzzle in Python

As part of making a constructive solution to Enigma 1444 I wrote a some Python code to capture a simple "sliding puzzle" solving algorithm. (You can see my code on the Enigmatic Code site).

This is all very well, but I wanted to see the algorithm in action. So instead of cutting up pieces of paper and sliding them around my desk, I wrote a Tk app using Python.


You need to specify the puzzle dimensions on the command line when you start the program. In this case for a 5×5 grid I used:
python sliding-puzzle.py 5 5

A window should show up with the puzzle in it, and you can interact with it by clicking on a tile (adjacent to the blank square) and it should move appropriately. It will keep track of the number of moves and the elapsed time, and if you select an appropriate Target from the drop-down menu it will tell you when you achieve it as a solution. You can choose from "Normal", which is the tiles in their "natural" position, or "Reversed", which is the tiles in reverse order. Note that it is not possible to solve a grid into the "Reversed" configuration for all puzzle dimensions, but that's what the Enigma is about, so that's the default.

There's a button marked Scramble. If you press that the grid will be placed into a random (but not impossible to reach from the initial position) configuration.

There's also a button marked Solve, which if you click it will start solving the puzzle using the algorithm I wrote for the Enigma puzzle.

When you click Solve the puzzle shows you the piece it is currently trying to place (by highlighting the piece in yellow), and also the position it is trying to place it in (by placing a yellow highlighted border around it). Once a piece is placed it is slightly greyed out. Also the Solve button changes to a Stop button, should you wish to abandon the automated solution.

If the target configuration is not possible, the message area will display Impossible Target, and the app will beep.

I used this to demonstrate that the smallest solution for Enigma 1444 - a 10×5 puzzle - is indeed possible in less than 15 minutes, and this is the configuration that the program is set to solve by default. Just fire it up, hit Solve and sit back and enjoy the show. It takes 1300 moves and on my machine it runs in about 4 minutes.

The default animation speeds mean you would have to pretty nimble-fingered to keep up with the program in real life (or use a cleverer algorithm to solve puzzles in fewer moves), as it makes around 5 moves/s. (There are command line parameters if you want to change the speed of moves). I manually reversed a 5×5 puzzle in 3 minutes (three times slower than my program), so a 10×5 puzzle should certainly be possible in under 15 minutes by hand. (Update: I reversed the 10×5 puzzle manually using this program in 824 moves, in 10m27s).

The next smallest solutions are also solved in less than 15 minutes by the program (but only just). A 14×7 puzzle is solved in 3828 moves, and a 11×10 puzzle is solved in 4122 moves. These both take about 14 minutes. After that a 22×5 solution is solved in 6344 moves and takes about 21 minutes.

If you like you can specify a target configuration on the command line. For example you can try to solve the puzzle for which Sam Lloyd offered $1,000 by running:
python sliding-puzzle.py 4 4 1 2 3 4 5 6 7 8 9 10 11 12 13 15 14

and then clicking Solve - but you'll find the solution is impossible.

There's still a few rough edges in the program, and it's not particularly efficient, but it's works sufficiently well for me to see my solution to Enigma 1444 working, so I'm unlikely to take it further.

I've tested it on Mac OS X 10.8.3 under Python 2.7.4 and Python 3.3.1 with Tk 8.5.9, and on Linux (Ubuntu 12.04.2) under Python 2.7.3 and Python 3.2.3.

Tuesday, January 1, 2013

The Complete Sherlock Holmes

Last year I decided to read the complete Sherlock Holmes stories in the order they were published before the next series of Sherlock starts (although I've since found out they are not even starting to film it until January 2013).

I started by downloading The Complete Sherlock Holmes Canon from sherlock-holm.es as a PDF file, but soon realised that reading books on a laptop was not the way I wanted to go. But then Caroline bought a Kindle e-Reader and I discovered that reading PDF files on a Kindle was also not the way I wanted to go either.

So, I downloaded the HTML version of the Canon, and converted it to an eBook using calibre and I've now managed to complete The Complete Sherlock Holmes.

As I was going along I discovered a few transcription errors, which I've mostly fixed (it didn't occur to me to fix them in the first couple of stories, so a few still remain), I re-ordered the stories to match the original publication dates, and I changed the spacing of some punctuation so as not to confuse the Kindle's dictionary function.

If you'd like to download my version here it is:

Monday, November 5, 2012

250 Enigma Variations

It's been 11 months since I started up the Enigmatic Code site — a place to share programmatic solutions to New Scientist's Enigma puzzles — and I've just posted the 250th Enigma Puzzle to the Enigmatic Code site. This means there is the best part of 5 years worth of puzzles there, along with my own solutions to them.

I've got all puzzles from 2012 (to date), 2011, 2010 and 2009 and most of 2008, as well as some puzzles from the very start of Enigma in 1979 (thanks to Google Books) along with a handful of other dates that I've come across.

And so to celebrate the 250th puzzle going up I've posted the oldest not-yet published puzzle I've been able to find — Enigma 12: Cubic Walks — which after pondering over a Rubik's Cube for some time I came up with a sort of solution to in Python, although I'm not entirely happy with it. But it makes the list of Notable Enigmas, which is my personal view of the 20 most thought provoking Enigma Puzzles I've posted. (Also on that page are a handful of Enigmas that I've not been able to come up with a satisfactory programmatic solution for).

I will keep on posting new Enigma Puzzles as they are published in New Scientist, (they usually go up on a Wednesday evening in the UK) and I'm filling out the gaps with puzzles that I already have solved. I have programs going back continuously to Enigma 1482, when I started using them as a weekly programming challenge. Up until Enigma 1554 I was using Perl, but then I switched to Python and I've been using Python since. Sometimes I publish my original Perl code, but usually now I just write a Python solution rather than clean up my Perl code ready for posting.

Once the puzzles I've already solved are posted I'll start working through Google Books and put up older puzzles.

If you're a fellow Programmatic Enigmatist feel free to add comments to the Enigmatic Code site.

Thursday, August 30, 2012

Mac to Mac AirPlay Mirroring

I've had my old laptop (currently a 2008 MacBook) plumbed into my TV for some time and use it mainly as a PVR by running EyeTV on it, but often I want to send media from my currently laptop to the TV and have never really found a satisfactory solution. [*]

Until now. Luckily the hardware on my MacBook Pro supports Intel's Quick Sync technology, so with the recent release of OS X 10.8 it is able to do AirPlay Mirroring to an AppleTV. Which would be great... if I had an AppleTV (and I've almost considered buying one just for this). But given that I've already got a MacBook plugged into my A/V set-up it would be more convenient to use that.

I tried a couple of free AirPlay server applications on the MacBook (both AirPlayer and BananaTV allowed media to be sent from Caroline's iPhone to the TV (BananaTV worked better with audio)) but they didn't allow AirPlay Mirroring from my laptop. But when I downloaded the paid AirServer app I found that it did exactly what I wanted. I'm less than a day into the week long free trial, but unless I find some serious flaws I'll be purchasing it.

Update 2012-09-24: There was a security update for my MacBook, which required a restart, which ended my free trial. But I purchased AirServer, and am happy with it. There are some problems with video/audio synchronisation when sharing the screen from the MacBook Pro to the MacBook (I found that setting the Audio Buffer Size to 2200 seemed to give the best synchronisation), but the best solution for streaming video is to do it from iTunes, and then the video and audio stay in sync.

[*] My previous best solutions were just to use a cable (3.5mm for just audio, HDMI for video/audio), although for audio only setting up AU Lab 2.1 to send the System Audio (intercepted by SoundFlower) to another instance of AU Lab running on the target system worked with the lowest latency. Setting up a reverse VNC connection worked well enough to allow displaying of photos to the computer plugged into the TV, but both of these are a bit fiddly compared to just plugging a cable in, or the wireless simplicity of AirPlay.

Sunday, June 24, 2012

Farewall appscript?

In preparing for Macaroni Penguins Gig #126 tonight I noticed that my newly updated iTunes 10.6.3 didn't seem to be playing with my py-appscript scripts.

A quick search brought up this posting entitled "The first nail in the coffin of Python appscript", which reveals that new security technologies coming along in Mountain Lion (OS X 10.8) might well stop existing appscript based scripts from working. And anyway appscript itself is no longer being developed or supported, so I fully expect all my useful little scripts to gradually decay into non-functionality over time.

For the time being I have managed to use appscript.terminology.dump() to make a static glue from iTunes 10.6.1 that I can use to allow my scripts to continue to run with iTunes 10.6.3, but it doesn't feel like a robust long-term solution.

Update 2012-09-12: I updated to iTunes 10.7 (under OS X 10.8) and my py-appscript scripts are working again. Hurrah!

Thursday, April 19, 2012

Another One Bites The Dust

In 2008 I bought a Western Digital My Book Home Edition 500GB external hard drive to do Time Machine backups to. Although when I got a Time Capsule the drive was repurposed as an adjunct to my Media Centre Computer (i.e. my old 12" PowerBook plugged into the TV), although it didn't seem to like the fact the PowerBook went to sleep and eventually the file system got corrupted. I wrote a Perl script to recover files from an "unrecoverable" HFS+ filesystem (if anyone is interested I could clean up this code and post it) and got all the data back off it, reformatted it and attached it as an external disk to the Time Capsule.

And so it chugged on, occasionally having things dumped on it. Until last week, when I noticed that the Time Capsule seemed to be playing up, and the cause was apparently the external disk. I disconnected it and had a quick look with it plugged into my laptop and it seemed to be OK (although in retrospect I should maybe have done a bit more investigation that just looking to see if a directory listing showed there were files there).

Shortly afterwards I happened to be in Maplin and noticed they had a deal on Seagate GoFlex Desk 2TB External Drives, and so I got one of those, hoping I would be able to copy all the data off the failing 500GB drive before it lost the plot completely.

It turned out that although all the empty boxes in the shop proclaimed the drive was USB 2.0 and "upgradable to USB 3.0" (the GoFlex drives have swappable bases that allow you to choose different interfaces) that the drive I got already had a USB 3.0 adapter base. And so I ended up with my first USB 3.0 device, which by itself isn't particularly useful. However the supplied cable was perfectly adequate to connect the rather wacky USB 3.0 Micro-B socket on the HDD to the standard USB 2.0 A socket on the Time Capsule, and everything seemed to work fine. I kicked off an archive of the Time Capsule's internal disk and the next morning all my backups had been duplicated to the new disk.

So then I tried to recover the data from the failing 500GB drive. It turned out that it wasn't as happy as I'd originally thought. Although files would show up in Finder, if you actually tried to copy them off the drive the whole thing failed, making spin-up/spin-down noises and then disconnecting. I tried it through various interfaces (FireWire and USB), and also with the drive in various physical orientations (you never know). I even tried a different power supply in case the original one could no longer supply enough juice, but to no avail.

After I decided that there wasn't anything critical on the drive (mostly old TV shows I hadn't got round to watching) and that it was out of warranty, I thought I'd open it up. This was easier said than done. I eventually managed to lever the sides of the MyBook slightly open with a screwdriver and then open it like, well, a book, and get to the drive inside.

The MyBook is a sturdy well-constructed package, but once I got in I found there was a WD Caviar GP 3.5" SATA drive inside. Unfortunately I don't have a 3.5" SATA/USB enclosure. I probably should have guessed it was a SATA drive, as the MyBook has an eSATA connection as well as FireWire and USB. So I had a last ditch attempt at reviving it without it's case on, and even tried dropping the drive from about 6" onto my desk - just in case it helped. Then it dawned on my that the adapter for the GoFlex drive is just a SATA/USB3 bridge, so I removed the GoFlex drive from it's base, and then precariously balanced the bare WD drive on top of the adapter and proceeded to recover all my data from the WD drive.

This makes me think that the SATA/USB/FireWire bridge board in the MyBook enclosure is the component that is failing. Although it's not completely failed as it still talks to the disk to some extent. I find this slightly perplexing as I would have thought it was the component least likely to fail. Maybe some component on the board is undergoing heat failure.

Anyway, I offer this story up to the Internet in the hope that someone in a similar situation may be able to recover some important data that they thought was lost for ever, by using the power of the search engine, a screwdriver and a SATA adapter.