2007年7月27日 星期五

用O(NlogN)的時間比較兩個序列的差異

Problem Definition

  • given two sequences of the same item set, compute how many order relations are different
  • order relation: a < b < c vs. c < a < b, in this case, there are two different relations which are (a, c) and (b, c)

Sample inputs and their results:

  • [a, b, c], [c, b, a] -> 3
  • [a, b, c, d], [d, a, b, c] -> 3
  • [a, b, c, d], [d, a, c, b] -> 4, the different order relations are (a, d), (b, c), (b, d), (c, d)

Algorithm

想法

展開所有可能的order relation需要C(N, 2)次,N是item set的大小,聽Oshin說有O(NlogN)的方法,用Merge Sort的概念即可。昨天睡不著想了兩個小時,感覺差一環就想通了。今早起來忽然想通關鍵的merge,利用已排好的特性,merge的時間只要O(n)。

Pseudo Code

大概寫寫,邊界沒有算很準,陣列由1開始算,R[1..m]的意思是R的sub sequence,範圍是1..m。

CompSeq(R, R’)
Input:R, R’ which are sequences (e.g. R = [a, b, c], R’ = [b, c, a])
Output:n, the number of different order relations

  1. for each c in R, H[c] := index of c in R, where H is a hash table
  2. return CompSubSeq(R’)

CompSubSeq(R)

  1. return 0 if |R| = 1
  2. let m := |R| / 2, R1 := R[1..m], R2 := R[(m+1)..|R|]
  3. return CompSubSeq(R1) + CompSubSeq(R2]) + Merge(R1, R2)

Merge(R1, R2)

  1. let n := 0, k1 := 1, k2 := 1 and R be a new array
  2. for i in 1..(|R1|+|R2|) do:
  3. if k2 > |R2| or (k1 < = |R1| and Smaller(R1[k1], R2[k2])),
    then R[i], k1 := R1[k1], k1+1
  4. else R[i], k2, n := R2[k2], k2+1, n+|R1|-k1+1
  5. end for
  6. return n

Smaller(a, b)

  1. return true if H[a] < H[b]

雜記

Ruby寫的版本見這裡,原本想寫完整版的測試,寫完演算法後懶了,果然應該先寫test code再開始寫,才不會懶得寫test code啊。

可以利用如下的方法實作test code:產生(a1, a2, …, an) item set的所有排列,在產生排列的同時,可以知道目前產生的是第幾組序列,得到序列值後,可以用O(N)的方法算出差了幾個relation,以(a, b, c, d)和(d, c, a, b)為例,(d, c, a, b)是第23個序列,23 = 3*3! + 2*2! + 0*1! + 1*0!,所以是3 + 2 = 5次;以(c, d, a, b)來說,這是第17個序列,17 = 2*3! + 2*2! + 0*1! + 1*0!,所以是2 + 2 = 4次。利用餘數的技巧,序列數轉成階乘表示只要O(N)。

昨天原本想用這個序列順序轉答案的方法來解這問題,大部份的思考在這裡打轉。雖然成功地將原問題reduce成找序列順序的問題,並且可以用O(N)的方法由序列順序算出答案,但想不到O(NlogN)算出序列順序的方法。

2007年7月22日 星期日

《海潮之聲》中文版小說

書藉基本資料: 海潮之聲

喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔喔!!沒想到竟然出了!!

想當年,我為了查相關資料,而找到龍貓森林這有趣的blog,和站長請益之後,買了第一集的日版回來練日文,妄想藉由我對這作品的愛來貫徹練日文的決心。結果我的愛徹底地被沒標假名的內文擊敗了,只讀了一兩章...

剛才從jnlin那得知中文版出了,而且還是一個月前的事,下次回台北一定要買回來看的啊!看來最近有小說可看了。(書架上一堆借來的書,你們就再多等一會兒吧...)

2007年7月21日 星期六

MoinMoin、PmWiki和DokuWiki editor比較

整理一下最近用Wiki的心得。MoinMoin的GUI editor超威,特別是table的編輯,還可以按右鍵選table/cell property,包含 text/border/background color,text alignment等設定,而且速度很快,GUI editor和text editor之間的切換也很快。有GUI editor後語法也不用查,先用GUI editor產生後再切到text editor看,很方便 ,基本上除表格外,我都用text editor,自由度較高,比較習慣(個人偏好)。

PmWiki和DokuWiki都是text editor加上輔助按鈕,按了可以產生sample code,DokuWiki的功能強一點,還有特殊符號字元表。語法文件方面,PmWiki列得很詳細,分基本和進階的教學,Wiki裝好後預設放在sidebar上,方便查詢。DokuWiki則是放在編輯頁面的上方,點了syntax鏈結後可以看到全部語法和範例,也滿清楚的,文件部份PmWiki和DokuWiki都不錯,MoinMoin因為GUI editor太方便了,我還不知道它的Wiki code文件放在那,因為一次也沒查過。

雖然乍看下PmWiki editor較弱,但我最喜歡PmWiki的Wiki syntax,簡潔易讀。而section editing部份,DokuWiki預設就有,PmWiki要裝plugin SectionEdit,而MoinMoin的作者認為可以用Include page的做法,而不需要section editing的功能,所以沒有這功能。

2007年7月20日 星期五

MySQL偽memory leak問題

Problem

我用的server是Debian 64bit (AMD64), DB server是 5.0.32,有8G memory,但MySQL使用一陣子後,用top和free會看到8G的memory都被吃掉,但沒有任何process用到這麼多memory,而且swap沒有被用到,關掉MySQL daemon後memory的用量也沒改變。

Solution

查到兩篇類似的苦主:

從第二篇裡找到解法:

Despite the fact that “top”, “/proc/meminfor”, “free” show me that 98% of all memory on server is used that memory is not really used by MySQL nor kernel (as I can see from /proc/slabinfo).

I wrote simple C app. which tries to allocate as much memory as possible calling malloc() in a loop I found how much free memory _really_ available. Looks like it is Linux reporting problem, but same time this _only_ happen to me with memory previously used by MySQL server. I can see memory returned back to free memory pool as soon as other applications exit.

上面說是top和free報錯數據,MySQL query結束後,query用掉的memory有還回去,但top和free的統計數據裡卻沒有減少。

我也寫了個 C app來試,如他所言一般,程式結束後memory回來了,但查了半天找不到單一process的maximum memory usage定義在那,有人說在limits.h裡,INT_MAX就是maximum memory,但顯然是錯的,我設到比它大的值,anyway,下面是我「要回」memory的 code,因為設到15*會超出上限被killed,只好設12*並同時跑多個,但想想這個數字也不太對,它比8G大,但跑起來大概只用了2G吧,不知道process到底怎麼跑的

#include <stdio.h> #include <stdlib.h> enum { MAX = 12000000000 }; char s[MAX]; int main(void) { int i; for (i=0; i<MAX; i++) s[i] = i; sleep(10); return 0; }

另外聽小豬說在Debian的MySQL 5.1上沒這問題,也許是已修正的bug吧。

備註:query cache相關指令

http://dev.mysql.com/doc/refman/5.0/en/flush.html
http://dev.mysql.com/doc/refman/5.0/en/query-cache-status-and-maintenance.html

The RESET QUERY CACHE statement removes all query results from the query cache. The FLUSH TABLES statement also does this.

還有可以用SHOW VARIABLES查環境設定,像是myisam_max_sort_file_size、max_binlog_cache_size。

2007年7月18日 星期三

享受生活.努力工作?

我並沒有忘記升等考的傳言,只是因為比賽太令我開心了,
所以覺得太早划到終點很可惜。
我想要慢慢地,以我自己的方式,朝著獨當一面的境界邁進。
是的...反正都要做,就開心地做。

by Akari, from ARIA comic 01 

最近又在想未來要做啥,相較於一般人來說,我從小就沒有特別志願,既沒有成為科學家的夢想,也沒有娶妻生子的憧憬,更沒有現實的2x歲賺進第一筆一百萬這類規劃。一直以來,二十多年過去,還是沒有。硬要說的話,人生目標是悠閒過生活,不過這樣的目標只會讓人愈來愈懶散,只肯撥出一些多餘時間為日後的悠閒準備,其餘時間要享受目前的生活。

昨天和大中聊到未來似乎沒啥幹勁,不知要做啥好,想找有意義又有趣又能賺錢的工作,真難啊,二十多歲正值人生邁向顛峰的開始,這麼沒幹勁怎麼行。兩人沒幹勁地聊著人生真沒幹勁,大中忽然想起他要準備AWA、GRE,下週起要開始工作,似乎快來不及準備了,於是大中就這麼脫離了沒幹勁小組,剩我一人沒幹勁。

想來想去,畢業後要嘛當工程師,要嘛出國念博士、回國當教授,似乎也沒第三條路可走。今天看完《阿拉斯加之死》,發現有第三條路:走入曠野。嗯,其實我們可以活得更自在地,但我已離不開便利商店和網路了,如果深山裡有這兩者的話,或許可以走入曠野做SOHO族接case維生。

今天聽wcpeng提到和羊的合作過程,他們如何努力地用email、MSN討論,不斷修改paper,最後投上ACM CIKM 2007。雖然羨慕羊的成果,可惜這不是聽完會熱血的事,如開頭引言所述,我想悠閒自在地做,而不是拼命地做。台灣人愈來愈奇怪,學界業界都講強努力努力,卻不明白這麼努力是為了什麼?或是被環境逼得不得不超時工作,生活品質降低,但產能不見得會提高多少,整個環境惡性循環。

如果睡飽清醒花一小時能做完的事,為什麼要熬夜拼兩小時做完它?費時品質又差。

如果能在正常工作時間內完成的事,為什麼要讚揚加班的人認真?搞得能做提前做完的事也要拉長做。

將研究看成工作的話,我始終無法接受教授們將修改paper視為理所當然的事,不斷地強調好的paper就是要不斷地修改。我相信好的paper需要多次修改,但這不表示大量修改是正常的。經驗可以累積,方法可以改進,為什麼paper不能愈寫愈快,愈改愈少次?比方程式設計師知道bug一定會產生,debug也是必然的,但程式設計師還是會不斷思考如何減少bug的產生,或是如何更快地debug。

也許是我天真,總覺得即使是努力,也可以輕鬆寫意地努力吧,沒必要強調吃苦當吃補,強調付出比別人更多的時間,將這視為美談。相反的,我始終相信偷懶才是進步的原動力,就像不滿於自行車而發明了摩托車;為了省下穿鞋時間而發明拉鍊。我少數的行為準則之一,就是做什麼事都要獲取經驗,不能愈做愈好,至少也要愈做愈快,要有成長做起來才有趣。

回頭來看工時,像歐洲人一樣,一週工作40小時,週休二日不上班,享受生活,這才是美好人生啊!

PS1

ARIA取材自威尼斯,看了大中拍的威尼斯照片,兩者真的很像,挺多現實生活的河髒了些,Gondola上坐的人多了些,舟與舟之間看來有點擠,不像ARIA那般色彩鮮麗。

PS2

別忘了《財經》百大企業之一的執行長,也認為要求超時工作的主管不是好主管,附篇ptt的文章《加班文化》,真是說出我的心聲,希望當我當主管時,不會忘了員工的不滿。

作者: elven (虛無之海、飄渺之空) 看板: Tech_Job
標題: Re: 加班文化…
時間: Wed Jul 4 00:31:05 2007

※ 引述《crary (crary)》之銘言:
: ※ 引述《yasteree (yasteree)》之銘言:
:
: 不想加班最簡單的方法…
: Show出你卓越的工作能力…拿出你的high performance….
: 工作並非只求把事情做完….
: 而在於是否你能達到老闆要求的120%….
: 人家靠加班表現..你則要拿出你的gut….
: 下午五點前我不只把事情做完..還把多的那20%也做好了….
: 這樣你就可以早下班了….
: 反之..如果只求把事情做完就下班….
: 老闆當然就只給你一般達到水平的評價與績效囉…
: 砍展 是衝出來的…

也許你在的環境這樣可行,但是有很多公司是行不通的。

明天下午三點主管要的東西,你明天一大早就放在他桌上,
這是high performance? Yes!
不過下次交給你這種任務,就不是明天下午要,而是當天下午就要!
交給別人沒辦法這麼快完成,所以這些事以後都算你的。

主管訂的工作進度如何如何…
表現你的High performance!超前進度20%! Good!
保證你開始share同事的work,誰叫你能力好,看起來就很閒。
別人做不完的你當然要幫忙,誰也不記得什麼guts什麼鬼。

誰記得你能力強工作表現好,只知道你沒在加班,一定沒貢獻,考績一定差。
希望你和你的主管非常match,他又挺你。
不然發股票/年終時…你就到旁邊畫圈圈吧!

現實,總是在謀殺理想,你有理想,很好。
等你當上主管當上老闆,好好實行你的理想。


※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.56.133.218

2007年7月13日 星期五

Parse invalid HTML by Hpricot (2)

關於Hpricot的基本介紹,可以參見前篇,Hpicot的API文件可以參見這篇這篇,怪的是好像沒在官網看到連到這些API網站的鏈結,我從Google找到的。Hpicot雖然好用,但文件似乎沒有很齊,這裡簡單說明crawl web pages會用到的部份。

開檔

可以從檔案或URL開啟,用法:

require 'uri' require 'open-uri' require 'rubygems' require 'hpricot' doc = Hpricot(open('http://fcamel.twbbs.org/'))

會得到一個Hpricot::Doc物件,接著可以使用search()找出特定部份的資料,我都是用CSS path,配合Web Developer查CSS path,容易使用。

Search

example code:

doc.search("//div#sidebar.list/ul/li/a").each do |t| ... end

這個例子裡,search回傳Hpricot::Elements,Elements是類似陣列的資料結構,每個元素的型別是Hpricot::Elem。t.inner_text的型態是String,tag內的純文字;t.attributes[…]是Hash,存放各屬性的值,比方用t.attributes[’href’]取出超鏈結指向的URL。

Hpricot::Elements可以繼續search,可以先取出一大區塊的HTML後,再配合if, else來找資料:

doc.search("//div#sidebar.list/").each do |e| if e.search("//h3.label").inner_text =~ /Introduction/ # find data in <h3 class='label'>Introduction</h3> ... elsif e.search("//h3.label").inner_text =~ /Related Work/ # find data in <h3 class='label'>Related Work</h3> ... end end

2007年7月11日 星期三

去年寫的小遊戲:Dice War改版

這個Blog好像幾乎沒提到Game,曾經,我也是個愛打Game的男孩啊!只是興趣轉到電腦後,比較少接觸而已。以前也想過要當Game Programmer,後來漸漸了解這行業而當興趣而已(同樣的事也發生在軟體工程師上啊)。

沒想到轉眼一年過去了,當初玩了Dice War這個遊戲, 覺得很有意思,想弄個多人連線對戰的版本,後來又想,乾脆再加入自訂AI,可以讓人和自訂的AI混戰, 應該更有意思,而且自己寫的話也可以自己調整遊戲性,就這樣衝了一週把它寫出來。有興趣的人可以看“WDW - Wow! Dice War!!”,包含遊戲和原始碼下載,以及玩法說明。

2007年7月6日 星期五

MoinMoin Wiki心得

簡介

MoinMoin官網

聽老光頭說,在他接觸的open source project裡,用MoinMoin當Wiki的居多,看到Fedora官網做得如此精緻,想來試看看MoinMoin,適合的話可以用來做lab首頁。

MoinMoin是用Python寫的CGI,由於用到CGI的緣故,裝起來比PHP寫的Wiki麻煩一些,由於安全考量,通常各目錄預設都是不能執行CGI,所以apache要多做設定。雖然沒有PmWiki或DokuWiki這麼好裝(1 ~ 5 mins即可裝好),但相較Twiki來說,MoinMoin Wiki好裝許多。

安裝

官網的安裝教學頗為散亂,我大概和MoinMoin Wiki的文件不合,有時寧願自己試也懶得翻文件,總覺得文件的脈絡沒有整理清楚。相較之下PmWiki和DokuWiki清楚多了。

  1. 從官網下載
  2. 解開後,參照Basic Installation執行安裝的script:

    python setup.py install --install-data='/usr/local'

  3. 參照Wiki Instance Creation新增Wiki base,直接用網上提供的script較快。
  4. 從網頁上按 login -> UserPreferences 註冊account,修改wikiconfig.py:

    superuser = [u"YourAccount", ]

    設定permission:

    acl_rights_before = u'YourAccount:read,write,delete,revert,admin Known:read All:read'

    Known表示已註冊使用者,All表示所有人(包含未登入者),這樣設完包含註冊的人和guest在內,預設權限都是唯讀,需要其它權限的話再改acl_rights_before。

(待修,改天再補完整點)

過程裡有錯誤發生時,可以參照web page的回應,或是看/var/log/http-error.log,error message寫得很清楚。可能會遇到的問題像CGI不能執行、Python版本不對或缺Python module,或是改config檔時沒照Python規定的縮排,懂一點Python有助於除錯。

Plugin

對我來說,一個Wiki的好處,除了安裝容易、Wiki code好寫、權限設定完整外,最重要的是plugin的質和量,這裡簡記一些plugin相關的心得。

對MoinMoin來說,

wiki code: [[XXX(args)]]

parser讀到這行wiki code後,會呼叫data/plugin/macro/XXX.py內的procudure “execute(macro, args)“。

相當簡單易懂的plugin做法,把plugin的python code放到data/plugin/macro/下,即可使用(CGI每次都會重讀,但standalone server可能要重跑server),因此史上最簡單也最有威力的plugin:in-line HTML,只要這麼寫:

in data/plugin/macro/HTML.py:

def execute(macro, args): return args or " "

wiki code example,貼flickr的圖(兩行合一):

[[HTML(<a href="http://www.flickr.com/photos/12203797@N00/287454598/" title="Photo Sharing"> <img src="http://farm1.static.flickr.com/112/287454598_d5c67feb2a_o.png" width="555" height="376" alt="couplet" /></a>)]]

表格

MoinMoin的table可以做到rowspans和colspans,而DokuWiki和PmWiki做不到colspans。使用table必備的plugin:MiniPage

雖然code有點醜,但透過MiniPage可以在table cell裡塞wiki code,做到像是table內的list,table中的table應該也OK,我沒試就是了,因為wiki code必需寫成一行,可讀性接近於 0,詳細介紹參照MiniPage上的說明。

surge protection

原意是避免被DoS,讓使用者各項操作到限定數量後,禁止對方的操作,但在我反覆測試編輯的情況下,反而是我一直被封,要等一會才能用。雖然可以調高限定數量,但還是很麻煩,後來發生狀況後我就直接砍surge log ( data/cache/surgeprotect/surge-log )。

ps.

有機會的話,再來寫篇三個Wiki的試用心得,現在是覺得各有好處,不見得那一個比較好或比較不好。

2007年7月5日 星期四

早起的陷阱

剛才差點中陷阱爬不起來,被try叫起來後睡了一下回籠覺,張開眼後驚覺已九點多了,急忙忙地爬起來,放音樂提振精神,看似一切完美即將趕上出門時間。

但…其實我還在夢裡,現在po文的行為應該不是二次陷阱吧? (孔明!?)

說到早起就不得不談今天要搬回台北的try,再會啦,感謝你多次拯救我睡過頭的危機。雖然一年來我們沒有打過puyo,但我們共同為Defender奮戰過,還有昨晚打一點點的Boxorz

記憶

在健文的版上看到小遊戲(?)讀心術,想起以前當家教時曾用這把戲唬過學生,藉此說明「數學其實很有趣的」,希望引起學生對數學的熱忱。這遊戲結合了創意,將簡單的把戲發揮更為淋漓盡致,可看成結合美工、創意的數學魔術!

想起完全忘記的事總會帶來很妙的感覺,像是想起大一大二有家教、想起大四上飛去北京五天。除了為記憶感到不可思議外,更覺得過去活得比想像中還要充實,從而感到欣慰(雖然回頭看最近的事,永遠嫌不夠充實)。

轉念想想為什麼會忘了這些事呢?這代表同一時期,有更多更累的事存在,轉而忘了這些「小負擔」,也顯得自己曾有過更深的磨練,進而為過去的自己感到驕傲,也更有自信開啟下一個挑戰。好漢不提當年勇,但正因有過當年的好漢,才有今日的自信。心胸有多大,舞台就有多大,一再地放大自己的眼界,提高自己的氣度,才能不斷地提昇自我,永不滿足地追求自我實現。

哈,好久沒寫這類喔喔喔地勵志文。

ps. 讀心術背後原理

1. pick a number 10a+b
2. follow the rules, you’ll get (10a+b) - (a+b) = 9a
3. all the figures with number 9n are the same

附中的回憶

(寫於2007-04-14,保留當時BBS上的排版)

看到flyhermit版上的”附中守夜”, 順著去看”史上最大搖滾教室”的相關活動,
激起了埋在深處的附中回憶, 無法退去的熱情,
剛才和yulong很high的聊了些附中的事

高中真是不可思議的階段,
能進附中對我來說也是奇蹟般的轉捩點,
在進附中前我對自己沒那麼強的自信,
也沒那麼強的熱情追求自我實現

真要追憶參與活動的回憶, 國中大概是最認真參與活動的時候,
高中比較被動, 加上參加的是電腦性社團, 活動都是技術面的,
動手做的活動只有畢典, 也因為畢典而有無法完成HSNU-Game的憾事

記得那時還因為要趕畢典進度而翻牆回學校佈置,
不確定有沒有守夜…

喀嚓!!

剛才回憶的鎖終於敲開了, 守夜的景象一張張地湧上心頭,
和TB等人一起在中興堂2F打牌, 玩殺手,
還有到附近某個同學家陪他拿東西,
五年前, 最後一次動手做, 認真投入的活動

還有某天和徐維懷(我肯定名字有打錯XD)輪流彈中興堂鋼琴的回憶,
irace當時也在場, 那時和徐維懷借了琴譜,
那陣子正好讓我對改變對鋼琴看法, 激起對鋼琴的興趣

大學後雖然活動沒少過, 但愈來愈技術向,
非技術向的嫌做起來太不順手, 費時不討好,
想做的事愈滾愈多, 而將投入活動的心埋藏起來,
甚至忘了辦活動的樂趣

有些事, 現在不做, 以後的確不會再做了,
一直有好多事想現在做啊…

ps. 經阿吉提醒,正解為「徐唯槐」。

2007年7月4日 星期三

厄夜變奏曲(含一點《鬥陣俱樂部》介紹)

囉哩叭嗦的開場白,只想說明這部片有多恐怖

大概半年前我看了《鬥陣俱樂部》(原名:”Fight Club”),驚為天人,像這樣劇情好、結局佳,又能令人思索的電影,實在難得一見,但這電影有個問題,使我遲遲定不下心來寫心得,因為《鬥陣俱樂部》富含大量的反社會思想,若看過沒多加思索,可能會被導引到負面無助益的思考,或著年歲已高的情況下,觀後忽然覺得人生了無意義,又無力捥轉,反而會活得更為行屍走肉。

我不覺得這樣的想法太過誇大,《鬥陣俱樂部》確實孕含這種力量,當然,多數人可能只當作普通娛樂片,它確實也是不錯的娛樂片。在種種考量下,我變為選擇性地找人聊這部片的樂趣,而沒有寫篇公開心得。那麼,我今天為何又提了出來?因為我發現比它更恐怖的東西。

《厄夜變奏曲》(原名:”Dogville”)是部相當奇特的電影,開場馬上告訴觀眾這是不折不扣的劇情片,空盪盪的舞台代表一個小村,只佈置必要的道具,連門都沒有,在地板上圈出一塊狗形表示看門狗,簡化至極的佈景突顯一個重點,什麼都是次要的,專心注意劇情就是。去除簡陋的佈景,鏡頭壓迫感地直拍人臉是另一問題,初看不太舒服,而且全劇長達168分鐘。無論從那一點來看,都是令人望之怯步的作品,但自從聽朋友介紹過它奇特的舞台呈現後,我一直想找機會看看,今天碰巧看到浩然圖書館新進這片,耐著性子看,看完一小時後視線已無法離開,直直想知道劇情發展,回神時168分鐘已經過去。看完片後,我有些晃神,一方面是168分鐘太長了些,另一方面結尾的衝擊對白令我不明所已。

若說《人魔》、《奪魂鋸》這類影片是視覺和聽覺上的恐怖片,那《厄夜變奏曲》不折不扣地是精神和思想上的恐怖片,從那毫無誠意的佈景來看,它毫無娛樂效果,我也不需如《鬥陣俱樂部》那般擔心,這部片只有想挖掘人性醜陋的人會看,對這些人來說,看這類片子不是問題。像我了解看鬼片或恐怖片(非思想面的)會令我睡不好,我自然不會看。

開場白寫這麼多,到底《厄夜變奏曲》在說什麼?劇情很簡單,一個封閉的小村莊,村民只有一二十人,在觀察者湯姆(男主角)眼裡,每個人都封閉內心,不願承認自己的弱點,像是自私、猜忌、傲慢。藉由新訪客葛莉絲(妮可基嫚飾演,全劇唯一賣點)的到來,湯姆利用她做人性實驗,藉由葛莉絲和村民的互動,突顯出村民不願承認的弱點。另外,充滿反諷意味的旁白是一大特色,。

以下是簡單的劇情描述

故事一開始非常美好,在葛莉絲的努力下,村民打開心門,自承缺點,使得整個村莊過得更快樂。但一些小小的火花,使得村民變本加厲地要求葛莉絲幫忙,葛莉絲愛這個村莊,也需要這個村莊窩藏她,不斷地積極正面地思考,但這樣的行為只使村民日漸過份,最終一發不可收拾,突顯出種種人性醜態。

以下是含劇情的心得,含些許負面情緒,不喜者勿看

全劇用了大量的雙關,Dogville(狗村)意味著村民如狗一般,劇末葛莉絲和父親的對話揭曉狗村的反諷點。葛莉絲認為當環境壓迫人們,人們不得不做壞事以維生時,我們有什麼權力指責他們?但導演顯然已有答案,狗村的行為沒有正當到如《悲慘世界》中尚萬強那般不得已,到像是順著本性開啟的惡。導演似乎想說明這樣的惡行沒那麼令人憐憫,而是比狗還不如的行為,於是劇末,一二十人和一隻狗組成的狗村,只有悻活那麼一隻狗。

也許導演想說的更為殘酷一些,被環境迫始為惡仍是不如狗的行為,不過在我看來,《厄夜變奏曲》較像是人為因素,而非環境因素(性侵不是生活必需的,和環境惡劣無關),但話說回來,環境不正是人造成的?似乎說也說不清。看到葛莉絲「醒悟」而下令屠村那幕,我的心裡有股痛快感,是的,劇情就該這麼演變,寬恕地饒過他們,不會令他們學到什麼,最多只是暫時性的恐懼和伴隨暫時性的安份。

在後半劇情裡,有太多可以探討的問題,而不知從何談起,似乎是一個個無解的問題。好比葛莉絲的順其自然是否有錯?若葛莉絲早一步呈現強烈的反抗,是否村民不會逐漸習慣解放惡意,終而麻痺為比狗還不如的存在?這麼看來,受了眾多不人道欺凌的葛莉絲,反而是原罪?

自認是觀察者的湯姆,不斷地用力思考而什麼也沒做,是另一值得探討的存在。如同旁觀葛莉絲被欺凌的其他村民,故作高尚而最終爆發的湯姆,是否在精神層面是更高的罪惡?

可以探討的內容太多,思索下去只會令人反感,令人無力。其中我認為有趣的一點,是引發葛莉絲父女吵架的原因 - 傲慢(arrogant),這也是開頭一再強調的伏筆。究竟像湯姆以實驗人性、觀察人性而樂,自以為是地高高在上看著一切才叫arrogant?或是認為權力即是一切,看到一群瘋狗就殺一隻警示他們的葛莉絲父更為arrogant?還是以崇高的道德標準審視一切、自認為崇高地承受一切的葛莉絲最為arrogant?

或著,以觀眾身份看著他們揭露人性醜態,並在旁冷靜分析的我們才是真正arrogant?

或著,自許為萬物之靈,以狗或其他動物字眼象徵低劣、目空一切的人類,一直以來都是arrogant的存在?

這部作品還有續集《命運變奏曲》,剛才和浩然薦購了,看看那天有緣觀看吧。老爸我不清楚,老媽老哥相信人性本善,借這種片子回家看不太好,對他們有害無益,只會令他們不舒服。

在Rails裡用AJAX Observers

Rails預設即有內建prototype.js,並提供一些語法操作prototype.js,會將rails code轉為prototype的function call。參照“Agile Web Development with Rails” ch18,有用Observer實作livesearch的例子,但這份code有點小問題。

in observe.rhtml:

<label for="search">Search term:</label> <%= text_field_tag :search %> <%= observe_field(:search, :frequency => 0.5, :update => :results, :with => 'term', :url => { :action => :search }) %> <div id="results"></div>

注意observe_field()要放在追蹤的field_id之後,observe_field()放到text_field_tag()之前會失效。

in xxx_controler.rb:

def search @phrase = request.raw_post || request.query_string ... end

這段code裡的request.raw_post會從POST取得form內的資料,但如同raw_post的名稱一般,它取得的是如同GET後附上”var=value”的內容,並且,observe_field()會把追蹤的field_id內的內容取來當做key,若使用者在text field裡輸入”hello”,raw_post內的值會是”hello=”,而不是預想的”search=hello”

因此,解決方法有兩種:

  1. 修改controller:改成request.raw_post[0,request.raw_post.length-1],去掉’=’
  2. 修改view (observe.rhtml):改成

    <%= observe_field(:search, :frequency => 0.5, :update => :results, :with => 'search', :url => { :action => :search }) %>

    參照官方文件,:with會補上key值,再將追蹤的field_id內的值填入key內。

照理說,預設把追蹤的field_id和它的值設為”field_id=value”再傳給:url指定的method才合理吧?

2007年7月3日 星期二

中華「甜愛玉」

在炙熱的夏天時,小時候我總會吵著老媽買愛玉來吃,特別是10元一盒方便食用的中華「甜愛玉」。但老媽總說加工物對身體不好,又嫌愛玉貴,吵個幾次才到菜市場買一大包的仙草,配著砂糖融成的糖水吃。為什麼每一年吵著要愛玉,最後買回來的是仙草,長大後問老媽,她只說忘記了。

隨著年歲增長,經濟能力從零提昇到可以自己生活的程度,一盒10元的中華甜愛玉自然不是問題,想吃時就吃,管它春夏秋冬。或是到大潤發一次買一堆,兩盒四盒地吃到爽。剛才在7-11看著最近推出的愛之味「寒天」和我曾吃過的7-ELEVEN「白葡萄廬薈凍飲」,兩者都是凍飲,喝(吃?)起來都很過癮,售價分別是30元和25元,足足是中華「甜愛玉」的兩倍以上。這時我煩惱的是,肚子只有一個,我沒辦法一口氣吃完兩個。

雖然長大後夢想幻滅了不少,多少曾以為長大後能辦到的事,在接近目標時才發現自己無法做到,才發現時間愈剩愈少。幸好,隨手實現的小夢想也不少。時間無法逆流,也只能走一步算一步,享受不同時期的樂趣吧。

別了,期待吃愛玉的我,取而代之的是,無法明白愛玉可貴之處的我。

ps. 離開7-11時,我手裡拿著愛之味「寒天」和7-ELEVEN「白葡萄廬薈凍飲」,而廬薈凍飲已在打這篇文章的途中喝完了,洗個澡過一會兒再來喝寒天吧。