C#」カテゴリーアーカイブ

Twitter の OAuth 1.0 認証を自分でコード書いてやってみた。

みむらです。

ひとまず、おべんきょーということで、後からも分かるように、
変数を多く使って文字列出力をふんだんに出しながら。

ソースコードが、海から来た侵略者に侵略されていますが、
そんなもの全く気にしない、むしろ、侵略されていないでゲソ!

—-

参考資料:

* http://oauth.net/core/1.0
* http://hueniverse.com/oauth/guide/authentication/
* https://dev.twitter.com/docs/auth/authorizing-request/

—-

https://gist.github.com/1395485

using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;

/*
 * この辺を参考に:
 * 
 * http://oauth.net/core/1.0
 * http://hueniverse.com/oauth/guide/authentication/
 * https://dev.twitter.com/docs/auth/authorizing-request
 */

namespace Direct_Commit_Twitter
{
    class Program
    {

        static void Main(string[] args)
        {
            //
            // 使うパラメータは次のようなもの。
            //
            // OAuth Consumer Key       : Consumer Key そのまま。
            // OAuth Token              : Access Token そのまま。 (今回はこれも取得。)
            // OAuth Nonce              : ランダム文字列を与える。 (毎回変更する。)
            // OAuth Signature          : OAuth Signature 以外の値で HMAC-SHA1 をとった値。
            // OAuth Signature Method   : Twitter は HMAC-SHA1 指定っぽいので HMAC-SHA1.
            // OAuth Time Stamp         : UNIX 時間 (1970-01-01 UTC からの秒数) を与える。
            //                          : (今回は GetUNIXTime() メソッドで取得します。)
            // OAuth Version            : 今回は 1.0 を使うので、1.0.
            //

            string consumer_key = "oDcUp76alv6VctYvRx2g";
            string consumer_secret = "mg1U9TEFVafIPQm0Y0YuLR8EZatXiDBvPLiiCConzbg";

            string access_token = "";
            string access_secret = "";

            string tweet_text = "ゲソーゲソー";

            /************************ 以下、黙々と処理 ********************/

            string[] verify_token;

            if (access_token == "" || access_secret == "")
            {

                #region 01. Request Token を取得しなイカ?
                {
                    Console.WriteLine("01 - Token を取得しなイカ?");
                    Console.WriteLine("-------------------------------------------------");

                    Random rand = new Random();
                    byte[] nonce_b = new byte[64];

                    rand.NextBytes(nonce_b);

                    string nonce = Math.Abs(BitConverter.ToInt64(nonce_b, 0)).ToString();
                    long unixtime = GetUNIXTime();

                    //
                    // OAuth Signature 生成のために、それ以外で仮のリクエスト文字列を作成する。
                    // この際、各パラメータは ABC 順にソートされている必要がある。
                    //
                    string signature_request = "POST&" + UrlEncode("https://api.twitter.com/oauth/request_token");
                    signature_request += "&" + UrlEncode(MakeParamString(consumer_key, nonce, null, unixtime, null, null, null));

                    //
                    // ちゃんとしたリクエスト文字列を作る。
                    //
                    string signature = GetSignature(consumer_secret, null, signature_request);
                    string param = MakeParamString(consumer_key, nonce, signature, unixtime, null, null, null);

                    DebugParamOut(consumer_key, consumer_secret, nonce, signature, unixtime, null, null, null);
                    return;
                    //
                    // 問い合わせ。
                    //
                    Console.WriteLine("* Access : https://api.twitter.com/oauth/request_token?" + param);
                    HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create("https://api.twitter.com/oauth/request_token?" + param);
                    hwr.Method = "POST";
                    WebResponse ret = hwr.GetResponse();
                    verify_token = new StreamReader(ret.GetResponseStream()).ReadToEnd().Split('&');

                    ret.Close();

                    Console.WriteLine();
                    Console.WriteLine("Response : ");
                    foreach (string s in verify_token)
                        Console.WriteLine("> " + s);
                }
                #endregion

                #region 02. Access Token を取得しなイカ?
                {
                    Console.WriteLine();
                    Console.WriteLine("02 - Access Token を取得しなイカ?");
                    Console.WriteLine("-------------------------------------------------");

                    string request_token = "";
                    string request_secret = "";

                    //
                    // ブラウザ開いて認証。
                    //
                    foreach (string s in verify_token)
                    {
                        int p = s.IndexOf("oauth_token=");
                        if (p != -1)
                        {
                            request_token = s.Substring(p + "oauth_token=".Length);
                            break;
                        }
                    }
                    Console.WriteLine("- OAuth Token : " + request_token);
                    Console.WriteLine("* Browser Open : https://twitter.com/oauth/authorize?oauth_token=" + request_token);
                    Process.Start("https://twitter.com/oauth/authorize?oauth_token=" + request_token);

                    //
                    // PIN を入力させる。
                    //
                    Console.Write("\nINPUT PIN : ");
                    string pin = Console.ReadLine();

                    foreach (string s in verify_token)
                    {
                        int p = s.IndexOf("oauth_token_secret=");
                        if (p != -1)
                        {
                            request_secret = s.Substring(p + "oauth_token_secret=".Length);
                            break;
                        }
                    }


                    //
                    // 以下 Twitter ともくもく通信。
                    //

                    Random rand = new Random();
                    byte[] nonce_b = new byte[64];

                    rand.NextBytes(nonce_b);

                    string nonce = Math.Abs(BitConverter.ToInt64(nonce_b, 0)).ToString();
                    long unixtime = GetUNIXTime();

                    //
                    // Signature 生成のための一時的なリクエスト文字列を作成。
                    //
                    string signature_request = "POST&" + UrlEncode("https://api.twitter.com/oauth/access_token");
                    signature_request += "&" + UrlEncode(MakeParamString(consumer_key, nonce, null, unixtime, request_token, pin, null));

                    string signature = GetSignature(consumer_secret, request_secret, signature_request);
                    string param = MakeParamString(consumer_key, nonce, signature, unixtime, request_token, pin, null);

                    DebugParamOut(consumer_key, consumer_secret, nonce, signature, unixtime, request_token, request_secret, pin);

                    //
                    // 問い合わせ。
                    //
                    Console.WriteLine("* Access : https://api.twitter.com/oauth/access_token?" + param);
                    HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create("https://api.twitter.com/oauth/access_token?" + param);
                    hwr.Method = "POST";
                    hwr.Headers.Add("Authorization", "OAuth");

                    WebResponse ret = hwr.GetResponse();
                    verify_token = new StreamReader(ret.GetResponseStream()).ReadToEnd().Split('&');

                    ret.Close();

                    Console.WriteLine();
                    Console.WriteLine("Response : ");
                    foreach (string s in verify_token)
                    {
                        if (s.IndexOf("oauth_token=") != -1)
                            access_token = s.Substring(s.IndexOf("=") + 1);

                        if (s.IndexOf("oauth_token_secret=") != -1)
                            access_secret = s.Substring(s.IndexOf("=") + 1);

                        Console.WriteLine("> " + s);
                    }
                }
                #endregion

            }

            #region 03. つぶやかなイカ?
            {
                Console.WriteLine();
                Console.WriteLine("03 - つぶやかなイカ?");
                Console.WriteLine("-------------------------------------------------");
                
                Random rand = new Random();
                byte[] nonce_b = new byte[64];

                rand.NextBytes(nonce_b);

                string nonce = Math.Abs(BitConverter.ToInt64(nonce_b, 0)).ToString();
                long unixtime = GetUNIXTime();

                string tweet_data = UrlEncode(tweet_text);

                string signature_request = "POST&" + UrlEncode("https://api.twitter.com/1/statuses/update.xml");
                signature_request += "&include_entities%3Dtrue%26" + UrlEncode(MakeParamString(consumer_key, nonce, null, unixtime, access_token, null, tweet_data));
                string signature = GetSignature(consumer_secret, access_secret, signature_request);

                string header_param = "OAuth oauth_consumer_key=\"" + UrlEncode(consumer_key) + "\",oauth_signature_method=\"HMAC-SHA1\"," +
                                      "oauth_timestamp=\"" + unixtime + "\",oauth_nonce=\"" + UrlEncode(nonce) + "\"," +
                                      "oauth_version=\"1.0\",oauth_token=\"" + UrlEncode(access_token) + "\"," +
                                      "oauth_signature=\"" + UrlEncode(signature) + "\",";

                DebugParamOut(consumer_key, consumer_secret, nonce, signature, unixtime, access_token, access_secret, null);
                Console.WriteLine("* Access : https://api.twitter.com/1/statuses/update.xml");
                Console.WriteLine("* Tweet at : " + tweet_text);

                HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create("https://api.twitter.com/1/statuses/update.xml");
                hwr.Method = "POST";
                hwr.ServicePoint.Expect100Continue = false;
                hwr.Headers.Add(HttpRequestHeader.Authorization, header_param);
                hwr.ContentType = "application/x-www-form-urlencoded";
                var s = new StreamWriter(hwr.GetRequestStream());
                s.Write("status=" + tweet_data + "&include_entities=true");
                s.Close();

                WebResponse ret = hwr.GetResponse();
                Console.WriteLine();
                Console.WriteLine("Response:");
                Console.WriteLine("> "+(new StreamReader(ret.GetResponseStream()).ReadToEnd()));

            }
            #endregion
        }

        // UNIX 時間を返す。
        static long GetUNIXTime()
        {
            return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
        }

        // URLエンコード (どうやらエスケープ文字は大文字にしないといけないらしい。)
        static string UrlEncode(string str)
        {
            string s = HttpUtility.UrlEncode(str);
            return _UrlEncodeUpper(s);
        }

        static string _UrlEncodeUpper(string str)
        {
            int p = str.IndexOf("%");
            if (p != -1)
            {
                str = str.Substring(0, p) + str.Substring(p, 3).ToUpper() + _UrlEncodeUpper(str.Substring(p + 3));
            }
            return str;
        }

        // パラメータ文字列を生成
        static string MakeParamString(string oauth_consumer_key, string oauth_nonce, string oauth_signature, long oauth_timestamp, string oauth_token, string oauth_verifier, string status)
        {
            string param = "oauth_consumer_key=" + oauth_consumer_key + "&oauth_nonce=" + oauth_nonce;

            if (oauth_signature != null)
                param += "&oauth_signature=" + oauth_signature;

            param += "&oauth_signature_method=HMAC-SHA1" + "&oauth_timestamp=" + oauth_timestamp;

            if (oauth_token != null)
                param += "&oauth_token=" + oauth_token;

            if (oauth_verifier != null)
                param += "&oauth_verifier=" + oauth_verifier;
            
            param += "&oauth_version=1.0";

            if (status != null)
                param += "&status=" + status;

            return param;
        }

        // Consumer Secret をKey とした、リクエスト文字列のハッシュを求める。
        static string GetSignature(string consumer_secret, string access_token_secret, string param)
        {
            HMACSHA1 hmacsha1 = new HMACSHA1();
            hmacsha1.Key = Encoding.ASCII.GetBytes(consumer_secret + "&" + access_token_secret);
            byte[] hash = hmacsha1.ComputeHash(Encoding.ASCII.GetBytes(param));
            
            return Convert.ToBase64String(hash);
        }

        // よくやる出力をまとめてみる。
        static void DebugParamOut(string oauth_consumer_key, string oauth_consumer_secret, string oauth_nonce, string oauth_signature, long oauth_timestamp, string oauth_token, string oauth_token_secret, string oauth_verifier)
        {
            Console.WriteLine("- OAuth Consumer Key = " + oauth_consumer_key);
            Console.WriteLine("- OAuth Consumer Secret = " + oauth_consumer_secret);
            Console.WriteLine("- OAuth Nonce = " + oauth_nonce);
            if (oauth_signature != null)
                Console.WriteLine("- OAuth Signature = " + oauth_signature);
            Console.WriteLine("- OAuth Time Stamp = " + oauth_timestamp);
            if (oauth_token != null)
                Console.WriteLine("- OAuth Access Token = " + oauth_token);
            if (oauth_token_secret != null)
                Console.WriteLine("- OAuth Access Token Secret = " + oauth_token_secret);
            if (oauth_verifier != null)
                Console.WriteLine("- OAuth Verifier = " + oauth_verifier);
        }
    }
}

 

とりあえず、記事自体がむちゃくちゃ長くなるので、

解説云々は次の記事に。

Twitterizer で UserStream を取得する。

みむらです。結構簡単だったのでぺけぺけ。

 


1.Visual Studio を立ち上げてプロジェクトを作る。

 

image

image

でけた。

 


2.Package Manager を起動して、 Twitterizer を入れる。

 

使い方および起動方法は以前書いた記事を : NuGet で簡単にパッケージを導入する

image

image

だん。

 


3.Twitter にアプリケーションを登録する。

 

https://dev.twitter.com/apps へアクセス。

image

画面の右上にある 「Create a new application」 をクリック。

 

image

こういう画面が出てきます。

 

ここでは、次の項目を入力します (なお、各項目は日本語でも問題ありません。):

項目名

説明

Name アプリケーションの名前を入力します。
10文字です。
やぎ、そしてやぎさん、ゆうびんさん。
Description どういうアプリケーションかという説明文を入力します。
10文字~200文字です。
めーと鳴いて、朝と夜を知らせるが、たまに昼間も鳴いてTL を荒らす。
WebSite ウェブサイトのアドレスを入力します。 http://mimumimu.net/
Yes, I agree 上に表示されている、Developer Rules Of The Road に納得できるのであればチェックをします。  
CAPTCHA 下に表示される2つの文字列を入力します。  

 

image

 

適当に入力したら、一番下の 「 Create your Twitter application 」 をクリックします。

image

こんな感じで、アプリケーションが登録されます。

 

この際、

image

ページの下の方の OAuth settings に表示されている、
Consumer keyConsumer secret をメモしておいてください。

(なお、このアプリケーションは記事投稿前に削除しているので、Key と Secret は無効です。

 


4.コードを書く。

 

Visual Studio に戻ってコードを書きます。

image

 

適当に書いてみたのが下記のコード:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Twitterizer;
using Twitterizer.Streaming;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            //
            // 先ほどメモした ConsumerKey と ConsumerSecret をここに入力。
            //
            string consumerKey = "GfX2lsqHQAyObh1vPaTUuQ";
            string consumerSecret = "ffLnE720PHwBHeZShGSEw6qTj5UQD1KgMoAqT9IhvuQ";

            //
            // アクセストークンを取得するために、ブラウザを立ち上げて認証ページを表示させる。
            //
            OAuthTokenResponse req = 
                    OAuthUtility.GetRequestToken(consumerKey, consumerSecret,"oob");
            Process.Start(OAuthUtility.BuildAuthorizationUri(req.Token).ToString());

            //
            // キーを入力させる。
            //
            Console.Write("YOUR KEY : ");
            string pin = Console.ReadLine();

            //
            // 認証情報を OAuthTokens に格納する。
            //
            OAuthTokenResponse actToken =
                    OAuthUtility.GetAccessToken(consumerKey, consumerSecret, req.Token, pin);
            OAuthTokens token = new OAuthTokens
            {
                ConsumerKey = consumerKey,
                ConsumerSecret = consumerSecret,
                AccessToken = actToken.Token,
                AccessTokenSecret = actToken.TokenSecret
            };

            //
            // 第1引数に認証情報、
            // 第2引数にクライアント名
            // 第3引数に取得に関する条件等を指定(今回は null)
            //
            var Stream = new TwitterStream(token, "侵略でゲソ", null);

            Stream.StartUserStream(null, null,
                    (x) => { Console.WriteLine("ID : " + x.User.Name + " - " + x.Text); },
                    null, null, null, null, null);

            System.Threading.Thread.Sleep(-1);
        }
    }
}

 

ちょっと一言:

この際、プログラムが動作しないようであれば、

大抵が .NET Framework 4.0 Client Profile を利用していることが原因なので、変えておきます。

 

1.プロジェクトファイルを右クリックして、プロパティを選ぶ。

 

image

 

2.「対象のフレームワーク」を 「.NET Framework 4」に変える。

 

image

読み込み直すかどうかのダイアログが出るので、「はい」をクリックします。

 


5.実行する。

 

image

 

「連携アプリを認証」をクリック。

image

 

見づらいですが、表示された番号と同じ物をアプリケーションに入力します。

image

うまくいくとこのように、ツイートがたらたら流れてきます。

 


2012/05/30 編集:

サンプルコードにおいて、

while(true) {} でループを回すと負荷がとんでもないことになるので、

メインスレッドを停止させるようにコードを修正しました。

NuGet で簡単にパッケージを導入する。

案外知られていない気がする。

Ruby や Python では、パッケージを簡単にインストールして利用する方法があって、

Ruby では gem
Python では easy_install

がこれに該当しますかね。

 

.NET にも NuGet という同様の仕掛けが存在し、
利用することが出来ます。

.NET開発の新標準「NuGet」入門(前編) - @IT
詳細な解説についてはここのあたりを見ておくと良いかと思います。

 

注:対象は Visual Studio 2010 以降の Visual Studio に限ります。


分からない人向け:

たとえば、今から Twitter の機能を利用したソフトウェアを作ろうとあなたが思ったとき、
以下の選択肢から一つ選ぶことになると思います。

1.自分で OAuth の認証書いて、アクセスするライブラリを作る。
2.インターネットから既存のライブラリをとってくる。

現代においては、教育目的を除いて 1 を選ぶことは殆ど無いかと思います。
(気に入る形に出来ない場合や、そもそも無い場合は作ることにはなりますが。)

 

となると、現実的な回答としては、2となりますが、
インターネットから探してきて、インストールして・・っていうのは面倒で、
カタカタっと名前を打ったりして、簡単にインストール出来た方がいいわけです。

インストーラが面倒くさいということも考えられるでしょうし、
そもそも、インストーラが無くて、自分で組み込まなければならない場合は面倒になりますし、
友人に教えながら作業するという場合や、雑誌にやり方を載せる場合などにおいては、
友人や読者にファイルのありかを教えなければなりませんし、
複数台に組み込む時なども・・・・ とまぁ、非常にナンセンスな訳です。

 

そんなわけで、 Python の easy_install や Ruby の gem
そして、この記事で触れる .NET の NuGet などのパッケージ管理ソフトウェアを用いることにより、
単純明快でかつ高速に、ライブラリを用意して使い始めることが出来ます。

また、ライブラリに更新があった場合、手動で入れた場合はまたインストールをしなければなりませんが、
大抵こういうパッケージ管理ソフトでは、アップデートも簡単に行える仕様が備わっています。

 

という感じで、長文になりましたが、
導入~更新 まで、ライブラリの利用に関するあらゆることを簡単に使えるようにした物。
それが、パッケージ管理ソフトウェア ということになります。


というわけで本題。

 

1.導入

http://visualstudiogallery.msdn.microsoft.com/27077b70-9dad-4c64-adcf-c7cf6bc9970c
上記URL より、 Download をクリックしてダウンロード、インストーラを起動します。

 

image

上のような画面が出ますので、インストールをクリックし、導入を完了させます。

 

2.開発を始める。

image

いつものように、ソリューションを開きます。

 

3.パッケージを導入する。

image

メニューバーの 「ツール」 → 「Library Package Manager」 → 「Package Manager Console」 をクリックします。

image

コンソールが立ち上がった。

 

今回は例として、

http://www.twitterizer.net/
上記URL にて公開している、「Twitterizer」を導入してみます。

 

image

Install-Package twitterizer

と打って、Enter で実行。

 

image

自動的に依存関係が解決された状態で、参照にライブラリが加わり、使えるようになる。

 

3.コード書いて動かす。

 

image

 

とりあえずこんな感じ。

 


というわけで、適当に超基本的なコマンドだけ、対応表にするとこんな感じなのかなぁ。

コマンド

NuGet

gem

easy_install

hoge をインストール Install-Package hoge gem install hoge easy_install hoge
hoge を更新 Update-Package hoge gem update hoge easy_install –U hoge
全部更新 Update-Package gem update easy_install –U
hoge を削除 Uninstall-Package hoge gem uninstall hoge  

NuGet のコマンドについては、

http://www.atmarkit.co.jp/fdotnet/chushin/nuget_01/nuget_01_02.html
上記URL に大体まとまっているかと思います。

 

そんな感じで。であであ。

IronPython を C# から使ってみる。

みむらです。

Python でさくさくっとコードを書いて実験するという人はいると思うのですが、
それを .net で応用してみようという感じの内容です。

今回は執筆時のバージョン IronPython 2.7.1 を用いて紹介します。

(本家 Python の Version 2.7.1 と多少の点は異なりますが、かなりの部分で互換性があります。)

 

1.環境準備

C# の開発環境として、今回は Visual Studio 2010 を使用します。

http://www.microsoft.com/japan/msdn/vstudio/express/
ない方は、こちらから express 版を入れておくと良いかと思います。

 

加えて、今回のメインである、IronPython を、
http://www.ironpython.net/
ここから、ダウンロードしてインストールします。

 

2.プロジェクト作成

Visual Studio を立ち上げて、プロジェクトを作成します。

image

image

Visual C# の 「コンソールアプリケーション」を作成。

 

3.参照に IronPython を追加する。

image

ソリューションエクスプローラの参照設定を右クリック –> 参照の追加

image

インストールディレクトリに移動して、

C:\Program Files\IronPython 2.7.1
or
C:\Program Files (x86)\IronPython 2.7.1

あたりにファイルがいると思います。

IronPython.dll と Microsoft.Scripting.dll を追加。

 

4.コードを書く

コードの先頭に

using IronPython.Hosting;
using Microsoft.Scripting.Hosting;

を追記。

最小のコードとしてはこんな所でしょうか:

using IronPython.Hosting;
using Microsoft.Scripting.Hosting;

class Program
{
    static void Main(string[] args)
    {
        ScriptEngine engine = Python.CreateEngine();
        ScriptSource src = engine.CreateScriptSourceFromString("print \"Hello Python World\"");
        src.Execute();
    }
}

5.実行

image

 

ということで、ばっちり Python コードが C# 上から実行可能です。


応用例をいくつか。

ScriptScope を定義することによって、C# 上のクラスや、他のオブジェクトを触ることも可能となります。

using System;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;

public class hoge
{
    public void call()
    {
        System.Console.WriteLine("Hello C# World");
    }
}

class Program
{
    static void Main(string[] args)
    {
        ScriptEngine engine = Python.CreateEngine();
        ScriptScope scope = engine.CreateScope();
        scope.SetVariable("hoge", new hoge());

        ScriptSource src = engine.CreateScriptSourceFromString(@"

print ""Hello Python World""
hoge.call()"
        
            );
        src.Execute(scope);
    }
}

実行結果:

image

 

上記のように、

CreateScope() メソッドで作成したスコープに対して、

SetVariable() メソッドを利用し、第1引数に名前、第2引数に実体を指定することにより、

Python 上から利用可能となります。

 

ただ一つ注意点としては、

クラスが public でないと正常に動作しないという点があります。

 

これは、個人的には Python のクラスが全て public なのが起因しているのかと予想しておりますが、

詳細はよく分かっていません。


別の例:

image

using System;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;

class Program
{
    static void Main(string[] args)
    {
        ScriptEngine engine = Python.CreateEngine();

        ScriptSource src = engine.CreateScriptSourceFromString("1+2+3");
        System.Console.WriteLine("RET : " + src.Execute());
    }
}

Execute メソッドの戻り値はそのまま実行結果になっていますので、

このように結果を C# 側に返すということも可能です。

 

また、

image

このように、GetVariable メソッドを利用して値を取得することも可能です。


 

IronPython の利用例としては、

プログラム上のマクロ機能の提供が一番大きいのではと考えております。

その他には、Python でライブラリが提供されている物に対して、IronPython を通して C# から利用するというパターン。

 

今回の IronPython と同様のコールの仕方を用いることで、

http://ironruby.net/

こちらの IronRuby を利用することも可能です。

執筆時点では Version 1.1.3 ですが、これは本家の Ruby の Version 1.9.2 と互換性があると明記されています。

 

.net では同じ .net 上で動作する言語同士を協調動作させることができますので、

こういうのもアイデアによっては非常に良い物になるのではないでしょうか。

 

最後に。私が某所でやってきた時のプレゼン資料を最後に貼り付けておきます。

Prolog を Excel で使う。

またしても、不思議なことをしてみました。

359779196

今回解かせたのは、
http://www.geocities.jp/m_hiroi/prolog/prolog01.html#chap4
こちらのウェブサイトで紹介されている、「家系図」の問題。

ダウンロードに関して
ソースコード: https://github.com/mimura1133/mm_Prolog_for_Excel
バイナリ:http://mimumimu.net/beta/programs/PrologExcel.zip

コードの紹介は今回は割愛しますが、
導入の方法について、かなり変態的なので紹介します。


導入編。

image

ファイルを展開すると、このようなファイルが入っています。

image

この中から、 install.bat を探し、右クリック –> 管理者として実行

実行したら、 Excel を立ち上げます。

image

ファイルメニュー内の「オプション」をクリック

image

開いたダイアログから、「アドイン」を選び、
一番下の管理について、「Excel アドイン」を選んで、「設定」を押します。

image

そして、オートメーションをクリック。

image

中から、PrologExcel.PrologExcel を選んで、OK を押す。

image

PrologExcel.PrologExcel が追加されるので、チェックを付けて OK を押す。


利用編

このアドインには大きく2つの関数があります。

1.Prolog_List 関数

Prolog_List()

Input : Excel List
Output: Prolog List

この関数は、

male taro
male ichiro
male jiro
male saburo

というような一覧が存在したとき、

male(taro).
male(ichiro).
male(jiro).
male(saburo).

このような、Prolog のリスト形式に変換してくれます。

さんぷる:
image

また、下記のように、いくつもリストがある場合、

image

特に難しい事はしていませんので、 Excel の通常の文字列結合同様、
「&」マークで結合すれば問題ありません。

image

2.Prolog 関数

Prolog()

Input : Program, Query
Output : Answer

第一引数に、リスト定義などを与え、
第二引数に、クエリを与えます。

image

クエリを投げる際は、

:- parents_of(X, ichiro).

のように、「?-」 ではなく、「:-」として投げるようです。

(・・私は Prolog を使う人じゃ無いのでよく分かりません・・。)

なお、この関数が実行される際、多少ラグが発生するのでご了承下さい。


とりあえず、こんな感じで。であであ。