どうりで

先週末より kamakuralive.net, kamakuraheart.orgなどのサーバーに対する作業がすばやく反映されないとか、うまくいかないことが続きました

そして、先週開催した鎌倉ライブデモンストレーション実行委員会での Webを通じたプログラム更新作業が完全に破綻したのです

どうやらローカルでバグをとったプログラムを updateしたにもかかわらず server上では更新されていないことを掴みました しかも、その過程で明確なエラーが表示されなかったのです

訳が分からず色々なテストプログラムを書いてようやく、その原因の少なくとも1つが、Zenlogic側の FTPがうまく動作しないことによると掴みました そして、それを自ら改善してようやく正常なプログラムを uploadすることができるようになったのです そして本日やはりこんなメールが送られてきました

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 
【Zenlogic】FTP接続障害発生のお知らせ
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━201

ご利用いただいておりますZenlogicホスティングにおいて、先日実施いたしま
したFTPサーバー(ProFTPd)のバージョンアップの影響により、FTP接続ができ
ない事象が発生しております。
                記 

■日時: 2018年10月26日(金) 20時00分頃 ~

 ※時間は24時間表記です。
 ※上記日時から10月28日(日) 06時00分までの間で順次、FTPサーバー
  (ProFTPd)のバージョンアップを実施いたしましたので、発生日時は
  ご利用サーバーによって異なります。

■対象: Zenlogicホスティングをご利用のお客様

■原因: FTPサーバー(ProFTPd)のバージョンアップの影響によって
     サーバー上に設置されているシンボリックリンクが認識されない

■発生している事象:
 接続先ディレクトリを「www」および「ssl」に設定している場合、FTP接続
 ができない(接続先ディレクトリが見えない/エラーが発生する)

 ※WEBサイトの表示やPHP等のプログラムの動作に影響はございません。

もちろん上の表記ではずいぶんとはしょりました 本当に困りました

cssを用いて formを横並びで表示するには?

<form></form>は基本的に縦にしか並びません 何というのでしょうか ブロック要素と呼ぶのでしょうか

これを cssを用いて横並びに表示するのはどうすれば良いか、色々と検索したところここにヒットしました ありがたいことです それで早速用いました こんな感じです

<div style="display:inline-flex;">
  <form method="post" action="action1.php" class="form-inline text-left" style="margin-right: 0.3em;">
    <button type="submit" class="btn btn-sm" name="session" value="<?= $row['id'] ?>">Chair追加</button>
    <input type="hidden" name="role_kind" value="1"/>
    <input type="hidden" name="sessionNo" value="<?= _Q($row['sessionNo']); ?>"/>
  </form>
  <form method="post" action="action2.php" class="form-inline text-left">
    <button type="submit" class="btn btn-sm" name="session" value="<?= $row['id'] ?>">Chair追加 (Role数)</button>
    <input type="hidden" name="role_kind" value="1"/>
    <input type="hidden" name="sessionNo" value="<?= _Q($row['sessionNo']); ?>"/>
  </form>
</div>

これによりこんなふうに表示されて、2つのボタンが並びます

formを横並び表示する

ヘルシンキから神戸 そして 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>";

 

 

まったく大変でした そして HorliX

先週後半は心血管インターベンション最大の日本国内学会である CVITが神戸で開催されました 僕自身はこの学会から半分リタイアなのですが、会長の倉敷中央病院門田先生より、たくさんの仕事を仰せつかり、亡くなられた親友 光藤先生に対する恩返しも込め、たくさん仕事させて頂きました

このため、先週は水曜日に神戸に入り、土曜日夜まで仕事をしたのです 流石に老体には辛く、ぐったりと疲れ果ててしまいました

それと平行して、MacBook Pro late 2016のバグマシンに苦しめられたのです 既に公表しましたように、USB type-C portが都合 4 x 2 (だって一度修理だしたのだから)の内、3っつが効かなくなり、さらには Command Keyが作動しなくなり、もう何時このマシンは反応しなくなるのだろう、と恐怖に苛まれました

このため、MacBook Pro 2018を注文し、それが届いたのですが、今週はじめより、TimeMachineからのリカバリーを試みるも、新たにuser accountが設定されたり、とても気に食わなかったので、何と3回も High Sierraを更からインストールすると共に、SSDを初期化してこれまでの記憶をすべて消し去ったのです

とは言っても社会生活しているので完全に記憶を消滅することは叶わず、結局必要なアプリをインストールして、backupより主要なファイルをリカバーして、そして各種設定したあげく、何とか今現在ブログにもアクセス可能となり、現在の仕事で重要なファイルが作動することも確認できました それが完了したのは、実は 13:15に自宅出発して大船駅から電車で成田空港に移動なのですが、作業完了は何と本日 13:14でした

まったく滑り込みです

でも一ついいことがあるのです、それは最近メールでのコンタクトのみなのですが、DICOM Viewer開発者の air様から 「何と HorliXが Appleの審査に一発で通過し、AppStoreに挙げてある」との情報でした

それで、本日この New MachineにHorlixを AppStoreよりインストールしたのです DICOM dataは大量のものが、OsiriXからのものをこのマシンにコピーしてあるのでこれを使う予定です  Horlixの説明文には痺れますね かっこいい ぜひ皆様方も「時代は Horlixだ」と叫びながら Osirixから切り替えましょう

久しぶりの 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を保持しているかが分かり データの流れが把握しやすくなりました