今また羽田空港国際線ラウンジ

本日は昼から 横浜みなとみらいのホテル東急で開催された日本心臓血管麻酔学会総会のランチョンセミナーに演者として招聘され、一時間の講演を行ってきました 演題は、TAVIです

この学会の会長は湘南鎌倉総合病院麻酔科の小出部長であり、僕の講演の座長をして下さったのは、鎌倉の心臓血管外科部長をされていて、今年から日本大学医学部心臓血管外科キョウジュに移転された田中 正史先生がされました 非常に栄誉なことでした

この講演のために、TAVIに関連したいくつもの論文を読破し、大変に勉強しましたが、頭の片隅では何時も、「ああ プログラミングしたい」と思い続けていましたよ

横浜で食事してから、鎌倉に戻り、そしてまた再び羽田空港に出発し、現在ラウンジなのです 明日、つまり9月17日土曜日 0:50AM発の羽田発フランクフルト行き ANA便でフランクフルトに飛び、1時間の Transitの後、ロンドンに飛びます

ロンドンに着けば土曜日8:00AM頃なのですが、ホテルに early check-inの後、Tokyo Valvesのmeetingが朝から夕方まで開催される予定なのです もちろん僕は絶対に参加していなければならないのです 僕以外は皆 20歳ぐらい以上若い先生方なのですが、何とか着いていこうと必死です 何時までそんな空元気が持つかなあ

という訳で数週間ぶりに Programmingをこのラウンジでしているのですが、フロントエンドの User Interfaceを造っていてどうにも頭悩まされたのです

それは、例えば <select><option>1</option><option>2</option></select> というhtmlのフォーム部品なのですが、走らせるとクリックした途端に文字が消えてしまうのです

うーん 何故だ こんな簡単な基本的部品でなんでそんなことが起こるのか?

起こっていることは事実なので一つ一つ原因を虱潰しに探索したのです その過程で「うん ひょっとして」と思うフシがあったのでそれを修正したところ、見事に解決です

それは僕みたいにやんちゃだとしばしばしてしまうのですが、DOM部品につける id tagを二重につけていたためなのです これは意外と見つかりにくいバグの要因となります idを二重につけていても大概は問題無く動作するのですが、条件が重なると異常な動作をします

もちろん idというのは一意的なものなので異常な動作、というのは正しい動作なのですが、なかなか見つけにくいのです

このような時には class属性にすれば良いのですが、class属性にしてしまうと今度は一斉に適用されていまいますよね

そんなこんなでこのラウンジでバグ潰しに20分ぐらい使ってしまいました でもこれってとっても楽しい時間なのです そうですね 子供の頃に鬼ごっこで遊んだような そんな時間なのです わかりますか? この感覚

昨日は

昨日は朝今年最後の症例となるTAVI1例実施しました たくさんの合併疾患を持っておられる方であり、また弁輪径も小さく、石灰化も強く、緊張を強いられる患者さんでした

大腿骨頚部骨折に対してこの夏先に人工骨頭置換術を受けられましたが、その時に重症大動脈弁狭窄症が発見され、術前に経皮的大動脈弁バルーン拡張術(BAV or PTAV)を行い、手術に臨んで頂きました

その時に左回旋枝に中等度病変も見つかったのですが、この半年間にその病変は変化無いため、今回は冠動脈病変はそのまま経過観察の方針で行いました

TAVIは、控えめ戦略で問題無く終了し、予定よりも早く終了し、患者さんはすぐに覚醒され、今朝もお元気です 良かったです

その後、外来診療、そしてPCIを1例行い、ライブデモンストレーション症例検討会を行いました

再び Ajaxに挑戦

ある臨床試験サイト構築中です その中で、登録症例一覧を出力し、その症例に飛ばす、というインターフェースが必要と感じました

それ自体は簡単なことですが、問題はいわゆるページングです ページングの問題は、ある程度大きなデータを扱うサイトを構築する時には何時も突き当たる難問です CakePHPなどのフレームワークを使用すれば、フレームワークに内在した機能で、簡単に作成できますが、PHPを用いてゼロから構築するとなるとそのような訳には行きません

想像してみて下さい 300件登録されたデータを一枚のページに出力するのは簡単ですが、通信の時間がかかるのと、もっと問題は、探しにくく閲覧しにくい、ということなのです 従って、優しいインターフェースとしては、たとえば、10ページ目20症例分を出力する、というようにページを選択できるようにするのです

もちろん、これをHTML + PHP + MySQLのみで実現するのは難しくありませんが、問題は、ページ切り替えの度に、ページ遷移が起こるので、通信トラフィックが増加するだけでなく、ユーザーから見れば、画面全体が書きなおされるので不愉快です

そこで出てくるのが Ajax (Asynchronous Javascript and XML)という技術です これまでにも何回か紹介していますが、この技術を使います

苦労の末、思い通りのインターフェースが構築できました

最終日になってもひどい時差ぼけ

昨日は FCI (Fundancion CardioInfantil)でのPCIを終わり、早めにホテルに戻り少し仮眠して、それから今回集まられた先生方と コロンビア料理の店で 8:00PMより会食がありました

コロンビア料理って何? と言われてもなかなか難しいのですが、そのお店では基本的に牛肉料理でした それと、とても小さな直径が1.5CMくらいのミニポテトがなかなかおいしいのです

お店の名前は Andres Carne de Res 俗に Andres D.C.というお店で、まあ皆が無茶苦茶騒ぎまくるお店です 今調べたらコロンビアのレストラン・ランキングで 10位のお店で非常に人気があり、お店は満員で人であふれかえっていました

当方はmain dishとして牛肉ステーキを頼んだのですが、300gぐらいあるのでしょうか 僕にとっては食べきれない量です 焼き加減など聞かれなかったので、「どうせカリカリの固いステーキでおいしくないのだろう」と思っていたのですが、焼き加減は mediumですが、とても柔らかく、また味もしっかりあり中南米で食べた牛肉の中では一番おいしい、と思いました

お店はボゴタの繁華街にあり、たくさんのレストラン、カジノ、バーなどが開いており、多くの人々が繰り出していました とても平和な雰囲気であり、危険な感じは一切しません 街角にも警察官や兵士あるいは爆弾探知犬などもおらず ある意味 日本の繁華街よりも安全な感じがしました もしもこんな場所に爆弾を仕掛けるようなことがあれば、どんな政治的信条があったとしても、許せない、そのように思いました

その後、近くのアジア料理のお店でラーメンを食べ、ホテルに戻ったらば 11:00PM それからパタンと寝たのですが、本日はこの中南米PCIツアー最終日だというのに 3:00AMにはしっかり覚醒してしまったのです 今朝も 8:30AMホテルを出発し、午前中同じ病院でPCIや講義など行い、それからホテルに戻り 23:00発のニューヨーク行の便で成田に向けて帰国します 成田に到着するのは日曜日の 16:00ということになりますから、やはり約30時間の旅程ということになるのです ニューヨークでは何と 6時間以上も一人でトランジットを過ごさねばなりません うーん 大変ですねえ

それにしても、エチェベリ先生[Dario Echeverri, MD (Director Servicio de Hemodinamia e Intervencionismo Cardiovascular Fundacion CardioInfantil – Instituto de Cardiologia, Bogota, Colombia)]には今回も大変お世話になりました ものすごく良い先生ですし、人望もあられます
s0412_4 s0412_5 s0412_6 s0412_7 s0412_8 s0412_9

どうにもスッキリしないのですが・・・

これまで紹介したように、今 紹介診療機関のデータベースを CakePHP 2.0を用いて作成しようとしています。データ構造は簡単です。基本的に二つのテーブルがリンクしているのみです。診療機関には複数の医師が存在しますので、 clinicsテーブルと physiciansテーブルの間には 1:n の関係があります。使い勝手を良くするために、以下の画面を考えています。

<h2>クリニック情報の編集</h2>
<?php echo $this->Form->create('Clinic'); ?>
<?php echo $this->Form->input('clinic_name', array('label'=>'クリニック名')); ?>
<?php echo $this->Form->input('clinic_kana', array('label'=>'クリニック呼び名')); ?>
<?php if(!empty($physicianList)) { ?>
	<table>
	<tr>
    <th>医師名</th>
	<th>医師呼び名</th>
	<th>編集</th>
	</tr>
	<?php foreach($physicianList as $physicians): ?>
	<tr>
	<td><?php echo h($physicians['Physician']['physician_name']); ?></td>
	<td><?php echo h($physicians['Physician']['physician_kana']); ?></td>

    <td><?php echo $this->Html->link('追加', array('controller' => 'physicians', 'action' => 'registration', $physicians['Clinic']['id'])); ?>
	<?php echo $this->Html->link('削除', array('controller' => 'physicians', 'action' => 'delete_pre', $physicians['Physician']['id'])); ?></td>
	</tr>
	<?php endforeach; ?>
	</table>
<?php } ?>
<?php echo $this->Form->input('postal', array('label'=>'郵便番号')); ?>
<?php echo $this->Form->input('address', array('label'=>'住所')); ?>
<?php echo $this->Form->input('phone', array('label'=>'電話番号')); ?>
<?php echo $this->Form->input('fax', array('label'=>'ファックス番号')); ?>
<?php echo $this->Form->input('kakaritsuke_flag', array('label'=>'かかりつけ登録医です')); ?>
<?php echo $this->Form->input('comment', array('label'=>'備考')); ?>
<?php echo $this->Form->input('map', array('label'=>'地図情報')); ?>
<?php echo $this->Form->input('id', array('type'=>'hidden')); ?>
<?php echo $this->Form->end('修正'); ?>
そして、PhysiciansController.phpでは以下のように受けようと思っています。
<?php
	//edit
	public function edit($id = null) {
		if($this->request->isPost()||$this->request->isPut()) {
			if(!empty($this->data)) {
				if($this->Physician->save($this->data)) {
					$this->Session->setFlash('保存しました');
					$this->redirect(array('action'=>'index'));
					return;
				}
			}
			//error
			$this->setFlash('保存に失敗しました');
		} else {
			//$id dataを読み込む
			if(!is_null($id)) {
				$this->data = $this->Physician->findById($id);
			}
		}
	}
	//delete
	public function delete_pre($id = null) {
		$this->data = $this->Physician->findById($id); // Physiciansのデータを $this->dataに読み込むのに必要
		$this->render('delete');
		$this->delete();
	}
	public function delete($id = null) {
		$clinic_id = $this->data['Physician']['clinic_id'];

		if($this->request->isDelete()) {
			$this->Physician->delete($this->request->data['Physician']['id']);
			$this->redirect(array('controller' => 'clinics', 'action' => 'edit', $clinic_id));
			return;
		}
	}
?>

ここでのミソは、一旦 delete_preアクションに飛ばし、そこで該当する idのデータをデータベースから読み込み、それを $this->dataに格納し、それから render()メソッドを用いて delete.ctpによる表示系に飛ばすということです。でも疑問は、本当にこんなややこしいことせねばいけないのでしょうか?
動作確認ではきちんと動作します。どなたかご教授お願いします。

2012-06-06 再び CakePHP – 2.0でのキャンセル、リセット・ボタンの判別

  echo $this->Form->create('Physician', array('type' => 'delete'));
  echo $this->Form->input('id', array('type' => 'hidden'));
  echo $this->Form->submit('削除', array('name' => 'delete'));
  echo $this->Form->submit('キャンセル', array('name' => 'cancel', 'type' => 'reset'));
  echo $this->Form->end();

というフォームを作成し、PhysiciansController.phpの中で、’delete’という名前と’cancel’という名前のボタンが押されたことをそれぞれ判別したいのですが、どちらのボタンを押しても、delete()というアクションに飛んでしまい、その中でボタンの判別ができないのです。
随分と色々試したり、コントローラーの中で pr()関数を用いて、どのようにオブジェクトが飛んでくるかを表示させたりしたのですが、ボタンを判別できるようなプロパティは無いのです。
それでコントローラーでの判別を止めて、以下のようにJavascriptと組み合わせることにしました。

上と同じなので省略ね
 echo $this->Form->submit('キャンセル', array('name' => 'cancel', 'onClick' => 'history.back()'));
  省略ね

これでとりあえずキャンセルボタンを押せば削除がキャンセルされて前のページに戻るようになりました。
うーん これは CakePHP流なのでしょうか? どうもすっきりしません。どなたかケーキ屋さん、教えて下さいな。

2012-06-05 CakePHP 2.0での POST dataの受け方

小倉ライブデモンストレーション前より悩んでいたことが解決
この親切なページのお陰です。
しかし、やはり同じように悩んでおられた方がおられたのですね。
僕はその歴史を良く知らないのですが、CakePHPはその前の Major versionである CakePHP 1.3から 現在の最新versionである CakePHP 2.0に移行中なのですが、問題は現在インターネットや書籍での解説はほとんどが 2.0ではなく 1.2 or 1.3のものなのです。
それらの解説を読めば

$this->params['forms']['id']

とすれば POSTで渡された $idを受けとることができる筈なのです。
しかし、そもそも $this->paramsなんて CakePHP2.0では無いのです。
それと同等の働きをするのが、何と

  $this->request->data['Model']['id']

なのです。もちろんここでのModelはそのデータが属するモデルであります。
これで懸案のプログラムが矛盾なく、しかもエレガントに動くようになりました。

2012-06-04 懸案事項の解決

小倉ライブの前から CakePHPのあるプログラムを書いていて頭を悩ましていました。ここに二つのテーブルがあります SQLで書けば

CREATE TABLE `clinics` {
  `id` INT( 11 ) NOT NULL AUTO_INCREMENT,
  `clinic_name` VARCHAR( 255 ) NOT NULL DEFAULT '',
  CONSTRAINT PRIMARY KEY (`id`)
} CHARACTER SET utf8 COLLATE utf8_general_ci;

CREATE TABLE `physicians` {
  `id` INT( 11 ) NOT NULL AUTO_INCREMENT,
  `physician_name` VARCHAR( 255 ) NOT NULL DEFAULT '',
  `clinic_id` INT( 11 ) NOT NULL DEFAULT '0',
  CONSTRAINT FOREIGN KEY (`clinic_id`) REFERENCES `clinics` (`id`),
  CONSTRAINT PRIMARY KEY (`id`)
} CHARACTER SET utf8 COLLATE utf8_general_ci;

このような二つのテーブルがありもちろん`clinic_id`.`id`は`clinic`テーブルの`id`を参照しており、`clinics`テーブルと`physicians`テーブルは 1:n の関係でリンクしているのです。
このような良くあるデータ構造の時に、修正画面を作るとすれば、僕であれば次のような画面を作成します

       診療所情報の修正画面

診療所名前    : ここに登録されている診療所名前が出る

診療所医師名   1: 名無しの権兵衛  [登録医師削除]
         2: 明日晴れのすけ    [登録医師削除]

         [修正][キャンセル]

このようにすれば、診療所名前修正もできますし、登録されている医師名の削除もできます。
CakePHPを用いてこのような画面出力の作成は一日もかからずにできました。しかし、問題は医師名削除だったのです。これが一筋縄では行かなかったのです。何とか動作するプログラムを書くことはできましたが、どうもすっきりしないのです。これが本当に CakePHPのお作法として正しいのでしょうか? はなはだ自信がありません。
何れにしてもこの過程で明らかになったことがあります。CakePHPはその根本に MVC (Model-View-Controller)という良く使われるアーキテクチャを用いているのですが、僕の問題はその MVCを本質的に理解していないのでは? ということなのです。
こんな時に、誰か身近に意見を聴ける方がいて下されば良いのですが・・・・ 実際インターネット質問欄に投稿しようとしても、コードが長くなり失礼と思えるので、なかなかできないのです。どうしましょうかね・・・