OmniAICreator/Qiita-1.07M huggingface dataset:
AtCoder向けのVSCode拡張機能を作成しました。

### 誰向けなの？
- VSCode拡張機能を作ってみたい人
- AtCoderをRustでやっている
　かつ　VSCodeを使用している
　かつ　楽して入出力例からテストコード作成したい人

### 何が書いてあるの？
- 拡張機能でやりたかったこと
- 拡張機能でできたこと
- 簡単な解説と躓いたポイント
- 最後に

### 拡張機能でやりたかったこと
- プロジェクトを自動で作成したい。←これまで手作業でコピペしてて面倒だった…
- テストコードを自動で作成したい。←これまで手作業で…
- workspaceを自動で変更したい。←これまで…

ちなみにもとにしたプロジェクトは[こちら](https://doc.rust-jp.rs/atcoder-rust-resources/)の手順で出力しました。

### 拡張機能でできたこと
自分の[環境](https://github.com/magurouhiru/vscode-atcoder-rust)ではですが、↑でやりたかったことはできました。
もしよかったら、使ってみてください。
↓こんな感じで「abc222」みたくコンテスト名を入力したら、いろいろやってくれます。
![demo_install](https://raw.github.com/wiki/magurouhiru/vscode-extension-atcoder/images/atcoder_extension_how.gif)

### 簡単な解説と躓いたポイント
大雑把な流れは↓の感じです。
1. コマンドパレット入力で処理開始
1. コンテスト名（「abc222」とか）を入力する箱を表示
1. 入力を確認して
   1. 想定した入力でなければ、メッセージを表示して終わり
   1. 想定した入力であれば、プロジェクトがあるか確認して
      1. プロジェクトがあれば、workspaceを変更して終わり
      1. プロジェクトがなければ、
         1. AtCoderのサイトから情報を取得
         1. プロジェクトのテンプレートをコピペ・一部書き換え
         1. workspaceを変更して終わり

躓きポイント１
どうやって環境を作るかわからない。
→本家の説明（[ここ](https://code.visualstudio.com/api/get-started/your-first-extension)）の通り作業する。

躓きポイント２
何をきっかけに拡張機能が動くかわからない。
→package.jsonとextension.tsで定義している。
　本家の説明は[ここ](https://code.visualstudio.com/api/extension-guides/command)
　僕の場合は↓の通り。
package.json（↓でコマンドパレットのイベントを定義）
```
  "activationEvents": [
    "onCommand:atcoder.createOrChangeProject"
  ],
  "main": "./dist/extension.js",
  "contributes": {
    "commands": [
      {
        "command": "atcoder.createOrChangeProject",
        "title": "Create Or Change Project"
      }
    ]
  },
```
extension.ts（↓で↑で定義したイベントの処理を登録）
```
export function activate(context: vscode.ExtensionContext) {
  let disposable1 = vscode.commands.registerCommand(
    "atcoder.createOrChangeProject",
    () => {
        ここにやりたい処理を書く。
    }
  );
  context.subscriptions.push(disposable1);
```

躓きポイント３
どうやったらテキスト入力できるのかわからない。
→vscode.window.showInputBoxを使う。
　本家の説明は[ここ](https://code.visualstudio.com/api/references/vscode-api)
　僕の場合は↓の通り。
extension.ts
```
      vscode.window
        .showInputBox({
          placeHolder: "abcXXX",
          prompt: "XXX に番号を入力してください。",
        })
```

躓きポイント４
タスクnpm watchを起動してるのにコンパイルしてくれない。
→Docker環境でやってる人はたまに発生するっぽい。
　watch-pollでできることもあるっぽい。（僕の環境はできなかったけど。）

躓きポイント５
npmで「/root/~」のファイルが読み取れなくてエラーになる。
→chmod -R 777 /rootで無理やりパーミッションを変更する。
　（僕はDockerの設定さぼってrootで作業してたから関係ないと思ったけど…よくわからん…）

### 最後に
ここまで読んでくれてありがとう！
意見、ツッコミ、どんなことでもコメントいただけると嬉しいです！！！
Macでのgrep検索を使いこなす

WindowsのさくらエディタのGrep検索便利だけどMacでgrep検索するには使えないので、この際しっかり覚えておこうと思い書き留めました

# ワイルドカードでファイル名を指定する
```
grep "hello" /Users/test/*.txt
```

# rオプションで、すべてのファイルを対象にサブディレクトリまで検索する
```
grep -r "hello" /Users/test
```

# 検索結果からファイル名だけを表示する
```
grep -rl "hello" /Users/test
```

# 一致した行の行番号を表示

```
grep -rn "hello" /Users/test
```

# 一致した行の前後3行も表示

```
　grep -r3 "hello" /Users/test
```


# 大文字小文字を区別しない
```
　grep -ri "hello" /Users/test
```
Datadog Logs Pipelinesの処理順序をTerraformで管理する

## できるようになること
- Pipelineの順番をTerraformで管理できるようになる(プリセットのPipeline含む)
- Pipelineの有効化/無効化をTerraformで管理できるようになる(プリセットのPipeline含む)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1313152/0f5d7ea3-fe0a-0f29-bdc4-32069341b581.png)


## 手順
- DatadogAPIでpipelineの一覧を抽出する(pipeline_idを出力させるため)

```
curl -X GET https://api.datadoghq.com/api/v1/logs/config/pipelines \
-H "Content-Type: application/json" \
-H "DD-API-KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "DD-APPLICATION-KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

- 目的のものがでてくる("id":"gfewuaiffwoafjowaeg9124")((idは適当な値に変更してます))
```
[{"id":"gfewuaiffwoafjowaeg9124","type":"pipeline","name":"Java","is_enabled":true,"is_read_only":true,"filter":{"query":"source:java"},"processors":[{"name":"Parsing Java Default formats","is_enabled":true,"source":"message","samples(省略)
```

- main.tfに以下の書き込み
```
resource "datadog_logs_integration_pipeline" "java" {
}
```

- terraform importでterraform.tfstateに落とし込む(backend "s3"はオフにしておく)
```
terraform import datadog_logs_integration_pipeline.java gfewuaiffwoafjowaeg9124
```

- terraform.tfstateの当該行に"module"を追加(moduleで構成している場合)
```
    {
      "module": "module.datadog",　←この行
      "mode": "managed",
      "type": "datadog_logs_integration_pipeline",
      "name": "java",
      "provider": "provider.datadog",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "id": "gfewuaiffwoafjowaeg9124",
            "is_enabled": true
          },
          "private": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
        }
      ]
    },
```

- 後は、datadog_logs_pipeline_orderで順番を変更する。
```
resource "datadog_logs_integration_pipeline" "python" {
    is_enabled = true
}
resource "datadog_logs_integration_pipeline" "java" {
    is_enabled = true
}
resource "datadog_logs_integration_pipeline" "nginx" {
    is_enabled = false
}

resource "datadog_logs_pipeline_order" "pipeline_order" {
    name = "pipeline_order"
    depends_on = [
      datadog_logs_custom_pipeline.java_test_custom,
      datadog_logs_integration_pipeline.java,
      datadog_logs_integration_pipeline.python,
    ]
    pipelines = [
      datadog_logs_custom_pipeline.java_test_custom.id,
      datadog_logs_integration_pipeline.java.id,
      datadog_logs_integration_pipeline.python.id,
    ]
}
```

## 結論
面倒なのでPipelinesの順序は流石に手で変更したほうがいい。
一番面倒なのはプリセットのPipelineは、ログを流し始めるまでpipeline_idが生成されない事。
環境ごとにJavaのログを流す→上記の工程を実施しないといけない。

## 参考
[https://www.terraform.io/docs/providers/datadog/r/logs_pipeline_order.html:embed:cite]
[https://www.terraform.io/docs/providers/datadog/r/logs_integration_pipeline.html:embed:cite]
DARTS

今更ながら、もはやNASの世界で一つの"古典"となりつつあるDARTS[^1]について簡単にまとめ、実装してみた感想を述べる。
## Abstract
DARTSは"勾配降下法"によりNeural Architecture Search (NAS) の構造探索を行う手法である。離散的に構造探索を行なっていたそれまでのNASと比して革命的な高速化が可能となった。

## What is DARTS?
　DARTSは以下の図 [^1] (a)のようなDAG(Directed Acyclic Graph)から候補アーキテクチャの選択を行う。
[^1]:URL : https://arxiv.org/abs/1806.09055
H Liu, K Simonyan, and Y Yang. In _International Conference on Learning Representations_, pp. 115–127, 2019.

このDAGではエッジに演算の候補が割り当てられ、エッジの色は候補の演算(＝レイヤーの種類)と対応している(ここで演算の候補の中に`zero`というものが存在しており、DAGにおけるエッジを選択しないことと対応している)。ちなみにこのDAGのノードはレイヤー間の接続関係を規定するためだけに存在しているので特に何らかの処理が行われているのではない。


![スクリーンショット 2022-06-25 0.12.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680028/f25c84ed-3a11-5fb1-2626-57cf57a14ad0.png)


・使用が許容される演算の集合を$O$, 候補となる演算を$o \in O$として表すと、DARTSは
```math
\bar{o}^{(i,j)} (x) = \sum_{o \in O}
\frac { {\rm exp} (\alpha_o^{(i, j)}) } { \sum_{o'\in O} {\rm exp} (\alpha_{o'}^{(i,j)}) } o(x)
```
によりDAGのノード$i$からノード$j$へ流れるデータの値を決めることができる。

・DARTSによる学習は以下の２種類の学習に分類可能
1. 候補アーキテクチャ生成(上式のパラメータ$\alpha_o^{i,j}$を最適化するための過程)
2. 候補アーキテクチャを特定のデータセットで学習

これらを繰り返し(注)、最終的には学習が収束した時点でDAGの各エッジで最も値が大きい$\alpha_{o_{max}}^{i,j}$に対応する演算$o_{max}$が選択され、エッジの有無並びにエッジ有の場合には演算の種類が決定される。これにより最適なアーキテクチャが決定する。

注) One-Shot NASというまことしやかな手法が成果を上げており、繰り返さなくても一度デカいDAGの学習さえさせて仕舞えば後はもうサンプリングの仕方如何だけで話が済むという手法が実際には導入されている。ここではOne-Shot NASの話は盛り込んでいない。

## Discussion
**Q1.** そもそも候補アーキテクチャがデータを流さない場合にどのようにパラメータ更新が行われているのだろうか(離散的な探索だったらこのような場合の対処は簡単なのだが...) 

**コードより**
--> レイヤーベースでそのようなことがないように保証されている。(Normal Cellでは畳み込み、プーリング共にpaddingを駆使して入力と出力でデータサイズの変化がないように組まれているらしい)

**Q2.** 局所解に陥らないのか？少なくとも真に高い山に辿り着けてはいないのでは ? (一応論文内では何回か回しているようだけど、にしても探索空間内のごく一部しか探索できてないんじゃね ? )
**論文より**
--> ４回シードを変えて回している。その結果として最もValidationでパフォーマンスが高いCellを採用。局所解の件に関しては一応これでDefenseできていることになっている。

## 回してみての所感

CIFAR-10でDARTSを回してみた。流石に環境構築が沼過ぎたので、DARTSを引用しているもっと最近の別論文[^2]の添付コード[^3]をいじって実装した。以下はConvolution Cell探索のメモ。

・DARTSでは各セルでどのエッジにどのオペレータを割り当てるかという重み$\alpha$を最適化している。この時、重み$\alpha$は同じ種類のセルであれば同じ値が共有されている。

・論文中Table1で掲載されている結果はあくまで採択されたアーキテクチャで**別個で**一から学習させたもの (アーキテクチャ探索過程で得られた結果は論文のものよりもはるかに低い精度となる：論文中Fig.3)。


・アーキテクチャ探索過程において、油断すると`zero`オペレータで最も高い重みが付与された。論文中ではこのオペレータを除外してオペレータ選択を行なっているという説明がなされている(この点に関しては後述)。

・アーキテクチャ探索に際しては、次の点がポイント

**1.** $Cell_k$の第1ノードと第2ノードは、ともに$Cell_{k-1}$と$Cell_{k-2}$から入力を受けるように指定。
**2.** 他のノードについては、入力として$Cell_{k-1}$と$Cell_{k-2}$, 自分より番号の小さいノードのいずれかから2つを選ぶ。この時、各エッジで候補オペレータに付与されるパラメータ$\alpha$の大きさTop-2を採択している。

ただしこの2.の時オペレータ`zero`が除外されている。また、「採択」は**最後に**行われるのであってアーキテクチャ探索過程で行われるのではない。探索過程ではあくまで全ての候補オペレータの算出する値の和が出力されている点に注意。

ここで疑問として、結局除外するならオペレータ`zero`はなぜ必要なのだろうかという問いが生じる。論文中には2ノード間の結合が"無い"ことを示すために用いられていると論文中には記載されているが、実質的に果たす機能とは何なのだろうか。
結論としてはあるノードに投射するエッジを2本選択するというタスクで、候補エッジXに割り当てるオペレータ`zero`の重み$\alpha$が高くなっていて、他のエッジYだったら、`zero`の重み$\alpha$が小さく、非ゼロオペレータが選ばれるのであれば、エッジYが採択されやすくなる。このように`zero`オペレータが存在することで、実質的に`zero`というオペレータが割り当てられたエッジが誕生する訳ではないが、間接的にエッジにランク付けをすることが可能となり、**Top-2エッジを各ノードで選択する**というタスクにとって都合が良いのである。

[^2]:URL : https://arxiv.org/abs/2102.07108
Y Shen, K Song, F Liu, M Zhang. _Proceedings of Machine Learning Research_, pp.11670-11681, 2021.
[^3]:https://github.com/MSU-MLSys-Lab/CATE.git
達人プログラマーを読んでみて

# はじめに
- [達人プログラマー](https://www.amazon.co.jp/%E6%96%B0%E8%A3%85%E7%89%88-%E9%81%94%E4%BA%BA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC-%E8%81%B7%E4%BA%BA%E3%81%8B%E3%82%89%E5%90%8D%E5%8C%A0%E3%81%B8%E3%81%AE%E9%81%93-Andrew-Hunt/dp/427421933X)を読んだので気になった箇所の感想を述べながら自分なりの具体例を交えて解説していきます。
- 参考程度に自分のエンジニア歴は1年で Rails, React をメインに web アプリケーション を開発しています。

# 割れた窓は放置しない
- 一回の妥協が後に破綻を生むという話
- Typescript でいえばこう
```typescript:hoge.ts
   hogeMethod(a: any) {
   // 何かの処置
   }
```
- 一回でも any で妥協すると無秩序が生まれてしまうかもしれないから気をつける

# 知識ポートフォリオをつくる
- 毎年新しい言語一つ学ぶ
    - 自分は去年 Ruby, Javascript を学習した。
    - 今年は静的型付け言語(goとか)使ってみようかな。
- 月一冊の技術書
    - これは最近できでいる気がする。

# 二重化
- これは有名な DRY 原則についての話。
- 繰り返し記述しているコードに気をつけるべきである。

```ruby
hoge.method1.method2
hoge.method1.method3
```

- 雑な例だがたとえばこのようなコードがあった時、どちらも `hoge.method1` までは動作が同等である。
- つまり繰り返している処理となるので DRY原則に違反している。

```ruby
new_hoge = hoge.method1
new_hoge.method2
new_hoge.method3
```

- この例だと対して DRY原則の旨味は感じられずむしろコード量が増えているとも捉えられるが、実際の開発ではこういった共通化が可読性に大きく関わってくる。

https://qiita.com/yatmsu/items/b4a84c4ae78fd67a364c

- ただこちらにも記載されている通り単純な二重化を防ぐという考え方は少しずれているということを意識した方が良い。
- 要約すればあくまで情報の共通化をするのであって見かけ上同じコードを全て共通化するべきでないという話。
- 繰り返しを避けるという理解に自分は止まっていたのでこれは知ってよかった。

# 直行性
- これは言葉の意味を捉えるのが難しいが、独立性を指すという認識。
- 一つのコードの変更が他の箇所に影響を与えない状態がベストということ。
- 依存性や密結合を避ける意味合いが強い。
- React のコンポーネント指向に通じる考え方のように思いました。

```react
const Movie = ({movie: MovieModel}) => {
  return (
    <>
      <img src={movie.image} />
      <div>{movie.name}</div>
    <>
  )
}
```

- 例えば、このような映画の情報を返すコンポーネントがあった時。
- こちらは依存している対象はなく、直行性があると言えます。

```react
const Movie = ({movie: MovieModel, type: string}) => {
  if (type === 'card') return null
  return (
    <>
      <img src={movie.image} />
      <div>{movie.name}</div>
    <>
  )
}
```

- ここにもし新たな条件、引数の文字列によって表示するか否かの場合分けが増えたらどうでしょうか。
- このコンポーネントは引数の `type` の中身に依存するようになりました。
- つまり直行性が下がったと言うことになります。
- このような状態は避けるべきであり、上記の場合は場合分けが必要となってしまった構造に問題があると言えます。

# 可逆性
- ここではすぐに手戻りできる柔軟さが大切だと述べています。
- 最終決定などは存在しないということです。
- いつ仕様が変化するかわからないから、決め打ちするのは危険であるという解釈をしました。
- この考え方はアジャイルやスクラム開発が解決すべきテーマかも。
- 私自身開発するときは、一旦実装してみて仕様と異なっていたら変更しても良いというマインドで日々開発しているので大いに共感しました。

# まとめ
- 技術が日々進化していく中根幹の考え方は普遍であり、この本の内容は色褪せないものであったので読んでよかったと思っている。
- この書籍に記載されている考え方は各フレームワークや言語に少なからず影響を受けている or 影響を受けた ようにも感じるので、自身が関わっている技術にどんな関わりがあるか調べると理解に繋がるかもしれないですね。
🔰GitとGitHubについてまとめてみる

# はじめに
Git/GitHubについてまとめます。
開発の流れは以前まとめたので、そちらをご覧ください。

https://qiita.com/hondano_gentuki/items/a972bdeb414e86721a65

今回は両者の違いに観点を置いて見ていきます。

# Git
ソースコードなどのファイルやフォルダの変更履歴を記録・追跡するためのバージョン管理システム。
gitでアプリケーションを管理すると、「いつ、どの、どこの部分をどのように編集した」という記録を残してくれます。ゲームで例えるとセーブです！！セーブしたらその部分からやり直すことも可能ですよね！そのイメージを持っていただければ分かりやすいと思います。ゲームと同様セーブポイントで遡ることが出来るようになっています。
このセーブデータを複数人で編集する場合、誰かがそのファイルを編集完了するまで待たなければいけないという問題もでてきます。それを解決するのが`GitHub`になります。

# GitHub
Gitの仕組みを利用し、簡単に複数人での開発ができるようにしてくれるWebサービスです。世界中の人々が自分の作品を保存、公開しています。

#### 両者の違い
- Gitは「ファイルの更新履歴を記録する仕組み」
- GitHubは「Gitの仕組みを使ってエンジニアを支援するWebサービス」

## リポジトリ
リポジトリとは、Gitの管理下にあるファイルやディレクトリの変更履歴を保管してもの。
管理したいアプリケーションのディレクトリを、バージョン管理の範囲として指定します。
### ローカルリポジトリ
ローカルリポジトリとは、自分のPC上（ローカル環境）に置くリポジトリのことです。
作成したリポジトリは自分のパソコンの中にあるため、ファイルやディレクトリを変更、修正した際は好きなタイミングで記録できます。
### リモートリポジトリ
リモートリポジトリとは、外部サーバー上に置くリポジトリのことです。リモートリポジトリを直接変更修正することはなく、ローカルリポジトリの変更修正を同期して、反映させることで更新します。
リモートリポジトリは外部のサーバー上にあるので、他の人に自分の作成したコードを共有できたり、チーム開発をしやすくしたりできます。複数人での開発ではリモートリポジトリを活用します。

## commit
ファイルやディレクトリの変更修正を、リポジトリに記録することです。
commitをすることで、変更修正の時系列の管理が行いやすくなり、変更修正を遡ることもできます。
#### コミットメッセージ
ファイルの変更修正の内容をわかりやすくするための記述です。コミットメッセージを書くことによって、変更修正したファイルの中身を確認しなくても、「どのような変更修正なのか」がすぐにわかります。

## push
ローカルリポジトリでのコミットをリモートリポジトリに反映させます。

## commit log
今までのcommit履歴が確認できます。アプリケーションの実装を振り返ることができる。

## インデックス
変更修正が一時的に保存される場所です。インデックスに保存されている内容がcommitの対象になります。

## add
追加するファイルや変更修正をインデックスに登録して、commitの対象にすることを意味します。

# 終わりに
簡単ですが今日はここまで。
インターフェイス分離の原則でカレー作り

カレー作り、もはや誰も見ていないであろうが第4弾

### こんにちは、Javaおじさんのシキムです。


40才目前で、プログラム工学に興味を持ったので本や記事で読んだ難しい話を
咀嚼して簡単な言葉で語りたいと思います。

-----

今回は、**インターフェース分離の原則 (Interface segregation principle**というものについてです。

ざっくりと、、、

インターフェースは、特化したものを用意する。

詳しくは偉い人の話を読んでください。

ここでは、この原則をカレー作成装置に見立てて解説したいと思います。

では、さっそくカレー作成装置を作りましょう。


今回は真カレー装置(夏)をベースに進めていきます。
----
(真カレー装置(夏)の詳細は第２弾をご確認ください。)

**野菜BOX作成キット**
　　容器
　　剥き方ノート(白紙)
　　切り方ノート(白紙)

**人参BOX**
　　容器：人参
　　剥き方ノート：ピーラーで皮を剥く
　　切り方ノート：輪切りに切る

**ジャガイモBOX**
　　～省略～

**玉ねぎBOX**
　　～省略～

**野菜BOXコンテナ**
　　人参BOX
　　ジャガイモBOX
　　玉ねぎBOX

**野菜下ごしらえ装置**
　入れるもの：
　　　野菜BOX

　作業：
　　　①容器の野菜を剥き方ノートと同じように剥く
　　　②皮を剥いた野菜を切り方ノートと同じように切る

　出てくるもの：
　　　下ごしらえ野菜

**肉下ごしらえ装置**
　入れるもの：
　　　肉

　作業：
　　　①肉を切る

　出てくるもの：
　　　下ごしらえ肉

**カレー作成装置**
　入れるもの：
　　　野菜BOXコンテナ、肉

　作業：
　　　①野菜下ごしらえ装置に野菜BOXコンテナのBOXを１つづつ入れて下ごしらえする
　　　②肉下ごしらえ装置に、肉を入れて下ごしらえする。
　　　③具材を鍋に入れて煮込む
　　　④カレールーを入れる
　　　⑤ご飯にかける
　　　⑧カレーにとんかつをトッピングする

　出てくるもの：
　　　カレー

おじさんは、ひらめきました。
----
カレーの野菜は、人参、ジャガイモ、玉ねぎがの3つが必ず入っています。
なので、こんな感じでカレー野菜BOXキットを作ってしまえばいいのではないでしょうか？

**カレー野菜BOX作成キット**
　　容器A
　　剥き方ノートA(白紙)
　　切り方ノートA(白紙)
　　容器B
　　剥き方ノートB(白紙)
　　切り方ノートB(白紙)
　　容器C
　　剥き方ノートC(白紙)
　　切り方ノートC(白紙)

では、カレー野菜作成キットを使って簡単カレー装置を作っていきましょう。
----
**カレー野菜BOX**
　　容器A：人参
　　剥き方ノートA：ピーラーで皮を剥く
　　切り方ノートA：輪切りに切る
　　容器B：じゃがいも
　　剥き方ノートB：芽に気を付けて皮を剥く
　　切り方ノートB：乱切り
　　容器C：玉ねぎ
　　剥き方ノートC：白くなるまで皮を剥く
　　切り方ノートC：半月切り

**カレー野菜下ごしらえ装置**
　入れるもの：
　　　カレー野菜BOX

　作業：
　　　①容器Aの野菜を剥き方ノートAと同じように剥く
　　　②皮を剥いた野菜を切り方ノートAと同じように切る
　　　③容器Bの野菜を剥き方ノートBと同じように剥く
　　　④皮を剥いた野菜を切り方ノートBと同じように切る
　　　⑤容器Cの野菜を剥き方ノートCと同じように剥く
　　　⑥皮を剥いた野菜を切り方ノートCと同じように切る

　出てくるもの：
　　　３種類の下ごしらえ野菜

**肉下ごしらえ装置**
　入れるもの：
　　　肉

　作業：
　　　①肉を切る

　出てくるもの：
　　　下ごしらえ肉

**カレー作成装置**
　入れるもの：
　　　カレー野菜BOX、肉

　作業：
　　　①カレー野菜下ごしらえ装置にカレー野菜BOXを入れて下ごしらえする
　　　②肉下ごしらえ装置に、肉を入れて下ごしらえする。
　　　③具材を鍋に入れて煮込む
　　　④カレールーを入れる
　　　⑤ご飯にかける

　出てくるもの：
　　　カレー

簡単カレー装置の完成です！
----
これで、コンテナも使わない**シンプルな装置**ができましたね。真カレー装置(夏)よりもいいように感じるところもあるかもしれません。
しかし、簡単カレー装置にインターフェイス分離の原則を無視している為に問題が発生します。

**それが玉ねぎの欠品！！！**

真カレー装置(夏)であれば、玉ねぎBOXを抜いたコンテナを用意するだけで玉ねぎ抜きカレーを作ることができました。
しかし、簡単カレー装置ではどうでしょうか？野菜を３つ入れることを前提としてしまったため、一か所空白になってしまいます。

この状態では、カレー野菜下ごしらえ装置が容器Bのやさいの皮を剥こうとしますが、野菜が取得できずに正常に動作することができず問題が発生してしまいます。

真カレー装置(夏)のほうがよさそうであることがわかりました。

以上が、おじさんなりのインターフェイス分離の原則の理解です。


　
　
　
　







**カレー作りシリーズ**

https://qiita.com/sikimuOji/items/a99fdc2de406a0f42fac
【Laravel】migrate時のエラー解決集


laravel開発で`php artisan migrate`を実行した際のエラーまとめ

## default値を設定できない型(BLOG型、TEXT型、GEOMETRY型、JSON型）

```.エラー内容
SQLSTATE[42000]: Syntax error or access violation: 1101 BLOB, TEXT, GEOMETRY or JSON column 'content' can't have a default value (SQL: create table `blog_posts` (`id` bigint unsigned not null auto_increment primary key, `created_at` timestamp null, `updated_at` timestamp null, `title` varchar(255) not null default '', `content` text not null default '') default character set utf8mb4 collate 'utf8mb4_general_ci')
```


マイグレーションファイルのtext型のcontentにデフォルト値を設定していたのが原因
```create_blog_posts_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('blog_posts', function (Blueprint $table) {
            $table->id();
            $table->timestamps();

            $table->string('title')->default('');
            // $table->text('content')->default('');  <- error
            $table->text('content');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('blog_posts');
    }
};
```

## 外部キー制約で型に互換性がない

```.エラー内容
  SQLSTATE[HY000]: General error: 3780 Referencing column 'author_id' and referenced column 'id' in foreign key constraint 'profiles_author_id_foreign' are incompatible. (SQL: alter table `profiles` add constraint `profiles_author_id_foreign` foreign key (`author_id`) references `authors` (`id`))
```

```create_authors_table.php
    public function up()
    {
        Schema::create('authors', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
        });
    }
```

```create_profiles_table.php
    public function up()
    {
        Schema::create('profiles', function (Blueprint $table) {
            $table->id();
            $table->timestamps();

            // $table->unsignedInteger('author_id')->unique(); <- error
            $table->unsignedBigInteger('author_id')->unique();
            $table->foreign('author_id')->references('id')->on('authors');
        });
    }
```
【authorのidとprofileのauthor_idを制約時にエラー】
author id : bigint(unsigned)
profile author_id : int(unsigned)
であり型に互換性がないためエラーが発生

profile author_idをunsignedBigInteger('author_id')で適切な型に指定すれば解決
MacにてAmazon EKSの設定をする。

# はじめに
Amazon EKSの環境設定をまとめる。
Mac環境を想定しています。

# 環境設定
1.  kube-ps1のインストール

    ```sh
    brew install kube-ps1
    ```
    ※ zshrcへの設定
    ```sh:.zshrc
    source "/usr/local/opt/kube-ps1/share/kube-ps1.sh"
    PS1='$(kube_ps1)'$PS1
    ```

    ※ コンテキストがプロンプトに表示される。
    ```sh
    # コンテキストの表示を消す場合
    kubeoff

    # コンテキストを表示させる場合
    kubeon
    ```

1.  kubectlのインストール

    ```sh
    brew install kubectl
    ```

    ※ エイリアスを設定すると便利です。
    ```sh:.zshrc
    alias k='kubectl'
    ```

1.  kubectxのインストール

    ```sh
    brew install kubectx
    ```
    ※ kubensも利用できるようになる。

# 実行環境の準備
1.  AWS CLIの設定
[AWS CloudFormationを動かすためのAWS CLIの設定](https://qiita.com/miyabiz/items/fed11796f0ea2b7608f4)を参考にしてください。

1.  EKSクラスタの構築
[Macでeksctlを利用してAmazon EKSのクラスターを構築する](https://qiita.com/miyabiz/items/75f83237795b0b7d52bd)を参考にしてください。

# EKSのコンテキストの設定
1.  コンテキストの設定

    ```sh
    # マネジメントコンソールからEKSのクラスタ名を確認し、${cluster-name}に入力する
    aws eks update-kubeconfig --name ${cluster-name}
    ```
    ※ AWSのクレデンシャル・リージョンは設定は[こちらを参照](https://qiita.com/miyabiz/items/fed11796f0ea2b7608f4)

1.  コンテキストの表示と切り替え

    ```sh
    # コンテキストを一覧表示
    kubectx
    
    # コンテキストのスイッチ
    kubectx　${context-name}
    ```

1.  namespaceの表示と切り替え
    ```sh
    # namespaceの指定
    kubens ${namespace}

    # namespaceの確認
    kubens
    ```

# EKSのPodにログイン
1.  Podにログインする
    ```sh
    # Podを一覧表示
    kubectl get po
    
    # Podにログイン
    kubectl exec -it ${pod-name} /bin/sh
    ```
【Android】ライブラリの導入方法【AndroidStudio】

# ライブラリとは
ライブラリを直訳すると"図書館"です
図書館では　それぞれの人が　それぞれの目的で それぞれの知識を得るために　それぞれの本を借りることができます
Android（プログラミング）における**ライブラリ**とは
その図書館のように　他の人が作った機能をお借りして使うことが出来るもの
と私は捉えています



# 導入方法
Android Studio内の左辺にあるprojectタブにある
GradleScript から　build.gradle(Module: app)　を選択
その中の　dependencies{} 内に　使用したいライブラリをコピペで貼り付けてください

すると　右上に　「Sync Now」と出てくるので　これをクリック
これでライブラリの実装が完了します

# よく使われるライブラリ
Android開発でよく使われるライブラリをまとめてくれている方がいたので
記事をお借りして貼っておきます
↑の方法を使えばこの記事にあるライブラリを自分の
実装にそのライブラリの機能を使うことができます！

https://qiita.com/tkhskt/items/64e68189a21fea7caa7c
LightSailめも

Springで作ったJarをLightSailに置いて実行したが、ちょっとしたら落ちていた。
ログ見たらメモリ不足でカーネルにKILLされていた。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211352/162928c2-ea6c-3bc1-98cf-aaa2812809b7.png)

メモリを増設（512MB→1G）して解消。

※参考文献
https://linuxfun.org/2021/07/23/upgrade-lightsail-instance/#i-3
https://aegif.jp/alfresco/tech-info/-/20201119-alfresco/1.3
表示速度を上げるための個人的な考察　N+1問題編　

N+1問題：データベースからデータを取り出す際に、大量にSQLが発行されて
動作が遅くなってしまう問題のことです。SQLとはデータベースとのやりとりをする際に用いるデータベース型言語(プログラミング言語ではないので注意)です。

実際にN+1問題が発生している様子を見ていきましょう。
N+1問題は1対多のアソシエーションの場合に多くみられるので、投稿一覧ページを見ていきたいと思います。


![ra.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667538/10021d84-5f2b-1401-9511-606e8a179d40.jpeg)

投稿一覧ページを表示した際のターミナルです。
見てわかる通り、多くのSQL文が発行されています。
いろいろな機能をつけていてSQL文が複雑になっているので簡単な例を用いて説明します。

    def index
        @posts = Post.all   #データベース上から投稿データを取得
    end

投稿一覧ページに関するメソッド定義です。
   
    <% @posts.each do |t| %>
         <%= t.user.name %>
    <% end %>
投稿一覧のviewの定義です。

この場合、まず、
(1)投稿内容の全件取得を行います。 1回
(2)N個ある投稿一つ一つに紐づいているユーザーを取得してくる　N回

合計でN+1回の処理を行っている。つまり、投稿データの個数Nの値が膨大になるにつれて、それに紐づいているUserテーブルへのアクセス回数も膨大となります。
このようなN+1問題の対策の一つとして

    def index
        @posts = Post.all   #データベース上から投稿データを取得
    end

の部分を

    def index
        @posts = Post.includes(:user)   
    end

に変えると良い。
includes()メソッドを用いることで、投稿に紐づいているユーザーを一回で全て取得することが可能となり、処理速度を改善することが可能となる。

また投稿一覧の表示個数を分割することで処理速度を改善することができると考えられる。それに関してはまた次回。
AWS Lambdaのマネジメントコンソールでjsを複数ファイルとして使う

- index.js だけでなく、別のjsファイルに書き、そのjsファイルをどう使うか確かめた時の情報です

## jsファイルの配置等の画面キャプチャ
- ものすごく手軽だった。zip圧縮でのソースコードアップと似てる
- 左のツリー <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1482752/655d6fa3-203c-05db-23e7-9e55de879f46.png" width="500" />


## index.js
```js

var myfunc = require('./myfunc.js');

exports.handler = async (event) => {
  console.log(`EVENT: ${JSON.stringify(event)}`);

  myfunc.dummy21();
  myfunc.foo();

  const response = {
    statusCode: 200,
    body: JSON.stringify('success.'),
  };
  return response;
};

```


## myfunc.js

```js
// モジュール定義
module.exports = {
    foo: function () {
        console.log("foo");
    },
    bar: function (v1, v2) {
        console.log("bar");
    }
};

module.exports.dummy21 = function () {
    console.log("dummy21") ;
};
```



## 実行結果
```js
Test Event Name
20220624-1

Response
{
  "statusCode": 200,
  "body": "\"success.\""
}

Function Logs
START RequestId: b336b9f8-ae3e-49e5-9073-46ce62ce8f4a Version: $LATEST
2022-06-24T14:44:53.043Z	b336b9f8-ae3e-49e5-9073-46ce62ce8f4a	INFO	EVENT: {"key1":"value1","key2":"value2","key3":"value3"}
2022-06-24T14:44:53.043Z	b336b9f8-ae3e-49e5-9073-46ce62ce8f4a	INFO	dummy21
2022-06-24T14:44:53.043Z	b336b9f8-ae3e-49e5-9073-46ce62ce8f4a	INFO	foo
END RequestId: b336b9f8-ae3e-49e5-9073-46ce62ce8f4a
REPORT RequestId: b336b9f8-ae3e-49e5-9073-46ce62ce8f4a	Duration: 4.97 ms	Billed Duration: 5 ms	Memory Size: 128 MB	Max Memory Used: 56 MB	Init Duration: 158.70 ms

Request ID
b336b9f8-ae3e-49e5-9073-46ce62ce8f4a
```


## AWSマネジメントコンソールでのソースコード画面

- myfunc.js <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1482752/ab2497b0-104e-1194-64de-cc59b71e97d4.png"  width="300" />

- Execution Result <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1482752/8a53cebf-ed67-e104-a7d1-4810c568efb2.png"  width="300" /> 

## 参考
- https://kaworu.jpn.org/javascript/node.js%E3%81%A7%E9%96%A2%E6%95%B0%E3%82%92export%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95

- https://www.yoheim.net/blog.php?q=20150101
React useStateで配列オブジェクトを扱う

# useState()フックで配列オブジェクトを作ります

```javascript:App.js
// 配列オブジェクト
  const [post, setPost] = useState(
    [
      "apple 🍎",
      "banana 🍌",
      "apple 🍎"
    ]
  )
```

### オブジェクトを更新する

```javascript:App.js
import { useState } from 'react'
import './App.css'

function App() {

  const [fruit, setFruit] = useState("")

  // 配列オブジェクト
  const [post, setPost] = useState(
    [
      "apple 🍎",
      "banana 🍌",
      "apple 🍎"
    ]
  )

  // 入力した文字をfruitに入れる
  const handleChange = (event) => {
    setFruit(event.target.value);
  }

  // 配列に追加
  const handleAddToArray = () => {
    setPost((prevState) => ([...prevState, fruit]));
    setFruit("")
  }

  // filter()を使ってbananaを削除
  const deleteArray = () => {
    setPost((prevState) => prevState.filter((value) => value !== "banana 🍌"))
  }

  // filter()を使ってappleを残す
  const findApple = () => {
    setPost((prevState) => prevState.filter((value) => value === "apple 🍎"))
  }

  return (
    <div className="App">
      <h1>Hello</h1>
      <input
        type="text"
        placeholder='Input something...'
        value={fruit}
        onChange={handleChange} />
      <p></p>
      <button onClick={handleAddToArray}>Add to Array 🧺</button>
      <br />
      <button onClick={deleteArray}>Delete Banana 🍌</button>
      <br />
      <button onClick={findApple}>Find Apple 🍎</button>

      {/* 配列オブジェクトを参照 */}
      <p>{JSON.stringify(post, null, '\t')}</p>
    </div>
  )
}

export default App
```
# 結果

![2022-06-24_23h48_14.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/235f76dd-e25e-1cdc-40e1-cf575f12479b.gif)
Rでバスケット分析（arules）のためにtransaction型に変換しようと思ったら、不正なクラス “ngCMatrix” オブジェクト : row indices are not sorted within columnsが出た

バスケット分析を行おうと、transaction型に変換しようとしたんですが、エラーが起きてしまいました。

```R
> as(
+   list(
+     "basket1" = c(
+       "SDGs"
+     ),
+     "basket2" = c(
+       "SDGｓ" # ｓが全角
+       , "SDGs"
+     ),
+     "basket3" = c(
+       "あさがお"
+     )
+     "basket4" = c(
+       "あさがお"
+       , "アサガオ"
+     )
+   ),
+   "transactions"
+ )
 validObject(.Object) でエラー: 
   不正なクラス “ngCMatrix” オブジェクト : row indices are not sorted within columns
```

原因はこれだけでないでしょうが、一応私がハマったエラーを記載しておきます

# 原因1: 全角・半角が併存している。
下記のように`SDGs` `SDSｓ(sは全角)`が併存しているときに、他のバスケットに`SDGs`が存在していたらエラーになるようです。
半角表記したときに同じ語になるワードが併存するのが鬼門みたいです。

```R
as(
  list(
    "basket1" = c(
      "SDGs"
    ),
    "basket2" = c(
      "SDGｓ" # ｓが全角
      , "SDGs"
    )
  ),
  "transactions"
)
```

私の場合、BigQueryで元データを取得していたので、以下の方法で半角表記に寄せました
https://itips.krsw.biz/bigquery-how-to-normalize-multi-byte-string-text/

# 原因2: ひらがな・カタカナが併存している
原因1のひらがな・カタカナ併存バージョンです。

```R
as(
  list(
    "basket3" = c(
      "あさがお"
    )
    "basket4" = c(
      "あさがお"
      , "アサガオ"
    )
  ),
  "transactions"
)
```

気持ち悪いですが、カタカナに寄せることで解決しました
https://sem-aa-bq.hatenablog.com/entry/2019/03/02/010721

# 原因3: 0(ゼロ)と○(丸印)が併存している

```R
as(
  list(
    "basket3" = c(
      "0円"
    )
    "basket4" = c(
      "0円"
      , "○円"
    )
  ),
  "transactions"
)
```

これは単純に置換すれば大丈夫です

# 原因4: ゼロ幅スペースがある
詳しくは[こちら](https://inside.pixiv.blog/2020/05/13/181507)をご覧ください。

# 注記
バスケット内に同じ要素が入っている場合、重複要素が削除されます。
gitでUnityを管理する

- 完全に自分がしたことの日記です
きっかけ
メインパソコンで開発していたのですが、サブパソコンでも作業を進められるようにしたいと思った

環境
windows

## git push → git pull
にてメインパソコンのバージョンをサブパソコンへ。
- .ignoreファイル面倒臭いかなと思ったけど、GitHubでリポジトリを作る時にUnity用のファイルをボタンで作れました。便利！
## 一応、サブパソコン→メインパソコンのバージョン管理もやっておきたい
$ add commit push

## なんか変更ファイルが多いな…
log tempの差分がcommitされてました。
.ignoreさん、ちゃんと仕事してくれよ！

## どうやらキャッシュを削除すれば出来るようです。
やってみる。
$ git rm -r --cached .

## 出来た！けど大量のwarning。なんだなんだ
ちらと見る感じ、LFやらCTLFやら。
直前にgitをsetupしたので奇跡的に知ってたのですが、gitさんはデフォルトでcheckoutの時とcommitの時に改行コードを変えちゃうみたいです（理由は知らん）

## git config --local core.autocrlf false
falseが表示された
よし、warning消えた！
pushしても問題無し！

# おまけ
cloneした時にUnityでそのプロジェクトを開こうと思ったら、「そのプロジェクトは無効です」と言われました。は？そんなこと無かろうて。と思ったのですが、リポジトリとプロジェクトの名前が同じだったせいで、必死にリポジトリをUnityで開こうとしてました。
みんなは気をつけようね（常人は起こらない）
【PHP基礎⑰】配列-1.foreach文

［問題］　　(参照：http://www.cc.kyoto-su.ac.jp/~mmina/bp1/hundredKnocksBasic.html)
要素数10の整数型の配列を宣言し、i番目の要素の初期値をiとし、順に値を表示するプログラムを作成しなさい。
配列の初期化は初期化子を使ってもよいし、繰り返しで初期値を代入してもよい。


# コード
```php
$a = [0,1,2,3,4,5,6,7,8,9];
foreach($a as $m){
    echo "$m \n";
}
```


# 結果
```
0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
```


☆配列
・変数には1つしか情報を格納できなかったが、配列には複数の文字列や数値を格納することができる。
　格納した値を要素という。
・配列は、0番目、1番目…というように、0から始まる。
・[　]で括る。
・その要素が配列の何番目かということを「キー」といい、配列＄mの4番目なら、「　＄m[4]　」と表記する。


☆foreach文

　　　foreach(配列変数　as　取り出した要素の値を格納する変数){
　　　　　　実行する処理;
　　　}
　
・配列に含まれる各要素の値を順に取り出したい時に場合に便利。
・foreach文では、配列に含まれる要素の数だけ繰り返しが行われ、1回繰り返すたびに配列に含まれる要素の値を変数に代入する。
・while文やfor文と違って、繰り返しが終了される条件式は存在しない。配列の要素の数だけ繰り返して終了となる。
【実践】2つコミットを戻したいそこのあなたへ

## 結論から

以下のコマンドを使うと、```--soft```モードでコミットを2つ戻します

```
$ git reset --soft HEAD^^
```

<br><br>

記事の後半では ```--soft``` か```--hard``` の話や ```^^```についての話を書きます

時間のある方はご覧ください

<br>

## まずは検証

現在のコミット状況

```
$ git log --oneline
4527f6d (HEAD -> master) add: c
74d50cc add: b
e1622d9 add: a
```

<br>

2つコミットを戻す

```
$ git reset --soft HEAD^^
```

<br>

戻りましたね👏

```
$ git log --oneline
e1622d9 (HEAD -> master) add: a
```

<br>

### ちょっと注意

ここでstatusを確認すると

```
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   b
        new file:   c
```

2つのファイルがステージングされていますね


下記のコマンドでuntrackedにしましょう

```
$ git restore --staged b c
```

<br>

ステージング前に戻りました

```
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        b
        c

nothing added to commit but untracked files present (use "git add" to track)
```

あとはファイルを消したり、addしなおしましょう

<br>

## --soft or --hard ??

### --soft

上記で検証した通り、```--soft```は **HEAD** (最新のコミットの状態) の位置のみ更新し、

**インデックスの状態は変わりません**

なので、検証の時のように```b```,```c```ファイルがステージングされていました

<br>

### --hard

ではhardだとどうなるのか?

**インデックスやワーキングツリー(自分のファイルの状態)も戻ります**

検証してみましょう

<br>

現在のコミット状況

```
$ git log --oneline
9a08549 (HEAD -> master) add: c
0c4a0b3 add: b
e1622d9 add: a
```

```--hard```をつけてresetします

```
$ git reset --hard HEAD^^
HEAD is now at e1622d9 add: a
```

```
$ git status
On branch master
nothing to commit, working tree clean
```

```
$ ls
a
```

完全に消えましたね！

### --mixed

default(何も指定しない)だと```--mixed```になります

これはインデックスまで戻すため```--soft```の際に行った

```restore```後の状態になりますね

<br>

## ^^ってなに?

2つ戻すってことです

<br>

下記のコマンドだと4つコミットを戻すことができます

```
$ git reset --soft HEAD^^^^
```

<br><br>

## 参考記事
- [[git reset (--hard/--soft)]ワーキングツリー、インデックス、HEADを使いこなす方法](https://qiita.com/shuntaro_tamura/items/db1aef9cf9d78db50ffe)
React useStateでオブジェクトを扱う

# useState()フックでオブジェクトを作ります
```javascript:App.js
const [post, setPost] = useState(
    {
      name: "mario",
      age: 5,
    }
  )
```

### オブジェクトを更新する

```javascript:App.js
import { useState } from 'react'
import './App.css'

function App() {

  const [post, setPost] = useState(
    {
      name: "mario",
      age: 5,
    }
  )

  // ageプロパティを更新する
  const handleClick = () => {
    setPost({ ...post, age: post.age + 1 });
  }

  // nameプロパティを更新する
  const handleChange = (event) => {
    const newName = event.target.value
    setPost({ ...post, name: newName });
  }

  return (
    <div className="App">
      <h1>Hello</h1>
      <button onClick={handleClick}>+</button>
      <p></p>
      <input
        type="text"
        placeholder='Input something...'
        value={post.name}
        onChange={handleChange} />
        {/* オブジェクトを参照 */}
      <p>{JSON.stringify(post, null, '\t')}</p>
    </div>
  )
}

export default App
```

# 結果
![2022-06-24_22h50_45.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/4598bb62-0506-fc87-6aa1-b5ce74246a35.gif)
Recursion（再帰）を理解する

## 再帰関数とは
自分自身を呼び出す関数のこと。ループと似ており同じコードを何度も実行するので、無限再帰を防ぐための条件が必要になる。 

https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Functions#recursion

## 再帰のコードを書くときのポイント


* 実際の値を当てはめて、コードの流れを考える
* どのような関数をどこで呼び出すか考える
* ベースケースとリカーシブケースを考える
* 「リカーシブケース」・・・何を対象に再帰処理を継続していくか（ループの繰り返し処理にあたる部分）
* 「ベースケース」・・・どういう条件を満たしたら再帰処理を止めるのか（ループ終了）
* 木構造で考えると分かりやすい

## 実際にコードを分解してみる

* じゃんけんの組み合わせ（下のサイトからコード参照）

https://medium.com/@sidiousvic/visualizing-recursion-b8107bd56b01
```js
const rockPaperScissors = (rounds = 3) => {
  let out = [];
  const weapons = ["rock", "paper", "scissors"];
  const play = (rounds, result = []) => {
    // exit case
    if (rounds < 1) {
      out.push(result);
      return;
    }
    // recursive case
    for (let i = 0; i < weapons.length; i++) {
      const weapon = weapons[i];
      play(rounds - 1, result.concat(weapon));
    }
  };
  play(rounds);
  return out;
};
```

* 分解して考えると・・・

```js
rockPaperScissors(); //関数呼び出しすると・・・

//　大前提　＝　すべてのループは３回ずつ回ること！！！

play(3, []); //rounds = 3

// loop 0 (i = 0 --> "rock") 親のループが始まる
weapon = "rock";
play(2, result = ["rock"]);

// loop 0-0 (i = 0 --> "rock")　親のループの中で、子のループが始まる
weapon = "rock";
play(1, result = ["rock", "rock"]);

// loop 0-0-0 (i = 0 --> "rock")　子のループの中で、孫のループが始まる
weapon = "rock";
play(0, result = ["rock", "rock", "rock"]);
//exit case === True
out = [["rock", "rock", "rock"]];
return 
//つまり「処理の終了」、孫のループの値が更新される。
play(0, result = ["rock", "rock", "rock"]);

// loop 0-0-1 (i = 1 --> "paper")
weapon = "paper";
play(0, result = ["rock", "rock", "paper"]);
//exit case === True
out = [["rock", "rock", "rock"], ["rock", "rock", "paper"]];
return 

// loop 0-0-2 (i = 2 --> "scissors")
weapon = "scissors";
play(0, result = ["rock", "rock", "scissors"]);
//exit case === True
out = [["rock", "rock", "rock"], ["rock", "rock", "paper"], ["rock", "rock", "scissors"]];
return 

// 孫のループがすべて回り切ったので、いったん子のループに戻る（子ループの値更新）
// loop 0-1 (i = 1 --> "paper")
weapon = "paper";
play(1, result = ["rock", "paper"]);

// また孫のループが始まる
// loop 0-1-0 (i = 0 --> "rock")
weapon = "rock";
play(0, result = ["rock", "paper", "rock"]);
//exit case === True
out = [["rock", "rock", "rock"], ["rock", "rock", "paper"], ["rock", "rock", "scissors"], ["rock", "paper", "rock"]];
return

// loop 0-1-1
// loop 0-1-2
// loop 0-2-0
// loop 0-2-1
// loop 0-2-2
// loop 1-0-0

以下、省略・・・

```

## 動画
オススメしていただいた動画。解説が分かりやすかったです。

https://youtu.be/6oDQaB2one8

## ひとこと

はじめて再帰のコードを一から書いたとき、再帰処理の流れより先に実行すべき関数ばかり考えて、手が止まってしまいました。その時に頂いたアドバイスが「再帰のコードを書くときのポイント」です。
何パターンかコードを見たり書いたりしているうちに処理の流れが理解できて、リファクタリングもできるようになりました。引き続き理解を深めていこうと思います！
【#10 エンジニア転職学習】Linux基礎　sed/awkコマンド

# はじめに
富山県に住んでいるChikaといいます。
毎日投稿を目標に、バックエンドエンジニア転職に向けた学習内容をアウトプットします。

連日になりますが、Linuxの基礎を進めましたので自分なりに気になったポイント等をまとめていきます。

バックエンドエンジニアになるまでの学習内容は以前投稿した以下の記事を基にしています。


https://qiita.com/Chika110/items/ef54dddd565a0193ef44

# 本日の学習内容
本日はテキスト処理の応用編という感じでsedとawkコマンドをやりました。どちらも以前基礎コマンド学習をした際にはなかった内容です。

* **sedコマンド・ awkコマンド　←Topic!!**

# sedコマンド・ awkコマンド
sed：非対話型エディタで決まったパターンのテキスト編集を効率よく行うコマンド
awk：テキストの検索や抽出・加工を行うコマンド、sedよりも応用が利く

* どちらのコマンドも「スクリプト」と呼ばれる特定の文字列等を引数に取る
* スクリプトには正規表現が使用可能

などの共通点がある。
awkは事前に作成しておいたスクリプトファイルを読み込んで実行する`-f`オプションもあったりと使い勝手が良さそうです。
実際に手を動かして、他のオプションや使い方を覚えていこうと思います。


使用している書籍はこちら↓

https://www.amazon.co.jp/%E6%96%B0%E3%81%97%E3%81%84Linux%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E4%B8%89%E5%AE%85-%E8%8B%B1%E6%98%8E-ebook/dp/B072K1NH76/ref=sr_1_1?adgrpid=113196705062&gclid=Cj0KCQjwzLCVBhD3ARIsAPKYTcR4WAb_4QVrwuBM_1mIPMFsQ6kNDJ-o4yIofVSAI7_eHpWCeva8kKwaAstgEALw_wcB&hvadid=489559881279&hvdev=c&hvlocphy=1009363&hvnetw=g&hvqmt=e&hvrand=10125867468998217428&hvtargid=kwd-1152146940662&hydadcr=21814_10996132&jp-ad-ap=0&keywords=%E6%96%B0%E3%81%97%E3%81%84+linux+%E3%81%AE+%E6%95%99%E7%A7%91%E6%9B%B8&qid=1655473534&sr=8-1




# おわりに
最後までお読みいただきありがとうございました。
明日もLinuxですが、シェルスクリプト編ということで大事なパートっぽいので集中していきます。
アドバイス・応援コメント等いただけますと幸いです。
変数・関数の命名ケーススタディ - My Best Practice for the name of Functions or Variables

# Funciton - 関数
timeComparison
  時間に関する何かを比較するんだろうなとはわかる。でも結局何をするものなのかわからない。
例えば、時間が過去かどうか判定するなら、validateObjectIsInPast
過去かどうかだけじゃなくて未来も判定したいよ、って人。それは関数を分けるか、それは何のための関数なのか考えるべき。きっと何のために時間を過去か未来かを判定しているのかってのがあるはずで、その場合はそれに即した命名をするべき。
(Objectはなにか特定の)

NumberingObjectReference
  ObjectのReference(数字)を生成するための関数。なんかNumberingって一般的じゃない気がするのでGenerateObjectReferenceでいい

# Variable - 変数
pastObject
=> IsPastObject　booleanはわかりやすく
isPermission
=> hasPermission  isだと権限かどうか。hasだと権限を持ってるかどうか

isEnable
=> isEnabled 過去分詞

atts
=> attendees  略しすぎてなんの変数かわからん

var emails string
var email []string
型と変数名は一致させよう。配列=>複数のものが入る=>変数名も複数形

# 両方

completeObject v.s. completedObject
completeObjectはObjectをComplete処理する関数に使う方が良い。
completedObjectはcompleteされたObjectを格納する変数に使う方が良い

# あとがき
Codingしていると、ついつい自分はわかるから、と適当な名前を付けてしまうことがありますが、
チームで仕事している場合は他の人が一目でわかるようになっているように心がけるようにしましょう。
また、タイミングを見つけたり事例を発見したらこの記事を更新したいと思います。

# Reference - 参考資料

https://qiita.com/Ted-HM/items/7dde25dcffae4cdc7923
https://qiita.com/KeithYokoma/items/2193cf79ba76563e3db6
https://qiita.com/usatie/items/b41adf8114188406d2b8
Python+VSCodeにおすすめの拡張機能

# 1.概要

2022年6月にこれまで使っていたAtomの開発が中止となりました...
[~GitHub、コードエディター「Atom」の開発を終了 ～年内にアーカイブ~](https://forest.watch.impress.co.jp/docs/news/1415735.html)

そのため、新たなエディタとしてVSCodeを導入し、約1か月使ってみて使える拡張機能を紹介したいと思います。

# 2.VSCodeのおすすめ拡張機能

### Python

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/5e8a5025-db59-7de0-fe05-7c4c36ff69f0.png" width=80%>

まずは普通にPython。これがないと、そもそもPythonを動かすことができない。

### Japanese Language Pack for VS Code

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/2245da99-db5b-1892-3104-2c14fa60a93f.png" width=80%>

日本でVSCodeを入れると、半自動的にインストールできる（○○をインストールしますかと聞かれる）。こちらをインストールすることでVSCodeが日本語に変換される。

### Todo Tree

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/cf28e646-c3c7-b6d2-96f7-6e5ddb9fb5d8.png" width=80%>

コメント欄に「#TODO」と入れると、TODOリストに記載したコメントが一覧で確認できる。途中までプログラムを作成した後に、続きはどこから開発すればいいか、タスクとして残すことができる。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/7e2925d1-704f-4692-df9e-2dceebb7821a.png" width=90%>

### Indent-Rainbow

インデントを入れると、色付けしてわかりやすくしてくれる。for文とかif文とかのインデント問題を発見しやすい。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/15837d65-1ef2-a4bc-da1f-fac68b0c3ac0.png" width=80%>

### Material Icon Theme

各ファイルをアイコン表示してくれることで、Pythonファイルなのかtextファイルなのか、見た目で判断できるようになる。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/52e63b27-a0ce-ddac-76fa-f32b647fe116.png" width=80%>

### Zenkaku

全角と半角のスペースを、色付けしてわかりやすく表示してくれる。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/dad46d0b-3f32-999c-6a82-e6b714b9dc76.png" width=80%>

### Better Comments

コメントを色付けしてわかりやすくしてくれる。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/7aa09e77-a215-238d-c91a-a2138230b76f.png" width=80%>

「!」が赤、「*」が緑、「?」が青、「TODO」がオレンジとなる。また、TODOにも色を付けたい場合は、「TODO!」と記載すれば、TODOかつ赤色にすることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/7b2936f9-5c36-af34-ffff-e97799d42791.png)

### Code Runner

動かしたいコードを選択し右クリックで「Run Code」を押下することで、選択している部分のみコードを動かすことができる。（一部分だけ動作を確認する際に便利）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/10b1d7db-a450-8f6d-bdeb-0fa447209342.png" width=80%>

### Pylance

問題のあるコード部分にエラーを表示してくれる。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/dee74ce9-23d4-c165-4129-8a0b09396396.png" width=80%>

以下インデントのミスを起こした場合。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/876572c0-a2e0-f46b-7d4d-78bcce1d1c8f.png)


### Python Indent

for文などでインデントを行うと、Pythonの構文に従って自動でインデントが行われる。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/8241ca12-6e51-f5ed-2890-5230097efd33.png" width=80%>


一旦上記を入れてプログラミングを行っています。もしほかに使える拡張機能があれば随時更新していきます。
bundle installしたときにUnfortunately, an unexpected error occurred, and Bundler cannot continue.が出た時の対処法

環境
- MacOS Montrey 12.4
- Rails 6.0.5
- Ruby 2.7.6
- Bundler 2.3.16

## エラー内容
```
$ bundle install
```

不可解なエラーの発生
```
--- TEMPLATE END ----------------------------------------------------------------

Unfortunately, an unexpected error occurred, and Bundler cannot continue.

First, try this link to see if there are any existing issue reports for this error:
https://github.com/rubygems/rubygems/search?q=undefined+method+%60full_name%27+for+nil+NilClass&type=Issues

If there aren't any reports for this error yet, please fill in the new issue form located at https://github.com/rubygems/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md, and copy and paste the report template above in there.
```

## 解決方法
Gemfile.lockを削除してもう一度bundle installする。

間違えてファイルをいじってしまったことでGemfile.lockを読み込めなくなっていたらしい。
bundle installするともう一度Gemfile.lockが作成されるので問題なし。
cannot connect to the docker daemon at unix:///var/run/docker.sock. is the docker daemon running? の解決方法

## 前提
__環境__
　Ruby 2.7系
　Rails 6.1系

## 結論
デスクトップからDockerのアイコンをクリックする等して再起動したら解決しました

## 経緯
1. docker-compose up でサーバーを立ち上げようとする
2. A server is already running. と表示され立ち上がらない
3. 以下コマンドを実行
 lsof -wni tcp:3000
4. 実行結果の「COMMAND」に「com.docke」と書いてある行のPIDをコピーして以下コマンドを実行（今思えばこれが誤りかと）
 kill -9 xxxxx（コピーした数字）
5. docker-compose up
5. cannot connect to the docker daemon at unix:///var/run/docker.sock. is the docker daemon running?と表示される

## 試したこと
```
% sudo service docker stop
% sudo service docker start
```
これでは解決せず。

```
% sudo systemctl start docker
zsh: command not found: systemctl
```
これでも解決しない。

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

調べて出てきたものをとりあえず打ってみたものの解決せず、この辺りでちょっと焦ってきましたが
Dockerのアイコンをクリックして再起動をしてみたら直りました。

## 今後注意する点

docker-compose upでサーバーが立ち上がらず
A server is already running.と表示されたら以下コマンドを実行する

```
% docker-compose run web rm /app/tmp/pids/server.pid
```
Markdown記法まとめ

# 概要
Markdown記法で使う表現をまとめておきます。


# 見出し
```
# 見出し1
## 見出し2
### 見出し3
（#の個数で大きさが変わる）
```
# 見出し1
## 見出し2
### 見出し3

# 強調・斜体・引用・インラインコード
```
**強調**はアスタリスク2つで囲う

*Italic*はアスタリスク1つで囲う

`インラインコードは`はバックダッシュで囲う

> 引用は大なり記号
```
**強調**はアスタリスク2つで囲う

*Italic*はアスタリスク1つで囲う

`インラインコードは`はバックダッシュで囲う

> 引用は大なり記号

# リスト・番号付きリスト
```markdown
- リスト1
- リスト2
    - リスト2-1
    - リスト2-2
- リスト3


1. 番号付きリスト1
2. 番号付きリスト2
    1. 番号付きリスト2-1
    2. 番号付きリスト2-2
3. 番号付きリスト3
```
- リスト1
- リスト2
    - リスト2-1
    - リスト2-2
- リスト3


1. 番号付きリスト1
2. 番号付きリスト2
    1. 番号付きリスト2-1
    2. 番号付きリスト2-2
3. 番号付きリスト3

# 表
```
|見出し1|見出し2|
|-|-|
|内容1-1|内容1-2|
|内容2-1|内容2-2|
```
|見出し1|見出し2|
|-|-|
|内容1-1|内容1-2|
|内容2-1|内容2-2|
混乱しがちなプログラミングの処理用語

業務でてきた処理の用語と基本情報で学んでいる内容が混ざってしまっているので、混乱したものを全て書き出してみます。

## 並行処理
並行の意味は英語で**concurrent**と呼びます。
```
A --------
           B --------　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　B -----------
                      C ----------
```
AとBとCの処理は一つの処理を行ってから、別の処理に移っています。
お茶を飲んで、ご飯を食べて、腹筋して、またご飯を食べると一人の人が別々の動作を行っています。

## 並列処理
並列の意味は英語で**parallel**と呼びます。
```
A -----------
B -----------
C -----------
```
同時にAとBとCの処理が走っています。
Aさんがご飯を食べる、Bさんが腹筋する、Cさんがお茶を飲むと同時に処理が走っています。


## プロセス
実行中のプログラムは「プロセス」と呼ばれます。プロセスは1つ以上の「スレッド」を持ちます。
```
|プロセス|
|スレッド①|
|スレッド②|
|スレッド③|
```

## スレッド
英語だとthreadです。プログラムの処理の実行単位です。
シングルスレッドの場合は下記のようなイメージです。
```
スレッド① -------- 
                 スレッド② --------
                                    スレッド③ -------
```
つまり一つのスレッドが終わり次第、次のスレッドが始まるイメージですね。
並行処理と同じイメージですかね。

マルチスレッドだと
```
スレッド① -------- 
スレッド② --------
スレッド③ --------
```
こちらは並列処理と同じイメージですかね。

## JavaScriptはシングルスレッド
JavaScriptはシングルスレッドなので、二つの処理を並行して実行させることはできません。関数を呼び出すとコールスタックと呼ばれる箇所に追加されます。

コールスタックはJavaScriptのエンジンの一部です。
WebAPIがコールバック処理し、キューに追加されイベントループがタスクを実行します。

コールバックキュートコールスタックを調べた後にコールスタックが空の場合はキュー内の最初のアイテムがスタックにプッシュされます。

コールバックがコールスタックに呼び出され、スタックからポップし、スタックからポップされます。

参考
[JavaScriptはなぜシングルスレッドでも非同期処理ができるのか](https://speakerdeck.com/task4233/why-can-javasctipt-invoke-asynchronous-in-single-thread?slide=12)
[JavaScript Visualized: Event Loop](https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif)

## まとめ
詳しく書こうとすると各言語によっての挙動やCPUのコア数によっての処理の違いなど、かなり深い話まで書けてしまうのでイメージでまとめました。
ツッコミところは多いですが、深掘りするところは今後も深掘りしていこうと思います。
【デザインパターン】悪戦苦闘！デザインパターン ~Visitorとダブルディスパッチ編~

## はじめに
本記事は、デザインパターン学習中の私が学習中に詰まったポイント、間違えてしまったポイントをもとに学んだことを書いたものです。
個人の理解に基づいておりますため、間違いがあれば教えていただけると幸いです。

★9ヶ月前くらいにデザインパターンの勉強のために執筆し、社内で公開していた記事をこちらにも投稿したものとなります。

## Visitorパターン、難しくないですか？　

私は難しかったです。

Visitorパターンの学習中に、「ダブルディスパッチ」という言葉が出てきました。そしてどうやら、「シングルディスパッチ」や「トリプルディスパッチ」も存在するらしい。

当時はパターン自体の難しさもあって結局理解が若干あやしいままになってしまったのですが、記事化するにあたって改めて整理し直してみようと思います。

## ダブルディスパッチとは？

ダブルディスパッチとは、オーバーロード（多重定義）されたメソッドについて、2個のオブジェクトが関与してどのメソッドが呼び出されるかを選択するものです。

言葉だけで説明するのも難しいため、以下のVisitorパターンのクラス図を用いて説明します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1062427/081bdbf1-603a-2f2c-ab4d-3f97edb4c721.png)


多重定義（オーバーロード）されているのはConcreteVisitor1のVisitメソッドです。ConcreteElement1とConcreteElement2の型の引数をそれぞれ持っています。

ConcreteElement1のAcceptメソッドおよびConcreteVisitorメソッドの実装例を以下に示します。

```csharp
internal class ConcreteElement1:IElement
{
	// ...(省略)

	public void Accept(IVisitor visitor)
	{
		// 自分自身をVisitorクラスに渡す
		visitor.Visit(this);
	}
}
```

```csharp
internal class ConcreteVisitor1:IVisitor
{
	// Elementの集合（Element1・2がごっちゃに入っている想定）
	IList<IElement> m_ElementList;
	int m_CurrentIndex;

	public ConcreteVisitor1(IList<IElement> list)
	{
		m_ElementList = list;
		m_CurrentIndex = 0;
	}	

	public void Visit(ConcreteElement1 element)
	{
		Console.WriteLine("訪れたのはConcreteElement1でした。");
		list[m_CurrentIndex++].Accept(this);
	}

	public void Visit(ConcreteElement2 element)
	{
		Console.WriteLine("訪れたのはConcreteElement2でした。");
		list[m_CurrentIndex++].Accept(this);
	}
}
```

メソッドの呼ばれる順番としては、

①ConcreteElement1のAcceptメソッドが呼ばれる。

②Acceptメソッドで、引数で渡ってきたConcreteVisitor1のVisitメソッドを、自分自身を引数に渡して呼び出す。

③引数に渡されたElementの型がConcreteElement1であるため、Visit(ConcreteElement1 element)メソッドの処理が実行される。

④Visit(ConcreteElement1 element)メソッドで、次のElementのAcceptメソッドを、自分自身を引数に渡して呼び出す。（次のElementがConcreteElement1なのか2なのかはこの時点ではわからない。）

以降、訪れていないElementが無くなるまで繰り返し

というようになります。

VisitorはAcceptメソッドを呼んで、Elementに「自分はConcreteElement1か2か」を教えてもらうことで、2つあるVisitメソッドのどちらをを実行すれば良いかが確定します。上の順番の③の時点ですね。

このように、 **呼ばれるメソッドの決定に2つのオブジェクトが関与する** のがダブルディスパッチです。

ちなみに、Visitor側はConcreteVisitorを容易に増やすことができますが、Element側はConcreteElementを増やすたびにVisitor側のインタフェースおよび実装にVisitメソッドのオーバーロードを増やさなければならなくなります。

## では、シングルとトリプルは？

XXディスパッチのXXはつまり、メソッドの決定に関与するオブジェクトの数です。

シングルディスパッチは、メソッドの決定に関与するオブジェクトが単一であることを示します。

Visitorパターンの例に合わせて言えば、他のElementクラスと関係なしに、ConcreteVisitor1クラス内でどのオーバーロードが呼ばれるかを決定している状態であれば、シングルディスパッチといえるのではないでしょうか。

逆に、3つのオブジェクトがメソッドの決定に関与するのが、トリプルディスパッチです。

ダブルディスパッチやトリプルディスパッチのように複数のオブジェクトが多重定義されたメソッドの決定に関与することを、多重ディスパッチと呼びます。

## まとめ

呼ばれるメソッドの決定に2つのオブジェクトが関与するというところが、言葉では「フーン、そうなんだ」と理解できても、実際の設計としてはなかなか理解の難しいところであると思います。

トリプルディスパッチの例が出せていない&探しても見つからない、という状態なので、記事としては片手落ち感があります。詳しい方がいらっしゃれば教えていただけると大変助かります。

◆◆◆
最後まで読んでいただき、ありがとうございました。 
以下は前回のデザインパターンの記事です。よければ合わせてどうぞ。
[【デザインパターン】悪戦苦闘！デザインパターン ~State・Strategy編~](https://qiita.com/kamikawa_m/items/b6bd075b4c96ec842e7b)
[【デザインパターン】悪戦苦闘！デザインパターン ~Proxy・Flyweight編~](https://qiita.com/kamikawa_m/items/1200abb70d02a79c4c53)
[【デザインパターン】悪戦苦闘！デザインパターン ~Mediator・Observer編~](https://qiita.com/kamikawa_m/items/b5f0622d06a8cf3dd231)
【備忘録】axiosのResponseに型を付与する。

対象のレスポンス
```
~/develop/node $ curl https://jsonplaceholder.typicode.com/todos/1
{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}%      
```
→jsonplaceholderの取得結果に型をつけていきます。

```typescript:app.ts
import axios from "axios"

// 型定義を実施
type User ={
    userId:number
    id:number
    title:string
    completed:boolean
}

// main処理の関数
const main = async ()=>{
    const user = await axios.get<User>("https://jsonplaceholder.typicode.com/todos/1")
    console.log('user.data: ',user.data)
    console.log('user.data.userId: ',user.data.userId)
    console.log('user.data.id: ',user.data.id)
    console.log('user.data.title: ',user.data.title)
    console.log('user.data.completed: ',user.data.completed)
}

// main関数を実行
main()
```

```shell:実行結果
~/develop/node $ ts-node app.ts
user.data:  { userId: 1, id: 1, title: 'delectus aut autem', completed: false }
user.data.userId:  1
user.data.id:  1
user.data.title:  delectus aut autem
user.data.completed:  false
```
【デザインパターン】悪戦苦闘！デザインパターン ~Mediator・Observer編~

## はじめに
本記事は、デザインパターン学習中の私が学習中に詰まったポイント、間違えてしまったポイントをもとに学んだことを書いたものです。
個人の理解に基づいておりますため、間違いがあれば教えていただけると幸いです。

★9ヶ月前くらいにデザインパターンの勉強のために執筆し、社内で公開していた記事をこちらにも投稿したものとなります。

## 違いがわからない

ObserverパターンとMediatorパターンは、どちらもオブジェクトからの通知を受け取って、それをもとに何か処理をするパターンであると学習で理解したつもりでした。しかし、「じゃあ学んだことを記事にしよう！」と思った段階で、二つのパターンの違いがあまり理解できていなかったと気付いたため、少し調べてみました。

## Mediator(調停者)パターン

まず、Mediatorパターンは、Mediator(調停者)という名の通り、 **複数のクラスからの通知を受け取ってそれぞれをいい感じに調停するというパターン** です。Mediatorクラスが通知をもとに各クラスに指示を出すため、通知を出す側のクラス群はお互いを知る必要がありません。

例えば、「テキストボックスAに文字を入力してボタンBを押すとテキストブロックCに文字が表示される」といったプログラムの場合、テキストボックスAのクラスとボタンBのクラスは、テキストブロックCのことを知る必要がありません。

Mediatorクラスへ「テキストボックスAに文字が入力されました」「ボタンBが押されました」という通知を出せばよいのです。「テキストボックスAに入力があり、ボタンBが押されたから、テキストブロックCに文字を表示するように指示をする」のはMediatorクラスの仕事になります。

## Observer(観察者)パターン

次に、Observerパターンは、 **観察対象のクラスの変化を観察するパターン** です。観察とは言っていますが、Observerクラス自身が能動的に観察対象の変化を監視している訳ではなく、逆に観察対象のクラスがObserverクラスに対して、「自身に何かしらの変化がありました」という通知を出しているのです。

例えば、「テキストボックスAに文字を入力する」というプログラムについて、Observerパターンは「50ミリ秒ごとにテキストボックスの状態を取得して変化を検知する」ということをするのではなく、「テキストボックスAに何か文字が入力されたら、テキストボックスAがObserverクラスに通知を出す」のです。

そのような特性から、Publish(出版)-Subscribe(購読)パターンとも呼ばれます。

Observerパターンは、このように通知に重点を置いたパターンですが、「通知を出したクラスに何か処理をさせたい」ということもあると思います。例えば、「テキストボックスAに文字を入力してボタンBを押したら、テキストボックスAを入力不可にしたい」といった場合です。

その場合には前述のMediatorパターンで解決できます。Observerパターンは、Mediatorパターンの「複数のクラスからの通知」の部分に活用することができるのです。

## まとめ

ObserverパターンとMediatorパターンは「オブジェクトからの通知を受け取って、それをもとに何か処理をするパターン」というふうに認識していました。
しかし、Observerパターンの主眼はあくまでも「 **状態変化を通知すること** 」にあり、観察対象が何クラスあるかや、それをもとに何か処理をするかどうかはパターンの範囲外でした。
逆に、Mediatorパターンは「 **複数のクラスからの通知を元に判断を行い、各クラスへ指示を出すこと** 」に主眼があるため、クラスは複数ある前提で、通知を元に何らかの処理を行うところまでがパターンです。Observerパターンは片方向、Mediatorパターンは双方向に通信を行うパターンであるということですね。

State・Strategyパターン（クラス図が同じ・使い方が違う）の際にも思いましたが、パターン自体に共通する部分があっても、パターンのキモになる部分や解決できる問題が違えば違うパターンであり、むしろ似ているからこそ違いを理解しておく必要があると思いました。

◆◆◆
最後まで読んでいただき、ありがとうございました。 
以下は前回のデザインパターンの記事です。よければ合わせてどうぞ。
[【デザインパターン】悪戦苦闘！デザインパターン ~State・Strategy編~](https://qiita.com/kamikawa_m/items/1200abb70d02a79c4c53)
[【デザインパターン】悪戦苦闘！デザインパターン ~Proxy・Flyweight編~](https://qiita.com/kamikawa_m/items/1200abb70d02a79c4c53)