2009年5月2日土曜日

[Game's Review]クイズマジックアカデミーDS(通常版)

(1)レビュー
 一時期ゲーセンではまっていて、
 いつかはDSで出て欲しいなと思っていましたが、ようやくでました。

 このゲームの醍醐味はやはり対戦でしょう !!
 自宅に無線LANの環境があれば、全国のプレイヤーと対戦ができます。
 しかし、相手も同じゲームを持っていないとできないのが残念(>_<)
 ダウンロード対戦もありにして欲しかったなぁ。。。

 最新のクイズの問題がサーバーから配信されるので、
 インターネット経由でダウンロードして、常に最新のクイズを楽しめます! 

(2)リンク
クイズマジックアカデミーDS(通常版)

クイズマジックアカデミーDS(通常版)

  • 出版社/メーカー: コナミデジタルエンタテインメント
  • メディア: Video Game

[Game's Review]ドラゴンクエストV 天空の花嫁(DS版)

(1)レビュー
 [DS版オリジナルの要素]
 ・花嫁候補が3人になった。
  ビアンカ、フローラに加えて、デボラが追加!
 ・すれちがい通信でオリジナル名産品集めが楽しめる。
  DSを閉じてかばんの中とかに入れておくだけで、
  ドラクエ5を持っている人とすれ違うと勝手に通信します。  
  他の人と通信するとお互いが作った『名産品』を交換するというもの。
  交換して受け取った名産品は専用の展示室に飾られます。

 モンスターを仲間にするシステムは従来通りです。
 以下は、はぐれメタルを仲間にした時の写真です。
 228匹目でグランバニアの洞窟で仲間にしました。
 はぐれメタル(その1)
 はぐれメタル(その2)

(2)リンク
ドラゴンクエストV 天空の花嫁

ドラゴンクエストV 天空の花嫁

  • 出版社/メーカー: スクウェア・エニックス
  • メディア: Video Game

[Game's Review]ドラゴンクエストIV 導かれし者たち(DS版)

(1)レビュー
 ドラクエ4は、ファミコン、プレステでプレイしましたが、
 思わず買ってしまいました!!

 リニューアル版では、プレステ版同様、6章までありますが、
 若干内容が異なります。

 裏ダンジョンは、ドラクエ8でお馴染みのあの二人組がでてきます(笑)

(2)リンク
ドラゴンクエストIV 導かれし者たち

ドラゴンクエストIV 導かれし者たち

  • 出版社/メーカー: スクウェア・エニックス
  • メディア: Video Game

[Game's Review]ドラゴンクエストVIII 空と海と大地と呪われし姫君

(1)レビュー
 本シリーズ初の3D対応のゲームです。

 従来シリーズは「上から見下ろす視点」でしたが、
 今作は「主人公視点」となることで、
 あたかも自分がフィールドを歩いたり洞窟を探検しているかのような
 感覚で楽しめました。
 「あたかも自分が~」ってところが、
 RPGの本来あるべき姿なのかなと思いました。
 (堀井雄二のこだわり!?)

 3Dのぐりぐりな動きには、2時間くらいのプレイで慣れると思います。
 また洞窟で方向が分からなくなって迷うのも楽しみ方の一つかなと…(笑)

 [今後のドラクエについて]
 次回作もそうですが、今回の3Dエンジンを使ったリニューアルも期待します!!

(2)リンク
ドラゴンクエストVIII 空と海と大地と呪われし姫君

ドラゴンクエストVIII 空と海と大地と呪われし姫君

  • 出版社/メーカー: スクウェア・エニックス
  • メディア: Video Game

[Game's Review]ファミコンミニ スーパーマリオブラザーズ

(1)レビュー
 旧ファミコン時代が懐かしく思い、つい買ってしまいました。
 当時のゲームは、シンプルが故に奥の深いゲームが多く、
 「スーパーマリオ」もその一つだと思います。

 【良い点】
 ・FC版と同様の操作性です。
 ・裏技もほぼ移植。
  以下、再現させた裏技。
  ・コンティニュー(タイトルからAボタン+スタート)
  ・スケートマリオ
   (ファイヤマリオで、土管から出た直前にAとBを同時押しっぱなし)
  ・マイナス1面(ステージ1-2)
  ・無限増殖
  ・透明パックンフラワー(8-4の水中面)
 【イマイチな点】
  ・9-1以降のステージがプレイできない。
   (FC版は「テニス」との併せ技が必要な為、GB、DSでは無理だと思いますが…)
  ・カメをハンマーブロスに当てようとすると、なぜかすり抜ける。(ステージ8-3)
   FC版では必ずヒットしていたはず。。。

(2)リンク
ファミコンミニ スーパーマリオブラザーズ

ファミコンミニ スーパーマリオブラザーズ

  • 出版社/メーカー: 任天堂
  • メディア: Video Game


2009年4月26日日曜日

[雑記]黄色い新幹線

出張の帰り広島駅にて偶然見かけました。
この黄色い新幹線は『ドクターイエロー』とも呼ばれ、
偶然見かけるとその日は、いいことがあるそうです。

偶然見かけたのはこれで2回目です。

前回は通り過ぎるのを遠めでしか見れませんでしたが、
今回は回送電車だったので写真を撮る余裕がありました。
その分、いいことあるといいなぁ。。。

ドクターイエロー(その1)
ドクターイエロー(その1)
ドクターイエロー(その2)
ドクターイエロー(その2)

2009年4月20日月曜日

[雑記]Excelで『履歴』は予約語?


Microsoftの表計算ソフト『Excel』のトリビア的ネタです(笑)

『履歴』という名前でシートを作成しようとすると、
こんなエラーが出ます。
『履歴』は予約語?

『履歴』が予約語!?Σ(゚□゚;)

予約語は半角英数字が一般的だと思っていたので、
全角が予約語になるのは珍しいですね。

ひょっとして、Excelを英語から日本語に翻訳する際に、
予約語も一緒に翻訳しちゃったのかな?

試しに『history』でシートを作ろうとすると、

普通にシートが作れます。。。

特にエラーも無く普通に作れちゃいました。。。

『履歴』ってどんな予約語なんだろう。。。

2009年4月12日日曜日

[.NET]例外の再スロー(Throwの引数の有無)

[はじめに]
・.NET系言語(C#、VB.NET)のプログラムコードで、
 以下のような構文を見かけることがあります。
  Try 
    Dim x As Integer = func2(a) 
    Return x 
  Catch ex As Exception 
    '何らかの例外後の後処理をして、再スロー 
    '(例外後の処理は割愛)... 
    Throw ex    '←ここに注目 
  End Try
[VB.NET]例外の再スロー[Throwの引数がある場合]
 Tryステートメント内で発生した例外をCatchして、
 再度スローする処理で、「Throw ex」と書く人が結構多いようですが、
 実はこのような書き方をすると、
 ここでCatchする以前のトレース情報が失われてしまうのです。

 トレース情報を保持しつつ再スローするには、
 以下の様に、「Throw ex」ではなく「Throw 」と記述します。
  Try 
      Dim x As Integer = func2(a) 
      Return x 
  Catch ex As Exception 
      '何らかの例外後の後処理をして、再スロー 
      '(例外後の処理は割愛)... 
      Throw    '←exは省略します。 
  End Try 
[VB.NET]例外の再スロー[Throwの引数がない場合]

 なぜか書籍やMSDNにも、前者の書き方でサンプルを紹介している為、
 知らない人が多いようです。
 (Throwステートメントとは直接関係ないサンプルだから、
  あまり重要視していないのだと思いますが…)
[参考文献]
「C#クックブック 第3版」
 「レシピ4.1 キャッチした例外を再スローするタイミングを把握する」で、
 Throwステートメントの引数の有無の違いを明確に説明しています。
 「Throw」(引数なし)の記述を推奨しています。
「プログラミングC#―C#2.0/.NET2.0/Visual Studio2005対応」
 「11.4 例外の再スロー」で、
 理由の説明はないが、「Throw」(引数なし)の記述を推奨しています。
[検証]  Throwステートメントの仕様について、  2つのパターンの検証プログラムを実行して、結果を比較してみた。
パターン1
 Throwステートメントに引数がある場合、
 Button1_Click()→Method1()→Method2()→Method3()→Method4()と
 メソッドを呼び、最下層のMethod4()で
 ゼロ除算の例外(System.DevideByZeroException)を意図的に発生させる。
 各々のメソッドのCatch句では、「Throw ex」(引数あり)で例外を再Throwする。
 最上位メソッドにて、例外の内容(ToString()した結果)を表示する。
パターン2
 Throwステートメントに引数がない場合、
 Button1_Click()→Method1()→Method2()→Method3()→Method4()と
 メソッドを呼び、最下層のMethod4()で
 ゼロ除算の例外(System.DevideByZeroException)を意図的に発生させる。
 各々のメソッドのCatch句では、「Throw 」(引数なし)で例外を再Throwする。
 最上位メソッドにて、例外の内容(ToString()した結果)を表示する。
・パターン1(Throwステートメントに引数がある場合)
Private Sub Button1_Click( _
    ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click
    Dim num As Integer

    Try
        num = Method1(1, 0)
    Catch ex As Exception
        MessageBox.Show( _
            ex.ToString(), _
            "例外[Throwの引数がある場合]")
    End Try
End Sub

Private Function Method1( _
    ByVal a As Integer, _
    ByVal b As IntegerAs Integer

    Try
        Return Method2(a, b)
    Catch ex As Exception
        Throw ex
    End Try
End Function

Private Function Method2( _
    ByVal a As Integer, _
    ByVal b As IntegerAs Integer

    Try
        Return Method3(a, b)
    Catch ex As Exception
        Throw ex
    End Try
End Function

Private Function Method3( _
    ByVal a As Integer, _
    ByVal b As IntegerAs Integer

    Try
        Return Method4(a, b)
    Catch ex As Exception
        Throw ex
    End Try
End Function

Private Function Method4( _
    ByVal a As Integer, _
    ByVal b As IntegerAs Integer

    Try
        'b=0の時に例外が発生する。
        Return a \ b
    Catch ex As Exception
        Throw ex
    End Try
End Function
[VB.NET]例外[Throwの引数がある場合]
・パターン1の実行結果(Throwステートメント[引数あり])  Throwの引数を指定した場合は、  保持されているトレース情報は、Method1、Button1_Clickのみで、  Method2、Method3、Method4は保持されていないことがわかります。  引数指定での再スローでは、それより前のトレース情報を保持しない為です。  この例では、   Method3で再スローする時に、Method4以降のトレース情報を保持しない、   Method2で再スローする時に、Method3以降のトレース情報を保持しない、   Method1で再スローする時に、Method2以降のトレース情報を保持しない為、  図のような結果になります。 例外[Throwの引数がある場合] ・パターン2(Throwステートメント[引数なし])
Private Sub Button1_Click( _
    ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click
    Dim num As Integer

    Try
        num = Method1(1, 0)
    Catch ex As Exception
        MessageBox.Show( _
            ex.ToString(), _
            "例外[Throwの引数がない場合]")
    End Try
End Sub

Private Function Method1( _
    ByVal a As Integer, _
    ByVal b As IntegerAs Integer

    Try
        Return Method2(a, b)
    Catch ex As Exception
        Throw
    End Try
End Function

Private Function Method2( _
    ByVal a As Integer, _
    ByVal b As IntegerAs Integer

    Try
        Return Method3(a, b)
    Catch ex As Exception
        Throw
    End Try
End Function

Private Function Method3( _
    ByVal a As Integer, _
    ByVal b As IntegerAs Integer

    Try
        Return Method4(a, b)
    Catch ex As Exception
        Throw
    End Try
End Function

Private Function Method4( _
    ByVal a As Integer, _
    ByVal b As IntegerAs Integer

    Try
        'b=0の時に例外が発生する。
        Return a \ b
    Catch ex As Exception
        Throw
    End Try
End Function
[VB.NET]例外[Throwの引数がない場合]
・パターン2の実行結果(Throwステートメント[引数なし])  Throwの引数を指定しない場合は、  関連するトレース情報(Method1、Method2、Method3、Method4、Button1_Click)を  全て保持していることがわかります。 例外[Throwの引数がない場合]

[VBA]ExcelVBAでオブジェクト指向の継承

[はじめに]
・ExcelのVBA(Visual Basic for Application)は、
 完全オブジェクト指向言語(JavaやC#等)ほどではないですが、
 オブジェクト指向によるプログラミングをサポートしています。
 『オブジェクト指向』と言えば、
 代表的な性質として以下の3つのキーワードがあります。
代表的な性質
継承
2つのクラス間で親子関係を持ち、子クラスが親クラスの性質を受け継ぐこと。
カプセル化
オブジェクト内部のデータを隠蔽したり(データ隠蔽)、オブジェクトの振る舞いを隠蔽したり、
オブジェクトの実際の型を隠蔽したりすることをいう。
多態性(ポリモフィズム)
実行される処理の実体が、コールされたメッセージではなく、メッセージを受けたオブジェクトに
よって決定される性質。
また、この性質を使って、
「同一のメッセージを使って、オブジェクトごとに異なった処理を行わせること」
[VBAのオブジェクト指向]
 VBAのオブジェクト指向は、完全オブジェクト指向言語(JavaやC#等)のそれと比べると、
 『子クラスのメソッドを経由して親クラスの変数やメソッドにアクセスできない』、
 『子クラス内から親クラスの変数やメソッドにアクセスできない』等の制限事項がある。
[多態性(ポリモフィズム)]
 『多態性(ポリモフィズム)』の説明で、
 『動物』に『鳴く』メッセージを通知する例がよく挙げられる。
 以下に、『多態性(ポリモフィズム)』を利用したサンプルコードを示す。
[クラス図]
クラス図
[クラスの説明]
Mammalクラス
 哺乳類を表すクラス。
 メソッドとして、Cry()を実装。
Dogクラス、Catクラス、Crowクラス
 イヌ、ネコ、カラスを表すクラス。各々のクラスはMammal(哺乳類)クラスを継承。
 メソッドとして、Mammal_Cry()を実装。
 ([親クラス名]_[親クラスのメソッド名]で、親クラスのメソッドをオーバーライドできます。)
[多態性(ポリモフィズム)]
・Dogオブジェクト、Catオブジェクト、Crowオブジェクトを
 Mammalオブジェクトの配列に格納する。
 MammalオブジェクトのCrowメソッドを経由して、
 Dogオブジェクト、Catオブジェクト、CrowオブジェクトのCrowメソッドを呼ぶ。
 以下のサンプルでは、3つのMammalオブジェクトのCryメソッドを呼んでいるが、
 実際に実行されるのは、Dog、Cat、CrowのMammal_Cryメソッドであることを示している。
 同一のCryというメッセージをMammalオブジェクトに通知しているが、
 受け取った各々のオブジェクト毎に異なった動作をしていることになる。(多態性(ポリモフィズム))
[サンプルコード]
Option Explicit
'[クラス名] Mammalクラス
'[説明] 哺乳類を表すクラス
'       Dog(イヌ)、Cat(ネコ)、Crow(カラス)の
'       親クラスとして利用

'[メソッド名]
'   Cry
'[機能]
'   動物の鳴き声を取得します。
'[前提条件]
'   子クラスでオーバーライドして下さい。
Function Cry() As String
    Err.Raise _
        999, , _
        "このクラスのメソッドは直接呼ぶことはできません。" & vbCrLf & _
        "子クラスでオーバーライドして呼んで下さい。" 
End Function
[ExcelVBA]Mammalクラス


Option Explicit
'[クラス名] Dogクラス
'[説明] イヌを表すクラス

'Mammalクラスを実装
Implements Mammal

'[メソッド名]
'   Mammal_Cry
'[機能]
'   動物の鳴き声を取得します。
'[備考]
'   メソッド名は、「親クラス名」_「メソッド名」
Public Function Mammal_Cry() As String
    Mammal_Cry = "ワンワン"
End Function
[ExcelVBA]Dogクラス


Option Explicit
'[クラス名] Catクラス
'[説明] ネコを表すクラス

'Mammalクラスを実装
Implements Mammal

'[メソッド名]
'   Mammal_Cry
'[機能]
'   動物の鳴き声を取得します。
'[備考]
'   メソッド名は、「親クラス名」_「メソッド名」
Public Function Mammal_Cry() As String
    Mammal_Cry = "ニャー"
End Function
[ExcelVBA]Catクラス


Option Explicit
'[クラス名] Crowクラス
'[説明] カラスを表すクラス

'Mammalクラスを実装
Implements Mammal

'[メソッド名]
'   Mammal_Cry
'[機能]
'   動物の鳴き声を取得します。
'[備考]
'   メソッド名は、「親クラス名」_「メソッド名」
Public Function Mammal_Cry() As String
    Mammal_Cry = "カァーカァー"
End Function
[ExcelVBA]Crowクラス


Private Sub CommandButton1_Click()

    '哺乳類のオブジェクト変数を宣言
    '要素数3つの配列を用意
    Dim man(2) As Mammal
    
    'イヌ、ネコ、カラスの
    'オブジェクトを生成
    Set man(0) = New Dog
    Set man(1) = New Cat
    Set man(2) = New Crow
    
    '各々の動物の鳴き声を表示
    MsgBox man(0).Cry()
    MsgBox man(1).Cry()
    MsgBox man(2).Cry()

    'オブジェクトを解放
    Set man(0) = Nothing
    Set man(1) = Nothing
    Set man(2) = Nothing

End Sub
[ExcelVBA]呼び出し元


[実行結果]
多態性(ポリモフィズム)の実行結果

2009年1月11日日曜日

[.NET]カスタマイズした構成情報の利用(.NET1.1以前が対象)

[はじめに]
(1)カスタム構成セクションとは?
  通常、アプリケーションの構成情報は、appSettingsノード配下の
  addノード(key属性とvalue属性)に記述するルールですが、
  独自のルール(独自のXMLタグ)で定義することもできます。
  この独自のXMLタグで定義された構成情報を、「カスタム構成セクション」と呼びます。
  「カスタム構成セクション」にアクセスする為には、
  プログラム上で「カスタム構成セクションハンドラ」クラスを実装し、
  構成ファイルに「カスタム構成セクションハンドラ」を追加する必要があります。
(2)カスタム構成セクションハンドラとは?
  カスタム構成セクションにアクセスする為には、
  その独自のXMLタグを解析する必要があります。
  その独自のXMLタグを解析するクラスを、「カスタム構成セクションハンドラ」と呼びます。
  カスタム構成セクションハンドラは、以下の(a)(b)の条件に従って実装する必要があります。
   (a)System.Configuration.IConfigurationSectionHandlerインタフェースを実装する。
   (b)IConfigurationSectionHandlerインタフェースのCreateメソッドに、
     カスタム構成セクションを解析する処理を実装する。
(3)カスタム構成セクションハンドラが、カスタム構成セクションにアクセスするには?
  カスタム構成セクションハンドラがカスタムセクションにアクセスする為には、
  構成ファイルに、構成セクションハンドラを追加する必要があります。
  追加することにより、カスタム構成セクションハンドラとカスタムセクションの対応付けを
  定義したことになります。
(4)利用可能な.NET Frameworkのバージョンは?
  本記事のサンプルは、.NET1.1以前で主流だった方法です。
  .NET2.0以降では、「ConfigurationSection」クラスを使用する方法が
  推奨されています。(.NET2.0以降でも使用可能)
(5))参考文献
  ・『MSDN Library for VisualStudio2008日本語版』
  ・『MCTSスキルチェック問題集70-536 .NET Framework2.0アプリケーション構築基礎』

カスタム構成セクションにアクセスする例を、以下の(1)~(4)に分けて示します。

(1)カスタム構成セクションの定義
  例として、日本の地域と県、県と県庁所在地の対応を定義しています。
[ソース]
<configuration>
  <myCustomGroup>
    <Country Name="Japan">
      <Area Name="Kanto">
        <Prefecture Name="Tokyo" MajorCity="Tokyo"/>
        <Prefecture Name="Kanagawa" MajorCity="Yokohama"/>
        <Prefecture Name="Ibaragi" MajorCity="Mito"/>
      </Area>
      <Area Name="Chubu">
        <Prefecture Name="Aichi" MajorCity="Nagoya"/>
        <Prefecture Name="Gifu" MajorCity="Gifu"/>
        <Prefecture Name="Mie" MajorCity="Tsu"/>
      </Area>
    </Country>
  </myCustomGroup>
        (以下省略)
          :
例:カスタム構成セクションの定義

(2)カスタム構成セクションハンドラの実装   System.Configuration.IConfigurationSectionHandlerインタフェースを   実装したクラスを定義します。   System.Configuration.IConfigurationSectionHandlerインタフェースの   Createメソッドに、カスタム構成セクションのアクセス処理を実装します。   この例では、カスタム構成セクションから、県と県庁所在地の一覧を取得し、   HashTableに格納しています。 [ソース]
''' <summary>
''' カスタム構成セクションハンドラ
''' ※.NET1.1以前で使用可能。
'''  .NET2.0以降ではSystem.Configuration.ConfigurationSectionクラスを推奨
''' </summary>
''' <remarks></remarks>
Public Class MyCustomConfigHandler1_1
    Implements System.Configuration.IConfigurationSectionHandler

    ''' <summary>
    ''' 構成セクションハンドラを作成する。
    ''' </summary>
    ''' <param name="parent">親オブジェクト</param>
    ''' <param name="configContext">構成コンテキストオブジェクト</param>
    ''' <param name="section">セクションXMLノード</param>
    ''' <returns>作成されたセクションハンドラオブジェクト</returns>
    ''' <remarks></remarks>
    Public Function Create( _
        ByVal parent As Object, _
        ByVal configContext As Object, _
        ByVal section As System.Xml.XmlNode) As Object _
        Implements _
        System.Configuration.IConfigurationSectionHandler.Create

        Dim configTable As New Hashtable()

        For Each areaNode As XmlNode In section.ChildNodes
            For Each prefNode As XmlNode In areaNode.ChildNodes
                configTable.Add( _
                    prefNode.Attributes("Name").Value, _
                    prefNode.Attributes("MajorCity").Value)
            Next
        Next

        Return configTable

    End Function
End Class
[VB.NET]例:カスタム構成セクションハンドラの実装

(3)構成ファイルにカスタム構成セクションハンドラの追加   「myCustomGroup」、「Country」の対応付けを定義し、   更に「Country」のセクションハンドラを定義しています。   type属性には、カスタム構成セクションハンドラのアセンブリ修飾名を指定します。   アセンブリ修飾名については、   MessageBox.Show( _    New MyCustomConfigHandler1_1().GetType().AssemblyQualifiedName)   で確認できます。 [ソース]
<configuration>
  <configSections>
    <sectionGroup name="myCustomGroup" >
      <section 
        name="Country" 
        type="CustomConfig.MyCustomConfigHandler1_1, 
              CustomConfig, 
              Version=1.0.0.0, 
              Culture=neutral, 
              PublicKeyToken=null"/>
    </sectionGroup>
  </configSections>
        (以下省略)
          :
例:カスタム構成セクションハンドラの追加

(4)構成情報の取得   以下に、カスタム構成セクションハンドラを使用して構成情報を取得する例を示します。   取得には、System.Configuration.ConfigurationSettingsクラスの   GetConfigメソッドを使用します。(※.NET2.0以降では警告がでます。)   GetConfigの引数には、起点となるカスタム構成セクションのノード名を指定します。 [ソース]
Private Sub Button1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button1.Click

    Dim rtn As Object = Nothing
    Dim configTable As Hashtable = Nothing

    '「myCustomGroup/Country」のXMLノードを起点とし、
    '構成情報を取得する。
    rtn = System.Configuration.ConfigurationSettings.GetConfig( _
        "myCustomGroup/Country")
    configTable = CType(rtn, Hashtable)

    '取得した構成情報をメッセージボックスに表示
    Dim sb As New StringBuilder()
    For Each k As String In configTable.Keys
        sb.Append(k & ":" & configTable(k).ToString() & vbCrLf)
    Next
    MessageBox.Show(sb.ToString())

End Sub
[VB.NET]例:カスタム構成セクションハンドラを使用して構成情報を取得する

2009年1月1日木曜日

[Algo]組合せの数(nCm)の算出

[はじめに]
・n個の中からm個を選ぶ組合せの数(nm)を算出するプログラムです。
 例:a、b、cの3個の中から2個を選ぶ組合せは、
   ab、ac、bcの3通りであり、その数を数学的表記で『32』と表現します。
 .NETのクラスライブラリには算出するメソッドがないようなので作ってみました。
nmを算出する公式はいくつかありますが、
 代表的な公式と各々の特徴について、以下にまとめます。
・参考文献
 『Javaによるはじめてのアルゴリズム入門』

以下に、算出方法に対するプログラム例を示します。

(1)階乗による算出
 公式nm=n!/{m!×(n-m)!}
/// <summary>
/// 異なるn個のものからm個を選ぶ
/// 組み合わせの総数 nCmを取得する。
/// </summary>
/// <param name="n">n</param>
/// <param name="m">m</param>
/// <returns>nCm</returns>
public static decimal CalcComb01(decimal n, decimal m)
{
    //nCm = nCm-1 ×(n-m+1)/ m 
    return CalcFact(n) / (CalcFact(m) * CalcFact(n - m));
}

/// <summary>
/// 階乗を計算する。
/// </summary>
/// <param name="n">n</param>
/// <returns>nの階乗(n!)</returns>
public static decimal CalcFact(decimal n)
{
    if (n <= 0m) {
        return 1m;
    }
        
    return n * CalcFact(n - 1);
}
[C#][階乗による算出]
異なるn個のものからm個を選ぶ組み合わせの総数nmを取得する。

(2)漸化式による算出
 一般的に、漸化式の計算は再帰処理で実装できます。
 公式
 (i)m=0の場合
  nm=1
 (ii)m>0の場合
  nmnm-1×(n-m+1)/m
/// <summary>
/// 異なるn個のものからm個を選ぶ
/// 組み合わせの総数 nCmを取得する。
/// </summary>
/// <param name="n">n</param>
/// <param name="m">m</param>
/// <returns>nCm</returns>
public static decimal CalcComb02(decimal n, decimal m)
{
    //以下の漸化式に従って、再帰により算出する。

    //(1)m=0の場合、
    //      nCm = 1
    if (m == 0)
    {
        return 1;
    }

    //(2)m≠0の場合、
    //      nCm = nCm-1 ×(n-m+1)/ m 
    return CalcComb02(n, m - 1) * (n - m + 1) / m;

}
[C#][漸化式による算出]
異なるn個のものからm個を選ぶ組み合わせの総数nmを取得する。

(3)Π(パイ)による算出
 「(2)漸化式による算出」の公式は、
 総乗(掛け算を集約したもの)と解釈できるので、
 以下の公式でも表現できます。
 公式nm=Π{(n-k+1)/k} (※1≦k≦M)
/// <summary>
/// 異なるn個のものからm個を選ぶ
/// 組み合わせの総数 nCmを取得する。
/// </summary>
/// <param name="n">n</param>
/// <param name="m">m</param>
/// <returns>nCm</returns>
public static decimal CalcComb03(decimal n, decimal m)
{
    //組合せ(nCm)を、
    //以下の公式に従って、ループにより算出する。
    //         m
    // nCm = Π {(n-k+1)/ k }
    //         k=1

    decimal product = 1;

    for(decimal k = 1 ; k <= m ; k++)
    {
        product = product * (n - k + 1) / k;
    }

    return product;

}
[C#][Π(パイ)による算出]
異なるn個のものからm個を選ぶ組み合わせの総数nmを取得する。

2008年12月29日月曜日

[.NET]メールの送信(.NET2.0以降)

[はじめに]
メールを送信するサンプルプログラムです。(最も簡単な例)
クラスライブラリ
 .NETFramework2.0から新たに追加されたクラスを使用しています。
 (1.1以前では『System.Web.Mail』名前空間のクラスが使用されていましたが、
  2.0以降は『System.Net.Mail』名前空間のクラスが推奨されています。)







クラス名/列挙体名概要
System.Net.Mail.SmtpClientクラスSMTPサーバを表すクラスです。
System.Net.Mail.MailMessageクラスメールを表すクラスです。
System.Net.Mail.MailAddressクラスメールアドレスを表すクラスです。
System.Net.Mail.Attachmentクラス添付ファイルを表すクラスです。
System.Net.NetworkCredential認証情報を表すクラスです。
System.Net.Mail.MailPriority列挙体メールの優先度を表す列挙体です。

CDO(Microsoft Collaboration Data Objects)
 Windowsでは、メールの送信機能として『CDO』を用意しています。
 CDOは、VB6やEXCEL VBA等からも利用することができますが、
 インタフェースがわかりにくいものでした。
 .NETでは、CDOの呼び出しをカプセル化することで、
 よりわかりやすいインタフェースを提供しています。
・参考文献
 『MSDN Library for VisualStudio2008日本語版』
 
以下にサンプルソースを示します
''' <summary>
''' メールを送信する
''' </summary>
''' <param name="argSmtpServer">SMTPサーバ名</param>
''' <param name="argPortNo">ポート番号</param>
''' <param name="argSmtpAuth">SMTP認証の有無</param>
''' <param name="argUserName">認証ユーザ</param>
''' <param name="argPassword">認証パスワード</param>
''' <param name="argEnableSsl">SSLの使用有無</param>
''' <param name="argTimeout">タイムアウト(ミリ秒)(Nothingで100000)</param>
''' <param name="argFrom">メールアドレス(From)</param>
''' <param name="argTo">メールアドレス(To)</param>
''' <param name="argCc">メールアドレス(Cc)</param>
''' <param name="argBcc">メールアドレス(Bcc)</param>
''' <param name="argPriority">優先度</param>
''' <param name="argSubject">件名</param>
''' <param name="argBody">本文</param>
''' <param name="argIsHtml">HTMLかどうか</param>
''' <param name="argFile">添付ファイル</param>
''' <param name="argSubEnc">エンコード(件名)</param>
''' <param name="argBodyEnc">エンコード(本文)</param>
''' <remarks></remarks>
Private Sub SendMail( _
    ByVal argSmtpServer As String, _
    ByVal argPortNo As Integer, _
    ByVal argSmtpAuth As Boolean, _
    ByVal argUserName As String, _
    ByVal argPassword As String, _
    ByVal argEnableSsl As Boolean, _
    ByVal argTimeout As Integer?, _
    ByVal argFrom As String, _
    ByVal argTo() As String, _
    ByVal argCc() As String, _
    ByVal argBcc() As String, _
    ByVal argPriority As System.Net.Mail.MailPriority, _
    ByVal argSubject As String, _
    ByVal argBody As String, _
    ByVal argIsHtml As Boolean, _
    ByVal argFile() As System.IO.FileInfo, _
    ByVal argSubEnc As String, _
    ByVal argBodyEnc As String _
    )
    'SMTPサーバを設定
    '※サーバ名、ポート番号を設定
    Dim sClient As New System.Net.Mail.SmtpClient( _
        argSmtpServer, argPortNo _
    )

    'SMTP認証の設定
    If argSmtpAuth Then
        '認証が必要な場合は、ユーザ名とパスワードを設定
        sClient.Credentials = New System.Net.NetworkCredential( _
            argUserName, argPassword _
        )
    End If

    'SSLの使用有無を設定
    sClient.EnableSsl = argEnableSsl

    'タイムアウトを設定
    If argTimeout.HasValue Then
        sClient.Timeout = argTimeout
    End If

    'メールの設定
    Dim mail As New System.Net.Mail.MailMessage
    Try
        'メールアドレス(From)
        mail.From = New System.Net.Mail.MailAddress(argFrom)
        '※メールアドレス(To)を設定
        If Not (argTo Is NothingThen
            For Each addr As String In argTo
                mail.To.Add(addr)
            Next
        End If
        'メールアドレス(Cc)
        If Not (argCc Is NothingThen
            For Each addr As String In argCc
                mail.CC.Add(addr)
            Next
        End If
        'メールアドレス(Bcc)
        If Not (argBcc Is NothingThen
            For Each addr As String In argBcc
                mail.Bcc.Add(addr)
            Next
        End If

        '優先度
        '   高い:System.Net.Mail.MailPriority.High
        '   普通:System.Net.Mail.MailPriority.Normal
        '   低い:System.Net.Mail.MailPriority.Low
        mail.Priority = argPriority
        '件名を設定
        mail.Subject = argSubject
        '本文を設定
        mail.Body = argBody
        '本文をHTML形式にするかどうか
        mail.IsBodyHtml = argIsHtml
        '添付ファイル
        If Not (argFile Is NothingThen
            For Each f As FileInfo In argFile
                mail.Attachments.Add( _
                    New System.Net.Mail.Attachment(f.FullName))
            Next
        End If
        'エンコード(件名)
        '例:shift_jis、iso-2022-jp
        mail.SubjectEncoding = Encoding.GetEncoding(argSubEnc)
        'エンコード(本文)
        mail.BodyEncoding = Encoding.GetEncoding(argBodyEnc)

        'メールを送信
        sClient.Send(mail)
    Finally
        mail.Dispose()
    End Try
End Sub
[VB.NET]メールを送信するサンプル

/// <summary>
/// メールを送信する
/// </summary>
/// <param name="argSmtpServer">SMTPサーバ名</param>
/// <param name="argPortNo">ポート番号</param>
/// <param name="argSmtpAuth">SMTP認証の有無</param>
/// <param name="argUserName">認証ユーザ</param>
/// <param name="argPassword">認証パスワード</param>
/// <param name="argEnableSsl">SSLの使用有無</param>
/// <param name="argTimeout">タイムアウト(ミリ秒)(nullで100000)</param>
/// <param name="argFrom">メールアドレス(From)</param>
/// <param name="argTo">メールアドレス(To)</param>
/// <param name="argCc">メールアドレス(Cc)</param>
/// <param name="argBcc">メールアドレス(Bcc)</param>
/// <param name="argPriority">優先度</param>
/// <param name="argSubject">件名</param>
/// <param name="argBody">本文</param>
/// <param name="argIsHtml">HTMLかどうか</param>
/// <param name="argFile">添付ファイル</param>
/// <param name="argSubEnc">エンコード(件名)</param>
/// <param name="argBodyEnc">エンコード(本文)</param>
/// <remarks></remarks>
private void SendMail(
    string argSmtpServer, int argPortNo, bool argSmtpAuth, 
    string argUserName, string argPassword, bool argEnableSsl, 
    int? argTimeout, string argFrom, 
    string[] argTo, string[] argCc, string[] argBcc, 
    System.Net.Mail.MailPriority argPriority, 
    string argSubject, string argBody, bool argIsHtml, 
    System.IO.FileInfo[] argFile, 
    string argSubEnc, string argBodyEnc)
{
    //SMTPサーバを設定
    //※サーバ名、ポート番号を設定
    System.Net.Mail.SmtpClient sClient = 
        new System.Net.Mail.SmtpClient(argSmtpServer, argPortNo);
    
    //SMTP認証の設定
    if (argSmtpAuth) {
        //認証が必要な場合は、ユーザ名とパスワードを設定
        sClient.Credentials = 
            new System.Net.NetworkCredential(
                argUserName, argPassword);
    }
    
    //SSLの使用有無を設定
    sClient.EnableSsl = argEnableSsl;
    
    //タイムアウトを設定
    if (argTimeout.HasValue) {
        sClient.Timeout = argTimeout;
    }
    
    //メールの設定
    System.Net.Mail.MailMessage mail = 
        new System.Net.Mail.MailMessage();
    try {
        //メールアドレス(From)
        mail.From = new System.Net.Mail.MailAddress(argFrom);
        //※メールアドレス(To)を設定
        if (argTo != null) {
            foreach (string addr in argTo) {
                mail.To.Add(addr);
            }
        }
        //メールアドレス(Cc)
        if (argCc != null) {
            foreach (string addr in argCc) {
                mail.CC.Add(addr);
            }
        }
        //メールアドレス(Bcc)
        if (argBcc != null) {
            foreach (string addr in argBcc) {
                mail.Bcc.Add(addr);
            }
        }
        
        //優先度
        // 高い:System.Net.Mail.MailPriority.High
        // 普通:System.Net.Mail.MailPriority.Normal
        // 低い:System.Net.Mail.MailPriority.Low
        mail.Priority = argPriority;
        //件名を設定
        mail.Subject = argSubject;
        //本文を設定
        mail.Body = argBody;
        //本文をHTML形式にするかどうか
        mail.IsBodyHtml = argIsHtml;
        //添付ファイル
        if (argFile != null) {
            foreach (FileInfo f in argFile) {
                mail.Attachments.Add(
                    new System.Net.Mail.Attachment(f.FullName));
            }
        }
        //エンコード(件名)
        //例:shift_jis、iso-2022-jp
        mail.SubjectEncoding = Encoding.GetEncoding(argSubEnc);
        //エンコード(本文)
        mail.BodyEncoding = Encoding.GetEncoding(argBodyEnc);
        
        //メールを送信
        sClient.Send(mail);
    }
    finally {
        mail.Dispose();
    }
}
[C#]メールを送信するサンプル
補足
本サンプルは、送信元メールアドレスをYahooメールで確認しています。(2008.12.29現在)
Yahooメールで確認するには、
『Yahooメールを他のメーラーで送受信できるようにする』必要があります。
Yahooメールの『POPアクセスとメール転送』で、『ブラウザアクセスとPOPアクセス』に設定して下さい。
あとは、
ユーザ名:YahooID
パスワード:YahooIDのパスワード
SMTPサーバ:『smtp.mail.yahoo.co.jp』
SMTPのポート番号:『587』
でメールを送信できます。

2008年12月21日日曜日

[.NET]関数(y=f(x))のグラフをImageに描画する

[はじめに]
・関数(y=f(x))の呼び出しは、デリゲート経由で行います。
 これにより、描画メソッド(DrawFunctionメソッド)を変更することなく、
 関数(y=f(x))を切替えることができます。
・非関数(xとyが1対1に対応していない)には対応していません。
 例えば、x2+y2=r2のような円を表すグラフは描画できません。
・Graphics.DrawLineメソッドで、一つ前の座標との直線を描画している為、
 連続していない関数(離散型)では一部正しく描画されないことがあります。
 例えば、y=tan(x)の場合、x=π/2で縦線が描画されます。
''' <summary>
''' 関数(y=f(x))のデリゲート
''' </summary>
''' <param name="x">入力</param>
''' <returns>出力</returns>
''' <remarks></remarks>
Public Delegate Function FuncHandler(ByVal x As IntegerAs Integer

''' <summary>
''' 関数(y=f(x))のグラフをイメージに描画する。
''' </summary>
''' <param name="targetImage">描画対象のイメージ</param>
''' <param name="fnc">関数(y=f(x))</param>
''' <param name="xFrom">X座標の最小値</param>
''' <param name="xTo">X座標の最大値</param>
''' <remarks></remarks>
Public Shared Sub DrawFunction( _
    ByVal targetImage As Image, ByVal fnc As FuncHandler, _
    ByVal xFrom As IntegerByVal xTo As Integer)

    Dim g As Graphics = Nothing

    Try
        g = Graphics.FromImage(targetImage)

        '描画領域を初期化(白で塗りつぶす)
        g.FillRectangle(Brushes.White, 0, 0, _
            targetImage.Width, targetImage.Height)

        '描画領域の原点を中央に移動
        Dim xMax As Integer = targetImage.Width * 0.5
        Dim xMin As Integer = -1 * xMax
        Dim yMax As Integer = targetImage.Height * 0.5
        Dim yMin As Integer = -1 * yMax
        g.TranslateTransform(xMax, yMax)
        '描画領域のY座標の向きを逆にする(Y座標の上方向をプラスにする)
        g.ScaleTransform(1, -1)

        '格子を描画する(水平線)
        For y As Single = 0 To yMax Step 10
            g.DrawLine(Pens.Cyan, xMin, y, xMax, y)
        Next
        For y As Single = 0 To yMin Step -10
            g.DrawLine(Pens.Cyan, xMin, y, xMax, y)
        Next

        '格子を描画する(垂直線)
        For x As Single = 0 To xMax Step 10
            g.DrawLine(Pens.Cyan, x, yMin, x, yMax)
        Next
        For x As Single = 0 To xMin Step -10
            g.DrawLine(Pens.Cyan, x, yMin, x, yMax)
        Next

        'X軸を描画
        g.DrawLine(Pens.Blue, xMin, 0, xMax, 0)
        'Y軸を描画
        g.DrawLine(Pens.Blue, 0, yMin, 0, yMax)

        '関数のグラフを描画
        For x As Integer = xFrom To xTo
            Try
                g.DrawLine( _
                    Pens.Black, x - 1, _
                    fnc.Invoke(x - 1), x, fnc.Invoke(x))
            Catch ex As ArithmeticException
                'ゼロ除算、数値演算のオーバーフロー、
                '定義されていない演算エラーは無視する
            End Try
        Next
    Finally
        If Not (g Is NothingThen
            g.Dispose()
        End If
    End Try
End Sub
[VB.NET]関数のグラフをImageに描画する例
(1)PictureBoxに、一次関数(y=2x)のグラフを描画する例 ・上記で定義したメソッド(DrawFunction)の使用例を以下に示します。  まずは、一次関数(y=2x)を定義します。
''' <summary>
''' 関数(一次関数)
''' </summary>
''' <param name="x">入力</param>
''' <returns>出力</returns>
''' <remarks></remarks>
Public Function fnc1(ByVal x As IntegerAs Integer
    Return x * 2
End Function
[VB.NET]例:一次関数の定義
・適当なイベント処理内で、DrawFunctionメソッドを呼ぶ処理を記述します。  DrawFunctionメソッドに渡す引数は、  ・グラフを描画するImageインスタンス  ・一次関数(y=2x)のデリゲート (※デリゲートとはメソッドの参照を格納する変数、型です。)  ・X座標の範囲(From、To)  です。  [デリゲートについて]   .NETでは、メソッドの参照を変数に格納し、変数経由でメソッドに   アクセスすることができます。 (デリゲート変数)   この例では、一次関数の定義をデリゲート変数に格納し、DrawFunctionメソッドに渡します。   メソッドの参照はAddressOf演算子で取得します。   デリゲート変数はFuncHandler型で定義し、fnc1と関連付けします。
Private Sub Button1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button1.Click
    Dim img As New Bitmap(Me.PictureBox1.Width, Me.PictureBox1.Height)

    '関数の参照をデリゲート変数に格納する
    '※関数を変更する場合は、デリゲート変数の中身を変更する。
    Dim f As New FuncHandler(AddressOf Me.fnc1)
    '関数のグラフを描画する。
    DrawFunction(img, f, img.Width * -0.5, img.Width * 0.5)

    Me.PictureBox1.Image = img
End Sub
[VB.NET]DrawFunctionメソッドの呼び出し
実行結果 一次関数 (2)PictureBoxに、二次関数のグラフを描画する例 ・デリゲート変数の内容を、二次関数のデリゲートに置き換えるだけで、描画内容を変更できます。
''' <summary>
''' 関数(二次関数)
''' </summary>
''' <param name="x">入力</param>
''' <returns>出力</returns>
''' <remarks></remarks>
Public Function fnc1(ByVal x As IntegerAs Integer
    Return 0.05 * (x - 10) * (x + 50)
End Function
[VB.NET]関数を二次関数で定義した場合
実行結果 関数を二次関数で定義した場合 (3)PictureBoxに、三角関数のグラフを描画する例 ・同様に三角関数も描画可能です。
''' <summary>
''' 関数(三角関数)
''' </summary>
''' <param name="x">入力</param>
''' <returns>出力</returns>
''' <remarks></remarks>
Public Function fnc1(ByVal x As IntegerAs Integer
    Return 50 * Math.Sin(x / 15)
End Function
[VB.NET]関数を三角関数で定義した場合
実行結果 関数を三角関数で定義した場合 (4)PictureBoxに、平方根の関数のグラフを描画する例 ・平方根の関数も同様です。
''' <summary>
''' 関数(平方根)
''' </summary>
''' <param name="x">入力</param>
''' <returns>出力</returns>
''' <remarks></remarks>
Public Function fnc1(ByVal x As IntegerAs Integer
    Return 10 * Math.Sqrt(x)
End Function
[VB.NET]関数を平方根で定義した場合
実行結果 関数を平方根で定義した場合

[雑記]ドローン(DJI Mini 3)

(1)雑記 もともと多趣味の友人 masakazu Drone 氏が、 最近、 ドローン にハマり始めて、 更に、新たな趣味が増えたとのこと。 ドローン を始めてから、 まだ1年も経っていないとのことですが、 旅行先で山や川の景色を 空撮 して、 Youtube ...