開發wxPython的利器 : PyCrust

六月 17th, 2009 2 comments »

一直想做的事

最近我在用wxPython開發某些程式,隨著開發的過程中,難免需要一些直接的測試,改動程式碼來進行測式似乎不是很明智的選擇,即使Python是直譯式的語言,每改一次重新啟動整個程式也是一種浪費,而且狀態每次也會重置,於是我開始想,我是否可以寫一個像Half-Life那樣的一個console整合到我的GUI中,如此一來我就可以在開發時直接進行某些測試,對某些特定的模組操作,如此一來開發的效率可以提升,對於程式而言也會更好除錯,但是雖然寫一個console不是什麼太難的事,但也不是什麼太輕鬆的事,為了早點完成程式,於是我就沒有真的去做

直到某本書的出現 : wxPython in action

當有一天我訂的書: wxPython in action終於來了,這本書要1500元,實在是不便宜,但是我認為卻很值得,我在書中發現我以前一直都沒仔細去注意到的東西,PyCrust,在翻過這章節時我驚訝地發現,這不就是我想做的嗎? 一個控制臺,可以讓我操作、觀察、測試我的GUI,而且整合的方法超簡單,只要一行指令

python pywrap.py main.py

在wx.py的package下的pywarp.py會自動找到app並且將PyCrust整合進去,在我程式中執行的畫面就像這樣

pycrust

在截圖中我利用pycrust將gui的背景換成了紅色,它不止是一款簡單的GUI,因為他是動態載入模組的name space,和一般IDE不同的是,他的自動完成是動態的,一般的IDE只抓得到靜態的成員,但是即然是動態載入又是在執行中,有什麼成員一清二楚,所以基本上自動完成功能感覺非常地強大,但相對的弱點是對於靜態的部份比較麻煩

它除了可以自動整合到現有的wxPython gui程式中,更可以把裡面各個元件分開來獨立使用

所以它可以幹麻?

對我來說,PyCrust將會是像神兵利器般好用的工具,像是開發遊戲之類需要大量的調校,一個console或是動態的機制是免不了的,而console提供了立即且互動式的環境,有了PyCrust,就等於有了現成的console可以使用,在遊戲的開發過程中,開發者可以利用這個console動態地改變各種參數來觀察反應等等,當然開發遊戲只是其中一個應用的例子,即使在一般的GUI中也會是很好用的工具

順帶一提

wxPython in action真的是難得一見的好書,有別於一般的書,它使用問句來當做標題,但是不會因為這樣而零散雜亂,相反的,你可以很正式地看完一次,也可以很快速地掃過一次,當你需要什麼東西時,那些問句可以幫助你很快地找到你需要的東西,豐富的截圖和圖解更讓人不用費心去猜想到底做出來會是什麼樣子,或是想像到底是如何運作,如果要學wxPython,我覺得這本書真的是非常值得推薦,做為工具書,這本也是必備的一本

在家遨翔全世界: 微軟模擬飛行 Microsoft Fight Simulator X

六月 16th, 2009 No comments »

飛行

飛行一直是人類的夢想,這對大多數人來說都遙不可及,我們所謂的飛行頂多是搭乘飛機而已,是需要長時間的訓練才能辦到的,但是飛行有相當的風險,沒辦法讓初學者一開始就駕使飛機,為了因應這樣的需求,模擬器被發明了,在進真的駕駛艙飛行前,初學者可以在模擬的環境下安全的學習如何飛行,原本這需要特殊的設備,現在拜由電腦的進步,在家也能夠進行模擬飛行,雖然是模擬的,和現實有一段差距,但是已經相當逼真了,玩家可以透過模擬飛行來飛遍全世界,我們現在就來介紹,微軟所推出的模擬飛行10,以下簡稱FSX

模擬飛行

模擬飛行是微軟所推出的一款模擬飛行遊戲,說它是遊戲似乎有點小看它,雖然是遊戲,但是有相當的擬真程度,有很多熱衷的玩家甚至組成了虛擬航線,也就是只存在線上的航空公司,玩家們要通過考試才可以成為機師,我們先來看看它的遊戲畫面

FSX遊戲畫面

如你所見的,進如眼廉的是複雜的儀表版,就跟現實中你會在飛機的駕駛艙看到的一樣,然後是窗外的景色,在這裡是桃園中正國際機場,沒有錯,FSX收錄了世界各地的機場,台灣的機場當然也在裡面,而這台飛機是波音747-400,基本的東西都跟現實中的差不多,就像開真的飛機似的,所以其實玩這款遊戲,就會發現原來開飛機這麼困難,需要非常非常多的知識,流體力學、通訊、精通英語等等,我個人只是偶爾玩一下,所以都是靠自己的直覺亂飛,偶爾看一下文章找一下資料,在某些程度來說他非常地困難,像是降落就非常地困難,我摔爛幾百架的飛機才漸漸有成功地降落

接著就讓我們來介紹FSX….

» Read more: 在家遨翔全世界: 微軟模擬飛行 Microsoft Fight Simulator X

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

三月 29th, 2009 1 comment »

美術苦手

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

石器時代

在很久很久以前,想要擴充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 2 comments »

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

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

再見了! Plone

二月 12th, 2009 2 comments »

終於,跟Plone說再見了,原因出在於最後一根稻草,來自主機商的自動訊息,說Plone的資料庫檔案超過500MB,需要執行清理的動作,雖然不是必要的,但是他的資料庫檔案會越來越大,我受不了了,為了Plone我已經升級了主機方案,記憶體還是超過限制,還弄了script去監視Plone記憶體使用量,定期重開,真搞不懂Plone到底是吃什麼長大的,就算不是歐落肥也是很營養的東西,當時就決定要把網站搬到其它CMS去,Joomla最近看起來蠻紅的,評估了一下就決定選擇Joomla,就在剛才處理伺服器的檔案,Plone的資料庫已經成長到了1.5GB….裡頭到底塞了什麼真令人好奇,然而我執行了清理之後只剩18MB,這之間的落差到底是從哪生出來了….Plone真的是怪獸中的怪獸,不過,早該跟這頭怪獸做個了斷

我花了一天的時間寫了一個小爬蟲爬了Plone的文章,然後用Joomla的XML RPC API傳文章上去,最後終於完成了,該是跟Plone說再見的時候了

新的Joomla!

第一次遇到Deadlock

二月 10th, 2009 1 comment »

凡事都要來個第一次,這兩天遇到一個deadlock,是我第一次遇到deadlock,其實很多deadlock都很明顯可以避免掉,但有些就不明顯,這次遇到的deadlock,是因為正在開發一個DirectShow的應用程式,我使用Python把核心部份寫好包裝成Extension給Python使用來加速開發,不然每次光等編譯就等到睡著

我使用DirectShow 的 Sample Grabber filter來抓取從DirectShow播放出來的音樂,DirectShow的graph會建立一個thread來處理事情,而它使用一個callback來回傳資料,好死不死,我的程式從Python的程式碼的Main thread呼叫graph的stop,但是stop似乎會等callback回傳,再來又好死不死的,callback因為要把資料丟回Python,要求Python的GIL,所謂的GIL就是Python直譯器的lock,整個Python行程只有一個,所以就變成下列情況

Main thread (hold GIL) -> call stop(Wait for callback) -> Callback acquire GIL -> GIL….(Hold by main thread)

囧…

這幾個笨蛋(設計的人比較笨),就這樣一直癡癡地等下去,等到天荒地老都沒有人會理他們,這真是悲慘….,所以在寫multi-threading的程式時一定要特別小心,明顯的deadlock當然是很容易避免,但是像這種文件上沒說清楚,隱涵著lock,又繞了一圈的情況,就很難一開始想到

提升效能 : 資料對齊

二月 3rd, 2009 No comments »

程式通常都被要求要先把事情做對,再來要求效能,很多人常把事情倒過來做,我以前也喜歡這樣做,為什麼? 因為想要提升效能需要很多瑣碎的知識,當你知道一樣新的想法可以讓程式更快,就會想迫不急待的把它加到你的程式裡,但是程式執行結果都未必正確的情況下,這樣做只會增加程式的複雜度,結果都不正確了,跑再快又有什麼用? 但是到了真正到了把事情做對之後,就是到了開始恨自己瞭解的東西太少,我開始回想以前那些零碎的知識片段,看見我的程式存取記憶體,還有指標,讓我想起了一個重要的概念,資料對齊,這是一個很重要的概念,當資料的位址或長度不是CPU善長處理的數值時,CPU就需要花更多時間去處理,這也就是為什麼資料需要對齊的原因,會發現這個概念是因為我以前在寫struct寫入檔案時一直遇到一個莫明奇妙的bug,我發現struct的大小比我預料的大,後來才知道是資料對齊,編譯器自動將它填到對齊好的大小,現在我回想起來,找了一下,找到了一篇很不錯的文章,圖文並茂地說明了資料對齊的概念

Data alignment: Straighten up and fly right

當瞭解資料對齊的概念之後,就會明白為什麼buffer的長度常常會取256, 512, 1024等等數字

Google中獎關鍵字測試

一月 31st, 2009 3 comments »

一時程式寫不出來,想說來試試Google是不是所有關鍵字都中獎 XD

google

首先看看Google,嘖嘖….Google看來是跟Skynet是一夥的

youtube

Youtube也中獎了,看來Youtube威脅Google霸業讓Google很不爽 XDDD

microsoft

接著試試微軟,看來Google也看微軟不爽很久了 XD

yahoo

沒想道死對頭Yahoo居然沒事!? 看來Google和Yahoo以及Skynet都有一腿!

我本來還想搜尋鮑魚,可是這鮑有毒的梗好像有點太虛了 XD

Google大暴炸! 這個網站可能會損害您的電腦

一月 31st, 2009 No comments »

剛剛在Google搜尋資料時突然發現,奇怪,怎麼好多網站都出現

這個網站可能會損害您的電腦

仔細看看是所有的網站都變成這樣了= =

googe出問題

googe出問題

仙人打鼓有時錯,連精明一世的Google也有腦殘出槌的一天阿= =

看來現在所有網站都被認為被植入病毒 XD,這麼一來就分不出到底哪個是有毒,哪個是沒毒了,全世界的電腦都中毒了,看來世界末日不遠了 XD 天網 Sky Net 背叛人類啦~

個人猜測是Google自己內部可能程式有問題放上線的可能比較大,例如測試碼沒清掉就上線= =』 PTT上次權限大放送似乎就是這種狀況 至於Google到底會不會犯這種低等錯誤 我也不知道 不過被入侵也是有可能XD 總而言之我好期待Google如何解釋這次事件的原因