2011年4月2日 星期六

寫程式的能力

寫程式的能力跟讀寫一樣,每個人多少都要會一點。

我所說的寫程式,不是正經八百的coding,
而是「指揮電腦」的能力。

電腦的運算與記憶能力(甚至體力)都比我們強
但就像常見的工具(如螺絲起子)一樣
它是我們可以運用的工具之一
我們來決定,螺絲是要鎖上還是卸下,
工具本身不負責思考或下決策。

電腦比一般傳統的工具靈活
也是一大堆工具的結合
特別是網際網路的快速發展
經由對外連線,可以取得的資訊與整合的服務,
都超過我們的想像,而且演變的速度越來越快,
如果能夠經由程式的技巧來整合這些資源
電腦能夠發揮更多的用途,
我們也會因而間接或直接的受益。

大致上,程式可以提供我們三種型式的方便:
大量處理、自動化、代理人

《大量處理》

GUI桌面程式的風行降低了使用電腦的障礙,
直覺而又漂亮的操作介面,
取代了指令模式的不親切,
讓個人電腦大量普及,是很好的設計。
然而GUI有一個問題就是,
它必須由人來操作,
由人來解讀螢幕上面的訊息,
沒有操作者,他就不會動,
只會靜靜等待著滑鼠被點一下
才進行下一個步驟。

想想看,假如你有成千或者上萬首歌曲放在電腦裡面,
有一天你想要整理分類,
或者只是複製到另外一台更大容量的外接式硬碟,
這時也許你想區分歌手或者作曲家,
把相同屬性的檔案放在相同的目錄,
也許發現同一首曲目曾出現於不同位置,
想順便移除重複的檔案,.....
諸如此類的「整理」工作。

處理數百個檔案並不是大(困難)問題,
但是數千個,可能得花上個幾天的時間,
就算有耐心的做一次,那下次呢?

如果把處理分類的規則寫成程式,
讓程式代勞,有效率的完成這些重複、規則性的選取、複製與貼上的程序,
這是日常生活裡大量處理的應用。

工作上也有類似的需求,
大量重複耗時的工作經常存在,
寫程式,能幫你解決這類問題。

《自動化》

有些事情需要在特定的時間或條件下才需要(能)去作,
或者一段期間內,每隔一定時間得去執行的事,
如果沒有寫程式來輔助,你只能持續地等待與檢查,事必躬親。
像這類可以排程去處理的事情,
透過程式來進行,不需要你人親自在現場,
也能夠自我啟動執行,自我偵錯,自我紀錄,自我儲存,
甚至將執行結果往外通知的方式,這就是自動化。

《代理人》

代理人的例子蠻常見,
但一般人多習以為常,不會特別去注意到。

就拿我們上網訂購高鐵票這件事為例,
高鐵的線上訂購網站就是高鐵公司的櫃台代理人,
反之,當年台鐵火車票過年期間,一票難求的時候,
也曾有人將購票程序寫成程式,
在半夜以代理人身份代替本尊連上網路訂票。
兩方面的代理人一來一往,就像真人互動一般,毫不含糊。
仔細想想,真的有趣極了。

寫程式,先要選擇自己合用的程式語言,
(合用,是說用起來順手,符合自己思考方式的)
而在經過這一、二十年來的開放原始碼運動發展之後,
如今簡單、好用、穩定、成熟的程式語言比比皆是。

運用工具一直是靈長類的的強項,
選擇、學習一個順手的程式語言,
磨練、培養自己寫程式的能力,
是今日我們必備的基礎能力之一了。

2011年3月29日 星期二

ActivePerl使用cpan安裝DBD::DB2模組

今天發現ActiveState公司所提供的ActivePerl 5.12.3版有個不錯的改進
(可能之前的版本就改進了,只是今天才注意到,不過這並不重要)。

以往在Windows環境底下使用Perl總有個令人覺得是次等公民的限制,
那就是對於部分需要C編譯程式才能完成安裝的模組,
如果沒有已經準備好的PPM(參考),那就無法安裝,也就是不能用。
如果找得到也有可能不是最新的版本,使用上總是有點不暢快,
於是習慣在Unix環境下使用Perl。

ActivePerl 5.12.3提供了gcc編譯器(應該是v3.4.5)
鍵入cpan後歡迎畫面會顯示這個資訊,
安裝模組的方式一如往常,
以安裝DBD::DB2為例:
install DBD::DB2
就可以了

只要Windows環境下DB2的環境是準備好的
整個安裝過程完全沒有問題
之後也寫了個簡單的測試程式確認連結、查詢資料庫是正常的

我覺得這個改進很好,讓人覺得呼吸順暢沒有束縛,開放原始碼真好。

2011年3月26日 星期六

好聽的 In my life

好聽的《In my life》,演唱跟口白版本一樣動人。





歌詞淺顯感人

In my life

There are places I remember all my life
Though some have changed
Some forever, not for better
Some have gone, and some remain
All these places had their moments
With lovers and friends I still can recall
Some are dead and some are living
In my life I've loved them all

But of all these friends and lovers
There is no one compares with you
And these memories lose their meaning
When I think of love as something new
Though I know I'll never lose affection
For people and things that went before
I know I'll often stop and think about them
In my life I love you more

Though I know I'll never lose affection
For people and things that went before
I know I'll often stop and think about them
In my life I love you more

In my life I love you more    

這一生中

有許多地方對我來說永生難忘
雖然有些地方早就人事已非
有些地方永遠一成不變
有些已經片瓦不留,也有些還保持原樣
它們全都曾參與過重要時刻
和戀人、和朋友,這些人在我的記憶裡依然那麼清晰
他們有些已經撒手人寰,有些還活在世上
這一生中我深愛這一切

但在全部的戀人和朋友之中
沒有一個人能與妳相比
這些回憶通通失去了它們的意義
當愛情對我又產生了新鮮感
雖然我很清楚我永遠不會失去這份情感
對於那些已成追憶的人、事、物
我知道我會常常停下腳步懷念它們
但這一生中,我愛妳最多

雖然我很清楚我永遠不會失去這份情感
對於那些已成追憶的人、事、物
我知道我會常常停下腳步懷念起它們
但這一生中,我愛妳最多

但這一生中,我愛妳最多……

2011年3月20日 星期日

Ubuntu上更新OpenOffice到3.3版的方法

安裝步驟
  1. 移除前版本 :  sudo apt-get remove openoffice*.*
  2. 下載 : 網址 OOo_3.3.0_Linux_x86-64_install-deb_zh-TW.tar.gz
  3. 解壓縮
  4. 安裝 : sudo dpkg -iR ./OOO330_m20_native_packed-1_zh-TW.9567
也許過程會因為作業環境不同而有點異常的情況發生,但大致上這麼做是沒有問題的。

另外注意到,由於SUN已被甲骨文公司併購,所以開放軟體社群另外建立了一個分支LibreOffice 免費文書處理軟體中文版。但操作介面類似與檔案格式仍然可以相通讀取。

我個人來說,自從家中"借用"的MS-Office 2003被告知說是非正版而移除安裝以後,就改用OpenOffice,連帶PC的作業系統改成Ubuntu超過一年了,個人使用上覺得穩定方便,也因為沒有安裝防毒軟體,所以PC運作效能也一直維持應有的水準。

    2011年3月19日 星期六

    習作-使用Open2來與外部程式交談

    # demo 使用Open來與外部程式交談
    # unix指令wc : print newline, word, and byte counts for each file
    # 在perl程式內執行wc, 提供計算資料以及取回計算結果
    
    use strict;
    
    use IPC::Open2;
    use IO::Handle;
    
    # init file handle
    my $read_fh  = IO::Handle->new();
    my $write_fh = IO::Handle->new();
    
    # 使用open2建立可與之交談的子程序
    my $childpid = open2($read_fh, $write_fh, 'wc');
    
    # 提供資料
    $write_fh->print("abc def\n24 187\n");
    # 關閉(結束)input handle, 否則wc會一直等待
    $write_fh->close();
    
    # 取回結果(可能多行, 使用陣列)
    my @wc = <$read_fh>;
    
    # 關閉(結束)input handle, 否則wc會一直等待
    $read_fh->close();
    
    print "$_\n" for (@wc);
    # 印出 2 4 15
    
    # 等待確認子程序已結束
    waitpid($childpid, 0);
    
    exit 0;
    

    在Perl程式裡面執行外部程式的方法很多,如何選擇使用,主要還是取決於需求以及外部程式的特性。

    有一類如系統指令,並不提供API,通常的用法就是在shell環境下,以指令的方式或者shell script的方式使用,用眼睛閱讀解讀,執行的輸出結果,或者再把它的輸出經由pipe,當成另外一個指令的輸入或者儲存寫到檔案裡面。


    如果需要能夠動態決定輸入內容,以及靈活使用(比如判斷、轉換、組成、轉送...)它的輸出,Perl提供open2這個基本函式,經由線上文件可以瞭解它的使用方法,以及需要注意(比如I/O buffer的觀念)的地方。

    外部程式並非永遠正確執行(比如可能找不到,或者傳入的內容不符合他的預期...),這點就需要檢查$?變數內容。

    為什麼是open2(),因為它只處理了STDOUT & STDIN這兩個File Handle,如果還需要STDERR的內容,那就要使用open3(),照文件說明所說,open2()其實是open3的wrapper,也就是它最終是去呼叫open3(),使用這個函式需要注意的是File Handle的Input/Output方向。

    然而,現在寫程式,比較不建議直接使用open2這些基本的函式呼叫了,因為你需要處理一些不必要的細節,學會使用CPAN上的模組,比如IO::CaptureOutput或者IPC::Cmd
    可以簡化一些處理細節,程式的bug也會減少很多。

    2011年3月9日 星期三

    設定備忘:讓User只能FTP而不能logon的方法

    參考來源

    為了安全起見(FTP一點都不安全),如果User不需要登入系統,就不要給他這樣的權限。
    要修改的有兩個設定檔案,分別是 /etc/passwd & /etc/shells

    /etc/passwd 存有使用者帳號資料,每行有7個欄位。(參見)





    1. 將最右邊的 /bin/bash 改成一個不存在的 shell , 比如 /usr/nologin,存檔。
    2. 再將這個shell種類加到 /etc/shells 最後面一行就可以了。

    2011年3月7日 星期一

    IBM主機中文碼的轉碼

    不同系統間的資料傳遞,如果只是單純的英數字資料,就不會碰到麻煩,
    但是,如果資料含有中文字,就要特別處理轉碼的問題,
    原本處理來自IBM主機資料時,一直 Convert::IBM390這個模組,
    也由於之前資料內很幸運的都沒有中文,
    所以一直也沒注意到這個無法轉換中文的限制,直到.....今天。

    Convert::IBM390只能夠轉換 IBM-1047 <=> ISO8859-1
    而 IBM主機上的Traditional Chinese EBCDIC編碼是IBM-937(cp937)
    目前Perl在CPAN上面的Encode模組找不到支援cp937
    另外唐鳳所寫的模組Encode::IBM可以支援。(但我沒試過)

    Unix-like作業系統上,也有一個iconv的指令,可已進行檔案轉碼的作業。
    簡單介紹可以參考這裡

    所以經由Perl可以間接使用iconv來轉碼,再將結果取回放回變數內,舉例如下。

    ###############################
    # CP937 => Big5 轉碼
    # 使用inconv指令
    #
    sub CP937_BIG5 {
    
        my $eb = shift;
        return '' unless $eb;
    
        # 在家目錄/tmp下
        my $big5file = $ENV{HOME} . '/tmp/big5file';
        open Convert, " | iconv -s -f IBM-937 -t big5 > $big5file "  or die;
    
        print Convert $eb;
        close Convert;
    
        open B5, '<', $big5file or die;
    
        my $big5 = <B5>;
        close B5;
    
        return $big5;
    
    }
    


    如果不想使用上面的方法,也可以改用Text::Iconv,比較簡潔。
    ###############################
    # CP937 => Big5 轉碼
    # 使用Text::Iconv來介接inconv指令
    #
    use Text::Iconv;
    sub CP937_BIG5 {
    
        my $eb = shift;
    
        if ($eb) {
            return Text::Iconv->new("IBM-937" => "big5")->convert($eb);    
        }
        else {
            return '';
        }
        
    }

    轉碼是個不得已沒有營養的作業,
    但為了現有營運中不同系統間的資料轉換,
    它又是個必須存在的基本工具。

    Perl提供了良好多樣性的方法來達到我們的目的,是個值得學習而又實用的程式語言。