IComparerを用いたリストのソート

IComparerを継承した独自クラスのインスタンスをリスト等で複数保持している状況下で、例えば、日付順にソートをしたい場合、以下の点に注意。

よくある手法(IComparer継承クラス内の記述)
//日時比較処理
public int Compare ( object x, object y )
{
TimeSpan ts = ( (UpdateHistory)x ).Date - ( (UpdateHistory)y ).Date;
return Convert.ToInt32( ts.TotalSeconds );
}

これだと、TotalSecondsで比較を行っている分には良いが、より厳密なTotalMiliSecondsで比較しだすと、オーバーフローを起こす。IComparerはint型のみの設定でLongが扱えないためである。
しかし、そもそもIComparerがintで必要十分なのは、以下のようになっているから。

  • 同値の場合、0を返す
  • y>xの場合、Integerの範囲で0より小さい値を返す
  • x>yの場合、Integerの範囲で0より大きい値を返す

要するに、差分値を直接returnしているのは、横着した表記をしているだけなのだ。int範囲内であれば、有効だし、文句も無いが、厳密な日付比較によるソート等では、正しくは以下のように書くべき。

//日時比較処理
public int Compare ( object x, object y )
{
TimeSpan ts = ( (UpdateHistory)x ).Date - ( (UpdateHistory)y ).Date;
long longTs = Convert.ToInt64(ts.TotalMilliseconds);
if (longTs > 0)
{
return 1;
}
else if (longTs < 0)
{
return -1;
}
else
{
return 0;
}

MSDN:IComparer
http://msdn.microsoft.com/ja-jp/library/system.collections.icomparer.compare(VS.80).aspx

なんて事は無いが、一応メモ。

GridView内でラジオボタンをグループ化する方法

2.0で起こる比較的有名なMSバグだが、どうやら3.0でも改善されていないらしい。
GridViewにRadioButtonコントロールを配置しても、IDが個々に振られてしまうため、グループ化できず、いくらでもラジオチェックできてしまうというもの。
javascriptを使用する等、回避法はあるが、ここは1つ、RadioButtonカスタムコントロールを作成する方が無難かと。あちこち、同様な内容が出回っているが、カスタムラジオボタンを作る上での必要そうなメソッド群を一応、メモ。
以下、publicなクラスCustomRadioButtonで記述。

protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
// このコントロールが選択されたか否か
bool newChecked = postCollection[GroupName] == this.UniqueID;
if (this.Checked != newChecked)
{
this.Checked = newChecked;
// コントロールが新たに選択されたときのみtrueを返す
return newChecked;
}
return false;
}

protected override void Render(HtmlTextWriter writer)
{
// 出力先を独自のTextWriterとして出力する
base.Render(new WriterWrapper(writer, this));
}

以下のprivateなクラスWriterWrapperも記述。

///


/// 属性を変更して出力するためのTextWriter
///

private class WriterWrapper : HtmlTextWriter
{
private CustomRadioButton control;

public WriterWrapper(HtmlTextWriter writer, CustomRadioButton control): base(writer)
{
// コントロールへの参照を保持しておく
this.control = control;
}

///


/// 属性の追加
///

/// 属性を表す列挙値
/// 属性に設定する値
///
/// RadioButtonが属性の設定のために本メソッドを呼び出すため、本メソッドで変更したい属性値を設定する
///

public override void AddAttribute(HtmlTextWriterAttribute key, string value)
{
switch (key)
{
case HtmlTextWriterAttribute.Name:
// ラジオボタンのグループを表す
// ユニークとせず、もともとプロパティで設定した値を出力する
base.AddAttribute(key, control.GroupName);
break;
case HtmlTextWriterAttribute.Value:
// POST時に出力する値を表す
// コントロールを識別する必要があるため、ユニークとする
base.AddAttribute(key, control.UniqueID);
break;
default:
base.AddAttribute(key, value);
break;
}
}
}

カスタム化しなくても、純正のRadioButtonが気兼ね無くGridViewに配置できる日が来る事を願う。

「要求を仕様化する技術、表現する技術」読書会を終えて

備忘メモを粒度無視で。

  • 要求において、品質要求はおろそかにされがち。機能要求等と同等に重要。
  • 明文化するのは、作るものの「合意」を取るため。
  • 理由"Reason"を、仕様書に設けるのは良いかも。上げられた要望が、何のために必要なのか後から精査しやすいし、顧客とのすり合わせでも使える。
  • アバウトな表現は使わない(〜等、etc)。全て挙げること。
  • 「要求」と「仕様」をはっきり区別すること。混同して利用している場合が大多数。
  • 要求をあいまいにしない。
  • 否定的な表現が出てきたら、怪しいと思うこと。
  • 全てのパターンを網羅すること(IFがあれば、ELSEもちゃんと考えること)。

DataTableにデータを格納した状態で、カラムを指定してDISTINCTをかける方法。

便利そうなので、メモ。

  • DefaultViewを使用する。

DataTable dt = GetAnyData();
DataView dv = dt.DefaultView;
DataTable dtResult = dv.ToTable("テーブル名", true, new string[]{"カラム1", "カラム2"});

ToTableにはいくつかオーバーロードがあるので、状況に応じて、使用するメソッドを選択すると良い。引数のbool部分が、DISTINCTを実施するか否かを設定する箇所。テーブル名を指定しなくてもOK。

LINQプロバイダ

これまで、ADO.NET(特にDataSet周り)に苦しめられてきた経験上、LINQの活躍に一応の期待を寄せているのだが、中々に魅力的。

  • LINQプロバイダとして、以下のものが用意されるとの事。(at .NETFramework3.5)

既存のDataSetへのクエリも記述でき、これまでの"Selectメソッド"に頼らなくて済む点が、素晴らしい。コレクションや配列への問い合わせも、XPathに頼らない要素の取得も、可能。統一的なLINQ構文で、様々なデータアクセスが行えるのは、ありがたいかも。
実装における、これらLINQの潜在能力がどれ程かは、使用者側に依るものだろう…。

ソフトウェアの原則

セミナー受講。何だかんだ、適当にやってきたテストという分野、一度、しっかりと勉強してみようと思う。

良いテストをしようとすると、以下の知識が必要。
1.業務知識
2.技術知識
3.ソフトウェアテスト技術知識

このうち、今回受講したセミナーは、3.がターゲット。
粒度無視で、覚え書きをば。

■検証

  • 変換作業の損失を最小限に抑える
  • 静的なテスト

■妥当性確認

  • コードが要件に合致しているかを確認する
  • 動的なテスト

ソフトウェアテスト

  • ポジティブテスト(正常系テスト)
    • 要件を満たしているかどうかをチェックするためのプログラム実行
    • 設計書ベース
  • ネガティブテスト(異常系テスト)
    • 欠陥を発見することを目的としたプログラム実行
    • 設計書ベース
  • リスクベーステスト
    • 主要機能が正常動作し、顧客/エンドユーザにとって最小限のリスクであるかを確証するためのプログラム実行
    • 同様なシステムにおけるリスク(過去経験等からの蓄積)

■システムの誤りの原因は、ギャップ

  • 顧客⇔技術者間でギャップがある
    • 話がうまく理解できていない
    • 顧客自体が欲しいものをわかっていない

■テスト技術

両者に優位性の違いはない


■品質とは

  • 仕様を満たすことではない
  • ユーザ要求を満たすことである
  • 品質は全ての「〜性」の集積

■テストに必要な心理学

  • 否定的な態度が必要
  • ネガティブシンキング
    • 何も信用しない事

ブラックボックス技法

  • 全数
  • All-Pair法/直交表(Orthogonal)
  • シングル・フォルト
  • At Least Once

■ホワイトボックス技法

カバレッジ

結合テストの結合戦略

上記3つは適宜、スタブ、ドライバを使用

  • ビッグバン

■テストコード自体のバグ対策

  • 現状、コードレビューを行うしかない

「定時で帰る仕事術」ローラスタック著

この手の指南書は、捻くれた基本性格上、否定的に捉えて読み進むのが常だが、為になる点があったので、自戒の念を込めて、以下に記述。

  • 細かいことにこだわらず、ま、いっかの精神
    • 胸が痛い。これが出来れば、小心で傷心する事もなく、公私共に周りにも迷惑かけなくなるのだが。
  • 慢性的な心配は時間の無駄。
    • その通り。
  • 悪い思考パターンを突き止めたら、別の考えができるよう訓練すること。
    • 耳が痛い。努力します。
  • 前向きに考え、積極的な姿勢を維持。
    • 百も承知なはずだが、今一度。
  • 持続的自己批判
    • ネガティブな独り言が自信と能力を蝕んでいく。まさにその通り。趣味はこの限りではないのだが…。
  • 悪い思考パターンにはまらない。
    • 理解している。実践は別として。
  • 職場では、癇癪を抑え、怒りをあらわにしない。
    • 得意とするところだが、上記のストレス解決策が出来た上で、成り立つものだという事も理解している。
  • 「ぼんやり」と「考え事」は別のもの
    • 否、経験上、考えすぎてアウトプットの純粋性が保たれない事も「ぼんやり」と映るはずである。

もはや、定時に帰るがどうのと言うより、人間性の問題と捉えるべきか。気の置けない友人には散々指摘されてきた事だけに、もっと精神的に大人にならなくてはならぬ。
高校時代の担任の先生から頂いた言葉と共に、自戒をば。