Archive for Python

My First WebApp

There are lots of technologies that I have been investigating recently, with the intent of building something useful. However, it’s hard to figure out if my plan makes sense without trying. So I am going to build a very simple application.

The specification looks like:

The application shall allow the user to send email notes to themselves

I often email short notes to myself as reminders or to capture short pieces of information. The number of steps involved in doing this is too many. I have to address the email, set a subject, navigate one of many email clients and then send. I want to IM myself and have it turn up as email.

My design for building this is a little bit more complex than it really needs to be. This is because the application is an excuse to try building a platform.

There are four pieces:

  1. Taskbar applet to send mail
  2. Web application to send mail
  3. Web service to receieve send mail request
  4. Application service to send mail

The task bar applet is the easy part (see QSystemTrayIcon). That will be built, initially for Windows, using Qt. If I’m enthusiastic, it may support RTF and HTML email as well as unicode text.

The web application, likely to be built last, will use django. I’m considering Ruby on Rails, but given I already know python and django provides sufficient functionality, it is my likely choice.

The web service will be built using the same web framework as the web application. I am trying to reduce the number of technologies a little bit.

The aims of the web service:

  • Provide a publically accessible API.
  • To allow for a flexible URL mapping scheme
  • To provide a REST style API.
  • To easily provide different data formats (XML, JSON).

The application service will be built using Haskell. It will be kept as an internal process. It will likely be built using a web service as well, but using JSON as the transport. I am choosing Haskell mainly to explore options.

After my recent foray into Lisp, I am confident I could build the application service using Lisp, but would prefer to use Haskell. This is partially to avoid paying license fees to Allegro, but mostly as I prefer having the type system of Haskell available. The architecture will allow me to swap back-ends if needed.

That is the plan. Progress and learnings should trickle in over the coming months.

Note: This is an exercise in playing with technology. There is no plan for providing this as a production level service.

Elementary Bluetooth using PyObjC

Bluetooth connectivity to devices is supported on Mac OS X using Cocoa APIs, so is possible to access from Python. Bluetooth itself opens up a large body of knowledge that I am only starting to investigate.

This article outlines some basics for using Bluetooth in Python.

Bluetooth access is achieved through two frameworks, IOBluetooth and IOBluetoothUI. Neither of these are included in PyObjC by default, so a basic wrapper class makes life easier. (see the PyObjC docs)

Add the following to IOBluetooth.py:


import objc as _objc

_objc.loadBundle('IOBluetooth', globals(),
  bundle_path=u'/System/Library/Frameworks/IOBluetooth.framework')

The loadBundle pattern is very useful, and allows the classes from any Objective C framework to be loaded into the PyObjC bridge. By putting it into a separate Python module, usage becomes less painful.

For example, the most recent device is:


>>> from IOBluetooth import *
>>> devs = IOBluetoothDevice.recentDevices_(1)
>>> devs[0].getNameOrAddress()
u'gmwils 6600'
>>> devs[0].isConnected()
1
>>>

In this case, my Nokia 6600 is still connected in AddressBook.

To create a new connection to a device, Apple provides access to their user interface for Bluetooth management. It is strongly recommended that these controls are used to provide consistency for the user and detailed error handling.

For example, selecting a service from a device with a dialog:


>>> from IOBluetoothUI import *
>>> browser = IOBluetoothServiceBrowserController.serviceBrowserController_(0)
>>> browser.runModal()
-1000
>>> results = browser.getResults()
>>> results[0].getServiceName()
u'Bluetooth Serial Port'
>>>

Note: you will need a IOBluetoothUI wrapper, similar to the IOBluetooth wrapper from earlier.

Useful documentation links:

Birthday Notes

Birthday Notes is an application with two purposes. On one hand it provides an easy way to keep track of people’s birthdays on Mac OS X. The other role it plays is to learn Cocoa programming using Python, Cocoa and PyObjC.

Why bother with yet another birthday tracking tool? Quite simply, most were too difficult to get the information that I wanted. The main aim of Birthday Notes is to provide a list of upcoming birthdays with relevant information.

For example, I rarely think of people’s birthdays in terms of their birth date (eg 1977-08-04). My brain is wired so that I remember that my birthday is on the 4th of August and that I’m currently 28 and turning 29 on my next birthday. Rather than show the birth date, Birthday Notes shows the birthday and the person’s age they turn on that day.

Birthday Notes features integration to Apple’s existing applications for storing data. This means that iSync support comes for free. The current focus is on a maintenance and reporting tool, so you can edit a person’s birthday from within Birthday Notes, but not create or delete. For additional actions, simply double click on the person’s name - they will be revealed in AddressBook.

I like to know some trivia about people’s birthdays, so Birthday Notes includes a bit of useless astrological information.

Birthday Notes is available for download. Requires OS X 10.4 or greater.

Any thoughts, suggestions, bugs or feedback should be sent to gmwils AT pseudofish.com, or posted in comments on this post.

For those interested in the code, it is available under a GPL license. To compile, Python 2.4, a recent build of PyObjC, and icalendar are needed.

Finally, my thanks to those who have been helping with alpha testing. This release marks the start of a public beta.

Bruce - Presentation software using PyGame

Richard Jones has posted Bruce, the presentation software he used at the recent OSDC.

Various presentation software was used during the conference along with many presentation styles. The ones that stuck out the most were the typical corporate slides in PowerPoint. Usually, as I feel asleep or played on my laptop during these. Presentation Zen needs to be read by many presenters, especially if they missed Paul’s presentation.

The presentation that had the greatest impact at showing live code was Richard’s using Bruce. With PyGame as a back end, there was no application swapping between the demo and the slides. The demos were contained within the slides!

Another interesting presentation platform was Autrijus’s. His talk was built using XUL, the scripting platform created by the Mozilla team. The slides he used are available on his site and you need to follow the link using Firefox to view them. He has even been referenced (unattributed) by a site listing their top five speakers!

Target - Finding Letters in Words

Target - A simple word puzzle. The beginnings of pain. The basic problem is a grid of nine letters printed in a newspaper. One of the aims is to generate words using the central letter from the square. The sub goal is to find the nine letter word that uses all of the letter.

The rules of the game are:

  • See how many words of four letters or more can you make from the letters shown in the grids.
  • In making a word, each letter must be used once only.
  • The word must contain the centre letter and there must be at least one nine-letter word in the list.
  • No plurals or verb forms ending with “s”; no words with initial capitals and no words with a hyphen or apostrophe are permitted. The first word of a phrase is permitted (eg inkjet in inkjet printer).
  • Words come from the main body of Chambers 21st Century Dictionary as the reference source.

And an example:

R I C
U H E
R N A

Target: 15 words, good; 22 very good; 30 excellent.

As a programmer, my inclination to solve these kind of problems is quite low. Scrabble is one of my weaker games. Alas, I am also very competitive, so when this became popular at a camp I volunteer at I was motivated to improve.

The catch is that I’m a little bit lazy. The way to improve at the game is to do lots of them. That doesn’t sound like fun to me.

Last time, I used a very simple regular expression and scanned the words list. I then manually filtered out the invalid words.

Having done a bit of Cocoa programming, I want to create a GUI version of a solver for this puzzle. However, an approximate solver isn’t good enough. I need to be able to exactly solve the word puzzle.

Sitting around at the OSDC, I took the opportunity to try and write the engine part.

A few attempts in Python and I worked out that for an algorithm such as this, either the language or my understanding of it was insufficient for experimentation. For this kind of problem, I tend to think of them mentally in functional style. Fortunately, Haskell is installed on my computer.

Firstly, I needed a function to check if a letter exists in a word:


letterInWord :: Eq a => a -> [a] -> Bool
letterInWord a [] = False
letterInWord a (w:ws)
    | a == w = True
    | otherwise = letterInWord a ws

Given that a letter can only be used once in a target word, a function that removes a letter from a word was needed:


removeLetter :: Eq a => a -> [a] -> [a] -> [a]
removeLetter l [] wss = wss
removeLetter l (w:ws) wss
    | l == w    = ws ++ wss
    | otherwise = removeLetter l ws (w:wss)

The two helper functions can then be glued together to determine if a given word is contained in the letters of the second word:


lettersInWord :: Eq a => [a] -> [a] -> Bool
lettersInWord [] [] = True
lettersInWord [] (w:ws) = True
lettersInWord (l:ls) [] = False
lettersInWord (l:ls) (w:ws)
    | letterInWord l (w:ws) = lettersInWord ls (removeLetter l (w:ws) [])
    | otherwise = False

This solution came together very quickly, but iterates twice through the word. A bit more time in Hugs and the two helper functions become one:


lettersInWord :: Eq a => [a] -> [a] -> Bool
lettersInWord [] [] = True
lettersInWord [] (w:ws) = True
lettersInWord (l:ls) [] = False
lettersInWord (l:ls) (w:ws)
    | isInWord = lettersInWord ls remainingLetters
    | otherwise = False
    where (isInWord, remainingLetters) = removeLetterInWord l (w:ws) []

removeLetterInWord :: Eq a => a -> [a] -> [a] -> (Bool, [a])
removeLetterInWord l [] wss = (False, wss)
removeLetterInWord l (w:ws) wss
    | l == w    = (True, ws ++ wss)
    | otherwise = removeLetterInWord l ws (w:wss)

This covers the basic search for words. It just misses a few of the rules. It doesn’t check if the middle letter is used and it doesn’t check word length. Something to add on a rainy day.

One question I have is whether or not I could do something like this in Python. It is possible to write Python code to do this, but the more interesting question is why I had mind block when attempting to use Python. I suspect this is because I have spent longer using Haskell for algorithms and tend to use Python as glue. Hopefully, PyGame will provide enough motivation to improve my Python coding.

Programmer efficiency aside, the next interesting question is how efficient the two languages are. Performance will matter, as the intent is to run this over a large dictionary of words. Interfacing into Python or Objective C for use in a Cocoa GUI is another question.

Of course, this is pretty close to being an anagram solver. This is a solved problem with many free ones on the Internet. Luckily, I get a kick out of solving the problem using my own program.