2012年4月25日 星期三

[Linux] 透過 Tarball 安裝軟體與桌面環境設定 @ Ubuntu 10.04

eclipse


安裝 Android 開發環境時,從 Android 官網介紹,安裝新版 ADT Plugin for Eclipse 建議採用 Eclipse 3.6.2 以上的版本,但 Ubuntu 10.04 環境中,預設是 3.5.2-2ubuntu4.3,因此打算從 Eclipse 官網下載 Eclipse Classic 3.7.2 版本,只是解壓縮後,要執行他還是必須透過 /path/eclipse/eclipse 方式,好一點是把他擺在系統環境變數可節省一些打字,然而,這些對使用 Ubuntu Desktop 的人來說,仍舊不方便。


幸運地,在網路上找到了解法:How to install Eclipse 3.7 on Ubuntu 11.04,在此就筆記一下對於 tarball 安裝該如何整合 desktop 環境操作。


主要三個步驟:



  • 安置 tarball 軟體

  • 設定環境變數

  • 設定 Desktop 選單環境


流程:


$ cd ~/
$ tar -xvf eclipse-SDK-3.7.2-linux-gtk.tar.gz
$ sudo mv eclipse /opt/
$ sudo chown -R root:root /opt/eclipse
$ sudo chmod -R +r /opt/eclipse


$ sudo touch /usr/bin/eclipse
$ sudo chmod 755 /usr/bin/eclipse
$ sudo vim /usr/bin/eclipse
#!/bin/sh
export ECLIPSE_HOME="/opt/eclipse"
$ECLIPSE_HOME/eclipse $*


$ sudo vim /usr/share/applications/eclipse.desktop
[Desktop Entry]
Encoding=UTF-8
Name=Eclipse
Comment=Eclipse IDE
Exec=eclipse
Icon=/opt/eclipse/icon.xpm
Terminal=false
Type=Application
Categories=GNOME;Application;Development;
StartupNotify=true


如此一來,在 Ubuntu Desktop 的功能分類就能看到 Eclipse 了,並且也能正確顯示 icon 圖示,收工!


2012年4月22日 星期日

[Android] 更改 AOSP 顯示的帳號資訊

setting_about


最近把玩 AOSP 時,在 setting/about 可以看到此 AOSP 的編譯相關資訊,基於隱私想要更改他 XD 接著透過 grep -r "username" 的搜尋方式,發現此資訊擺放處:out/target/product/panda/system/build.prop 裡頭。


來回測試,發現修改方式有三種,第一種就是建立一個假帳號來編譯,讓 AOSP 編譯過程中取得假帳號的資訊;第二種方式則是變更環境變數 User 資訊,接著再重新編譯;第三種則是直接修改 out/target/product/panda/system/build.prop 資訊,並刪掉系統關鍵檔案,使之只重新編譯關鍵東西即可。


第二種方式:


$ cd ~/aosp
~/aosp$ source build/envsetup.sh
~/aosp$ make clean
~/aosp$ User=username
~/aosp$ lunch full_panda-eng
~/aosp$ make -j4


大約執行兩三分鐘後,就可以去翻 ~/aosp/out/target/product/panda/system/build.prop 出來看看,搜尋一下應該看不到自己的帳號名稱。此流程適合剛開始編譯或剛好打算全部重編用的。


第三種方式:


$ cd ~/aosp
~/aosp$ source build/envsetup.sh
~/aosp$ lunch full_panda-eng
~/aosp$ vim out/target/product/panda/system/build.prop
~/aosp$ rm out/target/product/panda/system.img
~/aosp$ make -j4


由於許多東西早已編好了,只是重新 build system.img 而已,算是最快的解法吧。


以上算是無聊想到的東西,但第二種跟第三種解法跟一比較起來,不曉得有沒更細節的東西沒清掉 XD


[漫畫] 食夢者/爆漫王


圖: wiki - 爆漫王


好像是去年十月後,開始透過 iPad 閱讀畫籍,大概今年二月底還三月初追了這部漫畫到第 170 話,今天無聊上網查一下線上漫畫,不一會兒就看到完結的訊息了(176話) XD 這半年來,無聊時會翻翻電子書閱讀軟體,東看看西翻翻,畢竟我太少買書、看書了,隨意回想,我看了灌籃高手、幽遊白書、第三隻眼、七龍珠、城市獵人、地獄老師、神龍之謎等兒時未完成的故事,好不容易鼓起勇氣接觸新的漫畫,第一部就是這「爆漫王」。今年真奇妙,隨手拈來盡是夢想相關的主題意識。


這部漫畫是在講兩位國中生開始畫漫畫的故事,裡頭很多小東西很像創業、經商一樣,例如讓漫畫(家)生存下來,如何吸引讀者票數,各類畫風影響等等的,初次接觸這部漫畫有被吸引到 :D 但如果反過來先用經商、創業的角度來看待這部漫畫,那收穫應該是很少很少的。透過這部漫畫的閱讀,讓此刻的我會多加思考,對自己人生有意義的東西該多放一點生命、時間進去追求的囉 :)


2012年4月18日 星期三

師父: 那些我在課堂外學會的本事

師父 - 那些我在課堂外學會的本事


記得 n 年前聽同事分享這本書很好看,當下我就隨手跟圖書館預約了,直到 n > 1.5 年後?我終於排到這本書了 XD 不愧是熱門書,書皮都快翻爛了,我看了幾十頁就下單買了這本書。這本書其實是把常聽到的粗略小事濃縮成故事敘說出來,如果你周邊都是一群真正拿自己的錢在創業的,那或許早已聽過五四三呢。


這本書比較著重在數字的管理,算是挺善用數學的效應 :D 我覺得對一般有興趣創業的人都可以翻來筆記一下,不是多高深的技術,卻還挺有用的,應該算通用的角度跟經驗分享。如果說 「Rework 工作大解放:這樣做事反而更成功」是用來激勵人心,那「師父:那些我在課堂外學會的本事」則偏向營運管理吧 :D 我覺得這兩本都算是創業型書籍,而且不像教科書那種 xx 管理課程,必須在大公司才能展現,甚至這本書的某章節還帶到一點 Game Theory 的生活應用角度喔,就那句經典名言:尋求彼此「不滿意,但可以接受」的狀態。


這本書比較適合細細品味,偶爾翻個一兩回也挺不錯的。


[Java] 使用 Apache POI 擷取 Word、Excel、PowerPoint 文字


Apache POI - the Java API for Microsoft Documents


這次用 POI 的目的是練習把 Word、Excel 和 PowerPoint 裡頭的文字擷取出來,如果用 "extract"、"text" 和 "doc"、"docx"、"ppt" 和 "pptx" 很容易找到網路上用 Apache POI 所作的範例,此次我就拿這套來練習,那目標呢?我翻了一下 POI 的程式碼,至少要做到 doc、docx、ppt、pptx、xls、xlsx 的文字抽取,而測次結果的確都做得到了。


首先我很懶地看文字,只稍微看到官網的 Text Extraction 介紹,但那段就成為我程式的主要架構了,經過多次的旁敲側擊,讓我發現挖到寶的是 TestExtractorFactory.java!真的是太讚啦,簡單地說我想要了解 POI 跟如何去做的事,完完全全看 TestExtractorFactory.java 就搞定了!包含支援哪些檔案格式、怎樣用,全部清清楚楚,看來從 test case 開始也是另類的偷懶式學習。


最後,程式碼:


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.StringBuffer;


// https://svn.apache.org/repos/asf/poi/trunk/src/ooxml/testcases/org/apache/poi/extractor/TestExtractorFactory.java
import org.apache.poi.POIOLE2TextExtractor;
import org.apache.poi.POITextExtractor;
//import org.apache.poi.POIDataSamples;
//import org.apache.poi.extractor.*;
import org.apache.poi.extractor.ExtractorFactory;
import org.apache.poi.hdgf.extractor.VisioTextExtractor;
import org.apache.poi.hpbf.extractor.PublisherTextExtractor;
import org.apache.poi.hslf.extractor.PowerPointExtractor;
import org.apache.poi.hsmf.extractor.OutlookTextExtactor;
import org.apache.poi.hssf.extractor.EventBasedExcelExtractor;
import org.apache.poi.hssf.extractor.ExcelExtractor;
import org.apache.poi.hwpf.extractor.Word6Extractor;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.xslf.extractor.XSLFPowerPointExtractor;
import org.apache.poi.xssf.extractor.XSSFEventBasedExcelExtractor;
import org.apache.poi.xssf.extractor.XSSFExcelExtractor;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;


import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.poifs.filesystem.OfficeXmlFileException;


import org.apache.poi.xslf.usermodel.XMLSlideShow; // pptx 2007, http://poi.apache.org/apidocs/org/apache/poi/xslf/
import org.apache.poi.xwpf.usermodel.XWPFDocument; // docx 2007, http://poi.apache.org/apidocs/org/apache/poi/xwpf/
import org.apache.poi.xssf.usermodel.XSSFWorkbook; // xlsx 2007, http://poi.apache.org/apidocs/org/apache/poi/xssf/


class ExtractText
{
    public static String file(String path)
    {
        try { return pptx(new FileInputStream(path)); } catch(Exception e) { }
        try { return docx(new FileInputStream(path)); } catch(Exception e) { }
        try { return xlsx(new FileInputStream(path)); } catch(Exception e) { }
        return "";
    }
    public static String pptx(InputStream in) throws Exception
    {
        XSLFPowerPointExtractor o = new XSLFPowerPointExtractor( new XMLSlideShow(in) );
        o.setSlidesByDefault(true);
        o.setNotesByDefault(true);
        return o.getText();
    }
    public static String docx(InputStream in) throws Exception
    {
        XWPFWordExtractor o = new XWPFWordExtractor(new XWPFDocument(in));
        return o.getText();
    }
    public static String xlsx(InputStream in) throws Exception
    {
        XSSFExcelExtractor o = new XSSFExcelExtractor(new XSSFWorkbook(in));
        return o.getText();
    }
    public static void main(String argv[])
    {
        try
        {
            InputStream in = null;
            if( argv.length < 1 )
                in = System.in;
            else
                in = new FileInputStream(path);
            StringBuffer output = new StringBuffer();
            POITextExtractor textExtractor = ExtractorFactory.createExtractor(in);
            //POIFSFileSystem fileSystem = new POIFSFileSystem(in);
            //POITextExtractor textExtractor = ExtractorFactory.createExtractor(fileSystem);
            //POIOLE2TextExtractor oleTextExtractor = ExtractorFactory.createExtractor(fileSystem);
            //POITextExtractor[] embeddedExtractors = ExtractorFactory.getEmbededDocsTextExtractors(oleTextExtractor);
            //for (POITextExtractor textExtractor : embeddedExtractors)
            {
                if (textExtractor instanceof ExcelExtractor) // xls, excel 97-2003
                {
                    ExcelExtractor extractor = (ExcelExtractor) textExtractor;
                    //System.out.println(extractor.getText());
                    output.append(extractor.getText());
                }
                else if (textExtractor instanceof XSSFExcelExtractor) // xlsx, excel 2007
                {
                    XSSFExcelExtractor extractor = (XSSFExcelExtractor) textExtractor;
                    //System.out.println(extractor.getText());
                    output.append(extractor.getText());
                }
                else if (textExtractor instanceof Word6Extractor) // doc, word 95
                {
                    Word6Extractor extractor = (Word6Extractor) textExtractor;
                    // http://poi.apache.org/apidocs/org/apache/poi/hwpf/extractor/Word6Extractor.html
                    //for (String paragraph : extractor.getParagraphText() )
                    // System.out.println(paragraph);
                    //System.out.println(extractor.getText());
                    output.append(extractor.getText());
                }
                else if (textExtractor instanceof WordExtractor) // doc, word 97-2003
                {
                    WordExtractor extractor = (WordExtractor) textExtractor;
                    // http://poi.apache.org/apidocs/org/apache/poi/hwpf/extractor/WordExtractor.html
                    //System.out.println(extractor.getHeaderText());
                    //System.out.println(extractor.getFooterText());
                    //for (String paragraph : extractor.getParagraphText() )
                    // System.out.println(paragraph);
                    //System.out.println(extractor.getText());
                    output.append(extractor.getText());
                }
                else if (textExtractor instanceof XWPFWordExtractor) // docx, word 2007
                {
                    XWPFWordExtractor extractor = (XWPFWordExtractor) textExtractor;
                    //System.out.println(extractor.getText());
                    output.append(extractor.getText());
                }
                else if (textExtractor instanceof PowerPointExtractor) // ppt, ppt 97-2003
                {
                    PowerPointExtractor extractor = (PowerPointExtractor) textExtractor;
                    //System.out.println(extractor.getText());
                    //System.out.println(extractor.getNotes());
                    output.append(extractor.getText());
                    output.append(extractor.getNotes());
                }
                else if (textExtractor instanceof XSLFPowerPointExtractor ) // pptx, powerpoint 2007
                {
                    XSLFPowerPointExtractor extractor = (XSLFPowerPointExtractor) textExtractor;
                    extractor.setSlidesByDefault(true);
                    extractor.setNotesByDefault(true);
                    //System.out.println(extractor.getText());
                    output.append(extractor.getText());
                }
                else if (textExtractor instanceof VisioTextExtractor) // vsd, visio
                {
                    VisioTextExtractor extractor = (VisioTextExtractor) textExtractor;
                    //System.out.println(extractor.getText());
                    output.append(extractor.getText());
                }
                else if (textExtractor instanceof PublisherTextExtractor) // pub, publisher
                {
                    PublisherTextExtractor extractor = (PublisherTextExtractor) textExtractor;
                    //System.out.println(extractor.getText());
                    output.append(extractor.getText());
                }
                else if (textExtractor instanceof OutlookTextExtactor) // msg, outlook
                {
                    OutlookTextExtactor extractor = (OutlookTextExtactor) textExtractor;
                    //System.out.println(extractor.getText());
                    output.append(extractor.getText());
                }
            }
            System.out.println(output.toString().replaceAll( "[\n\t\r ]+"," "));
        }
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            // e.printStackTrace();
            // System.out.println(e);
        }
    }
}


編譯,使用 poi-bin-3.8-20120326.zip 版本:


$ javac -Xlint:deprecation -cp .:lib-3.8/commons-logging-1.1.jar:lib-3.8/poi-3.8-20120326.jar:lib-3.8/poi-ooxml-schemas-3.8-20120326.jar:lib-3.8/dom4j-1.6.1.jar:lib-3.8/poi-examples-3.8-20120326.jar:lib-3.8/poi-scratchpad-3.8-20120326.jar:lib-3.8/junit-3.8.1.jar:lib-3.8/poi-excelant-3.8-20120326.jar:lib-3.8/stax-api-1.0.1.jar:lib-3.8/log4j-1.2.13.jar:lib-3.8/poi-ooxml-3.8-20120326.jar:lib-3.8/xmlbeans-2.3.0.jar ExtractText.java


執行,使用 poi-bin-3.8-20120326.zip 版本:


$ java -cp .:lib-3.8/commons-logging-1.1.jar:lib-3.8/poi-3.8-20120326.jar:lib-3.8/poi-ooxml-schemas-3.8-20120326.jar:lib-3.8/dom4j-1.6.1.jar:lib-3.8/poi-examples-3.8-20120326.jar:lib-3.8/poi-scratchpad-3.8-20120326.jar:lib-3.8/junit-3.8.1.jar:lib-3.8/poi-excelant-3.8-20120326.jar:lib-3.8/stax-api-1.0.1.jar:lib-3.8/log4j-1.2.13.jar:lib-3.8/poi-ooxml-3.8-20120326.jar:lib-3.8/xmlbeans-2.3.0.jar ExtractText < MyOfficeFile2003.doc


$ java -cp .:lib-3.8/commons-logging-1.1.jar:lib-3.8/poi-3.8-20120326.jar:lib-3.8/poi-ooxml-schemas-3.8-20120326.jar:lib-3.8/dom4j-1.6.1.jar:lib-3.8/poi-examples-3.8-20120326.jar:lib-3.8/poi-scratchpad-3.8-20120326.jar:lib-3.8/junit-3.8.1.jar:lib-3.8/poi-excelant-3.8-20120326.jar:lib-3.8/stax-api-1.0.1.jar:lib-3.8/log4j-1.2.13.jar:lib-3.8/poi-ooxml-3.8-20120326.jar:lib-3.8/xmlbeans-2.3.0.jar ExtractText < MyOfficeFile2003.xls


$ java -cp .:lib-3.8/commons-logging-1.1.jar:lib-3.8/poi-3.8-20120326.jar:lib-3.8/poi-ooxml-schemas-3.8-20120326.jar:lib-3.8/dom4j-1.6.1.jar:lib-3.8/poi-examples-3.8-20120326.jar:lib-3.8/poi-scratchpad-3.8-20120326.jar:lib-3.8/junit-3.8.1.jar:lib-3.8/poi-excelant-3.8-20120326.jar:lib-3.8/stax-api-1.0.1.jar:lib-3.8/log4j-1.2.13.jar:lib-3.8/poi-ooxml-3.8-20120326.jar:lib-3.8/xmlbeans-2.3.0.jar ExtractText < MyOfficeFile2003.ppt


$ java -cp .:lib-3.8/commons-logging-1.1.jar:lib-3.8/poi-3.8-20120326.jar:lib-3.8/poi-ooxml-schemas-3.8-20120326.jar:lib-3.8/dom4j-1.6.1.jar:lib-3.8/poi-examples-3.8-20120326.jar:lib-3.8/poi-scratchpad-3.8-20120326.jar:lib-3.8/junit-3.8.1.jar:lib-3.8/poi-excelant-3.8-20120326.jar:lib-3.8/stax-api-1.0.1.jar:lib-3.8/log4j-1.2.13.jar:lib-3.8/poi-ooxml-3.8-20120326.jar:lib-3.8/xmlbeans-2.3.0.jar ExtractText < MyOfficeFile2007.docx


$ java -cp .:lib-3.8/commons-logging-1.1.jar:lib-3.8/poi-3.8-20120326.jar:lib-3.8/poi-ooxml-schemas-3.8-20120326.jar:lib-3.8/dom4j-1.6.1.jar:lib-3.8/poi-examples-3.8-20120326.jar:lib-3.8/poi-scratchpad-3.8-20120326.jar:lib-3.8/junit-3.8.1.jar:lib-3.8/poi-excelant-3.8-20120326.jar:lib-3.8/stax-api-1.0.1.jar:lib-3.8/log4j-1.2.13.jar:lib-3.8/poi-ooxml-3.8-20120326.jar:lib-3.8/xmlbeans-2.3.0.jar ExtractText < MyOfficeFile2007.xlsx


$ java -cp .:lib-3.8/commons-logging-1.1.jar:lib-3.8/poi-3.8-20120326.jar:lib-3.8/poi-ooxml-schemas-3.8-20120326.jar:lib-3.8/dom4j-1.6.1.jar:lib-3.8/poi-examples-3.8-20120326.jar:lib-3.8/poi-scratchpad-3.8-20120326.jar:lib-3.8/junit-3.8.1.jar:lib-3.8/poi-excelant-3.8-20120326.jar:lib-3.8/stax-api-1.0.1.jar:lib-3.8/log4j-1.2.13.jar:lib-3.8/poi-ooxml-3.8-20120326.jar:lib-3.8/xmlbeans-2.3.0.jar ExtractText < MyOfficeFile2007.pptx


只能說這軟體架構不錯,僅須稍微修改就能弄成自動判斷格式囉 :D 在此開發的環境是 Ubuntu ,因此在 -cp 參數的數值,多個 jar 檔是用冒號 ":" 分隔的,若是 Windows 的話,要改成對應的(不確定是不是分號 ";")


2012年4月12日 星期四

[iOS] 安裝 gcc、libgcc 和 header files @ iPad 5.0.1

有一陣子沒有玩 iOS 的東西,因為一些需求想要在 iOS 裡觀察系統變化,所以寫了一隻簡單的 C 程式,好不容易搞出個 gcc 後,編譯時會顯示 header file not found 的資訊,連 stdio.h 都找不到。所幸,網路上還滿多人把玩 nodejs on iPhone 的,不一會兒就找到解答啦 :D 順道筆記一下。以上的行為都是要 jailbreak 後才能進行的。


安裝 gcc:


在 Cydia 裡頭可以找到 gcc,但安裝時卻說需要 libgcc 才能進行,網路上有一些別人編好的 libgcc ,在此使用 http://apt.saurik.com/debs/ 裡頭的 libgcc_4.2-20080410-1-6_iphoneos-arm.deb,其中 saurik.com 正是 Cydia 開發及維護者,既然 jb 都建立在 Cydia 上頭,就沒啥好懷疑資安了 XD


@ iOS 系統
# cd /tmp
# wget http://apt.saurik.com/debs/libgcc_4.2-20080410-1-6_iphoneos-arm.deb
# dpkg -i libgcc_4.2-20080410-1-6_iphoneos-arm.deb


安裝完 libgcc 後,就可以在 Cydia 上頭順利安裝 gcc 囉


還有其他安裝法,可以參考:http://code.google.com/p/iphone-gcc/wiki/Installing


安裝相關 header files:


參考 How To: Set up GCC on iOS 4 的一些步驟,首先要在 iOS 裡頭安裝 rsync ,直接用 Cydia 安裝即可(我也順便安裝了 wget、vim 和 screen),接著,由於現有的 Mac OSX 環境是 Mac OSX 10.6 與 Xcode 4.2 (Build 4C199),裡頭用的是 iOS 5 SDK,因此採用的指令:


@ Mac OSX 10.6 + Xcode 4.2
> rsync -avz --ignore-existing -e ssh /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/usr/lib/ root@Your_Device_IP:/usr/lib
> rsync -avz --ignore-existing -e ssh /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/usr/include/ root@Your_Device_IP:/usr/include
> rsync -avz --ignore-existing -e ssh /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/PrivateFrameworks/ root@Your_Device_IP:/System/Library/PrivateFrameworks/
> rsync -avz --ignore-existing -e ssh /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/ root@Your_Device_IP:/System/Library/Frameworks/
> scp /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/usr/include/crt_externs.h root@Your_Device_IP:/usr/include/crt_externs.h


如此一來,就可以有對應的系統 header files 啦,雖然編譯時會顯示一堆 ld warning: bad symbol version,但對我而言剛好不影響程式的執行,就不管他了 XD 終於,我可以寫 C 了!!


2012年4月11日 星期三

[MySQL] SUBSTRING_INDEX 字串處理函式

最近因工作開始使用 MySQL ,才發現 MySQL 有內建非常豐富的函式,此例以 SUBSTRING_INDEX 作為代表。更多 String Functions 請參考 http://dev.mysql.com/doc/refman/5.0/en/string-functions.html


mysql> desc Test;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| Name | varchar(50) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> INSERT INTO `Test` (`Name`) VALUES ('A-1'),('A-2'),('A-3'),('B-1'),('B-2'),('C-1');
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0

mysql> SELECT * FROM `Test`;
+------+
| Name |
+------+
| A-1 |
| A-2 |
| A-3 |
| B-1 |
| B-2 |
| C-1 |
+------+
6 rows in set (0.00 sec)

mysql> SELECT SUBSTRING_INDEX(`Name`,'-',1) AS `TopItem` FROM `Test` GROUP BY `TopItem`;
+---------+
| TopItem |
+---------+
| A |
| B |
| C |
+---------+
3 rows in set (0.00 sec)


mysql> SELECT SUBSTRING_INDEX(`Name`,'-',-1) AS `SubItem` FROM `Test` GROUP BY `SubItem`;
+---------+
| SubItem |
+---------+
| 1 |
| 2 |
| 3 |
+---------+
3 rows in set (0.00 sec)

mysql> SELECT SUBSTRING_INDEX(`Name`,'-',-1) AS `BSubItem` FROM `Test` WHERE SUBSTRING_INDEX(`Name`,'-',1) = 'B';
+----------+
| BSubItem |
+----------+
| 1 |
| 2 |
+----------+
2 rows in set (0.00 sec)


2012年4月10日 星期二

遇見未來


這幾年看了幾齣七喜的廣告,還真不賴 XD 回想起來,台灣的廣告似乎只剩下一些"保險業"的廣告,也是用這一類觸動人心的角度。


2012年4月9日 星期一

RMaps 離線地圖 - 批次匯入個人 POI、KML 檔案

rmaps_with_poi


有在旅行的朋友,對於地圖的使用應該不陌生,然而 Google Maps 提供的服務是需要在網路的情況下使用,到了另一個國度後,便需要尋找免費的 wifi 服務才能使用。有十分好心的 Android app 開發者免費推出這款離線地圖軟體 - RMaps!起初我只是拿來存存台灣地圖觀看路線,而後使用上發現自助旅行更是需要!雖然此軟體介面上可以透過點選地圖任一點新增 POI 資訊,但這樣操作實在太慢,手機是一個適合閱讀的環境,還不太算適合書寫的環境。


my_places


這時候,建議先用用 Google Maps 之 My Places 服務,中文翻成 "我的地點",可以建立自己的地圖,並且透過 Google Maps 的操作介面新增所需要的景點位置,甚至景點筆記等等的,由於是在 PC 瀏覽器上頭操作,工作效率++


my_places_export


新增完景點後,點選完成,就會看到上述的樣貌,此時就可以看到 KML 字樣,點選它就會把此地圖所有 POI 資訊匯出成一個 KML 檔案,接著傳入手機記憶卡中,僅需在 RMaps 介面操作就可以把這些 POI 資訊匯入手機觀看啦


rmaps_01 rmaps_02 rmaps_03 rmaps_04


成果:


rmaps_with_poi


如此一來,在當地不熟時,可以僅開啟 GPS 定位(智慧手機多少有支援可查 spec 確認,且是免費的),接著就可以查看自己與景點的相對位置,實在是非常讚的自助旅行輔助軟體。


多提一點的是 GPS 定位僅供參考,如果周邊都是高樓大廈,那定位非常容易會偏掉,建議還是以當下看到的馬路名稱作簡單的人眼定位吧 :D 至於 RMaps 的離線地圖製作,可以搜尋 Mobile Atlas Creator 關鍵字,或是參考此篇簡略介紹 使用 Mobile Atlas Creator 製作台灣離線地圖 Zoom Level 0-17,最新版的 Mobile Atlas Creator 已經移除 Google Maps 來源,若真的需要可以去找找舊版(如 Mobile Atlas Creator 1.8 版),而旅遊景點通常不會太大(港澳約700MB),再加上現在手機記憶卡都很便宜了(16GB microSD大概 500~600元),因此用起來並不會不方便。


2012年4月8日 星期日

[旅遊] 香港、澳門 4天3夜 自由行、機加酒費用比較

大三巴 星光大道


今年剛好有一些特休假可以規劃,原先看著網路上七八千便宜的機加酒行程而動心(未稅價),等到搞清楚之後,才發現花的錢越來越多了,這一切果然都是商人的陰謀,我中計了 XD


以下是我這趟行程的大項目的費用表(若不需辦護照可以扣 3600 台幣;台胞證或幾個月台灣可以免港簽後,則又可以扣 600 台幣,兩人別忘了 x2 喔):


澳進港出4天3夜2人價目


港澳旅遊需準備的基本項目:



  1. 來回機票 (桃園<->香港/澳門,來回票約 8500~10000 元)

  2. 香港簽證 (電子簽證,一人 600 元)

  3. 酒店住宿

  4. 地鐵船票 (港澳船票、八達通卡、機場快線、景點覽車)


如果你跟我一樣是第一次準備自由行,那首先要搞懂的是"機加酒"的方案,所謂的機加酒就是機票加酒店的方案,且機票又有分未稅和含稅的,整體上全部要花的錢就叫作加過稅的,如機場稅、兵險稅、燃料稅等,而去香港的稅大概 2300 ~ 2600 左右,只要機票上沒標記加稅,那大概就是要再加個 2600 左右吧。所以,一開始吸引我注意的台幣八千塊三天兩夜的香港自由行,事實上加完稅就是一萬一了!


除了機票外,還有個東西叫作簽證,進入香港需要簽證,而旅行社辦理簽證的費用大多是一人 600 元的價錢,網路上可以找到代辦 290~300 元的價碼。但辦理簽證是需要護照影本的,基於擔心隱私問題,我想這次就給旅行社賺一下吧 XD 簽證主要是用在進出香港用的,目前進出香港還是需要簽證的(據說有再慢慢往免簽進行),進出兩次就是要申請一次簽證,如果你是先飛香港,再從香港搭船到澳門在返香港,再從香港回台灣的話,那等於進出香港兩次,慶幸的電子簽證可以用兩次,有問題還是播通電話問一下旅行社吧!


搞定機票、簽證後,就是安排住宿,好的旅舍跟差的旅舍除了價錢外,也會影響旅遊的心情。專業的背包客通常都會找很精簡的旅舍,達到更佳金錢效率,由於我不怎專業,就還是用簡單的方式(花錢)來解決 :P 說真的,原先看到機加酒時,覺得四天三夜收 16k 很貴,自作聰明地把 16k - 8k (來回機票) = 9k 當作住宿的錢,覺得三晚收 9k 很貴,更特別是兩人去等於三晚被收 18k,一晚住 6k。但當我全盤了解後,才發現在背包客網站上寫的那一句話:


「自由行不見得比機加酒便宜,但完成這一切是一種成就感」


是的,搞清楚後,才發現這次這種臨時起意的自由行真的被機加酒方案打到趴下來 XD 可能辛苦安排規劃後,結果才小賺甚至花的還比機加酒方案多,並且有些機加酒還有旅遊保險呢 (所幸現在刷信用卡時,大多就有旅遊保險功能) 總之,如果你不想花時間去構思從頭打造的自由行,那就訂機加酒方案吧 :D 基本上是不太會吃虧的,可以住還不錯的酒店、送旅遊交通費,如地鐵一日卡、船票和某個景點的入場券等。


如此一來,就大概可抓出個費用大概,僅需再加一些吃吃喝喝和購物價錢,應該就差不多囉。


一些經驗分享:



  • 香港機場快線旅遊套票可以連續3天內無限次乘搭港鐵、輕鐵及港鐵巴士,但是票價 300 港幣 - 機場快線實際搭乘費用 - 押金 50後,所剩的費用可能三天都還花不完,這時候就可以不用使用這種旅遊票。另外機場快線有優惠價,只要 2~4 人同行,可以在櫃檯買到優惠的價錢喔,例如香港島到香港機場,販賣機的兩人要價 HK200,但去櫃檯買 2 人同行票,只需 HK 160,印象 3 or 4 人同行會更便宜,所以大膽的人可以拉旁邊不認識的一起買。

  • 澳門有不少大型酒店都有免費巴士可以穿梭氹仔跟澳門半島,但實際上從澳門機場出發的接駁車並沒有很多家,因為澳門比較熱門的是在港口,從澳門半島的港澳碼頭跟氹仔臨時碼頭處,才會有發車頻繁的酒店接駁車,建議搭飛機進澳門的,先搭威尼斯人酒店接駁車進威尼斯人酒店(東側),接著穿越賭場後,可到達西側搭乘威尼斯人酒店接駁車去澳門半島的港澳碼頭,在港澳碼頭再轉搭其他酒店接駁車出去,除了可以順便逛一下威尼斯人酒店外,從港澳碼頭發車的接駁車頻率高較省時

  • 澳門有賭場的酒店都有提供免費的行李寄掛服務,例如下飛機後想去逛逛官也街,那可以先把行李寄放在威尼斯人酒店,接著從酒店西側步行去官也街或其他地方閒晃;在港澳碼頭搭車去其他間澳門半島的酒店(例如永利),可以閒逛後等到要從港澳碼頭往香港時,才去該酒店領回,並順便搭接駁車到碼頭。據說擺放很多天都沒關係的 XD

  • 到澳門旅遊時,可以先換港幣(台灣的銀行提供澳門幣/葡幣兌換的選擇不多),於當地機場(匯率較差,大概 100:101 )或是港澳碼頭(100:103)、議事亭前地(100:102.9)換錢,如果行程是從澳門機場去澳門半島的話,可以先搭威尼斯人酒店接駁車到威尼斯人酒店,再轉接駁車到港澳碼頭,這時就可以在港澳碼頭一樓大廳換錢。除此之外,在澳門要去香港時,可以在港澳碼頭再換回成港幣,十分便利

  • 進澳門或香港時,都需要填入境表。進澳門我很懶,直接用中文敘述也是 pass 的啦 XD 擔心被耽誤的,可以都用英文敘述;香港的話,當下比較勤勞一點,就寫英文啦。這些表格可以在搭飛機或搭船時跟空姐、服務人員領取。從澳門搭船進香港時,並不用掃描行李,幾乎等於搭客運那些步驟而已,所以在開船前 15 分鐘才買完票,還是搭的上的啦,但還是早點去比較好

  • 澳門跟香港用的插頭跟台灣不一樣,可以買萬用插頭或是跟住宿的旅館借萬用插頭來使用。別忘了電壓是 220V 的,大多 3C 充電器的 INPUT 都應該允許 100~240 V 的,可以留意一下

  • 規劃自由行最好半年前開始慢慢規劃,接著提早四個月開始訂機票,這時可以拿到優惠價,此例港澳早去晚歸來回機票可拿到 8500 價錢,約便宜1500元,接著提早兩三個月訂住宿的酒店或民宿也會比較便宜,最後則是申請簽證接著一兩個月前開始申請港簽,或是留意簽證的時效要能涵蓋旅程。上述的酒店和簽證都是需要護照的,須要先把護照辦妥,可以請旅行社代辦,價碼大概都 1800 附近,需七個工作天左右,機票僅需羅馬拼音跟護照上寫的一樣即可,因此若護照過期要重辦的話,剛好訂機票是沒問題的,但是酒店跟港簽是必須等新護照才能進行,這時若有不錯的民宿也能考慮一下,民宿大多不需護照資訊就能訂房,但入住時通常都還是會檢查一下

  • 返台後,手上所剩的港幣想要換回台幣的話,雖然在網路上可以查到匯率較好的銀行,但是不少間銀行換錢還是要收手續費 100 元台幣的,並且只收港幣 100 元以上的面額。這時候可以去台灣銀行換錢,雖然匯率不好,但是免手續費喔。假設匯率差的一塊港幣少換到 0.1 元的台幣,那 100 元台幣手續費等同要用 1000 港幣換台幣才賺得回來,因此手頭上的港幣不多時,且又有小額面額的鈔票要換,那直接去台灣銀行或其他願意收小額港幣又免手續費的也不錯,建議可以先打電話到銀行詢問


    • 假設有 800 港幣要換,在好匯率的銀行總共換得的 = HK 800*3.77 - 100手續費 = 2916 台幣

    • 假設有 800 港幣要換,在差匯率不收手續費的銀行 = HK 800*3.66 = 2928 台幣


  • 如果有用 Android 智慧手機,可以試試 RMaps app,這是免錢的程式,可以先透過 Mobile Atlas Creator 製作離線地圖,接著在 Google Maps 之 My Places (我的地點)標記所需的目的地,接著再匯出 KML 檔案,就可以把這些個人的 POI 匯入到手機上,超讚的,細節可參考 RMaps 離線地圖 - 批次匯入個人 POI、KML 檔案