OmniAICreator/Qiita-1.07M huggingface dataset:
FirstVRでリセンターを実装する

[前回の記事](https://qiita.com/ponZoo/items/b3c1564c7dd01f5cb373)で、FirstVRにもともと実装されているリセンター機能について説明しました。

今回は、このリセンター機能をボタンに実装してみようと思います。

SDKのダウンロード等の説明は、前回の記事を参照してください。

##実装
FVR/Samples/Scenesの中のOutputViewerを開きます。

今回もわかりやすいように、Cubeを手に入れ替えました。
<img width="1552" alt="スクリーンショット 2018-11-16 19.09.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/300418/f0dcd304-359e-0366-85c1-0bec6b80bdca.png">

SceneManagerにアタッチされているSampleViewerManager.csを以下のように書き換えます。

```C#:SampleViewerManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using FVRlib;

public class SampleViewerManager : MonoBehaviour {

	// FVR 
	public FVRConnection fvr;

	// vars
	public GameObject hand;
	bool touched = false;

	void Start () {
        hand = GameObject.Find("Hand_right");
	}


	void Update () {
        hand.transform.rotation = fvr.centeredRotation;

        /*** 以下をコメントアウト ***/
        //if (Input.touchCount == 1&&!touched) {
		//	fvr.Recenter ();
		//	touched = true;
		//}
		//if (Input.touchCount == 0&&touched) {			
		//	touched = false;
		//}
        /*** ここまでコメントアウト ***/
	}

    /*** 以下を追加 ***/
    public void RecenterButton(){
        fvr.Recenter();
    }
    /*** ここまで追加 ***/
}
```
コードを書き換えたら、シーンにボタンを設置します。

<img width="1440" alt="スクリーンショット 2018-11-16 19.52.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/300418/bed6c58d-90f9-11e8-9d4a-238f4c04aa3d.png">

<img width="1552" alt="スクリーンショット 2018-11-16 19.12.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/300418/1d813313-d3e0-ff88-89d4-cf06387ec6fb.png">

設置したら、ButtonオブジェクトのInspectorにあるOn Click()に項目を追加します。
SceneManagerをアタッチし、SampleViewerManager > RecenterButton()を選択します。
<img width="1440" alt="スクリーンショット 2018-11-16 19.18.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/300418/80a22453-ecfe-c03f-3d6a-464e786e1303.png">

これで、実装完了です。

##実機確認
スマホで実行してみると、こんな感じになります。
![IMG_0056.TRIM.gif](https://qiita-image-store.s3.amazonaws.com/0/300418/e90195f7-979f-8180-6a0f-a866e474d705.gif)
はじめてのGoogle Apps Scriptで棚卸ししてみようとして困った

#実態のあるモノの管理は大変

とてもたくさんある検証用端末の在庫確認が大変だったので、端末全部にシリアルナンバーのQRコード貼ってバーコードスキャナーでスキャンして一致したらチェックつけるとかできたら超便利なのではと思ったのでやってみた。
JSは触ったことがほぼ無い。

#はじめてのGAS
```javascript

while(query != "cancel"){  
  var query = Browser.inputBox("シリアルナンバーを入力し[OK]\\n中止する場合は[キャンセル]", 
                               Browser.Buttons.OK_CANCEL);
  for (var i = 3; i <= lastRow; i++){
    if (query == sheet.getRange(i, serialNumbersColumm).getValue()){
      sheet.getRange(i, checkBoxesCollum).setValue("✔");
    }
  }
}
```
バーコードリーダーはHIDとして認識されるので、バーコードやQRコードを読み込むと文字列を吐き出す。
`inputBox()`にバーコードリーダーを使ってシリアルナンバーの文字列を入力してOKを押す。入力されたシリアルナンバーと一致するものをスプレッドシート内にあるシリアルナンバーの列から探して、あったらチェックつける。キャンセルが押されるまでそれを繰り替えす。非常に単純。
`i`が3からなのは、シリアルナンバーが入ってるセルが3行目以降だから。




#思ったように動かない
上で書いたものは一応思ったようには動いた。ただ`for`ループの中で毎回`getRange()`と`getValue()`するのは重いのではと思い、今度はシリアルナンバーを`while`の外で配列に保存してみた。

```javascript
var serialNumbers = sheet.getRange(3, serialNumbersColumm, lastRow).getValues(); 
while(query != "cancel"){
  var query = Browser.inputBox("シリアルナンバーを入力し[OK]\\n中止する場合は[キャンセル]",
                               Browser.Buttons.OK_CANCEL);
  for (var i = 0; i <= lastRow; i++){
    if (query == serialNumbers[i]){
      sheet.getRange(i + 3, checkBoxesCollum).setValue("✔"); 
    }
  }
}
```
シリアルナンバー入力後にOKを押してから次の`inputBox()`のダイアログが出るのが明らかに速くなった。やったね。
ただチェックがOKを押した後すぐには反映されず、1つあるいは複数のシリアルナンバーを入力したあとに、ダイアログのキャンセルを押して`while`から抜けたときにまとめて`setValue()`される。

#どういうこと？
```javascript
while(query != "cancel"){
  var serialNumbers = sheet.getRange(3, serialNumbersColumm, lastRow).getValues(); 
  var query = Browser.inputBox("シリアルナンバーを入力し[OK]\\n中止する場合は[キャンセル]",
                               Browser.Buttons.OK_CANCEL);
  for (var i = 0; i <= lastRow; i++){
    if (query == serialNumbers[i]){
      sheet.getRange(i + 3, checkBoxesCollum).setValue("✔"); 
    }
  }
}
```
シリアルナンバーの配列への保存を`while`の中でやると思った通りの動作になる。けど、やってることは最初に書いたものと同じか、むしろいちいち配列に保存してるしでどっちにしろ遅い。

#なんで？
わかりません
IBM Cloud File StorageをPodにNFSv3でマウントする

# 経緯

IBM Cloud Kubernetes ServiceではStorageClassを指定したPVCを作成することでIBM Cloud File Storageを動的にオーダーできます。とても便利なのですが、そこで手に入れたPVをPodにマウントすると、NFSv4としてマウントされます。

一方、IBM Cloud File StorageではNFSはv3を使用することが**強く**推奨されているようです。そのため、PVの定義でマウントオプションを変更する必要があります。

# 手順

## 全部一斉に変える1 Liner

```
$ kubectl get pv -o name | cut -d "/" -f 2 | xargs -I {} kubectl patch pv {} -p '{"spec":{"mountOptions":["nfsvers=3"]}}'
```

なお、PVはnamespaceがないので上記コマンドで全てのPVがパッチされますのでご注意ください。
jquery.uiのdatepickerをiframeからはみ出させる

##動機
子画面として使用していたiframeが小さかったため、datepickerがテキストボックスを隠したり親画面の裏側に回り込んだりした。
しかしiframeを下に大きくするのはかっこ悪いので、見栄をはりたい。
![before.png](https://qiita-image-store.s3.amazonaws.com/0/307479/cdb66238-19a3-4708-da06-c9bf8ce84fe6.png)

##完成品
```javascript
"use strict";

$(document).ready(function(){
	//先に子フレームが閉じた場合の対策
	document.defaultView.onbeforeunload = function(event){$("#datepicker").datepicker("hide");};

	//datepicker作成
	$("#datepicker").datepicker({
		beforeShow:function(input,inst){
			const calendar = inst.dpDiv;
			//z-indexは親フレーム次第で要調整
			calendar[0].style["z-index"] = "9999";
			//親フレームのbodyに移動
			$('body', parent.document).append(calendar);
			//座標の原点が親フレームになるので、子フレームの座標分を調整
			setTimeout(function(){
				const pos = $(document.defaultView.frameElement).offset();
				$(calendar).css({
					top:"+=" + pos.top + "px",
					left:"+=" + pos.left + "px",
				});
			},1);
		},
	});
});
```
![after.png](https://qiita-image-store.s3.amazonaws.com/0/307479/a4738a30-7818-d2c3-19db-2672a090e078.png)

##参考にさせていただいた記事
[stackoverflow:Moving jquery datePicker outside of ifram](https://stackoverflow.com/questions/1217763/moving-jquery-datepicker-outside-of-iframe)
[qiita:iframe内のelementから親frameを含むpos座標を取得する方法](https://qiita.com/ozoneboy/items/b57bf4e67110b3756390)
[stackoverflow:iframe just before unload event](https://stackoverflow.com/questions/30718692/iframe-just-before-unload-event)
Ubuntu17.10にNVIDIAドライバをインストールしてみた。

素人のメモです。


# 1. 環境
　　　　・Ubuntu : 17.10
　　　　・グラフィックボード : GeForce GTX 1080
　　　　・ドライバ　: NVIDIA-Linux-x86_64-410.73.run


#2. NVIDIAドライバのインストール方法

以下のコマンドはドライバがインストールされていない場合は何も表示されません。
メモ程度に残しておきます。

GPUの種類の確認

```
~$ lspci | grep -i nvidia
```
NVIDIA driver version の確認

```
~$ cat /proc/driver/nvidia/version
```

GPUサマリ

```
~$ nvidia-smi
```

###1 . ドライバのインストール

以下のサイトからダウンロードしてください。
[ダウンロードページ](https://www.nvidia.co.jp/Download/index.aspx?lang=jp)

私の場合だと、**NVIDIA-Linux-x86_64-410.73.run**になります。

###2. コンソールモードに入る

```
Ctrl + Alt + F1
```
F1を押しても入れない場合は、F2~F5あたりで試してみてください。


###3. ユーザー名、パスワードを入力しログインする

以下のコマンドを入力し、実行権限を付加する

```
~$ sudo chmod 755 NVIDIA-Linux-x86_64-410.73.run
```

###4. GUIサービスの停止

```
~$ sudo /etc/init.d/gdm3 stop
```
ちなみにGUIサービスの再開は stop -> startに置き換えてください。




###5. ドライバの実行


```
$ sudo ./NVIDIA-Linux-x86_64-410.73.run 
```


これで実行できるはずだが、上手くいきませんでした。

そこで


```
ERROR: You appear to be running an X server; please exit X before          installing.  For further details, please see the section INSTALLING THE NVIDIA DRIVER in the README available on the Linux driver download page at www.nvidia.com.
```


のようなエラーが発生しました。
X server が動いているからインストールできないと。

対処法としては、

```
~$ ps ax | grep gdm
```
をタイプし、プロセスを停止させてください。

```
~$ sudo kill <PID>
```



これでできると思いましたが新たなエラーが...

```
ERROR: The Nouveau kernel driver is currently in use by your system.  This
         driver is incompatible with the NVIDIA driver, and must be disabled
         before proceeding.  Please consult the NVIDIA driver README and your
         Linux distribution's documentation for details on how to correctly
         disable the Nouveau kernel driver.
```

既存のドライバが入っているようなので、削除します。

こちらの対処法は、
/etc/modprobe.d/blacklist-nouveau.conf
に以下の内容を記載してください。

```blacklist-nouveau.conf
blacklist nouveau
options nouveau modeset=0
```
書き込んだら

```
~$ sudo update-initramfs -u
~$ sudo reboot
```

を実行してみてください。

インストール途中で

```
 error: Unable to find the development tool gcc in your path;. . .  
 error: Unable to find the development tool make in your path; . . .
```

のようなエラーが出てきますが

```
~$ sudo apt install gcc
~$ sudo apt install make
```
を実行させれば問題ないです。

これで上手くインストールできると思います。

これとは別にCUDAとcuDNNのインストールも後ほどアップロードしたいと思います。
リポジトリ

## リポジトリ
***コードの保管場所***
変更履歴として保存されている。
管理したいディレクトリをリポジトリの中に置くことで、そのディレクトリ内のファイルやディレクトリの変更履歴を記録することができる。
・リモートリポジトリ：サーバに配置して複数人で共有する用。
・ローカルリポジトリ：各人がそれぞれのPC上で使う用。
WindowsでNode.js環境構築

# nvm-windows
Windows  環境の Node.js の管理に `nvm-windows` を使用します。
nvm-windows は複数の Node.js 環境が必要なケースでバージョン切り替えなどの管理が楽になるツールです。
Linux、Mac環境では [nvm](https://github.com/creationix/nvm/) を使用します。
単独の Node.js 環境で十分な場合は、[公式インストーラ](https://nodejs.org/ja/) で十分です。
ウィザードに従ってインストールを行えば、Node.js とそれに対応したバージョンの npm がインストールされます。

## nvm-windows 最新インストール
nvm-setup.zip をダウンロードして解凍、nvm-setup.exe を実行します。
https://github.com/coreybutler/nvm-windows/releases/
インストールウィザードでは、nvm-windows のインストールディレクトリと Node.js のシンボリックリンクを作成するパスを選択します。
nvm-windows のインストールディレクトリはエスケープ考慮が無いようで、Program Files にインストールすると、nvm のコマンドが失敗します。
Node.js のシンボリックリンクのパスは Program Files を指定しても問題ありません。
インストールディレクトリとシンボリックリンクのパスに対し、ユーザー環境変数を通してパスが設定されます。
※現在時点のインストールバージョン : 1.1.7 (2018/8/2 リリース)

インストールが成功し、パスが通っていることを確認しましょう。

```
nvm version
```
実行結果（例）

```
1.1.7
```

## Node.js 最新インストール 
nvm-windows を利用して Node.js をインストールします。
Node.js と同時に npm のインストールも行われます。
npm は Node.js で作成されたライブラリを管理するツールです。
npm を利用することで、JavaScript のライブラリ管理が楽になります。
下記コマンドで最新バージョンの node.js とそれに対応した npm をインストールします。

```
nvm install latest
```
実行結果（例）

```
Downloading node.js version 11.7.0 (64-bit)...
Complete
Creating C:\node\nvm\temp

Downloading npm version 6.5.0... Complete
Installing npm v6.5.0...

Installation complete. If you want to use this version, type

nvm use 11.7.0
```
※npm は以下のサイトの表 Version 列の Node.js に対応する npm 列のバージョンがインストールされます。
https://nodejs.org/ja/download/releases/

インストールしたバージョンを既定のバージョンとして指定します。（例）    

```
nvm use 11.7.0
```
実行結果（例）

```
Now using node v11.7.0 (64-bit)
```
バージョンの確認

```
nvm list
```
実行結果（例）
現在選択されているバージョンに `*` が付きます。

```
  * 11.7.0 (Currently using 64-bit executable)
```
Node.js のバージョンを切り替える場合、`nvm use` コマンドを使用します。

Node.js のバージョンの確認

```
node -v
```
実行結果（例）

```
v11.7.0
```

npm のバージョンの確認

```
npm -v
```
実行結果（例）

```
6.5.0
```
vbsの作法

#概要

vbsの作法を調べてみた。
ConnectObjectで、イベントを捕らえてみた。

#写真

![image](https://qiita-image-store.s3.amazonaws.com/0/18104/086133df-7ac4-1e2d-9a90-b7fa404206aa.png)

#サンプルコード

```
Dim App6
Dim Appflg
Set App6 = Createobject("OHIcompo6.srv")
WScript.ConnectObject App6, "App6_"
App6.text = "hello"
Sub App6_exit()
	Appflg = 2
End Sub
Sub App6_ok()
	Msgbox App6.text
End Sub
Do
	WScript.Sleep(100)
	App6.ping
Loop until Appflg = 2
Set App6 = Nothing
```

以上。
StackStormで大量のログを扱うとFailedする(mistral-v2)


## 困ってること
st2のworkflowがfailedする。

1workflowから複数actionを呼び出しているが、大量のログを吐くタスクが正常終了した後、workflowがfailedになる。

```terminal
$ st2 execution get 5qehe8ktsmjq2ojy4wghq8ld
id: 5qehe8ktsmjq2ojy4wghq8ld
action.ref: hoge.fuga
parameters:
  size: 9600
  timeout: 1000
status: failed (68s elapsed)
start_timestamp: Thu, 15 Nov 2018 03:08:15 UTC
end_timestamp: Thu, 15 Nov 2018 03:09:23 UTC
+--------------------------+-------------------------+-------+-----------------------+----------------------------+
| id                       | status                  | task  | action                | start_timestamp            |
+--------------------------+-------------------------+-------+-----------------------+----------------------------+
| 5qehe8ktsmjq2ojy4wghq8ld | succeeded (65s elapsed) | task1 | hoge.fuga             | Thu, 15 Nov 2018 03:08:16  |
|                          |                         |       |                       | UTC                        |
+--------------------------+-------------------------+-------+-----------------------+----------------------------+
```

## 原因と解決
st2の設定値で1MBの制限があることが原因。
https://forum.stackstorm.com/t/allowing-large-results-in-mistral-workflows/139

上記URLによると、nginxのbody size checkとmistral自体の制限があるらしい。
以下を設定することで設定値を無制限にできる（上限値を入れる場合は、上限値の値を設定する）
※ quick installだと1MBで制限されているので、1MB以上のログを吐くworkflowがfailedになるらしい

### 設定内容
```text:/etc/mistral/mistral.conf
[engine]
# disable execution size checking
execution_field_size_limit_kb = -1
```
```text:/etc/nginx/conf.d/st2.conf
server {
    # disable body size checking
    client_max_body_size 0;
```

### 再起動
```terminal
$ sudo systemctl reload nginx
$ sudo st2ctl restart
```

## 補足
st2の動作を見ているとログの取扱オーバーヘッドが大きいように見える。
また、Web UIもログを見るのに適したUIとは思えないため（主観、大量ログを出力するとフィルタリングなどがしづらい）、詳細ログはstackdriverなどに入れて管理し、開始／終了／エラー時のtracelogだけを吐くなどに留めて置くほうが良いかも。

また、とりあえず無制限にしたが、あまりにも大きいログが入ってくると他のジョブ性能にも影響がでかねないため、制限値は検討しておいた方が良さそう。
docker-composeを使って、プライベートでstandaloneなgethを立ち上げて永続化する方法【失敗編】

https://m0t0k1ch1st0ry.com/blog/2017/11/12/ethereum-docker/
を参考に
https://github.com/m0t0k1ch1/ethereum-docker
でdocker-composeを使って、プライベートでstandaloneなgethを立ち上げます。

順調にすすみ、マイニングも始まります。接続して残高を確認。

```
$ docker exec -it geth geth attach rpc:http://localhost:8545

> eth.accounts
["0xe6e90fcdd98205bd23e0e17f6ec20ba5cab52228"]
> eth.getBalance(eth.accounts[0])
556000000000000000000
```

コンテナを停止します。

```
$ docker-compose stop
```

止まりますので、もう一度startします。gethに接続して残高を確認します。

```
$ docker-compose start
$ docker exec -it geth geth attach rpc:http://localhost:8545

> eth.getBalance(eth.accounts[0])
718000000000000000000
```

残高は保持されています。（マイニングしていたので増えてます）
コンテナの停止ではチェーンは維持されましたが、コンテナを削除してしまうとどうなるでしょうか？

```
$ docker-compose down
Stopping geth ... done
Removing geth ... done
Removing network standalone_default
```

再度upします。

```
$ docker-compose up -d
```

ログを見ると再度DAG生成が始まっています。残高を確認します。

```
$ docker exec -it geth geth attach rpc:http://localhost:8545

> eth.getBalance(eth.accounts[0])
1000000000000000000
```
まだマイニングが始まっていない状態なので、初期値しか入っていません。つまり、ブロックチェーンがdockerのdownのたびに再作成となっていて保持されていません。

これだと、開発としてはやりにくいので、ブロックチェーンが永続化されるようにしてみます。

前述のリポジトリをforkしていじってみます。

volumeの設定をします。

```Dockerfile
VOLUME ["/root/.ethereum"]
```

```Docker-compose.yml
    volumes:
      - ./gethdata:/root/.ethereum
```




起動の途中で`Initialised chain configuration          config="{ChainID: 1234…`となるはずだった箇所の前で

```
Writing default main-net genesis block
```

とでてしまい、プライベートネットワークの初期化が始まりません。

gethのソースコードを参照すると、このメッセージは、ジェネシスブロックが見つからないときに出るメッセージである。

どの時点かで、データディレクトリがなくなっているということのようだ。

#原因と解決方法

いろいろと試した結果、ジェネシスブロックはbuildの中でgeth initがRUNされたときに`/root/.ethreum`以下に適切に生成されている。

それが、コンテナ立ち上げのときにホストの空のディレクトリ`./gethdata` がマウントされて消えてしまう、というあたり前のことだった。

雰囲気でDockerやVOLUMEを使っていたせい。

解決編に続く。
Macのanaconda3にpolyglotをインストールする

## 前提
Macにpolyglotをインストールしようとしたのですが、icuがうまくインストールできませんでした。
Homebrewでicu4cをインストールしたつもりになっても、その後のpyicuのインストールでコケます。エラーメッセージは以下。
``FileNotFoundError: [Errno 2] No such file or directory: 'icu-config': 'icu-config'``
なので、anaconda3を用いればいいかもしれないと思い、普通にanaconda3で新規環境を用意してpipで各種ライブラリをインストールしようとすると、今度は``CompileError: command 'gcc' failed with exit status 1``といってgccの異常でコケます。
何これ、訳ワカンねぇよ！
とは思いましたが、何とか素直な感じにpolyglotをanaconda環境にインストールできたので、残しておきます。


## やり方
```bash
# Anacondaでpython3.6を指定してpolyglotと言う名前の仮想環境を作る
$conda create -n polyglot python=3.6 --no-deps -y
# 先ほど作った環境に移動
$source activate polyglot
# numpyは普通にインストール
$conda install numpy
# icuとpyicuをインストールするときにconda-forgeを指定する
$conda install -c conda-forge icu
$conda install -c conda-forge pyicu
# 残りの関連ライブラリをインストール
$pip install morfessor
$pip install pycld2
# ここまで来てようやくpolyglotをインストールします
$pip install polyglot
```
ちなみに、この方法を見つけるのには下記のコメントが役に立ちました。
https://github.com/aboSamoor/polyglot/issues/80#issuecomment-266301717
このコメントではicuは54.1を使えとありましたが、むしろそれだと上手くいかなかった（理由は忘れました、すみません…）ので、Anaconda Cloud ( https://anaconda.org/ ) から良さげなパッケージを検索して、conda-forgeのicuとpyicuを入れることにしました。
これで上手く行ってくれたのは本当に幸いでした。

### 余談
辞書等のダウンロード場所をセッティングするには、
``export POLYGLOT_DATA_PATH=/directry/you/choiced``
という環境変数を設定してあげてください。
Db2 : JSONデータをSQLで簡単に利用

Db2にはV10.5 FixPack1からMongoDB互換でJSONデータをデータベースに格納/照会できる機能がありました。

- Db2 NoSQL機能でJSONドキュメントを操作する3つの方法
    - [JSONドキュメントへのクライアント・アクセス](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.swg.im.dbclient.json.doc/doc/c0061316.html)


Db2 11.1.2.2からは、直接SQLを使ってJSONデータを保管や検索するサポートが追加されています。

わざわざNoSQLデータベースを用意する必要なく、JSONデータも手軽にRDBMSに格納しておきたい、SQLと一緒に使いたいという場合の簡単な方法になります。

- 参考
[モディフィケーション・パックおよびフィックスパックの更新](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.db2.luw.wn.doc/doc/c0061179.html#c0061179__MP2FP2
)

      - 開発者は SQL を使用して JSON データを直接保管および検索することができるようになりました。
JSON データは、BSON (バイナリー JSON) と呼ばれるバイナリー・エンコード形式で格納されます。開発者は、SQL ベースのルーチンを利用できるようになりました。



注）今後のDb2 11.1.4.4では更にJSON SQLファンクションの機能拡張がプランされています。


#Db2のJSON関数

SQL を使用して、JSON データの保管と取得を直接行う方法を見ていきます。

JSON 関連の関数は、JSON_VAL 関数を除いてすべてスキーマ SYSTOOLS にカタログされています。JSON_VAL はスキーマ SYSIBM にカタログされています。
（補足）これらの関数は、UTF-8 ベースのデータベース(Unicodeデータベース)に対して機能します。


|SYSTOOLS関数||
|:---|:---|
|JSON_VAL|JSON データを SQL データ・タイプで取得します|
|JSON_TABLE|2 つの列を持つ表を返します|
|JSON_TYPE|指定されたエレメントの BSON タイプを返します|
|JSON_LEN|JSON ドキュメント内の配列タイプのエレメント内にあるエレメント数を返します|
|BSON2JSON|バイナリー形式 (拡張 BSON) の JSON ドキュメントを判読可能な JSON テキスト形式に変換します|
|JSON2BSON|JSON ドキュメントを BSON 形式の同等のバイナリー表現に変換します|
|JSON_GET_POS_ARR_INDEX|JSON_TABLE 関数で配列値を抽出する必要なしに配列値を検索します|
|JSON_UPDATE|JSON_TABLE 関数で配列値を抽出する必要なしに配列値を検索します|
|BSON_VALIDATE|指定された BLOB データが有効な JSON データかどうかを検査します|

 

#参考資料



- [Db2 11.1 Knowledge Center](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.db2.luw.welcome.doc/doc/welcome.html)

    - [SYSTOOLS 関数](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.swg.im.dbclient.json.doc/doc/c0070298.html)
初めてのFTP~MacからFTP接続する~

# FTPとは
File Transfer Protocolの略。
ファイルを受け取ったり送信する際の決まりごと（プロトコル）です。

# FTPを使って何ができるのか？
簡単に行ってしまえば、Google Driveのようなものです。僕の上司はAmazon　S3のイメージだと言っていました。
誰かがファイルをFTPサーバー上にアップロードし、ユーザーはFTPクライアントからログインし、ファイルをダウンロードすることができます。
Google Driveのようにログイン情報が必要で、

- サーバーのホスト名
- ログインの時のUserID
- パスワード

を入力してアクセスします。

# SFTPって何？
SFTPはFTPの頭にSSHのSをつけたもの。
## FTPの弱点
FTPの弱点はデータの通信が暗号化されてないことです。なのでハッカーから侵入される危険性があります。ポートは20・21

## SFTP
FTPの機能を損なわず、SSHの安全性も兼ね備えているプロトコルです。sshなのでポートは22


# FTPの使い方
## 専用のツールを使う
これが一番楽です。

FileZilla
https://filezilla-project.org/download.php?show_all=1

こちらのサイトからアプリケーションをダウンロードして、そのGUI上でファイルの操作ができます。
僕は初めてFTPという単語を聞きましたが、5分くらいでファイルをダウンロードできました。

## CLIを使う
要はコマンドラインでコマンドを入力して接続するやり方です。

と思ったんですけど、現在MacOSからはFTP接続できないらしいです…

## 結論
Macからは専用のツールを使いましょう。
長期サポートバージョン Cognos Analytics 11.0.13のリリース

#Cognos Analytics 11.0.13のリリース
Cognos Analytics 11.0.13が2018年11月2日にリリースされています。

次バージョンである、Cognos Analytics 11.1がもうすぐリリース予定ですが、Cognos Analytics 11.0.13は、11.0.Xでの最終バージョンとなるようです。

このバージョンは、バグフィックスが中心で新機能はほとんど無いようですが、11.0.12までのバージョンと違い、長期サポートバージョン(LTS)という特別なバージョンになります。

Cognos Analyticsは、基本的に定期的にリリースアップし続けていく事でサポートを受け続ける事が可能ですが、11.0.13であれば、このバージョンのまま塩漬けにしても、基本2年間、延長契約で+1年間、合計3年の間、新規バグフィックス作成などのサポートを受ける事ができます。

この長期サポートバージョンは、次のCognos Analytics 11.1の場合、初期リリースから18ヶ月後くらいに11.1の長期サポートバージョンがリリースされる、という計画になるようです。

今Cognos Analytics 11.0.Xを使用されている環境では、一旦11.0.13に上げてしばらく塩漬けにしておいて、
・11.1の新機能を使いたい場合は、11.1.Xの適当なバージョンのリリースを待ってバージョンアップを行う
・新機能を特に使う予定が無い場合は、18ヶ月後に次の長期サポートバージョンが出たタイミングでバージョンアップを行う
というのが良いやり方なのかなと思います。

長期サポートバージョンに関して、こちらの記事もご確認下さい。
**IBM Cognos Analytics Long Term Support Release (LTS)**
https://www.ibm.com/communities/analytics/cognos-analytics-blog/ibm-cognos-analytics-long-term-support-release-lts-2/
【TIPS】Azure DevOpsのprivate agentでvstestがないエラー

> **Note:** 本記事は、2018年11月時点の内容です。

# 【Q】Azure DevOpsのPrivate Agentでvstestがないとエラーになった。なんでエラーになるの？

* ビルド時のエラーメッセージ例

```bash
No agent found in pool Default which satisfies the specified demands:
     msbuild
     visualstudio
     vstest
     Agent.Version -gtVersion 2.115.0 
```


# 【A】Private Agentの場合は、`Visual Studo Test Platform`のインストールが必要になる。

## 作業の手順
1. Visual Studio Test Platform Installerタスクの追加
2. Visual Studio Testタスクのオプション変更

### 【手順1】Visual Studio Test Platform Installerタスクの追加
* `Visual Studio Test Platform Installer`タスクを`Visual Studio Test`タスクの前に追加

### 【手順2】Visual Studio Testタスクのオプション変更
* `Visual Studio Test`のオプション`Test platform version`を`Installed by Tools Installer`に変更


## 参考資料

> **How can I set up VS Test Agent in Build tools enviroment.**

> * https://social.msdn.microsoft.com/Forums/en-US/65b1cf70-42e7-4698-9006-e2c5d997f6da/how-can-i-set-up-vs-test-agent-in-build-tools-enviroment?forum=tfsbuild

> **vstest task fails with Error: Visual Studio 2015 is not found. Try again with a version that exists on your build agent machine."**

> * https://github.com/Microsoft/vstest/issues/1349
【TIPS】vsts-agentのdocker imageで.Netがビルドできない

> **Note:** 本記事は、2018年11月時点の内容です。

# 【Q】vsts-agentのdocker imageで.Netのプロジェクトをビルドしたらエラーになった。なんでエラーになるの？

> **Docker Hub : vsts-agent** 

> * https://hub.docker.com/r/microsoft/vsts-agent/

> **Github : vsts-agent-docker**

> * https://github.com/Microsoft/vsts-agent-docker


* ビルド時のエラーメッセージ例

```bash
No agent found in pool Default which satisfies the specified demands:
     msbuild
     visualstudio
     Agent.Version -gtVersion 2.115.0 
```


# 【A】vsts-agentには、完全なMSBuild(.Net Coreのみ)が入っていないので.Netのビルドはエラーになるよ。docker imageを使わずに、Windows環境で、Build Toolをインストールしてね。

* vsts-agentに入っているツールは以下の通り。

```
Basic command-line utilities (curl, ftp, etc.)
Essential build tools (gcc, make, etc.)
Ansible 2.6.3
Azure CLI 2.0.38
CLang 6.0
CMake 3.10.2
Erlang/OTP 21
Firefox 61.0.1
GCC 5.4.0
Go 1.9.4 and 1.10
Google Chrome 68.0
Haskell 2014.2.0.0
Helm 2.9.1
Heroku CLI 7.7.10
HipHop VM (HHVM) 3.27.1
ImageMagick 6.8.9-9
Java OpenJDK 7 (1.7.0_95), 8 (1.8.0_181), 9 (1.9.0_4), 10 (1.10.0_2), and 11 (1.11.24)
Java tools (Ant 1.9.6, Gradle 4.6, Maven 3.3.9)
jq 1.5-1
kubectl 1.11.1
Mercurial 3.7.3
Miniconda 4.5.4
Mono 5.14.0.177
Microsoft SQL Server Client Tools 17.2.0.1
MySQL Client 5.7.23
MySQL Server 5.7.23
.NET Core SDK 2.1.400 (runtime 2.1.2)
Node.js 8.11.3 LTS (with bower, grunt, gulp, n, parcel, and webpack)
PhantomJS 2.1.1
PHP 5.6, 7.0, 7.1, and 7.2 (with composer, phpunit, and xdebug)
Pollinate 4.33
Powershell Core v6.1.0-preview.2
PyPy2 (6.0.0) and PyPy3 (6.0.0)
Python 2.7.15, 3.4.8, 3.5.5, 3.6.5 and 3.7.0 (available through the Use Python Version task)
rebar 3.6.1
rsync 3.1.1
Ruby 2.3.7, 2.4.4 and 2.5.1 (available through the Use Ruby Version task)
Scala sbt-extras
ShellCheck 0.3.7-5
Sphinx 2.2.9
Subversion 1.9.3
Terraform 0.11.8
xsltproc 1.1.28 and xalan 1.11
Xvfb 2:1.18.4
yarn 1.9.2
```

* ↓今後公開される可能性もありそうだが、まだの模様。

> **Github : MSBuild support** 

> * https://github.com/Microsoft/vsts-agent-docker/issues/44

> **Github : Any plans for releasing images for Windows Containers ??**

> * https://github.com/Microsoft/vsts-agent-docker/issues/1


* ↓公式ではないが、こんなのを公開している人もいる。ご参考まで。

> **Github : Building Windows Server Contianers with VSTS**

> * https://github.com/xtophs/vsts-building-windows-server-containers
ＭＳ（ＥＸＣＥＬ，ＡＣＣＥＳＳ）におけるMVCモデルとは（独断）

ＭＳ（ＥＸＣＥＬ，ＡＣＣＥＳＳ）のアプリケーションを作っていて、
ＭＶＣというものに当てはめるとどうなるのかを考えてみた。

１）ＡＣＣＥＳＳ
　アクセスはデータベースアプリケーションである。
　アプリケーションの中には、テーブル、クエリ、フォーム、レポート、マクロがある。

ＶＩＥＷ）　フォーム、レポート　→　これは確実にビューでしょう。

ＭＯＤＥＬ）　テーブル　→　データベースの中身なのでテーブルはモデルだろう。　
　　　　　　　　　　　　　　ＳＱＬを処理しているＡＣＣＥＳＳ本体もモデルということになる。

ＣＯＮＴＲＯＬ）　フォーム、クエリなどもコントロールだろう。
　　　　　　　　　マクロ、イベントプロージャは、用途によってはコントローラということになるかな・・・


２）ＥＸＣＥＬ
　エクセルはどうだろうか？
　エクセルの役目は、グラフを書いたり、シートにデータを入れたり、ピボットを計算したりすることになる。

　これはちょっと難解だ・・・

ＶＩＥＷ）　グラフ
ＭＯＤＥＬ）　シート、シート関数
ＣＯＮＴＲＯＬ）　ＶＢＡ


さて、ここまで書いたのには、それなりに理由がある。

ＡＣＣＥＳＳもＥＸＣＥＬも、半ば完成しているアプリケーションなので、
これはプログラミングからの観点からは、一種のフレームワークと見なせるのだ。

であれば、ＶＢＡのプログラミングでは、ＡＣＣＥＳＳ，ＥＸＣＥＬの良いところだけ使って、
あとは、プログラミングで補ったらどうかなと思うのである。



つまり、私の出した結論としては


１）ＭＯＤＥＬ　　バックエンドのＰＣ、共通ドライブに設置したＡＣＣＥＳＳテーブル
２）ＣＯＮＴＲＯＬ　　ローカルＰＣにインストールしたＡＣＣＥＳＳ（フォーム、クエリ）
３）ＶＩＥＷ　　　ローカルＰＣにインストールしたＥＸＣＥＬ（グラフ、ピポッドテーブル）

という構成で、プログラムを作るのがよさそうだ・・・


最近の流れ

ＭＳはＥＸＣＥＬにパワークエリと、パワーピボットなるものを入れてきた。
この流れは、ＣＯＮＴＲＯＬ、ＶＩＥＷをかなりＥＸＣＥＬ側に強化してきたような感じである。

しかしながら、いっぽうでパワークエリ、パワーピボットは、ＶＢＡでは扱えない。。。。

この流れが意味することは、ＥＸＣＥＬアプリケーションは、
もはやプログラミング可能なフレームワークとしてのニーズが
なくなってくるのではないだろうか？


で、思うところとしては、やはりＡＣＣＥＳＳ側をゴリゴリやりたくなってきた。
データベースは、別にアクセスじゃなくても、ＳＱＬサーバーとかＯＤＢＣでつなげばいいから

あとフォーム作成の容易さや、ＳＱＬやリレーションのＧＵＩが秀逸なので、
これは他のフレームワークには無い利点である。

足りないと思うのは、唯一グラフ表現のチープさである。

だから、ＪＡＶＡＳＣＲＩＰＴのＧＵＩライブラリを駆使して、
ブラウザ側で表記できれば、すんなり行くような気がする。

欲しいなと思う機能は、ＡＣＣＥＳＳのフォームを、ブラウザ側のＪＡＶＡＳＣＲＩＰＴから呼び出すか、
そっくりそのまま、フォームをブラウザベースで書き換えてくれるようなトランスレータだ。

これができれば、まだまだＶＢＡでのアプリ開発の可能性は
無限に広がるような気がしている。

（そうこうしているうちに、ＪＡＶＡＳＣＲＩＰＴ学習が進んだ暁には、
ＭＯＤＥＬもＮＯＤＥｓ．ＪＳでやれたりするんだろうけど。。。
そのときには、ＭＳからは離脱していくんだろうなあ）

そんな流れもあるので、ＭＳはＶＳＣＯＤＥやＡＺＵＲＥにも力を入れ始めたんじゃないかなあ
と勝手に思っている
初投稿：Advent Calendarに投稿することになった

諸事情でAdvent Calendarに投稿をする機会を得た。
ので、ちょっと本番前に投稿練習をしてみる。が・・・
#Qiitaってそもそもなんなの？

そもそもここから分かっていない。企画に参加するのはいいが、
Qiitaって本来何をするところで、自分どんな話題を投稿すべきなのか。
なんかその辺のブログサイトではないよね？さすがに日記とかは書いてる人見たことないし。


いや、なんかIT関連の調べものしててググったらQiitaのページが出てきたことはある。
だから、多くの人がそういうナレッジを適当に吐き出してる場所、という認識。
これでおそらく大枠は外れない気もするが、今まで一切気にしてなかったし、
今回自分が投稿することになったので、一応調べてみた。

[wikipedia](https://ja.wikipedia.org/wiki/Qiita)によると、
>Qiita（キータ）は、Incrementsが運営するプログラミング情報のナレッジコミュニティ。2016年現在で日本最大のプログラマーコミュニティとされている

とのことだ。

え？プログラミング？
いや、なんかスクラムとか開発の手法みたいなの紹介してるのもあるし、
そもそも開発関係ないコマンドTIPSみたいなのもあるよ？
いいの？これ？
 
まあおそらく、コミュニティの人数も多いし、プログラミングだけに話題を絞るのはもったいないので、
いろんな分野の技術的知識の共有をしていこうよ！という感じで、元々のテーマは**事実上無視されている** というのが正なんだろうか。

私には良い記事なんぞかける力も才能もないし、とても言葉が悪いのはわかっているが
それを承知であえて言わせてもらうと、テーマとすそ野を大きく広げるとそれだけ記載レベルは散らばりを見せ、クソ記事も量産化されるわけである。そして、この記事もそんなクソの一部である。
これはQiitaだけの問題ではないだろうが、せめて検索妨害にならないよう、自分でクソ記事ですフラグとか立てられないものか。


#で、Advent Calendarってなに？
そしてこれも分かっていない。
いや、何となく「特定のテーマにしたがってみんなで連続投稿する」ってのは、説明は受けていないが理解している。
が、自分だけ一人逸脱したことをしてしまったら申し訳ないので一応調べてみる。

[wikipedia](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%89%E3%83%99%E3%83%B3%E3%83%88%E3%82%AB%E3%83%AC%E3%83%B3%E3%83%80%E3%83%BC)によると、Advent Calendarとは本来以下の用途で使用されるものとのこと。
>アドベントカレンダー (Advent calendar) は、クリスマスまでの期間に日数を数えるために使用されるカレンダーである。待降節の期間（イエス・キリストの降誕を待ち望む期間）に窓を毎日ひとつずつ開けていくカレンダーである。すべての窓を開け終わるとクリスマスを迎えたことになる。 

これがいつしか、クリスマスまで記事の連像投稿みんなでしようぜ！的なノリになったようだ。
どうせオタクのエンジニアどもはクリスマスとか暇だろうし勉強しようぜ、ということだろうか。

ふむ、理にかなった企画だ。

つまるところ、現時点で本筋とは違う使い方してるし、テーマにそってればあんまり細かいこと気にすることはないよ、と。

#結局
ってことで、まぁとりえあず見出し、引用、リンクの書き方はわかった。
というか、[チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)やヘルプの見方がわかったので、細かいことは調べながらできるだろう。

基本的に私はひねくれた人間なので、
恐らく、すぐに役に立つ！みたいな知識は投稿しない。

たとえば最近ならHCIやハイブリッドクラウドなどの構成解説やいくつかのユースケース、
最適な利用シーンはどういうのが考えられるか？などを分析すると喜ばれそうな気はするが、
私がそんなことを書くわけはないのであった。
Carrierwave で filename にタイムスタンプを使用するとたまに画像が表示されない問題

## 前提
- Ruby on Rails で画像投稿機能を実装
- 画像は AWS s3 に保存

ここまでの流れは以下の記事などを参考にしてください。

[Railsでcarrierwaveを使ってAWS S3に画像をアップロードする手順を画像付きで説明する](https://qiita.com/junara/items/1899f23c091bcee3b058)

ただ今回の記事の内容では s3 を使用していることは特に関係ありません。

保存する際のファイル名は以下のように**現在時刻**のタイムスタンプを使用するように変更しました。

```rb
class ImageUploader < CarrierWave::Uploader::Base

  # （中略）

  def filename
    "#{Time.now.to_i}-#{original_filename}" if original_filename
  end
end
```

## 問題
アップロードした画像が「たまに」表示されない（リンク切れしてる）

## 原因
データベースに保存されている画像のファイル名
`1542353427-sample.png`

実際のファイル名
`1542353428-sample.png`

＿人人人人人人人＿
＞　微妙に違う　＜
￣Y^Y^Y^Y^Y^Y^Y￣

タイムスタンプの下一桁が異なっているので、おそらくどこかで時間に差が出てしまっている、と考えられますね。

Carrierwave 公式のwikiにも以下のように書いてありました。

https://github.com/carrierwaveuploader/carrierwave/wiki/How-to:-Use-a-timestamp-in-file-names

> you might get different timestamps written to the database and the file store.

データベースとファイルストアで違うタイムスタンプになるかもよ、と見事にはめられてしまったような気分です。

## 解決策
上記リンクを見た方はもう気づいているかと思いますが、Wikiに書いてあるように一時的にタイムスタンプをインスタンス変数として保存して、それをファイル名に利用すればいいのですね。

```rb
def filename
  @name ||= "#{timestamp}-#{super}" if original_filename.present? and super.present?
end

def timestamp
  var = :"@#{mounted_as}_timestamp"
  model.instance_variable_get(var) or model.instance_variable_set(var, Time.now.to_i)
end
```
（上記コードはWikiからコピペしてきました。）

`timestamp` メソッドの中ですが、`instance_variable_set`は戻り値としてセットした値を返すので、「ゲットする、またはセットする（セットした値を返す）」という処理でうまくいくようです。

## その他
この手の問題、過去にも悩まされた気がする...笑
クエリ解析メモ@編集中

目的
sql文に含まれるテーブル名を抽出したい
環境
Postgresql
Python 3.X

メモ
・with 句がクエリに含まれる場合、テーブル名は正しく表示されない
issueとしてsqlparseのgithubに上がっている(#404)
https://github.com/andialbrecht/sqlparse/issues
参考
https://stackoverflow.com/questions/30327632/get-all-tokens-using-sqlparse-recursively



```py
import sqlparse
from sqlparse.sql import Where, Comparison, Parenthesis, Identifier


class RecursiveTokenParser(object):
 def __init__(self, query):
    self.query = query
    self.names = []

 def get_table_names(self):
    elements = sqlparse.parse(self.query)

    for token in elements[0].tokens:

        if isinstance(token, Identifier):
            self.identifier(token)
        elif isinstance(token, Parenthesis):
            self.parenthesis(token)
        elif isinstance(token, Where):
            self.where(token)

    return [str(name) for name in self.names]

 def where(self, token):

    for subtoken in token.tokens:
        if isinstance(subtoken, Comparison):
            self.comparison(subtoken)

 def comparison(self, token):
    for subtoken in token.tokens:
        if isinstance(subtoken, Parenthesis):
            self.parenthesis(subtoken)

 def parenthesis(self, token):

    for subtoken in token.tokens:
        if isinstance(subtoken, Identifier):
            self.identifier(subtoken)
        elif isinstance(subtoken, Parenthesis):
            self.parenthesis(subtoken)

 def identifier(self, token):
    self.names.append(token)

 def get_query(self):  #
    return self.query


sql2 = """

With 
a as
(
 select 
   x,y
from g
)

select
x, y,z
from b
left join a
on b.id = a.id



"""
t = RecursiveTokenParser(sql2)

print(t.get_query())
print(t.get_table_names())
```
フォームの継ぎ合わせ

# ふたつの `begin`

プログラミング言語 Scheme の中で比較的頻繁に現れる構文として `begin` がある。 複数の式をひとつにまとめる構文で、おそらくは `if` と共に使う場合が多いのではないだろうか。

```
(if foo
    (begin (display "Hello, world") (newline)))
```

R5RS だとちょっとあやふやでわかり難いのだが、 R6RS と R7RS では `begin` は二種類あることが明記されている。 `begin` を使用する場所によって意味が切り替わるのだ。

- 上述の例のように、通常の式として表われる場合
- `<body>` 部やトップレベルなどに表われる場合

単純に複数の式をひとつにまとめるのはわかりやすい例で、 C などの文法で言うところの `{` `}` と同じような感覚だろう。

# `begin` の継ぎ合わせ

特殊な動作をするのは `<body>` 部やトップレベルなどに現われた場合だ。 `<body>` 部の詳細な定義はここでは述べないが、たとえば `lambda` 構文で引数の次の場所はそのひとつだ。

```
(lambda <formals> <body>)
```

`<body>` 部に現れる `begin` は上位フォームへの継ぎ合わせ (splicing) がおこなわれる。

つまり、たとえば

```
(lambda ()
  (display "Hello,")
  (begin (display "World")
         (newline)))
```

という式があった場合、 `begin` の内側はその外側にあるのと同じようにふるまうので、

```
(lambda ()
  (display "Hello,")
  (display "World")
  (newline))
```

と同じことになる。 要するに、 `begin` で囲まないのと同じだということだ。

# `begin` の継ぎ合わせが必要な理由

あってもなくても同じならどういうときに使うのかと思うかもしれない。 それは主にマクロのためだ。 マクロはひとつの式をひとつの式に変換するが、出力結果を複数の式にしたいこともある。 そういったときに見掛け上をひとつの式にするために `begin` でくるむのである。

たとえば、同じ値に束縛をたくさん作りたいようなことがあったとき、

```
(define a 0)
(define b 0)
(define c 0)
```

という風に並べるのは面倒であるから、一度に指定できるようなマクロを作ろうとするとこうなる。

```
(define-syntax define-zero
  (syntax-rules ()
    ((_ id ...)
     (begin (define id 0) ...))))

(define-zero a b c) ;; 使用例
(display a) ;; a は 0 に束縛されている

```

もしも、このときに `begin` が C などの `{` `}` と同じようにスコープを形成してしまうのだと、マクロで定義系の構文を生成するのは強い制限がかかることになってしまう。 `begin` が上位フォームに継ぎ合わされる (実質的に `begin` で__囲まないのと同じになる__) という、一見して奇妙にも思える規則はこうして有用に役立てられるのである。

# `let-syntax` と `letrec-syntax` の継ぎ合わせ

継ぎ合わせが起こるのは `begin` だけではない。 R6RS の `let-syntax` や `letrec-syntax` もそうだ。 ただ、 R5RS や R7RS ではこれらの構文では継ぎ合わせは起こらないという違いがある。

このような式を書いた場合、

```
(let ((foo 'a))
  (let-syntax ()
    (define foo 'b)
    'dummy-for-r7rs)
  foo)
```

R6RS では `'b` になるが、 R5RS や R7RS では `'a` となるという違いになって現われる。

とても地味な違いだが、<ruby><rb>凝</rb><rp>(</rp><rt>こ</rt><rp>)</rp></ruby>ったマクロを考えるときには R6RS の方がやりやすいと私は感じている。 継ぎ合わせをしてくれる場合には継ぎ合わせが起こって欲しくない箇所を適当に `let` でくるめば済むが、継ぎ合わせが起こらない分には継ぎ合わせを引き起こすことは出来ないので使い分けられないからだ。
azureにJenkinsのagentnodeのイメージを作成する

# azureのVMでの作業

dockerをインストール

https://docs.docker.com/install/linux/docker-ce/ubuntu/#set-up-the-repository

Javaをインストール

sudo apt install openjdk-8-jre-headless

/etc/docker/daemon.jsonに以下を書き込み

```
cat /etc/docker/daemon.json
{
"graph":"/mnt/docker"
}

```

これをしないとプライベートリポジトリにログインできない
https://qiita.com/dz_/items/2bb8c03a6fc797d30acd

```
sudo echo "nameserver 8.8.8.8" >> /etc/resolv.conf
```

azureのvmでは`/mnt`配下に作ったものはイメージ化してしまうと消えてしまう。
この段階でVMをimage化

# Slave起動後の設定

Jenkins作業用ディレクトリ作成

```
sudo mkdir /mnt/jenkins
sudo chown -R sbadmin.sbadmin /mnt/jenkins
```
権限の変更

```
sudo chmod 777 /var/run/docker.sock
sudo timedatectl set-timezone Asia/Tokyo
```
dockerでvue.jsコンテナを作る(vue-cli3)

## tl;dr
Vue.jsの環境をDockerで作ってみる。
※ createコマンドで作成 (vue-cli3.x系)

## ファイル構成
https://github.com/reflet/docker-vue.js-cli3

```:ファイル構成
├ src                       <- ソースコードを格納するフォルダ
├ docker-compose.prod.yml   <- docker-compose(本番)
├ docker-compose.yml        <- docker-compose(開発)
├ Dockerfile                <- Dockerfile(開発)
├ Dockerfile.prod           <- Dockerfile(本番)
└ README.md
```

## srcフォルダ作成
vue.jsのコードが展開されるフォルダを作成する。

```bash:ターミナル
$ mkdir src
```

## Dockerfileファイル作成
※ ライブラリのインストール先は、`/node_modules`フォルダに変更する

```dockerfile:Dockerfile
FROM node:11.1
RUN npm install -g @vue/cli

WORKDIR /app
COPY src .
RUN yarn install

EXPOSE 8080
CMD ["yarn", "serve"]
```
## docker-compose.ymlファイル作成
```yml:docker-compose.yml
version: '2'
services:
  web:
    build: .
    image: my/web
    container_name: 'web'
    ports:
      - '80:8080'
    volumes:
      - ./src:/app
```

## Vue.jsのプロジェクト作成
プロジェクト作成のコマンドを実行する。
※ これにより、srcフォルダ内にvue.jsのファイルが作成される

```bash:ターミナル
$ docker-compose run --rm web vue create .
```

ソースコードがsrcフォルダに作られる際に、`node_modulesができるので削除。

```bash:ターミナル
$ rm -rf src/node_modules/
```

インストール先を`/node_modules`に変更しているため、`.yanrc`ファイル追加。

```:src/.yanrc
--modules-folder /node_modules
```

## コンテナイメージ再作成
srcフォルダに作られたvue.jsのコードを取り込んでコンテナイメージを再作成する。

```bash:ターミナル
$ docker-compose build
```
## コンテナ起動
```
$ docker-compose up -d
```

Vueのバージョンを確認してみる

```
$ docker-compose exec web vue -V
3.1.3
```


## 動作確認
```bash:ターミナル
 $ open http://192.168.99.100
```
![test.png](https://qiita-image-store.s3.amazonaws.com/0/142279/b0a9a032-0c9c-5bd5-ce2b-cda97f57322f.png)

## 本番環境用の設定追加
本番環境では、構築方法が少し異なるので、別途作成します。

### Dockerfile.prod作成
dockerの機能にマルチステージビルドというものがあるようですね。
nodeコンテナでビルドを行い、、作成されたファイルをコピーしてnginxを起動できるようです。

コンテナが複数使い回せて便利♪

```dockerfile:Dockerfile.prod
# ビルド環境
FROM node:11.1 as build-stage
WORKDIR /app
COPY src .
RUN yarn install
RUN yarn run build

# 本番環境
FROM nginx:1.13.12 as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
```

### docker-compose.prod.ymlファイル作成
Dockerfile名とnginxがポートが異なるため、docker-compose.ymlファイルも別途作成する。

```yml:docker-compose.prod.yml
version: '2'
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile.prod
    image: my/web
    container_name: 'web'
    ports:
      - '80:80'
```

### コンテナ起動
本番用の設定で起動してみる。

```bash:ターミナル
# コンテナ起動
$ docker-compose -f docker-compose.prod.yml up -d --build

# コンテナ確認
$ docker-compose ps
Name         Command          State         Ports       
--------------------------------------------------------
web    nginx -g daemon off;   Up      0.0.0.0:80->80/tcp

# ブラウザ確認
$ open http://192.168.99.100

# コンテナ停止 ＆ 破棄
$ docker-compose -f docker-compose.prod.yml down
```

## DockerHubに登録
Create Automated Buildからgithubのリポジトリを登録する。
![dockerhub.png](https://qiita-image-store.s3.amazonaws.com/0/142279/5274c0e1-d909-aaf1-5bed-adeb92c7a456.png)
※ https://hub.docker.com/r/reflet/docker-vue.js-cli3/

これで、ひな形のコンテナはできました。
実際のアプリを作る際は、このDockerコンテナを使って作れそうです。

以上

## 参考サイト
- [Vue.js アプリケーションを Docker 化する](https://jp.vuejs.org/v2/cookbook/dockerize-vuejs-app.html)
What will you do next?


streampack です。
最近技術ネタが乏しく困っている時に、Inter BEE 2018(国際放送機器展) に出展してきました。今回で２回目です。

![Image from iOS (3).jpg](https://qiita-image-store.s3.amazonaws.com/0/232803/c5fa7fc0-49a0-e95e-1ed8-794b25ba6817.jpeg)

今年は、streampack VOD lite を発表してきました。 
今までと違うのは、安価で自動化でインフラ・アプリを構築し管理CMS・変換・配信・プレイヤーを提供できるところです。

去年の 2017年は streampack インテリジェンス機能(動画解析) に比べると...

https://cloudpack.jp/info/20171107.html

インパクトにかけ今更感は否めないですが、安価に動画配信したいニーズもちらほらあり、クローズドで社内向けの配信や過去に溜まったハードディスクをクラウドで動画管理したいお客様にとっては最適なプランかと思っています。

今回の Inter BEE では、、

### AI関連

黒柳徹子さんと会話できる AI ロボット。
AIよりも、黒柳さん製作精度がすごい。

![1672819B-1DF4-4847-A13A-C5512A19602C.jpeg](https://qiita-image-store.s3.amazonaws.com/0/232803/6dbd3c3c-aa56-1493-ebb2-d0c372c8f160.jpeg)

去年と比較すると多かったのは、 AI 動画解析関連でしょうか。
動画から字幕におこしたり、メタ情報を抽出し管理したりなどをやっているところをちらほら見かけました。

やることはできるけど、精度がねぇっと思ってたところ、
某Cloudのセッションで

*"AIの精度に100%はない"*

という名言の説明され、人間に正しいかを促す仕組みづくりをされて、
精度をあげているところに共感を受けたので、そこまで提供できてこそ
AI なんじゃないかと共感できるところがありました。

### 8kテレビ / ディスプレイ

Sony などのディスプレイ

う〜ん、見慣れたせいか、あまり良さがわからず。
4K で十分な気がしました。

こっちのディスプレイの方がおしゃれで実用的で使われそうな気がしました。

![Image from iOS (2).jpg](https://qiita-image-store.s3.amazonaws.com/0/232803/b742efe2-d480-3794-841e-26a2b35a2d7f.jpeg)


### 5G体験バス

![Image from iOS (5).jpg](https://qiita-image-store.s3.amazonaws.com/0/232803/2946e211-37b7-0fbe-3eb5-5c34ba12be4a.jpeg)

5G を体験できるバスが提供されてました。(ただし40分待ち・・・)
4G提供されだしてから、動画が快適に見れるようになり、電車などで YouTube などを見る人が増えたことを思い出します。従来の数百倍の速度で提供できることから、今後の動画ビジネスもまた変わりそうですね。

5Gの回線で
4k映像をVRで
ライブでデータを解析しながら
マルチアングルで
2020年オリンピックを観戦している
かもしれませんね。

将来を見据えて動かねばと、改めて実感するイベントでした。

What will you do next?
あなたなら何をしますか？
systemd-nspawnでコンテナ内からrebootできない問題と、その回避策について

# コンテナの中からrebootできない問題

Debian Stretchで採用されているsystemd 232では、systemd-nspwanコンテナの中で`reboot`コマンドを叩いても、コンテナが停止するだけで再起動してくれません。

https://github.com/systemd/systemd/issues/2809

このissueが関連しているようで、

https://github.com/systemd/systemd/pull/10306

このpull requestがパッチのようで、最近（2018-11-10）にmergeされたようです。

この修正はおそらくsystemd 240に含まれるものと考えられますが、Debian Stretchの現行バージョンにパッチが当てられるのかどうかはよくわからなかったので、ワークアラウンドを用意してみました。


# ワークアラウンド

コンテナで`/boot/reboot`という空のファイルがつくられたかどうかをホスト側から監視して、ファイルがつくられていて、かつコンテナがシャットダウン状態であればコンテナを起動する、という手順でrebootの代用にします。

## ホスト側の手順

```sh:/usr/local/sbin/nspawn_reboot_watchd
#!/bin/sh

while :; do
  ls /var/lib/machines |
  while read machine; do
    if  # "reboot" が存在していてかつ, コンテナが停止していれば
      test -f "/var/lib/machines/${machine}/boot/reboot" &&
      ! ( /bin/machinectl | grep "^${machine}" > /dev/null );
    then
      #echo "${machine} need reboot"
      echo "reboot container: ${machine}"
      rm "/var/lib/machines/${machine}/boot/reboot"  # rebootファイルを削除
      /bin/machinectl start ${machine}               # コンテナを再起動
    fi
  done
  sleep 5
done
```

```systemd.unit:/etc/systemd/system/nspawn_reboot_watchd.service 
[Unit]
Description=nspawn reboot watch
After=systemd-machined.service

[Service]
ExecStart=/usr/local/sbin/nspawn_reboot_watchd
Restart=always
RestartSec=5
StartLimitBurst=0

[Install]
WantedBy=multi-user.target
```

```shell-session
$ chmod +x /usr/local/sbin/nspawn_reboot_watchd
$ systemctl enable nspawn_reboot_watchd.service
# systemctl start nspawn_reboot_watchd.service
```

## コンテン側の手順

- `/boot/reboot`を作成して、シャットダウンするシェルスクリプトをつくり、rebootコマンドと置き換えます

```shell-session:コンテナ側の手順
$ cat <<EOF > /usr/local/sbin/nspawn-reboot
#!/bin/sh
touch /boot/reboot
shutdown -h now
EOF
$ chmod +x /usr/local/sbin/nspawn-reboot
$ unlink /sbin/reboot                                  # rebootコマンドを置き換える
$ ln -s -T /usr/local/sbin/nspawn-reboot /sbin/reboot  # rebootコマンドを置き換える
```

# 最後に

- systemdの方針として、古いバージョンでバグが見つかっても対応するのは各ディストリビューションの責任で、systemdとして旧バージョンに対するパッチを提供することは無いらしい
  - https://github.com/systemd/systemd/blob/master/docs/CONTRIBUTING.md#filing-issues
- Debianにおいて、メジャーバージョンが変わらない間にsystemdがバージョンアップされることがあるのかどうかとか、systemdでバグが見つかった場合のDebianチームの対応がどうなってるのかとか、そういえばなんも知らないので、調べとかないといけないと思った
Nintendo Switchから投稿された動画に自分を探す(4/4)

ここんとこなんかいろいろあって、最近はゴミ記事が増えて目的の記事を探すのが大変になった、とかいう意見も散見したけど、なに言ってんだネットなんてとっくの昔からノイズだらけだ、検索スキル磨けや、としか思わなかったので皆さんも気にせずどんどん書きましょうね。


さて、前回(3/4)
https://qiita.com/floatnflow/items/d0accb0689a51b8b01b0
の続き。

## OpenCVはイカの文字を読みやすくするか
文字認識の正答率を高めるために画像処理をしようという話。画面から切り出した文字をいかに学習データ(フォントでのレンダリング画像)に近づけるか、ということになると思われます。

使えそうなアルゴリズムは悠久の昔から先人の皆さんがいろいろと考えてくれてましてですね、今回少し勉強してみましたがなかなか感心してしまいますね。何気なく使っていたアンシャープマスクって、そんなタコが自分の足食ってるような原理でいいのか！とか。また、画像処理の多くは行列に対する演算処理なので、OpenCVが画像をndarrayで扱っているのも非常に理にかなっています。

試したのは、

画像 | 処理 | 関連するOpenCV関数
---|---|---
![org.png](https://qiita-image-store.s3.amazonaws.com/0/287199/416cd259-4f48-8a68-68d6-9a37b628bd9a.png) | オリジナル | -
![pr_01.png](https://qiita-image-store.s3.amazonaws.com/0/287199/3d0eac9f-6c4a-1a09-8c48-964318b9d9ac.png) | 平準化 (blur) | cv2.GaussianBlur() 等
![pr_02.png](https://qiita-image-store.s3.amazonaws.com/0/287199/6a9f9f7f-b236-20aa-c34e-0f58009eea54.png) | 反転 (invert) | cv2.bitwise_not()
![pr_03.png](https://qiita-image-store.s3.amazonaws.com/0/287199/ba3390f1-619d-dd96-6f00-ec5857f260e2.png) | グレイスケール | cv2.cvtColor()
![pr_04.png](https://qiita-image-store.s3.amazonaws.com/0/287199/0c14a821-2831-a1c7-45cb-f992572b4db8.png) | コントラスト | cv2.LUT()
![pr_05.png](https://qiita-image-store.s3.amazonaws.com/0/287199/0d3b8b24-ae67-2335-b94e-03b0751dd3a4.png) | 先鋭化 (unsharp mask) | cv2.addWeighted()
![pr_06.png](https://qiita-image-store.s3.amazonaws.com/0/287199/a0369757-e044-9557-380e-4c577b6c85ed.png) | 侵食 (erotion) | cv2.erode()
![pr_07.png](https://qiita-image-store.s3.amazonaws.com/0/287199/cc91df37-1f71-65d5-c7a9-52b4ab9aea46.png) | 拡張 (dilation) | cv2.dilate()
![pr_08.png](https://qiita-image-store.s3.amazonaws.com/0/287199/a374cd6e-180d-eca0-0e41-61d254182bb9.png)| 二値化 | cv2.threshold()

組合せやパラメータで認識結果がころころ変わるので、簡単なアプリ

![app.jpg](https://qiita-image-store.s3.amazonaws.com/0/287199/b6f0247c-186c-9c9e-69ad-c31af81d140d.jpeg)

を作っていろいろと試してみましたが、なかなか全体を最適化するのは難しいですね。あちらを立てればこちらが立たずのような。

なので結果的にこの工程はあまり意味なかったです。


## 終わりに
ということで、「運がよければ自分がやられたときの動画なら見つかるかもね」くらいのアプリケーションになりました。誤認識されやすい文字をそんなに使っていなければかなり正確に検出してくれますが、そもそも自分を倒したプレイヤーがその瞬間を含む動画をどれくらいアップしてるのかっつー話ですよ。

OpenCVやTesseractはなかなか素晴らしいツールです。Tesseract4.0のLSTMはどんくらい精度が上がってるのか楽しみですね。

私はサーバを持っていないので今回のアプリケーションを公開する予定はありませんが、もし公開するなら毎度OAuthで各自に検索させるのは非常に無駄が多いので、定期的にデータを収集してTweetのIDと認識したプレイヤー名のリストをDBに保存し、それに対する検索(あいまいオプション付き)という実装がいいでしょうね。

それにしてもいい加減月ごとのルールとステージ固定やめてくれないもんかな。

(了)
Memo > React or Vue



メモです。

Reactがいいのか、いやいや、Vueもいいのか、と迷っている自分向けのメモです。



2018年06月16日
[ReactとVueのどちらを選ぶか - Qiita](https://qiita.com/yoichiwo7/items/236b6535695ea67b4fbe)


24 DECEMBER 2017
[Vue.js vs React in 2017: state of art](https://pixeljets.com/blog/vue-js-vs-react-what-to-expect-in-2018/)

10 DECEMBER 2016
[Why we chose Vue.js over React](https://pixeljets.com/blog/why-we-chose-vuejs-over-react/)
Spring FrameworkとSpring Bootのいろんな対応表

備忘録として。
# Spring Framework
| バージョン | GA           | 対応Javaバージョン |
|:---------:|:------------:|:-----------------:|
| 4.3       | 2016年1月     | 6～8             |
| 5.0       | 2017年9月     | 8～10            |
| 5.1       | 2018年9月     | 8～12            |
| 5.2       | 2019年1月     | 8～15            |
| 5.3       | 2020年10月27日 | 8～19(予定)     |
| 6.0       | ~~2022年10月予定~~<br>2022年11月16日 | 17～   |
| 6.1       | [2023年11月16日](https://spring.io/blog/2023/11/16/spring-framework-6-1-goes-ga) | 17～ (※21対応)   |
> 対応Javaバージョンについてはレンジで書いているが、基本的にLTSリリース（8, 11, 17, 23, , ,）を使うことが推奨されている模様。

> 2022年10月現在、LTSリリース周期を3年から2年に変更する方向で議論中だそうです。もし2年になると 17 の次は 21 になります。

> 2023年9月19日、Java21 が LTS版としてリリースされました。
https://inside.java/2023/09/19/the-arrival-of-java-21/
## サポート状況

https://spring.io/projects/spring-framework#support

# Spring Boot
| バージョン | GA            | Spring Framework | Tomcat | 備考      |
|:---------:|:-------------:|:----------------:|:------:|:---------:|
| 1.5       | 2017年1月      | 4.3             | 8.5    |           |
| 2.0       | 2018年3月      | 5.0             | 8.5    |           |
| 2.1       | 2018年10月     | 5.1             | 9      | Java11対応 |
| 2.2       | 2019年10月     | 5.2             | 9      | Java13対応 |
| 2.3       | 2020年5月15日  | 5.2             | 9      | Java14対応 |
| 2.4       | ~~2020年10月予定~~<br>[2020年11月12日](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.4-Release-Notes) | 5.3 | 9 | Java15対応 |
| 2.5       | 2021年5月20日  | 5.3             | 9      | Java16対応 |
| 2.6       | 2021年11月19日  | 5.3             | 9      | Java16対応 |
| 2.7       | 2022年5月19日  | 5.3             | 9      | Java16対応 |
| 3.0       | 2022年11月24日  | 6.0             | 10      | ベースラインはJava17 |
| 3.1       | 2023年5月18日  | 6.0.9            | 10      | ベースラインはJava17 |
| 3.2       | [2023年11月23日](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.2.0-Release-Notes)  | 6.1            | 10      | ベースラインはJava17 |
> 以後、半年毎のリリースを目指すとのことです。（毎年5月と11月の第3 or 第4木曜日）

## サポート状況

https://spring.io/projects/spring-boot#support

# 参考
[Spring Framework Versions - Spring Framework Wiki](https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Versions)
[Supported Versions - Spring Boot Wiki](https://github.com/spring-projects/spring-boot/wiki/Supported-Versions)
[Spring Blog](https://spring.io/blog)

# 更新履歴
- 2020/06/11　情報追加と対応Javaバージョンの書式変更
- 2020/11/13　情報追加（Spring Framework 5.3 , Spring Boot 2.4 / 2.5）
- 2021/04/14　Spring Boot 2.2～2.4 の EOL予定を追記
- 2021/05/21　Spring Boot 2.5 GA による追記
- 2021/09/29　Spring Framework 5.3 のJavaバージョン更新、Spring Boot 2.2 EOL更新
- 2021/10/18　Spring Framework 6.0 および Spring Boot 3.0 追記
- 2022/01/28　一覧表からEOL列を削除し、サポート状況は公式ページへのリンクに変更。Spring Boot 2.6 追記
- 2022/10/13　情報追加・変更（Spring Framework 6.0 / 6.1 , Spring Boot 2.7 / 3.0）
- 2022/10/13　Java LTSバージョンリリース周期について注釈追記
- 2022/12/02　5年ぶりのメジャーバージョンアップ（リリース日の`予定`をカットしたのみです）
- 2023/05/19　Spring Boot 3.1 追記
- 2023/11/20　Framework 6.1 追記 および Java21について補足追記
- 2023/11/24　Spring Boot 3.2 追記
CakePHP ：save メソッド1_modifiedカラムの内容が変更する対応

# saveでデータを保存するとき、modifiedカラム変更の対応：

- データ内容が変わる場合、更新・新規ができるし、modifiedカラムの内容が変更できる:

 `$this->ModelName->save($data);` 

- データ内容が変わらずの場合、modifiedカラムだけ更新したい場合：

`$this->ModelName->touch($data);` // 追加して
 
`$this->ModelName->save($data);` 

以上です。
コマンドラインからPlantUMLを実行してエラーが出た時のメモ

## 環境
VirutalBox バージョン 5.1.18
ホストOS Windows7
ゲストOS CentOS Linux release 7.3.1611 (Core)
rootで実行
PlantUML version 1.2018.12 (Sun Oct 21 19:15:15 JST 2018)
Java Version: 1.8.0_144-b01

## Can't connect to X11 window
### エラー内容

```
$ java -jar /var/lib/plantuml/plantuml.jar test.puml
Exception in thread "main" java.awt.AWTError: Can't connect to X11 window server using ':0' as the value of the DISPLAY variable.
```

### 対応

```
$ unset DISPLAY
```

なぜエラーが出なくなったのかは調べてません

## Some diagram description contains errors
### エラー内容

```
# java -jar /var/lib/plantuml/plantuml.jar test.puml
Error line 3 in file: /vagrant/plantuml/test.puml
Some diagram description contains errors
```

### 対応

3行目に()があったので削除したら直りました

```
サーバ(A) -> サーバ(B) : rsync
```
↓

```
サーバA -> サーバB : rsync
```
頭チキンのプログラム vol.1

当面の目標はyukicoderの★1問題を全てこなすということにしました

もちろん、アプリなり何なりのことも忘れていませんよ？

古さ爆発のブラウザゲーを作る計画を立ててます

その前にマクロとか諸々も勉強したいので、時間がどれだけあっても足りませんが

今回はNo.18,98,35ですよ！

##No.18
```18.py
S=list(input())
D=[]
for i in range(len(S)):
    a=ord(S[i])-i-1
    if a<65:
        while a<65:
            a += 26
        
        D.append(chr(a))
    else:
        D.append(chr(a))

print(''.join(D))
```
文字列だったのでノータイムpythonです

リスト系の操作は全てpythonでやっている私です

正直Fortranで書く意味ありゅ？と精神崩壊しそうです

で、結局Fortranでも解きました

```18.f90
implicit none
character(1024) S
integer(8) A,i
read(*,*) S
do i=1,len_trim(S)
     A=ichar(S(i:i))-i
       do while(A<65)
          A=A+26
       end do
     S(i:i)=char(A)
end do
write(*,*) S
end
```
ようやく文字列でも普通にプログラミングをできるようになりました

"S(i)"とした所で反応しないんですよね、do構文だと

ですので、"S(i<font color=red>**:i**</font>)"にします

いやー、ようやく解決してストレス微軽減です


<br>ループ構文やケースバイケース系の構文は使わなければ使わないほど計算量減るんですね

そんな当たり前のことに最近気づきました

で、Fortranでいうmod、余りを利用して書いている人が多いんですけど、

私はループ文で永遠と何かさせる構造が好きなので、この形にしています

速さを言い始めると余りでやった方が計算回数が一回になるのでそっちの方がいいとは思います

まぁ余りでどーのこーのが思いつかなかっただけとも言いますがネ！

##No.98
```98.f90
implicit none
real(8) X,Y,R
read(*,*) X,Y
R=X*X+Y*Y
R=sqrt(R)
write(*,*) int(R*2+1)
end
```
Fortranにせよ、pythonにせよ、誤差が絡むと面倒になるんだなーと思う日々

最初はRの部分をまとめていたんですが、誤差が出て上手くいかないので分けました

そうすればうまくいきました

何故なんですかね？

##No.35
```35.f90
implicit none
integer(8) N,i,U,V
real(8),allocatable :: T(:)
character(100),allocatable :: S(:)
read(*,*) N
U=0
V=0
allocate (T(N))
allocate (S(N))
do i=1,N
   read(*,*) T(i:i),S(i:i)
end do
do i=1,N
   V=V+len_trim(S(i))
   T(i:i)=int((T(i:i)*12.0)/1000.0)
   if (T(i)>len_trim(S(i))) then
            U=U+len_trim(S(i))
   else
            U=U+T(i)
   end if
end do
write(*,*) U,V-U
end
```
これに関しては態々"(i:i)"の形にする必要なくなーい？とも思ったのですが、

なんとなく入れているだけです

やっていることは、総文字数を計算してタイプした文字の数を計算して引いただけ、です

超☆単☆純

<br><br>
恐るべし★1と最近戦慄する日々ですよ

今までが頭からガジガジの力業でできたから、★1は大体そんなもんだろーとか思っていましたが、

そんなに甘くないですねぇ

リストを並び変えて云々系が多いので、Fortranで書くの止めたくなりますよ

pythonに比べて確かにFortranは早いですが、2msか20msの違いですからね

遊ぶ分にはどっちにしろ十分早いです、人間の知覚スピード超えているから当たり前だよなぁ！

それにpythonの手直しコメントはぽつりぽつりともらうのですが、Fortranはほぼほぼなしというネ

ぬぬぬ...次回から過去に解いたChekiOの問題でも引っ張ってくることも視野に入れています
<br>
次回からはyukicoderと並行して何か出来たらなーと思います

以上！
マルチドメインのリストが欲しいときのコマンド

■用途
　マルチドメインのみのリストを利用してプログラムを組みたいときなど

■マルチドメインのリストを取得するコマンド

	cat httpd.confまでのパス　| grep -e ServerAlias -e ServerName | sed -E "s/\s*(ServerAlias|ServerName)\s*//g"

■phpでマルチドメインのリストを取得して配列に入れるプログラム

	$setting_domain = `cat {httpd.confまでのパス} | grep -e ServerAlias -e ServerName | sed -E "s/\s*(ServerAlias|ServerName)\s*//g"`;
	$list_domain = explode("\n", trim($setting_domain));
	$list_domain = array_unique($list_domain);