Archive for 三月, 2009

哇,好漂亮,可是請問按鈕到底在哪裡?

三月 29th, 2009

美術苦手

一直一來,寫程式是我的專業,但偶爾會有需要撈過界的時候,也是我最頭痛的時候,美術設計,像是網頁程式寫完,要開始把網頁美化,我發現這對我來說比什麼都還來得困難,光是配色就是門很大的學問,以前我對顏色一點概念都沒有,配出來的顏色很常是一些大便色,連我自己看了都想吐,畫圖也是一樣的,畫出來不是很難看,而是根本就不能看,我除了寫程式還得做美術? 我也沒有那樣的時間,或許正因為沒有花時間下去,這個世界是公平的,花多少時間下去,才會有多少的能力,一直一來我腦中響起ptt鄉民最愛講的話之一….

閃開! 讓專業的來

是的,沒有人是萬能的,該交給專業的人時就該這麼做,但是問題出在於,專業的人到底要去哪裡找? 自稱設計師的人滿山遍野,到底要從何找起? 我這陣子逛了不少設計師的網頁,大部份都相當漂亮,有些甚至是美到讓人讚嘆,但是卻大部份都有一個致命的通病….,那就是可用性0分

華麗但可用性0分網頁

大部份設計師的網頁開起來都是華麗的Flash滿天飛舞,我們先不論用Flash做網頁對SEO的殺傷性 (搜尋引擎應該是難以找到Flash裡的內容),就只從可用性來看

看網頁要先下載超過20秒以上的Flash是常態,很多我在開啟的過程中不耐煩就把網頁給關了,沒理由的跳出新視窗的更是數不清,經由廣告視窗的訓練,大家對於那種跳出來的視窗很常第一個直覺反應就是關掉它,我也不例外,好好的普通網頁可以用,跳出一個新視窗來到底是要做什麼我也搞不懂,最誇張的還有遇到用Flash擴成全營幕,我真的不知道什麼網站可以偉大到擴成全螢幕讓使用者專心來看你的網頁,如果遇到不知道怎麼跳出的使用者就糗大了,你可能會說,他進入時會顯示』按Esc跳出』阿,是這樣嗎? 以自己的觀點來設計網頁就是失敗之處,我們都認為Esc跳出好像是理所當然的事情,但是如果遇到Esc在哪裡都不知道的使用者呢? 是這樣的話可能會遇到下列情況

使用者不知道要怎樣跳出全螢幕模式,找了三分鐘都找不到,然後罵了:

幹! 爛網站

接著按電腦重開機鈕….

這不是不可能發生的事情,接著還有其它常見的通病,很多網站都喜歡用一些五四三的方式來代替按鈕,人物、物品、動物、阿貓阿狗之類的什麼鬼都有,看起來是很酷沒有錯,但是請問先生,我要怎麼知道哪個東西可以按? 是阿,我可以用滑鼠移過去點點看是嗎? 這似乎也是蠻有趣的驚喜不是嗎? 沒想到這東西居然可以按,呵呵,真有趣

大錯特錯! 如果你做的是遊戲,藏一些異想不到的東西在畫面裡,這還說得通,但可惜我們不是在玩遊戲,使用者也是,沒有使用者有那種美國時間來慢慢品嘗探索你網頁的樂趣,對於使用者來說,他們只想找到他們要的東西,其餘的東西都是雜訊,以這些設計師的網頁來說,我想找到的是他們的作品集,這下可好了,作品集的按鈕到底是哪一個? 一個一個試嗎? 不,關掉網頁,找下一個,這是最快的做法,所以,請不要挑戰使用者的耐心

除了不知所云的按鈕,你追我跑的設計也是頗受歡迎,很多人喜歡讓滑鼠移動靠近某些東西會有不同的變化,像是有些是越靠近圖片越大,我發現我想看那張圖片,但是我非得把滑鼠移到圖片的最中心才能把圖片停住且放到最大的樣子,我只能說我可能走錯網頁了,我以為我來到了CS甩槍訓練的Flash網頁,這只是一個例子,還有很多類似的設計,很酷,但是很難用

那創意怎麼辦?

我知道想要突破常規是很多設計人的心願,但是在那之前還有一個前提是可用性,如果說做出來的東西是藝術品,只要用眼睛看就好的純欣賞用的作品,那便沒有什麼可用性好說的,但是如果說做出來的是網頁,網頁的目的如果是要讓人使用,那麼天大地大不是台科大,而是使用者,一切都是為了使用者而打造的,使用者必須被擺在第一個順位,賞心悅目、有創意,但是一樣要有可用性,除非你的網頁做出來只是孤芳自賞的藝術網頁

值得一看的好書 : Don’t make me think

我不是什麼可用性的專家,但是我知道有針對網頁可用性的好書,叫做Don’t make me think,已經算是經典的好書,他的最高原則就是直覺,也就是讓使用者不需要思考就能使用的設計,如果你的網頁在我說的範圍裡,可以參考看看這本書,或是當做沒聽到,以上只是打打嘴砲,請別在意

Python的進步: ctypes

三月 21st, 2009

石器時代

在很久很久以前,想要擴充Python要使用API來包裝成Python可用的模組才可以,面對囉唆的一堆C API是一件痛苦的事,接著,進入了石器時代,人們開始使用工具,出現了SWIG、boost::python等,讓擴充Python變成一件更簡單的事情,但是即使是如此,這還是笨重的方法,產生了笨重的二進制檔,笨重的編譯工作,對於只是要將c語言的library擴充給Python使用而言這還不夠好,接著,終於有了進化,ctypes出現了,人們想說,與其做出pyd來給python使用這種多此一舉的事情,東西就在那裡,dll就在那裡,為何不能直接使用呢? ctypes的目的就是讓Python可以直接操做c語言寫的dll,這是一個大躍進,到了python2.5 ctypes還成為了標準的模組之一,這表示新的時代的到來

對ctypes的懷疑

相對於熟悉的事物,面對類似性質但是不同的事物時,總難免有多少疑惑,我在一開始也懷疑這樣能做到什麼地步? 但是在看了它的文件後我瞭解到,大部份dll使用ctypes都可以應用得很好,像是我擔心的callback,ctypes一樣可以提供方法來把python的函數包裝成c語言的callback丟給c語言的dll,運作得很好,其中我最擔心的是多緒的問題,因為有些callback是從其它thread呼叫的,因此如果沒考慮到multi-thread問題的話,callback就廢一半了,但是它一樣也考慮很週到,即使是從不同thread呼叫的python callback,也一樣可以運作得很好 舉個例子

DSPPROC = WINFUNCTYPE(None, HDSP, DWORD, c_void_p, DWORD, c_void_p)

在有了c語言函數的原形建立後,我們就可以使用它來包裝python的函數丟給c語言的dll處理

print BASS_Init(-1, 44100, 0, 0, 0)
 
stream = BASS_StreamCreateFile(False, 'c:\\god know.mp3', 0, 0, 0)
print stream
 
def dspProc(handle, channel, buffer, length, user):
    print handle, channel, buffer, length, user
 
cDspProc = DSPPROC(dspProc)
print BASS_ChannelSetDSP(stream, cDspProc, None, 0)
BASS_ChannelPlay(stream, False)
raw_input()

值得注意的是,因為Python有reference counter,也就是說,當沒有變數指向某個物件時,那個物件可能就會被回收,因此如果我們這樣寫

BASS_ChannelSetDSP(stream, DSPPROC(dspProc), None, 0)

Oops,恭喜你,你的程式很可能隨時會當掉,因為暫時的變數在被回收後,那塊記憶體就不再是c語言的函數,裡面可能塞了一些亂七八糟的東西,你的dll一呼叫那函數,遇到了些亂七八糟的東西會當掉也不是什麼奇怪的事,因此寫ctypes時,必須同時使用Python和C語言的觀點來看,舉另一個例子,如果某個C語言的API的文件上寫到,你傳進來的字串它不會copy,只會留著它的指標,在完成之前那個指標應該都還是要為有效的,這時,你就必須在python用一個變數一直保持著reference到產生出來的c語言字串記憶體空間,防止它被回收

除了callback以外,你可能會想到: 『阿,那struct和union怎麼辦?』 ,ctypes一樣有辦法,以下就是一個例子

class BASS_INFO(Structure):
    _fields_ = [
        ("flags", DWORD),
        ("hwsize", DWORD),
        ("hwfree", DWORD),
        ("freesam", DWORD),
        ("free3d", DWORD),
        ("minrate", DWORD),
        ("maxrate", DWORD),
        ("eax", BOOL),
        ("minbuf", DWORD),
        ("dsver", DWORD),
        ("latency", DWORD),
        ("initflags", DWORD),
        ("speakers", DWORD),
        ("freq", DWORD),
    ]

下一個時代的進步

人們總是覺得,事情還可以更好,事情只成功一半,用手寫ctypes是件很痛苦的事情,看著c語言的header檔複製、貼上、修改的無限迴圈,再也沒有比這個還無聊的事情,電腦的發明就是要解決問題,重覆性如此高和有規則的工作不應該浪費保貴的人力,因此,下一步就是c語言header的parser,理想的狀況是,可以自動parse c語言的header然後產生相對應的python ctypes寫的binding module,如果做到這個地步代表了什麼? 這意味著,Python能用的資源,從本來的常見module一下子突然擴大到了所有的c語言寫的library,這是多麼偉大的進步

再也沒有什麼比實例更重要了

我使用ctypes的目的在於寫BASS的python binding,BASS是一套audio library,因為它沒提供Python的binding,所以我只好自己寫,在無聊的複製貼上過程中,我有試著想過寫parser來自動化完成我的工作,但是c語言的parser已經複雜到了一個地步,如果要寫出那樣的parser,會比我直接用手寫還來得麻煩,所以就沒有繼續研究

BASS binding運作得很好,有興趣的朋友可以參考看看

pybass
pybassmix

24顆SSD串起來的怪物

三月 10th, 2009

現代的電腦,CPU跑得跟火箭一樣快,但是遺憾的是,就算CPU跑再快,它還得等週邊一大堆烏龜們,我想現在最慢的莫過於硬碟吧,即使容量以驚人的速度成長,但是效能成長還是很差勁,電腦常常需要等像烏龜一樣的硬碟,因此如果現代電腦最慢的組件被換掉了,將會是一大進步,瓶頸也會因此突破很多,以下看看超強用24顆SSD串起來的電腦,串很大~ 串不用錢

真期待SSD的時代到來,就可以跟龜速硬碟說掰掰了