Showing the past five entries...

April 21, 2008

Python Rosetta Stone Automation

Many, many months ago I had a long, long layover in the airport in Madrid. On the flight over from the States I had grown increasingly frustrated with the interface to "The Rosetta Stone" language learning software. Now I must confess, there actually is little to get wrong in this interface as the majority of the interaction with the software is done via clicking one of four buttons. However, I come from the UNIX world where I prefer everything to be able to be driven from a set of keyboard shortcuts and so I committed my layover to automating The Rosetta Stone.

Tonight I find myself writing from yet another long, long layover and I find myself revisiting The Rosetta Stone to brush up on my Spanish. I remembered my little application I wrote in Spain and so I made a few tweaks and decided to share it, just in case anybody should find it useful.

If anything, it demonstrates two concepts:

  • The bizarre Windows goop one must wade through in order to automate a Windows application with no known automation interface.
  • The power and expressiveness of well-abstracted code written in Python.

Here is the entire application. It is less than 50 meaningful lines of code:

import os
import sys
import time
from msvcrt import getch

sys.path.append("../win32automation")

import win32automation

os.system("title KeySetta")
win32automation.spawnProcess(
    r"C:\Program Files\The Rosetta Stone\The Rosetta Stone\TheRosettaStone.exe")
while 1:
    print "Waiting for application to start..."
    result = win32automation.windowFocus("The Rosetta Stone")
    if result:
        print "Window found!"
        break
    time.sleep(1.0)
print "Waiting 5 seconds for login screen to appear..."
time.sleep(5.0)
win32automation.sendKeys('jordanh{ENTER}')

print """
   Keyboard to Mouse Macros Enabled:

     - Answer selection:
       [7] [9]
       [1] [3]
       
    Please focus this window to enable them...
"""

coord_map = {"7": (180, 300),
             "9": (480, 300),
             "1": (180, 475),
             "3": (480, 475)}

while 1:
    win32automation.windowFocus("KeySetta")
    ch = getch()
    print "Last key pressed: %s\r" % (ch),
    if ch in ('1','3','7','9'):
        win32automation.windowFocus("The Rosetta Stone")
        x, y = coord_map[ch]
        win32automation.mouseMoveToRelative("The Rosetta Stone", x, y)
        win32automation.mouseClick(button="left")
    elif ch.lower() == 'q':
        print "Quitting!"
        break
    else:
        print "WARNING: Unknown key-macro event '%c'." % (ch)

sys.exit()

Granted the silly "win32automation" module I wrote is a little stupid. It is based on the excellent example provided over at http://del.icio.us/amoebapr/python. Notice for example none of the functions take an opaque handle to an object. Instead, all of the functions inside of the module require some sort of hint (such as a window title) in order to re-find the desired object before executing an operation on it.

Hopefully however sharing this code will spark somebody to develop a better, free Windows automation module for Python.

Download keysetta.zip (md5sum: a4336d883fcb10b11b8b660451e522a3)

Posted by jordanh at 11:30 PM | Comments (0) | TrackBack (0)

April 1, 2008

Final Shot

00259.jpg
View in Photoblog

This photo was taken by my father and sent to me.

My brother needed some logistical help shooting the final scenes of his movie and so my dad drove up from Los Angeles to the Bay Area in order to help him out. This was supposed to be final location for the movie he has been working on for going on two years.

The salty air ended up doing a number on his old VHS camera and he could not wrap production. The next day he needed to be on an airplane to move to New York City. Now he'll have to come back so he can finish his film.

 

Posted by jordanh at 12:35 PM | Comments (1) | TrackBack (0)

March 30, 2008

Matilija Creek Panorama

00258.jpg
View in Photoblog

CameraCanon PowerShot G9
LensCanon 7.4-44.4mm f/2.8-4.8 IS

Last month my job sent me to San Diego, CA. I stayed the weekend and drove up to Los Angeles in order to see my dad, his wife and family. Even though I was able to cheat winter and escape Minnesota for the full duration this year it was nice to be able to get out into the warm sunshine after four weeks of not having sun light feel warm on the skin.

We drove north to Ojai in order to go for a hike along Matilija Creek. Everything was beautiful and green. The creeks were full and flowing thanks to a melting snow pack.

Along the way I took a series of photographs with the intention to stitch them together into a panorama. This is about nine photographs stitched together. It is a crop of a panorama about three times this size.

It was the late afternoon and we were just finishing our hike that took the majority of the day. The sun was low on the horizon and there was a lot of dust in the air. The light was very soft but dramatic.

 

Posted by jordanh at 9:46 PM | Comments (0) | TrackBack (0)

Muxtape

Muxtape: mixtapes for the Internet generation. What a great idea! Here is my tape: http://jordanh.muxtape.com/

Check out these usage terms:

Muxtape is a service for creating mixtapes. Users may not upload multiple songs from the same album or artist, or songs they do not have permission to let Muxtape use. Individual users may not create multiple muxtapes. Accounts not meeting these restrictions are subject to termination without notice. Muxtape will never reveal your email address to a third party. Muxtape is alive.

The site is by talented web designer and photoblogger Justin Ouellette of http://chromogenic.net/. Justin's photoblogs was one of the first photoblogs I started monitoring regularly. He was definitely an inspiration in getting this site up and running.

I could really see this concept taking off. Sure, there are sites like such as last.fm which allow for the creation of personalized playlists or streaming radio stations or features such as iTunes iMixes but muxtape really neatly encapsulates the bare essence of sharing a pile of music in a format that might actually fit the soul of High Fidelity.

Some enhancements I could see to muxtape:

  • The ability to comment on somebody's muxtape
  • A feature which would allow you to see related muxtapes.
  • An archive feature which allows you to "tag" a previous muxtape so previous track lists are not lost when changes are made; perhaps a tagged entity is the only thing that could be commented upon.
  • The ability to download the muxtape in another standard playlist format (this could probably already be done by a third-party from the RSS with an appropriate XSLT!)

Posted by jordanh at 5:47 PM | Comments (1) | TrackBack (0)

March 24, 2008

ENTP

You Are An ENTP
The Visionary

You are charming, outgoing, friendly. You make a good first impression.
You possess good negotiating skills and can convince anyone of anything.
Happy to be the center of attention, you love to tell stories and show off.
You're very clever, but not disciplined enough to do well in structured environments.

In love, you see everything as a grand adventure. You enjoy taking risks for love.
And if things don't work out, you're usually not too much worse for the wear!

You would make a great entrepreneur, marketing executive, or actor.

At work, you need a lot of freedom to pursue your own path and vision.
How you see yourself: Analytical, creative, and peaceful

When other people don't get you, they see you as: Detached, wishy-washy, and superficial
What's Your Personality Type?

Posted by jordanh at 10:24 PM | Comments (0) | TrackBack (0)