Rcjp’s Weblog

April 2, 2008

Gaussian PIL Image Filter

Filed under: python — rcjp @ 6:54 pm

I could not see a gaussian filter in the python imaging library, but its simple enough to write one…

import ImageFilter
from PIL import Image
from numpy import *

def gaussian_grid(size = 5):
    """
    Create a square grid of integers of gaussian shape
    e.g. gaussian_grid() returns
    array([[ 1,  4,  7,  4,  1],
           [ 4, 20, 33, 20,  4],
           [ 7, 33, 55, 33,  7],
           [ 4, 20, 33, 20,  4],
           [ 1,  4,  7,  4,  1]])
    """
    m = size/2
    n = m+1  # remember python is 'upto' n in the range below
    x, y = mgrid[-m:n,-m:n]
    # multiply by a factor to get 1 in the corner of the grid
    # ie for a 5x5 grid   fac*exp(-0.5*(2**2 + 2**2)) = 1
    fac = exp(m**2)
    g = fac*exp(-0.5*(x**2 + y**2))
    return g.round().astype(int)

class GAUSSIAN(ImageFilter.BuiltinFilter):
    name = "Gaussian"
    gg = gaussian_grid().flatten().tolist()
    filterargs = (5,5), sum(gg), 0, tuple(gg)


im = Image.open('/home/rcjp/tmp/test.png')
im1 = im.filter(GAUSSIAN)
im1.save('/home/rcjp/tmp/testfiltered.png')

February 25, 2008

K language - ultimate coding brevity?

Filed under: python — rcjp @ 5:56 pm

After reading a thread on c.l.l and, over the last week, more than I care to on arc’s emphasis on brevity, I can’t decide if I’m impressed or appalled by the K language.

As K seems to be a proprietary language I wouldn’t normally look at it, but thankfully the Wikipedia entry has a link to a screencast by Michael Schidlowsky solving the birthday problem - how many people do you need in a room to, more often than not, have two or more persons with the same birthday. In K, to simulate 1000 rooms with 10 people in them its

#+/{~(#x)=#?x}’ {(1000,x) _draw 365} 10

using ipython I’d do:

In [1]: from random import randint
In [2]: def samebday(n): return n != len(set(randint(1,365) for i in range(n)))
In [3]: def bday1000(n): return [samebday(n) for i in range(1000)].count(True)
In [4]: bday1000(23)
Out[4]: 496
In [5]: %timeit bday1000(23)
10 loops, best of 3: 367 ms per loop


Casting the list of random ‘birthdays’ (just integers from 1..365) to a python set removes any duplicates, so just checking if the length has changed will show if two or more were the same. The tipping point is 23 according to wikipedia, and the bday1000 function simulating 1000 rooms shows 496 of those rooms had common birthdays - which is roughly half of them. Not as short as K, but concise enough for me I think.

January 31, 2008

Playing with Arc

Filed under: lisp — rcjp @ 12:12 pm

Paul Graham has made available a tarball prerelease of his new arc language. I’m currently running Ubuntu gutsy on my laptop so it needs a quick patch

~/lisp> tar -xvf ~/tmp/arc0.tar 
~/lisp> cd arc0
~/lisp/arc0> wget http://blakeley.com/linux-date.patch
~/lisp/arc0> patch arc.arc linux-date.patch 
~/lisp/arc0> rlwrap -C arc mzscheme -m -f as.scm
Use (quit) to quit, (tl) to return here after an interrupt.
arc> 

then you can go through the tutorial, or play with the webserver, which we’ll start in a new thread

arc> (defop hello req (pr "hello world"))
#<procedure:gs1431>
arc> (= webtest (thread asv))
#<thread: asv>
arc> ready to serve port 8080

and then look at http://localhost:8080/hello

The prompt doesn’t quite come back correctly here, but you can carry on typing

(defop hello req (pr "hello world changed"))
#<procedure:gs1438>

and refresh the browser. Kill the thread and quit with

arc> (break-thread webtest) 
arc> (quit)

Though initially disappointed that there was no native compiler (written in arc of course!), I’ve warmed to the syntax - I didn’t find myself in a fighting the language, or frustrated that I had to reinvent stuff I didn’t want to e.g., here’s how to split up a string using spaces or commas

arc> (tokens "abc def,ghi" [in _ #\ #\,])
("abc" "def" "ghi")

There’s plenty to play with by reading through the source. So far, it feels fun.

October 17, 2007

Show Nearest X11 System Colours

Filed under: python, utils — rcjp @ 1:16 pm

ColourInfo
Just a little utility to show the nearest system rgb colours (taken from rgb.txt) on an X11 system compared to the one under the cursor.

I couldn’t work out how to listen to mouse messages when I don’t own the window under the mouse pointer (on X Windows anyway) - so I cheated and this code takes a snapshot of the screen and displays it in the background. Obviously you can’t move/click on any windows when this thing is running! quit with ‘q’ or ‘ESC’ or just close the window.

#!/usr/bin/env python
#
# Takes a screenshot image of the root window and display a table of 
# nearest system colours compared to that under the mouse pointer
# can specify an argument 1..29 to show more colours (default 6)
# The window title shows the exact rgb values of pointer in hex
#
import gtk, re
from sys import argv

RGBCOLOURS = '/etc/X11/rgb.txt'   # rgb colour data

class ScreenColour(object):

    syscolours = {}  # hold system rgb.txt relating colours to names

    def __init__(self, rgbfile=RGBCOLOURS):
        # 1 pixel buffer for pixel under mouse pointer
        self.pix = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,False, 8, 1, 1)
        for line in file(rgbfile).readlines():
            if not line.startswith('!'):
                rgbname = re.compile(r'\s*(\d+)\s*(\d+)\s*(\d+)\s*(.+)')
                (r,g,b,name) = rgbname.match(line).groups()
                self.syscolours[name.rstrip()] = (int(r),int(g),int(b))

    def cmp_screencolour(self,col,basecol):
        """Numerical difference between colours col(name) and basecol(r,g,b)"""
        return sum(abs(a-b) for a, b in zip(basecol, ScreenColour.syscolours[col]))

    def pixelinfo(self):
        """Returns the (r,g,b) value of colour under mouse pointer"""
        (_, x, y, _) = gtk.gdk.display_get_default().get_pointer()
        self.pix.get_from_drawable(gtk.gdk.screen_get_default().get_root_window(),
                                   gtk.gdk.colormap_get_system(),
                                   x,y, 0,0, 1,1)
        col = self.pix.get_pixels_array()
        return (int(col[0,0,0]), int(col[0,0,1]), int(col[0,0,2]))

    def nearest_colours(self, n, basecol):
        """Return the nearest n system colours compared to basecol"""
        nearest = self.syscolours.keys()
        nearest.sort(key=lambda (c): self.cmp_screencolour(c, basecol))
        return nearest[:n]

class ColourInfoWindow(ScreenColour):

    """Draw a table of colours nearest to that under mouse pointer"""
    label = []
    eb = []
    oldrgb = (-1,-1,-1)

    def delete_event(self, widget, event, data=None):
        gtk.main_quit()
        return False

    def __init__(self, tablesize):
        self.tablesize = tablesize
        self.image = gtk.Window()
        self.image.set_decorated(False)
        self.image.add_events(gtk.gdk.POINTER_MOTION_MASK)
        self.image.connect("motion_notify_event", self.event_handler)
        #
        # set background from a screen shot of the root window
        #
        screen = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8,
                                gtk.gdk.screen_width(), gtk.gdk.screen_height())
        screen.get_from_drawable(gtk.gdk.get_default_root_window(),
                                 gtk.gdk.colormap_get_system(), 0, 0, 0, 0,
                                 gtk.gdk.screen_width(), gtk.gdk.screen_height())
        pixmap, mask = screen.render_pixmap_and_mask()
        self.image.set_app_paintable(True)
        self.image.realize()
        self.image.window.set_back_pixmap(pixmap, False)
        del pixmap
        self.image.fullscreen()
        self.image.show()

        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_size_request(200, 40*self.tablesize)
        self.window.set_resizable(False)
        self.window.set_transient_for(self.image)  # stay above screen image
        self.window.set_title("Colour Info")
        self.window.connect("delete_event", self.delete_event)
        self.window.add_events(gtk.gdk.KEY_PRESS_MASK)
        self.window.connect("key-press-event", self.event_keys)

        self.Colour = ScreenColour()
        vbox = gtk.VBox(True,2)
        for i in range(self.tablesize):
            self.label.append(gtk.Label("Unknown"))
            self.eb.append(gtk.EventBox())
            self.eb[i].add(self.label[i])
            vbox.add(self.eb[i])
        self.window.add(vbox)
        self.window.show_all()
        self.update_colours()

    def update_colours(self):
        rgb = self.Colour.pixelinfo()
        if self.oldrgb != rgb:
            self.oldrgb = rgb
            nearest = self.Colour.nearest_colours(self.tablesize, rgb)
            self.window.set_title("%02X %02X %02X" % rgb)
            for i in range(self.tablesize):
                try:
                    self.eb[i].modify_bg(gtk.STATE_NORMAL,
                                         gtk.gdk.color_parse(nearest[i]))
                    #
                    # if brighter than 128,128,128 switch to 
                    # a black background so text is visable
                    #
                    if (sum(self.syscolours[nearest[i]]) > 384):
                        w = '<span foreground="black">%s</span>' % nearest[i]
                    else:
                        w = '<span foreground="white">%s</span>' % nearest[i]
                    self.label[i].set_markup(w)
                except ValueError:
                    print 'unknown colour... ', nearest[i]

    def event_handler(self, widget, event=None):
        if event and event.type == gtk.gdk.MOTION_NOTIFY:
            self.update_colours()

    def event_keys(self, widget, event=None):
        if event:
            if event.keyval == gtk.gdk.keyval_from_name("Escape") \
               or event.keyval == gtk.gdk.keyval_from_name("q"):
                  self.window.destroy()
                  self.image.destroy()
                  gtk.main_quit()

if __name__ == "__main__":
    if len(argv) == 2 and (0<int(argv[1])<30):
        ColourInfoWindow(int(argv[1]))
    else:
        ColourInfoWindow(6)
    gtk.main()

October 10, 2007

Number reversing game

Filed under: python — rcjp @ 3:10 pm

Here is the reverse game where the object is to flip the initial numbers in a random sequence of 1..9 repeatedly until they are in order.

import random

numbers = random.sample(range(1,10), 9)
steps = 0

while numbers != sorted(numbers):
    print " ".join(map(str, numbers))
    nflip = int(raw_input("Flip how many? "))
    numbers[:nflip] = reversed(numbers[:nflip])
    steps += 1

print "Finished in %d steps." % steps

""" sample run...

In [6]: run finished/game.py
2 3 4 5 9 7 6 1 8
Flip how many? 4
5 4 3 2 9 7 6 1 8
Flip how many? 6
7 9 2 3 4 5 6 1 8
Flip how many? 8
1 6 5 4 3 2 9 7 8
Flip how many? 5
3 4 5 6 1 2 9 7 8
Flip how many? 7
9 2 1 6 5 4 3 7 8
Flip how many? 9
8 7 3 4 5 6 1 2 9
Flip how many? 8
2 1 6 5 4 3 7 8 9
Flip how many? 3
6 1 2 5 4 3 7 8 9
Flip how many? 6
3 4 5 2 1 6 7 8 9
Flip how many? 3
5 4 3 2 1 6 7 8 9
Flip how many? 5
Finished in 11 steps.
"""

October 6, 2007

Hash Tables

Filed under: c — rcjp @ 11:21 am

Just a quick note on how we used to use hash tables for the compiler code at Salford:

#include <stdio.h>
#include <stdlib.h>

/* point this at a debugging malloc if required */
#define newm_array(T,N) (T*)malloc(sizeof(T)*(N))
#define HASHSIZE    1024

struct symbol_list {
   symbol_list * next;
   int symbol ;
   char* name ;
   int size ;
};

symbol_list** base;

int main()
{
    ... we have some name we want to hash...

    base=newm_array(symbol_list*, HASHSIZE);

    /* clear hash table */
    i=0;
    while(i<HASHSIZE) {
        base[i]=NULL;
        i++;
    }

    int ih=0;
    char* p=name;
    while (*p) {       /* compute hash */
        ih=(ih<<1)+*p;
        p++;
    }
    ih=and(ih,HASHSIZE-1);
    symbol_list* x=base[ih];
    while (x != NULL) x=x->next; /* find empty chain */

    ... set x = name...
}

though might be better to make some functions

static unsigned hash(char *s)
{
    unsigned hashval;

    for (hashval = 0; *s != ''; s++)
        hashval = *s + 31*hashval;

    return hashval % HASHSIZE;
}

static entry *lookup(char *s)
{
    entry *np;

    for (np = hashtab[hash(s)]; np != null; np = np->next)
        if (wstrcmp(s, np->name) == 0)
            return np;
    return null;
}

October 1, 2007

Simple diff of 2 files

Filed under: c, lisp, python — rcjp @ 7:59 pm

A few days ago I wanted to compare to files each of which had one word per line (they were completion files for the rlwrap utility incidentally) thats easy enough with the unix shell commands, infact you can do it in one line

diff -iyw --suppress-common-lines <(sort -f file1) <(sort -f file2)

but I thought as a quick programming exercise I’d do it in C++/C, python and Common Lisp…

Calculating the difference is very easy using C++’s set_difference etc. but it is a surprise, I think for most programmers anyway, that you have to write your own case insensitive string comparison function. C++ sure is a peculiar mix of high and low level programming.

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <functional>

// 
// not sure there is any advantage to inherit from binary_function here?
// (infact we could just define a function rather than a struct and operator)
//
struct lessthan_nocase :
  public std::binary_function<const std::string&, const std::string&, bool>
{
    bool operator()(const std::string& s1, const std::string& s2) const
    {
        std::string::const_iterator p1 = s1.begin();
        std::string::const_iterator p2 = s2.begin();

        while(p1 != s1.end() && p2 != s2.end()) {
            if (toupper(*p1) != toupper(*p2)) return toupper(*p1) < toupper(*p2);
            ++p1;
            ++p2;
        }
        return s1.size() < s2.size();
    }
};

//
// set_difference only work on sorted containers
//
void sorted_readfile(const char* file, std::vector<std::string>& fvec)
{
    std::ifstream f(file);
    std::istream_iterator<std::string> finput(f), fend;

    copy(finput, fend, back_inserter(fvec));
    sort(fvec.begin(), fvec.end(), lessthan_nocase());
}

//
// dump results (show words if < MAXSHOW)
//
const unsigned int MAXSHOW = 10;

void display_diff(std::string title, std::vector<std::string> v)
{
    std::cout << title;
    if (v.size() < MAXSHOW) {
        std::cout << std::endl << std::string(title.size(), '-') << std::endl;
        copy(v.begin(), v.end(),
             std::ostream_iterator<std::string>(std::cout, "\n"));
    } else {
        std::cout << " =  " << v.size() << " words" << std::endl;
    }
    std::cout << std::endl;
}

int main(int argc, char* argv[])
{
    if (argc != 3) {
        std::cerr << "Usage: tdiff filename1 filename2" << std::endl;
        exit(1);
    }

    std::vector<std::string> f1;
    sorted_readfile(argv[1], f1);

    std::vector<std::string> f2;
    sorted_readfile(argv[2], f2);

    std::vector<std::string> notinf1;
    set_difference(f1.begin(), f1.end(), f2.begin(), f2.end(),
            back_inserter(notinf1), lessthan_nocase());
    display_diff("words in 1st but not in 2nd", notinf1);

    std::vector<std::string> notinf2;
    set_difference(f2.begin(), f2.end(), f1.begin(), f1.end(),
            back_inserter(notinf2), lessthan_nocase());
    display_diff("words in 2nd but not in 1st", notinf2);

    std::vector<std::string> symdiff;
    set_symmetric_difference(f2.begin(), f2.end(), f1.begin(), f1.end(),
            back_inserter(symdiff), lessthan_nocase());
    display_diff("symmetric difference", symdiff);

    std::vector<std::string> inter;
    set_intersection(f2.begin(), f2.end(), f1.begin(), f1.end(),
            back_inserter(inter), lessthan_nocase());
    display_diff("intersection", inter);

    return 0;
}

In C, the only thing to trip you up is getting the casting of the void * pointers in strcmp_nocase correct before trying to dereference them. Also I’ve cheated and used the non-ansi strcasecmp (sometimes called stricmp).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAXLINE  256
#define MAXWORDS 10000
#define MAXSHOW  10

typedef enum {false, true} bool;

bool strempty(char *str)
{
    char *p = str;
    while (*p) if (!isspace(*p++)) return false;
    return true;
}

int strcmp_nocase(const void *s1, const void *s2)
{
    /* The actual arguments to this function are "pointers to
       pointers to char", but strcmp() arguments are "pointers
       to char", hence the following cast plus dereference */
    return strcasecmp( *(char * const *)s1, * (char * const *) s2);
}

int sorted_readfile(char *filename, char **words)
{
    FILE *f = fopen(filename, "r");

    if (!f) {
        fprintf(stderr, "can't open %s\n", filename);
        exit(1);
    }

    int count = 0;
    char line[MAXLINE], *q;
    while (fgets(line, MAXLINE, f) && (count < MAXWORDS)) {
        if ((q=strpbrk(line,"\r\n"))) *q=0;     /* words dont include newlines */
        if (strempty(line)) continue;           /* skip blank lines */
        words[count] = (char *) malloc(strlen(line)+1);
        /* or words[count++] = strdup(line)*/
        strcpy(words[count], line);
        count++;
    }

    fclose(f);

    if (count == MAXWORDS) {
        fprintf(stderr, "increase MAXWORDS buffer size\n");
        exit(1);
    }
    qsort(words, count, sizeof(char *), strcmp_nocase);
    return count;
}

void display_diff(char *title, char **v, int vsize)
{
    int i;
    printf("%s", title);

    if (vsize < MAXSHOW) {
        printf("\n");
        for (i=0; i<strlen(title); i++) putchar('-');
        printf("\n");
        for (i=0; i<vsize; i++)
            printf("%s\n", v[i]);
    } else {
        printf(" = %d words\n", vsize);
    }
    printf("\n");
}

int main(int argc, char *argv[])
{
    if (argc != 3) {
        fprintf(stderr, "Usage: tdiff filename1 filename2\n");
        exit(1);
    }
    int i;
    char **f1words;
    f1words = malloc(MAXWORDS*sizeof(char*));
    int nf1words = sorted_readfile(argv[1], f1words);

    char **f2words;
    f2words = malloc(MAXWORDS*sizeof(char*));
    int nf2words = sorted_readfile(argv[2], f2words);

    char **diff;
    int ndiff = 0;
    diff = malloc(MAXWORDS*sizeof(char*));
    for (i=0; i < nf1words; i++) {
        if (!bsearch(&f1words[i], f2words, nf2words,
                     sizeof(char*), strcmp_nocase)) {
            /* could just point into f1words instead */
            diff[ndiff++] = strdup(f1words[i]);
        }
    }
    display_diff("words in 1st but not in 2nd", diff, ndiff);

    return 0;
}

In python, most of it is easy, though its perhaps not very pythonesque to cram some things on one line like I’ve done here. Making set case independent requires the __hash__ and __eq__ functions (I think that is all we need in this case) get overridden to use a saved lowercase version of the supplied string (see the python reference) .

import string

class NoCaseStr(str):
    def __init__(self, s):
        str.__init__(self, s)
        # keep a copy of the lower case string
        self.loweredstr = s.lower()

    def __eq__(self, s):
        return self.loweredstr == s.lower()

    def __hash__(self):
        return hash(self.loweredstr)

def display_diff(title, dset, Maxshow=10):
    if len(dset) < Maxshow:
        print title
        print len(title) * '-'
        print '\n'.join(dset)
    else:
        print title, '=', len(dset)
    print

def read_words(f):
    w = set(NoCaseStr(string.strip(word)) for word in open(f).readlines())
    w.discard('')# slightly clumsy... '  \n' gets stripped to '' so discard it
    return w

def tdiff(f1, f2):
    w1 = read_words(f1)
    w2 = read_words(f2)
    display_diff('in 1st but not in 2nd', w1.difference(w2))
    display_diff('in 2nd but not in 1st', w2.difference(w1))
    display_diff('symmetric difference',  w1.symmetric_difference(w2))
    display_diff('intersection',          w1.intersection(w2))

if __name__ == '__main__':
    import sys
    if len(sys.argv) < 3:
        print 'Usage: %s file1 file2' % sys.argv[0]
        sys.exit(1)

    tdiff(sys.argv[1], sys.argv[2])

My favourite language - Common Lisp has everything you need to do with without overriding anything. string-equal is case insensitive (as opposed to string=)

(defun read-words (file)
  (with-open-file (str file)
    (loop for line = (read-line str nil nil)
       for word = (string-trim " " line)
       while line
       unless (string= word "")
       collect word)))

(defun display-diff (title diff &optional (max-show 10))
  (format t "~A: ~V{~A~^ ~}~%" title max-show diff))

(defun tdiff (f1 f2)
  (let ((w1 (read-words f1))
        (w2 (read-words f2)))
    (display-diff "in 1st but not in 2nd" (set-difference w1 w2 :test #'string-equal))
    (display-diff "in 2nd but not in 1st" (set-difference w2 w1 :test #'string-equal))
    (display-diff "intersection" (intersection w1 w2 :test #'string-equal))))

(tdiff "/home/r/tmp/f1" "/home/r/tmp/f2")

September 20, 2007

Posting Code

Filed under: utils — rcjp @ 5:42 pm

After spending several frustrating sessions trying to find a solution to posting sourcecode on this blog I think I’ve got something workable.

Most of the methods I tried, including the one in the WordPress FAQ, fail on some operator characters found in lisp or C++ (like e.g.<<) and although I don’t use vim much these days, tending to prefer nvi, it does have a handy htmlize function :TOhtml. This, with some tweaking, generates html acceptable to WordPress from a buffer of code (or some lines marked in Visual Mode).

I used some vim scripting given below to strip out the <pre> section from the generated html, wrap <code> just inside it and copy it to the clipboard ready for pasting into the browser. I have it bound to the keystroke Alt-l. One further complication was that WordPress, trying to be helpful, swaps out some characters even though they are in a <code> block, so I do a search/replace for apostrophes.


func Convert2HTMLClip(line1, line2)
    if a:line2 >= a:line1
        let g:html_start_line = a:line1
        let g:html_end_line = a:line2
    else
        let g:html_start_line = a:line2
        let g:html_end_line = a:line1
    endif
    runtime syntax/2html.vim
    unlet g:html_start_line
    unlet g:html_end_line
    normal! gg
    exe ":0,/<pre>/- d"
    normal! A<code>
    normal! G
    exe ":?</pre>?+,$ d"
    normal! I</code>
    exe ":%s/'/\\&#39;/eg"
    exe ":%s/&amp;#39;/\\&amp;\\&#35;39;/eg"
    exe ":%s/&amp;#35;/\\&amp;\\&#35;35;/eg"
    normal! ggVG"+y
    exe ":bd!"
endfunc
command -range=% TohtmlClip :call Convert2HTMLClip(<line1>, <line2>)
map <M-l> :TohtmlClip<CR>

September 12, 2007

Inspirational

Filed under: physics — rcjp @ 4:09 pm


Buzz Aldrin, originally uploaded by rcjp.

Everytime I look at this image, I have to stare at it for several minutes in sheer astonishment. Kudos to NASA for making these images available. (for other sizes see here)

September 10, 2007

Blogging

Filed under: utils — rcjp @ 6:13 pm

I’ve been trying to decide between blogging from blogger.com or wordpress.com; here are a few of the features that swung the decision:

  • bigger blogging window: I don’t like typing through a letterbox and thankfully wordpress has Options->Writing->’Size of the post box’; couldn’t see anything similar in blogger though
  • private entries: amazingly blogger only lets you mark the whole blog as private, not individual entries like wordpress does
  • wordpress’s built in latex: its great to be able to type
    $latex \partial_{x}\alpha&s=2$

    and get \partial_{x}\alpha (the s=2 increases the size) see the faq entry

There were problems with wordpress though: I had to disable the wysiwyg editing of entries Users->Your Profile->’Use the visual rich editor when writing’ (at the top of the page) because switching between it and the code view kept messing things up; I prefer the code view anyway tbh.

The editor is a bit sluggish sometimes, pausing for something, but at least there are a few handy shorcuts - mark some text then press the keys:

Characters Code Lists
Bold: Alt+Shift+B Blockquote: Alt+Shift+Q Unordered List (ul): Alt+Shift+U
Italics: Alt+Shift+I Code: Alt+Shift+C Ordered List (ol): Alt+Shift +O
Link: Alt+Shift+A Read More: Alt+Shift+T List Item (li): Alt+Shift+L
Keyboard Shortcuts

Hopefully I’ll get around to coding something that’ll allow you to write in reStructuredText from within emacs and upload using the meta weblog api converting to html. All that is pretty easy I think, I’ve done parts of that process for my old blog; the hard part would be doing the reverse to allow you to edit existing posts parsed back to rst.

June 8, 2007

gtk containers

Filed under: c — rcjp @ 7:05 pm

The gtk glib library includes some standard container like linked lists…


/* Compile with cc doubly.c  `pkg-config --cflags --libs gtk+-2.0`  */

#include <glib.h>
#include <string.h>
#include <stdio.h>

void myfunc(gpointer data, gpointer user_data)
{
    printf("value %s\n", (char *)data);
}

int main()
{
    GList *list = NULL;
    GList *it = NULL;

    list = g_list_append(list, "one");
    list = g_list_append(list, "two");
    list = g_list_append(list, "three");

    for (it = list; it != NULL; it = it->next)
        printf("looping - %s\n", (char *)it->data);

    /* or alternatively  */

    g_list_foreach(list, (GFunc) myfunc, NULL);

    printf("length of list is %d\n", g_list_length(list ));
    return 0;
}

May 10, 2007

Sign Extending Unsigned Numbers

Filed under: c — rcjp @ 2:26 pm

Just playing about really, but I thought it would be worth re-affirming in my brain that you have to be careful using assembler instructions like CLW, CLQ etc. when dealing with unsigned numbers since they propagate the sign bit.:

    #include <stdio.h>
    void extend(unsigned char x)
    {
        int y;
        asm ("xor %%eax, %%eax;\n\t"      /* clear EAX */
             "movb %1, %%al;\n\t"         /* move the byte x into AL */
             "cbw;\n\t"
             "movl %%eax, %0;\n\t"
             :"=r"(y)                     /* output only */
             :"r"(x)                      /* input */
             :"%eax");                    /* clobbered regs */

        printf("x=%d, cbw extended=%d\n", x, y);
    }

    int main(void)
    {
        extend(127);
        extend(128);

        return 0;
    }

gives

    ~/c/tmp> ./a.out
    x=127, cbw extended=127
    x=128, cbw extended=65408

there is no binary flag for printf in C, but in Common Lisp:

    CL-USER> (format t "~20B~%" 128)
                10000000
    NIL
    CL-USER> (format t "~20B~%" 65408)
        1111111110000000
    NIL

Instead of doing it in inline C, I thought I’d try nasm + gcc

            extern  printf

            SECTION .data
    fmt:    db "cbw %d (previously %d)", 10, 0 

            SECTION .text
            global main        ; needed for gcc 
    main:
            push    ebp
            mov     ebp,esp

            xor     eax,eax
            mov     ax, 128
            push    eax
            cbw
            push    eax
            push    dword fmt
            call    printf

            add     esp, 12    ; pop 3 pushes
            mov     esp, ebp   ; clean stack frame
            pop     ebp
            mov     eax,0      ; no error return
            ret

building and running with

    ~/c/tmp> nasm -f elf nasm2.asm
    ~/c/tmp> gcc -o nasm2 nasm2.o
    ~/c/tmp> nasm2
    cbw 65408 (previously 128)

April 27, 2007

Finding open oflag Settings

Filed under: c, python — rcjp @ 11:03 am

In tracings you see the numerical value for flags like the oflag settings to the C open commands e.g.

    5901 open("/proc/asound/cards", 32768, 0666) = 7

to find out what they mean I just quickly did:

    In [36]: def oflag_to_string(oflag):
       ....:     for c in dir(os):
       ....:         if c.startswith('O_'):
       ....:             if eval('os.'+c) & oflag:
       ....:                 print c
       ....:
       ....:

    In [37]: oflag_to_string(32768)
    O_LARGEFILE

but afterwards realised I could have just done an strace since that nicely converts the values for you.

Producing Slides with Beamer

Filed under: utils — Tags: — rcjp @ 10:29 am

Next time I need to do some slides, I’m definitely going to use the latex beamer package. It seems really easy to use

    \documentclass{beamer}
    \usepackage[latin1]{inputenc}
    \usepackage{amssymb,amsmath}  % use mathematical symbols
    \usepackage{ccfonts, eulervm} % concrete fonts but with nicer upright maths
    \usetheme{Warsaw}

    \title{Title of my talk}
    \author{me}\institute{work}

    \begin{document}
    \begin{frame}
    \titlepage
    \end{frame}

    \begin{frame}
    I am the text located on the first content slide
    \begin{equation}
    x+y_2={1\over 2\pi}\int^\alpha_\infty \tan^2\beta = \Gamma\quad eqn1
    \end{equation}
    \end{frame}

    \begin{frame}
    And I am the text located in the second content slide
    \end{frame}
    \end{document}

I need to play with this some more. Some nice notes here

April 17, 2007

reStructured Text

Filed under: python, utils — rcjp @ 4:20 pm

rst is a very easy to use ascii markup language. With some python script or the rst2html tool you can quickly generate html. For example, the following html (between the horizontal lines) was generated by the program below and uses the python docutils module on the ascii testtext python variable (but would normally be a file read in from somewhere):


The Title

My first sentence and some more.

  • bullet one
  • two
    • sublists, just like bullet lists must be separated by blank lines
    • second sublist
  • three

and more paragraph text.


Referees: A.N. Other
Boo Boo

Some literal indented code:

program(1)
for i = 1, 10
    nothing
done

And some more text



Header 1 Header 2 Header 3
body row 1 column 2 column 3
body row 2 Cells may span columns.
body row 3 Cells may
span rows.
  • Cells
  • contain
  • blocks.
body row 4

Run with:

rst2html ttt2 > k.html

For more details look at docutils quickref. and also check the latest
developments validator and latex


and the python code…
#
# some example rst text manipulated with python below...
#
testtext="""
The Title
=========

My first sentence and some more.

- bullet one
- two 

  - sublists, just like bullet lists must be separated by blank lines
  - second sublist

- three

and more paragraph text.

:Referees:
    A.N. Other
    Boo Boo

Some literal indented code::

    program(1)
    for i = 1, 10
        nothing
    done

And some more text

+------------+------------+-----------+
| Header 1   | Header 2   | Header 3  |
+============+============+===========+
| body row 1 | column 2   | column 3  |
+------------+------------+-----------+
| body row 2 | Cells may span columns.|
+------------+------------+-----------+
| body row 3 | Cells may  | - Cells   |
+------------+ span rows. | - contain |
| body row 4 |            | - blocks. |
+------------+------------+-----------+

Run with::

    rst2html ttt2 > k.html

For more details look at docutils_ quickref. and also check the latest
developments validator_ and latex_

.. _Python: http://www.python.org/
.. _docutils: http://docutils.sourceforge.net/docs/user/rst/quickref.html#bullet-lists
.. _validator: http://docutils.sourceforge.net/sandbox/dugui/
.. _latex: http://docutils.sourceforge.net/sandbox/latex_directive/
"""

from docutils.core import publish_string, publish_parts
#
# quickly dump out the html using my own stylesheet
#
output = open("test-rst.html", 'w')
customcss = {'embed_stylesheet':False, 'stylesheet_path':'include/mystyle.css'}
output.write(publish_string(testtext, writer_name = 'html',
                            settings_overrides=customcss))
output.close()
#
# just dump the body part, no stylesheet at all
#
output = open("test-rst-body.html", 'w')
parts = publish_parts(testtext, writer_name = 'html',
                      settings_overrides=dict(embed_stylesheet=False,
                                              stylesheet_path=None,))
output.write(parts['html_body'])
output.close()


Pulling out the body text is handy for generating html that you are inserting inside another document, like this blog entry for example.

April 12, 2007

Circular Halo

Filed under: physics — rcjp @ 12:53 pm

circular-halo1

I hardly noticed this without my Polaroid sunglasses on, as the colours were quite faint (and I’m fairly colour-blind), but the camera seemed to pick it out reasonably well; though its not as impressive as this one.

I tried to estimate the angular measurement of the halo and got my measurements wrong by quite a bit. From the sun to the start of the arc was the distance from my thumb to little finger tips with my hand held spread out at arms length. That’s 2 feet away from my eye and 8 inches across (I’ve measure that before and its easy to remember - all nice round numbers; no metric system centimeters here for estimating thank you - those units are too small.) This gives the halo an angular radius of about… (using a handy Common Lisp prompt)


    CL-USER> (* (/ 180 pi) (atan 8/24))
    18.434948654789338d0

that’s nowhere near the 22 degrees its supposed to be. But of course, holding your arm up at an angle reduces the distance between your eye and your hand that I’d measured before with my arm out horizontally. Re-measuring at around 45 degrees the hand-eye distance is down to 20″ and directly overhead 16″:


    CL-USER> (* (/ 180 pi) (atan 8/20))
    21.801408877810637d0

much better, phew.

April 5, 2007

Patterns

Filed under: physics, python — rcjp @ 3:56 pm

I think I got the matrix formula for this pattern from “Introduction to Dynamics” by Percival and Richards (its certainly the pattern I remember from the book cover)

Pattern

You can get different patterns if you move the slider. Python gtk code…

import pygtk
pygtk.require('2.0')
import gtk, math

class Pattern(object):
    x, y = 0, 0
    points=[]
    alpha = 76.11
    def __init__(self, xsize, ysize):
        self.xsize, self.ysize = xsize, ysize
        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        window.set_title("Pattern")
        window.connect("destroy", lambda w: gtk.main_quit())
        vbox = gtk.VBox(homogeneous=False, spacing=5)
        window.add(vbox)
        self.area = gtk.DrawingArea()
        self.area.set_size_request(xsize, ysize)
        self.area.connect("expose-event", self.area_expose_cb)
        self.area.connect("size-allocate", self.calculate_points)

        slider = gtk.Adjustment(value=self.alpha, lower=0.0,
                                upper=100.0, step_incr=0.01)
        slider.connect("value-changed", self.slider_changed)
        self.hscale = gtk.HScale(slider)
        vbox.pack_start(self.area, expand=True, fill=True, padding=0)
        vbox.pack_start(self.hscale, expand=False)
        window.show_all()

    def slider_changed(self, slider):
        self.alpha = slider.get_value()
        self.calculate_points()

    def calculate_points(self, area=None, event=None):
        x, y, self.xsize, self.ysize = self.area.get_allocation()
        xscale = self.xsize/2.0
        yscale = self.ysize/2.0
        m = 52
        angle = self.alpha*math.pi/180.0
        c = math.cos(angle)
        s = math.sin(angle)
        self.points=[]
        try:
            for j in range(m):
                x = 0
                y = j/float(m)
                for n in range(200):
                    w = x
                    x = x*c - (y - x*x)*s
                    y = w*s + (y - w*w)*c
                    if abs(x)>4 or abs(y)>4: raise StopIteration()
                    if x>1 or y>1: continue
                    self.points.append((int(x*xscale+xscale), int(y*yscale+yscale)))
        except StopIteration:
            self.area.queue_draw()

    def area_expose_cb(self, area, event):
        blue = self.area.get_colormap().alloc_color("#0000FF")
        pointgc = self.area.window.new_gc()
        pointgc.set_foreground(blue)
        area.window.draw_point(pointgc, 20, 10)
        self.area.window.draw_points(pointgc, self.points)

def main():
    gtk.main()
    return 0

if __name__ == '__main__':
    Pattern(600, 500)
    main()

March 30, 2007

Old Blog Code

Filed under: python — rcjp @ 1:10 pm

just incase there is some useful code in it, this is what I used to use to generate my old blog before I gave up and moved to wordpress. I had a nested directory of text files that contained keywords that this python expanded into html tags. It even used to spawn off gimp to generate heading images.

import os, sys, re
global bloghome
bloghome = 'http://www.codephrenic.co.uk/blog/'   # where the blog is destined for (see below)
blogbase = '/home/r/blog'                         # where the files get generated to

# html tag translations
# e.g. link["www.physics.org", "the physics website"]
#      bigpic[{'src':'/mypic.jpg', 'title':'blah', 'width':100, 'height':100}]
tags = {
    'title'     : '<div class="header"><h2>%s</h2></div>',
    'entry'     : '<div class="entry">%s</div>',
    'date'      : '<div class="date">%s</div>',
    'list'      : '<ul>%s</ul>',
    'item'      : '<li>%s</li>',
    'link'      : '<a href="%s">%s</a>',
    'pic'       : '<img src="%s" alt="%s" width="50" height="50"/>',
    'picright'  : '<img class="floatright" src="%s" width="50" height="50"/>',
    'bigpic'    : '<img src="%(src)s" alt="%(title)s" width="%(width)d" height="%(height)d"/>',
    'italic'    : '<i>%s</i>',
    'tt'        : '<tt>%s</tt>',
    'bold'      : '<b>%s</b>'
    }

blogheader = """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
    <head>
        <title>rcjp blog</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <link rel="stylesheet" type="text/css" href="blog.css" />
        <link rel="stylesheet" type="text/css" href="titles.css" />
    </head>
    <body><div id="blogpage">
"""

blogfooter = '</div></body></html>'

def make_heading_image(title, category):
    print 'processing image %s' % category
    # change any  ' -> '\''
    cmd = """gimp --batch-interpreter plug_in_script_fu_eval -i -b '(blogheading "%s" 100 "Trebuchet MS" "%s")' -b '(gimp-quit 0)'""" % (title.replace("'", "'\\''"), blogbase+"/images/"+category+".png")
#     f = os.popen("%s" % cmd, 'w')
    f = os.popen(cmd, 'w')
    f.flush()
    f.close()

def func_expand(match):
    fname, body = match.group(1,2)
    try:
        if body.startswith('"') or body.startswith('{'):
            return tags[fname] % (eval(body))
        else:
            return tags[fname] % (body)
    except(TypeError), val:
        sys.exit('***ERROR: Tag "%s" has been supplied wrong arguments "%s"' % (fname, body))
    except(KeyError), val:
        sys.exit('***ERROR: Unknown tag "%s"' % fname)

def expand_string(str):
    # look for any functions of the form  func[...]
    # embedded that we should expand into html tags
    func = re.compile(r'(\w+)\s*?\[([^\[]*?)\]')
    found = 1
    while found > 0:
        (str, found) = func.subn(func_expand, str)
    return str

def escape_string(text):
    # change > to &gt; etc.
    # and deal with code[], it needs separate treatment because
    # the regexp approach in expand_string will find [] inside
    # code segments and try to expand it 
    searchstr = 'code['
    pos = text.find(searchstr)
    newtext = ''
    while pos >= 0:
        bcount = 1             # count the number of [ we have to skip
        newtext = text[:pos]+'<code>'
        pos += len(searchstr)
        while pos < len(text):  # find matching ] bracket
            if text[pos] == '[':
                bcount += 1
                newtext += '['
            elif text[pos] == ']':
                bcount -= 1
                if bcount == 0:
                    newtext += '</code>' + text[pos+1:]
                    break
                newtext += ']'
            elif text[pos] == '<':
                newtext += '&lt;'
            elif text[pos] == '>':
                newtext += '&gt;'
            elif text[pos] == '&':
                newtext += '&&;'
            else:
                newtext += text[pos]
            pos += 1
        if pos == len(text):
            sys.exit('Could not find matching bracket')
        text = newtext
        pos = text.find(searchstr)
    return text

def paragraphs(lines, is_separator=str.isspace, joiner=''.join):
    paragraph = []
    for line in lines:
        if is_separator(line):
            if paragraph:
                yield joiner(paragraph)
                paragraph = []
        else:
            paragraph.append(line)
    if paragraph:
        yield joiner(paragraph)

def process_entry(filename):
    print 'processing ', filename
    blogfile = open(filename, 'r')
    dir, name = os.path.split(filename)

    iday = int(name[6:8])    # turn 08 into 8 etc
    day = str(iday)
    if 4 <= iday <= 20 or 24 <= iday <= 30: # get the day suffix
        day+='th'
    else:
        day+= ['st', 'nd', 'rd'][iday % 10 - 1]

    months = {'01':'January', '02':'February', '03':'March', '04':'April', '05':'May', '06':'June',
              '07':'July', '08':'August', '09':'September', '10