OmniAICreator/Qiita-1.07M huggingface dataset:
夏休みなので小学生とPythonを勉強してみた - 課題2 掛け算九九

小学6年生の長男が夏休みの自由研究にPythonを勉強したいというので付き合ってみました。
どこから手を付けていけばわからないので、いくつか課題を出し、それを実現するコードを一緒に書くということを繰り返しました。

この記事では、「課題2 掛け算九九」について扱います。その他の課題については下記の記事をご覧ください。

* [夏休みなので小学生とPythonを勉強してみた - 課題1 FizzBuzz - Qiita](https://qiita.com/shakiyam/items/b8366fde704639abb63d)
* [夏休みなので小学生とPythonを勉強してみた - 課題3 掛け算ゲーム - Qiita](https://qiita.com/shakiyam/items/4b4df04369914df3baa6)
* [夏休みなので小学生とPythonを勉強してみた - 課題4 じゃんけん - Qiita](https://qiita.com/shakiyam/items/05c756b4726c941c1c5c)
* [夏休みなので小学生とPythonを勉強してみた - 課題5 サイコロの目の出る確率 - Qiita](https://qiita.com/shakiyam/items/9e0c5548efd0952ab250)
* [夏休みなので小学生とPythonを勉強してみた - 課題6 写真の整理 - Qiita](https://qiita.com/shakiyam/items/2dd2e2763ccf85b19126)
* [夏休みなので小学生とPythonを勉強してみた - 課題7 掛け算ゲームWeb版 - Qiita](https://qiita.com/shakiyam/items/3945a224a8774c332220)
* [夏休みなので小学生とPythonを勉強してみた - 課題8 掲示板 - Qiita](https://qiita.com/shakiyam/items/c3aa6425ff42b75d3310)
* [夏休みなので小学生とPythonを勉強してみた - 課題9 顔の検出 - Qiita](https://qiita.com/shakiyam/items/110b4819b12124587d80)
* [夏休みなので小学生とPythonを勉強してみた - 課題10 顔の認識 - Qiita](https://qiita.com/shakiyam/items/0125dd5db15976d5520e)

コードは[GitHub](https://github.com/shakiyam/python4kids)にて公開しています。

課題2-1 掛け算九九を表示する
----------------------------

### 指示 ###

掛け算九九を順番に表示するプログラムを作りましょう。

### ヒント ###

「フォーマット済み文字リテラル」を使うとprintの出力を見やすくフォーマットできます。

* [7.1.1. フォーマット済み文字列リテラル — Python チュートリアル](https://docs.python.org/ja/3/tutorial/inputoutput.html#formatted-string-literals)

### 回答例 ###

```python
for i in range(1, 10):
    for j in range(1, 10):
        print(f'{i} * {j} = {i * j}')
```

### 実行例 ###

```
1 * 1 = 1
1 * 2 = 2
1 * 3 = 3
1 * 4 = 4
1 * 5 = 5
1 * 6 = 6
1 * 7 = 7
1 * 8 = 8
1 * 9 = 9
2 * 1 = 2

途中省略

9 * 5 = 45
9 * 6 = 54
9 * 7 = 63
9 * 8 = 72
9 * 9 = 81
```

課題2-2 掛け算九九の表を表示する
--------------------------------

### 指示 ###

掛け算九九の表を順番に表示するプログラムを作りましょう。

### ヒント ###

print関数の出力で改行させないようにするには、endを指定します。

* [組み込み関数 print — Python 標準ライブラリ](https://docs.python.org/ja/3/library/functions.html#print)

### 回答例 ###

```python
for i in range(1, 10):
    for j in range(1, 10):
        print(f'{i * j:2}', end=' ')
    print()
```

### 実行例 ###

```
 1  2  3  4  5  6  7  8  9
 2  4  6  8 10 12 14 16 18
 3  6  9 12 15 18 21 24 27
 4  8 12 16 20 24 28 32 36
 5 10 15 20 25 30 35 40 45
 6 12 18 24 30 36 42 48 54
 7 14 21 28 35 42 49 56 63
 8 16 24 32 40 48 56 64 72
 9 18 27 36 45 54 63 72 81
 ```
夏休みなので小学生とPythonを勉強してみた - 課題1 FizzBuzz

小学6年生の長男が夏休みの自由研究にPythonを勉強したいというので付き合ってみました。
どこから手を付けていけばわからないので、いくつか課題を出し、それを実現するコードを一緒に書くということを繰り返しました。

この記事では、「課題1 FizzBuzz」について扱います。その他の課題については下記の記事をご覧ください。

* [夏休みなので小学生とPythonを勉強してみた - 課題2 掛け算九九 - Qiita](https://qiita.com/shakiyam/items/0e4153fe7c610b3e8e49)
* [夏休みなので小学生とPythonを勉強してみた - 課題3 掛け算ゲーム - Qiita](https://qiita.com/shakiyam/items/4b4df04369914df3baa6)
* [夏休みなので小学生とPythonを勉強してみた - 課題4 じゃんけん - Qiita](https://qiita.com/shakiyam/items/05c756b4726c941c1c5c)
* [夏休みなので小学生とPythonを勉強してみた - 課題5 サイコロの目の出る確率 - Qiita](https://qiita.com/shakiyam/items/9e0c5548efd0952ab250)
* [夏休みなので小学生とPythonを勉強してみた - 課題6 写真の整理 - Qiita](https://qiita.com/shakiyam/items/2dd2e2763ccf85b19126)
* [夏休みなので小学生とPythonを勉強してみた - 課題7 掛け算ゲームWeb版 - Qiita](https://qiita.com/shakiyam/items/3945a224a8774c332220)
* [夏休みなので小学生とPythonを勉強してみた - 課題8 掲示板 - Qiita](https://qiita.com/shakiyam/items/c3aa6425ff42b75d3310)
* [夏休みなので小学生とPythonを勉強してみた - 課題9 顔の検出 - Qiita](https://qiita.com/shakiyam/items/110b4819b12124587d80)
* [夏休みなので小学生とPythonを勉強してみた - 課題10 顔の認識 - Qiita](https://qiita.com/shakiyam/items/0125dd5db15976d5520e)

コードは[GitHub](https://github.com/shakiyam/python4kids)にて公開しています。

課題1-1 1から20まで表示する
---------------------------

### 指示 ###

1から20までを表示するプログラムを作りましょう。

### ヒント ###

連続した数字を生成するにはrange関数が便利です。

* [4.3. range() 関数 — Python チュートリアル](https://docs.python.org/ja/3/tutorial/controlflow.html#the-range-function)
* [組み込み関数 range — Python 標準ライブラリ](https://docs.python.org/ja/3/library/functions.html#func-range)

### 回答例 ###

```python
for i in range(20):
    print(i + 1)
```

```python
for i in range(1, 21):
    print(i)
```

課題1-2 3の倍数はFizzと表示する
-------------------------------

### 指示 ###

1から20までを表示するプログラムを作りましょう。ただし、3の倍数の場合はFizzと表示してください。

### ヒント ###

「もし～ならば、...」を実現するには、if文を使います。

* [4.1. if 文 — Python チュートリアル](https://docs.python.org/ja/3/tutorial/controlflow.html#if-statements)

Pythonで割り算の余りを求めるには、「%」を使います。

* [3.1.1. 数 — Python チュートリアル](https://docs.python.org/ja/3/tutorial/introduction.html#numbers)

### 回答例 ###

```python
for i in range(1, 21):
    if i % 3 == 0:
        print("Fizz")
    else:
        print(i)
```

課題1-3 5の倍数はBuzz、3と5の倍数はFizz Buzzと表示する
------------------------------------------------------

### 指示 ###

1から20までを表示するプログラムを作りましょう。ただし、3の倍数の場合はFizz、5の倍数の場合はBuzz、3と5の倍数の場合はFizzBuzzと表示してください。

### ヒント ###

if文の順番に注意。

### 回答例 ###

```python
for i in range(1, 21):
    if i % 15 == 0:
        print("FizzBuzz")
    elif i % 3 == 0:
        print("Fizz")
    elif i % 5 == 0:
        print("Buzz")
    else:
        print(i)
```
俺様サーバー構築記 - 画面色変更@デスクトップパソコン

「[俺様サーバー構築記 - 基本方針](https://qiita.com/katz_engineer/items/dbabcff4e14e9db2b10f)」以来構築を続けてきた俺様パソコン環境ですが、設定が進むにつれて、サーバとクライアントを行ったり来たりする作業が増えてきました。その結果、たまに間違えるんですよ。サーバの root で作業して、終わったつもりでそのままサーバ内で作業を続けてしまったり。

ひとまずサーバとそれ以外との区別が付けば良い、という訳で画面の色合いを変える事にしました。
私の環境ではシェルとして bash を常用していますので、このプロンプトに画面の色を変えるような設定を仕込む事にしました。

参考文献1：[Bashのプロンプトに色を付けてサーバやユーザを区別する](https://qiita.com/fernet/items/4dcb6f82520d87227121)
参考文献2：[エスケープシーケンス - 碧色工房](https://www.mm2d.net/main/legacy/c/c-06.html)

コンソール端末に対するエスケープシーケンスによる色設定なんて死ぬほど古い枯れまくった技術です。今時の若い方々は知らない方も多いでしょう、ってジェネレーションギャップを感じるほど古いです。参考文献もちょっと探せばもっと詳しいサイトが山程出てくると思いますが。

これで、下記のような配色を考えました。

サーバマシンのroot: 文字色=黒、背景色=赤
サーバマシンの一般ユーザ: プロンプトだけ文字色=白、背景色=青
クライアントマシン: 文字色=白、背景色=黒（デフォルト設定のまま）

これに基づき、下記のように設定します。

```console:サーバマシン
# cd
# ls .bash{rc,_profile}
ls: cannot access '.bashrc': No such file or directory
ls: cannot access '.bash_profile': No such file or directory
# cat >.bashrc <<'___'
> PS1='\[\e[30m\e[41m\][\u@\h \W]# '
> ___
# echo "source .bashrc" >.bash_profile
# sed -i -e "s/^PS1='\(.*\) '$/PS1='\\\\[\\\\e[37m\\\\e[44m\\\\]\1\\\\[\\\\e[39m\\\\e[49m\\\\] '/" /home/*/.bashrc /etc/skel/.bashrc
# svn ci /etc -m"Special colored prompt for the server machine"
Sending        etc/skel/.bashrc
Transmitting file data .done
Committing transaction...
Committed revision 10.
```

ちなみに ```.bashrc``` と ```.bash_profile``` については面倒臭いです。とてつもなく。

参考文献3：[.bash_profileと.bashrcなんて使い分けなくてよかったんや！](https://qiita.com/dark-space/items/cf25001f89c41341a9fd)
参考文献4：[.bashrc が反映されない件](https://jimbeam0203.hatenadiary.org/entry/20090809/1249823882)

しかしこれでユーザを間違える事は無くなりそうです。やったね :thumbsup_tone2:
docekrで/bin/sh: apt-get: not foundが出るのでbuildできない

### /bin/sh: apt-get: not foundが出る

下記の記事を参考にdockerfileにapt-getを使ったnpmのインストールを試みると
https://tsyama.hatenablog.com/entry/docker-not-found-npm

```
// このエラーが出た
/bin/sh: apt-get: not found
```

# 結論 - Alpine LinuxにUbuntuのパッケージマネージャーは使えない
この記事にAlpine Linuxのイメージには、
Ubuntuのパッケージマネージャーである`apt-get`は使えませんよ。と書いてあった。
https://stackoverflow.com/questions/45142855/bin-sh-apt-get-not-found

補足資料
[Alpine Linux で Docker イメージを劇的に小さくする](https://qiita.com/asakaguchi/items/484ba262965ef3823f61)

## 解決 - apk add --update nodejs nodejs-npm

`apt-get` -> `apk add`
解決法は上記の様にapt-getをapk addに置き換える事で解決します。

僕の場合はnodeを導入してnpmを使いたかったので`apk add --update nodejs nodejs-npm`を実行するとうまくインストールできました！


dockerfileにこれを追加してください！

```
RUN apk add --update nodejs nodejs-npm
```

1つのRUNで実行したい場合は`&& \`で繋げられます！
こちらの方が推奨されている書き方らしいですね！

```
RUN xxxx yyyy aaa && \
    aaa bbbb aa && \
    ccc hhhh iio && \
    apk add --update nodejs nodejs-npm
```

参考記事↓
https://superuser.com/questions/1125969/how-to-install-npm-in-alpine-linux

## 確認
一応確認の方法ですが、

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

でdoneと言ってくれたら下記のようにコンテナの中に入って

```
// 例
$ docker-compose exec {services} ash

// 僕の場合はphpやlaravelが入ってくるコンテナがappなので
$ docker-compose exec app ash
```

こんな感じに確認してください！

```
/WORK # node -v
> v10.16.0 
```
crontabを使うときに、個人的に気を付けていることをまとめてみた

#この記事について
Unix系OSでジョブの定時実行を行わせたいときに日々お世話になっているcrontab。
利用する際、個人的に気を付けていることを備忘も兼ねて、また案件への新規参画者が来た際に見せられるように
簡単にまとめてみることにした。

crontabとはそもそも何か？については以下のページを参照。

* crontab - Wikipedia ： https://ja.wikipedia.org/wiki/Crontab
* cronの設定方法 - Qiita ： https://qiita.com/hikouki/items/e744b3a4d356d2af12cf

#常時気を付けるべきと思う事項
##"crontab -e"の使用は厳禁
頻繁に言われていることだとは思いますが改めて。
案件に参画されたばかりの方が`crontab -e`を特に危機感を持たずに実行するのをよく見かけるので・・・。

`crontab -e` で、環境変数で指定されているエディタでcrontabファイルの編集ができるが
このときキーボードで**"e"**の隣にある**"r"**をタイプして`crontab -r`としてしまうと
**crontabに登録されている内容が警告なく全て消去されてしまう。**
万が一これを本番環境でやってしまおうものなら・・・考えただけでも恐ろしい。
当然バックアップ等がなければ復元できない。リスク回避のためにも厳禁とすべきでしょう。

上記のミスタイプへの対策として、/var/spool/cron/[ユーザ名]を直接エディタで修正してジョブを登録するという話も聞いたことが有るが、これも推奨されないと思う。
`crontab -e`で編集した際に行われる構文チェックが行われないため。

個人的には以下の方法を推奨したい。
この方法なら構文チェックもきっちり行われる。

```bash
# 現在のcrontabの設定内容をファイルに出力
crontab -l > crontab.txt

# crontabの設定内容が出力されたファイルをエディタで編集
vi crontab.txt

# 編集したファイルの内容でcrontabの設定を上書き。もし構文にミスがあればエラーとなるので安心
crontab crontab.txt
```
設定を出力したファイル（上の例ならcrontab.txt）をバージョン管理等できれば万全だと思います。

## 0分ジャストで動くジョブの登録を控える
これもよく言われる事項。
0分ジャストで実行されるジョブの登録は控え、少し時間をずらして（○時05分とか、○時10分とか）実行させるようにすべき。
理由は0分ジャストで実行されるバッチ等はその環境に複数あることが想定され、複数同時に実行されるとサーバに負荷がかかるため。

```bash
# 少しずつ時間をずらして登録すべき
05 * * * * /home/hogeuser/foo.sh
10 * * * * /home/hogeuser/bar.sh
15 * * * * /home/hogeuser/baz.sh
```

ただし、その環境で作業する人が複数いたとして、全員が「○時05分」にジョブを登録していたりすると
結局複数のジョブが同時に実行されてしまい本末転倒。
作業者が複数人いる場合はバッティングしないように調整しておくべき。

## "> /dev/null 2>&1"で実行結果を捨てるのは（基本的には）NG
実行結果がメールで通知されることへの煩わしさから、ジョブの実行結果を`> /dev/null 2>&1`で捨てることがあるが、
これではジョブの実行結果が意図したものではなかった場合に調査ができなくなってしまうので、基本的にはやめた方がいいと思う。
メールによる通知が不要なら、以下のようにファイルに実行結果を出力するなどすればよい。（放っておくとディスクフルになるので、ローテートの仕組みは別途必要）

```bash
# 推奨されない例
05 * * * * /home/hogeuser/foo.sh > /dev/null 2>&1

# 下記のように、ファイルに実行結果を出力するなどすべきと思う
10 * * * * /home/hogeuser/bar.sh >> /home/hogeuser/logfile.log
```

なお、`> /dev/null 2>&1`で結果を捨てるのが推奨されないのはジョブが失敗した場合の調査ができなくなるのを避けるためなので
別途、ジョブの実行結果がログとして出力されるような仕組みがあるのなら、`> /dev/null 2>&1`で捨ててしまってもよいと個人的には考えている。
もしも他に`> /dev/null 2>&1`を避けるべき理由があれば、**コメント欄で教えていただけると非常にありがたい**です。

#crontabでスクリプトを実行する際に注意すべきと思う事項
crontabの用途として多いのがスクリプトの定期実行だと思うので・・・。

##実行時の環境変数は、手動で実行する場合と一致させておく
つい先日、これでハマってしまったばかりです・・・。

crontabによるジョブ実行時の環境変数は、crontabの設定ファイル `/etc/crontab`に記載されたものである。
これが手動での実行時と一致していないと、意図しない結果となることがある。
crontabで`env`コマンドを実行させて、その結果を確認してみると、環境変数が違っていることが確認できる。

```sh:/etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
```
`/etc/crontab`の設定を変更すればよいのだが、
複数人で使用している環境で、既に他の人がcrontabのジョブを登録している場合
うかつに変更すると、影響が出てしまうことが考えられる。

その場合は、実行するスクリプトの1行目のシェバングに`-l`オプションをつけてあげればよい。
こうすると、そのスクリプトを実施する際の環境変数が手動の場合と同じになる。

```sh:example.sh
#!/bin/bash -l
```

#おわりに
私が普段気を付けていることを書き出してみただけの記事ですが、間違っているところもあるかもしれません。
お気づきの点、「書いてないけどコレも気を付けた方がいいよ」ってのがあれば教えていただきたいです。
都度、追記していきたいと思います。

#参考記事
Cronの使い方とテクニックと詰まったところ：https://qiita.com/UNILORN/items/a1a3f62409cdb4256219
crontabのガイドライン：https://qiita.com/onomame/items/71646c5517a39bcd01cc
スマホのボタンを押してLINEメッセージ送信

① IF「Button widget」THEN「LINE」のレシピを作る。
![Screenshot_20190813-175015.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/95d19f41-9a78-7860-3b36-8ab479af88f5.png)
![Screenshot_20190813-175048.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/6384bef1-272f-6af5-2e7c-a134887dda9e.png)
![Screenshot_20190813-175104.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/fbda8749-b74d-5199-e597-fe594380cb7a.png)
![Screenshot_20190813-175110.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/520b4cd0-7cf3-84cc-4351-0ca7b24de854.png)


② スマホのウィジェット。

![Screenshot_20190813-174945.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/c422d077-b9ec-d6c7-45d3-0c7585421976.png)
![Screenshot_20190813-174954.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145508/18417739-a895-101e-8fde-4bdafa9ef3ab.png)




https://ifttt.com/
JavaScriptを学ぶ④（ランダム宝探しゲームの作成♪）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458009/6b226f6d-7d6f-3b2d-0f29-2696c5cc8b59.gif" width=50%>

```html
<script>
  'use strict';

  const num= 5;
  const winner = Math.floor(Math.random() * num);

for (let i = 0; i < num; i++){
  const rizard = document.createElement('div');
  rizard.classList.add('box');
  if(i === winner){
    rizard.dataset.result = 'win';
  }else{
    rizard.dataset.result = 'lose';
  }

  rizard.addEventListener('click',function(){
    if(rizard.dataset.result === 'win'){
      rizard.textContent = 'Win!';
      rizard.classList.add('win');
    }else{
      rizard.textContent = 'Lose!';
      rizard.classList.add('lose');
    }
  });
  document.body.appendChild(rizard);
}
</script>
```
```css
body{
  display:flex;
  flex-wrap:wrap;
}
.box{
  width:100px;
  height:100px;
  background:skyblue;
  cursor:pointer;
  transition:0.8s;
  margin: 0 8px 8px 0;
  text-align:center;
  line-height: 100px;
}
.win{
  background:pink;
  border-radius:50%;
  transform:rotate(360deg);
}
.lose{
  transform:scale(0.9);
}
```

なかなかプログラムがややこしくなりましたが、
１つずつ確実に理解していきましょう(^^)

`const num= 5;`
`const winner = Math.floor(Math.random() * num);`
の部分から見ていきます♪

#Math.floor(Math.random() * num);
`Math.floor(Math.random() * num);`
の部分は、検索すればすごく良い記事を見つけました♪:relaxed:
[いまさらですが、Math.random()](https://qiita.com/chihiro/items/ac916100d18a51db6329)

館単に書くと、`Math.random()`は０～１未満の小数をランダムで作り出します。
`Math.floorで小数を切り捨てるという意味になります:v:

●Math.floor(数字)
小数以下を切り捨てして整数にします　以外にも、
●Math.ceil(数字)
数字を切り上げして整数にします
●Math.round(数字)
数字を四捨五入して整数にします

よって、
`const winner = Math.floor(Math.random() * num);`
は、０～５未満のランダムの数字を小数点切り捨てで作成し、
その数字を、winnerという定数にするよ～という意味になるということですね(^^)

次は、、、
for (let i = 0; i < num; i++){
  const rizard = document.createElement('div');
  rizard.classList.add('box');
  if(i === winner){
   ` rizard.dataset.result = 'win';`
  }else{
   ` rizard.dataset.result = 'lose';`
  }

#dataset.result
ここの部分は、`dataset.result`を調べてのですが、イマイチ分からず……
悲しいですが、気にしすぎずに次にいきたいと思います:cry:
フォーム作成①

簡単なフォーム作成。

````
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" type ="text/html"  charset="utf-8"/>
  <title>ゲーム作品感想フォーム</title>
</head>

<body>
  <h2>好きなゲーム作品感想投稿サイト</h2>
  <form action ="formTest1" method ="post">


  ハンドルネーム:<br />
  <input type ="text" name ="name" size ="30" value=""/><br />

  メールアドレス:<br />
  <input type ="text" name ="mail" size ="40" value=""/><br />

  性別:<br />
  <input type ="radio" name ="sex" size="20" value="男性"/>男性<br />
  <input type ="radio" name ="sex" size="20" value="女性"/>女性<br />


 ハード:<br />
<form method="POST" action=<?php echo $_SERVER["PHP_SELF"]?>

  <input type ="checkbox" name="hard" value="PS4"/>PS4
  <input type ="checkbox" name="hard" value="PS3"/>PS3
  <input type ="checkbox" name="hard" value="Switch"/>Switch
  <input type ="checkbox" name="hard" value="vita"/>vita
  <input type ="checkbox" name="hard" value="3DS"/>3DS
  <input type ="checkbox" name="hard" value ="その他"/>その他<br />

作品名:<br />
<input type ="text" name ="title" value=""><br />

ゲームの感想:<br />
<textarea  type = "text" name ="review" value =""/></textarea><br />

<input type ="submit" value="送信"/>
[Golang]goroutineを使った並行処理が、めっちゃシンプルにかける件

# お急ぎの方へ　いきなりサンプルコード

```golang:並行処理のサンプルコード
package main

import (
	"fmt"
	"time"
)

func task1() {
	fmt.Println("task1 処理開始")
	for i := 0; i < 3; i++{
		time.Sleep(time.Second * 2)
		fmt.Printf("task1 %d/3 処理済み...\n", i+1)
	}
	fmt.Println("task1 処理終了")
}

func task2() {
	fmt.Println("task2 処理開始")
	for i := 0; i < 5; i++{
		time.Sleep(time.Second * 1)
		fmt.Printf("task2 %d/5 処理済み...\n", i+1)
	}
	fmt.Println("task2 処理終了")
}

func main() {
	fmt.Println("main 処理開始")
	go task1()
	go task2()
	time.Sleep(time.Second * 8)
	fmt.Println("main 処理終了")
}
```

# 非並行処理の場合

## コード

```golang:並行処理のサンプルコード
package main

import (
	"fmt"
	"time"
)

func task1() {
	fmt.Println("task1 処理開始")
	for i := 0; i < 3; i++{
		time.Sleep(time.Second * 2)
		fmt.Printf("task1 %d/3 処理済み...\n", i+1)
	}
	fmt.Println("task1 処理終了")
}

func task2() {
	fmt.Println("task2 処理開始")
	for i := 0; i < 5; i++{
		time.Sleep(time.Second * 1)
		fmt.Printf("task2 %d/5 処理済み...\n", i+1)
	}
	fmt.Println("task2 処理終了")
}

func main() {
	fmt.Println("main 処理開始")
	task1()
	task2()
	fmt.Println("main 処理終了")
}
```

## 解説
とても簡単なコードです。

- スリープで時間を区切りながら、forループで回している
- task1メソッドとtask2メソッドは、それぞれ違う回数のループ、違う時間のスリープに設定

非並行処理の場合は、当然毎回毎回スリープに引っかかりつつも、１つずつ処理を終わらせて、次の処理に入っている様子が分かるかと思います。

## 非並行処理パターン実行の様子
![画面収録 2019-08-13 18.07.17.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330623/8fcd7b69-5eea-97f7-9f9e-0c9d6b240bd4.gif)

# 並行処理の場合

## コード

```golang:並行処理のサンプルコード
package main

import (
	"fmt"
	"time"
)

func task1() {
	fmt.Println("task1 処理開始")
	for i := 0; i < 3; i++{
		time.Sleep(time.Second * 2)
		fmt.Printf("task1 %d/3 処理済み...\n", i+1)
	}
	fmt.Println("task1 処理終了")
}

func task2() {
	fmt.Println("task2 処理開始")
	for i := 0; i < 5; i++{
		time.Sleep(time.Second * 1)
		fmt.Printf("task2 %d/5 処理済み...\n", i+1)
	}
	fmt.Println("task2 処理終了")
}

func main() {
	fmt.Println("main 処理開始")
	go task1()
	go task2()
	time.Sleep(time.Second * 8)
	fmt.Println("main 処理終了")
}
```

## 解説
内容としては、先ほどとほぼ同じ…

- スリープで時間を区切りながら、forループで回している
- task1メソッドとtask2メソッドは、それぞれ違う回数のループ、違う時間のスリープに設定

こんな感じです。

しかし、**並行処理の場合は、main処理の中に`go`という記述がしてあります。**
これによって、**task1とtask2、そしてmainは並行して処理が行われます。**

当然、毎回毎回スリープに引っかかるのですが、3手に別れてそれぞれが処理を終わらせていっているので、**実行結果が入り乱れているのが分かるかと思います。**

## 並行処理実行の様子
![画面収録 2019-08-13 18.08.52.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330623/f1cdf02a-225e-f899-db5c-e7b8751f840c.gif)
JavaScript の 変数 の 値 を 更新 ～変数名 = 上書きしたい値;～

# 目的

- JavaScriptの変数に格納されている値を上書きする方法を知る。  
※変数の基本的な記載方法は[こちら](https://qiita.com/miriwo/items/248e0cef61479e96b621)

# 押さえるポイント

- 変数に格納されている値や文字列は上書きすることができる。
- 上書きするときは「let」はいらない。

# 書き方の例

- 下記に汎用的な変数に格納されている値を上書く処理を記したJavaScriptファイルの内容を記載する。

``` javascript
# 既に定義と値の格納が完了している変数に対し、上書きを行う処理
変数名 = 数値;
変数名 = "変数に格納する文字列";
```

# より具体的な例

- 「name」という名前の変数を定義して、文字列「miriwo」を格納する。
- 「name」に格納された「miriwo」を「miritarou」に上書き(更新)する。
- 下記に変数定義と変数への格納方法を記したJavaScriptファイルの内容を記載する。

``` javascript
# 変数の定義と、「miriwo」の格納
let name = "miriwo";

# 「miriwo」を「miritarou」に上書き
name = "miritarow";
```
Windows 10 > Windows Updateが8時間経過しても終わらない > SysMain(旧名: Superfetch)を切る

```txt:動作環境
Windows 10 Pro (64bit) バージョン v1903
```

### 概要

- Windows Updateを適用したが8時間経過しても終わらない
- Disk Usage 100%になっており、それが関係するのかもしれない

### 対処

- [Windows Update hanging and causing 100% Disk usage](https://forums.tomshardware.com/threads/windows-update-hanging-and-causing-100-disk-usage.2975293/)

Superfetchを切るといいらしい。
SuperfetchはSysMainと名前が変わっている。

### SysMainを切った後

Disk Usageは再度99%になっているが、インストール中の数字の変わり方が早くなったようではある。
Disk Usageが高い状態はずっとそのままではなく、時々50%などに落ちるようではあった。

1時間30分でインストールが終わった。
Serializeを直列化なんて訳すから分からなくなるんだ

# Serializeを直列化なんて訳すから分からなくなるんだ
JavaなどにSerializeが実装されていますが、「これ日本語ではなんて言うんですか？」
とエンジニアに効くと、おそらくほとんどの方は「直列化」と答えるのではないかと思います。

ただ、よくよく考えるとこれは妙な訳です。
日本語で「直列」というと、基本的に「並列」と一対の概念で、「直列○○」があったら「並列○○」が存在するのが普通です。

しかし、エンジニアに「Serializeは直列化なんですよね。それならその反対はparallelize(並列化)なんですか？」　と聞くと、
「いや違う。deserialize(非直列化あるいは直列化復元)だ」と答えます。

何なんでしょうこれは。

## そもそもSerializeってどういう単語なんだっけ？
``serialize``という英単語自体にプログラム以外の文脈で振れたことのある方はあまり多くないのではないかと思います。
ただ、分解してみるとすぐになじみのある単語にぶつかります。

```
series (名詞・カタカナで使われるシリーズ)
↓
serial (seriesの形容詞系・シリアルナンバー　などのシリアル)
↓
serialize (serial＋ize で動詞化したもの)

```

要するに、``serialize``というのは``series化する``という英単語ということですね。

ではなぜ、これが直列化するという訳になるのか？
それは、``series``という英単語がカタカナで日本語に定着している「シリーズ」よりも広い概念で、
電気回路などの「直列」の意味を持っているからです。(英語で直列回路はseries circuitです。)
つまり、``series``の一部の「直列」に当たる部分として訳すと``serialize = 直列化``という図式が出来るわけですね。

### Serialize=直列化で一対一なのか？
``series``という単語が「直列」の意味を含んでいて、serializeはその派生語のため「直列化」の**意味にもなりうる**ということはわかりました。
では、``serialize=直列化``の図式は常に成り立つのでしょうか？
これに関しては**明確にNo**です。
例えば、英英辞典でSerializeを確かめてみると、以下の解説が出てきます。

```
to print or broadcast a story in several separate parts
```
https://www.ldoceonline.com/jp/dictionary/serialize

この場合、日本語としては「連載する」とか「シリーズ化する」と言った意味合いです。
つまり、``serialize``というのは文字通り``series化``することを意味しており、かなり幅の広い``series``という単語の守備範囲のうち**どこを指しているのかは、文脈から判断しなければならない**ということです。

### seriesという単語の守備範囲
``series``という言葉は「連続して続くこと・もの」を指します。
参考:
https://eng-etymo.com/archives/4513
https://ejje.weblio.jp/content/series

この概念を電気回路や並列処理の文脈に適用すれば「直列」と言うことになりますし、
採番に適用してSerialNumberとすると通し番号と言うことになります。

それでは、プログラムにおけるSerializeはどのような文脈なのか？
英語版Wikipediaで確認してみましょう

```
In computer science, in the context of data storage, serialization (or serialisation) is the process of translating data structures or object state into a format that can be stored (for example, in a file or memory buffer) or transmitted (for example, across a network connection link) and reconstructed later (possibly in a different computer environment).[1] When the resulting series of bits is reread according to the serialization format, it can be used to create a semantically identical clone of the original object. For many complex objects, such as those that make extensive use of references, this process is not straightforward. Serialization of object-oriented objects does not include any of their associated methods with which they were previously linked.

This process of serializing an object is also called marshalling an object.[2] The opposite operation, extracting a data structure from a series of bytes, is deserialization (also called unmarshalling).

```
https://en.wikipedia.org/wiki/Serialization

この中でseries系の単語が使われている部分は以下の2か所です。

```
When the resulting series of bits is reread according to the serialization format,

The opposite operation, extracting a data structure from a series of bytes,
```

それぞれ、
「(Serializationの)結果のビット列(series of bits)がSerializationの形式に則て再読み込みされた場合」
「(Serializationの)反対の処理、すなわちバイト配列(series of bytes)から構造を抽出すること」
と言ったところでしょうか。

要するにこの場合のSerializeはビットないしバイト「列」(series)化するという意味です。
「直列化」でも間違ってはいないのかも知れませんが、素直に「バイト列化」あたりに訳した方が意味が通りやすいと思います。

## まとめ
* JavaなどにおけるSeriazlize=バイト列化する
* 英語=日本語で一対一だと思って訳すと守備範囲が異なる単語で変な訳になる
Laradockでサクッとnuxt.js環境を作る

Laradockの立ち上げ方は、[Laradockの公式ドキュメント](https://laradock.io/getting-started/)を読みましょう。

## Laradockのdocker-compose.ymlを修正する。

laradoclディレクトリ内のdocker-compose.ymlファイルを以下のように修正します。

```

### Workspace Utilities ##################################
workspace:

ports:
        - "${WORKSPACE_SSH_PORT}:22"
        - "3000:3000"
```

`docker-compose up -d workspace`でworkspaceコンテナを立ち上げましょう。

`npx create-nuxt-app {好きなアプリ名}`コマンドを打ちます。

インストール前にいろいろオプションを聞かれますが、axiosの使用やSSR（サーバサイドと連携させる）のか、SPA（シングルページ構成）にするのかあたりを決めておけば、あとはnoneかデフォルトを選んでおけばいいと思います。

後から追加や削除もできるので、よくわからない人はとりあえずエンター押して進めましょう。

そうすると、インストールが始まります。

インストールが完了したら、`cd アプリ名`でアプリのルートディレクトリに行きます。

`vi package.json`コマンドを打ちます。

以下のように修正してください。

`dev`が`nuxt`のみになっていますが、IPとポートを指定してあげます。

```
"scripts": {
    "dev": "HOST=0.0.0.0 PORT=3000 nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "test": "jest"
  },
```


`yarn dev`もしくは `npm run dev`でターミナルにこんな感じの表示が出ればOKです。

（IPは若干誤差があるはずです）

```
   ╭─────────────────────────────────────────────╮
   │                                             │
   │   Nuxt.js v2.8.1                            │
   │   Running in development mode (universal)   │
   │                                             │
   │   Listening on: http://172.21.0.2:3000/     │
   │                                             │
   ╰─────────────────────────────────────────────╯
```

ブラウザで`localhost:3000`を打てば、nuxtのトップページが表示されるはずです。
VCIでラグドールを作る（Lua不要）

#概要
<blockquote class="twitter-tweet"><p lang="cy" dir="ltr">© Unity Technologies Japan/UCL <a href="https://t.co/WcaotcAb4j">pic.twitter.com/WcaotcAb4j</a></p>&mdash; 120 (@120byte) <a href="https://twitter.com/120byte/status/1161179663378472960?ref_src=twsrc%5Etfw">August 13, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
これの作例を書きます。
#作例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286581/0f493693-0bb7-d6d3-3daf-ac5922a68c01.png)
まず掴むためだけのサブアイテムを作ります。何故こんなことをしたかは後述の注意をご覧ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286581/0d42bf1f-78ed-31d0-19b1-dc830a06d1e6.png)
人型のrootにFixed Jointを付けて先の掴む用オブジェクトをConnected Bodyに指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286581/18d3b4de-3287-6b10-9bb6-3ecad379257a.png)
後は各関節構造に従って順にHinge JointのConnected Bodyを指定します。関節のオブジェクト？を外に引っ張り出す必要はありませんが、この方が作業しやすかったです。なお、これらの関節部分にサブアイテムを付ける必要はありません。付けても良いですが、合わせて必要になるであろうコライダーを追加すると物理が暴れやすくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286581/cfa499df-ff69-5e3c-2565-ad900186347c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286581/b4a211f9-4c10-fe3a-a76b-199bb1f216d1.png)
仕上げに各関節の可動範囲(Hinge JointのUse LimitをONにしてLimitのMinとMaxを設定)を指定します。図のガイドはEdit Joint Angular Limitsの左のボタンを押すと表示されます。図のように全部見たければ対象を複数選択してから押せば図のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286581/978f350b-c425-313e-908e-23191aa9427d.png)
MinとMaxが左右で同じ値を使えない場合(設定しても反対側を向く時)はAxisの値をマイナスにすると良いかもです。
#可動範囲参考値
首：-30～30
腕：-60～80
肘：0～60
手首：-30～30
足：-120～30
膝：0～140
足首：-60～45
#捕捉
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286581/bfe17a22-3432-fbcd-98b3-5a3c9c9848cc.png)
足と手は垂直・水平だと流石に違和感があるので少し角度を付けました。この場合、Hinge JointのAxisの値を小数点単位で調整して角度を合わせています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286581/99f445e2-ae13-2fc3-0734-3a95c37d3054.png)
左腕の例
#注意
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">人型は直接持たない方が良い……？ <a href="https://t.co/qF9y2VWhJ9">pic.twitter.com/qF9y2VWhJ9</a></p>&mdash; 120 (@120byte) <a href="https://twitter.com/120byte/status/1161011085643673600?ref_src=twsrc%5Etfw">August 12, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
原因は良く分かっていませんが、人型のrootに直接サブアイテムとコライダーを入れて掴むと暴れてしまいました。
#余談
アリシアさんのFBX(VRMではない)をVCIで取り込んでバーチャルキャスト内で表示すると、右腕が左側にめり込む謎現象が発生するので、一度VRMに変換してVRM系コンポーネントを全部削除して使っています。一度VRMを通ると関節角が正規化されるのでこの効果を期待した所、右腕の不具合？を回避できました。可動範囲の参考値もVRMの正規化が適用されていれば、別モデルでも同じ値が使えるかもしれません。
作例では表情が付いていますが、アニメーションで対応しています。
#関連
ニコニ立体ちゃん（アリシア・ソリッド）
https://3d.nicovideo.jp/alicia/
Cube Room
https://poly.google.com/view/1fahMeqZOw_
生贄モデル（暴れてた子）
https://3d.nicovideo.jp/works/td33034
VCIで人型の関節を動かす
https://qiita.com/120byte/items/485e38c935ddc547bb63
VCIで人型の関節を動かす２
https://qiita.com/120byte/items/44c1f024f9133f0bf050

© Unity Technologies Japan/UCL
Laravelにおけるメール送信方法まとめ

# やること
1.Mailableクラスの作成（app/mailディレクトリ）
2.Mailableクラスにbuild()の記載（textやsubjectメソッドの指定など）
3.mailファザードのtoメソッドを記載
4.メールテンプレートの作成

# Mailableクラス
　Laravelではメール送付のためのクラスとして、
　Mailableクラスがある。

```php

php artisan make:mail クラス名
```
　を実行するとapp/Mailディレクトリにクラスが作成される。

# Mailableクラスで使えるメソッド
mailableクラスの設定は、buildメソッド中で行う。
Mailableクラスで記載のクラス内にすでにbuildメソッドがあるので、
その中で記載していく。

- from：メールの送信者を指定
- with:テンプレートビューへデータを渡す（メール内でファイル名やIDを表示する場合など）
- subject:メールタイトルを指定
- text:メールを平文テキストで送付する際にtextメソッドでテンプレートを指定する
- view:メールをHTMLで送付する際にtextメソッドでテンプレートを指定する

なお、text,viewのテンプレートの場所は引数で指定する。

```php

/**
 * メッセージの生成
 *
 * @return $this
 */
public function build()
{
    return $this->view('emails.orders.shipped')
                ->from('example@example.com');
}
```

# メール送付のためのクラスの呼び出し
クラスの呼び出しはmailファザードのtoメソッドを使用することでメールを送付することが可能。
引数に宛先を渡してあげ、sendメソッドに渡す。
コントローラーに記載とLaravelリファレンスでは書いてあるが、
処理次第ではコントローラー以外でも問題なさそう。

```php

Mail::to(宛先)->send(new Mailableのクラス名($パラメーター));
```

# テンプレートの作成
textまたはviewで指定したディレクトリ配下にテンプレートを作成する。
テンプレートは通常Blade テンプレートで記載する。
Blade テンプレートなので、Withで渡した引数をテンプレート内で{{ @変数名 }}で使用可能。

```php

class CompleteMail extends Mailable
{
    use Queueable, SerializesModels;

    // パラメータ
    public $parameter;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($parameter)
    {
        $this->parameter = $parameter;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        $q_id = $this->parameter['q_id']
        return $this->view('emails.orders.shipped')
                    ->from('example@example.com');
                    ->with([
                        'q_id' => $q_id
                    ])
    }
```

```

この度はお問合いただきまして誠にありがとうございます。

─────────■　問い合わせID　■──────────
{{ @q_id }}

今後とも、よろしくお願いいたします。

```


# ローカル開発時の動作確認
メールログは、
ConfigのMail.phpにあるdriverを

```
　'driver' => 'log',
  'pretend' => false,
```
に変更することでLog上にメールタイトルから宛先、本文などが落ちるようになる。


---
**参考**
 [Laravelリファレンス](https://readouble.com/laravel/5.5/ja/mail.html)
chromeのinactiveタブの描画問題

### 概要

chromeでinactiveタブにJS処理を実行して描画する時に、うまくレンダリングされないことがある。

### 内容

1. タブAでボタンをクリックすると、新たなタブBを開く
2. タブBである処理が終わったらタグ間通信でタブAに通知する
3. タブAでタブBでの処理完了を受信したら、タブA画面の検索結果一覧を再描画する
4. ユーザがタブBで閉じるボタンをクリックしたら、タブBのウインドウを閉めてタブAの画面に戻す
5. タブAの検索結果一覧（ReactList）をスクロールしても、本来のスクロールイベントが発生しないため、問題が発覚する

### 環境

OS:MacOS High Sierra V10.13.6
Chrome： V76.0.3809.100


### 原因

Chromeが裏タグのレンダリングは普段と違って何かあるではないかと推測される


### 対策

原因がはっきりと分からないので、タブAの再レンダリング処理の実行タイミングをactiveになる時(`focus`イベント)に変更する。
円周率を再度考えてみた

#円周率とは
小学生のときに円周率を習いますが、改めて円周率とは何かと言われると難しいです。

円周率の定義：直径１に対する円周の長さ（もしくは半径１に対する上半分の円周の長さ）

昔はこのように習いますが、そもそも円とは何か、円周の長さとは何か、ということが曖昧なままになっていたと思いますので、改めて考えていきます。

#定義再考
半径ｒの円：$x^2+y^2≦r^2$を満たす$(x,y)$の集合全体を円と呼び、その境界$x^2+y^2=r^2$を満たす$(x,y)$の集合全体を円周と呼ぶ
曲線の長さ：$C^1$級関数$y=f(x)$に対して、
$\int_a^b \sqrt{1 + f^{'}(x)^2}dx$となる
※なぜこうなるのかは微分積分の本を参照してください
円周の長さ：半径の長さ１の円の方程式（上半分のみ）$y=\sqrt{1 - x^2} (-1 \leq x \leq 1) $対して、曲線の長さの公式を適用すると
$$Θ(t)=\int_t^1\sqrt{1+y^{'}(x)^2}dx$$
これが、x座標が$t$から$1$まで動く時の円の長さになります。そうすると、円周率の定義は$-1$から$1$までの長さとするべきなので、$t=-1$としたときの$Θ(-1)$について
$$\begin{align}\pi &= \int_{-1}^1\sqrt{1+y^{'}(x)^2}dx
\end{align}$$


で円周率を定義すべきといえます。

円周率の定義をするのに微分積分が必要なのかと思うかもしれませんが、数学の辞書を見ると積分を使った定義が書いてあったりします。また定義といってもいくつかパターンがあるようですが、どれも本当にきっちりやろうとすると、高校や大学以上の数学が必要になります。数学では曖昧さがあれば思わぬところで大きな間違いをしてしまうので、厳密にやることが求められます。

#円周の長さが半径（直径）の長さに比例するかを確認
半径$r$の円の方程式$x^2+y^2=r^2$に対して曲線の長さの公式と、積分の変数変換の公式を使うと$\int_{-r}^r\sqrt{1+y^{'}(x)^2}dx=r\int_{-1}^1\sqrt{1+y^{'}(x)^2}dx$となるので、半径$r$の円周の長さ（上半分）=$\pi×r$となります。$\pi$は定数なので、円周の長さは半径$r$に比例することが分かりました。曲線の長さの公式では$y^{'}(x)$に2乗がついているので、上半分も下半分も同じ長さです。これにより、円周の長さは$2\pi r$になります。
ubuntuでC++をpython3に公開する

## 初めに
C++のソースをpython3で使用するためにboostpythonをインストールしました。
一般的な方法だとboostを公式サイトからダウンロードして使用するみたいですが、pythonとC++の共有以外のboostは特に必要ないため楽な方法がないか探してaptインストールを見つけました。

## 環境
 - Ubuntu:18.04.2
 - python3:3.6.8

## 必要ライブラリのインストール
1.最初にaptのインストールリポジトリを最新にします。

```
apt update
```

2.ubuntuのバージョンによっては既にインストールされているため、不要ですが今回はなかったのでpython3をインストールします。

```
apt install python3
```

3.boostpythonに必要なため、pythonとC++の共通ライブラリをインストールします。

```
apt install build-essential python3-dev
```

4.今回の目玉であるboostpythonをインストールする

```
apt install libboost-dev
```


@additengineer さんのコメントで以下のコマンドを追加。
ライブラリのインストール可能なバージョンや環境によってはmake時に-lのライブラリパスがない旨のエラーがでます。その際は、以下を入れてください。

```
apt install libboost-all-dev
```

## 使用方法
1.pythonに公開するC++のソースを作成します。今回はわかりやすくするため、クラスではなく文字列を返却する関数。


``` C++:CModule.cpp
#include <boost/python.hpp>

std::string hello() {
    return "hello world";
}

BOOST_PYTHON_MODULE(CModule) {
    using namespace boost::python;
    def("hello", &hello);
}
```

2.C++のコンパイルのために必要なので、boostpythonの内部で使用するpythonとC++の共有ライブラリのパスを調べます。※python2とpython3が共存している環境ではpython3側を明示的に指定すること

```
python3 -c 'from distutils.sysconfig import *; print(get_python_inc())'
```

3.コンパイルは、簡単にするため今回はmakeファイルを使用せずにg++でコンパイルをします。

```
g++ -I 2で調べたインクルードパス -DPIC -shared -fPIC -o アウトプットモジュール名 1で作成したC++ファイル -lboost_python3
```
```
g++ -I/usr/include/python3.6m -DPIC -shared -fPIC -o CModule.so CModule.cpp -lboost_python3
```

4.pythonから呼び出す
   公開したC++の設定どおりにpython側から該当関数を呼び出す。

``` python
>>> import CModule
>>> CModule.hello()
'hello world'
```
[Ruby] Unicode 文字について調べるための Ruby スクリプト

# Ruby スクリプトについて

Unicode 文字について調べるとき https://www.compart.com/en/unicode というサイトを利用している。毎回ブラウザで検索欄にコードポイントを入力して検索するのは面倒なので、次の Ruby スクリプトを用意した。

```rb:unicode
#! /usr/bin/env ruby
# frozen_string_literal: true
require 'net/http'
require 'pathname'

if ARGV.empty?
  puts('コマンドライン引数を指定してください。')
  exit(1)
end

URL = 'https://www.compart.com/en/unicode'

ARGV[0].chars.each.with_index(1) do |char, i|
  # (例) 鬱 -> U+9B31
  unicode = format('U+%04X', char.ord)

  uri = URI(Pathname(URL).join(unicode).to_s)
  response = Net::HTTP.get_response(uri)

  message =
    case response.code.to_i
    when 200
      uri
    when 404
      '見つかりませんでした'
    else
      "レスポンスエラー #{response.code})"
    end

  puts("(#{i}) #{char} (#{unicode}): #{message}")
end
```

# 実行例

```:stdout
$ ./unicode ニ二
(1) ニ (U+30CB): https://www.compart.com/en/unicode/U+30CB
(2) 二 (U+4E8C): https://www.compart.com/en/unicode/U+4E8C

$ ./unicode 👨‍👩‍👧‍👦
(1) 👨 (U+1F468): https://www.compart.com/en/unicode/U+1F468
(2) ‍ (U+200D): https://www.compart.com/en/unicode/U+200D
(3) 👩 (U+1F469): https://www.compart.com/en/unicode/U+1F469
(4) ‍ (U+200D): https://www.compart.com/en/unicode/U+200D
(5) 👧 (U+1F467): https://www.compart.com/en/unicode/U+1F467
(6) ‍ (U+200D): https://www.compart.com/en/unicode/U+200D
(7) 👦 (U+1F466): https://www.compart.com/en/unicode/U+1F466
```

iTerm2 を使っている場合、command キーを押しながらターミナル上の URL をクリックすることでブラウザで開くことができる。
Javaの管理とSTS(Eclipse)のビルドパスの設定

## JavaのVersion管理
Javaのversionめっちゃあるので、[sdkman](https://sdkman.io/)で管理しています。

最近インストールの書き方が難しくなりました。後ろの`adpt`忘れないように!

```bash
sdk install java 11.0.4.j9-adpt
```


## とあるプロジェクトのjavaのversionを指定
とあるプロジェクトのjava-versionを指定したいです、ので、[jenv](https://github.com/jenv/jenv)を利用します。


sdkmanで入れたやつはこんな感じでjenvに追加できる。

```bash
jenv add ~/.sdkman/candidates/java/11.0.4.j9-adpt/
```

ディレクトリ直下に`.java-version`ファイルを置くことで、そこに書かれたJavaのversionがそのディレクトリで利用されるようになる

```bash
$ cat .java-version
openjdk64-11.0.4

$ java --version
openjdk 11.0.4 2019-07-16
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.4+11)
Eclipse OpenJ9 VM AdoptOpenJDK (build openj9-0.15.1, JRE 11 Mac OS X amd64-64-Bit Compressed References 20190717_289 (JIT enabled, AOT enabled)
OpenJ9   - 0f66c6431
OMR      - ec782f26
JCL      - fa49279450 based on jdk-11.0.4+11)
```

### STS(Eclipse)に設定
いつもわからなくなるEclipseの設定

メニューの`環境設定` -> `Installed JRE`でAddして、先ほどのJDKのパス突っ込んであげる 

<img width="693" alt="スクリーンショット 2019-08-13 17.05.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199256/c7c07132-0fc1-f37b-8294-fb1a1bbd69d7.png">

終わりです。
仕事の空き時間でツールを作る (飽き性向け)

# 最初に
仕事中の合間合間にできる手透きな時間、たまにあると思います。
ニュース見たり qiita見たり、適当に時間を過ごしますが、飽きてきますよね。

飽きたので、何か作りましょう。**何でも**いいです。

開発期間が長くても飽きるので短時間で作りましょう。


# 何を作るか
仕事中に使い辛い機能とか、操作があるかと思います。
それを改善する為のツールを作りましょう。

あるいは電卓でも良いです。キー入力判断できるツールとか、ただ時間を表示するだけでも良いです。

**ハードルは下げれば下げただけ**良いです。

# 1時間で
大したものは作れませんし、作りたくありません。必要最低限レベルのモノしか作らないようにしましょう。1時間で作りましょう。
見た目、操作性は一度捨てた方がやり易いです。

# 何の目的で作るのか
業務改善のツールを作る...という目的で作れたら立派ですが、暇だからです。


# 環境
使い慣れたモノか、visualStudioを使いましょう。

画面を作れる環境だと良いです（分かりやすいので）。

# 作る
Windows フォームアプリケーション等でプロジェクトを作成しましょう。

ぼんやり完成イメージが掴めるなら、**なるべく簡素に**作成しましょう。簡素に。
あるいは、こんな感じに作りましょう。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365607/b2c93c0b-9d96-ac46-e84c-ea7699665b8e.png)
↑ ①プロジェクトを作ります　（満足度が違うので名前は考えて付けたほうが良い）
</br>
</br>
![無題2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365607/362d1ffc-534a-0f51-0ce0-527df8d3be81.png)
↑ ②ボタンを置きます
</br>
</br>
![無題3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365607/84ae7868-f637-bfea-a258-24a31c9e7bfa.png)
↑ ③ボタンのクリックイベントに処理を書きます（ここではフォームテキストが1⇒2⇒3...になる想定で作ってます）

</br>
![無題4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365607/8aac95cb-f33a-b2e5-54bb-479fe53de638.png)
↑想定通りになりました。

想定通りにならなかったら、一度放棄しましょう。
次に暇なときに作り直すか、別のモノを作りましょう。

修正するより、新しく作ったほうがやる気が出ます。


## ちゃんと動いたら
喜びましょう。

</br>
## 次に暇になったら
新しいモノを作りましょう。

でも、作ったものに愛着が湧いているなら、
デザインを凝ったり、新機能を追加してあげましょう。

## 最後に
暇な時でOKです。

</br>
</br>
人に伝わるように書くって難しいネ
[Swift 5]URLからクエリパラメータを取得する方法:URLComponentsを使用

今回、URLスキームで渡されるクエリを使用したいために調べました。
もちろん、httpから始まるURLのクエリを取得する時にも使えます。

`https://www.example.com/index.php?message=arigato`
みたいなURLの時、
クエリ部分である`?message=arigato`の`arigato`が使いたい時

```swift
// URLからURLComponentsにする
let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true)
    if let queryValue = urlComponents?.queryItems?.first?.value {
        print(queryValue)  // -> arigato
    }
```
クエリが一つだけ、もしくは1番目のものを使いたい時はこれだけでOKです。
複数のクエリがあるときは、`queryItems`が配列になっているので、適切な方法でアクセスしましょう
e.g. `queryItems[2]`

`=`の左が`name`、右側が`value`で取得できます。

e.g. `queryItems[2].name`, `queryItems[2].value`

最初は`url.query.components(separatedBy:"=")`などで文字列分割しようとしていたけど、適切な方法が見つかってよかった！^-^

##参考
https://stackoverflow.com/questions/43118687/split-url-query-in-swift
https://stackoverflow.com/questions/38720933/whats-the-difference-between-passing-false-and-true-to-resolvingagainstbaseurl
【Flutter】DioでHttp通信のログを出力する

# 背景
私はFlutterのHttpクライアントに[Dio](https://github.com/flutterchina/dio)を使っています。
今回は通信がうまくいっていなかったため、ログを確認したいと思いました。

# 対応
DioにはInterceptorを追加することができます。
今回はデフォルトで用意されている`LogInterceptor`を追加しました。

```dart:
final dio = Dio();
dio.interceptors.add(LogInterceptor());
```

この状態で通信すると下記のようにログが出力されます。

```
I/flutter (27182): *** Request ***
I/flutter (27182): uri: <リクエストURL>
I/flutter (27182): method: GET
I/flutter (27182): contentType: application/json; charset=utf-8
I/flutter (27182): responseType: ResponseType.json
I/flutter (27182): followRedirects: true
I/flutter (27182): connectTimeout: 0
I/flutter (27182): receiveTimeout: 0
I/flutter (27182): extra: {}
I/flutter (27182): header: 
I/flutter (27182):  <ヘッダー名>: <値>
I/flutter (27182): 
I/flutter (27182): *** DioError ***:
I/flutter (27182): DioError [DioErrorType.RESPONSE]: Http status error [404]
I/flutter (27182): uri: <リクエストURL>
I/flutter (27182): statusCode: 404
I/flutter (27182): headers:
I/flutter (27182):  <ヘッダー名>: <値>
I/flutter (27182):  
```

どうやら404でエラーになっていたようです。
VS Code のターミナルからインストールしたライブラリを実行する

# はじめに
VS Code のターミナルから、npmやyarnでローカルインストールしたパッケージを実行すると、「そんなコマンド無いです。」的なメッセージが出がちです。

例えば、ローカルインストールした eslint を実行すると、

```cmd:Windows
'eslint' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
```
とか

```bash:MacOS
bash: eslint: command not found 
```
の様に実行できません。ローカルインストールした先を環境変数 PATH に設定してないからですが、かといって毎回 `./node_modules/.bin/eslint` などと打つのは流石につらい。。

# 環境変数 PATH を設定する
VS Code のワークスペースに環境変数が設定できるので、以下の様に PATH を設定しておくと便利です。

```json:.code-workspace
{
  "folders": [
    {
      "path": "."
    }
  ],
  "settings": {
    "terminal.integrated.env.windows": {
      "PATH": "${workspaceRoot}\\node_modules\\.bin;${env:PATH}"
    },
    "terminal.integrated.env.osx": {
      "PATH": "${workspaceRoot}/node_modules/.bin:${env:PATH}"
    }
  }
}
```

Windows　なら `terminal.integrated.env.windows`、
Mac なら `terminal.integrated.env.osx`、
に記載します。
Linux なら `terminal.integrated.env.linux` らしいです。値は多分 Mac と同じだと思います。（環境が無いので未確認。）

package.jsonファイルと同じ場所に .code-workspaceファイルを置くのが好み（`folders.path` が `.` からも見て取れますね。）なんですが、ユーザー設定に書く方が一般的なんでしょうか？
確かにワークスペース毎に設定ってもの非効率ですかね？
ユーザー設定なら以下な感じでしょうか。

```json:settings.json
{
  "terminal.integrated.env.windows": {
    "PATH": "${workspaceRoot}\\node_modules\\.bin;${env:PATH}"
  },
  "terminal.integrated.env.osx": {
    "PATH": "${workspaceRoot}/node_modules/.bin:${env:PATH}"
  }
}
```

# .code-workspace ファイルとは
Visual Studio や eclipse で言う「プロジェクトファイル」の様なイメージでしょうか。
VS Code のメニューから「ファイル」-「名前を付けてワークスペースを保存」で、作業中のワークスペースを保存できます。「hogehoge.code-workspace」の様に名前を付けられます。
VS Code は前回のワークスペースをデフォルトで開きますが、複数のワークスペースの作業をしている場合は、対象の .code-workspace ファイルをダブルクリックで開けて便利だと思います。

# 頻繁に使うコマンドは package.json の script に書く
これなら、自動で `./node_modules/.bin` にPATHが通った状態だし、VS Code のメニューから「ターミナル」-「タスクの実行」で実行できるので便利です。

```json:package.json
{
...(略)...
  "scripts": {
    "lint": "eslint src/ --ext .ts"
  },
...(略)...
}
```
みたいな。（例です。コマンドでlintってしないよね。。）

# まとめ
複数の開発環境が同居してるのに PATH の設定が辛いからグローバルインストール、あーバージョンがー、といった事態は無くせるんじゃないでしょうか。
正規表現におけるメタ文字とバックスラッシュの役割

##1,正規表現とは?

正規表現とは、**「いくつかの文字列を一つの形式で表現するための表現方法」**です。

どういう意味かと言うと、例えば電話番号って１１桁あるけど、

「090-1111-1111」のように間に「-」を挟むことが多いです。別の書き方で「09011111111」と「-」を書かずにそのまま１１桁で表記することもあります。

このように同じ意味でも異なった表記をする場合があるので、それら全てを同じフォーマットで統一させるのが正規表現の役割なのです。

##2,メタ文字とは?

正規表現で文字列を表現するとき、いくつかの特殊文字を使うことがあります。

`.   ^   $   [   ]   *   +   ?   |   (   )`

これらの特殊文字を**メタ文字**と呼びます。メタ文字の役割は普通の文字以上の役割を果たします。

以上の解説だとわかりにくいと思うので、例をだして説明します。

`.`このコンマはなんでもいい一文字を表します。

```javascript

str.match(/a\.c/)
```

上のようなコードの場合、aとcの間には何でも文字が入るわけです。abcでもazxでもマッチングが成立します。

##3.バックスラッシュ(/)の役割は?

`.`のような特殊文字を使用する場合、文字の直前に**バックスラッシュ**をつける必要があります。

```javascript

'I have 3 pens'.match(/\d/)

=> #<MatchData "3">
```

`d`という特殊文字は何らかの数字を表す文字で、その直前に`\`をつけることで使用できます。

`'I have 3 pens'`の文字列で数字を表すのは3なので、3とマッチングするわけです。

##補足:正規表現の一覧

正規表現のメタ文字はたくさん種類があります。全て覚える必要はないと思いますが、どんなメタ文字があるのか興味を持つこともいいでしょう。

[正規表現一覧](http://gimite.net/help/devas-ja/all_regex.html)
MediaConvert で設定ファイルが出し入れ可能に！

あつがなついですね。streampack 木村です。
このスプーナリズムな言い回しは古くはエンタツ・アチャコまで遡るそうです。

さて、そんな真夏の最中、AWS MediaConvert がコンソール上で設定ファイル（JSON） の入出力に対応したとのことで触ってみました。（2019/8/9 新機能）

[AWS Elemental MediaConvert Simplifies Editing and Sharing of Settings](
https://aws.amazon.com/jp/about-aws/whats-new/2019/08/aws-elemental-mediaconvert-simplifies-editing-and-sharing-of-settings/)

# ジョブの作成

まずは適当に一つジョブを作成してみます。
以前の記事で作った CMAF 出力を流用します。

[AWS MediaConvert で CMAF を試す！](https://qiita.com/tomopyonsama/items/e4d58af20928cab41cb5)

こんな感じ

<img width="955" alt="スクリーンショット 2019-08-13 15.11.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172426/a4f1e50b-9078-f85f-7eb3-8fa990ce45a8.png">

# ジョブのエクスポート

先程作成した`ジョブの概要`を開くと、`JSONのエクスポート`という新しい項目がありますのでこれをクリックすると JSON ファイルを保存できます。

<img width="655" alt="スクリーンショット 2019-08-13 15.12.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172426/e3df9163-066b-1d1c-1e49-6f43c46b08f2.png">

# ジョブの編集

設定値はすべて編集できますが、とりあえずビデオのビットレートと出力先を変更し、適当に名前をつけて保存します。

## ビットレート

`"Bitrate": 1500000,` から
`"Bitrate": 1000000,` に

## 出力先

`"Destination": "s3://media-conv/encoded/cmaf/bbb1500/",` から
`"Destination": "s3://media-conv/encoded/cmaf/bbb1000/",` に


# ジョブの作成

さて、保存した JSON を使って新規ジョブを作成します。
`Import job` をクリックして JSON を選択します。

<img width="939" alt="スクリーンショット 2019-08-13 15.18.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172426/2cf6fdf8-bc32-1169-0015-d0efb63649ea.png">

ジョブがインポートされるので画面右下の `作成` をクリックするとキューに追加されエンコードが開始されます。


# おまけ

AWS CLI なら普通にコマンドで取得できます。

```
$ aws --endpoint-url https://xxxxxxxxxx.mediaconvert.ap-northeast-1.amazonaws.com --profile xxx mediaconvert get-job --id 1565677146840-yd2ab2
{
    "Job": {
        "Arn": "arn:aws:mediaconvert:ap-northeast-1:591693767697:jobs/1565677146840-yd2ab2",
        "CreatedAt": 1565677146,
        "Id": "1565677146840-yd2ab2",
        "OutputGroupDetails": [
            {
                "OutputDetails": [
                    {
                        "DurationInMs": 596400,
                        "VideoDetails": {
                            "HeightInPx": 608,
                            "WidthInPx": 1080
・・・以下略
```

# まとめ

同じアカウント内でコピーする場合はコンソール上からジョブの `複製` で簡単にコピーできますので使いみちが思い浮かびませんが、もし異なるアカウントでジョブ設定を移行する場合は便利なのかな？・・・
[Swift 5] Protocolを使ったDelegateの実装方法の例

いつも使うときに忘れてしまう、protocolを使ったDelegateの実装方法をメモしておきます。

ParentとChildの関係のように、一方が他方のインスタンスを生成するなどして知っている時に使う方法です。
なので、お互いを知らない遠いViewController同士での指示等には使えません。
（勘違いありましたら、お教えください）

##まずは肝要のDelegateをprotocolで定義します。
```Protocol.swift
protocol MessageDelegate: AnyObject {
    func sendMessage(_ message: String)
}
```
1. `AnyObject`に適合することで、classでしか使えなくなります。
2. メソッドの引数には送りたいものを入れて渡せるようにしましょう。

ここでは仮に`message`という文字列を引き渡すこととします。

##「お〜い、〇〇して〜！」と指示を送りたい側の定義
```ChildViewController.swift
final class ChildViewController {

    weak var messageDelegate: MessageDelegate?

    @IBAction func didTapSendButton(_ sender: UIButton) {
        messageDelegate?.sendMessage("Childからメッセージ送信")
    }
}
```

1. `weak`(弱参照)かつ`Optional`で`Delegate`を宣言します。
2. 送りたいタイミングの場所でDelegateのメソッドを呼び出します。
3. ここでは、「Childからメッセージ送信」という文字列を引数で渡しています。

ここでは、StoryboardとOutlet接続してある`SendButton`が押されたタイミングとしています。

##「分かった！やったるよ！」と指示を受け取る側の定義
```ParentViewController.swift
final class ParentViewController {
    // ParentからChildに遷移するためにViewControllerのインスタンスを生成
    let vc = UIStoryboard(name: "child", bundle: nil)
        .instantiateInitialViewController() as! ChildViewController
    // このタイミングで、ChildViewControllerで宣言してある`MessageDelegate`に自ら(Parent)を代入
    vc.MessageDelegate = self  // 「俺に任せろ！！」の意
    navigationController.pushViewController(vc, animated: true)
}
```
インスタンスを作成する時にDelegateに自らをセット

```ParentViewController.swift
// ParentViewControllerでMessageDelegateに適合します。
extension ParentViewController: MessageDelegate {
    // `sendMessage`メソッドを実装します（Xcodeからも「必須だよ」と教えてくれます）
    func sendMessage(message: String) {
        // 引数のmessageにはChildで入力した「Childからメッセージ送信」という文字列が入ってきます。
        print(message)  // コンソールに「Childからメッセージ送信」と出力される。
    }
}
```
指示を受けたら行いたい処理を書く。
この場合は、Childから受け取ったメッセージを出力しているだけですが、色々任せられますね。

以上、これで次にDelegate実装する時にも迷わない…
YAMAHA RTXルータ Vlan設定 - ポートVlanとタグVlan

RTXルータにポートVlanとタグVlan使ったネットワークの設定手順を記載。設定した後saveを忘れないように。

# ポートVLANの設定

## 前提
・RTXルータのLAN1に設定
・LAN1のIPアドレスに192.168.100.1が設定されている。
・PCとポート1を接続
・ポート1から8までを設定(Vlan1:ポート1~6、Vlan7:ポート7,Vlan8:ポート8)
・ポート7、8には個別にIP設定(7が192.168.103.1,8が192.168.104.1)
・ポート7にはDHCPサーバを用意
・administratorで実行

### ポートVLANモードに切り替え
```
# lan type lan1 port-based-ks8995m=divide-network
```

### VLANとポートの対応付けを指定
```
# vlan port mapping lan1.1 vlan1
# vlan port mapping lan1.2 vlan1
# vlan port mapping lan1.3 vlan1
# vlan port mapping lan1.4 vlan1
# vlan port mapping lan1.5 vlan1
# vlan port mapping lan1.6 vlan1
# vlan port mapping lan1.7 vlan7
# vlan port mapping lan1.8 vlan8
```
### VlanのIPアドレスを指定
```
# ip vlan7 address 192.168.103.1/24
# ip vlan8 address 192.168.104.1/24
```

### DHCPサーバの追加
不要の場合は省いてOK。

```
# dhcp scope 103 192.168.103.2-192.168.103.191/24
```

### DNSへのアクセス許可追加
こちらも不要の場合は。

```
dns host any
```

# タグVlanの設定
## 前提
・LAN3にVlanID101,102のタグVlan設定
・VlanID101が192.168.101.0/24
・VlanID102が192.168.102.0/24

### 設定
```
# switch control use lan3 on terminal=on	
# ip lan3 address 192.168.100.1/24
# vlan lan3/1 802.1q vid=101 name=VLAN101
# ip lan3/1 address 192.168.101.1/24
# vlan lan3/2 802.1q vid=102 name=VLAN102
# ip lan3/2 address 192.168.102.1/24
```

### DHCPサーバの追加
```
dhcp scope 101 192.168.101.2-192.168.101.191/24
dhcp scope 102 192.168.102.2-192.168.102.191/24
```

### ちなみにスイッチ側の設定(Catalyst 2960の場合)
```
Switch(config)# int Fa0/1
switchport mode trunk
Switch(config-if)# switchport trunk allowed vlan 101,102
Switch(config-if)# switchport mode trunk
Switch(config-if)# no shutdown
```
※通常以下コマンドでdod1qを指定するが、2960はdod1qしか使えないので投入できない。
switchport trunk encapsulation dot1q


## あとはVLANのポート割り当て
VlanID101の場合。

```
Switch# conf t
Switch(config)# vlan 101
Switch(config-vlan)# name VLAN名
Switch(config-vlan)# exit
```

### 割り当て

```
Switch(config)# int range 割り当てたいインターフェース
Switch(config-if-range)# switchport mode access
Switch(config-if-range)# switchport access vlan 101
Switch(config-if-range)# no shutdown
Switch(config-if-range)# exit
```

最後にshow vlanなどで確認。
マークダウン習得への第一歩

#タイトル
まずタイトルは文頭に#をつければいいです。
\#の個数を増やすとでタイトルのレベルが下がっていきます。
たとけば次のように記述すると、その次のような出力になります。

```markdown:タイトル
#タイトル１
##タイトル２
###タイトル３
```

#タイトル１
##タイトル２
###タイトル３ 

#リスト
リストは +,-,* のどれかを文頭に付ければいいです。
リストの前に空行をいれることと、+,-,* の後に半角スペースを入れることに注意してください。

```markdown:リスト
* リスト１
* リスト２
* リスト３
```

* リスト１
* リスト２
* リスト３


引用は>らしい
>ここ引用文

リンクはこうね
[グーグルへのリンク](https://google.com)

マークダウンって便利ですね。なにより書きやすい。HTMLを直接書くよりまったく楽にかける。
そりゃ当たり前だけどね。
MinIO on Docker

Amazon S3互換のシステムを使うことになった。
うちでも環境構築して勉強しようと思う。
検索すれば、色々ありますね。
お気に入りのページは
[コマンド1つで作れる！かんたん自宅Amazon S3互換環境！]
(https://qiita.com/kotauchisunsun/items/c870bb65cfa12edcce13)
です。
Dockerイメージは[minio/minio](https://github.com/minio/minio)から入手できます。
でもここでは自分でビルドしてみます。

```Dockerfile:Dockerfile
FROM golang:1.13-rc-alpine

LABEL maintainer="MinIO Inc <dev@min.io>"

ENV GOPATH /go
ENV CGO_ENABLED 0
ENV GO111MODULE on

RUN  \
     apk add --no-cache git && \
     git clone https://github.com/minio/minio && cd minio && \
     go install -v -ldflags "$(go run buildscripts/gen-ldflags.go)" && \
     cd dockerscripts; go build -tags kqueue -ldflags "-s -w" -o /usr/bin/healthcheck healthcheck.go

FROM alpine:3.10.1

ENV MINIO_UPDATE off
ENV MINIO_ACCESS_KEY_FILE=access_key \
    MINIO_SECRET_KEY_FILE=secret_key \
    MINIO_SSE_MASTER_KEY_FILE=sse_master_key

EXPOSE 9000

COPY --from=0 /go/bin/minio /usr/bin/minio
COPY --from=0 /usr/bin/healthcheck /usr/bin/healthcheck
COPY --from=0 /go/minio/dockerscripts/docker-entrypoint.sh /usr/bin/

RUN  \
     apk add --no-cache ca-certificates 'curl>7.61.0' 'su-exec>=0.2' && \
     echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf

ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"]

VOLUME ["/data"]

HEALTHCHECK --interval=1m CMD healthcheck

CMD ["minio"]
```
オリジナルと比較してベースOSのバージョンを上げています。また、docker-entrypoint.shをローカルディスクではなく、前段のステージからのコピーとしました。