OmniAICreator/Qiita-1.07M huggingface dataset:
obnizでRDM-01を動かす

最近スイッチサイエンスで[RDM-01](https://www.switch-science.com/catalog/5381/)という基板の販売が開始されました。

このRDM-01は[音リモコン](https://www.amazon.co.jp/dp/B07KRBKFFJ/)というAlexaスキルと連携して使える基板になっており、この基板を使うことでEchoから出力される音を解析し、Arduino等で認識ができる形に変換、出力することができます。
つまりこのRDM-01を使うことで、サーバーサイドの開発をすることなく、直接ハードウェアに命令を送ることができるようになります。

そんなRDM-01ですが、"obniz"で動かしたらどうなるのか、やってみました！

#準備するもの
- [obniz](https://obniz.io/) 
- [RDM-01](https://www.switch-science.com/catalog/5381/)
- micro usb ケーブル (電源を取るため)

RDM-01は同梱されているピンヘッダを半田付けする必要がありますが、半田付けをしたらobnizに挿すだけなので、とてもシンプルになります。
取り付けるとこんな感じです。
![IMG_4821.JPG](https://qiita-image-store.s3.amazonaws.com/0/324560/25d9ad76-ef76-2046-1556-da998ccc8b2b.jpeg)

#obnizのソースコード
画像のようにRDM-01を0~6ピンに挿入して使用した時のコードを示します。
コードはscriptの中だけになります。

```obniz_RDM-01_sample.js
 
 
let Decode = ["D","1", "2", "3", "4","5", "6", "7", "8","9", "0", "*", "#","A", "B", "C"]

var flg = false;
var obniz = new Obniz("OBNIZ_ID_HERE");
obniz.onconnect = async function () {
    
//電源の設定
  var usb = obniz.wired("USB" , {gnd:5, vcc:6} );
  usb.on();
  
  //ディスプレイ
  obniz.display.clear();
  obniz.display.print("RDM-01起動！");
 
  //メインループ
  obniz.repeat(async function(){
    if(await obniz.io0.inputWait() == true && flg == false){//StDの反応を確認し、反応しているかどうか確認する。
      flg = true
      q1 = await obniz.io4.inputWait();
      q2 = await obniz.io3.inputWait();
      q3 = await obniz.io2.inputWait();
      q4 = await obniz.io1.inputWait();
      
      var result = (q4 << 3) +  (q3 << 2) +  (q2 << 1) + q1

      obniz.display.clear();
      obniz.display.print(Decode[result]);
      console.log(Decode[result])//PCの画面上にもログとして表示する
      await obniz.wait(10);
    }else if(await obniz.io0.inputWait() == false && flg == true){
     flg = false 
    }
  }) 
}

```

obnizは割り込み機能がないので、メインループを作り、そこでずっとチェックをしています。
またStD(音を拾えたことを知らせるピン)が立ち上がったら、最初の一回だけ反応するようにしました。こうすることで、なんども同じ値が取れることがないようにしています。


#最後に
RDM-01をobnizで使ってみましたが、とても簡単にRDM-01が使える環境だなと感じました。
ただ、電源のとりかたを誤ると、ほとんど信号が取得できないのもわかりました。
今回のコードはそれを調べた上で一番ベストなやり方になっています。

これを参考にRDM-01を使っていただければと思います。
最初からやり直すために、Docker イメージ / コンテナ / ボリュームを全削除する

#ターゲット

Docker環境を一からスタートさせたい人向け
動いているコンテナがあると、イメージを削除することができないため、はじめにコンテナから削除する。


#docker コンテナ　全削除(強制)

```
docker rm -f `docker ps -a -q`
```

#docker イメージ　全削除

```
docker images -aq | xargs docker rmi
```

#docker ボリューム　全削除

```
docker volume rm $(docker volume ls -qf dangling=true)
```
netlifyでホームページを公開する

HTML、JavaScript、CSSだけの簡単なページを公開したかったので[netlify](https://www.netlify.com/)使って見ました。
5分くらいで簡単に公開できるし、HTMLフォームからPOSTされたらnetlify側で取得して、APIから呼び出せて、100送信まで無料枠みたいなので小さいホームページには十分です。

1. [get started for free]をクリック
![スクリーンショット 2019-02-10 13.18.25.png](https://qiita-image-store.s3.amazonaws.com/0/162167/69757a3b-5e36-ea9e-3bf0-40da6112ca2f.png)

2. 連携するアカウントを聞かれるのでGitHubを選びました
![スクリーンショット 2019-02-10 13.43.48.png](https://qiita-image-store.s3.amazonaws.com/0/162167/a70fa5d9-d934-2c7a-23d7-49a7c09055a1.png)

3. [New site from Git] クリック
![スクリーンショット 2019-02-10 13.44.59.png](https://qiita-image-store.s3.amazonaws.com/0/162167/e6a5c290-a3ef-bd78-fca2-747f39d13b2d.png)


4. 公開したいレポジトリーを選びます。
![スクリーンショット 2019-02-10 13.22.14.png](https://qiita-image-store.s3.amazonaws.com/0/162167/8800fbb1-e714-32c3-7440-a9e671927114.png)

5. ブランチはmasterのまま、ビルドコマンドは必要ないので空白、ディレクトリーも直下に置いているので空白のまま[Deploy site]クリックします。
![スクリーンショット 2019-02-10 13.22.40.png](https://qiita-image-store.s3.amazonaws.com/0/162167/6c6c0303-d2f3-debf-e620-236b39130c54.png)

6. 選択しているレポジトリはこんな構成です
![スクリーンショット 2019-02-10 13.49.28.png](https://qiita-image-store.s3.amazonaws.com/0/162167/5a9be83c-032c-0627-1f6d-b8c06a456dbd.png)


7. これで公開完了！
TortoiseGitからBacklogにpushできないときのトラブルシューティング

# はじめに
TortoiseGitから、Blacklog上に作ったリモートリポジトリにPushしようとしたが、「gitは正常に終了しませんでした (終了コード 128) 」のエラーが出て、Pushができたかったので、その時のトラブルシューティング。

# 解決方法　その１
リモートリポジトリに始めてpushする時、ユーザー名とパスワードを聞いてくるのだが、この時のユーザー名が、TortoiseGitに作ったアカウントのユーザー名ではなく、どうもメールアドレスのようだった。
なので、コンパネの資格情報マネージャー－資格情報から、登録されているTortoiseGitのアカウントを削除する。

# 解決方法　その２
TortoiseGitの設定－ネットワークから、sshクライアントをデフォルト値の
「C:\Program Files\TortoiseGit\bin\TortoiseGitPlink.exe」から
「C:\Program Files\Git\bin\sh.exe」に変更する。
※ググると、msysgitのssh.exeでもOKとの情報有
![image.png](https://qiita-image-store.s3.amazonaws.com/0/94029/c3e9cb02-821e-5ef4-1627-2b6e61515aa8.png)
上記２点を変更する事で、pushに成功しました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/94029/b5a71b1e-623c-ac66-8d0b-98241362913f.png)
経験者と未経験者のプログラミング学習方法の違い

#はじめに
現在、SI企業に入社して約4年が経過しようとしています。
後輩社員も増えて、テストや設計などのプログラミングがない工程からPJに参加した彼ら（彼女ら）とプログラミングの学習方法について話していてギャップを感じたので、それについて書いていこうと思います。

ここで言う経験者・未経験者っていうのは業務経験ではなく、プログラミングそのものについての習熟度と考えて頂いたほうがわかりやすいかもしれません。

※まるで私の考えている学習方法が＝経験者の方法という書き方になっています。
　なにか誤りがありましたらご指摘お願いします。

#未経験者の考えるプログラミング学習方法
本などを見ながら学習したい
あるいはなにか資格などを取る、研修やスクールに参加しながら学習を進めたいというものです。

共通しているのは学習のカリキュラムを自分以外の誰かに決めてもらいたいということですね。

#私の考えるプログラミング学習法
なにかプロダクトを自分で作るというものです。
何かを参考に作るのはいいと思いますが、基本的に学習の道筋を自分で考えていくことになります。
私は基本的に新しいものを設計するのが面倒（）なので新しい言語を学習するときも同じような物を作ります。
例えば掲示板とかログイン機能があってDBに登録、削除、更新する処理があれば十分かなと思っています。
更にいうと実用性があるとモチベーションが続きます。
プログラムって結局それ自体は手段なので・・・
VBAを覚えたいと思ったときは手元のファイルを整理するものを作りました。

最近、WEBエンジニアの人が転職するときにポートフォリオを作ってGithubに公開するべきなんて話を聞きますね。
私は今の会社に入社する前からこういったプロダクトを作るという考えはありました。
（当時はPHPを触っていたのでPHPで作りました）
恥ずかしい話ですがポートフォリオを作るとかGithubで公開するというのを知りませんでした。
ポートフォリオって当時聞いてもデザイナーさんとかが持ってるイメージでエンジニアの人もそういうのを作っているのは知りませんでした。

#私が感じる未経験者の考える学習方法の問題点
##設計力が身につかない問題
毎回同じようなものを作っていたらそこまで設計力は身につかないかもしれません。
でも1つでも自分で１から考えて作り上げたという経験は力になると思いますし、2つ3つと新しいものを作っていくのに必要な能力は設計やプログラミング力ではなくアイディア力だと思います。
なので色々なパターンを作り上げる経験というのは業務の中で身につけていけばいいです。

ただカリキュラムに沿った学習だとテキストに書いてあるデータ入力をしておしまいになってしまう場合が多いように感じます。
テキスト通りに作っていれば臨界値テストや異常系テストにも対応できる作りにはなっていると思います。
ただその各コードの意味をしっかり理解して学習を終えている人がどれくらいいるのでしょうか？
自分で作ったシステムだとじゃあ変な文字入れてみようとかいろいろ思いついてバージョンアップされていくと思います。
作った物自体はテキストなどの中の課題になっているものより良くないものになるかもしれませんが高い経験値が得られると思っています。

#プログラミング以外の知識が身につかない問題
プログラミングの学習なんだからそれ以外身につかないでいいだろうってツッコミが来そうですねｗ
ただ遅かれ早かれ開発環境、サーバ、データベース、バージョン管理など必要になってくる知識だと思います。
なのでそこらへんについても一通り学んで置くのがいいと思います。
例えばProgateなどプラウザ上で動く環境で学習してしまうとそこら編の知識が一切身につきません。
クラスとは？型ってなに？ifってなに？とかそのレベルの人はいいですがいま基本的なプログラミンはできる
そこからレベルアップをしたいという人はテキストに沿った学習では成長は見込めないのではないかと思います。

#最後に
上記の話をしたときに後輩さんから言われたのは
何を作ればいいかわからない
です。
仮想サーバの構築がわからないとかならこのサイトを見てやってみてとなるんですがね。
私は作るものは本当に何でもいいと思っています。
MVC的な感じで画面、サーバー処理、DBがあればその難易度、作り込み具合はさほど大きな問題でないと考えています。

何を作ればいいかわからない
この気持がわからないといえば嘘になります。

自分で作ったものに自信なんてないし、恥ずかしさのほうが強いのでGithubなどを知った今でもコードを公開したりはしていません。
ただエンジニアと言う職業はこういう問題点を見つけて修正していくという作業がとにかく多くて大切な仕事だと思っています。
なので何を作るということは大した問題ではないのですが、それを作って試行錯誤していくという経験はとても大切なのではないかと思います。
CloudFormation の注意点Tips

最近CloudFormationを触り始めました、AWSのリソースをテンプレートから作成できるのは便利なのですが、その反面注意する必要がある点もあったので、備忘録も兼ねて紹介したいと思います。

# 対象読者

* CloudFormation初心者

# 前提
本記事では以下の構成のCodePiplineでリソースを作成することを前提として話していきます。
私がその構成でしかCloudFormationを扱ったことがないので、
他の構成やでは当てはまらない点もあるかもしれませんが、その点についてはご了承お願い致します。

###  CodePipeline

* 1. Source ステージ
    * CodeCommit上のリポジトリのmasterブランチ
* 2. Build ステージ
    * 必要なyamlファイルを生成し、`artifacts`で指定して後続のステージで参照できるようにしています
* 3. MakeChangeset ステージ
    * CloudFormationのアクション「変更セットの作成または置換」で各stackのchangesetを作成します
* 4. Deploy ステージ
    * CloudFormationのアクション「変更セットの実行」で各stackの作成または更新を行います

# stackで作成されたリソースはコンソール上から変更、削除しない
コンソール上からStackでリソースの設定を変更すると。CodePipelineを実行した時に、テンプレート通りのパラメータに設定されず、コンソール上で設定したパラメータが残ってしまう場合があります。

私は特にLambdaに対してやっていましたが、
APIGatewayをトリガー設定を間違ったパラメータで変更してしまい、CodePipelineを再実行しても設定が戻らず、
必ずエラーになるAPIを作成してしまったことがあります。

設定を元の状態に戻せるのであれば問題ないかもしれませんが、基本的にstackで作成されたリソースをコンソール上から変更するのはやめましょう。

# stackで作成されたリソースはコンソール上から削除しない
コンソール上からリソースを削除するとChangeset作成の段階で失敗します。
Changeset作成時はどうやら変更前のリソースは存在するものという前提で動いているようです。

もし削除してしまった場合、一番確実な対象法は**stackを削除して再度作り直す**ことです。

私も次のCodePipelineの実行でLambdaが再作成されるだろうと思い、下手にパラメータを変更したLambdaを削除してしまいました。。
泣く泣くstackを削除して再度作り直しましたが、まだlambdaだけのstackで良かったです。
（実際どうなるのかはわかりませんが、これがDynamoDBだったりRDSだったらと思うとゾッとします）


# DynamoDBの1テーブルに対して複数のGSI変更はできない
これはDynamoDBの仕様でもあるのですが、一つのテーブルに対してGSIの変更は一つずつしか変更できません。

* 新規テーブルを作成する場合
    * 複数のGSIの作成は可能です。
* 既存テーブルに対して複数のGSIの作成または変更した場合
    * エラーとなり更新に失敗します。

もし既存テーブルに対して複数のGSIの変更を行いたい場合は面倒ですが、一つのGSIを変更するたびにデプロイする必要があります。


# VPC内のLambdaを含むstackを削除する場合、VPC内のLambda削除に40分の遅延が発生する
これはよくStackOverflowでもissueが上がってたりしますが、VPC内のlambdaを含むstack削除するとそのLambdaの削除に40分程時間がかかります。
これはLambdaに紐付いているENIが削除されるまで待機しているのが原因のようです。

対応としては(~~本来やって大丈夫かはともかく~~)コンソール上でENIのリストからLambdaに紐付いているENIを削除することで、遅延を減らすことができます。
Serverless Frameworkではstack削除時に並行してENIを削除するためのプラグインも公開されています。

# まとめ

CloudFormationは便利な半面扱いづらい箇所も多く、使えば使うほど、悩まされる部分も増えている気がします。
今後も何かしら気づいた点があれば、記事を更新して（~~ついでにもっと読みやすくして~~）いきたいと思います
[Raspberry Pi]apt-get updateがうまくいかないとき

# 概要

以下のようなエラーで、apt-get updateがうまくいかなかった。なので、いろいろ調べて直した。

```
pi@raspberrypi:~ $ sudo apt-get update
ヒット:1 http://archive.raspberrypi.org/debian stretch InRelease
無視:2 http://raspbian.raspberrypi.org/raspbian stretch InRelease
エラー:3 http://raspbian.raspberrypi.org/raspbian stretch Release
  404  Not Found [IP: 2001:41c9:1:3ce::1:11 80]
パッケージリストを読み込んでいます... 完了
E: リポジトリ http://raspbian.raspberrypi.org/raspbian stretch Release には Release ファイルがなくなっています。
N: このようなリポジトリから更新を安全に行うことができないので、デフォルトでは更 新が無効になっています。
N: リポジトリの作成とユーザ設定の詳細は、apt-secure(8) man ページを参照してくだ さい。

```

## 参考

- http://livedoor.blogcms.jp/blog/sce_info3-craft/article/edit?id=9988995
- https://retax.work/2018/06/16/post-265/
- http://www.raspbian.org/RaspbianMirrors


## やったこと

上記のサイトなどを参考にして、

```
apt-get clean
sudo rm -rf /var/lib/apt/lists/*
```

を実行。さらに、ミラーサーバーのURLに置き換える。

```
sudo nano /etc/apt/sources.list
```

最後に、apt-get updateを実行したところ正しく実行できた。
Railsでシンプルカレンダーを使う

#ゴール：めっちゃシンプルカレンダーを作るぞー

![Calender.png](https://qiita-image-store.s3.amazonaws.com/0/200663/1f0764f1-f243-4235-078c-468999a2f282.png)


この記事を参考にしました。
https://qiita.com/mikaku/items/0971442a7308dc669122

だいたい、これを読めばいけます。
最終アウトプットがこんな感じになったので、メモ的なものです。

この記事で書かれていないポイントとして、

```
bundle install
```
などをしたら、

```
rake db:migrate
```
で、マイグレーションも必要ということです。

でないと、エラーなっちゃうので。

日付を押したら、詳細に飛ぶみたいなことがしたいなぁと思っている。
picoCTF 2018 Aca-Shell-A - Points: 150

#問題

https://2018game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/82503e8b-648c-d731-3006-1967a03a206d.png)


#解いてみた

接続してみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/fc6e724a-d421-4b09-00e1-39ef9240b3e0.png)

何をすればいいのかよくわからないので、flagが書かれたファイルがないか調べてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/2907bf4e-2737-5c95-3f3e-e9504ca1a891.png)

なんでかよくわかりませんが、別のフォルダに対してlsができないのでわざわざcdしないといけない仕様です。。。
intelを消すように言われたのrmで消します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/1cfbf228-39f5-4447-99a9-efe33e13b089.png)

ファイルを消して「echo 'Drop it in!'」と書くと何か発動するようです。
executablesフォルダに一気に行こうとしても失敗するので一つずつ移動します。。。
中のファイルを実行すると変な文字がたくさん出てきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/6ff70595-77b1-bf72-9cb4-cc0d7bdcfded.png)

ユーザ名を表示するように言われたので、whoamiをしてユーザ名を表示します。
passwordsフォルダにファイルをコピー"しろ"なのか"したよ"なのかよくわからなかったので、移動してみます。
ファイルがなかったのでコピーコマンドやってみるもののファイルがない？
いろいろやっているうちに時間切れで接続できなくなりました。


再度、最初から挑戦です。。。
これまでのところは省略します。。。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/1da437a4-76ca-3c44-3449-52b9cef88f34.png)

どうやら、インプットに対してコマンドを理解しているわけではなくて、固定文字列と比較して、一致するかどうかで判断しているんでしょうか。
さっきのコピーコマンドも一緒の意味だと思うのですが。。。

まぁ一応flag出ました。
toastrにオプションがつけれない

# フラッシュメッセージをtoarstrで見栄え良くしたい

下記の記事を参考にtoarstrを導入してみた。

http://blog.yuhiisk.com/archive/2018/05/04/rails-flash-message-with-toastr.html

# オプションがつけれない

フラッシュメッセージをもっとカスタマイズしたいと思い、
下記のデモを参考にオプションコードを記述してみたが、
フラッシュメッセージに反映されなかった。

https://codeseven.github.io/toastr/demo.html

# gemが違う

toastrのgemが2種類あり(もっとあるのかも)、試しに別のgemを入れてみた。

初めは 
`gem 'toastr-rails'`を導入していたが、
`gem 'toastr_rails'`を導入してみた！

# 結果
別のgemを導入したら同じコードでもtoastrのオプションがついた。

**toastrを導入するなら`gem 'toastr_rails'`を使った方が良いのかもしれない。**
SQL INDEXつきテーブルを結合する際の駆動表は小さく！

結合順序により速度が変わる話。
INDEXをつけているカラムの値がちゃんとばらついていれば、レコード数が少ないテーブルを駆動表に選ぶことでスキャンレコード数を減らせます。
# 前置き
テーブルを結合するアルゴリズムの一つに、`Nested Loop`があります。
テーブルのレコードごとに、もう一方のテーブルのレコードを一つずつ見に行く2重ループのアルゴリズムです。
![NestedLoop.jpg](https://qiita-image-store.s3.amazonaws.com/0/320952/e956f3fd-6fe4-f801-cf45-326d75966cbb.jpeg)
左の最初にスキャンするテーブルAは**駆動表**、右のテーブルBは**内部表**と呼ばれます。テーブルAとテーブルBのレコード数をそれぞれ`R(A)`、`R(B)`とすると、スキャンするレコードの数は単純に計算して`R(A) × R(B)`。上図の場合は12になります。結合順序を変えても同じ。
しかしINDEXが張られてるとスキャンレコード数は減ります。
# INDEXとスキャンレコード数の関係
内部表の結合キーのカラムにINDEXが張られていると、内部表でスキャンするレコード数が減ります。駆動表のレコード1件に対し、INDEXをたどって内部表のスキャンレコードを絞れるからです。主キーを結合キーに指定した場合は、内部表のスキャンレコード1件になります。
![kudo1.jpeg](https://qiita-image-store.s3.amazonaws.com/0/320952/abbc0435-43cd-aa14-091d-2c01f465a3b5.jpeg)

上図ではテーブルAの3番目のレコードの結合キーに対応するテーブルBのレコードがなかったため、全体のスキャンレコード数は7になっています。
もし`R(B) < R(A)`であれば、テーブルBを駆動表に選ぶことでスキャン数を`R(B) × 2`に減らせます。
![kudo2.jpg](https://qiita-image-store.s3.amazonaws.com/0/320952/4bb954de-fdab-a2a7-7c4e-c9f531d77cc1.jpeg)

上図では先ほどの結合対象がないレコードのスキャンが減っているので、全体のスキャンレコード数は6に減っています。
仮に駆動表が大きくなるような順番でクエリを書いていても、オプティマイザがいい感じに順番を入れ替えてくれます。
## ユースケース
パッとは思いつかなかった。。
完全に想像ですが、転職サービスなどで以下の感じでデータ管理してる場合、いいユースケースになりそうです。

- `USER`テーブル
    - 会員情報を入れる。主キーは`USER_ID`。
- `CAREER_SHEET`テーブル
    - 会員ごとの経歴シート情報を入れる。経歴シート作成時にユーザーごとのレコードが作られるので、常に`USER`よりもレコード数は少ない（会員登録だけして経歴シート未記入の人もいるため）。

これらのテーブルを`USER_ID`をキーにして結合する場合は、レコード数の`CAREER_SHEET`を駆動表に選択するのが正解ですね。
# 注意
INDEXが張られているカラムの値が十分にばらついてない場合は、駆動表が小さくても結局内部表のループがたくさん残ってしまうので、期待した効果は出ないです。
# 参考資料
[SQL実践入門──高速でわかりやすいクエリの書き方](https://www.amazon.co.jp/SQL%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80%E2%94%80%E2%94%80%E9%AB%98%E9%80%9F%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8A%E3%82%84%E3%81%99%E3%81%84%E3%82%AF%E3%82%A8%E3%83%AA%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9-WEB-DB-PRESS-plus/dp/4774173010)
jQueryとchrome拡張機能でお手軽な画像スクレイピング

## 要件
現在表示しているページの画像をまとめて保存したい。
liタグや兄弟要素で特にかなり楽にスクレイピングできる。

## サンプル（ヤ●オクの商品ページ）
```js
$('.ProductImage__link img').each(function(i, element){window.open(element.currentSrc)});
```
上記のコードをコンソールで実行後、拡張機能で一括保存

## 材料
- jQueryさん
- [chromeの拡張機能（Save Tabbed Images）](https://chrome.google.com/webstore/detail/save-tabbed-images/hhcoikfhkkadkgklepjkfgafmjoggefh?hl=ja)

## 手順
1. 保存したい画像のセレクタを確認<br>
→ 上記の例だとimgタグにクラスがないので、親のaタグを利用して<br>
　$('.ProductImage__link img')として要素を取得できます。
2. each()でwindow.open('画像のURL')を実行
3. Save Tabbed Imagesで保存

## 実行イメージ
![jQuery.gif](https://qiita-image-store.s3.amazonaws.com/0/162197/29c5c737-f4e3-08bb-3b2f-af6643963321.gif)

## 感想
jQuery、まだまだ現役👴
jQuery読み込んでなかったら使えないけどそこはご愛嬌
~~window.open()は使えない時もあるよ~~
npm run watch で webpackのエラーが出た時の対処方法

# 実行したコマンド
npm run watch

# エラー内容
Error: custom keyword definition is invalid: data/errors should be boolean

# 原因
ajv@6.9.0を使用するとwebpackが正しく動作しない不具合がありました。

# 対応
ajvのバージョンをダウングレードする。
6.8.1にするとエラーが無くなりました。

```
npm uninstall ajv
npm install ajv@6.8.1
```

# 参考
https://github.com/webpack/webpack/issues/8768
wscatでファイルの中身の文字列をサーバに送り付けるには

`-x, --execute <command>`の引数に`cat`などで出力すればよい。

```shell
$ wscat ws://localhost --execute $(cat ./file)
```

また、`-w, --wait <seconds>` で文字列を送り付けてから切断するまでの待ち時間を調整できる。

バージョン2.2.1で動作確認。
pandas 困ったことまとめ

よく調べるので自分用にメモします
# DataFrameで特定列の値がリストに含まれる行だけを抽出
```python
import pandas as pd
df = pd.DataFrame({'N1': [1, 2, 3, 4, 5, 6],
                   'N2': [10, 20, 30, 40, 50, 60],
                   'N3': [6, 5, 4, 3, 2, 1]},
                  columns=['N1', 'N2', 'N3'])
df
#   N1  N2  N3
# 0   1  10   6
# 1   2  20   5
# 2   3  30   4
# 3   4  40   3
# 4   5  50   2
# 5   6  60   1
```
``pandas.DataFrame.isin(list)``を使用してN1列の値のうちmaskに含まれる行だけを抽出

```python
mask = [1, 3, 5]
df[df['N1'].isin(mask)]
#    N1  N2  N3
# 0   1  10   6
# 2   3  30   4
# 4   5  50   2
```
# DataFrameで条件に合う行に新しい列を追加する(条件に合わないところはNaN)
``df.loc[条件, 新しい列の名前]=value``という風に代入していく

```python
df.loc[df['N1']==1, 'N4']=1000
df
#    N1  N2  N3      N4
# 0   1  10   6  1000.0
# 1   2  20   5     NaN
# 2   3  30   4     NaN
# 3   4  40   3     NaN
# 4   5  50   2     NaN
# 5   6  60   1     NaN
```
30日でできる!OS自作入門をMac(High Sierra)でやってみた

**この記事は他の方々のブログなどを元にMacの環境構築をしております。その際にハマった事などを書いていく記事です。**

#30日でできる!OS自作入門とは
・30日で0からメモリ管理もタスク管理の機能も備えている立派な(はりぼてではあるが)OSを作る事ができる素晴らしい本である！
・基本的にwindowsで作るようになっているが、素晴らしい方がMacでも開発できるようにライブラリを作ってくださった方がいたためMacで挑戦してみる

#開発環境
MacBook Air
OS : macOS High Sierra　バージョン10.13.6
プロセッサ : 1.6GHz Intel Core i5
メモリ : 8GB
グラフシックス : Intel HD Graphics 6000 1536MB

#環境構築
(初めのDay2まではqemuでなんとかやっていたのだがDay3あたりでうまく行かなくなった。)

・そのためMacで環境構築ができるライブラリを作って下さった方の力をお借りして環境構築を行なった。
(https://github.com/sandai/30nichideosjisaku)
・README.mdに書いてある通りにやって見たのだが環境構築でいくつかハマった。
- Q.appのダウンロードページのリンクが切れてい多様で使えなかった。検索して見るとQ.appの他のリンクが見つかったためこちらを使用した。
(https://q-emulator.jp.uptodown.com/mac/download)
- シェルスクリプト実行のところで、curl <install.shのurl> | shと書いてあるが上手く実行できなかったため、一度wgetでダウンロードしてからchmodで実行権限を付与してから実行させたら上手く動いた。

#Day14の高解像度に使用の部分で高解像度にできなかった
・Sierraで似た事例になっている方がいたのでこの方の記事を参考にしてやって見たがHighSierraのためか上手く行かなかった
(https://qiita.com/tatsumack/items/491e47c1a7f0d48fc762)
そのため、高解像度にするのは諦めてDay14のharib11c/asmhead.nasをコピーして低解像度のモードで使用することにした。
【AWS】 LambdaでNode.jsネイティブモジュールを利用する

# はじめに
Node.jsランタイムのLambda上で、`firebase-admin`モジュールを利用してfirestoreを操作しようとしたときエラーが起きました。
エラーが起きた原因は`firebase-admin`で利用している`grpc`がネイティブモジュールであることが原因で解決できたのでメモ程度にまとめました。

# Lambdaとは
AWSのFunction as a Serviceです。
Httpリクエストやスケジューリングでイベントを発火して、事前に用意しておいたコードを実行させることができます。
Nodejs、Python、Ruby、Java、Go、.NETで書かれたコードを実行させることができます。

### Lambdaの環境
・オペレーティングシステム – **Amazon Linux**
・AMI – amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2
・Linux カーネル – 4.14.77-70.59.amzn1.x86_64
・AWS SDK for JavaScript – 2.290.0
・SDK for Python (Boto3) – 3-1.7.74 botocore-1.10.74

# Node.jsのネイティブモジュールとは
**Node.jsで利用できるモジュールの中にC/C++で書かれているものがあります**。
そのようなモジュールはクロスプラットフォームのコマンドラインツールでビルドしてから利用できるようになっています。
そのようなモジュールはネイティブモジュールと呼ばれ、ビルドされたモジュールは違うOSでは動かないことが多々あります。

つまり、**MacやWindowsPCのローカル環境でネイティブモジュールをインストールして、そのモジュールを利用したコードを書きLambdaで実行させようとするとOSの違いでうまく動かないことがある**ということです。

# Lambdaでネイティブモジュールを利用する方法

Lambdaでネイティブモジュールを利用したい場合、Amazon LinuxというOSで動くモジュールを準備する必要があります。
Amazon Linuxの環境を構築して、その環境内でモジュールをインストールすればいいので、Dockerの出番です。

Dockerが使えない場合、Dockerを使えるようにしておいてください。

### Amazon LinuxのContainer起動

AmazonはAmazon Linuxのイメージを公開しているので、プルしましょう。

```bash
docker pull amazonlinux:latest
```

PCのボリュームをマウントして、Amazon Linuxイメージでコンテナーを対話モードで起動します。

※下記のコマンドではtempというフォルダをマウントしています。

```bash
docker run -it -v $PWD/temp:/temp --name native-module-sample amazonlinux:latest
```

### Node.jsを利用できるようにする

rpmを利用できるようにする。

```bash
curl -sL https://rpm.nodesource.com/setup_8.x | bash -
```

yumでネイティブモジュール利用に必要なものをインストールする。

```bash
yum install gcc-c++ make
```

yumでパッケージマネジャーのyarnをインストールする。

```bash
curl -sL https://dl.yarnpkg.com/rpm/yarn.repo | tee /etc/yum.repos.d/yarn.repo
yum install yarn
```

yumでNode.jsをインストールする。

```bash
yum install -y nodejs gcc-c++ make
```

これで、8系のNode.jsとnpmが利用できるはずです。

### ネイティブモジュールをインストールしてみる

ローカルPCのtempフォルダをマウントしているので、マウント先でネイティブをインストールします。

※下記のコマンドでは`firebase-admin`をインストールしています。firebase-admin内で利用しているgrpcがネイティブモジュールです。

```bash
cd temp
npm init -y
npm install firebase-admin
```
インストールが終了したら、ローカルPCのマウントしているフォルダを確認しましょう。
`node_modules`ができているはずです。

nodejs/node_modules/*の構成でzip化してLambda Layerとしてアップロードしましょう。

後は、Layerを登録したLambdaにモジュールを利用したコードをアップロードすれば実行できるはずです。

# さいごに
ローカル環境ではうまく動くのにLambda上では動かない原因として、ネイティブモジュールが関わっている場合もあります。エラーで行き詰まっていたら一度ネイティブモジュールの存在も疑ってみてもいいかもしれません。

# 参考
[DockerでAWS Lambda用のNode.jsネイティブモジュールをビルドする](https://engineering.mobalab.net/2018/06/06/build-node-native-module-using-docker-for-lambda/)
laradockでphp artisan migrateが動作しない時の対処法

https://teratail.com/questions/112354
こちらの記事を参照。

Sites/laradock
Sites/myproject

上記のディレクトリ構造で、myproject内で
php artisan migrate
を入力してもエラー
 Illuminate\Database\QueryException  : SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known
が出力してしまったが、
cd ../laradock
でlaradock内で
docker-compose exec workspace bash
を行い、この中で
php artisan migrate
コマンドを入力すると無事にコマンドが動作した！
うれしー
NAT ゲートウェイを設定してみる - EC2

#NATゲートウェイを構築してみる#

【構成】
InternetGatway
　|
EC2（WEBサーバ）← 直接インターネットにに出れるようにする。
　|
EC2（DBサーバ）← WEBサーバを踏み台として、インターネットに出れるようにする。

---

【パブリック IP】
WEBサーバには、パブリック IP を割り当てる設定。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/a24c537f-3643-b834-2b7f-df5a968b437f.png)

DBサーバには、パブリック IP は割り当てない。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/4a1f3f93-045c-753e-c7ba-443fd1b7ba25.png)

---

【セキュリティグループ】
WEBサーバは、インターネットからSSHとHTTPのみを許可するように設定する。
※ここでは、SSH　0.0.0.0/0 になっているがよくないです、実際に許可るるアドレスのみを登録する！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/6d8934f2-349c-2cfa-5e04-fcb942597c52.png)

DBサーバは、WEBサーバからSSHとMYSQLのみを許可するように設定する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/41dd504c-21db-f160-519e-2832693470dc.png)

---

【SSH】

```
scp -i ~/Downloads/web.pem ~/Downloads/web.pem ec2-user@アドレス:/home/ec2-user/

ssh -i ~/Downloads/test-key.pem ec2-user@WEBサーバに割当てたパブリック IP

ssh -i ~/test-key.pem ec2-user@DBサーバに割当てたプライベート IP
```

でログインする。

しかし、この段階ではDBサーバはインターネットに出れないので、yum などは使えない。そこで次。

---

【NAT ゲートウェイ】
WEBサーバ側のサブネットにNATゲートウェイを作成する。
![スクリーンショット 2019-02-09 20.00.37.png](https://qiita-image-store.s3.amazonaws.com/0/280929/900e896f-250f-a0ca-c88f-c5290d53f83e.png)

DBサーバ側にルーティングテーブルに、0.0.0.0/0はNATゲートウェイに向けるようにする。
![スクリーンショット 2019-02-09 19.59.02.png](https://qiita-image-store.s3.amazonaws.com/0/280929/23c5a55f-9b08-8bc7-8566-17ed4e77e963.png)

すると、DBサーバからもyum などが利用できるようになる。


**注意**

- 高可用性にするには、AZごとに配置が必要。
- インターネット側からNATゲートウェイにアクセスできない。

NATゲートウェイはサブネットからインターネットに出て行くサービスなので、NATゲートウェイにログインしたり、逆にインターネット側からNATゲートウェイに乗り込むことはできません。
踏み台サーバを配置もしくは[AWS Systems Manager](https://aws.amazon.com/jp/systems-manager/)を利用する必要がある。


#試験の出題で覚えておくこと#

- NATゲートウェイはパブリックサブネットに配置する。
- プライベートサブネットにセキュリティグループを設定する。

#帯域幅#
　NATインスタンス：選択したインスタンスタイプに依存
　NATゲートウェイ：5 Gbps の帯域幅をサポートし、45 Gbps まで自動的に拡張します。
MacのFinderでプレビューが突然表示されなくなった

突然プレビューが表示されなくなり困ったのでメモ🗒
MacのFinder（ファインダー）でプレビューが突然表示されなくなった場合の解決方法。
jpgやsvgの内容が見れないので作業効率が下がってしまいます💦

![f4c8837f0f0d6c5540235b35fc22764d.png](https://qiita-image-store.s3.amazonaws.com/0/29272/5712f0fa-5177-8ae0-023e-489ea9fa8b84.png)

メニューで以下を設定、またはショートカットでプレビューが表示されます👌

#解決方法

- ⚙️ 表示＞プレビューを表示
- ⌨️ ショートカット＞ `Ctrl` + `Cmd` + `P`

![751d850c54ebb3c28f41be9baa0fc0e1.png](https://qiita-image-store.s3.amazonaws.com/0/29272/764340fb-ee89-fbaf-97df-cdfae2838141.png)


これで解決できます。
MacのFinderはカスタマイズすると作業効率が上がるんで設定しておきたいものです。
合わせて読みたいにおすすめ記事を貼っておきますので、ご参考にどうぞ🙌

#合わせて読みたい
Mac の Finder について理解する - Apple サポート
https://support.apple.com/ja-jp/HT201732
apple公式のサポート記事です。Finderの基本を学べます👍

MacのFinderを使いやすくする個人的お気に入り設定6つ
https://ushigyu.net/2015/05/18/mac-finder-configuration/
おすすめの設定についてのまとめ記事です。参考になります🔍
Django Webアプリ作成(1) Djangoとは

環境
OS : macOS Mojave
Anaconda : python3.6.7
Django==2.1.5

#Djangoとは
PythonをベースにしたWebフレームワーク
WebフレームワークとはWebアプリケーションを簡単に作れる仕組みのこと。
Pythonフレームワークでは他に、FlaskやBottleなどがある。

#Djangoのフレームワーク構造
Djangoを構成する要素はいろいろあるが、その中でも「モデル」(M)、「テンプレート」(T)、「ビュー」(V)の3つが最重要であり、これらをまとめて「MTVフレームワーク」と呼ばれる。
「モデル」はアプリケーション内部で扱うデータとビジネスロジックを担当する。
「テンプレート」と「ビュー」はともにUIへの出力を担当するが、
「テンプレート」はデータの見せ方を、「ビュー」はデータの選び方を担当する。

#事前準備
Django用の仮想環境の作成

```
conda create -n django
```
上のコードの"django"の部分は仮想環境名なので自分の好きな名前で良い。

作成した仮想環境に入る

```
source activate django
```
ターミナルの先頭に(django)と出ていればOK。

Djangoパッケージのインストール

```
conda install django
```

インストールされているか確認(仮想環境上のパッケージを表示)

```
conda list
```

以上で、Djangoを始める準備は完了。
次回から少しずつWebアプリの作成を進めていこうと思う。

**参考**
[Condaコマンドについて](https://qiita.com/yuta_rug/items/3df4629910a75ff343b6)
便利SQL

小ネタですが、知ってると便利なやつ。 (動作確認は全てmysql5.7で行なっています)

### 入れようとしているレコードのキーが既に存在していれば更新、なければ新規追加する
- **INSERT ON DUPLICATE KEY UPDATE**
  - 指定したキーのレコードが存在しなければINSERT, 存在する場合はUPDATEしてくれる優れもの。
  - https://www.s-arcana.co.jp/tech/2011/11/insert-on-duplicate-key-update.html

### CSVとかで大量のデータを一度に早くつっこみたい
- **LOAD DATA LOCAL INFILE**
  - 定型フォーマットのテキストデータを読み込むとき。BULK INSERTより高速です
  - https://dev.mysql.com/doc/refman/5.6/ja/load-data.html


諸事情により他の方が実装してくれている生のSQLを使っていますが、色々発見があって面白い今日この頃。
PowerShell CSOMを使ってSharePoint Onlineサイトコレクションにあるすべてのサブサイトを取得する

# SharePoint Server では AllWebs プロパティで取得できる

オンプレミスである SharePoint Server では、サーバーAPI の SPSite.AllWebs を使うことでサイトコレクションにあるすべてのサブサイトを取得できます。

このプロパティから返されるサブサイトにはトップレベルサイトも含みます。

[SPSite members](https://docs.microsoft.com/en-us/previous-versions/office/sharepoint-server/ms469472%28v%3doffice.15%29)

| Name     　　 | Description |
|:-- |:--|
|AllWebs      　　　| Gets the collection of all Web sites that are contained within the site collection, **including the top-level site and its subsites.**|

以下のように使います。

```powershell
$site = Get-SPSite http://contoso.com
$allwebs = $site.AllWebs
```
# SharePoint Online サイトコレクションには Allwebs がない

クライアントサイドAPIの Siteクラスにはすべてのサブサイトにあたるプロパティがありません。

[Site members](https://docs.microsoft.com/en-us/previous-versions/office/sharepoint-server/ee541164%28v%3doffice.15%29)
すべてのサブサイトに該当するプロパティなし

# SharePoint Online サイトは Web.Webs でサブサイトを取得する

サブサイトにあたる Webクラスには配下のサブサイトを取得するプロパティがあります。ただし、このプロパティが返すのは1階層下のサブサイトまでです。2階層以下のサブサイト（= 孫サブサイト）は含みません。

[Web members](https://docs.microsoft.com/en-us/previous-versions/office/sharepoint-server/ee546309%28v%3doffice.15%29)

| Name　　　 | Description |
|:--|:--|
|Webs|Gets a Web site collection object that represents all Web sites immediately beneath the Web site, **<font color="Red">excluding</font> children of those Web sites.**|

# ファンクションを使ってすべてのサブサイトを取得する

Web.Websプロパティを再帰的に呼び出すことで起点とするサブサイト配下のすべてのサブサイトを取得できます。以下はそれをファンクションにしたものです。

```powershell
#配下の全てのサブサイトを取得する
function GetSubWebs()
{ 
    Param
    ( 
        [Microsoft.SharePoint.Client.ClientContext]$context, 
        [Microsoft.SharePoint.Client.Web]$rootWeb 
    ) 

    $webs = $rootWeb.Webs 
    $context.Load($webs) 
    $context.ExecuteQuery() 

    $websList += $webs 
 
    foreach($sWeb in $Webs) 
    {   
        #自分（= このファンクション）を再帰的に呼び出して
        #孫サイトをすべて取得する
        GetSubWebs -RootWeb $sWeb -Context $Context 
    }

    return $websList
}
```
作成したファンクションは以下のように使用します。
$websCollection という配列を作成して、ファンクションの返り値（= サブサイト）を格納します。注意点として、起点になるサブサイトはファンクションの返り値に含まれないため、別個で配列に追加する必要があります。

```powershell
#対象サイトのオブジェクトを取得する
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl)
$ctx.Credentials = $credentials

$web = $ctx.web
$ctx.Load($web)
$ctx.ExecuteQuery()

#「配下の全てのサブサイトを取得する」ファンクションを呼び出す
$websCollection = @()
$websCollection += $web
$websCollection += GetSubWebs -rootWeb $web -context $ctx
```

# SharePoint PnP を使う

SharePoint PnP Cmdlets を使うともっと簡単にすべてのサブサイトを取得できます。Get-PnPSubWeb にある Recurse パラメータを使うと孫サイトの取得までやってくれます。便利。

```powershell
Connect-PnPOnline -Url $siteUrl -Credentials $credentials

$webs = @()
$webs += Get-PnPWeb
$webs += Get-PnPSubWebs -Recurse
```
中退→フリーター→無職からベンチャーのWebエンジニアに内定をもらった話

大学院中退。1年レジ打ち。半年無職でプログラミングを勉強。転職エージェントをつかって自社サービスを運営しているベンチャーのRailsエンジニアとして内定をもらった。

#1.経歴
大学では物理学科でした。講義でFortranというかなり古いプログラミング言語を学び、微分方程式や積分などをプログラミングで計算していました。
大学では暇だったのでHTMLを独学で学んで、ホームページを作ったりしていました。
卒業後、大学院に進学しましたが、大学院での専攻が興味と違うものだったので1年で中退しました。

とくにやりたいこともなかったので、生活費を稼ぐためにドラッグストアでバイトを始めました。1年ほど続けて「このままずっとバイト生活でいいのかなあ」と思って、とりあえずやめてから考えることにしました。

#2.オンラインサービスでプログラミングを勉強
バイトをやめる頃にYouTubeで、プログラミングを学べるオンラインサービスの[Progate](https://prog-8.com/)と[Aidemy](https://aidemy.net/)の動画を見ました。
・Progate
[堀江貴文のQ&A「PCはもういらない！！」〜vol.1001〜](https://youtu.be/moLe-Io3fYc)
vol.1007までの7本
・Aidemy
[堀江貴文のQ&A「AIプログラミングを学んで稼ぐ！？」〜vol.1035〜](https://youtu.be/6zlCShiIa3I)
vol.1049までの7本(とびとびです)

Progateは初心者向けのプログラミング学習サービスで、AidemyはAI(人工知能)のプログラミング学習サービスです。AIが流行っていたので、おもしろそうだなと思って軽い気持ちで始めてみました。

AidemyでAIのプログラミングをしてみたかったので、まずProgateでPythonという言語を勉強しました。大学でプログラミング経験があったので全くプログラミングをしたことない人よりはサクサクできたと思います。その後、Aidemyで3か月ほどAIのプログラミングを勉強しました。Udemyでも少しAIについて勉強しました。

その頃Aidemyで、勉強したことを記事にしてアウトプットする[第2回#Aidemynote](https://prtimes.jp/main/html/rd/p/000000048.000028316.html)というコンテストが開催されていました。いままで記事を書いたことはなかったのですが、ちょうど画像認識をひと通り勉強したところだったので参加してみました。下の記事がぼくが書いたものです。
[「エアコン消したっけ？」をAIでなくそう！](https://qiita.com/it31415/items/f3726b547795904837ef)
ディープラーニングをつかって、家のエアコンのオン・オフを見分けるAIをつくりました。

すると、[SNSでもっともシェアされたという「オーディエンス大賞」という賞を受賞することができました。](https://prtimes.jp/main/html/rd/p/000000068.000028316.html)たくさんの方に見てもらってコメントをしてもらって、とてもうれしかったです。

#3.転職活動
3か月ほど勉強してアウトプットもしたので就職しようと思いました。「転職エージェントに登録するといい」という記事をネットでみたので、大手の[マイナビエージェント](https://mynavi-agent.jp/)と、エンジニアに強い[ワークポート](https://www.workport.co.jp/)と[レバテック](https://career.levtech.jp/)に登録しました。

とくにレバテックには非常にお世話になりました。職務経歴書を添削してもらって書類選考率がかなり高くなりました。また、LINEでやりとりするときもすごくスピーディーで、ほとんど人生相談みたいに電話で何度も話をしてもらいました。他のエージェントで進んでいる求人に対しても、無理やりレバテックの求人を勧めることなく、フラットに意見をしてもらいました。ほんとうにありがとうございました。

最終的に4社から内定をいただきました。
・Web系の自社サービスをしているベンチャー
・大きな企業のデータサイエンティスト
・自社サービスもしているベンチャーのSIer
・自社システムも開発しているSIer

非常に悩みましたが、自分でWebサービスをつくってみたいし、実務未経験から入るのは難しい自社サービスの企業で成長したいと思い、ベンチャーでRailsエンジニアとして働くことに決めました。もうすぐ入社日です。

#4.おわりに
大学でのFortranやHTMLの経験、オンラインサービスでのプログラミング勉強経験、ホームページを作ったり記事を書いたり自らアウトプットする姿勢を評価してもらうことが多かったです。「ただプログラミングを勉強しました」よりも、簡単なものでいいからアウトプットして目に見える形で成果物をつくることで、無職からでも自社サービスの企業に内定をもらうことができました。

オンラインサービスでの勉強の話や転職エージェントでの転職活動の話など、詳しく知りたい方がいればQiitaやnoteやTwitterにコメントしていただければ記事を書こうと思います。
また、記事の感想やアドバイスやダメ出しなどもコメントしていただけるとうれしいです。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">転職するまでの話を記事にまとめてみました<br><br>未経験の方のエンジニア転職の参考にしてもらったり、無職のひとに勇気をあたえられたらうれしいです<br><br>中退→フリーター→無職からベンチャーのWebエンジニアに内定をもらった話｜IT暇人<a href="https://twitter.com/rails?ref_src=twsrc%5Etfw">@Rails</a>エンジニア <a href="https://twitter.com/it31415?ref_src=twsrc%5Etfw">@it31415</a>｜note（ノート） <a href="https://t.co/X10h5n3fSH">https://t.co/X10h5n3fSH</a></p>&mdash; IT暇人@2月からRailsエンジニア (@it31415) <a href="https://twitter.com/it31415/status/1091657144519163906?ref_src=twsrc%5Etfw">2019年2月2日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
電通生よ、もうEmacsで苦しみながらコードを書くのをやめよう

# はじめに
この記事の対象者はプログラムを書くために毎回計算機室に行くWindowsユーザーの為のものです。
Macユーザー、linuxユーザーはおとなしくsshしてください。
もちろんwindowsにlinuxを積むのが僕は一番いいと思います。

# おうちからコードを書きたい
どこからでも作業ができるのがリモートの良いところである。
電通大のプログラミングの課題が授業時間内に終わることなどごくまれなことであり、多くの課題を授業時間外でこなさなくてはならない。
これを毎回計算機室に行くのはとても非効率なことこの上ない。君のパソコンは何の為にあるんだ？

さて優秀な電通生の諸君はもちろんご存じだとは思うが、電通大の教育系サーバーにはsshで接続できる。
https://www.cc.uec.ac.jp/ug/ja/remote/ssh/
sshの方法は二つで

- パスワードログイン
- 秘密鍵によるログイン

の2つ。秘密鍵が推奨されているけどパスワードの方が楽。
ちなみにiedはすでに秘密鍵ログインとなっている。セキュリティ的にもそっちの方が強いし仕方ないね。

# 問題提起
Widowsユーザーの諸君、君たちには

- Tera-Termを使う
- PuTTYを使う
- linuxを積む

という3つの選択肢が提示されている。
僕が学部の2年まではTera-Termを使っていた。
Tera-TermやPuTTYも悪くはない。決して悪くはないが、ここでコーディングをするとなると不都合が生じる。
それはコード編集でEmacsやVimを使う羽目になることだ。

君が強いプログラマーで熱狂的なEmacserもしくはVimmerであれば文句は言わない。ブラウザバックを押してくれ
(※電気通信大学では学部1年の授業でEmacsを布教されるので熱烈なVimmerは左手の小指を折って憤死する)

が、君がもし誤字をして数時間を溶かすような初心者であれば僕は強いエディタに頼るべきだと思う。
慣れても誤字ぐらいするわ、人間だもの

sshで接続したものをダウンロードしてローカルで編集、アップロードする方法も無いではないがデバッグがめちゃくちゃしにくい。

そこでお勧めするのがVscodeやAtomのssh拡張機能だ。

# 汝、便利なエディタを使いたまえ
便利な時代に生まれたからには便利なものを使わなくては損である。
君は現代でも洗濯板使ってるタイプ？？？
それの方が汚れが落ちるとかなんかポリシーがある人は洗濯板を使うといい。

僕は洗濯機を使うけどね。

## Vscode
Visual studio Codeはmicrosoftさんが出してるソースコードエディタ。
僕はSurfaceを買っちゃうほどのmicrosoft信者なので(shift-jisと設定回りについてはアンチ)こっちを使っている。
黙ってインストールするといい。
https://code.visualstudio.com/

vscodeには便利な拡張機能が死ぬほどある。
今回お勧めするのがSSH FSだ。
https://marketplace.visualstudio.com/items?itemName=Kelvin.vscode-sshfs

sshで接続してファイルを直接編集できるのだ。


まずPuTTYをインストールする。
そうPuTTYをインストールするのだ。
https://www.putty.org/
どうやらPuTTYの機能を拝借しているようなのでやってくれ。

そして上のSSH FSをインストールしてVScodeを再起動して適応する。
そうすると
![yeah.png](https://qiita-image-store.s3.amazonaws.com/0/263565/d86896b2-e9f0-5d2b-6a67-ac89fb3753a2.png)
左下にこんなタブが出てくる。

- SSH　FILE　SYSTEMSを開いて右クリック。
- 「CREATE a SSH FS configuration」
- 適当な名前をつけて接続先を作る。

そうすると次のような設定ファイルが出てくる。

![yo.png](https://qiita-image-store.s3.amazonaws.com/0/263565/6f53f7df-f324-d62d-8f63-3ede9b8ac3f3.png)

labelは好きにしてくれ。なんでもわかりやすい名前を付けて。
一度Tera-termでもPuTTYでもログインしてpwdと打ってで自分のrootを確認しておくといいよ。
だいたいが/home2/y入学年の西暦/ユーザー名だと思う。

ユーザー名っていうのはいつも使ってる小文字一文字+学籍番号のやつ
passwordのところにpasswordを書いておいて自動ログインする方法もあるけどセキュリティ上よろしくないからtrueにしておくと接続するときに入力する形になるよ。

秘密鍵を使うときはPuTTYで作成し
passwordの代わりに

```
"privateKeyPath":"ファイルのアドレス",
"passphrase":true
```
とするよ。
あとは保存すると接続する？って聞いてくるからパスワード入れておしまい。

## Atom
使わないのでわかりませーーん()

https://qiita.com/informationsea/items/d2576b1ab678965d9a02

ちょっと古い記事だけど多分こんな感じでやればできると思うよ。
設定の詳細とかはvscodeのやつを参考にするといいかも。

# 便利なリモートライフを
君も便利なエディタでおうちから課題をやろう！！！！！！

以上。
picoCTF 2018 grep 2 - Points: 125

#問題

https://2018game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/d1bda04f-e725-3d90-d688-b651f19d9cbe.png)


#解いてみた

このパスどこに？という疑問が。
picoCTFサイトの右上にshellっていうタブがあってそこからっぽい。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/c8017200-67a4-70b3-b297-4ced425c7cf4.png)

shell押すとユーザとパスワードを求められます。
サイトのログインと同じものらしいので入力してもログインできない。
いろいろやってみた結果、パスワードに記号が入っているとサイトはログインできるけどshellはログイン失敗するらしい。

どうにかしてもらいたい。。。

shellにログインして問題文のフォルダにアクセスしてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/7366e679-264f-cda2-0df1-f59a7e7a9b4e.png)

```
grep -r "pico" /problems/grep-2_0_783d3e2c8ea2ebd3799ca6a5d28fc742/files
```

ですかね。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/4b5207f4-b986-2072-a01e-73754d9072c1.png)
ERROR custom keyword definition is invalid: data/errors should be boolean

<!-- TOC -->

- [1. 概要](#1-概要)
- [2. 解決策](#2-解決策)
- [3. 詳細](#3-詳細)

<!-- /TOC -->

# 1. 概要

Nuxt.js で新規のプロジェクト作成して実行しようとしたら下記のエラーが出ました．

```
 ERROR  custom keyword definition is invalid: data/errors should be boolean
```

# 2. 解決策

下記を実行すれば fix できました．

```console
$ npm uninstall ajv
$ npm install ajv@6.8.1
```

# 3. 詳細

プロジェクトを新規作成

```console
$ npx create-nuxt-app sample-003
? Project name sample-003
? Project description My stylish Nuxt.js project
? Use a custom server framework none
? Choose features to install
? Use a custom UI framework none
? Use a custom test framework none
? Choose rendering mode Universal
? Author name Hayato Akatsuka
? Choose a package manager npm
```

プロジェクト実行すると「 ERROR custom keyword definition is invalid: data/errors should be boolean」と怒られました．

```console
$ cd sample-003
$ npm run dev

 WARN  Address `localhost:3000` is already in use.

ℹ Trying a random port...
 ERROR  custom keyword definition is invalid: data/errors should be boolean

  at Ajv.addKeyword (node_modules/ajv/lib/keyword.js:65:13)
  at module.exports (node_modules/ajv-errors/index.js:10:7)
  at Object.<anonymous> (node_modules/schema-utils/src/validateOptions.js:22:1)
  at Module._compile (internal/modules/cjs/loader.js:678:30)
  at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)
  at Module.load (internal/modules/cjs/loader.js:589:32)
  at tryModuleLoad (internal/modules/cjs/loader.js:528:12)
  at Function.Module._load (internal/modules/cjs/loader.js:520:3)
  at Module.require (internal/modules/cjs/loader.js:626:17)
  at require (internal/modules/cjs/helpers.js:20:18)
```

本件については，webpack で issue が作成されていました．

- [webpack broken by ajv@6.9.0, "custom keyword definition is invalid: data.errors should be boolean" · Issue #8768 · webpack/webpack](https://github.com/webpack/webpack/issues/8768)

解決方法は ajv を下記の通りアンインストール後にインストールします．

```console
$ npm uninstall ajv
$ npm install ajv@6.8.1
```

ちゃんと動きました．

```console
$ npm run dev

 WARN  Address `localhost:3000` is already in use.
ℹ Trying a random port...
ℹ Preparing project for development                                                                                                                   ℹ Initial build may take a while                                                                                                                      ✔ Builder initialized                                                                                                                                 ✔ Nuxt files generated
✔ Client
  Compiled successfully in 8.39s
✔ Server
  Compiled successfully in 7.72s
ℹ Waiting for file changes

   ╭─────────────────────────────────────────────╮
   │                                             │
   │   Nuxt.js v2.4.3                            │
   │   Running in development mode (universal)   │
   │   Memory usage: 182 MB (RSS: 261 MB)        │
   │                                             │
   │   Listening on: http://localhost:50482      │
   │                                             │
   ╰─────────────────────────────────────────────╯
```
Macで空き容量を増やすためにやったこと

自分用メモ


1. まずどこで容量を食っているの確認
    * OmniDiskSweeper
    * https://www.omnigroup.com/more/

2. Dockerあたりで容量を食っていた
    * $docker system prune -f
    * Docker.rawが大きくなっていたので削除
        * https://forums.docker.com/t/where-does-docker-keep-images-containers-so-i-can-better-track-my-disk-usage/8370/11
        * $rm ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux
        * rm ~/Library/Containers/com.docker.docker/Data/vms/0/Docker.raw (2019/04/18, Pathは変わることがある?)
    * [効果] 人による. docker使ってる人で同じように困っている人はたくさんいたので調べるといろいろ出てくる

3. Mac関連
    * $brew cleanup -s 

4. Mac ストレージの空き領域を増やす方法 (Apple公式)
    * https://support.apple.com/ja-jp/HT206996

5. その他
    * Xcodeが大きい...
    * そもそも大きな容量を積んだMacbookを買いましょう (反省)
picoCTF 2018 Inspect Me - Points: 125

#問題

https://2018game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/c4499b5c-4da6-9bd6-d64a-d055a45cee20.png)

#解いてみた

アクセスしてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/ce0d5aa3-adf6-2b03-99fa-1cabf8bf185c.png)

特に何もないサイトにつながりました。
ソース見てみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/cbb2263a-5d73-6977-31ce-9ecfd3143c48.png)

最後が「}」ではないフラグが出てきました。1/3だけフラグがあります。
直前に書いてあるcssとjsが怪しいのでそちらも見てみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/0b4c648e-d7de-472b-dae0-72d6848f8cde.png)

CSS見てみると「}」で終わってますが、2/3らしいので、一応jsも見てみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/57e04186-fe1c-c43f-6873-626020fee2e7.png)

？
やはり2/3の「}」で終了していたようです。
vi 基本操作

# vi 基本操作

### カーソル移動

```
# コマンドの前に繰り返す回数を指定することができる。例えば、4j は4行下に移動する。

h - 左　　
j - 下に移動する
k - 上に移動する
l - 右に移動する
w - 次の単語ごとに最初の文字に移動する(句読点で止まる)
W - 次の単語ごとに最初の文字に移動する(句読点を無視する)
e - 次の単語ごとに最後の文字に移動する(句読点で止まる)
E - 次の単語ごとに最後の文字に移動する(句読点を無視する)
b - 前の単語ごとに最初の文字に移動する(句読点で止まる)
B - 前の単語ごとに最初の文字に移動する(句読点を無視する)
0 - 行の最初に移動する
^ - 行の最初の文字に移動する
$ - 行の最後に移動する
G - 指定の行に移動する(5Gは5行目に移動する)
```

### テキストの挿入

```
i - インサートモードを開始する
I - 行の始めでインサートする
a - カーソルの後でインサートする
A - 行の最後でインサートする
o - カーソルの場所で改行する
O - カーソル下に空白の行を挿入する
ea - 単語の最後の文字でインサートする
Esc - インサートモードを終了する
```

### テキスト編集

```
r - カーソルの文字を置き換える(インサートモードに入らない)
J - 1行下の行を現在の行の最後に移動する
cc - 行を消して置き換える
cw - 単語を消す
c$ - 行を消す
s - カーソル位置の文字を消す
S - 行を消して置き換える
xp - カーソル位置の文字を1つ右に移動する
u - 1つ前の操作を取り消す
. - 1つ前の操作を繰り返す
```

### ビジュアルモード

```
v - 文字単位でビジュアルモードを開始する
V - 行単位でビジュアルモードを開始する
Ctrl+v - 矩形選択(ブロック選択)を開始する
Esc - ビジュアルモードを終了する
```

### ビジュアルコマンド

```
y - 選択箇所をコピーする
d - 選択箇所を消す
```

### カット・ペースト

```
yy - 1行分コピーする
yw - 単語をコピーする
p - カーソルの後にクリップボードをペーストする
P - カーソルの前にクリップボードをペーストする
dd - 1行削除する(カットする)
dw - 現在地の単語を削除する(カットする)
x - 現在地の文字を削除する(カットする)
```

### 終了

```
:w - ファイルを保存する
:wq - ファイルを保存して、エディタを終了する
:q - エディタを終了する(ファイルに変更があった場合は失敗する)
:q! - エディタを強制終了する
```

### 検索・置換

```
/pattern - パターン検索をする
?pattern - パターン検索を後方にする
n - 検索を同じ方向に繰り返す
N - 検索を逆方向に繰り返す
:%s/old/new/g - ファイル内全てののoldをnewに置き換える
:%s/old/new/gc - ファイル内全てののoldをnewに置き換える(確認あり)
```

### 複数のファイルへの操作

```
:e filename - 新しいバッファでファイルを編集する
:bnext (or :bn) - 次のバッファに移動する
:bprev (of :bp) - 前のバッファに移動する
:bd - バッファを削除する(ファイルを閉じる)
:sp filename - 新しいファイルを新しいバッファで開き、画面を分割する
ctrl+ws - 画面を分割する
ctrl+wv - 画面を垂直方向に分割する
ctrl+ww - 画面を切り替える
ctrl+wq - 画面を閉じる
picoCTF 2018 pipe - Points: 110

#問題

https://2018game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/28de5edb-091a-3ed0-0c07-79e16d793777.png)


#解いてみた

問題に書いてある2018shell.picoctf.com 34532にncで接続してみます。

```
nc 2018shell.picoctf.com 34532
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/943684f4-6c48-76b2-019e-9640be4a2878.png)

大量に文字が出てきます。
たぶんどっかにflagがあると思うのでgrep使ってみます。

```
nc 2018shell.picoctf.com 34532 | grep pico
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/4163e710-f884-90f3-7df7-8d7a3f806641.png)
エンタープライズ・アジャイル実践セミナー参加レポート


# エンタープライズ・アジャイル実践セミナー #02

2019/02/08（金）に開催された、
[プロダクトオーナー実践編 ～スプリントプランニング～ ](https://graat-agile.connpass.com/event/113670/) 
に参加しました。

---
## スプリントを取り巻くプロセスとは
<img width="368" alt="スクリーンショット 2019-02-10 10.23.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/65426/0b6565d9-4e1f-b19b-6312-54334d78f96e.png">

### 理想と実態について
- POの役割は「プロダクトバックログを整備する」ところから  
- 企画段階から開発可能な段階まで詳細化する必要があるが、  
  企画が練られていない状態でスクラムが開始され、最終的に破綻するケースも多い

## バックログの作成プロセス
<img width="368" alt="スクリーンショット 2019-02-10 10.52.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/65426/83098c90-4966-cf46-68c6-96cddd78f196.png">

### プロダクトロードマップを作成する
  - 開発着手GOが出た企画に対して、以下を考慮して計画を策定する
    - いつ市場に投入すべきか
    - 現場は対応できるか
    - 開発チームは対応できるか

### バックログばらし
  - 業務運用に関わるバックログ
  - サポートに関わるバックログ
  - 開発に関わるバックログ
  - リリースに関わるバックログ  
    ⇒ ここまできて、開発可能なバックログを作成する

### バックログの洗練
  - 企画・開発チーム双方から参加する、モブワークで作成する
    - どう作るのか
    - どこまで作り込むか
    - 「やること」と「やらないこと」の境界線はなにか
    - 「完成時に確認する」為の項目はなにか

### プロダクトバックログのリファインメント
  - 詳細の追加
  - 見積もり
  - 並び替え
  - レビューと改訂  
  ⇒ 定期的に行うのが良い  
<img width="368" src="https://qiita-image-store.s3.amazonaws.com/0/65426/349d9dd1-22da-6be6-02da-5b39231c927b.jpeg">

### 計画の見直し
  - マイルストーンに見直しが発生するなら経営と話が必要
  - POとしては求められる

## POがやるべき３つのこと
  - プロダクトマネジメント組織を中心とした、価値創造の組織・仕組みを作る
  - 「価値」から話を始める
    - Outcome（市場に受け入れられたところ）まで確認できるか
  - フェーズによる役割の変化を理解する

### プロダクトマネジメント組織を中心とした、価値創造の組織・仕組みを作る
  - 前半に話をしたこと
 
### 「価値」から話を始める
  - 「リーンスタートアップ」や「デザイン思考」は、「既存の代替手段を起点とする」場合に強い
  - しかし、仮説を立てる人の視点が小さいと、小さいものしかできない
  - また、仮説を立てる世界の外側に到達したい未来があった場合、気づく方法が確立されていない
  - 「新しいシーンの開発を起点とする」場合には、別のアプローチが必要（匠Methodなど）

### フェーズによる役割の違いを把握する
  - プロダクトの成長を支える品質
  - プロダクトの組織の大きさに応じた関心事
 
---

## 「プロダクトオーナー実践編 ～スプリントプランニング～」
  - 機能要求と課題のマッピングを行う
    - 要求仕様書に記載された課題一覧から機能一覧とのマッピングを行う
  - 機能一覧を作成
    - ユーザーストーリー、ポイントを記述 
  - プロダクトバックログリファインメントを行う
    - チームからフィードバックをもらう
    - 優先順位決めのグループポリシーを決める
    - それに従って並び替える  
    - <img width="368" src="https://qiita-image-store.s3.amazonaws.com/0/65426/614f5a79-b532-6a55-7255-951905c0a047.jpeg">
  - プロダクトバックログ作成
  - スプリント作成
  - タスク分割
  - スプリント開始
 
---

### 参考資料

[エンタープライズ・アジャイル実践セミナー #01](https://graat-agile.connpass.com/event/106995/)
[エンタープライズ・アジャイル実践会〜プロダクトオーナーがエンタープライズアジャイルで抱える苦悩と対処〜](https://www.slideshare.net/fullvirtue/eaug)
【Dockerfile版】DockerでWindowsを操作できるAnsibleコンテナを構築する

[DockerでWindowsを操作できるAnsibleコンテナを構築する]
(https://qiita.com/myalpine/items/ea18b3b22c14c60efc3c)をDockerfileで書いてみました。

#コンテナ完成までの流れ
1. Dockerfile（イメージ作成の定義ファイル）を作成
2. Dockerイメージを作成（docker buildコマンド）
3. コンテナを作成して起動（docker runコマンド）

#1. Dockerfile（イメージ作成の定義ファイル）を作成
Docker for Windowsで作業を進めていきます。
ディレクトリ： C:\Ansible
Dockerfileは以下の通り。

```dockerfile:Dockerfile
#ベースとなるイメージ
FROM centos:centos7

#作成したユーザの情報
MAINTAINER myalpine

#SSHをインストール
RUN yum install -y openssh-server openssh-clients sshpass

#pipをインストール
RUN curl https://bootstrap.pypa.io/get-pip.py | python

#pywinrmをインストール
RUN pip install pywinrm

#Ansibleをインストール
RUN yum install -y epel-release && yum install -y ansible
```
#2. Dockerイメージを作成（docker buildコマンド）
Dockerfileがある「C:\Ansible」上でビルドします。

```docker
C:\Ansible> docker build -t ansible .
```

Dockerイメージができたことを確認。

```docker
C:\Ansible> docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ansible             latest              8deb4dc504a0        6 seconds ago       514MB
centos              centos7             1e1148e4cc2c        2 months ago        202MB
```

#3. コンテナを作成して起動（docker runコマンド）
```docker
C:\Ansible> docker run -it -d --name ansible ansible:latest
5611fc63e9ffc656eb40e02074b5c6d4f622b2dada64bf88e958dc353d13e38f
C:\Ansible> docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
5611fc63e9ff        ansible:latest      "/bin/bash"         2 minutes ago       Up 2 minutes                            ansible
```

Windowsを操作できるAnsibleコンテナが完成しました！
picoCTF 2018 strings - Points: 100

#問題

https://2018game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/b5075c6e-0b89-7489-926f-54c64bce4f70.png)

#解いてみた

ファイルをダウンロードして、サクラエディタで見てみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/77389a16-ce38-ec4a-87b2-e83f7450fc6f.png)

検索すると答えありました。
docker-composeでPHPとMySQLを連携させてみる

PHPとMySQLのコンテナをつくり、そのコンテナ間で連携できるものをdocker-composeを使って作っていきます。

# 前提

## ホスト環境
macOS Mojave 10.14.2

## ディレクトリ構成

```
├── docker-compose.yml
├── index.php
├── mysql
│   ├── Dockerfile
│   ├── mysql_conf
│       └── custom.cnf
├── php
    └── Dockerfile
```


# 手順

## カスタムネットワークの作成
```bash
$ docker network create [network_name]
```

[network_name]には， 任意の名前を指定する


## Dockerfile, docker-compose.ymlを書いていく


### php/Dockerfile
PHP,Apacheのイメージを元に必要最低限の拡張モジュールをインストールします。

```dockerfile
FROM php:7.2-apache
RUN apt-get update && \
  # PHPのExtensionをインストール．
  docker-php-ext-install pdo_mysql mysqli mbstring

WORKDIR /var/www/html

EXPOSE 80
```

### mysql/Dockerfile
動くものを作りたいので、とりあえずイメージだけ

```dockerfile
FROM mysql:8.0
```

### docker-compose.yml
```yml
version: '3'
services:
  app:
    container_name: php
    build:
      context: ./php
      dockerfile: Dockerfile
    tty: true
    volumes:
      - ${PWD}:/var/www/html
    ports:
      - "80:80"
    network_mode: "sample-network" # 上で作成したカスタムネットワークの名前を記載する

  db1:
    container_name: mysql
    build:
      context: ./mysql
      dockerfile: Dockerfile
    environment:
      - MYSQL_ROOT_PASSWORD=pass
    volumes:
      # MySQLの設定ファイル
      - ./mysql/mysql_conf:/etc/mysql/conf.d
    network_mode: "sample-network"

networks:
  sample-network:
```

## MySQLの設定ファイルを書く
MySQL8.0を実行した時， `The server requested authentication method unknown to the client`エラーが発生したので， 一応下記の設定を追加しておく．

### mysql/custom.cnf
```conf
[mysqld]
default_authentication_plugin=mysql_native_password
```

## docker-composeを実行
バックグラウンドで実行させるため， `-d`オプションをつける

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

## PHP側の設定

### 確認用スクリプトを書く
`index.php`

```php
<meta charset="UTF-8">
<title>テスト</title>
<?php
    try {
        # hostには「docker-compose.yml」で指定したコンテナ名を記載
        $dsn = "mysql:host=mysql;dbname=sample;";
        $db = new PDO($dsn, 'root', 'pass');

        $sql = "SELECT * FROM test";
        $stmt = $db->prepare($sql);
        $stmt->execute();
        $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
        var_dump($result);
    } catch (PDOException $e) {
        echo $e->getMessage();
        exit;
    }
```

## MySQL側の設定

### コンテナ内に入る
```bash
$ docker container exec -it mysql /bin/sh
```

### MySQLへ接続
パスワードは `docker-compose.yml`の環境変数で指定

```bash
$ mysql -ppass
```
適当なデータベースとテーブルを作成

```sql
mysql> CREATE DATABASE sample;
mysql> USE sample;
mysql> CREATE TABLE test(id int AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255));
mysql> INSERT INTO test (name) VALUES ('John');
```

## ブラウザで確認

http://localhost:80/index.php へアクセス

データが表示されることが確認できるかと思います
SQL Server 役立つSQLメモ

# 乱数生成
```sql
SELECT ABS(Checksum(NewID()) % 9)
```

# テーブル件数
```sql
SELECT o.NAME, i.rowcnt 
FROM sysindexes AS i
  INNER JOIN sysobjects AS o ON i.id = o.id 
WHERE i.indid < 2  AND OBJECTPROPERTY(o.id, 'IsMSShipped') = 0
ORDER BY i.rowcnt desc
```

# constraintsを無効にする
```sql
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
```

# constraintsを有効にする
```sql
EXEC sp_msforeachtable @command1="print '?'", @command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
```

# Index一覧を選択する
```sql
SELECT
	 TableName = t.name,
	 IndexName = ind.name,
	 IndexId = ind.index_id,
	 ColumnId = ic.index_column_id,
	 ColumnName = col.name,
	 ind.*,
	 ic.*,
	 col.*
FROM
	 sys.indexes ind
INNER JOIN
	 sys.index_columns ic ON  ind.object_id = ic.object_id and ind.index_id = ic.index_id
INNER JOIN
	 sys.columns col ON ic.object_id = col.object_id and ic.column_id = col.column_id
INNER JOIN
	 sys.tables t ON ind.object_id = t.object_id
--WHERE
--	 ind.is_primary_key = 0
--	 AND ind.is_unique = 0
--	 AND ind.is_unique_constraint = 0
--	 AND t.is_ms_shipped = 0
ORDER BY
	 t.name, ind.name, ind.index_id, ic.index_column_id;
```
tcpreplayのインストール

#tcpreplayについて
キャプチャしたパケットを再送できたり書き換えができたりする素晴らしいツール
負荷試験とか特定条件のパケットで起こる事象を再現するのにものすごい便利


#参考にしたページ
http://otsuka752.github.io
上記のページで大変わかりやすい説明があるので
上記でリファレンスを確認すると大体解決する。


#インストール
環境：Vagrant 2.2.2
     centos 7.6.1810 (Core)

centosだとEPALリポジトリからインストールできる。

```
#yum install epel-release
#yum install -y tcpreplay
[snip]
Installed:
  tcpreplay.x86_64 0:4.3.1-1.el7                                                

Dependency Installed:
  libpcap.x86_64 14:1.5.3-11.el7          tcpdump.x86_64 14:4.9.2-3.el7         

Complete!
```
問題なくインストールされているか確認

```
#  tcpreplay -V
tcpreplay version: 4.3.1 (build git:v4.3.1)
```
インストール完了

この後はpcapファイル（dumpファイル）を再送したり編集したり色々できる。