Refresh Firefox page from Emacs

March 16, 2009

I often need to refresh page in Firefox when I edit page template or javascript file. This is especially true when working on grok-awesome.

Though I use tiling window manager StumpWM and it’s very easy to switch to running Firefox with keyboard shortcut and make refresh, it’s even easier not to leave focus from Emacs window and just send command to Firefox to refresh itself.
For that I use:

  • MozRepl firefox plugin to allow connect to Firefox’s REPL. After installation in Tools -> MozRepl menu I chose ‘Activate on startup’ for convenience
  • MozRepl Emacs integration (If you use nXhtml package in Emacs you already have that integration and can skip this part)

Command to refresh Firefox is BrowserReload();

Final touch is small anonymous function to send that command to mozrepl, keybinding to C-x p and we’re all set:

(global-set-key (kbd "C-x p")
                (lambda ()
                  (interactive)
                  (comint-send-string (inferior-moz-process)
                                      "BrowserReload();")))

Now anytime just press C-x p and refresh command will be sent to Firefox starting along the way mozrepl session in your Emacs if it’s not been already started.


Grok Awesome

March 12, 2009

I’ve started developing blog software for “A Smashing Web Framework” Grok.

The reasons behind that:

  • There is no full-featured blog software for Grok. There is a simple version Grokstar, but as for me it doesn’t fit the bill.
  • I created simple blog for Zope3 several years ago and let it languish. Now it’s time to revive it taking into account how Grok simplifies development with Zope3 technologies.
  • I’m not completely happy with WordPress. For one thing, I’d like to have easy-to-use REST API so I can use it in my Emacs to make posts.
  • I simply love Grok. You should try it and you’ll love it too.

My fledgling project lives on GitHub and it’s called grok-awesome :)


Emacs dark theme + IPython colors

March 9, 2009

Ever wondered how to make IPython colors be nice on dark background of your dark (no pun intended) Emacs theme like blackboard ?

Just add to your .emacs

(setq py-python-command-args '("-pylab" "-colors" "Linux"))

before you load ipython package

(setq py-python-command-args '("-pylab" "-colors" "Linux"))
(require 'ipython)

Now IPython uses ‘Linux’ color scheme which is suitable for dark background with light fonts instead of default ‘LightBG’.

Here it is:

Python 2.5.2 (r252:60911, Sep 30 2008, 15:41:38)
Type "copyright", "credits" or "license" for more information.

IPython 0.9.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object'. ?object also works, ?? prints more.

  Welcome to pylab, a matplotlib-based Python environment.
  For more information, type 'help(pylab)'.

In [1]: d = dict()

In [2]: ?d
Type:           dict
Base Class:     <type 'dict'>
String Form:    {}
Namespace:      Interactive
Length:         0
Docstring:
    dict() -> new empty dictionary.
    dict(mapping) -> new dictionary initialized from a mapping object's
        (key, value) pairs.
    dict(seq) -> new dictionary initialized as if via:
        d = {}
        for k, v in seq:
            d[k] = v
    dict(**kwargs) -> new dictionary initialized with the name=value pairs
        in the keyword argument list.  For example:  dict(one=1, two=2)

In [3]: 

“Release It!” is just what the doctor ordered

March 2, 2009

I’ve just finished reading excellent book Release It!: Design and Deploy Production-Ready Software

If you are involved or plan to be involved in developing any system that must be available 24 x 7 x 365 then you owe it to yourself to read this book.

The key ideas you should understand are:

  • system will fail
  • life of software only begins when you release it into production

With that in mind the book is a treasure trove of useful advices how to make your system scale and succeed in production.

The book resonates with my own personal experience in developing and maintaining critical Python application and many things that Michael Nygard describes I learned the hard way: blocked threads, socket timeouts, integration point failures and latency, asynchronous handling, caching, database growth and of course “cold shivers” you get when the system goes down.

While book is sprinkled with notes about Java related issues it’s nevertheless technology agnostic which makes it a valuable source of information for every developer.

It gets two thumbs up from me.


Autovivication and Y Combinator in Python

April 14, 2008

Sometimes you may need to have nested dictionaries initialized without much hassle.

“Autovivication” comes in handy. What you want to achieve is:

>>> d = dict()
>>> d['q']['w']['r'] = 777

Of course what you’ll get will be:

>>> d['q']['w']['r'] = 777
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'q'

If you don’t need deeply nested dictionaries defaultdict with dict default factory will do the job:

>>> from collections import defaultdict
>>> d = defaultdict(dict)
>>> d
defaultdict(<type 'dict'>, {})
>>> d['a']['b'] = 33
>>> d
defaultdict(<type 'dict'>, {'a': {'b': 33}})
>>> d['a']['b']
33

Here are another ways to have unlimited level of nested dictionaries.
1) Define custom class inheriting from built-in dict:

class default_dict(dict):
    def __missing__(self, key):
        self[key] = value = self.__class__()
        return value
>>> d = default_dict()
>>> d
{}
>>> d['q']['w']['r'] = 777
>>> d
{'q': {'w': {'r': 777}}}
>>> d['q']['w']['r']
777

2) Recursive function + defaultdict:

def make_dict():
    return defaultdict(make_dict)
>>> from collections import defaultdict
>>> d = defaultdict(make_dict)
>>> d
defaultdict(<function make_dict at 0xb7c5295c>, {})
>>> d['q']['w']['r'] = 777
>>> d
defaultdict(<function make_dict at 0xb7c5295c>, {'q': defaultdict(<function make_dict at 0xb7c5295c>, {'w': defaultdict(<function make_dict at 0xb7c5295c>, {'r': 777})})})
>>> d['q']['w']['r']
777

3) And for fun you can use Y Combinator (in short – making anonymous lambda recursive) which is actually as (2) but you don’t have to have recursive function defined:

def Y(g):
    return ((lambda f: f(f))
            (lambda f:
                 g(lambda x: f(f)
                   (x))))

defdict = Y(lambda mk_dict:
                lambda x=None: defaultdict(lambda x=None: mk_dict(x)))
>>> d = defdict()
>>> d
defaultdict(<function <lambda> at 0xb7c52a74>, {})
>>> d['q']['w']['r'] = 777
>>> d
defaultdict(<function <lambda> at 0xb7c52a74>, {'q': defaultdict(<function <lambda> at 0xb7c56c6c>, {'w': defaultdict(<function <lambda> at 0xb7c56a74>, {'r': 777})})})
>>> d['q']['w']['r']
777

Array module in Erlang

April 13, 2008

Recent Erlang releases (since R12B) have array module included.

Now binary search algorithm can be implemented quite efficiently with functional arrays:

-module(bsa).
-export([binsearch/2]).

binsearch(Arr, Key) ->
    binsearch(Arr, Key, 0, array:size(Arr)).

binsearch(Arr, Key, LowerBound, UpperBound) ->
    Mid = (LowerBound + UpperBound) div 2,
    Item = array:get(Mid, Arr),
    if
        UpperBound < LowerBound -> -1;
        Key < Item ->
            binsearch(Arr, Key, LowerBound, Mid-1);
        Key > Item ->
            binsearch(Arr, Key, Mid+1, UpperBound);
        true ->
            Mid
    end.

Running time for lists based binary search (just for comparison):

56> {Time, Val} = timer:tc(search, binsearch,
56>                        [lists:seq(1, 1000000), 1000000]).
{506513,  1000000}

Running time for array based binary search:

57> f().
ok
58> {Time, Val} = timer:tc(bsa, binsearch,
58>               [array:from_list(lists:seq(1, 1000000)), 1000000]).
{17,  999999}

Erlang for Python programmers: Part V

November 16, 2007

Previous parts: Intro, Part I, Part II, Part III and Part IV

List comprehensions.

List comprehensions is very familiar topic for Python programmer. It’s a syntactic sugar which provides a succinct notation for producing elements in list.

Erlang:

[Expr || Qualifier1,...,QualifierN]

Expr – is an arbitrary expression
Qualifier is either a generator or a filter.
A generator is of form Pattern <- ListExpr where ListExpr evaluates to a list of terms.
A filter expression should evaluate to true or false.

1> [X || X <- [1,2,3,4,5,6], X > 3].
[4,5,6]

This is read as: list of X such that X is taken from list [1,2,3,4,5,6] and X is greater than 3.

In foregoing example: X <- [1,2,3,4,5,6] is a generator and X > 3 is a filter.

Several filters can be combined:

2> [X || X <- [1,a,2,3,b,4,5,6], X > 3].
[a,b,4,5,6]
3> [X || X <- [1,a,2,3,b,4,5,6], integer(X), X > 3].
[4,5,6]

Generator part may act as a filter in list comprehension:

4> [X || {X, a} <- [{1, a}, {2, b}, {3, a}, erlang]].
[1,3]

Generators can be combined too in list comprehensions. This is the Cartesian product of two lists:

5> [{X, Y} || X <- [1, 2, 3], Y <- [a, b]].
[{1,a},{1,b},{2,a},{2,b},{3,a},{3,b}]

This is how elegantly quicksort algorithm is solved with the help of list comprehensions in Erlang:

-module(sort).
-export([qsort/1]).

qsort([]) -> [];
qsort([Pivot|Tail]) ->
    qsort([X || X <- Tail, X < Pivot])
        ++ [Pivot] ++
        qsort([X || X <- Tail, X >= Pivot]).

Compile and run:

6> c("/home/alienoid/dev/erlang/sort", [{outdir, "/home/alienoid/dev/erlang/"}]).
{ok,sort}
7> sort:qsort([7, 5, 9, 3, 6]).
[3,5,6,7,9]

Usage of list comprehensions instead of some higher-order functions:

8> lists:map(fun(X) -> X*2 end, [1, 2, 3]).
[2,4,6]
9> [X*2 || X <- [1, 2, 3]].
[2,4,6]
10> lists:filter(fun(X) -> X rem 2 == 0 end, [1, 2, 3, 4]).
[2,4]
11> [X || X <- [1, 2, 3, 4], X rem 2 == 0].
[2,4]

Python:

[expression for expr1 in seq1 if cond1
            for expr2 in seq2 if cond2
            for exprN in seqN if condN]

this actually transforms to:

for expr1 in seq1:
    if not cond1:
        continue
    for expr2 in seq2:
        if not cond2:
            continue
        for exprN in seqN:
            if not condN:
                continue

So in Python Cartesian product of two lists [1, 2, 3 ] and ['a', 'b'] will look like:

>>> [(x, y) for x in [1, 2, 3] for y in ['a', 'b']]
[(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b'), (3, 'a'), (3, 'b')]

Variable bindings and scope rules in List Comprehensions:

Current Python 2.x “leaks” loop variable into surrounding scope. This should be solved in Python 3.0

>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> vlist = [x for x in 'abc']
>>> vlist
['a', 'b', 'c']
>>> x
'c'

To avoid leaking loop variable into surrounding scope we can use generator expression which doesn’t “leak”:

>>> vlist = list(x for x in 'abc')
>>> vlist
['a', 'b', 'c']
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined

Erlang has following scope rules for variables in list comprehensions(from Erlang manual):

  • all variables which occur in a generator pattern are assumed to be “fresh” variables
  • any variables which are defined before the list comprehension and which are used in filters have the values they had before the list comprehension
  • no variables may be exported from a list comprehension

So, Erlang doesn’t “leak” variables:

1> [X || X <- [1, 2, 3]].
[1,2,3]
2> X.
** 1: variable 'X' is unbound **

Be careful, sometimes you need to move some pattern matching operations into filter:

-module(listcomp).
-export([select/2]).

%% This select produces following warning during compilation:
%% Warning: variable 'X' shadowed in generate
select(X, List) ->
    [Y || {X, Y} <- List].

The function doesn’t produce desired result:

1> listcomp:select(b, [{b, 1}, {c, 2}, {b, 3}]).
[1,2,3]

So we modify generator and move pattern matching operation into filter to achieve what we need:

-module(listcomp).
-export([select/2]).

%% Moving X from pattern matching into filter
select(X, List) ->
    [Y || {X1, Y} <- List, X == X1].
2> listcomp:select(b, [{b, 1}, {c, 2}, {b, 3}]).
[1,3]

As you saw, while different in syntax, both languages provide valuable language construct which allows to write shorter and more elegant programs.


Delete blank lines with flush-lines

October 22, 2007

Sometimes after I copy-paste code snippets from web page into emacs buffer I get text with superfluous blank lines delimiting code.

Marking region and running M-x flush-lines RET ^$ RET quickly makes it better by removing those pesky blank lines. This is, of course, makes sense only if pasted code doesn’t contain blank lines you want to preserve.

Update:
You may need to use something more complex than simple ^$ (something like ^\W*$ as regexp) if “blank” line contains some whitespace characters.

Example before:

-export([test1/0,

         test2/0,

         test3/0,

         double/1]).

After marking region and applying M-x flush-lines RET ^\W*$ RET (in your case just ^$ may be sufficient):

-export([test1/0,
         test2/0,
         test3/0,
         double/1]).

Incremental search forward

October 5, 2007

Well-known incremental search forward(isearch-forward Lisp function) which is invoked with C-s has also additional useful key-bindings which I use often to instruct what to search. After you pressed C-s in buffer they are:

  1. C-w to yank next word or character in buffer onto the end of the search string, and search for it. You can repeatedly press C-w consuming next word or character.
  2. C-y to yank rest of line onto end of search string and search for it.
  3. M-n/M-p to search for the next/previous item in the search ring.

As usual for more information read help (C-h k C-s or C-h f isearch-forward RET ).


align-regexp

October 3, 2007

This interactive Emacs Lisp function was very handy for me during some log files analysis.

You mark region, invoke function, provide regexp and voila – your region is aligned.

Example data from align-regexp help:

Fred (123) 456-7890
Alice (123) 456-7890
Mary-Anne (123) 456-7890
Joe (123) 456-7890

Let’s say we want to align region on “(” character. For that we mark region we want to align and invoke function with: M-x align-regexp RET ( RET
Result of such invocation will be:

Fred      (123) 456-7890
Alice     (123) 456-7890
Mary-Anne (123) 456-7890
Joe       (123) 456-7890