OmniAICreator/Qiita-1.07M huggingface dataset:
LM studio（ローカルLLM）をVScode上で利用してみた

みなさんchatgptやcloude、github copilotつかってますか？
もうAIなしのコーディングはできないと思ってませんか？
しかしながら、機密性の高い情報を入力することは憚られる、、、

でも大丈夫！ローカルならね！

ということで、ローカルLLM（Large Language Model）が簡単に動かせるLM studioとVScodeで利用するための簡単なガイドです。

### ステップ1: 環境の準備
LM Studioを利用する前に、必要な環境を整える必要があります。以下の記事をみれば簡単に windows、Mac、Ubuntuともに設定できるはずです。。。

https://qiita.com/kharada_toyotec/items/d81214234bc429475789



### ステップ2: LLMのインストール
次に、使用するLLMをインストールします。[Hugging Face](https://huggingface.co/)というプラットフォームからモデルをダウンロードすることができます。自分の持っているPCと相談しながらどのモデルを使用するかを選択してください。今回私はCodeLlama-7b(5bit量子化)を使用していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659400/ba3810d9-24bd-8e11-be24-12c9945c5a9e.png)



### ステップ3: ローカルサーバーを立てる
今回は、VSCodeからアクセスしてLLMを利用するためにLM Studio上でローカルサーバーを立てます。画面左の「サーバー」アイコンをクリックし、「Start Server」ボタンをクリックします。これで、localhost:1234にアクセスすることで、LLMを利用可能になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659400/21a7b98a-cd5f-713e-e69c-03b91a27119c.png)



### ステップ4: VScode上での設定
LLMをVScodeで利用するためには、continue.という拡張機能をインストールします。この拡張機能を使うと、VScode上でCursorのような機能を実現することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659400/5e4be0b1-d082-9aab-76d1-0b1f951d5451.png)

インストール後、拡張機能アイコンをクリックします。すると下部にモデル名と+ボタンが出てくるので+ボタンを押してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659400/cf4543d3-ecf1-862a-f48c-a66923cf9cb9.png)

Add New Modelという画面に遷移するのでそこで、LM Studioを選択してください

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659400/9510a585-3d2d-05d7-9bce-142f4a9e0749.png)

Configure Model画面に遷移したら今回ダウンロードしたモデルであるCodeLlama-7bを選択してください。
これで準備は完了です！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659400/8255a135-5e55-5a1f-ab8a-8dbf87c4e46e.png)

### 実際の使い方
<iframe width="100%" height="480" src="https://www.youtube.com/embed/Fo_yR0Q2ajA" title="LM Studio in VScode" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

ローカルサーバーなので、色々応用が利きそうです！
性能は既存の大規模モデルにはかないませんが、無料でかつ安全であることを考えれば十分だと思います。



### 参考文献

https://qiita.com/kharada_toyotec/items/d81214234bc429475789

https://wohl-yz.net/archives/2363#%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC
[TypeScript] 添え字を活用して、連番の配列を生成する。

今回は、与えられた数をもとに連番の配列を生成する必要があったため、参考をもとに整理していきます。2または3通りの記述方法があります。

## 参考

https://qiita.com/suin/items/1b39ce57dd660f12f34b

## 前提
- 生成するのは、[ 0, 1, 2, 3, 4, ..., num]のような添え字を要素にもつ配列です。

| 省略形 |  |  意味 |
|:-:|:-:|:-:|
|  v |  value |  要素 |
|  i |  index |  添え字 |


## 結論
この記事では主に以下の記述方法を説明します。しかし、実際に使用するのはドキュメントより引用した記述方法がよいです。

```typescript
// numに期待する配列の要素の数を代入
const numS = [...Array(num)].map((v, i) => i);
```

以下の記述方法は、**ドキュメントより引用**したものです。コメントでいただきましたが、こちらの方が処理が軽量とのことです。前者ではなくこちらを使うほうがよいです。

```typescript
// 連番の生成
// 配列はそれぞれの場所が `undefined` で初期化されるため、
// 以下の `v` の値は `undefined` になる
// Array.from(arrayLike, mapFn)
Array.from({ length: 5 }, (v, i) => i);
// [0, 1, 2, 3, 4]
```

## 本文
ここから順を追って説明します。

### `Array(num)` の説明
Arrayコンストラクターを使用して、引数 `num` と同じ数の**空の配列**を生成します。ここで `.map()` メソッドを使用しても、要素が空であるため何も起こりません。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/Array

### `[...Array(num)]` の説明
配列のスプレッド構文「...」を使用して、配列のコピーを作成します。これにより、`undefined` の配列を生成できます。
空の配列にわざわざ `undefined` を格納するのは、のちに `.map()` メソッドで要素を取り出すためです。

https://typescriptbook.jp/reference/values-types-variables/array/spread-syntax-for-array

### `.map((v, i) => i)` の説明
`配列.map()` メソッドを使用することで、`undefined` を添え字に変換します。
このメソッドは、与えられた関数（`callbackFn`）のなかで3つの引数を取ります。それは、`element`、`index`、`array` の3つです。ここで使用するのは`element` と `index` です。`element` には配列から取り出した要素が入り、`index` には配列のなかの要素がもつ添え字が入ります。

ここでは、適当な変数（`v`）に要素を取り出し、それを無視する形で添え字（`i`）を要素に格納します。これにより、[ 0, 1, 2, 3, 4, ..., num]のような添え字を要素にもつ配列が生成されます。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map

## 結論
`[...Array(num)].map((v, i) => i)` によって、まずは空の要素をもつ配列を生成し、その配列に `undefind` を格納します。そして、`.map()` メソッドで `undefind` に添え字を格納します。

一度、`undefined` を挟むのは `.map()` メソッドで配列から要素を取り出すためです。

## 追記
### コメントより参考

Arrayオブジェクトの `.from()` メソッドと `.key()` メソッドを使用する方法もあるようです。

| メソッド |   | 説明 |
|:-:|:-:|:-:|
|  静的メソッド |||
|  `.from()` |  配列を生成します。 |  **反復可能オブジェクト**や**配列風オブジェクト**から配列を生成します。また、連番を生成できます。`Array.from({ length: 5 }, (v, i) => i);` |
|  インスタンスメソッド |||
|  `.keys()` |  添え字をそのまま配列にします。 |  与えられた配列の添え字を要素に格納した、新たな配列を生成します。 |


https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/from

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/keys


### ドキュメントより引用
ドキュメントの `Array.from()` メソッドのページに、**連番の生成方法**の記述がありました。

```typescript
// 連番の生成
// 配列はそれぞれの場所が `undefined` で初期化されるため、
// 以下の `v` の値は `undefined` になる
Array.from({ length: 5 }, (v, i) => i);
// [0, 1, 2, 3, 4]
```

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/from#%E3%82%A2%E3%83%AD%E3%83%BC%E9%96%A2%E6%95%B0%E3%81%A8_array.from_%E3%81%AE%E4%BD%BF%E7%94%A8
あまり難しく無い技術記事執筆のパターン5選

# ⁠経緯

[アドベントカレンダーの運営](https://qiita.com/tfandkusu/items/c7ae3a416f4859b44876)に引き続き、メンバーによる技術的発信を促す活動をしています[^1]。今回はその活動の一環として、私の経験に基づき表題の内容を社内 LT 会で発表しました。その結果は好評で、社外にも公開することを勧められたので投稿しました。

[^1]:Mobile チームの EM である [makiyama](https://x.com/_rmakiyama) との 1on1 で活動内容をすり合わせながら進めています。また、会社のメンバーからはアンケートのへの回答などのご協力を頂いています。

記事の構成としては、あまり難しく無い技術記事執筆のパターンを5つ記事の例を含めて紹介し、それぞれのメリットデメリットを執筆の難易度、読み手への価値提供、採用貢献、キャリアアップの観点で説明しています。

# パターン1. うちではこうやっている

採用貢献ならばこれがやりやすいと考えます。シンプルに現場で使っている技術を紹介するだけです。その技術選定になった経緯を説明できるとなお良いですが、紹介するだけでも、その技術スタックが十分にモダンならば、求職者は開発者体験が良い状態で仕事ができるという安心感を持って入社して頂けます。

## ⁠記事の例

https://rni-dev.hatenablog.com/entry/2021/08/30/121839

前職で Android エンジニアの採用担当をしていた時に書きました。元ネタ紹介はありますが、ほぼ列挙しただけの記事です。

https://blog.kyash.co/entry/2023/12/12/083000

こちらは私の所属チームの先輩の記事です。ただ単にトランクベースで開発していますだけでなく、チーム内での認識合わせの様子や参考文献の紹介など、レベルの高い「うちではこうやっている」だと思います。

## ⁠メリット

* 実態を紹介するだけなので⁠書くのは簡単
* 直接的に採用貢献になる

## ⁠デメリット

* 技術そのものの解説でないので、列挙しただけでは高い技術力のアピールにはならない
* 現場の技術より、より良いソリューションがあり、そちらがメジャーな場合は、採用貢献としては逆効果になる

# パターン2. ⁠課題解決

個々の技術はありふれたものですが、それらを組み合わせることで、課題解決する様子を紹介する記事です。

## ⁠記事の例

https://qiita.com/tfandkusu/items/acbc0906046bb7b2b1db

当時の Qiita にはデイリーランキングがあり、最高3位になった記事です。やっていることは ffmpeg コマンド、Google Cloud Platform の AI 系サービス、畳み込みニューラルによる画像分類とありふれた技術を組み合わせただけです。

## ⁠メリット

* 課題解決の様子を紹介するだけなので、書くのは簡単
* 課題解決のための柔軟性や引き出しの多さはアピールできる

## ⁠デメリット

* 技術そのものの解説でないので、高い技術力のアピールにはならない
* 解決できる課題が無いと書けない

# ⁠パターン3. 新技術の応用方法

新しい OSS のリリースなど、新技術が出てきたら、応用方法を紹介する記事です。

## ⁠記事の例

https://qiita.com/tfandkusu/items/5319b755ab2f1293359a

[Konsist](https://github.com/LemonAppDev/konsist) という Kotlin プロジェクトのクラスやメソッドの命名や構成がガイドラインに沿っているかを確認するツールがリリースされたので、会社のプロジェクトでよくやる書き忘れが無いかを確認する方法を記事にしました。

## ⁠メリット

* 新技術をすぐに使うアンテナの高さをアピールできる
* 新技術で解決した課題の内容を通じて、現場の開発体制を紹介できる

## ⁠デメリット

* 新技術に対して応用方法が毎回思いつくとは限らない

## ⁠備考

モバイルでは [Android Dagashi](https://androiddagashi.github.io/), [iOS Osushi](https://ios-osushi.github.io/) で新技術が紹介されます。

# ⁠パターン4. 和訳

英語しか情報が無いものを日本語で紹介する記事です。

## ⁠記事の例

https://qiita.com/tfandkusu/items/e65eacc80e066c0e86c4

iOS/Android クロスプラットフォーム技術のひとつである [SKIE](https://skie.touchlab.co/) は英語で書かれている公式サイトに十分に情報があり、これはサンプルコードを作成しながら日本語でまとめただけの記事です。

## ⁠メリット

* 学習にはなる
* 英語に抵抗感がある読者には価値提供になる

## ⁠デメリット

* 英語慣れしている読者には新たな価値提供ができない
* 高い技術力のアピールにはならない

# ⁠パターン5. 実装のハマりどころ解決

プロダクトを実装していて、問題があって対処したところを紹介する記事です。

## ⁠記事の例

https://qiita.com/tfandkusu/items/043c5dc3e79d33fe7bda

Android アプリ内に iOS と共通に使えるレイアウトを載せたときに発生した問題と、その解決方法を紹介しています。

## ⁠メリット

- 同じところでつまづいた人に対しては価値提供になる
- 問題が複雑な場合は、高い技術力のアピールになる

## デメリット

- 他人の日本語の記事で解決してしまった場合は、記事のネタにならない

このデメリットに対しては社内でご意見がありました。他人の日本語の記事があっても、なぜ解決できたのかの説明が不十分なケースがあるので、詳しい理由を掲載することで、新たな価値提供になることがあります。

# まとめ

今回は採用やキャリアアップのために技術記事執筆を検討しつつも、テーマ探しが難しかったり、書こうとしている記事はすでに他の人が公開しているという人に向けて、あまり難しく無い技術記事執筆のパターンを5つ紹介しました。参考になれば幸いです。
PowerShell でディレクトリのシンボリックリンクを作成する方法

### PowerShellでは new-item を使用を使用する（要・管理者権限）
~~~powershell:
New-Item -ItemType SymbolicLink -Path "リンク" -Target "リンク先（実体のディレクトリ）"

#意味は同じ
New-Item -ItemType SymbolicLink -Path "リンク" -Value "リンク先（実体のディレクトリ）"

#記載の順番を入れ替えても良い
New-Item -ItemType SymbolicLink -Target "リンク先（実体のディレクトリ）" -Path "リンク"
~~~

### コマンドプロンプトでは mklink /D を使用していた
~~~powershell:
mlkink /D "リンク" "リンク先（実体のディレクトリ）"
~~~
【iOS】過去にfastlane matchで生成した証明書を更新する方法

# はじめに
約1年前にfastlane matchを使ったCI/CD環境の構築について記事にまとめました。
それから一年が経過して証明書の更新が必要になり追加作業をしたので、その内容をまとめます。

https://qiita.com/yoshitaka/items/b33a45bd5d2ccf49da9c

ちなみに上記の記事を書いた当時は、業務で使っているCI/CDの環境構築を自分でも一通り構築してみたいというモチベーションのもと、Bitriseを使ったCI/CD環境を構築しました。


# 内容
環境構築をした際は、`match init`から行ったのですが、今回は証明書の更新なので
配布と開発用で下記2つのコマンドを一年ぶりに実行しようと思います。

- `fastlane match appstore`

- `fastlane match development`

しかし、何もせずにこのまま実行すると

Githubの証明書リポジトリに期限の切れた証明書が存在することから再生成されません。

<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/fa02779c-f895-60a8-b6bb-cee33ad7ae0b.png">

Githubの証明書リポジトリを確認すると変更もlast yearになっています。（それはそう）

<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/ab59e0b9-ed13-1834-e393-2a66736d00ff.png">

まずはコマンド実行前に証明書リポジトリから期限切れのものを削除します。
（一緒にプロビジョニングプロファイルも削除しました）

削除してから再実行すると新しい証明書とプロビジョニングプロファイルが生成され、証明書リポジトリにも保存されました。

![スクリーンショット 2024-05-18 17.45.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/df9c028c-17ba-a379-abe9-5f4d9fdc8392.png)

<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/7465bc0d-d47f-4cea-d4c4-6eecdcb41032.png">

ちなみにApple Developerの`Certificates, Identifiers & Profiles`は特に変更せずに実行しましたが、実行時に生成されるプロビジョニングプロファイルの名前が期限切れのものが存在することでシンプルなものから数字が後ろについたものになりまして、先に消してから実行した方がよかったなと思いました。。。

<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/e13dc1a5-7a83-e41a-e85b-74086b232562.png">

# おわりに

証明書の更新作業もほとんど手間要らずで最高でした。
本当はnukeコマンドも使ってみようかなと思ったのですが、`Certificates, Identifiers & Profiles`から手動で消すでもあまり手間は変わらないなと思ったのと、別アプリで使っている証明書も存在するのでやらずにしました。また機会があればで。

https://docs.fastlane.tools/actions/match/#nuke

# 参考
https://qiita.com/kotarella1110/items/840af2cf80aaea1fb035
LoRA: 大規模モデルを効率化する低ランク適応手法の革新

※ このページは「LORA: Low-Rank Adaptation of Large Language Models」の要約になります。

## このページでわかること

- 巨大な事前学習済みモデルを効率的に適応させるために、重みを固定し低ランク行列を注入するLoRA（Low-Rank Adaptation）手法を提案
- LoRAは学習パラメータを大幅に削減し、GPUメモリの使用量を減らしつつ、モデル品質を維持または向上させる
- 実験により、GPT-3やRoBERTaなどでの優れたパフォーマンスが確認された

## 対象読者
- 大規模な言語モデルの効率的な適応手法に関心があり、新しいアプローチや技術を理解し、研究や開発に活用したいと考えるエンジニアや研究者

## ファインチューニングの問題点

1. **大規模モデルの完全なファインチューニングの非効率性**：GPT-3のような巨大な事前学習済み言語モデルを特定のタスクに完全にファインチューニングする際の計算リソースおよびメモリのコストが非常に高い
   
2. **適応手法のトレードオフ**：現存する適応手法は、多くの場合、推論時の遅延を引き起こすか、利用可能なシーケンス長を減少させることで、モデルの品質と効率の間にトレードオフを生じる

3. **効率的な適応方法の欠如**：巨大な言語モデルを効率的に適応させつつ、モデル品質を維持または向上させる方法が不足している

## LoRA
### LoRA とは？

LoRA（Low-Rank Adaptation）は、巨大な事前学習済みモデルの全てのパラメータを再学習することなく、特定のタスクに適応させるための効率的な手法です。LoRAは事前学習済みのモデルの重みを固定し、トランスフォーマーアーキテクチャの各層に低ランク行列（ランク分解行列）を注入して、学習可能なパラメータの数を大幅に減らします。

### LoRA のメリット

1. **計算リソースの節約**：
   - 学習パラメータの数を10,000倍減らし、GPUメモリの必要量を3倍減らすことができる
2. **モデル品質の維持・向上**：
   - LoRAは、GPT-3やRoBERTaなどのモデルで完全なファインチューニングと同等またはそれ以上のパフォーマンスを示している
3. **追加の推論遅延なし**：
   - LoRAはアダプターと異なり、追加の推論遅延を発生させない
4. **タスク間の迅速な切り替え**：
   - 共有モデルを凍結し、タスクごとに小さなLoRAモジュールを入れ替えるだけで済むため、運用効率が向上する

### LoRA の手順
1. **事前学習済みモデルの重みを固定**：
   - 事前学習済みの重み行列 \(W\) を凍結し、これを更新しないようにする
2. **低ランク行列の注入**：
   - 各層の重み行列の更新を低ランク行列 \(A\) と \(B\) の積 \(BA\) で表現する
   - \(B\) は \(d \times r\) 行列、\(A\) は \(r \times k\) 行列で、\(r\) は低ランクの次元
3. **トレーニング**：
   - 学習中は、凍結された重み行列 \(W\) に対して低ランク行列 \(A\) と \(B\) のみを学習する
   - 学習可能なパラメータは \(A\) と \(B\) のみであり、元のモデルの重みは変更されない
4. **適応と推論**：
   - 推論時には、学習された低ランク行列 \(A\) と \(B\) を元の重み行列に加算することで、新しい重み行列 \(W + BA\) を得る
   - これにより、推論遅延を増加させることなく、モデルを適応させることができる

### LoRA の性能

1. **パフォーマンス**：
   - 実験により、LoRAはRoBERTa、DeBERTa、GPT-2、GPT-3などのモデルで、完全なファインチューニングと同等またはそれ以上のパフォーマンスを示した
2. **ベンチマーク**：
   - GLUEベンチマークでは、LoRAはRoBERTaやDeBERTaで優れたパフォーマンスを発揮
   - GPT-3では、WikiSQLやMultiNLI、SAMSumなどのタスクで完全なファインチューニングと同等以上の結果を示した
3. **効率性**：
   - 学習パラメータを大幅に削減し、GPUメモリの使用量を大幅に減らすことで、計算リソースの効率性を向上させた

## まとめ

以上が LoRA の要約でした。LoRA は現在では有名な手法ですが、具体的に何をやっているかを知らない方は簡単にでも知っておくとよさそうですね。

おわり。
AGP8以降からnamespaceはgradleへ

# はじめに
AGP8.0がリリースされたのは去年の4月ごろなのでもう1年が経過しているのですね。
本当にあっという間だと感じますが、AGP8以前はmanifestのnamespace設定は警告表示となっていました。
ですがAGP8からはgradleへの記述が必須になりましたので、詳細などを備忘録的にまとめたいと思います。

# gradleへ記述が必須となった背景
以前のAGPバージョンでは、アプリケーションIDとパッケージ名を区別していましたが、Manifestでパッケージ名が定義され、Gradle内でアプリケーションIDが設定される形となることで混乱を招くと判断し、Gradleへの記述が必須となったようです。

また、AGP 8.0以降では、プロジェクトごとに一意のnamespaceを指定することが必須になったことにより、コードとリソースが一貫性のある名前空間内で管理されるようになります。
それによりビルドパフォーマンスの向上するとのこと。

# 設定方法
これは非常に簡単で、app以下のgradleへnamespace設定を記述するのみです。

```app/build.gradle
android {
    namespace 'com.example.myapp'
    ...
}
```

また、モジュール単位でnamespaceを設定する必要がある点は注意が必要です。
ちなみにAGP8以上でnamespaceをmanifestへ記述していると、以下エラーが表示されます。

```
Namespace not specified. Please add 'namespace' to your module's build.gradle file.
```

# さいごに
RaspberryPi5で遊んでいますが、本当にパフォーマンス上がりましたねー
昔はだいぶしんどかったのに、もうミニPCとしても普通に使えるレベル、、、
無料版GoogleColabで13BのLLMを動かす方法（OOMにならない！/Fugaku-LLM-13Bも動いたぞォ！）

# 無料版GoogleColabで7Bや13BのLLMを動かす方法（OOMにならない！）

## 結論
bitsandbytes(量子化)で4bitや8bitでロードすればいい
(メモリの消費量が抑えられる代わりに、LLMの精度は落ちます)

AutoModelForCausalLM.from_pretrainedの引数に` load_in_8bit=True,`や` load_in_4bit=True,`を追加するだけ

(7Bはbitsandbytes使わなくてもGPUで動かせたため、消しました)

## 成功例

#### accelerateとbitsandbytesのインストール
なぜか、普通にインストールすると謎のエラーが出るので、おまじない（アンインストール＆インストール）を行う

```
!pip uninstall accelerate bitsandbytes -y
!pip install accelerate
!pip install -i https://pypi.org/simple/ bitsandbytes
```

### 13Bを4bitでロード


論理上動くはずって感じでしたが、富岳LLMも動きましたねェ～～
そして、4bitで読み込んでも回答はちゃんと返ってきた！


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911989/b324545e-b1dd-3e83-efa5-e4291f5dc69e.png)


#### ソースコード
※Fugaku-LLMは規約同意やらなんやらしないと使えないので、HuggingFaceにログインする必要があります

```python
from huggingface_hub import login
# HuggingFaceログイン
login("HF_TOKEN")
```

```python
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

model_path = "Fugaku-LLM/Fugaku-LLM-13B-instruct"
tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.bfloat16,
                                             device_map="auto", load_in_4bit=True,)
model.eval()

system_example = "以下は、タスクを説明する指示です。要求を適切に満たす応答を書きなさい。"
instruction_example = "スーパーコンピュータ「富岳」の名前の由来を教えてください。"

prompt = f"{system_example}\n\n### 指示:\n{instruction_example}\n\n### 応答:\n"

input_ids = tokenizer.encode(prompt,
                             add_special_tokens=False,
                             return_tensors="pt")
tokens = model.generate(
    input_ids.to(device=model.device),
    max_new_tokens=128,
    do_sample=True,
    temperature=0.1,
    top_p=1.0,
    repetition_penalty=1.0,
    top_k=0
)
out = tokenizer.decode(tokens[0], skip_special_tokens=True)
print(out)

```
【SwiftUI】Viewの@BindingプロパティをViewModelに渡す

# はじめに
Viewに渡された@BindingプロパティをViewModelで使用する場合、ViewModelのイニシャライザでBindingを受け取る必要がある

# コード
```View.swift
import SwiftUI

struct Item_Image_Select_V: View {
    @StateObject private var viewModel: ViewModel
    @Binding var data: String
    init(data: Binding<String>) {
        self._data = data
        self._viewModel = StateObject(wrappedValue: ViewModel(data: data))
    }
    // hogehoge...
}

```

```ViewModel.swift
import SwiftUI

extension Item_Image_Select_V {
    @MainActor class ViewModel: ObservableObject {
        @Published var dataVM = ""
        private var dataBinding: Binding<String>?
        init(data: Binding<String>) {
            self._dataVM = Published(initialValue: data.wrappedValue)
            self.dataBinding = data
        }
        
        func something() {
            // dataVMを処理し、自身のViewに反映。また、同様にdataBindingも更新し、親Viewに反映
            // つまり、２つのプロパティを更新する必要がある
        }
    }
}
```
EC2とRDSでWeb環境構築するよ！（最終回：Web環境の構築編）

EC2とRDSのWeb環境構築の最終回です。
第４回：RDS編はこちら
https://qiita.com/kikurage2030/items/82205ab72742a5ee5b85

## サービスの全体象
作りたいサービスの概要はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/00cd9bdd-7272-b7c8-213d-616e17591a30.png)

EC2にWebサーバを立ててPHPのプログラムがMySQLにアクセスしてテーブルの情報を表示する画面を作ります。
いわゆる一般的なWebシステムの構成でWebサーバはPublicサブネットに公開し、DBサーバはPrivateサブネットで冗長構成としてEC2のみのアクセスを許可する制御とします。また独自ドメインを取得してDNSでの名前解決も行えるようにします。

このシリーズで取り組む内容は
第１回：VPC・サブネット周りの作業
第２回：EC2の構築
第３回：Route53の登録　
第４回：RDSの構築
<font color=red>第５回（最終回）：Web環境の構築　ここ！</font>
を予定しています。今回は第５回（最終回）：Web環境の構築編となります。

<br>

## Web構築作業概要
EC2環境とRDS環境が作成されたので後はEC2のTomcat上で動くプログラムを作成して動作確認をするのみです。プログラムの実行環境であるPHPのインストール作業と簡易的なWeb画面の表示処理を実装し、WebサービスがRDSにアクセスして必要な情報を取得し画面に表示できることを確認します。



順序としては
1.PHPのインストール
2.PHPの簡易プログラムの実装
の順番で実施。



## 1.PHPのインストール
Webシステムが動作するためのランタイム環境（PHP）をインストールします。
EC2にログインして以下のコマンドを実行

PHPのインストールを実施
$sudo dnf install -y php php-mysqli php-fpm php-json php-devel php-gd

PHP関連のライブラリをインストール
$sudo yum install -y php php-mbstring

これでPHPのブログラムが動作する環境が作成されました。
<br>

## 2.PHPの簡易プログラムの実装
ここではMySQLにアクセスしてユーザーテーブルから情報を取得して画面に表示する簡易的な画面を作成します。
実装内容は以下の通りです。
```PHP:test.PHP
<?php
// MySQLの接続エンドポイント、ユーザー名、パスワードを定義
$dsn = 'mysql:host=aws-mysql-db.ctg84chzcg8w.ap-northeast-1.rds.amazonaws.com;charset=utf8mb4';
$username = 'admin';
$password = 'XXXXXXXXX';


// try-catch
try {
        // データベースへの接続PDOインスタンスを生成
        $pdo = new PDO($dsn, $username, $password);

        // SQL文
        $sql = "select user,host from mysql.user where user='rdsadmin'";

        // プリペアドステートメントを作成
        $stmt = $pdo->prepare($sql);
        $stmt->execute();
        $dataset = $stmt->fetch(PDO::FETCH_ASSOC);
        // 接続を閉じる
        //$pdo = null; 
} catch (PDOException $e) {
        // UTF8に変換します
        exit(mb_convert_encoding($e->getMessage(), 'UTF-8', 'SJIS-win'));
}
function escape1($str)
{
        return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
        <meta charset="utf-8">
        <title>DataSelect</title>
</head>
<body>

        <?php foreach ($dataset as $a) : ?>
                <?= escape1($a) ?>
        <?php endforeach; ?>

</body>
</html>

```
<br>
こちらのtest.phpファイルをApacheの実行環境フォルダに配置してあげます。(/var/www/html配下)




実行結果、MySQLで取得したユーザー名（rdsadmin）とホスト（localshot）の情報が画面に表示されました。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/555bebd5-3b80-e3b8-0464-2b6ab8fc1402.png)

以上で５回にわたって開設したEC2とRDS関係のWebサービスの構築概要の説明は以上です。
自社の勤怠入力をseleniumで自動化してみよう_Part1【環境構築編】

※本記事の対象OSは<font color="DarkOrange">Mac OS</font>になりますのでご留意ください。

## 背景
筆者が所属する会社の勤怠システムは、入力が少々手間のかかるもので、日々打ち込むのが面倒くさいなと思っていた。
ネットで検索したところ、seleniumというpythonのフレームワークを利用すると、ブラウザの起動からシステムへのアクセス、フォームへの入力などを自動化させることができる、との記事を見つけた。
筆者はJavaエンジニアでPythonの知見はまったくないが、せっかくなので挑戦してみることにした。

## 必要なツール
・<a href="https://zenn.dev/sawao/articles/e7e90d43f2c7f9">Homebrew</a>
・pyenv
・python
・selenium
・chromeDriver

■selenium
ブラウザ操作を自動化するためのフレームワークです。
Webアプリケーションのテストを目的としてリリースされました。その他にも、パソコン上で行う日常業務の自動化や、Webサイトの情報を収集して欲しい情報だけを抜き出すスクレイピングにも活用されています。

■chromeDriver
ブラウザを制御するためのドライバです。
ブラウザ操作を自動化するには、ブラウザごとに異なる専用のドライバが必要です。通常、パソコンにインストールされているブラウザとそのバージョンに合わせてドライバを用意する必要があります。

## Homebrew、pyenv、pythonのインストール

以下を参照。
<a href="https://www.kikagaku.co.jp/kikagaku-blog/homebrew-install-howto/#i-5">・Homebrewのインストール手順</a>

```bash:実際に入力したコマンド（Homebrewの設定）
# Homebrewのインストール
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# 環境変数設定（上記のコマンド結果にパスを通してくださいと表示されるので、 Add Homebrew to ~ に続く以下２つのコマンドを実行）
echo 'eval "$(/usr/local/bin/brew shellenv)"' >> /Users/[ユーザ名]/.bash_profile

eval "$(/usr/local/bin/brew shellenv)"

# 設定ファイルに出力されたか確認
vi /Users/[ユーザ名]/.bash_profile

# インストールできたか確認
brew -v
## →（出力結果）Homebrew 4.2.19

# 設定ファイル反映
source /Users/[ユーザ名]/.bash_profile

```

## pyenvとpythonのインストール
以下を参照
・<a href="https://prog-8.com/docs/python-env">pyenv、pythonのインストール手順</a>

※pyenv経由せずに直接pythonをインストールしたい方は<a href="https://qiita.com/omo_taku/items/bc97f69391b2f4627f36">こちら</a>参照

【注意事項】
・pythonのバージョンは３系であればなんでも良い。（筆者は 3.12.2 を指定）
・上記記事内で、pyenvの初期化の設定をするのだが、設定ファイル（.bash_profile / .bashrc / .zhrcなど）は、Homebrewの環境変数を記載したファイルと同じファイルを指定してあげる。（筆者は、<font color="Chartreuse">/Users/ユーザ名/.bash_profile</font> に追記した）


```bash:実際に入力したコマンド（pyenvの設定）
# pyenv インストール
brew install pyenv

# pyenv バージョン確認
pyenv -v

# pyenvの設定
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> /Users/[ユーザ名]/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> /Users/[ユーザ名]/.bash_profile
echo 'eval "$(pyenv init -)"' >> /Users/[ユーザ名]/.bash_profile

# 設定ファイル反映
source /Users/[ユーザ名]/.bash_profile
```
```bash:実際に入力したコマンド（pythonの設定）
# インストール可能なPythonのバージョン一覧
pyenv install --list

# バージョン3.12.2をインストール
pyenv install 3.12.2

# Python実行時このバージョンで実行されるよう設定
pyenv global 3.12.2

# バージョン確認
python --version

```



## seleniumとchromeDriverのインストール
以下を参照
https://doku-pro.com/chromedriver-mac-windows/#MacChromeDriver

【メモ】
Windowsの場合は、ブラウザのChromeとバージョンを合わせてあげる必要があるらしい


```bash:実際に入力したコマンド（seleniumの設定）
pip3 install selenium
```
```bash:実際に入力したコマンド（ChromeDriverの設定）
brew install chromedriver
```
※Chromeドライバーのバージョンが変更された場合、再度`brew install chromedraiver`を実行。そのバージョンにあったドライバーにしてくれる。

### ⇨ これでMacでの環境構築は完了。
robloxでassistant その59

# 概要
robloxでassistantやってみた。
練習問題やってみた。

# 練習問題
カメラを頭上からプレイヤーに追従させろ


# 手順
- replicatedfirstに、localscriptを追加。
- スクリプトを書く。
```

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local player = Players.LocalPlayer
local camera = game.Workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
RunService.RenderStepped:Connect(function()
	if player.Character then
		local character = player.Character
		local target = character:FindFirstChild("HumanoidRootPart")
		if target then
			camera.CFrame = CFrame.new(target.Position + Vector3.new(0, 10, -3), target.Position)
		end
	end
end)


```

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/d9d2ebf2-7095-7e33-a88e-369aa76310de.png)



以上。
opencv-pythonの「module 'cv2.dnn' has no attribute 'DictValue'」対策

# 1.はじめに

Pythonの`opencv-python`モジュールでバージョン4.8あたりから`module 'cv2.dnn' has no attribute 'DictValue'`というエラーが出始めたようで，筆者もこの問題に遭遇しました．

バージョンを下げるとか，エラー箇所をコメントアウトする　とか暫定対策的な記事が多かったですが，筆者の環境では解決ができましたので，記事に残すことにしました．

## 1-1.使用環境

- Windows11
- WSL2
- Ubuntu 22.04.1 LTS
- Dockerベースイメージ：nvcr.io/nvidia/pytorch:24.04-py3

# 2.対策

筆者の環境で効果があったのは，[こちらのコメント](https://github.com/opencv/opencv-python/issues/884#issuecomment-1806982912)でした．

筆者の場合は，`opencv-python-headless`ではなく`opencv-python`にしましたが，同様に問題は解決できました．

```bash
pip uninstall -y opencv
rm -rf /usr/local/lib/python3.10/dist-packages/cv2/
pip install opencv-python==4.9.0.80
```

- 1行目のuninstallですが，`nvcr.io/nvidia/pytorch:24.04-py3`にインストールされているのが`opencv-python`でない為か，uninstall対象として指定するのは`opencv`が正しいようです．
`opencv-python`でインストールされたものをuninstallする場合は，`opencv-python`を指定するのが正しいと思われます．
- 2行目のPythonバージョンと3行目の`opencv-python`のバージョンは各自の環境に合わせて改変してください

# 3.さいごに

根本対策に悩んでいる方の参考になれば幸いです．

# 4.関連リンク

- [module 'cv2.dnn' has no attribute 'DictValue' #884](https://github.com/opencv/opencv-python/issues/884)
    - バージョン下げたらいいよ　という対策 → https://github.com/opencv/opencv-python/issues/884#issuecomment-1684691124
        - 筆者はバージョンを下げられる状況になく，今回はこの対策を採用できなかった
    - 再インストールしたらいいよ　という対策 → https://github.com/opencv/opencv-python/issues/884#issuecomment-1806982912
        - 筆者の環境で解決の参考になった対策
    - `AutoFix()`を使ったらいいよ　という対策 → https://github.com/opencv/opencv-python/issues/884#issuecomment-1880049391
        - 都合により多重階層の深めのところでOpenCVのバージョン更新がされてしまう環境にあり，`AutoFix()`の挿入ができず，採用できなかった
    - コメントアウトしたらいいよ　という対策 → https://github.com/facebookresearch/nougat/issues/40#issuecomment-1888077509
        - ソースコードを触るのはちょっと・・・と思い，採用しなかった
配列を並べ替える

JavaScriptで配列を並び替える方法のメモ。
数値、アルファベットの場合は`sort`を使用します。
```js
const array = ['Delta', 'Bravo', 'Alfa', 'Charlie', 'Echo']
console.log(array.sort()) // ['Alfa', 'Bravo', 'Charlie', 'Delta', 'Echo']
```
降順の場合、
```js
const array = ['Delta', 'Bravo', 'Alfa', 'Charlie', 'Echo']
array.sort((a, b) => {
  if (a > b)
    return -1
  if (b > a)
    return 1
}) // ['Echo', 'Delta', 'Charlie', 'Bravo', 'Alfa']
```
数値の配列でも同じようにソートできます。
日本語の場合は`localeCompare`を使用します。
```js
const array = ["うし", "わに", "あひる", "みかん", "よっと", "いぬ", "かばん"]

// 昇順
array.sort((a, b) => a.localeCompare(b, 'ja'))
// 降順
array.sort((a, b) => b.localeCompare(a, 'ja'))

```

参考

https://devsakaso.com/javascript-sort-method-asccending-descending/

https://it7c.hatenadiary.org/entry/20160213/1455367099
パターン認識とは

『はじめてのパターン認識』の第1章の勉強メモです。

# パターン認識とは

パターン認識とは、物事の類型を知る働き、およびその内容。

|用語|説明|
|----|----|
|クラス|物事の類型|
|識別|クラスを判断すること|
|特徴抽出|有効な特徴を抽出すること|
|識別規則|クラスと有効な特徴を結び付ける規則|
|学習|識別規則を更新すること|
|特徴ベクトル|抽出された特徴を並べてベクトルの形にまとめたもの|
|学習データ|学習するために入力データとクラスの対応関係を表したデータ|
|汎化能力|学習データにはなかった未知の入力データ|

# 特徴の型

特徴は、以下に大別される

|特徴|説明|
|----|----|
|定性的特徴|非数値データとして抽出されたもの|
|定量的特徴|数値データとして抽出されたもの|

特徴は、そのデータの特性により、さらに複数の尺度に分類される。

|尺度|ラベル|順序関係|加減算|比例|
|---|:-:|:-:|:---:|:---:|
|名義尺度|〇|×|-|-|
|順序尺度|〇|〇|-|-|
|間隔尺度|-|-|〇|×|
|比例尺度|-|-|〇|〇|

定性的な特徴を計算机上で表現するためには２値変数で符号化する。この２値変数をダミー変数という。

# 特徴ベクトル空間と次元の呪い

適応制御において未知の複雑な関数を学習するために必要なデータが、次元の増加と共に指数関数的に増加することを**次元の呪い**という。

$d$次元単位超立方体の中心から頂点までの距離は
```math
D(d)=\left\{d\times \left(\frac{1}{2}\right)^2\right\}^{\frac{1}{2}}=\frac{1}{2}\sqrt{d}
```
となる。

# 章末問題

## 1.1

[下章](# 指紋認証について)を参照。

## 1.2

### (1)

[下章](#単位超立方体について)を参照。

### (2)

[下章](#単位超立方体について)を参照。

### (3)

$3$次元超立方体の$2$次元超平面(面)の個数は、問題式に則り、$_3 C_2 2^1=6$となり、正しい。
$1$次元超平面(辺)の個数は、$_3 C_1 2^2=12$となり、正しい。
$0$次元超平面(頂点)の個数は、$_3C_0 2^3=8$となり、正しい。

### (4)

$d$次元超立方体の超平面は$0$次元～$d-1$次元が存在するので、総数は$\sum_{m=0}^{d-1} \\ _dC_m2^{d-m}$個となる。

### (5)

```math
\begin{multline}
\begin{split}
\sum_{m=0}^{4} {}_5C_m2^{5-m}&= {}_5C_02^5+ {}_5C_12^4 +{}_5C_2 2^3+{}_5C_3 2^2+{}_5C_4 2^1\\
&=32+80+80+40+10\\
&=242
\end{split}
\end{multline}
```

# 単位超立方体について

$d$次元の単位超立方体とは、$d$次元ユークリッド空間$(x_1,x_2,\cdots,x_d)$において、$(x_1,x_2,\cdots,x_i,\cdots,x_d|x_i=\pm 1,\forall |x_n|\leq 1)$となる面の集合。

単位超立方体の$m(m< d)$次元の超平面は、残りの$d-m$次元の座標を$+1$または$-1$に固定した面のこと。その個数は、$m$個の次元の選び方$_d C_m$と残りの$d-m$次元の座標の取り方$2^{d-m}$より、$_d C_m 2^{d-m}$個となる。

単位超立方体の頂点は$0$次元の超平面のことなので、$_d C_0 2^d~2^d$個となる。

単位超立方体の面(ファセット)は$m-1$次元の超平面のことなので、$_d C_1 2^1=2d$個となる。

単位超立方体の辺は$1$次元の超平面のことなので、$_dC_12^{d-1}=d2^{d-1}$個となる。

単位超立方体の体積は、すべての直交する辺の長さを掛け合わせたもの。その値は、$d$次元で直交するする辺の数は$d$個で辺の長さは$1-(-1)=2$となるので、$2^d$となる。

単位超立方体の表面積は、すべての$d-1$次元超平面の体積を足し合わせたもの。その値は、$d-1$次元平面の体積は$2^{d-1}$でその個数は$_d C_1 2^1$となるので、$2^{d-1}\times_d C_1 2^1=d2^d$となる。

# 指紋認証について

指紋認証の方式には大きく分けて、特徴点(マニューシャ)方式、イメージマッチング方式、隆線特徴方式がある。
特徴点方式では、マニューシャと呼ばれる特徴点を求め、位置と属性を用いて類似度を計算する。イメージマッチング方式では、画像の類似度を計算する。隆線特徴方式では、小ブロックに分割して、そのブロック内の指紋の隆線の特徴を数値化して類似度を計算する。

マニューシャには、指紋の模様の途切れ(端点)や分岐(分岐点)を採用することが多い。

# Rの実行環境を整える

## Rをインストールする

- [Rの公式サイト](https://cran.r-project.org/)からインストーラをダウンロードする
- インストーラを実行し、すべて「次へ」で進める

## Visual Studio Codeで利用する

- Rの拡張機能をインストールする
    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3530831/103a2459-63b1-a7ca-d46a-5ccd24957d71.png)

- 「Ctrl」+「+」+「,」で設定を開き、「設定を開く」ボタンからsetting.jsonを開く
- 下のように、R.exeのパスを記載し、保存する

    ```json
    "r.rterm.windows": "C:\\Program Files\\R\\R-4.4.0\\bin\\x64\\R.exe"
    ```

# 参照

- [『はじめてのパターン認識』](https://www.morikita.co.jp/books/mid/084971)
- [指紋認証システム](https://www.jstage.jst.go.jp/article/itej1997/58/6/58_6_759/_pdf/-char/ja)
ABC354回答メモ

# 0.はじめに

　緑を維持できるよう気合を入れて臨みました。
 Cがやや難しかったですが、まぁ、順調にA~Cは解けました。
 Dは典型的な問題かと思いましたが、結局解き方が思いつかず
 時間切れとなりました。
 解説見たら行けるかと思いきや、ちょっと受け止め切れていない感じです。
 ただ、全体的な難易度が高かったのか、レートは+2とちょっと持ち直しました。


# 1.A - Exponential Plant
　サーッと呼ん、単純に２の日数-1乗で比較したら間違っていて
 前日分に加算することでうまくいきました。
 
　https://atcoder.jp/contests/abc354/submissions/53587600


# 2.B - AtCoder Janken 2
　問題を読んでもシチュエーションが全くしっくりこない感じでしたが
 心を無にして書いてある通りで実装しました。
 【考え方】
 　・SとCを読み込みCは合計Ｔを求めるため加算
 　・SはリストＬに格納し、後で昇順ソート
 　・SとCの入力後、ＴのＮmodをi取り、Lのｉ番目を表示して終了

　https://atcoder.jp/contests/abc354/submissions/53594461


# 3.C - AtCoder Magics
　シチュエーション的にはイメージがつかみやすい問題でした。
 実装となると、意外と悩みましたが、O(N)+ソートくらいでいけば
 大丈夫だろうと実装しました。
　前提として AとCはそれぞれ重複が無いというのを見落として
 若干複雑になった気はします・・・。
 
 【考え方】
 　・カードを強い順でならべる。
 　・一番強いカードは生き残りにいれる
 　・以降のカードは以前のカードのコストより小さかったら捨てる
 　・最後に生き残りをソートして出力

 【実装】（カードの強さとコストが同じ場合もある考えです）
  1.Nをインプット
  2.カード用リストLを空で初期化
  3.AとCを読み込みLに格納
  　格納方法：（強さ:A,コスト:C,カードの順番:i+1）をタプルでアペンド
　4.Lを降順ソート
　5.先頭の強さMAにLの先頭レコードの強さを格納
　6.直前の強さCAにLの先頭レコードの強さを格納
　7.直前の強さまでのコスト最小値CCに先頭レコードのコストを格納
　8.現在の強さ内でのコスト最小値CC2に先頭レコードのコストを格納
　9.回答用リストansに先頭レコードのカードの順番を格納
　10.Lを2レコード目から見ていく
　　-1.現在のレコードの強さがMAと同じとき
  　(強さが同じならコストが小さくても捨てないという勝手な仕様)
　　--1.現在のレコードの順番をansに追加
　　--2.CCに、CCと現在のレコードのコストの小さい方をセット
　　-2.現在のレコードの強さがMAと異なりかつCAと同じとき
　　--1.CCが現在のレコードのコスト以上の時
　　---1.現在のレコードの順番をansに追加
　　---2.CC2に、CC2と現在のレコードのコストの小さい方をセット
　　-3.現在のレコードの強さがMAとも異なりかつCAとも異なるとき
　　--1.CAに現在のレコードの強さをセット
　　--2.CCにCC2とCCの小さい方をセット
　　--3.CC2にCC2とCCの小さい方をセット
　　--4.CCが現在のレコードのコスト以上の時
　　---1.現在のレコードの順番をansに追加
　　---2.CC2に、CC2と現在のレコードのコストの小さい方をセット
　11.ansを昇順でソート
　12.ans内の要素数を出力
　13.ans内の値を出力

　無駄に複雑な実装になってしまいましたが、まぁAC頂けました。


　https://atcoder.jp/contests/abc354/submissions/53609884



以上
NestJSでX-Powered-Byヘッダーを非表示にする

NestJSでバックエンドアプリケーションを開発している最中、デバッグ中にコンソール画面でAPIレスポンスに`X-Powered-By: Express`ヘッダーが表示されていることに気づきました。

![APIレスポンス](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/2a7ad608-15e0-68c3-53ce-6a3e516ffb97.png)

このままでは攻撃者に技術スタックが特定されるリスクがあるので、`X-Powered-By`ヘッダーを非表示にする必要があります。

まず、ルートに次の記述があるはずです。

```typescript
const app = await NestFactory.create(AppModule);
```

次に、以下をインポートします。

```typescript
import { ExpressAdapter } from '@nestjs/platform-express';
import express from 'express';
```

最後に、以下のようにコードを修正します。

```typescript
const expressApp = express();
expressApp.disable('x-powered-by');
const adapter = new ExpressAdapter(expressApp);
const app = await NestFactory.create(AppModule, adapter);
```

これで、`X-Powered-By`ヘッダーが表示されなくなります。

![修正後のAPIレスポンス](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/d3e3913c-a7bb-3b53-04dd-3600d6739374.png)

以上の手順で、技術スタックを露見させずにアプリケーションのセキュリティを向上させることができます。

**※補足**
以下でもOKみたいです。

```ts
import { NestExpressApplication } from '@nestjs/platform-express'

const app = await NestFactory.create<NestExpressApplication>(AppModule)
app.disable('x-powered-by')
```
kubeadm＆flannelでKubernetesクラスタ構築した際のエラーとその解決策

## 目的
kubeadmでコントロールプレーン初期化後、flannelをデプロイした際に発生したエラーと
その解決法をご紹介します。

## 環境
- Oracle VM VirtualBox 7.0.12
- ゲストOS：CentOS7.9
- kubeadm：1.30.1
- flannel：0.25.1

![クラスタ構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3737555/f56e14ef-6822-ed05-37f5-5198e42f03d6.png)

## 実行したこと
### kubeadmでクラスタ作成
以下コマンドでコントロールプレーンノードの初期化を行いました。
(これが後のエラーの原因になるので記載します)

```
kubeadm init --apiserver-advertise-address=192.168.22.11 --pod-network-cidr=10.255.0.0/16
```

### flannelインストール
以下コマンドでflannelをデプロイします
```
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
```


flannelのPodが起動しているか確認すると、エラーになっていました。

```
# kubectl get pods --all-namespaces 
NAMESPACE      NAME                               READY   STATUS              RESTARTS       AGE
kube-flannel   kube-flannel-ds-vdxlk              0/1     Error               6 (4m6s ago)   7m33s
kube-system    coredns-7db6d8ff4d-5wwkg           0/1     ContainerCreating   0              12m
kube-system    coredns-7db6d8ff4d-mrmh8           0/1     ContainerCreating   0              12m
kube-system    etcd-master01                      1/1     Running             0              12m
kube-system    kube-apiserver-master01            1/1     Running             0              12m
kube-system    kube-controller-manager-master01   1/1     Running             0              12m
kube-system    kube-proxy-p8mxz                   1/1     Running             0              12m
kube-system    kube-scheduler-master01            1/1     Running             0              12m
```

### ログ確認
エラーの原因を探るため、Podのログを確認します。
```
# kubectl logs -n kube-flannel  kube-flannel-ds-vdxlk
(省略)
E0518 06:27:33.516770       1 main.go:333] Error registering network: failed to acquire lease: subnet "10.244.0.0/16" specified in the flannel net config doesn't contain "10.255.0.0/24" PodCIDR of the "master01" node
I0518 06:27:33.516792       1 main.go:422] Stopping shutdownHandler...
```
flannelで指定されたサブネット10.244.0.0/16はPodCIDRの10.255.0.0/24に含まれないためエラーが出ているようです。
flannelのyamlファイルをダウンロードして設定を確認してみると、確かに10.244.0.0/16が指定されていました。
```
# view kube-flannel.yml
(省略)
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }
(省略)
```

## 解決策
flannelで使用するサブネットは、コントロールプレーン初期化時に「--pod-network-cidr」で指定したサブネットを指定します。
今回は10.255.0.0/16を指定したので、flannelで指定するサブネットも10.255.0.0/16にしてみたところ、正常に起動しました。
```
# sed -i 's/10.244.0.0\/16/10.255.0.0\/16/' kube-flannel.yml

# kubectl apply -f kube-flannel.yml

# kubectl delete pods -n kube-flannel kube-flannel-ds-vdxlk

# kubectl get pods -n kube-flannel
NAMESPACE      NAME                               READY   STATUS    RESTARTS   AGE
kube-flannel   kube-flannel-ds-dfvmh              1/1     Running   0          8s
```
Redmine v5.1系で knowledgebaseプラグインの記事を検索する

# はじめに

Redmine v4系で使用していたknowledgebaseプラグインが、Redmineをv5系にバージョンアップするとknowledgebaseプラグインで記載した記事内容が検索でヒット出来なくなっていました。

コードを確認してRedmine v5系でもknowledgebaseプラグインの記事検索する方法がわかったので記録しておきます。

# テスト環境

* Redmine v5.1.2
    * ruby 2.7.8p225
* Redmine knowledgebaseプラグイン （本家はv5に対応しておらず、フォークされたものを使用）
    * https://github.com/yzzy/redmine_knowledgebase

# 修正箇所

上記 knowledgebaseプラグインの以下の場所を修正する。

``` ruby:redmine_knowledgebase/lib/redmine_knowledgebase.rb 修正前
Rails.configuration.to_prepare do
  Redmine::Activity.register :kb_articles
  Redmine::Search.available_search_types << 'kb_articles'
end
```

``` ruby:redmine_knowledgebase/lib/redmine_knowledgebase.rb 修正後
#Rails.configuration.to_prepare do
  Redmine::Activity.register :kb_articles
  Redmine::Search.available_search_types << 'kb_articles'
#end
```

どうやらRailsのバージョンが上がったことによる影響のようです。
修正方法も本当は参考文献のようにやるべきだと思いますが、固定環境でとりあえず動かす分には上記でなんとかなりました。

# 参考文献

* https://zenn.dev/tohosaku/articles/3ccdeb2f38bb07
S3バケットのコピーを作る

AWS Cloudfront のコンテンツのスナップショットを作るために、そのオリジンとしていたAWSのS3バケットのコピーのやり方を備忘として残しておきます。

# AWS CLI for Windowsをインストールする
WebブラウザからアクセスできるAWSの管理コンソールでは、S3バケットをコピーする機能がないため、コマンドラインインタフェース（CLI）を使います。ここではWindows PowerShell から使うために、AWS CLI for Windows をインストールします。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

AWSCLIV2.msi ファイルをダンロードしたら、手元のWindows 上で実行してインストールします。

インストールが済んだら、PowerShell を立ち上げて、インストールされたAWS CLI のバージョンを確認しておきましょう。

<pre>aws --version
aws-cli/2.15.53 Python/3.11.8 Windows/10 exe/AMD64</pre>

# S3のコピーに使用するIAMユーザを追加する
AWS CLIで使用するAWSのIAMユーザ（ここではcli-user）を作ります。今回はS3にアクセスするので、AmazonS3FullAccess ポリシーをそのユーザの権限としてアタッチします。

WebブラウザからAWS マネジメントコンソールにアクセスして、IAM(Identity and Access management)でユーザcli-userを作ります。

作った cli-userの「許可ポリシー」にAmazonS3FullAccess ポリシーをアタッチ（追加）します。

また、「アクセスキーを作成」から、AWS CLIでアクセスする際に使用するアクセスキーを作っておきます。アクセスキーを作ると、「アクセスキー」と「シークレットアクセスキー」のペアが作られるので、Windows 上で使うために控えて置きます。ここでは説明のために、次のキーが作られたと仮定して進めます。
アクセスキー：abcd1234abcd
シークレットアクセスキー: ABCD1234ABCD

# AWS CLIの環境設定
PowerShell上で、AWS CLIに必要な設定ファイルを作成します。
ホームディレクトリの直下に .awsディレクトリ（~/.aws）を作成して、この下にconfigファイル、credentials ファイルを作成します。
<pre>mkdir .aws</pre>

configファイルには、AWS CLIの出力フォーマット(output)と、使用するリージョン(region)を指定しておきます。

また、credentials ファイルにはアクセスキーとシークレットアクセスキーを指定します。

configファイルやcredentials ファイルには複数の設定を「プロファイル」として記載できるので、今回は「test」というプロファイル名で設定しておきます。

=====config=====
<pre>[test]
output = json
region = us-east-1</pre>

=====credentials=====
<pre>[test]
aws_access_key_id = abcd1234abcd 
aws_secret_access_key = ABCD1234ABCD</pre>

# S3バケットをコピーする
S3バケット間で直接コピーする方法がないので、S3バケットの内容を一度Windows にコピーして、そのコピーを別のS3バケットに再度コピーします。

説明のために、コピー元のS3バケットを s3://original.foo.bar、コピー先のS3バケットを s3://copy.foo.bar とします。

まずは、AWS CLI を使ってS3バケット s3://original.foo.bar からPC上のs3backup フォルダにコピーします。
<pre>aws s3 cp s3://original.foo.bar ./s3backup --recursive --profile test</pre>

続いて、PC上のs3backup フォルダのファイルをS3バケット s3://copy.foo.bar にコピーします。
<pre>aws s3 cp ./s3backup s3://copy.foo.bar --recursive --profile test</pre>
OpenStudioのチュートリアルを試してみる　その4

# 1. はじめに
先日[OpenStudioのチュートリアルを試してみる　その3](https://qiita.com/bebebefu/items/4a77143907e4e7c4c488)の記事にて、以下のリンクの動画シリーズで紹介されているOpenStudioを用いたfire station（消防署）のモデル作成・シミュレーションの5番目の動画についての手順を追っていきました。今回はこの動画シリーズの6番目の動画の手順を追っていきたいと思います。

https://www.youtube.com/playlist?list=PLRW2KXkdSVUdY2iQ6yjohNT5E5ElLVIhU

# 2. 実施環境
CPU: CORE i5 8th Gen
メモリ: 8GB
OS: Windows 11 22H2

# 3. 手順
本記事で内容・手順を追った動画（上記動画シリーズの6番目の動画）：

https://www.youtube.com/watch?v=0r1-arLaz20&list=PLRW2KXkdSVUdY2iQ6yjohNT5E5ElLVIhU&index=6

## 3.1 Weather Fileのダウンロード
デフォルトではWeather fileがないので以下の図で赤枠で囲んだリンク(https://energyplus.net/weather) に飛びます。
![6_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/07629848-680c-5f6f-be7d-e255bb49febb.png)


ここでは動画と同じようにNorth and Central America (WMO Region 4)＞USA＞Oregon＞Medford-Rogue Valley Intl AP 725970 (TMY3)＞Download ALL　と項目を選んでデータをダウンロードしてきます。

そしてダウンロードしたWeather fileをOpenStudioのフォルダに保存します。手順としてはCの直下にあるOpenStudioのフォルダ（openstudio-3.7.0）の中にある"EnergyPlus"のフォルダの中に"Weather"というフォルダを作ります。
そして"Weather"フォルダの中に先ほどダウンロードしてきたデータを以下の図のように保存します。
![スクリーンショット 2024-05-19 080308.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/cfaac66b-5bb0-f497-50bc-6394bbd5096b.png)


## 3.2 OpenStudioでのWeather Fileの読み込み
OpenStudioの画面の"Set Weather File"（下図で赤枠で囲んだところ）をクリックします。
![no6_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/9920f669-fd8e-1d8c-c692-cde0299deaf4.png)

そして先ほど保存したWeather Fileのepwファイルを以下の図のように選択して"開く"をクリックし読み込みます。
![スクリーンショット 2024-05-19 080642.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/c9ec9f65-2aea-399d-c88d-3073ce34c030.png)


## 3.3 Design Day Fileの読み込み
以下の図で赤枠で囲んだ"Import From DDY"をクリックします。
![no6_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/502b8fbe-1c97-58b8-4479-91e0c4888945.png)

そして先ほど保存したWeather FileのDDYファイルを以下の図のように選択して"開く"をクリックして読み込みます。
![スクリーンショット 2024-05-19 081052.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/4ece5dee-cce7-79a7-2b8d-70c3898c76ab.png)

そして以下の図が読み込みを完了した状態ですが、赤枠で囲んだ"Humidity"などのタブをクリックし情報が適正に読み込めているかを確認します。
![no6_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/7f030fda-ed94-3ac0-0377-9c59bacb1a50.png)

## 3.4 Daylight Saving Timeの設定
以下の図の赤枠で囲んだ"Daylight Saving Time"のところを"On"にします。詳細な設定は他の動画で行うそうなので、ここではまずOnにだけします。
![no6_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3581920/285860f9-9218-7826-a27e-772d8bf4d51e.png)

# 4. まとめ
とりあえずここまでも特にエラーなく進めることができました。なお、今回参考にした動画ではほかにもOpenStudioについての有用な機能の解説がなされておりました。しかしその動画の中ではOpenStudioの設定に反映することはなく、他の動画で設定方法も含め紹介されるとのことでしたので本記事では省略しました。
次回は動画シリーズの7番目：https://www.youtube.com/watch?v=RsLllMkMjqQ&list=PLRW2KXkdSVUdY2iQ6yjohNT5E5ElLVIhU&index=7 を実施していきたいと思います。
Javaで「変数宣言で型推論を利用する」の動作を確認してみた

# 概要

Javaで「変数宣言で型推論を利用する」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/var/index9.html

# 実装

以下のファイルを作成しました。
```JSample9_1.java
class JSample9_1{
  public static void main(String[] args){
    var old = 24;
    var name = "Yamada";

    System.out.println("年齢：" + old);
    System.out.println("氏名：" + name);
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample9_1.java 
$ java JSample9_1 
年齢：24
氏名：Yamada
```

# まとめ

何かの役に立てばと。
Proxmox8 を試してみる　その２０　ログイン画面を日本語/noVNC解像度の変更

# Proxmoxの使用を改善したい
Proxmoxを便利に使用していますが微妙に改善したいなというのが、以下２つ。改善する方法がわかったので残しておきます。
　・ログイン画面のデフォルト言語を ”日本語” にしたい。
　・noVNC解像度をフルHDに変更したい。

# ログイン画面のデフォルト言語を ”日本語” に変更
いつものログイン画面、英語がデフォルト。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/71149104-b40b-1b45-99c4-bed37f217aff.png)

どうやら `/etc/pve/datacenter.cfg` にデフォルト言語（Default GUI language.）を設定できるらしい。

https://pve.proxmox.com/wiki/Manual:_datacenter.cfg

```cmd
# vi /etc/pve/datacenter.cfg
language: ja
```

変わるかな？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/4239cba5-7d92-81c8-7d16-c8026c74b66e.png)

# noVNC解像度を フルHDに変更
仮想マシンを操作するときの noVNC は便利なのですが、デフォルトの解像度 "1280x800" 変更できないかな・・・できれば フルHD に。と思っていました。

まず、BIOS が `OVMF(UEFI)` に設定されていることが前提です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/15fcd3c2-326a-c7fa-e6b6-c7c4b81f5c17.png)

仮想マシンを起動するタイミングで ESCキーを押してBIOS設定画面に進めます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/2919f1f6-1506-40a5-121a-a5cfd4c45a2e.png)

Device Manager を選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/de02059f-4e07-3d00-af63-3ebc4df54367.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/4c683055-1561-1819-8ce3-be99ec4800c9.png)

OVMF Platform Configuration を選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/a3eb5686-e9c7-4125-145f-86189d0f79d4.png)

デフォルト解像度では "1280x800" ですので、この `<1280x800>` を選択すると 640x480 ～ 2560x1600 の解像度を選択することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/1fe6cf82-8d8a-9fed-9ad9-68e63f3232d4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/57c79631-20a3-6144-3b8a-9c003aa23c41.png)

Commit Changes and Exit にて保存。VMを再起動すると設定した解像度になります。 (^^♪

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/485a027c-a6a8-63f9-f148-4a48493d8bce.png)
Next.js 14 と microCMSで作る俺得RSSリーダー：企画〜機能洗い出し編

## 開発の背景・目的
毎朝のメディアチェックをどうにか簡易化できないかなぁと思ったのが発端。

ちょうどmicroCMSを勉強中だったので、ポートフォリオ作成ついでに開発を検討。

せっかくなので、ワタシが個人開発をするときの開発フローや設計手法などを公開。

## 個人開発フロー
ワタシが個人開発をするときのフローは以下の通り。

1. 企画
1. WF作成
1. ページ・機能洗い出し
1. 技術選定・設計
1. 開発
1. リリース・運用

通常のプロジェクトフローに比べると、要件定義~基本設計がWF作成にぎゅっと濃縮されている感じ。
個人開発をするときの多くは技術のキャッチアップがメインだったりするので開発しながらナレッジためて修正して...みたいなことを繰り返していくと設計しない方がいいまである。
（というか設計できるレベルの知見がない場合も多い。）

## 企画

本プロジェクトの企画案をまとめていきます。

### 企画概要：
「ワタシのワタシによるワタシのためのワタシ俺得RSSリーダー」

毎朝のメディアチェック、だるいよねワタシ。
たまにさぼっちゃうよねワタシ。

今の世の中にはRSSという素晴らしい技術がありながら今まで一回も使ったことがないので使ってみるのもありかな...?とか考えていたよね。

でも既存のRSSリーダーってちょっとださかったりするよね。
シンプルでスタイリッシュかつ+αの機能がついたものがあると嬉しいよね。

キャッチアップしたいものはNext14やReactのApp Router,microCMSなど。
基本的な技術はすでに得ているので、応用分野を公式ドキュメント見ながら作っていけたらいいなぁと。

## WF作成
WFもさくっと作ります。
自分的感覚ですが、WF作成に3h以上かけると開発意欲が低下するのとレイアウトを決めるのに迷走し始めるのでできるだけ"サクッ"と。

![RSS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531585/d569b696-2ee6-618a-be42-0d68e4c09849.png)

（1hくらいで作った）

## ページ・機能洗い出し

### ページ一覧
 - TOPページ
 - 検索結果ページ
 - RSS一覧
 - リンク別ページ
 - カテゴリ別ページ
 - 月別ページ
 - ブックマークページ

### 機能一覧
 - URIによるRSS取得
 - ブックマークフラグ
 - TOPページに表示するカテゴリフラグ
 - キーワードによる検索機能
 - カテゴリ機能

多分漏れもあるけど、こんな感じ。
実務と違って失敗しても怒られるわけじゃないけど、できるだけスムーズに開発できるよう、この辺は慎重に。

## 次回予告
ここまではアイディア段階なので、次回はきちんと形にできるように技術選定や設計段階に入っていきます。

理想は **"あとは書くだけ"** の状態になるまで設計を詳細化することですが、一人でやっていると漏れが必ずあるのでPMの方がいたらぜひコメントしてください
【AWS】ロードバランサーを運用する上で重要！ターゲットグループのヘルスチェックの基本と設定方法

# はじめに
ロードバランサーは、**複数のサーバー（ターゲット）に対して負荷を分散する仕組み**です。高い可用性と拡張性を実現する上で欠かせないツールですが、その運用には注意が必要です。特に重要なのが、ターゲットの健全性を監視する「**ヘルスチェック**」の設定です。今回は、ヘルスチェックの基本的な仕組みから、具体的な設定方法、ベストプラクティスまでを解説します。

# ターゲットグループとヘルスチェックの役割
ロードバランサーの構築では、まず負荷分散の対象となるターゲット（EC2インスタンスなど）を「**ターゲットグループ**」としてまとめます。ターゲットグループには、**同じ役割を持つターゲットを登録**します。
ロードバランサーは、ターゲットグループ内の「正常な」ターゲットにのみトラフィックを転送します。つまり、どのターゲットが正常で、どのターゲットが異常かを常に把握しておく必要があります。ここで活躍するのが「ヘルスチェック」です。
ヘルスチェックは、**ロードバランサーからターゲットに対して定期的に行われるリクエスト**です。応答内容に基づいて、各ターゲットの状態が「正常」か「異常」か判定されます。異常と判定されたターゲットには、ロードバランサーからのトラフィックが流れなくなります。

# ヘルスチェックの仕組み
ヘルスチェックの具体的な流れは次のようになります。

:::note info
**1**. ロードバランサーが、指定されたプロトコル（HTTP、HTTPS、TCP）とポートを使ってターゲットにリクエストを送信
**2**. ターゲットからの応答を一定時間（タイムアウト）待つ
**3**. 応答内容に基づいてターゲットの状態を判定
　**a**. 正しい応答があった場合は「正常」
　**b**. タイムアウトしたり、指定されたHTTPステータスコード以外の応答があった場合は「異常」
**4**. 一定回数の成功/失敗に基づいて、最終的なターゲットの状態を決定
:::

つまり、ヘルスチェックの設定では、リクエスト先のプロトコルやポート、パス（HTTP/HTTPSの場合）、タイムアウト値、実行間隔、異常/正常と判断する基準（しきい値）などを指定します。

# ヘルスチェック設定の変更方法
ヘルスチェックの設定は、ターゲットグループの作成時に行いますが、後からの変更も可能です。変更手順は以下の通りです。

:::note info
**1**. EC2管理コンソールにログインし、左ペインの「ロードバランシング」から「ターゲットグループ」を選択
**2**. 設定を変更したいターゲットグループをクリック
**3**. 「ヘルスチェック」タブを開き、「編集」ボタンをクリック
**4**. 必要な項目（プロトコル、パス、タイムアウト値など）を変更
**5**. 「変更内容の保存」ボタンをクリック
:::

変更内容は数分以内に反映されます。なお、コマンドラインから設定変更する場合は、**modify-target-group**コマンドを使用します。

# ターゲットのヘルスステータス
ヘルスチェックの結果は、各ターゲットの「**ヘルスステータス**」として表示されます。主なステータスは以下の通りです。

:::note info
**initial**：ターゲット登録直後、またはヘルスチェック開始直後の状態
**healthy**：ヘルスチェックに成功した状態
**unhealthy**：ヘルスチェックに失敗した状態
**unused**：ターゲットがターゲットグループに登録されていない状態
**draining**：ターゲットの登録解除作業中の状態
:::

これらのステータスは、EC2管理コンソールのターゲットグループ詳細画面や、**describe-target-health**コマンドで確認できます。ステータスがhealthy以外の場合は、その理由を示すエラーコードも表示されます。

# ヘルスチェック設定のベストプラクティス
最後に、ヘルスチェックを効果的に活用するためのポイントをまとめます。

:::note info
・**ターゲットの用途に合ったプロトコルとポートを使う**
　→ 例えばWebサーバーならHTTP/80、APIサーバーならHTTP/8080など
 
・**HTTP/HTTPSの場合、ヘルスチェック専用のエンドポイントを用意する**
　→ 処理の軽いシンプルなパスにする。レスポンスで過剰な処理が走らないよう注意

・**間隔は長めに設定する**
　→ ターゲットに過剰な負荷がかからないよう、60秒以上の間隔がおすすめ

・**異常しきい値は小さめに設定する**
　→ 2～3回の連続失敗で異常とみなすのが一般的

・**正常しきい値は大きめに設定する**
　→ 異常から復帰したターゲットを安全に運用に戻すため、5回以上の連続成功を条件とする

:::

以上を踏まえつつ、**実際のトラフィックパターンに合わせて設定値を微調整する**のが理想的です。状況に合わせて柔軟に設定を見直し、ターゲットの状態変化を的確に捉えられるよう努めましょう。
ヘルスチェックはロードバランサーを運用する上で重要な機能ですが、設定次第で大きな効果を発揮します。本記事を参考に、ぜひ最適なヘルスチェック設定を見つけてください。適切なヘルスチェックは、ロードバランサーの安定運用に大きく役立つはずです。

# 参考
https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/network/target-group-health-checks.html
robloxでassistant その58

# 概要
robloxでassistantやってみた。
練習問題やってみた。

# 練習問題
ドミノ倒しがしたい。

# 手順
- ServerScriptServiceに、scriptを追加。
- スクリプトを書く。
```

local workspace = game.Workspace
local a = 0
local add = math.pi / 12
local radius = 30
for count = 0, 30 do
	local p = Instance.new("Part", workspace)
	p.Size = Vector3.new(4, 8, 1)
	local x = math.cos(a) * radius
	local y = math.sin(a) * radius
	p.Position = Vector3.new(x, 4, y)
	p.Orientation = Vector3.new(0, a * 180 / math.pi * -1, 0)
	p.Anchored = false
	radius = radius + 0.3
	a += add
end


```

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/c21c067d-f16a-dc48-9dd7-e9294e01790b.png)


以上
!/bin/bashを記載しているのにentrypint.shでerrorが発生する場合の解決策

# !/bin/bashを記載しているのにentrypint.shでerrorが発生する場合の解決策

## 発生した事象
docker compose runでrails newをする際に、以下のエラーが発生
```
exec /usr/bin/entrypoint.sh: exec format error
```

## 原因
いろいろ調べてみて、entrypoint.shに#!/bin/bashを記載すると良いとかplatform: linux/amd64を指定してあげれば良いという記事があった。
どちらもやってみたが、解決はできなかった。

そこで、再度他の方が書いているentrypoint.shの記載と再度見比べてみる。一部違う部分があった。

## 解決策
他の方は一行目に#!/bin/bashが記載してあったが、エラーが発生したentrypoint.shは一行目に別のコメントを#で残していて２行目に#!/bin/bashを記載していた。

これを削除するとエラーが解決した。
```
# コメント　←　記載していた部分を削除
#!/bin/bash
set -e
```