久しぶりにTAVIを行いました

本日は朝から札幌東徳洲会病院心臓センターで三件のTAVIがあり、その中の一例を治療させて頂きました

北海道地震の被害からも立ち直りTAVIが本格的に再開されたのです 僕が治療させて頂いたのは、ご高齢の方でしたが、かなり高度な大動脈弁狭窄症であり、治療してよかったと思います 9:30AMよりTAVIのセッションが開始となり、合計で三例の治療を終わったのは 14:00でした 縦に三例を4.5時間半で入れ替えなども含んでする、というのは相当に早いですよね 入れ替え時間を含め、麻酔も含めて一例 1.5時間ということになります 素晴らしいですね

長期間の海外出張で、しかも西に東にですので、相当に体のリズムが狂ってしまいましたが、徐々に回復です とは言っても色々なメールには応答できていません 頭が回りません

頭のリハビリには Javascriptの勉強をしています Javascriptと言っても、正確には ECMAScript20151 というもので、別名 ES6と呼ばれている言語仕様のものです 現在ではほとんどのブラウザ上にこの ES6は実装されていますし、node.jsにも実装されています

言語仕様は非常に先進的なものであり、これまでのプログラミングの大きな考え方 (= パラダイム)を変更するほどのインパクトがあります 際立って紹介されているのが、アロー演算子とか Promiseとかいうものです Promiseに関しては未だ勉強を開始していません 現在はアロー演算子の習得にかかっています

/*jslint node: true */
/*jshint esversion: 6 */
"use strict";

const ary = [1, 4, 7, 9, 32, 43];
let reducer = (accumulator, initialValue) => accumulator + initialValue;
let result = ary.reduce(reducer);
console.log(result);

ここで、最初の2つのコメント欄が無いと、jslintという文法チェッカーでエラーを吐かれます

このプログラムは、配列の合計を求めるという他愛もないものですが、重大なパラダイムシフトがあるのです とっても難しいのですよ

ヘルシンキから神戸 そして WSL

WSLという言葉をご存知でしょうか Windows Subsystem for Linuxのことです

Microsoftは数年前より急速に Open Softwareに舵を切り替え、その代表として WSLという仕組みを開始したのです これは Windows10というこれまで Microsoftを支えてきた OSの中に Linuxという Open Softwareの OSをシームレスに走らせる仕組みです

もちろんこれまでに Windows10の上では、VirtualBoxや、VMWareといった有名な仮想マシン、あるいは Dockerなどのコンテナと呼ばれる仮想マシンの小型版がフリーで走っていました しかし、VirtualBoxや VMWareは Windows10の中に新たにコンピューターシステムを立ち上げるもので、マシンに対する負荷が大きいものでした

これに対して WSLというのは Windows10 OSの上に Linuxの APIを emurateする型で Linux OSを立ち上げるものです ここいら辺に関しては僕も知識がいい加減であり間違ったことも言っていると思いますので、それぞれが調べて下さい 何れにしても WSLを立ち上げたのです

その方法はネットで検索すると色々出てきますが、僕の場合、このサイトに従いました 少なくとも 2018/SEP/13の最新 Windows10 version 1803においてはこれで正しくインストールできます

とは言うもののこのサイトの後ろ半分に書かれている内容はかなり高度なものであり難解です とりあえず僕はここまで つまり、<Hyper の設定 for WSL>という部分まで行い結果的にこのような画面となりました

Linux (Ubuntu) on Windows10
Linux (Ubuntu) on Windows10 on MacOS

さて昨日は成田空港から羽田空港に移動し、伊丹空港に飛び、それから神戸の高橋病院に入りました そこで三例のPCIを行わせて頂きました

楽しく過ごしました

こっ こっ こっ これは素晴らしい

javascriptは関数型言語として捉えるとものすごく先進的な言語であるらしいのです もっとも ECMA Script 6 (ES6)あるいは  ECMAScript2015とも呼ばれるもの以降の話のようですが・・・

てなわけで少しだけ勉強しようと思っているのですが、何はともあれ javascript実行環境が無いと練習できません もちろんそのような意味では各種Browserには javascriptが内蔵されているのでそこで consoleを叩けば良いのですが、なかなか面倒ですよね

あるいは $node としてnode.jsを立ち上げその中で実行するのもありですが、これは文ごとでの実行となり今一つですよね

ところが VSCodeでは簡単に実行できることが分かりました もちろん node.jsがインストールされていないと駄目なのでしょうかね なかなか素晴らしいですよ

我ながら役立つこともあるのですね

2014年にこのブログに uploadした Qtでの DIB class に関する C++のコードに対して それから 4年経ってコメントがありました  Thanks というものです これは外国からのコメントでした

正直この頃は Qtで何とか C++により DICOM Viewerを作ろうとしていたのでしょうね いやあ その頃のことは忘れてしまいました その後、僕は急速に Script言語による Web programmingに傾倒して行き C++なんて忘れてしまいました ああ

でも Internetのつながりとは大きいですね

本日は Dockerのお勉強

Dockerというのは今話題の何と言ったらばいいのでしょうかね 自分でそんなに理解していないので表現できないのだけど、とにかくイメージとしては 「自分自身のパソコン上で Linuxを自在に走らせることを可能にする」ものです

例えば、自分の MacOSの上で少しの手間で Linux上で走る Web Serverやら SQL databaseを走らせ、MacOSではその Web Serverやら MySQLと通信してあたかも仮想のインターネットが自分の MacOS上に形成されるのです

自分で Webのプログラム組む時にテストとして 仮想インターネット環境を作らねばならず、この目的では 以前より使用されていた XAMPとか 今も盛んに使用されていて自分も使っている MAMPがあるのですが、そんなことせずに(多分)そのような環境を作ることができるのです しかも、それで動作すれば、そのファイル(イメージ)を持ち込めば世界中どのマシンでも動くらしいのです

うーん自分でも良く分からないので説明できないのですが・・・

これまで何冊かの書籍を Kindleで購入してきたのですが、どうも今ひとつピント来ず、またサンプルが動作しないのでつまづいてきました

今回、「Docker/Kubernetes実践コンテナ開発入門」という書籍を Kindleで購入して少し読み始めました

Docker書籍

この書籍は Just Publishedであり、昨日 download可能となりました それでテストしているのですが、なかなかこの書籍は書かれている内容が Docker初心者には理解し難いものがあり、色々とテストしてようやく最初のサンプルプログラムが走りました

#! main.go -- go言語でサーバーを立ち上げるためのプログラムを書く

package main

import (
  "fmt"
  "log"
  "net/http"
)

func main() {
  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    log.Println("received request")
    fmt.Fprintf(w, "Hello Docker from DOCKER/KUBERNETTES BOOK!!")
  })

  log.Println("Server was started.")
  server := &http.Server{Addr: ":8080"}
  if err := server.ListenAndServe(); err != nil {
    log.Println(err)
  }
}

このGO言語で書かれたプログラムは port番号8080で Web Serverを立ち上げるものです なんだか色々と難しいことが書いてあるけど、やってるのは もともと GO言語のライブラリとして用意されている fmt, log, net/http といったライブラリを読み込んでそのライブラリに既に用意されている命令を呼び込んでいるたけです

そしてこれをコンパイルするために用意されている Dockerfile という拡張子無いファイルが重要なのです

FROM golang:1.9

RUN mkdir /echo
COPY main.go /echo

CMD ["go", "run", "/echo/main.go"]

このファイルを同じフォルダに Dockerfile という拡張子の無いファイル名で置くのです

このファイルでは書いてある通りに、 goloang version 1.9という既に定義されている色々な仕掛けを読み込み、それから Dockerが作成した特殊環境 Conatinerの中に /echo というフォルダを作成し、それからそのフォルダにさっき、compileした main.goという実行形式をコピーし、それから go して run してサーバーを立ち上げろ ということなのです

しかし、ここまで理解するのに色々とハマりました まず第一に、これらのファイルをどこに配置すれば良いのか、その説明が本には無いのです

仕方なく、僕は 文書フォルダの中に DOCKERKUBERNETES-BOOKというフォルダを作成し、そこに2つのファイル Dockerfileと main.goを置きました そして

$cd Documents/DOCKERKUBERNETES-BOOK

として current folderをこのフォルダに移動させそこで terminalより 以下の Docker commandsを打ちました

$docker image build -t example/echo:latest . // 実は最後のピリオドが重要です これが current directoryを表しているのですよ

これにより コンテナの中で go言語で書かれたサーバー立ち上げプログラムがコンパイルされてサーバーが立ち上がりました しかし、一発で立ち上がればいいのですが、main.goの中で typo (打ち間違い)が当然あります その時にeditorで何回もさっきの image buildを行っても エラーが出るのです

何回見直して typoを修正しきってもエラーを吐くのです これにはまいりました インターネットで原因を調べても良く分かりません

ふと思いついて ひょっとしてコンパイルされたイメージがコンテナの中に既に存在するのでエラーになるのでは? と思いました あたりでしたね

 

$docker image build --no-cache -t exmaple/echo:latest .

とすれば再びビルドして新たなイメージを作り直します

またこのようにしてできたイメージは

$docker container run example/echo:test

として簡単にスタートできますね そしてこのWeb Serverに外部から port 9000でアクセスさせるためには まず走っている イメージ-サーバーを停止せねばなりません

$docker ps

により走っているイメージプロセスを表示させます その最後に nameというタグがありますので、そのネームを用いて

$docker stop [nameの部分に表示される名前] //この名前は dockerが不規則に作成しているものです

としてそのプロセスをまず停止します それから再度 port forwardingしながら WEb Serverを立ち上げるために 再度以下のコマンドによりサーバーを立ち上げます

$docker container run -d -p 9000:8080 example/echo:latest

こうすることにより dockerで走っているサーバーの 8080 portがメインマシン ここでは僕の macOSですがこの port 9000と繋がります( = port forwarding) 結果的にはこの macOSでブラウザから localhost:9000とすれば、メッセージが表示されるのです

フーッ ここまで来るのに一時間使いましたね

全く馬鹿なことをしてきた

この暑さに参っているのか頭脳の回転が遅くなっている 自分でもなんて馬鹿なんだと思うほど頭脳の回転が遅くなっている 知らない内に脳梗塞でも起こしているのだろうか?

自分の年齢から考えれば、さらには CHADS-VASCなども考慮すればその可能性は妥当である でも「自分だけはそんなことないよね」などとのほほんと構えている 自分がそんな人間だから患者さんの気持ちは痛いほど分かる そしてその気持が分かれば分かる程に患者さんのことを思う気持ちが高まっていく

とは言っても自分の頭の回転が悪いのは自分で許せない、何とか回転を早くせねばならない そんな時に立ち向かうのはやはりプログラミング でも自分はプロのプログラマではないので、アマチュアのプログラマなので、自称「アマグラマ」と呼んでいる

さてそのアマグラマが何とか少し頭の回転を取り戻したのが次の Web上での MySQLデータ修正の php program このデータというのは 実は 鎌倉ライブのweb公開用予定表 でも現在公開しているものとは不完全に修正書き換えしてあり、昨年の予定表も混在しているので混乱の的かも? まあしかし鎌倉ライブなんてそんなに世間の注目集めないのでこのまま混在していても開催までに修正すれば実害は無いのだろうと思って勝手に割り切っている

そもそも今年は鎌倉ライブ予定表のデータ構造を徐々に変更しようとしているのだ 何故ならばもっと論理的な整合性のあるデータ構造にすれば、その先修正はいらなくなるだろう と期待しているから

とりあえず、テーブルのカラムを一つ増やし、そのカラムに別のカラム上のデータを変換しながらコピーするプログラムを phpで書いたのである ばっかみたいなプログラムだけと暫くプログラム書くことから遠ざかっていたので書いている内にプログラミングの感覚が戻ってきてなんとなく自分が賢くなってきたように思うのだ

ということでそのプログラムの一部

$stmt = $pdo->prepare( "SELECT * FROM `session_tbls2018` WHERE '1' = '1';" );

try {
  $pdo->beginTransaction();
  $flag = $stmt->execute();
  if ( !$flag ) {
    $infor = $stmt->errorInfo();
    exit( $infor[ 2 ] );
  }

  $pdo->commit();
} catch ( Exception $e ) {
  $pdo->rollBack();
  echo "Failed to update Database" . $e->getMessage();
}
$rows = $stmt->fetchAll( PDO::FETCH_ASSOC );
$stmt1 = $pdo->prepare("UPDATE `session_tbls2018` SET `beginDate` = :beginDate WHERE `id` = :id;");

foreach ( $rows as $row ) { // 全てのデータ
  if ( ( $row[ 'id' ] > '171' )AND( $row[ 'id' ] < '186' ) ) {	//2017年 座学修正用
    $begintime = date( 'Y/m/d H:i:s', strtotime( '2017/12/09' . $row[ 'begin' ] ) );
    $stmt1->bindValue( ":beginDate", $begintime, PDO::PARAM_STR );
    $stmt1->bindValue( ":id", $row[ 'id' ], PDO::PARAM_INT );
    $stmt1->execute();
    try {
      $pdo->beginTransaction();
      $flag = $stmt1->execute();
      if ( !$flag ) {
        $infor = $stmt1->errorInfo();
        exit( $infor[ 2 ] );
      }

      $pdo->commit();
    } catch ( Exception $e ) {
      $pdo->rollBack();
      echo "Failed to update Database" . $e->getMessage();
    }
    echo $begintime . "<br>";
  }
  if ($row['id'] == 185) echo "座学が修正されました<br><br>";

 

 

久しぶりの PHPネタ

今開発中の Web Applicationではデータ構造が複雑なため、SQLで読み込んだり書き込んだりする時にたくさんのバグが混入しています

特に画面遷移においてデータをどのように受け渡しするか? それが自分の中でも混乱してしまうのです どうすれば良いか? それで考えたのが 以下のような utilityを作ることでした

<?php


function DEBUG_CONT() {
  echo "-----------------------------------------------------------------------<br>";
  if ( !isset( $_POST ) ||empty( $_POST ) ) {
    echo "<strong>POSTは空っぽです</strong><br>";
  } else {
    foreach ( $_POST as $key => $value ) {
      echo '&nbsp;&nbsp;&nbsp;$_POST[' . $key . '] = ';
      if (mb_strlen($value) > 50) {
        echo mb_substr($value, 0, 50).'・・<br>';
      } else {
        echo $value.'<br>';
      }
    }
  }
  echo "-----------------------------------------------------------------------<br>";
  if ( !isset( $_SESSION ) ||empty( $_SESSION ) ) {
    echo "<strong>SESSIONは空っぽです</strong><br>";
  } else {
    foreach ( $_SESSION as $key => $value ) {
      echo '&nbsp;&nbsp;&nbsp;$_SESSION[' . $key . '] = ';
      if (mb_strlen($value) > 50) {
        echo mb_substr($value, 0, 50).'・・<br>';
      } else {
        echo $value.'<br>';
      }
    }
  }
  echo "-----------------------------------------------------------------------<br>";
  return;
}

function DEBUG_STOP() {
  echo "-----------------------------------------------------------------------<br>";
  if ( !isset( $_POST ) ||empty( $_POST ) ) {
    echo "<strong>POSTは空っぽです</strong><br>";
  } else {
    foreach ( $_POST as $key => $value ) {
      echo '&nbsp;&nbsp;&nbsp;$_POST[' . $key . '] = ';
      if (mb_strlen($value) > 50) {
        echo mb_substr($value, 0, 50).'・・<br>';
      } else {
        echo $value.'<br>';
      }
    }
  }
  echo "-----------------------------------------------------------------------<br>";
  if ( !isset( $_SESSION ) ||empty( $_SESSION ) ) {
    echo "<strong>SESSIONは空っぽです</strong><br>";
  } else {
    foreach ( $_SESSION as $key => $value ) {
      echo '&nbsp;&nbsp;&nbsp;$_SESSION[' . $key . '] = ';
      if (mb_strlen($value) > 50) {
        echo mb_substr($value, 0, 50).'・・<br>';
      } else {
        echo $value.'<br>';
      }
    }
  }
  echo "-----------------------------------------------------------------------<br>";
  exit();
}

?>

これで該当するベージに DEBUG_CONT();などとすれば、何の$_SESSIONあるいは $_POSTを保持しているかが分かり データの流れが把握しやすくなりました

本日は日曜日 ブックスペース栄和堂

本日は久しぶりの日曜日です 12時開店のブックスペース栄和堂で3.5時間ぐらい一杯のコーヒーでまったりとした時間を過ごしています

ここは電源とインターネットフリーなのでプログラミングするにはとても良い環境なのです 本日は珍しくお客さん少なく僕以外にはこれまで3名のみであり、しかも何れも1時間ぐらいで出ていきました

例の学会演題プログラムに関しては、共同演者登録の部分でデータベース構造を根本的に変更し、それに伴いプログラムも大幅に書き換えているのです なかなか基本的な構想がまとまらないのでプログラム書きながら変更しながらの作業です それでもローカル Web上ですぐに検証できるのでとても良いですね これがコンパイラーによる作業であればこうはいきませんよね

それにしても僕の持っている武器は PHP/jQuer/Bootstrap/MySQL/htmlぐらいの乏しいものですのでなかなか思いどおりには行きません 新しい世界観 たとえば今注目しているのは Vue.jsですが、これなんか多分永久に届かない世界かも知れません やはり圧倒的に新しい物に取り組む勢いが年齢と共に低下しているのを感じます そんなことに負けたくはないのですが、現実も見ねばならないでしょう どこかで妥協して結果的に自分の能力を最大限に引き出す戦略が必要なのかも です

でも、救いの一つは、本日も Airさんとやり取りしていて新たな世界の入り口に片足の足首だけ入れることができました ありがとうございます

あーん あーん

まさしく「あーん あーん」です

自分の能力が低下しています これまでは自分でも「僕って天才」と思えることがいくつもありました でも 最近は無いのです 無いのは未だいい 問題は 明らかに自分の能力が低下しているのでは? と思うのです

これまで、僕の最大の能力は Typing speedでした 何故か 何故ならば僕は日本語入力の時には「かな漢字」変換を行い、アルファベットを打つ時には、自動的にANSII Key Boardの配列になるのです そのように自分を 30年ぐらい前に訓練したのです この結果、自分の Typing speedは理論的に日本語入力の時に、ローマ字カナ変換に比較してほぼ倍のスピードになるのです

これスピードだけの問題ではなく、自分の思考がタイピングにより制約されないことを意味し、その結果頭脳の空間が拡大するのです

それに疑問を挟むようなことが最近あるのです 歳か? あるいは頭脳の病気か?

まあやれるところまでやらざるを得ません それで答えが出てくるでしょう

何れにしても現在は僕は未だまだ元気であり頭脳も明晰です 今も phpで画像 uploadの部分の勉強しながらプログラム書いています JTVT2019のプログラムは自分の尊厳を賭けて仕上げるつもりです

インターネットを通じたつながり

今朝は体調不良 もう歳かな それでも本日 TAVI二件、その後 MitraClip 1件あります まあそろそろ体調も戻り、またTAVIに関しては若手に完全に任せますので良いでしょう 全力を MitraClipに傾けますよ

それはそうと今朝メールを開けると「ぎぎ」としました 僕のこのプログにコメントが投稿されていたのです いやあとても感激しました この方はかなり高度なプログラミング知識と技術をお持ちの医療関係者だと推察します その方が、ご自身で開発されている DICOM Viewerである Horlixにおいて、ある種の DICOM-USフォーマットが読み込みできないために(しかもこれが Philipsなのです: 実際この Philips machineの DICOM-USは変です 当院でも読み込めない事例が発生しています!!)、 DICOMで検索しておられて僕のこのブログにヒットされ、そしてコメントを頂いたのです

とてもとても僕なんて足元にも及びません そんな方からのコメント「ぎぎ」とすると共に感激です 思わずこんな返信してしまいました

ちなみに僕の DICOM Viewer開発苦労話はここにまとめてあります

 

air様

コメント頂きありがとうございます Githubなども見させて頂きました また、OpenDolphin関係のページも見させて頂きました 世の中にはすごい方がおられるものだ、とただただ感心するのみです
私なんかは既に 68歳ともなり、頭脳はどんどん硬くなると共に処理能力が劣る一方です そんな自分でも Z80 assemblerでプログラミングの真似事を始めた20歳台の頃の、わくわくした思い、それを取り戻したくて、かつ謎であった DICOM-XA それに取り組んだのは既に 10年以上の前のことでした
しかし、自分の能力がとても足りず JPEG規格書を読んでもなんのことかさっぱり理解できない状態が続きました 自分の患者さんに引退された工学部教授がおられ、その方の教え子に信号処理を専門にやられている研究員の方がおられたので、その方をご紹介して頂き、直接 JPEG規格書と DICOM規格書から DICOM-XAが JPEG losslessで圧縮されていることを掴み、そのHuffmann Code解読プログラムをなんとか書くことを開始しました それでも何がなんだ最初はさっぱり分からず、随分と苦労して慣れない C++ (VisualStudio)を用いてプログラム書き始めました
最後にはようやく DICOM-XAで動画を Windows上で動かすことに成功しました
それができるともうそれ以上進むのは自分では無理だと達観してしまい、DICOMの世界から離れてしまい、今は Osirixの単なるユーザーになっています
Osirixが高額でありしかもひどいことには、MacBook Proの USB-C端子4つの内2つが自然故障して、修理に出したところ、logic board交換となり、それと共に Osirixのライセンス切れてしまい、またまた 100K円の支払い発生するという理不尽を経験して、Horosともめぐり逢いました
そしてその Horosより派生させ、さらに改良を加えられている Horlixをご紹介頂き感激しています
でも正直、自分でも Webのプログラムを Githubに蓄えたりしていますが、 air様の Horlixに関して、どのように実行ファイルを作成すれば良いのかその手順すら理解できない自分です
開発などでお忙しいでしょうが、どうぞ今後共お時間のある時で結構ですので、ご指導宜しくお願いします

齋藤 滋