OmniAICreator/Qiita-1.07M huggingface dataset:
ffmpeg NVENC についての（個人的な）評価とまとめ

#目的
興味深い資料を２つ見つけました。

[Video Encode and Decode GPU Support Matrix](https://developer.nvidia.com/video-encode-decode-gpu-support-matrix)
Nvidia製GPUのNVENC対応状況が記載されている。
![Screenshot from 2019-06-26 23-52-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253609/ec63c49b-1ecc-eeb1-f5f9-06b24c81eb8b.png)
ここ、
NVENC（ハードウェアエンコーダ）がチップ上にいくつあるか表記されている。
GTX製品は大半が１である。（まぁ２でもいいんだけど）
つまり、CUDAコアの数に左右されずGPU上に１つ存在し、
その性能は等価であると考えられる。

[Nvidia NVENC](https://en.wikipedia.org/wiki/Nvidia_NVENC)
ここにNVENCについてwikiが存在する。

NVENCにも世代があり、現在第６世代（Turing）であることがわかる（初めて知った）。
つまり、同世代のNVENCならその性能は等価であると考えられる（２回め）。

エンコしかしないのに高価なGPU買いたくないし・・・
検証を行った。

#検証環境

webmファイルを用意したが、相性が良くなかったのでCPUでmp4へ変換しておく。
各エンコに使用したコマンドは以下

＃CPU enc
ffmpeg -i tasty.webm -c:v h264 tasty.mp4

＃GPU enc
ffmpeg -i tasty.mp4 -c:v h264_nvenc tasty_nvenc.mp4

動画データ
335 Seconds
4K
webm : 587MB
MP4 : 455MB
NVENC : 94MB

劣化具合？いえ、知らない子ですね。

##ハードウェア構成
面倒くさいので全てバラバラです。
ハードウェアエンコなので、NVENC性能が測れてそうならそれでいいじゃないですか。


|CPU|Threads |GPU|OS| enc | TIME|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|E5-2687W <br>v4 x2|48|k620|CentOS6|CPU|248|
|i9-9900k|16| Tesla K20c<br>(Kepler)|CentOS7|GPU|475|
|i7-8700k| 12| GTX660<br>(Kepler)|CentOS7|GPU|473|
|i3-9350KF|4|GTX980<br>(Maxwell)|Ubuntu<br>18.04|GPU|81|
|i7-7700|8|GTX1060<br>(Pascal)|CentOS6|GPU|60|

## GPU比較
|NAME|Architecture|Cores|Clock|MEM|TDP|
|:-:|:-:|:-:|:-:|:-:|:-:|
|Tesla <br>K20c|Kepler|2496|706|GDDR5 <br>5GB|225W|
|GTX660| Kepler|960|1033|GDDR5 <br> 2GB|140W|
|GTX980 |Maxwell|2048|1216|GDDR5<br>4GB|165W|
|GTX1060| Pascal|1280|1708|GDDR5<br>6GB|120W|

#考察
K20cとGTX660はコア数が圧倒的に違うが、ほとんど同じエンコード時間である、
ということがすべてを物語っていそう。
そしてコア数とか関係なく世代が新しいければ速い。
メモリとかもあんまり関係なさそう。

#結論
誰かTuringください
SQL で外部結合するときは条件をどこに書くかを意識しよう

## はじめに

業務系のシステム開発をしていると、トランにマスタをぶつける際に外部結合にすることがあります。
これは、万が一、マスタが取得できなくても検索対象となるべきトランの欠落を防ぐためです。

但し、外部結合は、絞込み条件をどこに書くかによって検索結果は異なります。安全のために外部結合にした結果、バグを埋め込んでしまっては元も子もないので気を付けましょう。

## 具体例

### 対象とするテーブル

【受注T】

|受注NO|商品CD|金額|
|:---|:---|---:|
|001|AAA|100|
|002|BBB|300|
|003|CCC|500|

【商品M】（商品CD='BBB'が欠落）

|商品CD|商品名|商品区分|
|:---|:---|---:|
|AAA|商品A|0|
|CCC|商品B|1|

### マスタが欠落しても外部結合していれば、受注データは表示される

```sql:
select
    T.受注NO
  , T.商品CD
  , M.商品名
  , T.金額
from
    受注T T
    left outer join 商品M M
         on T.商品CD = M.商品CD
```
|受注NO|商品CD|商品名|金額|
|:---|:---|:---|---:|
|001|AAA|商品A|100|
|002|BBB|null|300|
|003|CCC|商品C|500|

- 商品名は表示されないレコードが存在するが、受注Tの対象データは全て検索されている。
- select するのは、T.商品CD で、M.商品CD でないことに注意。

### 商品区分='1'の商品の受注のみを表示する（誤り）
```sql:誤り
select
    T.受注NO
  , M.商品CD
  , M.商品名
  , T.金額
from
    受注T T
    left outer join 商品M M
         on T.商品CD = M.商品CD
        and M.商品区分 = '1'
```
|受注NO|商品CD|商品名|金額|
|:---|:---|:---|---:|
|001|AAA|null|100|
|002|BBB|null|300|
|003|CCC|商品C|500|

- 絞り込んだ後で、外部結合しているので、受注Tの全レコードが検索される。

### 商品区分='1'の商品の受注のみを表示する（考察→成果へ）
```sql:結果オーライ
select
    T.受注NO
  , M.商品CD
  , M.商品名
  , T.金額
from
    受注T T
    left outer join 商品M M
         on T.商品CD = M.商品CD
where
    M.商品区分 = '1'
```
|受注NO|商品CD|商品名|金額|
|:---|:---|:---|---:|
|003|CCC|商品C|500|

- 外部結合した後に絞り込む。
- 但し、上記の場合は、商品Mに存在しない受注Tのレコードの商品区分は null になるため、left outer join ではなく、inner join で結合するのが正しい。

```sql:上記を踏まえた修正
select
    T.受注NO
  , M.商品CD
  , M.商品名
  , T.金額
from
    受注T T
    inner join 商品M M
         on T.商品CD = M.商品CD
where
    M.商品区分 = '1'
```

- inner join にした場合は、inner join の条件部分で絞り込んでも、where 条件で絞り込んでも、結果は同じになるが、個人的には、inner join の中で先に絞り込んだ商品Mと受注Tを結合した方がよいと思う。（最近のDBは賢いので、どっちで書いても実行計画は同じになることが多い。）

```sql:最終版
select
    T.受注NO
  , M.商品CD
  , M.商品名
  , T.金額
from
    受注T T
    inner join 商品M M
         on T.商品CD = M.商品CD
        and M.商品区分 = '1'
```

## 番外編

### 結果はあってるけど、おかしなSQL

```sql:結果があえばよいってわけじゃないぞ！
select
    T.受注NO
  , M.商品CD
  , M.商品名
  , T.金額
from
    受注T T
    left outer join 商品M M
         on T.商品CD = M.商品CD
        and M.商品区分 = '1'
where
    M.商品CD is not null
```

- 受注Tの全件に対して商品Mをぶつけた後に絞り込むので効率が悪いし、そもそも、SQL の組み立て方からしておかしいてす。

## おわりに

そもそもテーブル間の整合性が担保できないDBに問題があるのですが、世の中のシステムは結構いい加減です。いい加減なシステムのSQLは、いい加減なものがちょこちょこあって、改めて基本を押さえましょうという意味で書きました。
コンテナの指揮者、Docker Composeのおはなし



### Docker Composeとは
「複数のDockerコンテナを、諸々の設定含め一発で一気に起動できちゃうよ」な便利道具

いくつかのDockerコンテナを立ち上げて環境構築しようと思った時に毎回docker runで全部立ち上げるのは大変です。

そんな時にまさに指揮者（Composer）のようにコンテナを自由自在に扱えるようにしてくれるのがDocker Composeです！

###Docker Composeの使い方

Docker Compose起動！！

と言っても起動はしてくれません。

docker-compose.yml 
(もしくはdocker-compose.yaml)

というファイルに設定をつらつら書いていきます。

なんだ、スクリプトファイル書くのと変わらんやん、と思うかもしれません。

正直僕も違いはそこまでわかりませんが、断然簡単です！（らしい）

僕がDockerに触れ始めた時にはもうComposeもあったので...

とりあえずdocker-compose.ymlの中身を見ていきましょう！


###docker-compose.yml

```docker-compose.yml


services:
 fabric-ca:
    image: hyperledger/fabric-ca
    ports:
      - "7054:7054"
    volumes:
      - ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config
    container_name: fabric-ca
    networks:
      - basic

  couchdb:
    container_name: couchdb
    image: hyperledger/fabric-couchdb
    environment:
      - COUCHDB_USER=xxx
      - COUCHDB_PASSWORD=xxx
    ports:
      - 5984:5984
    networks:
      - basic
```

こんな感じです。
Hyperledger Fabricのfabcarサンプルで使うファイルを省略してみました。

dockerを使ったことがあると大体掴めると思います。

servicesがそれぞれのコンテナで、その下の階層でオプションを指定します

**image** でイメージを指定
**ports**　でホストのポートと対応するコンテナのポートを指定
**volumes**　でホストのディレクトリとコンテナ内のディレクトリをマウント
**container_name**　で名前を設定。コンテナIDを使わなくても名前でアクセスできるようになったりしてわかりやすい。
**environment**　でコンテナ内の環境変数をセットできる。
**networks**　でコンテナをどのネットワークに置くか指定できる。デフォルトだとおそらくbridgeネットワークです。

他にもdockerコマンドのオプションに対応するものは大体あると思います。

オプションの順番がfabric-caとcouchdbでバラバラなのが少し気持ち悪いですが、まあこんな風に適当にもかけちゃうよってことですね。

[Docker Compose公式ドキュメント](http://docs.docker.jp/compose/toc.html)

###docker-composeコマンド
docker-compose.ymlファイルが書けたらもうほとんど終わりです！

あとはコマンドを打ち込む！
下記はいくつかよく使うコマンドです

```
#コンテナ全部起動
docker-compose up
#デタッチドモードでバックグラウンドで起動
docker-compose up -d
#コンテナ全部終了
docker-compose stop
#コンテナを全削除
docker-compose rm
#コンテナのログを出力
docker-compose logs

```

他にも色々あります
先ほどのドキュメントやヘルプをご参照ください！

###まとめ
Docker Composeが便利だよと言うお話でした。

昔はローカルでシステムの環境構築するのに数日かかることもあったとか、なかったとか。
便利な世の中になりました。
先人達に感謝。

今度は最近話題のKubernetesについても勉強してまとめてみたいと思います。

Kubernetesについてよく出てくるワードが

「コンテナオーケストレーション」

オーケストラのように調和のとれた秩序ある環境を構築するということなのでしょうか。

指揮者のさらに上をいく技術っぽそうな感じがプンプンしてきます。

楽しみです。
USB接続のモバイルルーターでポートスキャンツールnmapがエラーになるときの対処と反省

自分の環境に対し、お手軽に外部の回線からポートスキャンを実施したいときはありませんか？
手持ちのSIMとモバイルルーターで実現できるのですが、エラーが出てしょぼいハマり方をしてしまったので、
その反省も兼ねて対処方法をメモしておきます。

## 環境
* Windows 10 (有線LAN 1つのデスクトップPC)
* [Nmap 7.70](https://nmap.org/download.html)  
  WSLではなく、Windows用のインストーラーで標準インストールし、Windowsで動作させています。(Zenmapが一緒に入ってくるもの)
* Pocket Wifi (Softbank 304ZT)  
  PCとUSB接続しています。

## 発生したエラー
`example.com`の443ポートだけスキャンしてみました。
`example.com`の部分は自分の環境に書き換えてください。

```
> nmap -p443 example.com
Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-25 15:57 ???? (?W???)
dnet: Failed to open device eth1
QUITTING!
```
`eth1`…今回USB接続したPocketWifiのデバイスが開けないようです。
`eth0`は普通のNICで有線LANでしたが、そちらの回線では問題なく動作しました。

ちなみにWindowsではあまり馴染みのない`eth0`や`eth1`ですが、

```
> nmap --iflist
```
で何なのかわかります。
※例えば`ipconfig /all`でMACアドレスを見比べたりするとわかると思います。

## 対処方法
大したことはなく、**Npcap 0.996をインストール**したらうまく動きました。

```
> nmap -p443 example.com
Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-25 16:09 ???? (?W???)
Nmap scan report for example.com (xxx.xxx.xxx.xxx)
Host is up (0.045s latency).
rDNS record for xxx.xxx.xxx.xxx: xxxxxxxx

PORT    STATE SERVICE
443/tcp open  https

Nmap done: 1 IP address (1 host up) scanned in 0.78 seconds
```

原因はWindows用インストーラー`nmap-7.70-setup.exe`に付属するNpcapが少し古く
`0.99-r2`というバージョンだったことでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117852/bfc64463-c984-5015-4b53-11b4c737c315.png)
インストール時はあまり気にせず進めてしまっていました。
`0.996`は同じページのすぐ下にリンクされていたので、入手して上書きインストールし無事解消しました。

## 反省点
**公式で配布されているものは同梱物も含め常に最新のものであるという思い込み**があったため、
ここに行きつく前にドライバの再インストールやファイヤーウォールの設定変更、他の端末での検証など
無駄に時間を取られてしまいました。

よく見たら[ダウンロードページ](https://nmap.org/download.html)のところにちゃんと書いてありました。

> Note: The version of Npcap included in our installers may not always be the latest version. If you experience problems or just want the latest and greatest version, download and install the latest Npcap release. 

訳
注意：インストーラに含まれているNpcapのバージョンは、必ずしも最新のものとは限りません。問題が発生した場合、または最新かつ最高のバージョンが必要な場合は、最新のNpcapリリースをダウンロードしてインストールしてください。


**教訓：しっかりページを読みましょう**
docker-composeのrails環境で、bootstrap4が反映されない時〜

DockerでRailsの開発環境を構築したのですが、Bootstrap4の導入でハマったため投稿します。


## 公式サイトの手順に沿ってインストール

まず以下の公式サイトに従って導入しました。
[Bootstrap4](https://github.com/twbs/bootstrap-rubygem)

## エラー発生
```console:
ActionView::Template::Error (Autoprefixer doesn’t support Node v4.8.2. Update it.):
```
AutoprefixerがNode v4.8.2のサポートしていないため、updateしてくださいエラー。
大人しくアップデートするか、もしくは以下のgemをGemfileに追記。

```console:Gemfile
gem 'mini_racer'
```

bundle installを実行。

## またエラー発生
```console
ActionView::Template::Error (File to import not found or unreadable: bootstrap.
```
bootstrapを読み込めないというエラー。
bundle installを実行しているのになぜだろうとログを見ていると、
何回実行してもinstalling bootstrap4が走っている。
これキャッシュ関係してるとかある・・・？と疑問に思い調べてみました。
以下を実行し、エラーは解消できました。

```console
docker-compose build --no-cache
```

## めでたくbootstrap4導入完了
アプリ画面を確認するとちゃんとbootstrapがちゃんと反映されていました！
調べている最中は悔しい気持ちでいっぱいになるのに、
なんだかんだずっと続けられるのは、達成した喜びがあるからかなと改めて感じました。

参考サイト：
[Bootstrap4](https://github.com/twbs/bootstrap-rubygem)
[Dockerでコンテナ内にbundle installされない問題の解決法](https://fuqda.hatenablog.com/entry/2019/03/21/204118)
IBM Db2 on Cloud を Node-RED から利用するとき。無駄な CONNECTIONS を残さない。

## このページは？
IBM Db2 on Cloud は、Lite プランの場合、`5 simultaneous connections` という制限があります。通常利用する場合は、特に気になることでもないのですが、Node-RED フローの作り方によっては、下のようなエラーが発生してしまうことがあります。

このエラーが `起こりにくく` する Tips です。

![エラー１](https://dl.dropboxusercontent.com/s/ekhym3xkjwlmvuk/20190626-01-01.png)

## 目標
[exceeded maximum limit of 5 connections] という風に怒られにくくする

## 知識材料 
- [IBM Cloud](https://cloud.ibm.com/)
- [Node-RED](https://nodered.jp/)
- [IBM Db2 on Cloud](https://cloud.ibm.com/catalog/services/db2-on-cloud)

## 利用環境
- [Cloud Foundry Node-RED Starter](https://cloud.ibm.com/catalog/starters/node-red-starter)

# 検証する画面仕様
- データの検索・登録・更新 する Webページ

## 問題が起きるパターン
どうやら、フローに接続された `dashDBノード` は、一回でも実行するとセッションを張りっぱなしにする模様。

下のようなフローの場合、

- 「検索時」に一番上の dashDBノード が実行され
- 「新規登録時」に真ん中の dashDB ノードが実行され
- 「更新時」に一番下の dashDB ノードが実行され

気がつくと、３つのセッションが常時接続状態になります。

![](https://dl.dropboxusercontent.com/s/6dpd3yh32ckg4qs/20190626-01-02.png)

このまま何も考えずに `dashDBノード` を新しく増やしてフローに接続していくと
[exceeded maximum limit of 5 connections] というエラーが発生し、アプリケーションが思ったように動かなくなります。
また、IBM Cloud の DashDB Console からもアクセスできなくなります。
(当ページ上部のエラー画像）

## 現在の接続数確認
現在の IBM Db2 on Cloud への接続数は、画面左上の「ハンバーガーメニュー」から
「MONITOR」→「Connections」から確認できます
![](https://dl.dropboxusercontent.com/s/6niyqyjdv963ekk/20190626-01-03.png)

## 接続数を増やさない
下のフローのように、dashDB を操作するための API を自分で公開します。
「検索」「新規登録」「更新」の各処理は、[dashDB 処理 API]を呼び出すようにします。
`dashDB ノード` の数は１つになるため、IBM Db2 on Cloud への接続数は 「１」になります。
![](https://dl.dropboxusercontent.com/s/ut7x1ysgrx9xi5p/20190626-01-04.png)

「検索」「新規登録」「更新」の処理フローは、`dashDBノード` から `http Request ノード` に接続を切り替えるだけです。

ただし、セキュリティを考慮していないので、実際に使用する場合はなんらかの対策が必要かもしれません。
AWSにおけるネットワーク間を接続の方法

AWSにおいて構築したネットワークを相互に接続する方法として以下の3つをまとめる。
とりあえず覚書程度、都度更新していければ・・・。

**・VPC Peering**
**・Shared VPC（VPC Sharing）**
**・AWS Transit Gateway**

※sharerd VPCとtransit GatewayはRAM(※1)の機能により実現される

# VPC Peering
2つのVPC間でプライベートなトラフィックのルーティングを可能にする。
アカウント、リージョンを跨ぐ接続が可能。
但し、VPCを跨ぐ通信は不可であるため、通信させたいVPC間ごとにPeeringし、フルメッシュで接続しなければならない。

# Shared VPC（VPC Sharing）
共有させたいサブネットを持つアカウント（所有者）からSharedの招待を受けたアカウント（参加者）は共有されたサブネットを利用できる。

所有者はリソースの作成・削除・変更ができる。
但し、参加者が共有サブネット内に作成したリソースは削除できない。

参加者はサブネット内のリソースを使用、表示、作成、変更および削除できる。
但し、他の参加者または所有者に属するリソースを表示、変更、または削除することはできない。 
また、他の参加者が作成したリソースは認識できない。
ルートテーブルやNACLの閲覧は可能。

請求はアカウントで分割される。
参加者はサブネット内のアプリケーションリソースの使用、データ転送に対して料金を請求される。

共通基盤をそれぞれのネットワークに配置せず、1ヵ所で集中管理できるため、リソースや運用管理の手間を省略できる。

**制限**
同じAWS Organization(※2)に所属している必要がある。
デフォルトVPC内のサブネットはシェアできない。

サポートされていないサービス
・Amazon Aurora
・AWS CloudHSM
・AWS Glue 
・Amazon EMR
・Network Load Balancer 

AWSの仕様として、あるAWSアカウントにとっての「us-east-1a」は、別のAWSアカウントにとっては「us-east-1b」となるように、AWSアカウントによってAZ名と実態が異なる場合がある。
AWSアカウント間で正しくAZを特定するには、AZ IDというAZの固有IDを使う。

#AWS Transit Gateway
以前はCloudFormation等を利用したTransit VPCで実現していたことを
マネージドサービスとして利用できるようになった。

AWS Transit GatewayはAmazon VPCやVPN、Direct Connect Gateway(DXGW)を接続するハブの役割を果たす。
内部に複数のルートテーブルを持ちAmazon VPCやVPN、DXGWごとに関連付けを指定でき、セグメント化が可能。
また、アカウントを跨いで接続することができる。

※東京リージョンでのDirect Connect(※3)はサポートは未だ

#補足：オンプレミスとAWSのネットワークを接続する方法
（別途まとめられれば・・・）

###■Direct Connect(DX)
VPCごとにVirtual Interface(VIF)を作成

###■Direct Connect Gateway(DXGW)
各VPCに対してVIFを作らなくても、DXGWに対してVIFを紐づければ、DXGWから各VPCに接続できるようになりました

---

※1 RAM（AWS Resource Access Manager）：AWSのリソースを任意のAWSアカウント、またはAWS組織内で簡単かつ安全に共有できるサービス 
※2 AWS Organization：複数のAWSアカウントを一元管理できるサービス
※3 Direct Connect：AWSとオンプレミスのネットワーク環境を接続するサービス
log4php：LoggerAppenderSyslog のバグに対応する

## log4php とは

[apache公式](http://logging.apache.org/log4php/)

php版ログモジュール。
以下の設定が可能

- ログ出力先
- ログフォーマット
- ログレベル
- ローテーション

## LoggerAppenderSyslog とは

[LoggerAppenderSyslog 公式](https://logging.apache.org/log4php/docs/appenders/syslog.html) 

linuxの場合は、システムログに出力する
windowsの場合は、イベントログに出力する

phpはシステムログに出力する関数 [syslog](https://php.net/manual/ja/function.syslog.php) があるので、LoggerAppenderSyslog を使わなくてもよいが、ログ設定を一つに纏めたいから使う。

## 準備

ファイル構成

- index.php
- log4php.xml
- composer.json
- composer.phar

```ruby:index.php
<?php
require 'vendor/autoload.php';
Logger::configure('log4php.xml');

$logger = Logger::getLogger('syslog');

$msg = '12345678901234567890';
$logger->error($msg);
```

```ruby:log4php.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration xmlns="http://logging.apache.org/log4php/">
    <appender name="mySyslog" class="LoggerAppenderSyslog">
        <param name="facility" value="USER" />
        <param name="option" value="PID" />
    </appender>

    <logger name="syslog">
        <appender_ref ref="mySyslog" />
    </logger>
</configuration>
```

```ruby:composer.json
{
    "require": {
        "apache/log4php": "2.3.0"
    }
}
```

composer.phar は [公式](https://getcomposer.org/download/)からwget
`wget https://getcomposer.org/download/1.8.6/composer.phar`　2019-06-11 時点


## LoggerAppenderSyslog バグの再現

```
$ php composer.phar install
$ php index.php

$ tail -f /var/log/message
Jun 26 23:05:20 hostname journal: Apache log4php[30746]: ERROR - 12345678901234567890
Jun 26 23:05:20 hostname journal: Apache log4php[30746]: 901234567890
```

### ２行出力されてるやん！しかも、
### 文字切れてる

設定変えたら直る予想は空振り。facility を変えると文字切れする位置が変わる怪現象に遭遇するおまけつき。
index.php でsyslogしても１行しか表示されないので、log4phpが原因なのは確定。
mb_string は空振り。調べてもわからなかったので、覚悟を決めて探検することに。

vendor\apache\log4php を探検
イベントぽい LoggerLoggingEvent.php があったから、ログ出力とイベントで2回という予想は空振り。かくかくしかじかで、
vendor\apache\log4php\src\main\php\appenders\LoggerAppenderSyslog.php->append の、syslogで２行出力されることが分かったが、原因は不明


## 解決策

メッセージをnull文字で終端したら直った

`$msg = '12345678901234567890';`
　↓
`$msg = '12345678901234567890'."\0";`

![やれやれだぜ](https://ctrlzr.sakura.ne.jp/img/ameblo/yareyare3.gif)
IFTTTでGmailメール送信が使えなかったので代替手段としてHotmailの転送を使ってみた

# やりたいこと

- Alexaの買い物リストを見ないので、WunderListに放り込みたい

# 「IFTTT」と「wunderlistにメール」でできそう
## IFTTT
- Alexa to XXX via gmail のアプレットがある

## wunderlistにメール
- fromメールアドレスごとにリストに分配してくれる（「XXX@hotmail.co.jp」からのメールを、「お買い物」に入れる設定をした
- この設定をした上でfromに指定したアドレスから、me@wunderlist.comにメールを送れば、リストに追加される
- [設定画面へのリンク:WunderListにメール](https://www.wunderlist.com/account/mailtowunderlist)

# 問題発生
- どうやら、Gmail連携が失敗するらしい（メールの送信ができない）※どうもいつからか使えなくなってそのまま？

# 解決編(IFTTT + Alexa to my mail)
- IFTTT の Alexa to my mail で自分のHotmailアドレスに送信

<img width="200" alt="0ABEAF63-3DFD-44DB-AD58-6B5C22D17AB7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74969/933158db-96d4-9d15-fce2-632f43fce47d.png">
<img width="200" alt="36C08F15-8490-40D9-977A-B3AF9F224865.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74969/52e4cba5-9562-33ec-1dd6-ac779b510355.jpeg">

- Hotmail にて、action@ifttt.comからのメールをme@wunderlist.comに転送するルールを作成
![スクリーンショット 2019-06-26 23.42.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74969/a19f6687-15bb-5a93-f233-e34001148660.png)

- [やりかた：Microsoftサポート](https://support.office.com/ja-jp/article/%E3%83%AB%E3%83%BC%E3%83%AB%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%82%92%E8%87%AA%E5%8B%95%E7%9A%84%E3%81%AB%E8%BB%A2%E9%80%81%E3%81%99%E3%82%8B-45aa9664-4911-4f96-9663-ece42816d746)

# 結論
- 解決しました
- 「FW：」といつもつくのが若干不満
ns3を扱うための概念について

# 本記事の注意
本記事は初学者向けに書いているため、誤った表記があるとは思いますが、わかりやすさを優先しているためこのようにしています。
ご了承ください。

# ns3とは
ns3とは離散型のネットワークシミュレーターである。
ns3のプログラムを作る上で重要な要素がいくつかある。

ネットワークの通信には、TCP/IPやOSI参照モデルなどの概念が存在しているが、ns3もそれらの概念を取り入れている。たぶんだが、TCP/IPモデルが近い。
ns3ではコンテナのように組み合わせてプログラムを作成していく。
ns3は主に４つのコンテナが存在している
1. NodeContainer
2. DeviceContainer
3. InterfaceContainer
4. ApplicationContainer


<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191643/b6c20162-36d1-e0fb-51a7-8c08c467e273.png width= 70%>
これら4つは４つで一つのものであることを忘れないように！

これらの4つ一つ一つに、補助をするhelperと呼ばれるパーツが存在している。

# 1. NodeContainer
NodeCountainerは扱うノードが何であるかを示すもの！
例えば？
PCなのかスマートフォンなのかルータなのかなど
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191643/470aa11d-b394-94b8-f8cd-287f01fc8b95.png width =70%>


実際にPCノードを2台生成してみよう。

```c++:Node
NodeContainer pc_nodes; //pc_nodesの部分は自由に決めれる
pc_nodes.create(2); //2台のpcを生成している
```
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191643/5a842ad7-081b-a776-613b-11b84d26edb6.png width = 70%>

# 2. DeviceContainer

DeviceContainerはノードが持っている通信機能はなんであるかを指定するためのもの！
例えば？
イーサネットなのかWiFiなのかBluetoothなど
<img src =https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191643/0ffddf7f-532d-8eb3-6174-49f38a6c8fd5.png width = 70%>

実際にPCノードにイーサネット機能を付与してみよう！

```c++:Device
NetDeviceContainer pc_devices; //pc_nodesのためのデバイスを作成
PointToPointHelper pointToPoint; //イーサネットに決定
pc_devices = pointToPoint.Install (pc_nodes); // PCノードに機能を追加
```
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191643/8ae7783e-3baa-d39b-562c-99fc763de1ce.png width =70%>


# 3. InterfaceContainer
InterfaceContainerはみんなが使っているWIFIやスマートフォンのセルラー回線にはそのネットワークのデバイス(部品)ごとにIPアドレスって呼ばれる番号が付与するためのもの

実際にPCノードに付与されたデバイスにIPアドレスをつけてみよう

```c++:Interface
Ipv4InterfaceContainer interfaces; //pc_deviceのためのインターフェースを作成
InternetStackHelper stack; //後日記入
stack.Install (nodes); //後日記入
Ipv4AddressHelper address; //アドレスの設定をするための部品を生成
address.SetBase ("10.1.1.0", "255.255.255.0"); //アドレス空間を10.1.1.0~10.1.1.255に※設定サブネットマスクの設定が"255.255.255.0"であるため
Ipv4InterfaceContainer interfaces = address.Assign (pc_devices); //pc_deviceにIPアドレスを付与
```

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191643/27831553-7e64-f1c0-2f86-77178fb14020.png width =70%>

# 4. ApplicationContainer

ApplicationContainerは、シミュレーションがどんな通信をするのかを設定するためのもの！
例えば？
AさんはUDP通信でBさんのpcへ通信したいなぁみたいな感じ！

実際にAさん(ノード番号0)はBさん(ノード番号1)に通信してみよう

```c++:Application
ApplicationContainer apps; //通信シナリオを作るためのアプリケーションを作成
OnOffHelper onoff ("ns3::UdpSocketFactory",Address (InetSocketAddress (interfaces.GetAddress (1), port))); //Bさんに通信が来るように設定
onoff.SetConstantRate (DataRate ("448kb/s"),512);
apps = onoff.Install (pc_nodes.Get (0)); //Aさんが通信をするように設定
apps.Start (Seconds (1.0)); //開始時間
apps.Stop (Seconds (2.0)); //終了時間
```
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191643/b6c20162-36d1-e0fb-51a7-8c08c467e273.png width= 70%>

やったー完成


**次の記事は、ns3における無線通信の基礎になります。お楽しみに**
Java 9 以降でリモートデバッグするときはホストの指定も必要


# 環境
**OS**

`Windows 10 64bit`

**Java**

```
> java --version
openjdk 11.0.3 2019-04-16
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.3+7)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.3+7, mixed mode)
```

# 検証用の実装
```text:フォルダ構成
> tree /f
├─build
│  └─classes
│     └─java
│         └─main
│                 Hoge.class
└─src
    └─main
        └─java
                Hoge.java
```

```java:Hoge.java
class Hoge {
    public static void main(String... args) {
        System.out.println("Hello World");
    }
}
```

# Java 9 より前
Java のプログラムを Eclipse とかでデバッグするときは、起動時のオプションに次のような呪文を追加する。

```

> java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=y -cp build\classes\java\main Hoge
```

Java 9 より前であれば、これでリモートから `8000` ポート指定でデバッガーをつなぐことができた（もちろんポートを開いておく必要はある）。

# Java 9 以降だとエラーになる
しかし、 Java 9 以降でこのオプションで起動した JVM にリモートからデバッガで繋ごうとすると、次のようなエラーになる。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28302/e0ae21ad-9992-28dc-9f94-77a1ab061340.png)

## Java 9 で、ホスト指定していない場合はリモートから接続できなくなった
[JDK 9 Release Notes | Notes and Changes](https://www.oracle.com/technetwork/java/javase/9-notes-3745703.html#JDK-8041435)

> JDWP socket connector accept only local connections by default 
> The JDWP socket connector has been changed to bind to localhost only if no ip address or hostname is specified on the agent command line. A hostname of asterisk (*) may be used to achieve the old behavior which is to bind the JDWP socket connector to all available interfaces; this is not secure and not recommended.

Java 9 で、ホストを指定していない場合は自動的に `localhost` にバインドされるようになり、リモートからは接続できなくなったらしい。

これまで通り任意のリモートから接続できるようにするには、 `address=*:8000` のように `*` を使うことで実現できる。
（ただし、セキュリティ的によくないので推奨はされないらしい[^1]）

[^1]: デバッガで接続する時点で本番ではない環境だし別にそこまで気にする必要はない気はする。え？本番もデバッガで接続する？アッハイ

# * 指定で接続してみる
```
> java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=*:8000,suspend=y -cp build\classes\java\main Hoge
```
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28302/947c96f8-854e-429e-2ca3-04cd5a4e25f7.jpeg)

つながった。


# 参考
- [ローカルマシン以外で動いているjvmをEclipseでデバッグする - TIM Labs](http://labs.timedia.co.jp/2011/03/jvm-eclipse-remotedebug.html)
- [Can't remotely debug on Java 9 Tomcat 9 in docker container - Stack Overflow](https://stackoverflow.com/questions/47168235/cant-remotely-debug-on-java-9-tomcat-9-in-docker-container)
ActionView::Template::Error:PG::AmbiguousColumn: ERROR…でRSpecが失敗して困った。

# はじめに
RSpecでテストを行っていたところ、下記のエラーが出て困ってしまいました。
ですので、エラーの原因と解決策をここに残したいと思います。

前提条件として、私の環境は次の通りです。

```ruby
ruby 2.6.3
rails 5.2.3
```

# エラーについて
RSpecのsystem specを実行するとエラーが発生しました。
開発環境では特にエラーは起きておらず、テストのみでしかエラーが発生していなかったので困りました。

```ruby
ActionView::Template::Error:PG::AmbiguousCoulumn: ERROR: column reference "created_at" is ambiguous ...

```

## 原因
上記のエラーに関係しているコントローラーはこちらです。

```ruby:tasks_controller.rb
@tasks = @tasks.joins(:labels).order("created_at: :desc")
```

Taskモデルに、TaskモデルとアソシエーションしているLabelモデルをjoinsで結合しています。
それにより`order("created_at desc")`が、tasksテーブルにある`created_at`を指しているのか、labelsテーブルにある`created_at`を指しているのか、曖昧（ = AmbiguousCoulumn ）になっていることがエラーの原因でした。

## 解決策
下記のどちらかの方法で、どのテーブルの`created_at`を使うのか指定してあげます。

```ruby
@tasks = @tasks.joins(:labels).order(created_at: :DESC)
@tasks = @tasks.joins(:labels).order("tasks.created_at: :desc")
```

## 参考
https://github.com/rails/rails/blob/b9ca94caea2ca6a6cc09abaffaad67b447134079/activerecord/lib/active_record/relation/query_methods.rb#L293

　
以上です。
[Java] (実質的にfinalで)再代入ができないシーン

# マルチ例外処理

eが実質的にfinalになる。

```java
    public static void main(String[] args) throws IOException{
        try{
            throw new IOException();
        }catch (RuntimeException | IOException e){
            e = new RuntimeException();  // Cannot assign a value to final variable 'e'
            throw e;
        }
    }
```

ただし、マルチではなく単一例外のキャッチでは、キャッチした例外とそのサブクラスであれば再代入が可能。

```java

static class FooException extends Exception{}
static class BarException extends FooException{}

public static void main(String[] args) throws FooException{
        try{
            throw new FooException();
        }catch (FooException fe){
            fe = new FooException();
            fe = new BarException();
            throw fe;
        }
    }
```

# ラムダ式を定義

下の例では、ラムダ式中に使われるローカル変数が実質的にfinalとなり、再代入時にコンパイルエラーが発生。

```java
public interface Greeting {
    void sayHi(String name);
}
```

```java

String name = "Ken";
Greeting g = n -> System.out.println("Hi, " + name);
name = "Taro"; // ★ここでコンパイルエラー
g.sayHi(name);
```

# try-with-resources

実質的にfinalではないが、再代入ができないJDBCの例

```java
        import java.sql.Connection;
        import java.sql.DriverManager;
        import java.sql.SQLException;

        Connection connection = null;
        try (connection = DriverManager.getConnection("url") { // unknown class "connection" 

        } catch (SQLException e) {
            e.printStackTrace();
        }

```
ちなみに、通常のtry-catchであれば可能

```java
        try {
            connection = DriverManager.getConnection("url");
        } catch (SQLException e) {
            e.printStackTrace();
        }
```
ある社内SEの歩み

## はじめに
初めまして
大手SIer　→　ブラック　→　ブラック　→　ヤクザブラック　→　グレーだけど潰れそう(今ここ)
という経歴を渡り歩いてきたとある社内SEのお話です。
書く練習含めて今回はとりあえず自分のご紹介。

## きっかけ
なんかアウトプットすれば、技術力が身につくと聞いて安易にQiita始めました。
一応簡単なWebサービス作ったので、そのアウトプットしようと思うんですが、
どちらかというと社内で起こった出来事を書いたほうが楽しそうな気もしています。
だって、役職の経歴も書いてみると
主任　→　平　→　平　→　係長　→　部長　→　本部長　→　平　→　部長(今ここ)

ものすごいジェットコースターです。
ちなみに社長に近づけば近づくほど、プログラムを書けないです。

さて、じゃあそんな私の保持するスキルセットをご紹介します。

## スキルセット
【IT系】
C#.NET   なんでも作れる。でもUnityとか知らないよ。
VB.NET   なんでも作れる
Ruby(on Rails)　CRUDレベルなら
Java　なんでもだったが、レガシー化
html5,CSS,JS　ごりごりのbootstrap使ってレスポンシブもどきレベル
エクセルマクロ　なんでも作れる

Oracle　　　なんでもだったが、レガシー化
SQLServer　 チューニング含めてなんでも
PostgreSQL  普通くらいまあ、RDBの仲間だから大丈夫やろ
MySQLほか　　見たことあるだけ。同上
SQLは手でそこそこ書けるかな。

Windows命
CentOS　しかたなく・・・Rails Puma Nginxを動かすためだけの知識あり。

開発環境 Windows命　でもRails触るようになって、VMwareでCentOSやら
をやらざるを得なくなった・・・MicroSoftに命捧げると誓ったのに。。。
まとめるとレガシーなものばかりなことが分かります。
ちなみに社内SEは私と同様特定の言語しか知らない人は多いです。
1つ目のブラックにいたおっちゃんはVBscript？しか使えなかったですけど、会社で生き残っていました。
そのほか雑務もかなりやってましたけどね。

【業務系】
生産性の向上
ヒアリング、業務フローを絵に書く。改善する。まとめる。
ポイントはどの業務を捨てるか。
システム導入時の導入側窓口とっても得意。胃が痛むけど。
あとはお金まとめたり、売上サマリ作ったり、マネジメントしたり

## 足りないところ
持ってるスキルが古い。できることが少ない。
以上

## や、や、やばい・・・
このままだとただの便利屋さんになってしまう。僕はエンジニアですって言えないレベル。。。
ということに最近気づきました。私も使えない社内SEになりかけています。もはやなってる？

## 目標
モダンな技術を使って、Webサービスをちゃちゃっと作れるような力をつける
・RailsでまずWebサービス作る
・サーバーサイド、クライアントサイドで分離した感じでWebサービス作る
　サーバーサイドはRailsのAPI、クライアントサイドはVue.js、AndroidアプリだとKotlin,IOSだとSwift
・調子に乗ってきたらサーバーサイドをGoにしたり。indexDBだっけ？クライアントサイドでDBもてるやつ。を駆使したり。
上記ができるようになれば、一歩前進するかな？してくれ。

## 最後に
このサイトを使っている人たちはどちらかというとバリバリな開発者が多いと思われますが、
社内SEにももっとスポットが当たることを望みます。
技術力で劣っていたり、あまり社外に出ない人が多いとは思いますが、
それでもこのまま舐められっぱなしは許せん。
社内SE共通の悩みとしてとにかく雑務が多く、開発に没頭できる時間が取れないというハンデがあります。
だがしかし、時間は作るもんだと考えて逆襲や！社内SEのみなさん、頑張りましょう！
filterの使い方メモ


### filterを使って配列内の特定の情報だけ取り出す。    

#### ts

      testStr  = [
        "aaa",
        "bbb",
      ]

    test = () => {
     return this.testStr.filter(function(_element : String) {
        return (_element != "aaa");
      });
    }

    console.dir(this.test());
　
#### console
    0 : bbb
pythonでテスト駆動開発をしながらAtcoderを解くABC071

#今日の目標
前回テストの大切さを知ったので、テスト駆動開発で競技プログラミングを解くことを試してみる

## 事前に考えたこと
競技プログラミングはそんなに処理が多くないから無駄じゃない？
→自分はその簡単な処理でもエラーを起こすので必要
→問題を適切な単位に分割する練習になる

コードが長くなるよね？
→それはしょうがない。諦める
 
## 開発環境整備
https://qiita.com/NaokiHamada/items/0689cd85fb3e1adcda1a
を参考にした。
　1.別にドキュメントはいらないとも思ったが、この方法だと、１つのファイルで（テストケースを記述したファイルとかを必要なく）できる。
　2. "if __name__ == '__main__':" を以下のように末尾につけることでそのまま提出コードにすることができる。

```
def print_ans(s):
---
中略
---
if __name__ == '__main__':
 s = input()
 print_ans(s)
```

の２点からこれにしました。（他にいい方法あったら教えてください）

ちなみにSphinixのインストールには少し手間取りました。
```sphinx-quickstart　```
を押して基本はEnterを押すだけでいいのですが、一回目にやったときはautodocumentをNo（デフォルト）にしてから、あとでconf.pyを書き換えたからなのか、テストが実行できませんでした。


# 問題セット　ABC072
## A
X-tと0の大きい方の数を出力するだけです。
テストのやり方としては、"""(”または’を3つ）でコメントアウトした中に、
”>>> ”でインタラクティブ実行で入力と出力を書いてテストする流れになります。

シンプルでいいですね。

実行は

```
python -m doctest examples.py
```
です。

ちなみに、失敗するといくつのテストで失敗したかが表示され、成功したら何も表示されません。

```a.py
def print_ans(X,t):
    """Print max(X-t,0)

    Parameters
    --------------

    Examples
    ------------
    >>> print_ans(3,0)
    3
    >>> print_ans(3,2)
    1
    >>> print_ans(2,5)
    0
    """
    print(max(0,X-t))

if __name__ == '__main__':
    X,t = map(int,input().split())
    print_ans(X,t)
```
## B
文字列を受け取って、1,3,5,7..の文字を繋げた文字列を返します。]
range(0,len(s),2)でステップ数（ループを回る時の回り方）を1つ飛ばしに指定しています。

```b.py
def print_ans(s):
    """Print substring of s, odd_th char

    Parameters
    --------------
    Examples
    >>> print_ans("a")
    a
    >>> print_ans("ab") 
    a
    >>> print_ans("aibc")
    ab

    """
    for i in range(0,len(s),2):
        print(s[i],end="")

if __name__ == '__main__':
    s = input()
    print_ans(s)

```
## C
　数字が要素のリストを受け取って、x-1<= a <=x+1　となるリストの要素a がもっとも大きくなる　x を求め、その時の条件を満たす要素a の個数を出力します。

　単純にxの値を１ずつ増やしていくとTLE（時間制限エラー）だったので、そーとして、リストの要素の値でループを回したのですが、それでもTLEでした。

　値は正しいのですが、TLEが解決できなくて諦めました。
O(N)にはなってると思うんだけど。。

```c.py
def print_ans(s):
    """Print substring of s, odd_th char
    >>> print_ans([1])
    1
    >>> print_ans([1,4])
    1
    >>> print_ans([0,3,4,5])
    3
    >>> print_ans([1,2,3,2,5,6])
    4
    
    """
    b = list(set(s))
    ans = 1
    """TLE 
    for i in range(b[0],b[-1]+1):
        ans = max(b.count(i)+b.count(i+1)+b.count(i+2),ans)
    """
    
    for i in range(len(b)):
        ans = max(ans,s.count(b[i])+s.count(b[i]+1)+s.count(b[i]+2))
    print(ans)

if __name__ == '__main__':
    N = input()
    a = list(map(int,input().split()))
    print_ans(a)

```

#振り返り
　とりあえず、テスト駆動開発でできるようになったのでよかった。
今は全体のコードをテストしているが、今後細かく分けて（関数を細かく分けて）テストできるようになる。

　あとは、C問題で詰まって次に行けなかったので、回答を見ても良いからCまでときたい。
　

参考
https://qiita.com/NaokiHamada/items/0689cd85fb3e1adcda1a
リストのn番目を取る。ただしリストがnより短い場合は一番最後を取る

「リストのn番目を取る。ただしリストがnより短い場合は一番最後を取る」
(メソッド名にするなら`getAtOrLast`？)
というロジックが欲しい時の簡潔な実装について書きます。

愚直にやると、インデックスを1つずつ下げてループとか、
仕様でリストの長さが高々3とかに決まっている場合は決め打ちで1個1個見ていくのでもできますが、
あんまりキレイじゃないので別の方法を考えてみました。

別に特定の言語に寄らないので擬似コードで書くとこんな感じです。

```:擬似コード
リスト.最初のn個を取得().最後の要素を取得();
```

--------------------

試しに何種類かの言語で書いてみます。

```js:jsの場合
let list = ["a", "b", "c", "d", "e",];
console.log(list.slice(0, 3).slice(-1)[0])
// -> c

list = ["a", "b",]
console.log(list.slice(0, 3).slice(-1)[0])
// -> b
```

```python:pythonの場合
list = ["a", "b", "c", "d", "e",]
print(list[:3][-1])
# -> c

list = ["a", "b",]
print(list[:3][-1])
# -> b
```

```php:phpの場合
$list = ["a", "b", "c", "d", "e",];
echo array_slice(array_slice($list, 0, 3), -1)[0] . PHP_EOL;
# -> c

$list = ["a", "b",];
echo array_slice(array_slice($list, 0, 3), -1)[0] . PHP_EOL;
# -> b
```

```php:phpの場合_LaravelのCollectionを使用できる場合
$list = ["a", "b", "c", "d", "e",];
echo collect($list)->take(3)->last() . PHP_EOL;
// -> c

$list = ["a", "b",];
echo collect($list)->take(3)->last() . PHP_EOL;
// -> b
```
PHPのerror_logの出力先はどこ？ 

#はじめに
普段、何気なく使用している`error_log`。

エラーログの出力先はこちら。(確認コマンドとともに）

```
tail -f /var/log/php/php.log
```


「このエラーログの出力先はどこで設定しているの?」
と疑問に思ったので、あらためて調べてメモ。

#そもそもphp.iniはどこ？
エラーログの出力先はphp.iniにかかれているようですが、そもそもphp.iniはどこにあるのかわからなかったので、その確認方法。

phpinfo()に書かれるみたいなので、便利な確認コマンドがあった。

```
php -r "echo phpinfo();" | grep "php.ini"
```
参照:https://qiita.com/ritukiii/items/624eb475b85e28613a70



```:出力結果
Configuration File (php.ini) Path => /etc
Loaded Configuration File => /etc/php.ini
```

ふむふむ、/etc/php.iniにありますのね〜

#php.iniの設定を確認
下記コマンドで確認

```
cat /etc/php.ini | grep error_log
```


```:出力結果
error_log = /var/log/php/php.log
```

おお、ここで設定されているようでした。
妄想プロダクト室「星の家」の構想プロトタイプ

![hoshinoya.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420554/d8d6b1ad-2fc7-2560-1492-feaddace6b0d.jpeg)
# はじめに
おっさんになったからだろうか、、、、。
最近、やけに”癒し”を求めるようになった。
（満員電車はもう勘弁してくれ）

無趣味な私は暇さえあれば、スマホを意味もなくダラダラ見てしまう。
このような行為は休憩と言わず、むしろ疲れてしまう。
私は自分を癒すために「光の癒しプロダクト」をつくってみることにした。

# 「星の家」概要
「光の癒しプロダクト」＝「星の家」。
全てを想定通りにつくることは難しかったため、構想の一部をプロトタイプ。
自分の位置でみれる星座情報によって、表現される光が変化する構想で、
その構想をプロトタイプ。
（そのため、表現部分は仮である）

## 素材
- node.js
- Line messenger api
- 星をみる人api
- obniz
- サーボモータ
- （ランプシェードのシェード部分）
- （照明）

## 構成図
![image_2.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420554/45805297-e121-454f-f128-38c5e2551497.jpeg)

## 使い方
###①位置情報の入力
<img width="375" alt="iOS の画像 (1).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420554/6c9f9448-25b1-bd96-ea51-1008b32dd193.png">
<img width="375" alt="iOS の画像.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420554/c2463874-0efc-2bf2-b4e2-ddaae181a5a3.png">

###②モーター起動
![名称未設定-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420554/3142bbd5-8fad-b8c1-401c-a754dbe431a5.jpeg)

# 今後・その他
###現在の日時を取得したい。
現在、固定の日時で記述されてしまっています。
星座は日時が大事なので、可変にしたい。
###サーボモータの処理を止めたい
サーボモータの処理が終わらず、一回の位置情報の入力で動き続けます。
###肝心のobnizからの出力部分を考察、制作したい。
今回は概念のプロトタイプなのですが、具体的にプロダクトとして完成形にするならどのような表現にするか考えていきたい。
###ソース
![スクリーンショット 2019-06-26 20.36.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420554/ffd77465-aec3-8745-7ebc-fbffccd950c1.png)
Slack カスタムインテグレーションが非推奨へ

# TL;DR
- カスタムインテグレーションが非推奨になった
    - 今までIncoming Webhook、Slack Commands、Botsなどを設定していた場所
- 「Start Building」から「App」を作成して、ワークスペースにインストールするという方法が推奨
- なおインテグレーション枠は消費する

詳しくは以下をどうぞ。

# はじめに
Slackのカスタムインテグレーションのページに行くと、以下のように注意書きがありました。
![Slackカスタムインテグレーション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170435/1e07db64-57aa-baa7-76c3-a62e9f4a600f.png)

「アプリとの置き換え」のリンクは[こちら](https://api.slack.com/custom-integrations#migrating_to_apps)なので、このリンク先（英語）を読めば解決する話ではありますが。

# カスタムインテグレーションとは
よくSlack Botに利用される、メッセージを外部から投稿できる `Incoming Webhook`
逆に、Slackに投稿されたメッセージを外部に飛ばす `Outgoing Webhook`
Slackに1ユーザとしてBotを追加する `Bots` （カスタムBot）
スラッシュコマンドを独自に作成できる `Slash Commands`
などです

**これらの設定は場所を変えて存在するので、今後、Slack Botを作るときにIncoming Webhookを使えない、というわけではありません**

ただ今後この辺の設定を行うときは、カスタムインテグレーションとして行うのは避けたほうがいいとは思います。
削除するかも、と書かれているので。
（ずっと前に非推奨になったLegacy Token(旧名忘れました)は今でも一応使えているので、今回のこれもすぐ削除されることはないとは思いますが）

# 今後の設定について
では今後、どこから設定すればいいか、ですが、[ここ](https://api.slack.com/)です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170435/dafeeedd-d319-ca7e-db38-c28b67966e98.png)

この「Start Building」からAppを作成する、という流れで設定していくことになります。

Appを作って、ワークスペースにインストールする、という感じですね。
このApp、インテグレーション枠を1つ消費します。

今までは `Incoming Webhook` というインテグレーションを1つ追加すれば、その中の設定がいくら増えようともインテグレーション枠は1つのままでしたが、この方法だと枠を消費します。
（なお、Botsは元から枠を消費していました）

# App（アプリ）について
この「App」とはどのようなものか、軽く書いておきます。
（詳しくは、そのうち書くかもしれません）

一言でいうと、「インテグレーションを自作する」です。

Appの名前を決め、次にAppの各種設定をします。
先ほどの、「Start Bulding」で名前と開発用ワークスペース（Appを利用したいワークスペース）を決めた次の画面がこちら。
![api.slack.com_apps_AKWF5R24U_created=1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170435/9fbe9fac-b864-8807-be37-9250978c9e58.png)

この画面でわかる人はだいたいわかると思いますが、この画面で、Appの設定をします。
- Incoming Webhookだけ使う
- Slash Commandsだけ使う
- Botとして導入するための権限設定
などなど

# さいごに
今後、Slack Botを作る人や、今使っている人は、「Start Building」からAppを作成して、ワークスペースにインストールする、という方法で行いましょう。（公式の推奨なので）
プラグインのUI

#前提

[kibana Plugin開発（Javascriptの自習）](https://qiita.com/nekolder/items/7a821ddd19903f9e2a1e)の続きの話で、EuiTableの話しです。

#EuiFramework
プラグインのmain.js内でEuiXXXというものをインポートしています。

```javascript:main.js
import React from 'react';
import {// このEuiXXXX部分
  EuiBasicTable, 
  EuiPage,
  EuiPageHeader,
  EuiTitle,
  EuiPageBody,
  EuiPageContent,
  EuiPageContentHeader,
  EuiPageContentBody,
  EuiText
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
  :

```

プラグインを作るときにテーブル表示を簡単にできるということで、EuiBasicTableを使いました。

https://elastic.github.io/eui/ を見るといろいろあります。
テーブルの表示でonlineの部分でEuiHealth を使って色が変わるアイコンを使っていました。
Propの説明で、カラムのところでfieldは、itemsに指定したアイテムの名前で、nameは表示する名称とのこと。
nameは、displayの方がいいと思ってしまう。。。


indicesを表示する場合にhealthというカラムでgreen,yellow,redと値をとります。なのでこれをそのまま利用すればアイコン化できます。
columnsの定義で、healthの部分を以下のよういすると、アイコンも表示してくれるようになります。
2つ目の{health}を書かなければアイコンのみになります。

```javascript
const columns=[ // テーブルヘッダ
 { field:'health', name:'health',
      render: helath => {
        return <EuiHealth color={health}>{health}</EuiHealth>;
      },
 },
 { field:'status', name:'status', },
 { field:'index', name:'index', },
 { field:'uuid', name:'uuid', },
　：
```

とりあえず、EuiFrameworkでかなりのことができることがわかりました。
obnizとLINE botで好きな女優に腹筋を応援してもらう

[前回](https://qiita.com/karu/items/87e79eeb3c3a0892d00a)はobnizと距離センサーで、腹筋カウンターを作りました。
今回は好きな女優が腹筋を応援してくれるっていうのを作ります。
と言ってもBingの画像検索APIを利用して画像を取得して
腹筋する毎に取得した画像をボットから流すというやつです。

#作る

画像は[Bing Image Search](https://docs.microsoft.com/ja-jp/rest/api/cognitiveservices-bingsearch/bing-images-api-v7-reference#countrycodes)を利用して取得します。
最初**cc**という検索結果を取得する国を指定していなかったせいか
全然知らないおじさんの画像とか出てきて困りました。

実装したファイルは以下3点

- server.js(ボットサーバー)
- Fukkin.js(obnizを利用した腹筋カウンター)
- searchImg.js(画像検索用)

**server.js**
長いのでexpressでlineからのwebhookを受けた時の処理のみ抜粋。
「○○○でふっきん」をトリガーに「○○○」を画像検索しています。
腹筋回数は10としています。

```js
async function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  const message = event.message.text
  const replyToken = event.replyToken
  const userId = event.source.userId

  if (/^.+でふっきん$/.test(message)) {
    await pushMsg(userId, 'OK準備するね！')
    const q = message.replace(/(.+)でふっきん$/, '$1')
    const images = await searchImg(q, 10)
    await wait(3000)
    await pushMsg(userId, '腹筋スタート!')
    await wait(1000)
    new Fukkin(10, async count => {
      const img = images.pop()
      await pushMsg(userId, `${count}!`)
      await pushMsg(userId, countReply[count - 1])
      console.log(img)
      await client.pushMessage(userId, {
        type: 'image',
        originalContentUrl: img,
        previewImageUrl: img
      })
    }, async count => {
      await pushMsg(userId, `おつ！`)
    })
    return Promise.resolve()
  }

  if (message !== 'ふっきん') return reply(replyToken, '腹筋しようよ〜')

  await pushMsg(userId, '待ってました！')
  return reply(replyToken, '誰に応援してもらう？')
}
```

**Fukkin.js**
こちらは[前回](https://qiita.com/karu/items/87e79eeb3c3a0892d00a)と同じです。

**searchImg.js**

```js
const request = require('request')
const _  = require('lodash') 
const subscriptionKey = 'サブスクリプションキー'

function searchImage(q, howManyGet){
  let options = {
    method: 'GET',
    baseUrl: 'https://api.cognitive.microsoft.com',
    url: '/bing/v7.0/images/search',
    qs: {
      'q': q,
      'cc': 'JP',
    },
    headers: {
      'Accept-Language': 'ja,en',
      'Ocp-Apim-Subscription-Key': subscriptionKey
    },
    json: true
  }
  return req(options, howManyGet)
}

function req(options, howManyGet) {
  return new Promise(resolve => {
    request(options, (err, res, body) => {
      const images = body.value.map(item => item.contentUrl).filter(url => /^https/.test(url))
      const shuffled = _.shuffle(images).slice(0, howManyGet)
      console.log(shuffled)
      resolve(shuffled)
    })
  })
}
module.exports = searchImage
```

#成果
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/6Ro_bF8YBsg/0.jpg)](http://www.youtube.com/watch?v=6Ro_bF8YBsg)

#まとめ
もう少し応援されている感が欲しい。
あと、[Face API](https://azure.microsoft.com/ja-jp/services/cognitive-services/face/)を使って、顔の表情でソートして、腹筋の回数が増すごとに徐々に笑顔になっていくっていうのもやりたかったのですが、今回は時間ぎれとなったので見送ります。。
それから、今さらだけど腹筋のカウントするなら加速度センサーを使うべきだったかも。。そういうアプリ結構あるようだし。
今回は以上です！
レガシーJavaエンジニアの（ストリーム + ラムダ式）入門

Java8を現場で使うようになったのでストリームとラムダ式を使うようになった。
調べなくても書けるようになったものを書いていく（随時更新予定）

## 更新履歴
ご指摘ありがとうございます。
2019/07/19：タイトルを変更（ストリームを追加）
2019/07/19：IntStreamの説明を**int型の要素をもつstream**に変更

## 参考
参考になったサイトがあったら追記していく。
[Qiita - Java Stream APIをいまさら入門](https://qiita.com/kumazo/items/284098c530fceb05805c)

## ラムダ式概論
関数インターフェースを使う。
streamを生成して行う。
Java8から使える。
生成操作→中間操作→終端操作の順に処理する。

## 生成操作
理解出来たら増やしていく。

### stream()
Streamを生成する。
サンプルはリストからStreamを生成。

```java
        List<String> list = Arrays.asList("hoge","fuga","poyo");
        list.stream()
```

### IntStream.range(startInclusive, endExclusive)
int型の要素をもつstreamを生成する。`endExclusive`は含まない。
0～9のIntStreamを生成する。

```java
IntStream.range(0, 10)
```

### IntStream.rangeClosed(startInclusive, endInclusive)
int型の要素をもつstreamを生成する。こっちの`endInclusive`は含む。
1～10のIntStreamを生成する。

```java
IntStream.rangeClosed(1,10)
```

## 中間操作
理解出来たら増やしていく。

### filter
条件にマッチした要素だけのstreamを新たに生成する。
偶数だけのstreamを生成。

```java
IntStream.range(0,10).filter(i -> i % 2 == 0)
```

### mapToObj
Objectに変換する。
サンプルは~Integer~ intをStringに変換している。

```java
IntStream.range(0,10).mapToObj(i -> String.valueOf(i))
```

## 終端操作

### forEach
ループ処理。戻り値なし。

```java
IntStream.range(0,10).mapToObj(i -> String.valueOf(i)).forEach(System.out::println);
```

### collect
リストやマップを作成できる。
サンプルはListを作成。

```java
List<String> list = IntStream.range(0,10).mapToObj(i -> String.valueOf(i)).collect(Collectors.toList());
```

### toArray
配列を作成。

```java
String[] array = IntStream.range(0,10).mapToObj(i -> String.valueOf(i)).toArray(String[]::new);
```
### count
要素の件数を返す。

```java
long count = IntStream.range(0,10).mapToObj(i -> String.valueOf(i)).count();
```

## おわりに
随時更新します。
初心者向け！使うと便利なGitコマンド集(commit --amend, stash, diff)

#はじめに
こちらは最近プログラミングを始めたばかりの初心者の方を対象としています。

Gitコマンドは様々なものがありますが、
学習し始めの頃はとりあえずadd、commit、push、pullやbranch、checkoutなど…
本当に基本的なコマンドしか使用していませんでした。
最初はこれらだけでも十分作業できるので問題なかったんです。
でも今思うと基本的なのに全然活用できていなかったコマンド達があるので３種類ご紹介します！
簡単に説明しているので、詳しい内容に興味を持たれたらぜひ調べてみてください！

# 1 .git commit --amend　(コミット名を修正)
コミット名を間違えてしまった場合の修正コマンドです。
とても簡単に修正できるので、謝ったコミット名を諦めてそのままにしたり、わざわざコミット自体を取り消したりする必要はありません！

例として、"add new file"と言うコミット名を謝って"aad new file"としてしまった場合

```
$ git commit -m "aad new file"
```

```
$ git commit --amend
```
このコマンドだけで、直前のコミット名を修正できます。
コマンドを打った後、コミット名を変更するエディターが起動するので、編集して保存するだけです！

# 2 .git stash  (addしたくない変更作業を逃がす)
主にブランチを分けて作業をする際に便利です。
例えばメインであるmasterブランチからAというブランチを切って、とあるタスクの作業をしていたとします。
ところが作業途中で、Aブランチで作業していたタスクよりも優先度が高い作業が出てきたとします。
早くまたmasterブランチから違うブランチを切って作業をしなければなりません。
よし！まずはmasterブランチに移動だ！

```
$ git checkout master

error: Your local changes to the following files would be overwritten by checkout:
        app/controllers/test.rb
        app/views/test.html.slim
Please commit your changes or stash them before you switch branches.
Aborting

```
エラーが出て、
**”変更したファイルがaddとcommitされてないからしてから移動して！”**
と怒られます。
ここで、丁寧にaddしてcommitしてももちろん良いです。
しかし中途半端に変更している状態の場合は、”もう少し変更してからコミットしたい！”とか
”むしろちょっといじっただけだしこの変更分残さなくても良いんだけど！”　と思う場合があるわけです。
その場合に活躍するのがstashです。

**stashは、一時的に変更分を退避させることができます。**
もちろん退避させたデータはまた呼び出すこともできますし、不要であれば削除することも出来ます！
では、早速退避させましょう！

```
$ git stash
```
はい、これだけです！
この後にgit checkout masterをしてみると、ちゃんと移動できるはずです。
stashしたリストを見たい場合は、

```
$ git stash list
stash@{0}: WIP on ブランチ名: stash時のコミット名など
stash@{1}: WIP on ブランチ名: stash時のコミット名など
stash@{2}: WIP on ブランチ名: stash時のコミット名など
```
このように上から最新順に見ることができます。
stashしたデータを戻したければ、

```
$ git stash apply stash@{0}
```
これだけです！{}の中には、リストで確認した該当の番号を指定してください。
他にもstashした履歴を消したり、色々なstashコマンドがあるのですがここでは割愛します。

# git diff (各ファイルの変更箇所を確認)
git statusはステージング前の状態の**変更があったファイル名のみ**を出力するのに対し、
git diffは**変更した各ファイルそれぞれに対して、実際にどこがどう変更されたのか**まで確認することができます。

```
$ git diff
```

このコマンドを打つだけ！
そうすると、まずは変更のあったファイル名の下に、変更箇所が詳しく表示されるはずです！
+表記が追加した内容
-表記が取り消した内容になります。

git diffは様々なオプションがあり、とても便利なのでぜひ興味ある方は調べてみてください！

# さいごに
簡単ではありますが、３種類のコマンドを紹介しました！
基本的だけど、もしかしたら最初は使ってないかもしれないコマンドたちでした！:grin:
ぜひ活用してみてください！
FirebaseCLIでDeployするとき「これ本番に向いてるやんけ！」と気付けるScript

# はじめに

Develop環境にDeployするものを誤ってProduction環境にDeployしてました:sob:と涙を流さないためのScriptをまずは個人使用のため書いてみました。(ゆくゆくはチームに浸透させるのが目標)

Script書かずとも以下のようにDeploy先がコマンド実行後に表示されるのですが、
ここで気付けたとしても冷や汗もので心に良くない。。。と思っているため書いた次第です:smile:

```
=== Deploying to 'xxxxxx-development'...
```

個人的に、コマンドを覚え何度かDeployしてくると`Depoly慣れ`により油断してやらかさないようにしてる予防線みたいなものなのですがこんな感じのScript書いてますという記事です。


# Script
基本的には、`firebase use`でDeploy先を確認し`production`だった場合は確認を取り
Deployしたいのはall,function,rule,hostingのうちどれなのか、functionの場合は全ての関数なのか指定した関数なのかといった具合に対話形式でDeployできるようにしてます！

```shell
#!/bin/bash

function main() {
    local DEPLOY_TARGET=`firebase target`
    if echo $DEPLOY_TARGET | grep "production"; then
        echo "Do you want to deploy in a production environment?(y/n)"
        read answer
        case $answer in
            y | Y)
                select_deploy_part
            ;;
            n | N)
                echo "bye!"
            ;;
        esac    
    else
        select_deploy_part
    fi
}

function check_target_function() {
    echo "If you want to deploy only a specific function, please enter the function name"
    echo "If you press Enter without input, all functions will be deployed"
    read function_name
    if [ $function_name ]; then
        firebase deploy --only functions:$function_name
    else
        firebase deploy --only functions
    fi
}

function start_deploy() {
    case $1 in
        firestore:rules | hosting)
            firebase deploy --only $1
        ;;
        functions)
            check_target_function
        ;;
        all)
            firebase deploy
        ;;
        *)
            echo "bye"
        ;;
    esac
}

function select_deploy_part() {
    echo "Please select the target number you want to deploy"
    local PART_LIST="firestore:rules hosting functions all"
    select selection in $PART_LIST
    do
          if [ $selection ]; then
                  start_deploy $selection
            break
          else
            echo "invalid selection."
            echo "bye!"
            break
          fi
    done
}

main


```

# 最後に

使っていくうちにもっと良い方法を見つけたり,他の方からご指摘いただいた内容を反映してどんどん進化させていくので気になる方はぜひWatchしてください:smile:

[DeployScript](https://github.com/yotsu12/DeployScript/blob/master/deploy.sh)
wordpressでCAPTCHAの認証画像が表示されなくなった場合の対処法

Qiitaで空前のブームなっているGCPを使用した永久無料のWordPress環境構築を、以下の記事を参考にして作ってみました。
[1時間で出来る！最強のWordPress環境構築(永久無料)](https://qiita.com/ryuta69/items/dbb0db5cf7099b7a7cc4)

記事を参考にして環境構築を進めている途中に、WordPressのダッシュボード画面に遷移したところ下記のようにCAPTCHA画像が表示されなくなってしまい、ログインをすることができなくなってしまいました。

色々試行錯誤ログインができましたので、同じ状況になっている方の参考になりましたら幸いです。

![wordpress1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60753/81d0b780-9338-24a7-6268-be2b351100a2.png)



##原因
原因は「SiteGuard WP Plugin」を導入したことによってどうやら認証画像を読み込むことができなくなってしまい、画像ファイルが壊れたように表示されたみたいです。



##解決方法
###GCPにアクセスしコンソール画面を開く
まずは下記リンクからGCPにアクセスをします。
[Google Cloud Platform](https://console.cloud.google.com/?hl=ja)


GCPの画面にアクセスをしたら、左上にある三本線のメニューから「ComputeEngine>VMインスタンス」で下記画像のページに移動します。
そして、赤い枠部分の「SSH」をクリックしましょう。
![wordpress2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60753/aa628ea5-771d-1f1c-1c33-61c8f8f5c0f1.png)

「SSH」をクリックしたら、黒い背景のコンソール画面が開くと思いますので下記コマンドを入力し、ディレクトリを移動し、「siteguard」のプラグインが格納されているディレクトリが存在するか確認しましょう。

```
cd /home/bitnami/apps/wordpress/htdocs/wp-content/plugins
ls -l siteguard
```

「siteguard」のディレクトリがあることを確認できたら、下記コマンドを打ってディレクトリ名を変更しましょう。
変更することで強制的にプラグインが無効化することができます。

```
sudo mv siteguard siteguard_1
ls -l siteguard_1
```
この状態でWordPressのログイン画面に遷移すると、CAPTCHAの認証画像が表示されると思います。
なので、表示された認証画像の文字を入力してログインしましょう。

###「SiteGuard WP Plugin」の設定変更
ダッシュボードに遷移したら、「SiteGuard WP Plugin」の設定画面に移動します。
下記画像の通り、左のメニューにある「SiteGuard」をクリックし、「画像認証」をクリックします。
![100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60753/185a622a-dcac-3454-0b0a-f92314404776.png)

画像認証設定画面に遷移したら、下記画像の赤枠部分をクリックし「OFF」にします。
![101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60753/2d7f2150-f34c-2612-3ba0-0e293912e4cb.png)

これで、画像認証が無効化されログイン画面に画像が表示されなくなります。

###ディレクトリ名を元に戻す
最後にプラグインが格納されたディレクトリの名前を無効化するために名前を変えていたのを元に戻します。
先ほど表示した黒いコンソール画面に下記コマンドを入力し元に戻しましょう。

```
sudo mv siteguard_1 siteguard
ls -l siteguard
```

元の名前のディレクトリにしたら完了です。


##最後に
画像認証を無効化にしたままだと、セキュリティ的に問題があるのでreCAPTCHAやGoogleAuthenticatorなどのプラグインをいれておきましょう。

参考URL
[Google AuthenticatorプラグインでWordPressブログを2段階認証に設定する方法](https://www.suzukikenichi.com/blog/how-to-set-2-step-verification-for-wordpress/)
[reCAPTCHA v3+WordPressの設定方法、フォームへの設置手順](https://virusee.net/recaptcha-v3-install/)
Ubuntuのターミナルを Zsh + oh-my-zsh で使いやすく(備忘録)

**環境** ubuntu 18.04
**完成状態**↓
![Screenshot from 2019-06-26 21-56-38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448172/a3b3ec7d-db1a-1304-6de8-55b72481bf0a.png)

# zshをインストールしてデフォルトシェルにする
```
sudo apt update
sudo apt install zsh powerline fonts-powerline
chsh -s /bin/zsh
```
ログアウト＆再度ログインしたらデフォルトシェルがzshになってるはず
powerlineはoh-my-zsh:agnosterで必要

# oh-my-zshをインストール

- githubからソースコードをclone
- zsh confファイルのコピー
- テーマを変更(`ZSH_THEME="robbyrussell"`を`ZSH_THEME="agnoster"`に変更)
- PC名が長いので非表示(`prompt_context () { }`を.zshrcの末尾に追記)

```
git clone https://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
gedit .zshrc
```


## [依存解決]VSCodeのターミナル文字化けを直す
![Screenshot from 2019-06-26 20-36-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448172/82ad6c72-5b19-979f-25b9-4b21a6029329.png)

`Ctrl`+`,`で設定を開き，機能>ターミナル>Integrated: Font Familyに`ubuntu mono,PowerlineSymbols`を記述
![Screenshot from 2019-06-26 20-50-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448172/8b1151f9-6edb-d089-5ea7-fcd43403c859.png)
ターミナルを再起動して解決
![Screenshot from 2019-06-26 21-40-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448172/860a3c10-ce6a-d01a-cefa-2dd27c1d35cc.png)

# 参考サイト
https://dev.to/mskian/install-z-shell-oh-my-zsh-on-ubuntu-1804-lts-4cm4
https://stackoverflow.com/questions/28491458/zsh-agnoster-theme-showing-machine-name