[備註] 安裝與整合 xUnit 測試框架@VS2012

開發環境:Visual Studio 2012, Update 1 (必須)。

說明:VS2012 已整合各測試框架的 Test Runner,包括 NUnit, xUnit 等。藉由標準的介面,可讓各類測試框架於 VS2012 內的 Test Explorer 歸納測試方法 (methods),並執行測試、瀏覽測試結果。

xUnit 可說是繼老牌 NUnit 的後起之秀。關於兩者之間的比較,可參考-xuint和其他的單元測試框架的比較。個人尤為欣賞 xUnit 的 DDT (Data Driven Test)的機制-Theory,可參考這一篇-xUnit Theory, the Data Driven Unit Test

xUnit Theory 可讓測試方法具有參數 (parameters),而能接收多個資料來源 (InlineData, PropertyData, ClassData, ExcelData, OleDB/Sql ServerData)的資料輸入,讓測試機制更能充分利用測試數據。一個 Theory 可參考如下的寫法。

 1: [Theory]
 2: [InlineData(1, 2, 3)]
 3: [InlineData(3, 4, 7)]
 4: [InlineData(30, 10, 40)]
 5: public void Add_AddDataValues_ReturnsExpectedResult(int first, int second, int expected)
 6: {
 7:     var actualResult = Calculator.Add(first, second);
 8:  
 9:     Assert.Equal(expected, actualResult);
10: }

安裝:兩個 xUnit 套件是必要安裝的 (全於 VS2012 內安裝)。

  1. xUnit.net runner for Visual Studio 2012 extension
  2. 利用 NuGet 安裝 xUnit.NET。

閱讀全文 »

[活動記實] 讀書會~Clean Code (無瑕的程式碼)@加爾第咖啡

** 所有相關活動的完整照片,可至-「2013.05.18_Clean Code 讀書會」Flickr 相片集瀏覽。 **

上上星期六 (5/18) HSDc. 所舉辦的「Clean Code (無瑕的程式碼) 讀書會」,在相當熱絡的研討與歡樂的氣氛下,圓滿落幕了。

「Clean Code」中譯本的技術編輯(Simon, 博碩文化)也特別蒞臨此次的活動,與會過程中不只用心地回應讀者許多問題外,還分享了在翻譯該書時的用字遣詞,以盡能表達出原文的意境,實在相當感謝他能為業界翻譯如此高品質的譯本。還有,他也為讀友們帶來一項福利,在博碩的粉絲團內按個「讚」,就有機會抽中「Clean Code」原版書籍,定價可是 NT$2,200,不便宜呢。

這次讀書會的導讀與主持不得已就由我個人來擔任。我把時間安排大致分為讀書內容的心得分享、問題提問、自由討論。

一開始先作個腦力激盪 (brain storm),這裡我用心智圖 (mindmap)先整理出關於「Clean Code」的 5W-What, Why, When, Which, Who。雖然看來僅是簡單的整理,但讀友們大都發言踴躍,在分享一些對「乾淨的程式碼」的看法與心得,以及一些問題討論,這樣也討論到中午 12:40 才休息,大家各自用完中餐後,下午 1:30 繼續研討。

Clean Code 心智圖

下午整個主題就完全以書本大綱內的「How-to」為重心了,一章一章地討論大綱內容。畢竟作者就已開宗明義內提及:「小事情上誠實,可不是一件小事。」;同時又提到:「神 (我以為是魔鬼?)就在細節內。」。所以,程式碼當然就要回歸到「How-to」細節內,這可是不能眼高手低的。

事實上,這本書大概到第 10 章就足夠了,後續的內容,有其他作者撰寫的、有作者早期的論文,也有從「Refactoring」一書節錄的重構型錄,許多內容其實翻過就可以了。(不過看來我最認真!? 關於第14章-「持續地精煉」,我可是逐行閱讀其程式碼,整整花了三個晚上還不容易了解內容,直至與 Ringle 討論過後,他認為該範例還是不夠「Clean」,仍需要繼續「精煉」。 >_<) 即使只研讀到第10章左右,但也不容易,直到下午約5:00結束時才勉強「翻完」,其實仍是有諸多細節尚未討論的。不過也算是盡心了,讀友們的發言夠是踴躍了,也相信有許多研討的內容對未來他們的工作,在長期上會有相當體會與助益的。 讀書會@吳興街加爾第咖啡

閱讀全文 »

[備忘] Excel VBA-如何判斷 ChartObject 是否存在

當利用 VBA 新增一 ChartObject,如下:

Dim chobj As ChartObject
Set chobj = Worksheets("Sheet1").ChartObjects.Add(50, 40, 400, 200)
chobj.name = "chart1"

則該 Excel 工作表關閉後,該 ChartObject 仍然存在。可以想像工作表關閉後,在工作表內所包含的工作表 (Worksheet)、圖表等物件生命仍存在 (除非物件被 Destroy),它只是被永續冬眠 (hibernate)至檔案資料庫內,待開啟檔案後,這些物件會再次的活化 (Activation)。

問題:如果手動刪除掉該 ChartObject,該如何在 VBA 程式內判斷已不存在,而需要自動再新增同名的 ChartObject?

解決方案:程序內需要宣告「On Error」陳述,然後利用任一陳述式(statement,如 If or With) ,可直接參考 (reference)到該 ChartObject。若不存在,則該陳述會發生錯誤,然後再判斷該錯誤代碼,在錯誤區塊 (block)內新增同名的 ChartObject。

說明:

閱讀全文 »

Excel VBA-關於儲存格變動性的設計議題

問題:當工作表內有多組被參照的儲存格需撰寫 VBA 程式作處理運算,但不希望因被參照儲存格的位置 (座標)變動後,而頻繁修改程式碼。

描述:參考下圖,當有一組表格內的儲存格,例如「加權指數」,有包括「成交價」、「最高價」、「最低價」、「成交量」... 等屬性 (property)。若撰寫 VBA 程式時,係以「絕對座標」參考值 (例如「成交價」座標現為 "B4")來處理,則當上述任一屬性座標更動時 (或新增屬性而移動原來屬性位置),程式碼必須修正調整。這也說明了若以單一儲存格的「絕對座標」作為撰寫程式的參考值,不會是好的寫作方式。
Excel 儲存格

解決方案:利用 Excel Range 物件,標定一組儲存格作為參考表格,再以「相對座標」來取得所參考的儲存格。

閱讀全文 »

利用 LINQ 實現期指Tick檔彙整為K棒

參考這一篇:「How to group a time series by interval (OHLC bars) with LINQ」。

我這裡使用 C#.NET 實作,並作了一些小小的修正,使之確實可以執行,並可從期交所所下載的原始 Tick 資料檔,經由前置的解壓縮、轉換為 Tick 物件型態,再透過該實作邏輯,就可以將 Tick 物件依所指定的時間週期 (time-interval),群組為所謂的「分K棒」(其實,正確的稱呼應該為 OHCK Bar)。

這裡也不禁對 LINQ 實作技術感到讚嘆! 它讓中間層 (middleware)的物件結構與資料來源 (data-sources)的存取,變得更為簡單太多了,所以也使得 Tick 轉K棒 的轉換邏輯,可以利用相當簡潔的語法 (類 SQL 語法),而達成該功能的實現。

底下的程式碼並未包含前述所提包括解壓縮、轉換為 Tick 物件等邏輯,只從一群已有 Tick 資料的 Collection 集合 (型態為 IEnumerable),依據所指定的 Interval 時間間隔,轉換為 K棒 (含開、高、收、低、量)的實作邏輯。

Tick 與 OHLC-Bar(K棒) 物件結構為:

    public class Tick
    {
        public string Symbol { get; set; }     //商品代號        
        public DateTime Timestamp { get; set; }  //成交日期時間
        public decimal Price { get; set; }     //成交價格
        public uint volume { get; set; }       //成交量
    }
 
    public class OHLCBar
    {
        public string Symbol { get; set; }  //商品代號
        public decimal OPEN { get;set; }  //開盤價
        public decimal CLOSE { get; set; }   //收盤價
        public decimal HIGH { get; set; }  //最高價
        public decimal LOW { get; set; }   //最低價
        public uint VOLUME { get; set; }   //成交量
        public DateTime BeginTime { get; set; } //開始時間
        public TimeSpan Interval { get; set; }   //時間區間
    }

閱讀全文 »

[C# 實作筆記] 將 Zip壓縮檔內的文字檔轉至記憶體內的List集合

    目標:

  1. 在 C#.NET 程式內處理 *.zip 壓縮檔 (內含文字檔)的解壓縮 (decompress)。
  2. 將解壓縮後的文字檔讀進記憶體內 (memory),並將每行 (per-line)的字串 (string)儲存至 List 集合 (collection),以俾方便處理。
    主要做法:

  1. 因官方未提供處理解壓縮 .zip 壓縮格式機制,所以需下載 3rd party 的類別庫 (class library)。這裡以 SharpZipLib ( formerly NZipLib) 類別庫來處理解壓縮。
  2. 利用 SharpZipLib 內的 ZipInputStream 開啟 .zip 壓縮檔。
    string fname = @"C:\Download\TxtData.zip";
    ZipInputStream zipStream = new ZipInputStream(File.Open(fname, FileMode.Open));
  3. ZipInputStream 會依據所指定的緩衝區大小,依序將已解壓縮的文字檔內容讀至「位元組陣列 (Byte array)」;同時再利用已新增的 MemoryStream (記憶體串流)物件讀進 Byte array。
                    MemoryStream memStream = new MemoryStream();
                    int bufferSize = 2048;     //指定的緩衝區大小
                    int readCount = 0;           //回傳已讀取的位元組數目
                    byte[] buffer = new byte[bufferSize];
     
                    readCount = zipStream.Read(buffer, 0, bufferSize);   
                    while (readCount > 0)
                    {
                        memStream.Write(buffer, 0, readCount);
                        readCount = zipStream.Read(buffer, 0, bufferSize);
                    }
  4. 閱讀全文 »

軟體思維顧問

專職軟體輔導與教育訓練的獨立顧問。輔導企業資訊單位如何有效組織系統開發與維護;輔導開發人員達成有效的專業分工。傳授如何把軟體作軟 (Keeping Software Soft)的技能,得以提昇系統的彈性/延展,並進而創造系統的再利用價值。

Personal