OmniAICreator/Qiita-1.07M huggingface dataset:
ReactでのJest + Enzyme導入

# はじめに
本記事は、Udemyの[2019 Update! React Testing with Jest and Enzyme](https://www.udemy.com/course/react-testing-with-jest-and-enzyme/)という講座を聴講した内容をまとめたものです。自身のメモと、同じ初心者の方のJest導入のつかみになればと思いまとめました。

著者もプログラミング自体始めて2ヶ月程度の初心者のため、間違いや不適切な表現などがありましたらぜひぜひコメント欄にてお知らせください。

# Enzyme導入
Enzyme概要について、以下、[Enzyme公式doc](https://airbnb.io/enzyme/)より引用。
>Enzyme is a JavaScript Testing utility for React that makes it easier to test your React Components' output. You can also manipulate, traverse, and in some ways simulate runtime given the output.
Enzyme's API is meant to be intuitive and flexible by mimicking jQuery's API for DOM manipulation and traversal.

## Enzymeをセットアップ
CRA (create-react-app)にはEnzymeがないので別途インストールが必要。

### 必要なパッケージをインストール。
```terminal
npm install --save-dev enzyme jest-enzyme enzyme-adapter-react-16

※enzyme-adapter-react-[version]とする
```

### パッケージをインポート
インストールしたパッケージをインポートし、Enzymeインスタンスのconfigureメソッドを用いて設定を行う。

テストを実行するファイルのファイル名は、`[テスト対象コンポーネント名].test.js`とする。
`import ReactDOM from 'react-dom'`は不要なので削除する。

```App.test.js
import Enzyme, { shallow } from 'enzyme';
import EnzymeAdapter from 'enzyme-adapter-react-[version]';

Enzyme.configure( { adapter: new EnzymeAdapter() });
```

## 実際にテストする
テストするコンポーネント

```App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
    render() {
        return (
            <div className="App">
                <h1>Hello World</h1>
            </div>
        );
    }
}

export default App;
```

テストを実行するファイル

```App.test.js
test('renders without crashing', () => {
    const wrapper = shallow(<App />);
    expect(wrapper).toBeTruthy();
});
```

### shallow()
引数に渡したコンポーネントのみテストを行う。コンポーネント内の子コンポーネントはプレースホルダーとして扱われて実際にはレンダーされないため、子コンポーネントを干渉させずに純粋に単一コンポーネントをテストできる。shallowは「浅い」の意。

### wrapper
Enzymeに標準搭載されているAPIで、レンダーされたコンポーネントを格納することで、多くのメソッドを使うことができる。
例えば、ShallowWrapperインスタンスのメソッドの一つであるdebug()は、レンダーしたコンポーネントをHTMLライクなStringとして返す。上記の例のようにAppコンポーネントを格納した状態で`console.log(wrapper.debug());`とすると、以下のような結果がString（文字列）として返ってくる。

```
<div className="App">
    <h1>
        Hello World
    </h1>
</div>
```

各メソッドについて、詳しくは公式docの[Shallow Rendering API](https://airbnb.io/enzyme/docs/api/shallow.html)を参照。

### expect()
Jestの標準搭載メソッドで、テストしたいコンポーネントの様々な値をテストすることができる。例えば、上記例の`toBeTruthy()`ではコンポーネントの値には興味がなく、trueを返すかどうかをテストする。JavaScriptでは、`false`, `0`, `''`, `null`, `undefined`,`NaN`がfalse値として扱われるので、それ以外であればテストが通ることになる。

こういったメソッドを使い分けながら様々な値をテストしていく流れ。
各メソッドの詳細は公式docの[Expect](https://jestjs.io/docs/en/expect)を参照。

# さいごに
まだUdemyの動画を見終わっていないので、全て見たら改めて追加情報をまとめようと思います。
reactアプリをnginxを通してhttpsで公開する


# 確認環境
OS: Amazon Linux release 2 (Karoo)

# nginxのインストール
Amazon Linux 2 では標準で Nginx の YUM 向けパッケージが提供されていないため、extraリポジトリからインストールします。

```
$ sudo amazon-linux-extras install nginx1.12
```
バージョンの確認

```
$ nginx -v
nginx version: nginx/1.12.2
```

nginxの起動

```
$ sudo service nginx start
```

# nginxへのSSL設定
`/etc/nginx/conf.d`に、以下のファイルを配置します。

- `conf`ファイル(nginx設定ファイル)
- `crt`ファイル(サーバー証明書ファイル)
- `csr`ファイル(公開鍵ファイル)
- `key`ファイル(秘密鍵ファイル)

### オレオレ証明書の作成

```
$ cd ~ 
$ openssl genrsa 2048 > server.key
$ openssl req -new -key server.key > server.csr
$ openssl x509 -days 3650 -req -signkey server.key < server.csr > server.crt
$ sudo mv server.* /etc/nginx/conf.d/
$ cd /etc/nginx/conf.d
$ sudo chown root:root server.*
```
※`server.scr`作成時の答えは全て`enter`で回答しました。

### 設定ファイルの追加
設定ファイルを追加します。ここでは、`my_ssl_app`という名前にしました。
ちなみに、`/etc/nginx/conf.d/*.conf`は、`/etc/nginx/nginx.conf`から呼び出されます。ワイルドカード（`*.conf`）で呼び出されるため、名前は何でも構いません。

```
$ cd /etc/nginx/conf.d
$ touch my_ssl_app.conf
```
`my_ssl_app.conf`を以下のように編集します。

```
server {
    listen       443 ssl;
    server_name  localhost;
    ssl_certificate      /etc/nginx/conf.d/server.crt;
    ssl_certificate_key  /etc/nginx/conf.d/server.key;
    location / {
        proxy_pass http://127.0.0.1:3000;
    }
}
```

### nginxの再起動

```
sudo nginx -s reload
```

### 👀ブラウザで確認
ブラウザからhttps接続して確認すると、502 Bad Gateway のエラーページが表示されます。これは、reactアプリが起動していないためです。
![bad_gateway.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395902/d23cd02c-3312-eab3-cbbd-a7cf4125fce6.png)

# reactアプリの作成

### nodejsのインストール（インストール済なら不要）

```
$ curl --silent --location https://rpm.nodesource.com/setup_10.x | sudo bash -
$ sudo yum -y install nodejs
```

### reactアプリの作成

```
$ npx create-react-app my_app
```

### アプリの起動

```
$ cd my_app
$ npm start
```
※最新(2020/1/7時点)のreact-scriptでssl接続時に問題が発生しているようです。react-scriptが3.3.0だった場合、[リンク先](https://qiita.com/uemuram/items/a8f727b780bfd115bbaf)の対応（react-scriptの3.2.0へのバージョンダウン）を行ってください。

### 👀ブラウザで確認
ブラウザからhttps接続して確認すると、以下のページが表示されます。
![hello_react.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395902/3dd6a266-e961-3e1a-5015-cef5ab1b22d9.png)
以上。
緯度・経度を反映させたネットワーク図を描きたい。

#はじめに

以前作成したプロジェクト参画機関の地図へのプロット（[ggplot2で地図にプロジェクト参画機関の所在地をプロットする。](https://qiita.com/restructure/items/976fef268d0c02a69940)）に関して、Rで緯度と経度を重ね合わせたネットワーク図を描いてみたいと思っていました。

![スクリーンショット 2020-01-19 18.16.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149401/b9d3c970-f4c5-96d9-a10a-958d85d2ba37.png)


最終的にはこちらにプロットした地図に、ノードだけでなくエッジも反映させたネットワークグラフを描画したいと思っています。

色々試行錯誤してみたのですが、結論的にはうまくできませんでした。
今後のために、途中経過を記載しておこうとおもいます。
また、詳しい方がいらっしゃったらアドバイス頂けますと幸甚です。

#snaパッケージを使ってみる。

以下のスライドでsnaパッケージを使用したグラフの作成方法が紹介されていました。

- [Rで方言のネットワーク分析](https://www.slideshare.net/AyakaOnohara/r-11532674)

こちらのスライドを参考に作成にさせて頂き、以下のコードを記載しました。

```ruby:R
#snaパッケージを読み込み
library(sna)

#二部グラフのcsvファイルを読み込み
proj <- read.csv("proj.csv", row.names = "proj") 
proj <- as.matrix(proj)
result <- proj%*%t(proj)  

#念のため「result」の内容を確認。
> result
  k n s
k 2 0 1
n 0 1 0
s 1 0 1

#プロット地点の緯度・経度を記載したcsvファイルを読み込む。「locsaitama」と定義。
locsaitama <- read.csv("location.csv",header = T,row.names = 1)
#locsaitamaの緯度と経度が記載されている1列目と2列目を「coo」と定義。
coo <- locsaitama[,1:2]

#プロットする。
#coord = cooで、座標にcooを反映
#displaylabels = TRUEでラベルを表示。
#jitter = FALSEで頂点の座標のブレを無くす。
gplot(result,gmode = "graph",coord = coo,displaylabels = TRUE,jitter = FALSE)
```
なお、proj.csvの内容は以下のとおりです。
![スクリーンショット 2020-01-20 21.20.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149401/84eb9e9f-1f4b-4b63-daeb-b71fd4262145.png)


また、location.csvの内容は以下のとおりです。
![スクリーンショット 2020-01-19 17.45.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149401/ebbdc21c-f85d-7b2e-8f91-0c65337d3308.png)

すると、こんな感じで出力されます。
![スクリーンショット 2020-01-20 21.26.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149401/53593309-b3e9-70a8-7747-dd59815c7fa2.png)


最初の地図のプロットと比較してみると、位置的には緯度・経度が反映されているようです。

しかし、これに地図を重ねることができませんでした。

共立出版から2017年に出版された「Rで学ぶデータサイエンス8 ネットワーク分析 第2版」の第11章p302では、GGallyパッケージのggnetworkmap関数を用いた方法が記載されており、最終的にはこんな感じの表示をしたいと思っています。
（著者の先生のブログにグラフが掲載されています。）

- [地図上に航空路線を描く](https://snatool.hatenadiary.org/entry/40123580)
Cousera - Andrew Ng 先生の Machine Learning Week 5

## 概要

Week 5 ではニューラルネットワークを誤差逆伝搬法を使って学習することを学びました。

## 誤差逆伝搬法

- 誤差逆伝搬法は、コスト関数の微分を得る方法
- 微分が分かれば今までと同様に最適化手法を適用できる

## 誤差逆伝播法のアルゴリズム

各データに対して、

1. 入力層に入力値をセット
2. forward propagation を普通に計算
3. さっきのδを入力層に向かって計算する. 最初は単に δ(L) = (出力層 - データの答え)
4. 中間層は各エッジのウェイトと接続先のエラーをかけて足し合わせたものをエラーとする
5. 各ノードの出力とそのエラーをかけたものを配列として集めて Δ とし、前回の Δ と足す 
6. 最後に、エラーの重みに関する偏微分と等しくなる D を計算する. D は Δ / m + λΘ だが、証明は難しいとのこと

λ は正規化の係数
δ (デルタの小文字) は各レイヤーの各ノードのエラー。以下のように計算する

- 最後のレイヤーの各ノードの出力と答えの差
- 中間のレイヤーは 

```math
δ^{(l)} = (Θ^{(l)})^Tδ^{(l+1)} .* g'(z^{(l)}) 
```

簡単に言うと、重みとその出力のエラーをかけて合計しただけのものと同じようなもの

## 直感的な理解は難しい

- 誤差逆伝播法が直感的に分かってなくてもちゃんと使える
- 線形回帰やロジスティック回帰と比べて誤差逆伝搬法は数学的にクリーンというわけではない
- 可視化するのも難しい。

## 誤差逆伝搬法を理解するための工夫

わかりやすさのために変えること

- 正規化を無視
- ロジスティック回帰の代わりに誤差の二乗を使う

## Backpropagation in Practice

今まで使ってきたアルゴリズムはベクトルを受け取ってベクトルを返すものだったが、ニューラルネットワークは重みなどが行列になった。行列からどうベクトルを取り出す (Unroll する) のかという話。

行列を長いベクトルにする。(:) を使ってベクトルとして取り出して結合する

```matlab
thetaVec = [Theta1(:); Theta2(:); Theta3(:)];
```

戻すときは reshape を使う

```matlab
Theta1 = reshape(thetaVec(1: 100), 10, 11); 
```

Theta1 は 10x11 の行列

パラメータが行列になっているほうが扱いやすいが、最適化アルゴリズムはベクトルを受け取るように作られていることが多いので unroll する必要がある

## Gradient Checking

- Backpropagation はバグを作りやすい
- 最急降下法がちゃんと実装できているか確かめる方法

Θを少し増やした値と少し減らした値の J の傾きをもって Θ の傾きの近似とする

```math
\frac{d}{dΘ}J(Θ) ≒ \frac{J(Θ+ε) - J(Θ-ε)}{2ε}
```

εはとても小さな値で、

```math
ε = 10^{-4}
```

だいたいこれくらいの値を使う。小さすぎると問題があるそう。

### Θがベクトルの場合

- 各パラメータに関して上と同じことを行う
- 得られた数値が誤差逆伝搬法で得られた数値に近いか確かめる (小数点以下数桁が同じとか)
- gradient checking はとても遅い処理なので実際の学習の際には使わないようにする。

## Random Initialization

Θの初期値

- ゼロで初期化するのはロジスティック回帰ではよいがではうまく行かない
- 各エッジの重みが同じだと偏微分も等しくなるので、どのエッジも同じ値になってしまう
- ランダムに初期化する

## Putting It Together


- コスト関数を作る
- 誤差逆伝播法によってコスト関数の微分の式が与えられる
	- Gradient Checking でも近似した微分の式が得られる
- Gradient Decent や他の最適化手法によって微分が0の場所に近づくようにしていく
	- パラメータの微分をベクトルとして渡すように作られているので unroll する
- コストが最小になる重みが見つかる

## 課題メモ

### Pause 問題

https://v-crn.hatenablog.com/entry/2019/09/25/Octave_5.1.0%E3%81%A7pause%E3%81%AE%E6%8C%99%E5%8B%95%E3%81%8C%E3%81%8A%E3%81%8B%E3%81%97%E3%81%84

macOS で octave を実行すると pause がうまく動かない問題があり、いままでは pause があるところを消して対処していた。
ここに載っている pause 関数を pause.m として ex4 ディレクトリに入れておけばうまく動いた。

```matlab:pause.m
function pause
  input('','s');
end
```

### Octave-gui

課題の実装時に行列のサイズが合わずに内積ができなかったりするミスが頻発して、そろそろ実行、デバッグのルーチンが大変になってきた。
Octave-gui を使うとブレークポイントを張ったところで止めて現在の変数の中身を GUI から見ることができるので便利だった。
しかし、1つ目のブレークポイントで止めた時にコンソールでコマンドを入れるとなぜかプログラムが続行してしまう不具合があった。止めたいところの前の適当な場所にブレークポイントを張って一度止めておくと、二度目の停止では問題なく動いた。

### 課題内容について

- Feedforward NN は前作ったのと同じコードが使える
- ラベル出力と数値を変換するのは対角行列を作る diag を使うと便利だった
- Backpropagation を実装するのはえらい大変だった。数式通りに作ればよいが、内積でつまづいた。行列のサイズと縦横を気をつけること。また例によって縦横の違いで数式と内積の順番が異なることがある。コード量は多くない
- Regularization した結果は、してない結果と同じ J や Theta1_grad に入れるが、テストがうまく作られてて Regularization してなくても通る設問としてないと通らない設問になっていて submit できる
Cousera - Andrew Ng 先生の Machine Learning Week 4

## 概要

- ロジックを実現するニューラルネットワークを作る
- 今回はあまりノートを取っていなかったのでメモだけ

## 講義メモ

- ニューラルネットワークの入力にはX0、バイアスユニットやバイアスニューロンと呼ばれる1を出力するものを置くこともある
- アクティベーション関数: いままでの授業で言うところのシグモイド関数とかにあたる
- ウェイト: パラメータ (シータ) のこと

### パラメータ

- a_i(j): j レイヤーの i 番目のユニットの出力
- Θ(j): jレイヤーからj+1レイヤーへの重みの行列
- s_j: jレイヤーのユニット数

重みの行列のサイズは s_(j+1) x (s_j + 1) となる　(s_j + 1 の + 1はバイアスノードがあるから)

### ニューラルネットワークのよさ

基本的にニューラルネットワークはいままでのロジスティック回帰とやってることは変わらない。興味深いのは層が2つ以上あるおかげで、1層目などでニューラルネットワーク自身が作り出した特徴量をロジスティック回帰に入力できること。いままでの授業では x1 * x2 + x1^2 + x1^2 * x2^2 のような組み合わせの特徴量を作っていたが、パラメータの数が増えすぎる問題があった。

### 論理ゲートを作る

AND, NOT, OR から XNOR のニューラルネットワークを作るには、それぞれを表すニューラルネットワークをまず作り、重みを先に計算してから、AND, NOT を重ね合わせた1層を作り、2層にORを置く. AND, NOT は入力が同じなので重ね合わせて一つの層にできる。
Virtualboxで、USB 2.0 / 3.0 を使う

# Virtualboxで、USB 2.0 / 3.0 が使えなかった。
Virtualboxで仮想マシンにUSBを使わせたかったのですが、「USB 2.0」や「USB 3.0」を選択しようとすると「無効な設定が見つかりました」となってしまい、適用できません。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513300/07b7464a-be38-b073-e607-d4a4a40d46ee.png)
#環境
OS: Windows 10
Virtualbox: 6.1.2 r135662 (Qt5.6.2)
#対処
USB 2.0 / 3.0 を使う為には、Extension Pack のインストールが必要です。
https://www.virtualbox.org/wiki/Downloads

- All supported platforms をクリックし、ファイルをダウンロード。
↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513300/2fbd4488-b0a4-5adc-9618-2e78343cb907.png)

- ダウンロードしたファイルを実行。
↓
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513300/ca62e58d-de14-2c9b-a31a-0f38bfa2d550.png)

- あとはトントントン
↓
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513300/23746ead-8ef5-7f15-43cd-1df669d28824.png)
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513300/37682b9a-2a9e-f7c8-c9d5-fb94338b904b.png)
![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513300/9d54fe88-fe5a-943f-5922-d91c2e43624f.png)

- UBS 2.0 を選択しても、警告が出なくなりました。3.0 もOKです。
↓
![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513300/2a64cfa1-c93e-0b15-3142-11a0bb2db80e.png)
「invalid_grant Invalid JWT Signature.」エラーが突然発生したときの対処方法

datastoreを絡めたAPIを触っていると、ある日突然以下のようなエラーが発生するようになった。

```json
{
  "error": "invalid_grant",
  "error_description": "Invalid JWT Signature."
}
```

全く心当たりがなかったので色々調べると、どうやら`GOOGLE_APPLICATION_CREDENTIALS`に割り当てているサービスアカウントが関係してそうだったので、以下でアカウントを切り替えて動作確認しようとした。

```sh
$ gcloud auth activate-service-account --key-file ${service-account-path}
```

すると最初のエラーと同様のエラーが出力された。

```sh
ERROR: (gcloud.auth.activate-service-account) There was a problem refreshing your current auth tokens: invalid_grant: Invalid JWT Signature.
```

そこでサービスアカウントを生成し直したところ正常に動作することを確認した。

```sh
# 割り当ても問題なし
$ gcloud auth activate-service-account --key-file ${new-service-account-path}
Activated service account credentials for: [new-service-account@project-name.iam.gserviceaccount.com]
```
React Nativeでコードの変更が反映されない時（Android）

## コードを変えても反映されない問題（RN）
React Nativeでしばらく触っていなかったプロジェクトやアップグレードを行なった際に、コードを変えても変更がデバイス上で反映されないことがある。

以下のコマンドで解決した。

```bash
react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/

# ↑を叩いたらいつも通り起動
react-native run-android
# or npx react-native run-android
```

参考：
https://stackoverflow.com/questions/48304116/react-native-run-android-do-not-updating-modified-code
【React】useReducer をもっと自由に活用しよう

## useReducer をもっと自由に

皆さん、`useReducer` は活用していますか？
`useState` で十分と思っている場合でも `useReducer` に置き換えることで、コードがシンプルかつ、わかりやすくなります。

そのためには、Reduxの呪縛を解き払ってください。`useReducer`に Action type は必要ないですし、Flux Standard Action も必要ありません。また、今回は`dispatch`も`dispatch`らしい使い方はしていません。
つまり、Redux と同じ使い方をする必要はありません。

```js:🙅‍♀️別にActionType必須ではない
const [state, dispatch] = useReducer((state, action) => {
  switch(action.type) {
    case 'FOO_ACTION':
      return { ...state, foo: action.foo }
    case 'BAR_ACTION':
...
```

## useReducer 活用例

では、`useReducer` を使用すると、どのように変わるのでしょうか。簡単なサンプルコードをもとに紹介します。
【追記】下記の例は、Reactではうまく動作しません[^1]（preactでは動作します）。後日差し替え予定ですが、イメージのつかみやすさから一旦この例のまま紹介します。

[^1]: React では、DOM の Event を独自オブジェクト(`SyntheticEvent`)で  wrap しているのですが、それの有効期限が `useReducer` の処理実行タイミングまで生きていないのが原因です。

```jsx:例)テキストフィールド
const { value, onChange } = useInput()

return (
  <input type="text" value={value} onChange={onChange} />
)
```

上記はなんの変哲もないテキストフィールドです。
これに合うカスタム Hooks (`useInput`) を、`useState` と `useReducer` でそれぞれ作成します。

### useState の場合

```js:useStateを使用した場合
export const useInput = () => {
  const [value, setValue] = useState('')

  const onChange = useCallback((event) => {
    setValue(event.currentTarget.value)
  }, [])

  return { value, onChange }
}
```

`useState` を使用した場合、Hooks は2つ使用します。今回の用途では `useCallback` はオーバーキル感がありますが、他コンポーネントや他 Hooks で使用する可能性がありますので、メモ化しておくのが良いでしょう。
いずれにしても、`onChange` 関数を作成するには `setValue` をラップします。

### useReducer の場合

```js:useReducerを使用した場合
const inputAction = (state, event) =>
  event.currentTarget.value

export const useInput = () => {
  const [value, onChange] = useReducer(inputAction, '')

  return { value, onChange }
}
```

`useState` を使用した場合よりも、シンプルになりました。
`useReducer` で記述するメリットは下記の2つです。

- 状態とそれを更新する関数が、ワンセットになる
- reducer 部分は純粋関数であり、Hooks やコンポーネントの外に出せる

1つ目について、`setValue` のような中間の Setter が生まれませんし、用途に合わせる関数(`onChange`)を別途作る必要もありません。
また、2つ目の関数外部化は、テストがしやすくなるだけでなく、無駄なオブジェクトを生成しないというパフォーマンス面のメリットもあります。


## まとめ

`useReducer` を使用する場合、Redux 等の使い方に縛られる必要はありません。
単純な state でも `useReducer` に置き換えることで、コードがシンプルかつ、わかりやすくなり、テスタビリティがあがってパフォーマンスも上がります！
Javascriptのspliceで削除すな

# 概要
Backendで動くJavascriptのコードを引き継いだ際に、ちょっとやばそうなミスをしていたので共有します。


## 環境
OS：Windows 10
言語：Javascript
## splice関数？
Javascriptの配列標準関数。
大体の使い方は以下を参照。
[spliceは切り取るだけのメソッドではなかった](https://qiita.com/seihmd/items/dfeb41e12d693c9d4d7c)

# 問題箇所
問題の箇所は以下。
特定の形のエラーデータをspliceで削除しようとしていた。

```javascript
// ErrorData削除処理
for(var i=0; i<array.length; i++){
  if(checkErrorData(array[i]===true)){
    array.splice(i, 1);  // i番目の要素を削除
  }
}
```

一見問題なさげに見えるけど大問題。
splice関数は配列のインデックスをめちゃくちゃにするので一連のループ処理で何度も実行するとえらいこっちゃになる。

# ちょっと掘り下げ
実例で考える。
![配列初期.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527371/e4c2cbdc-9857-f3d5-209c-622f8f379420.jpeg)

Errorデータを削除するため、i=3時に削除が実行されます。
![配列初期.002.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527371/f20f3ccf-2ba1-e330-7675-8ebdc629cf66.jpeg)

この時、削除された段階で配列が作り替えられています。forループのカウンタiはそのままインクリメントされるため、元々index=4だった要素に対してErrorチェックが行われません。

![配列初期.003.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527371/064bb28a-5e5c-6ca1-d4b5-564db853e91d.jpeg)

# 問題まとめ
Errorデータの次のデータにチェックが行われない構造になっていますね。
なので以下のデータで削除漏れが起こります。
![配列初期.004.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527371/8b276e9c-0874-9184-3819-40db0c250c04.jpeg)

# 対策
1. splice関数を使ったお姉さんに文句をいいましょう
2. 配列から要素を削除する際はfilter関数を使いましょう

- filter関数は以下を参考

[【JavaScript入門】filterで配列のデータを抽出する方法](https://www.sejuku.net/blog/21887)

削除というよりはErrorデータ抜きの新しい配列を代入する感じです。
速度的にも圧倒的にこっちの方が早いですね。
以下に書き換えました。

```javascript
// ErrorData削除処理
array = array.filter( function (item) {
  return checkErrorData(item) === false;
})
```

callback関数でitem（配列の各要素）をチェックして、正常なデータの時だけtrue値を返す感じです。

以上、駄文でした。
K3s バージョン v1.17.0+k3s.1 リリースノート翻訳

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

この記事は、Rancher Labs社のK3sのバージョンv1.17.0+k3s.1のリリースノート(原文は以下)を翻訳したものです。

Release v1.17.0+k3s.1 · rancher/k3s
https://github.com/rancher/k3s/releases/tag/v1.17.0%2Bk3s.1

--------

# v1.17.0+k3s.1

K3sのバージョン命名規約を変更しました。K3sのメタ情報を追加したkubernetesバージョンを示すバージョニングモデルに移行しました。このリリースでは、kubernetesをバージョンv1.17.0にアップグレードし、バグを修正しています。

## v1.0.0からのバグ修正と機能拡張

v1.0.0からの全てのイシューリストは[v1.17.0+k3s.1マイルストーン](https://github.com/rancher/k3s/milestone/13?closed=1)を参照してください。

## このバージョンの特徴

Kubernetes v1.17.0にアップグレード [#1174](https://github.com/rancher/k3s/issues/1174)
Helm ControllerをHelm v3にアップグレード [#1218](https://github.com/rancher/k3s/issues/1218)
ソース・ファイルから実行可能なファイルができるまで

## この問いの答えがわかりますか

```text
1. 複数のオブジェクト・ファイルを結合してEXEファイルを生成するツールは？
2. プログラム実行時に、データやオブジェクトのために動的に確保されるメモリ領域のことを何という？
```

答えは

```text
1. リンカー
2. ヒープ領域
```

です。

本記事では、これらの理解が進むことへの手助けとなるような記事を目指します。

## 異なる言語をCPUで処理できるようにするために

皆さんはどの言語を使ってプログラムを書いていますか。C, C++, Java, Ruby, PHP, Javascript, Go, Rust, Scalaなど、数限りないほどの種類のあるプログラミング言語のうちのいくつかを使っているのではないでしょうか。

言語が違うのになぜ、プログラムは動作し、何かを表示したり何かを計算したりすることができるのでしょうか。

それは、異なる言語を、CPUが読める共通の言語へと変換しているからです。

CPUが解釈できるのはネイティブ・コード(マシン語)のみです。

私が普段扱う、Ruby, Javascript, Goなど、**どの言語においても例外なくマシン語に変換**されCPUが理解できる形へと変換されているのです。

そしてこの変換のことを**コンパイル**と呼び、コンパイル(翻訳)する機能を持ったプログラムのことを**コンパイラと**呼びます。

### マシン語とは

マシン語は16進数(2進数でも表せますが、読みやすさから16進数が使われているみたい？)の羅列です。
`3E CD 32 00 01 76`こんな感じの数値の羅列です。

### コンパイルとマシン語の例

以下のコードをどこの環境でも良いので、コピーして `sample.c` とか、なんでも良いのでファイルを作成してください。

```c
#include<stdio.h>
int main() {
  printf("Hello, World\n");
  return 0;
}
```

以上のコードをコンパイルしてみましょう。macであれば、brewでgccをインストールしてください。

```sh
brew install gcc
```

インストールしたら `gcc sample.c -o sample` を実行してみてください。

コンパイルが終わると `sample` というファイルが作成されているはずです。このファイルがsample.cをコンパイルしてバイナリファイルに変換された実行ファイルになります。
以下のコマンドで実行でき、

```sh
./sample
```

以下のコマンドでファイルの中身を確認してみましょう

```sh
cat sample
```

このファイルの中身を見るとわかりにくいと思うので、以下のサイトで16進数へと変換してみてください。マシン語は変換後の数値で表現されています
http://tomeko.net/online_tools/file_to_hex.php?lang=en

### リンカー

最初の段階で問題として出したリンカーですが、先ほどのコンパイル時に密接に関わっています。

gccコマンドによってコードがバイナリへと変換されるわけなのですが、次のような流れで変換が行われています。

```text
コード
→ コンパイルによってオブジェクトファイルへと変換
→ リンカーによって各種関数がコードにリンク
→ 実行ファイル完成
```

オブジェクトファイルという新しい言葉がでてきましたが、あまり気にせず飛ばしてしまいましょう。
`リンカーによって各種関数がコードにリンク`ですが、関数というのはその言語が標準で持っている関数を紐づけて(`リンク`)いたりする。

## スタックとヒープ

[メモリーとディスクとの関係について](https://qiita.com/mergit/items/98b0753288d8b1422479)で説明したメモリーですが、１つのプログラムが占有する領域では4つの領域に分けられます。

1. 変数のための領域
2. 関数のための領域
3. スタックのための領域
4. ヒープのための領域

です。

スタックは関数の内部で一時的に使用される(ローカル)変数や、関数を呼び出すときの引数を格納しているメモリ領域
ヒープはプログラムの実行時にデータやオブジェクトを格納するメモリ領域

となっています。

実行ファイルをメモリに読み出すときに、必要な領域が確保されます。
言語によって変わる部分もありますが、int, int64, string, floatなど型を定義する言語(静的型付け言語)の場合は、アプリケーション実行前に前もって実行用のファイルをコンパイルし、スタック領域の確保のためのコードは自動で生成されるためエンジニアは何も意識する必要がありません。
またc言語の場合は`malloc, free`関数を使うことで確保と解放を明示的に示しますが、それ以外の場合はヒープ領域のことを特別意識することは少ないでしょう。(知らない言語もあるので言い切れないですが)

### 参考

[プログラムはなぜ動くのか](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AF%E3%81%AA%E3%81%9C%E5%8B%95%E3%81%8F%E3%81%AE%E3%81%8B-%E7%AC%AC%EF%BC%92%E7%89%88-%E7%9F%A5%E3%81%A3%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98-%E7%9F%A2%E6%B2%A2%E4%B9%85%E9%9B%84/dp/4822283151/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=31ZWKMQS79060&keywords=%E3%81%AA%E3%81%9C%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AF%E5%8B%95%E3%81%8F%E3%81%AE%E3%81%8B&qid=1579409356&sprefix=%E3%81%AA%E3%81%9C%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AF%2Caps%2C105&sr=8-1)

### シリーズ

[プログラムはなぜ動くのか](https://qiita.com/mergit/items/2e594e2da8456a64f3da)
ffmpegで雑にアニメーションgif作る

zshのhistory飛ばしてしまったので。

```shell-session
ffmpeg -i input.mov -vf 'fps=15,scale=800:-1' output.gif
```

とかで15フレーム/秒、アスペクト比保ったまま幅800pxに縮小(拡大)したアニメーションgifができる。
雑なのでパレットは用意してません。
録画はmacOSなら `Cmd+Shift+5` とかで。

:arrow_down: こんなスクリーン録画してgif作るときに便利
![zsh_diff.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9676/c80b1ca3-0596-8218-a5ee-a976db15c1db.gif)
「Settings Sync」を使ってVS Codeの設定をバックアップする方法

# はじめに
Setting SyncというVS codeの拡張機能がとても便利そうだったので
試しにinstallしてみました。
その時の手順を簡単にまとめたものです。
# Settings Syncとは？
VS Codeの各種設定をGitHubのGistに保存することで、
設定のバックアップ並びに、他端末と設定を共有することが出来ます。
インストールしていた拡張機能の情報も含めて保存してくれる為、非常に便利な拡張機能です。

# 必要なもの
 1. VS Code
 2. GitHubのアカウント

# Settings Syncのインストール方法
まずは以下の拡張機能をVS Codeでインストールします。
![Settings Sync.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239956/e0b9905a-e82f-900e-2abd-a233ad5d5388.png)

インストールが完了すると、設定画面が表示されるので、
右上にある「Login With GitHub」をクリックすると、ブラウザで同期の確認ページが開きます。
![Settings Sync_WelcomeSettings.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239956/c82f94d1-db50-bfe8-b971-bb578995bd79.png)

次に、「Authorize  amohovhannisyan」ボタンをクリックすると、Success!と表示される(画面取り忘れました)

「SKIP」ボタンを押して、Gistの新規作成をします。
![settings Sync-Gist.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239956/5c56997f-ef3f-4e7f-0fbb-25a662675564.png)

GitHubのGistに「cloudSettings」が作成されていれば成功です。

# Settings Syncの使い方
## 設定を更新/アップロードする
　コマンドパレットから「sync update」と入力し、コマンドを実行する
　（または、「Shift」+「Alt」+「u」）

## 設定のダウンロード
　Sync Settingsをインストール後、Gitsの新規作成ではなく、「Visual Studio Code Settings Sync Gist」を選択
　紐づけが完了したらコマンドパレットから「sync download」と入力しコマンドを実行する
　（または、「shift」+「Alt」+「d」）
開発者用フォントJetBrains MonoとConsolasを比較してみる

2020年1月15日に公開された開発者用フォント「JetBrains Mono」を試してみます。

無料でダウンロードできます。
https://www.jetbrains.com/lp/mono/

Visual Studio Codeにデフォルトで入っていた`Consolas`と比較してみます。

# 数字

Consolas
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138682/cc4cca7c-fbf0-0c6e-84b4-07f6fecdace6.png)

JetBrains Mono
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138682/4a3eac96-97a0-a324-65a4-e6f888a25caf.png)

0、3、4のデザインが特徴的のように思います。

4がかっこよくて好きです。

# アルファベッド

Consolas
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138682/ec086e02-0777-1979-1d7b-9eb2535f3b1d.png)

JetBrains Mono
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138682/0bb10a1a-1376-85bf-cbfe-d9dcaf45f072.png)

小文字が全体的に大きめになっている気がします。

FやJあたりを見ると、横棒が長めになっている事もわかります。

同じフォントサイズでもConsolasより大きめになっています。

# 記号

Consolas
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138682/83fd1ab7-8009-1e8d-90b5-263512d13478.png)

JetBrains Mono
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138682/a1366cfd-f4b6-e511-4d31-2fec6dd25819.png)

$や@のデザインが特徴的です。

*は線の数を減らしているようです。

# 全体的に

全体的に直線を多く使ったシャープなデザインになっています。

エディタが今までよりかっこいい雰囲気に感じることもあるかもしれません。

選択肢が増えて楽しいです。

以上です。

---

以下は参考になれば
[Visual Studio CodeにJetBrains Monoフォントを設定する](https://mrkmyki.com/2020/01/17/visual-studio-code%e3%81%abjetbrains-mono%e3%83%95%e3%82%a9%e3%83%b3%e3%83%88%e3%82%92%e8%a8%ad%e5%ae%9a%e3%81%99%e3%82%8b/)
Flaskアプリをherokuにデプロイ（苦苦々）

#Flaskアプリをherokuにデプロイ（苦苦々）
なかなか苦労させられる。

$ heroku logs --tailで遭遇したエラー
`error code=H10 desc="App crashed"`
`error code=h14 desc="no web processes running"`
など。
それぞれをStackoverflowなどで対処療法しても解決しない。
しかし下記の方法でうまく行った。


###Python仮想環境を作る
```bash
$ virtualenv flaskapp
$ cd flaskapp
```

#####仮想環境をアクティベイトする
```bash

$ source bin/activate
```

#####こんな感じになる。

```bash

$ (flaskapp) $
```

#####ここでマシン環境に影響を及ぼさずにpipでいろいろインストールできる。
たとえば、

```bash

$ (flaskapp) $ pip install requests
$ (flaskapp) $ pip install Flask
```

とかとか。

ここではgunicornとFlaskをインストールする。

```bash
$ (flaskapp) $ pip3 install Flask gunicorn
```

【gunicorn参考】: GunicornはpythonのWSGI(Web Server Gateway Interface) HTTP ServerでRubyのUnicornの派生。Gunicornは様々なフレームワークと比べると、とってもシンプルな実装で、軽量なサーバー。
参照：https://qiita.com/arata-honda/items/09e1c350b1bd8a186e9c
【使い方】
pip install gunicornでgunicornをインストールして、
gunicorn hello:appで起動する。


###Herokuの準備

Herokuのサインインは済んでいる前提

#####Heroku CLIインストール
```bash

$ (flaskapp) $ wget -qO- https://cli-assets.heroku.com/install-ubuntu.sh | sh
```

#####Herokuにログイン
```bash

$ (flaskapp) $ heroku login
```

######準備ファイル
- Procfile

```bash
$ echo "web: gunicorn app:app --log-file -" > Procfile
```

- requirements.txt

```bash

$ (flaskapp) $ pip3 freeze > requirements.txt

Click==7.0
Flask==1.1.1
gunicorn==20.0.4
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
Werkzeug==0.16.0
```

- runtime.txt（任意）

```bash
$ (flaskapp) $ python -V | sed -n "s/Python /python-/p" > runtime.txt
```

- app.py

```python
from flask import Flask
import os

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 5000)))

```
ここでただ単にapp.run()としないところが味噌。

この時点でローカルでちゃんと動くか確認。

```bash
$ (flaskapp) $ python app.py
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

$ curl http://127.0.0.1:5000
Hello World!
```

###herokuへデプロイ

```bash

$ (flaskapp) $ git init
$ (flaskapp) $ echo "*.DS_Store" > .gitignore
$ (flaskapp) $ git add .
$ (flaskapp) $ git commit -m 'first commit'
$ (flaskapp) $ heroku create
$ (flaskapp) $ git push heroku master
```

###動作確認
#####Herokuコンソールの画面右上のOpen appボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/ef07abc6-251a-6e7f-124b-40cda3c1ee1f.png)

別画面が開いて無事にHello Worldと表示された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/50a17141-c436-3ff1-a2bb-4d6ab0551bf1.png)


<br>

###追記

#####Herokuにフォルダを追加したい場合
Flaskでよく使う`staticフォルダ`などをアプリに追加してHerokuにデプロイしてもheroku上に作られない。理由はgitはカラフォルダを無視してしまうから。
なんでもいいからstaticフォルダにファイルを入れておいてからデプロイするとstaticフォルダが作られる。

<br>

参考：[【完全版】Flaskで作ったAPIをHerokuにデプロイする手順（備忘録）](https://qiita.com/ahpjop/items/e333eaf304dcdd72d886)
参考：[Error: No such file or directory: '/app/{myappname}/static'”](https://stackoverflow.com/questions/19323513/heroku-django-oserror-no-such-file-or-directory-app-myappname-static)
high_voltageで利用規約等の静的ページを作る

#high_voltageで静的ページ（プライバシーポリシー、利用規約など）作成
routesとcontrollerの記述不要
headerやfooterを適用したい場合

`gem high_voltage`
で

```routes.rb
/pages/*id 
```
を自動生成してくれる。rails routesで確認しよう
routes.rbには記述しないでいい

#つまづいたところ
https://github.com/thoughtbot/high_voltage

Disabling routes
The default routes can be completely removed by setting the routes to false:

```
# config/initializers/high_voltage.rb
HighVoltage.configure do |config|
  config.routes = false
end
```
※high_voltageのgithub参照

config.routes = false
はhigh_voltageのルートを使えなくするという意味。ここを読まずにコントローラーを作成したりルーティングを記述したりして複雑にしてしまっていた。

high_voltageのgithubやREAD.MEを参考にしてよく読む。

#レイアウト指定

```initializer.rb
config.layout = 'customer' 
#customer.html.slimがheader footerが書かれているlayout配下のfile
```
で適用したいレイアウトを指定

views/pages内に

```confirm.html.slim
=link_to 'プライバシーポリシー', page_path('privacypolicy')
```



```confirm.html.slim
=link_to '利用規約', page_path('terms')
```

と記述する

リンクごとにpages/privacyやpages/termsが表示されるようになります。

コピペじゃなくてなぜ動いているかを考えよう(自戒)
Synology DockerでJenkinsをセットアップするのに必要な手順 (initialAdminPasswordが知りたいんじゃ)

# 前提
Synology NAS DS218+で遊んでいます。
NAS ：Synology DiskStation 218+
　　　 RAM：10GB（2GB+8GB）
　　　 HDD：4TB + 3TB

8GBはインストールはできるけどサポート外になるのでお気をつけて<br>


# 概要
Jenkins-blueoceanをセットアップした時の初期パスワードの確認方法がわからなかったのが、やっと分かったのでメモ

# ローカルの場合
ローカルでの初期パスワードの確認は、terminalで
```cat $HOME/jenkins_home/secrets/initialAdminPassword```
を入力し、表示されるパスワードを利用します。

# Synology Docker jenkinsの場合
~~Synologyとsshで接続してこのコマンドを入力しても見つかりません。~~
Synology Dockerのコンテナから、セットアップしたJenkinsの詳細を表示し、詳細画面の[概要][プロセス][ログ][端末]から「端末」を選択。
作成ボタンを押下したら表示される[bash]を選択。
terminalが表示されるので、
```cat var/jenkins_home/secrets/initialAdminPassword```
を入力し、表示されるパスワードを利用します。

# Synologyにsshで接続して、Docker jenkinsのパスワードを確認する場合
sshから接続した場合、「dockerにアクセスする」という作業が必要なことに気づいていませんでした。

Synology NASにアクセスする
・IPアドレスとポート番号は環境に合わせて
・UserNameはSynologyに登録されているアカウントを利用
・パスワードは@前に付けてるSynologyアカウントのパスワード
```$ ssh UserName@192.168.100.100 -p 22```

指定のコンテナにbashで接続する
・sudoをつけないとpermission deniedが出て繋がりません
・パスワードは@前に付けてるSynologyアカウントのパスワード
``` UserName@NAS$sudo docker exec -it ContainerTab bash```

あとは
```cat var/jenkins_home/secrets/initialAdminPassword```
するだけ
Vue TypeScript バリデーションチェック

#Vuetifyのrulesを使う。
Vuetifyの`rules`を使うことで比較的簡単に実装できます。
なので今回は`vuetify`の`rules`を使います。

前にはてなブログでvuetifyについて簡単に書いた記事書きました。
https://taitoajiki.hatenablog.com/entry/2019/10/21/232910


#いざ、実装
```Vue
<template>
<v-text-field solo :counter="10" :rules="bbb"></v-text-field>
</template>
<script src="./Rules.ts"></script> 
```
```TypeScript


  private bbb: any = [
    (v: any) => !!v || "Name is required",
    (v: any) => this.nameRules(v)
  ];
 
   private nameRules(value: any): any {
    return value.length <= 10 || "Name must be less than 10 characters";
  }

```

###ポイント
`rules`は配列にすること。

入力文字されたがコードの`v`に入ってくること。

そして`bbb`の中の関数はfalseの場合に何の文字を
<b>`false`のときにどんな文字を表示をさせるのか</b>が大事です。


###説明
`nameRules`を説明すると、`return`を見てもらうと
入力文字が10文字以下の場合は`true`を返します。
そして10文字以上のは`false`となって表示する文字が返却される。
という感じです。



#はてなブログ、Twitterやってます。
Twitterを始めました。始めたばかりで友達少ないのでフォロー待ってます！
Twitterはこちら⬇︎
https://twitter.com/apasn1
はてなブログはこちら⬇︎
https://taitoajiki.hatenablog.com/



##Vuetifyのvalidation公式ドキュメント
https://vuetifyjs.com/ja/components/forms
僕のC#基礎の基礎

Python、Java、VBAのみしか使用したことがない自分用の超超基本的な記述の仕方の解説。
なんか色々な言語やりだすと些細な差がわからなくなったりするんですよね。

####超基本
- 行の終わりは`；`。
- コメント
 - 一行 `//`
 - 一部　`/*` ～ `*/` 
- 文字列は`'`でも`"`
- 比較演算子で
 - 積：`&&`
 - 和：`||`
 - 否定：`!`
- 定数`const`
- 数値型の文字型への変換`データ.toString()`
- 変数基本は、キャメルっぽい。（自分が読んだ本がそう書いてたからそう思った。）
- メソッドでの参照渡し

```c#
//定義側
private void method(ref x){
    //処理
}

//呼出し側
y = method(ref x) 
```
【4時間ノーカット】現役フロントエンドエンジニアが写経したらどうなるか

個人的には日本で初めての試みだと思っている。
ある程度習熟したフロントエンジニアが
本気で写経したらどうなるかを4時間ノーカットで撮影した。

# なぜそんなことをしたか

JavaScriptに詳しくて優秀なひとが
マークアップで苦戦する姿を何度か見たことがある。

手際の良さや、どういう思考回路で実装しているかは
非常に言語しずらいため教材になりにくい。

そういった方々に向けて、
ある程度マークアップのできる自分が仕込み無しのライブコーディングを公開することで
成長のヒントになれば良いと思った。

# 業界あるある　〜CSSナメられがち〜

HTMLやCSSは仕事の単価が低い。
いつか自動化されるとも思っている。

しかし、いまの時代はまだ
フロントエンドのエンジニアがマークアップをすることは珍しくない。

もしあなたが現役のフロントエンジニアで
いくらJavaScriptに詳しくても、マークアップが遅かったり品質が悪かったりすると
第三者からみたときにトータルで仕事が遅いと思われたり、品質がよくないなと思われてしまう。
これは本当にもったいない。

Mizchiさんみたいに
自分の個性を自覚してポジショニングできるひとだったらまだしも

ほとんどのエンジニアは
この現実から逃れられることはできないと思うので
私はフロントエンドエンジニアでも
マークアップの練習をしてほしいなという考えを持っている。

# お題

Youtubeのチャンネルページ

![design.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124296/547bbabd-39d7-b616-53e3-ce9cfdc00e36.png)

# ルール

- 画像のレイアウトを写経してください
- アイコンとかはなんでもいいです。(アイコンの再現は必要ないです)
- JSは必要ないです(react, vueも使わない)
- PCのみでおっけーです

# 結果

![localhost_1234_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124296/f1558f8e-236a-1792-9966-00f8f2f1859f.png)


# 動画

最後ちょっとスタミナ切れてますね..。

https://youtu.be/bVjp_1l_l6Y
カルシウムイメージングをDeep Learningで解析する「STNeuroNet」

2019年のPNASに新しいカルシウムイメージングの解析ソフトが論文発表されていました。
Deep Learningを手法として用いており、STNeuroNetと名付けられてます。
ベースのプラットフォームとしては、niftynetが用いられているようです。

GitHubページ：https://github.com/soltanianzadeh/STNeuroNet
論文：https://www.pnas.org/content/116/17/8554

今の標準ツールとしては、CaImAn(Calcium Imaging Analysis)がありますが、これはCNMF(条件付きの非負値行列因子分解)を手法として用いています。
それに対して、STNeuroNetはDeep Learningを用いて細胞の場所を割り出します、

概要としては、
まず前処理で動画から背景を取り出し標準化した3次元データを作ります。
次にそのデータにDeep Learningの入力にし、ネットワークの出力として、細胞の確率マップが画像として出力されます。
そして、後処理として確率マップに閾値処理をすることで細胞の場所を求めているようです。

またネットワークの構造としては、DenseVNetをベースにしているようです。

##インストール
インストール方法はwikiでいくつか紹介されていますが、MATLABとPythonの両方を使う方法を用いました。
環境：OSはUbuntu16.04 GPUはRTX2080、MATLAB2017b、Anacondaです。
CUDAは8.0、cuDNNは6(**マニュアルに書いてる7ではエラーになった**)をインストールしました。

まずGitHubページからコードをダウンロードします。
次にそのフォルダに移動してenvironment.ymlを用いて仮想環境を構築し、必要なパッケージをインストールします。

```
git clone https://github.com/soltanianzadeh/STNeuroNet.git
cd STNeuroNet
conda env create -f environment.yml -n stneuronet
source activate stneuronet
pip install matlab
pip install tensorflow-gpu==1.4 --ignore-installed
pip install niftynet==0.2.0.post1
```
これでAnacondaの環境設定はできました。

MATLABを使用する場合は、MATLAB本体の他に
1.Deep Learning Toolbox
2.Image Processing Toolbox
3.GUI Layout Toolbox　(これは外部のツールボックスで、https://jp.mathworks.com/matlabcentral/fileexchange/47982-gui-layout-toolbox からダウンロードできる。)
この3つがツールボックスとして必要です。
MATLABの本体があれば、**MATLAB Runtimeは必要ありません。**

##デモを動かす
使用方法としては、MATLABで前処理と後処理を行い、その間のDeep Learningの部分だけはPythonを用いるということになります。
デモの画像としては、Allen Brain ObservatoryのデータセットとNeurofinderのデータセットを用いることができます。
Allen Brain ObservatoryのデータセットはAWSのS3インスタンスに存在し、使用するにはAWSのアカウントが必要です。
そのため、自由にダウンロードできるNeurofinderの方のデータセットを使用しましょう。(ホームページはhttp://neurofinder.codeneuro.org/)
Neurofinderデータセットの中でも、'100','101', '200', '201', '400','401'の画像が使用できます。
###画像確認
view_marking.mで、画像とROIの位置を確認するGUIが起動します。
パラメータがAllen Brain Observatoryのデータ用になっているのでNeuroFinder用に変更します。
またこのコード実行することで、前処理するために必要な形式(_processed.nii.gz)に画像が変換されました。
そのためデモをするためにはこの処理が必要になります。

###前処理
demo_preprocess.mを用いて行うことができます。
パラメータがAllen Brain Observatoryのデータ用になっているのでNeuroFinder用に変更します。

###Deep Learning
Deep LearningはAnacondaでniftynetを使用することで行われます。
まずconfigファイルを作成し、それをAnacondaでrunします。
configファイルはdemo_config_empty_neuro.iniに画像の場所などを加えることで作成できます。
フォルダ内にはトレーニングによって生成されたモデルが既に存在するのでそれを使用します。以下のコマンドでセグメンテーションが実行されます。

```
net_segment inference –c <configのパス>
```
これで、確率マップ(probability map)が生成されました。

###後処理
demo_postprocess.mを用いて行うことができます。
パラメータがAllen Brain Observatoryのデータ用になっているのでNeuroFinder用に変更します。
これによって、セグメンテーション画像が生成されます。画像は細胞１つ１つの領域が1スライスに表された2値のスタック画像になっていました。

この他に、新しい画像からROI取りを行うにはdemo_ManualLabeling.m、後処理の閾値で最適なものを設定する場合はdemo_optThresh.mが使用できるようです。これらはトレーニングを行う際に使用します。

##感想
Deep Learningを用いているため、GPU付きのPCが必要です。
また前処理や後処理も必要で、その際にはパラメータ調整をしなければなりません。
その点ではCaImAnの方が使い勝手は良さそうですが、Deep Learningを用いたセグメンテーションをする点では非常に興味深いソフトだと感じました。
今度はAllen Brain Observatoryのデータセットやトレーニングも試してみたいです。
【Java】多重forループを一重にする方法

**ネタです**

# はじめに
Javaに限らず，プログラムを書いていると何重ものforループを書かなければならない時が発生します．

例. int型三次元配列の全ての要素を1にしたい．

```java
final int n = 10;
final int[][][] cube = new int[n][n][n];

for (int i = 0; i < n; i++) {
  for (int j = 0; j < n; j++) {
    for (int k = 0; k < n; k++) {
      cube[i][j][k] = 1;
    }
  }
}
```

しかし，このようなループはネストが深くなったり行数が無駄に増えるため，プログラムの保守性が悪化する原因となります．
そこで，多重forループを一重にする方法を考えます．

# forループの構文
問題を解決するために，まずはforループの構文を確認して行きます．
[Eclipse JDT](https://help.eclipse.org/2019-12/index.jsp?topic=%2Forg.eclipse.jdt.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fjdt%2Fcore%2Fdom%2FEnhancedForStatement.html)によると，for文は以下のような構成になっています

> for (
                        [ ForInit ];
                        [ Expression ] ;
                        [ ForUpdate ] )
                        Statement

また，ForInitとForUpdateは以下のように定義されています．

> ForInit:
>                Expression { , Expression }
> ForUpdate:
          Expression { , Expression }

`ForInit`と`ForUpdate`は複数の式を指定できるので，`ForInit`に多重forループで必要となるそれぞれの変数の宣言を`ForUpdate`で変数の更新を書くことができそうです．

# やってみた
それでは実際に一重のforループにしていきます．

## 初期化式
先ほどの例だと，必要な変数は`i,j,k`の三つなので，初期化式は

```java
int i = 0, j = 0, k = 0
```
で大丈夫そうです．

## 条件式
次に（終了）条件式ですが，今回の場合は`j,k`の値に関係なく，一番外側のループを制御する`i`について

```java
i < n
```
と書くことができます．

## 更新式
最後に更新式について考えていきます．
ループの内側を制御する変数から順番(`k -> j -> i`)に考えていきます．
まず`k`についてですが，ループの度にインクリメントし，なおかつkの値がnになるタイミングで0になればよいので

```java
k = (k + 1) % n
```
と書けます．

次に`j`についてですが，`j`の更新のタイミングは`k`が0になったタイミングであり，それ以外では値は変わらないため

```java
j = k == 0 ? (j + 1) % n : j
```
となります．

最後に`i`ですが，更新のタイミングは`k == 0 && j == 0`なので

```java
i = j == 0 && k == 0 ? i + 1 : i
```
です．

## 結果
これまでの結果を統合すると以下のように書き換えられます．

```java
final int n = 10;
final int[][][] cube = new int[n][n][n];

for (int i = 0, j = 0, k = 0; i < n; k = (k + 1) % n, j = k == 0 ? (j + 1) % n : j, i = j == 0 && k == 0 ? i + 1 : i) {
  cube[i][j][k] = 1;
}
```

最初の三重ループのコードに比べるとネストが減り，すっきりした印象を受けたのではないでしょうか？

# おわりに
今回は多重forループを一重ループに変換する方法を紹介しました．
ぜひこれを参考にしてコードの可読性を高めてください！
vue create で作成したプロジェクトでコンパイルエラーが発生した場合

#vue createでプロジェクトを作成

```
vue create my-project
```

質問をマニュアルで進め、無事プロジェクトの作成に成功したので開発サーバーを起動します。

```
cd my-project
npm run serve
```

#エラー発生
すると、次のようなエラーが


```
 ERROR  Failed to compile with 1 errors                                         

error  in ./src/main.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: [BABEL] <project-path>/my-project/src/main.js: Package exports for 
'<project-path>my-project/node_modules/@babel/helper-compilation-targets'
do not define a '.' subpath (While processing: 
"<project-path>/my-project/node_modules/@vue/cli-plugin-babel/preset.js")
```

#解決策
Node.jsのバージョンを`13.2.0`以上にあげる必要があります。

##Node.jsのバージョンを上げる方法
### nをインストール
Node.jsのバージョン管理ツールである[n](https://github.com/tj/n)をインストールします。

```
npm install -g n
```

###最新バージョンを確認
`n --stable`で安定版、`n --latest`で最新版を確認できます。
2019/1/20 現在の実行結果です。

```
n --stable
12.14.1
n --latest
13.6.0
```

###最新版をインストール
```
n latest
```
`sudo`が要求されたら、`sudo n latest`のようにして実行してください。

インストールされたかバージョンを確認します。

```
node -v
```

もう一度プロジェクトを作成。無事解決することができました。
<img width="1368" alt="スクリーンショット 2020-01-19 17.18.50 1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496565/a45b12e6-99b0-4fe2-0329-650f69cf1eaf.png">


#参考サイト
[Error: Package exports for <path to project folder>/node_modules/@babel/helper-compilation-targets' do not define a '.' subpath](https://stackoverflow.com/questions/59706130/error-package-exports-for-path-to-project-folder-node-modules-babel-helper-c)
[Node.jsとnpmをアップデートする方法 | Rriver](https://parashuto.com/rriver/tools/updating-node-js-and-npm)
基本的なHTMLとCSS

HTML基本構造

```html
<!DOCTYPE html>
<html lang="ja">
    <head>
    <meta charset="utf-8">
    <title>テキスト</title>
    <meta name="description" content="テキスト">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="style.css" type="text/css">
　　<head>
```
　　　　　　　　
```css
＠charset "UTF‐8";
```
***
●テキスト
タグ　用途　　
head　　　 ページ設定情報を記入
body　 　　　ページのコンテンツを記入
title　　　　ページタイトル
p　　　　　　段落　　
b　　　　　　文字を太く
i　　　　　　文字を斜め
u　　　　　　下線を引く
h1　　　　　 見出し　題名
s　　　　　　取り消し線　正解関係なくなった
del　　　　　取り消し線　削除訂正された
em　　 　　　強調文字
strong 　　　意味を強調
small　　　　文字を小さく
ruby　　　 　ルビ
rp　
rt　　
hr　　      水平線 区切り　終了タグ不要
br　　      改行

***
●引用・転載
blockquote　転載
dl　        
dt　　　　　説明したい言葉
dd　　　　　説明文
dl
ul　　      配置順に意味を持たないリスト
ol　　      配置順に意味を持つリスト項目
li　      　リストアイテムを意味する
div　　　　　ブロックレベル要素としてグループ化 
　　　　     幅や位置、余白などの指定が柔軟に出来る　　ブロック要素
span　　　　　幅や位置、余白などの指定に多少制限がある
　　　　     テキストの装飾を中心とした使い方が多い　　インライン要素
***
●表
table 　    表を示す
tr　　　    横　行を示す
th　　 　   見出しを定義する項目
td 　    　 見出しデータを定義する項目
 
***
●リンク
a　　     　URL
a href="サンプルURL">サンプルサイト/a
img　    　画像
img src=”（URL/保管場所/画像）”alt=”画像名前”
width 　     横幅
height　     高さ
***　　　　　　　　　　　　　　　　　　　　　　　
●文字に関するスタイル
font-size 　　　   文字の大きさ(フォントサイズ) 
color 　　　　　   文字の色 
font-weight　　    文字の太さ     p style
font-family 　　   文字の字体 　　　h1 style
text-decoration    テキストの装飾  span style
***
●枠線に関するスタイル 　　h1 style
border 　　　　　    枠線 
border-(※各辺) 　   枠線の各辺　(上top/下bottom/右right/左left) 
border-radius        枠の丸さ 
***
●背景に関するスタイル  <body style>
background-color:#ccd4dd;             背景の色 
background-image url(./image/.jpg);   背景の画像 
background-repeat:no-repeat;          背景の画像の繰り返し 
background-position:center            背景画像の表示開始位置 
background-attachment fixed;          背景画像の固定・移動 
background-size cover;                背景画像のサイズ 
                                      背景全般 
***
●横幅と高さに関するスタイル 
width       横幅      height      高さ 
***
●余白に関するスタイル 
margin              外部余白 
margin-(※各辺)     外部余白の各辺(上top/下bottom/右right/左left) 
padding             内部余白 
padding-(※各辺)    内部余白の各辺(上top/下bottom/右right/左left) 
***
●ボックスサイズの算出方法を指定 
box-sizing 　
枠線(border)や内部余白(padding)の大きさをwidthやheightに含めるか 
***
●テキストに関するスタイル 
text-align 　　　　水平方向の位置 
line-height  　　　行の高さ 
***
●表示に関するスタイル 
display 表示 
float
***
●位置に関するスタイル
position　　　　位置 
top 　　　　　　上からの位置 
bottom　　　　　下からの位置 
left 　　　　   左からの位置 
right 　　　　　右からの位置 
z-index 　　　　重なりの順序指定 
***
●横並び(浮動)に関するスタイル 
float          横並び(浮動) 
clear          横並び(浮動)の解除 
***
●影に関するスタイル
box-shadow      ボックスの影 
text-shadow     テキストの影
githubのPushでエラーになる対処法

##エラー

```
namenoMacBook-Pro:filename name$ git push origin master
fatal: unable to find remote helper for 'https'
```
fatalでエラーになっています。

##対処法
```
namenoMacBook-Pro:filename name$ sudo git push origin master
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 8 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), 1.04 KiB | 1.04 MiB/s, done.
Total 7 (delta 0), reused 0 (delta 0)
To https://github.com/Hanae05/node.js.git
 + 196bace...489869b master -> master (forced update)
```
git push origin masterの前にsudoを書いて実行してみて下さい。
今度は上手く行きました。

##それでもまだエラーになる方
https://qiita.com/H__Goro_/items/7a598a82aa00378b5415
↑こちらの記事を参考にしてみて下さい。
pip3のパッケージを一括でアップデートするためのシェルスクリプト


pip3のパッケージをワンライナーで雑に一括アップデート出来なかったので、シェルスクリプトを書きました。
実行後に`pip3 check`で依存関係を確認しましょう。

```zsh
#!/bin/zsh
# 更新が必要なパッケージの名前をファイルに書き出す
pip3 list -o | awk '{print $1}' > outdated_pip3_packages.txt

# ファイルの中身、3行目からパッケージ名が並んでいる
# Package
# ----------
# numpy
# pandas
# ~~~

# 書き出したファイルを1行ずつ読み込んでアップデート
cnt=0
while read line
do
  cnt=`expr $cnt + 1`
  if test $cnt -ge 3 ; then # パッケージ名が並ぶのは3行目から
    echo "Updating package $line..."
    pip3 install -U $line
  fi
done < outdated_pip3_packages.txt
echo "Update $cnt packages done!"

# パッケージの更新に使ったファイルを消す
rm outdated_pip3_packages.txt
```
グローバル変数とローカル変数1

```py:1
player = '太郎'

def f():
    print(player)

f()
```

```:1の実行結果
太郎
```

```py:2
player = '太郎'

def f():
    print(player)
    player = '次郎'
f()
```

```:2の実行結果
Traceback (most recent call last):
  File "Main.py", line 7, in <module>
    f()
  File "Main.py", line 4, in f
    print(player)
UnboundLocalError: local variable 'player' referenced before assignment
```
グローバル変数playerには太郎が入っている。
ローカル変数playerには次郎を入れた。
しかし、ローカル変数playerを宣言する前に、
print(player)を実行しようとしている為にエラーとなる。

それを改善する為に、
print(player)の前にローカル変数を宣言する必要がある。

```py:3
player = '太郎'

def f():
    player = '次郎'
    print('local:', player)

f()
print('global:', player)
```

```:3の実行結果
local: 次郎
global: 太郎
```

グローバル変数を関数内で書き換えたい場合は、

```py:4
player = '太郎'

def f():
    global player
    player = '次郎'
    print('local:', player)

f()
print('global:', player)
```

```:4の実行結果
local: 次郎
global: 次郎
```
睡眠時無呼吸症候群(SAS)対応のためのCPAP機器ドリームステーションが届いた

2020年は変革の年だと思っているので、十数年苦しんできた睡眠時無呼吸症候群(SAS)対応のため、ここ数年迷ってきた CPAP 機器の導入に踏み切りました。届いたCPAP機器は以下のもの。

せっかく届いた機器ですので、ちょこっとだけ情報をまとめてみました。

# ドリームステーション

* [Philips DreamStation] (https://www.philips.co.jp/healthcare/product/HCNOCTN447/dreamstation-cpap-bipap-cpap-bi-level-therapy-systems) 持続的気道陽圧ユニット

液晶右にあるダイアルで操作します。ダイアルは回転のほか、押すとクリック動作になるのがポイント。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/708dfbc1-0f64-a601-1231-b1a48b9cc541.png)

利用イメージは以下のような感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/aa9d5e13-8919-e1b3-8630-799246e7ca3d.png)

メインスイッチが無い (手前のスイッチは一時停止用) ので、スイッチ付きの電源タップと併用すると便利です。

# iPhone アプリ使ってみた

Philips からCPAP治療のためのモバイルなアプリケーション [ドリームマッパー](https://www.philips.co.jp/healthcare/product/HCNOCTN196/-) が公開されているみたい。Apple Store に以下の無料アプリがありました。

* [DreamMapper 17+](https://apps.apple.com/jp/app/dreammapper/id530569351)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/cbb7e7be-bfd8-ea40-62af-59e84f554b4c.png)

ダウンロードして起動してみると、以下のようなユーザー登録の画面になります。必要な情報を入力して先に進んでいくと

<img width="375" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/c04abccf-1bb5-d5f2-cb09-9858c3f74319.png">

CPAP機器との Bluetooth 接続も機器に表示されたコードの入力で自動的に進み、実際にCPAP機器の情報が転送された結果がこちら。

<img width="375" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/e89381f9-9368-7b95-8cbc-8d34229cfc06.png">
どうやら昼の12時が日の境のようです。昨夜から今朝にかけて12時過ぎまで寝てしまったので、超えた分が今日の睡眠としてカウントされた模様。

こういったアプリはデータの蓄積が大事だと思うので、今後いろいろ試したいと思います。自分のデータを Web API か何かで取ってこれると面白そうですけどね！

# メモリカード

医師から指示されたのは、診察の際にCPAP機器からメモリカードを抜いて持参すること。で、そのメモリカードが単なる SDカードに見えるので、当然、PCに刺してみます。

※ あくまで個人の興味でリスク承知でやっていますので、真似しないでくださいね

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/41927dcc-6515-2338-d5b6-7ef3e4d5cd46.png)

FAT32 でフォーマットされた 2GB の SDカードでした。まあ、医師の PC などで閲覧するので、あまり特殊なフォーマットにすることは無さそうですよね。そして中身は以下の感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/0fff19bf-a909-e8a8-4e9f-2b1e65980f3b.png)

※ マスクしてある部分のフォルダ名は CPAP 機器のシリアル番号の一部が使われています

で、この Clear* っていうフォルダが怖いというか、この CPAP機器のリセット時のバックアップな気がするのですが…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/2b17c11f-c1dd-be32-01af-984995c80426.png)

ただこれ、過去の利用状況が丸々残っているような… 他人の個人情報ではないかという気がしており、中身は触れないほうが良さそうですw

LAST.TXT には現在のフォルダ(マスクしてある部分)が指定されており、このフォルダ内が私のデータだと思われます。ここだけ定期的にバックアップして、(もしわかれば)中身を見ていきたいと思います。

# というわけで

というわけで、届いた CPAP 機器のファーストインプレッションでした。既に活用されている諸先輩型、何か面白い情報などありましたら、コメントいただけますと嬉しいです。

それではまた！
matplotlib 基礎 / fig と axes の違い

# Overview
matplotlib の figure, add_subplot が自分の中でおまじない化しているので、理解を深める意味で記事にまとめる。

以下の import を前提とする。

```python
import matplotlib.pyplot as plt
```

# Figure
matplotlib において、冒頭で以下のおまじないを記述することがよくある。

```python
fig = plt.figure()
```
`figure()`は、全体の描画領域を確保するFigureインスタンスを生成している。大きなキャンバスやホワイトボードを用意するイメージ。

### 引数
引数なしでも利用可能だが、以下の引数を指定できる。

| 引数 | 処理|
| --- | --- |
| figsize | タプル形式で描画サイズを指定<br/>単位はインチ |
| dpi | 1インチあたりのドット数を指定 | 
| facecolor | 背景色を指定 |
| edgecolor | 枠線色を指定<br/>デフォルトの枠線幅が0.0なのでlinewidth必須|
| linewidth | 枠線幅を指定 |


# Axes(add_subplot)
以下のおまじないも、冒頭でよく見る。

```python
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
```
`add_subplot` は、全体描画領域 Figure 上にグラフ描画領域を生成する。ホワイトボードに紙を貼って、その紙上にこれからグラフを描写するイメージ。
このとき生成されるインスタンスは**Axes**クラスと、少しややこしい。

Figure と Axes(subplot) の関係性イメージは以下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38277/7caffd7e-ef18-7043-488a-f60df0d45a3a.png)

### 引数
add_subplotの引数は、以下の用途で指定する。

| 引数 | 処理|
| --- | --- |
| 1つ目 | 行数を指定 |
| 2つ目 | 列数を指定 |
| 3つ目 | 描画箇所を指定 |

1,2つ目で指定した行列数で先に生成した Figure を分割し、3番目で指定した箇所にグラフを描写する。

例えば、`add_subplot(3,3,5) は Figure を 3 x 3 で分割した真ん中のセルを指定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38277/1508bd58-42c4-48f5-e1ac-373f878dc23f.png)

ちなみに、 `add_subplot(1,1,1)` は `add_subplot(111)` と同義。


# 描写してみる
ここまで理解できれば、あとは`add_subplot` で生成した Axes 上でグラフを描写するだけである。

```python
fig = plt.figure()
ax = fig.add_subplot(111)

ax.hist([1, 2, 3])
fig.show()
```
思考停止で雑なグラフを描写するとこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38277/22849572-cc12-c2be-826c-b313379d8a9b.png)



# Reference
こちらの記事を参考にしています。
[matplotlibの描画の基本 - figやらaxesやらがよくわからなくなった人向け](https://qiita.com/kenichiro_nishioka/items/8e307e164a4e0a279734)