OmniAICreator/Qiita-1.07M huggingface dataset:
C#のデリゲートって何？

## はじめに ※読み飛ばし可
人生初のQita投稿ということもあり、この記事を書いているやつがどんな人間かを簡単に自己紹介させてください。
見出しにも書いてあるとおり、内容にはまったく関係ないので読み飛ばしていただいても構いません。

わたしは新卒で6年間働いたSIer企業を辞めて、この2022年の5月から自社開発企業に転職しました。
前職は大規模で社会インパクトも大きいながらも、技術スタックおよび開発プロセスともに非常にレガシーなシステムの開発に携わっておりました。

規模に比例した責任感とやりがい、会社自体の安定感に魅力はあったものの、立ち位置上「コードが書けないマネージャ」まっしぐらなキャリアに違和感と危機感を持ち、とうとう思い切って転職を決意しました。[^1]

転職先では、これまた人生初のC#での開発現場でエンジニアとして新しいキャリアを歩んでいます。正直、わからないことだらけで文字通り毎日が勉強ですが、自分の整理も兼ねて少しずつアウトプットしていこうと思い、Qiitaをはじめました。

ネット上には詳しい方がいくらでもいるので、そういう方からすると説明不足や分かりづらい点があるかと思いますが、もし誤りなどがあればご指摘いただければと思います。

## この記事でわかること
この記事のテーマはC#の「デリゲート」です。C#を勉強してて、2番目にピンとこなかった概念です[^2]。「デリゲートってこういうものか」ってのがわかってもらうのがこの記事のゴールです。

## この記事で扱わないこと
匿名メソッドやLINQについては、扱いません。また、C#としてあらかじめ定義されているデリゲートのクラス「Action」、「Func」も一旦置いておきます。

## 結局、デリゲートってなんなのか？
前置きが長くなりました。
デリゲートを一言で言えば、**メソッドを参照できる型**。この型で作った変数にはメソッドを格納できる。[^3]

## 宣言の仕方
デリゲートは、自分で宣言できる型。宣言のために「deligate」キーワードを使う。
```csharp
public delgate bool hoge(int value);
```

## で、デリゲートの結局なにがうれしいのか
正直わたしはこの説明を受けて「変数にメソッドが格納できるから何？」状態だったので具体例で考えてみます。実際は、ラムダ式を使うので、以下の例のような書き方はしないのですが、わかりやすさのためにラムダ式が導入される前の想定で書いています。


(例)
```csharp
public delegate bool JudgementCondition(int value); //デリゲートの宣言

public int Do() {
	var numbers = new[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,};
	JudgementCondition judgementCondition = IsEven // デリゲート型「JudgemntConditon」にIsEvenメソッドを代入
	var count = Count(number, judgementCondition);
	Console.WriteLine(count); // 5
}

// nが偶数か調べる
public bool IsEven(int n); { 
	retun n % 2 == 0;
}

// 判定条件に当てはまる要素をカウントする 
public int Count(int[] number, JudgementCondition judgementCondition){
	int count = 0;
	foreach (var n in numbers) {
		if (judgementCodition(n) == true)
			count++;
	}
}

```

今回作ったデリゲートは「int型の引数を受け取って、bool型の戻り値を返す」型です。したがって「int型の引数nが偶数かどうかbooleanで判定するメソッド」IsEvenを代入することができます。


でも、代入できるはIsEvenだけではありません。同じように奇数かどうか調べるメソッドとか、5の倍数かを調べるメソッドも同じように代入することができるわけです。


つまり、デリゲートに代入するメソッドを変更することで、さまざまな条件で要素数をカウントできるようになりました。
逆に、デリゲートを使わないと、判定条件ごとにいくつものCountメソッドを作らないといけません。

実際は、これを「匿名メソッド」と「ラムダ式」を使うことでよりスッキリ書くことができます。デリゲートという概念があるから、日頃お世話になってるラムダ式が使えるということだと理解しています。

## 名前から考える「デリゲート」
わたしは何か新しい概念を学ぶときに、その概念の名前や語源を結構意識します。その名前の由来や語源がピンとこないとあまり頭に入ってきません。

「deligate」の単語の意味としては[「代表者、代理人」](https://www.weblio.jp/content/Deligate)があります。よく「委譲する、委任する」の動詞で解説されますが、わたしは「代表者、代理人」の訳のほうがしっくりきました。推測ですが、処理自体は参照先の実際のメソッド（例でいうと、isEven）が担っており、あくまでデリゲート自体は代表者である。というニュアンスだと思っています。

## 参考文献
- [『実戦で役立つ C#プログラミングのイディオム/定石&パターン』](https://www.amazon.co.jp/dp/B06WP7HJ27/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)：実践的かつわかりやすくおせわになっている1冊。C#の基本文法を一通りやったあとにオススメ。

[^1]:なので、「扱っているシステムがレガシーだったから」というよりかは、自分のキャリアに対する危機感から転職に踏み出したという感じです。
[^2]:現状、1番目はジェネリックです。それについてはおいおい…。
[^3]:「関数を格納できる変数」と紹介している記事も結構あった
WindowsServer 2019 でNPS構成時はFWに要注意！

# 2016以下のNPS環境からリプレースされる方へ
NPSのリプレースや冗長化は比較的簡単で元となる設定をエクスポートしてインポートするだけでよいのですが、WindowsServer2019では追加設定が必要になります。

# FW例外登録しているのにDROPされる
WindowsServer2019環境でNPSを構築し、設定をインポートしてみたのですが
イベントログなので、一向に認証がされている形跡がありませんでした。
色々調査していると、**FWを無効にすると正常に動作する**ことを確認しました。

しかし、NPSサービスを構成したときにFWにはNPSのポート（UDP 1812、1813、1645、1646）が自動許可されるようになっており、実際FW設定画面でも許可されているルールを確認しました。
にも関わらずDROPのログを取得してみると、上記ルールが無視されてDROPされているのです。
なんとも不可解な症状。。と思いながらネット検索していると以下MSのドキュメントがヒットしました。
https://docs.microsoft.com/ja-jp/windows-server/networking/technologies/nps/nps-firewalls-configure

 上記ドキュメントにまさに今回のDROPされる注意が記載されていました。

> Server 2019 では、このファイアウォールの例外は、RADIUS トラフィックを効果的に検出して許可するために、サービス アカウントのセキュリティ識別子を変更する必要があります。 このセキュリティ識別子の変更が実行されない場合、ファイアウォールは RADIUS トラフィックをドロップします。 管理者特権でのコマンド プロンプトから、sc sidtype IAS unrestricted を実行します。 このコマンドは、IAS (RADIUS) サービスが他の NETWORK SERVICE サービスと共有するのではなく、固有の SID を使うように変更します。

OSのバージョンが変わるときはちゃんとドキュメントを読むようにしましょう😊
【Cloud Run】 デプロイするために必要なパーミッション（GCP）

# 背景

Cloud Run にデプロイするために必要なパーミッションが↓に書かれていますが、それでは十分ではなかったので、覚書です。

https://cloud.google.com/run/docs/reference/iam/roles#additional-configuration

※`--execution-environment=gen2` を利用する必要があったため、2022-06-20現在 `gcloud beta run deploy` を利用しています（`beta` の指定が必要）。

```shell
// コマンド例
gcloud beta run deploy ${APP_NAME} --source . \
  --execution-environment=gen2 \
  --no-allow-unauthenticated \
  --service-account=${SERVICE_ACCOUNT} \
  --http-timeout=${HTTP_TIMEOUT}
```

# 上記ドキュメントに記載された内容

以下を、デプロイを実行する（= `gcloud beta run deploy`を実行する）ユーザに付与する。

- `roles/run.admin` (Cloud Run Admin)
- デプロイ時に、`--service-account` で指定するサービスアカウントの `Service Account User` ロール
  - 具体的な方法は、ドキュメントの `To assign the IAM Service Account User role on the Cloud Run runtime service account:` 以降の手順を参照
 
# 上記以外に必要だったロール

## 必要なロール（とそれが欠けていた時に出るエラー）

- Artifact Registry Reader
```
ERROR: Permission denied while accessing Artifact Registry. Artifact Registry access is required to deploy from source.
ERROR: (gcloud.beta.run.deploy) PERMISSION_DENIED: Permission 'artifactregistry.repositories.get' denied on resource '//artifactregistry.googleapis.com/projects/<project>/locations/asia-northeast1/repositories/cloud-run-source-deploy' (or it may not exist).
- '@type': type.googleapis.com/google.rpc.ErrorInfo
  domain: artifactregistry.googleapis.com
  metadata:
    permission: artifactregistry.repositories.get
    resource: projects/<project>/locations/asia-northeast1/repositories/cloud-run-source-deploy
  reason: IAM_PERMISSION_DENIED
```
- Cloud Build Editor
```
// at the "Building Container" phase
ERROR: (gcloud.beta.run.deploy) PERMISSION_DENIED: The caller does not have permission.
```

- Service Usage Consumer
```
// at the "Building Container" phase
ERROR: (gcloud.beta.run.deploy) PERMISSION_DENIED: Caller does not have required permission to use project <your_project>. Grant the caller the roles/serviceusage.serviceUsageConsumer role, or a custom role with the serviceusage.services.use permission, by visiting https://console.developers.google.com/iam-admin/iam/project?project=<your_project> and then retry. Propagation of the new permission may take a few minutes.
```
- Storage Admin
```
ERROR: (gcloud.beta.run.deploy) The user is forbidden from accessing the bucket [<project_name>_cloudbuild]. Please check your organization's policy or if the user has the "serviceusage.services.use" permission
```

## エラー例 
2番目のフェーズの `Building Container` でエラーが発生した例。
```shell
Building using Dockerfile and deploying container to Cloud Run service [<server_name>] in project [<project_name>] region [<region>]
X Building and deploying... Building Container.
  ✓ Uploading sources...
  - Building Container... Logs are available at [https://console.cloud.google.com/cloud-build/builds/xxxxx].
  . Creating Revision...
  . Routing traffic...
  . Setting IAM Policy...
Deployment failed
ERROR: (gcloud.beta.run.deploy) PERMISSION_DENIED: The caller does not have permission
```
【Nuxt.js】Nuxt.jsでJSONファイル表示

JSONにミスがあると上手く表示されないため、
以下のような調節チェックツールでJSONファイルのチェックを行ってください。
https://tools.m-bsys.com/development_tooles/json-beautifier.php

axiosをインストールしてください。
axiosのインストールは<a href="https://qiita.com/misaki_soeda/items/091058a70c448f744dbd" target="_blank">こちら</a>

# ファイル構造
```
├── static
│　　　　　　└── data
│　　　　　　　　　　└── member.json （JSONファイル）
├── pages
│　　　　　　└── index.vue （表示させたいファイル）
```

```json:member.json
{
  "members": [
    {
      "name": "佐藤さん",
      "hobby": [
        "釣り",
        "ゲーム",
        "アニメ"
      ]
    },
    {
      "name": "山田さん",
      "hobby": [
        "サッカー",
        "ドライブ"
      ]
    }
  ]
}
```

```vuejs:index.vue
<script>
export default {
  async asyncData({ $axios }) {
    const res = await $axios.$get('/data/member.json');
    return {
      members: res.members
    }
  }
}
</script>
```

あとは表示させたいところに表示させるだけです。
今回は配列も作成したため、配列の箇所は<b>v-for</b>を使用していきます。

```vue:index.vue
<section v-for="member in members" :key="member.id">
	<h2>{{ member.name }}</h2>
	<ul>
		<li v-for="hobby in member.hobby" :key="hobby.item">{{ hobby }}</li>
	</ul>
</section>
```
【Nuxt.js】axiosをインストール

# axiosとは
HTTP通信を簡単に行うことができる <b>JavaScriptライブラリ</b>。

以下でインストールしてください。
個人的にはyarnを推奨しております。

yarn
```
yarn add @nuxtjs/axios
```

npm
```
npm install --save @nuxtjs/axios
```

## nuxt.config.js の 「modules」 に追記
```javascript:nuxt.config.js
export default {

==略==
 
  // Modules: https://go.nuxtjs.dev/config-modules
  modules: [
    // https://go.nuxtjs.dev/axios
    '@nuxtjs/axios',
  ],

==略==

}
```

こちらでaxiosを使える準備は完了です！
アルゴリズム　選択ソート（昇順）

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h2>説明</h2>
配列から最小値を探し、配列の先頭要素と入れ替えていくことで並べ替える。

```java
public class Main {
	public static void main(String[] args) {
		int[]data = {31, 41, 59, 26, 53, 58, 97, 93, 23, 84};
		System.out.println("並び替え前");
		for (int i = 0;i < data.length;i++) {//data.length:10
			System.out.print(data[i]+ " ");//[0]-[9]を出力
		}
		System.out.println();//改行
		
		 //選択ソート開始
		for (int i = 0; i < data.length - 1;i++) {
			for (int j =i + 1;j < data.length;j++) {
				if(data[i] > data[j]) {//trueなら入替
					int a = data[i];
					data[i] = data[j];
					data[j] = a;
				}
			}
		}
		System.out.println("並び替え後");
		for (int i = 0;i < data.length;i++) {
			System.out.print(data[i]+ " ");
		}
		System.out.println();
	}
}	
```
<h2>プロセスの確認</h2>

![スクリーンショット 2022-06-20 22.15.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2133160/e9ba97f2-6a4a-2957-45ac-017b37179866.png)

![スクリーンショット 2022-06-20 22.15.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2133160/0507fd3c-d61e-0768-d1e0-eca82ad2b16d.png)

![スクリーンショット 2022-06-20 22.15.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2133160/3bf8f68b-6e36-4b1a-87a3-c58450c90098.png)

![スクリーンショット 2022-06-20 22.15.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2133160/b4248f9d-b6b7-8760-e6b2-4096cbfc38e7.png)





</body>
</html>
会社Tech Blog書いた記事集め

自分がFusic Tech Blogに書いた記事の一覧をQiitaに残したいと思いました。

### TerraformでAWS CodePipeline(ECR pushで発火) + CodeBuildを作る
https://tech.fusic.co.jp/posts/2021-12-10-terraform-codepipeline-ecr-source/

### Terraform state mv整理(resourceをmoduleに変えただけなのに何でdestroy!?)
https://tech.fusic.co.jp/posts/2021-10-26-tf-state-mv-1/

### Terraform import整理(AWS Management Consoleでポチポチ作ったものを反映したい)
https://tech.fusic.co.jp/posts/2021-10-12-tf-import-1/

### TerraformでAWS Secrets Managerをいい感じで扱う
https://tech.fusic.co.jp/posts/2021-09-29-tf-secrets-manager1/

### Terraform data整理(AWS account idハードコーディングしたくないなぁ)
https://tech.fusic.co.jp/posts/2021-09-16-tf-data-ref-1/

### Terraform target整理(state listで欲しいリソースを選んでapply)
https://tech.fusic.co.jp/posts/2021-09-07-tf-target-state-list/

### Terraform console整理(これarnありましたっけ? nameとかありましたっけ?)
https://tech.fusic.co.jp/posts/2021-08-25-use-terraform-console/

### AzureのAzure AD tenant、Subscriptions、Resource groups整理
https://tech.fusic.co.jp/posts/2021-08-24-azureadtenant/

### GPS マルチユニット SORACOM Editionを活用してサテライトオフィス鍵管理システム開発に挑む(feat mockmock)
https://tech.fusic.co.jp/posts/2020-03-04-soracom-gps-multiunit/
Firebase SDK とFirebase Admin SDKの違い

ドキュメントやネット記事を読んで、Firebaseを操作するコードが違うと疑問を持ったあなたに送ります。
## そもそも
Firebaseへの操作の仕方は複数あります。

## Firebase SDK 
エンドユーザーがFirebase を操作するために使用するライブラリ
## Firebase Admin SDK
管理者権限でFirebase を操作するために使用するライブラリ

## Firestoreへのアクセスの違い
使用するSDKによって初期化とFirestoreのアクセスの仕方も異なります。

### Firebase SDK（ Web バージョン 9 ）
```
import { initializeApp } from 'firebase/app'
import { getFirestore, collection, query, getDocs} from 'firebase/firestore'

const firebaseConfig = {
  //...
}
const app = initializeApp(firebaseConfig)
const db = getFirestore(app)

const getUsers = async() => {
  const q = query(collection(db,  'users'))
  const usersSnapshot = await getDocs(q)
  usersSnapshot.forEach((doc) => {
    console.log(doc.id, ' => ', doc.data())
  })
}
getUsers()
```

### Firebase Admin SDK（v10）
```
import { initializeApp, cert } from 'firebase-admin/app'
import { getFirestore } from 'firebase-admin/firestore'

const serviceAccountKey = require('../serviceAccountKey.json')
const app =　initializeApp({
  credential: cert(serviceAccountKey)),
  databaseURL: '指定されたURL',
})
const otherFirestore = getFirestore(app)

const getUsers = async () => {
  const usersSnapshot = await otherFirestore.collection('users').get()
  usersSnapshot.forEach((doc) => {
    console.log(doc.id, ' => ', doc.data())
  })
}
getUsers()
```
【#6 エンジニア転職学習】Linux基礎　alias, シェル変数, 環境変数

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

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

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


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

# 本日の学習内容
本日はテキストエディタの基本操作と、Linuxシェルをより使いやすくする設定方法の部分を勉強しました。

* **テキストエディタ基本操作　←Topic!!**
* シェル変数、環境変数
* alias
* bashファイルの編集

# テキストエディタの基本操作
参考書籍ではVimをメインに紹介されていました。
vim専用のコマンド入力が行える「***ノーマルモード***」と文字入力が行える「**インサートモード**」を切り替えながら編集していくテキストエディタのようです。

たまにインサートモードに入って、コマンド実行ができなくなってしまうのでその時はEscキーを押して解除する。

コマンドもLinux同様豊富にあり、ヤンクやデリートもカーソルキーと合わせて実行していくようです。

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

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の基本を進めていこうと思います。
アドバイス・応援コメント等いただけますと幸いです。
よく使うGitコマンド

> 自分用メモ

## ローカルの差分内容が正しいのでリモートに上書きしたいのにエラーが出る場合
```
git push -f origin hoge
-f はforce（強制）オプション
```
## リモートの差分内容が正しいので、 ローカルに上書きしたいのにエラーが出る場合
```
git fetch origin hoge
＝リモートの当該ブランチの内容を取ってくる

git reset --hard origin/hoge
# reset(取り消し=上書き)
# --hard(最新という意味)
# リモートにある当該ブランチの最新状態でローカルを塗りつぶす（わりと強力なコマンド。一回実行すると取り消せない。取扱い注意。どのブランチのどのバージョンを持ってくるかちゃんと確認する）
```
- 参考
	- [www-creators.com/archives/1097](www-creators.com/archives/1097)

## 間違えてコミットまでしてしまったとき、そのコミットを取り消したいとき
```
$ git reset --soft HEAD^
```
## これまでのコミットログ履歴を一時的に確認したいとき
```
$ git log　# どのバージョンを見たいかコミットログのSHA値（ada25....）を確認する
> commit qwertyuiopasdfghjklzxcvbnm
> Merge: aaa111 bbb222
> Author: hoge tarou
> Date:   Tue Jun 20 18:53:25 2022 +0900

$ git switch -d qwertyuiopasdfghjklzxcvbnm  # 一時的に見たいコミットログを指定する
> HEAD is now at qwertyu CDKの修正

# 特定のコミットログまで戻したい場合は
git reset --hard ハッシュ値
```

## 強制的にgit pullをしてローカルの内容をリモートの内容で書き換えたい
- [https://hrroct.hatenablog.com/entry/2020/11/04/203109](https://hrroct.hatenablog.com/entry/2020/11/04/203109)
- `結論だけ書くと対象をmasterブランチとします。 ローカルの修正は消えますので、要注意です。`

```
# masterブランチにチェックアウト
git checkout master

# リモートの最新の状態を取り込む
git fetch origin master

# リセットする
git reset --hard origin/master
```
```
# もし既にmasterブランチにいて、git pullやgit mergeによりコンフリクトを起こしてたら…
# merge処理の取り消しを行う
git merge --abort

# リモートの最新の状態を取り込む
git fetch origin master

# リセットする
git reset --hard origin/master
```

## 特定のcommitまで戻り、リモートへ強制pushしたいとき
- [https://naomi-homma.hatenablog.com/entry/2020/08/09/120602](https://naomi-homma.hatenablog.com/entry/2020/08/09/120602)

```
# ①戻りたいcommitのハッシュ値を調べる
git log //ハッシュ値を調べる
上記コマンドを打つとコミット毎に以下のような表示が出てきます。
commit ************************ //ハッシュ値

# ②特定のcommitまで戻る
git reset --hard ハッシュ値

# ③戻した結果をリモートへ強制push
git push -f origin ハッシュ値:master
	-f オプションで強制的にpushしています。
で、
$ git reset --hard zxcvbnmasdfghjqwertyu
```

## タイポのままpushまでしてしまったコミットメッセージを修正したい
- [https://qumeru.com/magazine/510](https://qumeru.com/magazine/510)
```
git commit --amend -m "修正後のコミットメッセージ"
git push --force origin ブランチ名
```

## 逆マージの場合
- source(masterとかdevとか)とtarget(feature/hogeとか)ブランチ両方で手元で
```
$ git pull 
```
- targetブランチで
```
$ git merge dev
```
```
<<<<<<<HEAD(Current Change) と >>>>>>>dev-env(Incoming Change)

#上記がvscode上に表示されるので取り込みたい差分を選択すれば良い
```
【Rails】【MySQL】Mysql2::Error: Specified key was too long; max key length is 767 bytes

昨日分の記事を投稿し忘れていました。こんばんは。今日はテックキャンプ現役受講生のアプリ開発Day４です。トップページのレイアウト作成とdevise導入をしていました。そこで遭遇したエラーについて概要と解決方法について紹介します。


# Caused by:Mysql2::Error: Specified key was too long; max key length is 767 bytes
railsでdeviseのマイグレートファイルをマイグレートしようとしたときに出てきたエラーです。エラー内容を要約すると、「mysql2では767バイトのデータしか登録できないのに、deviseで作ろうとしたキー（カラムのこと？）は許容量をオーバーしてます。」というものです。一応エラーが出てきた経緯を記述した上で、解決方法を最後に記入しています。
# エラーが出るまでの経緯

①まずはアプリケーションとDBを準備します。
```ruby:ターミナル
rails _6.0.0_ new sample -d mysql
rails db:create 
```
②次にdevise導入のために、Gemfileに以下を記述します
```ruby:Gemfile
gem 'devise'
```
③Gemを他のGemと整合性を合わせてインストールします
```ruby:ターミナル
bundle install
```
④deviseをインストールし、マイグレーションファイルを作成します。
```ruby:ターミナル
rails g devise:install
```
⑤ユーザー登録機能を作成するためのdeviseを生成します
```ruby:ターミナル
rails g devise user    
```
⑥以下の写真のように、今回はnicknameカラムを追加します（今回のエラーとはあまり関係ないかも）。
![スクリーンショット 2022-06-19 21.56.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707093/a83ba800-ae0e-93c9-54e6-b1e631db4b5a.png)
⑦最後にマイグレートします。
```ruby:ターミナル
rails db:migrate
```
⑧エラー発生！
# エラー発生の原因
mysqlにデータを登録する際の文字コードが原因になります。railsではデフォルトでの文字コードがutf8mb4となっています。この文字コードのデータ量が、mysqlで受け取れるデータ量を超えてしまうために今回のエラーが発生します。従って、今回はdatebaseに登録される文字コードをよりデータ量の少ない「utf8」に変更して、エラーを解決します。
# 解決方法
①config/database.ymlの「encoding: utf8mb4」の部分を「encoding: utf8」と変更します。
![スクリーンショット 2022-06-19 22.38.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707093/d81ca5f5-a909-6278-ad3b-329ad312b8b7.png)
②DBをリセットします（※）。
```ruby:ターミナル
rails db:migrate:reset 
```
③エラー解決です。



※②でrails db:migrateすると、「Mysql2::Error: Table 'users' already exists」とエラーが出るかもしれません。これはタイトルのエラーが出ながらも、テーブルが既に作成されているためです。手っ取り早く「rails db:migrate:reset」を利用しましたが、データを消したくない場合は別の手順を踏んでください。
# 参考サイト
https://qiita.com/terufumi1122/items/9ea764618eba01144e09

https://penpen-dev.com/blog/mysql-utf8-utf8mb4/
AWS CLI でS3バケットを扱う

> よく忘れるので自分のためのメモ

## CLIの準備
```
$ aws configure
```

## AWS S3の設定をする
- コンソールから以下を入力し、100MB以上のアップロードする場合は自動でマルチパートアップロードになるよう設定（AWSの推奨らしい）
```
$ aws configure set default.s3.multipart_threshold 100MB
```
- ダウンロードする
```
$ aws s3 cp  s3:/hoge-bucket/{ダウンロードしたいファイル} {ダウンロード先パス}
```
- 再帰的
```
$ aws s3 cp s3://hoge-bucket/{フォルダ名} {ダウンロード先パス} --recursive
```
- アップロード
```
$ cd {アップロードファイルパス}
$ aws s3 cp {アップロードファイルパス} s3://hoge-bucket/
```
- フォルダごとアップロードする場合はオプション --recursive をつけて再帰的にアップロードする
```
$ aws s3 cp {フォルダパス} s3://hoge-bucket/ --recursive
```
-  アップロードの確認は以下のコマンドまたは、Web上から確認出来る
```
aws s3 ls s3://hoge-bucket/
```
[Python] [EXCEL] 結合セルをdataframeに読み込んで、欠損値の各行に値を入れる　☆便利☆

エクセルで複数のセルが結合されているものを読み込む時と、先頭の行のみに
値が入り、他はNaTになってしまいます。
（このような結合されたエクセル）
![スクリーンショット 2022-06-20 174854.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823476/aa33b5d5-cdc2-89d4-8643-b8ab3f104dfe.png)

Pandasで読み込むと・・
```python
import pandas as pd
df=pd.read_excel('MergedCellTable.xlsx') #　上のファイル名です
```
![スクリーンショット 2022-06-20 181608.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823476/d554f65a-654d-85b0-21a5-a00b63746755.png)
そこで、結合されていた列に対してmethod='ffill'でfillnaします。
```python
df['Date']=df['Date'].fillna(method='ffill')
df['City']=df['City'].fillna(method='ffill')
```
![スクリーンショット 2022-06-20 181837.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823476/7615d898-a0a4-5fd0-ac13-b2e263965806.png)
エクセルデータ取り込み時のデータの前処理に便利です！
6.11 (標準) 最尤推定5，推定量の評価4，デルタ法2

## 方針

(1)はパラメータpを変換して新しくできたパラメータthetaの最尤推定量と不偏推定量を求める問題．
まずpの最尤推定量を求めてから，それを変換すればthetaの最尤推定量になる．不偏推定量はE[X]=p, Var(X)=np(1-p)よりXとX^2の項から成ることは明らかなので，係数をa,bとおいて連立方程式を導く．

(2)は漸近分布が一致することを示す．デルタ法とスラツキーの定理を利用する．

## 答案

![6. 2周目-26.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1702786/15eeb146-1c73-586c-cbd2-292707466e8c.jpeg)
![6. 2周目-27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1702786/a6c665dd-77bf-775e-d380-19ac21e6c184.jpeg)


## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
【初心者】プログラムを作る材料5つ　その２「OS」

# はじめに
IT歴2ヶ月の初心者プログラマー鹿太郎です。
初心者なりに感じた疑問や分からないことを発信していきたいと思います！

続いては、プログラムを作る材料その２！「OS」について紹介します！

# OSとは
OSとは、コンピュータを動かすためのソフトウェアのことです。

ん？どゆこと？
例を見てみましょう。

・キーボードから文字を入力すると、入力した文字が画面に表示される。
・マウス・タッチパッドなどで画面を操作できる。
・イヤホンを接続すると、イヤホンから音が流れる

これらができなければ困りますね。

つまり、OSはコンピュータにとって脳みそのようなものです。

# OSの役割
そんな、コンピュータの脳みそであるOSの役割は以下の5つです。

・タスク管理
・メモリ管理
・ファイル管理
・周辺機器（デバイス）の管理
・APIの提供

これだけではよくわからないので、一つずつ見ていきましょう！

# タスク管理
CPUなどを利用して、タスク（アプリケーションが要求する処理）を実行管理する機能のことです。

例としては、アプリケーションの実行や、キーボードからの入力などが挙げられます。

また、このタスク管理には、マルチタスクとマルチスレッドの２種類があります。

それぞれ、
・マルチタスク：タスクを並列で処理
・マルチスレッド：タスクを細分化したスレッドを並列で処理
となっています。

# メモリ管理
タスクにメモリを割り当てたり、タスクが終わったメモリの開放などを行う機能のことです。

メモリの開放を行わなければ、値が入ったままになってしまい、メモリリークを起こしてしまいます。

# ファイル管理
名前の通り、コンピュータ上で扱われるファイルをまとめる機能のことです。

これを行うことで、データの破損や不具合などのトラブルにも対処することができます。

# 周辺機器（デバイス）の管理
マウスやキーボードなどの周辺機器とコンピュータをつなぐ架け橋的な機能のことです。

上記の ”OSとは” で示した例は、すべてこの機能の特性を用いています。

# APIの提供
APIは「Application Programming Interface」の略称で、アプリケーション(ソフトウェア)を作るときに利用できる機能と方法をまとめたものです。

そのような、様々なAPIなどのソフトを提供する機能のことです。

#
結論：「OSはコンピュータの脳みそである！」

次回は、プログラムを作る材料5つ　その３「コンパイラ」について紹介します！
ではまた。

参考文献：https://tech-camp.in/note/pickup/1013/
TECH CAMP15日目　~コマンド操作~

# Vimとは
「vim」とは、サーバー上で使用できるテキストエディタです。vimコマンドを用いることで、指定したファイルの編集をターミナルから行うことが可能です。

`:w`	作成・編集したファイルを保存します。
`:q`	vimを終了します。
`:q!`	編集した内容を保存しないでvimを強制終了します。
`:wq`	編集した内容を保存してvimを強制終了します。

__zsh__...ログインシェルと呼ばれプログラムを実行する時に、ユーザーの要求に一番最初に対応する役割を担います。OSがCatalina以降
__bash__...bash」とは、zsh同様、ログインシェルの1つ。OSがMojave以前
なぜインフラストラクチャ層の依存を外側に持っていくといいのかを説明する

## これは何
オニオンアーキテクチャやクリーンアーキテクチャなどでは、インフラストラクチャ層の依存関係を一番外側に持っていくことが多いです。
↓のような感じです。

https://qiita.com/cocoa-maemae/items/e3f2eabbe0877c2af8d0#%E3%82%AA%E3%83%8B%E3%82%AA%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3%E3%81%AE%E9%9A%8E%E5%B1%A4%E6%A7%8B%E9%80%A0

最近「インフラストラクチャ層を外側に持っていく必要性が何かよくわからない」という話を聞いたので、必要性を説明できたらと思います。

## そもそも設計でいうインフラストラクチャとは何を指しているか

「インフラストラクチャ層を一番外側に持っていく」、という言葉を聞いたときに、どういう印象を持ちますか？
僕は初めて聞いたとき「どういうこと？」となりました。
この言葉を聞いたときの僕のインフラのイメージは「サーバー」でした。
つまり、アプリケーションサーバーやDBサーバーなどです。
これを一番外側に持っていく、ってどういうこと！？というのが僕の最初の感想でした。

インフラストラクチャ層が示している「インフラストラクチャ」は正確にいうと、「アプリケーション外のシステムにアクセスするためのコード」のことです。
具体的なものは以下の通りです。

- DBクライアント
- KVSクライアント
- メールクライアント
- APIクライアント
- etc

設計の話をしているときは、インフラストラクチャの名前が出てきたときはそういう認識でいると色々なものが理解しやすいと思います。

## インフラストラクチャ層を一番外側に持っていくとはどういうことか

前項で説明した通り、設計の世界で話すインフラストラクチャとは、「アプリケーション外のシステムにアクセスするためのコード」です。
インフラストラクチャのコードには、たいていアプリケーション層の中で参照する必要があります。
DBへの永続化やメールの送信、APIを叩くなどは、アプリケーション層で行われるためです。
これを愚直に書くと以下のようになると思います。
今回はユーザー一覧を取得する処理を想定します。（ライブラリなどは擬似です）

```rb:ユーザー一覧取得しているコード
def UserRepository
  def find_all
    DBClient.execute(`SELECT * FROM users`)
  end
end

def ApplicationService
  def initialize
    @user_repository = UserRepository.new
  end
  
  def get_users
    @user_respository.find_all
  end
end

def ApplicationController
  def index
    service = ApplicationService.new
    @users = service.get_users
  end
end
```

上のコードだと、`ApplicationService`は`DBClient`に依存しています。つまり依存関係的に`DBClient`は`ApplicationService`の内側に来てしまっています。

そこで、インフラストラクチャである、`DBClient`を依存関係の外側に持っていきます。
使う手法は依存性の注入です。

```rb:ユーザー一覧取得しているコード
def UserRepository
  def find_all
    DBClient.execute(`SELECT * FROM users`)
  end
end

def ApplicationService
  def initialize(user_repository)
    @user_repository = user_repository
  end
  
  def get_users
    @user_respository.find_all
  end
end

def ApplicationController
  def index
    user_repository = UserRepository.new
    service = ApplicationService.new(user_repository)
    @users = service.get_users
  end
end
```

このようにすることで、`ApplicationService`からの`UserRepository`への依存は無くなりました。

## これがなぜ必要なのか？
前項までで、インフラストラクチャとは何か、依存を外側に持っていくとは何かを説明しました。
この項で、今回の記事の目的でもある「なぜいいなのか」を説明していきたいと思います。

簡単にいうと、「アプリケーションコード外のシステムを状況によって変えられるようになるため」です。
状況はおもに以下の二つの条件で変わります。

1. アプリケーション環境の実行環境（production, development, test等）
1. 使うサービス、システムの変更

1について一番わかりやすい例で言うと、テスト時のモックです。テストを行う際は、各テストケースにおいて正しいロジックで動作するかの検証を行うと思います。そこにDBやメーラーなど、アプリケーションコード外のシステムまで絡むとテストで気にしないといけないところが増えてしまいます。インフラストラクチャ層との依存を断ち切り、インフラストラクチャ層のコードをモックすることで、ロジック部分と、インフラコードが正しく動作しているかの検証を分けて行うことができるようになります。

2については、そもそも使っているシステムが変わる場合です。システムが変わればインフラストラクチャ層のコードも大きく変わることは多いとおもいます。このコードが依存の内側に入っていると、アプリケーションはそのままでは簡単には動きそうもありません。
しかし、インフラストラクチャ層を外に出しておき、インターフェースをしっかり作っておければ、インフラストラクチャ層のコードの修正のみに集中することができるようになります。

## まとめ
設計の世界では、変化が少ない（概念に近いコード部分）ものの依存をできるだけ内側に、変化の大きい（具体的なシステムに近いコード部分）の依存を外側に持っていくことで、変更に対して閉じているコードを作ることを目指します。

インフラストラクチャ層を外側に持っていくことの意義をこの記事で感じていただけたら幸いです。
webapck（eslint-webpack-plugin）でESLintが動くというけどタイミングは？

以前、[ところでwebapckでESLintが動くというけどタイミングは？](https://qiita.com/yuta-katayama-23/items/5d73bbe79c19301551df#%E3%81%A8%E3%81%93%E3%82%8D%E3%81%A7webapck%E3%81%A7eslint%E3%81%8C%E5%8B%95%E3%81%8F%E3%81%A8%E3%81%84%E3%81%86%E3%81%91%E3%81%A9%E3%82%BF%E3%82%A4%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AF)において、ESLintが実行されるコードがトランスパイル前なのか後なのかについて触れていたが、ESLintでparserを指定しているか？否かで動きは変わっているというのが正確な所だと思われる。

つまり、ESLintは基本的には何も`parser`や`parserOptions`を指定しなければデフォルトではコードがES5で書かれたものとして構文チェックを行い、その構文チェックの際には特にコードのパース（変換）は行わない（以下、[公式](https://eslint.org/docs/user-guide/configuring/language-options#specifying-parser-options)からの引用）。

>  By default, ESLint expects ECMAScript 5 syntax. You can override that setting to enable support for other ECMAScript versions as well as JSX by using parser options.（デフォルトでは、ESLint は ECMAScript 5 の構文を想定しています。パーサオプションを使用すれば、他の ECMAScript バージョンや JSX のサポートを有効にするために、この設定を上書きすることができます）

もし、`parser`や`parserOptions`が指定されていれば、ESLintは構文チェックを行う前にその指定されたパーサーでコードを変換してから構文チェックを行う。ESLintの構文チェックをした結果、エラーがあれば元のコード上で指摘されるが、それは各パーサーが変換前のコード上の位置と変換後のコード上の位置を記録しているからだろう（[@babel/eslint-parser](https://github.com/babel/babel/tree/main/eslint/babel-eslint-parser)に以下のように書かれているので）。

> ESLint allows for the use of custom parsers. When using this plugin, your code is parsed by Babel's parser (using the configuration specified in your Babel configuration file) and the resulting AST is transformed into an ESTree-compliant structure that ESLint can understand. All location info such as line numbers, columns is also retained so you can track down errors with ease.（ESLint はカスタムパーサーを使用することができます。このプラグインを使うとき、あなたのコードはBabelのパーサーによって解析され（Babelの設定ファイルで指定された構成を使って）、結果のASTはESLintが理解できるESTreeに準拠した構造に変換されます。行番号や列のような位置情報もすべて保持されるので、エラーを簡単に追跡することができます。）
React Native の Native Modlues を作るも、今は re-architecture の作業期間中で時期が悪かったというのを共有したい

React Native と聞くと、全てを JavaScript や TypeScript で作っていると思うかもしれませんが、ネイティブ特有の機能を Native Modules として、Swift や Kotlin で作ることができます。今回、久々に Native Modules を作ったら、色々変わっていたのと、一部で開発に詰まってしまったので、共有したいと思います。

## Native Modules を作る

公式ドキュメント [Native Modules NPM Package Setup](https://reactnative.dev/docs/next/native-modules-setup) に従って操作すれば、できます。

```
npx create-react-native-library {作りたいモジュール名}
```

とタイプして対話型 UI で情報を入力したら、雛形が完成します。簡単ですね。これは callstack の [react-native-builder-bob](https://github.com/callstack/react-native-builder-bob) を呼んでいます。

次に `yarn` をすると、必要なライブラリや cocoapods のインストールがされ、開発が開始できます。`src/index.ts` で React Native 側のコードを書いています。そのコードを書き終えると、再び `yarn` すると、TypeScript がトランスコンパイルされてます。

その後は、`example` ファイルの `ios` と `android` のプロジェクトを開き、ネイティブ側のコードを書いています。

一通りの開発が終われば、`GitHub` などに挙げて

```
yarn add https://github.com/****/****.git
```

とタイプすれば Native Modlues を導入できます。また npm に登録すれば、モジュール名で導入できるようになります。

## ここからが本題です

Native Modules の動作確認でクラッシュしないのを確認して、開発プロジェクトに導入したところ、特定の操作でクラッシュしました。なぜだ・・・。

調べたところ、Native Modules の `example` の React Native が 0.63 であり、導入したプロジェクトが 0.68 のため、React-Core が提供する `RCTEventEmitter.m` の [`sendEvent(withName:body:)`](https://github.com/facebook/react-native/blob/main/React/Modules/RCTEventEmitter.m#L49) の内部実装が変更されていました。ネイティブから React Native にイベントを送信するときに、クラッシュしました。

> RCTCallableJSModules is not set. This is probably because you've explicitly synthesized the RCTCallableJSModules in {モジュール名}, even though it's inherited from RCTEventEmitter.

修正対応するため、すぐに Native Modules の `example` の React Native を 0.68 にアップデートしました。0.68 は新しいアーキテクチャに対応するため、多くの変更があるのでアップデートは大変でした。

その後、いろいろと `RCTCallableJSModules` 関連を見ましたが、分からない。残念ながら時間的に今日は諦めました。またの時間に、他の有名どころのライブラリのコードなどを見漁って、調べようと思います。

もし解決法を知っている方がいたら、教えてもらえると幸いです。

## まとめ

React Native は年に数回、とても面倒に感じることがあるのですが、まさに今です。Native Modules の公式ドキュメントにも書いているのですが、今はアーキテクチャの開発期間中の真盛りなので、Native Modules の開発はすこし大変そうです（私の理解力が足りないだけ）。
nodemailerとGmailと2段階認証


2段階認証を使っているGmailのアカウントを使ってnodemailerでメールを送ろうとしたら詰まったので、自分用の備忘録メモ。
## nodemailerでGmailからメールを送りたい
nodemailerでGmailを使ってメールを送る場合はこんな感じのコードでできる。

``` js
const nodemailer = require('nodemailer');

async function sendEmail() {
  const transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
      user: process.env.EMAIL,
      pass: process.env.EMAIL_PASS,
    },
  });

  const mailContents = {
    from: process.env.EMAIL,
    to: process.env.TO_EMAIL,
    subject: 'Test Mail',
    text: 'Hello from nodemailer!',
  };

  await transporter.sendMail(mailContents, function (error, info) {
    if (error) {
      console.log(error);
    } else {
      console.log('Email sent: ' + info.response);
    }
  });
}

sendEmail().catch(console.error);
```

はずなんだけど、エラーが出てしまった。Gmailの認証がうまく行っていないっぽい。

```
Error: Invalid login: 534-5.7.9 Application-specific password required. Learn more at
534 5.7.9  https://support.google.com/mail/?p=InvalidSecondFactor ix19-20020a170902f81300b0016362da9a03sm543170plb.245 - gsmtp
    at SMTPConnection._formatError 
<中略>
  code: 'EAUTH',
  response: '534-5.7.9 Application-specific password required. Learn more at\n' +
    '534 5.7.9  https://support.google.com/mail/?p=InvalidSecondFactor ix19-20020a170902f81300b0016362da9a03sm543170plb.245 - gsmtp',
  responseCode: 534,
  command: 'AUTH PLAIN'
}
```

## 解決法
以下のページからGoogleアカウント上でアプリパスワードなるものを設定して、そのパスワードでログインをすればOK。
https://myaccount.google.com/u/1/apppasswords

> アプリパスワードを使用すると、2 段階認証プロセスに対応していないデバイス上のアプリから Google アカウントにログインできるようになります。

とのこと。

nodemailerのドキュメントに書いてあった。
https://nodemailer.com/usage/using-gmail/
AtCoderで入茶した感想【色変記事】

こんにちは！みちらからと申します！
半年強かけてついに**AtCoder**で**茶色コーダー**になることができたので感想などをつらつらと書いていこうと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611375/592c018f-7d4a-424e-5ac4-4b636dcf0345.png)
レーティングのグラフ
# 2021年12月〜2022年3月頃まで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611375/858e1404-6adc-62d7-9d1c-e0f3c9b2cfd4.png)
↑このへん
**始めてすぐの時です**
AtCoderを始める前からある程度のPythonのプログラムは作れたのでTwitterでAtCoderを見てやってみようかな〜と思い、せっかくなら知らない言語でと参加しようとC++の勉強を始めます。この頃は**A問題**だけ解いて満足していました。(A問題はプログラミングが少しでもできれば誰にでもできるレベル)

:::note
AtCoderの初心者向けの解説＆問題集の**APG4b**にはお世話になりました。ここで一ヶ月ほど勉強してから12月末に初参加をしました。
:::

# 3月〜4月
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611375/d26f5aea-2a4b-3991-87e1-3b38fb8ee143.png)
↑このへん
3月頃に**AtCoder Problems**というAtCoderの問題を一覧で見ることができてどれを解いたかが一目でわかるサイトを知り、**A、B問題**の過去問を解き始めます。めちゃくちゃ簡単な**C問題**なら解けなくもないなってなってきた頃です。
一度**Python**で**AtCoder**に参加したのですが**AB問題を解くのがとても楽**で、**C問題**の計算量のことなどは当時は知らなかったので**基本的にPython**で解くようになります。今もその癖で**C問題**をPythonで**TLE**(実行時間制限超過)するのを繰り返しています。

# 5月〜6月
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611375/94e17ae8-ddcd-6a2c-7d4f-43dd390c3c99.png)
↑このへん
**ここらへんから面白くなってきます**
５月に入ってから始めて**ARC**(AtCoder Regular Contest) に参加し、緑diffのA問題が奇跡的に解けます。それでレートが84も上がってイキっていたら次のARCはA問題は茶色diffなのにACできずにレートは10溶けました。初めてのレート減少だったのでかなりショックでした。さらに次のABCで参加登録したのに参加するのを忘れていてレートが50下がり、ARC初参加で上がったレートがほとんど溶けてしまいます。しかし、そこでめげはしませんでした。逆に僕の闘志に火がついたような感じになり、そこから**AtCoder Problems**で**C問題**を解きまくり始めます。その後はちょっとレートが上がる角度が大きくなり、ついに**6月19日**の**ARC142**で過去最高パフォの**1315**を叩き出して一気にレートが148も上がり、入茶を果たしました！
ちなみに**ARC142**は、かなり**物議を醸したコンテスト**で、具体的にはABC問題は茶、茶、水の妥当な難易度の問題でしたが、**D以降の問題が全て赤diff**というバランスの悪いコンテスト構成、**C問題**で**コーナーケースがシステムテストに含まれていない**問題(まあこれのおかげでC問題解けたので私は気にしませんが)などが話題に上がっていました。

# ギャラリー
**精進グラフ**
最近めちゃくちゃ伸びてるのがわかると思います
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611375/0ce43bb4-20cf-1637-bdc4-e03d89bdfc0a.png)
**AtCoder Problemsのいろいろ**
 ↓はAchievement
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611375/7bd52222-e96e-da53-1a32-7657b83b1550.png)
↓ABCのA~C問題をたくさん解いてました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611375/9e9e1191-3c27-f329-23b2-0b7f32b84c35.png)
↓たくさん問題を解く日とそうでない日がありましたが最近は毎日少しずつやってます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611375/c43e4863-8328-2181-493d-7020dee970d8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611375/15f1ca06-fa13-fa67-77eb-40fffb4dde2d.png)
↓茶や緑diffの問題はまだ難しいですね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611375/fa2fde9d-4b0e-23a5-19cc-142f40acd3c2.png)

# おわりに
AtCoderでレーティングの色が変わった記念として書き始めたこの記事ですが、書いているうちに色々なことを思い出してあ〜こんなこともあったな〜などの気付きがたくさんあったので書いていて楽しかったです。これからはレーティングを上げるのは大変になってくるとは思いますが精進しまくって来年くらいには水色コーダーになりたいなーと思っています。初めて書いた記事なので色々と読みにくいところもあったと思いますが、この記事を読んで頂きありがとうございました。それではまた次の記事で！さようなら！

# 参考文献
[AtCoder](https://atcoder.jp/)
[AtCoder Problems](https://kenkoooo.com/atcoder/#/table/)
React （GraphQL + Tailwind CSS）の構成でアプリを作成しました【Pokemon Application】

## 環境の準備

①ターミナルでreactアプリケーションを作成する。

```
$ npx create-react-app <プロジェクト名>
$ cd <プロジェクト名>
$ npm start
```

② 必要なパッケージをインストールする。

公式サイト:[Tailwind CSS](https://tailwindcss.com/)

```
$ npm install -D tailwindcss postcss autoprefixer
$ npx tailwindcss init -p
```

```
$ yarn add @apollo/react-hooks
$ yarn add apollo-boost
$ yarn add graphql
$ yarn add graphql-tag
```

## コンポーネント・ファイル構成

```
 src
  ├─ components
  ├─ comtainer
  ├─ graphql
       ├── DetailCard.js
       ├── Header.js
       └── SummaryCard.js
  ├── App.js
  ├── index.css
  └── index.js
 ├── .env
 ├── craco.config.js
 ├── tailwind.config.js
```


## 参考サイト
[Build a Pokemon App | React & GraphQL Tutorial | React Tutorial 2020](https://www.youtube.com/watch?v=yKFoAF7J0mc)
GeolocationAPIが止まらなくて困った話

# やりたかったこと
Vue.jsでGeolocationAPIを使って現在地を取得したい。
## 実行環境
Laravel：7.20.0
Vue.js：3.2.37
docker:3
# 初期のコード
```vuejs:LocationSerach.vue
<script>
export default {
    methods: {
        getCurrentLocation: function () {
            console.log("処理開始");
            return navigator.geolocation.getCurrentPosition((position) => {
                console.log("処理中だよ！");
                let coords = position.coords;
                let current = {
                    latitude: coords.latitude,
                    longitude: coords.longitude,
                };
                console.log("処理終了");
            });
        },
    },
    mounted() {
        let currentLocation = this.getCurrentLocation();
        console.log(currentLocation);
        console.log("処理終わってる？");
    },
};
</script>
```
```
# 期待する結果
処理開始
処理中だよ！
処理終了
{latitude: xxx, longitude: yyy}
処理終わってる？
```
実際の結果↓
![スクリーンショット 2022-06-20 19.38.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550050/3594ddb2-bc7b-1f23-b9a7-277e218edf75.png)
実行結果から、関数の処理より先にログ出力の処理がされている。
# 何が起こっているのか？
どうやら、navigator.geolocation.getCurrentPositionは非同期処理で動いているようです。
geoloctionAPIの使い方についての記事を調べると、この関数をそのまま使っている記事もあったので、もしかしてVue.jsで使うと挙動が違うのかな？
と思いましたが、codePenで挙動を確認したところそんなことはありませんでした。
![スクリーンショット 2022-06-20 20.24.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550050/dbe14fd8-367c-77a2-cf8f-fdd2d7d2f98f.png)
# 完成形
async/awaitで処理を待ってもらうように実装しました。
mountedにasyncをつけられるのがわからず、無名関数をでやろうとして詰まってました（汗
```vuejs:LocationSerach.vue
<script>
export default {
    methods: {
        getCurrentLocation: function () {
            return await new Promise((resolve, reject) => {
                navigator.geolocation.getCurrentPosition((position) => {
                    let coords = position.coords;
                    let current = {
                        latitude: coords.latitude,
                        longitude: coords.longitude,
                    };
                    resolve(current);
                });
            });
        },
    },
    async mounted() {
        let currentLocation = await this.getCurrentLocation();
        console.log(currentLocation);
    },
};
</script>
```

# 最後に
今回Promiseやasync/awaitを使ったのが初めてだったので、書き方が拙いところがあるかもしらません。
もし、同じように悩んでいる方が居たら少しでも助けになればと思います。
# 参考
https://ja.stackoverflow.com/questions/63728/javascirpt-async-await%E3%82%92%E7%94%A8%E3%81%84%E3%81%9F%E9%9D%9E%E5%90%8C%E6%9C%9F%E5%87%A6%E7%90%86%E3%81%AE%E5%88%B6%E5%BE%A1%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6

https://techblg.app/articles/how-to-fetch-data-and-set-data-vuejs/

https://qiita.com/NT1123/items/d1051d360e1b1f9174ab
ec2ssmが便利だと思う

## ec2ssmが便利だと思う
某所でやっつけでつくったec2のNameタグをタブ補完してssmログインするツールを、引数にprofileを指定できるようにして汎用性をもたせました。
ssmの設定については、このあたりの記事を参照。

https://zenn.dev/t_morooka/articles/eb98e6a5c9a493

ec2ssmはこちら。
https://github.com/yuhiwa/ec2ssm

ssm自体の説明は他にまかせます。
ec2ssmは```ec2ssm Nameタグ```でec2にログインできるaws cli(aws ssm)のラッパーです。


### 使い方

#### 1. Nameタグをインスタンスに設定する
分かりやすい名前をインスタンスのNameタグに設定しましょう。

#### 2. ~/.aws/credentialsに記載する
```
# ~/.aws/credentials

[default]
aws_access_key_id=...
aws_secret_access_key=...

[myprofile]
aws_access_key_id=...
aws_secret_access_key=...
```
#### 3. ec2ssmをインストールする
```
# cd ~
# git clone https://github.com/yuhiwa/ec2ssm.git
# cd ec2ssm
```

#### 4. awscliとssmプラグインをインストールする
```
# sudo pip3 install --upgrade awscli
# curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip"
# unzip sessionmanager-bundle.zip
# sudo python3 sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin
# sudo pip3 install boto3 pexpect
```

#### 5.zsh設定を編集する
~/.zshrc.localに以下を追記する
```
function ec2ssm { ~/ec2ssm/ec2ssm.py $1 $2 $3 }
function _ec2ssm { compadd $(cat ~/.aws_instances*) }
compdef _ec2ssm ec2ssm
```

#### 6. Nameタグとインスタンスの情報を取得する
プロファイルごとにNameタグとインスタンス情報を取得する
```
ec2ssm update
ec2ssm update --profile myprofile
```

#### 7. ec2ssmでssmログインする
```
ec2ssm test-ec2-01
ec2ssm my-ec2-01 --profile myprofile
```
意識が低いツールなので、第一引き数がupdateとNameタグの両方を兼ねている...

#### 8. 環境変数にログインユーザとパスワードをセットすると自動で入力してくれる
```
export EC2USER=hoge
export EC2PASSWORD=password
ec2ssm test-ec2-01
```
ssmログインして、hogeユーザでログインできれば終了です！
ec2ssmスペース入力後、Nameタグ名はzsh補完がききます。

#### まとめ
全体の構成が以下の記事が読みやすかったので、参考にさせていただきました。
https://zenn.dev/koya/articles/0ee9ccc0561059
ec2sshが有名だったので、こちらも参考にさせていただきました。
https://github.com/mirakui/ec2ssh
WinScpをバッチで自動化

# 本記事で出来るようになること
LinuxサーバからWinScpを使用して、ファイルの移動ができるようになる
1. バッチファイルでWinScpを起動する
1. 処理を記載したテキストファイルを読み込み実行する

# 環境
VMwareでLinuxサーバを立てています。
* Windows 10
* WinScp
* Linuxサーバ(CentOS7)

以下のことが実行できるバッチファイルを作成する。
Windows10内にバッチファイルを作成する。
作成したバッチファイルを実行すると、Linuxサーバから特定のファイルをWindows10の特定のフォルダに移動する。


# バッチファイル作成
```bat:WinScp.bat
@echo off

:: WinSCP.comのパス
"C:\<パス>\WinSCP\WinSCP.com" /script=.\WinScp_content.txt

pause
```

WinScp.batと同じ階層に以下WinScp_content.txtを作成してください。
```text:WinScp_content.txt
# Linuxサーバに接続をする
open ユーザ名:パスワード@xx.xx.xx.xx
# 例：open root:PassW0rd@192.168.0.1

# バイナリ転送モード
option transfer binary

# 確認メッセージの無視
option confirm off

# Linuxサーバ → Windows（フォルダでも可）
get /<Linuxサーバのパス>/ファイル名 "C:\<Windowsのパス>\"

# Windows → Linuxサーバ（フォルダでも可）
put "C:\<Windowsのパス>\ファイル名" /<Linuxサーバのパス>/ファイル名

# Linuxサーバ のファイル削除
rm /<Linuxサーバのパス>/ファイル名

# 日付
echo %TIMESTAMP#yyyymmdd%

# コネクション 切断
close

# ログアウト
exit
```

# その他操作
|コマンド|操作側|説明|
|:-------|:---|:---|
|cd      |Linuxサーバ|ディレクトリ移動|
|chmod    |Linuxサーバ|ファイル権限変更|
|cp       |Linuxサーバ|ファイル複製|
|ls       |Linuxサーバ|ディレクトリ内表示|
|mkdir    |Linuxサーバ|ディレクトリ作成|
|mv       |Linuxサーバ|ファイルを移動・名前変更|
|pwd      |Linuxサーバ|ディレクトリ表示|
|rmdir    |Linuxサーバ|ディレクトリ削除|
|echo     ||メッセージ表示|
|lcd      |Windows|ディレクトリ移動|
|lls      |Windows|ディレクトリ内表示|
|lpwd     |Windows|ディレクトリ表示|
|synchronize |LinuxサーバとWindows|ディレクトリ同期|

# まとめ
`Linuxサーバ　→　WinScp　→　Windows`を実現させるには２つのファイルが必要です。
* バッチファイル（.bat） = WinScpを起動
* テキストファイル（.txt） = WinScpで実行する内容

# ＋α
* コマンドプロンプトを表示させないで実行する方法

https://qiita.com/Tetsu_K/items/f4af2e26b2d16bc6fe1f
マルウェア解析ソフトの使い方

書かなくても覚えていたが，最近はすぐに忘れて困るのでメモすることにした。

# x64dbgの使い方

### system breakpoint のチェックを外す

### ASLRの無効化
CFF explorer　>　Optional Header > Click here で `DLL can move` のチェックを外し保存

### エクセプションでブレークしないようにする
Options  >  Preferences  >  Exceptions 
00000000 - FFFFFFFF を選択し， `Do not break` を選択 

### アドレスへの移動
ctrl + g

### EIPに戻る
`*` (アスタリスク)

### 直前のinstructionに戻る
`-` （ハイフン）

### OllyDbgの `検索 バイナリ文字列 B` と同等の検索
OllyDbgのようにはじめからダンプ画面にdataセクションが表示されていない。
よって，ダンプ1～5タブにdataセクションを表示させた上で，パターンを検索する。

### アセンブリ命令の書き換え
書き換えたいところで space キー

### APIへのブレークポイントの設定
Command:に `bp WriteProcessMemory`

### Callスタックを使ったAPIのぬけ方
`Call Stack`タブ
一番上をクリック
右クリックして `Follow To` を選択
リターンアドレスに移動するので，F2でBPを設定

### WriteProcessMemoryで書いた悪性コードの抜き方
`bp WriteProcessMemory`
Callスタックを使って，APIをぬける
レジスタウィンドウの下の `Default`ウインドウの第１引数( esp+4 )を右クリックして `Follow in Dump`
`Dump`ウィンドウで右クリックして　`Follow in Memory Map`
該当行で右クリックし，`Dump Memory to File`

### スタックの値が再び参照されたときにブレークさせる
スタックで右クリック
ハードウェアブレークポイントを設定する
Hardware Access Dword (x32dbgの場合)
※この機能は、Ollydbgにはない。

### マシン語の検索
例えば
push 0
push 0
push 11
push esi
を検索する場合
CPUで右クリック > Search for > Current Module > putten (Ctrl+Shift+B)
hexに　6A006A006A1156を入力
# Ghidra の使い方

### Analysis Options
WindowsPE x86 にチェックを

### 指定アドレスにジャンプ
`G` キー

# IDA の使い方

### xor をやっているところを検索する
双眼鏡Tアイコン（Search for text）で，xorを検索する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/cacf30ec-b4eb-7214-2d02-c17bab083136.png)
Rubyの問題を解いて知識を深める。⑤

# はじめに
今日も問題を解いていきます！
この問題集も、今日を含め残り3日！！

# Q21　簡単な計算を行うRubyプログラムの作成
二桁以上の整数を入力すると、十の位と一の位の数字の足し算、十の位と一の位の数字の掛け算をそれぞれ行い、最後に2つの結果を足し合わせて出力するプログラムをRubyで作成。
ターミナルでの入力例
```
> 二桁の整数を入力してください
> 15

# 1 + 5 と 1 × 5 をそれぞれ計算

> 足し算結果と掛け算結果の合計値は11です
```
解答
```ruby
def addition(a, b)
  a + b
end

def multiplication(a, b)
  a * b
end

def slice_num(num)
  # 10の位
  tens_place = (num / 10) % 10
  # 1の位
  ones_place = num % 10
  return tens_place, ones_place
end

puts "二桁の整数を入力してください"
input = gets.to_i
X, Y = slice_num(input)
add_result = addition(X, Y)
multiple_result = multiplication(X, Y)
puts "足し算結果と掛け算結果の合計値は#{add_result + multiple_result}です"
```
今までの問題に比べて一気に複雑化してきた印象。
ポイントはRubyの性質上、整数同士（integer型）の計算だと返り値は整数になるので、小数点以下は切り捨てられること。
また、カンマで区切ることで複数の変数を定義しているという点。X, Y に10の位、1の位を同時に代入している。

# Q22 if,else問題
以下の仕様を満たすメソッドnumを作成。
- メソッドの実引数として「1以上の正の整数」を3つ用意し、それぞれを仮引数a,b,c としてnumメソッド内で使用する
- 第一引数と第二引数は足し算をし、変数abに代入する
- 第三引数が3以下の場合は変数abを第三引数の値で割り、結果を出力する
- 第三引数が4以上の場合は変数abを第三引数の値で掛け、結果を出力する
雛形
```ruby
def num(a, b, c)
  # ここに条件式を実装する
end

# 呼び出し例
num(1,5,3) 
num(1,5,5)
```
出力例
num(1,5,3) → 2
num(1,5,5) → 30
解答
```ruby
def num(a, b, c)
 ab = a + b
if c <= 3
 puts ab / c
else
 puts ab * c 
end

# 呼び出し例
num(1,5,3) 
num(1,5,5)
```

# Q23 if,else問題
ECサイトのポイント付与サービスを考える。
購入金額が999円以下の場合、3%のポイント
購入金額が1000円以上の場合、5%のポイント
このように付与されるポイントを出力するメソッドを作る。

ただし誕生日の場合はポイントが5倍。
誕生日の場合はtrue, 誕生日でない場合はfalseで表す。
また、小数点以下をすべてのポイント計算が終わったあとに切り捨てる。

呼び出し方：
calculate_points(amount, is_birthday)
出力例：
calculate_points(500, false) → ポイントは15点です
calculate_points(2000, false) → ポイントは100点です
calculate_points(3000, true) → ポイントは750点です
解答
```ruby
def calculate_points(amount, is_birthday)
  if amount <= 999
    point = amount * 0.03
  else
    point = amount * 0.05
  end
  if is_birthday
    point = point * 5
  end
  puts "ポイントは#{point.floor}点です"
end
```
ポイントは.floorメソッドを用いること。
.floorメソッドは小数点の切り捨てに使う。
```
irb(main):001:0> 3.1.floor
=> 3
irb(main):002:0> 3.9.floor
=> 3
```

# Q25 FizzBuzz問題
1〜100までの数字をターミナルに出力。ただし、「3の倍数」のときは数字の代わりに文字列でFizzと、「5の倍数」のときはBuzz、3と5の倍数である「15の倍数」のときはFizzBuzzと出力。
解答
```ruby
def fizz_buzz
  num = 1 #1〜100のため。
  while num <= 100 do　#１００になるまで繰り返す。
    if num % 15 == 0 #3*5=３と5の倍数
      puts "FizzBuzz"
    elsif num % 3 == 0　#３の倍数
      puts "Fizz"
    elsif num % 5 == 0　#5の倍数
      puts "Buzz"
    else
      puts num #数字を出力
    end

    num = num + 1 #数字に1を足す
  end
end

fizz_buzz
```
繰り返しと条件分岐の組み合わせ。この問題は未経験のプログラミングの問題で出る確率が高そう。（あくまで個人的な予想ですが。。）

# 終わりに
if,elseの問題が多いのでかなりなれてきた感じがある。
明日に続く。
「レベル」準同型暗号によるレベルと演算速度の関係

**@kenmaro**です。
普段は主に**秘密計算、準同型暗号などの記事について投稿しています**。
秘密計算に関連するまとめの記事に関しては以下をご覧ください。

> - [秘密計算エンジニアを始めて２年半が経った。](https://qiita.com/kenmaro/items/48059dd60f79e80f5ef8)
> - [秘密計算エンジニアを始めて3年が経った。](https://qiita.com/kenmaro/items/a1d90a074d552b7bf886)


#### 勝手に秘密計算アドベントカレンダーについて

この記事は

https://qiita.com/kenmaro/items/3e8a124ce4306fe040dc

の「4日目」の記事
としようかと思っています。
興味のある方はアドベントカレンダー参加してみませんか？
ご連絡お待ちしております。

## 概要

今回ですが、シンプルに、
**「レベル」準同型暗号（格子暗号）の演算について計算速度を簡単に測定してみようと思います。**


## 「レベル」準同型暗号とは

幾度となく言及してきましたが、マイクロソフトリサーチが開発、メンテナンスしている
マイクロソフト SEALは、BFV形式、BGV形式、CKKS形式の格子暗号が実装されています。

このいずれの形式も、「レベル」準同型暗号と呼ばれます。
英語では、Leveled homomorphic encryption　です。

この「レベル」がどういう意味かというと、乗算の回数を「レベル回」までに限定した準同型暗号という意味です。

例を挙げた方がわかりやすいと思います。
たとえば、暗号状態である計算を実行したいときに、掛け算を２回する必要があります。
その時は、レベル「２」の鍵ペアを生成します。

レベル「２」の鍵を生成すると、この鍵で暗号化された暗号は、２回乗算を行うことが可能です。
それ以上の乗算を実行しようとするとエラーとなります。

このレベルは、理論上いくらでも大きくすることができます。
たとえば、レベル「１０」とすると、暗号化した後に１０回掛け算を行うことが可能な暗号を生成可能です。


## レベルと実行速度の関係
以上の話を聞くと、設定時の「レベル」は大きい方が便利な気がします。
暗号状態で「１回」しか乗算できない「レベル１」の暗号を生成するよりも、
暗号状態で「５回」乗算できる「レベル５」の暗号を生成した方が便利ですよね。

しかし、レベルの大きさは演算速度に大きく影響してしまいます。
基本的には「レベルの大きさ」は実行時間とトレードオフの関係にあります。
レベルが大きい暗号は、生成に時間もかかりますし、乗算などを実行するときにも大きな時間がかかってしまうのです。


## レベル準同型暗号と最適化
以上のことから、準同型暗号（ここでは格子暗号での話です）を用いた演算を実装するときに、以下のプロセスが必要となります。

- どういう計算をするか把握
- 何回乗算が発生するか理解
- 適切な「レベル」を持った暗号パラメータを設定
- 暗号状態での演算を実装

例えば、暗号状態で行いたい演算に、乗算が「２回」含まれているとすると、
生成するべき暗号のレベルは「２」となります。
レベル１の暗号を生成しては計算を最後まで実行できませんし、
レベル２が必要である際に、レベル３の暗号をわざわざ作って実行速度を低下させるメリットはないからです。


## どのくらいレベルによって実行時間が変化するか

ここまでで、準同型暗号（格子暗号）を用いた演算を実装する時は、
演算にどのくらいのレベルが必要なのかについてきちんと把握しておく必要がある、ということを理解していただけたかと思います。

ここでは、実際にレベル１〜6の鍵ペアをSEALライブラリを用いて生成し、それぞれの設定で

- 鍵生成
- 暗号化
- 復号
- 加算
- 乗算
- シリアライズ
- デシリアライズ（シリアライズの逆）

の実行時間について計測してみたいと思います。


### 結果

以下に結果をまとめています。
単位は全て（秒）です。

| レベル | 鍵生成 | 暗号化 | 復号   | 加算   | 乗算   | 回転   | シリアライズ | デシリアライズ | 
| ------ | ------ | ------ | ------ | ------ | ------ | ------ | ------------ | -------------- | 
| 1      | 0.12   | 0.005  | 0.0014 | 0.0003 | 0.0045 | 0.0013 | 0.0008       | 0.001          | 
| 2      | 0.213  | 0.007  | 0.0021 | 0.0004 | 0.007  | 0.0025 | 0.003        | 0.0015         | 
| 3      | 0.72   | 0.020  | 0.006  | 0.0012 | 0.021  | 0.009  | 0.009        | 0.0034         | 
| 4      | 1.04   | 0.023  | 0.0077 | 0.0015 | 0.027  | 0.0125 | 0.012        | 0.0044         | 
| 5      | 1.41   | 0.027  | 0.0096 | 0.0018 | 0.034  | 0.016  | 0.015        | 0.005          | 
| 6      | 1.87   | 0.030  | 0.011  | 0.0021 | 0.041  | 0.022  | 0.017        | 0.0055         | 


先述の通り、レベルの大きな暗号パラメータを使用するにつれて、
各演算の実行速度が増加していることがわかると思います。


ざっくりですが、レベル１からレベル５になると、全ての演算は１０倍程度になるということがわかりました。




## まとめ

今回は、「レベル」準同型暗号の演算について、各演算の実行速度がレベルの変化に伴ってどのように変化するか、
ということについてまとめました。

準同型暗号を用いた演算を考える時は、一度この表を見ることで実行時間の見積りができる可能性がありますので、
ぜひ参考にしてみてください。


今回はこの辺で。


@kenmaro
【Ruby】ブロックについてまとめてみた！

# はじめに
Rubyのブロックについて、勉強したことをまとめました！

# ブロックとは
メソッドに渡せる処理のかたまりのこと

# ブロックと引数の違い
どちらもメソッドに渡すものというのは共通していますが、
+ 引数は「オブジェクト」を渡すもの
+ ブロックは「処理」を渡すもの
になります。



# ブロックの記述方法
下記のように2通りの書き方があります！
```ruby
a = [1,2,3]
# ①　doからendまでがブロック
a.each do |n| #|n|は「ブロックパラメータ」と呼ぶ
    #処理内容をここに書く    
end

# ②　{}内がブロック
a.each { |n| #処理内容をここに書く }
```

# ブロックの機能・挙動・メリットについて
下記の「配列内にある奇数を削除する」コードを用いて説明します！
```ruby:配列内にある奇数を削除する
a = [1,2,3,4,5]
a.delete_if do |i|
    i.odd?
end
puts a #=> 2,4
```
## 前提
上記コードを読む上での前提になります！
+ delete_ifメソッドは、下記の2つの処理を行います。
    1. 配列の中身をひとつずつ繰り返す
    1. ブロックからの戻り値がtrueの場合にその要素を削除する
+ oddメソッド は、奇数であればtrueを、そうでなければfalseを返す

## 挙動
下記を、配列aの要素の数だけ繰り返します。
1. delete_ifメソッドにより、要素の値を取り出し、ブロックに処理が移る
2. ブロックでは、|i|のブロック引数を介して、1.の値を受け取る
3. 受け取った値を用いて、ブロック内のodd?メソッドが行われる
3. oddメソッドがブロック内の最後の式になるため、その評価結果をdelete_ifメソッドに返す
3. delete_ifメソッドは、ブロックから返された値を受け取り、その値がtrueであれば削除を行う

## ブロックの持つ機能
上記のケースを踏まえ、ブロックには大きく二つの機能があることが分かります。
1. 呼び出し元のメソッドから値を受け取り、
1. ブロック内の最後の式の評価結果を、呼び出し元メソッドに返す

## ブロックを使うメリット
今回のケースでは、
1. delete_ifメソッドが持つ機能に対して
1. odd?メソッドを呼び出した
わけですが、この2.部分は、ブロックの機能を使って、他の処理に書き換えてもいいわけです！
つまり、**ブロックを用いれば、「共通処理」と「可変処理」を組み合わせた処理を記述することできるようになります！**

# ブロックを使うケース
ブロックとセットで使用する頻度の多いメソッドとして、下記3点が挙げられます。
1. mapメソッド
1. selectメソッド
1. findメソッド
## mapメソッド
mapメソッドとは、ブロックからの戻り値で、新しい配列を生成するメソッド
例えば下記のコードように、「配列の値を、10倍にして返す処理」を行う場合に使用します。
```ruby:配列の値を、10倍にして返す例
a = [1,2,3,4,5]
b = a.map {|i| i * 10}

p b #=>[10, 20, 30, 40, 50]
```
## selectメソッド
selectメソッドは、ブロックからの戻り値が真の場合のみ、その要素を配列に格納するメソッド
例えば下記のコードのように、「配列から偶数のみ抽出し、新しい配列をつくる」場合などに使用します。
```ruby:配列から偶数のみ抽出し、新しい配列をつくる例
a = [1,2,3,4,5]
b = a.select {|i| i.even? }
p b #=>[2,4]
```
## findメソッド
findメソッドは、ブロックの戻り値が真になった最初の要素を返します。
例えば下記のコードのように、「配列の一番最初の偶数を探す」場合などに使用します。
```ruby:配列の一番最初の偶数を探す
a = [1,2,3,4,5]
b = a.find {|i| i.even? }
p b #=>2
```
# ブロックに渡す配列を簡潔に書く方法
下記のように、ブロックに配列を渡すときは、より簡潔に書くことができます！
```ruby:ブロックに渡す配列を簡潔に書く例
a = [
    [10,20],
    [5,10],
    [10,10],
] 
result = []

#ブロック引数が1つの場合
a.map do |i|
    left = i[0]
    right = i[1]
    result << left * right
end
p result #=> [200,50,100]

#ブロック引数が２つの場合（上記より簡潔になる）
result = []
a.map do |left,right|
    result << left * right
end
p result #=> [200,50,100]
```
## &とシンボルを使って簡潔に書く
下記のコードは、&:メソッド名の書き方をすると、より簡潔に書けるようになる
```ruby:&:メソッド名で書いた例
a = [1,2,3]

a.select{|n| n.odd?}

#上記を「$:メソッド名」で書いた場合
a.select(&:odd?)
```
## &:メソッド名で書くための条件
下記3つの条件を満たす必要があります
1. メソッドを一回呼び出す以外の式がない
1. その式に引数がない
1. ブロック引数が一つだけ

# まとめ
なんとなく使ってたブロックでしたが、意外に奥が深かったです！
間違っている箇所やアドバイスがあれば、是非教えて頂きたいです！