OmniAICreator/Qiita-1.07M huggingface dataset:
Docker + WordPress 環境構築(Mac)

# 概要
wordpressの環境をdockerで用意する方法をまとめていきます。

# 前提
* mysql 5.7
* Docker for Mac
無ければ[Dockerの公式](https://hub.docker.com/editions/community/docker-ce-desktop-mac)からインストール

# コンテナ作成

それではdocker-compose.ymlでコンテナを作成していきます。

適当にディレクトリを用意してdocker-compose.ymlファイル作成

```
$ mkdir docker
$ cd docker
$ vim docker-compose.yml
```

docker-compose.ymlファイルを下記のように記述

```docker-compose.yml
version: '3.3'

services:
   db:
     image: mysql:5.7
     ports:
      - "3306:3306"
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: root
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     image: wordpress:latest
     depends_on:
       - db
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
       WORDPRESS_DB_NAME: wordpress
     volumes:
       - ./wordpress:/var/www/html
volumes:
    db_data:
```

Sequel ProでDBに接続したいので今回はmysql5.7系でインストールします。８.0系はSequel Proのバージョンによって動かないことがあるので対策が必要です(下記リンクを参考)

[MySQL8.0.x に Sequel Pro で接続する](https://qiita.com/ucan-lab/items/b68db1db931c954da921)
[MySQL8.0でSequel Proを使えるようにする](https://qiita.com/KeisukeToyota/items/1c128729127feed7597f)

またSequel Proに接続するためにpostsを追記していますが

```
ports:
 - "3306:3306"
```

3306が既にlocalでmysqlが起動している場合があるので、3306以外を使う必要があります。

```
volumes:
  - ./wordpress:/var/www/html 
```

上記はDockerのバインド・マウントを利用して、./wordpress(ホスト側のディレクトリ)と/var/www/html以下のwordpressのファイル群(コンテナ側のディレクトリ)を接続しアクセスできるようにします。

このバインド・マウントによりホスト側のwordpressのファイルを編集するとコンテナ側にも反映させることができます。

参考:
https://qiita.com/mom0tomo/items/7e611ac829863d4c5c82

docker-compose.ymlを作成したディレクトリ内でコンテナの作成と起動

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

コンテナが生成されているか確認


```
$ docker-compose ps
```

```
       Name                  Command           State            Ports         
------------------------------------------------------------------------------
docker_db_1          docker-entrypoint.sh      Up      0.0.0.0:3306->3306/tcp,
                     mysqld                            33060/tcp              
docker_wordpress_1   docker-entrypoint.sh      Up      0.0.0.0:8000->80/tcp   
                     apach ...   
```

生成、起動されているのでブラウザから[http://localhost:8000/](http://localhost:8000/)アクセスすると...

![スクリーンショット 2019-12-01 16.01.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379873/a1cedc56-312c-1b99-65f1-03b36a0f2bcc.png)

wordpressの画面が見れました。

# Sequel Proで接続

最後にDB管理ツールのSequel Proでmysqlコンテナに接続していきます。
![スクリーンショット 2019-12-01 16.13.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379873/2ea72d0a-0a23-e89f-25de-93a97da815c3.png)
docker-compose.ymlのDBの情報を入力して接続すると成功し

![スクリーンショット 2019-12-01 16.14.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379873/a2e47049-8d4d-afd5-28af-bdf8822d50e4.png)

デフォルトでテーブルがいくつか確認できます。


# 最後に

今回は以上です。

自分用のwordpressの環境が整ったので何か作成していきます。
ありがとうございました。


# 参考
https://qiita.com/mom0tomo/items/7e611ac829863d4c5c82
https://qiita.com/ucan-lab/items/b68db1db931c954da921
Microsoft Teams Unitalk なお話

# 本投稿は・・・

[Office365 Advent Calendar 2019](https://adventar.org/calendars/3960)
の投稿となります！

# 弊社では・・・

設立当初から固定回線を引いていません。
代表電話番号は、クラウドの電話サービスを使用しており
社長の携帯にアプリを入れてもらって、対応しているスタイルでした。
社長以外のメンバーへの問い合わせについては
いったん社長が受電し、その後各メンバーにMicrosoft Teamsを使用して伝達後、折り返し個人の携帯などから連絡するというやりとりをしておりました。

# ところが・・・

会社の知名度が向上したことなどから、着電数が増加し
社長の負荷がが増大しておりました。
かといって、固定電話をいちいち引くことも厳しい。
というかやだ。

# そのタイミングにこいつが発表されたのです！

Unitalk!!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/f509f7f0-623e-a8b7-2c79-d8d80c4b6387.png)

弊社は速攻で飛びつき、問い合わせました！！
そして紆余屈折を経て
9/4に導入することができました。

# Unitalkを導入する上で必要なもの

- Microsoft Teams (Office365)
- 電話システム （Office365）
- Softbank Calling for Office365 (Softbank)
- Unitalk (Softbank)

# 申し込みから開通まで

1. 規定の申込用紙が会社の指定住所に届く
2. 記入し、PDF化してメールにて送付
3. 原本をSoftbankに送付（受領により住所確認完了）
4. 開通時にメールにて連絡

# 開通後の設定

Skype for Business 管理センターより、開通した番号が一覧で表示されていますので
電話システムを持っているアカウントに割り当てることで利用することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/06671c66-3e8f-8d3f-0077-02e43ff3ddb6.png)

# Unitalkを入れてよかったこと

## 03や092といった一般電話番号を取得できる

これは本当に一番大事な要件！
これがなければ導入していない。

## Teamsから外線がかけられる！着電できる

アプリを別途起動しておく必要はなく、Teams通話と同じように
外線からの着電が通知されて、そのまま通話することができる。
また、逆に発信も、Teamsにて人を検索して電話するのと同じ感じで発信することができる。

## Office365 電話帳データを何もせずに利用できる

スマートフォンにOffice365の電話帳を同期する際は、スマホ内部アプリの電話帳からOffice365にアクセスして同期させる必要があったり、多要素認証を入れたアカウントだと、専用パスワードをわざわざ作る必要があったりと面倒。
だけど、Microsoft Teamsは、Office365の電話帳に同期されており、そのデータをそのまま着信の通知や発信に使用できるため、非常に楽。

## 海外から受発信可能

海外にいた場合、携帯電話の番号は一切使用できず、また、ほかのクラウド電話サービスも、海外での利用は使えなかったり、音質が非常に悪かったりすることが多い。
しかし、Teamsの場合は、端末とTeams間は、今いる国から一番近いリージョンで接続されており、そこから日本国内リージョンとは高速な通信網でつながっており、その先で国内通話という流れとなるため、音質が非常によく、遅延も全く感じさせないレベル。
これには正直非常に驚いた。

## 実は転送が可能

通話中の電話を、別のメンバーに転送することができる。
なお、転送先のメンバーは、<font color="DeepPink">**Unitalkはおろか、Softbank Calling、電話システムも必要としない。**</font>


というわけで、Unitalk めちゃめちゃ便利な製品です！
法人だけしか加入できないという問題はありますが
これから、Cloud PBXを導入したいという会社さんにはマジでおすすめですよ！

# 本件の内容について・・・
第２８回 Office365勉強会にて、デモを交えた登壇を行う予定です。
こちらのコミュニティページを常にチェックしておいてください！
[Japan Office365 Users Group]()
まだgit checkout でブランチ名をコピペしているの？

# 爆速で簡単にgit checkoutをしたい

個人的にvimを使い出してから,vimmerになってきた自分ですがvimを使えば使うほどマウスやトラックパッドを触っている時間がどうしても鬱になってしまう...

gitのブランチ移動も毎日のようにしますが

git branch -> コピペ -> git checkout `ペースト`

なんてことしていたらそれだけで集中が途切れてしまいます.

なんとかできないものかと頭を抱えていたある日...

## pecoとかいう神ツールがあった

[え、まだpecoを使ってないの？？？ - Qiita](https://qiita.com/vintersnow/items/08852df841e8d5faa7c2)

[公式レポジトリはこちら](https://github.com/peco/peco)

こちら何かと言うと標準出力をインタラクティブにgrepしてくれることができます.

`$ brew install peco`

で簡単にインストールできます.

実際使ってみるとこんな感じ↓↓↓↓
![f77e0f9704d7240cf473004d8c0d65a5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105153/1c4a8dcf-2b28-9122-ff3e-7f6a976d5b82.gif)



標準出力を pipe `|` で `peco` に渡してあげるとあいまい検索でgrepできます.

だからなんだって感じですけどこれを `git checkout` に応用してみます.

# git branch | peco | xargs git checkout

`master` から `develop` にcheckoutしてみます.

![d3260e31251cabbccb7803f3bdbf8548.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105153/e7408fff-37af-cfc1-2484-bc1f26cfedaf.gif)

こんな感じで一度もマウスに触れることなく,スムーズにcheckoutを終えることができました.

iterm2なんかを使ってると,コピペがうまくできなくてマウスでカーソル選択して何度も何度も `command + c` を連打して...

というストレスフルなcheckoutとはもうおさらばです.

何度も使うコマンドってやっぱりできるだけストロークは少なく,快適に終えたいですよね.

とはいえ流石に毎回 `git branch | peco | xargs git checkout` とか打ってられないので

お好みのshell configにaliasを貼っておくと便利です.
僕は少々乱暴ですけど

```zsh
alias br='git branch  | peco | xargs git checkout'
```

ってやってます⤴️
HTMLテーブルのborder優先順位

## 経緯
HTMLテーブルのスタイルを”border-collapse: collapse”にしたとき
borderをセルをフォームの入力によって色を変えたら上手くいかなかった。
調べてみるとスタイルの指定の仕方で優先度があったので備忘録として残します。

## 結論
優先度順
1．**border-hidden**
2．**border-width**（太いほど優先）
3．**border-style**（double、solid、dashed、dotted、ridge、outset、groove、insetの順に優先）
4．上記が同じ場合はテーブル内でより左にあるもの、上にあるものの順で優先されます。
5．**border-style: none**　（もっとも優先順位の低い状態）

以上、閲覧ありがとうございました。
Corsera( How to Win a Data Science Competition: Learn from Top Kagglers)メモ

#気になった部分まとめ
1. Families of ML algorithms
・Linear
　⇨logistic regression or SVM
・Tree-based
・kNN
・Neural Networks
これがアルゴリズムのベース
ここからSVMとか手法が色々別れる

2. Why is it called random then?
Say our dataset has 1,000 rows and 30 columns. There are two levels of randomness in this algorithm:
この文章のAt column levelのところで、ランダムフォレストは列でもランダムに取ってきますって言っているけどそうなの？
行でランダムなのは知ってたけど、列は知らなかった。

3. When is a random forest a poor choice relative to other algorithms?
ここの文章は覚えておいて良さそう、顧客とかに説明する際ありそう。
1〜3まで、
https://www.datasciencecentral.com/profiles/blogs/random-forests-explained-intuitively

4. differences between random forests and extremly random forests. 
https://yoshoku.hatenablog.com/entry/2019/05/02/005231
#Rails での ransackable_scopes の使い方と SQLの例

```rb
class User
  def full_name
    "#{first_name} #{last_name}"
  end

  private

  def self.ransackable_scopes(auth_object = nil)
    %i(full_name_like)
  end
end


```

こんな使い方してます

他のDBカラムからの検索と、つじつまをあわせて、実装的にレールに乗るために

```rb
User.full_name_like('A').to_sql
=> "SELECT `users`.* FROM `users` WHERE (((last_name LIKE '%A%') OR (first_name LIKE '%A%')) OR (CONCAT(`last_name`, `first_name`) LIKE 'A'))"

```

すごく頑張ってる感

ありがとうransack

おめでとうransack

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
dlib, cv2のインストール

最近はコマンドさえ知っていれば一瞬でできるようになりました。

## cv2


```python:
pip install opencv-python
```

##dlib
Dockerfileに書くなら以下のようにする。

```bash:
RUN apt-get update && apt-get upgrade -y && \
    apt-get install -y --no-install-recommends \
    curl \
    cmake \
    cmake-curses-gui \
    cmake-gui \
    git \     
    gobject-introspection \
    libbz2-dev \
    libcairo2-dev \
    libgirepository1.0-dev \
    libreadline-dev \
    libsqlite3-dev \
    lbssl-dev \
    cmake \
    

RUN pip install dlib
```
【Gang of Four】State

#State
**[目次](https://qiita.com/Tonkachi0620/items/03986742efbb7e3a9bbe)**

よく`XXXStatus`のような状態を管理するプロパティを持たせ、`switch(XXXStatus){ // caseにより色々な処理を行う }`ような実装をすることがあると思います。
状態が増えるとswitch文が長々と続くことになり読む側も大変になっていくのを、状態１つ１つをオブジェクトにすることによりスマートにしようというのが本パターンの主旨だと考えています。

##目的
オブジェクトの内部状態が変化したときに、オブジェクトが振る舞いを変えるようにする。クラス内では、振る舞いの変化を記述せず、状態を表すオブジェクトを導入することでこれを実現する。

##構成要素
・Context 色々な状態があるクラス
・State 状態の抽象クラス
・ConcreteState 状態の具象クラス

##実装
自動販売機を実装することにします。
実装する自動販売機の状態としては以下の2つの状態と2つの操作があることと、商品の価格は一律100円とします。
状態
・商品の価格未満の金額が入金されている。
・商品の価格以上の金額が入金されている。

操作
・入金する。
・商品のボタンを押す。

###State 状態の抽象クラス
```State.kt
package state

interface State {
    fun coin(v: VendingMachine)
    fun push(v: VendingMachine)
}
```

###ConcreteState 状態の具象クラス
商品の価格未満の金額が入金されている状態を表すクラス

```LackState.kt
package state

class LackState: State {
    override fun coin(v: VendingMachine) {
        v.insertMoney(50)
    }

    override fun push(v: VendingMachine) {
        v.errorMessage()
    }
}
```

商品の価格以上の金額が入金されているクラス

```SufficientState.kt
package state

class SufficientState: State {
    override fun coin(v: VendingMachine) {
        v.warningMessage()
    }

    override fun push(v: VendingMachine) {
        v.buy()
    }

}
```

###Context 色々な状態があるクラス
抽象クラス

```Context.kt
package state

interface Context {
    fun coin()
    fun push()
}
```

自動販売機具象クラス

```VendingMachine.kt 
package state

class VendingMachine: Context {
    companion object {
        private val lack = LackState()
        private val sufficient = SufficientState()
    }

    private var state: State = lack
    private var money = 0

    override fun coin() {
        state.coin(this)
    }

    override fun push() {
        state.push(this)
    }

    fun warningMessage() {
        println("これ以上の入金は不要です。")
    }

    fun errorMessage() {
        println("必要な金額が投入されていません。")
    }

    fun insertMoney(m: Int) {
        println("お金を投入しました。")
        money += m
        if (money >= 100) {
            state = sufficient
        }
    }

    fun buy() {
        println("飲み物を取り出し口からお取りください。")
        state = lack
    }
}
```

###使う人

```Client.kt
package state

class Client {
    init {
        val v: Context = VendingMachine()
        v.coin()
        v.push()
        v.coin()
        v.coin()
        v.push()
    }
}
```

###出力結果
```
[out-put]
お金を投入しました。
必要な金額が投入されていません。
お金を投入しました。
これ以上の入金は不要です。
飲み物を取り出し口からお取りください。
```

`Context`型の`VendingMachine`クラスのインスタンスを生成する`Factory`クラスを実装するとよりよくなると思います。
Mathematical notations in deep learning papers (1)

# Norm

```math
{ \left\| z\left( x \right) -e \right\|  }_{ 2 }^{ 2 }
```

|| in mathematical notation means matrix norm. The number on the right bottom means p-norm. In the above example, it's a 2-norm or L2 norm. The 2 on the upper right means square.

### Reference
http://mathworld.wolfram.com/VectorNorm.html
http://mathworld.wolfram.com/MatrixNorm.html
https://mathtrain.jp/lpnorm
https://scicomp.stackexchange.com/questions/2822/what-norm-to-choose-when
自分の書いたコードの処理速度について考えさせられた話

## 近況
AtCoderの問題を解いて、コーディングの練習をしていますが、
最近はC問題にも手を出し始めました。
それに伴い、A・B問題ではあまり気にしなくてよかったことを気にしなくては行けなくなってきました。

##処理速度について

そう、それはプログラミングの処理速度です。

分岐や繰り返し文を必要以上に書いてしまうと、
入力値の桁が大きすぎて、制限時間以内に処理が終わらず不正解となってしまいます。

プログラミングの勉強のため読んだ本でも、仕事でも、
**「分岐や繰り返しは多くなるとよくない」**と散々聞いてきましたが、
「ネストが深くなって読みにくくなるくらいでしょ？」
「別に何億とかの処理繰り返すわけでもないし、for文の中でさらにfor文回しても問題ないでしょ？」
くらいに思って、処理を最小限にする・無駄な計算はしない、ということはとりあえず二の次に考えていました。

##何で躓いたか
それを考えなければ行けなくなったのが、以下の問題

[AtCoder contest127 -C-Prison](https://atcoder.jp/contests/abc127/tasks/abc127_c)

こちらの問題
N&nbsp;M
L1&nbsp;R1(例:1..3)
L2&nbsp;R2(例:2..4)
⋮
LM&nbsp;RM

という入力値が与えられるので、M 行存在するL..Rの数字の中に、
いくつ重複が存在するかを数える問題です。

例えば、上の例だと、{1,2,3}と{2,3,4}の中には、
重複している数字は3なので、答えは1となります。

##最初どうやって解いたか
では、この問題に私が最初どう解いたかというと、
以下のようなコードです。

```sample.rb
_n,m = gets.split(' ').map(&:to_i)

can_pass = [] 
existed = []
(m).times do |a|
    l,r = gets.split(' ').map(&:to_i)
    if a == 0
        existed = (l..r).to_a
    else
        can_pass = (l..r).to_a
        existed = can_pass & existed
    end
end
puts existed.length

```
変数existedとcan_passの中身を比較して、
重複している部分をexistedに残していって、
最後まで残った数字の数を数えるという方法です。

sampleでも全部期待している値が出たから、
これは正解だろうと思って提出しましたが、
結果がこちら。

<img width="731" alt="スクリーンショット 2019-12-01 16.15.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521445/2cb94b80-6045-16b7-7861-d10ab96cd669.png">

見事に制限時間をオーバーしております....

##何が問題か
処理速度についてあまり今まで考えたことがなかったので、正直困りました。
「そんなポンポン解放思いつくわけないだろう...」と。

この解き方の何が悪いかと考えてみると、
M回(最大10^5回)繰り返して、1≤Li≤Ri≤N(最大10^5個)の数字を検索して、いるため、
M*N回文処理が行われていることが問題でした。

##どのように解決したか

そこで私がどのように解いたか、というのが
以下のような方法です。

```sample.rb
_n,m = gets.split(' ').map(&:to_i)
l = []
r = []
m.times do |a|
    single_l,single_r = gets.split(' ').map(&:to_i)
    l << single_l
    r << single_r
end
array = (l.max..r.min).to_a
puts array.length

```

まずLとRをそれぞれの配列に格納し、
Lの最大値とRの最小値、つまり、M行存在するL..Rの数字に重複している数字を、
数えて来るという方法にしました。
これにより、処理を行う回数は、M回となるので、
無事、制限時間内に回答が出力されるようになりました。

##学び

解説を見てみると、他の解放もあるようでしたが、
すっと頭の中に入ってこなかったため、自分の解法しか理解できていないのですが、
別のやり方でもM回の処理で回答を出力することが可能なようです。

問題文を見て、頭の中で回答を考えて、コードを書くとなると、
どうしても原始的に1から10まで、
問題に書かれている処理を実装しようとしがちです。

ですが、そのまま処理すると必要以上に計算に処理がかかってしまったりすることがあるため、
出来るだけ無駄をなくすためにできる処理の方法がないかということを、
常々考えながら、コーディングしていくことが大事だと感じました。

他にもっと良い解法があるのか、他の人の回答を見て勉強しようと思います。
rails での enumと、日本語化のやり方

# enumの実装と日本語化
某プログラミングスクールの課題で、
enumの実装と、対応する日本語化の機能を実装しましたので、
そのやり方を投稿させていただきます。
＜railsでの開発、haml記法を想定しています。＞

※本記事が初投稿です
わかりにくい点が見受けられるかと思いますが、ご容赦ください。。。

# enum実装の経緯
productsテーブル：statusカラム（integer型)の場合
statusカラムに保存されている情報（１、２など）を、変数を用いて表示させたかったが、

　→　DBに格納されている数字で表示されてしまう

例）viewで「@product.status」と記載 → １　が表示される・・・
これを、「@product.status」 → ”新品、未使用” などの日本語へ変換したい

# 実装方法
<前提として>
ruby 2.5.1
rails 5.2.3
なお、enum実装のメリットとしては、下記の２点が大きいと思います
・コードが読みやすくなる
・データの管理がやりやすい　

それでは、段階を踏んで実装をしていきます。

##1. gem の導入

``` ruby
gem 'rails-i18n'
gem 'enum_help' 
```
bundle install　の実行


##2.モデル（product)にenumを記載

```ruby:product.rb
 enum status:{
    '---':           0, #---
    unused:          1, #新品、未使用
    nearly_unused:   2, #未使用に近い
    not_injured:     3, #目立った傷や汚れなし
    bit_injured:     4, #やや傷や汚れあり
    injured:         5, #傷や汚れあり
    bad:             6,  #全体的に状態が悪い
  }
```
今回はselectboxを作成するため、1~6の選択肢として記載。
選択されたstatusは、DBには1~6として格納される。
(記載した英語は、自由で大丈夫です）

##3. ja.ymlに変換したい日本語を記載
###### ※ 　ja.yml　がない場合は、 config>localsの下に作成してください。

```ruby:ja.yml
ja:
  enums:
    product:
      status:
        '---': "---"
        unused: "新品、未使用"
        nearly_unused: "未使用に近い"
        not_injured: "目立った傷や汚れなし"
        bit_injured: "やや傷や汚れあり"
        injured: '傷や汚れあり'
        bad: '全体的に状態が悪い'
```
階層が綺麗になっていないと、日本語化出来ないので要注意

##４.  viewに記載
```ruby:new.html.haml
= f.select  :status, Product.statuses.keys.map {|k| [I18n.t("enums.product.status.#{k}"), k]}
```
Product : モデル名
statsues : カラム名（複数形にしてください）
keys.map {|k| [I18n.t("enums.product.status.#{k}"), k]}
 →　選択肢を１つ１つ取り出して、日本語に変換して並び替えるイメージです。

##5. 変数を表示する場合
statusに1が格納されている前提で、最後に'_i18n'を記載する

```ruby.sample.haml
(enum 実装ナシ）            @product.status 　     →　" 1 "       
（enum実装アリ:日本語変換ナシ）　       〃　　　　　　   　→  ”unused”   
（enum実装アリ:日本語変換アリ）  @product.status_i18n 　→　”新品、未使用”
```

## 最後に
DB設計の段階で、どのようにデータを管理するか、しっかり確認・詰めておくべきでした。。。
最初は、statusカラムの型をstringにしてしまったため、苦戦しました。
チーム開発半ばで、DBからデータを取って来た時に数字で表示されてしまって、
これは何とかしないといけないなと思ったことがスタートでした。

皆様のお役に立てれば幸いです
VCIで親子関係っぽい振る舞いをさせてみる（位置だけ……

#概要
VCIで親子関係使えないの不便ですよね。ということで位置だけですが、親子関係っぽい振る舞いをさせてみました。

#動作
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/YSo6abUoZ3">pic.twitter.com/YSo6abUoZ3</a></p>&mdash; 120 (@120byte) <a href="https://twitter.com/120byte/status/1201040195782504448?ref_src=twsrc%5Etfw">December 1, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#実装
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286581/27cedc74-a1f7-b6d9-a036-5370a6c23c52.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286581/4f2e224d-935e-ae7f-7192-1966c1bd335a.png)※Cube1～3は同じ

```lua
local current = ""
local relation = {"Cube1", "Cube2", "Cube3"}
local localPos = {Vector3.zero, Vector3.zero}
local index = 1

function updateAll()
    SetPos()
end

function SetPos()
    if current == relation[index] then
        -- 子の位置を移動
        for i = index, #relation - 1 do
            local pos = vci.assets.GetSubItem(relation[i]).GetPosition()
            vci.assets.GetSubItem(relation[i + 1]).SetPosition(pos - localPos[i])
        end
    else
        -- 子の位置を更新
        local parent = vci.assets.GetSubItem(relation[index]).GetPosition()
        local child = vci.assets.GetSubItem(relation[index + 1]).GetPosition()
        localPos[index] = parent - child

        if index < #relation - 1 then
            -- 次の子へ
            index = index + 1
            SetPos()
        else
            index = 1
        end
    end
end

function onGrab(target)
    current = target
end

function onUngrab(target)
    current = ""
end
```

#捕捉
currentは掴んでいるオブジェクトの名前が入るので、掴んでいるオブジェクトの子に対して、位置を移動するか、ローカル座標？の更新をします。relationには先頭から親～子の順で名前を入れておきます。localPosは子になるオブジェクトのローカル座標？を入れます。indexはSetPos関数が再帰なので、relation参照時の要素数として使います。

#蛇足
補足の文中のローカル座標に？が付いている辺りでお察し頂ければと思いますが、自信がないので、「こいつ頭悪いなー」程度に眺めて笑ってもらえたらと思います。きっとカッコいい式でもっとスマートに実現できる気がしています。
Azure ADについてのメモ

個人用のメモ。
Azure ADについてまったく知識がなかったので覚書として概要をメモしておきます。

## Azure ADとは
* Saasとして提供されるユーザ、デバイス、ディレクトリ管理サービス。インターネット上の統合認証基盤。
* Azure ADでできる主なこと
    * ユーザー及びデバイスの管理
    * アプリケーションの管理（ユーザーに対して割り当てるアプリ）
    * 様々なクラウドサービスへのシングルサインオン（SAML認証 or パスワード認証）
    * 多要素認証
    * オンプレリソースへのリバースプロキシ（アプリケーションプロキシ）
* 元々はOffice365のユーザ認証で利用されている。Office365テナント契約時には自動的に環境作成されるが、Azure AD無償版の範囲なので、より幅広くサービス利用する場合は有償ライセンスの契約が別途必要。

## オンプレActive Directoryとの関係性
* **オンプレのActive DirectoryとAzure ADは完全に別物。**信頼関係も結べない。
* ただしAzure AD Connectを構成することで、オンプレADからAzure ADにディレクトリ情報、オブジェクト、パスワードを同期可能。
* 同期は基本的に一方向（オンプレ→Azure AD）
* Azure ADでアカウントのパスワードを変更した場合のみ、オンプレADにパスワードを反映可能。（パスワードの書き戻し）
* Azure AD Connectで「パススルー認証」を構成すると、ユーザがAzure ADアクセス時にオンプレのADでユーザ認証できるようになる。IDフェデレーション環境に従来必要であったAD FSは不要。


## 利用できる認証方式
* MFA(多要素認証）（ワンタイムパスワード、SMS）
* Windows Hello for Business(登録デバイス＋生体認証）
* デバイス認証（管理化デバイス or 個人デバイスの判断）
* 条件付きアクセスポリシー（信頼できる場所、デバイスの状態、ユーザー）

## Azure AD ドメインサービス？
* Azure AD上に構成するドメインコントローラーのサービスもある。
* Kerberos認証やLDAP読取りアクセスを行うオンプレのアプリを、リフト＆シフト方式でAzureに移行し、オンプレでそのアプリをホストしているハードウェアを廃止したいときなどに使用する機能。
* Azure ADドメインサービスでオンプレのAD DSのすべての機能が提供されているわけではない。オンプレのADをそのまま移行できるわけではないので注意。

> **Azure ADドメインサービスの制限事項**

> * Domain Admins / Enterprise Adminsがない
    * 上記の権限が必要な場合は利用不可
    * 同レベルのアカウントとしてAAD DC Administratorsを利用

> * Default Domain Policyを変更できない
    * パスワードポリシーなどは変更できない
> * フォレストに対する管理、変更ができない
    * 信頼関係、スキーマ拡張、機能レベルの変更


### 参考にしました

[Active Directory？Azure Active Directory？混乱ポイントを整理！](https://cloud.nissho-ele.co.jp/blog/arrange_activedirectory_and_azureactivedirectory/)
[Active DirectoryのPaaS版、Azure Active Directory Domain Servicesとは？](https://cloud.nissho-ele.co.jp/blog/azure-active-directory-domain-services/)

## 気になること

* Azure AD + GSuiteの運用　ユーザプロビジョニングなど運用効率はいかがなものか
* 将来的にオンプレのActive DirectoryはAzure ADに移行できるものかの検討
* Intuneを利用したデバイス管理　BYOD利用のアクセス制御、ログ運用とユーザビリティのバランスについて
* 他の認証基盤サービスとの比較　ex.HENNGE One コスト面での対比など

Azure ADで行えることは非常に多岐にわたっており、夢が広がりまくることまでは認識したが
実際の社内での運用において必須とされる要件や、内製可能な範囲は限られるはずなので
他の類似サービスとは、運用上のマスト要件部分での比較が必要だなと思った次第。

とりあえずAzure ADと、Azure上に構築したVMのActive Directoryサービスを
勝手に混同してイメージしていたのには恥じ入るばかり。。
引続き学習を進めます。
Raspberry Pi 4 Model B でケースファンを取り付ける

# Raspberry Pi 4 Model B でケースファンを取り付ける

[Raspberry Pi 4 Model B 用のケース](https://www.amazon.co.jp/gp/product/B07VF82T12/) を購入してファンを取り付けたのですが、

接続方法を簡単にメモっておきます。

https://www.raspberrypi.com/documentation/computers/os.html#gpio-and-the-40-pin-header の図を確認します。

1. 図の赤の端子に赤いケーブルを挿します。
2. 図の黒の端子に黒いケーブルを挿します。

## 参考情報

- https://www.raspberrypi.org/documentation/usage/gpio/
- http://igarashi-systems.com/sample/translation/raspberry-pi/usage/gpio.html
ABC049C - 白昼夢 / Daydream

#問題
https://atcoder.jp/contests/abs/tasks/arc065_a
<img width="1105" alt="スクリーンショット 2019-12-01 16.22.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/9cc5efad-472d-91ea-331c-89b21fbf1364.png">

#1回目
##回答
```ruby
str = gets.chomp
DREAM = "dream"
DREAMER = "dreamer"
ERASE = "erase"
ERASER = "eraser"

equal_flag = "NO"


while true
  str_size = str.size
  if str_size >= 5
    sliced_str = str.slice( ( str_size - 5 )..( str_size - 1 ) )
    if sliced_str == DREAM || sliced_str == ERASE
      if str == sliced_str
        equal_flag ="YES"
        break
      end
      str = str.slice( 0..( str_size - 6 ) )
      next
    end
  end
  if str_size >= 6
    sliced_str = str.slice( ( str_size - 6 )..( str_size - 1 ) )
    if sliced_str == ERASER
      if str == sliced_str
        equal_flag ="YES"
        break
      end
      str = str.slice( 0..( str_size - 7 ) )
      next
    end
  end
  if str_size >= 7
    sliced_str = str.slice( ( str_size - 7 )..( str_size - 1 ) )
    if sliced_str == DREAMER
      if str == sliced_str
        equal_flag ="YES"
        break
      end
      str = str.slice( 0..( str_size - 8 ) )
      next
    end
  end
  break
end

puts equal_flag

```
##結果
<img width="1089" alt="スクリーンショット 2019-12-01 16.24.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/6a665646-cf82-d8f8-6a76-ffa90dd850cb.png">

#2回目
##回答
```ruby
S=gets.chomp
s = S.gsub("eraser","").gsub("erase","").gsub("dreamer","").gsub("dream","")
puts s.size==0?"YES":"NO"
```
##結果
<img width="1088" alt="スクリーンショット 2019-12-01 16.24.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/8eea9d25-6d90-a2ce-3eb4-677628c60b0c.png">

#感想
自分の知っている知識だけでも解けてしまうので他の人の回答がめっちゃ参考になる。
今回はパフォーマンスめちゃくちゃ影響したし、
実際の業務でこれに気付かなかったらこのパフォーマンスのままリリースされてしまっていたかと思うと怖い。
正規表現も今度触ってみよう。
XcodeGenを使うとチーム開発が楽になる話

この記事は豊田高専コンピュータ部アドベントカレンダー1日目の記事です
## XcodeGenとは
iOSアプリ開発で複数人での開発をすると色々とつらいことがあるのでそのつらいことをなるべく無くそうという感じのツールです。具体的にはプロジェクトへのファイルの追加など行うとプロジェクトファイルが書き換わるのですが、そのプロジェクトファイルは人間におおよそ理解のできない形式で書かれており、チーム開発をしているとそれが恐ろしいコンフリクトを生み、その解消がとてもつらいという問題があります。そのプロジェクトファイルをコード(yaml)から生成することでチーム開発をやりやすくしようという感じのツールになります。
https://github.com/yonaskolb/XcodeGen

## 触ってみる
なにはともあれ百聞は一見にしかずなので触ってみましょう。まずはXcodeGenをインストールします

```bash
$ brew install xcodegen
```

XcodeGenを入れられたら次はXcodeのプロジェクトを作成します。プロジェクト名は今回は「SampleGen」とします。プロジェクトの作成手順は今回は割愛します。

プロジェクトを作成できたらプロジェクトファイルの内容を`project.yml`に書き起こしていきます。

```yaml:project.yml
# プロジェクト構成・設定
name: SampleGen
configs:
  Debug: debug
  Release: release
options:
  groupSortPosition: top
attributes:
  ORGANIZATIONNAME: ymgn
fileGroups:
 - SampleGen
 - SampleGenTests

# ターゲット
targets:
  SampleGen:
    type: application
    platform: iOS
    sources:
      - path: SampleGen
    settings:
      base:
        PRODUCT_BUNDLE_IDENTIFIER: ymgn.SampleGen
        ASSETCATALOG_COMPIER_APPICON_NAME: AppIcon
        INFOPLIST_FILE: SampleGen/Info.plist
      configs:
        Debug:
          GCC_OPTIMIZATION_LEVEL: O
        Release:
          GCC_OPTIMIZATION_LEVEL: s
  SampleGenTests:
    type: bundle.unit-test
    platform: iOS
    dependencies:
      - target: SampleGen
    settings:
      TEST_HOSTS: $(BUILT_PRODUCTS_DIR)/SampleGen.app/SampleGen
      INFORPLSIT_FILE: SampleGenTests/Info.plist
    sources:
      - SampleGenTests

# スキーム
schemes:
  SampleGen:
    build:
      targets:
        SampleGen: all
    run:
      config: Debug
    test:
      config: Debug
      gatherCoverageData: true
      targets:
        - SampleGenTests
    profile:
      config: Release
    analyze:
      config: Debug
    archive:
      config: Release
```

要素一つ一つを説明するのはつらいのでXcodeGenのリポジトリにあるドキュメントを参照してもらうとして、プロジェクトファイルの項目に対応した要素が存在します。プロジェクトファイルからyamlへの書き起こしは手で書きましたが、自動で書き起こしてくれる方法などあればぜひコメントで教えてください。

`project.yml`はプロジェクトファイルと同じ階層に配置し、プロジェクトに追加する必要はありません。
project.ymlが出来上がったらプロジェクトファイルは削除しても構いませんが、写しミスがあった場合悲しいので残しておくとよいでしょう。
project.ymlがあるディレクトリで

```bash

$ xcodegen generate
```

を実行するとプロジェクトファイルを生成します。既存のプロジェクトファイルがある場合は書き換えられます。

最低限の実装になっているのでそのままビルドするとおそらくSigningでエラーが出ると思いますので、Teamは手動で追加してもらうとエラーは消えるはずです。

これで一通りの導入は終了です。

## まとめ
上記では手順だけ示したのであまり恩恵がわからないかもしれませんが、targetの追加や、ライブラリ、Embeded Frameworkの追加などもproject.ymlで記述できるのでコマンド一発でどの環境でもコンフリクトのない状態のプロジェクトファイルが生成されます。実際に使用する際はプロジェクトファイルは.gitignoreなどで管理には含めないようにすることに注意してください。
もっと詳しく知りたい場合はXcodeGenのリポジトリや他記事を参照してもらえると多くの設定が利用できたり、設定ファイルを分割できたりすることがわかると思います。iOSアプリのチーム開発で困っている人はぜひ試してみてください。

## おまけ
XcodeGenを使ったプロジェクトをBitriseなどのCI/CDツールに載せるとプロジェクトファイルが存在しないため、validationが通らなくて焦るかもしれません。しかし、最初のvalidationが通らなくてもPROJECT_PATHには単に生成される.xcodeproj(もしくは.xcworkspace)のファイル名を入力して、workfrowにXcodeGenをビルド前に実行するようにすればビルドできるようになります。

<img width="818" alt="スクリーンショット 2019-12-01 16.23.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210069/97e8da0c-f292-ff28-f7bf-db4396b056ce.png">

Bitriseであればこのようにxcodegenのコマンドを使用するためのユーティリティが存在します。
[Unity] Androidアプリの64ビット対応でつまづいた話

# はじめに
Play StoreにAndroidアプリをあげる際に**64ビットにしてね！！**と言われ，対応したはずなのに64ビット対応できてないと何度も怒られようやく解消できたので，解決方法をまとめます．


# なんで64ビット対応するの？
[参考](http://tsubakit1.hateblo.jp/entry/2019/01/18/003659)
ざっくりいうと，2021年8月以降64ビットしか扱えないから対応してねという理由．

# 環境
- Mac OS Mojave 10.14.6
- Unity 2018.3.6f1

# 調べたとおり64ビット対応する
[このサイト](https://www.petitmonte.com/unity/android_64bit.html)などを参考に64ビット対応します．
1. Unity>Preference>External toolsのNDK部分を埋める.
![スクリーンショット 2019-11-22 16.51.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487681/678f96ee-35c6-a756-56a8-ce6ed82ad6f7.png)


2. Unity>Edit>Project Settings>Player>Configurationで，Script BackendをIL2CPPにして，ARM64にチェックマークを入れる．

![スクリーンショット 2019-11-22 16.51.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487681/76ee7718-125c-de3e-38a5-cef2d85429ea.png)


これでビルドすれば,64ビット対応完了！！！のはずだった．．．

# 「このリリースは Google Play の 64 ビット要件に準拠していません」
はい，またこのエラーがでました．64ビット対応できてないらしい．
調べていたら[この記事]()に出会った.

ほう，X86を入れてビルドするとだめらしい．．．

# "X86"を外してビルドする．
- "x86"のチェックマークを外す
![スクリーンショット 2019-11-22 16.51.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487681/bd065329-7245-8800-488d-b881ab1d060a.png)

これをビルドしたら無事に上げることができました！

これをすると32bitで動いていたものが動かなくなりますが，まぁしょうがないでしょう．

# 所感
ARM64にチェックマークを入れてね，という記事はあったが，x86を選択するとだめというトラップに見事引っかかってしまった．Unity 2019以降だとそもそもx86がないのでこういうことが起こってしまったのだろう．

しかし無事に対処できて本当に良かった．
初心者のためのobniz案内

#はじめに
この記事は、いままで電子工作とかやったことない人（私）が、[obniz](TODO)というとても初心者に優しいマイコンボードをはじめて触っていろいろ作れるようになったのがうれしかったので記事を書いてみました！
これからやってみたいという人の手助けになれば幸いです。
![obniz-board.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/be6ae58f-e16b-9bf3-8d94-21e32cccc45b.jpeg)

#この記事の対象
・電子工作とかしてみたいけど、はじめ方わからない！
・そもそも電子工作ってどんなことするの？

#電子工作でなにができるの？
100均で買ってきたおもちゃに距離センサーを積んでチキンレースゲームを作ったり
「[IoT × LINEbotでチキンレースゲームを作ってみた](https://qiita.com/cog1t0/items/06938e90a59bf9a58069)」

いろいろ組み合わせようとしてうまくいかなかったのですが
朝顔の観察日記を自動化してみようとしたり
「[アサガオの観察日記を電子工作で自動化してみよう](https://qiita.com/cog1t0/items/06938e90a59bf9a58069)」

などなど、おもちゃの新しい使い方を開発したり、めんどくさいなぁと思うことを自動化してみたりと
日常をちょっとだけ便利にできます！

#はじめてみよう ~ まずはLEDを光らせてみる
ものすごーく簡単に説明するために、まずはobnizでLEDを光らせてみます。

0.今回はobnizをwebページから実行するので、事前にwifiに繋いでおきます
1. obniz モバイルバッテリー LEDを用意します
![IMG_1527.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/732e161d-c185-ea82-a98e-d8ca25c5d57a.jpeg)
2. obnizの[LEDの紹介ページ](https://obniz.io/ja/sdk/parts/LED/README.md)を読んで繋ぎ方を調べます
3. obnizと部品を繋げます
![IMG_1528.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/c7d23e1b-91b8-151b-484f-1f0a7f039d6a.jpeg)
4.さっきの紹介ページでお試しのプログラムが書いてあるので、実行ボタンを押してみると
![IMG_1529.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/162a37a4-c74b-5d43-e6ea-81fa777adbac.jpeg)
5. 光ります
![IMG_1530.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/cdafafde-0e36-b08c-b650-925f599c787d.jpeg)

驚きのはじめやすさ

#もうちょっと難しいことをしてみる
obnizには「開発者コンソール」という、プログラミング用の専用ページが用意されています。
![スクリーンショット 2019-12-01 15.06.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/fa99d878-7f56-0c8c-610e-16f60507b289.png)
プログラミングが苦手な人にはブロックプログラムも用意されています
![スクリーンショット 2019-12-01 15.09.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/5a35e5ff-aadb-ca6e-852f-1dab2d814185.png)
実行すると↓
![proto2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/cc8888ae-1592-4052-ecb7-eee9f3820de8.gif)

プログラミングに慣れてる人は、自分でサーバーを立てて実行するもよしです。

#他にどんなことができるの？
obniz公式が[いろんな作例](https://obniz.io/ja/explore)を出しているので、なにができるか探してみると楽しいです！
[自動でついて、時間も記録するライト](https://obniz.io/ja/explore/33)
[キッズプロジェクト。振ってアニマル！](https://obniz.io/ja/explore/39)

自分でプログラミングするのはちょっと。。。という人には[ウェブアプリ](https://obniz.io/ja/webapp/)が用意されているので、材料を買って組み立てれば動くものもあります
[トイレに誰かいますかセンサー](https://obniz.io/ja/webapp/4)

他にも、[パーツライブラリ](https://obniz.io/ja/sdk/parts)を見ると、こういう部品が使えるという紹介がされていて、見るだけでワクワクしますね（さっきのLEDの紹介ページもここです）

#まとめ
初心者で英語があんまり得意でない私にとっては、
作例やドキュメントが**日本語で**たくさんあって、
obnizのIDさえ入力したらとりあえず動かせる（動かすまでのところで力尽きない）のが本当に助かったので、これを機にはじめてみようと思う人がいたら嬉しいです！

#12/3の記事は…
@tkyko13 さんです！
[UE4] レベル上でアニメーションを確認したい時は Update Animation in Editor がおすすめ！

アニメーションを確認するだけのために毎回PIE実行をするのは非常に面倒です。また、プロジェクトの規模が大きくなるにつれてイテレーションも悪くなりがちです。そんな時とき今回ご紹介する```Update Animation in Editor```を使えばその悩みが解消される！…かもしれません！

![sequencer.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/77d888c9-fdeb-98b0-6bd0-0750ca8796d7.gif)
```Skeletal Mesh Component```には```Update Animation in Editor```というプロパティがあります。そして、これを有効にすると、**PIEやStandaloneを実行しなくても、レベル上に配置されたモデルのアニメーションを再生することができます**。
![animationpreview.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/dd150e50-a75f-1aec-d136-be17fd874e7b.gif)
更に```Animation Blueprint```が指定されている```Skeletal Mesh Component```の場合は、```Update Animation in Editor```を有効にすることで、その```Animation Blueprint```のState Machine と Event Graphの一部イベント（```Initialize Animation```, ```Update Animation```, ```Post Evaluate Animation```）を実行できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/5a793104-87ce-5087-fc82-7b5745136ece.png)
![animbp.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/240c8997-2049-a996-28cc-8ffd9a379fa1.gif)
この機能・仕様を活用することで様々な場面で効率化を図ることができます！
例えば、実際のレベル上で足のIK制御の確認・調整ができたり…
![IK.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/5d7dd1a8-b4af-4649-d7bf-bebb3a163c68.gif)
Sequencerからの```Animation Blueprint```を制御する際のプレビューが格段に楽になったりと非常に便利です！
![sequencer.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/a1d3aa6b-99c7-f44b-9035-efbcd02d1e22.gif)

シンプルな機能ですが様々な活用方法があるかと思います！是非色々試してみてください！

おまけ：
少し前の話ですが、この機能を活用して大量のアニメーションをプレビューするためのプラグインを作ってみました。やってることは単純なのですがこういう活用例も…ということでご紹介しました。
https://github.com/pafuhana1213/AnimationPreviewer

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">購入した大量のアニメーションを確認してリターゲットして…という手順が大変だったので、プレビュー用のエディタ拡張を作ってみました。AnimSequence、SkeletalMeshの自動検出、プレビュー用アセットへのリアルタイムリターゲットを実装。満足したので近日中にGithubに公開します <a href="https://twitter.com/hashtag/UE4?src=hash&amp;ref_src=twsrc%5Etfw">#UE4</a> <a href="https://twitter.com/hashtag/UE4Study?src=hash&amp;ref_src=twsrc%5Etfw">#UE4Study</a> <a href="https://t.co/1i79uryzPj">pic.twitter.com/1i79uryzPj</a></p>&mdash; おかず (@pafuhana1213) <a href="https://twitter.com/pafuhana1213/status/1184895541680848897?ref_src=twsrc%5Etfw">October 17, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

おしまい
Mouse Dictionary Kaggle supportが超便利

[wtetsu](https://qiita.com/wtetsu)さんの[Mause Dictionary](https://chrome.google.com/webstore/detail/mouse-dictionary/dnclbikcihnpjohihfcmmldgkjnebgnj)をkaggleでも使えるようにするchromeエクステンション[Mouse Dictionary Kaggle support](https://chrome.google.com/webstore/detail/mouse-dictionary-kaggle-s/bepofoammpdjhfdibmlghoaljkemineg)が便利なので皆さんにもっと知ってほしいです。おしまい。
SpringでCookieを取得する

よくあるやり方は、HttpServletRequestからgetCookiesしてそこから取り出すというやり方でした。
以下のような形です。

```CookieController.java
    @GetMapping("cookies3")
    public String showCookies3(HttpServletRequest httpServletRequest) {
        Cookie[] cookies = httpServletRequest.getCookies();
        Arrays.stream(cookies).forEach(cookie -> System.out.println(cookie.getValue()));
        return VIEW_NAME;
    }
```

ただ、Springを利用するともう少し簡単に取得できます。

## Cookieの生成

適当にCookieをセットします。

```CookieController.java

    private final String VIEW_NAME = "demo/cookie/index";

    @GetMapping("/")
    public String index(HttpServletResponse httpServletResponse) {
        httpServletResponse.addCookie(new Cookie("key1", "value1"));
        return VIEW_NAME;
   }

```

 

## Cookieの取得

以下のようにCookieValueアノテーションを利用することで簡単に取得できます。引数はCookieのキー値です。

 

```CookieController.java

    private final String VIEW_NAME = "demo/cookie/index";

    @GetMapping("cookies1")
    public String showCookies1(@CookieValue("key1") String cookieValue) {
        System.out.println(cookieValue);
        return VIEW_NAME;
    }

```

ただし、上記の書き方だとCookieが削除されるなどして取得できない場合は実行時エラーとなります。
※Resolved [org.springframework.web.bind.MissingRequestCookieException: Missing cookie 'key1' for method parameter of type String]）

そのため、以下のように@CookieValueのrequiredをfalseにする（デフォルトはrequired = true）ことで回避可能となります。

ただしこの場合は引数にはnullがセットされるため、defaultValue属性を指定することで、Cookieから取得できない場合はデフォルト値を指定することが可能となります。

```CookieController.java

    private final String VIEW_NAME = "demo/cookie/index";

    @GetMapping("cookies2")
    public String showCookies2(
            @CookieValue(name = "key1", required = false, defaultValue = "default value1") String cookieValue) {
        System.out.println(cookieValue);
        return VIEW_NAME;
    }
```

以上です。
CNCFのGraduated Projectsの"Graduated"について調べてみた

 
CNCFの公式サイトでLandscapeを見ると、様々なアプリケーションの一覧が表示されます。

その中で、KubernetesやFluentd, Prometheusなどが含まれているCNCF Graduated Projectsというものがありますが、最近CNCFを調べ始めた私としてはGraduatedが何を意味するのか分かりませんでした。

なので、Graduatedが何なのか、簡単に調査してまとめてみました。

## Maturity Levels(成熟度)

Cloud Nativeの公式サイトの[Graduated and Incubating projects](https://www.cncf.io/projects/#) のページの末尾に下記のような解説があります。

> Maturity Level
> CNCF projects have a maturity level of sandbox, incubating, or graduated which corresponds to the Innovators, Early Adopters, and Early Majority tiers of the Crossing the Chasm diagram. The maturity level is a signal by CNCF as to what sorts of enterprises should be adopting different projects. Projects increase their maturity by demonstrating their sustainability to CNCF’s Technical Oversight Committee: that they have adoption, a healthy rate of changes, committers from multiple organizations, have adopted the CNCF Code of Conduct, and have achieved and maintained the Core Infrastructure Initiative Best Practices Badge. Full details are in the Graduation Criteria v1.1.
日本語に訳すと下記のようになります。

```text
Maturity Levels(成熟度)

CNCFのプロジェクトにはsandbox(遊び場), incubating(培養中、増殖中), graduated(進んだ、卒業した)というMaturity Levelsが割り当てられています。

これはChasm diagram(『キャズム』)におけるInnovators, Early, Adopters, そしてEarly Majorityの階層に対応しています。

成熟度はエンタープライズがどのプロジェクトを採用すべきかを示す、CNCFによる指標です。

プロジェクトはCNCF’s Technical Oversight Committee(CNCFの技術監査委員会)への持続可能性のデモンストレーションを行うことによってMaturity Levelsを高めていきます。

持続可能性は採用、健全な変更、複数のorganizationsからのコミッター、CNCFのCode of Conductへの従属、そしてCore Infrastructure InitiativeのBest Practices Badgeを達成し維持していることが必要です。

完全な詳細はGraduation Criteria(卒業基準)に示されています。
```

これを読むとGraduatedになっているプロジェクトはCNCFが定める基準によって、Graduatedとして分類されたプロジェクトであることが分かります。

そしてGraduatedは下記のように、成熟度としては最も成熟した段階のことを示していることも分かりますね。

<img width="1240" alt="Screenshot 2019-12-01 16.07.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79990/d3dfcbfa-68f1-95ae-7f72-27c66e372c49.png">
mac スクリーンショットの保存先を変える

# スクリーションショットの保存先を変更する
初期状態だとデスクトップに保存されますね。
かなり邪魔なので好きな場所に保存できるように設定を行いましょう。

保存先を写真フォルダの中にする

```
defaults write com.apple.screencapture location ~/Pictures;killall SystemUIServer
```
# 写真フォルダ以外の保存先の保存する場合
`~/Pictures`のところを自分の保存したいパスに変えることができます。
例えば自分のデスクトップに`screenShot`というフォルダの中に入れたいとするとしましょう。

```
defaults write com.apple.screencapture location ~/Desktop/screenShot;killall SystemUIServer
```

このような書き方になります。

# パスの出し方が分からない初心者へ
このようなファイルがあったとします。
<img width="1470" alt="スクリーンショット 2019-12-01 15.56.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387055/59b1273f-2d57-5764-145b-1571393a4fd2.png">
フォルダでオプション(二本指で同時クリック)を開きます。
開いた状態でoptionキーを押すとここになんちゃらなんちゃらのパスをコピーするという裏メニューが出てきますので
こいつをクリックするとこのファイルのパスが取れます。
<img width="1470" alt="スクリーンショット 2019-12-01 16.01.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387055/548c19dd-9f50-8885-2bc3-c46d7b3621a0.png">
golangのAtCoder向けデバック方法(VSCode)

goでAtCoder（競技プログラミング）を始めたところVSCodeでのデバッグでつまづいたのでメモ.

## 経緯

コードが期待通り動かない
→ 変数を追いながらdebugしたい
→ delveは標準入力を受け付けられない
→ testファイル内でos.Stdinをスタブし, bufio.NewScannerを再定義して解決

## Sample Code
回答用コード.
struct IO に 各種input/output用の関数を実装する.
デフォルトでは標準のbufio.Scannerでstdinをinput.

```main.go
package main

import (
	"bufio"
	"fmt"
	"os"
)
type IO struct {
	scanner *bufio.Scanner
	writer  *bufio.Writer
}

func newIO() *IO {
	return &IO{
		scanner: bufio.NewScanner(os.Stdin),
		writer:  bufio.NewWriter(os.Stdout),
	}
}

func (io *IO) nextLine() string {
	io.scanner.Scan()
	return io.scanner.Text()
}

func (io *IO) nextInt() int {
	i, e := strconv.Atoi(io.nextLine())
	if e != nil {
		panic(e)
	}
	return i
}

func (io *IO) printLn(a ...interface{}) {
	fmt.Fprintln(io.writer, a...)
}

var io = newIO()

func main() {
	io.scanner.Split(bufio.ScanWords)      // switch to separating by space
	io.scanner.Buffer([]byte{}, 100000007) // switch to read large size input
	defer io.writer.Flush()

	N := io.nextInt()
	hoge := someProcess(N)
	io.printLn(hoge)
}
```

デバッグ用コード.
Stdinをstubしてio.scannerを上書き.
`./stdin.txt`から入力を読み取りmain()を実行する．

```main_test.go
package main

import (
	"bufio"
	"io/ioutil"
	"os"
	"testing"
)

func TestAnswer(t *testing.T) {
	inbuf := readFile("./test.txt")
	stubStdin(inbuf, func() {
		main()
	})
}

func readFile(fileName string) string {
	bytes, err := ioutil.ReadFile(fileName)
	if err != nil {
		panic(err)
	}

	return string(bytes)
}

// Stubs Stdin in 'fn'
func stubStdin(inbuf string, fn func()) {
	inr, inw, _ := os.Pipe()
	_, _ = inw.Write([]byte(inbuf))
	inw.Close()
	os.Stdin = inr
	io.scanner = bufio.NewScanner(os.Stdin)
	fn()
}
```


## 参考
- [Go言語で標準入出力をスタブする方法](https://qiita.com/nak1114/items/a2a9b036097ea120b12b)
DockerをWindowsノートＰＣで触ってみた

会社でGCPを使っていて、いろいろ勉強しなければなりません。恥ずかしい内容ですが、備忘録として残しておきます。将来、GCPでデータ処理、データ蓄積をしたいなー、とも思っています。自宅でWindowsノートＰＣでTutorial 動かしました。

## Windowsの設定: Hyper-V をONにする

- 「Windowsの機能の有効化または無効化」で Hyper-V をONにして、再起動する。
- 「Windows 管理ツール」から「Hyper-V マネージャー」を起動してみる。（今回は関係ないですが、仮想マシンはまだ何もありません。)

![2019-12-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294040/12b1b4ae-8142-cf27-50ce-6b14af92b3b7.png)


## Docker Desktop for Windows　を使ってみる。

- [Docker Hub](https://hub.docker.com/)で登録してからダウンロード。
  Downlaod Docker Desktop for Windows のボタンを押して指示に従っただけですが、CUIのdockerのツール一式がインストールされたようです。

- 以下は[tutorial](https://hub.docker.com/?overlay=onboarding) をフォローしただけ。Power Shell で動かしました。

```
 git clone https://github.com/docker/doodle.git
```
./doodle/cheers2019 というディレクトリで、build して、ローカルで動かします。build してできるものはイメージと呼ばれるようです。ソースコードはGO lang で書かれていました。xxxxxはＩＤで、-t <イメージ名> です。

```
> docker build -t xxxxx/cheers2019 .
```

### build する/イメージを作る(docker build)

build の設定は、同じディレクトリにあるDockerfile に書かれているものが読まれます。読んでもよく分かりません。

```
FROM golang:1.11-alpine AS builder
RUN apk add --no-cache git
RUN go get github.com/pdevine/go-asciisprite
WORKDIR /project
COPY cheers.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -ldflags '-extldflags "-static"' -o cheers cheers.go

FROM scratch
COPY --from=builder /project/cheers /cheers
ENTRYPOINT ["/cheers"]
```

### ローカルで動かす (docker run)

　Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
　Run a command in a new container

ローカルで動かします。-i はコンテナの標準入力、-tはtty　を利用するオプションだそうです。--rm はコンテナ終了時にコンテナ自動的に削除します。

```
> docker run -it --rm xxxxx/cheers2019
```

###  イメージを共有できるようにする (docker push)

Docker Hub registry にpush(shipする？)し、共有できるようです。

```
> docker login; docker push xxxxx/cheers2019
```

サンプルには他にsummer2019, halloween2019, birthday2019があり、全て同じような内容なようでした。。。

- CUI の使い方は[ここ](https://docs.docker.com/engine/reference/commandline/docker/)にドキュメントがありました。
- 振り返ってみるとCUIではログインや認証に関する操作をしませんでした。多分、Docker Desktop for Windows が全て良きにはかってくれたのだと思います。
- Google Cloud Platform で動かしてみるのが、次のステップなのだが。

- 参考にさせていただきました。ありがとうございます。
 - [WindowsでDocker環境を試してみる](https://qiita.com/fkooo/items/d2fddef9091b906675ca)

 - [【備忘録】【Docker奮闘記:1】Docker for Windows インストール](https://qiita.com/manamiTakada/items/c1394e5e3358802a9446)
  - [docker run -itでDockerコンテナの中にはいる](https://www.kabegiwablog.com/entry/2018/07/19/140000)
　- [docker runの--rmオプション(コンテナ終了時にコンテナ自動的に削除)べんりです](https://qiita.com/hoshino/items/9545d255cc0103b3d296)
5年以上誰も手をつけていなかったAWS環境を改善した話

# はじめに

　昨年の12月から約10ヶ月ほど、とあるベンチャー企業のAWS環境を改善していました。今はその会社にいないのですが、会社の Jira と Confluence 以外にも知見をまとめておいたほうが良いかなと思ってアドベントカレンダーに書くことにしました。

# 組織の状況

　以前にエンジニアが大量に退職したことにより、大量のメンテナンスできないソースコードがありました。それとともに、何の用途で動いているか分からないEC2サーバーもたくさんありました。 Technology & Infrastructure チーム（以下TIチーム）というのがあったのですが、障害対応をする人たちと数年がかりで新しい基盤を作っている人たち（たぶん目前の問題を諦めた人々）がいて、いわゆる[サバイバルモード](http://suzaku-tec.hatenadiary.jp/entry/2017/10/29/222735)にありました。ちなみにアプリケーションのバグの量も半端なく、バグ修正チームが数年単位で存在しています。

このTIチームを解体することになり、私がAWSを触ってみたいというわりと個人的な理由と、直前にサービス系で使っていたElasticsearchの検索性能改善のタスクをやっていた時にインフラ周りに改善の余地がある、カネになりそうな仕事の匂いがしたのでチーム名を「SRE」として、実質１人で AWS環境を見直すことになりました。

# 成果

　4万ドル/月ほどかかっていたAWSの費用を半年ほどで 2万ドル/月くらいにして、社長に褒められました。

# 最初にやったこと

　SREのオライリーの青い本は分厚すぎて読む時間が十分にとれなかったのと、NewRelicを使っていたこともあって、SLI/SLOの章だけをまず熟読し、SLI/SLOを決めました。そもそもサービスの非機能要件はいままで定められておらず、それにより営業がお客様に説明する際にも言ってることがマチマチになっていた、ということもあり、部門ごとのリーダーを集めたミーティングでSLI/SLOについてディスカッションし、合意をとりました。障害対応基準・レスポンスタイムなど簡単な指標だけを整備してコンフルエンスにまとめました。そして、NewRelic で毎日監視したり、Cloudwatchのアラームを見直すようにしました。

# AWSの営業に連絡

　営業の方はとても親身にしてくれて改善点・改善方法をたくさん教えてくれるので仲良くしましょう。ここで Trusted Advisor や Business Support のお試しプランを教えてもらって、いろいろとはかどりました。
特に Trusted Advisor をBusiness Support で使うとSREで必要な業務が見えるようになったりするのでおすすめです。

# コスト削減

　JAWS-UG 六本木一丁目支部に参加した時に知り合った方と、[JAWS-UG南武線グループ（非公式）](https://www.facebook.com/groups/1099875800091892/)でお会いした際に会社のシステムについて相談したら、「チョット何言ってるかワカラナイんですが、運用コストがかかりすぎですねえ・・・」というリアクションをされたので、一般的に考えてヤバいんだな、と思いました。
　AWS にはコストを分析してアドバイスしてくれるツールや、今では無駄遣いを指摘してくれる「Resource Optimization Recommendations」がありますが、当時はまず月額料金の高いサーバーからすべてリストアップして、用途・インスタンスタイプ・月額料金・今後どうするかを書き出しました。今後どうするかについては、だいたい以下の形に落ち着きました:

- 今すぐ停止・削除する（psとかでプロセス調べて、使ってないとわかればすぐ）
- 使ってるやつは年間契約する
- 別のマネージドサービスなどに置き換える(古いリアルタイム通信用nodejsのプロキシ用途のEC2はALBに、WordpressサーバーはLightsailに、など..)
- インスタンスタイプをスケールダウンする(スケールダウンについてもAWSのRecommendation である程度わかります。htopとかで見ながら使用状況を観察. NewRelic Infrastructureでも横断的に監視すると分かります)
- 5年以上塩漬けになってたEC2は paravirtual の仮想化方式のやつも多く、これらはちょっと苦労してスケールダウンしました [EC2の t1.microをt2.microに変換する](https://web.archive.org/web/20190517012523/http://www.agilegroup.co.jp/technote/t1micro-to-t2micro-migration.html)
 
あと、もちろんオートスケールするという選択肢もあったのですが、ちょっと難しそうだったので後回しにしました。

# ことあるごとにやったこと

　以前のTIチームにはなぜか AWSに関する権限が十分に与えられていなかったので、その都度グループチャットでCTOに連絡して権限付与をお願いしました。10回くらいやったら、だいたいのことができるようになりました。

# やればよかったこと

 [AWS改善マップ] (https://dev.classmethod.jp/cloud/aws/kaizen-map/)

　在任中は、AWS Config / AWS GuardDuty / Business Support の１ヶ月お試し あたりを入れました。GuardDuty を入れたら、EC2がビットコイン採掘のbotとして使われていることがわかって焦りました。。

# 最後に

　たぶん上記のような事例はあまりないと思うのですが、もし古い高コストAWS環境でお困りの方がいらっしゃいましたら、ご相談ください。

# 参考にしたページ

[EC2インスタンスタイプ比較] (https://www.ec2instances.info/)
ターミナルでコマンド実行時に「Operation not permitted」が出たときの対処法

AWSでec2-userでログインしようとターミナルでコマンドをいじっていた際に、標題のエラーが出てしまったので、
その際の対処法を備忘録として記載します。

#背景・エラー内容
まず、実行しようとしていたコマンド内容を記載します。
以下のようにダウンロードした鍵のファイルを.sshディレクトリに移動しようとしてました。

```:terminal
$ cd ~
#ホームに移動

$ mkdir ~/.ssh
# .sshというディレクトリを作成

$ mv Downloads/ダウンロードした鍵の名前.pem .ssh/
# mvコマンドで、ダウンロードしたpemファイルを、ダウンロードディレクトリから、.sshディレクトリに移動。

　=>このコマンドを実行した際に標題のエラーが発生しました。
　　*~~~~~の部分は実行しようとした内容が記載されてました。
　~~~~:Operation not permitted
```


#検証・原因
今回のエラーについて原因を特定するために、以下の検証を実施しました。
結果、今回のエラーの原因については、下記検証結果の通り、Downloadsディレクトリに対してターミナルのコマンドが効かなかったことが原因でした。

```:terminal
Downloads $ ls
#lsコマンドでもコマンドが有効にならないか確認
=>同様のエラー発生
　~~~~:Operation not permitted
=>以上のことからDownloadsディレクトリに対してターミナルのコマンドが有効になってないことを確認。

```

#エラー解決方法
それでは、解決方法について記載していきます。
＊動作環境はMacbookとなります。
1.　Appleのりんごマークから「システム環境設定」を開く。
2.　「セキュリティとプライバシー」の中にある4つのタブのうち、1番右にある「プライバシー」を選択。
3.　「フルディスクアクセス」を選択。ロックを解除した後に、「＋」ボタンをクリック。
4.　アプリケーション一覧の中から「ターミナル」を追加。

エラーがでてできなかった内容をコマンド入力。そして確認。

```:terminal
$ mv Downloads/ダウンロードした鍵の名前.pem .ssh/
# mvコマンドで、ダウンロードしたpemファイルを、ダウンロードディレクトリから、.sshディレクトリに移動。

$ cd .ssh
#.sshディレクトリに移動。

.ssh $ ls
ダウンロードした鍵の名前.pem
#.sshディレクトリにしっかり移動できているか確認。
 =>無事移動できていました。解決です。
```

以上となります。最後までご覧いただき、ありがとうございました！
今後も学習した事項に関してQiitaに投稿していきますので、よろしくお願いします！
記述に何か誤りなどございましたら、お手数ですが、ご連絡いただけますと幸いです。


###参照
ターミナルでコマンド実行時に「Operation not permitted」と表示される場合の対処法
https://gori.me/mac/mac-tips/112082
初心者　データベース基礎　Rails

いろいろ調べて自分なりにまとめました。

#リレーショナル型データベース（RDB）とは


リレーショナル型データベース（以下、リレーショナル・データベース）は、データを行（レコード）と列（カラム）から構成される2次元の表形式で表します。列は各項目を表し、行はデータのエントリー（レコード）を表します。データ同士は複数の表と表の関係によって関連付けられ、SQL（構造化問い合わせ言語）によりユーザーの目的に応じて自由な形式で簡単に操作できます。そして、リレーショナル・データベースは、重複排除や一元管理の為のルールももっている。

##①データベースの役割

データベース基本操作　（CRUD）
Create   作成・保存 
Read     取得 
Update   更新 
Delete   削除 


##②SQLとは

SQLは、RDBMSのデータ操作や定義を行うための言語。

#SQLの3つの役割

###1.データ操作のSQL

DML（Data Manipulation Language）
INSERT | Create | 作成・保存 |
SELECT | Read   | 取得 |
UPDATE | Update | 更新 |
DELETE | Delete | 削除 |

###2.データを定義するDDL（Data Definition Language）
（データを格納するためのデータベースやテーブルを作成する）

CREATE | 新しいデータベース、テーブルを作成する
ALTER  | データベースやテーブルの更新
DROP   | 既に存在するデータベースや、テーブルを削除する

###3.データ制御のSQL

アカウントによって権限があり、アクセスできるアカウントもあれば、できないアカウントもあるような
制御を行う。
Mac Eclipseインストール

WindowsからMacに移行したので、後学のために議事録的に残していきます。



Pleiades All in Oneダウンロード

[こちら](https://mergedoc.osdn.jp/)でダウンロードします。
今回はEclipse 2019-09を選択します。
<img width="1190" alt="スクリーンショット 2019-12-01 14.55.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215898/841dc791-0ce9-8249-29c1-9dc85b457e18.png">

Mac64bitのJavaのFull Editionをダウンロード。
<img width="792" alt="スクリーンショット 2019-12-01 15.13.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215898/bdeb5b48-15a5-2969-d07c-b56521d20f0b.png">

ダウンロードしたファイルをクリック。
Windows版とは違うんですね。
ドラック＆ドロップで左から右にアイコンを持っていきます。
<img width="912" alt="スクリーンショット 2019-12-01 15.29.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215898/7165343a-9446-525a-653c-7ea4e16774dc.png">

アプリケーションフォルダから以下のアプリを起動する。
Eclipse_2019-09.app

と、次のエラー。
<img width="532" alt="スクリーンショット 2019-12-01 15.44.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215898/2b608326-81da-acbb-998d-c1dc5bd88877.png">

セキュリティから許可します。
システム環境設定 > セキュリティとプライバシー > このまま開く
<img width="780" alt="スクリーンショット 2019-12-01 15.48.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215898/07d41b1e-0390-5517-f09a-40c146cb904e.png">

開く
<img width="602" alt="スクリーンショット 2019-12-01 15.49.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215898/b535ac82-7f40-6459-408d-5bb9a8bc00ab.png">

そのまま「起動」
<img width="715" alt="スクリーンショット 2019-12-01 15.50.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215898/b1fb1229-b2b1-8171-b8e8-4bfd5c12b5d7.png">

次の画面が表示されたらインストール完了です。
想像以上に簡単でした。
<img width="1136" alt="スクリーンショット 2019-12-01 15.51.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215898/fc1ae9f9-0995-1780-2c88-170e7a301840.png">