2023-01-02

哇10年沒寫文章了!

這10年來,我先是開了公司,然後結婚,到了德國工作,回台灣生下長子,之後前往美國南加州唸博士班,在那裡生了第二個孩子。之後開了第二家公司,回台灣開了第三家公司。在回饋母校彰化高中清華大學後,又開了第四五家公司。

現在我到美國繼續唸未完的博士班,可能以後就待在這裡長住了。往後的人生,又會發生什麼奇妙的事呢?

2012-01-09

如何在 Windows 底下添加系統服務(system service)

以下程式碼呼叫方法:

註冊服務
ruby name.rb reg

註銷服務
ruby name.rb del

服務執行之程式碼位於 service_main 區塊內

require 'rubygems'
require 'win32/service'
require 'win32/daemon'
include Win32

SERVICE_NAME = "RubyService"
SERVICE_DISPLAY_NAME = "A Ruby Service by vegafish"

if ( ARGV[ 0 ] == "reg" )
    Service.create({
        :service_name     => SERVICE_NAME,
        :service_type     => Service::WIN32_OWN_PROCESS,
        :description      => 'A custom service I wrote just for fun',
        :start_type       => Service::AUTO_START,
        :error_control    => Service::ERROR_NORMAL,
        :binary_path_name => 'c:\\ruby187\bin\ruby.exe ' + File.expand_path($0),
        :load_order_group => 'Network',
        :dependencies     => ['W32Time','Schedule'],
        :display_name     => SERVICE_DISPLAY_NAME
   })

    puts( "Service " + SERVICE_DISPLAY_NAME + " Registered." )
    Service.start( SERVICE_NAME )
    exit( 0 )
elsif ( ARGV[ 0 ] == "del" )
    if Service.status( SERVICE_NAME ).current_state == "running"
        Service.stop( SERVICE_NAME )
    end
    Service.delete( SERVICE_NAME )
    puts( "Service " + SERVICE_DISPLAY_NAME + " Removed." )
    exit( 0 )
end

class Daemon
    def service_init
        sleep( 5 )
    end
    
    def service_main
        filecount = 0
        watchfile = "c:\\vegafish.txt"
        while( running?() )
            sleep( 3 )
            if ( File.exists?( watchfile ) )
                filecount++
                File.rename( watchfile, watchfile + filecount.to_s )
            end
        end
    end
end

Daemon.mainloop()

2012-01-08

The Bug of Google Picasa Public URL

If you upload pictures via mobile Google+, your Picasa public URL will be changed* automatically.

This bug is not fixed at 2012-01-08.

* Changed from Gmail account to Google+ account number, e.g. http://picasaweb.google.com/vegafish -> http://picasaweb.google.com/117166741167778447153

2011-10-03

以 Java 實作 Base 64 Encoder

或許有人會覺得奇怪,Java 本身已經有支援 Base 64 Encoder 了,為什麼還要自己重新寫一個? 事實上,Java 平台的 Base64Encoder 需要 import sun.misc.BASE64Encoder,然而這個類別卻不是在所有平台上面都可以正常執行(我個人的經驗是,在 android 執行時會當機)。 以下為 Base 64 Encoder 實作程式碼,歡迎各位朋友切磋學習。
private static String base64_encode( byte[] bytes ) {
        String[] base64 = { "A", "B", "C", "D", "E", "F", "G", "H",
                            "I", "J", "K", "L", "M", "N", "O", "P",
                            "Q", "R", "S", "T", "U", "V", "W", "X",
                            "Y", "Z", "a", "b", "c", "d", "e", "f",
                            "g", "h", "i", "j", "k", "l", "m", "n",
                            "o", "p", "q", "r", "s", "t", "u", "v",
                            "w", "x", "y", "z", "0", "1", "2", "3",
                            "4", "5", "6", "7", "8", "9", "+", "/" };
        String encoded = "";

        int pad_length = 0;
        if ( bytes.length % 3 == 1 )
            pad_length = 2;
        else if ( bytes.length % 3 == 2 )
            pad_length = 1;
        
        byte[] padded = new byte[ bytes.length + pad_length ];

        for( int i = 0; i < bytes.length; ++i ) {
            padded[ i ] = bytes[ i ];
        }
        if ( pad_length == 1 ) {
            padded[ padded.length - 1 ] = 0;
        } else if ( pad_length == 2 ) {
            padded[ padded.length - 1 ] = 0;
            padded[ padded.length - 2 ] = 0;
        }
        
        for( int i = 0; i < padded.length; i += 3 ) {
            encoded += base64[ ( ( padded[ i ] & 255 ) >>> 2 ) ];
            encoded += base64[ ( ( ( padded[ i ] & 3 ) << 4 ) | ( ( padded[ i + 1 ] & 255 ) >>> 4 )  ) ];
            encoded += base64[ ( ( ( padded[ i + 1 ] & 15 ) << 2 ) | ( ( padded[ i + 2 ] & 255 ) >>> 6 )  ) ];
            encoded += base64[ ( padded[ i + 2 ] & 63 ) ];
        }
        
        encoded = encoded.substring( 0, encoded.length() - pad_length );
        
        if ( pad_length == 1 ) {
            encoded += "=";
        } else if ( pad_length == 2 ) {
            encoded += "==";
        }

        return encoded;
    }

2011-09-02

再玩一下 AES 加密解密

上次在這篇「玩了一下AES加密解密」裡面寫的程式碼有些缺點,就是加密過後的結果是 byte[] 而不是 String,對於 Java 的操作上不是很方便。看了幾位高手的博文,自己做了些改良,同時也將程式碼放上來拋磚引玉。主要的改良是透過 BASE64Encoder 和 BASE64Decoder 將 byte[] 轉為可讀的英文字母 + 數字字串,這在網址的傳遞上也有好處,不需要變成%xx%xx的 UTF-8 形式,更容易偵錯與閱讀,也不減少其安全性。
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder; 

public class Base64AES {

    public static String decrypt( String key, String text ) throws Exception {
        byte [] results = decrypt( key.getBytes(), new BASE64Decoder().decodeBuffer( text ) );
        return new String( results );
    }

    public static String encrypt( String key, String text ) throws Exception {
        byte[] results = encrypt( key.getBytes(), text.getBytes() );
        return new BASE64Encoder().encode( results );
    } 
    
    public static byte[] encrypt( byte[] key, byte[] msg ) throws Exception {
        if ( key.length != 16 ) {
            throw new IllegalArgumentException( "Key length should be 16." );
        }
        SecretKeySpec spec = new SecretKeySpec( key, "AES" );
        IvParameterSpec ivSpec = new IvParameterSpec( key );
        Cipher cipher = Cipher.getInstance( "AES/CBC/PKCS5Padding" );
        cipher.init( Cipher.ENCRYPT_MODE, spec, ivSpec );
        return cipher.doFinal( msg );
    }
    
    public static byte[] decrypt( byte[] key, byte[] msg ) throws Exception {
        if ( key.length != 16 ) {
            throw new IllegalArgumentException( "Key length should be 16." );
        }
        SecretKeySpec spec = new SecretKeySpec( key, "AES" );
        Cipher cipher = Cipher.getInstance( "AES/CBC/PKCS5Padding" );
        IvParameterSpec ivSpec = new IvParameterSpec( key );
        cipher.init( Cipher.DECRYPT_MODE, spec, ivSpec );
        return cipher.doFinal( msg );
    }
    
    public static void main( String[] args ) throws Exception {
        String msg = "This is so easy.";
        
        System.out.println( "原字串: " + msg );
        System.out.println( "加密後: " + encrypt( "vegafish12345678" , msg ) );
        System.out.println( "解密後: " + decrypt( "vegafish12345678", encrypt( "vegafish12345678" , msg ) ) );
    }

}
執行結果如下:
原字串: This is so easy.
加密後: KczRl5uSsrgfwWRKpfR5FoKEIVU0jPvxX1VsEYl/jl0=
解密後: This is so easy.

2011-08-31

少子化的感想

少子化對臺灣所造成的影響,就是未來20年的經濟不景氣甚至倒退、生產力被侵蝕、到消亡的地步,已經有很多書籍探討,如《人口減少經濟時代》(ISBN 978-986-788942-3),在此就不多做論述了。

政府為何要人民生育?因為我們追求的是經濟成長率,我們一輩子都活在成長的年代,不管是營業額、GDP。一兩季的營業額負成長,即使是大如台積電的公司,員工、股東們會怎麼看?同樣的,當經濟負成長時,政府就得要擴大公共支出、舉債建設,以便提振景氣。

然而之前的經濟成長是怎麼來的呢?簡言之,龐氏騙局(Ponzi scheme)。從前的人民靠著新加入的勞動人口來推動經濟成長,加入的人比退出的人多,經濟就成長。而臺灣的經濟並不是靠高附加價值產業起家的,加入的人比退出的人少,經濟當然會衰退。

如果公司的營業額負成長達兩年、四年甚至十年,這種股票我們會想買嗎?很明顯的未來,我們已經看到了,只是從沒想過。那麼,我們已經在社會裡面的人要怎麼辦呢? :)

因為人民的短視近利,政客靠著生育補助、教育補助、老人照顧等等,就可以騙到選票。但人民卻忘了最基本的事情:為什麼要領生育補助、老人照顧的錢?

「因為我們和子女、父母相處的時間被剝奪了」

民主國家政府,很擅長利用數字混淆視聽。不論央行和政府如何唬爛,在世界上許多專業的投資者都是用國際金價當成購買力指標,直到現在,各國的幣值、甚至償債能力仍還是用黃金做為結算單位。

1990 臺灣人均收入 TWD 223,860 元,換算美金 USD 8,325 元,購買力相當於 20.8 oz 黃金
2011 臺灣人均假設 TWD 600,000 元,換算美金 USD 20,000 元,購買力相當於 11.4 oz 黃金

臺灣現在的實質薪水,比1990的薪資少了一半,所以雙薪家庭才能負擔一個20年前一個正常家庭的生活。在20年前的傳統是,爸爸出門賺錢,媽媽在家顧小孩、照顧爸媽、公婆。現在則是夫妻兩人去上班,小孩丟給爸媽、保母。這種環境下,不要說注重生活品質的人不想生了,就連想花時間陪小孩的人也沒辦法生。

會有這種「實質薪資下降」的結果原因很多,這邊的空間不夠寫(誤)。人民希望政府達到經濟成長的目標->政府為了達到目標,創造出有利企業賺錢的環境->企業為了追求獲利,會為了穩定的低毛利來源,放棄了投資高附加價值的產品,如創意、設計、藝術產業,甚至為了賺錢壓榨勞工。

我只能說臺灣人的現狀,是自找的啊。

2011-08-24

玩了一下AES加密解密

我將自己寫的程式碼貼上來,這是很簡短的程式,希望高手能稍加提點我自己不足之處。
import javax.crypto.Cipher;

import javax.crypto.spec.SecretKeySpec;

public class TestAES {

public static byte[] encrypt( byte[] msg ) throws Exception {
byte[] key = "vegafish12345678".getBytes(); // key 長度 = 16
return encrypt( key, msg );
}

public static byte[] encrypt( byte[] key, byte[] msg ) throws Exception {
if ( key.length != 16 ) {
throw new IllegalArgumentException( "Key length should be 16." );
}
SecretKeySpec spec = new SecretKeySpec( key, "AES" );
Cipher cipher = Cipher.getInstance( "AES" );
cipher.init( Cipher.ENCRYPT_MODE, spec );
return cipher.doFinal( msg );
}

public static byte[] decrypt( byte[] msg ) throws Exception {
byte[] key = "vegafish12345678".getBytes(); // key 長度 = 16
return decrypt( key, msg );
}

public static byte[] decrypt( byte[] key, byte[] msg ) throws Exception {
if ( key.length != 16 ) {
throw new IllegalArgumentException( "Key length should be 16." );
}
SecretKeySpec spec = new SecretKeySpec( key, "AES" );
Cipher cipher = Cipher.getInstance( "AES" );
cipher.init( Cipher.DECRYPT_MODE, spec );
return cipher.doFinal( msg );
}

public static void main( String[] args ) throws Exception {
String msg = "要被加密的訊息, the text would be encrypted.";

System.out.println( "原始String : " + msg );
System.out.println( "byte[]加密後: " + new String( encrypt( msg.getBytes() ) ) );
System.out.println( "byte[]解密後: " + new String( decrypt( encrypt( msg.getBytes() ) ) ) );
}

}

2011-08-16

Re: [新聞] 台灣生育率跌破1全球最低 (by hedonic.bbs@ptt.cc)

作者: hedonic (黑東尼克) 看板: Gossiping
標題: Re: [新聞] 台灣生育率跌破1全球最低
時間: Mon Aug 15 15:12:29 2011

※ 引述《blackponpon (自我充實)》之銘言:
: 為什麼新加坡在全球經濟不景氣的情況下可以脫穎而出
: 甚至政府還能夠發紅包給人民(不是消費券 那種東西就算了)
: 當政府說"沒有不景氣 只有不爭氣"的時候
: 我只想反問政府一句話:"那你爭氣了嗎?"


心得一下,我有兩位以前的同事到新加坡去工作(大馬僑生),目前都剛剛結婚

新加坡政府鼓勵增產很迂迴。

他鼓勵" 家庭的價值 ",甚麼是家庭的價值呢? 就是族群和諧、階級消除、互相扶持
創造回憶、社會公平。

新加坡的所得稅極低,即使外國人也只有10%,而所得極高,平均是台灣的兩倍,
雖然新加坡人抱怨他們房價上漲了五成,兩房的小家庭要20萬新幣( 大概台幣五百萬)

根據調查,新加坡人有97% 認為它們有能力購買房屋。

所以新加坡政府有很多手段去抑制房屋成為商品,包括年齡限制、轉手限制、諸如此類

第二點則是鼓勵新加坡的國家認同度,鼓勵新加坡人以新加坡國民自豪,大量吸納
外國人才進入,大量人才交換。

一旦年輕人順利成家、安心工作、居住解決,自然就會生養下一代。新加坡的教育相反的
對於高等教育並不是採用無差別升大學方式,平均教育年限並不高( 對台灣而言是很低)。
企業提供大量獎學金( 新加坡大企業有一半以上是國營企業)~~

新加坡的公務員採用面試方式錄用,也是會看顏色看血統看學習紀錄,( 總之不是看你會
不會考試),擔任公務員薪資並不會比民間特別高,(每次區長拿來比較的是新加坡的高官)
,由於新加坡的國營企業太廣泛所以其實所謂的公務員或是在國營事業都是幫李家打工。


現在回過頭來看我們腦殘的中華民國ER 區長以及弱智部下

我們有強調家庭價值嗎?

我們有賦稅公平,受薪階級所得稅低嗎?
我們有高所得環境嗎?
我們有低房價環境嗎?
我們有強調國家認同嗎? ( 好像有ROCER說燒成灰會變成TIWANESE)
我們有保障青年就業嗎? ( 22k.....
我們有優秀的高級公務員嗎?

我另一個同事,夫妻都是台大碩博士,收入兩人年薪破兩百,最近在台北想看個三房的
老公寓,開價幾乎都在兩千以上,中正大安信義他們連問都不敢問。

我們的房屋成為商品投資標的,兒童成為教育鬥爭犧牲品,公共政策成為撒錢途逕,
區長只有口號,部長都找一些阿里不達的廢渣,只會辦口號票選,不然就辦台灣國花博
( 有基隆、新北、新竹、花蓮等等國家參加)。

你叫人家怎麼安心生蛋?

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 59.124.255.100


我並沒有說新加坡不是獨裁國家。他是民主制度,共產國家。
李家天下控制了新加坡主要的經濟活動,包括公用事業、媒體。( 別忘記這些台灣大部分
也還在KMT手上,當然KMT控制力已經弱化很多了)

新加坡對國宅的控制很細膩,包括格局、族群、每個組屋要按照人口族群比例分配,
比如你是印度人,你要賣掉也只能賣印度人之類,總之嚴格控制各種轉賣。

許多組屋也設定比如結婚才能買,幾口之家才能買之類,另外區位也配合大眾運輸等等

但總之人家是真的再推社會住宅,不像台灣是口水住宅,或是像A7那種去搶農民給財團
在分配給人的不公不義宅。

民主社會一樣可以推公平國宅政策,只是我們的高官每個都是比有錢的,郝龍斌市長
他爸爸一生當兵繁忙之餘還買了七八十塊土地,你認為他會希望房價飆漲還是社會公平?

我住在天龍區,我的周圍一堆法官、老師、國營事業、銀行退休人員,大多有數間房產
你覺得台北人希望房價飆還是平?

2011-08-13

富爸爸窮爸爸 之 現金流遊戲 (Cashflow 202 e-game) 介紹

現金流遊戲這個遊戲已經有十幾年的歷史,其目的是將投資理論(Modern Portfolio Theory)教育給普羅大眾。這個遊戲是由「富爸爸.窮爸爸」系列書籍作者「羅伯特.清崎」所開發,一開始是紙上遊戲,後來演變為電子遊戲的形式。以「寓教於樂」的方式,讓使用者了解近代現實生活之投資理論,有很重要的幫助。

「富爸爸.窮爸爸」系列書籍旨要在提倡一個重要的觀念(轉載自 Wikipedia):「資產就是將錢放進你口袋裡的東西,而負債則是把你口袋的錢拿走的東西。」資產和負債不同的現金流向,會造成不同的財富結果。窮人只通過工作獲取收入,通過消費將掙來錢花出去,沒有任何資產。中產階級通過工作獲取收入,再去購買一些他們認為是資產的負債,然後通過償還負債,花光他們的錢,他們同樣也沒有資產。而富人則通過購買資產來產生收入,再用收入來購買資產,不斷地循環下去,最終獲得大量的財富,實現無需工作也能不斷獲得收入的財務自由狀態。同時,他認為,能真正讓人達到財務自由的,不是工作,也不是金錢,而是能帶來源源不斷現金流的資產

這個遊戲一開始,你扮演一隻老鼠,在現實生活中的財務迷宮繞圈圈(如圖1),無法掙脫這個圈圈,遊戲的目的簡單而言,在於讓玩家賺取到超過支出兩倍之被動收入,就可以逃出財務迷宮,進入財富高速公路,最後實現玩家的夢想。

老鼠賽跑
圖一:老鼠賽跑


實際上,財務迷宮是一個圈圈,老鼠的形象代表一般人,逃不出這個財務迷宮的圈圈,因為一般人總是有了收入,進而支出花費,但從未考慮要增加自己的被動收入。當花費增加,一般人只知道要改變工作、或是增加工時(接外務或打工),而不是先考慮添購能夠產生被動收入的資產。這代表了一般人若是失業、或是某些因素不能、不想工作的時候,就是不斷的吃老本、耗費儲蓄;但如果有足夠的被動收入,即使在不工作的狀況之下,儲蓄仍然會不斷增加,這就是被動收入的美妙之處。

那麼,什麼是可以產生被動收入的資產?在遊戲中只有一種:「各式各樣的房地產,透過收租金的方式,來製造現金流入」。而在現實生活中,可以產生被動收入的資產有很多:例如股票(每年會發配股利)、投資公司、商店或服務(投入資本回收獲利)、不動產如房屋、公寓或土地(透過出租的方式收取租金),其觀念是大同小異的:「用現金,買到一個不需要工作,而會每年,甚至每個月產生錢之標的物」就像會下金蛋的金雞,這就是被動收入。

遊戲進行過程中,走到綠色的格子,代表你有機會可以投資股票、選擇權(option)、或是房地產,遊戲設計者為了簡單化,遊戲中的股票沒有股息(dividend)僅用來賺取資本利得(capital gains);走到深藍色的格子,代表市場有變化,此時可以改變自己的投資部位;走到粉紅色的格子和紫色的格子,代表每月支出增加了,粉紅色代表非理性購物、意外,紫色代表玩家添了一個孩子(這個遊戲並不是提倡不要生孩子,而是告訴玩家,當不了解被動收入的重要時,和孩子相處的時間就會大幅下降,而孩子也不會快樂);當通過黃色或站在黃色的格子,就會獲得一次月收益(表示過了一個月);當走到紫色的格子,代表失業,需要支付一個月的支出,並暫停兩回合,本遊戲的失業機率出奇的高,會讓玩家感受到失業的痛苦(畢竟一般時候不常體會)。

每次有財務狀況的變更(如圖二),就需要更新自己的財務報表,若玩家有會計學(accounting)的基礎,一下就會知道遊戲裡面的報表有兩個:現金流量表(cash flow statement)和資產負債表(balance sheet),若玩家沒有會計學的基礎沒關係,遊戲會一直提示你將這個新的財務狀況歸檔至正確的會計名目下(如圖三)。

財務狀況變更
圖二:財務狀況變更


整理財務報表
圖三:整理財務報表


當玩家一旦取得了每月支出的兩倍被動收入,就可以逃出老鼠賽跑(如圖四)。在現實生活中,當被動收入超過每月支出的時候,就可以不用工作,讓被動收入來養活自己、甚至繼續累積資產,遊戲中訂為支出兩倍,可能是為了增加遊戲困難度之故。

逃出老鼠賽跑
圖四:逃出老鼠賽跑


逃出老鼠賽跑的迷宮之後,代表了完全的財富自由,遊戲中以進入財富高速公路(如圖五)的方式表示,玩家會發現自己可以買得起任何東西、投資失敗也完全不在意等。這邊要解說一下所謂的不在意:「因為被動收入大於投資失敗的損失,在投資心理學(psychology of finance)上會讓人冷靜,不會因為資產損失而患得患失、作出愚蠢判斷」這有些誇張,但不失為一種給玩家一個向財富自由靠攏的願景。

財富高速公路
圖五:財富高速公路


遊戲結束畫面,如圖六。

遊戲結束
圖六:遊戲結束

2011-08-01

中油直營站地圖

此系列地圖中,標示了臺灣中油公司直營加油站的地點與地址,並做以下標示:
黃色:提供刷卡自助加油服務的加油站
綠色:24小時營業的加油站
紅色:提供刷卡自助加油服務,並且24小時營業的加油站

資料來源:台灣中油全球資訊網
各位朋友若發現有任何錯誤、闕漏,請用信件或於地圖上留言的方式告訴我。
您的熱心將是地圖正確的重要因素。

中油直營站地圖(北北基)
中油直營站地圖(北北基) http://goo.gl/yR6Pd


中油直營站地圖(桃竹苗)
中油直營站地圖(桃竹苗) http://goo.gl/dkqP3


中油直營站地圖(中彰投)
中油直營站地圖(中彰投) http://goo.gl/qK61L


中油直營站地圖(雲嘉南)
中油直營站地圖(雲嘉南) http://goo.gl/jr6E8


中油直營站地圖(高屏)
中油直營站地圖(高屏) http://goo.gl/Fx4jE

2011-07-31

如何用 Blendtec 製作芒果奇異果飲料

先讓我們看看這位大叔如何用 Blendtec 把 iPhone4 打成碎片好了。(默)



其實這篇只是用來證明 Blendtec 可以直接把水果打成泥,不用切塊。

材料(2人份):
芒果 x 0.5顆
奇異果 x 3顆
不用加水、不用加糖

步驟:
1. 材料去皮
2. 丟進 Blendtec 並闔上蓋子
3. 按 Cycle Menu 直到螢幕出現 Beverage(飲料)選項
4. 按 Speed 直到螢幕出現 Fruit Drinks 選項
5. 按 Start/Stop 一次
6. 處理過程中,請壓著上蓋
7. 處理完畢後,將成品倒出即得

Blendtec 全貌
Blendtec 全貌


材料一覽
材料一覽


奇異果切半去皮
奇異果切半去皮


芒果去皮
芒果去皮


這麼大塊也可以處理
這麼大塊也可以處理


闔上蓋子
闔上蓋子


選擇 Fruit Drinks
選擇 Fruit Drinks


按下 Start/Stop
按下 Start/Stop


處理中
處理中


不到40秒就處理完畢
不到40秒就處理完畢


成品
成品

2011-05-04

使用 RMaps 記錄路徑並匯出到 Google Maps

RMaps 是 android 的地圖應用程式,一般用在手機無網路連線時,來觀看離線地圖。如何下載並製作離線地圖在 Dr. TYT 的 Android 地圖 有教學,這裡就不贅述了。

但其實很少人知道,RMaps 有如同另一個應用程式 My Tracks 的功能,可以記錄手機移動的路徑,並且可以匯出到 Google maps 做記錄。以下為使用此功能的步驟詳解:

1. 開啟 RMaps,並叫出功能表,點選 Tracks 選項。如圖一所示:

圖一
圖一


2. 欲開始記錄路徑時,點選 Start track record 按鈕。如圖二所示:

圖二
圖二


3. 正在記錄路徑的過程中,會在 android 狀態列顯示一個腳踏車的圖示,使用者可以根據這個圖示知道 RMaps 正在記錄,也可以點選它回到 RMaps 程式中。如圖三所示:

圖三
圖三


4. 路徑記錄完畢之後,點選 Stop 停止記錄。如圖四所示:

圖四
圖四


5. 點選路徑名稱標籤右方的綠色勾勾,該條路徑就會顯示在 RMaps 的地圖上,此步驟只和 RMaps 的顯示有關,若不想顯示路徑記錄可以略過。如圖五、六所示:

圖五
圖五

圖六
圖六


6. 長按路徑名稱標籤,叫出選單後,選擇 Export to KML file。如圖七所示:

圖七
圖七


7. 在步驟6.之後,記憶卡中的 \rmaps\export 目錄下,會看到一個 路徑名稱.kml 的檔案,這就是剛剛所匯出的路徑檔。

8. 在 Google maps 自己建的地圖內,點選 編輯 按鈕。如圖八所示:

圖八
圖八


9. 在地圖的編輯模式下,點選 匯入。如圖九所示:

圖九
圖九


10. 選擇步驟7.所看到的 kml 檔,再按 從檔案上載 按鈕,完成後即可在自建地圖內看到 RMaps 所記錄的路徑了。如圖十所示:

圖十
圖十

2010-11-28

Wii: Super Mario Bros. 25th Anniversary 超級瑪利歐25週年之紅色限定版 開箱

四年前,Wii 在日本發行之後,體感操作的遊戲風靡了全世界,帶領了 PS3 和 Xbox360 跟著推出各種體感裝置與遊戲。不能免俗地,我也在三年前從日本買了一台 Wii 讓家中長輩使用。然而,我一直缺少一臺屬於自己的 Wii,其中最大的原因是:Wii 只有黑色白色機體,卻沒有我喜歡的紅色

在今年11月初時,我的同事與其女友去日本旅遊,將他們的寶貝貓咪託我代養一週(工商服務時間,新竹/竹東貓咪代養,每週新臺幣 $500)。他們在日本碰巧看到了紅色限定版的 Wii 和 NDSiLL,也知道我喜歡紅色的東西,很貼心的詢問我有沒有需要。這是我夢寐以求的款式啊!二話不說就請同事幫我帶回來了,實在很感謝他們的幫忙。

超級瑪利歐25週年紀念版,2010-11-07 發售,共發行 NDSiXL 與 Wii 兩種限定版主機,活動官方網站。以下,就是 Super Mario Bros. 25th Anniversary 之 Wii 紅色限定版,開箱照。

這臺 Wii 剛下飛機
這臺 Wii 剛下飛機

外盒正面
外盒正面

外盒背面
外盒背面

內建超級馬利歐
主機內建超級馬利歐遊戲(遊戲中?方塊的字會變成25)

外盒側面
外盒側面,說明內容物以及注意事項
「Color aka」

打開盒子
打開盒子側面,發現盒內印刷也有巧思
「THANKS TO YOU ALL!」

第一層內容物
第一層的內容物,那張白色的小紙片是零售店的保證書

第二層內容物
第二層的內容物,在主機機身上方的是原廠贈送的拭鏡布

組裝後
組裝起來的照片

主機+主副手
主機和主副手一起入鏡

主手手把
主手手把,內建動感強化器
「Wii MotionPlus INSIDE」

NDSi和PSP
無關主題的照片

2010-11-04

Ruby 驅動外部程式的方法: %x, exec, system, IO.popen

以下外部程式名稱以「external_cmd」為範例
Linux 前景執行外部程式指令:
# external_cmd
或以背景執行外部程式:
# external_cmd &

1. %x 是最普遍的方法,用在想要取得外部程式的標準輸出結果,但該外部程式不需要標準輸入時。另外,無論是否以背景執行該外部程式,呼叫 %x 的 ruby 程式皆會等待外部程式結束,才會繼續執行。
Ruby 範例程式碼如下,執行外部程式的輸出會儲存在 external_cmd_output 變數內。注意{}裡面並不需要再用雙引號來框住指令。另外,%x 方法和 `` 語法相同。
external_cmd_output = %x{external_cmd}
external_cmd_output = %x{external_cmd &}
external_cmd_output = `external_cmd`
external_cmd_output = `external_cmd &`


2. exec 方法會在執行外部程式完畢以後,終止呼叫 exec 的 ruby 程式,不傳回任何值。
Ruby 範例程式碼如下。
exec "external_cmd"
puts "never get here." # 這一行的 ruby 程式不會被執行


3. system 方法會在執行外部程式完畢以後,傳回執行的結果,成功則傳回 true,失敗則傳回 false。system 和 %x 方法的不同之處,除了傳回值不一樣,我認為使用的時機最大的不同點在於執行背景程式的時刻。以 %x 背景執行外部程式時,會等待該外部程式結束後,再執行下一行 ruby 程式;然而以 system 背景執行外部程式時,在傳回執行結果後,無須等待外部程式結束即執行下一行 ruby 程式。
Ruby 範例程式碼如下,執行外部程式的結果(成功與否)會儲存在 external_cmd_result 變數內。
external_cmd_result = system "external_cmd"
external_cmd_result = system "external_cmd &"


4. IO.popen 方法適用於外部程式需要標準輸入的時候,如互動式的外部程式。若 IO.popen 執行的外部程式需要標準輸入時,在標準輸入串流被關閉後才會開始執行。
Ruby 範例程式碼如下,其中「text of output」這段文字會被輸入到 external_cmd 的標準輸入,另外 external_cmd 的標準輸出會被 puts 印出。
IO.popen( "external_cmd", 'r+' ) do |pipe|
    pipe.puts "text of output"
    pipe.close_write
    puts pipe.read
end

2010-09-10

CentOS 5.5 安裝 Ruby 1.8.7 + SQLite 3.6.16 + Rails 2.3.8

註1:本文件描述由無到有的 ruby 安裝流程,並不適合用在升級 ruby 套件的使用情境。
註2:安裝時需要以 root 帳號登入系統。

0. 前置安裝環境,若已安裝這些套件則本步驟可省略:

# yum -y install zlib-devel curl-devel expat-devel gettext-devel gcc make


1. 安裝 ruby 1.8.7:

# cd ~
# wget http://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p249.tar.gz
# tar zxvf ruby-1.8.7-p249.tar.gz
# cd ruby-1.8.7-p249
# ./configure --prefix=/usr
# make
# make install

[可省略] 檢查 ruby 版本:

# ruby -v

畫面應顯示:

ruby 1.8.7 (2010-01-10 patchlevel 249) [i686-linux]


2. 安裝 rubygems 1.3.5:

# cd ~
# wget http://rubyforge.org/frs/download.php/60718/rubygems-1.3.5.tgz
# tar zxvf rubygems-1.3.5.tgz
# cd rubygems-1.3.5
# ruby setup.rb

[可省略] 檢查 rubygems 版本:

# gem -v

畫面應顯示:

1.3.5


3. 安裝 sqlite 3.6.16:

# cd ~
# wget http://www.sqlite.org/sqlite-amalgamation-3.6.16.tar.gz
# tar xvzf sqlite-amalgamation-3.6.16.tar.gz
# cd sqlite-3.6.16
# ./configure --prefix=/usr
# make
# make install

[可省略] 檢查 SQLite 版本:

# sqlite3 -version

畫面應顯示:

3.6.16


4. 安裝 ruby 支援 sqlite3 的套件:

# gem install sqlite3-ruby

[可省略] 檢查是否安裝成功:

# gem list

畫面其中一行應顯示:

sqlite3-ruby (1.3.1)


5. 安裝 rails 2.3.8:

# gem install rails --version 2.3.8

[可省略] 檢查 rails 版本:

# rails -v

畫面應顯示:

Rails 2.3.8

2010-09-09

Ubuntu 10.04 LTS 安裝 Ruby 1.9.2 + SQLite 3 + Rails 3.0.0

註:本文件描述由無到有的 ruby 安裝流程,並不適合用在升級 ruby 套件的使用情境。
更新日期: 2010-09-10

1. 安裝所需的函式庫:

$ sudo apt-get install curl git-core build-essential zlib1g-dev libssl-dev libreadline5-dev


2. 安裝 ruby version manager (RVM),其中有個步驟需要變更使用者為 root:

$ sudo bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )
$ sudo su
$ mkdir -p ~/.rvm/src/ && cd ~/.rvm/src && rm -rf ./rvm/ && git clone --depth 1 git://github.com/wayneeseguin/rvm.git && cd rvm && ./install
$ exit


3. 安裝 ruby 1.9.2 (含 rubygems 1.3.7):

$ sudo rvm install 1.9.2
$ sudo rvm --default ruby-1.9.2

[可省略] 檢查 ruby 版本:

$ ruby -v

畫面應顯示:

ruby 1.9.2p0 (2010-08-18 revision 29036) [i686-linux]


3. 安裝 sqlite3 和 sqlite3-ruby 套件:

$ sudo apt-get install sqlite3 libsqlite3-dev
$ sudo gem install sqlite3-ruby


4. 安裝 rails 並製造一個 rails 命令的捷徑:

$ sudo gem install rails
$ sudo ln -s -f /usr/local/rvm/gems/ruby-1.9.2-p0/gems/rails-3.0.0/bin/rails /usr/bin/rails

[可省略] 檢查 rails 版本:

$ rails -v

畫面應顯示:

Rails 3.0.0

2010-08-24

Ubuntu 10.04 LTS 安裝 Ruby 1.8.7 + SQLite 3 + Rails 2.3.8

2010-09-09 更新:修改5.,指定 Rails 安裝版本。

1. 安裝 ruby 1.8.7:
$ sudo apt-get install ruby-full

[可省略] 檢查 ruby 版本,螢幕應顯示 ruby 1.8.7 (2010-01-10 patchlevel 249)
$ ruby -v

2. 安裝 gems 1.3.5:
$ sudo apt-get install rubygems

[可省略] 檢查 rubygems 版本,螢幕應顯示 1.3.5
$ gem -v

3. 安裝 sqlite 3:
$ sudo apt-get install sqlite3
$ sudo apt-get install libsqlite3-dev

4. 安裝 ruby 支援 sqlite3 的套件:
$ sudo gem install sqlite3-ruby

5. 安裝 rails 並製造一個 rails 命令的捷徑:
$ sudo gem install rails --version 2.3.8
$ sudo ln -s -f /var/lib/gems/1.8/bin/rails /usr/bin/rails

[可省略] 檢查 rails 版本,顯示畫面其中一行應為 rails (2.3.8)
$ gem list

2010-08-23

Ubuntu 10.04 LTS 安裝 Ruby 1.9.1 + Rails 2.3.8

2010-09-09 更新:Ruby 1.9.1 是不穩定的版本,並不建議依照本篇的方式安裝。請讀者參考另外兩篇以完成環境建置:
Ubuntu 10.04 LTS 安裝 Ruby 1.9.2 + SQLite 3 + Rails 3.0.0
Ubuntu 10.04 LTS 安裝 Ruby 1.8.7 + SQLite 3 + Rails 2.3.8

1. 安裝 ruby 1.9.1:
$ sudo apt-get install ruby1.9.1-full
$ sudo ln -s -f /usr/bin/ruby1.9.1 /usr/bin/ruby

[可省略] 檢查 ruby 版本,應為 ruby 1.9.1:
$ ruby -v

2. 安裝 gems for ruby 1.9.1:
$ sudo apt-get install rubygems1.9.1
$ sudo ln -s -f /usr/bin/gem1.9.1 /usr/bin/gem

[可省略] 檢查 rubygems 版本,應為 1.3.5:
$ gem -v

3. 安裝 sqlite 3:
$ sudo apt-get install sqlite3
$ sudo apt-get install libsqlite3-dev

4. 安裝 ruby 支援 sqlite 的套件:
$ sudo gem install sqlite3-ruby

5. 安裝 rails:
$ sudo gem install rails
$ sudo ln -s -f /var/lib/gems/1.9.1/bin/rails /usr/bin/rails

[可省略] 檢查 rails 版本,應為 rails (2.3.8):
$ gem list

2010-03-27

Blendtec Total Blender 開箱

會注意到 Blendtec,要感謝下方影片中的大叔,總是很努力不懈地用 Blendtec「處理」最新的科技產品(下方是用 Blendtec 將 iPhone 打碎的影片),當我第一次看到的時候簡直嚇壞了!令我對 Blendtec 留下深刻的印象。


之後再看產品的介紹時,了解它可以處理各種食物,不管是磨咖啡粉(連iPhone都可以磨成粉,咖啡豆應該難不倒它)、製作餅乾麵團、煮濃湯、打思樂冰、作果醬、冰淇淋或是最簡單的果汁或精力湯,都在它的守備範圍內,讓剛開始學烹飪的我魂牽夢縈!可惜看到臺灣代理商的價格並不是我能負擔得起的,實在令我裹足不前。幸運的是,我有個美麗又熱心的好朋友在美國唸書,就麻煩他回國的時候將自己用過的 Blendtec 二手賣給我囉!該說的都說完了,請看以下圖片!

盒裝外觀
盒裝外觀

打開紙箱就看到一本 Blender 送的食譜
打開紙箱就看到一本 Blender 送的食譜

說明書以及注意事項
說明書以及注意事項

左邊是調理杯底部,右邊是杯蓋
左邊是調理杯底部,右邊是杯蓋

將杯蓋拿起後,本體電線露出來了
將杯蓋拿起後,本體電線露出來了

左邊是調理杯,右邊是 Blender 本體
左邊是調理杯,右邊是 Blender 本體

調理杯攪拌棒特寫
調理杯攪拌棒特寫

本體與調理杯接盒處特寫
本體與調理杯接盒處特寫

整體外觀(可以看到左後方有 Roomba 正在休息)
整體外觀(可以看到左後方有 Roomba 正在休息)