六月 26, 2016
» 台大資工校友訪談

五月 10, 2016
» 前進舊金山

五月 17, 2014
» 未來已經到來 – 量化和連結生活中的一切

三月 13, 2014
» 蹲下是為了跳得更高

三月 12, 2014
» blog搬新家

十月 27, 2012
» 過早最佳化是萬惡的根源

三月 19, 2012
» 我為什麼要念博士

十月 29, 2011
» 影響力

八月 15, 2011
» Sikuli Plays Angry Birds on Google Games

Franck Dernoncourt wrote a Sikuli Script for playing Angry Birds on Google Games.
The script is simple but efficient: it achieves high-scores that are very hard to beat. It tries different launching angles and beats Sergey Brin’s high-score on map 1-4 (36710 vs 29920).

The demo of this script can be seen on youtube.

The full script can be downloaded at here.
frameborder=”0″>

五月 31, 2011
» 駭客們,起來創業吧

三月 19, 2011
» 分享我的vim設定檔

三月 10, 2011
» Trading Bot for Magic Online

Raymond Cheung has created an open-source Magic Online Trading Bot with Sikuli to buy and sell digital products. Magic Online deals in thousands of digital cards that are bought and sold for with real money. Therefore the bot must be as accurate as possible.

The logic takes information from the Sikuli scripts that read the screen for product information and then, after processing that information, uses Sikuli scripting to interact with the Magic Online interface to finish the transaction.

Read the README on his GITHUB for further details. There is a full demonstration of the bot in the youtube video below.

三月 2, 2011
» 做研究與寫論文

二月 23, 2011
» 追求神乎其技的程式設計之道(番外篇)

一月 31, 2011
» 追求神乎其技的程式設計之道(十一)- 抽象化與命名

追求神乎其技的程式設計之道系列: 一 二 三 四 五 六 七 八 九 十 休眠已久的神乎其技系列又復活了!這篇文章其實寫很久了,只是一直斷斷續續到今天才完成它,久到讓很多人覺得這系列已經完結了…。但我想只要我還有在寫程式,這系列就永遠不會結束吧。 簡潔、彈性、效率 我一直覺得寫程式是一種藝術活動。程式語言是一種要求極度精確的表達方法,只要少打一個字母就可能造成完全不同的結果,但同時卻又不限制你要如何達到目標。 程式設計師有極大的自由來讓一個程式按照自己的想法「活起來」,不同人針對同樣的目標所寫的程式也一定不同。有人會用極簡主義來把變數命名為a、b、c,也有人會把用匈牙利命名法讓變數前後長出鬍子和尾巴;有人堅守DRY原則(Don’t repeat yourself),只要類似的程式出現兩次,就把他們抽象化成一個函數,也有人用copy/paste寫程式,不管怎麼page up或page down都一直看到一樣的東西還能泰然自若;有人寫程式把所有東西都塞在main裡面,也有人寫個Hello world就要搞一個class HelloWorld(雖然有些時候是被囉嗦的J語言強迫的…);有人沒聽過Big O也寫程式寫得很開心,但也有人嫌stdlib的qsort太慢硬是要自己重寫一個…。 儘管每個人的信仰和原則不同,但大體上程式藝術家也不過是在「簡潔」、「彈性」、「效率」這三大目標上進行一連串的取捨(trade-off)和最佳化。 「簡潔」的程式也「易讀」,沒有多餘的敘述或重複的程式碼,每個概念都只有唯一的一段碼在描述它。如果多了,就容易產生不一致的行為,如果少了,就是沒做到該做的事。有「彈性」的程式容易修改和擴充,只要在一個對的地方彈彈手指,不用因為老闆朝三暮四或是需求改變就得把整個程式重新翻修一次。有「效率」的程式會用最適合的資料結構存放每一樣資料,用最快的演算法做每一項必要的計算,並去除任何不必要的間接行為 (indirection)。 雖然目標很明確,但程式設計之所以像藝術就是因為大部分時候我們都沒辦法兼顧這三項目標:為了效率,可能就得犧牲彈性和簡潔;反過來說,為了彈性或簡潔,也常得犧牲效率作為代價。幸運的是,效率的追求在電腦硬體和編譯器技術的進步下已經不像20年前那麼重要,只要選對資料結構和演算法,幾乎已經沒有必要手動做低階的最佳化。除去效率之外,彈性和簡潔其實是比較容易同時達到而又不互相衝突的目標。要達到這目標,其中關鍵的能力就是今天的主題:「抽象化」(abstraction)。 最簡單但也是最難的事情 很多人沒聽過抽象化這個詞,甚至以為自己不會這件事,但其實從我們宣告第一個變數起,抽象化就已經開始了。 「這個變數要叫什麼名字?」 幫變數命名時,其實就是在賦予那個變數一個「意義」。人的記憶力有限,很難記住大量且沒有意義的資訊。但如果資訊有了一個固定且有邏輯的名字,我們也就有一個容易記憶的符號來代替整個複雜的概念。換句話說,我們可以把非常複雜的概念濃縮為一個容易處理和記憶的小單位,這個過程就叫做「抽象化」。 抽象化可以讓程式變得簡潔。好的程式設計師會習慣從重複的程式碼中找出共同或相似的部份,並且把這個部分提取出來變成一個更通用的概念。任何複雜的概念都可以被抽取出來替換成一個變數、一個函數、一個類別、一個模式、一個模組、甚至是一個系統,並加上適當的命名,就能讓這個程式「一看就懂」,任何註解都不需要寫。抽象化也能讓程式有彈性。經過適當抽象化的程式,每個概念都有一個獨立的「單位」(可能是變數、函數、類別、模組、或系統)可以表示,每個概念中包含的細節也被隱藏在適當的範圍內,不管要修改或擴充原本的程式都能讓需要碰觸的地方減到最少。 雖然抽象化是讓程式簡潔又有彈性的關鍵,但出乎意料的這是一個容易理解卻很難精通的能力。抽象化做得太少,程式會變得凌亂不堪,不同層級的概念和資訊互相交雜在一起,不僅讓程式變得難讀也難改。抽象化做得太多,就是所謂的over design,明明需求只有印一個Hello World,卻用了10種design patterns蓋起101大樓以應付根本就不會出現的「未來需求」。 抽象化這個主題可以講三天三夜講不完,但今天我只想提其中最簡單也最難的事:「命名」。 命名可以說是寫程式時最簡單但也是最難的事了。這件事沒什麼人會教,沒多少書會寫,因為這件事看起來非常容易,即使你把程式裡的變數照字母順序a, b, c, d, Continue reading

八月 31, 2010
» 42年的鴻溝 – Dyna Book與iPad

昨天睡前心血來潮翻了一下《世紀末軟體革命復刻版》,這本我一直非常喜愛的經典書籍。(註)意外翻到書中提到Alan Kay在1970年代的Xerox PARC(Palo Alto Research Center)提出Dynabook概念的那段歷史: 曾經有好長一段時間,電腦給人的印象是處理複雜運算的龐然巨物,CPU龐大不說,磁帶機、終端機…硬體設備本身便以大著稱。這些「巨物」處理的事務也是龐大的:大量的數據、大量的資料…。電腦是不折不扣的資料處理機,和人們的生活其實是八竿子打不著邊的。 1969年,一位Ohio大學的研究生Alan Kay提出了一個構想:他希望創造一「本」可以帶著跑的電腦,並且利用電腦的資料儲存和運算能力,模擬甚至取代現有的紙跟筆。這台電腦的理想體積要和紙張的筆記本相近,能夠用它來從事寫作、繪畫、個人行程編排或是財務管理、通訊,或者是用它來取代傳統的教科書等「死板」的文字。 如果書本不再只是單向地灌輸知識,而是能對讀者的迴響做出反應(從最簡單的回答問題的正確到複雜的全文檢索等),甚至讓讀者也參與創作的過程(例如透過網路,作者可以和讀者交流,而在「筆記本」上的內容可以隨時更動),那麼我們所得到的,將是一個和當時截然不同的文化 – 對「電腦」的概念不同了,以往對「書本」、「資訊」的概念也將翻新。Kay把他理想電腦稱作Dyna Book,是「動態」的「書」,而不是xx computer,等於不再把電腦當做「電腦」了。 這段歷史我很久以前就知道了,但我一直以為Dyna Book的概念是更接近於筆記型電腦的東西。但昨天看到這段文字時,我卻有了完全不同的感覺,心裡異常的激動,因為這段文字描寫的Dyna Book,似乎更像另一個東西,一個直到今年才出現的東西。上網查了一下Alan Kay當初的論文,看到這圖我才明瞭,原來Dyna Book的設計根本就不是電腦!! 1968年Alan Kay的Dyna Book,其實就是2010年Apple iPad的原型啊。 看到這讓我不禁感嘆,1970年的Xerox PARC真是個傳奇性的研究單位,從以太網路(Ethernet)、最早的個人電腦Alto、圖型使用者介面(GUI)、物件導向程式設計(OOP)和第一個物件導向語言Smalltalk都是在這被發明出來的。(附帶一提,GUI、OOP、Smalltalk的發明人其實都是Alan Kay。)可是Xerox畢竟是個做影印機的公司,PARC做出了這麼多驚世發明,雖然跟影印機都沒關係,但不論哪一樣東西持續發展下去都大有可為,結果Xerox就這樣讓這些概念被Apple和Microsoft免費拿去創造了現今的電腦王國…。 但話說回來,即使在70年代Xerox就投下資源去做Dyna Book,結果也一定不會成功。對當時的環境來說,Dyna Book的概念實在太過先進,能實現這個產品的軟硬體技術都還不存在。除此之外,當時的電腦是只有大型企業或是尖端研究機構才會有的東西,大眾還沒辦法接受每個人都需要一台有「運算能力的機器」(computing device)這件事。即使到了1993年,那個個人電腦才剛開始普及的時代,Apple推出的Newton(最早被稱為PDA的機器,話說回來也還是想實現Dyna Book所描繪的遠景),最後也是慘淡收場。 商業界有本很有名的書叫「跨越鴻溝」(Crossing the Chasm)。這本書的核心概念是說一個新科技被接受的時間可以分為五個時期,過了最早的創新期後,要先讓一群對新科技比較敏感及狂熱的「早期接受者」(early adopters)接受後,再來才能大量擴張到「早期的主流大眾」(early majority)。但很要命的是在early adopters這個區域有一個巨大的鴻溝,如果一個創新的科技不能得到夠多early adopters的支持,就會直接跌落谷底而死亡。 Dyna Book在1968年前提出的概念,一直到2010年才真正實現並跨過鴻溝讓主流大眾接受。不知道該說是Alan Continue reading

七月 23, 2010
» iPad電子書及電子漫畫閱讀軟體試用心得

最近買了iPad,老實說主要的目的是拿來看漫畫。在美國待久了最惆悵的就是很難找到中文漫畫看,現在在加州還算好,10 mile內就有一家中文漫畫租書店,但在Boston則是想都別想…。所以iPad出來後我就一直很關心拿來看漫畫的效果如何,結果之前看到了Apple IPad 漫畫迷的褔音 (含開箱及漫畫測試多圖)這篇文章,就讓我決定要來試試iPad到底能不能滿足我長久缺少漫畫灌溉的心靈。 我總共試了GoodReader、CloudReaders、Bookman、iBunko HD、iBooks這五個app。上面那文章還有提到一個Comic Reader Mobi,但據說作者之前對Apple耍了點小花招,結果被懲罰下架一年,所以現在根本就買不到了。(花15塊買的人不知道做何感想……) 這五個軟體我本來是最看好iBunko HD(他也最貴,$5.99讓我猶豫了挺久才買的),但全部試一輪下來還是覺得免費的CloudReaders拿來看漫畫最好用。 無奈CloudReaders的介面實在不太好看,讓我很想去問這個作者能不能幫他免費改寫一下,還是我乾脆自己來寫一個算了。 (本來想說花點錢買iBunko HD應該就能滿足我,但結果他很致命的不能直著讀一次掃兩頁的漫畫… 唉,為什麼ipad軟體不能要求退錢呢) anyway,下面是試用心得的簡單記錄,就分享給有興趣的人參考了。 GoodReader GoodReader(itunes連結)是超級強大的檔案管理和閱讀程式,除了PDF外也能看Office或是iWork的檔案,但偏偏就是不支援jpg.zip,就變得不太適合拿來看漫畫。但如果要看其他格式的文件或是看Google Docs上的文件,GoodReader是非常好的選擇。 優點: 超強大的檔案管理功能,一般電腦上能做的他幾乎都能做 可直接從Web下載檔案(內建瀏覽器) 支援超多格式txt, pdf, doc, ppt, xls, iwork 08/09, HTML, Safari webarchives 可從Mail server, MobileMe, Google Docs, Dropbox, WebDAV server, Continue reading

五月 25, 2010
» 為什麼我用Mac

這篇文章其實已經醞釀很久了。起因是前幾個月看了tinyfool的为什么我认为每个程序员都应该用Mac OS X?youxu的开发人员为何应该使用 Mac OS X 兼 OS X 小史,我當時就很想順便分享一下我的經驗,但那時忙著Sikuli實在沒法靜下心來寫文章,直到最近稍微閒下來了才又想起這件事。

我從2005升上研究所前買了第一台Mac mini到現在已經五年了,說起來其實沒有很長,但自從2005年起,我就成了非Mac不用一族。但用Mac是一回事,我要先澄清我不算是狂熱的Apple粉絲,我除了Apple的電腦外,只有跟朋友以超低友情價買過一台開學優惠送的ipod touch來玩,除此之外,我沒有iphone、沒有ipad、也沒有Apple鍵盤滑鼠以外的周邊產品。在2005年以前,我高中和大學約6年都是用Linux作為主要工作環境。我一路從Slackware、RedHat、Mandrake(後來改名Mandriva)、玩到Debian、Ubuntu,那段時期我有數台24hr online的Linux server,還換過3台laptop,但都是裝Linux。在更之前呢,從國小的386 PC算到高一將近10年就是用DOS和Windows了。

這篇文章主要想分享的是作為一個programmer使用各種作業系統開發的經驗,不是想要說服大家全改用Mac。雖然從時間上看起來我用DOS和Windows最久,但我真正開始大量寫程式是國中開始用Visual Basic的事,所以我在DOS和Windows平台的開發經驗其實算是最少的。而大學階段是我最密集寫程式的時候,所以我的經驗和使用的工具也都是以UNIX派的為主,不見得適用所有人。

我在DOS+Windows、Linux、Mac這三大主流平台上都混過一段時間,這個遷徙的歷史其實也代表了我個人心態上的轉換。

在剛開始學電腦的時候,我是純粹的使用者。我用電腦玩遊戲,國中幫老師用excel做全班的成績單,閒來無事就隨手玩玩photoshop、3D studio等軟體自娛娛人。我記得在386的DOS時代要玩個遊戲還挺不簡單,雖然很多遊戲都說只要打play.bat就可以玩了,但事實上總要修改config.sys和autoexec.bat裡的一些記憶體或音效卡的設定才能玩。所以那個時代的使用者其實大都是玩家級的人物,多少都對Adlib、EMS、XMS、可恨的640K限制有些了解才有辦法「玩」電腦。

國中開始寫程式之後,我的心態就不太一樣了。像一般玩家般玩電腦已經不能滿足我,我開始熱切的想了解電腦內部運作的一切原理,想了解每個程式是怎麼寫出來的,每個零件是怎麼運作的,每一個細節我都想知道。而我剛好就在這段時間接觸到Slackware Linux。

Slackware Linux其實是一個不太好用的Linux distribution,可能很多人也沒聽過它。現在的Ubuntu和Windows沒兩樣,一直按「next」就能裝完整個系統並開始使用。但那時的Linux裝完後可是「什 麼 都 沒 有」。沒有X11,更別提其上的GNOME或KDE;文字編輯器只有vi(不是vim)和joe;沒有make、沒有gcc、…,總之,真的什麼都沒有。那個時候裝Linux其實是為了自己架MUD server,但當時Linux的安裝教學都說裝完的一件事就是自己重新compile kernel。(因為預設的kernel很陽春,幾乎什麼driver都沒有,不自己compile的話很多硬體都動不了。)其實當時我覺得這還蠻酷的,make config打完出現數百個選項可以慢慢勾選,讓我這種想要一窺作業系統裡面在搞什麼鬼的人非常過癮。(一開始我還不知道有make menuconfig可以用,所以其中一個選項不小心選錯就會非常痛苦要整個重來……)但過了一段時間我就發現,MUD server沒架起來,但倒是很會重編Linux kernel和設定xf86config。

國中我還在用Visual Basic寫程式時,其實沒有注意到「平台」不同的影響,因為當時我只用Windows和VB寫程式,也不會其他語言,更不用提在不同平台寫程式。一直到上高中學了C,開始寫比賽的程式時,才讓我注意到Turbo C和gcc雖然都可以compile C的程式,但有某些header檔(像是conio.h)是只有Turbo C中才能用的。發現這件事後,我才突然搞懂library是什麼,還有Linux下有一堆libxxxx及libxxxx-dev的套件是在做什麼的。

Windows和Linux的關鍵差異 – 資訊透明度 – 也就在這裡顯現出來。在我學VB的時候,我把當時一本VB5的經典書籍從頭到尾全讀過了,但我竟然對library一點概念都沒有。我以為我能用的東西就是VB提供的那些元件,後來我多學了一點後發現我還能呼叫Windows API做一些VB辦不到的低階功能,我從來沒想過要去利用別人已經寫好的程式和函式來節省自己的開發時間。簡單說,我以為要造一輛車子,就是要從輪子甚至是螺絲釘自己做起。

某方面來說這是個好事,因為我的第一個VB遊戲「黑白棋」,就是這樣一個個pixel從無到有自己畫出的。但如果要寫更大的程式,每次都從輪子做起就不是個好主意了。接觸到Linux後,我也學了很多open source界的「哲學」,其中最重要的就是重用別人的輪子。

記得很久以前在Redhat和Mandrake上裝軟體非常痛苦,雖然每個程式都被包裝成一個RPM檔,但RPM之間的相依性常會讓人發瘋。每裝一個軟體都有可能會跳出數個相依的library或套件需要安裝,然後使用者必須自己去找這些相依的RPM,更糟的是這些相依套件可能會沒完沒了的依賴更多其他的套件…。(還好後來改用Debian就不用再被這個RPM地獄折磨了。)

這個過程讓我深刻的體會到,軟體應該是像金字塔一樣一層疊著一層往上蓋的,Linux套件的包裝方式清楚的讓使用者能夠看出來一個軟體是利用了哪些library建構起來的,如果自己想寫有類似功能的程式,很容易就可以找到相關的library來用。但在Windows下就不是這麼一回事了。Windows的軟體是為end-user設計的,目標使用者很可能什麼都不懂,所以發佈軟體時應該要把所需要的library或套件全部包進去變成一個龐大的自動安裝程式,使用者只要一直按下一步就可以裝完了。這讓使用者變得比較輕鬆,但同時也一些對開發者有益的細節也隱藏起來了。

Windows的軟體大多是完全不透明的,安裝時你不知道它裝了什麼,也不知道它寫了什麼到registry,更別提要知道他的某某功能是怎麼做的。但Linux是在另一個極端,每個程式的一切都是透明易懂的,RPM或DEB套件裡有什麼東西一個指令就一清二處,每個套件需要用到哪些相依套件也是明明白白。此外,Linux下的設定檔都是純文字,只要文字編輯器就可以修改,不但方便編輯,也方便寫自動化的script或是備份系統。當然,更不用提Linux下幾乎所有程式都是open source的,只要有興趣,隨時可以打開每天在用的軟體的source研究它是怎麼做的。這些事情在Windows底下則是天方夜譚,所有的細節都被自然的包裝和隱藏起來了。這種透明度的差異對於充滿好奇心的程式設計師會產生南轅北轍的影響,當你接觸的東西越開放,就能自然而然接觸和學習電腦從裡而外的各種知識;但當你接觸的東西越封閉,就只能受限於黑盒子的限制而當個單純無知的使用者。

高中時轉到Linux作為工作環境還有另一個很大的原因:「效率」。Linux的世界是架構在文字設定檔和command line工具上的,整個OS的操作都可以用command line解決。更方便的是搭配shell script或是Perl、Python這種script language,可以輕易把系統裡各種小工具結合起來完成複雜的工作。command line有個很大的好處,你每天用的操作介面,和寫自動化script的介面是完全一樣的。也就是說,你只要把每天打的指令串起來放進一個檔案,就自然變成了shell script,而日後只要執行這個script就能自動完成需要一連串指令的工作。這種工作方式滿足了我身為一個「懶人」的慾望,因為我懶得每天用手親自重複做同樣的事情,所以我寫script將這些事自動化。當script寫的越多,就會面臨越複雜的工作,這時就會想要學更多”UNIX power tools”的用法(這是O’REILLY的一本好書)或是更強大的「黏合」語言(像是Perl)來組合不同工具。透過這種正向循環,可以不斷刺激自己提昇工作效率:事情做得越快,就可以想得更多,解決更複雜的問題,進而就能學得更多,做得更快。

大學那幾年我成了虔誠的Linux command line信徒,不管是什麼樣的事情我都可以用各種小工具加上Perl或shell script來解決,而Windows在這方面就完全比不上Linux。Windows的哲學是一套軟體可以做N種事情,但如果你想做的事情不在它原本設計的功能裡,只能兩手一攤什麼事也做不了。

資訊的透明度和command line帶來的高效率讓我非常享受在Linux上工作的樂趣,然而Linux也不是沒有缺點。當我學得越多,對系統底層的好奇心漸漸被滿足後,Linux的缺點就漸漸暴露出來,其中最讓我受不了的是殘破不全的driver支援。讓我印象最深刻的是在802.11b無線網路剛開始流行時,我花了很多時間在找driver和當白老鼠compile最新的driver,重編kernel幾乎是每日例行公事。除了無線網卡外,就算是有線網卡Linux都不見得支援,最惡名昭彰的莫過於Dlink系列的卡,他們的530TX甚至還被暱稱為惡魔卡。(這張便宜的卡在當時非常流行,但偏偏在Linux上就是不能用…)

雖然我是個programmer,但我同時也是一般user。在我想要快樂用電腦看電影或上網時,還要不時的處理系統內部的問題其實有點惱人,更別提當我只想寫一般的桌面程式或是Web app時,為什麼我還得跟Linux kernel奮戰呢?

除了硬體相容性外,Linux這種過於開放的平台還有個大問題是缺乏統一且一致的user experience design,導致usability常常奇差無比,而這也是很多open source軟體普遍共有的問題。程式設計師在乎的是功能面的設計,每個人做自己想要或喜歡的功能,雖然看起來和樂融融,但很少project有專門的團隊負責思考user是誰,他們想要什麼,以及他們會怎麼用這個軟體。同樣的功能但由不同的介面呈現,帶給使用者的感覺也會有天南地北的差異,而由千百個open source軟體拼湊起來的Linux系統帶給使用者的就是千百種不同的設計和使用方式。(後來Ubuntu的出現大大的改善了這個問題,但那時我早已跳到Mac上了…。)

就在Linux的缺點慢慢浮現後,我同時也注意到身邊很多FreeBSD/Linux hacker們開始改用Mac OS X。深入了解後,我很快發現Mac是一個完美解合Linux的效率和開放,同時又兼顧了精心設計過的user experience design的平台。Mac作業系統核心是BSD的近親Darwin,上層有跟Linux相同的command line shell,所以我以往在Linux慣用的設定檔和程式(bash、screen、vim…)全都可以直接帶到Mac上使用。(更棒的是還能像在Debian下一樣用apt-get install或是port install一個指令就自動裝完所有相依套件)

而在command line的上面則是Apple設計的GUI系統,美觀、一致、充分為使用者「設計」過的介面,輕易的就打敗我在Linux上較調半天的FVWM設定。(我換過和較調過無數的window manager,從enlightenment、GNOME、KDE、Window Maker、FVWM…)除此之外,我也不用再自己重編kernel和找driver,每一台Mac都是買來後一打開就能用了。

後來Mac用久了,漸漸發現更多Mac的好處,尤其是對於programmer而言。

每一台Mac都有附Mac OS X的安裝光碟,裡面同時附帶Xcode。而只要把Xcode裝上去後,我整台Mac就已經準備好可以讓我工作了。Xcode是Apple開發的IDE,可以開發各種常見的程式語言,但其實我不用這個。我都用Xcode底層的command line工具,像是gcc、make、svn,加上OS X內建的screen、vim、perl、python、apache(只用這些的話其實連Xcode都不用裝,每一個OS X都內建),我就有了完整的程式開發環境,而且我甚至還不需要連上網路就可以有這些。除此之外,Xcode裡還附帶很多好用的開發、除錯工具,像是我最愛的Shark(非常好用的profiling和memory debug工具)、或是Malloc Debug(找memory leak的好東西)、BigTop(監看每一個process耗用的資源記錄)。

自從我轉到Mac後,後來因為需要寫跨平台程式而切到Windows時,都覺得極端痛苦。因為Windows是給一般使用者的系統,而且所有程式都是獨立分開的,每次光要把開發環境準備好就要先耗上一整天在下載和安裝。後來我學乖了直接裝cygwin弄一個假的UNIX環境出來,但cygwin畢竟還是跑在Windows上,系統設計的哲學不同讓cygwin還是格格不入。(像是Windows就是沒有用文字檔存放系統設定,所以也沒辦法用一般的文字工具自動操作;Windows也沒有提供夠多的command line工具可以控制系統;Windows也沒有符號連結(symbolic link),我之前想用Bazaar check out一個有符號連結的repository就爆炸了…)

從Linux轉到Mac,讓我可以花更多時間專注在我想寫的程式上,而不是拿去研究driver的相容問題,或是Linux kernel新增的設定選項。對於一個應用程式或網頁程式的開發人員來說,這些底層的細節都是不重要的。雖然說Windows也把系統底層的細節藏起來了,但它實在藏的太徹底了。萬一偶爾需要看系統底層的訊息來debug,在Mac上還是跟Linux一樣直接到/var/log下grep一下就有了,但在Windows上除了「回報給微軟」外,也沒太多辦法可以自力救濟。

Mac上很多設計也改變了我使用電腦的方式。例如說QuickSilver讓我可以用鍵盤快速啟動任何程式,甚至是做更複雜的操作。Spotlight讓我不再需要思考怎麼把檔案文件分類整理到不同folder裡,需要什麼就像用google一樣只要直接用spotlight找就好了。Mac上的繪圖、設計軟體都有很貼心的設計,例如OmniGraffle的自動對齊線,可以幫忙使用者輕易設計出平衡、一致、美觀的圖像、網頁、或是圖形介面。Mac上幾乎什麼都可以自然地用drag and drop操作(例如Safari很早以前就可以把檔案拖到網頁裡上傳),但很奇怪Windows上就是有些地方可以有些不行。

整體來說,Mac是一個融合Windows和Linux雙方優點的平衡點,我可以像一般使用者一樣不費心力的操作電腦,也可以用高效率的command line處理複雜的任務,甚至是在需要的時候扮演hacker挖掘底層的錯誤訊息,或是利用Darwin Ports安裝和修改我需要的open source軟體。但除了Mac外,其實我還是有在用Linux,只是都跑在遠端的server上而已。主要原因是在沒有圖形介面時,Mac就沒有什麼優勢了。所以到現在即使我的laptop都改用Mac,我也還是會有一個terminal連到我的Linux server上。(雖然說主要是拿來掛IRC和BBS的…)


五月 7, 2010
» Do the right thing and do the thing right

這學期糊里糊塗的就忙過去了,回頭看看blog,學期中竟然連po篇文章的時間都沒有。(順便跟有留言的讀者道歉,之前太忙也沒時間回,留言似乎就這樣積到喜瑪拉雅山上了….)

因為畢業前一定要做一次助教,剛好老闆這學期開課人少不夠,就被拉去做助教了。在MIT做助教還真不是普通花時間,難怪拿的薪水比之前做RA還多。在這當助教一學期後,有個簡單的心得:全天下的學生其實都沒兩樣,MIT的學生也沒有比台大的學生厲害。以前在台灣當鄉民,聽過很多外國月亮比較圓的謠言,最經典的像是「美國大學生都不蹺課,因為學費很貴」(才怪XD MIT學費一年三萬多美金,蹺課的也多的是),「美國名校學生都強如鬼神,人人考試都100」(才怪XD 考試出來成績也還是常態分佈;期末project也一堆做得亂七八糟,能讓人眼睛一亮的一隻手都數不滿。)

以前我也在台大當過助教,相較之下,兩個地方能讓人眼睛一亮的學生比例其實差不多。這實在蠻令人納悶的,這兩個學校的學生原本也都是各地頂尖的「強者」,但被聚集在一起後,整體程度也還是回歸到常態分佈。(這就是所謂的人外有人,天外有天,一山還有一山高?)

觀察這些強者中的強者其實是蠻有趣的事,到頭來我覺得這些人其實也是普通人,一樣要吃飯睡覺,一樣有男/女朋友,一樣有各種千奇百怪的興趣。但唯一不同的是,這些強者似乎比較知道怎麼做「對的事」。

昨天我跟其他兩個助教加教授四個人馬拉松5個小時看了四十幾組的project demo,因為題目是各組自訂的,大家應該都是選了自己最有把握最有興趣的東西做。每一組都或多或少有做出點東西,有的組雖然做的功能很單純,但他們把這些簡單的事做得非常好;有的組雖然做了很多東西,但其實大多跟我們在意的重點沒什麼關係。

馬拉松一天後,晚上有個助教就收到其中一組的抱怨信。他們說10分鐘的demo時間根本不夠,他們花了很多心思把程式修到沒有bug,還花了很多時間做了功能A、B、C、D、E,但成績竟然不到全班平均。

收到這樣的信其實還蠻囧的。他們其實不是做得不好,只是根本沒搞清楚重要的事是什麼,所以雖然花了很多力氣,但方向完全就搞錯了,不重要的事做到200%也不會變重要。此外,更糟的是他們一直都沒有意識到哪裡不對了,所以才理直氣壯的來討分數。反觀能讓人眼睛一亮的組,他們一開始就花了比較多力氣確定要做什麼才是對的,一旦確定後,雖然做的事情可能比較小,但因為做了「對的事」並且也把事情「做對了」(do the right thing and do the thing right),成果就能讓非常人印象深刻。

一個最好的現代例子莫過於twitter。twitter的功能實在簡單到不行,在web 1.0甚至bbs時代就有一大票功能遠強過twitter的留言板或論壇網站,但twitter卻異軍突起了。原因很單純,twitter選擇了幾個對的事(WEB+限制長度的短訊+公開API),然後把他們做到最好。

Do the right thing and do the thing right雖然是很簡單的概念,但令人意外的,即使在世界上可能是天才密度最高的地方,卻還是只有非常、非常少人能同時做到。


五月 6, 2010
» Use Clipboard to Extract Text with Sikuli

Sikuli 0.10 has added tons of cool new features. Now it is easier to write smarter scripts to do more interesting and useful tasks than you can ever imagine. Here is one of my favorites. The original idea of this script was contributed by RaiMan, one of the most active Sikuli users. I simplified it a little bit and made a video to show how it runs in a real environment.

The source code of the Sikuli script that downloads a bunch of files.

The script to download a bunch of files.

The goal of this script is to download all ZIP files whose file name starts with “Sikuli-IDE-osx” in a web page. To find all ZIP files is easy, because they have an identifiable icon. However, we can’t simply click on the icon. We need to click on the hyperlink next to the icon, instead. The really tricky thing is, how to know a hyperlink that starts with “Sikuli-IDE-osx”?

The simplest solution is capturing a screenshot of the text “Sikuli-IDE-osx”, and putting the screenshot as the parameter of click(). Unfortunately, this way is not really robust since the images of text only have tiny differences. Sikuli’s fuzzy image matching engine may treat “S1kul1-1DE-esx” as the same as what we want. So, a right way to do this is – extracting the text from the web page.

You may recall that there was an ancient technology named OCR (Optical Character Recognition), which recognizes text from scanned books. However, current OCR engines do not really work well. They are slow and inaccurate.

In fact, even without OCR, we still can extract text from the screen using Sikuli.

How?

Use the clipboard!

The following script tells you how to do that. At first, we use Sikuli to find all locations of the ZIP icon (line 7). On line 8, we sort the list of the matched locations by their y coordinate, it’s not necessary though. The key steps are line 10 and 11. We click on the space between the icon and the hyperlink next to it using the new target offset attribute of a pattern. (denoted by a small red cross in the ZIP icon on line 7. See the figure below for its setting window.)

And then we hold the mouse button and drag to the location 600-pixel right to the center of the icon. This step (line 2) actually simulates using a mouse to select a line of text with a dragDrop(). After the selection, we simply press Command+C (Ctrl-C on Windows) to copy the selected text into the system clipboard.

Copy (extract) text from a browser.

Aha! We got the precise text in the clipboard. :)

The rest of the script are trivial. Sikuli 0.10 provides a new API Env.getClipboard() to get the content of the system clipboard. We can use this function to get the text of the hyperlinks and then use Python’s string function (startswith) to filter out the files we need.

I also made a tiny video that shows how this script looks like when it is running.

biggo.com.tw

A Django site.