OmniAICreator/Qiita-1.07M huggingface dataset:
WSL同士のファイル転送

# 解決したい問題点：WSL同士でファイル転送をしたい

ついにWSLにもUbuntu 18.04が来ました。
思ったよりも早くきて、びっくりしつつ、とても喜んでいます。

ところが！
このUbuntu 18.04は新しいWindowsStore Appとして配布されました。
そこで起こるのが、旧Ubuntuアプリから新Ubuntu1804アプリへの環境移行。

私は開発環境のセットアップをgitレポジトリ化＆スクリプト化してあるため、こちらはあまり問題になりませんでした。
しかし、今まで扱っていたファイルをどうするのかという問題が残りました。

# 問題解決の大変さ：WSLのファイルシステムの特殊さ

WSLはファイルシステムが特殊で、Windows10のファイルパスを使ってファイルのやりとりをすると問題が起こります。

## Linuxから見たWindowsでのファイル権限

WSLはWindows10のファイルシステムにアクセスできます。
しかし、Windows10を経由すると、すべてのファイルに実行権限が付与されてしまいます。
つまり、WSL1からWSL2にファイルをコピーするのに「WSL1→Windows 10→WSL2」と経由すると、すべてのファイルに実行権限がついてしまいます。
1つ2つのファイルならいいですが、大量になると、権限の復旧が面倒です。

## Windows10から見たWSLのファイルパス

WSLのファイルは、Windowsでの実体がひじょうに深いところにあります。
ファイルパスは以下です。

```:Ubuntuの場合
%LOCALAPPDATA%\Packages\CanocialGroupLimited.UbuntuonWindows_"何か"\LocalState\rootfs
```

```:Ubuntu1804の場合
%LOCALAPPDATA%\Packages\CanocialGroupLimited.Ubuntu18.04onWindows_"何か"\LocalState\rootfs
```

しかも、Windows10からWSLのファイルを読めますが書き込みはできません。
WSLのファイルを変更をすると、WSLから不可視なファイルとなってしまいます。[^1]

[^1]: Windows版Source Treeがひじょうに便利なのですが、この制約のせいでWSL内のgitレポジトリを扱うことができません。

また前述の実行権限の都合により、Ubuntu1804から`/mnt/c`経由でUbuntuのファイルにアクセスはできますが、やはり実行権限がついてしまいます。

# 解決策：そうだ、sshしよう

Windowsを経由せず、WSLのLinux同士で通信すれば解決できます。
他のLinuxサーバがあればそこを経由でもいいですが、ネットワークを経由したくありません。
そこで、新たなWSLで可能になった、WSLでsshdを立てることにしました。

## Ubuntu1804でsshdの設定をする

一時的に、パスワードでの認証をオンにします。
sshdを使い続けるのであれば、RSA認証にあとで変えましょう。

```bash:/etc/ssh/sshd_config
PasswordAuthentication yes
```

なお、参考文献にある以下サービスの停止は必要ありませんでした。

- SSH Server Broker
- SSH Server Proxy

また、以下のsshdの`UsePrivilegeSeparation no`の設定も必要ありませんでした。

## Ubuntu1804でsshdを起動する

Ubuntuのsshdを以下のコマンドで起動します。

```shels-session
# service ssh start
```

## Ubuntuからアクセスする

ここまでくれば、sshもscpも使えます。
ダイレクトにコピーすることができました。

```shell-session
$ scp -r [コピーしたいフォルダ] [Ubuntu1804のユーザ名]@localhost:[コピー先]
```

## Ubuntu1804のsshdを止める

使わないものは止めておきましょう。

```shell-session
# service ssh stop
```

# まとめ

- WSL間のファイルのやりとりはダイレクトで行おう
- WSLでは、親であるWindows10を経由するとファイルのあれこれに面倒が増える

# 参考文献

- [脳内メモ＋＋：Windows10 BashへのSSH接続メモ](http://fftest33.blog.fc2.com/blog-entry-121.html)
- [Windows Subsystem for Linux メモ](https://qiita.com/melito/items/1511836186163020d1ad)
【Swift】セルのボタンタップ時にタグ無しでセルの情報を取得する

テーブルビューのセルにボタンを設置してボタンタップ時にセルの情報を取得したかったのですが、タグを使えば簡単にできるもののタグ番号って何を表しているかがぱっと見でわかりずらいので使用を禁じられたので、別の方法で取得してみました。

```ruby:Protocol
protocol CustomCellDelegate {
    func customCell(didPushButton customCell: CustomCell)
}
```

```ruby:CustomCell
class CustomCell: UITableViewCell{

    var data: [String: Any]?
    var delegate: CustomCellDelegate?
    
    override func awakeFromNib() {
    }
    @IBAction func pushButton(_ sender: Any) {
        self.delegate?.customCell(didPushButton: self)
    }
}
```

```ruby:ViewController
ViewController: UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var tableView: UITableView!

    var data: [[String: Any]] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.delegate = self
        self.tableView.dataSource = self

        let nib = UINib(nibName: "CustomCell", bundle: nil)
        self.tableView.register(nib, forCellReuseIdentifier: "CustomCell")

        for id in 1...5 {
            self.data.append([
                "id": id
            ])
        }
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.data.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell") as! CustomCell
        
        cell.delegate = self
        cell.data = self.data[indexPath.row]

        return cell
    }
}

extension ViewController: CustomCellDelegate {
    func customCell(didPushButton customCell: CustomCell) {
        guard let row = self.tableView.indexPath(for: customCell)?.row else {
            return
        }
        
        print(customCell.data!["id"])
    }
}
```

こっちの方がぱっと見わかりにくいのでは…🤔
Git tagの更新

# Git tagの更新

知らなかったのでメモ

tagは更新が出来ないので、一度削除してから同名のtagを設定して
リモートへ反映が必要

```
# ローカルのタグを削除
$ git tag -d [tag_name]

# 削除をリモートへ反映
$ git push origin :refs/tags/[tag_name]

# タグを設定
$ git tag [tag_name]

# タグをリモートへ反映
$ git push --tags origin
```
コミュニティ版コアスクリプトにプルリクエストを送ってみた


#通ったプルリクエスト

##Window_Options.drawItem()で座標が正しく反映されていないバグの修正
実はXが0であることを前提に処理が書かれていたため、正しく動いていませんでした。
1行修正して、そのまま通りました。

##Game_Interpreter.requestImagesの修正
*Game_Interpreter.requestImages()*は画像や音声などのリソースを先読みする処理です。
しかし、プラグインコマンドによる画像の要求には対応していない問題がありました。
そこで、プラグインコマンドに対応するように修正。
また、コマンド全てをまとめてチェックしていたのをコマンド一つずつのチェックへ処理を分けました。

##アイテム使用時のフリーズの修正
Scene_ItemBase.canUse()はスキルに使用者を*this.user()*で確保した後に、Game_ActorのcanUse()でチェックしています。
しかし、何らかの理由により*user()*でnullが返ってくると落ちてしまいました。
公式フォーラムでも報告があったのですが、原因を突き止めて修正。
バグ修正でしたので、素早く通りました。

#通らなかったプルリクエスト
##BattleManager.checkBattleEnd()の修正
判定部分を関数化してフックしやすくする提案。
しかし、関数追加は予想外の所で問題を起こすことがありえるので、行わなかったとのこと。
外から見た動作は変化していないのに、なぜ問題が起こる可能性があるかですが、個人的には新規追加された関数を使ったプラグインが出たときの事を想定しているのだと思います。
新しいバージョンで増えた関数を前提にプラグインを書くと、古いバージョンでは動かなくなってしまいます。
また、プラグインと本体スクリプトのバージョンが変わったときに、思わぬ場所に影響が出る可能性があります。
単純な関数追加でも、ダメな場合の好例です。

その他、同時期に提案したが通らなかったプルリクエストも同様だったので割愛。

#まとめ
 - バグ修正は通りやすい。できれば、症状などについてまとまっている記事があるとGood。
 - 機能追加やプラグインのためのメソッド追加は大きなメリットが無いと通らない。
 - プルリクエストが大きすぎると通らない。機能別に分けた状態かつ影響の少ない方法を考えよう。
 - コアスクリプトはとても保守的。便利な新機能と動作の安定性なら後者を優先する。

大体はこんな感じです。
githubは不慣れでしたが、ここまでのプルリクエストで使い方を掴めました。
プラグイン作成とは勝手が違い、安定性を重視してます。
（デュエリスト的な言い方をすれば、ミラフォや分断の壁を警戒してモンスターの展開を抑えるような雰囲気）
リポジトリは英語が多くて身構えてしまいますが、中の人は日本人もいますので、相談はしやすいです。

恐れずにオープンソースの世界に踏み出してみましょう。
AWSでDeep Learning使おうとした話

# クラウドで学習したい
自前PCでもいいけど、クラウドだと出先でもできるってことでAWSでの環境構築。

# アカウント作成
これは、いろんなところで書かれているので割愛。

# インスタンスの作成
これも、いろんなところで書かれているので割愛。

# インスタンス作るとエラー
![AWS二時間待て.png](https://qiita-image-store.s3.amazonaws.com/0/257883/59ce891e-668a-8b79-1838-c3b31f1ce5eb.png)

2時間待てと言われたので、犬のように待つ。

# 2時間待ったけどエラー
![AWSエラー.png](https://qiita-image-store.s3.amazonaws.com/0/257883/71387998-c391-1978-ec96-fcc5945b76f6.png)

要約するとGPUインスタンス作りたいならリクエストしてくれってことらしい。
http://aws.amazon.com/contact-us/ec2-request

![リクエスト.png](https://qiita-image-store.s3.amazonaws.com/0/257883/7e8770be-97ba-c47b-9b5e-dd4b6a705e02.png)
リクエスト送って、犬のように待つ。
3時間待って返信きた。とりあえず作れるようになった。
![追加お知らせ.png](https://qiita-image-store.s3.amazonaws.com/0/257883/880be02c-1c38-b1b8-23b2-e07afff632da.png)


# 最初からAnaconda入ってた
![anaconda最初から入ってる.png](https://qiita-image-store.s3.amazonaws.com/0/257883/d1830f16-d3a1-fc36-dc8e-df2320a5490c.png)
AWS、きみはやればできる子だった。（下に最初から書いてあった）
https://docs.aws.amazon.com/dlami/latest/devguide/tutorial-conda.html

```bash:shell
Please use one of the following commands to start the required environment with the framework of your choice:
for MXNet(+Keras1) with Python3 (CUDA 9) _____________________ source activate mxnet_p36
for MXNet(+Keras1) with Python2 (CUDA 9) _____________________ source activate mxnet_p27
for TensorFlow(+Keras2) with Python3 (CUDA 8) ________________ source activate tensorflow_p36
for TensorFlow(+Keras2) with Python2 (CUDA 8) ________________ source activate tensorflow_p27
for Theano(+Keras2) with Python3 (CUDA 9) ____________________ source activate theano_p36
for Theano(+Keras2) with Python2 (CUDA 9) ____________________ source activate theano_p27
for PyTorch with Python3 (CUDA 8) ____________________________ source activate pytorch_p36
for PyTorch with Python2 (CUDA 8) ____________________________ source activate pytorch_p27
for CNTK(+Keras2) with Python3 (CUDA 8) ______________________ source activate cntk_p36
for CNTK(+Keras2) with Python2 (CUDA 8) ______________________ source activate cntk_p27
for Caffe2 with Python2 (CUDA 9) _____________________________ source activate caffe2_p27
for base Python2 (CUDA 9) ____________________________________ source activate python2
for base Python3 (CUDA 9) ____________________________________ source activate python3
````

とりあえずデフォルトの仮想環境で動作確認するために、python3のtensorflowに仮想環境をチェンジ。

```shell
$ source activate tensorflow_p36
```

kerasのテストコードを試す。

```shell
$ git clone https://github.com/keras-team/keras.git
$ cd keras/examples/
$ python mnist_cnn.py
```

![deepleaningテスト.png](https://qiita-image-store.s3.amazonaws.com/0/257883/5fa7d7b2-c016-00f7-300e-03f27cc639c7.png)

3分で終わった早えぇ……。

# 後始末
![ちゃんと停止させておく.png](https://qiita-image-store.s3.amazonaws.com/0/257883/ce2869d9-7d65-60c8-7694-0fa38cacc979.png)

終わったらちゃんと停止させておく。
一時間$1.542（1.542*110=170円くらい）はなかなか高い。。。

これを使って次は顔認識の学習の話をする。
Wi-Fiが突然繋がらなくなった時

# 起きた問題
MacBook Proのメンテナンスを行い自宅に持ち帰ってニュースサイトをチェックしようとしたところ、ブラウザ(Chrome)の表示が下記のようになり通信ができなくなりました。
正確にはhttp通信がブロックされている感じでした。
※他のプロトコルの通信は正常に動作しているように見受けられました。

![スクリーンショット 2018-05-22 0.19.19.png](https://qiita-image-store.s3.amazonaws.com/0/236049/52f064ea-0b7c-e1a3-f704-827faa8d9ce1.png)


iPhoneはWi-Fi通信が出来ており、原因が掴めず頭を抱えること数日・・・

# 環境
- MacBook Pro (13-inch, 2016, Four Thunderbolt 3 Ports)
- macOS High Sierra 10.13.4
- AirMac Express ベースステーション (ファームウェア:7.4.9)
- So-net光コラボマンションタイプ
- iPhone X / iOS 11.3.1

# 解決
MacBook Proのネットワーク設定を確認したところ、下記のようになっていました。
(※high Sierraをクリーンインストールしたので、macOSのデフォルト値のようです。)
![スクリーンショット 2018-05-22 0.16.50.png](https://qiita-image-store.s3.amazonaws.com/0/236049/7f000518-d4e2-b3b4-1e7f-473f8f6a8611.png)

これを下記を参考にGoogleパブリックDNSに変えてみると・・・

Google Public DNS
https://developers.google.com/speed/public-dns/docs/using
![スクリーンショット 2018-05-22 0.18.32.png](https://qiita-image-store.s3.amazonaws.com/0/236049/286f01a0-8898-9502-6771-f682c6d08077.png)

つながりました。

# 補足
iPhoneがつながっていたのが気になりiPhoneのDNSを確認してみたところ

<img width="375" alt="IMG_77AE7B42192A-1.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/236049/0bbbc4f6-0003-32c9-5f64-522424f69c91.jpeg">

パブリックDNSの指定が既にされていました。
(いつやったんだっけ・・・)

また、メンテナンス作業を行った事務所のネットワーク環境では問題なく接続がされていました。

デフォルトのDNSでなぜつながらないのか、パブリックDNSにすることでつながるようになる仕組みなどは、今後改めて掘り下げてみたいと思います。

余談ですが、GoogleパブリックDNSは一説では世界最速DNSとのことです。
シェルスクリプトで外部のSQLServerにDDLを流す

# シェルスクリプトでSQLServerにDDLを流す

## インストール
- sqlcmdコマンドが必要なので、
実行環境に「Microsoft ODBC Driver for SQL Server」をインストールしておく

- Microsoftのドキュメントを参考にインストールを行いました
[ドキュメント](https://docs.microsoft.com/ja-jp/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017#ubuntu-1604-1)

- インストールが完了後、対象のSQLServerに接続して実行確認します

```
$ sqlcmd -S [DB_HOST],[PORT] -d [DB_NAME] -U [DB_USER_NAME] -P [DB_PASSWORD] -I -Q
"query"
```

## シェルスクリプトで実行

```sql.sh
# -iで実行するファイル名を指定
# -bで実行結果の返り値を受け取ります
sqlcmd -S [DB_HOST],[PORT] -d [DB_NAME] -U [DB_USER_NAME] -P [DB_PASSWORD] -i [filename] -b

#実行結果
res=$?
# -bの返り値が0より大きければエラー
if [ $res -gt 0 ]; then
    echo "エラーとして実行終了"
    exit 1;
else
　　　　　　　　echo "成功"
fi

```
AWS SNS の権限を絞るための Policy 設定

2018/05/22 時点の情報です

やろうとしたことができなかったのでメモ。

# Endpoint の作成を制限する

Endpoint を作成する対象のアプリケーションを絞ろうと思ったが、できないらしい

<img width="1079" alt="スクリーンショット 2018-05-22 14.52.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/117087/63af4dc0-4253-3051-a4d8-7a7a6ae741c0.png">

all resources とのこと。

アクションを複数まとめて指定した場合、エディタ上では Resources 欄には入力ができる状態になるが、設定すると二つに分かれた記載になる（んで、 CreatePlatformEndpoint の項目では Resources が `*` になる）
以前はこれをやってくれなくて、意味分からん状態になった記憶...

# Publish する Endpoint を制限する

Publish する Endpoint を制限したいときは、 Endpoint が所属する Platform Application を指定することはできる。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "sns:Publish",
            "Resource": [
                "arn:aws:sns:<region>:<account>:app/<app_name>"
            ]
        }
    ]
}
```

次のように、 endpoint の範囲指定することはできない（arn はランダム文字列が振られるので、需要もほぼないと思いますが。）

```json:bad
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "sns:Publish",
            "Resource": [
                "arn:aws:sns:<region>:<account>:endpoint/<app_name>/*"
            ]
        }
    ]
}
```

Topic は試してないのですが、入力欄は Topic Name を指定すると周辺に書いてあるので、当然できると思います。
iOS課金付きアプリ申請したら、購読型課金を強制された

# まず、どうして購読型課金を強制されたのか
『購入後3ヶ月間自社サービスを提供するための課金』を消化型アイテムとして申請したからだ。
アップルはこのような種類の商品は購読型にするべきだとしつこく主張する。

# どうして購読型課金にしなかったのか
ご存知の方もいると思うが、Apple IDを一意に表現できるIDのようなものを取得する機能が、iOS SDKから一切提供されていない。
アプリの造りとして、そのApple IDを使用している端末が、ある商品を購読中かどうかだけ判定すれば良いのであればそれで構わない。

しかし、例えば自社サーバー上にエンドユーザーのアカウントをアプリが初回起動時に自動作成し、ユーザーによってサービスが課金されたかどうかをアカウントに紐づけて扱う場合、不都合が生じる。

Apple IDを一意に表せるものがないということはApple IDと自社サービス上のアカウントを１対１で関連づけることができない。
なので現在は端末のUUIDとアカウントを関連づけているので、端末とアカウントが１対１で関連づいているということだ。

つまり、同じApple IDを使用する別の端末を利用すると、すでに購読課金をしていた場合、サービスは未課金の状態と認識されているのに、Appleアカウントではすでに課金されていることになるので再課金もできない。
また、サービス上、使用回数制限を伴うものを扱っているので、１つの購読課金に対して複数のアカウント（端末の数だけ）を課金したアカウントと扱うわけにもいかない。

このサービスのアカウントを手動ログイン方式にした場合も問題解決にはならない。
なぜなら、全てのユーザーがきちんと同じApple IDを利用する端末間で同じアカウントにログインしてくれたら問題はないが、そうでない場合、問題は悪化する。さらに異なるApple IDで使用される端末でもサービスを利用可能となる。

そこで、あくまで課金は１つの端末のみでサービスを使用できるようにするためのものとした。消化型課金アイテムは購入処理が終わると、即座にそのユーザーのアカウントに購入した事実を伝え、的確に処理が完了すると消化されるようにした。

# そして購読型課金を強制された
上記のことをアップルには解りやすく何度も説明したつもりだ。アップルは頑なにNoの姿勢。
そこで、このように提案してみた。
「これは購読型のサービスではなく、一定期間サービスを利用するための利用権の引換券である。引換券は他のアプリにもよくみられる『コイン』などと同様な商品のはずだ。一般的に『コイン』は通常、消化型課金であり、課金後、開発会社自身のサービスでレシートが確認されれば、サービス上で『コイン』は発行され、アプリはそれを受けて消化型課金を消化するようAppleのサービスに対して申請するものだ。また、必要ならiTunes Connectに登録している課金アイテム説明文から『〇ヶ月間サービスを利用する権利』という文言を取り除く。」

アップルはそれに対し、「それは一つの対処法になるかもしれない」と返事をくれたが、その段階ではまだ、「そうすればリリースを許可する」とは約束はしなかった。

# 結果報告
無事、アプリとその課金アイテムは審査を通過した。
「３ヶ月間」という文言をストア登録情報から省き、アプリ内部で説明をすることによって解決した。しかし、アプリの根本的な部分が変わった訳ではない。そしてこれまでにあるような妥協案の説明によって審査を通過できたということは、あくまで審査員というおそらく一人の人間の説得に成功したからだろう。（最低限のガイドラインはあるにしても。）そしてその人間はたくさんいるであろう審査員の中からおそらくランダムで割り振られる。もしかしたら、いくら説得しても折れない人間、理解に及ばない人間もいるだろう。つまりアプリ審査は、いままでも、これからも「運ゲー」だ。
Dockerfile リポジトリの CI 上で microscanner を実行しよう

## はじめに

[microscanner](https://github.com/aquasecurity/microscanner) に関する[記事](https://dev.classmethod.jp/tool/docker/microscanner/)を読んで、自分の Docker image リポジトリの CI に入れてみたので手順を紹介します。

導入時間は10分ほどになります。

## 作業手順

### トークンの発行

まず始めに以下のコマンドを入力して、microscanner のトークンを発行します。

```sh
docker container run --rm -it aquasec/microscanner --register <your-email-address>
```

[Y/n] で Y を選択すると入力したメールアドレスにトークンが届きます。

### TravisCI の設定

https://travis-ci.org/profile から特定のリポジトリのチェックを入れて、 `Settings` をクリックします。

![スクリーンショット 2018-05-22 12.58.16.png](https://qiita-image-store.s3.amazonaws.com/0/64520/abdc81b1-45b1-e2a6-d43e-231fe9d35473.png)

メールで取得したトークンを `Environment Variables` に追加します。
画像のように入力し `Add` をクリックして完了です。

### ファイルの設置

次に、以下の `microscanner.txt`, `.travis.yml` をリポジトリ直下に配置します。

```txt:microscanner.txt
ADD https://get.aquasec.com/microscanner /
RUN chmod +x /microscanner
RUN /microscanner ${token}

RUN echo "No vulnerabilities!"
```

`.travis.yml` は以下の設定にします。

```yaml:.travis.yml
sudo: required
services: docker
before_install: cat microscanner.txt >> Dockerfile
script: docker container build --build-arg=token=$TOKEN --no-cache .
```

`microscanner.txt` は microscanner を動かすために必要なファイルになります。
`.travis.yml` の before_install を見ていただくとわかるのですが、CI上でのみ `Dockerfile` にスクリプトが追加されるようになります。

これらをリポジトリに push すると、CI 上で脆弱性チェックが行えるようになります。
失敗時の様子を試したい方は参照サイトでも紹介されている [piesecurity/apache-struts2-cve-2017-5638](https://hub.docker.com/r/piesecurity/apache-struts2-cve-2017-5638/) を使って試すとわかりやすいと思います。

以上、 microscanner を TravisCI 上で実行する方法でした。

## 参照サイト

- [無料で脆弱性検査！Dockerfileに4行追加で導入できるmicroscannerを試してみた ｜ Developers.IO](https://dev.classmethod.jp/tool/docker/microscanner/)
DICOM RTをpythonを使って解析する

放射線治療の分野ではDICOM RT形式のファイルを扱うことが多いが，これに関する日本語の記事が少ない。自分で何度も調べてしまうので備忘録としてメモする。

#環境
pythonを使ってdicomを解析するときは [pydicom](https://github.com/pydicom/pydicom) があると便利。DICOM RTにも対応してくれている。
本稿では[anaconda](https://anaconda.org/)で[JupyterLab](https://github.com/jupyterlab/jupyterlab)を使ったとして話を進める。単純に自分の好みなので，何でも良いけども。

#開発の進め方
pydicomのインストールはanacondaに任せるとして，python(ここではipython)スクリプト上でimportする。

```python
import dicom
```

そして使いたいdicomファイルを指定する。例えば

```python
dicomplan_path="C:/Users/me/RP.dcm"
```

といった具合に。
そしてdicomファイルとして読み込む。

```python
d=dicom.read_file(dicomplan_path)
```

これでdicomは読み込めた。
そうしたら，jupyterの補完機能を使えるので，例えば `d.`などと打って`tab`を押せば候補が沢山出てくる。

そのうち，例えば

```python
d.BeamSequence
```
などとしたとする。
そうすると

```python
<Sequence, length 1, at 195B50D64F8>
```
とかでてきて，なんじゃそりゃ？となる。
そういうときは

```python
d.BeamSequence[0]
```
とかしてやると中身がでてくる。

```
(0008, 0070) Manufacturer                        LO: 'Linac'
(0008, 0080) Institution Name                    LO: 'Hospital'
(0008, 1040) Institutional Department Name       LO: 'Radotherapy'
(0008, 1090) Manufacturer's Model Name           LO: 'Linac'
(0018, 1000) Device Serial Number                LO: '0123456'
```
みたいな感じ。
なのでその下にタグを追記すると下の階層にアクセスできる。
注意しなければならないのが，

```python
d.BeamSequence[0](008,0070)
```

ではだめで，下記のように

```python
d.BeamSequence[0][0x008,0x0070]
```

丸括弧でなく四角括弧，数字の前に`"0x"`をつけなければならない。
若き日の自分はこの`"0x"`をつけるのがわからずに随分悩んだことがあった。
そして，例えばSource-Axis Distanceは

```python
d.BeamSequence[0][0x300a,0x00b4]
```

とすると，

```
(300a, 00b4) Source-Axis Distance                DS: '1000'
```
と返ってくるのだが，これを数値として使いたかったら

```python
d.BeamSequence[0][0x300a,0x00b4].value
```
として`'1000'`として値を抜き出し，それを`int()`なり`float()`なりすると使えるようになる。
以上。

放射線治療に関するトピックが少ないので書いてみました。
Karabinerで最強（さいつよ）プログラマーを目指す

もう最新のMacでは使えなくなってしまった Karabiner ですが、 Karabinerを使いたいがためにまだOSをアップデートしていません。

そんな私がさいつよのKarabinerの設定を晒します。

## private.xmlでない設定
- [ex] Control+W to Option+Delete
    - エディター、Chromeなど含めてどこでも terminal のように word 削除がしたい！
- Mouse Keys Mode V2
    - マウスはキーボードで動かすものです。色々ショートカットが効かないアプリでも、手を動かさずにクリック
    - でも頻繁にマウス使うときはマウスを使う。さいつよは、状況によってツールを使い分ける
- 左右のコマンドキーを「英数/かな」としても使う
    - もちろん必要

## private.xml
- Vim同じ Control-H,J,K,L でカーソル移動
    - もうカーソルキーなんていらない
- Contrl-G,;で、word移動
    - word移動も、当然必要。 Vimのキーの横において感覚的にわかりやすく
- Option-C で ターミナルKill
    - これは単純に Control-Z,X,C,V,S を Commandと同様にしているから

```private.xml
<?xml version="1.0"?>
<root>
    <item>
        <name>Ctrl-H to LEFT</name>
        <identifier>private.ctrl-h_to_left</identifier>
        <autogen>
            __KeyToKey__
            KeyCode::H, VK_CONTROL,
            KeyCode::CURSOR_LEFT
        </autogen>
    </item>
    <item>
        <name>Ctrl-J to DOWN</name>
        <identifier>private.ctrl-j_to_down</identifier>
        <autogen>
            __KeyToKey__
            KeyCode::J, VK_CONTROL,
            KeyCode::CURSOR_DOWN
        </autogen>
    </item>
    <item>
        <name>Ctrl-K to UP</name>
        <identifier>private.ctrl-k_to_up</identifier>
        <autogen>
            __KeyToKey__
            KeyCode::K, VK_CONTROL,
            KeyCode::CURSOR_UP
        </autogen>
    </item>
    <item>
        <name>Ctrl-L to RIGHT</name>
        <identifier>private.ctrl-l_to_right</identifier>
        <autogen>
            __KeyToKey__
            KeyCode::L, VK_CONTROL,
            KeyCode::CURSOR_RIGHT
        </autogen>
    </item>
    <item>
        <name>Option-C to Control-C</name>
        <identifier>private.option-c_to_control-c</identifier>
        <autogen>
            __KeyToKey__
            KeyCode::C, VK_OPTION,
            KeyCode::C, VK_CONTROL
        </autogen>
    </item>
    <item>
        <name>Control-; to Control+Option+RIGHT</name>
        <identifier>private.control-semicolon_to_option-right</identifier>
        <autogen>
            __KeyToKey__
            KeyCode::SEMICOLON, VK_CONTROL,
            KeyCode::CURSOR_RIGHT, VK_OPTION
        </autogen>
    </item>
    <item>
        <name>Control-G to Control+Option+LEFT</name>
        <identifier>private.control-g_to_option-left</identifier>
        <autogen>
            __KeyToKey__
            KeyCode::G, VK_CONTROL,
            KeyCode::CURSOR_LEFT, VK_OPTION
        </autogen>
    </item>
</root>
```
Vue.jsもぐもぐ会

# Vue.jsの情報収集

[Vue.js Japan](https://github.com/vuejs-jp/home)
[Forum](https://forum.vuejs.org/)
[Awesome vue](https://github.com/vuejs/awesome-vue)

---

# 誰かに質問したいとき

<img width="366" alt="スクリーンショット 2018-05-22 7.42.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/96323/1d7db1a0-beec-89de-5952-b5683a3f0f79.png">

---

# Vue.jsの参考となる資料、ドキュメント

[Vue.js 公式ドキュメント](https://jp.vuejs.org/v2/guide/index.html)
[Sample Code](https://vuejsexamples.com/)
[ElementUIフレームワーク](https://github.com/ElemeFE/element)
[Vuesaxフレームワーク](https://lusaxweb.github.io/vuesax/)

---

# 環境構築

```shell
curl -L git.io/nodebrew | perl - setup
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
nodebrew install-binary v8.11.2
nodebrew use v8.11.2
npm install -g vue-cli
vue init webpack my-project
cd my-project
npm install
npm run dev
```
[テンプレート一覧はこちらへ](https://github.com/vuejs-templates)

---

# 今日のお題

data, props, computed

---

## data, props, computed

ざっくり言えば、Classが持つメンバー変数

--- 

## data, props, computed
### Vueのtemplate、 またはVueのmethodから使うときは違いを意識しない。

---

## 本当？

> 結論から言うとVueのtemplate、 またはVueのmethodから使うときは違いを意識しない。

[参考リンク](https://codesandbox.io/s/q8pvmzplx4)

---

時間が余ったのでコードを読みましょう


---
## propsは親からデータを渡すときに使います。

メモ確認事項

- propsが使えるようになるタイミング
- dataにpropsの値を入れたらどうなるのか 

[参考リンク](https://codesandbox.io/s/q8pvmzplx4)

---

## 進め方の提案

- 聴いてたい
- 手を動かしたい
- 話したい
- 読みたい


## 次回以降に向けて準備中のテーマ

- 勝手に注文v5をVue.js化プロジェクト(超絶もくもく会)
- Vueで実装する2種類のアニメーション
- VueでD3をいい感じに取り入れる方法はあるのか?
- Vueとリアルタイムなデータベースを実装する。(NoSQLのデータ設計を含む)
- VueとVuexとfirebaseの辛さ
- VueとVuexでstate設計

---


付録jsの勉強
[Dwangoの何か](https://asciidwango.github.io/js-primer/)
[Promise Book](http://azu.github.io/promises-book/)
Chronyの時刻自動同期設定

設定忘れてたのでメモ

# 手順

1. `/etc/chrony.conf`ファイルを編集する

    ```
    # cp -a /etc/chrony.conf /etc/chrony.conf.org.`date +%F` && vi /etc/chrony.conf
    ```
    
    ```chrony.conf
    # Use public servers from the pool.ntp.org project.
    # Please consider joining the pool (http://www.pool.ntp.org/join.html).
    server ntp.nict.jp iburst
    server ntp1.jst.mfeed.ad.jp iburst
    server ntp2.jst.mfeed.ad.jp iburst
    server ntp3.jst.mfeed.ad.jp iburst
    ```

2. chronyd を再起動する

    ```
    # systemctl restart chronyd
    ```

## 確認

次のコマンドを実行する。

```
# chronyc sources
```

実行結果

```
210 Number of sources = 4
MS Name/IP address         Stratum Poll Reach LastRx Last sample              
===============================================================================
^* ntp-b3.nict.go.jp             1   6    17     2   +465us[+3554us] +/- 6620us
^- ntp1.jst.mfeed.ad.jp          2   6    17     3  -3926us[ -837us] +/-   82ms
^- ntp2.jst.mfeed.ad.jp          2   6    17     2  -4467us[-4467us] +/-   81ms
^- ntp3.jst.mfeed.ad.jp          2   6    17     2  -3844us[-3844us] +/-  119ms
```
NEHotspotConfigurationManagerを使ってWi-fiに接続する（Objective-C版）

iOS11からPublic APIとしてWi-fi接続のAPIが公開されたので
今更ですが記述します。
Objective-Cのサンプルって少なくなりましたね〜

事前にcapabilities->Hotspot ConfigurationをONにしておいてください。

```objective_c:hoge.m
#import <NetworkExtension/NetworkExtension.h>

NEHotspotConfigurationManager *manager = [NEHotspotConfigurationManager sharedManager];
NEHotspotConfiguration *config = [[NEHotspotConfiguration alloc] initWithSSID:@"your ssid" passphrase:@"your passwd" isWEP:NO];
[manager applyConfiguration:config completionHandler:^(NSError *error){
    if(error) {
        NSLog([error localizedDescription]);
    }else{
        NSLog(@"connected");
    }
}];
```

参考：
https://qiita.com/sushichop/items/3a5682caedf9a8799514
https://dev.classmethod.jp/smartphone/nehotspotconfiguration/
エクセルを閉じるときに「図が大きすぎます。入りきらない部分は切り捨てられます。」という警告が出る

## 課題
以下のコードであるシートのRangeを別のシートにコピペしたんですが、

```c#
Globals.[コピー元シート].[名前付範囲].EntireColumn.Copy(
    ((Excel.Range)Cells[1, 1])
    .Resize[1, [必要な列数]]);
```

エクセルを閉じるときに

```
「図が大きすぎます。入りきらない部分は切り捨てられます。」
```

という警告が出てうるさいです。


## 解決
クリップボードに大きなデータが残っているのが直接的な原因です。
コピー先を指定して Copy した場合はクリップボードを使わないのじゃないか、
という点は未確認ですが、とりあえずクリップボードをクリアしようと

```c#
Clipboard.Clear();
```
したのですが、クリアされず。

[dobon.net](https://dobon.net/vb/dotnet/system/nostaclipboard.html)さんの記事によると、
クリップボードを操作するためにはスレッドがSTA（Single Thread Apartment）である
必要があるそうです。
先の記事を参考に、STAスレッド内でClipboard.Clear()を呼び出したところ、
無事クリップボードがクリアされました。

```c#
System.Threading.Thread t = new System.Threading.Thread(()=> {
    Clipboard.Clear();
});
t.SetApartmentState(System.Threading.ApartmentState.STA);
t.Start();
t.Join();
```

### 環境
|アセンブリ| Version|
|----|----|
| Excel | 2010 |
| C# | 4.0.0.0 |
| Microsoft.Office.Tools | 10.0.0.0 |

## 参考
[クリップボードのデータの取得、設定がうまくいかないときは](https://dobon.net/vb/dotnet/system/nostaclipboard.html)
Rubyスクリプトでmainする

Rubyで50行くらいの小物スクリプトを作る
→気がついたら色々増えてメソッドに分割する（だいたい100行）
→気がついたら色々増えてファイルに分割する（だいたい300行）
→ところでこれ、どこがトリガーになってるの？

みたいな事が稀によくある。
そういう時に`main`が欲しくなる事がある。
Goとかにあるアレ。

やり方はあまり難しくなく、以下のような感じにすると良い。

```rb:hoge.rb
def main
  # あれとかこれとか
end

if __FILE__ == $0
  main
end
```

このファイルを`ruby hoge.rb`のように実行すると、`main`内の処理が実行される。

ちなみに、`__FILE__`は自身のファイルを指し、`$0`は[実行されたファイル](https://docs.ruby-lang.org/ja/latest/method/Kernel/v/0.html)を指す。
要するに「呼び出されたファイルが自分の時に実行してね」という事。
[ansible]パッケージのインストール状況に応じて、タスクを実行するか判定する

よくありそうな話ですが、どうするのがスマートか悩む場面がありましたので書きます。

# シナリオ
hogeパッケージがインストールされていない時だけ、something.shを実行する

# テスト環境
## ansible実行環境
```
Amazon Linux AMI release 2017.09
ansible 2.4.2.0
python version = 2.6.9 (unknown, Nov  2 2017, 19:21:21) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]
```

## リモートホスト（ansibleで操作するホスト）
```
Amazon Linux AMI release 2017.09
```

# パターン1
インストール状況をrpmコマンドで確認する

```yml
- shell: rpm -qa | grep hoge
  register: hoge_is_installed
  ignore_errors: True
  changed_when: False

- shell: /path/to/something.sh
  when: hoge_is_installed.stdout == ""
```

## 講評
* 少なくともこのansibleのバージョンでは、以下のようなWARNINGが出力されるのが嫌だ

```
TASK [hoge : command] ***************************************************************************
 [WARNING]: Consider using yum, dnf or zypper module rather than running rpm

ok: [xxx.xxx.xxx.xxx]
```

* スマート度32点（所感）

# パターン2
rpmの代わりにパッケージマネージャ使ってねということなので、yumモジュールで対応する

```yml
- yum:
    list: hoge
  register: hoge_package_info

- shell: /path/to/something.sh
  when: hoge_package_info.results | selectattr("yumstate", "match", "installed") | list | length == 0
```

## 補足説明
* 上記の`hoge_package_info`変数の中身は以下のようになる（例としてcurlパッケージの場合）

```json
ok: [xx.xx.xx.xx] => {
    "hoge_package_info": {
        "changed": false,
        "failed": false,
        "results": [
            {
                "arch": "x86_64",
                "envra": "0:curl-7.53.1-14.81.amzn1.x86_64",
                "epoch": "0",
                "name": "curl",
                "release": "14.81.amzn1",
                "repo": "installed",
                "version": "7.53.1",
                "yumstate": "installed"
            },
            {
                "arch": "x86_64",
                "envra": "0:curl-7.53.1-16.84.amzn1.x86_64",
                "epoch": "0",
                "name": "curl",
                "release": "16.84.amzn1",
                "repo": "amzn-main",
                "version": "7.53.1",
                "yumstate": "available"
            }
        ]
    }
}
```

## 講評
* スマート度60点（所感）
* `selectattr`を使うために、実行環境側にjinja2が入っていなければ別途インストールが必要（今回の環境であれば `yum install python-jinja2` 等）
  * ansibleを実行するための環境構築、みたいな世界がちょっと嫌だ
  * pythonとansibleだけあればサッと動くようにしておきたい気持ち

# 終わりに
どちらかというとパターン2のほうがWARNINGも出ずansibleの推奨に沿っているように思われる、かつ比較的スマートかなと思います。
でもできればスマート度80点以上くらいを目指したいですね。
いい方法をご存知の方がいたら教えていただけると嬉しいです。

# 参考文献
[yum - Manages packages with the yum package manager — Ansible Documentation](http://docs.ansible.com/ansible/latest/modules/yum_module.html)
[[ansible] Check via the yum module and a registered value if a package is installed or not · GitHub](https://gist.github.com/goldyfruit/f4f274be3144e6afca69)
PHPで中継用WebAPIを作成する

PHPで中継用WebAPIを作成した際のメモ。

### 基本情報
- 執筆：2018/5/8
- OS：Windows10(64bit)
- nginx ver：1.14.0
- PHP-FPM ver：7.2.4
- インタフェース：json

### 機能概要
イメージは下図のとおり。HTTP POSTリクエストを受けて外部のWebAPIにアクセスし、返却されたデータを編集してresponseデータを返却する。<br/><img src="https://qiita-image-store.s3.amazonaws.com/0/237065/96d78284-7809-a837-e5a9-eca08eca306f.jpeg" width="50%">

### POSTで受け渡されたパラメータの取得(上図②部分)
受け渡される形式により処理を変える必要がある。

- HTMLフォームでリクエストが受け渡される場合

```php
$_POST['id'];
```

- jsonで受け渡される場合（今回のケース）

```php
$params = json_decode(file_get_contents('php://input'), true);
echo $params['id'];
```
※こちらのサイトを参考にさせて頂きました。
http://blog.takady.net/blog/2017/10/28/php_get_json_from_post_request_body/

### PHPからのPOSTリクエスト（上図③部分）
パラメータ、レスポンス共にjson形式でやり取りするAPIなので、json_encode/decodeを利用し連想配列との変換を行う。

```php
// API仕様に基づく構造をまず連想配列で作成しjson形式へencode
$param = array('name1' => 'value1', 'name2' => 'value2');
$data_json = json_encode($param);
// リクエストヘッダーは仕様に基づいて設定
$header  = array(
    'Content-Type: application/json',
    'charset: UTF-8'
);
// contextはお決まり(かな？)
$context = array(
    "http" => array(
        "method"  => "POST",
        "header"  => implode("\r\n", $header),
        "content" => $data_json
    )
);
$context = stream_context_create($context);
// URLはもちろん仕様に基づくものへ。返却値は再び連想配列へdecode
$contents = file_get_contents('http://hogehoge.com/jsonapi', false, $context);
$res_json = json_decode($contents , true);                
```
Rakeタスクの定義元ファイル名と行番号を一瞬で把握する

例えば Railsの`db:migrate`とかのコードだったり、沢山ある独自タスクをパッと調べたい時に便利なやつ。

## 実行例
```shell
$ rake -g source_list

about   <your_gem_file_path>/railties-5.2.0/lib/rails/tasks/misc.rake:10
db:migrate      <your_gem_dir>/activerecord-5.2.0/lib/active_record/railties/databases.rake:59
db:migrate:down <your_gem_dir>/activerecord-5.2.0/lib/active_record/railties/databases.rake:110
db:migrate:redo <your_gem_dir>/activerecord-5.2.0/lib/active_record/railties/databases.rake:81
db:migrate:status       <your_gem_dir>/activerecord-5.2.0/lib/active_record/railties/databases.rake:123
db:migrate:up   <your_gem_dir>/activerecord-5.2.0/lib/active_record/railties/databases.rake:97
```

この例だと、`db:migrate`タスクは `databases.rake` の59行目に定義されていることになります。

## インストール方法
下記のスクリプトを、`${HOME}/.rake directory`に置き、rakeタスクに`-g`オプションを付与することで、ディレクトリ以下のタスクが読み込まれ、実行できるようになります。
https://gist.github.com/tkyowa/f41fef9150fccc3217ab
GitHub リポジトリに CC Licenses を設定したい

（この記事は [Zenn に移行](https://zenn.dev/spiegel/articles/20200919-ccl)しました。今後のメンテナンスはありません）

Web 上で GitHub リポジトリを作成する際に “Add a license” で各種オープンソース・ライセンスを設定できるが，オープンソース・ライセンス以外の「自由のライセンス」は設定できない。この記事では GitHub リポジトリに [CC Licenses] を設定する方法を紹介する。

GitHub リポジトリのライセンスはリポジトリ直下の `LICENSE` ファイルで指定できる。そこで [CC Licenses] の legal code を `LICENSE` ファイルとしてセットする。

[CC Licenses] の legal code のテキスト版は以下から取得できる。

- [BY 4.0 (plaintext)](https://creativecommons.org/licenses/by/4.0/legalcode.txt)
- [BY-SA 4.0 (plaintext)](https://creativecommons.org/licenses/by-sa/4.0/legalcode.txt)
- [BY-NC 4.0 (plaintext)](https://creativecommons.org/licenses/by-nc/4.0/legalcode.txt)
- [BY-NC-SA 4.0 (plaintext)](https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode.txt)
- [BY-ND 4.0 (plaintext)](https://creativecommons.org/licenses/by-nd/4.0/legalcode.txt)
- [BY-NC-ND 4.0 (plaintext)](https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode.txt)
- [CC0 1.0 legalcode.txt](https://creativecommons.org/publicdomain/zero/1.0/legalcode.txt)

取得したテキストファイルを `LICENSE` にリネームしてリポジトリ直下に置き commit & push すれば OK。これでリポジトリの Web 表示も

![license.png](https://qiita-image-store.s3.amazonaws.com/0/68318/b3c24838-d135-74c5-5e42-5d18b1674ce0.png)

のような感じになる。

なお， [CC Licenses] はプログラムコード用には調整されていないので，プログラムコードの利用を許諾するのであればオープンソース・ライセンスを適用することを強くお勧めする。

- [Githubによる、オープンソースライセンスの選び方 | オープンソース・ライセンスの談話室](http://www.catch.jp/oss-license/2013/09/10/github/)
- [たくさんあるオープンソースライセンスのそれぞれの特徴のまとめ | コリス](https://coliss.com/articles/build-websites/operation/work/choose-a-license-by-github.html)

## ブックマーク

- [Plaintext versions of Creative Commons licenses and CC0 - Creative Commons](https://creativecommons.org/2011/04/15/plaintext-versions-of-creative-commons-licenses-and-cc0/)
- [Plaintext versions of Creative Commons 4.0 licenses - Creative Commons](https://creativecommons.org/2014/01/07/plaintext-versions-of-creative-commons-4-0-licenses/)
- [改訂3版： CC Licenses について | text.Baldanders.info](http://text.baldanders.info/cc-licenses/)

[CC Licenses]: https://creativecommons.org/licenses/
Mac のスリープ切替のログから今日の出退勤時刻を推定する

現在の勤め先には日報を書くという制度があるのですが、今日何時に出社したか忘れた場合や昨日何時に退勤したか忘れてしまった場合に思い出したり調べたりするのが大変なので、 Mac のスリープログを確認して推定しました。

会社に来たら Mac を開きますし、会社から帰る時は Mac を閉じるので、ある程度の精度で取れると思います。

# コマンド

こんなコマンドでできそうです。

```text:terminal
$ sudo pmset -g log | grep "Kernel Idle sleep preventers" | grep $(date +'%Y-%m-%d') | sed -n '1p;$p'
```

今日の日付で取るようになっているので、日付を自分で指定したい場合は 2 つめの grep の `$(...)` の箇所を `"yyyy-mm-dd"` で置換してください。

```text:terminal
$ sudo pmset -g log | grep "Kernel Idle sleep preventers" | grep "2018-05-01" | sed -n '1p;$p'
```

コマンドを実行すると次のような出力が得られるはずです。

```text:terminal
2018-05-21 11:00:22 +0900 Assertions          	Kernel Idle sleep preventers: IODisplayWrangler
2018-05-21 19:57:06 +0900 Assertions          	Kernel Idle sleep preventers: -None-
```

一行目がその日の一番早い時間に記録された情報で、二行目がその日の一番遅い時間に記録された情報です。
日付をまたいで仕事をした場合などは正しく表示できませんが、だいたいはこれで確認できるはずです。

もっといい方法があれば教えてください :pray:
さくらインターネットのスダンダードプランでPythonをCGIとして使う

さくらインターネットのスタンダードプランでサーバをレンタル中

この環境で、CGIにPythonが使えるようセッティングしたときのメモ



まず、SSHでサーバへアクセスし、最新のPythonをインストールする

（参考サイト：https://qiita.com/non0311/items/04222771ef9aa1970f7a ）

当方はMacユーザーのため、ターミナルを使用してSSHでのアクセスを実施します


```
FTPサーバ名： sample.sakura.ne.jp

FTPアカウント： sample

FTP初期フォルダ： www

パスワード： password
```


上記がアクセスする際に準備しておくべき情報

もちろん「sample」の部分は自分の環境に合わせて読み替えてください

以下のコマンドで接続後、パスワードを聞かれますので入力


```
ssh sample@sample.sakura.ne.jp
```


アクセスしたら、以下の順番でコマンドを実行していきます

（筆者のインストール時、Pythonの最新バージョンは3.6.2でした）


```
% mkdir -p ~/work/py3

% cd ~/work/py3

% wget --no-check-certificate https://www.python.org/ftp/python/3.6.2/Python-3.6.2.tgz

% tar zxvf ./Python-3.6.2.tgz

$ cd ./Python-3.6.2

$ ./configure --prefix=$HOME/local/python

$ make

$ make install
```

見ての通り、インストール先は$HOME/local/pythonになります



次に.cshrcを書き換えます（「-----」の間のコマンドを追記）

（筆者はエディタにViを使用しているため、書き換えにはViを使用しました）


```
% vim ~/.cshrc

-----

set path = ($path $HOME/local/python/bin)

setenv PYTHON $HOME/local/python/lib

-----

% source ~/.cshrc

% rehash
```

これでインストールは完了



ローカルの環境に戻り、Pythonのプログラムファイルをアップロードして実行を試して見ましょう（そのままオンライン上で簡単な実行ファイルを作成しても結構です）



ファイルの拡張子は「.cgi」とし、パーミッションはとりあえず「755」にして試します


```
#!/home/user_name/local/bin/python3.6 

#-*- coding: utf-8 -*- 

print("Content-Type: text/html\n") 

print("Hello, world!")
```



こんな感じで保存し、FTPでファイルをアップロード

パーミッションを実行できるファイル（「755」）へ設定変更し、ファイルへアクセスすればブラウザ上には「Hello, world!」が表示されるかと思います



シバンの書き方でオロったので
個人的にはここがポイントです（user_nameは各自の環境で読み替えてください）www

（参考サイト：http://ura22.sakura.ne.jp/pycgi/prepare.html ）
GASの実行urlにparameterをつけて、関数内で取得する方法

GETだけじゃなくPOSTの場合でもurlのパラメーターを関数内で取得できる。

```text

https://gas-no-url?param1=value1
```

```javascript

doPost(e){
  Logger.log(e.parameter.param1); //value1
}
```
URLクラスとURLSearchParamsクラスの使い方メモ

urlをいじくり回すのはもうこれだけあればいいじゃんと思ったのでメモ。

元になるurl: `http://example.com/hoge/?a=1#foo`

---

## URLクラス

https://developer.mozilla.org/ja/docs/Web/API/URL

```js
const url = new URL(window.location);
url.href; // http://example.com/hoge/?a=1#foo
```

## URLSearchParamsクラス

https://developer.mozilla.org/ja/docs/Web/API/URLSearchParams

```js
const params = new URLSearchParams(window.location.search);
params.toString(); // a=1
```

### pathnameを置換する

```js
const url = new URL(window.location);
url.pathname = '/bar/';
url.href; //  // http://example.com/bar/?a=1#foo
```

### searchを置換する

```js
const url = new URL(window.location);
url.search = 'b=あ';
url.href; // http://example.com/hoge/?b=%E3%81%82#foo
```

### hashを置換する

```js
const url = new URL(window.location);
url.hash = 'bar';
url.href; // http://example.com/hoge/?a=1#bar
```

### searchとhashを削除する

```js
const url = new URL(window.location);
url.search = '';
url.hash = '';
url.href; // http://example.com/hoge/
```

### searchに追加する

```js
const url = new URL(window.location);
url.searchParams.append('a', 2);
url.href; // http://example.com/hoge/?a=1&a=2#foo
```

### URLSearchParamsをオブジェクトからインスタンス化する

```js
const params = new URLSearchParams({ 'b': 2 });
params.toString(); // b=2
```

### URLSearchParamsを配列からインスタンス化する

```js
const params = new URLSearchParams([['b', 1], ['b', 2]]);
params.toString(); // b=1&b=2
```

### searchをURLSearchParamsで置換する

```js
const url = new URL(window.location);
const params = new URLSearchParams([['b', 1], ['b', 2]]);
url.search = params;
url.href; // http://example.com/hoge/?b=1&b=2#foo
```
Node.js SQLの処理でnull部分をエラーなく処理する方法

今回の場合は、PostgreSQLでやっていて壁にぶち当たったのですが
他のSQLでも同じかと思います。

正常であればresult.rowsという配列にsqlの返り値が入ります。

結論

```javascript
if (Object.keys(result.rows).length > 0){
    console.log("true");
} else {
    console.log("false");
}
```
オブジェクトのキーの個数で判定してあげると
エラーが出ずにelseに入ってくれる。


rows[0]で判定した結果

```javascript
if (result.rows[0]){
    console.log("true");
} else {
    console.log("false");
}
```
これだと、値が入っていない時rows[0]はエラーになります。

次に

```javascript
if (result.rows){
    console.log("true");
} else {
    console.log("false");
}
```
これだと、値が入っていなくてもresult.rowsが存在するので
どちらもtrueになる。
AWSのEC2インスタンスの歴史

所属している会社では実はかなり前からEC2を使用しています

オンデマンドとスポットインスタンスとリザーブドインスタンスを独自に組み合わせてるのですが、
先日、ついにスポットインスタンスが足りなくなりました。利用しているRegionのAZでのキャパシティ不足のようです

今まで足りないなんて事なかったのにー！
と思いつつ調べたら弊社がリクエストしてるスポットインスタンスはc3系でした。
現行はc5系。。
そりゃ無くなるわ。。

これからはリザーブドにするかー
と思いつつ、リザーブドの3年を買った場合、3年が経過するより前に新スペックが出そうなのでちょっとだけ歴史を調べました

今一番興味あるのはc系のインスタンスなので、とりあえずc系だけ

バージョン | 利用開始月 | スパン
----|---- |----
c1 | 2008年3月 | - 
cc2 | 2011年11月 | 3年8ヶ月
c3 | 2013年11月 | 2年
c4 | 2015年1月 | 1年2ヶ月
c5 | 2017年11月 | 2年10ヶ月

大体２年スパンで新しいのが出るのですねー
次に出るのは２０２０年頃かな？

情報源は以下
https://aws.amazon.com/jp/blogs/news/
http://aws.typepad.com/aws_japan/
EasyMovieTextureで動画再生する時のあるある

# 概要
### EasyMovieTextureとは
UnityのRendereで手軽に動画を再生できるAssets様。[こちら](https://assetstore.unity.com/packages/tools/video/easy-movie-texture-video-texture-10032)
Unityの動画再生機能だとゲーム処理が止まったりするし、ちょっと変わった形状のメッシュ上で再生とかもできない。
そこでこのAssetsでごにょごにょすると、天球動画や、モデルに変わった演出をしたりもできる。

### この文書について
そんなEasyMovieTextureを使うにあたって、自分がつまずいたところをあるあるとして取り上げ、解決方法もまとめました。


# あるある
### パッケージサイズオーバー
![image.png](https://qiita-image-store.s3.amazonaws.com/0/222816/cb630619-2a3f-f55c-86af-cd66e859451d.png)
Android Asset Packaging Tool failed. See the Console for details.


```
CommandInvokationFailure: Android Asset Packaging Tool failed.

stderr[
ERROR: Zip flush failed, archive may be hosed
ERROR: packaging of 'raw.ap_' failed
]
```
上記のようなstderrが出ていたらパッケージサイズオーバーを疑いましょう。

Androidの仕様で、ファイルサイズの合計が2GB以上だとパッケージングできません。
高解像度全天球動画だと、およそ2分くらい。
これ以上はStreamingAssetsに入れられないので、
file://sdcard/movies/movie.mp4
のようにsdcardに入れておきましょう。


### 動画サイズオーバー
これも上記と似ていますが、厄介なのがエラーが出ないこと。
上記の問題を「それならちょっと動画削ればいいや」でクリアした場合に後追いで発生しやすく、
実機で動かそうとすると動画が再生できない状態になります。

これもサイズオーバーが原因で、
500MB以上のファイルがビルドされないという理由で、
再生先のファイルを見失うらしいです。


### PCビルドで試したら映らない
EasyMovieTextureはAndroid,iOS用なので、PCビルドでは表示できません。
~~これはどうしようもないのですが、ちょうどいいアセットをご存知の方が居たら教えてください。~~ 
https://twitter.com/izm さんからアドバイスいただきました！

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">こんにちはー。デカい動画はシーク時間もかかるのでbuildに含めないの推奨です。また、WindowsPCビルド時（あるいユニティエディタ）はffmpegバックエンドで再生できると思います。パス指定が変とか、動画解像度が高すぎるかも。</p>&mdash; izm (@izm) <a href="https://twitter.com/izm/status/998823049418850305?ref_src=twsrc%5Etfw">2018年5月22日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



# 募集
他にこんな問題が発生したよ、などがあれば教えてください。
こちらの方で確認したりまとめたりしたいなーと思います。
Laravelプロジェクトから別のLaravelプロジェクトのartisanコマンドをたたくと.envが勝手に実行元のがそのまま使われる

## 概要

LaravelそのものというよりはDotEnv PHPとPHP putenv()の話のようだが、
Laravelプロジェクトから別のLaravelプロジェクトのartisanコマンドをたたくと.envは実行元のが使われてしまう模様
Lumenも同様らしいし、同一サーバーCurlでも同じらしい

自分の環境は
PHP：7.2.4
Laravel：5.6.15

## 状況
```
/var/hoge
  ├LaravelA
  │  ├.env
  │  ├app
  │  ├bootstrap
  │  ├config
  │  ├public
  │  └artisan
  └LaravelB
      ├.env 
      ├app
      ├bootstrap
      ├config
      ├public
      └artisan
```

こんな感じでプロジェクトを二つ作り

LaravelAから

```php
exec("php /var/hoge/LaravelB/artisan foo:bar", $output, $return);
```

こんな感じで実行すると、artisan foo:barでは完全にLaravelBの環境で動くことが期待されるが、
なぜかLaravelBのコードで、LaravelAの.envを用いて実行される。

なかなか気づかずにLaravelAとBでDBを分けている中で、テーブルが見つからないが出まくり、
bootstrap/cache/config.php のdatabase部分の中身がどう考えても、LaravelBのconfig/database.phpにLaravelAの.envを適用したものだった

## メモ

現状はとりあえず変数レベルで上書きし、ごまかし運用

```php
            config(['database.connections.pgsql.database' => $dbConfig]);
```

同一サーバー内のCurlでも起きる模様
https://github.com/laravel/framework/issues/16407

その他見てたもの

- https://github.com/laravel/lumen-framework/issues/605
- https://github.com/laravel/framework/issues/14511

LaravelBでキャッシュクリアしても同じものが作られるだけだった

```php
// 実行後停止してしまう
$this->artisan("config:cache");
Artisan::call("config:cache");

// 後続タスクも動くが同じファイルが作られる
exec("php /var/hoge/LaravelB/artisan config:cache", $output, $return);
```

いい対応方法があれば知りたい。
6:30JST頃に Supervisor が死んだので自動アップデートを無効にした

本日 2018-05-22 6:30JST WebサービスのDjangoが軒並みダウンしていました。

※単純な復旧なら sudo service supervisor start

## 環境
16.04 LTS (Xenial Xerus)
supervisor
uwsgi
django



## 原因
supervisor の自動アップデートがあり、その後 supervisor が起動しなかった。
なぜ再起動しなかったかは不明。


```/var/log/supervisor/supervisord.log
2018-05-22 06:26:33,504 WARN received SIGTERM indicating exit request
2018-05-22 06:26:33,574 INFO waiting for torico-blog to die
...
2018-05-22 06:26:43,599 WARN killing 'torico-blog' (16181) with SIGKILL
```
supervisor が、子プロセスを KILL している


```/var/log/dpkg.log
2018-05-22 06:26:32 startup archives unpack
2018-05-22 06:26:33 upgrade supervisor:all 3.2.0-2ubuntu0.1 3.2.0-2ubuntu0.2
2018-05-22 06:26:33 status half-configured supervisor:all 3.2.0-2ubuntu0.1
2018-05-22 06:26:33 status unpacked supervisor:all 3.2.0-2ubuntu0.1
2018-05-22 06:26:33 status half-installed supervisor:all 3.2.0-2ubuntu0.1
...
```

supervisor の自動アップデートがかかったようだ。

## 対策

supervisor の自動アップデートはしないようにしました。

自動アップデートしているのは、Unattended-Upgrade です。アップデートするかしないかの設定は

```/etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
```
ここにあり、```Unattended-Upgrade "0";``` で完全無効にできます。ただし脆弱です。

完全無効にせずとも、ブラックリストが設定できますので supervisor を追加するとよさそうです。

```/etc/apt/apt.conf.d/50unattended-upgrades
// List of packages to not update (regexp are supported)
Unattended-Upgrade::Package-Blacklist {
//      "vim";
//      "libc6";
//      "libc6-dev";
//      "libc6-i686";
        "supervisor";  // ←追加
};
```
自分の書いたNim記事のまとめ

## 概要
* 自分の書いた記事を参照することが多くなったので、テキトウなカテゴリでまとめてみます

### まとめ

| カテゴリ1 | カテゴリ2 | 内容 |
| ---- | ---- | ---- |
| 文字列 |  | [nim文字列操作](/6in/items/93d8083a8a7f2542d426) |
|  |  | [nim文字列操作(unicode)](/6in/items/f47e44ee243aed47898c) |
|  |  | [nim文字列操作(正規表現)](/6in/items/df4fdc58a6f280f2c1ec) |
|  |  | [nim文字列操作(PEG)](/6in/items/badaf8ef40184304d779) |
|  |  | [テキスト表出力](/6in/items/0be083dceb88ff594f53) |
| ファイル |  | [nimファイル操作](/6in/items/cbb161c401afe054314f) |
| コレクション |  | [nimコレクション操作](/6in/items/61d16b4b86dcd15dedc5) |
|  |  | [nim内包表記](/6in/items/809f4eb788d00503a825) |
| 日付 |  | [nim日付操作](/6in/items/e9faa1a4bb3bd0a899dd) |
| JSON |  | [nimのJSON操作](/6in/items/9a45671827d9064cab98) |
| YAML |  | [nimのYAML操作](/6in/items/393768c22751feb9eda0) |
| データベース | sqlite | [nimデータベース操作(sqlite)](/6in/items/d2f145c98cd21da46ef0) |
|  | mysql | []() |
|  | postgres | [nimデータベース操作(PostgreSQL)](/6in/items/b51186e2154a089232dc) |
| プロセス | プロセス | [nimプロセス実行](/6in/items/967b4174c2881c6f0845) |
|  | スレッド | [nimスレッド操作](/6in/items/5e07c075c7d760d47ce1) |
|  | ターミナル | [Nimからターミナル実行](/6in/items/b8abb8f0410e8e1eaf6a) |
| 開発環境 | エディタ | [VSCodeによるNim開発環境](/6in/items/78c3c8995567f2244a46) |
|  | クロスコンパイル | [Nimクロスコンパイラのやり方(Linux->Windows)](/6in/items/c72d73d063146e6272fa) |
|  | デバッグ | [Nimのデバッグ](/6in/items/379bc1ba18241ddf5404) |
|  |  | [VSCodeによるNimのデバッグ(ステップ実行)](/6in/items/10325115859c93a1d6ba) |
|  |  | [Nimでマクロを利用して変数のダンプを行う](/6in/items/cabc9cac89e97ef4b826) |
|  | Nimble | [Nimbleによるプロジェクトテンプレート](/6in/items/81dd2f7fdf292149874b) |
| ツール・その他 | 拡張子検索 | [Nimで拡張子検索ツールを作ってみる](/6in/items/6a989635eb0eeaffdaab) |
|  | 文字コード判定 | [Nimでファイルの文字コードを(外部ライブラリを利用して)判定する](/6in/items/77cac18d57a6741d8eab) |
|  | 文字列置換 | [Nimでファイル内文字列置換ツールを作る](/6in/items/8860eb38ea7376503293) |
|  | JNI | [JavaからJNI経由でNimを呼び出してみる](/6in/items/c8ea07dde7b0df995480) |
|  | メイン処理 | [Nimのメイン処理とコマンドライン引数について](/6in/items/c735cb2ffbe79f3f9d94) |
|  | HTTPサーバー | [NimのAsyncServerで遊ぼうとしてみたら](/6in/items/94912afcf312bacf000b) |
|  |  | [JestyをただのHTTPサーバーとして使う](/6in/items/35aea6ece65a2a97b1c4) |
|  | ロゼッタコード | [ロゼッタコードを見やすくするTamperMonkeyScript](/6in/items/5559846d77af48c0b85d) |
|  | シングルバイナリ | [Nimから動的ライブラリに依存しないLinuxコマンドの作成](/6in/items/3544cec69dd53960c2df) |
|  | ブラウザで開発 | [どこでもNim](/6in/items/d73ccc98e3cf6b6f4468) |
|  | ソースのフォーマット | [nimprettyでソースを綺麗にする](/6in/items/06912f6526db68391109) |
|  | qiita投稿用のMD作成 | [NimでNimソース実行](/6in/items/2c7817b4d2e728b8f3fa)
Golang で MongoDB のデータを削除 (Delete)

Golang で MongoDB のデータを削除します。
次のプログラムで作成したデータを削除します。
[Golang で MongoDB のデータを作成 (Create)](https://qiita.com/ekzemplaro/items/18f49a75cb90b5060464)

ライブラリーのインストール

```bash
go get gopkg.in/mgo.v2
go get github.com/joho/godotenv
```

```golang:mongo_delete.go
// ---------------------------------------------------------------
//
//	mongo_delete.go
//
//					Jun/11/2019
// ---------------------------------------------------------------
package main

import (
	"fmt"
	"os"
	mgo "gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"time"
	"github.com/joho/godotenv"
)

type City struct {
	ID        bson.ObjectId `bson:"_id,omitempty"`
	Key      string
	Name      string
	Population     int
	Date_mod time.Time
}

// ---------------------------------------------------------------
func main() {
	fmt.Fprintf (os.Stderr,"*** 開始 ***\n")
	key_in := os.Args[1]

	fmt.Printf ("key_in = %s\n" , key_in)

	user := os.Getenv("user")
	password := os.Getenv("password")

	mongoDBDialInfo := &mgo.DialInfo{
	Addrs:    []string{"127.0.0.1"},
	Timeout:  60 * time.Second,
	Username: user,
	Password: password,
	}
	
	session, err := mgo.DialWithInfo(mongoDBDialInfo)
	if err != nil {
		panic(err)
	}

	defer session.Close()

	session.SetMode(mgo.Monotonic, true)

	db_name := "city"

	cc := session.DB(db_name).C("saitama")

	colQuerier := bson.M{"key": key_in}
	err = cc.Remove(colQuerier)
	if err != nil {
		panic(err)
	}

	fmt.Fprintf (os.Stderr,"*** 終了 ***\n")
}

// ---------------------------------------------------------------
```

```text:Makefile
mongo_delete: mongo_delete.go
	go build mongo_delete.go
clean:
	rm -f mongo_delete
```

```text:.env
user = '******'
password = '******'
```

実行コマンドの例

```bash
./mongo_delete t1167
```

次のバージョンで確認しました。

```text
$ go version
go version go1.13.8 linux/amd64

$ mongo --version
MongoDB shell version v3.6.8
git version: 8e540c0b6db93ce994cc548f000900bdc740f80a
OpenSSL version: OpenSSL 1.1.1f  31 Mar 2020
allocator: tcmalloc
modules: none
build environment:
    distarch: x86_64
    target_arch: x86_64
```
Command Pattern

# Command Pattern
コマンドで実行する振る舞いと、実際の処理を分けて考える

# Reference
- [tutorialspoint:Command](https://www.tutorialspoint.com/design_pattern/command_pattern.htm)
- [journaldev:Command](https://www.journaldev.com/1624/command-design-pattern)
- [geeksforgeeks:Command](https://www.geeksforgeeks.org/command-pattern/)
- [iluwatar:Command](https://github.com/iluwatar/java-design-patterns/tree/master/command)