想換 blog…

WordPress 預設的這些版面說有多不配程式就有多不配,不付錢的話能客製程度又低(事實上我覺得非常爛,很後悔幹嘛用),但能直接上傳圖片什麼的還是有其方便處。這陣子一直在想要不要整個換 Octopress 然後放 github,不但簡單清爽而且能用版本管理系統來寫 blog 實在是很讚的一件事情。另一件麻煩事是雖然大家很推崇用 markdown 來寫,但我最常用的其實是 org-mode,從 org-mode 是可以輸出 markdown 沒錯啦,但繞那麼遠是要幹嘛… markdown 跟 org-mode 還差蠻多的,寫習慣 org-mode 以後換到 markdown 都還要去查語法,例如連結 org-mode 就是 [[link][description]] 然後 markdown 就是 [description](link) 或是 [description][footnote id] ,這種小地方真的蠻討厭的。然後譬如強調字體 org-mode 是 *bold*, /italic/, _underlined_, `=code=’ and `~verbatim~’ 這部份 markdown 就完全不一樣。

這陣子想簡化一切事情,譬如 blog 也該算是個人知識管理的一部分,不能快速搜尋翻找就不太對,而且最好是這類東西都有個共通界面去紀錄,Evernote 就是蠻好的想法,配上 postach.io 當 blog 就不錯,但真的不適合我。之前稍微嘗試過,但我的記事情方法是森林狀的,然後他整個散落各處,用筆記本跟 tag 去分反而找不到而且覺得超討厭。猜想這個跟另一種思維方式的人會很配,也說明為何他這麼紅吧。Anyway, 以前不會很在意在這類東西之間換來換去,但現在越來越覺得用熟悉的工具去盡量節省時間是很重要的。(這又牽涉到一些研發上的思考,一直以來常在換技術換語言之類的,專注某領域然後深耕是不是也很重要,然後這領域究竟該是像 web programming 這種很具象的領域還是說應該是某種抽象的「平行處理」之類的領域呢?似乎該是後者,但問題是我沒有後者,這就尷尬了…)

言歸正傳。所以說,為了簡化,反而現在會花很多時間想辦法去做「簡化」這件事(很弔詭吧),例如之前 org-mode 都隨便亂用,一直到最近因為要唸線代,一堆數學符號不知道怎麼作筆記很不爽(事實上之前重學機率的時候就碰到這問題,但就放著不管),貪快用紙筆的話鐵定沒過多久就不知道扔去哪了,於是就立下決心去看一下 LaTex 到底公式怎麼打,一學之下發現意外的簡單,而且直接 emacs 裡面熱鍵切換就可以看到結果,超方便的啊,到底以前幹嘛不學,學一下不就可以省事很多嗎(懊悔)。但這些就真的很奇怪,這些工具拖著想說先不要學,結果有一天就是會碰到然後還是得學。什麼都學的結果就是會一堆東西,但都是工具,會用工具根本就是沒屁用的事情啊,要會真的很硬的東西才有用吧。比如說今天我人工智慧學超強然後寫 lisp(隨便亂講的,不知道業界做 AI 會用什麼語言),寫論文用 LaTeX 這樣就很夠了吧。再不然寫 Java 用一堆 Apache 的東西專門弄雲端,或是只寫 JavaScript 然後一直寫 web,再不然寫 C 然後是 kernel developer 這樣都很好啊,但我會的一堆可就什麼都不是,東弄弄西弄弄的到現在 30 眼看 40 了到底在幹嘛啊(嘆氣)。

總之(上段言歸正傳明顯是失敗了),如果能有時間的話,完美解應該是寫個 wordpress.xml 的 parser 把過往文章好好的轉到 org-mode 去,然後再把 org-mode 跟 Octopress 整合起來,最後整個丟去 github,應該就 happily ever after 了吧。這簡直費工到炸,雖然很想弄但究竟什麼時候才會有時間啊(抱頭)… 更別說 wallagroup 那邊一大堆要看的 code 還沒看一堆答應的功能也還沒寫,這都是正職跟唸書以外的事情,但我光這兩件事就做不完了啊…

Advertisement

rxvt / xterm + freetype + 中文顯示 (Chinese)

.Xresources

XTerm*faceName: Ubuntu Mono
XTerm*faceNameDoublesize: WenQuanYi Micro Hei Mono:minspace=true
XTerm*faceSize: 12
XTerm*faceSize1: 8
XTerm*faceSize2: 10
XTerm*faceSize3: 12
XTerm*faceSize4: 14
XTerm*faceSize5: 16
XTerm*faceSize6: 24

Rxvt.font: xft:Ubuntu Mono:size=12,xft:WenQuanYi Micro Hei Mono:pixelsize=18:minspace=true
Rxvt.letterSpace: -1
Rxvt.lineSpace: 2

xterm 比較討厭的地方是 freetype 的 failover 做不是很好,顯示一些 unicode 的字型時在 faceName/faceNameDoubleSize 裡頭找不到的話,就會放棄變成方塊;為了避免,只好裝 rxvt-unicode。後來因為太喜歡 rxvt fading 的功能,就決定換用了。

其中 rxvt 的 letterSpace 是要配合第一字型(在此是 Ubuntu Mono)的特性去調整的,Ubuntu Mono 間距比較寬,所以用 -1 來減少,這樣在我筆電 X220 上垂直分為左右二欄還可以有清楚的 80 欄寬。lineSpace 則是因為 Ubuntu Mono 比較寬而高度不夠,會導致文泉驛 render 出來的字太小,而且整個螢幕都是字時閱讀起來很吃力,所以加一些高度給他。麻煩的是,高度好了以後,仍然有時會跑出方塊,urxvt 顯示錯誤是

urxvt: unable to calculate font width for 'WenQuanYi Micro Hei 
Mono:slant=0:weight=200:pixelsize=19:minspace=True', ignoring.
...

size 轉到 pixelsize 是由螢幕解析度決定的,所以是否會有這情況,以及這情況發生時出來的數字,都不一定。我的情況是 pixelsize=19 出問題,由於字體大小是由第一個字型,也就是 Ubuntu Mono 決定,所以增加 pixelsize 沒用,只能試減少。減到 18 時剛剛好,字型漂亮,欄寬也夠。

xrdb -merge ~/.Xresources 可以直接讀入改好的 .Xresources,這樣下一個開的 x-terminal-emulator 就會套用新的設定。
font-test

Two-Finger Scrolling on ThinkPad X220 + Ubuntu 12.04 (precise)

The TrackPoint on a ThinkPad laptop is one of the main reasons why I kept buying laptops from them. However, as a heavy laptop user who refused to carry around one extra mouse, the constant usage of TrackPoint can cause a significant amount of pain to my fingertip, which is very unpleasant. An once-in-a-while quick movement is okay, but scrolling up/down takes longer and requires more pressure, which is the main cause of discomfort.

As a possible solution, I’ve tried to enable TouchPad and two-finger scrolling. However, for some reason it didn’t work by setting it in gnome-control-center, so instead I used the old faithful xinput. From the output of xinput list-props "SynPS/2 Synaptics TouchPad", it’s easy to spot “Synaptics Two-Finger Scrolling”, and the two parameters can enable vertical and horizontal scrolling, respectively.

The default setting of two-finger scrolling was far from intuitive — normally people would expect it to work just like the way it works on touch devices: you touch the screen, then you can push the document up by moving your finger up. That means scrolling down when your finger is moving up. But on my laptop, moving two fingers up means scrolling up, which causes the document to move down!

To make this problem worse, there is no setting in gnome-control-center to inverse this. Again, this can be solved with xinput by simply changing the values of “Synaptics Scrolling Distance” from 100 100 to -100 -100.

Here is my current .xsessionrc:

xinput set-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation" 1
xinput set-prop "TPPS/2 IBM TrackPoint" "Evdev Wheel Emulation Button" 2
xinput set-prop "TPPS/2 IBM TrackPoint" "Device Accel Velocity Scaling" 50
xinput set-prop "SynPS/2 Synaptics TouchPad" "Synaptics Two-Finger Scrolling" 1 1
xinput set-prop "SynPS/2 Synaptics TouchPad" "Synaptics Scrolling Distance" -100 -100

Run Pencil on Ubuntu 12.04 / 12.10

Pencil is simply the best (open) sketchy mockup solution on Ubuntu. However, as described on its download page, you cannot install it as a Firefox extension because it’s not compatible with the Firefox 18.x that comes with Ubuntu 12.04. The standalone version runs okay but some features such as export as PNG fails silently because of the same compatibility issue.

Turns out you don’t need to install the deb package provided on its website. Simply download the latest tar ball from the download page on google code, then download xulrunner (Mozilla runtime) from ftp.mozilla.org. I used the latest supported version: 16.0.2.

Now extract these to a preferred place, then add a file called pencil anywhere in your $PATH with the following content:

exec <somewhere>/xulrunner/xulrunner --app "<somewhere>/pencil-2.0.4/usr/share/pencil/application.ini"

then chmod +x pencil, done.

如何印清單

2005 年我問過 Thinker 這樣的問題:想程式常碰到要印出清單的情況,對人類而言習慣的格式是:

1, 2, 3, 4

但這個格式對於 C 語言來說卻不太好處理。一般可以寫成這樣:

<<一般作法>>=
void normal(const char *list[], const int len)
{
    int i = 0;
    printf("%s", list[i++]);
    for (; i < len; i++) {
        printf(", %s", list[i]);
    }
    puts("");
}
@

但是 printf 這行會重複,似乎不是最好的寫法。如果不要重複,那就得在迴圈中加個判斷式,但每次都要多個判斷又好像有點浪費:

<<判斷作法>>=
void condition(const char *list[], const int len)
{
    int i;
    for (i = 0; i < len; i++) {
        if (i != 0)
            printf(", ");
        printf("%s", list[i]);
    }
    puts("");
}
@

當時 Thinker 想了想,給了我一個用 function pointer 的答案

void dummy() {
}

void line() {
   printf("  ------\n");
}

inter = &dummy;
for(i = 0; i < n; i++) {
   inter();
   printf("%s\n", record[i]);
   inter = &line;
}

話說,事隔多年,今天在看其他東西的時候,突然想到這個問題可以用 Clifford’s Device 的方法做。

<<Clifford>>=
void clifford(const char *list[], const int len)
{
    int i = 0;
    while (1) {
        if (0) {
          clifford:
            printf(", ");
        }
        printf("%s", list[i++]);
        if (i >= len)
            break;
        goto clifford;
    }
    puts("");
}
@

各位看官,可有什麼新想法嗎?

<<list.c>>=
#include <stdio.h>

<<一般作法>>

<<判斷作法>>

<<Clifford>>

int main(int argc, char *argv[])
{
    const char *list[] = {
        "one",
        "two",
        "three",
    };
    const int l = sizeof(list) / sizeof(char *);

    normal(list, l);
    condition(list, l);
    clifford(list, l);
    return 0;
}
@

當然啦,如果是 python,這問題可簡單了:

>>> l = ['one', 'two', 'three']
>>> print ', '.join(l)
one, two, three

另,本文採用 Noweb 格式,用工具跑一遍就可以產生 list.c 。

virtualenv, python-rope and pylint

python-ropemac is really useful for developing python in emacs, and pylint is also very handy as a analyzer. However, they both don’t work very well with virtualenv, especially because I always run emacs in server mode, and the server instance is usually not under virtualenv.

Here is how to make things work:

Edit .ropeproject/config.py:

# You can extend python path for looking up modules
    prefs.add('python_path',
              '/your-virtualenv-dir/lib/python2.7/site-packages/')

For pylint, generate (by pylint --generate-rcfile) or copy your default pylintrc to project root dir. Edit it:

# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
init-hook='this_file="/your-virtialenv-dir/bin/activate_this.py";execfile(this_file, dict(__file__=this_file))'

After this pylint will work even in emacs.

Curious case of closure in Go and Python

At http://tour.golang.org/#39, I found the following sample code:

package main

import "fmt"

func adder() func(int) int {
	sum := 0
	return func(x int) int {
		sum += x
		return sum
	}
}

func main() {
	pos, neg := adder(), adder()
	for i := 0; i < 10; i++ {
		fmt.Println(
			pos(i),
			neg(-2*i),
		)
	}
}

Its document reads:

… functions are full closures. The adder function returns a closure. Each closure is bound to its own sum variable.

Take that into consideration, it might be easier to understand the execution result:

0 0
1 -2
3 -6
6 -12
10 -20
15 -30
21 -42
28 -56
36 -72
45 -90

To me, variable sum is similiar to ‘instance variable’, in Object-oriented’s terminology. However, in Python, things can be quite different.

def adder():
    sum = 0

    def f(x):
        sum += x
        return sum
    return f


def main():
    pos, neg = adder(), adder()
    for i in xrange(0, 10):
        print pos(i), neg(-2 * i)

The code looks roughly the same, but it will raise the following exception:

Traceback (most recent call last):
  File "closure.py", line 17, in 
    main()
  File "closure.py", line 13, in main
    print pos(i), neg(-2 * i)
  File "closure.py", line 5, in f
    sum += x
UnboundLocalError: local variable 'sum' referenced before assignment

This is because if sum is to be modified, Python must decide which variable to change. sum += x is the same as sum = sum + x, and sum = suggests it’s a local variable, since all variable is by default local in Python. Given that, expression sum + x can not be evaluated because sum, as a local variable, is still undefined here.

If the sum += x line is removed, and sum + x is returned directly, the result will be:

0 0
1 -2
2 -4
3 -6
4 -8
5 -10
6 -12
7 -14
8 -16
9 -18

It runs okay, but the result is wrong. Where does function f get the value of sum? If Python cannot find a variable in locals(), it will try to find it from the scope above it, i.e. function adder, and sum is indeed defined in it. The real Python equivelent of the Go program above will be:

class adder:
    def __init__(self):
        self.sum = 0
    def __call__(self, x):
        self.sum += x
        return self.sum


def main():
    pos, neg = adder(), adder()
    for i in xrange(0, 10):
        print pos(i), neg(-2 * i)


if __name__ == '__main__':
    main()

Functions are already first class objects in Python. Here we create a class that its instance behaves like a function, so it is a function because of duck typing.

Swap every windows between workspaces in awesome wm

awesome is the tiling windows manager I use daily and I just wrote a very useful (at least for me) function for it. Basically it swaps every client (similar to windows) between the current tag (similar to workspace) and the target tag. Normally I put terminal clients for my current task at tag#3, right next to my Emacs-only tag#2 so I can quickly switch between browser (#1), editor and terminals. Now if I want to switch to a different task I just need to swap in terminals from another tag while swap out current terminals to that tag.

-- i is the index of target tag in variable `tags'
function ()
   local screen = mouse.screen
   local from = client.focus:tags()[1]
   local to = tags[screen][i]
   if to then
       t = to:clients()
       for i, c in ipairs(from:clients()) do
           awful.client.movetotag(to, c)
       end
       for i, c in ipairs(t) do
           awful.client.movetotag(from, c)
       end
   end
end

I put this under

-- Bind all key numbers to tags.
-- Be careful: we use keycodes to make it works on any keyboard layout.
-- This should map on the top row of your keyboard, usually 1 to 9.
for i = 1, keynumber do
    globalkeys = awful.util.table.join(globalkeys,
        awful.key({ modkey }, "#" .. i + 9,
                  function ()
                        local screen = mouse.screen
                        if tags[screen][i] then
                            awful.tag.viewonly(tags[screen][i])
                        end
                  end),
        awful.key({ modkey, "Control" }, "#" .. i + 9,

in my copy of default rc.lua.

Multi-thread testing in Pyramid

If you want to do multi-thread testing in Pyramid, it probably won’t work the first time because request and registry are thread local, and things like get_renderer will call get_current_registry. When it happens in a thread, it won’t get the same value as it would have in the main thread.

So, here is a hack to address this:

import pyramid.threadlocal
from threading import Thread, Lock

candidates = [
    (self._test1, ()),
    (self._test2, ()),
    (self._test3, ()),
    ]

def random_func(pyramid_thread_locals):
    pyramid.threadlocal.manager.push(pyramid_thread_locals)
    time.sleep(random.random())  # 0 ~ 1 sec
    func, args = random.choice(candidates)
    func(*args)

pyramid_thread_locals = pyramid.threadlocal.manager.get()
threads = [Thread(target=random_func, args=(pyramid_thread_locals, ),)
           for i in range(100)]
for thread in threads:
    thread.start()
for thread in threads:
    thread.join()

There is no guarantee that pyramid.threadlocal.manager will always be there. Even if it’s there, there’s no guarantee it can be used this way. So, this should only be considered as a temporary workaround.