Uncategorized


Sikuli帶來的意義與無限的潛力

Saturday, January 30th, 2010

這禮拜真是我人生中最瘋狂的一天了..。

自從Sikuli發表後,我本來還打算一封封回覆所有的問題,後來發現排山倒海而來的郵件和留言速度遠大過我能閱讀和回覆的量。前幾天我優先把Sikuli比較大的bug和一些平台問題修掉,昨天釋出了0.9.7讓各平台都提升到同樣的版本(只剩Linux還是沒有抓圖的快捷鍵了),整體運行的速度也提昇了不少,並且新增了一個.skl格式讓人能透過command line或double-click直接執行script。如果之前下載過舊版的朋友強烈建議升級到0.9.7。

修完緊急的bug後,我們會再陸續補上一些文件和教學,說明一些常見的問題要怎麼解決。例如說,畫面上有多個一樣的元件(像check box, radio button)要怎麼處理如果按特殊鍵或是在不同的鍵盤排列上使用(用dvorak的人還真不少,一堆人跟我說type()在dvorak上會有問題)..。

但這篇文章中我想談的不是被上萬人盯著的壓力,而是關於Sikuli能帶來的改變,以及未來的潛力。

有些人說Sikuli看起來只是另一個按鍵精靈或是AutoHotkey,但其實Sikuli還有許多在這個直觀意義之上的潛力我們沒直接說出來。

第一,Sikuli最重要的革命是程式碼的可讀性(readability)和易用性(usability)。把螢幕截圖直接放在程式碼裡面,讓人能直接「看到」他想控制的東西,這是從來沒人想過的事情。以往的方法,不管是透過應用程式自己的程式介面(API)或是透過XPath拿到網頁裡的某個元件,都是只有程式設計師才能寫、才能讀懂的神秘外星語言。機器喜歡精確的語言,人類花越多力氣把事情描述的越清楚,機器就越容易讀懂。

可是,有沒有人想過,人類發明這麼多程式語言來操控電腦,究竟是便利了人類還是便利了電腦?現在我們每天用的程式語言,不管是C++、Java、C#、Python、Javascript..都是只有程式設計師才能寫才能讀的語言。更諷刺的是,這些「現代」語言跟五十年前就有的LISP、Fortran本質上並沒有什麼不同,一樣都是純文字,一樣要求精確嚴謹的語法,一樣是架在百層高塔的系統架構上。即使是訓練有素的程式設計師,要寫程式做些有用的事情也都得先翻翻充滿黑話的說明文件,看看需要的功能對應到什麼函式,運氣不好可能還得學個COM+之類的鬼東西才能使用。

如同我在追求神乎其技的程式設計之道(十):程式設計師的生產力之謎中提過的一樣,即使同為程式設計師,運用電腦的效率依然會有數十倍甚至百倍的差距。如果每天都要按一百個按鈕,程式設計師可以找到適合的命令列工具使用,或是自己寫程式呼叫應用程式提供的函式,就可以用一個按鍵取代這一百個按鈕。那完全不懂程式的一般使用者呢?恐怕只能兩手一攤任由別人寫好的軟體擺佈。也就是說,即使一個人掌控了鍵盤和滑鼠,但實際上卻是被別人的軟體限制住,如此使用電腦其實完全沒有自由可言。

Sikuli的革命把寫程式的門檻降低了,人們和系統或應用程式溝通不再需要讀用黑話寫的文件,也不用搞懂底層的架構是怎麼做的,只要把平常使用鍵盤滑鼠的方式,再加上想控制目標的螢幕截圖,就可以輕易寫成能自動執行的程式。

Sikuli Script範例

除了好寫外,任何人看程式和圖都能很容易讀懂程式到底做了什麼事,於是Sikuli很自然就能成為一種寫教學文件的最佳媒介。以往的教學文件常常step by step列出使用者要做的事,加上使用者應該要看到的畫面,很巧的是這兩者Sikuli script都有。但比傳統的文字描述更好的是,只要把Sikuli的指令混用在文件中,或是透過簡單的對應把文字描述轉成script,這樣一份文件不只人能看懂,連電腦都能執行這些步驟並且一步步告訴你要按的按鈕在哪裡。

第二,除了直觀上的GUI自動化外,其實Sikuli更重要的意義是提供了一種把使用者操作UI的互動過程記錄下來的新方法。以程式設計師的黑話來說,這可以說是GUI操作過程的serialization,如果用一般人的方法說,這就是把人機互動過程「數位化」的一種方法。

電腦發展的過程中,一條必經之路就是把人類周遭的一切資訊全部數位化。一旦資訊被數位化,就可以輕易儲存在電腦裡,或是透過網路分享給別人,電腦科學家也才能發展更多方法來處理、分析、運用這些資料。在21世紀的今天,人們把聲音、影像、文字全都數位化了,所以我們可以輕易的複製、傳播、使用這些資訊。但在人們如此依賴電腦的今天,人和電腦的互動過程其實一直沒有一個好方法可以記錄,所以更別提要複製或是分享這種互動過程。

而Sikuli在這個人機互動領域開了一條全新的道路,這也是為什麼Sikuli的論文是出現在「User Interface Software and Technology」的會議上,而不是在討論程式語言的會議上。

人機互動的過程一旦能被一個標準的方法記錄下來,接著就能複製,就能分享,就能讓電腦自動執行或是演算這些過程。未來的應用方式有千百種,唯一的限制只是看我們的想像力而已。

第三,Sikuli把電腦視覺的研究領域,從真實世界延伸到電腦的桌面上。這點說起來真是很有趣,電腦視覺的研究人員數十年來嘗試想讓電腦能像人一樣「看」這個「真實世界」,可以像人一樣認得別人的臉,或是認得馬路長什麼樣才能讓電腦自動開車,但卻沒什麼人想到讓電腦「看」電腦自己輸出的畫面。在技術上來說,電腦螢幕上的資訊全都是電腦自己產生出來的,沒有光影問題,沒有角度問題,辨識上的難度遠低於真實世界所需的難度。以現在的電腦視覺技術來說,辨識螢幕上的東西簡直可以說是殺雞用牛刀。

Sikuli把電腦視覺和人機介面兩個研究領域打通了,有很多古老的問題(例如OCR,文字辨識)在真實世界很難解決,但在電腦桌面上卻可能可以發展出又快又準確的方法。Sikuli也可能激發更多人把電腦視覺應用到軟體介面上的創意,讓使用者介面不只是簡單使用,也能讓每個人能真正隨心所欲的操控電腦。

第四,建立在Java平台上並且open source的Sikuli,很有潛力能讓每個人都能打造給自己的專屬程式。

Sikuli不只是提供了一堆自動按滑鼠和按鍵的指令集而已,每一個Sikuli script都是一個和Python語法相容的程式。這意味著你可以使用任何的Python語法,不管是迴圈、if、定義function、或是定義class,每一個Sikuli script都是一個真正的Python程式(嚴格來說,應該是Jython,但這中間的差別並不太重要)。除此之外,Sikuli核心是跑在Java平台上,所以可以輕易的使用任何Java的函式庫。例如說,你可以用swing建立一個新的視窗包含了兩個按鈕,按下第一個就用Sikuli執行每天上班前的例行工作,而按下第二個紐則執行下班前的例行工作。會寫程式的人可以輕易混用Sikuli和現有的函式庫,把Sikuli當成和系統或其他應用程式溝通的媒介,並在上層建立自己的新介面。也就是說,這就是桌面環境的mashup,可能的應用是無限大。

雖然不懂程式設計的人,難以撰寫複雜的GUI程式或是資料處理。但Sikuli結合了現有的平台並且open source,這樣的好處是會有來自世界各地有閒有能力的人幫忙讓Sikuli變得更簡單更好用,並結合其他的程式語言或是函式庫讓寫程式的整體門檻大大降低。

雖說Sikuli現在還不是那麼完美,但我相信open source會加快Sikuli的發展,讓更多有興趣的人進來幫忙。很多技術上的問題其實都好解決,例如有人問到是不是桌面換個skin後script就廢了,或是能不能在背景執行script。這些問題其實都有好幾種可能的答案可以解決,只是有沒有必要現在就做而已。技術問題向來都不是能阻擋我的絆腳石,真正困難的只有突破自身創意和想像力的界線而已。

每個人使用電腦的方法都不同,軟體公司設計的軟體也只能按照大部分使用者的需求和習慣所設計。但不論有多少功能,總是不可能涵蓋到每個人的大大小小需求。讓每個人都能寫程式(不論他們是不是知道他們正在寫程式)是我一心嚮往的目標之一,或者說是我希望每個人都能100%按照自己的意願花最少力氣完成最多工作。但在今天的電腦環境上,不會寫程式就有太多事都無法做到,即使會寫程式的人,也不見得願意花那麼多力氣去研究讓自己未來更省力的方法。

這個問題的癥結不在於使用的人太懶惰或是不夠聰明,而是電腦太難用。一個人得經歷幾年的訓練才能熟悉這種用程式「掌控」電腦的感覺,實在太不合理。或許沒有人想研究讓寫程式變得更簡單是因為怕丟了自己的飯碗,但我偏偏就覺得每個人應該要有聰明使用自己工具的自由,而不是反過來被工具限制了自己。所以,我希望Sikuli能讓更多人把使用電腦的自由搶回自己手中,而不是被軟體工程師們掐住脖子動彈不得。

寫到最後,能參與Sikuli這個project其實最需要感謝的人是和我合作的Tom Yeh,在我進MIT前他就在跟我老闆Rob Miller討論用螢幕截圖來搜尋文件的可能性,所以其實在我還在當兵時我們就已經搭上線開始合作了。後來我到了MIT後,一連串的討論就激發出許許多多混合螢幕截圖和電腦視覺所產生的點子,其中第一個成果就是現在的Sikuli。

Sikuli Script只是這一串研究的開端和基石,在這之上其實我們還做了很多東西。例如說我們已經有一個能錄製螢幕和使用者動作的程式,可以把使用者的動作自動轉換成Sikuli Script,也就是說使用者一行程式都不用寫,只要把想做的步驟做一次,程式碼和螢幕截圖就會自動產生出來讓你修改或直接使用。用這個錄製程式,我們可以輕易的在現有的GUI系統上觀看全系統的操作歷史,甚至是自動redo某一部分操作。有這些系統做基礎,我們能做的事情實在太多了,我只怕自己時間和能力有限,沒辦法把所有的點子都做出來。所以,這也是我們把Sikuli公開的目的,希望開放這塊寶石後,能有更多人發揮想像力發明出更有趣更有用的東西來,並徹底打破現今使用電腦的方法,一起來改變世界吧!

Change The World!

Monday, January 25th, 2010

之前一直沒機會跟大家分享我在MIT到底在做什麼研究,但拜登上MIT首頁的一篇報導「Picture-driven computing」所賜,我這兩年的project Sikuli像原子彈爆炸一般透過slashdot和twitter以不可思議的速度擴散開來。而這幾天,剛好碰上學校每年都會舉辦的滑雪三天三夜旅行,我照著計劃坐上遊覽車到四小時車程外的緬因州滑雪。第一天晚上到旅館發現沒網路可用,只好早早上床睡覺養足隔天的精神。到了隔天中午,在雪場的餐廳吃午飯時,我想說該來試試有沒有網路用,於是拿出ipod touch連上網後,沒想到迎面而來的是近百封關心sikuli的郵件。在震驚之餘,我還沒意會過來到底發生什麼事了,直到我看到一封來自跟我同實驗室的學長Michael發給實驗室所有人的信,標題寫著:「Sikuli on Slashdot!」,接著我才意識到:啊!原來是遭到slashdot effect攻擊了!(slashdot是全世界關心科技、網路、電腦技術的人幾乎必看的網站,只要某個網站一被登上slashdot,馬上就會遭到來自世界各地數以千計的閱覽攻擊,其效果等同於分散式阻斷服務(DDoS)攻擊,而這現象就被稱為slashdot effect。我以前都以為只有網站會有突然出現的巨大流量,沒想到連我的信箱也會…)

在這件事情之前,我從沒體驗過媒體和網路的力量可以有多麼驚人。從MIT News發出的一篇報導,隔天被轉載到一小部分科技、技術網站,並且在twitter上開始有人開始口耳相傳這個新玩意。再過一天,有人把這消息推上了Slashdot: MIT Offers Picture-Centric Programming To the Masses With Sikuli,很快的sikuli這名字開始傳遍世界。我在twitter上搜尋了sikuli,想看看人們都說些什麼,結果看到由各種不同語言寫的tweet不斷湧出,就在我還沒看完一頁時又冒出 「xx more tweets since you started searching」 的訊息。搜尋出來的tweets除了絕對多數的英文外,也看到很多俄文、法文、日文,反倒是中文的消息最少,實在讓我有點哭笑不得。(關於訊息的傳播,我也透過這次的事件觀察到不同國家對同一事件反應的一些有趣現象,以後再另寫新文跟大家分享。)

人在偏僻的山中滑雪,突然看到這麼多人們在討論著我的project,還有信箱裡塞滿各種關於sikuli的問題,讓我興奮得不得了。當時我的心情其實完全顧不得滑雪了,但難得的旅行還抱著電腦一直坐在餐廳裡實在也有點可惜,只好趁著有網路時把每封信大略瀏覽一下,下午就趁著坐纜車上山的空檔想想怎麼回覆這些郵件。

太陽下山後,我終於按奈不住卸下裝備就拿著電腦回到餐廳裡繼續連上網,結果又是更多的郵件湧入、更多的tweets、更多的衝擊。而當初把sikuli open source的決定,也讓我接到來自世界各地開發人員的意見和回饋,有人在一天內幫我把Linux上還沒實作的幾個功能寫完並送了patch給我,也有人為了在它的64-bit Windows上執行而直接hack了沒有原始碼的二進位EXE wrapper。除了寫程式的人外,有專業的user experience designer願意加入,也有人志願幫忙移植到Linux的工作。看著這些不知道什麼時候才能回完的信,我突然發現,我似乎真的做了一件不得了的事….。

在MIT裡其實常常能看到許多很驚人的點子,但可惜的是即使在MIT,大部分的東西也都停留在為研究而做的雛形階段,研究人員雖然產出了論文,但如果沒有對的人讀到那些文章,很多好點子也不過是停留在紙上變成可回收的資源而已。

Sikuli的論文其實在去年九月就在ACM關於user interface中最頂尖的會議UIST上發表了,在當時還拿了Best Student Paper Award,但為什麼一直到今天才突然爆發開來變成人們口中「革命性的新發明」呢?

說起來這還是得感謝MIT有自己的News office,一個記者剛好問了我老闆最近有沒有什麼有趣的研究,於是sikuli這個字就從這篇報導散播開來。但除此之外,我也蠻慶幸之前自己決定要把sikuli release出去,而且老闆也很支持我這麼做,整學期都沒問我「研究」上的進度。(把程式release跟研究本身沒什麼關係,有些教授對這些研究結果的實作是否能實用也不太關心,甚至覺得做這些事是浪費時間。)

其實一般人可能很難想像,要把一個研究用的雛型打磨到能夠公開讓任何人用的程度,所花費的力氣可是遠超過寫出最重要的核心功能。我花了幾個星期研究怎麼把Java程式包成Mac上的.app,研究怎麼把.sikuli變成能夠點兩下就打開的document package,怎麼把sikuli會用到的一大包dynamic libs包進.app中讓使用者不用安裝其他的相依函式庫…。搞定Mac後,我又花了一陣子把Sikuli移植到Windows上,雖然上層是Java寫的很好解決,但有部分程式碼是透過JNI連結到C++呼叫OS提供的API才能完成的。因為我一直都用Mac開發,所以這些東西本來都只有寫Mac版的,但為了要真正讓多數人能用這個軟體,只好跟老闆要了一台PC裝上Windows來完成這些相依平台的程式碼。Windows並不是我熟悉的平台,除了國中時玩過VB外,之後就幾乎沒在Windows上寫過什麼程式了。所以為了搞定Windows的移植,除了得速成學會一些Windows API外,還得搞定DLL+EXE的包裝,最後再包成installer讓人能一路按Next就裝完整個軟體。雖然這些事情我都是第一次做,但還好沒遇到太多困難,即使每個禮拜都要花兩三天寫Distributed Algorithms的作業,剩下的時間也剛好夠我處理完這些瑣碎的工作。

完成Mac和Windows初步的包裝後,我也一邊開始做網站、API文件,也請跟我合作的Tom一起寫了一些教學文章,順便讓實驗室的同學們當一下測試的白老鼠。因為周圍沒什麼人用Linux desktop(真是有點出乎意料?),所以Linux版就暫時被我擱著沒動。
後來大家都去放聖誕假期時,我趁著空閒做了一個demo的影片放到youtube上,但因為我也還不急著釋出public beta,所以也沒跟其他人說我做了這個影片。

就在MIT News來採訪的前幾天,0xlab剛好有幾個人突然寫信問我有沒有Linux版的sikuli。雖然不知道他們怎麼發現的,但看到有人想用我也就有了勁想把Linux版趕快完成。花了一天在我新要來的PC上裝好ubuntu後(還包含一個小時在搞定這台電腦的無線網卡driver…。沒想到到了2010年我竟然還在做這種事情…),再修一修Makefile後就包了一個功能不全的Linux版放到網站上。

有句話說「機會是留給準備好的人」。當sikuli被公諸於世的時候,之前做好的事情就突然就派上了用場。MIT News促成了這個好機會讓sikuli這個很酷的想法脫離UI研究會議的小圈圈,進入世界上有網路的每個角落,這時我之前憑著一股熱血就自顧自的作了這麼多的雜事,突然都有了它的意義。於是,在機會到來時,demo的影片加上能下載試用的軟體讓人們親眼看到並且能把玩這個革命性的點子,結果就讓twitter上充滿了一大片的「holy crap this is awesome! http://sikuli.csail.mit.edu」。

我一直夢想著要做些不一樣的事情來改變世界,徹底發揮我的長處做出能夠對世界產生巨大影響力的東西。還記得三年前我在申請MIT時,在SOP上大膽的寫了我的目標「I believe that programming environments should be smarter and more intuitive, and it is my goal to reinvent one that allows beginners to learn easily and adepts to be more productive.」,而三年後的今天,我非常興奮我踏出了改變世界的第一步。

給程式設計師的Vim入門圖解說明

Tuesday, December 8th, 2009

12-09 Update: The English version of Vim Visual Cheat Sheet is also available. PNG, PDF)

(更新: 在圖內加入基本指令表和說明以及PDF版,方便大家列印出來貼在牆上隨時查看。)

剛在寫那篇關於vi和文字編輯器的文章時,本來想附上一個vim的超簡單入門連結,但找了一下都沒有很滿意的,所以決定自己動手先來畫個入門用的說明圖。

vim-cheat-sheet-full
PDF版下載

vim-cheat-sheet-diagram

這個圖把vim中基本的移動方法都畫上去了,為了方便programmer,特別列出了很多只有寫程式才會用的按鍵。除了這些以外,其實還有一些好用的東西我還沒想到怎麼畫上去比較好(像是tags、沒有標準快速鍵的tab、man..),如果大家有idea歡迎提供。

這些圖示依照移動的單位大小分為以下幾個種類,分別用不同顏色標示:
(注意,這不是完整的vim快速鍵列表,只是我覺得比較常用的鍵而已。)

字元(character)
h
j
k
l
單字(word)
w
下一個word
W
下一個word(跳過標點符號)
b
前一個word
e
跳到目前word的尾端
行(line)
0
跳到目前行的開頭
^
跳到目前行第一個非空白字元
$
跳到行尾
段落(paragraph)、區塊(block)
{
上一段(以空白行分隔)
}
下一段(以空白行分隔)
[{
跳到目前區塊開頭
]}
跳到目前區塊結尾
%
跳到目前對應的括號上(適用各種括號,有設定好的話連HTML tag都能跳)
螢幕(screen)、絕對位置
H
螢幕頂端
M
螢幕中間
L
螢幕底部
:x
xG
跳到第x行(x是行號)
搜尋(search)
/xxxx
搜尋xxxx
#
往前搜尋目前游標所在的字(word)
*
往後搜尋目前游標所在的字(word)
fx
在目前行往後搜尋字元x
gd
跳到目前游標所在的字(word)的定義位置(寫程式用, 跳到定義變數/函式的地方)
分割視窗
:split
分割視窗(可加檔名順便開啟另一檔案)
:diffsplit xxx
以分割視窗和檔案xxx做比較(diff)
Ctrl-W p
跳到前一個分割視窗(在兩個分割窗來回切換)
Ctrl-W j
跳到下面的分割窗
Ctrl-W h
跳到左邊的分割窗
Ctrl-W k
跳到上面的分割窗
Ctrl-W l
跳到右邊的分割窗
自動補齊(Auto-completion) (在Insert Mode中使用)
Ctrl-N
自動補齊檔案內的下一個可能字(word)
Ctrl-P
自動補齊檔案內的上一個可能字(word)
Ctrl-X Ctrl-F
自動補齊檔名

[HCI] 淺談模式”mode”與文字編輯的技術與學習

Monday, December 7th, 2009

很久以前就想過要寫一篇關於文字編輯(text editing)的文章,當然我要講的不是要怎麼寫文章,而是關於使用文字編輯器(text editor)的技術。

文字編輯可以說是電腦歷史上最古老也最被廣泛使用的功能之一,無論是古老的mainframe或是現代的PC、Mac,甚至是手機,上面一定都有文字編輯的功能。人們每天都在用文字編輯器,不管是寫blog、打報告、寫程式,即使只是用twitter或plurk寫一句話,也都是在做文字編輯。既然這件事每個人每天都在用,還有什麼好談的呢?有趣的地方就在於,雖然大家每天都在用文字編輯器,但很少人會仔細去想要如何才能把這件事做得更快更好。怎樣的編輯器才是一個好用的編輯器?怎樣的編輯器用起來才能讓人感到行雲流水、人機合一的美妙境界?

我們先從一般最常見的編輯器說起。一個常見的編輯器就像Windows的記事本一樣,或是瀏覽器內預設的文字輸入區(textarea),支援游標移動/選取、新增/刪除/修改文字、複製/剪下/貼上、搜尋/取代等基本功能。這種常見的編輯器用起來很簡單,只要在鍵盤上打字就能新增文字,按下backspace或delete鍵就能刪除文字;用滑鼠點擊任何文章內的地方游標就會移動過去;複製、搜尋等功能可以透過menu bar找到,或是利用一些約定俗成的快速鍵(Ctrl-C, Ctrl-V..)就可以在編輯文章中快速呼叫這些功能。這種編輯器的特色是學習門檻很低,要記憶的只有一些特殊的快速鍵,即使不記得也能透過menu bar或是context menu找到。

如果用之前說過的usability來分析這種編輯器,大概可以知道這樣子的UI具有容易學習(高learnability)、不容易忘記(高memorability)、不容易產生Errors、一般用起來也不會有太大不滿(satisfaction)。一切看起來都很美好,唯一的問題是,這種編輯器的efficiency到底是好還是不好?

回答這個問題前,先繼續看另一種編輯器的設計,我們才能比較不同設計的好壞。

在1976年UNIX剛誕生不久時,出現了一個特殊的編輯器叫做vi。vi引入了一個很特殊的概念:模式(mode)。

vi和一般常見編輯器最大的不同在於它有兩種模式,命令模式(command mode)和插入模式(insert mode)。在命令模式下任何鍵盤輸入都會被解讀成送給編輯器的特殊指令,例如移動游標、複製/貼上、搜尋..等等全都是送給編輯器的命令。而在插入模式下,鍵盤輸入的字會被送入編輯中的文件內,這模式也就是一般編輯器預設的模式。

在HCI的研究中,模式(mode) 是一個很常被探討的概念。在不同的模式下,使用者即使給了相同的輸入,但系統卻會產生不同結果。日常生活中最常見的例子就是汽車的排檔:在D檔時踩油門車子會前進,但在R檔時踩油門車子卻會後退。而有多種模式的UI會帶來最大的問題是mode error,也就是使用者分不清或是忘記現在系統所在的模式,而得到了非預期的結果。這種error問題可大可小,最嚴重可能就是開車時忘記在R檔而踩了油門想往前進卻撞上後面的車。也有些比較輕微的,像是在打字時忘記caps lock是開著的而不小心打出一連串的大寫文字就比較無所謂,因為看到後馬上就能回頭修正。

但如果是在看不到的時候意外開著caps lock打字呢?(像是打密碼的時候)還好最近幾年出現下面這種設計,在密碼輸入框上面顯示caps lock的狀態,用來避免打密碼時不小心開了caps lock造成的mode error。

mode-error

vi引入mode到編輯器中,最大的問題就是產生了mode error的可能。也就是說,使用者如果以為他在insert mode而快樂的開始打字,但結果卻是什麼事都沒發生(除非他剛好按到a或i進入了insert mode..)。這問題也是造成vi難以入門的原因:你可以想像有許多第一次進到vi的人,打半天字卻什麼都沒有跑出來會帶來多大的挫折感。而且mode error可怕的地方在於,不是只有新手會碰上這種error,即使是vi的專家也常常會在insert mode打指令或是在command mode中打文章。(如果你在文章中看到:wq這種怪東西,就知道那人是用vi的了)

說起來mode帶來不少壞處,但它也不是沒有好處。讓我們反觀一般編輯器的”mode”設計。常見編輯器其實不是沒有mode,而是他們的mode是「暫時」的(這叫spring-loaded mode),靠Ctrl、Shift、Alt、Cmd、Win這些功能鍵來「暫時」進入命令模式。例如說Ctrl-C可以複製文字,這其實就是靠Ctrl賦予”C”這個鍵暫時的特殊功能,而取消原本在文件裡插入”C”的預設功能。用spring-loaded mode的好處是不容易產生mode error,因為使用者平常就只處在一種mode中,只有當使用者想要用特殊功能時,才必須先刻意按住某些特殊功能鍵來啟動它。spring-loaded mode的壞處在於,Ctrl、Alt、Shift這些鍵的位置在鍵盤的邊緣,再加上還必須按住不放(有時候還要兩三個鍵一起按住),使用者常常就得用彆扭姿勢讓小指和無名指按住,造成精神與肉體上的折磨。在按住這些功能鍵的同時,快速鍵的位置還不能距離太遠才能用單手按到,所以我們才會看到最常用的快速鍵都集中鍵盤左下角(Z undo、A全選、X剪下、C複製、V貼上、F搜尋…)。

後來文字編輯器變得越來越複雜,快速鍵也大量增加,這時在有限的空間內分配快速鍵的位置並且讓使用者容易學習又不容易忘記就成了一件困難的事。現代的一般編輯器,包括很多寫程式用的IDE,大量使用各種混合Ctrl、Shift、Alt的快速鍵,這種快速鍵設計哲學是把每一個功能對應到一組複合鍵上。理所當然的,功能越多,快速鍵就越多越難記。

因為多了mode,vi和一般編輯器的命令設計哲學也非常不同。vi的哲學是把功能分解成最小單元,再把這些最小單元一一對應到不同按鍵上,最後再利用一連串的按鍵組合產生使用者想要的複雜功能。以移動游標來說,vi把這件事分得非常仔細,從字元(character)、單字(word)、行(line)、句子(sentence)、段落(paragraph)、螢幕(screen)、區塊(block)、到檔案(file)都有對應的鍵可以以不同的單位大小來移動游標,例如按w可以跳到下一個單字(word),}可以跳到下一個paragraph…等等。乍看之下似乎很複雜,連移動游標看起來都這麼麻煩,但這樣設計的好處在後面。文字編輯還有很多動作可以做,像是刪除、剪下、複製..等等。vi把動作和操作的單位分解開來,例如:刪除(delete)是d、複製(yank)是y,這樣我們就只需要分別記憶動作對應的鍵和單位對應的鍵,就可以交叉組合出多種一般編輯器做不到的複雜功能。例如說,dw就是刪除(delete)一個單字(word)的意思,y}可以複製(yank)一個段落(paragraph)。如果你想要的話,單位前面還可以加上量詞,例如說d2w是刪除2個單字。

vi的這種設計避免了快速鍵的組合爆炸(想想看如果把各種組合都對應到一個ctrl-alt快速鍵會有多少個..),並且讓使用者能完全使用鍵盤來精確、快速的編輯一個文件,一旦熟悉這種操作後,手都不用離開鍵盤,不管是寫程式或是寫文章都有了一種人機合一的流暢感,心中想到哪裡游標就能精確移動到哪裡,不管多複雜的文字操作都能快速解決,心中的爽快感其實是難以用筆墨形容的。一般編輯器依賴於滑鼠作為移動和選取的主要工具,其實不管在learnability、memorability、errors都優於vi的鍵盤設計,但最大缺點就是efficiency很低。原因之一是,要用滑鼠一隻手就得離開鍵盤,光是這個時間用鍵盤操作的人都已經做完了(用laptop的touch pad就是另一回事了);原因之二是,滑鼠移動是不精確的,要把游標對準某一點所花的時間遠比按下鍵盤上固定位置的按鍵來得長(請參閱之前關於Fitt’s Law的文章);原因之三是,即使是用鍵盤控制游標,也沒辦法針對不同單位大小做控制,所以常常會看到一般使用者按住方向鍵等游標慢慢移動到某個地方..。(註:一般文字編輯器有個小技巧,這裡順便告訴大家:Windows上按Ctrl+左/右可以以一個word為單位移動,Mac上是Alt+左/右。幾乎所有可以打字的地方都能用。)

身為一個靠打字(不管是寫程式或是寫論文)吃飯的人,文字編輯可以說是我在電腦上花最多時間的工作之一。我很幸運在國中就接觸到Linux,所以也就接觸到了vim(vi後來的延伸版,是目前最流行的vi版本),沒想到這一用就用了十年…。vim也是我從國中開始用的每一台電腦裡都必裝的軟體,即使學了數十種程式語言,從Windows、Linux換到Mac,我到現在都還是用vim寫程式、寫論文、寫報告..。甚至在command line (bash)下面,都可以設定成vi mode,接著就能用vi的快速鍵來編輯指令。寫程式如果沒有vim,我等於被打斷一條腿一樣(不誇張,每次被迫在IDE裡寫程式我都有種武功被廢了的感覺…)。雖然一開始學vi/vim的門檻較高,但我很高興一開始花了點時間去學它,後來就再也不用學新的editor或IDE,只靠這一招半式就能行遍天下,實在非常值得呀。

[HCI] 費茲定律Fitts’ Law與使用者介面設計

Friday, October 2nd, 2009

之前在[HCI] 談人機介面設計與Usability一文中提到了usability的概念,並用了Windows的開始鈕說明了在設計UI上容易忽略的陷阱。這篇文章我會繼續探討介面設計與usability,並以效率(Efficiency)與UI設計時最重要的定律之一費茲定律(Fitts’ Law)為重點。

設計軟體的操作介面並不難,但很多時候直覺的設計並不一定能達成想像中的目的。這就是usability的研究想要了解的,到底什麼樣的設計才是「更好」的設計?什麼樣的設計其實只會讓usability變得更糟?

以menu bar為例,menu是圖形介面(GUI)的最基本元素之一,現代軟體功能越來越強大,包山包海的結果就是menu變得越來越多、越來越深,每一個menu展開後幾乎都有sub-menu,甚至還有sub-sub-menu等等複雜的選單。我每次教我爸媽用電腦時,都覺得Windows的menu根本是設計來折磨使用者的,奇妙的是竟然很少聽人在抱怨這介面很難用,而是紛紛強迫自己「學會」這種操作模式。

我想會看到這篇文章的讀者,早就很習慣於操作GUI了,也沒想過選單能有什麼好用或難用之別。所以先讓我們來想想要開啟一個埋藏在sub-menu裡的功能是多困難的工作(就假設是檔案/最近開啟/某檔案.txt好了)。第一,把游標移到menu bar的「檔案」上,並停住不動;第二,按下滑鼠左鍵打開檔案選單,把游標「垂直往下」移到「最近開啟」上停住;第三,等sub-menu打開,把游標「水平往右」移進sub-menu裡;第四,再度「垂直往下」找到某檔案.txt,在上面停住並按下左鍵。好,想像完畢後你可以試著用你的非慣用手操作滑鼠做一次看看。

如果是已經很熟悉GUI的使用者,想必都不覺得操作選單有什麼困難的,但當你被迫用非慣用手操作時,一定會感覺到操作速度大大的降低,甚至沒辦法精準控制游標進入sub-menu,這時我們才有機會體認到操作滑鼠其實並不容易。除此之外,如果仔細觀察,還可以發現進入sub-menu又比平常把游標移到任意地方還困難,因為必須把游標保持在一條狹長的「隧道」裡水平移動,如果在移動時不小心移出了這條隧道,sub-menu就會關閉。

gimp

有個有趣的案例發生在一個著名的open source影像處理軟體GIMP上(可以說是免費版的photoshop)。當初開發GIMP的團隊曾做過一個有趣的決定,他們決定拿掉固定在視窗頂端的menu bar,並用可以在任何地方按右鍵打開的context menu取代。因為context menu可以在任何地方打開,GIMP的開發團隊認為這樣可以加快存取menu的速度。這個想法很直覺,但真的對efficiency有幫助嗎?

既然我都說了這麼多,答案當然不會是yes。

context menu對efficiency並沒有幫助,反而使之變得更差。為什麼呢?

gimp2

如上圖,從第一層的選單要進入第二層時,必須先經過第一層狹窄的隧道(紅色區域),才能進入第二層選單。如果直接走直線路徑到想要按的目標,就會先經過第一層的其他項目,導致不同的sub-menu被打開。傳統的menu bar也是有sub-menu,所以直覺上可能不會覺得多一層的sub-menu會有多大影響,但事實上是這種把游標限制在一條隧道裡的設計大大的降低了操作游標的速度,和一般可以經由任意路徑指到目標的操作有指數級的速度差異。

Fitt在1954年提出了Fitt’s Law,可以說是人機互動領域的第一條「定律」,對人類指向任一目標的動作建立了一個數學模型。基本的概念是,移到目標上的時間(T)可以表示為目標距離(D)與目標大小(W)的函數。具體來說,T = a +b log2(D/W+1),a和b都是一個常數。

Fitt’s Law告訴我們,移到任意目標上的時間大約跟目標距離除以目標大小的對數成正比。也就是說,目標越遠移動時間就越長,目標越小時間也會越長;反之,目標越近或目標越大的話,所需時間就越短。有趣的是,距離和目標大小的影響並不算大,經過log讓這兩個變數的影響降低了一個指數等級。例如距離變長1000倍,並不會讓時間也變成1000倍,而是變成log2(1000),大約是10倍而已。

在軟體介面上,Fitt’s Law有個特例值得討論一番。在電腦裡的滑鼠游標,有個基本特性是其活動範圍被限制在螢幕裡,只要游標到了螢幕邊緣,無論再怎麼繼續往同一個方向移動滑鼠,游標還是只能停留在邊緣上。這個特性讓UI設計有了戲劇性的變化,一個最有趣的例子是Windows和Mac OS X的menu bar設計。

Microsoft的Windows自古以來的UI設計都是把menu bar放在視窗的title bar下面,而Mac OS採取完全不同的設計:把menu bar固定在螢幕最頂端。一般人大多覺得這兩種設計只是習慣問題,沒有什麼客觀差別,但如果你已經學會了Fitt’s Law,你覺得哪一種設計比較好呢?

Mac OS X menu bar

Windows menu bar

如果直接套用Fitt’s Law,第一個得到的答案很可能會是Windows的設計比較好,因為當滑鼠從視窗內移往menu bar時,距離會比移到螢幕頂端還近。可是,別忘了考慮螢幕邊緣所造成的影響。Mac把menu bar放在螢幕頂端,雖然距離變長了,但目標的大小也跟著變成了「無限大」。因為螢幕的邊緣會阻擋住游標的行動,於是使用者可以盡情的把用力滑鼠往上一甩,不用停下來「對準」目標,也就等同於目標的大小變成了無窮大。在Fitt’s Law中,當W是無限大時,整個log函數得到的結果會變成0,也就是說T就會變成一個簡單的常數值a,跟距離或大小都沒有關係了。

如此比較之下,我們就可以發現Mac把menu bar放到螢幕頂端是有其用意在的,因為它大大減少了把滑鼠放進menu bar並對準目標的時間,使用者只要把滑鼠用力往前一移,自然就會進入menu bar裡面了。我在[HCI] 談人機介面設計與Usability一文中也提過Windows開始鈕的例子,跟menu bar的例子也是相同的道理。

到目前為止,我們已經看過了三種形式的menu。對於efficiency而言,我們知道Mac的設計比Windows的設計還好,那如果和GIMP的context menu比起來呢? 從Fitt’s Law可以得知,Mac的設計已經達到極限了,無論如何也沒辦法捨去那個常數a,所以我們可以直接來比Windows的設計和GIMP的設計哪個比較差XD。

前面提過,sub-menu是一種很難的指向操作,除了要把游標移到目標上,還限制了中間經過的路徑在一個隧道裡。在Fitt’s Law之後,Accot and Zhai提出了Steering law。其結論非常簡單,讓游標經過一個寬度W的隧道移動距離D的時間 T = a + b * D / W。換句話說,把移動路徑限制住的話,其移動到目標的時間和一般性移動(Fitt’s Law)所需的時間是指數級的差距,這也就是為什麼電流急急棒可以變成一個有百萬獎金的挑戰,而隨意動動滑鼠則簡單的多。

了解了Steering law之後,再回來看sub-menu的設計,你就會發現sub-menu是一個多不人道的設計。每一層的menu其實都是一個steering操作:垂直的menu移動比較簡單,因為menu寬度通常都蠻寬的;但每當要水平移動進入下一層sub-menu時,就是一個困難的挑戰,因為這時的寬度變成了menu item的高度,通常也就是一個字母高而已。和Fitt’s Law不同的是,寬度(W)變小n倍,對時間的影響不再是對數,而真的就是讓時間變長n倍。所以說呢,如果可以迅速又準確進入多層sub-menu的滑鼠高手,其實也有參加電流急急棒比賽的能力呢!

回過頭來看Windows和GIMP的menu設計,這時就可以明顯比較出來。GIMP把所有的選單操作全都變成了steering操作,Windows雖然也有sub-menu的問題,但至少第一層還是任意的指向操作,所以就efficiency來說,GIMP的設計其實是一大失策..。

最後,再順便提兩個Windows和Mac OS X對於sub-menu造成的問題所提供的解決方法。微軟和Apple都知道sub-menu很難操作,所以他們其實都有偷偷的在介面上做了一點貼心的設計。微軟的方法是,在游標要進入sub-menu時,如果不小心移出隧道外,只要在一定的時間內移回來,sub-menu就不會消失。這個方法其實有些風險,主要是因為這個「時間」很難掌控。如果這個設定的時間太短,那就沒多大效果;但如果設定太長,使用者如果是真的想要移到別的menu item打開另一個sub-menu,就會覺得系統反應太慢(就是那種頓頓的感覺)。所以,微軟的這個方法其實並不是很有效的解決這問題。

而Apple雖然也是用同樣的方法來sub-menu不要馬上消失,但他們又加上了一個聰明的設計:sub-menu的延遲消失只有在游標到sub-menu的頂端和底端形成的三角形內有效。換句話說,如果使用者是想進入sub-menu中,他甚至可以直線移動滑鼠進入其中而不會意外打開另一個不同的sub-menu(只要在設定的延遲時間內移動完成)。而假如使用者是想打開另一個sub menu,那直覺的把滑鼠往下移動就會自然的避開這個三角形區域而避免了「頓頓的」感覺。

Apple's solution for sub-menus

在UI設計上,Apple一向是比其他公司用心許多。這種聰明的設計雖然很小(甚至沒什麼人會注意到),但在每天反覆的使用中就能自然減少使用者的挫折感和提昇操作的流暢度,這也是為什麼我常說Mac有許多貼心的設計,用起來會自然讓人感覺很愉快,而其他系統在UI設計上所下的功夫就明顯不足了。