VNCViewerでMacに繋ぐと109キーボードが使えない

mac mini を使い始めたのだが、Windows から VNC Viewer 経由で mac を使っているせいか、109キーボードをきちんと認識しない。何故か、USキーボード(ASCIIキーボード?)に誤認されるようだ。

ネットを見た感じでは、解決できないらしい。

VNC 使用時のキーレイアウト|Mac mini でリビングPC
http://ameblo.jp/macmini/entry-10000922847.html

SE奮闘記: WindowsからMacにVNCで接続すると「=」と「’」が入力できない
http://se-suganuma.blogspot.com/2009/11/windowsmacvnc.html

上の記事にある通り、押せないキーは

「=」(イコール)、「’」(シングルクォート)、「`」(バッククォート)。

直接、キーボードを繋げればいいんだが、Windows をメインに使っている者としてはちと不便なので、調べてみると、

Ukelele

20100830_05.jpg

を使うと、キーボードのバインドを変更できる。

mac の場合は、キーバインドが、

システムの場合 /Library/Keyboard Layouts

個人ごと ~/Library/Keyboard Layouts

に *.keylayout というファイルで保存すると、そのキーバインドが「ことえり」で使える。

そんな訳で、Ukelele を使ってキーコードを頼りに変えようとしたのだが、残念ながら、何処か変なところでキーコードを変えているらしく、「”」と「’」のどちらも「”」のキーコード 39 に割り当てられていて、区別が付かず。

# 仕組み的には、中身は unix だから keyboard map があるんだけど、どれだっけ?

半日ほど色々やったのだが、面倒なので、10キーのほうに割り当てていしまうことに決めた。

20100830_03.jpg

20100830_04.jpg

10キーの「/」の位置に「’」(シングルクォート)と「`」(バッククォート)を割り当ててしまう。

あと、「=」は、キーバインドが間違っている(?)ので、直した。

このファイルは、JapanJIS.keylayout に置くので右クリック(ってできたっけ?)などでダウンロードして使って下さい。

ちなみに、109キーボードを VNCViewer 経由でつなげた時のレイアウトなので、直接109キーボードを繋げたときはどうなるのか試してはいません。

このファイルを、~/Library/Keyboard Layouts のフォルダに置いて、ことえりで「環境設定を表示」→「英字入力時のキーボード配列」で「109.JIS」を選択すると使えます。

20100830_06.jpg

あと、109キーボードを使っていて、困るのが「ことえり」で漢字モードに入って、英語モードに戻れないこと。

Ctrl+Shift+j で漢字モードに入るのだが、Ctrl+Shift+; で抜けられない。「;」のキーでShiftを押すと「+」になってしまうため。

なので、Alt + Space で漢字と英数字を切り替えるのがベター、というか、それしかできない。

ひとまず、これでプログラミングができそうだ。

 

カテゴリー: ツール | 2件のコメント

C#からMySQLを扱う(更新編)

C#からMySQLを扱う(更新編)

射撃しながら前進(あるいは迷走)する方への援護射撃。第2弾です。

MySQLでも、SQL Serverでも、Oracleでも、データをグリッドで表示する場合は、DataSetを使うのが断然楽です。
顧客が、グリッドのチープな画面を許容してくださるならば、グリッドでOKでしょう。

// コネクション作成
MySqlConnection cn = new MySqlConnection(
 "Data Source=localhost;Database=konicadb;User ID=konica;password=konica");
MySqlDataAdapter da = new MySqlDataAdapter(
 "SELECT * FROM sample", cn);
DataTable dt = new DataTable();
// 検索
da.Fill(dt);
// 表示
dataGridView1.DataSource = dt;

こんな風に、DataTable を使って書けます。

 

ちなみに、DataSet で書く場合は、

// コネクション作成
MySqlConnection cn = new MySqlConnection(
 "Data Source=localhost;Database=konicadb;User ID=konica;password=konica");
MySqlDataAdapter da = new MySqlDataAdapter(
 "SELECT * FROM sample", cn);
DataSet ds = new DataSet();
// 検索
da.Fill(ds);
// 表示
dataGridView1.DataSource = ds;

何が違うかというと(これも歴史的な話になるのですが)、もともと、DataSetは、複数のテーブルを扱える設計になっています。なので、DataSetは複数のテーブルを扱うのですが、普通は上の例のように、ひとつのテーブル(検索結果)しか扱いません。
なので、

dataGridView1.DataSource = ds;

とした場合は、最初のテーブルを使う、という仕様になっているんですね。
これが、ADO.NET のバージョンで DataTable ってのが出てきました。所詮、ひとつのテーブルしか扱わないのですから、DataSetの部分は無駄、という考えです。
なので、DataSetとDataTableは、同じように扱って大丈夫です。

 

ちなみに、DataSetから最初のテーブルを取り出す場合は、

dataGridView1.DataSource = ds.Tables[0];

と書きます。

 

余談ですが、DataSetに複数のテーブルを使う場合は、

MySqlDataAdapter da = new MySqlDataAdapter(
 "SELECT * FROM person;" +
    "SELECT * FROM company", cn);
DataSet ds = new DataSet();
// 検索
da.Fill(ds);

のように、データアダプタに対して、SQL文を二つ書きます。これは、SQL Server のみ使える機能です。
# つまりは、このために DataSet は複数のテーブルを扱えるようになっているわけです。

 

■データを追加 INSERT

データを追加するINSERT文は、通常はMySqlCommandクラスを使います。
この場合、素直にMySqlCommandクラスを使ったのが次の例です。

MySqlConnection cn = new MySqlConnection(
        "Data Source=localhost;Database=konicadb;User ID=konica;password=konica");
// コマンドを作成
MySqlCommand cmd =
    new MySqlCommand("insert into sample values (10,'konica',null,null)", cn);
// オープン
cmd.Connection.Open();
// 実行
cmd.ExecuteNonQuery();
// クローズ
cmd.Connection.Close();

SELECTの場合と違うのは、コネクションのオープンとクローズを前後に入れないと駄目なところですね。
実は、このオープン&クローズはデータアダプタが担っているのです。
データアダプタを使って INSERT 文を実行する場合は、こんな風になります。


MySqlConnection cn = new MySqlConnection(
        "Data Source=localhost;Database=konicadb;User ID=konica;password=konica");
// コマンドを作成
MySqlDataAdapter da =
    new MySqlDataAdapter("insert into sample values (11,'konica',null,null)", cn);
// データテーブル
DataTable dt = new DataTable();
// 実行
da.Fill(dt);
// 結果は無視

SELECT文とは違って、Fillメソッドで呼び出した後の結果は無視します。

 

さて、このままSQL文を書いてもいいのですが、各データを書くのが非常に面倒です。
で、よくやるパターンは、stringクラスのFormatメソッドが使われます。

MySqlCommand cmd =
    new MySqlCommand(
    string.Format("insert into sample values ({0},'{1}',{2},{3})",
        id, name, url, date));

変数を使って、整形をするパターンですが、これには重大な欠点があります。

 

・文字列の場合は「’」を使って囲まないといけない。忘れるとエラーになる。
・nullが指定できない。
・SQLインジェクションが発生する。

SQLインジェクションの問題もそうですが、文字列を意識しないといけなかったり、nullが指定できないのは致命的です。なにより、日付型(DateTime型)の指定が非常に困難です。

なので、MySqlCommandクラスでパラメータを指定するのがベターです。

MySqlConnection cn = new MySqlConnection(
        "Data Source=localhost;Database=konicadb;User ID=konica;password=konica");
// コマンドを作成
MySqlCommand cmd =
    new MySqlCommand("insert into sample values (@id, @name, @url, @date )", cn);
// パラメータ設定
cmd.Parameters.Add(
    new MySqlParameter("id", 13));
cmd.Parameters.Add(
    new MySqlParameter("name", "konica"));
cmd.Parameters.Add(
    new MySqlParameter("url", null));
cmd.Parameters.Add(
    new MySqlParameter("date", DateTime.Now));

// オープン
cmd.Connection.Open();
// 実行
cmd.ExecuteNonQuery();
// クローズ
cmd.Connection.Close();

MySqlCommandクラスでSQL文を指定する時に、「@name」のようにパラメータを指定して、MySqlParameterオブジェクトで値を指定します。

 

このようにパラメータを使うと、先の3点が一遍に解決できますし、さらに、日付型のようなちょっと指定の難しい型も簡単に設定できます。

# 本来は、ストアドプロシージャを使うのが筋なのですが、SQL文の埋め込みとストアドプロシージャは「配置」が異なるので、一概に交換できるとは言えません。なので、プロジェクトごとに、SQL文の埋め込みにするか、ストアドプロシージャにするかを考える必要があります。

■データを追加で自動採番のIDを使う場合

さて、INSERT文は書けるようになりましたが、自動でIDを振っているときはどうするのか、が問題です。
これは普通に次のように書きます。

MySqlConnection cn = new MySqlConnection(
        "Data Source=localhost;Database=konicadb;User ID=konica;password=konica");
// コマンドを作成
MySqlCommand cmd =
    new MySqlCommand("insert into sample ( name, url, date ) values ( @name, @url, @date )", cn);
// パラメータ設定
cmd.Parameters.Add(
    new MySqlParameter("id", 13));
cmd.Parameters.Add(
    new MySqlParameter("name", "konica"));
cmd.Parameters.Add(
    new MySqlParameter("url", null));
cmd.Parameters.Add(
    new MySqlParameter("date", DateTime.Now));

// オープン
cmd.Connection.Open();
// 実行
cmd.ExecuteNonQuery();
// クローズ
cmd.Connection.Close();

INSERT文で列名を指定するパターンですね。

 

ただし、ここで問題があります。このINSERTをした後でIDを取得したいときってありますよね。この場合はどうするのでしょうか?
これは、最終に更新したIDを取得するクエリを叩きます。

MySQLの場合は、「SELECT LAST_INSERT_ID()」を使うので、

MySqlConnection cn = new MySqlConnection(
        "Data Source=localhost;Database=konicadb;User ID=konica;password=konica");
// コマンドを作成
MySqlCommand cmd =
    new MySqlCommand("insert into sample (name, url, updatedate) values (@name, @url, @date)", cn);
// パラメータ設定
cmd.Parameters.Add(
    new MySqlParameter("name", "konica"));
cmd.Parameters.Add(
    new MySqlParameter("url", null));
cmd.Parameters.Add(
    new MySqlParameter("date", DateTime.Now));
MySqlCommand cmd2 =
    new MySqlCommand("SELECT LAST_INSERT_ID()", cn);

// オープン
cmd.Connection.Open();
// 実行
cmd.ExecuteNonQuery();
// 更新IDを取得
var id = cmd2.ExecuteScalar();
// クローズ
cmd.Connection.Close();

MessageBox.Show(“更新ID:” + id);

 

のように動かせば、最後に更新したIDを取得できます。
ExecuteScalarメソッドは、long型を返すのですが、キャストが面倒なのでvar型で受け取ってOKです。

■INSERT時の例外はどうするのか?

INSERT時に型チェックやIDの採番などでエラーが発生する場合があります。
これは、普通にC#の例外処理(try-catch)を入れてやれば取得できます。

MySqlConnection cn = new MySqlConnection(
        "Data Source=localhost;Database=konicadb;User ID=konica;password=konica");
// コマンドを作成
MySqlCommand cmd =
    new MySqlCommand("insert into sample (name, url, updatedate) values (@name, @url, @date)", cn);
// パラメータ設定
cmd.Parameters.Add(
    new MySqlParameter("name", "konica"));
cmd.Parameters.Add(
    new MySqlParameter("url", null));
cmd.Parameters.Add(
    new MySqlParameter("date", DateTime.Now));
MySqlCommand cmd2 =
    new MySqlCommand("SELECT LAST_INSERT_ID()", cn);
try
{
    // オープン
    cmd.Connection.Open();
    // 実行
    cmd.ExecuteNonQuery();
    // 更新IDを取得
    var id = cmd2.ExecuteScalar();
    // クローズ
    cmd.Connection.Close();
}
catch (SqlException ex)
{
    // 例外処理
    MessageBox.Show("例外発生:" + ex.Message);
}

■データを削除 DELETE

 

削除も同じように書けます。

int id = 15; // 削除するID

MySqlConnection cn = new MySqlConnection(
        "Data Source=localhost;Database=konicadb;User ID=konica;password=konica");
// コマンドを作成
MySqlCommand cmd =
    new MySqlCommand("delete from sample where id = @id", cn);
// パラメータ設定
cmd.Parameters.Add(
    new MySqlParameter("id", id));
// オープン
cmd.Connection.Open();
// 実行
cmd.ExecuteNonQuery();
// クローズ
cmd.Connection.Close();

ここまで来ると簡単ですね。

 

■データを更新 UPDATE

更新も同じように書きます。

int id = 20; // 更新するID

MySqlConnection cn = new MySqlConnection(
        "Data Source=localhost;Database=konicadb;User ID=konica;password=konica");
// コマンドを作成
MySqlCommand cmd =
    new MySqlCommand("update sample set updatedate = @date where id = @id", cn);
// パラメータ設定
cmd.Parameters.Add(
    new MySqlParameter("id", id));
cmd.Parameters.Add(
    new MySqlParameter("date", DateTime.Now));
// オープン
cmd.Connection.Open();
// 実行
cmd.ExecuteNonQuery();
// クローズ
cmd.Connection.Close();

こんな風にパラメータを使うと、順不同に書けるのコードも見やすくなります。
■DataSetをいつ更新するのか?

 

所詮 DataSet はキャッシュなので、データの追加/削除/更新した場合は、もう一度 DataSet を読み直すのが吉です。

DataSet/DataTableの内容を直接更新することも可能ですが、かえってややこしいので、業務的にはやめたほうがいいです。

# LINQ to SQL や ADO.NET Data Entity の場合は、オブジェクト自身そのものを通すので、更新しなくても良いでしょう。ただし、SQL Server と Oracle しか使えないので。

手順としては、

・追加したら検索
・削除したら検索
・更新したら検索

にします。

具体的には、

MySqlConnection cn = new MySqlConnection("...");
// コマンドを作成
MySqlCommand cmd =
 new MySqlCommand("insert into TPerson ( @id, @name, @age )", cn);
cmd.Parameters.Add(new MySqlParameter("id", 1));
cmd.Parameters.Add(new MySqlParameter("name", "konica"));
cmd.Parameters.Add(new MySqlParameter("age", 100));
// 実行
cmd.ExecuteNonQuery();
// DataTabel/DataSetを再読み込み
MySqlConnection cn = new MySqlConnection("...");
MySqlDataAdapter da = new MySqlDataAdapter(
 "SELECT * FROM TPerson", cn);
da.Fill(m_dt);

のように、ローカルに保存しているDataSet/DataTable(m_dt)に、設定します。

 

■DataSet/DataTableをどのような形式で持つのか?

実は、例では Tsample 簡単なテーブルをデータグリッドに表示するだけなのですが、実務ではもっと複雑な形式でグリッドに表示することになります。
この場合は、どのパターンでデータを保存するかを「考える」必要があります。

ひとまず、アンチパターンを書き並べておくと、

・複数テーブルを利用している場合、それぞれのテーブルをDataTableに保管しようとする。
・グリッドに表示するときに、常に複雑なフィルタが必要になる。

ような設計になっている場合は、考え直してください。
このような設計は、非常にデータをシンプルに検索する方法に変更します。

指針としては、

.データグリッドやリストに表示する単位で、DataSet/DataTable に保存する。

でOKです。

例えば、

TPerson
+ id
+ name
+ age
+ companyid

TCompany
+ id
+ name

のようなテーブルがあって、グリッドに

+ TPerson.name
+ TCompany.name

の2つを表示している場合には、

MySqlDataAdapter da = new MySqlDataAdapter(
 "SELECT p.name as 'PName', c.name as 'CName' " +
    " FROM TPerson p, TCompany c " +
    " WHERE p.companyid = c.id ";
DataTable dt = new DataTable();
// 実行
da.Fill(dt);

のように、DataTable に保存しておきます。

 

これを表示する画面ごとに取得してしまいます。
昔ならば、メモリが問題になってしまうのですが、今のコンピュータならば、多少のメモリのロスは大丈夫でしょう。
逆に、大量のデータをグリッドに表示するような場合は、DataSetに保存せずに、一回ずつ検索したほうが良いし、表示形式そのものを考え直す必要があります。

カテゴリー: 開発, MySQL | 6件のコメント

C#でMySQLをDataSetで扱う

射撃しつつ前進する方への援護射撃です。

群馬に行った時、データセットの件で「う~ん」と思い、なんとなく落とし穴に陥りそうな匂いはしていたのですが、時間が取れずにそのままに。

という訳で遅ればせながら、.NET(C#)でMySQLを扱うときのコツなんかを、詳しめに書いておきます。

■接続方法はADO.NET Driver for MySQL (Connector/NET)を使う

まず、.NETから扱えるように下記をダウンロードしてインストールします。

MySQL :: Download Connector/Net

http://www-jp.mysql.com/downloads/connector/net/

20100827_01.jpg

■名前空間は MySql.Data.MySqlClient

SQL Server の場合は System.Data.SqlClient を使いますが、MySQL の場合は MySql.Data.MySqlClient をインポートします。

C# だったら先頭の行に

using MySql.Data.MySqlClient;

でOK

■主なクラス

ADO.NET経由でSQL Serverを扱う場合は、

コネクション SqlConnect

アダプタ SqlDataAdapter

となっています。

これが MySQL の場合は

コネクション MySqlConnect

アダプタ MySqlDataAdapter

となればOK。

巷のADO.NETのサンプルもこれを書き換えれば大抵動きます。

肝心のDataSet、DataTable クラスに関しては、SQL Serverでも MySQL でも同じものを使います。最初のコネクションとアダプタの名前が違うだけです。使い方は統一されているので、クラス名だけ変えれば普通は通ります。

20100827_02.jpg

■サンプル

いわゆる、こんな画面を作ってデータ接続をテストすると場合

20100827_03.jpg

サンプルコードはこちら

// クリアボタン
    private void button1_Click(object sender, EventArgs e)
    {
        // 挿入時のクリア
        dataGridView1.Columns.Clear();
        // バインド時
        dataGridView1.DataSource = null;
    }

    // DataSetボタン
    private void button2_Click(object sender, EventArgs e)
    {
        // コネクション作成
        MySqlConnection cn = new MySqlConnection(
            “Data Source=localhost;Database=konicadb;User ID=konica;password=konica”);
        MySqlDataAdapter da = new MySqlDataAdapter(
            “SELECT * FROM sample”, cn);
        DataTable dt = new DataTable();
        // 検索
        da.Fill(dt);
        // 表示
        dataGridView1.DataSource = dt;
        // データ保持
        m_dt = dt;

    }
    ///
    /// データ保持用
    ///
    DataTable m_dt;

    // DataSet自前ボタン
    private void button3_Click(object sender, EventArgs e)
    {
        // コネクション作成
        MySqlConnection cn = new MySqlConnection(
            “Data Source=localhost;Database=konicadb;User ID=konica;password=konica”);
        MySqlDataAdapter da = new MySqlDataAdapter(
            “SELECT * FROM sample”, cn);
        DataTable dt = new DataTable();
        // 検索
        da.Fill(dt);
        // 自前で表示
        dataGridView1.Columns.Add(“ID”, “ID”);
        dataGridView1.Columns.Add(“name”, “名前”);
        foreach (DataRow item in dt.Rows)
        {
            int n = dataGridView1.Rows.Add();
            dataGridView1.Rows[n].Cells[0].Value = item["id"];
            dataGridView1.Rows[n].Cells[1].Value = item["name"];
        }
    }

    // 保存済みのDataSetボタン
    private void button4_Click(object sender, EventArgs e)
    {
        // 表示
        dataGridView1.DataSource = m_dt;
    }

    // LINQは動かせない
    private void button5_Click(object sender, EventArgs e)
    {
        // これはSQL Serverしかできない
        string cnstr = “Data Source=localhost;Database=konicadb;User ID=konica;password=konica”;
        DataContext dc = new DataContext(cnstr);
        var tb = dc.GetTable();
        dataGridView1.DataSource = tb;
    }

    [TableAttribute(Name = "sample")]
    public class TSample
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public DateTime UpdateDate { get; set; }
    }

データグリッドで表示するだけならば、DataSourceプロパティを使ったほうが簡単です。列名なんかが固定であれば、デザイン時に表示する文字列を入れて、バインドする列名を入れておけばOK。

DataSet(ここではDataTable)の使いどころは、保存済みのDataSetボタンのところのように、一度キープしたものをデータベースに接続せずに使えることですね。いわゆるキャッシュの役割です。

当然、DataSetに一時的に更新状態をキープして、一気にデータベースにコミット、という流れもできるんですが、型付きDataSetを作らないと効率的でないので、最初は避けたほうがよいかなと思っています。MySqlCommand を使って、ちまちま INSERT文やUPDATE文を書いたほうが、後々の見通しが良くなります(経験上ですが)。

■DataSetとは何ぞや?

という訳で、DataSetとは何ぞやを、もうちょっと。

最初にデータベース接続に関しては歴史的に、

– ODBC接続

– RDO,DAO,ADO

– ADO.NET, DataSet

– ADO.NET, 型付きDataSet

– LINQ to SQL

– ADO.NET Data Entity

な流れがあります。

ODBC接続は、SQL文を流してちまちまと受け取る方法ですね。Oracleで埋め込み型のPL/SQLを使っているとカーソルを使ったり、フェッチを使ったりとややこしいことこの上ないのですが、C言語からモロ扱えるしろものです。今でも結構やります。

これじゃあ、大変という訳でRDO,DAO,ADOなんてのが出来ました。

主にVBやExcel VBAから使っていたもので、接続する方法をCOM/ActiveXなんかで扱えるようになっています。VB6ぐらいにはお世話になったものです。VB6自体は本格的なオブジェクト指向言語ではない(一部、クラスが使えますが)ので、C++で作成したActiveXを使うという形で、「オブジェクト」を扱うん出うのです。

これを VC++で使っていたりしました。

この最終形のADO(ActiveX Data Objects)の.NET版が、ADO.NETです。

最初は、ADOの移植版という形。

その中でDataSetというのが、データキャッシュの役割を持ちます。

おそらく当時、ASP.NETを作った関係で、WEBサイトのキャッシュをする必要があってのDataSetかなぁ、と。

最初、DataSetは型がない(列名を持たない)ので、アクセスするときのパフォーマンスが落ちました。また、C#のような厳密にメンバを指定したい場合なんかは、文字列で列名を書くのはちょっと…な感じでした(Row[“name”]みたいなの)。

これを、Tsample.name のようにプロパティ名にしたいなぁ、と思ったのが型付きDataSetの始まりです。

この型付の話は、当時、データベースとオブジェクト指向を繋げるという意味で、「O/Rマッピング」と言われています。今では、この手の自動生成ツール(Ruby on Railsとか)が主流になりましたが、その最初の頃ってな感じです。

O/Rマッピングが流行って、データベースからクラスのコードを自動生成してくるのに慣れてくると、一方で SQL 文をプログラマが書かなくなったんですね。自前のデータアクセス方法を提案し始めたというところです。

それが、LINQであったり、という訳で、LINQ to SQL なんかがあります。

LINQ自体は、データベースに限らないのですが、まあ、関数言語の良いとこ取りな感じで。

一方で、ADO.NET Data Entity というのがあって、これがDataSetの正式な子供ですね。Visual Studio でデータベースに接続して、データクラスを自動生成してってやり方です。

このような流れの中で、MySQL は

– ADO.NET, 型付きDataSet

– LINQ to SQL

– ADO.NET Data Entity

のところが使えません。厳密には型付きDataSetは使えるのですが、ちまちまと自前で作らないといけないので、メンテ上非常に大変(それを上回る保守コストならば別ですが)。

なので、MySQL+.NETという組み合わせでは、MySQLのConnectorを使って DataSet/DataTable を使うのが定番かと思います。

■DataSetの使いどころ

MSさんの宣伝記事ならば、

DataSetで、複数のデータ更新ができるのでデータベースに直結せずに、全てのCRUD処理をDataSetを媒介したほうが効率が良い。

20100827_04.jpg

と言いたいところなのですが、現場レベルとしては、ちょっと困るところが出てきます。

1)複数のテーブルが連携しているときの処理が分かりずらい。

2)大量のデータを更新中に、DataSet内で止まってしまう。

のようなお困りが発生します。

1)のほうは、マスターテーブルのような単純なテーブルに関しては DataSet/DataTable を使うと非常に早く更新ができるので楽です。

ですが、他のテーブルのリレーションがあった場合、同時更新などで別のキーを参照する場合の時は、コミットする前の場合、DataSet内のテーブルを探らないと駄目なので、この処理が非常に面倒です。なので、この場合は、トランザクションを付けて、直接データベースにアクセスしたほうが楽にコーディングができます。

2)のほうは、致命的なところがあって、データ量が非常に多くなる(1万件など)場合は、DataSet自体のメモリが大きくなると同時に、更新時にいちいちデータのチェックが走るので、結構重たい処理になってしまいます。この更新処理をDataSet内部のコードを弄って、分割したりするよりは、素直に更新時は直接データベースにアクセスにしに行ったほうがすっきりしたコードが書けます。

という訳で、実際はこんな風に使います。

20100827_05.jpg

ええ、なんか見たことがある矢印の向きですよね。

20100827_06.jpg

こんな風に、MVCスタイルにするとコードが見やすくなります。

つまり、コントローラ部分を分離させた方が、コードの見通しが良くなる、という予想が立ちます(実際、そうなります)。

カテゴリー: 開発, MySQL | 6件のコメント

.NET(C#)でXML-RPCを使ってブログに投稿する

Moonmile Solutions Blog » .NET(C#)でRSSフィードを受信する
http://www.moonmile.net/blog/archives/1234

の続きで、今度は wordpress に投稿するAPI な話。

モノ的には、XML-RPC.Net
http://www.xml-rpc.net/

を使って、wordpress にコマンドラインから投稿ができるところまで作ります。

■xml-rpc.net をダウンロード&ビルド

最初に、http://www.xml-rpc.net/ から、ライブラリをダウロードします。現時点では、Version 2.4.0 ですね。

このzipファイルを解凍して、プロジェクトを見ると、xmlrpc なるプロジェクトがあるので、ビルドします。

ここで注意が必要なのは、そのままビルドしようとすると、

エラー 1 アセンブリ ‘D:\work\kidtwi\src\ReadRSS\xmlrpc\obj\Debug\CookComputing.XmlRpcV2.dll’ を署名しているときに暗号に失敗しました — ‘キー ファイル ‘..\CookComputing.key’ の読み込み中にエラーが発生しました — 指定されたファイルが見つかりません。 ‘ xmlrpc

のようなエラーが発生します。これは署名ファイルを探しているときにファイルがないというエラーなので、本来ならば署名ファイルを用意するべきなのですが、面倒なので、

AssemblyInfo.cs ファイルの該当箇所をコメントアウトします。

[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile(“..\\CookComputing.key”)]
[assembly: AssemblyKeyName(“”)]

これでビルドをすればOK。

対象のフレームワークは、ツールに合わせて「.NET Framework 4」などに変更すればよいでしょう。

■xmlrpcプロジェクトを参照設定する

ツール用のプロジェクトを作って、先のxmlrpcプロジェクトを参照設定します。

あるいは、できあがった CookComputing.XmlRpcV2.dll を参照設定します。

■xmlrpcプロジェクトを参照設定する

投稿時のコードの全文はこれです。

using CookComputing.XmlRpc;
namespace AutoPost
{
    class Program
    {
        static void Main(string[] args)
        {
            Program pg = new Program();
            // コンソールから取得
            string title = Console.In.ReadLine();
            string content = Console.In.ReadToEnd();
            // 投稿
            pg.BllogerNewPost(title, content);
        }

        // ユーザー名
        string username = “<ブログのユーザー名>”;
        // パスワード
        string password = “<ブログのパスワード>”;
        // 投稿先のURL
        string url = “<投稿先のURL>”;

        public void BllogerNewPost(string title, string content)
        {
            //プロキシクラスのインスタンスを作成
            IBlogger proxy = (IBlogger)
                CookComputing.XmlRpc.XmlRpcProxyGen.Create(
                typeof(IBlogger));
            //URLを指定
            proxy.Url = url;

            int id = 0;
            // content を生成
            content = string.Format(“<title>{0}</title>”, title)
                + string.Format(“<category>{0}</category>”, 3)
                + content;
            try
            {
                //blogger.getRecentPostsを呼び出す
                id = proxy.newPost(
                    “”,             // WordPressの場合は無視
                    “1”,            // 念のため1にしておく
                    username,
                    password,
                    content,
                    false);
            }
            catch (Exception ex)
            {
                Console.WriteLine(“エラー:” + ex.Message);
                return;
            }

            //結果を表示する
            Console.WriteLine(“id: ” + id);
        }

    public interface IBlogger : IXmlRpcProxy
    {
        /// <summary>
        /// 新規投稿
        /// </summary>
        /// <param name=”appkey”>無視</param>
        /// <param name=”blogid”>無視</param>
        /// <param name=”username”>ユーザー名</param>
        /// <param name=”password”>パスワード</param>
        /// <param name=”content”>本文</param>
        /// <param name=”publish”>公開するかどうか</param>
        /// <returns>エントリのIDを返す</returns>
        [XmlRpcMethod(“blogger.newPost”)]
        int newPost(
            string appkey,
            string blogid,
            string username,
            string password,
            string content,
            bool publish );
    }
}

キーポイントは、

  • プロキシクラスを作る(IBloggerのところ)
  • メソッドは、XmlRpcMethod で属性として指定する。
  • 実行時に、XmlRpcProxyGen クラスでプロキシを生成する。

XML-RPC で呼び出す時のメソッドは、XmlRpcMethod 属性で指定しますが、blogger api では、タイトルと本文を

<title>タイトル<title>本文…

な感じで書きます。

カテゴリも指定する場合は、

<title>タイトル<title><category>1</category>本文…

このように、カテゴリIDを指定します。

※ このカテゴリIDを取得するのが一苦労なんですよね……データベースを直接見るか、wordpressのapiを使ってリストを呼び出して調べるか、という方法になります。カテゴリの一覧を取得する方法は後日。

このソースでは、標準入力から投稿用のデータを入れています。

最初の一行目はタイトル
<p>二行目から本文を書きます。</p>
<p>そのまま投稿されるのでHTML形式で書いておきます。</p>
<ul>
<li>こんな風に
<li>箇条書きとかも書けますね。
</ul>

こういう形で、1行目はタイトル、続く2行目からは本文になります。本文は、そのまま表示されるのでHTML形式で書いておきます。

■投稿を実行する

実際に投稿をしてみると、

D:\work\kidtwi\src\ReadRSS\AutoPost\bin\Debug>AutoPost.exe  < post1.txt
id: 1279

こんな風に、投稿に成功したときには、IDを返してくれます。

■参照先

結構参考にしたので、並べておきます。

XML-RPCとは何ぞや?の話とかは、こちらをどうぞ。

[WordPress] XML-RPC を使用する方法 | Sun Limited Mt.
http://www.syuhari.jp/blog/archives/1373
MovableType で使える XML-RPC API
http://www.na.rim.or.jp/~tsupo/program/blogTool/mt_xmlRpc.html
XML-RPC wp ≪ WordPress Codex
http://codex.wordpress.org/XML-RPC_wp
どぼんさんのメールマガジン
http://dobon.net/vb/melma/dotnet74.txt

ここでは、wordpress を対象にしましたが、Blogger の場合は、Google からも API が提供されています。

Developer’s Guide: .NET – Blogger APIs – Google Code
http://code.google.com/intl/ja/apis/blogger/docs/2.0/developers_guide_dotnet.html

 

カテゴリー: 開発 | .NET(C#)でXML-RPCを使ってブログに投稿する はコメントを受け付けていません

Visual Studio LightSwitch ベータ版を試す

そんな訳で、LightSwitch 英語 ベータ版がダウンロードできるようになりました。

窓の杜 – 【NEWS】ビジネスアプリケーション開発環境「Visual Studio LightSwitch」ベータ版が公開
http://www.forest.impress.co.jp/docs/news/20100824_388969.html

MSDNのほうは、もうちょっと前からダウンロードできたそうなんですが、不覚ながら今日までノータッチ。

なので、早速インストール。

20100826_01.jpg

Visual Studio LightSwitch Edition という形になっていますが、おそらく Visual Studio 2010 Shell Edition 上に実装されていると思います。

.NET Framework 4 が必要なので、結構時間がかかります(再起動もあります)。

あらかじめ作成しておいたデータベースや、テーブルを使いながら、それに合った画面を自動作成するという、Ruby on Rails のようなスタイルです。

画面は、いわゆるCRUD型が用意されています。

それにデータベースのテーブルをバインドするだけなので、単純なテーブルならば、さっくりと入出力画面ができてしまいます。

20100826_02.jpg

画面は、Siverlight 4 のアウトブラウザが使われてます。勿論、ブラウザ上で動かすことも可能。

20100826_03.jpg

このあたりのレイアウトが、どれだけデザインできるのかが、普及の焦点になると思うのですが、ひとまず、利用できる範囲を考えてみると、

  • 単純なテーブル操作(CRUD)に留めた、マスターメンテに活用
  • いわゆるユーザー画面が、一般ユーザー向きではなく、メンテするときのSE向けかと。

Visual Studio での製作は、思ったより癖があります。

普通、ノンコーディングと言うと、データベースからのドラッグ&ドロップが思い浮かぶのですが(Visual Studio 2010 でのデータセットなど)、UI が旧来のドロップダウンから選択する、という方式なんですよね。

20100826_04.jpg

これは結構悩みます。

というのも、画面を作成するときのスタイルって

  1. どのテーブルを作成するのか決める。
  2. そのテーブルに対して、どのような操作をするか決める。

の手順で作ろうとします。この流れでいくと、

  1. データベースから、特定のテーブルを選択して、ドラッグ&ドロップする。
  2. テーブルに対して、CRUDの画面を決める。

の流れがいいんです。

ASP.NET MVC でも、こんな風に、

  1. 対象のビューコンテンツ(モデル)を選択する。
  2. ビューコンテンツに対して、どのようなCRUDを行うか、選択する。

の順に上から下へになっています。

20100826_05.jpg

ですが、LightSwtich の場合は、横になっているためか、左から右へと視線が移るので、

  1. CRUDのための画面を選択する。
  2. どのテーブルに対してなのかを選択する。

の逆順になってしまうんですよね。

まぁ、まだまだベータ版ということなので、UIの向上に期待、ということで。

そうそう、書き忘れるところでしたが、

LightSwitch

って

Lights Witch

のアナグラムでしょうか?

つまりは、ストライクウィッチーズ(ストパン)なのか?

20100826_08.jpg

とか、思ったり思わなかったり。期待したりしなかったりと。

まあ、Witches しか合ってないんだけどね。一応、Google 用に(笑)。

カテゴリー: 開発 | Visual Studio LightSwitch ベータ版を試す はコメントを受け付けていません

C#とVisual Basicのコードを相互変換

.NET言語では、C#とVisual Basicが主流なのですが(傍流ではF#もあります)、ネットに流れているサンプルコードは、C#だけだったり、時には Visual Basic だけだったりします。

分野としては、

  • Visual Basic は、UI 系のtips が多い
  • C# は、ライブラリ系のtips が多い

訳ですが、片方だけで使えて、片方では使えない、というものは、ほとんどありません(仕組み的に Visual Basic で書けて、C# で書けない、というスタイルもありますが)。

なので、片方のサンプルを見つけたら、自分の使い勝手のよい方にコンバートできると楽なのです。

以前は、SharpDevelop を使っていたのですが、最近は WEB 上で変換しています。

Convert C# to VB.NET – A free code conversion tool – developer Fusion
http://www.developerfusion.com/tools/convert/csharp-to-vb/

Convert VB.NET to C# – A free code conversion tool – developer Fusion
http://www.developerfusion.com/tools/convert/vb-to-csharp/

こんな風に、クラス全体を貼りつけて、Convert ボタンを押します。

20100825_08.jpg

すると、変換されたコードのできあがり。

20100825_09.jpg

.NET Framework 2.0 までしか対応していないそうなので、無名クラスなんかがうまくできませんが、大抵のコードは大丈夫です。LINQのコードも、きちんとコンバートできているので非常に便利です。

Python や Ruby にも変換できるようですが、どれだけ変換できるのかは分かりません。

 

 

カテゴリー: ツール | C#とVisual Basicのコードを相互変換 はコメントを受け付けていません

Java Update がうっとおしいので停止させる方法

多分、知っていると思うけど、自分用のメモです。

Java Update って、うっとおしいんですよね。Windows Update も、うっとおしいんですが、ま、これは簡単に止められるし。

さて、

Java Update は、元Sun(現Oracle)が配布している Java のアップデート状態をちまちま見ます。

Windows Update よりも無害なんですが( Windows Update は、業務マシンを停止させることがあるので、自動更新はしておりません)、起動時に出てくるダイアログがなんとも。

なので、これも停止させてしまいます。

  1. コマンドプロンプトで、msconfig を起動。
  2. システム構成から、「スタートアップ」タブを開いて、「Java(TM) Paltform SE Auto Update」のチェックを外す。

20100825_07.jpg

これで Java Update が起動しなくなるので、ダイアログがでなくなります。

Adoble とか Google とかも消してもいいですね。

 

 

カテゴリー: ツール | 2件のコメント

.NET(C#)でRSSフィードを受信する

アメブロのアレ関連でもありますが、海外(英語圏)のサイトをクロールして、まとめブログを作ろうかなと。

Google のクロール目当てなので、Wordpress で立てるだけで十分なので、

手順としては、

  1. 主要な英語圏のプログラム系ブログから、RSS を受信
  2. 適当にサマリを整形して、定期的にブログにアップ

を自動化させます。

英語圏のブログを集めるのは、Google のクロールに対応するためです。このブログもそうですが、英単語(コンピュータ系の用語)が入っているブログは、結構 Google からのアクセス数があります。まぁ、ロボットのアクセスがあったところで、どうということもないのですが、アメブロのアレをするためには、ロボットであってもアクセスがあるほうがいいので。

という訳で、定期的に2,000PV/日ぐらいあるサイトを作ります。

RSS で集めるときに、PHP で書いてもいいんですが、まぁ、.NET のクライアントを作ります。

.NET には、RSS フィードのクラスがあって、

System.ServiceModel.Syndication を参照設定します。

RSS 2.0/ATOM 1.0フィードを処理するには?[3.5、C#、VB]http://www.atmarkit.co.jp/fdotnet/dotnettips/753rssfeed/rssfeed.html

を参考にして、作ったのがこれ(ほとんど同じですが)。

class Program
{
    static void Main(string[] args)
    {
        if (args.Count() != 1)
        {
            Usage();
            return;
        }
        string url = args[0];

        using (XmlReader rd = XmlReader.Create(url))
        {
            SyndicationFeed feed = SyndicationFeed.Load(rd);
            Console.WriteLine(“題名: {0}”, feed.Title.Text);
            Console.WriteLine(“詳細: {0}”, feed.Description.Text);
            foreach (SyndicationItem item in feed.Items)
            {
                Console.WriteLine(“—“);
                Console.WriteLine(“件名: {0}”, item.Title.Text);
                Console.WriteLine(“日付: {0}”, item.PublishDate.ToString());
                Console.WriteLine(“内容: {0}”, item.Summary.Text);
            }
            Console.WriteLine(“—“);
        }

    }

    static void Usage()
    {
        Console.WriteLine(“ReadRSS [URL]”);
        Console.WriteLine(“URL: RSS配信のURL”);
        return;
    }
}

引数にURLを指定して、RSSフィールドを受信します。

これをバッチにするか、常駐プログラムにするかすればOKですね。RSSリーダーを作る気はないので、UIはどうでもいいのです。DBに入れるか、XML形式で保存するか、というところです。

もう一方のブログへのアップロードですが、XML-RPCを使うか、Atom Publishing を使います。どうやら、

XML-RPC.Net
http://www.xml-rpc.net/

のライブラリを使って、さっくりと WordPress にアップロードできれば、それで十分かも、と思っています。

で、

ふと思ったのですが、アップロードを自動にするのであれば、何も wordpress などを経由する必要はないんですよね。直接 HTML を吐き出して、ftp でアップロードする、バッチを書けばいいわけで…こっちのほうが私的には簡単そう。

wordpress を利用したほうが、デザイン面でテンプレートの流用ができるのですが、今回の目的は「アメブロのアレ」のためのサイトなので、人間に対するデザインは必要ありません。

まあ、電子書籍サイトの技術調査も含めて、XML-RPC.NET を使ってみますか。ちょっと思案。

 

 

カテゴリー: 開発 | .NET(C#)でRSSフィードを受信する はコメントを受け付けていません

アメブロのアレ(あるいは、アクセス解析な話)

ここ1か月ほど、「アメブロのアレ」と称してツイッター上で呟いていたのですが、それのおまとめ。

発端は、「アメブロのランキングを上げたいなぁ」なところで、アフリエイトとか、集客とか(あるい程度はありますが)、ではないので、あしからず。単純に、アクセス数を上げて、ランキングを(ある程度まで)上げる方法を模索しております。

さて、結論から言うと、1年程前の記事が正しいです。

【アメブロのPV水増し】アクセス解析ツールごとのアクセス数の違い【パシのSEOブログ】
http://www.jweb-seo.com/blog/wordpress/2009/04/30/629

アメブロのPVが界王拳並みな件 – カイ士伝
http://blogging.from.tv/wp/2009/04/29/2046

Google Analytics とアメブロのアクセス解析を比較しています。

Goolge のほうは、アメブロより非常に低くPV(Page View)が出ます。

というのも、Google のほうは、Google などのクローラのアクセス数はカウントしませんが、アメブロのほうはクローラのアクセス数もカウントするんですね。

「アクセス解析」自体が、何を以てPVとするか?の問題はさておき、Google とアメブロの「アクセス解析」では、根底のPVの勘定の仕方が異なる、ということです。

これを踏まえた上で、いくつか実験をすると、

■アメブロでは、1回アクセスすれば1つカウントされる

これは、Google からでも百度(パイドウ)からでも同じ。誰かがちょっと間違ってクリックしても、じっくり読んでも、ロボットがやってきても1回と勘定されます。

これは、RSSにアクセスしても、ブラウザでアクセスしても同じです。

更に云えば、

  • wgetやcUrlというツールを使って、アクセスするだけでも1つ増えます。

試しに、wgetで、5秒置きに100回アクセスすると、100アクセス分上乗せされました。

■アメブロのランキングは、PVが多ければ上位になれる

アメブロにもランキングがありますが、ランキングの表示の仕方として、

  • 1位から3位
  • 1位から10位
  • 1位から50位
  • 51位から100位

という見え方の違いがあります。

私が狙うのは、「1位から50位」のところ、50位以内というページですね。

方法によっては、1位から3位、1位から10位も十分狙えるのですが、ちょっとフェアでない「方法」なので、50位位にしておきます(苦笑)。

エンジニアランキング(2,500人程度)の場合は、4000PVで10位前後、700PVで50位以内、を目安に考えてください。

そのほかの母数が多いランキングは、もうちょっと別な手段を取らないと上位に食い込めません。

50位以内を狙うというのは、一言で云えば「弱者は弱者にやさしいかも」の作戦です。アメブロには「ぺた」という機能がありますが、トップ3の著者に対して見返りを期待するよりも、50位以内のほうが期待値が高いということです。「見返り」というのは、こちらのPVをアップさせてくれるかも、ということです。

50位以下の場合は、ランキングのページから見づらい(トップ10からアクセスしづらい)という点で、アクセスアップは望めません。なので、一気に、50位以内を狙って、徐々に安定化させるのがよいでしょう。

■wgetを廻すだけで、PVが増えて、ランクアップする

という訳で、wget で廻すだけでランキングのアップが期待できます。

方法は簡単です。50位以内が狙える、700PV分だけ廻してしまえばよいのです。

$url = ‘http://ameblo.jp/アメブロID/’;
for ( $i=0; $i<10; $i++ ) {
 `wget $url`;
 sleep(30);
}

こんな風に簡単な perl スクリプトを使って、ぐるぐる廻してしまうだけでPVがアップ、かつ、ランキングがアップできます。

■もう一工夫して、iframeを使う

wget の方法ですが、ちょっと難点があります。

1つだけのマシンからアクセスをするので、IPアドレスが同じなんですよね。なので、「アクセス者数」が少なくて、いっぺんにばれてしまいます。

# 運営サイドにばれるというか、自分以外は見れないので、どうでもいいんですが。

また、毎日 wget のスクリプトを廻さないといけないので、ちょっとむなしいですね。いえ、PVだけを自分で廻すという行為自体が「むなしい」のは、さておき(苦笑)。

アメブロ以外に、そこそこアクセスのあるブログを持っていれば、iframeを使うという方法があります。

ここのブログのソースを見ると、

<iframe src=”http://ameblo.jp/アメブロID/” width=”1″ height=”1″ scrolling=”no”>
</iframe>

な記述がありますね。

こうすることで、このブログのアクセス数を、そのままアメブロのアクセス数に加算することができます。

試してみると、都合よく、Google のクローラのアクセスもアメブロに加算してくれるので、結構簡単にアクセスアップができます。更に云えば、Google クローラの IP が使われるため、「アクセス者数」もアップするんですね。

ちなみに、自分のカウント用に、特定ページを設けておくと、二重帳簿の元ネタが分かるようになります。

■アメブロのペタはランキングに関係ない

さて、一般的にアメブロのランキングを上げるためには、

  • 読者を増やす
  • アメブロのペタをたくさん貰う

という話がありますが(運営サイドからも)、実験をすると関係ないことが分かります。

というのも、ペタのお返しをする自動ペタツールというのが結構ありまして、これはペタを直接打つんです。

問題は、アメブロのPVには、ルームの閲覧は加算されていない、ってことです。

これは、どういう事かというと、自動ペタツールを作ってみた分かったことなのですが、

  1. 自動ペタツールを使う。
  2. ルームから「ペタ」のリンクを辿る。
  3. ペタのページから、クリックをエミュレートする。

という方法でツールは成り立っています。

ここで、1や2のページは、PVにはカウントされません。故に、アクセス解析にも出ません。故に、ランキングに無関係なのです(今後の方針で変わるかもしれませんが)。

ということは、実は、

読者はペタを沢山増やしたとしても、ルームなどから直接ペタをしたときには、ランキングに貢献しない。

という結論になります。

きちんと、ブログを読んで、ペタをしている方には効果があるのですが、自動ツールはこのような問題(?)があります。

■更新回数を増やせばランキングがあがる

という訳で、アメブロの更新回数を単純に増やせば、ランキングは単純に上がります。

これは、

  1. 更新回数を増やす。
  2. Google のクローラがPVを増やす。
  3. PVが直接、ランキングに反映される。

という流れで、ランクが上がります。

なので、SEO対策としては、人相手ではなく Google のような機械相手にやればOKってことです。

~~

ちょっと長くなったので、効果的なアクセスアップの方法は後日。

今、私が取っている戦略としては、

  1. iframeで下駄を履かせて、50位以内にする。
  2. 50位以内をキープして、見返りを求める(ペタとか、でもランキングに関係ない)。
  3. 更新回数を徐々に増やす。
  4. 英単語、コンピュータ用語を交えて、アクセスアップ

なところです。

4ですが、Google のクローラと関係してくるところです。

 

カテゴリー: 雑談 | アメブロのアレ(あるいは、アクセス解析な話) はコメントを受け付けていません

粘菌コンピュータについて思考実験(2)

粘菌コンピュータの続きを20分ほど。

時間に関して決定的な解決ができる場合と、決定的でない解決の場合の2種類があるわけです。

数学的に言うと、

「発散」、「収束」がありますね。よくやる n を無限大にすると、収束する、という計算です。

nを無限大という条件自体は、時間である t を無限大にする、という計算にも置き換えられます。

さて、この数学的に収束する場合ですが、実は3種類あります。

発散と、収束と、振動ですね。

(「振動」だったかどうか、ちょっと覚えていないのですが、この用語は後で調べるとして)、

発散の場合は、t を無限大にしても、値が特定できないパターンです。

一般的な発散の式も当てはまりますが、複雑系のようなバタフライ効果も、これに当てはまります。

収束の場合は、逆に t を無限大にすると、ひとつの値に定まるパターンです。

これは、t が無限大という点で、無限時間ということになりますが、実際に計算するという事実とは離れて、「計算可能」という範囲で、値が定まる、というパターンも含めます。

これが示しているところは、

1/t の t → 無限大 は、容易に 0 と推測できます(あるいは、証明もできます)。

更に、

円周率 π は、一定の値である(発散しない)という計算も、求められます。

ご存じのとおり、π の値は、3.141592… と延々に続くわけですが、πという仮想的な値に定まる、ということは証明がつくわけです。

# 余談を云えば、10進数では、πの値は、3.14… になりますが、π進数では、1 ですね、という話です。

さて、もうひとつは、振動の例です。

この振動の例は、簡単なものがあって、

sin ( t ) の場合、t を無限大にした時は、どうなるかというと、不定 … いや、1から-1間に特定できます。

これは、発散とは違って、予測可能ではあるが、その時の値は特定できない、というパターンです。

予測可能であるが、その時刻には特定できない、ということは、無限大の時間空間の中で、ある時刻の値は特定できるが、ある時刻自体が非決定(あるいは、揺らぎがある)という場合には、値そのものは決定的ではない、ということを示し、かつ、おおざっぱなところでは比較的決定的であるという、少し不思議なパターンになります。

この例は、卑近なところでは、ニュートン力学と量子力学の関係になります。

例えば、

ボールを投げたときの着地点は、ニュートン力学において、決定的です。

ですが、空気抵抗などの揺らぎを考慮すると、量子力学的に、不定になります。

この狭間は、一見非連続に見えますが、実は連続的なものです。

非連続というのは、ニュートン力学から量子力学の分野の計算になった、という点で非連続的に見えるのですが、物体そのものが変化をしない(ボールという物体そのものは、観察者に関わらず、ひとつである … という仮定ではありますがw)、ので、物体という軸においては、連続的という訳です。

勿論、量子力学で学ぶ、「観察者」の存在は重々承知しているわけですが。

そんな訳で、

計算をしても発散してしまう問題。

計算をしていけば収束する(あるいは、数学的に収束が証明できる)

という分野とは別に、

計算していくけど、大ざっぱには求められるが、厳密には求められない、という量子力学風な(というのか、複雑系な)話がでてきます。

ああ、粘菌コンピュータの話になかなかつながりませんが、もう少しで辿り着く予定です。

 

 

カテゴリー: 雑談 | 粘菌コンピュータについて思考実験(2) はコメントを受け付けていません