OmniAICreator/Qiita-1.07M huggingface dataset:
インタラクションなしで「パスワードありのユーザ」を追加する方法

Ubuntu/Debian系での操作方法について記す。

`adduser`コマンドでユーザ追加する方法では、インタラクティブな操作が要求されます。
(--gecos ""オプションでは、パスワードは聞かれてしまいます。)
そこで、`useradd`コマンドを使った方法を採用。


## 1. 依存アプリケーションをインストール。
  - パスワードハッシュ生成に必要な`mkpasswd`は`whois`パッケージでインストール。

```bash
sudo apt-get install -y whois
```

## 2. パスワード：*`Password#1`*、ユーザ名：*`hogeusername`*をそれぞれ、任意値に置き換えて実行する。
 
```bash
#-mオプションでホームディレクトリを作成する。
sudo useradd -m -s /bin/bash -p `echo Password#1 | tr -d '\n' | mkpasswd -s -m sha-512` hogeusername
#ついでにSudoも追加。
sudo gpasswd -a hogeusername sudo
```

## 3. あとはお好みで`/etc/skel`配下の`.bashrc`などをホームディレクトリにコピーしましょう。

* `useradd`コマンドには、オプションがいろいろあるので適宜変更する。

```bash
$ useradd -h
使い方: useradd [オプション] LOGIN
        useradd -D
        useradd -D [オプション]

オプション:
  -b, --base-dir BASE_DIR       新アカウントのホームディクトリの
                                ベースディレクトリ
  -c, --comment COMMENT         新アカウントの GECOS フィールド
  -d, --home-dir HOME_DIR       新アカウントのホームディレクトリ
  -D, --defaults                useradd のデフォルト設定を表示または変更
  -e, --expiredate EXPIRE_DATE  新アカウントの期限切れ日付
  -f, --inactive INACTIVE       新アカウントのパスワード無効化日数
  -g, --gid GROUP               新アカウントの主グループの名前または ID
  -G, --groups GROUPS           新アカウントの補助グループのリスト
  -h, --help                    このヘルプを表示して終了する
  -k, --skel SKEL_DIR           雛型ディレクトリに指定のものを使う
  -K, --key KEY=VALUE           /etc/login.defs のデフォルトより優先される
  -l, --no-log-init             ユーザを lastlog, faillog のデータベースに
                                追加しない
  -m, --create-home             ユーザのホームディレクトリを作成する
  -M, --no-create-home          ユーザのホームディレクトリを作成しない
  -N, --no-user-group           ユーザと同名のグループを作成しない
  -o, --non-unique              UID が同じユーザの作成を許す
  -p, --password PASSWORD       新アカウントの暗号化されたパスワード
  -r, --system                  システムアカウントを作成します
  -R, --root CHROOT_DIR         chroot するディレクトリ
  -s, --shell SHELL             新アカウントのログインシェル
  -u, --uid UID                 新アカウントのユーザ ID
  -U, --user-group              ユーザと同じ名前のグループを作成する
  -Z, --selinux-user SEUSER     SELinux のユーザマッピングに指定した
                                SEUSER を使う
```

自動化最高です。
正規表現に出てくる"?:"について

phpの正規表現をみる中で「?:」という書き方の意味がわからなかったので調べました。

公式マニュアルの[サブパターン](https://php.net/manual/ja/regexp.reference.subpatterns.php)に、下記のように記載があります。
> 開きカッコの後に "?:" を付けると、そのサブパターンは値のキャプチャを行わず、 キャプチャ用サブパターンの番号としてもカウントされません。
> 例えば、 文字列 "the white queen" に対し、次のパターンをマッチングさせてみましょう。


マニュアルにコード例が書いてあったものの、結果が載っていなかったので確認のために試してみました。
PHPをインタラクティブモードで実行して確認を行います。

```bash
$ php -a
```

## ?:をつけない場合
マニュアル通りの文字列とパターンでの実行結果です。

```php
php > $text = 'the red king';
php > preg_match('/the ((red|white) (king|queen))/', $text, $m);
php > var_dump($m);
array(4) {
  [0]=>
  string(12) "the red king" // パターン全体にマッチした結果
  [1]=>
  string(8) "red king" // 外側の括弧にマッチした結果
  [2]=>
  string(3) "red" // 内側の1番目の括弧にマッチした結果
  [3]=>
  string(4) "king" // 内側の2番目の括弧にマッチした結果
}
```

## ?:をつける場合
こちらも同じくマニュアル通りです。
内側の1番目の開き括弧の後に "?:" を記載したため、こちらはキャプチャが行われておりません。

番号も0,1,2となっているため、下記の記述の通りになっているようです。
> そのサブパターンは値のキャプチャを行わず、 キャプチャ用サブパターンの番号としてもカウントされません


```php
php > $text = 'the red king';
php > preg_match('/the ((?:red|white) (king|queen))/', $text, $m2);
php > var_dump($m2);
array(3) {
  [0]=>
  string(12) "the red king" // パターン全体にマッチした結果
  [1]=>
  string(8) "red king" // 外側の括弧にマッチした結果
  [2]=>
  string(4) "king" // 内側の2番目の括弧にマッチした結果
}
```

もちろん内側の2つの括弧両方に"?:"を記載すると、両方ともキャプチャされなくなります。

```php
php > preg_match('/the ((?:red|white) (?:king|queen))/', $text, $m3);
php > var_dump($m3);
array(2) {
  [0]=>
  string(12) "the red king"
  [1]=>
  string(8) "red king"
}
```
opsworksのcreate-deploymentでインスタンスを指定したくてハマった

CircleCIでaws-sdk使って、Opsworksのデプロイをしていたときに、
ちょっとした事情でインスタンスを指定してデプロイをしたかったので、
どうやってやるのか公式ドキュメントを調べてたら

```
create-deployment
--stack-id <value>
[--app-id <value>]
[--instance-ids <value>]
[--layer-ids <value>]
--command <value>
[--comment <value>]
[--custom-json <value>]
[--cli-input-json <value>]
[--generate-cli-skeleton <value>]
```
>The instance IDs for the deployment targets.
>https://docs.aws.amazon.com/cli/latest/reference/opsworks/create-deployment.html

ふむふむ、 `--instance-ids`でEC2インスタンスのID(i-XXXXXXのやつ)を指定すればいいのかと思ったら違った。。。

この `--instance-ids`で指定するのは`OpsWorks ID`だった。

![rails-app3_-_Instances_-_LIFELABEL-STG_–_AWS_OpsWorks.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100766/d97f6570-7d35-7f9d-6e27-ad480e346347.png)

`EC2 instance ID`ではないので注意
PHP on Docker for Mac

## 【実行手順】
### ▼準備
```
$ mkdir {任意のディレクトリ}/php_apache
$ mkdir {任意のディレクトリ}/php_apache/html
$ touch {任意のディレクトリ}/php_apache/Dockerfile
$ touch {任意のディレクトリ}/php_apache/html/index.php
```
### ▼Dockerfileを編集
```
$ vim {任意のディレクトリ}/php_apache/Dockerfile
```
```Dockerfile.
FROM php:7.2.11-apache
```
### ▼イメージをビルド
```
docker build {任意のディレクトリ}/php_apache/ -t php_apache_image
```
### ▼イメージの作成完了を確認
```
docker images
```
### ▼コンテナ作成・起動
```
docker run -d -p 80:80 -v /Users/{UserName}/data/dockerfiles/php_apache/html:/var/www/html --name php_apache_container php_apache_image
```
### ▼コンテナの起動を確認
```
$ docker ps
```
### ▼PHPを編集
```
$ vim {任意のディレクトリ}/php_apache/html/index.php
```
```index.php
<?php
phpinfo();
```
### ▼アクセス
[localhost](http://localhost/index.php)

# 【参考】
https://upd.world/docker-php-de/
3月からRailsの勉強を始めた僕がこれまで作ったアプリ

GW中にポートフォリオ2作目を作って先日デプロイしました。
それがこちらです。
[Tabelle](https://tabelle.club/)
ざっくり説明すると食べ物の好みで繋がるSNS的なアプリです。
![tabelle.club_fkdolly(iPhone 6_7_8) (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396318/c0f31868-73d5-3aad-fb6d-878c6335a0ad.png)

食べ物は自由に追加できますし、その食べ物について写真とともに投稿することもできます。
![tabelle.club_fkdolly(iPhone 6_7_8) (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396318/f4bebfb2-f68e-7d44-979a-b916d9e19f37.png)

ユーザープロフィールに飛ぶと「好きな食べ物」「苦手な食べ物」タブで一覧表示されるので、食べ物の好みが合いそうだと思ったらフォローすることもできます。
大量に投稿が貯まれば飯テロになるアプリを目指しました笑


ちなみに1作目はこちらです◎
[MUSSIC](https://mussic.me/)
こちらは思い出の場所と曲を投稿できるアプリです。
![mussic.me_fkdolly(iPhone 6_7_8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396318/04d1b35d-034c-e511-762e-a0578014b978.png)

ログインして投稿画面を開くとまずはGoogle Mapsが表示されます。地名を入力するとオートコンプリートで予測一覧が出るので選択すると、
![mussic.me_fkdolly(iPhone 6_7_8) (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396318/f1ea1f30-18ff-9df2-ae2b-ed5535818bac.png)

こんな感じです（大阪に住んでいるので梅田にしました笑）。
OKボタンを押すとSpotify APIでの曲選択画面に移ります。こちらもアーティスト名を入力すると、
![mussic.me_fkdolly_4_songselect(iPhone 6_7_8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396318/8cc85797-34d4-59c7-f3e0-d571cf9716b2.png)

こんな感じでアルバム上位の候補が出てきます。
アルバムを選択すると、
![mussic.me_fkdolly_4_songselect(iPhone 6_7_8) (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396318/95ce12a1-92b6-e765-fd87-11e9bc789c35.png)

収録曲一覧が出てきます。曲名を選択してOKボタンを押して、最後の確認画面でコメントを入力すれば投稿完了です。
ユーザープロフィールではその人の投稿一覧が見られますし、またトップページには全ての投稿が地図上にマーカー表示されています。
![mussic.me_(iPhone 6_7_8) (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396318/ae61c01b-65a8-b453-9d95-2df9a43923c0.png)

以上2つが現時点での僕のポートフォリオです。現在この2つを携えて未経験からエンジニアへの転職を目指しております。
来週からいよいよ面接が始まるので気合入れて頑張ります！
【一日目】Unity でモブプログラミング[B02_Dase]

# Unity でモブプロしました

4/20 に Unity でモブプロしミニゲームを作りました。この記事で記載するのは「02_Dase」というチームの記録になります。いろいろと困難もあったため、そういったことを含めて記録します。

# どういったゲームをつくる？

メイドイン ○ リオにあるゲームを移植することにしました。ゲームの概要は以下のとおり。

- 人の口から食べ物が入る
- 食べ物は口から胃など移動させていく
- プレイヤーは食べ物をおしりから出すよう人を回転させる

書いてて思いましたがこのゲームは説明が難しいですね。「結局どんなゲームやねん」って思っている方は、以下に GIF アニメがあるのでご確認いただければ幸いです。

# モブプロ開始！

10 時 30 分。モブプロのチーム早速行き詰まります。素材がねえ。ギミックがカンタンなクセに素材がねえ。これまでの勉強会では素材なども準備された状態から学習を初めていましたが、なにもない状態で初めて有り難みを痛感することに。とりあえずは素材を探して加工するところからスタートしました。

- 素材　その１　顔

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412322/ec5df5ae-40f2-d8af-f76f-d2f3481afb88.png" width="25%">

- 素材　その２　身体

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412322/9a41f7dc-f967-dcc1-a133-edc084a38066.png" width="50%">




上記の素材を作る前は食べ物を通過する部分を白で塗りたくってました。そんなことをすると Unity の Collider を手動で設定していかないとダメなので慌てて修正しています。

# 回転操作で揉める・・・

### 物理演算のアプローチで悲劇 (´；ω；｀)

素材の顔と身体を１つのグループにして回すような操作を施すわけですが、なぜか物理演算的なアプローチを取ることに・・・。「localEulerAngles」や「Quaternion.Euler」などを使って回転操作を作るわけです。

でもそんなに慣れていなかったせいか、回転速度などを制御できませんでした。意図しない豪速での動作で食べ物が抜けたりするなどのトラブルが発生。午後の３時に完全に行き詰まります。お菓子食いてぇ・・・。

# シンプルな発想で乗り越える

これムリだな～って思っていろんな人にバトンタッチしていくことに。本来は 15 分ごとに順番に交代しながらですが、緊急事態なのでいろいろな人が入れ替わり立ち替わりで操作します。モブプロ的にはどうなのよって思うかもしれませんが、このライブ感は何かエモい雰囲気があります。

### 物理演算の処理を抜本的にやめる

結局どうなったのかというと「transform.Rotate」を使うことで解決できました。大量にあった物理演算関連の処理がたった１行に置き換わり問題解決。ボクたちは難しく考えすぎてたんだぁ・・・。

# 最後の最後で操作感がおかしい

タップすると自動的に回転方向が変わるような操作となり、ほぼゲームとして出来上がってきました。が！なぜかタップしても回転方向が変わらないことがある・・・。やっぱりこれムリだな～って思って佇んでいたところ、基本的なところが間違っていたわけです。

### 操作部分の処理を通常の「FixedUpdate」から「Update」に

タップを検知する部分が「FixedUpdate」に記述されていました。これだと操作が検知されないことがあるわけで・・・。タップ操作の処理を「Update」に移して問題解決。

# 完成したゲーム

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412322/3b9df164-82d3-b4ca-2fec-92d64d742838.gif" width="50%">



食ったモノを出す！そんな「出せ」っていうミニゲームです。
なぜオニギリが回転しないのかって？それはオニギリを親にして「Main Camera」を子にしたヤツがいたからです。まあ、でも時間が限られているのでそういう実装もしょうがないかなと。モブプロなんで修正できる人が修正すればイイんですが、これまでの経緯を見てもらえれば、そんな余裕は一切ナシ！！

# 振り返り

- 素材を準備するということを考えてなかったため苦労した
- ヘンに物理演算を使ってみようというところから悲劇が始まった
- 操作関連を FixedUpdate に書くという基本的なことを忘れていた
- そんなこんなでイロイロとあったが無事にできてよかった
- みんなよくガンバった！
【メモ】MVC (Model - View - Controller)

# 前置き
<details>
<summary>続きを読む</summary>
本記事はプログラミング初学者が、Ruby/Ruby on Railsを学習する上で得た知見を、自分なりにまとめるためのノートです。  
もし「この表現は誤っている」、「理解の仕方がおかしい」などありましたらご教示いただけると幸いです。  
</details>

# MVCについて
UIを持つアプリケーションを実装するためのデザインパターンのひとつ。
MVCから派生したMVP(Model - View - Presenter)とか、MVVM(Model-View-ViewModel)などもある。
MVCでは役割をmodel、view、controllerの3つに分担して実装します。

## MVCにおける役割
- Model  
ビジネスロジック、データの変更をビューへ通知
- view  
モデルのデータを取り出して表示処理を行う
- Controller  
ユーザからの入力をモデルへ伝える

# MVC2について
WebでデータとUIを分離する時にMVCモデルを参考にしたデザインパターン。
WEBアプリケーションでMVCと言われた場合はこちらを指す。
RailsチュートリアルでもMVCの説明がされていますが、こちらはControllerが仲立ちして、ViewとModelはやり取りしないMVC2の図。

## MVC2における役割
- Model  
ビジネスロジック、処理結果のデータをコントローラへ引き渡し
- view  
コントローラからデータを受け取り表示処理を行う
- Controller  
ユーザからの入力をモデルへ伝える、ビューへデータを引き渡し、表示処理を指示

# まとめ
WEBだとModelからViewへの通知が必要ないし、MVCと言えばMVC2。
Controllerは入力を受け付けてModelへパスを要求
Modelはボールを持ってControllerへセンタリング
ControllerはリターンボールをViewへスルーパス
viewはボールをゴールへシュート！　超エキサイティング！ってことですね。

# 参考情報
<details>
<summary>参考情報へのリンク</summary>
古い記事を含みますのでご留意ください。
-> qiita
　[Webアプリケーション開発者から見た、MVCとMVP、そしてMVVMの違い](https://qiita.com/shinkuFencer/items/f2651073fb71416b6cd7)
-> github
　[サバクラ両方で動く JavaScript の大規模開発を行うために](https://gist.github.com/tily/1362110)
-> Studio ARCANA技術ブログ
　[MVC と MVC2 について改めて考えてみる](https://www.s-arcana.co.jp/tech/2011/07/mvc-mvc2.html)
-> Java好き
　[MVCをWebに適用した｢MVC2｣](https://javazuki.com/articles/mvc2-tutorial.html)

</details>
ProxySQL を使って EC2 をプロキシサーバとして利用し、特定の IP から RDS にアクセスする

# 背景
社内の RDS の一つに、一時的に特定の外部の固定IPからアクセスできるようにしたい。
そこで、特定の外部の固定IPからのみアクセス可能な EC2 に ProxySQL を設定し、そこ経由で RDS にアクセスしたい。
(今回は MySQL)

# AWS マネジメントコンソール上での準備

## VPC の用意
VPCを用意しておきます。

## RDS の準備

RDS インスタンスを立ち上げる。
インバウンドには、後述する EC2 のセキュリティグループを設定。
port は 3306 を空けておく。
ここでは説明のため、↓のようなユーザ/パスを設定することにする。

```
user: app
password: pass
```


## EC2 の準備
今回は Amazon Linux を想定。
インバウンドとして、接続してくる外部の固定IPを設定。
port は 22(SSH用)と 6033(proxy用) を空けておく。

# EC2 上での操作

## RDS インスタンスに接続してテーブルを作成
ユーザは AWS マネジメントコンソールで RDS インスタンスを作る時に作られている。

```bash
$ sudo yum -y install mysql mysql-devel
$ mysql -h [RDSのエンドポイント] -u [マスターユーザー名] -p
// RDSインスタンスへの接続
Enter password:
```

```sql
// テーブル作成
CREATE TABLE users(
    id INT(11) AUTO_INCREMENT NOT NULL, 
    name VARCHAR(30) NOT NULL ,
    PRIMARY KEY (id));
```

## ProxySQL をインストール
↓ファイルを開いて

```bash
$ vi /etc/yum.repos.d/proxysql.repo
```

↓を書き込む

```
[proxysql_repo]
name= ProxySQL YUM repository
baseurl=https://repo.proxysql.com/ProxySQL/proxysql-2.0.x/centos/latest
gpgcheck=1
gpgkey=https://repo.proxysql.com/ProxySQL/repo_pub_key
```

インストール

```bash
$ yum install proxysql
```


## ProxySQL 管理画面での操作

/etc/proxysql.cnf の設定

```
mysql_variables=
{
  admin_credentials="admin:admin"
  mysql_ifaces="127.0.0.1:6032;/tmp/proxysql_admin.sock"
  threads=1
  interfaces="0.0.0.0:6033;"
}
```

## ProxySQL 起動

```bash
# 止めるときは stop
$ sudo service proxysql start
```

## ProxySQL 管理画面から proxy 設定

```bash
$ mysql -u admin -padmin -h 127.0.0.1 -P6032 --prompt='Admin> '
```

```sql
# サーバ情報とユーザを作成
INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (0,[RDSのエンドポイント],3306);
INSERT INTO mysql_users (username,password) VALUES ('app','pass');

# RUNTIME へ適用
LOAD MYSQL SERVERS to RUNTIME;
LOAD MYSQL USERS TO RUNTIME;

# 永続化
SAVE MYSQL SERVERS TO DISK;
SAVE MYSQL USERS TO DISK;
```

# 固定IPを持つ外部からの操作

```bash
mysql -h [EC2のエンドポイント]  -u app -ppass -P6033
```

これで接続できます。
先ほど作ったテーブルも確認できるはず。


# 参考ページ一覧
https://github.com/sysown/proxysql/wiki  
https://confluence.sharuru07.jp/pages/viewpage.action?pageId=2883888
自己署名証明書の作成

# 【概要】
備忘録
## 【実行手順】
### ▼秘密鍵を生成
```
$ openssl genrsa -aes256 -out {KeyName}.key 2048
```
パスフレーズを設定する。

### ▼パスワードなしの場合
```
openssl genrsa -out {KeyName}.pem 2048
```

### ▼CSRを作成
秘密鍵を元に発行した公開鍵が本物であるかどうかを証明書を作成

```
openssl req -new -key {KeyName}.key > {CSRName}.csr
```

### 証明書を作成
```
openssl req -x509 -key {Keyname}.key -in {CSRName}.csr -out {CRTName}.pem -days 3560
```

### ▼サーバー証明書を作成
```
$ openssl req -x509 -key {Keyname}.key -signkey {CSRName}.pem -out {ServerCSRName}.pem -days 3560
```
CodeBuildでDocker in Dockerする(CloudFormation)


# やり方
CodeBuild Project > Environment > PrivilegedModeをTrueにする

> PrivilegedMode:
> プロジェクトで Docker イメージを実行する方法を示します。true を指定して、Docker コンテナ内の Docker デーモンを実行できるようにします。
> [AWS CodeBuild プロジェクト環境](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-environment.html#cfn-codebuild-project-environment-privilegedmode)

## Before

```yaml
  CodeBuildProject:
    Description: Creating AWS CodeBuild project
    Type: AWS::CodeBuild::Project
    Properties:
      Artifacts:
        Type: CODEPIPELINE
      Description: !Sub Building stage for ${Branch}.
      Environment:
        ComputeType: BUILD_GENERAL1_SMALL
        EnvironmentVariables:
          - Name: Branch
            Value: !Ref Branch
        Image: !Ref CodeBuildImage
        Type: LINUX_CONTAINER
      Name: !Sub ${ServiceName}-${Branch}-build
      ServiceRole: !Ref CodeBuildRole
      Source:
        Type: CODEPIPELINE
      TimeoutInMinutes: 5
```

## After

```yaml
  CodeBuildProject:
    Description: Creating AWS CodeBuild project
    Type: AWS::CodeBuild::Project
    Properties:
      Artifacts:
        Type: CODEPIPELINE
      Description: !Sub Building stage for ${Branch}.
      Environment:
        ComputeType: BUILD_GENERAL1_SMALL
        EnvironmentVariables:
          - Name: Branch
            Value: !Ref Branch
        Image: !Ref CodeBuildImage
        Type: LINUX_CONTAINER
        PrivilegedMode: True
      Name: !Sub ${ServiceName}-${Branch}-build
      ServiceRole: !Ref CodeBuildRole
      Source:
        Type: CODEPIPELINE
      TimeoutInMinutes: 5
```


# エラー
上記の指定をしないと↓のエラーが出る。

```bash
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```

# 備考
- 手作業でやる場合: [CodeBuildでDocker in Dockerする](https://qiita.com/reireias/items/c02e5e7b2f099f2dab9e)
外出先から自宅LANにsshでいろいろアクセスしたみた

# はじめに
外出先から自宅LANにsshでいろいろアクセスしてみたのでメモ

# 試してみたこと
* sshエージェント転送
* 外出先のローカルPCにリモートサーバ(Ubuntu)のブラウザを表示させてみた



# SSHエージェント転送
## 環境
* PC
  - Windows10上のCentOS6.10(VirtualBox)
* 踏み台サーバ
  - GCEのCentOS6.10
* 自宅LANのサーバA
  - 自宅LANのグローバルIPにsshすると自宅ルータからフォワーディングされるサーバー

普段は外出先PCからサーバAに直接sshしているが、今回はGCEを経由してsshアクセスしてみました

## sshエージェント転送とは
## 概要

```
【外出先】　　　　　　【GCE】　　　　　　　　【自宅LAN】
　　PC---------->踏み台サーバー---------->サーバーA
　 　　　(ssh)　               　(ssh)
```

### 前提
PCからサーバーAに対してPCの秘密鍵で公開鍵認証でログインできること

### sshエージェント転送でできること
* 踏み台サーバからサーバAにsshするときに`手元のPCの秘密鍵`で`サーバAに公開鍵認証`できるようになる
* 秘密鍵を踏み台サーバに置かなくてよい

## sshエージェント転送利用方法
### PC------>踏み台サーバー
外出先でPCにてssh-agentの起動　(MAC,Ubuntuは不要みたい)

```
$ eval "$(ssh-agent)"
Agent pid 4312
```

秘密鍵の登録

```
$ ssh-add 秘密鍵の場所 
Identity added: 秘密鍵の場所
```

登録の確認

```
$ ssh-add -l
2048 xxxxxxxxxxxxxxxxxxxxxxx 秘密鍵の場所 (RSA)
```

踏み台サーバへのアクセス(-Aでエージェント転送を有効)

```
ssh -A 踏み台サーバIP
```

踏み台で確認(手元のPCの秘密鍵のディレクトリ構成の秘密鍵が表示される)

```
$ ssh-add -l
2048 xxxxxxxxxxxxxxxxxxxxxxx 秘密鍵の場所 (RSA)
```

### 踏み台サーバー------>サーバーA
サーバーAにssh。外出先の手元にあるPCの秘密鍵で公開鍵認証でsshログインできる

```
ssh サーバーAのIP
```

# 外出先のローカルPCにリモートサーバのブラウザを表示させてみた
## 環境
* PC
  - Windows10上のCentOS6.10(VirtualBox)
* 踏み台サーバ
  - 自宅LANのCentOS6.10
* 自宅LANのサーバA
  - Ubuntuデスクトップ

## 概要

```
【外出先】　　　　　【自宅LAN】　　　　　　【自宅LAN】
　　PC---------->踏み台サーバ---------->サーバーA
　 　　　(ssh)　               　(ssh)
```

* 踏み台サーバ
  - 自宅LANにsshするときにルータからフォワーディングされるサーバ。外出先からsshするとまずははここにたどり着く
* サーバーA
  - このサーバーのブラウザをPCに表示させる

## トンネルの作成
* -L でローカルPCの50022ポート(wellknownポート以外で何番でもよい)を指定
* PCの50022ポートから踏み台サーバにアクセスしてその後、サーバAのIPポート２２につなげるトンネル
* このプロセスはそのままにしておく(端末をそのまま)

```
ssh 自宅グローバルIP(踏み台にフォワーディングされる) -L 50022:サーバAのIP:22
```

イメージ

```
【外出先】　　　　　　　　　　【自宅LAN】
　　PC-------------------->サーバーA
　　　　　　(sshトンネル)　          
```

## リモートサーバのブラウザのローカルPCでの表示
ポートはトンネルで作成したポートを指定してsshでXオプションをつけてアクセス。するとトンネルを通って(踏み台を通り)一気にサーバAにアクセス

```
ssh -p 50022 サーバAのユーザ名@localhost -X
```

ブラウザを起動するとサーバAのブラウザがローカルに表示される

```
firefox
```


# 参考
[まんがでわかるLinux　シス管系女子3](
https://www.amazon.co.jp/%E3%81%BE%E3%82%93%E3%81%8C%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8BLinux-%E3%82%B7%E3%82%B9%E7%AE%A1%E7%B3%BB%E5%A5%B3%E5%AD%90%EF%BC%88%E6%97%A5%E7%B5%8CBP-Next-ICT%E9%81%B8%E6%9B%B8%EF%BC%89-Piro-%E7%B5%90%E5%9F%8E%E6%B4%8B%E5%BF%97-ebook/dp/B00TQMFOCW/ref=sr_1_5?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E7%AE%A1%E7%90%86&qid=1557451442&s=gateway&sr=8-5
)
nvm で npm の prefix がいつの間にか意図しない状態になっていた

## 1. 意図しない状態

```
$ npm config get prefix
/usr/local
```

* `npm install -g xxx` やると `/usr/local` 配下にインストールしようとして、エラーが出る。そもそも、そこに入ってほしくなーい！
* コピペの賜物かなw

## 2. このコマンドで戻った

```
nvm install node && nvm alias default node
```

* 最新の node がインストールされちゃったけど。困らんしいいのだが。
* 最新の node も、元々使っていた node も、期待通りの `prefix` になったよー。

## 3. 期待通り

```
$ npm config get prefix
/Users/higuchi/.nvm/versions/node/v11.13.0
```

以上
【質問】カレンダー招待通知に関するお問合せ

下記の様なGASを記述しました。

スプレッドシートCalには
1行目：イベントタイトル
2行目：担当者メールアドレス(カレンダーID)
3行目：開始時間
4行目：終了時間(2019/04/01 12:00)
5行目：場所
6行目：説明
7行目：カレンダー登録状況
の情報があります。

下記のコードでは、
自分のカレンダーへの登録及び担当者へのカレンダーへの登録はできるのですが、カレンダーの招待通知ができず困っております。

リファレンスも見てみましたが、解決できませんでした。
お分かりになられる方がいらっしゃいましたら、ご教示いただけますと幸いです。

https://developers.google.com/apps-script/reference/calendar/calendar-app#createeventtitle-starttime-endtime-options

function createCalendar() {
  var sh = SpreadsheetApp.getActive().getSheetByName('Cal');
  var values = sh.getDataRange().getValues();
  var calendars = CalendarApp.getDefaultCalendar();　

  for(var i = 1; i < values.length; i++){
    var title = values[i][0];
    var startTime = values[i][2];
    var endTime = values[i][3]; 
    var option = {
　　　　　location: values[i][4],
　　　　　description: values[i][5],
　　　　　guests:values[i][1],
　　　　　sendInvites: true};

    added = values[i][6];
    if(added == "") {
  calendars.createEvent(title, startTime, endTime, option);     
      sh.getRange(i+1, 7).setValue("追加済み");
   }
 }
}

尚、下記の内容ではカレンダーの招待通知は出せました。
function createCalendar() {

var event = CalendarApp.getDefaultCalendar().createAllDayEvent(
    'テスト',
    new Date('August 15, 2019'),
    new Date('August 16, 2019'),
    {
    location: 'Bethel, White Lake, New York,U.S.', 
    guests:"担当者メールアドレス",
    sendInvites: true});
}

何卒、宜しくお願いいたします。
React基礎①

#React基礎
Reactを勉強するにあたり、コンポーネントなどの理解を深めるため
アウトプットをするため記事を書く。
##Hello World
いつものやつ

```jsx
//コード１
ReactDom.render(
    <h1>Hello,world!</h1>,
    document.getElementById('root')
  );
```

##JSXの導入
JSXとはReactでアプリケーションを作るためのJavaScript文法の一つ。
JSXはBabelというJSXコンパイラというソフトウェアを使って、ブラウザに配信する前に
JavaScriptに変換される。

例えば、nameという変数を宣言して、それを中括弧に囲んでJSX内で使用している。
以下では、nameという変数をelementの中に埋め込んでいる。
そして、ReactDOM.renderで呼び出し、htmlのid=rootの要素に格納される。
JSX の記法としては2行目のようにタグを含めて宣言することができる。

```jsx
//コード２
const name = 'React Taro';
const element = <h1>Hello,{name}</h1>;
    
ReactDOM.render(
    element,
    document.getElementById('root')
);
```
###※注意1：ReactDOM.renderの第一引数の値はひとまとまりにしなければならない。

例えば

```jsx

//コード３
ReactDOM.render(
    <h1>a</h1>
    <h2>b</h2>
    ,document.getElementById('root')
);
```
のように複数の要素を持つのは禁止されている。
コード３は以下のように変更すればよい。

```jsx

//コード４
ReactDOM.render(
    <div>
        <h1>a</h1>
        <h2>b</h2>
    </div>
    ,document.getElementById('root')
```
JSX はif文やfor文も使うことができる。

```jsx
//コード５
function getHello(user) {
  if(user){
      return <h1>Hello, {user}!</h1>;
  }
  return <h1>Hello, Guest!</h1>;
}
```
###注意２:JSXでの閉じタグがないタグ
例えば、imgタグがある。

```html
<img src="user_image.png">
```
この場合JSXでは閉じタグが必須なため以下のようになる。

```jsx 
<img src={user.imageURL} />
```
というように最後に「/」をつける必要がある。

##インジェクション攻撃を防ぐ
1. インジェクション攻撃とは<br>
    インジェクション攻撃は
    >攻撃者がサーバーに、データベースを操作するSQL文やコマンド、JavaScriptといったスクリプト文などを送って、想定外の動作をさせる攻撃を指す。
    
2. 防止<br>
ReactDOMはJSXに埋め込まれた値をレンダリングされ表示される前にエスケープ処理します。<br>
ここでエスケープ処理とは、プログラミング言語などの文字列、すなわち特別な意味を持つ文字や記号を
別の文字に置き換えることで悪意のあるユーザーからのアクセスに対処する処理である。<br>

###注意３
JSXはキャメルケースの命令規則を使用しているのでHTMLとは
少し違った属性名となっている。<br>
例えば`class => className`に置き換わっています。

###Babelの挙動

BabelはJSXを``React.createElement()``の呼び出しに変換する。
React.createElement()はバグの混入を防止する。

##参考文献
* [React](https://reactjs.org/)
* [うつだってWebと英語で生きていける](https://mittsu-blog.com/learn-react-on-0base-what-is-jsx)
* [インジェクション攻撃](https://tech.nikkeibp.co.jp/it/atcl/keyword/14/260922/021000019/)
Windowsでの文字変換をmacみたいにする方法

日本語キーボードの「無変換」キーで半角英数入力、「変換」キーでひらがな入力にする方法です。
# 1. Google 日本語入力をインストールする
こちらからインストールしてください。
[Google 日本語入力](https://www.google.co.jp/ime/)

初期設定を聞かれますが、問題がなければこのままで良いでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309128/155bf1a4-dd29-fe1f-72ca-cae92982124a.png)

# 2. キーバインドの設定
文字入力モードになるとタスクバーに文字入力のアイコンが出てくるので、これを右クリック。（ブラウザの検索窓をクリックすれば出てきます。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309128/544b1290-3772-c3b2-6a9e-ef91f6c1b5a7.png)
「プロパティ」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309128/39b2f75a-16b4-0a5f-79f8-e8ee21a0abd3.png)
「一般」→「キー設定」→「編集」でキーバインドを設定していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309128/aefd1dfe-78dd-e8eb-c859-6d7147a6a43a.png)
「入力キー」でソートして「Muhenkan」を探して、「入力文字なし」のモードに対してコマンドを「IME無効化」に設定します。（コマンドはダブルクリックで変更できます。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309128/e6ba9188-e62a-54e3-a28d-10866fd68f94.png)
他の「Muhenkan」のモードはコマンドを「半角英数に入力切替」に設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309128/961728cb-25f3-2021-0d27-a01591b6d1a2.png)
次は「Henkan」を探して、すべてのモードに対してコマンドを「ひらがなに入力切替」に設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309128/33043f13-69b4-94fb-6dac-b4fe6d0d7487.png)
これで設定は完了です！「OK」ボタン→「適用」ボタンを押して設定を適用させましょう。

# 補足
下記リンクのようにWindows標準装備のMicrosoft IMEでも設定できるのですが、この方法ではSlack等の一部のソフトで変換が効きませんでした😭
https://qiita.com/Yuwji/items/8ffd17606ba7833ec7ca
SQL文を作成に必ず知っておくべき項目

#SQL文のチューニング

具体的な解決策までは書いてませんが、チューニングのヒントを簡単に整理しました。

#### オプティマイザモードがコストベースモードであるか、ルールベースのモードであるか確認しておく。

#### 数値は数値型のタイプで、文字は文字型のタイプで比較する。
phpなどのインタープリタ言語の経験が主なメンバーに注意させていますが、書いたSQLを見ると、よくデータ型を無視して比較します。オプティマイザが陰でキャスト処理してくれていることをお忘れなく。このくらい別にいいでしょーと言われますが、大量データになると悪魔に出会います。

#### WHERE句に比較条件にインデックスを利用する場合は、インデックスの列を記述する。
当たり前なことですが、コードレビューで以外と見つかります。

#### 複数の列がインデックス一つで指定された場合、WHERE句にすべてを記述する。

#### 複数の列がインデックス一つで指定された場合、前方の列を指定してインデックス範囲を狭める。
複合インデックスの使用では気をつけましょう。

#### インデックスになる列は型など変更しない。
ここまでくると、設計の見直しになります。

#### インデックス列にNULL値を使用しない。
NULLはブラックホールと思えば、理解が早いです。NULLに触れたレコードは消える！
あれこれ悩まずに「NOT NULLと規定値」に決めましょう。統計関連テーブルでは特に注意です。

#### 否定形で指定する場合にはインデックスを使わない。できるだけ否定形を使わない。
否定形を使わないといけない場合は手を止めて設計を疑いましょう。

#### ORを使用すると、インデックスが使われないことがある。
ORはより神経を立てて使用します。SQLは絞る（AND）感覚で書きたいです。

#### 不必要にDUALテーブルを使用しない。(Oracle)

#### インデックスのデータを20％以上参照すると予想される場合、インデックススキャンを避ける。
実行プランで「スキャン」が見えたらアウト！テーブルスキャンが見えらたさらにアウト！

#### 不必要にDBMSで提供された関数（SUM、SGIN、DECODE、NVLなど）を使用しない。

#### インデックス列にLIKEで比較する場合は、必ず後ろに比較演算子（%）を位置する。前方に位置するとインデックスを使用しなくなる。
大量データの検索では絶対に禁止です。開発環境では引っかからなくリリースした途端、痛い目にあうパータンです。
あいまい検索のため、使わざるをえない場合もあるが、覚悟の上です。

#### ヒントを適切に使用する。
実行プランを熟知してから使いましょう。

#### アクセスパスの優先順位を知っているべきである。
チューニングの基本項目です。

1.ROWIDによる単一ロー
2.クラスタ結合による単一ロー
3.UNIQUEかPKを持つハッシュ・クラスタのキーによる単一ロー
4.UNIQUEかPKによる単一ロー
5.クラスタ結合
6.ハッシュ・クラスタのキー
7.インデックスクラスタキー
8.複合カラムインデックス
9.単一の列のインデックス
10.インデックスが設定された列で指定範囲の検索
11.インデックスが設定された列で指定なし範囲の検索
12.ソート - マージ結合
13.インデックスが設定された列でMAXまたはMIN
14.インデックスが設定された列でORDER BY
15.フルテーブルスキャン

#メモ
オプティマイザが段々賢くなりいつかはチューニングは人間から離れるのでしょうか・・・
しかし、何であっても基礎は底力に間違いありません。
window.onloadは同じページで複数回使用することができないのでaddEventListenerを使用する必要がある。

参考記事
https://www.sejuku.net/blog/19754


JavaScriptでwindow.onloadを使用する機会があったのですが同じページで二回使ったらものの見事に動きませんでした。


    function init() {
          imgs = new Array(3);
        imgs[0] = new Image(250, 207);
        imgs[0].src =  "{% static "javascript/images/pic0.jpg" %}"
        imgs[1] = new Image(250, 207);
        imgs[1].src =  "{% static "javascript/images/pic1.jpg" %}"
        imgs[2] = new Image(250, 207);
        imgs[2].src =  "{% static "javascript/images/pic2.jpg" %}"
    }
    window.onload = init;


このwindow.onloadは複数使うと一番最後に記載したものだけが反映されます。
というか関数を代入するという構成になっているから関数を代入するたびにその前に代入したものが消えてしまってるんでしょうね。
<br>

というわけでこれはこう書き換えます。
```

    window.addEventListener("load",function() {
    	  imgs = new Array(3);
        imgs[0] = new Image(250, 207);
        imgs[0].src =  "{% static "javascript/images/pic0.jpg" %}"
        imgs[1] = new Image(250, 207);
        imgs[1].src =  "{% static "javascript/images/pic1.jpg" %}"
        imgs[2] = new Image(250, 207);
        imgs[2].src =  "{% static "javascript/images/pic2.jpg" %}"
    }, false)
<br>

   function init()を削除して、window.addEventListener("load",function() に書き換えます。無名関数になっていますね。
そして最後に, false)を加えます。
無名関数になって代入もしようがないのでwindow.onload = init;も当然削除ですね。
<br>
window.onloadを複数回使いたいときはこのような書き方ならばOK。
試してみてください。

補足
コメントをいただいたのでコードを修正しました。

```
window.addEventListener("load",function() 
```
を

```
document.addEventListener('DOMContentLoaded', function()
```



参考記事
https://noumenon-th.net/programming/2017/06/11/domcontentloaded/


<br>
実は画像を処理するコードだったのですがこれで特に問題なく動きました。
ありがとうございます！！！
プログラミング学習記録83〜JavaScriptでストップウォッチを作ろう〜

##今日やったこと
- ドットインストール「JavaScriptでストップウォッチを作ろう」

ドットインストール「JavaScriptでストップウォッチを作ろう」を見ながら、ストップウォッチを作ってみました。

最初に完成版のコードをコピペしてから、講義を進めながら完成版のコードにコメントアウトで解説を書いていく勉強法が自分にあってるなと感じました。

この進め方で進めていくのは今日で2回目ですが、今までやってきた中で一番しっくりきます。

基礎文法をさらっとやったらドットインストールでやるくらいのアプリなら大体理解できるようになっています。

なので、動画を見ながらコードを写経していくよりも書かれたコードの意味を日本語に翻訳してメモしていく方が知識が整理される気がします。

明日も同じ要領で三択クイズを作っていきたいと思います。

おわり
Courseraの動画ファイルに日本語字幕を表示する方法

[1] VLC media playerのダウンロード
[2] Courselaからmp4と字幕ファイル(赤枠部)をダウンロード

<img width="960" alt="qiita.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383255/720ef2dc-df2d-96ab-8b36-c418329f026d.jpeg">

[3] mp4をVLC media playerで開く
[4] 字幕タブから「字幕ファイルの追加」を選択して、[2]でダウンロードした字幕ファイルを選択

<img width="960" alt="無題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383255/12eb1c74-35f1-9987-9b7f-43670faf9d50.png">
awsのec2に踏み台経由でssh接続するためのconfigの作成

# はじめに

aws上のec2が複数存在する場合には踏み台となるサーバのみにグローバルIPを設定して、他は踏み台経由でログインするようにしているところが多いかと思います。

その際に、サーバがたくさんあるとローカルIPを調べたりするのが大変です。
なので、aws-cliを使って一気に config ファイルを作成することができたので共有します。

# 環境

- OS ubuntu 18.04(Windows10 WSL上)
- SSHのバージョン　OpenSSH_7.6p1 Ubuntu-4ubuntu0.3, OpenSSL 1.0.2n  7 Dec 2017

# 前提

- aws-cliインストールと設定済み
- 踏み台サーバ用の秘密鍵ファイルとその他のサーバ用の秘密鍵ファイルを作成済み。（ログインできるところまで確認済みのほうがよい）
- jqをインストールしてあること。

# ファイルの作成

（注意）作成するファイルのモードはすべて600です。（ディレクトリは700)
この後作成するファイルも同様です。

## .ssh/config作成

configファイルでIncludeが利用できるようになったので、まずはデフォルトのみのconfigファイルを作成します。
configファイルの設定は後勝ちなので大事なことは最後に記述しましょう。

```config:.ssh/config
Include conf.d/*

Host *
  ServerAliveInterval 300
  AddKeysToAgent yes
  StrictHostKeyChecking no
```

同時に.ssh/conf.dのディレクトリも作成します。

## 踏み台用のconfigファイル作成

以下のように作成します。一行目以外は自分の環境に合わせて変更してください。

```config:.ssh/conf.d/bastion.conf
Host bastion
  HostName bastion.hogehoge.com
  User bastion
  IdentityFile ~/.ssh/bastion.pem
```

できたら接続確認をしましょう。

```sh:
$ sh bastion
Last login: xxx from xxx.xxx.xxx.xxx

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/xxxx.xx-release-notes/
$ 
```

無事にログインできたら、各サーバの設定を行います。

## いったんひとつのサーバへの接続確認

awsのコンソールでインスタンス名とプライベートIPを確認して以下のようなファイルを作成します。

```config:.ssh/conf.d/test1.conf
Host aws_test1
  HostName xxx.xxx.xxx.xxx
  User ec2-user
  IdentityFile ~/.ssh/ec2-user.pem
  ProxyCommand ssh -W %h:%p bastion
```

ポイントはProxyCommandですね。

ファイルを作成したら、ログインできるか確認してみましょう。

## 共通部分の切り出し

先ほどの設定でうまく接続できたら、共通部分を切り出します。

```config:.ssh/conf.d/aws_common.conf
Host aws_*
  User ec2-user
  IdentityFile ~/.ssh/ec2-user.pem
  ProxyCommand ssh -W %h:%p bastion
```

Hostの指定は共通の接頭辞（今回はaws_）を付けてください。

## 各インスタンスごとの設定ファイル作成

ここが今回のポイントです。

以下のコマンドですべてのインスタンスに対する設定ファイルができます。

```sh:
aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | "Host aws_" + .Tags[].Value + "\n HostName " + .PrivateIpAddress + "\n"' > ~/.ssh/conf.d/aws_all.conf
```

ファイルを作成したら、ログインできるか試してみましょう。

# Windows10の場合

Windows10にも標準でOpenSSHが入っています。（最近知りました。もう*termとかいらないですね。）

C:\Users\ユーザ名\.ssh にファイルを作成すれば同様のことが可能です。
ただし、以下の2点に注意する必要があります。

- jqをインストールしたりが面倒 → なので、WSLを利用するほうが楽かと思います。
- ProxyCommand sshがエラーになるため、ProxyCommand C:\Windows\System32\OpenSSH\ssh.exeと書きましょう。

# 終わりに

いい感じのconfigファイルができたら社内で共有しておくとありがたがられるかと思います。
aws-cliとjqの組み合わせはかなり強力なので、どんどん活用しましょう！！

# 参考

- [`Include`キーワードで`ssh_config`を分割できるようになった件](https://qiita.com/masa0x80/items/ecb692ad93f7d06a07b0)
- [AWS CLIを使ってEC2インスタンスの情報を取得する](https://qiita.com/toshiro3/items/37821bdcc50c8b6d06dc)
SQL【書き順と実行の順序】

#書き順
SELECT
FROM JOIN
ON
WHERE
GROUPBY
HAVING
ORDERBY



#実行の順序
FROM（どのテーブルかを選ぶ）
ON（テーブル同士がどのカラムで結合するかを選ぶ）
JOIN（結合するテーブルを選ぶ）
WHERE（選択する行を選ぶ）
GROUPBY（行ごとにまとめる。どの列でまとめるかを決める）
HAVING（GROUPBYでまとめたもののうち条件に合うものを抽出する）
SELECT（結果に出すカラムを選ぶ）
DISTINCT（重複をなくして結果を出す）
ORDERBY（順番を決める。どのカラムを昇順or降順にするか）
TOP（LIMIT）（上位何件を結果として出すか）

#SQL文の書き方備忘録
##複数のテーブルを結合するときの書き方
**SELECT** カラム名
**FROM** テーブル名1
**JOIN** テーブル名2
  **ON** テーブル名1.結合キー列 = テーブル名2.結合キー列
**JOIN** テーブル名3
  **ON*** テーブル名X.結合キー列 = テーブル名3.結合キー列

#最後に+参考
railsを勉強していてモデルを操作する際になにが起きてるか気になったので調べました。
https://dev.classmethod.jp/server-side/db/difference-where-and-having/ (HAVINGとWHEREの違い)
https://qiita.com/suzukito/items/edcd00e680186f2930a8　（評価順序）
Nuxt.js V2環境でモジュールモードで作り直してみた

# 概要
Nuxt.js v2でのモジュールモードでaxiosを使ったシンプルなサンプルがないので作ってみました。v3でクラシックモードは廃止になりますし。

モジュールモードはここを参考。
https://qiita.com/y-miine/items/028c73aa3f87e983ed4c
サンプルはここのお天気サンプルをモジュールモードに書き直してみました。
https://qiita.com/kawa64372358/items/02348536eea1881676e8

詳細はコードのコメントでわかると思います。

# コード
モジュールモードではexportだけでstoreを記述するのがポイント。
store/index.js

```

import axios from 'axios';

//データを定義
export const state = () => ({//stateは必須
    weather:null    //データ
});

//データの更新系を定義。関数で定義
export const mutations = {
    updateWeather (state, weather) {
        state.weather = weather;//データの更新
    }
}
//外部からのコールイベントを定義。関数で定義
export const actions = {
    //通信
    async fetchWeather({commit}){
        const res = await axios.get(`http://weather.livedoor.com/forecast/webservice/json/v1?city=400040`).catch((err) => {
            throw new Error(err);
        });
      
        // レスポンスがコンソールに表示
        console.log(res.data);
        commit('updateWeather', res.data);//mutations経由でデータを更新
    }
}

```

components/Pages/ForcastCard/index.vue

```
<template>
  <div class="forcast-list">
    <h2 class="forcast-list__title">{{ forecast.dateLabel }}</h2>
    <dl>
      <dt class="forcast-list__telop">{{ forecast.telop }}</dt>
      <dt>
        <img
          v-show="forecast.image.url"
          :src="forecast.image.url"
          class="forcast-list__image"
          alt="forcast.image.title">
      </dt>
    </dl>
  </div>
</template>

<script>
export default {
  //親のvueから値をpropsで受け取る
  props: {
    forecast: {
      type: Object,
      required: true
    }
  }
};
</script>

```

pages/index.vue

```
<template>
  <section class="weather">
    <h1 class="weather__title">{{weather.title}}</h1>
    <ForcastCard
      v-for="(forecast, i) in weather.forecasts"
      :forecast="forecast"
      :key="`weather__forcasts-key-${i}`"/>
  </section>
</template>

<script>

//自作コンポーネント取り込み
import ForcastCard from '~/components/Pages/ForcastCard';

//バインディング機能
import { mapState, mapMutations, mapActions } from 'vuex'

export default {
  //コンポーネントを定義
  components: {
    ForcastCard
  },
  //キャッシュされる計算を定義。おもにバインディングで使う
  computed: {
    //バインディングの情報をここで配列で指定。バインディングがなければ$store.state.xとかでアクセス可能。
    ...mapState(['weather']),
    ...mapActions(['fetchWeather'])
  },
  //通信実行。表示で即時実行
  async asyncData({ store, params }) {
    await store.dispatch('fetchWeather');
  }
};
</script>

```
Cognos Analytics 11.1.2 のリリース

#Cognos Analytics 11.1.2 のリリース
2019/4末にCognos Analytics 11.1.2がリリースされました。

マニュアルに変更点がのってますので、主たる変更点を紹介します。
https://www.ibm.com/support/knowledgecenter/SSEP7J_11.1.0/com.ibm.swg.ba.cognos.ca_new.doc/c_ca_nf_11_1_2_container.html

#Cognos に Jupyter Notebook が取り込まれた
Jupyter Notebookとは、Pythonなどの言語のプログラムを実行し結果を記録できるツールです。
**jupyter Notebookの紹介**
https://qiita.com/horankey_jet_city/items/f29c3477a5099f12cb18

このJupyter Notebookの機能そのものが、Cognosに組み込まれています。
新規メニューから、Jupyter Notebookの機能が起動され、画面のイメージで、Cognosポータル上のアップロードデータ等のデータエントリーを取り込み、Python等のスクリプトで高度分析を行い、結果をデータセットとして保存し、ダッシュボードやレポート等のソースデータとして使用する事ができるようになりました。
![JupyterNotebook.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/4cf0e29d-1580-57f2-99c5-1619c9dffe4e.jpeg)

Jupyter Notebookのスクリプトのスケジュール実行や、Jupyter Notebookで作成したファイルをCognosに取り込む事も可能です。

Jupyter Notebook機能のセットアップ手順はマニュアルを参照ください。
**Installing IBM Cognos Analytics for Jupyter Notebook Server**
https://www.ibm.com/support/knowledgecenter/SSEP7J_11.1.0/com.ibm.swg.ba.cognos.inst_cr_winux.doc/c_inst_jupyter.html

#アップロードファイルをチーム・コンテンツに直接保存できるようになった
アップロードファイルは、これまでマイ・コンテンツに保存されていましたが、直接チーム・コンテンツに保存できるようになりました。

#データ・モジュールの機能追加
データ・モジュールでダイアグラムを見る際に、フォーカスや自動配置の機能が使えるようになったようです。
また、計算アイテムの作成で、集計後に計算を行う指定ができるようになりました。
https://www.ibm.com/support/knowledgecenter/SSEP7J_11.1.0/com.ibm.swg.ba.cognos.ca_new.doc/c_ca_nf_11_1_2_modeling.html

#ダッシュボードの機能追加
ダッシュボードでのデータアイテムのソート順を、「カスタム」つまり自由に並び方を指定できる機能が追加されました。
https://www.ibm.com/support/knowledgecenter/SSEP7J_11.1.0/com.ibm.swg.ba.cognos.ug_ca_dshb.doc/t_create_custom_sort.html

データアイテム内の特定のデータを自由にグループ化できる機能が追加されました。
https://www.ibm.com/support/knowledgecenter/SSEP7J_11.1.0/com.ibm.swg.ba.cognos.ug_ca_dshb.doc/t_create_custom_group.html

簡単ですが11.1.2のリリースと新機能の概要のご紹介でした。
expoでreact-native-debuggerを使う(reduxのデバック)

# はじめに
expoを使ってreact-nativeで開発している際のデバック方法でreact-native-debuggerがあります。実機で動作を確認する際のデバック設定が少し面倒だったためまとめます。reduxのデバックがメインです。
# アプリのインストール
まず最初にreact-native-debuggerのアプリを[ここから](https://github.com/jhen0409/react-native-debugger/releases)インストールします。
# node_modulesの編集
次にnode_modules/react-native/Libraries/Core/Devtools/setupDevtools.jsを開いて下さい。<img width="1075" alt="スクリーンショット 2019-05-10 18.19.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314314/98234c84-a717-eecd-553a-bcd505a68f69.png">
52行目のhostの部分を編集します。Your IPのところは今繋がっているIPアドレスを入れて下さい。Macの場合はIPアドレスは、システム環境設定→ネットワーク→状況のところの「IPアドレスhogehogeが設定されています。」のところにあります。編集後↓
<img width="1075" alt="スクリーンショット 2019-05-10 18.23.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314314/03c07d74-7ee3-5f81-08ad-a58d6b231a5b.png">
# App.jsの編集
App.jsをこんな感じにします。
<img width="935" alt="スクリーンショット 2019-05-10 18.41.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314314/a74a58b3-9894-d68a-67a5-c0932e91e1fd.png">
ポイントは

```
const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
```

です。最初はこれがなくてうまくいきませんでした。
設定はこれで終わりです。

# 手順
- 　``` http://localhost:<port>/debugger-ui```を閉じて下さい
- 　react-native-debuggerのアプリを起動して下さい
- 　スマホの方のDebug JS Remotelyを有効にして下さい
- 　```REACT_DEBUGGER="unset ELECTRON_RUN_AS_NODE && open -g 'rndebugger://set-debugger-loc?port=19001' ||" npm start```でプロジェクトを起動して下さい。

# 参考、出典など
- https://github.com/jhen0409/react-native-debugger/blob/master/docs/getting-started.md
- https://stackoverflow.com/questions/52946133/unable-to-use-react-native-debugger-after-updating-react-native/52953017#52953017
Amazon Connectで保存された音声データをIBM SpeechToTextで文字起こしする

# やりたいこと
顧客とエージェントが通話した音声データを文字起こしする。

AmazonConnect → S3 → 文字起こし(Lambda) → S3

# 前準備
- Amazon Connectで`通話記録動作の設定`しS3に音声データが保存される様にしておく。
- IBM Speech to Textを使用出来る様にしておく(https://www.ibm.com/watson/jp-ja/developercloud/speech-to-text.html)

# やり方
```src/sample.ts
import {Handler} from "aws-lambda";
import {S3} from "aws-sdk"

export const handler: Handler = async (event: any) => {
    const s3 = new S3Service(new S3());

    // 一時作業ディレクトリを使用する
    let fs = require('fs');
    const wavPath = '/tmp/' + (new Date()).getTime() + '.wav';

    for (let record of event.Records) {
        // AmazonConnectのデフォルト設定だとURLエンコードされているため、URLデコードする
        let key = decodeURIComponent(record.s3.object.key);
        const bucketName = record.s3.bucket.name;

        const object = await s3.get(bucketName, key);
        // 一時作業ディレクトリに.WAVファイルを保存する
        fs.writeFile(wavPath, object.Body, 'binary', function (e) {
            if (e) {
                console.error(e);
                return;
            }
        });

        // SpeechToTextの設定
        const SpeechToTextV1 = require('watson-developer-cloud/speech-to-text/v1');
        const speechToText = new SpeechToTextV1({
            iam_apikey: 'XXXXXXXXXXXXXXX', // TODO IBM_APIKEYを置き換える
            url: 'https://gateway-tok.watsonplatform.net/speech-to-text/api'
        });
        let recognizeParams = {
            audio: fs.createReadStream(wavPath),
            model: 'ja-JP_NarrowbandModel',
            content_type: 'audio/wav'
        };

        // SpeechToTextを呼び出して文字起こししたデータをS3に保存する
        const s2tJson = await speechToText.recognize(recognizeParams);
        key = key.replace('.wav', '');
        await s3.put(bucketName, key + '_s2t.json', JSON.stringify(s2tJson));
    }
    return {};
};

class S3Service {
    constructor(private s3: S3) {
    }

    async get(bucketName, key) {
        const params = {
            Bucket: bucketName,
            Key: key
        };
        return await this.s3.getObject(params).promise();
    }

    async put(bucketName, key, body) {
        const params = {
            Bucket: bucketName,
            Key: key,
            Body: body,
        };
        return await this.s3.putObject(params).promise();
    }
}
```

serverless.ymlは一部抜粋
bucket名を`AmazonConnect`で音声データが保存されるbucket名に変更すること
S3をトリガーとするため、`sls deploy`の後、`sls s3deploy`を行うこと

```serverless.yml
plugins:
  - serverless-plugin-existing-s3

functions:
  speechToText:
    handler: src/sample.handler
    events:
      - existingS3:
          bucket: connect-XXXXXXXXXXXXXX
          events:
            - s3:ObjectCreated:*
          rules:
            - suffix: .wav
```

# おまけ
`Amazon Kinesis Video Streams`を使用すれば問い合わせフロー内の顧客音声も.WAVファイルに出来るので、組み合わせると文字起こし出来る範囲が広がります。

(2019/11/25)Amazon Transcribeが日本語対応された為、AWS内で文字起こしを完結出来そうですね。
railsにテンプレートエンジンslimを導入する方法。

#動作環境 
OS: centos7
ruby2.4.1
rails5.2.3
#導入方法
まず、railsのディレクトリにあるGemfileに次のコードを加えます。
 
```ruby:Gemfile
...
gem 'slim-rails'
gem 'html2slim'
```
※`slim-rails`はrails上でslimを利用するためのgemで、`html2slim`はERB形式のファイルをslim形式に変換してくれるgemです。

上記のコードを追加したら、gemの追加を反映させるためにターミナル上で`bundler`を実行します。

```ruby:
bundle
```
これで、rails上でslimを利用することが出来ます。

ただ、現時点では`app/views/layouts`ディレクトリにERB形式のファイルが存在するので、このファイルをslim形式に変更しておいた方がいいです。

ファイル形式の変更は、次のコマンドをターミナル上で実行すると完了します。※先ほどインストールした`html2slim`が変更を助けてくれます。

```ruby:
bundle exec erb2slim app/view/layouts/ --delete
```

# 参考書籍

[現場で使える Ruby on Rails 5速習実践ガイド](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Ruby-Rails-5%E9%80%9F%E7%BF%92%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-%E5%A4%A7%E5%A0%B4%E5%AF%A7%E5%AD%90/dp/4839962227)
【Python】randomってどのくらいrandomなの

# はじめに
randomモジュールを使っていて、ふと「このrandomって、どのくらいランダムなんだろう」と思ったのでmatplotlibを使って棒グラフで表してみました。
因みに、どのくらいランダムなんだろうというのはどの程度のばらつきや偏りがあるのかという話です。
大したものではないので、コードの簡単な説明と結果のベタ張りだけにします。気になった方はコピペして動かしてみてください。

# コード
0~9の乱数を10,000個生成してそれぞれの乱数が何個ずつ出たかを数えます。
それを4回繰り返して結果を見ます。
4回繰り返したのは、結果を4分割にして表示させたかっただけで他意はありません。

```python:rangene.py
import random
import matplotlib.pyplot as plt


def gener(min_v, max_v, length, sort=False, sortType=False):
    '''
    gener(min_v, max_v, length, sort=False,sortType=False):
    min_v ~ max_vの乱数をlength個生成する。
    default: sort=False デフォルトはソートは行わない。
    default: sortType=False ソートの順。デフォルトは小さい順(昇順)

    exit: q
    '''
    rand = []
    keys = [i for i in range(min_v, max_v+1)]
    values = []
    for i in range(length):
        rand.append(random.randint(min_v, max_v))
    for i in range(max_v+1):
        values.append(rand.count(i))
    dic = dict(zip(keys, values))
    if sort is True:
        occurrence_num = sorted(
                dic.items(),
                key=lambda x: x[1],
                reverse=sortType)
        dic.clear()
        dic.update(occurrence_num)
        return dic
    return dic


# title:     Generate [length] random numbers from [min_v] to [max_v]
# xlabel:    randint()
# ylabel:    count()
for i in range(1, 5):
    dic = gener(0, 9, 10000, sort=True, sortType=True)
    left = [str(k) for k, v in dic.items()]
    height = [v for k, v in dic.items()]
    label = left
    print('------------------------------------------------------------------')
    print(i, '回目の実行結果')
    print(dic)
    plt.subplot(2, 2, i)
    plt.bar(left, height, tick_label=label)
    plt.grid(True, axis='y', linestyle='dashed', zorder=1)
plt.show()
print('------------------------------------------------------------------')
```

# 結果
![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400994/ef6b8f9e-b0f8-a63b-1e38-a2506ba470d7.png)

# 考察
多少の誤差はありましたが、ほぼ偏りはないと言えます。
以上のことを踏まえて、乃木坂のくじを引きに行きました。
くじを箱から引く時は奥の方から取ろうなどは考えずに上から適当に取ったところ、一等のポスター賞が当たりました。つまり、そういうことだと思います。(どういうこと)
Node-REDでSesame Webhookを使う

# はじめに
2019年5月10日にSesame Webhookが公開されました。
今までは鍵の情報をpushで知るにはIFTTTを使うしかなかったのが
Webhookで受け取ることが出来ます。
オートロックなども比較的簡単に作れますね。

受け取れる情報が、Device IDとlockedだけなのは少し残念でした。
DASHBOARDのHISTORYのようにAuto Lock, Manual Lock, APIの区別を
付けられるようになればもっと細かいオートロックの仕組みなども
作れるようになったのになと思っています。

# 必要なもの
- SESAME mini
- Node-REDの環境

# 参考文献
- Sesame Webhookのドキュメント https://docs.candyhouse.co/#sesame-webhook

# 手順１．Webhookの有効化
CANDY HOUSEのダッシュボードにログインして
下の方のAPI settingsからSEND CODEを押して
送られてきた認証コードを入力してConfirm。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257268/e6f06d11-8e20-7ef8-a323-ebcf5487d01a.png)
CANDY HOUSEダッシュボード
https://my.candyhouse.co

Servicesの一番下のWebhookのEDITをクリックして
POSTに変更した後に、Webhookを受け取るURLを入力します。

# 手順２．フローの作成
inputノードのhttp、outputノードのhttp responseとDebugを配置してつなげます。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257268/31f90a04-ef00-7207-9dfc-5aceab77e9b1.png)![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257268/0e13b9a1-67c2-0b5b-2680-e487b797e0b5.png)![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257268/c171d0e8-1281-715d-f3fa-860eb105a4a9.png)

httpノードのnode propertyで、MethodをPOST、
URLを手順１で指定したURLになるように設定します。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257268/0cd321ca-b356-bacf-9ae8-68427830b5dc.png)

これで鍵が開閉されると、Debugノードに通知が届くようになります。

```
{"device_id":"********-****-****-****-************","locked":true}
```

# 手順３．オートロックを作る
セサミの公式アプリではオートロックは４分まで設定できます。
しかしちょっと郵便受けに荷物を取りに行ったりしていると
４分というのは短すぎることがあります。
ここではオートロックのノードを作成します。

手順２で作成したhttpノードにSwitchノードをつなげて
propertyにmsg.payload.locked、条件にis falseを指定します。
lockedがfalseとなった時、つまり解錠されたときにフローが進みます。

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257268/a8a3aba5-4543-a90f-9346-dc447aa5ea39.png)

SwitchにDelayノードを接続して、オートロックまでの時間を設定します。
まずはテストとして５秒などを設定してちゃんと動作するか確認します。

そしてDelayノードに解錠のノードを接続します。
解錠のノードの作り方は[「Node-REDでSesame API v3を使う」](https://qiita.com/kamijyo/items/a0517a23d997902db749)の[手順４](https://qiita.com/kamijyo/items/a0517a23d997902db749#%E6%89%8B%E9%A0%864-%E5%AE%9F%E8%A1%8C%E7%B5%90%E6%9E%9C%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B%E3%83%95%E3%83%AD%E3%83%BC)で解説しています。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257268/1f163a23-c931-9f6c-0e46-28e36dc227be.png)

これで鍵が開くと５秒後に閉まるオートロックが完成しました。
実際にはWebhookやAPIの作動までの時間などのラグがあるため
もう少し時間がかかると思います。

Delayの時間を変えれば自由な時間でオートロックをすることが出来ます。

# おわりに
記事作成時点(2019年5月10日19時)ではアプリや手動での開閉など
API以外を使用した鍵の開閉ではWebhookが作動していないようです。

Webhookが動作しないと本記事のオートロックも作動しないので
鍵が閉まっていると思ったら閉まっていないこともありえます。

しっかりと動作確認をして自分の用途にあわせた設定をしてください。
Pythonの依存ライブラリをプロジェクトごとに管理し、別マシンでも一括インストールできるようにする方法

#記事概要
Pythonでtensorflowを実行するのに、サンプルによってバージョンを切り替える必要が出てきたのと、複数の環境で実行しようと思ったときに毎回必要ライブラリを一つずつインストールするのがかなり面倒だと感じた。
nodeJSのnpmみたいに個別にライブラリの管理ができるようにしたいと考え調べてみたらところ、venvを使えば実現できそうだったのでメモ。


# 仮想環境の作成
プロジェクト個別にモジュールを管理するにはvenvと呼ばれる仮想環境を作成する必要がある。仮想環境を作成するフォルダに移動し、以下のコマンドを入力することで環境を作ることができる。

```shell
#コマンドフォーマット
python -m venv [仮想環境名]
#コマンド例
python -m venv tutorial-env
```

#### 実行時エラーが出た時の対処方法
上記コマンドを実行したところ、以下のようなエラーが出てしまいました。



```:コマンド実行時のエラー
$ python -m venv tutorial-env
Error: [Errno 2] No such file or directory: 'C:\\Program Files\\Python37\\lib\\venv\\scripts\\nt\\python_d.exe'
```
原因を調べたところ、以下のコピー元ディレクトリからコピー先ディレクトリに、対象ファイルをコピーすることで問題を解決することができた。
（この問題はすべての環境で発生するのかどうかは不明。まずはそのままコマンド実行し、エラーが出たら対応してください。）

```:コピー元ディレクトリ  
C:\Program Files\Python37
```

```:コピー先ディレクトリ  
C:\Program Files\Python37\Lib\venv\scripts\nt`
```

コピー対象ファイル
1) python_d.exe
2) python_d.pdb
3) pythonw_d.exe
4) pythonw_d.pdb


## 仮想環境の起動
以下のコマンドを実行することで仮想環境を起動することができます。これを実行した後にpipコマンドを実行すると仮想環境にライブラリが追加され、pythonコマンドを実行すると、仮想環境に登録されているライブラリのみが利用されます。

```:windows
tutorial-env\Scripts\activate.bat
```


```shell:linux_or_mac
source tutorial-env/bin/activate
```

実行が成功すると、以下のようにコマンドラインの先頭に（環境名）が追加される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/f6e342d8-6739-78b2-628d-1ecd2ab2d547.png)

## 確認方法
コマンドライン上に仮想環境名が以下のように表示されている状態で``pip install numpy``を実行してみる。

```:コマンドライン
(tutorial-env) D:\git-repo\venvtest>
```

コマンド完了後、tutorial-envの配下にnumpyフォルダが作成されていればOK。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/f20681a5-b392-77da-a6b8-81b8a3b51113.png)

## 現在インストールされているパッケージの確認
以下のコマンドで、現在の環境にインストールされているライブラリの一覧を確認できる。

```:コマンド
pip list
```

```:実行結果
Package           Version
----------------- -------
astroid           2.2.5
colorama          0.4.1
isort             4.3.18
lazy-object-proxy 1.3.1
mccabe            0.6.1
pip               19.1.1
pylint            2.3.1
setuptools        40.8.0
typed-ast         1.3.5
wrapt             1.11.1
```

## インストールされているパッケージ一覧を出力する
以下のコマンドで現在の環境にインストールされているライブラリの情報をテキストファイルをに出力できる。複数人で開発をする時や自分の作ったプログラムを外部公開する時などに便利。


```:コマンド
pip freeze > reqiurements.txt
```
## 出力したパッケージ一覧にあるパッケージを一括インストールする
依存ライブラリを一括インストールするときは、以下の様にfreezeコマンドで出力したファイルを-rの後に記述する。
```:コマンド
pip install -r requirements.txt
```

```:実行結果
(tutorial-env) D:\git-repo\venvtest>pip install -r requirement.txt
Collecting joblib==0.13.2 (from -r requirement.txt (line 1))
  Using cached 
--省略--
repo\venvtest\tutorial-env\lib\site-packages (from astroid<3,>=2.2.0->pylint==2.3.1->-r requirement.txt (line 5)) (1.4.0)
Installing collected packages: joblib, numpy, scipy, scikit-learn, pylint
Successfully installed joblib-0.13.2 numpy-1.16.3 pylint-2.3.1 scikit-learn-0.21.0 scipy-1.2.1
```


##参照ページ
- pythonドキュメント  
https://docs.python.org/3/tutorial/venv.html
- venvコマンド実行時エラーの対応方法  
https://stackoverflow.com/questions/55380296/how-to-fix-error-errno-2-no-such-file-or-directory-c-program-files-pytho
#vim のコマンド履歴を前方一致でフィルタリングするのはこんなに簡単  (何か文字入力してから上下キー)  #初心者 向け )

`:` とか `/` とか `/a` とか `/alice` とか

そもそも入力した文字でフィルタリングしてくれるじゃん！

知らなかった！

( `:` とか `/` とか モードごとに履歴をたどってくれるのは知っていたけど、単純に文字を前方一致でフィルタしてくれているのは初めて意識した )

# 以上。

![image](https://user-images.githubusercontent.com/13635059/57511267-d7152100-7343-11e9-8b14-3a95908cf309.png)


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1765








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->