Command-Line Interface Software


A binary-to-text encoding format. Encodes 3 bytes or two ASCII 7-bits characters into 2 Unicode characters. Think "Base64 for Unicode" plus RLE.


2012-12 micro_macho

Dissection of minimal Intel 32-bits, 204 bytes, Mach-O "Hello World" executable file.

2012-03 utis_explorer

Find OS X UTIs, build up the inheritance tree, save it as a Graphviz graph.


2012-01 pmlogs_to_ical

Create a calendar of wake-sleep sessions based on power management logs.


2011-11 gmap_tiles

Download and merge Google Maps tiles.



Draw any file as a picture.



Helps in localizing Cocoa applications by showing unused/missing keys in Localizable.strings.


2011-01 efx-backtest

Back-test eForex trading strategies with this minimalist Python engine.



Graph the import dependancies in an Objective-C project.

blog post


Download photos from Facebook photo albums.

github repository


Get hints about unused methods in your Objective-C code.

$ python ~/ 
# the following methods may be unreferenced
-[MyClass notUsed]

blog post
github repository


Save you tweets in CSV format. Because you never know.

$ python nst021

github repository


Reads iCal events and reports the time you spend on projects.

$ python -c "Heures_2009" -l
From 2009-09-01 to 2009-09-30
Annual Meeting       8.50
MobiWalk             3.50
MetaMin              11.50
Memoria Mea 2        105.25
Total                128.75

github repository


Dump the URLs opened in Safari with these six lines of Python :


import os
from Foundation import NSDictionary

last_sessions = os.path.expanduser("~/Library/Safari/LastSession.plist")

d = NSDictionary.dictionaryWithContentsOfFile_(last_sessions)

for sw in d['SessionWindows']:
    tss = sw['TabStates']
    for ts in tss:
        bfls = ts['BackForwardList']
        for bfl in bfls:
            print bfl['URL']

2009-01 NSArray+Functional.h

This is a category to add Python like map, filter and reduce methods to Cocoa NSArray:

@interface NSArray (Functional)

- (NSArray *)filterUsingSelector:(SEL)aSelector, ...;
- (NSArray *)mapUsingSelector:(SEL)aSelector, ...;
- (id)reduceUsingSelector:(SEL)aSelector;


You can then program in functional style:

NSArray *a = [NSArray arrayWithObjects:@"a", @"ab", @"abc", @"bc", @"c", nil];

NSArray *x = [a filterUsingSelector:@selector(hasPrefix:), @"a", nil];
NSArray *y = [a mapUsingSelector:@selector(uppercaseString), nil];
NSArray *z = [a reduceUsingSelector:@selector(stringByAppendingString:)];


x: (a, ab, abc)
y: (A, AB, ABC, BC, C)
z: aababcbcc

Read the blog post talking about it: Map, filter and reduce in Objective-C/Cocoa.


[2009-01-14] bug fix by mjtsai: don't set arg in the while loop condition
[2009-01-17] support most argument types, added unit tests, tested on intel and ppc

github repository


SpotLook tracks use UTIs to know what kind of file to search.

In order to prepare the defaults tracks, I did search for UTIs lists on the web.

I put the most interresting links in SpotLook FAQ.

One ressource was especially useful, it's an autogenerated graph of the system UTIs.

Sadly, the author did not post the ruby script he wrote to generate the tree.

It immediately made me think of how I would write such a script.

So here's a script, obviously written in my scripting language of choice :)

It does not build up the UTIs hierarchy (since it's not what I need) but it lists the UTIs used by Spotlight importers on your system.


Test dead links from a web page list. Written to help someone on a newsgroup.

$ cat links.txt
$ python links.txt    <- dead link


Send an email or and SMS when a server is down. Use it with cron.


Convert utf-8 text into iso-latin-1 by minimizing characters loss.

Faites par exemple un coper-coller de la page d'accueil du Monde et collez-la dans SubEthaEdit. Vous êtes obligés d'utiliser l'encodage utf-8. Vous pouvez le convertir en iso-latin-1, mais les caractères qui ne sont pas représentables en iso-latin-1 seront remplacés par des '?'.

Quand on essaie de faire une telle conversion, les différents langages ou logiciels proposent généralement le choix entre :

Or ce que je veux le plus souvent c'est convertir en minimisant les pertes, de manière à ce que le texte reste lisible, en convertisant par exemple les caractères "oe", "euro", etc.

Le script permet de faire ça. Notez que si vous tombez sur un caractère impossible à convertir, le script lèvera une exception. Il suffira alors de rajouter la conversion souhaitée dans le script.

$ python mon_texte_utf8.txt > mon_texte_latin1.txt


Built a web page with Flickr sets photos showed in big. updated 2009-06-08

Am I the only one to find that Flickr sets are ridiculously small and uncomfortable to browse?

Yes, I know, you could use Pywebpics to make your own gallery on your own server.

But photos take place and it might be more convenient to store them on Flickr.

flickrGallery is a quick Python script that does the following:

input: a title string

output: an html file showing the photos set with a normal size

example: before after

2009-08-03 this script now works online at

2006-04 airportkey.m

AirportKey can convert a WEP password from ASCII to hexadecimal Airport "equivalent network password" (Apple proprietary hash) without being connected to the Aiport base station. It uses Apple private framework Apple80211.framework.

$ airportkey 
Translate a string into a 40 or 104-bit Apple hashed WEP key.
usage: airportkey  
        password:       the ASCII WEP password
        use104bits:     0 for 40 bit key and 1 for 104 bit key 
        version: 0.1
$ airportkey toto1234 1

See also:


Quickly create and update a web photo gallery.

See an example gallery.

Typical scenario

  1. create a project $ pywebpics my_project
  2. put some photos in my_project/source
  3. run pygallery again $ pywebpics my_project
  4. your gallery is ready!
  5. add some more photos in your source folder
  6. run pygallery again
  7. the latest photos are added to your gallery!
  8. edit my_project/config.txt
  9. run pywebpics again
  10. write your ftp settings in my_project/config.txt
  11. run pywebpics with the -upload option $ pywebpics -upload my_project
  12. your gallery is online!
  13. add some more photos in your source folder
  14. run pygallery with the -upload option
  15. your local and remote galleries are updated!

I personally find the concept very original and practical. A gallery is stored in a project directory that contains all the photos as well as a config file. To add new photos, you just need to add them in the source directory and run the script on the project directory, and every steps will be done automagically.


Quickly upload a file on your website, and get the file url back, ready to be copy-pasted.

Useful when you are talking by chat or email and want to share a (big) file.

$ myftp                  - list directory
$ myftp file.txt         - send file.txt
$ myftp rm file.txt      - removes file.txt


$ myftp test.txt 
sending 171 bytes


Le Boggle is a letter game edited by Parker. The players must find as many words as they can in a 4×4 letters grid (or more) in three minutes. See the official rules.


For example: try to find as many French words as you can in the following grid (there are 42!):


Here is a script that allows to create and resolve grids of any size. It comes with a 128970 words French dictionary. Even with such a big dictionary, the script car solve 50×50 grids in 13 seconds on a PowerBook 1.5 GHz.
the French dictionary

en français

in English


She: Would you count 2 minutes and a half plase? I : $ timer 2 30

Starts a timer. Useful for tea or cooking.

Uses the curses library. Lets you set the meal. With Mac OS X >= 10.4, the script pronounces a vocal alert.


Counts the number of hearbeats per minute.

For example, you can use it to count your mp3's bpm or your number or heartbeats or breaths per minute.

$ python
BPM - Calcule les bpm sur les 4 derniers beats.
Appuyer sur a chaque beat, 'q' pour quitter.

BPM : -
BPM : 83
BPM : 82
BPM : 85
BPM : 87
BPM : 86
BPM : 87


pdfmi stands for PDF meta-information.

This script displays pdf files metadata.

The script is very concise, thanks to Python's syntax!

Obsolete on Mac OS X since version 10.4, because mdls is more accurate.

$ python adarsa.pdf 
Title        : AdaRSA
Author       : D. Lifschitz et N. Seriot
Subject      : Projet de semestre, EIVD 2003
Keywords     : eivd, ada, cryptographie, rsa
Creator      : LaTeX with hyperref package
Producer     : pdfTeX-1.10b
CreationDate : D:20030713174200
ModDate      : D:20030615105433
Trapped      :


Count a word occurrences, or each word occurrencies in a file.

Written to answer an inquiry in a newsgroup.

With one parameter, display the number of occurrences of each word in a given file.

With the parameters, display the number of occurrences of a given word in a given file.

Usage: woc [] 

-h, --help : Show this help text and exit
-v, --version : Show file version and exit

lines : number of lines
sword : number of single words
twords : number of total words
chars : number of characters
$ woc ihm.txt
lines 1
swords 8
twords 11
chars 52

2 : win
1 : sp4
1 : projet
1 : ms
1 : menu
1 : controls
1 : common
1 : 60


The AVS number (Assurance-Vieillesse et Survivants, AHV in German) is like the swiss social security number. It is made from personnal data, such as name, sex, date of birth and nationality. It also includes a checksum.

This script was originally part of a PyObjC application.

See also: Le numéro d'assuré



Quickly checks the TV program by parsing the TSR web site.

Written with Pierrick Terrettaz and Cédric Lüthi.

This script is now obsolete since the TSR changed its website.

$ tv -h
   Affiche le programme TV
   USAGE: python /Users/nst/bin/tv [+] [-now | -next]

see everything ("enter" after each channel):

$ tv
$ tv TF1 M6 Arte

see what is running now:

$ tv -now
$ tv France2 TSR1 Eurosport -now

see only programs that haven't started yet

$ tv -next
$ tv RTL9 -next