開発」カテゴリーアーカイブ

Visual Studio でのインデントの整形方法。

メモ。

コーディング技法 : http://msdn.microsoft.com/ja-jp/library/aa291593(v=VS.71).aspx

このページを見てみますと、
インデントに関して「空白4個などに定め」とあります。

たぶんタブでもいいんでしょうけれど、何となくタブ幅でまた議論になりますので、
空白4文字にしてみます。

 

というわけで、Visual Studio での設定:

1.「タブの保持」から「空白の挿入」へ変更する。
(なお別の方法にする場合、ここを規約に則った形に設定します。)

image

2.コードを全部選択して、Ctrl-K, Ctrl-F と押す。

・・・コードの量にあわせて時間が掛かりますが、ソースコードがすべて整形されます。


追加メモ:
下記の2つのアドインも入れておくといいかも。

Indent Guides:
http://visualstudiogallery.msdn.microsoft.com/e792686d-542b-474a-8c55-630980e72c30

スクリーンショット

入れますとこういう感じで、ガイドラインがエディタ上に表示されるため、
インデントのスペース数がおかしい場合はここですぐにわかります。

 

Productivity Power Tools :
http://visualstudiogallery.msdn.microsoft.com/d0d33361-18e2-46c0-8ff2-4adea1e34fef/

このアドインは多くの機能がありますが、
(詳細は窓の杜の記事を参照してください。)

空白とタブのインデントがごちゃ混ぜに入っている場合、どちらかに直してくれる機能があります。

image

混ざっているソースコードを開きますと、こういうメッセージが表示され、
Tabify でタブによるインデント、
Untabify でスペースによるインデントに統一されます。

銀行丸めと四捨五入。

というわけで、端数の丸め処理についてです。

端数処理ということで、たぶん思いつくのは、

  • 切り捨て
  • 切り上げ
  • 四捨五入

こんなところではないかと思います。

ここで、テストデータとして

11.4, 11.5, 11.6, 12.4, 12.5, 12.6

という6つのデータを用意します。
それぞれの処理についてですが、通り下記のようになります。

データ 切り捨て 切り上げ 四捨五入
11.4 11 12 11
11.5 11 12 12
11.6 11 12 12
12.4 12 13 12
12.5 12 13 13
12.6 12 13 13

 

C や C# そして Ruby や Java などでは、実数を整数に丸める際、
単純にキャストしますと切り捨てますが、

round 関数で丸める際に、挙動が異なります。

Python:
image

Ruby:
image

C#: (自作のシェル経由でごめんなさい)
image

 

C や Ruby, Java では四捨五入がデフォルトで行われますが、
C# では、銀行丸めがデフォルトで行われます。

正式名称は 「最近接偶数への丸め」と言いますが、
「銀行丸め」のほか、「JIS丸め」「ISO丸め」とも言われます。

[Wikipedia の解説記事]

JIS丸めとは?
http://homepage1.nifty.com/s_miyake/hp/jisround.htm

JIS Z 8401
http://www.jisc.go.jp/app/pager?id=94037

 

上の記事の文章を用いて、簡単に説明すれば、

N桁で丸める場合
第N桁が偶数なら 5以下は切り捨て。それ以外は切り上げ。
第N桁が奇数なら 5未満は切り捨て。それ以外は切り上げ。

 

この挙動について、
11.5 と 12.5 という2つの値を整数値に丸めるという場合で説明しますと、

まず 11.5 の場合。
整数値に丸めるので、整数第1位に丸めることになります。

この場合、整数第1位の値は 1 となり、「奇数」です。
次にこの一つ下の値を参照し、 5 であるため、奇数で5未満でないため切り上げ。

よって、 12 となります。

 

次に 12.5 の場合。

同様に整数第1位の値を見ると 2 となり「偶数」です。
一つ下の値は 5 であるため、偶数で5以下のため切り捨て。

よって、12 となります。

 

ただどうしてこういう丸め方をしているかというと、
主に銀行や統計などにおいて、誤差を小さくするために用いられています。

整数に丸める時の注意 – DiaryException
http://d.hatena.ne.jp/LaclefYoshi/20110430/1304138274

こちらの記事におもしろい実験結果がありますので、参照して頂けたら。

 

上記ブログで用いられている R という言語は、統計に特化した処理系ですので、
やはり誤差を抑えるために、銀行丸めが行われているものと思われます。

 

というわけで、先ほどの結果に、銀行丸めと合計を追加すると以下のようになります。

 

データ 切り捨て 切り上げ 四捨五入 銀行丸め
11.4 11 12 11 11
11.5 11 12 12 12
11.6 11 12 12 12
12.4 12 13 12 12
12.5 12 13 13 12
12.6 12 13 13 13

 

というわけで、統計やトレードなどを行う場合はありがたいわけですが、
どうしても四捨五入を行わなければならない場合があります。

その場合は、Math.Round(val) としているところを、

Math.Round(val, MidpointRounding.AwayFromZero);

とすることで解決可能です。

image

 

ではではー!

小学生にも情報教育をば。

どうもみむらです。

いきなり質問ですが、下記の2つの文章の共通点をあげてください。

A.里の秋。

静かな静かな 里の秋
お背戸に木の実の 落ちる夜は
ああ 母さんとただ二人
栗の実 煮てます いろりばた

B.静かな湖畔

静かな湖畔の 森のかげから
もう起きちゃいかがと カッコが鳴く
カッコ カッコ
カッコ カッコ カッコ

 

はい、もうわかりましたよね。

こたえは、誰しもがわかるあれです。

続きを読む

Console Twitter を公開しました。

image

ておくれてない、まだ、まだだっ!!
ということでみむらです。

先日の OAuth の記事 を書いた後、やっぱりクライアントを作りましょうということで。

ttytter っぽいものを意識しましたが、自分が使いやすいように作ってみました。

 

Microsoft .NET Framework 3.5 がある環境であれば実行可能です。
(Windows 7 では標準搭載)

 

http://mimumimu.net/software/#ConsoleTwitter
上記URL よりダウンロード可能です。

 

ただつぶやくだけではなく、下記のコマンドを使うことで様々な操作も可能です。

/rep リプライ一覧を表示
/rep (番号) (ツイート) リプライを送ります。

ex) /rep 01 ておくれてない!

/fav お気に入りに登録したツイートを表示します。
/fav (番号) お気に入りに登録します。
/unfav (番号) お気に入りを解除します。
/rt (番号) リツイートします。
/find (テキスト) 指定したテキストで Twitter 上のツイートを検索して表示します。

 

コンソールで表示されて、全部がキーで行うということで、
シンプルでかつ、操作も覚えやすいのでは無いでしょうか。

 

ということで、よろしくお願いします-。


追記:ソースコード公開しました。

https://github.com/mimura1133/Console-Twitter

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);
        }
    }
}

 

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

解説云々は次の記事に。