OmniAICreator/Qiita-1.07M huggingface dataset:
【2022年11月版】Linuxでストレージのベンチマーク計測(diskspd)

# はじめに

CrystalDiskMark みたいにストレージのベンチマークを計測したい
CrystalDiskMark の中で使われている diskspd を使おう

# 環境

Ubuntu 22.04.01

# インストール

```terminal
$ sudo apt install -y build-essential libaio1 libaio-dev
$ git clone https://github.com/microsoft/diskspd-for-linux.git
$ cd diskspd-for-linux/
$ make -j4
$ sudo cp ./bin/diskspd /usr/local/bin/
```

# 計測

- SEQ1M Q8T1 READ

```terminal
$ diskspd -c1G -Zr -b1M -d5 -o8 -t1 -W0 -Sd -w0 -L ./SEQ1M_Q8T1.dat
```

- SEQ1M Q8T1 WRITE

```terminal
$ diskspd -Zr -b1M -d5 -o8 -t1 -W0 -Sd -w100 -L ./SEQ1M_Q8T1.dat
```

# さいごに

かんたんでしたね

# 参考情報

とてもありがたい


- [【diskspd】ストレージのベンチマーク方法（Linux版CrystalDiskMarkを作ってみた）](https://hackers-high.com/linux/storage-benchmark-like-crystaldiskmark/)

- [diskspdでストレージパフォーマンスを計測する](https://developers.gmo.jp/12344/)
Astro の打ち上げ 🐋🚀

## 手順

### 1. `docker-compose.yml` を作成

```yml:docker-compose.yml
services:
  node:
    image: node:lts-alpine
    volumes:
      - ./project/:/project/
    working_dir: /project/
    ports:
      - "3000:3000"
    tty: true
    # command: 'npm run dev -- --host 0.0.0.0'

```

### 2. コンテナの起動 🐋

```sh
docker compose up
```

### 3. Astro のインストール

```sh
docker compose exec node npm create astro@latest .
```

実行後、↓ 質問があるので、

```
Need to install the following packages:
  create-astro@1.2.3
Ok to proceed? (y) y

╭─────╮  Houston:
│ ◠ ◡ ◠  I'll be your assistant today.
╰─────╯

 astro   v1.6.10 Launch sequence initiated.

✔ Using . as project directory.
? How would you like to setup your new project? › - Use arrow-keys. Return to submit.
❯   a few best practices (recommended)
    a personal website starter kit
    an empty project✔ Using . as project directory.
✔ How would you like to setup your new project? › a few best practices (recommended)
          ■■▶ Copying project files...(node:79) ExperimentalWarning: The Fetch API is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
✔ Template copied!
✔ Would you like to install npm dependencies? (recommended) … yes
✔ Packages installed!
✔ Would you like to initialize a new git repository? (optional) … no
◼  Sounds good! You can come back and run git init later.

✔ How would you like to setup TypeScript? › Strict
✔ TypeScript settings applied!

  next   Liftoff confirmed. Explore your project!
         Run npm run dev to start the dev server. CTRL+C to stop.
         Add frameworks like react or tailwind using astro add.

         Stuck? Join us at https://astro.build/chat

╭─────╮  Houston:
│ ◠ ◡ ◠  Good luck out there, astronaut!
╰─────╯
```

回答するとインストールが完了する。

### 4. Astro の打ち上げ 🚀

```sh
docker compose exec node npm run dev -- --host 0.0.0.0
```

http://localhost:3000 にアクセスする。

![welcome to astro](https://i.gyazo.com/1db5127d446aa1d563cca1c37403b510.png)

## 参考

- [はじめに 🚀 Astro ドキュメント](https://docs.astro.build/ja/getting-started/#%E6%9C%80%E5%88%9D%E3%81%AE%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E5%A7%8B%E3%82%81%E3%82%8B)
- [astrojs - Astro js site inside docker can not be reached from chrome - Stack Overflow](https://stackoverflow.com/questions/73567964/astro-js-site-inside-docker-can-not-be-reached-from-chrome)
顔面フィルタリングアプリ（あくまで設計だけです。）

# わたしの自己紹介
1社目：テストをする人　350万円
2社目：SE　430万円
3社目：AWSに関わる人　600万円

:::note info
3社目で大きく**年収**が上がりました。
:::
趣味：節約（風呂なし4万5000円、半額弁当生活）
資格：AWS SAA、TOEIC 700点オーバー

# はじめに　マッチングアプリについて
わたしは昨年結婚をしました。
私たち夫婦はマッチングアプリで知り合って結婚まで行きました。

:::note info
マッチングアプリで結婚した人は2022年の現在は5人に1人の割合でお見合いや会社で街コンよりも割合が増えている見たいです。
:::

私はマッチングアプリのペアーズとwithを使っていました。
フィルタリングを活用して、表示数を私自身減らしていました。
フィルタリング機能とは年齢や年収・現在住んでいる場所・子供が欲しいかどうかなどをあらかじめプロフィールで登録している情報から弾くことができます。

# フィルタリングについて
お金持ちや庶民に関わらず時間だけは24時間と平等です。
例えば、専業主婦/主夫になりたい人間は年収500万円以上のパートナーしか表示させないということができます。
結婚相手を選ぶ上で何が大事かというアンケートにおいて〜位にルックスが含まれます。
わたし、「ルックスで相手を見てない」ってやつが大嫌いです。
何故ならば証拠がないからです。
日本人が結婚を行う上で仮面舞踏会で知り合って、ルックスを知らないまま結婚をしたケースは約30年間日本で過ごしていますが、ニュースでも聞いたことがありません。
ルックスを見た上で我々は結婚を決めているからです。
年収を知らないで結婚をするケースは十二分にあるでしょう。
趣味を知らないで結婚をするケースも当然あると思います。
が、ルックスだけは知らないで結婚するケースは存在しません。
が、上述しておりますが、国内でもトップのマッチングアプリサービスにおいて顔面フィルタリングはありません。

全くないかと言われると微妙ですが
グラマー・スリム・普通など体型を自己評価するものがありますが、
グラマーで本当に私が考えているグラマー体型は10人に2,3人しか存在しません。
グラマーというのはBMIがいくつで、胸のサイズがいくつで、という数値化は当然されていないため入力するその人の感性により決められてしまいます。

# 顔面フィルタリングの機能があったら
もしもボックスの世界ではありませんが、機能がある場合、どのようなことが起こるかというと
ぱっちり二重で、髪の毛がロングのストレートでスタイルがいい人しか表記させないということや
逆に一重で歯並びが悪い人間を弾くことができるようになります。
ルックスに点数をつけることはどうかという一部の人間は当然一定数いますが、
私から言わせると無しの人間に時間を使うことの方が双方にとって不幸せです。
無しだとどちらかが思った時点で恋愛は無しになります。


:::note info
ルックスに点数をつけることはどうかという一部の人間は当然一定数いますが、
私から言わせると無しの人間に時間を使うことの方が双方にとって不幸せです。
無しだとどちらかが思った時点で恋愛は無しになります。
:::


## 顔面フィルタリングの設計について
男女共にアンケートを取り、好き嫌いを明確にする。
例えば、目の大きさは顔面の割合に対して目がどれだけの大きさを占めているか
胸の大きさは横向きの写真を撮ることや正面からの膨らみからある程度わかると思います。
もちろん目が極端に大きい場合はプラスではなくマイナスに働くこともあるため目や胸の大きさに関して0点-100点で示すのではなく小さい-大きいという表記にすることでフィルタリングができるかと思います。

## 一番大切なこと
なぜ設計だけなのかというと、わたしには技術力がないということももちろんあるのですが、
こちらの学習をするためには尋常じゃないほどのAIの学習コストがかかること
超人手が必要であること

:::note info
顔面フィルタリングがマッチングアプリに搭載されたとしても活用されない未来しか見えないのであくまでわたしの妄想だけの世界に留めておきます。
:::
DDDがわからない～バインダーしよう～

# 渡すのめんどくさい健康診断
A君は健康診断に来ました。
~~~text:健康診断
1. A君は受付で診療開始時間のメモをもらう。(時間メモ)
2. A君は体重を測ってもらいメモをもらう。(体重メモ)
3. A君は身長を測ってもらいメモをもらう。(身長メモ)
4. A君は視力を測ってもらいメモをもらう。(視力メモ)
5. A君は聴力を測ってもらいメモをもらう。(聴力メモ)
6. A君は体重メモ、身長メモ、視力メモ、
   聴力メモをお医者さんに渡して健康診断の結果をみてもらいました。
~~~
この様に何枚ものメモを渡すのはめんどくさいのでこういった場合には、バインダーを使いましょう。
[※こういうやつ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703178/fc7d55a3-b628-5e2f-4152-954dafaec403.png)

~~~text:健康診断
1. A君はバインダーをもらう。(A君バインダー)
1. A君は受付で診療開始時間のメモをもらいA君バインダーに入れる。(時間メモ)
2. A君は体重を測ってもらいメモをもらいA君バインダーに入れる。(体重メモ)
3. A君は身長を測ってもらいメモをもらいA君バインダーに入れる。(身長メモ)
4. A君は視力を測ってもらいメモをもらいA君バインダーに入れる。(視力メモ)
5. A君は聴力を測ってもらいメモをもらいA君バインダーに入れる。(聴力メモ)
6. A君はA君バインダーをお医者さんに渡して健康診断の結果をみてもらいました。
~~~

A君はお医者さんにはバインダーを渡すだけで済むようになりました。

# バインダー名
今回、バインダーに入れることによりもう一つメリットが出来ました。それはバインダーに名前が付けられたことです。A君バインダーとつけることによりただの体重メモだったものがA君の体重メモと認識できるようになりました。
これにより同じように何人も健康診断をしてどんどんメモが増えたとしても管理が容易になります。

# ただし
今回はバインダーなのでメモと違い、体重が変わった場合などに必要に応じてメモを入れ替えることが可能です。ただし、バインダーの使いまわしもトラブルの原因となるので注意しましょう。
Livebook で九九の表を作る（Enum版、Nx版）

## はじめに

我が子が九九を暗唱しているので、私は九九を実装することにします

せっかくなので、 Enum でループするバージョンと Nx で行列演算するバージョンを2種類実装してみましょう

最終的に Kino.DataTable でいい感じに表示してみます

実装の全量はこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/99.livemd

## 準備

```elixir

Mix.install([
  {:nx, "~> 0.4"},
  {:kino, "~> 0.7"}
])
```

## Enum

```elixir
qq =
  1..9
  |> Enum.to_list()
  |> then(fn list ->
    Enum.map(list, fn x ->
      Enum.map(list, fn y ->
        x * y
      end)
    end)
  end)
  |> dbg()
```

![スクリーンショット 2022-11-18 23.57.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/53c03ea4-5b02-8863-54d2-983a6197af82.png)

特に解説するまでもないですが、 `Enum.to_list(1..9)` で 1 から 9 までの配列ができます

その配列を二重ループさせれば九九の出来上がりです

## Nx

Nx でやった方がシンプルだよね、と思ったけど結構ゴチャゴチャしてしまった

```elixir
qq =
  {1, 9}
  |> Nx.iota()
  |> Nx.add(1)
  |> then(&Nx.dot(Nx.transpose(&1), &1))
  |> Nx.to_flat_list()
  |> Enum.chunk_every(9)
  |> dbg()
```

まず `Nx.iota({1, 9})` で 1 * 9 の2次元行列を作ります

![スクリーンショット 2022-11-19 0.01.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/8286cf23-026a-1ec7-366f-981ce0a5e530.png)

これだと 0 から 8 になっているので `Nx.add` で全要素に 1 を足します

![スクリーンショット 2022-11-19 0.03.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/fa4986c2-ef98-419f-90e2-8bbd7e15228f.png)

`&Nx.dot(Nx.transpose(&1), &1)` つまり、転置行列との内積によって一気に九九の計算をします

![スクリーンショット 2022-11-19 0.04.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/c39d546e-e4fe-a23b-6b9f-3831871a103b.png)

`Nx.to_flat_list()` で1次元配列にします

![スクリーンショット 2022-11-19 0.06.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/9437ea00-81d9-d125-c5af-748f15e7c957.png)

`Enum.chunk_every(9)` で 9 個毎に配列を分割すれば九九の出来上がりです

![スクリーンショット 2022-11-19 0.08.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/55b11322-26c9-4ed0-61a5-1302d81d0cbf.png)

## キレイに表示する

DataTable に表示しましょう

```elixir
qq
|> Enum.map(&%{List.first(&1) => &1})
|> then(&[%{0 => Enum.at(&1, 0)[1]} | &1])
|> Enum.reduce(fn x, merged -> Map.merge(merged, x) end)
|> Kino.DataTable.new()
|> dbg()
```

`Enum.map(&%{List.first(&1) => &1})` で、各段のマップにします

![スクリーンショット 2022-11-19 0.11.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/39c160a4-4b22-c098-c3af-836ac82a8c07.png)

`then(&[%{0 => Enum.at(&1, 0)[1]} | &1])` で、左端に何の段なのかを示す列を追加します

![スクリーンショット 2022-11-19 0.11.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/6939afbb-2b4f-088d-4b6f-8ffa4398942d.png)

`Enum.reduce(fn x, merged -> Map.merge(merged, x) end)` により、マップの配列だったのを一つのマップに統合します

![スクリーンショット 2022-11-19 0.13.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/61af8340-7a15-fc02-0bd4-836cc102ca65.png)

これを `Kino.DataTable.new()` に入れればキレイに表示できました

![スクリーンショット 2022-11-19 0.10.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/fc02e697-c99a-67ee-3ae9-9bf0147001d7.png)

## まとめ

ループ処理をできるだけ行列演算に変換するための訓練ですね
ストレージアカウントの作成

●ストレージアカウントの作成
■ストレージアカウント名
一意になる様に指定。ストレージアカウント名を後から変更することはできない。

■パフォーマンス
ディスクおよびパフォーマンスの種類としてStanrdardまたはPremiumのいずれかを選択する。Standardを選択した場合はストレージアカウントの種類がStandard汎用v2となる。Premiumを選択した場合は、続いて表示されるPremiumアカウントの種類の選択によってストレージアカウントの種類が決定される。

※パフォーマンスおよびストレージアカウントの種類は後から変更することができないため、適した種類を選択する必要がある。

■冗長性
レプリケーションオプションを選択するパラメーター。
AndroidのlibpdでJavaレイヤーで音声データを取り扱う

libpdのサンプルを見ると端末の音声入力・音声出力を使う例しかなく、実際に出力される音声のPCMデータにアクセスする方法がよくわかりませんでした。

調べてみたところ、`PdBase.startAudio()`ではなく`PdBase.process()`を使うことでlibpd組み込みの音声入出力ではない、任意の音声データを処理させることができそうだってことがわかったので、これを実装するのに必要な手順をメモがてらまとめてみました。

## .pdファイルを適当な場所に配置する

assets内などに保存された.pdファイルをストレージ上の適当な場所に保存します。
たとえば、`assets/my_patch.pd`に保存されている.pdファイルをアプリのプライベートなファイル領域に保存するなら以下のような感じで保存できます。

```kotlin
private fun preparePatch(): File {
  val patchName = "my_patch.pd"
  val patchFile = File(context.filesDir, patchName)
  if (!patchFile.exists()) {
    context.assets.open(patchName).copyTo(patchFile.outputStream())
  }
  return patchFile
}
```

## .pdファイルを開く

libpdで.pdファイルを開きます。開くのに成功するとハンドルが返されます。ハンドルは、後でlibpdを終了させファイルを閉じる時に使用します。

```kotlin
val patchFile: File = ...
val handle = PdBase.openPatch(patchFile)

// ... 不要になったら

PdBase.closePatch(handle)
```

## オーディオを開く

```kotlin
val inChannels = 2 // 入力を使わないなら0
val outChannels = 2
val sampleRate = 44100 // 48000とか、必要に応じて
val handle = PdBase.openAudio(inChannels, outChannels, sampleRate)

// ... 不要になったら

PdBase.closeAudio()
```

## 音声処理を開始

```kotlin
PdBase.computeAudio(true) // これをやらないと`dac~`などの`~`系オブジェクトが動作しない

// 入力音声・出力音声データを入れる配列。長さは64の倍数xチャンネル数にする
val tick = 1 // 毎回のループで処理するtick数。1tick=64サンプルの音声を処理する。
val inputAudio = FloatArray(tick * 64 * inChannels)
val outputAudio = FloatArray(tick * 64 * outChannels)

while (!Thread.interrupted()) {
  PdBase.pollMidiQueue()
  PdBase.pollPdMessageQueue()
  Thread.yield()

  // TODO inputAudio にマイクなどからの入力音声データを入れる

  if (PdBase.process(tick, inputAudio, outputAudio) != 0) {
    // PdBase.process error
    break
  }

  // TODO outputAudio の音声データをスピーカーに出力したりする
}
```

`// TODO inputAudio にマイクなどからの入力音声データを入れる`のところは、`AudioRecord.read()`で音声入力データを取得して埋めます。
`// TODO outputAudio の音声データをスピーカーに出力したりする`のところは、`AudioTrack.write()`で音声をスピーカーに出力したりします。
上記は必ずしもこの方法で処理する必要はなく、ネットワークへ流したりネットワークから読み取ったり、ファイルに書き出したりすることも考えられるでしょう。
Oracle Apexはなぜ流行らないのか、流行ってはいけないのか

## 目次

- [目次](#目次)
- [About Oracle Apex](#about-oracle-apex)
- [時代は脱Oracle](#時代は脱oracle)
- [保守性が低い](#保守性が低い)
- [データベースとアプリケーションが密結合である](#データベースとアプリケーションが密結合である)
- [モダンな開発と相性が悪い](#モダンな開発と相性が悪い)
- [不明な注意点](#不明な注意点)
- [Oracle Apexを採用しても良い場合](#oracle-apexを採用しても良い場合)
- [終わりに](#終わりに)

## About Oracle Apex

`Oracle Apex`とは、`Oracle Database`に密結合で、データベースファーストなWebアプリケーション用ローコード開発プラットフォームです。

Oracle Database上のテーブルや、REST API、CSV等から、それらのデータを利用するWebアプリケーションを簡単に作成することができます。

ローコードツールであるため、GUIを利用して作成しますが、GUIでは足りない機能を実装する場合、フロントサイドとしては`JavaScript`を、サーバーサイドとしては`PL/SQL`を利用してアプリケーションを作成します。

データベースと密結合であり、サーバーサイドは`PL/SQL`を利用するため、高速です。

## 時代は脱Oracle

今は、脱Oracleの時代です。

Oracleの高額で複雑なライセンス料金、貧弱なSQLパーサー、ナンセンスなマルチテナントアーキテクチャ、使いづらいツール類、ベンダーロックイン...などなど、Oracleを利用するのは、最早時代遅れです。

今や、より高性能で、高機能、低コストのOSSがあります。

にも関わらず、`Oracle Apex`は`Oracle Database`をバックエンドとして要求します。

他のデータベースでもバックエンドとして使えるのならば、問題にはなりませんが、実際にはデータソースとして`MySQL`を利用することができるのみです。

これらの仕様は時代に逆行しているとしか言えません。

## 保守性が低い

コードで実装する場合、サーバーサイドは`PL/SQL`を利用して記述されます。

`PL/SQL`は、データクエリ等を行う問い合わせ言語である`SQL`を拡張し、プログラミング言語にしたものです。

ですが、`PL/SQL`は可読性が低く、メンテナンスや機能追加が、実装した本人でなければ(あるいは実装した本人ですら)、難しいです。

`PL/SQL`は、`DBA`の人がデータベースの管理をするためのツールとして利用する分にはいいですが、それ以外の場合は、利用するべきではありません。

また、データベースにロジックが含まれると、スケーリングにおいて問題が発生します。

**データベースにロジックを含めるべきではありません。**

また、`Oracle Apex`だけでなく、ローコードツール全般に言えることですが、GUIで実装する場合においても、行った変更に合わせて、最適になるようにパラメータが変更されますが、このパラメータ調整によって意図しない部分まで変更されてしまい、どの部分が変更されたかわからなくなってしまう問題が発生します。

また、GUIでの実装では同じような機能を複数の場所で定義できるので、どこを見ればよいかわかり辛く、更にコードでの実装と組み合わせてカオスになります。

## データベースとアプリケーションが密結合である

3層Webアプリケーションとしては、データーベースサーバー、アプリケーションサーバー、Webサーバーと分離されています。

分離されているのには理由があります。

これらが、分離されていない場合、各レイヤーで発生した問題への影響範囲が他のレイヤーまで、広がってしまいます。

また、データベースとアプリケーションが密結合な場合、スケーリングに問題が発生します。

## モダンな開発と相性が悪い

`Git`を利用してソースコードを管理、CI/CDを回して、自動テスト・自動デプロイのようなことができません。

Oracle Apexの場合、GUIで作成された部分も実際には`PL/SQL`が生成されているため、`PL/SQL`をエクスポートして、`Git`で管理することもできますが、いちいちエクスポートする必要があります。

## 不明な注意点

可用性は?

Oracle RACのようなクラスタ構成にした場合、Oracle Apexもクラスタによる高可用構成になっているのか?

## Oracle Apexを採用しても良い場合

これは、以下の3点に絞られます。

- Oracle Databaseを使っている`DBA`が`DBA`のための管理ツールとしてのWebアプリケーションを作成する場合
- Oracle Databaseを利用しており、機能的にGUIで設定できる項目のみ利用する(`JavaScript`や`PL/SQL`を手動で作成しない)場合
- Oracle Databaseを利用して、REST APIを作成する場合

`DBA`の管理ツールとして利用する場合は、データベースとよく統合されているため、扱いやすく、スケーリングも問題になりません。

機能も、そこまでこだわって実装する必要がないので、基本的にGUIで利用できる機能とそれほど複雑ではない`PL/SQL`で実装可能であるため、デメリットよりもメリットの方が大きいと考えられます。

同じく、機能の要件にそれほど厳しくないものである場合、デメリットよりもメリットの方が大きい可能性があります(現実問題として`DBA`の範囲から抜け出してしまうとそうならない場合の方が大きいと思いますが)。

また、REST APIを作成する機能のみを利用する場合も、デメリットの少ないユースケースと言えそうです。

~~脱Oracleどころかより依存していってる点を除けば...~~

## 終わりに

`Oracle Apex`は、自分でコーディングする技術を持たない`DBA`用の玩具です。

そんなもので、実際に業務で利用するアプリケーションを作成するというようなことは考えない方がよいです。
イテレーターのクローンもどき

JavaScript のジェネレーターでは実行途中のイテレーターをクローンできません。無理やりそれっぽいことをしてみました。

# 実装

`next()` に渡す引数をキャッシュして、毎回最初からやり直すことで強引にクローンのように見せかけます。

```js
function makeCloneableIterator(g) {
  const it = g();
  const args = [];
  return {
    next(arg) {
      args.push(arg);
      return it.next(arg);
    },
    clone() {
      const ret = makeCloneableIterator(g);
      args.forEach(ret.next);
      return ret;
    }
  };
}
```

## 使用例

途中から再開しているように見えます。

```js
const it = makeCloneableIterator(function*(){
  yield 1;
  yield 2;
  return "return";
});

console.log(it.next());
const it2 = it.clone();
console.log(it.next());
console.log(it.next());
console.log(it2.next());
console.log(it2.next());
```
```text:実行結果
{ value: 1, done: false }
{ value: 2, done: false }
{ value: "return", done: true }
{ value: 2, done: false }
{ value: "return", done: true }
```

# リストモナド

イテレーターをコピーできないことは、ジェネレーターでリストモナドを模倣する際に障害になっていました。

https://qiita.com/7shi/items/e5365885fb53c015630c

https://esdiscuss.org/topic/how-would-we-copy-an-iterator

今回の実装を使えばリストモナドも模倣できます。

```js
function* ListMonad(g) {
  function* f(it, arg) {
    const r = it.next(arg);
    if (r.done) {
      yield r.value;
    } else {
      for (const v of r.value) {
        const it2 = it.clone();
        yield* f(it2, v);
      }
    }
  }
  yield* f(makeCloneableIterator(g));
}
```

## 使用例

Haskell のコードを移植してみます。

```haskell
main =
  print $ do
    x <- [1, 2, 3]
    y <- [x * 10, x * 100, x * 1000]
    return $ x + y
```
```text:実行結果
[11,101,1001,22,202,2002,33,303,3003]
```

<p class="codepen" data-height="300" data-default-tab="js,result" data-slug-hash="ExRbWBW" data-user="7shi" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">  <span>See the Pen <a href="https://codepen.io/7shi/pen/ExRbWBW">  Cloneable  Iterator</a> by 七誌 (<a href="https://codepen.io/7shi">@7shi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

※ 出力の `log()` は次の実装を使っています。

https://qiita.com/7shi/items/ca174dac3af8235c5bd2

## 経緯

これまでリストモナドを模倣するのに `for` を使ったり、強引に CPS 変換をしたりしていました。

https://qiita.com/7shi/items/8ec339bcddbb6692b738

https://qiita.com/7shi/items/55f10aa99108afd5a128

今回の実装はあくまで実験的なもので、`for` を使うのが素直な気はします。

# 参考

回答で [forkable-iterator](https://github.com/tjenkinson/forkable-iterator) というライブラリが紹介されています。

https://stackoverflow.com/questions/46416266/how-to-clone-an-iterator-in-javascript

これは値をキャッシュすることでイテレーターをコピーする方法です。リストモナドの例のように値が変わる場合には使えません。
Githubのスターでランキングを作ってみる in python

Qiita初投稿。頑張って書きます。

最近GitHubのAPIを使ってスクレイピングアプリ的なものを作りました。
題して「Github Star Rank」

 https://app-rank-git1.herokuapp.com/
pythonとflaskを使用してます。


スターの数を取得して人気のリポジトリTop５を表示します。

どうやってAPIを叩いたかを自分用に記録していきます。


1、APIの取得

これがまず最初の難関。GitHub APIのページでスター関連（starring）のAPIを探したが、どれもランキングに使えそうな物が無い。例えばどのユーザーがどのリポジトリにスターを押したかとか、このリポジトリーには誰がスターを押したか、とかはAPIで叩ける。でもGitHub全体でどのリポジトリーがスター数を獲得したかは網羅してないようだ。

しかし色々調べていくと解決の鍵はsearchカテゴリーにあるんじゃないかと思えてきた。ドキュメントでも"Search API を使うと、GitHub で特定のアイテムを検索できます"と記されてる。盲点だった。

でもどうやってsearch APIでスターを探すのか、、
これまた調べていくとドンピシャなキーワードに辿り着く。

stars:>1

これをGitHubページの左上の検索窓で調べるだけ。
何じゃこりゃと思ったがこのキーワードでまさに私が欲しかった情報にありつけたのだ。

https://github.com/search?q=stars:%3E1&s=stars&type=Repositories


2、APIの作成


とりま上のリンクで人気リポジトリーが見れます。

これだけでもアプリ制作には十分なのだが、もう少し一捻りを加えて・・

![advanced.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2980135/7ea760bc-6f3a-2ad5-212b-477caa1d0a0f.png)

検索結果のページの左側、Languagesの下にあるAdvanced Search で条件を絞り、2022年9月の結果を出します。



そうです。いっそのこと月刊人気リポジトリーアプリにしちゃおうというワケです。


![search.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2980135/b7947f88-6ddc-2684-d4a6-4b534315d329.png)



:arrow_up:の画像のようにCreated on the datesの箇所に日付を指定します。そんでSearchボタンを押して表示されたページのURLを取り出してAPIと組み合わせます。

ちなみにWritten in this languageで言語指定も出来ます。例えばPython関連の人気リポジトリーを調べても面白いかも:stuck_out_tongue_winking_eye:




https://api.github.com/search/repositories?q=stars%3A%3E1+created%3A2022-09&type=Repositories&ref=advsearch&l=&l=

こんなん:arrow_up:作りました。これで2022年9月の人気リポジトリーがjson形式で見れます。

あとはこちらをPythonのrequestsで読み取り加工していくのですが・・・


とりあえず今回はスターランキングに必要なAPIの取得方法について書きました。また別の記事でPython側とHTML側でどんな処理をしたのかを書いていきたいと思います。

あ、ちなみにデプロイしたアプリなんですがめっちゃショボい仕様になってます。改善の余地ありありです。
こんなアプリでも評価してくださる方、何かアドバイスをくださる方がいらっしゃたら尻尾振って喜びます。



Qiita記事初めて書いたがこんなんでいいのか？とりま今後ともよろしくお願いします。
Javaのenum型(列挙型)

## enum型とは
・定数を一つの型でまとめて管理できるクラス(一応)
・通常のクラスとは異なり、new演算子でオブジェクトは生成できない
・同じような意味を持つ定数をまとめて管理できる

### 定義方法

```java
public enum Animal {
    CAT,
    DOG,
    FOX,
}
```
### 使ってみる
今の現場ではenum型の定数を使った時、フィールドに値がセットされる使い方が多い。

```java
public enum Animal {
    CAT("猫",1),
    DOG("犬",2),
    FOX("狐",3);

    private String name;
    private int id;

    private Animal(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public int getId() {
        return id;
    }
}
```

```java
class Pet {
    public static void main(String[] args) {
        Animal animal = Animal.CAT;

        if(animal.getName().equals("猫")) {
            System.out.println("にゃー"); //ここが実行される
        }
        else if(animal.getName().equals("犬")) {
             System.out.println("わん");
        }
        else {
             System.out.println("コン");
        }
    }
}
```

### 個別の実装
enum定数ごとに個別の実装も持てる

```java
enum Animal {
    CAT("猫") {
        @Override
        void exec() {
            System.out.println("にゃー");
        }
    },
    DOG("犬") {
        @Override
        void exec() {
            System.out.println("わん");
        }
    },
    FOX("きつね") {
        @Override
        void exec() {
            System.out.println("こん");
        }
    }
    //個別実装したいメソッドを抽象化させる
    abstract void exec();
}
```

### enumのメリット
enumで定数を管理することによって予期せぬ値が渡されるのを防ぐ。
以下のcryメソッドは猫、犬、きつねのどれかが来た時を想定して作られたメソッド。
executeメソッドでは「うさぎ」を引数にcryメソッドを使用しているので本来の使い方としては誤っている。
しかし文法的には間違っていないのでコンパイルエラーにはならずに実行されてしまう。

``` java
class Animal {
    final String CAT = "猫";
    final String DOG = "犬";
    final String FOX = "きつね";

    public void cry(String name) {
        if(name.equals(CAT)) {
            System.out.println("にゃー");
        }
        else if(name.equals(DOG)) {
            System.out.println("わん");
        }
        else {
            System.out.println("こん");
        }
    }

    public void execute() {
        String RABBIT = "うさぎ";
        cry(RABBIT);
     }
}
```

enumを使用すれば「うさぎ」を引数にしようとした時点でコンパイルエラーを起こしてくれる

```java
public enum Animal {
    CAT("猫",1),
    DOG("犬",2),
    FOX("狐",3);

    private String name;

    private Animal(String name, int id) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
```

```java
class Pet {
    public static void main(String[] args) {
        //RABBITは定義されていないのでコンパイルエラー
        String animal = Animal.RABBIT;
        cry(RABBIT);
    }

    public void cry(String name) {
        if(name.equals(CAT)) {
            System.out.println("にゃー");
        }
        else if(name.equals(DOG)) {
            System.out.println("わん");
        }
        else {
            System.out.println("こん");
        }
    }
}
```

## 終わり
enumの使い方はまだまだありそうです！
実務ではenumはかなりの確率で見るので、まだまだ探っていかないとダメですね:relieved:
間違っている箇所などがあれば教えてください！
Catch allルーティングとActive Storage

Active Storageを使おうとしたら、ルーティングが干渉する事態が発生しました。

## Catch allルーティングとは

Railsのルーティングは`resources`などによるリソースフルなものや、`get 'path/to/:id'`のようなパス形式の指定が一般的ですが、ワイルドカードを使うこともできます（[Rails Guide](https://railsguides.jp/routing.html#%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%82%B0%E3%83%AD%E3%83%96%E3%81%A8%E3%83%AF%E3%82%A4%E3%83%AB%E3%83%89%E3%82%AB%E3%83%BC%E3%83%89%E3%82%BB%E3%82%B0%E3%83%A1%E3%83%B3%E3%83%88)）。

ルーティングの一部に`*name`と入れると、スラッシュも含んでマッチしうるものがすべて回収されて、アクションの側では`params[:name]`のように取得することができます。特に、`get '*all'`のように書いてしまえば、あらゆるURLによる`GET`リクエストがこのルーティングにマッチするようになります。このような、「あらゆるURLにマッチングするルーティング」を「Catch allルーティング」のように呼ぶこともあります。

## Catch allルーティングの問題点

ルーティングは上から順に処理されていくので、Catch allルーティングが途中にあると、それ以降にあるルーティングはなんの意味も持たなくなってしまいます。自分で書いたルーティングでそんなことをする人はいないかと思いますが、ここで問題になってくるのがActive Storage（やAction Mailbox）です。

Active Storageなどが提供するルーティングは、通常の設定ではユーザーが手書きしたものよりあとに来てしまうので、Catch allをユーザーが書いているとActive Storageのルーティングは使われなくなってしまいます。

## 対処法

対処法としては、いくつか考えられます。

### Catch allルーティングに穴を開ける

ルーティングには、`constraints`としてそのルーティングを使う条件を指定することができます。ここで`%r{(?!rails/).*}`のような指定を行って、`rails/`以下をルーティングから一括して外す、という方法も考えられます。ただし、アドホック感が否定できないです。

### ロード順を変える

Active Storageを先にロードできれば、問題は解決します。以下の設定を`config/application.rb`に書きましょう。

```application.rb
config.railties_order = [ActiveStorage::Engine, :main_app, :all]
```

なお、`[:all, :main_app]`のような設定を紹介しているものも見かけましたが、これを行うとアプリ全体の動作が大きく変化してしまいます。
VSCode+WSLのGitで "Missing or invalid credentials" エラーの対処法

# ネタバレ
* Windows側の資格情報マネージャーでGitHubの資格情報を消してWSLを再起動する


以下，詳しい経緯と解説です．

# Gitの失踪
ある日，VSCodeでWSL上のレポジトリ（GitHubで管理）を開いて`git fetch`を実行すると，まさかの
```shell:WSL
$ git fetch
git: command not found
```

！！？
消した覚えないんだけど……
もしかして Windows 側で Visual Studio (VSCodeじゃなくて) のインストール作業をしたせい？

それで，とりあえずWSL上でGitを再インストールしたのはいいものの，今度はこんなエラーが．
```shell:WSL
$ git fetch
Missing or invalid credentials.
Error: connect ENOENT /run/user/1000/vscode-git-xxxxxxxxxx.sock
    at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1157:16) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'connect',
  address: '/run/user/1000/vscode-git-xxxxxxxxxx.sock'
}
Missing or invalid credentials.
Error: connect ENOENT /run/user/1000/vscode-git-xxxxxxxxxx.sock
    at PipeConnectWrap.afterConnect [as oncomplete] (node:net:1157:16) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'connect',
  address: '/run/user/1000/vscode-git-xxxxxxxxxx.sock'
}
remote: Repository not found.
fatal: Authentication failed for 'https://github.com/******/'
```
😅

# 原因調査
* まずは落ち着きましょう。
* `type git`で`git`の在り処を確かめても，`git is /usr/bin/git`（Windows上にあるGitを参照しているわけではない）と出るので，WSL内の問題に思えました．
* しかし，Windows上のレポジトリをVSCodeで開き，エラーが出るかどうか確かめましょう．
レポジトリがない場合は新たにクローンするのでも良いです．（認証が必要なプライベートレポジトリの方がいいですね）
やってみたところ，エラー内容は詳細に出ませんが，クローンできませんでした．

つまり，(WSL関係なく) Windows側の資格情報に問題があったようです．
**WSL上のGitの資格情報は，Windows側で保持している**ということが分かりました．

# 対処法: Windows上の資格情報を消す  

スタートメニューから「資格情報マネージャー」を開き，「Windows 資格情報」をクリックします．  
「汎用資格情報」に一覧がざっと表示されますので，github に関係しそうなものを削除してしまいましょう．  

削除後に追加されているのを確かめた感じ，以下の2つが当該の資格情報のようです．  
* `vscodevscode.github-authentication/github.auth`
* `git:https://github.com`

削除後，再びWindows上でクローンを行ったところ，改めて GitHub へのサインインを求められますが，無事にクローンできました！

## WSL だとまだ動かない！？ 
そして次にWSL上のレポジトリで`git fetch`を試してみるわけですが，同様に動きません．
（そのおかげで先ほどのエラーメッセージ内容を取得できたわけですが…）

「再起動は全てを解決する」という名言のもと，WSLを再起動します．
全てのWSL関連のものを閉じて少し待つのでもよいですが，確実に再起動するには，Powershell上で以下のコマンドを実行します．
（強制的にシャットダウンされてしまうので注意．）
```powershell:Powershell
wsl --shutdown
```

その後，再び`git fetch`を試してみたところ，エラーなく正常にフェッチできました．
めでたしめでたし．

# まとめ
* Gitの認証でエラーが出た際は，まずWSL固有の問題か，Windowsでも再現する問題かで切り分ける．
* WSLにおけるGitの資格情報は，Windows側で管理している．
* Windowsの資格情報マネージャーでGitHubの資格情報を消去後，WSLを再起動する．

おしまい．
rqt_plotでtopic名を指定して実行

rqt_plotでtopic名の指定をコマンドラインからおこないたい

次のように,引数に入れればok

```
$ rqt_plot /turtle1/pose/x:y:z
$ rqt_plot /turtle1/pose/x /turtle1/pose/y /turtle1/pose/z
```

参考

http://wiki.ros.org/rqt_plot
paizaラーニング「同値判定 Python3編」

https://paiza.jp/works/mondai/conditions_branch/conditions_branch__complex_step3

#### 私の回答

```
n=int(input())
ans=0

a=list(map(int,input().split()))
b=list(map(int,input().split()))
for i in range(n):
    if a[i]==b[i]:
        ans+=1
print(ans)
```

#### 模範解答 
```
n = int(input())
a = [int(x) for x in input().split()]
b = [int(x) for x in input().split()]

ans = 0
for i in range(n):
    if a[i] == b[i]:
        ans += 1

print(ans)
```

- A_i == B_iである要素の個数を計算します。
- まずは 2 つの配列を用意し、入力を受け取ります。
- 次にループを用いて各要素が一緒かどうか比較し、一緒の場合は答え用の変数をカウントアップします。
Javaで何か作ってみる(2022/11/18 Day29)

## 今日やった事
- Udemyの動画教材を少し見た。（**J1-14_クラスとメソッド** まで見た。）
## 参考にしたもの
- [【超絶丁寧解説】Javaプログラミングをゼロから学ぶ！絶対挫折させない「基礎入門」講座【講師評価4.3】](https://www.udemy.com/course/uz-java-kiso/)
    &rarr; Javaの勉強に使用しているUdemyの動画教材。
## 所感
- 内容理解は完璧。
- springそろそろ着手したいな。
&rarr;動画教材探しておくか。
## 明日の予定
- 引き続き、動画教材を進めていく。
Javaで何か作ってみる(2022/11/17 Day28)

## 今日やった事
- モニターアームの設置で終わってしまった。
## 参考にしたもの
- 特になし。
## 所感
- 今日は本当何も勉強しなかった、ただただ反省。。。
- モニターアームを設置する事で、デスクが広くなり、快適になったのでよしとしよう。
## 明日の予定
- 引き続き、Javaの勉強を進めていく。
Visual Studio Code のデバッグコンソールで「利用可能なデバッガーがありません。'variables' を送信できません」の対処

# 背景
Node.js を学び始め、Visual Studio Code でデバッグをし始めたところ、下のようなエラーが出た

> 利用可能なデバッガーがありません。'variables' を送信できません
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/159306f9-2b97-2647-cb0f-cc793c510312.png)

なんだこれ？となったので、その解決法を記録

# 理由
単に、built-in Node.js Debugger が停止してしまっているので、Object として Console.log(Object) とした場合の 'variables' が表示出来ない。ってことだった。

Debug 中にコード上で、Object を Hover Over させるのと同様ってことですね。

# 回避策
console.log(Object) をした後　～　終了　までの間のどこかに Brake Point を設定しておくことで、
デバッグコンソールにオブジェクトを表示した際に、built-in Node.js Debugger を生かしておけば OK

## 欲しかった設定はない
自動で Break Point 設定出来ないのかなと　Launch.json 設定を調査したが・・

> stopOnEntry: 起動直後に Brake Point を仕掛ける

はあったが、stopOnExit は無かった・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/809eb1ae-a80b-714b-9380-01840a8a714d.png)

https://code.visualstudio.com/Docs/editor/debugging#_launchjson-attributes

# あとがき
Windows Terminal で npm コマンド動かしてくつもりだったけれど、デバッグ考えるとやっぱり Visual Studio Code を使うことにした。
ということで、デバッグに役立つ情報を調べてまとめていきたいね。

https://learn.microsoft.com/ja-jp/windows/terminal/install
今日、限定、共有記事の不具合に遭遇した。

限定、共有記事　は、AdventCalendarとの連携機能があることを去年知った。　

しかし、不便だということも、同時にわかった。　

せっかく、限定共有で記事を書いても、　
執筆日が当日ではなく、実際に書いた日になり、　
各種トレンドなどに入る機会を逃す。

今日発見したのは、すでに過去に投稿済みになっている記事が、　
あたかも限定、共有扱いになっているように見える。　

実際に編集しようとすると、からっぽ。　
表示で見ていると記事はある。　

なんじゃらほい時代は、まだまだ続く
今日、編集リクエスト処理をまとめてした

Qiitaの編集リクエストは何回か失敗した。　　

すでに、著者が構造的な編集をしている最中に、　
構造的な編集リクエストがあると、　
構造がぐちゃぐちゃになるというのを何回か経験した。　

そこで、編集リクエストは原則対応しないことにした。　
システムがうまく連携できない操作で、　
時間を取るのはたいへんだから。　

それでも１年間、編集リクエストの処理をしていないと、　
結構貯まるらしい。　

単純な間違いだけ、今日、編集リクエストをまとめて処理した。　

Markdownの仕様が変わったことの警告が出た。　

そうだ、そっちも放置していた。　
なんとかせねば。
Elixirコードからmix.exsの中身を取得する方法


[Elixir]: https://elixir-lang.org/
[Erlang]: https://www.erlang.org/
[Phoenix]: https://www.phoenixframework.org/
[Nerves]: https://hexdocs.pm/nerves
[Livebook]: https://livebook.dev/
[IEx]: https://elixirschool.com/ja/lessons/basics/basics/#%E5%AF%BE%E8%A9%B1%E3%83%A2%E3%83%BC%E3%83%89
[Mix.Project]: https://hexdocs.pm/mix/Mix.Project.html
[Mix.Project.config/0]: https://hexdocs.pm/mix/Mix.Project.html#config/0
[Mix.Projec - Invoking this module]: https://hexdocs.pm/mix/Mix.Project.html#module-invoking-this-module
[Application.get_all_env/1]: https://hexdocs.pm/elixir/Application.html#get_all_env/1
[Application.get_env/3]: https://hexdocs.pm/elixir/Application.html#get_env/3
[Application.compile_env!/2]: https://hexdocs.pm/elixir/Application.html#compile_env!/2
[Module attributes]: https://elixir-lang.org/getting-started/module-attributes.html#as-constants


設定を取得したいことはないでしょうか？
[Elixir]コードはコンパイルされるのでコンパイル時の設定と実行時の設定とを区別して考えることが大切なようです。

https://qiita.com/torifukukaiou/items/17d55cf896c24b13350e

## コンパイル時の設定

```elixir
Mix.Project.config()
```

ドキュメントをよく読んでみると、いろいろ注意事項が書かれています。[Mix.Project.config/0]はコンパイル時の設定のみに使用すると考えておいた方が良さそうです。

> [This module contains many functions that return project information and metadata. However, since Mix is not included nor configured during releases, we recommend using the functions in this module only inside Mix tasks. If you need to configure your own app, consider using the application environment instead.][Mix.Projec - Invoking this module]

> [Do not use Mix.Project.config/0 to find the runtime configuration. Use it only to configure aspects of your project (like compilation directories) and not your application runtime.][Mix.Project.config/0]


- Mixはリリース時には含まれておらず、設定もされていない
- Mixタスクの中だけで使用することが推奨されている

## 実行時の設定

実行時に設定を取得する場合は`Application`モジュールの関数を利用します。

- [Application.get_all_env/1]
- [Application.get_env/3]
- [Application.compile_env!/2] + [モジュール変数][Module attributes]


実行時に設定を読み込み

```elixir
defmodule MyApp do
  def some_config do
    Application.get_env(:my_app, :some_config)
  end
end
```

コンパイル時に読み込み、結果を[モジュール変数][Module attributes]に書き込む

```elixir
defmodule MyApp do
  @some_config Application.compile_env(:my_app, :some_config)
end
```

## ご参考までに

https://qiita.com/piacerex/items/e0b6e46b1325bb931122

https://qiita.com/torifukukaiou/items/1edb3e961acf002478fd

https://qiita.com/piacerex/items/e5590fa287d3c89eeebf
paizaラーニング「足したり引いたり Python3編」

https://paiza.jp/works/mondai/conditions_branch/conditions_branch__complex_step2
#### 私の回答
```
n,a,b=map(int,input().split())
if (n+a+b==0) or (n+a-b==0) or (n-a+b==0) or (n-a-b==0):
    print("YES")
else:
    print("NO")
```

#### 模範解答

```
n, a, b = [int(x) for x in input().split()]

if n + a + b == 0:
    print("YES")
elif n + a - b == 0:
    print("YES")
elif n - a + b == 0:
    print("YES")
elif n - a - b == 0:
    print("YES")
else:
    print("NO")
```

- 本問題は N ± A ± B が 0 になるか判定する問題です。
- Nが 0 になる場合は全部で 4 通り考えられます。
    1. N + A + Bが 0 になる場合
    1. N + A - Bが 0 になる場合
    1. N - A + Bが 0 になる場合
    1. N - A - Bが 0 になる場合
- これらをすべて試して、どれかが 0 になる場合はYESを出力します。
EC2 AmazonLinux2にyumでインストールしたApacheの設定ファイルの場所

# 概要

- AmazonLinux2にyumでインストールしたApacheの設定ファイル（httpd.conf）の場所をメモ的に記載する。

# ファイルの場所

```shell
/etc/httpd/conf/httpd.conf
```
Paizaラーニング　「けた数の測定 Python3編」

https://paiza.jp/works/mondai/conditions_branch/conditions_branch__complex_step1
けた数の測定なので、単純にlen関数を使えば良いのかと思ったので、以下のように回答しました。
しかし、条件分岐メニューの問題集だったので、模範解答は条件分岐が使われていました。

#### 私の回答
```
n=input()
print(len(n))
```

#### 模範回答
```
n = int(input())

if n <= 9:
    print(1)
elif n <= 99:
    print(2)
else:
    print(3)
```
- Nのけた数を出力します。
- Nの大きさで以下のように場合わけします。
    1.  Nが 9 以下の場合、答えは 1 です。
    1. Nが 10 以上 99 以下の場合、答えは 2 です。
    1. Nが 100 以上 999 以下の場合、答えは 3 です。
Apache パスワードファイルを生成しようとするとエラーになる

# 概要

- ApacheにてBasic認証用パスワードファイルを生成しようとするとエラーになる問題を解決した。

# エラーまでの経緯

1. AWSのEC2でAmazonLinx2マシンを起動しApacheをインストールし起動した。
1. 下記コマンドを実行してパスワードファイルの生成を試みた。

    ```shell
    $ sudo mkdir -p /usr/local/apache/passwd/passwords
    $ sudo htpasswd -c /usr/local/apache/passwd/passwords hogefuga
    ```

# エラー

1. 下記のエラーが出力されパスワードファイルの生成をする事ができない。

    ```shell
    htpasswd: cannot create file /usr/local/apache/passwd/passwords
    ```

# 解決までの経緯

1. 原因は単純だった。
1. パスワードファイル作成前にディレクトリを生成しているところで「passwords」というディレクトリを作ってしまっている。
1. 次のコマンドで「/usr/local/apache/passwd」ディレクトリ直下に「passwords」というパスワードファイルを生成しようとしている。
1. なので「/usr/local/apache/passwd」ディレクトリ直下に「passwords」がある状態でそれと同じ階層に「passwords」というパスワードファイルを生成する様に命令している。名前がかち合って後者のコマンドが実行できなかった。
1. 「passwords」ディレクトリを削除し、パスワードファイルを再生成したらエラーは解消した。

    ```shell
    sudo rm -rf /usr/local/apache/passwd/passwords
    sudo htpasswd -c /usr/local/apache/passwd/passwords hogefuga
    ```

# 参考文献

https://httpd.apache.org/docs/2.4/howto/auth.html
Aterm WG1200HS 最小の設定【DNSフォワーディングがすぐ死ぬときの対処法】

DNSフォワーディングが数時間で死ぬときは、下記や設定値の初期化をすると解消されるかも

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/58f0a77b-ea84-eca9-a9bb-4e73ecb3a38e.png)


`詳細モードに切替`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/0ebb7dc6-952c-9ebd-35d8-25271f7b33e3.png)

# TVモードを使用しない

トップページ ＞ Wi-Fi 設定 ＞ Wi-Fi 詳細設定(2.4GHz)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/f2a185c5-8e98-505b-d31a-7640139e58f3.png)

トップページ ＞ Wi-Fi 設定 ＞ Wi-Fi 詳細設定(5GHz)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/8abd7895-77d5-0fcc-328e-6b19c08d2773.png)

# セカンダリSSIDを使用しない

トップページ ＞ Wi-Fi 設定 ＞ Wi-Fi 詳細設定(2.4GHz)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/6b2f5999-df30-8572-824a-eacc1879abc3.png)


# WPS機能を使用しない

トップページ ＞ Wi-Fi設定 ＞ WPS設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/c0b1796f-fed1-efae-cdb8-47eef9f72326.png)
【DevContainer】Featureの作成方法

## リポジトリを作成する

Feature作成用のリポジトリを作成します。  

以下のリポジトリをテンプレートとして使用します。  

https://github.com/devcontainers/feature-starter

## 必要なファイルを作成する

まず、Feature用のディレクトリを`src`以下に作成します。  

ディレクトリ名はFeatureの名称に対応させます。  
`sample`というFeatureを作成する場合には`src/sample`というディレクトリを作成します。  

Feature用のディレクトリには`devcontainer-feature.json`と`install.sh`が必要です。  

`devcontainer-feature.json`にはFeatureの設定を記述します。  

```json:devcontainer-feature.json
{
  "name": "Hello, World!",
  "id": "hello",
  "version": "1.0.0",
  "description": "A hello world feature",
  "options": {
    "greeting": {
      "type": "string",
      "proposals": [
          "hey",
          "hello"
      ],
      "default": "hey",
      "description": "Select a pre-made greeting, or enter your own"
    }
  }
}
```

`name`,`id`,`description`,`options`は後ほどの手順で自動生成される`README.md`に反映されます。  
`id`はFeatureのディレクトリ名に対応させる必要があります。  

`devcontainer-feature.json`で使用できるプロパティの詳細については以下のページをご参照ください。 
 
https://containers.dev/implementors/features/#devcontainer-feature-json-properties

`install.sh`にはFeatureの処理を記述します。  

```sh:install.sh
#!/usr/bin/env bash
set -e

GREETING=${GREETING:-undefined}
echo "The provided greeting is: $GREETING"

cat > /usr/local/bin/hello \
<< EOF
#!/bin/sh
RED='\033[0;91m'
NC='\033[0m' # No Color
echo "\${RED}${GREETING}, \$(whoami)!\${NC}"
EOF

chmod +x /usr/local/bin/hello
```

`${GREETING}`のように記述すると`devcontainer-feature.json`の`options`に設定した値を受け取れます。

## テスト

Featuresのテストを実行します。

テストの手順については以下をご参照ください。  

https://qiita.com/P-man_Brown/items/5ef5d2fa22d231f20e42

テストには`docker`と`devcontainer-cli`が必要です。  
上記のテンプレートリポジトリを使用している場合はDevContainersを起動すると`docker`および`devcontainer-cli`が使用できます。  

## GHCRに公開する

作成したFeatureをGitHub Container Registryに公開します。  

まず変更を`push`します。  

リポジトリのホームから「Actions」をクリックして「Management Release dev container features & Generate Documentation」を実行します。

![FF40E568-AE84-4C46-9FB6-7AE4A52AD4B4のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/963535d2-f277-b638-b953-77576a2dafbc.png)

すると`src/Feature名/README.md`が自動生成されGHCRにFeatureが公開されます。  

## 参考

https://containers.dev/implementors/create-feature/
GCPのサポートのbase feeを請求するbilling accountを変える方法

以下のページによると、GCPのサポート費用は、GCP利用料に依存する部分と、依らない固定費(base fee)からなります。
例えば、Standard Supportの場合は、$29/monthが固定費で、3% of monthly chargesが利用料に依存する部分です。

https://cloud.google.com/support

さて、サポートプランはGCP Organizationに紐付く一方で、Organization内に複数のbilling accountを持つこともできます。
1つのOrganization内に複数のbilling accountがある場合にbase feeはどのbilling accountに請求されるのでしょうか？

# 答え
SupportのSettingsで確認・変更できる。

Support > Settings画面でPrimary Billing accountを確認・変更することができます。
ここで設定したアカウントに対してbase feeが請求されます。
なお、3% of monthly chargesのような利用料に依存するサポート費用はそれぞれの費用が発生したbilling accountに対して請求されます。

![スクリーンショット_2022-11-18_21_08_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74551/5a569f2e-fb5d-4802-64a1-ebd22ff26a5e.png)
ChromeでJavaScriptを編集できなかった。

# 経緯
JavaScriptで遊ぼうと思いVisualStudioCodeで編集していたが、実行の段階でデバッガーにブラウザを指定してくるので、ブラウザで編集しようとおもった。

しかしコード表示はできるものの、編集できなかったので「やっぱりVSCodeで編集かな」と思っていたが、検索すると皆さん編集、保存、反映、できているようで納得できなかった。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2783830/8f314e90-a6cd-a3df-8f32-56c54000f5f4.png)
例えば矢印の部分をコメントアウトしようとしたが編集できなかった。
# 解決方法
### 設定
設定⇒ワークスペース⇒フォルダーを追加⇒許可する。
![２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2783830/6200f932-8a1f-b2fa-7da0-bc46d91790f9.png)
### 確認
矢印部分に緑丸がついて編集できるようになる。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2783830/bda2493e-e3ee-7709-7ba6-5a248dd502fa.png)
# 実際にやってみた
### 編集
横矢印部分をコメントアウトすると、縦矢印部分にアスタリスクが付いた。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2783830/0b567cde-9510-bfb5-ab0d-af3c732a4f3a.png)
### 保存
「Ctrl+S」で保存されてアスタリスクが消える。
### 反映
「F5」キーで反映される。
## 参照
プログラムコードは[こちら](https://into-the-program.com/javascript-read-the-file/)を参照しました。
Google Sheetsでセルの相対参照をする方法

Google Sheetsで現在のセルの場所から右にM個、下にN個いった場所にあるセルを参照する方法です。
M, Nをマイナスの数にすると左や上を参照できます。

```
OFFSET(INDIRECT(ADDRESS(ROW(),COLUMN())), N, M)
```

# 解説
まず、括弧の対応が分かりやすいように体裁を整えます。


```
OFFSET(
  INDIRECT(
    ADDRESS(ROW(),COLUMN())
  ),
  N,
  M
)
```

上記の処理は、まずROW関数とCOLUMN関数で現在のセル位置を取得します。
それぞれの関数はセルの位置を整数で返すため、それをADDRESS関数に渡すことで、 `A3` や `B12` などのアルファベットと数字からなる形式の文字列に変換します。
その後、INDIRECT関数に渡すことで文字列からセル参照に変換し、最後にOFFSET関数にセル参照と相対位置を渡すことで相対参照を実現しています。
建設業許可業者一覧PDFをCSV変換

https://www.mlit.go.jp/totikensangyo/const/1_6_bt_000089.html

> <おことわり>
> ※検索システムのアクセス集中による不具合が発生しているため、一時的に掲載しております。
> ※この建設業者一覧及びこの建設業者一覧を加工・変更したものを商用利用、出版、不特定又は多数に対して二次配布することは許可しません。

# ダウンロード
```
# 建設業許可業者一覧のPDF
wget https://www.mlit.go.jp/totikensangyo/const/content/001520358.pdf -O data.pdf

# tabula-java
wget https://github.com/tabulapdf/tabula-java/releases/download/v1.0.5/tabula-1.0.5-jar-with-dependencies.jar
```

# PDFからCSV変換
```
# ヒープの最大サイズを12GB
java -jar -Xmx12G tabula-1.0.5-jar-with-dependencies.jar -o data.csv -p all -l data.pdf
```

# データクレンジング
```python
import pandas as pd

df0 = pd.read_csv("data.csv", dtype=str, header=None)
df0

# 許可番号 欠損削除
df0.dropna(subset=[0], inplace=True)

# 許可番号 数字以外を除去
df1 = df0[df0[0].str.isnumeric()].copy()

# 特に神奈川県の住所に空白が多いので削除
for col in df1.select_dtypes(include=object).columns:
     df1[col] =  df1[col].str.replace(" +", " ", regex=True)

# CSVに保存
df1.to_csv("result.csv", encoding="utf_8_sig", index=False, header=False)
```

# PDF自動ダウンロード
```sh
apt install html-xml-utils
apt install libxml2-utils

curl -sS https://www.mlit.go.jp/totikensangyo/const/1_6_bt_000089.html \
| hxnormalize -x \
| xmllint --html --xpath '//a[strong/span[contains(text(),"建設業許可業者一覧（PDF）")]]/@href' - \
| cut -d= -f2 \
| tr -d '"' \
| sed 's;^/;https://www.mlit.go.jp/;;' \
| xargs -n 1 curl -o data.pdf
```
CORSについて書いてみた

## はじめに
最近、五等分の花嫁にハマっているキティちゃんです。おはこんばんにちは。ハマりすぎて、1日で1期を、2日で2期を全て見終わりました。アニメも見終わったので映画も見ようと思ったのですが、近場は全て公開終了でした。悲しいですね。さて、前置きはここまでとして、今回はCORSについて書いていこうと思います。

## きっかけ
診断をやっている友人からCORSの話を聞いて、話のネタになりそうだなと思ったためです。

## CORSとは
Cross Origin Resource Sharing の略で、直訳するとオリジン間リソース共有と言ったりします。WebアプリケーションにてJavaScriptの活用が進み、同一オリジンポリシーの制限を超えて、サイト間でデータのやり取りをするケースが増えました。サイトを超えてデータをやりとりできる仕様として策定されたものがCORSとなります。
例ですが、かつてCORSがなかった時はブラウザからサーバA(hxxps://testhogehoge.com)にアクセスしたら、サーバAの「testhogehoge.com」の同一オリジンとしか通信することができませんでした。現代のサイトでは、異なるホストからデータを取得したりすることも当たり前ですが、異なるホストとも通信ができるようにしている仕組みがCORSとなります。

## 同一オリジンポリシーとは
JavaScriptなどのクライアントスクリプトからサイトをまたがったアクセスを禁止するセキュリティ上の制限です。
何度か同一オリジンという言葉が出てきていますが、以下の条件を満たすものが同一オリジンとなります。

1.URLのホストが一致している
2.スキーム（プロトコル：httpなど）が一致している
3.ポート番号が一致している

## どんな脆弱性が潜んでいるのか
CORSが策定されたことで、異なるオリジンとも通信ができるようになりましたが、制限をかけない場合、どこからのアクセスでも受け付けてしまい、CSRF(意図しない更新処理ができてしまうこと)や情報の漏洩(更新処理が成功した結果のレスポンスから個人情報の取得)に繋がることがあります。例としては以下などがあります。

1.ユーザーがブラウザで攻撃者の用意したWebサーバーXにアクセスしてしまう
2.WebサーバーXから攻撃用スクリプトをブラウザが受け取る
3.ブラウザ上でスクリプトは実行され、サーバB(hxxps://api.testhogehoge.com)へアクセスする
4.サーバBでは何かしらの更新処理が行われ、その結果がブラウザへ送られる
5.受け取った結果を攻撃用スクリプトが攻撃者側へ転送する

## どのように対策をするのか
Access-Control-Allow-Originヘッダなどの「Access-Control-Allow-XXXXX」を用いて、信頼できるオリジンであるか、信頼できないオリジンであるかをサーバーがブラウザに伝え、信頼できる場合のみ、正常なレスポンスを返します。また、CSRFを防ぐために、X-CSRF-Tokenヘッダを付与し、サーバー側でX-CSRF-Tokenの値をチェックをするという方法があります。

## どのように確認をするのか
HTTPリクエスト、HTTPレスポンスを確認し、「Origin」、「Access-Control-Allow-XXXXX」など適切なオリジンのみ通信を許可する設定がされているかを確認します。また、HTTPレスポンスヘッダで、「Access-Control-Allow-Origin：*」という設定をすることも可能です。「＊」は全てのオリジンを許可する設定となります。基本的には公開情報用APIに用います。公開情報用APIではない場合は、通信を許可するオリジンのみ指定することを推奨します。また、CSRF対策を講じている場合は、トークンの値を削除、書き換えなどをして、トークンの値がサーバー側でチェックされているか確認をします。


## 終わりに
今回はCORSのことについて書いてみましたが、恥ずかしながら、CSRFの対策にもなるというのは初めて知りました。分からないことも、書いてまとめたりすることで、整理ができ、理解に繋がりますね。あと、今回は特に書きませんでしたが、CSRF対策にはプリフライトリクエストというものがあります。プリフライトリクエストは単純リクエストの条件を満たさない場合にブラウザで自動で発行するリクエストです。詳しくは各自で調べてみてください。
今回はここで終わりにします。最後までありがとうございました。


## 参考
・『体系的に学ぶ 安全なWebアプリケーションの作り方 第2版』　著者：徳丸浩様

・『今日こそ理解するCORS』　徳丸浩のウェブセキュリティ講座
https://www.youtube.com/watch?v=yBcnonX8Eak&ab_channel=%E5%BE%B3%E4%B8%B8%E6%B5%A9%E3%81%AE%E3%82%A6%E3%82%A7%E3%83%96%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E8%AC%9B%E5%BA%A7

・『CORSはCSRFの対策にならないという話（あるいはCORSは何でないか）』
@netebakari 様
https://qiita.com/netebakari/items/41baa7e1d0b8d89f9d12
BigQueryで絶対にSELECTできないVIEWをつくる その2

Partition filterがRequiredなテーブルを作成して、

![スクリーンショット_2022-11-18_20_38_56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74551/9681d691-4d46-3246-895d-1a615d9f4987.png)

そのフィールドに対するWHERE句の存在しないVIEWを作成すると、

```sql
create view ill_formed_view2 as
select * from require_partition_filter_table;
```

どうやっても以下のエラーが発生してSELECTできません。

```
Cannot query over table '<project_id>.<dataset_id>.require_partition_filter_table' without a filter over column(s) 'hoge' that can be used for partition elimination
```
Future of automated driving, ボッシュ自動車handbook 11版(159) p.1934

Future of automated driving , Future of automated driving ,  ボッシュ自動車handbook 11版(159)

人生で影響を受けた本100冊。

https://qiita.com/kaizen_nagoya/items/16af53acbb147a94172e

に掲載した本のうち、「新人プログラマ応援」企画で「私の推薦書３３冊」として３３冊紹介した。

新人プログラマ応援　私の推薦書３３冊

http://qiita.com/kaizen_nagoya/items/98c62f051dbdb4f8aca2
残りの６７冊から、順に過去の読書感想を引用し、新たな読書感想文を追記する。

 <この項は書きかけです。順次追記します。>


# ボッシュ自動車ハンドブック version 11, 2022

Automotive Handbook  May 2, 2022

https://www.amazon.co.jp/dp/1119911907/

ボッシュ自動車handbook(英語)11版(0-1) 課題と記事一覧new

https://qiita.com/kaizen_nagoya/items/a9d2887bf2a7598dc8e5

# Contents
Motor vehicle, 28
Basic principles, 32
Mathematics and methods, 204
Materials, 258
Machine parts, 354
Joining and bonding techniques, 426
Vehicle physics, 462
Operating fluids, 538
Refrigerants for air-conditioning systems, 591
Drivetrain(駆動系), 594
Internal-combustion engines(内燃機関),642
Management for spark-ignition engines,800
Gasoline-engine operation with alternative fuels, 886
Management for diesel engines, 906
Electrification of the drive, 970
Emission-control and diagnosis legislation, 1042
Chassis systems, 1108
Vehicle bodies,  1310
Comfort and convenience, 1392
Safety systems in the motor vehicle, 1410
Vehicle security systems, 1430
Automotive electrics, 1450
Vehicle electrical systems for hybrid and electric vehicles, 1560
Automotive electronics, 1620
Infotainment 1780
Drive assistance and sensors, 1804
Drive assistance systems 1872
Future of automated driving 1934
Appendics, 1940

#  Future of automated driving , p.1934

## Automation levels
## Obstacles to automated driving
## Stages on the road to autonomous driving


# Reference
[2] SAE J3016
Taxonomy and Definitions for Terms Related to Driving Automation Systems for On-Road Motor Vehicles 

https://www.sae.org/standards/content/j3016_202104/
# 自己参考資料(self reference)

ボッシュ自動車ハンドブック 

https://qiita.com/kaizen_nagoya/items/8e330ce57880f04d71d9
ボッシュ自動車handbook(英語)10版　目次

https://qiita.com/kaizen_nagoya/items/57c799ff544c96efdea9

自動車工学とBosch Vehicle Handbook

https://qiita.com/kaizen_nagoya/items/d13ff6b0e4d7c8907c0d

 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞

# 文書履歴(document history)
ver. 0.01 初稿 20221118
BigQueryで絶対にクエリを実行できないVIEWを作る その1

以下のようなカラム名の重複するクエリをBigQueryのWeb UIからVIEWとして登録するとどうなるでしょうか？

```sql
select 1 as hoge, 1 as hoge
```

![スクリーンショット_2022-11-18_20_25_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74551/6231d318-f02d-d427-f8bf-2934ca3309c2.png)

# 答え
VIEWは作成されるが、どのようにSELECTしても失敗するVIEWになる。

viewのスキーマ的には重複したカラム名が許されないようなので、片方の名前が `hoge_1` になっています。

![スクリーンショット 2022-11-18 20.26.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74551/d913bdc4-00d9-df54-63ab-2cddc16eb8a9.png)

試しに色々な方法でクエリを実行できるかどうか検証してみましょう。

```sql
select * from `<project_id>.<dataset_id>.ill_formed_view1`;
-- Duplicate column name 'hoge' in definition of view '<project_id>.<dataset_id>.ill_formed_view1'

select hoge from `<project_id>.<dataset_id>.ill_formed_view1`;
-- Column name hoge is ambiguous at [1:8]

select hoge_1 from `<project_id>.<dataset_id>.ill_formed_view1`;
-- Unrecognized name: hoge_1; Did you mean hoge? at [1:8]

select null from `<project_id>.<dataset_id>.ill_formed_view1`;
-- Duplicate column name 'hoge' in definition of view '<project_id>.<dataset_id>.ill_formed_view1'

select null from `<project_id>.<dataset_id>.ill_formed_view1` limit 0;
-- Duplicate column name 'hoge' in definition of view '<project_id>.<dataset_id>.ill_formed_view1'
```

どうやってもエラーになるようです。

# ちなみに
Web UIではなく、CREATE VIEW文でこのようなVIEWを作ろうとするとエラーになります。

```
create view `<project_id>.<dataset_id>.ill_formed_view1` as
select 1 as hoge, 1 as hoge;
```
Interior monitoring systems, ボッシュ自動車handbook 11版(158) p.1932

Drive assistance and sensors, Interior monitoring systems,  ボッシュ自動車handbook 11版(158)

人生で影響を受けた本100冊。

https://qiita.com/kaizen_nagoya/items/16af53acbb147a94172e

に掲載した本のうち、「新人プログラマ応援」企画で「私の推薦書３３冊」として３３冊紹介した。

新人プログラマ応援　私の推薦書３３冊

http://qiita.com/kaizen_nagoya/items/98c62f051dbdb4f8aca2
残りの６７冊から、順に過去の読書感想を引用し、新たな読書感想文を追記する。

 <この項は書きかけです。順次追記します。>


# ボッシュ自動車ハンドブック version 11, 2022

Automotive Handbook  May 2, 2022

https://www.amazon.co.jp/dp/1119911907/

ボッシュ自動車handbook(英語)11版(0-1) 課題と記事一覧new

https://qiita.com/kaizen_nagoya/items/a9d2887bf2a7598dc8e5

# Contents
Motor vehicle, 28
Basic principles, 32
Mathematics and methods, 204
Materials, 258
Machine parts, 354
Joining and bonding techniques, 426
Vehicle physics, 462
Operating fluids, 538
Refrigerants for air-conditioning systems, 591
Drivetrain(駆動系), 594
Internal-combustion engines(内燃機関),642
Management for spark-ignition engines,800
Gasoline-engine operation with alternative fuels, 886
Management for diesel engines, 906
Electrification of the drive, 970
Emission-control and diagnosis legislation, 1042
Chassis systems, 1108
Vehicle bodies,  1310
Comfort and convenience, 1392
Safety systems in the motor vehicle, 1410
Vehicle security systems, 1430
Automotive electrics, 1450
Vehicle electrical systems for hybrid and electric vehicles, 1560
Automotive electronics, 1620
Infotainment 1780
Drive assistance and sensors, 1804
Drive assistance systems 1872
Future of automated driving 1934
Appendics, 1940

# Interior monitoring systems,  p.1932

## Camera based interior monitoring
# Reference
参照なし

# 自己参考資料(self reference)

ボッシュ自動車ハンドブック 

https://qiita.com/kaizen_nagoya/items/8e330ce57880f04d71d9
ボッシュ自動車handbook(英語)10版　目次

https://qiita.com/kaizen_nagoya/items/57c799ff544c96efdea9

自動車工学とBosch Vehicle Handbook

https://qiita.com/kaizen_nagoya/items/d13ff6b0e4d7c8907c0d

 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞

# 文書履歴(document history)
ver. 0.01 初稿 20221118
AmazonLinux2にMySQL8.0クライアントを入れて接続

自分用備忘録

# 環境
```
$ cat /etc/system-release
Amazon Linux release 2 (Karoo)
$ uname -a
Linux hogehuga.ap-northeast-1.compute.internal 5.10.144-127.601.amzn2.x86_64 #1 SMP Thu Sep 29 01:11:59 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
```

# 手順
```
$ sudo rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
$ sudo yum update

$ sudo rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
$ sudo yum install mysql-community-client -y
$ mysql --version
mysql  Ver 8.0.31 for Linux on x86_64 (MySQL Community Server - GPL)
```

# 接続
```
$ mysql -h <接続先> -P 3306 -u <ユーザー名> -p
```


# 参考
https://qiita.com/ogatamaquzilla/items/7f2e90806f3b6851e7b0

https://qiita.com/CyberMergina/items/f889519e6be19c46f5f4