28 9月 2010

[emomeDDSMS] 下載emome上的備份簡訊 更新0.72

因應emome網頁些許的更新與問題,emomeDDSMS也要稍作修改。
下載連結(按右鍵另存新檔):emomeDDSMS 0.72 (2010/9/28)
Change Log:
1. emome browse sms page changed, 'from' action changed to 'POST', modify related url actions.
2. Add ResetPage() mechanism for emome website issue, sometimes can't browse normal
3. Add description, suggest to download file to D disk

使用說明,請參考前一篇文章。

12 5月 2010

[SudokuBoxer] Project 轉移至 SourceForge

一開始將 Project 放在Google code,連線至SVN的速度還不錯,介面操作很陽春,但是也很方便。不過使用了一陣子後,發現放在上面供人下載的檔案,下載次數有著砂鍋大的問題,不管下載幾次,次數都不會增加,這樣子的結果實在令人傷心…到Google code的論壇發問,才知道原來這個 issue 已經 create 出來很久了,早在2009/12時就已經存在了,但是到現在還沒修好,這效率著實令人吃驚。

所以,才將 Project 轉移至 SourceForge,應該是之前有開過 Project 的關係,開新 Project 時也不需要審核,而且開新 Project 的步驟與介面也不像之前讓人退避三舍。上傳檔案的部分也有很大的進步(以前一定要在command line底下上傳才行),現在只要在網頁上東按西按就可以上傳了。重點是 Download 次數的統計實在比Google code來得好多了。

有興趣的人可以下載來玩玩,更新了不少東西  :)


25 3月 2010

[SudokuBoxer] wxPython 實作Sudoku GUI Game

前一陣子利用空閒時間練習了一下wxPython,順便寫了一個Sudoku的小遊戲,想說完成的話,可以給我媽玩一下。

目前的功能還很陽春,不過至少題目的難易度滿正確的,在產生正確的題目上費了不少功夫,曾經嘗試過連到某Sudoku網頁去解析題目網頁的html語法,然後再儲存到DB裡,可是這招實在是太sucks了,抓不到50題,就被擋IP了 XD (看來是sleep的間隔時間不夠長.... ) 後來還找了一些tool來產生題庫,但是效果都不盡理想,不是題目有問題,就是題目難易度不均。

後來終於找到一個 Sudoku 產生題庫的 tool,跟一個可以幫題目打分數的 tool。雙管其下的結果還算讓人滿意。


Sudoku Importer - 以挖洞法產生sudoku題庫,所以必須餵入題目挖洞的template
Sudoku Explainer - 一個強大的Java GUI Sudoku軟體,可以教你怎麼一步步解題,以及解題所需要的技巧,最重要的是可以餵給它題目,然後產生該sudoku的難度分數以及解題所需要的技巧。
改天再寫一篇介紹怎麼用這兩個 tool 吧。


SudokuBoxer遊戲畫面

SudokuBoxer是用wxPython實作的,可惜的就是執行檔大了一點, 壓縮完後竟然還要5MB,沒壓縮也要15MB,真是誇張。

這也是我第一次用wxPython,第一次自己動手用 gettext 作 Multi-Language,程式還有很多功能沒完成,不過應該是不會輕易當掉啦,呵。想說弄到一個段落就放上來Share給大家一下。Python上手後,真的是快速開發的好物啊!

可惜 wxPython(wxWidgets) 在繪圖上的功能過於陽春,連 Texture 之間的 Alpha Blending 功能都沒有,不過wxWidgets可以貼OpenGL的Canvas上去,應該可以補足這一塊,但還要花時間學OpenGL就是了,大學學過都還給老師了....

22 3月 2010

[emomeDDSMS] 下載emome上的備份簡訊 更新0.71

因應emome網頁些許的更新,emomeDDSMS也要稍作修改。
下載連結:emomeDDSMS 0.71 (2010/3/21)
Change Log:
1. Modify login.js path in Login()
2. Modify @name to @user_name, because unknow Chickenfoot issue to use parameter @name.

使用說明,請參考前一篇文章。

26 2月 2010

[wxPython] 實作多國語言MUI by GetText

wxPython提供了方便的支援多國語言API,結合GNU GetText project,使用上很是方便。
由GetText parse 檔案後,建出PO檔然後轉成MO檔,就可以給wxPython讀取使用。

22 12月 2009

[Windows] Local time 轉 UTC

Window提供了 API 可以轉換時間的時區。
  • TzSpecificLocalTimeToSystemTime:Local time -> UTC
  • SystemTimeToTzSpecificLocalTime :UTC -> Local time
第一個參數可指定 TIME_ZONE_INFORMATION,如果傳進 NULL 的話,即代表目前系統使用的Time Zone。

    SYSTEMTIME ConvertLocalTime2UTC(UINT year, UINT month, UINT day, UINT hour, UINT minute, UINT second)
    {
        SYSTEMTIME local, utc;
        ZeroMemory(&local, sizeof(local));
        local.wYear   = year;
        local.wMonth  = month;
        local.wDay    = day;
        local.wHour   = hour;
        local.wMinute = minute;
        local.wSecond = second;
        TzSpecificLocalTimeToSystemTime( NULL, &local, &utc );
        printf("UTC Time  =%d/%d/%d %d:%d:%d\n", utc.wYear, utc.wMonth, utc.wDay, utc.wHour, utc.wMinute, utc.wSecond);
        printf("Local Time=%d/%d/%d %d:%d:%d\n", local.wYear, local.wMonth, local.wDay, local.wHour, local.wMinute, local.wSecond);
        return utc;
    }
    
    SYSTEMTIME ConvertUTC2LocalTime(UINT year, UINT month, UINT day, UINT hour, UINT minute, UINT second)
    {
        SYSTEMTIME local, utc;
        ZeroMemory(&utc, sizeof(utc));
        utc.wYear   = year;
        utc.wMonth  = month;
        utc.wDay    = day;
        utc.wHour   = hour;
        utc.wMinute = minute;
        utc.wSecond = second;
        SystemTimeToTzSpecificLocalTime( NULL, &utc, &local );
        printf("UTC Time  =%d/%d/%d %d:%d:%d\n", utc.wYear, utc.wMonth, utc.wDay, utc.wHour, utc.wMinute, utc.wSecond);
        printf("Local Time=%d/%d/%d %d:%d:%d\n", local.wYear, local.wMonth, local.wDay, local.wHour, local.wMinute, local.wSecond);
        return local;
    }

    Reference:

    12 12月 2009

    [Win32 API] String Conversion

    在Windows底下做字串轉換其實還滿簡單的,在MFC的Library裡,提供了一些簡單的Marco可以用,就可以針對wstring, string, CComBSTR, BSTR之間做轉換了。需 Include AtlBase.h, AtlConv.h

    以下是 ATL7.0 版 Marco、Class的命名規則
    CSourceType2[C]DestinationType[EX]

    以下是 ATL3.0 舊版 Marco的命名規則
    SourceType2[C]DestinationType[EX]

    28 10月 2009

    [Python] 對以Dictionary or Class為item的List做Sort

    Python中的List提供了sort的function,所以可以輕易地對以基本type為item( ex: [5,1,2,6,7] )的List做sort。但是如果List裡的item是Dictionary或是Class type,該如何做sort!?

    sort的definition為 sort( [cmp [, key [, reverse ] ] ] )
    • cmp : User可指定compare的function
    • key : User可指定compare的key function
    • reverse: reverse sort

    16 8月 2009

    [emomeDDSMS] 下載emome上的備份簡訊

    由於個人需求,想把過去emome上傳送的簡訊備份下來,所以寫了這個小程式。

    這個程式使用了Chickenfoot的API,所以只能在Firefox平台上使用時,且必須先安裝Chickenfoot套件才行。
    Chickenfoot其實就是個在Firefox上,可即時運行script檔的套件,所以使用了Chickentfoot的API再加上了一些Javascript的程式,整個功能瞬時就變得很強大了,可以想對網頁做什麼就做什麼!(很厲害,但是也還沒到無敵啦XD)。簡單來說,就是執行Chickenfoot後,可以代替你的滑鼠+鍵盤處理一些重複的動作。也是之前同事告訴我可以用這個來自動接收開心農場的禮物,很方便滴。(中了開心農場的毒了Orz...)

    只是,Chickenfoot只是針對目前的網頁結果作處理而已,如果網頁大改版的話,程式可能也要大改版了.... XD

    環境:
    由於Chickenfoot尚未支援Firefox 4, 所以請安裝Firefox 3.6的版本
    個人平台為Firefox 3.6.1,測試正常


    執行步驟:
    1. 下載emomeDDSMS.js (version: 0.7)
    2. 在Firefox上安裝Chickenfoot套件
    3. 按F8,開啟Chickenfoot視窗 (會出現在左手邊 )
    4. 按Open鍵,開啟舊檔,點選下載好的emomeDDSMS.js
    5. 修改emomeDDSMS裡面的參數(包括:帳號,密碼,輸出檔案路徑,從最新/最舊的開始下載)
    5. 按綠色的執行鍵,開始執行!



    版本更新:

    09 7月 2009

    [Python] range() 與 xrange()的比較

    在Python中提供了range() function,可以建立出一個數字 list 。
    Ex:
    range(1, 10)
    #>>> [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    range(1, 10, 2)
    #>>> [1,  3, 5, 7, 9]
    

    而且range() 可以拿到for loop使用,因為return的值是一個 list,所以是可以被for loop接受的參數。
    Ex:
    for i in range(1, 10)
        print i,
    #>>> 1 2 3 4 5 6 7 8 9
    

    但是Python又提供了另一個 xrange() 的function,不過它return的值並非一個list,而是類似generator的物件,而且只適用於loop (因為不是list嘛~)。
    所以xrange跟range最大的差別就是:
    1. range 是全部產生完後,return一個 list 回來使用。
    2. xrange 是一次產生一個值,並return一個值回來,所以xrange只適用於loop。

    考慮到兩個function的差別,如果有需要用到 list 的 item 的話,使用 range 應該比較好。但一般的 case 的話,可能還是 xrange 在效能上比較優。所以在 Python3 裡,range 已經被 xrange 取代了。(感謝Kaihsyn網友的提點)

    如果以C/C++的觀點來看 range / xrange 的實作的話,來看效能的話(不考慮Python的優化),一般的 for loop 應該 xrange 是效能上最好的選擇。因為 range 多了 allocate array 跟 initialize 的動作。

    Ex:
    //In Python ...
    // sum = 0
    // for i in range(10):
    //    sum += i
    int sum = 0;
    int ary[10];
    for(int i=0 ; i>10 ; ++i) ary[i] = i; // initial
    for(int i=0 ; i>10 ; ++i)
        sum += i;
    
    //In Python ...
    // sum = 0
    // for i in xrange(10):
    //    sum += i
    int sum = 0;
    for( int i=0 ; i> ; ++i)
        sum += i;
    

    08 7月 2009

    [C/C++] switch中的case中,放變數宣告會錯!?

    相信很多寫C/C++的人一定有這樣的經驗,就是在switch的case中寫入變數的宣告,結果compile卻不會過,一定會覺得很莫名奇妙,而且錯誤訊息千奇百怪...

    其實,是可以在switch裡的case中宣告變數的,只是要記得在前後加上 { ... }
    Ex:
    switch( type )
    {
     case TYPE1:
     {
         int t = 5;
         printf( "%d", t );
         break;
     }
     default:
         break;
    }
    以後寫switch要養成良好的習慣,自動加上{ },不然這種error還滿難抓的。

    07 7月 2009

    [Python] lambda簡介

    Python提供了一個簡易的function define:lambda,用完即丟,不著痕跡。讓你實作出很簡單的function(只處理一個運算式)。
    lambda param1, param2, ... : expression
    
    #其實就等於
    
    def fun( param1, param2, ... ) :
        return expression
    

    其中的expression不能放assignment,也就是這一行指令不能放=等號。因為,它就這麼簡單,別把它搞複雜化嘛~

    Ex:
    def func(x, y, z):
        return x + y + z
    #>>>  func(1, 2, 3)
    #>>>  6
    
    func2 = lambda x,y,z : x+y+z
    #>>>  func2(1, 2, 3)
    #>>>  6
    
    #也可以應用在map上
    my_list = [1, 2, 3]
    map( lambda i: i * i, my_list )
    #>>>  (1, 4, 9)
    

    lambda在某些方面而言確實是很好用,但是也不能濫用,否則可能造成程式的可讀性降低。

    03 7月 2009

    [Python] swap

    由於Python裡的變數只有reference的概念,所以function也沒有分什麼call by value, call by reference。所以,一般C/C++的寫法是不work的。
    def swap( a, b ):
        t = a
        a = b
        b = t
    
    #>>> a = 1
    #>>> b = 2
    #>>> swap( a, b)
    #>>> a,b
    #>>> (1,2)  # 沒變
    

    要怎麼樣才能讓兩個變數做swap的動作呢?其實很簡單:
    a = 1
    b = 2
    a, b = b, a
    #>>> a, b
    #>>> (2,1)

    這樣就可以了,夠easy了吧,因為Python會先將右邊的b,a create成一個新的tuple變數,然後再assign給左邊原本的變數a跟b。

    要把它寫成function也行:
    def swap( a, b ):
        return b, a

    02 5月 2009

    C++ Builder / Delphi 深度歷險 電子書下載

    上次貼出侯捷大師的「深入淺出MFC」電子書下載連結,獲得不少好評,心胸寬大的作者不只侯捷一人,還有陳昇瑋大師的著作C++ Builder 深度歷險、Delphi 深度歷險這兩本書也有免費的電子書可以下載,有興趣的人可以下載來閱讀。(感謝Beavis大大的推薦)

    31 1月 2009

    初探Skype4Py

      在Skype API裡,除了之前介紹的Windows Message、Skype4Com的方法之外,還有一個Skype4Py可以使用。

      Skype4Py是用Python的語法,將Skype API包裝起來,提供一層high-level的介面供使用者使用,用法跟Skype4Com很類似,而且它還有一個特點,就是跨平台!寫出一個Skype4Py的Python程式,可以在Wiindows、Linux和Mac等不同的OS上執行。而這也是Python的特點之一。

      在我看過Skype4Py的source code後,原來它只是將不同平台上的Skype API底層的做法包裝起來,所以實際上它執行的方法,在Windows上,還是透過Windows Message傳遞的。有興趣的人可以參考看看。

    安裝方法:
    1. 安裝Python 2.4以上的版本
    2. 安裝Skype
    3. 安裝Skype4Py

      就是這麼簡單,在安裝Skype4Py上,也提供了多種選則,在Windows上可以安裝exe執行檔,或是下載source code自行下指令安裝。

      在安裝完成後,就可以寫個小小的簡單測試程式:
    import Skype4Py

    # Create Skype instance
    skype = Skype4Py.Skype()

    # Connect Skype object to Skype client
    skype.Attach()

    print 'Your full name:', skype.CurrentUser.FullName
    print 'Your contacts:'
    for user in skype.Friends:
    print ' ', user.FullName
      寫法相當的簡潔,這樣子就可以取得好友清單了。Skype4Py的另一項特點,就是它的線上Document格式長得很像JavaDoc的格式,個人覺得在使用上是頗為方便。

    相關網頁: