ウィリアムのいたずらの、まちあるき、たべあるき

ウィリアムのいたずらが、街歩き、食べ物、音楽等の個人的見解を主に書くブログです(たま~にコンピューター関係も)

Google デベロッパー交流会 12月7日(5日まで申し込み延期されたらしい)

2007-11-30 22:52:13 | Weblog

Google デベロッパー交流会っていうのがあるんだって。
【締切延長】 デベロッパー交流会に参加し
てみませんか?
http://groups.google.co.jp/group/developer-round-table/browse_thread/thread/2e144dc3ed78127?hl=ja

によると(以下斜体は上記サイトより引用)


「Google Code ディスカッション グループ」に登録された皆様にご案内です。 


12月7日(金)に開催予定のデベロッパー交流会に本グループの登録者の中から 
150名様を ご招待します。 


  パネリストとGoogleエンジニアによるディスカッションに加え、Google Gearsについての 
  最新プレゼンテーションも行います。ご興味のある方はぜひご観覧をご応募ください 


     ///// 12月開催 デベロッパー交流会概要 ///// 


      開催日時 : 2007年12月7日(金) 13時開場 
      開催場所 : 東京コンファレンスセンター・品川 
      アジェンダ : 
          13:00-13:30 受付 
     13:30-14:15 Google Gears プレゼンテーション 
     14:15-14:30 休憩 
     14:30-15:15 パネルディスカッション 
     15:15-15:30 休憩 
     15:30-16:15 パネルディスカッション 



だそうな。申込期間を延期して12月5日までになったらしい。
なので、今、申し込める。
上記のサイトに、(上の文の下に続いて)申し込むところがある・・・

けど・・

一番書き出しに書いてあるように、「Google Code ディスカッション グループ」に入らないと(って登録すれば入れるんだけど)これに申し込めない。
それに入るのにも、上記の申し込むところからいける(申し込み用紙が出てきて

※応募には「Google Code ディスカッション グループ」への登録が必要です

と書いてあるところからいけると思った・・たしか・・

ほうこくおわり


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

暗号技術を外国人に教えたら、記録残さなきゃいけないの??CGは??

2007-11-30 19:35:31 | Weblog

ここのスラッシュドットニュース
外国人への軍事転用可能な技術の提供、企業に記録を義務付けへ
http://slashdot.jp/articles/07/11/29/1425258.shtml

なんだけど(以下斜体は上記サイトより引用)


このニュースは、隣国の話ではなく、日本の話だ。 日経新聞の記事によると、経済産業省が軍事転用可能な技術の海外流出を防ぐという名目で次のような趣旨の政策を計画している。

・企業や大学に対し、所属する技術者が外国人に技術情報を提供する際、記録を残すよう義務化
・海外に移住した技術者にも外部に技術情報を提供する場合は、一定の期間を定めて政府に事前申請するよう義務付ける
・無許可の技術提供や輸出に対する罰則を強化
・外国為替法改正を視野に来年中の制度整備を目指す


軍事転用可能な技術って言ったら、暗号とかそうだよねえ。。
暗号の授業をするときは、全部記録を残すの?
いや、大学の講義なら、テープとっちゃえ(^^)っていうのはできるけど、
大学院の指導内容・・とかもお??


でもこれ、CGとかも、シュミレーションに使えるとかいいだしたら、
きりないようにおもうんですけどお・・

P.S 日本のAさんが、アメリカのプロバイダBから、
  インターネットで暗号技術講座をストリーム配信した場合は?
  (中国のCさんに向けて)

  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

グーグルケータイOS、androidのお勉強(4)-データベースアクセス部分。

2007-11-30 13:06:46 | ケータイ

シリーズグーグルケータイOS、androidのお勉強、前回は、チュートリアルのStep1に相当する、サンプルプログラムをダウンロードしてくるところをやりました。

 ということで、今回はStep2に相当する、データベースアクセス部分です。。





■データベース操作―DBHelper

 このまえのノートパッドの例のなかに、すでに、データベース部分はコーディングされているようです。それをみて、お勉強してみましょう。
 DB操作を行うクラスは、DBHelperですので、プロジェクトのなかのsrcの下の、パッケージcom.google.android.demo.notepad1にある、DBHelper.javaをみます。

メソッドからすると、以下のことをやっているようです。

●コンストラクタ=生成
  引数のコンテキスト(ctx)からctx.openDatabase(データベース名、null)で
  データベースをオープン、

  オープンできないときは、
    ctx.createDatabaseでデータベース作成
    db.execSQL("Create Table文");
  でテーブル作成

●挿入(createRow)
  ContentValuesで値の組(レコード)がはいるところを生成
  ContentValuesのオブジェクトのput(項目名、引数)でレコードに値設定
  db.insertでそのレコードをテーブルに挿入

●行削除(deleteRow)
  db.deleteで引数にIDを指定して削除

●全行取得(fetchAllRows)
 db.queryで検索して、その結果をCursorクラスにいれる
 このカーソルはc.first()で最初の行、
        c.next()で次の行、
        c.count()で全部の行数
        c.getLong(pos)で現在さしている行のpos番目の項目(先頭0)の値
        c.getString(pos)で現在さしている行のpos番目の項目(先頭0)の値
になるので(getLong、getStringは返す値により、よきにはからう)、適当に操作する

●1行取得(fetchRow)
 db.queryの指定IDの行の検索結果をかえす。
 カーソルからの値取り出しは全行取得と同様

●更新(updateRow)
  ContentValuesで値の組(レコード)がはいるところを生成
  ContentValuesのオブジェクトのput(項目名、引数)でレコードに更新する値設定
  db.updateでその値を更新(更新先のIDを指定する)

●クローズ
  db.close()する




■ということで・・・

 操作手順は、
(1)DBHelperクラスを生成する
(2)上記の、全行検索、行検索、更新、削除、挿入のメソッドを呼び出し、
   お好きなように・・・
(3)クローズをよびだしてとじる

というかんじでしょうか。。

ちなみに、上記の中で書いたdbというクラスは、
android.database.sqlite.SQLiteDatabaseに説明があり、
カーソルは、android.database.Cursorに説明があり、
値をセットしたContentValuesは、android.content.ContentValuesにあり、
生成時の引数のContextは、android.content.Contextにある




ということで、データベースぶぶんの説明おわり
Step2もおしまいということで、つぎからStep3




  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

みっくみくぷろぐらみんぐ

2007-11-29 22:25:49 | Weblog

初音ミクのフィギアを(趣味で?)作った人がいるみたいっていうはなしは、前に書いたけど、今度は、初音ミクの売り物のフィギア??が大人気だそうな。

ここのニュース
初音ミクフィギュアに予約殺到 2日で1万突破の「異常なペース」
http://www.itmedia.co.jp/news/articles/0711/27/news111.html


ちなみに、その「ねんどろいど 初音ミク」のAmazonでの予約販売っていうのは、
こちら 
ねんどろいど 初音ミク (ノンスケール ABS/PVC塗装済み可動フィギュア)
http://www.amazon.co.jp/exec/obidos/ASIN/B000ZGMF8O/kimagureeigan-22/ref=nosim/

ねぎもってるのとか、かわいいよね(^^)

うーん、まえに、
ベアプログラミング(ぺじゃないよ、熊のベアーのベアプログラミング)。っていうのを書いたけど、日本では「みっくみくぷろぐらみんぐ」になりそうですな。

 初音ミクのフィギアを机の上においておいて、
 「まず、初音ミクに相談しろ!そのあと、それでもわかんなかったら、聞きに来い」
 ってなかんじ(^^)


。。。なことに、なるわけねーか(^^;)


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

オブジェクト指向で開発の最初から最後までの手順例-その37:雛形(10)

2007-11-29 18:23:28 | 開発ネタ

オブジェクト指向でやる場合の最初から最後までの流れを、実際の例を挙げて書いていくシリーズ「オブジェクト指向で開発の最初から最後までの手順例」

 現在、「いままでのまとめ」にある、「(4)フレームワークにもとづき、クラスなどの開発手順、雛形の確定」をやっています。

 で、その雛形など、作らなきゃいけないものとして、大きく分けて、

  1.画面
  2.コントローラー
  3.モデル部分
  4.DBアクセス部分

とあり、前回までで「3.モデル部分」の説明がおわったので(下から順にやってます)今回は「2.コントローラー」の概要です。




■コントローラーとしてのサーブレット

 今回のシステムでは、

・クライアント側はAJAX
  →POSTまたはGETで引数を送信

・サーブレットが、
   ・データを受け取り
   ・モデルを起動、引数セット
   ・引数を受け取って、XMLとして書き出し

・クライアント側のAJAXでは、そのXMLを読み込み、次画面表示

というようにします。ここで、ビューは、AJAXになり、モデルは、サーバーにあるモデル(いままでつくったやつ)です。

 ということで、Viewから値を受け取り、モデルを起動、その値を受け取ってビューに返すコントローラー部分は、サーブレットってことになります。




■コントロール(サーブレット)の機能

 ということで、そのサーブレットの機能です。
 さっき
   ・データを受け取り
   ・モデルを起動、引数セット
   ・引数を受け取って、XMLとして書き出し
 と書きましたが、詳しく書くと、こんなかんじです。


・データを受け取る→ハッシュマップに入れときます
   画面からの引数の受け取り
   セッションのデータ受け取り

・モデルを生成し、モデルの該当メソッドを起動します
   →場合によっては、ここでトランザクションを発生、
    コミットすることもあります。

・値を返す
   セッションへのデータセット
   XMLで、値を返す


というかんじです。




次回から、具体的に、上記の内容のプログラムを書いていきたいと思います。



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

JavaでMacアドレスを取得する方法

2007-11-29 14:41:01 | JavaとWeb

 メルマガ用に、自分へのメモメモ

 JavaでMacアドレスを取得する方法について、書いてあるページ

ここ
2006年 1月 19日 木曜日
今日のAPI: JavaからネットワークカードのMACアドレスを取得する

にやり方が書いてあって、

ここ
クラス NetworkInterface
http://java.sun.com/javase/ja/6/docs/ja/api/java/net/NetworkInterface.html


に、その取得するときに使うクラス、java.net.NetworkInterfaceがある。

(メソッド java.net.NetworkInterface#getHardwareAddress() を使う)



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

社長もリーダーも技術がわからないと、そのような会社は出来る-特別ではない

2007-11-29 13:57:13 | Weblog

ここのブログ
ブラック会社に勤めてるんだが、もう俺は限界かもしれない
http://urasoku.blog106.fc2.com/blog-entry-217.html

が話題らしい。

内容は、
・新入社員1日目に、納期2週間、VBとC#(画面がHTMLなんだって)の開発
・リーダーは、なにいってもだめ
・出来る人は朝の3時帰社
・1人わかんないのが、いじめられてる(上原さん?)
・たいこもちがいる。

で、これのコメントに、「こんなにひどいのか?」ってありますけど、
結構あります。




以下のような会社の構造だと、そうなります。

・社長はお人よしだが、最近の技術は分からない

・なので、仕事を取ってきてしまう

・リーダーも最近の仕事はわからない。
 →文系、理系の話にかこつけているひとがいたけど、まったく関係ない
   理系でコンピューター専門でも、今の開発に追いついていけるわけではない。
   極論で言うと、理系でも、10年前は2週間かけて言語を覚えたとしたら
   早いといわれた。
   今は、上記のように、納期2週間先で、知らない言語で併記で仕事を取ってくる
   文系理系より、ストレートな頭の良さのほうが重要。

・会社に分かる人が1人だけいる。

こうなると、上記のような会社ができます。




こんなかんじです。

・社長は技術的にわかんないので、面白そうだと仕事を取ってくる

・リーダーの人はその仕事をこなす能力はないので、下にふる
 →たんに、「できたか」と聞くだけしか出来ない。
  30台くらいで、勉強してないで、仕事だけやってると、こうなる。
  昔といまで、開発方法論も、求められる学力、頭の良さも全然違うから。

・残りの人間は、易しい仕事をとってきた、リーダーのたいこもちか、
 全然分からないいけにえの人。
 中間の人は、やめてしまう。

・だから、仕事は肝心な部分をのこして、先に進まない。
 新入社員が来ても、上の人は説明できないので、
 なにもできず、プレッシャーだけ感じ、
 結局、すぐにやめてしまうので、仕事だけのこる

・結果、仕事だけのこり、納期目前になるが
 リーダーは技術的にどうしたらいいか分からない。
 そこで、人手が足りないという
 (人が来ても技術がわかんないから、指導できないので、解決にはなってないが)

 でも、求人募集をしても、ある程度分かっているやつは、
 こりゃだめだとおもって、すぐにやめる。

 なので、結局、人をとる場合、未経験者可にしてしまう
 →ここまでしないと人が来ない

っていうパターンだと思う。

 リーダーが忙しそうなのは、結局、技術力がないから(っていうより、ストレートに頭が悪い場合も多い)仕事がこなせない。なので、忙しいケースが多い。




この手のタイプは、結構多いと思うよ。

昔と違って、頭に自信があるからこの業界に来たというより、コンピューターがすき!とか、ひどい場合は将来性がありそうだから(=>ない!って)っていう理由で来る人もいるので・・


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

ベアプログラミング(ぺじゃないよ、熊のベアーのベアプログラミング)。

2007-11-28 22:56:36 | Weblog

ペア(pair)プログラミングは、うーんって思ったけど、
ベア(bear)プログラミングは、ありかも!

ここの記事
ペアプログラミング、実践してますか?
http://slashdot.jp/askslashdot/07/11/26/2234227.shtml

のコメントにあるんだけど(以下斜体は上記サイトのコメントより引用)

えっと「ベアプログラミング」って言っちゃうとジョークか何かと思われそうですが、
質問責めに辟易した著者が「まずこのぬいぐるみに相談しろ。それでも解決しなかった時には聞きに来い」ってやったら、実際に質問に来る人の数が減ったって話ですね。
オカルトでもジョークでもなく「相談するためには状況を整理する必要があるが、その過程で問題点が見つかり解決するというのはよくあること」って話。


これ、いえそうな気がする。
効果大きいかも。。



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

グーグルケータイOS、androidのお勉強(3)-サンプルのプロジェクトを作る

2007-11-28 17:39:52 | Weblog

 前回のグーグルケータイOS、androidのお勉強で、チュートリアルのサンプルプログラムをダウンロードしてきて、そのあと、そこに入っているNotepadv1について


Notepadv1のプロジェクトをeclipse上に作ります。

 作り方は、ここのやりかたでOKのはずです・・
グーグルケータイOS Androidのインストール(3)サンプルの実行
http://blog.goo.ne.jp/xmldtp/e/2d016981f3b9b3b3dfa44230a5757633
(ロケーションとかは、当然、今回用に変えてください)


と書いたのですが、意外とすんなりとできないので、
実際にプロジェクトを作るまでの手順をかいておきます。




(1)ダウンロードしてきたファイルは、
C:/android_sdk/samples/

の下に、解凍した物を置いて、サンプルのフォルダが、
C:/android_sdk/samples/NotepadCodeLab/Notepadv1
になるようにしました。

 これ以外のところにおいてもかまいませんが、その場合、(5)のところで
指定するロケーションが変わります。

(2)まず、eclipseを立ち上げます

(3)そしたら、以下のように、メニューバーから

  ファイル→にゅー→プロジェクト

を選択


(4)以下のダイアログが出てくるので、
  あんどろいど→あんどろいどぷろじぇくと
 を選択して「ねくすと」ボタンをクリック


(5)以下のダイアログになる。
  Contentsを下をえらび、Locationに(1)のところを指定すると、
ProjectやPropertiesがはいる。そしたらFinish


(6)以下のダイアログが出て、この時点ではエラーになるが無視
 →ここがむずかしいところ


(7)インストールしたNotepadv1を選択した状態で、
   プロジェクト→クリアを選択


(8)そうすると、以下のようなダイアログが出る。
Notepadv1を選択(他は別にいい)してOK


(9)おなじく、Notepadv1を選択した状態で、
  らん→らんを選択


(10)以下のダイアログが出たら、
  あんどろいどあぷりけーしょん
 を選択してOK


(11)ここで、もし、シミュレーターが立ち上がっても、
 ホーム(山の写真みたいなの)しかでなかったら、
 (9)と(10)を繰り返す

(12)そーすると、以下のようながめんになるはずです。


ここでプロジェクトができました&それを確認しました。




ということで、やっとプロジェクトができました・・

が、長くなりすぎたので、このへんで



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

JUnitにおける、事前条件、事後条件の自動生成とチェック

2007-11-28 14:23:35 | 開発ネタ

 先ほどの再度、JUnitな単体テストにおける、事前条件・事後条件・不変表明の考え方の話だと、

事前条件:入力となる対象全部の値が、その関数が動く範囲にはいっているか
     対象:・引数
        ・外部変数、共有メモリ
        ・ファイルやDB,通信内容

     チェック内容:・値の範囲・種別
            ・値の間で満たすべき条件(関係)
            ・このプログラムが起動するために満たすべき条件

事後条件:出力となる対象全部の値が、要求を満たした結果になっているか
     対象:・返り値
        ・外部変数、共有メモリ
        ・ファイルやDB,通信内容

     チェック内容:・値の範囲に入っている
            ・この処理を行ったらなるべき結果になっている
            ・値の間で満たすべき条件(関係)


ということになったのですが(不変表明は、事前条件、事後条件の両方で不変であることを調べることにより、実現するものとします。この場合、事前条件、事後条件の中に吸収されてしまいます)、これをやると、たいへんそうです。

ということで、JUnitでこのことがチェックでき、かつ事前・事後条件を、仕様書から自動生成できることを考えます。




■JUnitの場合の事前条件・事後条件確認方法

 JUnitにおいて、たとえば、さっき(前のエントリ)の受注だったとしたら、Zyutyuクラスのaddメソッドで受注の処理をするモノに対するチェックは、
ZyutyuTest.javaを作って、

import junit.framework.TestCase;
import java.util.*;

public class ZyutyuTest extends TestCase {

	/*
	 * コンストラクタが必要になります
	 */
	public ZyutyuTest(String arg0)
	{
		super(arg0);
	}
	
	/*
	 * メソッド名のはじめを大文字にして、
	 * testをつけたメソッドがテストメソッドです
	 */
	 public void testAdd()
	 {

		Zyutyu zyutyu = new Zyutyu();
		HashMap map = new HashMap();

		//	事前条件を
	 	//	assertでたしかめたうえで、ハッシュマップにセット
		//	:
		//	: (つづく)

		//	処理する
		ret = zyutyu.add(map);

		//	事後条件を
		//	assertでたしかめる
		assertEquals(0,ret);
		//	:
		//	: (つづく)
	 }
}


こんなかんじで、事前条件である、入力値をassertで確認しておき、
処理した後に、事後条件もassertで確認することとします。
問題は、この事前条件、事後条件のところのassertを書く方法ということになります。




■事前条件・事後条件の自動生成方法

 事前条件・事後条件を自動生成するためには、

事前条件
・入力値となる値が、メソッドの定義書(仕様書)に定義されている
・入力する画面項目の妥当性(範囲など)が、画面定義書に記載されている
・入力するテーブル項目の妥当性(範囲など)が、テーブル定義書に記載されている
・入力するテーブル間の関係が、どこかに記載されている(普通ER図だけど・・)

そして、これらが、自動生成できる形になっている
(つまり、上記の仕様書がExcelとかにあって、assertの文に落とせる)

事後条件
・結果が入力値を利用して、出力値がどうなるか、メソッド定義書(仕様書)
 に定義されている
・返り値の結果がメソッド定義書(仕様書)に定義されている
・出力画面項目の妥当性(範囲など)が、画面定義書に記載されている
・出力するテーブル項目の妥当性(範囲など)が、テーブル定義書に記載されている
・出力するテーブル間の関係が、どこかに記載されている(普通ER図だけど・・)

そして、これらが、自動生成できる形になっている
(つまり、上記の仕様書がExcelとかにあって、assertの文に落とせる)




具体的に例をしめせばいいんだろうけど、
そーしてると、本来の「プログラム検証論」をよんでいる暇がなくなってしまうので、
このへんにしておきます。



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

再度、JUnitな単体テストにおける、事前条件・事後条件・不変表明の考え方

2007-11-28 12:18:06 | Weblog

 きのうの話の続きで、この後の話のつなぎの話。

 じゃあ、普通の業務において、JUnitで単体テストをする場合、事前条件・事後条件・不変表明をどのように考えればいいかという話になってくる。

 この場合、仕様を出した人は、「要求を満たす」ばよいのであれば、(要求を出した人からみたら)、そのプログラムの中身は、どーでもよくて、ちゃんと、入力値をいれたら、期待する出力値を返せばよい。

 つまり、事前条件を満たす任意の入力を入れたときに、期待する結果になれば、関数の中身はどうでもいい(Y=X+1でも、Y=X;Y++;でも、どっちでもいい)=>関数の外延性っていう話になってくる。

ということは、

事前条件:入力となる対象全部の値が、その関数が動く範囲にはいっているか
     対象:・引数
        ・外部変数、共有メモリ
        ・ファイルやDB,通信内容

     チェック内容:・値の範囲・種別
              →文字は漢字のみ(半角カタカナ禁止)など
            ・値の間で満たすべき条件(関係)
            ・このプログラムが起動するために満たすべき条件
              →ステータスが3または5のとき動くなど

事後条件:出力となる対象全部の値が、要求を満たした結果になっているか
     対象:・返り値
        ・外部変数、共有メモリ
        ・ファイルやDB,通信内容

     チェック内容:・値の範囲に入っている
            ・この処理を行ったらなるべき結果になっている
            ・値の間で満たすべき条件(関係)

ということになる。
でも、ここで、
「・値の間で満たすべき条件(関係)」っていうのがあるけど、この関係は、事前でも事後でも、処理中でも決まっているわけで、この条件は常に(普遍的に)満たさないとまずい。

ということは、
不変表明として、
・利用する変数間で、満たすべき関係を満たしているか?

っていうことをチェックすればいいことになるんじゃないかな。




 たとえば、受注プログラムを考える。

 受注プログラムは、
・受注画面の変数(いっぱいあるけど、まとめてzyutyu_g.*とあらわす)
・商品マスタデータ(いっぱいあるけど、まとめてsho_tbl.*とあらわす)
・得意先マスタデータ(いっぱいあるけど、まとめてtok_tbl.*とあらわす)

を入力として

・OKかNGを返し
・受注テーブルを書き出し(いっぱいあるけど、まとめてzyu_tbl.*とあらわす)

すればよい。

ということは、事前条件は、
該当するzyutyu_g.*、sho_tbl.*、tok_tbl.*に関して、
・それぞれの値が範囲内か?
・関連を満たしているか(zyutyu_g.画面商品名∈sho_tbl.商品名)
           (zyutyu_g.得意先名∈sho_tbl.得意先名)
 (名前じゃなくってコードかも?)
・このプログラムが動く条件=文脈に依存しないかな?


になって、事後条件は、
該当するzyu_tbl.*と返り値が
・範囲内か?
  →zyu_tblのある項目が初期化されてなくてとんでもない値とかなーい?
・期待する処理内容を満たしているか
  →zyu_tblに、当該レコードが作成され、
    zyutyu_g.商品数量=zyu_tblの当該レコードの.商品数量

ということになる。そしてここで、不変条件は、
入力、出力項目(商品、得意先、受注テーブル)がそれぞれ満たすこと
・たとえば、受注テーブルの受注IDはダブりがない。
とか、項目間で満たすこと
・受注テーブルの商品ID∈商品テーブルの商品ID
とかになってくると思う




 だけど、これをチェックしたら、ものすごいことになると思うんですけど・・

 っていうことで、次には、JUnitの事前条件、事後条件、不変表明などの自動化について考えたいと思います。


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

JUnitは単体テストであるという論理的証明と現実的否定 その2

2007-11-27 15:53:18 | 開発ネタ

 さっき書いた、JUnitは単体テストであるという論理的証明と現実的否定についてですが、

さっきの結論としては、

 ホーア論理にのっとって、
   事前条件、
   事後条件、
   不変表明
を適切にとれば、プログラムの正しさが、検証条件の正しさに還元されるので、
検証が正しければ、そのユニット内のプログラムは正しいといえる。つまり、ユニットテストを行ったといえる。

ということになった。

ということは逆に言うと、ホーア論理が成立しないような状況では、無理!っていうことになる。この場合について、まあ、ちょっと思いつくものを挙げてみる。




■そもそも、再帰の場合、事前とか事後。。??

 ホーア論理は、「Clarkeの不完全性定理」っていうので成り立たないっていうことがあるらしいが、そのとき、使われるらしい、再帰について・・
 再帰されてしまうと、それ以前に、何が事後で、何が事前なんだ(^^;)っていう感じになってしまうような気が・・・
 それに、あとの話になってくるんだけど、停止性の問題が出てくると思うし。。

 ただ、業務の場合、再帰させないプログラム(繰り返しで済むプログラム)は多いので。。。




■停止性の問題

 while(1)などと書いてしまい、停止しないと、事後条件が成立しない・・・

 というか、無限ループになったら、普通バグだ(^^;)

 停止性を保障するには、停止条件(JavaやCのfor文の;で区切られた2番目のところ)が成立すればいい。
 だけど、この停止条件を使う値を書き換えてしまったら??

for(int i = 0 ; i < 配列 strのサイズ分 ; i ++ )
{
   if ( str[i] == 漢字1バイト目だったら )
   {
     i--;  // i ++ の書き間違い
   }
   //  なんかしょり
}

 とかやってしまっては、文字の並びによっては、永遠に終わらない
 (漢字1バイト目だと、前の文字に戻され、forの3つ目で++され、
  漢字1バイト目に、そーすると、ifの頭にきて。。。)

 このように、停止条件にかかわる変数が、書き換えられてしまう場合、永遠に終わらなくなってしまい、事後条件もなにも、調べられない。

 これって、結構ある気がする。つまり

   ・while(1)などとかいてしまう
   ・停止条件にかかわる変数をプロセス内で書き換えてしまう。




■事後条件とか、「そんなのかんけーねー」っていうので、goto文をかく

 いまやもう、こういうgoto文を使う人はいないと思うけど、
 事後条件とか関係なく、
 goto文で、事後条件にぬけずに、プロセスの先頭に無理やり移動させてしまう
 (もちろんある条件では終了させないと無限ループになっちゃうので、抜けると思うけど)

 つまり、事前条件があって、それが成立するとき事後条件というわけで、この順番を変えてしまうようなことや、永遠と事後条件が来ないようにしてしまうと・・・




ただ、ここで問題になるのは、2番目の停止性の問題くらいじゃないかなあ・・・
他にもあるかもしんないけど。。

っていうことは、なんか、適当なコーディング規約+適切な事前事後条件と不変表明を作れば、JUnitでのテストとユニットテストの等価性は保障されると思う。

 だけど、Junitの本って、この辺が書いてなくて、表明いれて、緑にすればOKみたいに書いてない??そーいう意識では、ユニットテストをやったことは保障されない気がする・・・けど、どーなのどーなの(^^;)?



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

JUnitは単体テストであるという論理的証明と現実的否定。

2007-11-27 10:59:16 | 開発ネタ

 今お勉強している「プログラム検証論」を読んで思ったことを書いて見たいと思います。ウィリアムのいたずらが読んでお勉強したての内容なんで、思いっきり間違ってるかもしれませんよ(^^;)

 それに、今3章読んでいる最中なんで、後の章に行ったら否定するかも。

 では、以下内容です。




 よく、JUnitは単体テストをやっているといわれる。
 そりゃーそです。JUnitのJはJava,UnitはUnit Test=単体テストを意味しますから。

 しかし、JUnitがやっているテストと、一般に言われる単体テスト、すなわち、条件網羅、命令網羅などを行い、その網羅率を元にテスト状況を判断するホワイトボックステストを前提としたテストとは、異なっています。

 ということは、JUnitが行う表明によって、これらのホワイトボックステストと同等だということを数学的に証明しないといけません。そうでないと、JUnitのやっている行為は、結合テストになってしまいます(assertionを、プログラムに1行1行入れるのであれば、たしかにホワイトボックステストと同等になりますが、そうでなく、初めと終わりに入れるだけでは、結合と、大して変わりはありません)。




 ということで、今回と、(このシリーズの)次回の2回にわけて
(1)ある条件下においてJUnitは単体テストであるということを
   数学的に、このように証明できそうという論理的証明っぽい話と

(2)しかし、その条件は成立していないから、JUnitをやっても、
   単体テストを行ったことにはならない(その条件に基づいた
   バグはのこる=これが致命傷になる可能性大)という
   現実的な否定の話

を書こうと思います。

今回は(1)の数学的証明の話。




■JUnitのテスト内容

 JUnitにおいて、テストしている内容は、

  ・事前条件
  ・事後条件
  ・クラス不変表明

をチェックしています。
(これをassertionとして、入れています)

 つまり、一連のプログラムにおいて、適切な
  ・事前条件
  ・事後条件
  ・クラス不変表明
 を設定し、その条件を満たせば、一連のプログラムは正しい
 という、「プログラムの正しさを検証条件の正しさに還元」すればいいわけです。




■ホーア論理による証明

「プログラムの正しさを検証条件の正しさに還元」の言葉は、実は「プログラム検証論」の45ページ3行目から引用したものなのです。つまり、”ある範囲において”、このことは、ホーア論理により証明できます。

 ホーア論理におけるプログラムの正当性の証明は、「プログラム検証論」の38ページの囲みにあるように、代入公理(=代入文)と、帰結規則(AならばB)以外の推論規則の前条件と後条件を検証条件とすればいい。
 そうすると、プログラムの正しさは、検証条件の正しさに帰結するというお話だ。

 このとき、一連のプログラム(メソッド、自分が作った関数など)において、その関数に入る前を事前条件、プログラムが終わったときを事後条件、プログラム内における前条件、後条件を不変表明と、適当に取れば、ホーア論理により、プログラムの正当性は証明されたように見える。




■JUnitと契約による設計とホーア論理

 で、昨日書いたように、JUnitは、契約による設計に基づいていて、ここの事前条件、事後条件、不変表明は、たぶん、上記のホーア論理の前条件、後条件の話のことだと思う(オブジェクト指向入門とかをみてないので、確認したわけじゃないけど)

 ってすると、結論は、以下のとおりとなる。

 ホーア論理にのっとって、事前条件、事後条件、不変表明を適切にとれば、
 プログラムの正しさが、検証条件の正しさに還元されるので、

 検証条件が正しく設定され、その結果が正しければ、そのユニット内のプログラムは正しいといえる。つまり、ユニットテストを行ったといえる。
(JUnitのユニットテストは、一般の単体テストに相当するといってよい)




■次回予告

 ということで、JUnitのassertionによるテストをやることと、一般のテストにおける単体テストとの等価性を示したわけですが、これは、「ホーア論理が満たされれば」ということになります。

 次回は、現実的には、これは、コーディング規約によって制約をつけないとできないし、その制約は、結構簡単に破られてしまうので(意識しないと)JUnitのテストは、一般の単体テストとは等価にならないという現実的否定を書きたいと思います。

 ちなみに、Clarkeの不完全性定理を応用?して、再帰プログラムについてと、ホーア理論のwhileにおける停止性に関するループの問題について、考えてみたいと思います。





  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

24金のiPod classicだって!

2007-11-26 22:48:06 | Weblog

ここの記事
純度が高すぎる、金のiPod classic
http://www.gizmodo.jp/2007/11/_comput.html

によると(以下斜体は上記サイトより引用)

「Computer Choppers」がまたやってくれました。

MacBook Proに続き、iPod classicが24金になって販売されます。24金…純金ですよ! …でも、クリックホイールの純白部分が気になりますねぇ。流石にここまでコーティングできなかったんでしょうか。

まだ値段は発表されていませんが、金の相場によって買い時があるかもしれませんね。販売はMac専門通販サイト「PowerMax」で行われる予定です。


ってことで、そのサイトに写真が出てるけど。。。

うーん、高そうだけど、たしかに、白い部分が。。。
ここも金にしちゃうと、なにがなんだか、わかんなくなっちゃうからかなあ(^^;)


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

オブジェクト指向で開発の最初から最後までの手順例-その36:雛形(9)

2007-11-26 19:12:49 | 開発ネタ

オブジェクト指向でやる場合の最初から最後までの流れを、実際の例を挙げて書いていくシリーズ「オブジェクト指向で開発の最初から最後までの手順例」

 現在、「いままでのまとめ」にある、「(4)フレームワークにもとづき、クラスなどの開発手順、雛形の確定」をやっています。

 で、その雛形など、作らなきゃいけないものとして、大きく分けて、

  1.画面
  2.コントローラー
  3.モデル部分
  4.DBアクセス部分

とあり、前回「3.モデル部分」の説明をしました。今回は、サンプルコード(「モデル部分テンプレート」)です。





■サンプルコード(「モデル部分テンプレート」)

 モデル部分のサンプルとしては、あんまりよくないのですが、消費税項目の追加、削除、編集、検索についての例を挙げてみたいと思います。
こんなかんじ
import java.util.*;

public class Shohizei {
	
	/*
	 * 	返り値:正常終了<BR>
	 */
	public	static	final	int	RETOK	=	0;

	/*
	 * 	返り値:データがない<BR>
	 */
	public	static	final	int	NODATA	=	1;

	/*
	 * 	返り値:システム上のエラー<BR>
	 */
	public	static	final	int	SYSTEM_ERROR	=	-1;

	/*
	 * 	返り値:DB上のエラー<BR>
	 */
	public	static	final	int	DB_ERROR	=	-2;

	/*
	 * 	返り値:コミット/ロールバック失敗ー<BR>
	 */
	public	static	final	int	TRAN_ERROR	=	-3;
	
	/*
	 * 消費税追加<BR>
	 * @param	data	引数データ
	 * @return	処理結果(0以外エラー)
	 * 
	 */
	 public int insert(HashMap	data)
	 {

		/*==========================*/
		/*	データチェック	    */	
		/*==========================*/
		if ( data	==	null )
		{
			return	NODATA;		
		}
		
		//	今回は省略

		//*=========================*//
		//*	生成		    *//
		//*=========================*//
		SHOHIZEI_TBL	shohi = new SHOHIZEI_TBL();
		if ( shohi	==	null )
		{
			return	SYSTEM_ERROR;		
		}

		MyConnection con = null;
		if ( data.get("MyConnection")	==	null )
		{
			con	=	new MyConnection();
			if ( con	==	null )
			{
				return	SYSTEM_ERROR;		
			}
			data.put("MyConnection",con);
		}
		
		//*=========================*//
		//*	処理		    *//
		//*=========================*//
		//	connectionの設定
		data.put("MyConnection",con);
		
		//	処理
		if ( shohi.insert(data)	!=	0 )
		{
			return	DB_ERROR;		
		}

		//*=========================*//
		//*	コミット	    *//
		//*=========================*//
		if ( con	!=	null )
		{
			data.remove("MyConnection");
			if ( con.commit()	!=	0 )
			{
				return	TRAN_ERROR;		
			}
		}
		
		//*=========================*//
		//*	結果設定	    *//	
		//*=========================*//
		return	RETOK;		
	 }

	/*
	 * 消費税削除<BR>
	 * @param	data	引数データ
	 * @return	処理結果(0以外エラー)
	 * 
	 */
	 public int del(HashMap	data)
	 {

		/*==========================*/
		/*	データチェック	    */	
		/*==========================*/
		if ( data	==	null )
		{
			return	NODATA;		
		}
		
		//	今回は省略

		//*=========================*//
		//*	生成		    *//
		//*=========================*//
		SHOHIZEI_TBL	shohi = new SHOHIZEI_TBL();
		if ( shohi	==	null )
		{
			return	SYSTEM_ERROR;		
		}

		MyConnection con = null;
		if ( data.get("MyConnection")	==	null )
		{
			con	=	new MyConnection();
			if ( con	==	null )
			{
				return	SYSTEM_ERROR;		
			}
			data.put("MyConnection",con);
		}
		
		//*=========================*//
		//*	処理		    *//
		//*=========================*//
		//	connectionの設定
		data.put("MyConnection",con);
		
		//	処理
		if ( shohi.del(data)	!=	0 )
		{
			return	DB_ERROR;		
		}

		//*=========================*//
		//*	コミット	    *//
		//*=========================*//
		if ( con	!=	null )
		{
			data.remove("MyConnection");
			if ( con.commit()	!=	0 )
			{
				return	TRAN_ERROR;		
			}
		}
		
		//*=========================*//
		//*	結果設定	    *//	
		//*=========================*//
		return	RETOK;		
	 }

	/*
	 * 消費税更新<BR>
	 * @param	data	引数データ
	 * 			変更対象は、項目名の前に*chkをつける
	 * @return	処理結果(0以外エラー)
	 * 
	 */
	 public int update(HashMap	data)
	 {

		/*==========================*/
		/*	データチェック	    */	
		/*==========================*/
		if ( data	==	null )
		{
			return	NODATA;		
		}
		
		//	今回は省略

		//*=========================*//
		//*	生成		    *//
		//*=========================*//
		SHOHIZEI_TBL	shohi = new SHOHIZEI_TBL();
		if ( shohi	==	null )
		{
			return	SYSTEM_ERROR;		
		}

		MyConnection con = null;
		if ( data.get("MyConnection")	==	null )
		{
			con	=	new MyConnection();
			if ( con	==	null )
			{
				return	SYSTEM_ERROR;		
			}
			data.put("MyConnection",con);
		}
		
		//*=========================*//
		//*	処理		    *//
		//*=========================*//
		//	connectionの設定
		HashMap rec = new HashMap();
		HashMap wrec = new HashMap();
		
		rec.put("MyConnection",data.get("MyConnection"));
		String[] key = (String[])data.keySet().toArray(new String[0]);
		for(int i = 0 ; i < key.length ; i ++ )
		{
			if ( key[i].substring(0,4).compareTo("*chk")	==	0 )
			{
				wrec.put(key[i].substring(3),data.get(key[i]));
			}
			else
			{
				rec.put(key[i],data.get(key[i]));
			}
		}
		Vector where;
		if ( wrec.isEmpty()	==	true)
		{
			where	=	null;
		}
		else
		{
		 	where	= new Vector();
			where.add(wrec);
		}
		
		//	処理
		if ( shohi.update(rec,where)	!=	0 )
		{
			return	DB_ERROR;		
		}

		//*=========================*//
		//*	コミット	    *//
		//*=========================*//
		if ( con	!=	null )
		{
			data.remove("MyConnection");
			if ( con.commit()	!=	0 )
			{
				return	TRAN_ERROR;		
			}
		}
		
		//*=========================*//
		//*	結果設定	    *//	
		//*=========================*//
		return	RETOK;		
	 }

	/*
	 * 消費税取得<BR>
	 * @param	data	検索絞込み対象
	 * @return	検索結果(nullのときエラー)
	 * 
	 */
	 public Vector select(HashMap	data)
	 {

		//*=========================*//
		//*	生成		    *//
		//*=========================*//
		SHOHIZEI_TBL	shohi = new SHOHIZEI_TBL();
		if ( shohi	==	null )
		{
			return	null;		
		}

		//*=========================*//
		//*	検索対象設定	    *//
		//*=========================*//
		Vector where;
		if ( data	==	null )
		{
			where	=	null;
		}
		else
		{
			where	= new Vector();
			where.add(data);
		}	

		//*=========================*//
		//*	検索		    *//
		//*=========================*//
		return	shohi.select(null,where);		
	 }
	 
}

(上記< > ¥は、本当は半角)

で、2つ以上のテーブルを更新して、トランザクション操作の例をしめしたほうがいいのですが、いつも、消費税なんで、今回も消費税にしてみました。
なお、コメントに書いてありますが、変更する場合、変更もとの項目は、*chkを付けて送ります(項目名は変更後の値を示します)

別パッケージにしたほうがよかったかも・・・
あと、「public static final int」で宣言しているRETOKとかは、共通部分として、別クラスに飛ばしたほうが良かったかも。。




モデルに関しては、いろんなメソッドがあるので、まあ、上記のサンプルを示してとりあえず、先に進むこととします。次は、コントローラー、すなわちサーブレット部分についてです。



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする