OmniAICreator/Qiita-1.07M huggingface dataset:
【AWS】パブリックサブネットとプライベートサブネット

## パブリックサブネットとプライベートサブネットについて

### **パブリックサブネット**
通信がインターネットに直接出入りすることができるサブネット

### **プライベートサブネット**
通信がインターネットと直接出入りできないサブネット

### **〜関連知識〜**
#### ルートテーブル
サブネット間の通信経路を定義するための設定
どのIPアドレスへの通信に対して、どの経路を用いて接続するかを定義したもの
#### デフォルトルート
特定の宛先へのルートが存在しない場合に使用されるルート
エンジニアの働き方（テスト投稿）

## プロジェクトの流れ
エンジニアの仕事は、以下の流れで進みます。
<br>
1. **要件定義**: プロジェクトの目的と要件を明確にします。
2. **設計**: システムの設計を行います。
3. **実装**: コーディングを行います。
4. **テスト**: 作成したシステムをテストします。
5. **デプロイ**: システムを本番環境にデプロイします。

<br>

## コラボレーションとコミュニケーション
チームで協力するために、以下のツールを使用します。

- **GitHub**: コード管理
- **Slack**: チーム内でのコミュニケーション
- **Jira**: プロジェクト管理

<br>

## 技術スキルの向上
以下のような活動を行います。

- **勉強会**: チーム内での勉強会
- **オンラインコース**: オンラインコースやチュートリアル
- **コミュニティ参加**: 技術コミュニティへの参加

<br>

## まとめ
エンジニアとしての働き方は、プロジェクトの計画、コラボレーション、技術スキルの向上に注力しています。この記事を参考に、自分の働き方を効率的に行ってみてください。

---

<br>

### 参考文献
- [GitHub - Getting started](https://docs.github.com/ja/get-started)
- [Slack - Getting started](https://slack.com/help/articles/360000345063-Getting-started-for-new-users)
- [Jira - Getting started](https://www.atlassian.com/ja/software/jira/guides/getting-started/basics)
AIアプリ開発プラットフォームDifyで導入(docker-compose)とOllama連携

## Difyとは
[Difyドキュメント](https://docs.dify.ai/v/ja-jp)によれば、「DifyはオープンソースのAIアプリ開発プラットフォームです。Backend as ServiceとLLMOpsの理念を融合し、開発者が迅速にAIアプリケーションを構築できるようにします。同時に、プログラミングが得意でない方でも、自分のアイデアをすぐにAIアプリにできる直感的なインターフェースを提供しています」とのこと。
LLMを利用したアプリケーション開発は、とても大変だけど、Difyを使えば簡単に作ることができるよってことらしいです。

ところでLLMOpsとは何ぞや？

## LLMOpsとは？
Copilotに聞いてみたところこんな回答でした

>LLMOps（Large Language Model Operations）は、大規模言語モデル（LLM）の開発、デプロイ、保守を管理するための手法やベストプラクティスのセットです。これは、機械学習モデルの運用を管理するMLOps（Machine Learning Operations）に似ていますが、LLM特有の要件に対応しています。
>具体的には、LLMOpsは以下のようなステップを含みます
>
> - 基盤モデルの選択：事前にトレーニングされたLLMを選び、下流のタスクに適応させる
> - 精度改善：ファインチューニングやプロンプトエンジニアリングを通じてモデルの精度を向上させる
> - 評価指標の設計：LLMの性能を評価するための指標を設計し、モニタリングする
> - セキュリティとプライバシーの強化：不正アクセスやプロンプト・インジェクション攻撃からモデルを保護する
>LLMOpsを導入することで、LLMの性能を維持しつつ、効率的かつ安全に運用することが可能になります

つまり、LLMによる開発で考えなといけないたくさんのことを、フレームワークのような感じでまとめてくれているので、それに従って開発をしていけばうまくできるようにしているもの、ということですね。

## Dify導入
以下の環境で行っています
OS Windows 11
WSL Ubuntu22.04 WSLにはdockerインストール済み (※WindowsからDocker Desktopでインストールしています)

以下の[Difyのドキュメント](https://docs.dify.ai/v/ja-jp/getting-started/install-self-hosted/docker-compose)にDocker Composeデプロイがあるのでそちらを参照します。
ただ、これだとgitでクローンして、Dockerビルドするやり方となります。

そこで、DifyのGitHubサイトを見るとdocker-compose.yamlの例があるので、そちらを使います。

https://github.com/langgenius/dify/blob/main/docker/docker-compose.yaml

こちらをダウンロードして利用すれば簡単にDifyが起動できます。(--force-recreateがあると、都度作成するのでつけておくと便利です)
以下のポートを80のままだと、他で使用されているものがあると動かないので、とりあえず88とかにしています。8080とか9080とかにしているのをよく見ますね。
```yaml
  nginx:
    image: nginx:latest
    ...
    ...
    ports:
      - "${EXPOSE_NGINX_PORT:-88}:${NGINX_PORT:-80}"
```

```
docker-compose up -d --force-recreate
```

localhost:88にアクセスすると以下のような画面が表示されます。
特に指定のアドレスやパスワードはないので適当に登録してログインしましょう。
localhostなので、インターネットに接続することはなくローカルに保存されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/5fe0da0f-7497-19b3-4e9f-b9c406ef2e6b.png)

自由に触って、Difyを使ってみましょう。

## OllamaでローカルLLM
ログインして、設定画面に入ると、「モデルプロバイダー」があります。
その中に、Ollamaがあるので選択して、モデルを使用します。
以前の記事でOllamaをwslで使用できるようにしていますが、wsl上でOllamaが起動していれば、モデルが選択できるようになっているはずです。

https://qiita.com/mkuwan/items/ff84679ed8308ae78979

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/b3a6e671-7819-4b5c-5104-51edb39ef8f9.png)

Ollamaで動いていても、Difyでは現時点は、LLMかText Embeddingとしてしか利用できないようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/5783b3c1-1de7-4ace-34b0-372bf2450940.png)

wslと接続する場合ですが、Base URLをhttp://host.docker.internal:11434 にします。
これでDifyでOllamaが使えるようになります。

あとは自由に触っていきましょう
よきAI Lifeを！！
営業リスト作りが変わる！メールアドレスを一括取得する方法

メールマーケティングは、現在のマーケティングチャネルの中で注目すべき投資対効果（ROI）を示しています。メールアドレスは新規顧客獲得の基盤となるため、メールリードの生成はあらゆるビジネスにとって重要な取り組みです。

本記事では、ウェブスクレイピングを活用してリード獲得のためのメールアドレスを収集する具体的な方法をご紹介します。

<h2>メールマーケティングのメリット</h2>
世界のメールユーザー数は約40億人で、2025年までに46億人に達すると予想されています。この膨大なユーザーベースにより、メールは企業と顧客を結ぶコミュニケーション手段となっています。

ウェブスクレイピングを使えば、ウェブサイトからメールアドレスを一括で抽出でき、手作業でのコピー＆ペーストの手間が省けます。多数のメールアドレスを入手することで、メールを通じた直接的なマーケティングキャンペーンを展開し、より多くの顧客を引き付けることができます。

2024年においても、企業の87%がメールマーケティングを事業の推進力と考えており、38%の企業がメールマーケティング予算を増やす予定だと言います。

しかし、誰も迷惑メール、特に内容が画一的で無関係なものは好みません。そのため、動的コンテンツは、メールマーケティングチームが注力すべきカスタマイズ手法の筆頭に挙げられます。メールアドレスをスクレイピングすることで、製品やサービスに関心を持つ可能性の高い見込み客や組織を見つけ出し、カスタマイズされたマーケティングキャンペーンでターゲットを絞ることができます。

<h2>メールアドレス収集時の注意点</h2>


<h4>1. プライバシーと同意</h4>
ほぼすべてのウェブサイトにユーザープライバシー保護のポリシーがあります。明示的な許可なくメールアドレスをスクレイピングすることは、多くのプラットフォームでユーザープライバシーの侵害となる可能性があります。

<h4>2. 法的考慮事項</h4>
日本の個人情報保護法や特定電子メール法に違反する可能性があります。ウェブスクレイピングを始める前に、関連する法規制をよく理解しておく必要があります。

<h4>3. データの正確性と適合性</h4>
オンラインで収集したデータが必ずしも最新のものとは限らず、また商業目的での使用が許可されていない場合もあります。そのため、収集した情報から適切なアドレスを慎重に選別することが求められます。

<h2>メールアドレスの入手先</h2>

以下のような日本の主要プラットフォームがメールアドレス収集に適しています：

<ol>
<li>Indeedやリクナビ：日本の人材採用プラットフォームで、会社情報または採用条件を見つけられます。</li>
<li>LinkedIn：ビジネスプロフェッショナルのプロフィールを見つけられます。</li>
<li>Twitter：多くのユーザーがプロフィールにメールアドレスを記載しています。</li>
<li>GitHub：開発者のメールアドレスを見つけるのに適しています。</li>
<li>食べログやGoogleMaps：ショップオーナーや関連ビジネスのリードを見つけるのに使えます。</li>
</ol>

<h2>Octoparseでメールアドレススクレイパーの使い方</h2>

Octoparseは、コーディングスキルに関係なく誰でも使えるメールスクレイピングツールの一つです。以下の4つのステップで、簡単にメールアドレススクレイパーを構築できます。

1. 新しいタスクの作成
2. ページ上のメールアドレスの自動検出
3. ワークフローの作成とカスタマイズ
4. タスクの実行とスクレイピングしたメールアドレスのエクスポート

![octoparse screenshot-20240904-121646.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/7a3b890e-88be-6193-c4bf-30b5f8d5661d.png)


また、Octoparseはウェブサイトからデータをスクレイピングするためのプリセットテンプレートも提供しています。これらのテンプレートを使用すれば、わずかな必須パラメータを入力するだけで、追加のクリックなしで目的のデータを取得できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/5bcc7128-a319-77e3-8e88-158192812fd2.png)

[メールアドレスクローラー](https://www.octoparse.jp/template/email-social-media-scraper)

<h2>まとめ</h2>

メールアドレスは、マーケティングにとって今でも重要な資産です。潜在的な顧客やパートナーに直接リーチできるため、メールマーケティングは現在も広く活用されています。ウェブスクレイピングは、リード獲得のための最新のメールアドレスを収集する効率的で実用的なアプローチです。これにより、マーケティング活動の充実により多くの時間を費やすことができます。

[Octoparse公式サイト](https://www.octoparse.jp/)
Qiita の記事を書くということ

# はじめに
「インプットした知識は、自分でかみ砕いてアウトプットしないと意味がない」とか、「自己啓発のために」とか、そんな堅苦しい話をするつもりはありません。
本音ベースでいうと、「書け」という風潮から、書いているだけです。
とりあえず、書く、というスタンス。

Qiita の記事を書き始めて 1 カ月程度ですが、堅苦しい話は抜きにして、どうやって書いているか、雑に書きなぐっていきます。

繰り返しですが、意識高い系の話をするつもりはないので、そちらを希望の人は、別の記事を読んだほうが良いです。
ここまで見ていただいて、ありがとうございました。

# 書け、と言われても、ネタがねぇ。。。
うん。ないです。
なので、自分が興味を持ったことのメモを記事にしています。
文体はある程度考えますが、AI がどうにかしてくれます。

私の場合、仕事で Office 製品を扱うことが多いので、そのメモが多めかもしれません。
昔は開発をやっていたこともあって、VSCode も興味があったので触ってみたメモを書きました。
なんか、開発者向けの環境がそろったものを無料提供されていたので、触ってみた感想を書きました。
まぁ、バラバラです。

自宅で音楽サーバーを作りたくなったので、そのあたりのメモを投稿するかもしれません。
(Raspbery PI が余っているのと、昔のそこそこいいスピーカーが余っているので使いたいなと思っただけ。記事のため、なんて、これっぽっちも思っていないです。)

# でも、こんな内容で投稿したら、恥ずかしいよ・・・
うん、思ってた。
けど、見ないですよ。
というか、興味なかったら、ブラウザで戻るボタン押されるだけです。
なので、「こんな内容かよ」って思っている人はそもそも見ません。
見られないのだから、恥ずかしい、なんて気にする必要なし。
だって、見られないんだもの。

# メモっていっても、あれもこれも、と大量になっちゃう
まぁ、大量になってもいいと思います。
自分はめんどくさいので、まずゴールを決めて細切れにします。
だって、メモって、大量に書かないでしょ。ポイントだけ書くでしょ。
で、条件が変わるなり、分岐があったら、メモを分けるでしょ。
その感覚。
先輩の記事から盗んだけど、「前提」とか見出し作って、その「メモ」に書く前提を書きまくる。
前提が多ければ多いほど、小さくできる。

とっ散らかったら、目次ページ作ればいいだけ。
細切れにすれば、書きやすい。


# でも、マークダウンとか意味わからんって・・・
ぶっちゃけ、使わなくてもいいと思う。
せいぜい、「#」くらいで。
このメモも、「#」しか使っていないので、シンプルでしょ。
なんか、装飾したいなー、と思ったら、この辺りを開いておけばいいかと。

https://qiita.com/Qiita/items/c686397e4a0f4f11683d

自分は、記事を書くタブとは別のタブに開いていたりします。

# さいごに
まぁ何だろう。
この手のものって、自分の中でハードル上げたり、完璧を求めたりしすぎないほうがいい。
(以前、上司に言われた言葉。)
それもあって、自分の中ではメモです。
【資格】LinuCレベル3 303 Security 取得への冒険譚

## はじめに

ますだです。
普段は AWS 案件の保守や運用辺りを担当してます。  
今回、LinuCレベル3 303 Security に合格したので、アウトプットも兼ねて学習方法や期間についてゆるっと書いてみます。
(語ることが少ないため薄味です)

---

## ざっくり纏め

- **LinuCレベル3 303 Security**：[公式](https://linuc.org/linuc3/303.html)
- **合格ライン**：520 点 (65 ～ 75 ％ 程度)
- **結果**：626 点 (≒ 78 %)
暗号化 64 % (17 問)
ホストセキュリティ 87 % (16 問)
アクセス制御 90 % (10 問)
ネットワークセキュリティ 76 % (17 問)
- **学習期間**：2024-08-19 ～ 2024-09-04 (17 日間)
- **教材**：[Ping-t](https://mondai.ping-t.com/g) (これだけ)
---

## スペック

- 業界未経験からキャリーバック片手に上京して 5 年
- AWS サービスに触れる機会多め
- AWS セキュリティに関わる設計等の経験あり
- ただ 303 範囲の技術はほぼ未使用
- 頭は良くないので勉強は時間と量でごり押しタイプ

---

## 受験のきっかけ

1. **レベル 3 取っとけ**  
   大半の理由がこれです。
   レベル 2 だと中途半端だし、負荷低そうなのでさっくりと。
2. **セキュリティ知識の深化に向けて**  
   DB・ネットワークとお勉強を進めてきたので、サーバサイドのセキュリティも基礎固めしたかったため。
3. **情報処理安全確保支援士の足掛かり**  
   秋試験まで期間が空きそうだったので繋ぎに。
---

## 学習方法

問題演習のみ (Ping-t)。
ザ・王道。ほんとに語ることもないです。
ちなみに日々の経過を ChatGPT に落として、よしよし褒めて貰いながら進めていました。

1 週目の結果：2 割
2 週目の結果：422 / 477 正解 (88.4%)
3 週目の結果：457 / 477 正解 (95.8%)

あとPing-t のコマ問は 4 周くらい通してます。
(疲れた時にキーボードカチャカチャ楽しい)

前回の CCNA の時にスケジュールを詰め込み過ぎていた & 予定勉強期間にプライベートの用事が重なっていたため、1 週間見積りを甘く期間を取っていました。

## 少しだけ感想
- コマンドは結構簡単
- 時間も余裕あるし、試験範囲も狭い
- レベル 2 受かってる人ならついでに取った方がよいよ
- 他は特になし！ (合格体験の記事数が少ないのも分かる気が)

---

## まとめ + 次にやろうかなーてきなこと
  
- **今後の学習予定**  
  10 月の 情報処理安全確保支援士 (本命)。
　午前 2 がちょろそうなので、午前 1 を移動時間で解きつつ、午後に全力ですかね。
 　ちなみに IT パスポートしか持ってない人です。

`(市場は荒れてますが、淡々と毎月 10 万積み立て民です。放置が一番。)`

---

以上、LinuCレベル3 303 Security に合格するまででした。
少しでも参考になれば嬉しいです！
【AWS認定合格記】AWS デベロッパーアソシエイト(DVA-C02)

## はじめに
:::note warn
受験は今から約半年も前のことになりますが、当時の勉強方法などの備忘録を記載しています。
:::


軽く自己紹介すると、、
◆学部卒(非情報系)
◆新卒でSIerに入社し、3年目。
◆取得資格
| 資格名 | 取得日 |
|:-----------|:-----------|
| 基本情報技術者 | 2021年11月  |
| AWS クラウドプラクティショナー | 2023年2月 |
| AWS ソリューションアーキテクトアソシエイト | 2023年7月 |
| AWS ソリューションアーキテクトプロフェッショナル | 2024年3月 |
| AWS デベロッパーアソシエイト | 2024年3月 |
| AWS sysOps Administrator アソシエイト | 2024年4月 |


:::note info
sysOpsAdministratorアソシエイトを取得するまでは、業務ではAWSに携わったことはありませんでした。
:::



## 勉強方法
使用した問題集は、**CloudTechのみ**でした。

 https://kws-cloud-tech.com/

個人的なCloudTechの使い方は以下。
　①まずは、CloudTechの問題に目を通してみる。
　②分からないワードを調べる。
　③答えを見てなぜその答えなのか、解説を読む。分からないところは調べる。
　④全ての問題で①〜③を行う。
　⑤実際に答えを見ずに解けるか確認する。



## 勉強期間
合格までに要した期間は**約2週間**。

平日：約3時間〜4時間
休日：約7時間~9時間

ざっくりの計算で**約70時間ほど**でした。

DVAの受験1週間前にSAPを取得しており、ほぼSAPと同時並行で勉強していました。



## 試験当日

| 時間 | 流れ |
|:-----------|:-----------|
| 13:30 | 試験開始|
| 15:00 | 試験終了|
| 翌朝3時 | 合格通知メール届く|　


試験は140分間ですが、1時間半ほどで解き終わりました。

試験終了後の感覚としては、1週間前に受けたSAPよりcloudtechと似たような問題が出たので、少し手応えは感じていました。

https://aws.amazon.com/jp/certification/certified-developer-associate/

## モチベーションの保ち方
1週間前にSAPに受かっていたため、このまま一気に何個か取っていこう！と当時は勝手にモチベーションが上がっていました。
自分は、1つ難しい資格を取った後は、自然とモチベーションが上がる性格だったようです。

## 受験〜合格しての所感
### ついに4つ目！安心！
当時、4月以降に次のPJが決まるため、PJを上司が決めるまでになるべく多く資格を取って、少しでもAWSのやる気があるアピールがしたかったので、嬉しいというよりも安心の気持ちが大きかったように思います。
ROS 2 HumbleでLD19を使いたい！

## はじめに

最近流行りの小さいLIDARことLD19をROS 2 Humbleで利用する際の手順記録です．

### 2025年2月12追記

ROS2 JazzyおよびAmazonで売ってる安い方のLIDARでも[動作確認できたとコメント](https://qiita.com/B-SKY-Lab/items/53bd08e63080c25f33e6#comment-ed3104567cfd5b55bf8a)をいただきました！
お使いの方はスクロールしてご確認ください．

## 前提

ROS 2 Humbleの環境構築が済んでいること

## 使用機器など
- LIDAR: LD19 ([スイッチサイエンス販売ページ](https://www.switch-science.com/products/8599))
- OS: Ubuntu 22.04
- ROS: ROS 2 Humble


## ldrobot-lidar-ros2のビルド

基本的にはREADMEの手順に従えば良い．

### リポジトリのクローン

```bash
cd ~/ros2_ws
git clone https://github.com/Myzhar/ldrobot-lidar-ros2.git
```

### udevルールの設定

```bash
cd ~/ros2_ws/src/ldrobot-lidar-ros2/scripts/
./create_udev_rules.sh
```
`ls /dev/tty*`
`/etc/udev/rules.d`が見つからない旨のエラーが出た場合は以下を実行してから再度↑のコマンドを叩く．

```bash
sudo mkdir -p /etc/udev/rules.d
sudo apt install udev
```
### 関連パッケージのインストール


```bash
sudo apt update
sudo apt install libudev-dev
sudo apt install ros-${ROS_DISTRO}-diagnostic-updater
sudo apt install ros-${ROS_DISTRO}-nav2-util
```


### ビルド

```bash
cd ~/ros2_ws/
rosdep install --from-paths src --ignore-src -r -y
colcon build --symlink-install --cmake-args=-DCMAKE_BUILD_TYPE=Release
```

以下のようにエラーなく`3 packages finished`で終わればビルド成功です．

```
Starting >>> ldlidar_component
Finished <<< ldlidar_component [0.18s]                     
Starting >>> ldlidar_node
Finished <<< ldlidar_node [0.15s]                  
Starting >>> ldlidar
Finished <<< ldlidar [0.09s]                  

Summary: 3 packages finished [0.65s]
```



## LD19を使う

### ビルド結果の読み込み

以下のコマンドでビルド結果へパスを通す．

```bash
cd ~/ros2_ws/
source install/setup.bash
```

### デバイス名の設定を変更

設定ファイルを開く．vim以外のエディタに読み替えてもよい．

```bash
cd ~/ros2_ws/
vim install/ldlidar_node/share/ldlidar_node/params/ldlidar.yaml 
```

`comm`以下の`serial_port`の値を実際に接続されているデバイス名に変更する．以下の例では`/dev/ttyUSB0` に変更している．

デバイス名は`ls /dev/tty*`などのコマンドで確認できる．LD19を抜き差しする前後で`ls /dev/tty*`を叩き，増減した差分がLD19のデバイス名である（はず）．

```
/**:
  ros__parameters:
    general:
      debug_mode: true # true to activate debug messages

    comm:
      serial_port: '/dev/ttyUSB0' # serial port name
      baudrate: 230400 # serial baudrate
      timeout_msec: 1000 # data communication timeout in msec
（以下略）
```

### LIDARノードの実行

以下のコマンドで設定ファイルを読み込みながらLIDARのノードを起動できる．
`ros2 run`での起動は推奨されていない．

```bash
ros2 launch ldlidar_node ldlidar.launch.py
```

### LIDARノードをactivateする

前述のコマンドで実行した直後の`ldlidar_node`はinactivate状態であるため，以下のコマンドでactivateすることでスキャン結果のtopicがpublishされるようになる．tmuxの別ペインやterminalの別タブなどで以下を実行する．

```
ros2 lifecycle set /ldlidar_node configure
ros2 lifecycle set /ldlidar_node activate
```


### rviz2の実行

```bash
ros2 launch ldlidar_node ldlidar_rviz2.launch.py
```

以下のようにスキャンした点群が表示されれば成功です！お疲れ様でした．
（画像は見やすいように`Size(Pixels)`をデフォルトの3から10に変更しています）

![Screenshot from 2024-09-04 18-39-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1490597/95d19edb-3ab7-ff6b-07f3-7e7b6b2d219e.png)
Java Gold 例題 ジェネリクス

次のコードについて、正しい選択肢を選んでください

```java
HashSet<Short> set = new HashSet<>() {{
     add((short)0);
     add((short)1);
     add((short)2);				 
}};
		 
for(short i = 1; i <= 3; i++) {
    set.remove(i - 1);
}
		 
System.out.println(set);
```
1. [0, 1, 2]が出力される
1. 何も出力されない
1. []が出力される
1. コンパイルエラー
1. 実行時エラー

<details><summary>解答</summary>

正解: 1
```
[0, 1, 2]
```

{}の中はインスタンス初期化ブロックで、このブロック内でaddメソッドを使ってセットに要素を追加しています。
この時点で、setには`Short`型の0, 1, 2の3つの要素が含まれています。
`remove(i - 1)`では`short`と`int`の式なので`Integer`にボクシングされます。
HashSetではShort型を扱いますが、`Integer`オブジェクトを削除しようとしているため、`remove`は何もしません。
`Collection<E>.remove(Object obj)`では、どんなオブジェクトでも削除できますが、それが予期せぬ結果を招くことがあります。

:::note
[`EXP04-J. オートボクシングされた値が想定した型を持つようにする`](https://www.jpcert.or.jp/java-rules/exp04-j.html)
:::

要素を削除する場合、`remove()`の引数を明示的にキャストする必要があります。
```java
set.remove((short)(i - 1));
```

出力
```
[]
```

</details>


https://qiita.com/T-ngtj/private/df254aacd05be698199a
🚀 Just Launched: PCNSA Exam Questions Now Available on Our Website!

🔗 [https://awslagi.com/course/pcnsa/](#)

Are you preparing for the **PCNSA: Palo Alto Networks Certified Network Security Administrator** exam? We’ve got great news for yo![PCNSA Palo Alto Networks Certified Network Security Administrator.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442951/0f81406f-420e-a315-aa5f-6d466363f7c2.jpeg)
u! Our website has just published a comprehensive set of **practice exam questions** tailored specifically for the PCNSA certification.

### Why These Practice Questions Are Essential

- **Authentic Exam Experience**: Our questions mirror the actual exam format, helping you familiarize yourself with the types of questions you'll face on test day.
  
- **Up-to-Date Content**: The cybersecurity landscape is ever-changing, and so are the certification requirements. Our questions are updated regularly to reflect the latest exam objectives and industry trends.

- **Detailed Explanations**: Each question comes with in-depth explanations to ensure you understand the concepts, not just memorize the answers.

### Benefits of Earning the PCNSA Certification

- **Boost Your Career**: As a certified Network Security Administrator, you'll be recognized as a knowledgeable and skilled professional in the cybersecurity domain.
  
- **Enhance Your Skills**: The PCNSA certification helps you master the deployment, management, and troubleshooting of Palo Alto Networks’ security systems.
  
- **Industry Demand**: With cyber threats on the rise, organizations are in dire need of qualified professionals to protect their networks. This certification makes you a valuable asset.

### Who Should Take This Exam?

- **Aspiring Network Security Professionals**: Whether you're just starting in cybersecurity or looking to specialize, this exam is a critical step in your career path.
  
- **IT Administrators**: If you're managing network security in your current role, the PCNSA certification will validate your expertise and potentially open doors to advanced opportunities.

### Get Started Today!

Don't leave your exam preparation to chance. Visit our website now to access the newly published **PCNSA exam questions** and take your first step toward certification success. Practice makes perfect, and with our resources, you're well on your way to acing the exam.
【メモ】PythonでiRICのソルバーを作る際の格子の配列について

# はじめに
よく忘れるので自分用のメモです。

# 本編

CGNSから読み込んだ際の格子点の属性の配列は1次元の配列で返ってきます。
その時のデータのインデックスは以下のようになり、列優先で返ってくる仕様となっています。

```python
# --------------------------------------------------
# CGNSから読み込む時は1次元配列、順番は以下
# --------------------------------------------------
#      j
#      ↑
#     4| 24, 25, 26, 27, 28, 29
#     3| 18, 19, 20, 21, 22, 23
#     2| 12, 13, 14, 15, 16, 17
#     1|  6,  7,  8,  9, 10, 11
#     0|  0,  1,  2,  3,  4,  5
#       ----------------------- →　i
#         0   1   2   3   4   5
# --------------------------------------------------
```


試しに下記のようなコードで、以下の(11*6)の格子の格子点のx座標、y座標を読み込んでみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626673/51257ec7-7f41-5e02-6231-4215d6787580.png)


```python
import iric

# ファイル名を指定(デバッグ用)
cgns_name = ".\project_py\Case1.cgn"

# CGNSを開く
fid = iric.cg_iRIC_Open(cgns_name, iric.IRIC_MODE_MODIFY)

# 格子サイズの読み込み
isize, jsize = iric.cg_iRIC_Read_Grid2d_Str_Size(fid)
print("isize=" + str(isize) + " jsize=" + str(jsize))

# 座標の読み込み
grid_x_arr, grid_y_arr = iric.cg_iRIC_Read_Grid2d_Coords(fid)
print("grid_x_arr")
print(grid_x_arr)
print("grid_y_arr")
print(grid_y_arr)
```

すると11行6列の格子点の座標は以下のように列優先で読み込まれていることが確認できました。

```
isize=11 jsize=6
grid_x_arr
[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9. 10.  0.  1.  2.  3.  4.  5.  6.
  7.  8.  9. 10.  0.  1.  2.  3.  4.  5.  6.  7.  8.  9. 10.  0.  1.  2.
  3.  4.  5.  6.  7.  8.  9. 10.  0.  1.  2.  3.  4.  5.  6.  7.  8.  9.
 10.  0.  1.  2.  3.  4.  5.  6.  7.  8.  9. 10.]
grid_y_arr
[0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.2 0.2 0.2 0.2 0.2 0.2 0.2
 0.2 0.2 0.2 0.2 0.4 0.4 0.4 0.4 0.4 0.4 0.4 0.4 0.4 0.4 0.4 0.6 0.6 0.6
 0.6 0.6 0.6 0.6 0.6 0.6 0.6 0.6 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8
 0.8 1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1. ]
```

ただ、実際にプログラム内で計算する時は$(i,j)$で指定したいことが多いので2次元配列に変換したい。
しかしpythonは行優先の言語のため変換する際には行列を逆に変換したうえで、行列を入れ替えることで2次元はいい列に変換を行う。
```py
# 格子の形に整形
grid_x_arr = grid_x_arr.reshape(jsize, isize).T
grid_y_arr = grid_y_arr.reshape(jsize, isize).T

print("Reshaped grid_x_arr")
print(grid_x_arr)
print("Reshaped grid_y_arr")
print(grid_y_arr)

```

```:出力結果
Reshaped grid_x_arr
[[ 0.  0.  0.  0.  0.  0.]
 [ 1.  1.  1.  1.  1.  1.]
 [ 2.  2.  2.  2.  2.  2.]
 [ 3.  3.  3.  3.  3.  3.]
 [ 4.  4.  4.  4.  4.  4.]
 [ 5.  5.  5.  5.  5.  5.]
 [ 6.  6.  6.  6.  6.  6.]
 [ 7.  7.  7.  7.  7.  7.]
 [ 8.  8.  8.  8.  8.  8.]
 [ 9.  9.  9.  9.  9.  9.]
 [10. 10. 10. 10. 10. 10.]]
Reshaped grid_y_arr
[[0.  0.2 0.4 0.6 0.8 1. ]
 [0.  0.2 0.4 0.6 0.8 1. ]
 [0.  0.2 0.4 0.6 0.8 1. ]
 [0.  0.2 0.4 0.6 0.8 1. ]
 [0.  0.2 0.4 0.6 0.8 1. ]
 [0.  0.2 0.4 0.6 0.8 1. ]
 [0.  0.2 0.4 0.6 0.8 1. ]
 [0.  0.2 0.4 0.6 0.8 1. ]
 [0.  0.2 0.4 0.6 0.8 1. ]
 [0.  0.2 0.4 0.6 0.8 1. ]
 [0.  0.2 0.4 0.6 0.8 1. ]]
```
AWS SDK使用部分をエミュレートするmotoライブラリの注意点、実装方法について

# はじめに

今回はpythonでwebAPIの実装後、テストコードを書く際に、motoのバージョン5.x以降で記載方法が変わっているので、そちらについてまとめました。

# motoとは
motoは、AWSサービスに向けた処理をモックするためのPythonライブラリ(サードパーティ)です。

DynamoDBやS3などに向けた処理を実際のAWS環境を用意せずともローカル環境で完結して、テストコードの実行が可能になります。

# 実装方法について

以下のリリースノートに記載の通り、以前のデコレーターの記載方法である「@mock_dynamodb」などのサービス毎に指定した記載方法ではなく、「@mock_aws」 に統一されたそうです。

■リリースノート
https://docs.getmoto.org/en/5.0.0/docs/releases.html

以下はS3に向けたバケット作成の処理をモック化する場合のソースです。
例1 直接使用する場合
```py
import boto3
from moto import mock_aws
from mymodule import MyModel

@mock_aws
def test_my_model_save():
    conn = boto3.resource("s3", region_name="us-east-1")

    conn.create_bucket(Bucket="mybucket")
    model_instance = MyModel("steve", "is awesome")
    model_instance.save()
    body = conn.Object("mybucket", "steve").get()["Body"].read().decode("utf-8")
    assert body == "is awesome"

```
例2 withステートメントを使用した場合
```py
import os
import yaml

import boto3
import pytest
from moto import mock_aws

from you_dir import lambda_handler

# credentials ダミーデータ設定
@pytest.fixture()
def aws_credentials():
    os.environ["AWS_ACCESS_KEY_ID"] = "testing"
    os.environ["AWS_SECRET_ACCESS_KEY"] = "testing"
    os.environ["AWS_SECURITY_TOKEN"] = "testing"
    os.environ["AWS_SESSION_TOKEN"] = "testing"
    os.environ["AWS_DEFAULT_REGION"] = "ap-northeast-1"

# モック化
@pytest.fixture()
def aws(aws_credentials):
    with mock_aws():
        yield boto3.client("dynamodb", region_name="ap-northeast-1")

# テストデータ
def load_yaml(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        return yaml.safe_load(file)

# テーブル作成
@pytest.fixture()
def init_dynamoDB(aws):
    test_data = load_yaml('test_data.yaml')

    # インスタンス生成
    dynamodb_client = boto3.client('dynamodb')

    for table_info in test_data['dynamodb']['tables']:
        table_name = table_info['name']
        table_schema = table_info['schema']
        table_data = table_info['data']

        table_result = dynamodb_client.create_table(
            TableName=table_name,
            KeySchema=table_schema['KeySchema'],
            AttributeDefinitions=table_schema['AttributeDefinitions'],
            GlobalSecondaryIndexes=table_schema['GlobalSecondaryIndexes'],
            ProvisionedThroughput=table_schema['ProvisionedThroughput']
        )
```
motoのバージョンが5.x以降で以前のデコレーターの記載方法で書いてしまうと、importエラーになってしまうので、motoライブラリを使用する際はバージョンも含めて注意が必要です。

# さいごに
ざっくりとmotoのバージョン5.x以降で使用する際の注意点について簡潔にまとめまてみました。motoを使用してSDKをモック化したテストコードを書く際は気を付けましょう。
Python 初級入門 モジュールとパッケージ編

## 前提
- python初学者、触ったことない人が投稿しています
- 個人的にあまり馴染みのない書き方について記載しています
- 誤っている箇所等があればコメントでご指摘いただけると幸いです
- こちらの記事は[制御フロー編](https://qiita.com/takemaru_shuna/items/3adfe0d5a3cfb79df7e0)の続きとなっていますので気になる方は是非！


## import
- import方法は複数存在する　
→ モジュールから読み込むようにすると混乱が起きづらくて良いとされている
→ 会社によってはフルパスで記載すべきというところもある。ただ、長くなりがちなのでモジュールからがベターと言われている
- また相対パスより絶対パスの方がよしとされている？（あまりわかっていない）
- 以下実装例です

```utils.py
def say_once(word):
    return (word + '!')
```
```main.py
import package.utils
res　=　lesson_package.utils.say_once('hello')
print(res) # hello!

# 以下のように書くことも可能
from package import utils
res　=　utils.say_once('hello')
print(res) # hello!

# 以下のように書くことも可能
from package.utils import say_once
res　=　say_once('hello')
print(res) # hello!
```
- またモジュールのディレクトリに`__init.py__`を作成することで、`＊`でimportすることも可能
- ただ、何が許可されているかが分かりづらいため闇雲に使うことは推奨できない
```__init__.py
__all__ = ['say_once']
```
```main.py
from package.utils import *
res　=　say_once('hello')
print(res) # hello!
```

## ImportError
- 古いパッケージでも、新しいパッケージでも使えるように
```py
try:
    from package import utils
except ImportError:
    from package.utils import say_once
utils.say_once('word)
```
# 作ったパッケージの配布（PyChamを使用しています）
1. pc上部のメニューバーのtoolsを選択し、`create setup.py`を押下
1. 入力項目に適当な値を入力する
1. `setup.py`が作成され中身を確認すると先ほど設定した内容が記載されています
1. 再度pc上部からtoolsを選択し、`Run setup.py Task`を押下
1. distファイルが作成されるためそれを周りに配布することが可能
1. 実際に展開して中身を確認することも可能

```setup.py
# こんな感じのものが作成されているはず
from setuptools import setup

setup(
    name='pythonProject',
    version='1.0.0',
    packages=['lesson_package', 'lesson_package.talk', 'lesson_package.tools'],
    url='https://www.google.com',
    license='',
    author='hoge',
    author_email='',
    description='test'
)

```

## 組み込み関数
- `print()`とも組み込み関数
- 組み込み関数にどんなものがあるのかは[公式](https://docs.python.org/ja/3/library/functions.html)を参照してください
```py
# 代表的なやつ
# keyで並び替え
ranking={'a': 100, 'b':85, 'c':90 }
print(sorted(ranking)) # ['a', 'b', 'c']

# valueで並び替え
print(sorted(ranking,key=ranking.get)) # ['b', 'c', 'a']

# valueで並び替えかつ点数が高い順
print(sorted(ranking,key=ranking.get, reverse=True)) # ['a', 'c', 'b']
```

## 標準ライブラリ
- [ライブラリ一覧](https://docs.python.org/ja/3/library/index.html)
```py
#　標準ライブラリはimportして使う（具体例）
# sの文字列で使われている文字をカウント
# defaultdict（int）によって初期値をわざわざ設定しなくても使える
from collections import defaultdict
s = 'dfafjknjsfslhajk'
d = {}
d = defaultdict(int)

for c in s:
    d[c] += 1
print(d) # {'d': 1, 'f': 3, 'a': 2, 'j': 3, 'k': 2, 'n': 1, 's': 2, 'l': 1, 'h': 1})
```

## サードパーティーライブラリ
- [Pypi](https://pypi.org/)から検索し、`pip`を使ってインストールすることが可能 
- インストール方法等は記載してある

## import時の注意事項
- ローカルのパッケージが優先されるので名称の被りには注意が必要
- 標準ライブラリとサードパーティーのimportは一行開けるのが良い
- 自分達で作成したパッケージの際も一行開けるのが良い
- 標準ライブラリ - サードパーティー - 自作パッケージの順が好ましい
- 上記はアルファベット順でそれぞれの中で記載する

```py
import collection
import os

import aaa
import termcolor

import package
```

## 学習してみて（つぶやきに近いです）
- importについては知らないことが多かったですね
- ただ、やり方それぞれにメリット、デメリットがあるのでそこは個人的に意識しないと事故とか可読性の問題に繋がるなと思いましたね
- 今まで自分が触ってきた言語とは違う感じだなっと思った（知らなかっただけかもしれないが）
- パッケージの配布とかやってみたさはありますね

## 最後に
- 次回はオブジェクトとクラスについて学んでみようと思います
- demoAppについて少し考えなくては。。。
UnityのTextで禁則処理する

TextMeshProを使っていない現場だってあるんですよ！


# 作ったもの

HyphenationJpn_uGUI compatible with Unity2022

https://github.com/izugch73/HyphenationJpn_uGUI

## インストール

1. Open `Package Manager`
1. Click `Add package from git URL...`
1. Add the uri: `https://github.com/izugch73/HyphenationJpn_uGUI.git?path=Assets/Plugins/HyphenationJpn`

お好みで`#0.1.1`とか。
Readme.mdに書いてどうぞ...


## 使い方

サンプルシーンそのまま置いてますが、`Text`のあるところに`HypenationJpn`を置いて、`SetText`すると動作すると思います。

# Fork元

[テラシュールブログ](https://tsubakit1.hateblo.jp/)の椿さんが**10年前**に作ったTextの禁則処理をUnity2022.3で動くようにしたものです。偉大な先人に感謝。。。

https://github.com/tsubaki/HyphenationJpn_uGUI


## マイグレーション内容

### GetText -> SetText

なぜかセッターの名前が`GetText`だったのを`SetText`に修正（偉大な先人であるため、私が知らない謎の理由があるのかもしれない。畏れ多くもメソッド名を変更）
```csharp:HyphenationJpn.cs
	public void SetText(string str)
	{
		text = str;
		UpdateText(text);
	}
```

### OnValidate
`OnValidate`はエディタでしか動作しない

```csharp:HyphenationJpn.cs
#if UNITY_EDITOR
        protected override void OnValidate()
        {
            base.OnValidate();
            UpdateText(text);
        }
#endif
```

### PRの吸収

https://github.com/tsubaki/HyphenationJpn_uGUI/pull/2

### その他
- asmdef
- package化
- サンプル更新


# TextMeshProをご利用の方
→ https://nekojara.city/unity-textmesh-pro-line-breaking
Google Colaboratoryで環境変数を設定する方法


# はじめに

API キーやトークンをソースコードに直接書くとロクなことがありません。

例えば、あとで修正しようと思って放置したまま、Github にプッシュしちゃったり...

Google が提供する Python 実行環境である`Google Colaboratory`でも、何か外部サービスの API キーなどを読み込んでリクエスト投げたりすることは多いと思います。

その場合の設定方法をメモで残しておきます。

# 環境変数の設定方法

設定方法はめちゃくちゃ簡単！

Google Colab の画面左にあるメニューから鍵アイコンをクリックして「新しいシークレットを追加」でキーとバリューを入れるだけ。
![環境変数の設定方法](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418680/a7e97970-b199-071c-66c7-9502d071b87d.jpeg)

「次のコードで Python の秘密鍵にアクセスします。」とサンプルコードまで提示してくれているので、コード内で環境変数を使いたい場合はその通りに書けば OK。

「ノートブックからのアクセス」というトグルを ON にしないと参照できないのでそこは注意！

![Pythonコードから環境変数を参照](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418680/82ece92b-f464-6058-ade9-8c326049ff0e.jpeg)

# おわりに

セキュリティ意識とても大事！

というか、開発するうえでの最低限のセキュリティ関連の知識持ってないと、とんでもないインシデント起こす危険性もあるから、必要な教養ですね。

あとタイトルとは関係ないけど、Google Colab で使える Gemini（生成 AI）めちゃくちゃ便利かもしれん！

今まで使ったことなかったけど何をしたいかプロンプトで与えるとすぐに Python コードとして出力してくれる。

VSCode で Github Copilot を課金して使ってるけど、Google Colab でも同じことができると考えたらいろいろ捗りますね！
SwiftでSign In With Appleがめんどかった

## はじめに
iOSアプリのリリースの際にサードパーティー製の認証(google signinなど)を用いるとSign in with Appleの機能を必須にしないといけないらしい．そのためにSign in with Appleを実装したのだが，意外と手順が面倒だったのでまとめる

## 前提
FirebaseAuthを用いてSign in with Appleを実装する．
Apple Developer Programへの登録は済んでいる
基本的なFirebaseとクライアントの連携は終わっているものとする

## 準備
[Certificates, Identifiers & Profiles](https://developer.apple.com/account/resources)ページでSign in with Appleを有効にする

![スクリーンショット 2024-09-04 18.15.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500127/038c8a8a-4872-83db-1a91-8ce9ab739905.png)

Server-to-Server Notification Endpointは`https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler`に設定する．`YOUR_FIREBASE_PROJECT_ID`は自分のfirebase consoleから確認してください

![スクリーンショット 2024-09-04 18.16.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500127/efe22499-67bf-da23-6f24-24dca7e1fff4.png)

そして注意すべくポイントとしてfirebaseの連携するアプリケーションのバンドルIDとApple Developer上で登録するバンドルIDは一致させてください．

![スクリーンショット 2024-09-04 18.25.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500127/0aa5b3c5-70e7-8435-1c10-8e4137aeb205.png)



そしてXcode上でもSigning & Capabolitiesの項目にSign in with Appleを追加してください．

![スクリーンショット 2024-09-04 18.20.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2500127/9ea43b53-a6cf-5b00-f5f6-6eebad2de280.png)

その後[firebaseのドキュメント](https://firebase.google.com/docs/auth/ios/apple?hl=ja#sign_in_with_apple_and_authenticate_with_firebase)に沿って実装していけば無事にSign in with Appleを実装することができます．

## 終わりに
Sign in with Appleをする方(エンドユーザー)は簡単でいいが実装する方(開発者)は意外とめんどい．．．
【TypeScript】public修飾子, protected修飾子, private修飾子の違いについて解説する

# はじめに

public修飾子,protected修飾子,private修飾子の違いについて備忘録としてまとめておきます。

# 3つの修飾子の違い

|修飾子|役割|
|:-:|:-:|
|public修飾子|クラス内外で使えるプロパティ|
|protected修飾子|自分のクラス内,継承先で使えるプロパティ|
|private修飾子|クラス内でのみ使えるプロパティ|

以上です。
OSPFでルーティング（CCNA第４回） 座学編


# OSPFでルーティング（CCNA第４回） 座学編
前章ではマルチアクセス環境でのOSPFを学習した。

## 前章
こちらの続きになります。まだ読んでない方はこちらからお読みください。

https://qiita.com/YukiTetsuka/items/12cd7f52711d331b2ba2

## OSPFでのルーティング方法は？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3847927/6f24da8e-9b80-c423-ff51-74832bba1f20.png)
上記のようなネットワークがある。`Router1`から`Router3`への適切なルートはどこか。

### メトリックの計算
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3847927/899b4c3d-6289-b079-bac5-fe1f5044780e.png)
今回の場合、オレンジ色と水色の2ルート考えられる。
OSPFでは、メトリックとして帯域幅から計算するコスト値を使用する。

オレンジ色はインターフェースを3つ経由しているため**コスト3**
水色はインターフェースを4つ経由しているため**コスト4**

結果、オレンジ色のルートが最短だと判断されルーティングテーブルに登録される。

#### OSPFでのコスト
コストは、OSPFでルーティングを行う上で大事な判断材料である。
コストは、 
```math 
10^8 / 帯域幅(bps)
```
で求めることができる。

:::note info
**ファストイーサネットおよびギガビットイーサネットのインターフェイスでは、コストは1**になる。

林口 裕志; 浦川 晃. シスコ技術者認定教科書 CCNA 完全合格テキスト＆問題集［対応試験］200 -301 (p.347). 株式会社 翔泳社. Kindle 版. 
:::

### 等コストロードバランシング
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3847927/476a4fc1-1d14-565a-e706-39103254e2f9.png)
上記のような最短ルートが複数発生する場合もある。
その場合、最大4ルートがルーティングテーブルに登録される。（今回は2ルート）

また、Ciscoルーターでは複数のルートがある場合、トラフィックを分散して異なるルートでの通信を行う。それにより、1つのルータにかかる負担を軽減させることができる。

### ルートの変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3847927/899b4c3d-6289-b079-bac5-fe1f5044780e.png)
上記のようにデフォルトの帯域幅をそのままコストとして計算すると、1Gbpsでも100Mbpsでも同じコスト１として扱われる。しかし本来は、1Gbpsのほうが最適なルートである。そのため、コスト値を調整する必要がある。

#### 調整方法
調整方法には以下の3種類がある。
- インターフェースのコスト値を直接変更
- コスト値の計算結果を変えるため、インターフェースの帯域幅を変更
- コストの計算式の分子10の8乗の値を変更

##### 例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3847927/0128b974-e4f1-eb55-e87a-0a2b8f65251f.png)
この場合、10の部分はFastEthernetとしコスト値を直接変更した。

オレンジ色は10 + 10 + 1を経由しているため**コスト21**
水色は10 + 1 + 1 + 1を経由しているため**コスト13**

となり、水色が最短ルートとなる。

## マルチエリア ( OSPF )
ルーターが数が膨大になると、ネットワーク全体を把握するために多くのリソースが必要となり、システムに負荷がかかってしまう。
そこで、**インターフェイスをいくつかのグループに分ける**ことで、負荷を軽減することができる。そのグループを**エリア**と呼ぶ。

### 保持情報
同じグループ内のルーター同士は詳細なトポロジを把握する。
その一方で、他のエリアの情報はルート情報のみ保持する。これにより、1ルーターのLSAの保持数を減らすことができる。

:::note info
**シングルエリアOSPF** : 1つのエリアだけでOSPFを動作させる
**マルチエリアOSPF** : 複数のエリアでOSPFを動作させる

林口 裕志; 浦川 晃. シスコ技術者認定教科書 CCNA 完全合格テキスト＆問題集［対応試験］200 -301 (p.347). 株式会社 翔泳社. Kindle 版. 
:::

### バックボーンエリア
バックボーンエリアとは、すべてのエリア間の通信の通過地点となるエリアであるため必ず設定しなければならない。

### ルーターの役割
| 役割 | 説明 |
| -- | -- |
| 内部ルーター | 別エリアと接していないルーター |
| バックボーンルーター | バックボーンエリアに所属するルーター。インターフェイスが1つでも所属していればバックボーンルーターとなる。 |
| エリアボーダールーター(ABR) | 二つ以上のエリアに所属しているルーター |
| ASバウンダリールーター(ASBR) | 外部(OSPF以外)のネットワークに所属しているルーター |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3847927/9bfe3787-9c8e-e885-841e-ebfe4d10c59a.png)


## 付録

### パッシブインターフェイス
OSPFでは通常、OSPFを有効にしたインターフェースの情報(LSA)とHelloパケットが送信される。
しかし、**PCやサーバーと接続されている側のインターフェイスからHelloパケットを送信する必要はない**。
そこでOSPFを有効にしながらも、Helloパケットを送受信しないようにすることを、**パッシブインターフェイス**という。

### MTUのサイズ
MTUとは1度の通信で送信できるパケットの最大サイズのことである。
この**MTUの値よりも大きいサイズのDBDパケットを受信できない**。
そこで、対向ルーターとMTUの値を同期するか、MTU不一致を検出する機能を無効にすることで解決できる。

### 

# 参考文献
- 林口 裕志; 浦川 晃. シスコ技術者認定教科書 CCNA 完全合格テキスト＆問題集［対応試験］200 -301 (p.325). 株式会社 翔泳社. Kindle 版. 
- https://note.com/sato_manabi/n/nb179b5e60762
Excel VBAでシートを一度に作成する方法

# Excel VBAでNo1〜No50までのシートを一度に作成する方法

Excelで多数のシートを一度に作成する必要がある場合、手動で作成するのは非常に手間がかかります。そこで、Excel VBAを使用してNo1からNo50までのシートを一度に作成する方法をご紹介します。

## 手順概要

VBA (Visual Basic for Applications) は、Excelでの自動化を実現する強力なツールです。今回の目的は、VBAを使用して、No1からNo50までのシートを自動で生成するコードを作成し、効率的に複数のシートを作成することです。

## コードの紹介

以下は、No1からNo50までのシートを自動的に作成するためのVBAコードです。このコードをExcelのVBAエディタにコピーして実行することで、指定されたシートが簡単に作成されます。

### VBAコード

```
Sub CreateSheets()
    Dim i As Integer
    Dim sheetName As String
    
    Application.ScreenUpdating = False
    
    For i = 1 To 50
        sheetName = "No" & i
        If Not SheetExists(sheetName) Then
            Sheets.Add(After:=Sheets(Sheets.Count)).Name = sheetName
        End If
    Next i
    
    Application.ScreenUpdating = True
End Sub

Function SheetExists(sheetName As String) As Boolean
    Dim ws As Worksheet
    On Error Resume Next
    Set ws = ThisWorkbook.Sheets(sheetName)
    On Error GoTo 0
    SheetExists = Not ws Is Nothing
End Function
```

### コードの説明

1. **CreateSheets** プロシージャ:
    - このサブプロシージャは、シート名「No1」から「No50」までをループで作成します。
    - `Application.ScreenUpdating` を `False` に設定することで、シートを作成している間の画面更新を無効にし、処理速度を向上させます。
    - `sheetName` 変数には、「No1」から「No50」までのシート名が順次割り当てられます。
    - `SheetExists` 関数を使用して、同じ名前のシートが既に存在するかどうかを確認し、存在しない場合にのみ新しいシートを追加します。

2. **SheetExists** 関数:
    - この関数は、指定したシート名が現在のブックに存在するかをチェックします。存在する場合は `True` を、存在しない場合は `False` を返します。

### 使用方法

1. **VBAエディタを開く**:
   - Excelを開き、`Alt + F11`を押してVBAエディタを開きます。
   
2. **新しいモジュールを追加**:
   - `Insert > Module` を選択して、新しいモジュールを追加します。

3. **コードを貼り付ける**:
   - 上記のVBAコードをコピーして、追加したモジュールに貼り付けます。

4. **コードを実行**:
   - `F5`キーを押すか、VBAエディタの「Run」ボタンをクリックしてコードを実行します。

これで、Excelのワークブックに「No1」から「No50」までのシートが自動的に作成されます。同じ名前のシートが既に存在する場合は、新たに作成されることはありません。

## まとめ

VBAを活用することで、Excelでの作業を効率化できます。特に、複数のシートを一度に作成するタスクは手動で行うと時間がかかりますが、このVBAコードを使えば簡単に実行できます。ぜひご自身の業務に活用してみてください。


## 追記
No.１のシートをコピーして、No.2〜No50のシートを作成するコードについては、以下になります。
```
Sub CopySheets()
    Dim i As Integer
    Dim sheetName As String
    
    ' "No1"シートが存在するか確認
    If Not SheetExists("No1") Then
        MsgBox "シート 'No1' が存在しません。"
        Exit Sub
    End If
    
    Application.ScreenUpdating = False
    
    ' No2からNo50までのシートを作成
    For i = 2 To 50
        sheetName = "No" & i
        If Not SheetExists(sheetName) Then
            ' "No1"シートをコピーして新しいシートを作成
            Sheets("No1").Copy After:=Sheets(Sheets.Count)
            ActiveSheet.Name = sheetName
        End If
    Next i
    
    Application.ScreenUpdating = True
    
    MsgBox "シートのコピーが完了しました。"
End Sub

Function SheetExists(sheetName As String) As Boolean
    Dim ws As Worksheet
    On Error Resume Next
    Set ws = ThisWorkbook.Sheets(sheetName)
    On Error GoTo 0
    SheetExists = Not ws Is Nothing
End Function
```
ESlintとprettierの関係など

JavaScriptやTypeScriptを用いて開発をする際、ESLintとPrettierはもはや必須。
それぞれの違いやどう組み合わせて使うのかをまとめていきます。

## 1. ESLint
目的: ESLintは、コードの静的解析ツールです。主に、コードのバグ、問題、ベストプラクティスに反する部分を指摘してくれます。例えば、以下のような問題を検出します。

- 文法エラーやタイポ
- コードのスタイルに関するルール（例えば、セミコロンの有無、クォーテーションの種類など）
- 未使用の変数や不要なコード
- 一貫性のないコーディングスタイルやベストプラクティスに反するコード

設定: ESLintは、ルールセットをカスタマイズできるため、プロジェクトやチームのコーディング規約に応じて設定できます。また、様々なプラグインや拡張機能を追加することで、特定のフレームワーク（React、Vueなど）に適したルールを導入することが可能です。

## 2. Prettier
目的: Prettierは、コードフォーマッタです。コードのスタイル（フォーマット）を自動的に整え、統一感のあるコードを維持します。Prettierは以下のような部分を自動的に整形します。

- インデントやスペース
- 行の長さ
- 括弧やカンマの配置
- 改行の位置
- 
設定: Prettierはあまり細かく設定できないように設計されています。デフォルトの設定に従って、すべてのコードをフォーマットすることで、一貫性を保つことを目的としています。

## 3. ESLintとPrettierの関係
重複する領域: ESLintとPrettierには、コードスタイルに関して重複する部分があります。例えば、どちらもインデントやクォーテーションのスタイルを管理することができます。ただし、ESLintはより広範なコード品質のチェックに重点を置いており、Prettierはフォーマットの自動化に特化しています。
コンフリクトの解消: ESLintとPrettierを一緒に使う場合、フォーマットに関するルールで競合が発生する可能性があります。このような場合、Prettierと競合するESLintルールを無効にするESLint設定で回避することができます。また、eslint-plugin-prettierを用いることで、PrettierをESLintのルールとして組み込むことができます。これにより、ESLintがPrettierのフォーマットを検証し、フォーマットが適用されていない場合に警告を出します。
GASからLINEに通知する

Google Apps Script(GAS)からLINEへPush通知を送信する方法をまとめました。
GASだとちょっとした仕組みを手軽にかつサーバレスで作れるので、これにPush通知の機能まで付けられるのは鬼に金棒です。

というわけでさっそく説明していきます。

# 1. 事前準備
## (1)LINEでの設定
### ①通知先のLINEグループを作成
以下の手順でLINEグループを作成してください。

https://guide.line.me/ja/friends-and-groups/create-groups.html

なお、通知先が自分自身のみの場合は「自分だけしかいないグループ」を作成すればOKです。
※後述しますが、作成したグループに通知を送信するためには、グループ内に「LINE Notify」も追加する必要がありますので、通知先が自分自身のみの場合は、最終的には「自分とLINE Notify」の2ユーザがグループ内に存在する形になります。
### ②LINE Notifyの設定
通知の送信にあたり、LINEの通知のサービスである「LINE Notify」を設定し、①で作ったグループで使える状態にします。
以下が分かりやすかったのでこちらを参考に設定してください。
この設定で取得したトークンはこの後のGASでの設定でも利用します。

https://zenn.dev/sheep8/books/261ed6375b5eb0/viewer/e8dc1e

## (2)GASでの設定
### スクリプトプロパティ(環境変数)の設定
(1)の②で取得したトークンをGoogleスプレッドシートで使えるよう設定します。
直接コード上にトークンを記述するハードコーディングはセキュリティ上の理由から避ける必要があります。  
そこで、以下の手順のとおりスプレッドシートの「スクリプト プロパティ」(一般的な「環境変数」に相当)にトークン等を格納し内部的に呼び出せるようにします。
1. スプレッドシート上部のメニューにある「拡張機能」の配下にある「Apps Script」を選択。すると、新しいタブでコードエディタが表示される
![スクリーンショット_2024-08-31_22_34_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123999/0c60f887-6941-962e-90c9-f0f5772fd002.png)
2. エディタの左側にある歯車アイコンにカーソルを合わせると表示される「プロジェクトの設定」を選択
![スクリーンショット_2024-08-31_22_33_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123999/1658be42-964c-359c-ede5-afa4f3f4fa62.png)
3. 設定画面の一番下に「スクリプト プロパティ」という項目がある。これを設定するため「スクリプト プロパティを追加」を選択
![スクリーンショット_2024-08-31_22_43_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123999/315a6d56-373a-1452-ef0b-5dcfbb1b0705.png)
4. スクリプト プロパティ(環境変数と同義)の設定欄が表示されるので、以下のとおり設定
    ⅰ.「プロパティ」欄で適当な名前を入力(ここでは`LINENOTIFY_TOKEN`)
    ⅱ. 取得したLINE Notifyのトークンを貼り付ける
    ⅲ. 入力内容を保存するため「スクリプト プロパティを保存」を選択
![スクリーンショット_2024-09-06_8_30_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123999/1c733ca0-d04b-331d-4fd8-4f9a6a854adb.png)

これで事前準備は完了です。

# 2. 実装
まずは通知用の`lineNotify`関数を作成します。
この`lineNotify`関数に通知したいメッセージ内容を引数として渡すことで、そのメッセージが(1)①で作ったLINEグループに通知される、という想定です。
## (1)通知用関数
```js:GAS
function lineNotify(message) {
    // スクリプトプロパティに格納したLINE Notifyのトークンを読み込む
    const lineToken = PropertiesService.getScriptProperties().getProperty("LINENOTIFY_TOKEN");
    // httpリクエスト内容の準備
    const options = {
        "method": "POST",
        "payload": {"message": message},
        "headers": {"Authorization": "Bearer " + lineToken}
    };
    // httpリクエストをLINE NotirfyのAPIに送信 → 指定のLINEグループに通知が飛ぶ
    UrlFetchApp.fetch("https://notify-api.line.me/api/notify", options);
}
```

## (2)通知実行
では、実際に実行してみましょう。
```js:GAS
function pushNotify(){
    // 意味もなく3連発してみる
    lineNotify("通知テストです");
    lineNotify("通知テストざます");
    lineNotify("通知テストでごわす");
}
```
![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123999/844da6ad-70c1-3117-5eb0-01275c7880a7.png)

無事通知が届いたでごわす。

# おわりに
実際に使ってみました。

https://qiita.com/S_Kosaka/items/2e571b6a1ac7fad4ceff
Chocolateyを使おう！という話（入門）

## はじめに
こんにちは、たきがわです。
この記事は𝓐𝓝𝓖𝓔𝓛 𝓒𝓪𝓵𝓮𝓷𝓭𝓪𝓻 ４日目の記事です。**そう、四番手。**
技術スタックがないけど記事は書きたい！ということでAngel Dojoのチーム活動中に役に立ったことを記事にしました。

他の方（とてもつよい）の記事は下記のOrganizationから！
https://qiita.com/organizations/2024-angel-dojo

## 前提:ソフトウェアのインストールってめんどくさい
ソフトウェアをインストールする際に、公式サイトを探して、ダウンロードして、インストーラーを実行して、設定を調整するのって結構めんどうですよね。
それが複数のソフトウェアになると更に大変です。~~OSのクリーンインストールした時は特に。~~
そんなめんどうな作業をコマンドでいい感じにしてくれる、今日はそんな便利なツール、Chocolateyについてご紹介します。

## 導入
https://chocolatey.org/install

こちらに公式のインストール手順があるので従います。

:::note warn
注意
PowerShellは管理者として実行してください
:::
1. Choose How to Install Chocolateyはindividualを選択して下部のコマンドをコピー
2. PowerShellを開いてコマンドを実行
3. `choco -v`コマンドでインストールを確認

## 早速使ってみよう
:::note warn
注意
使用する際は管理者で実行してください
:::
### chocolateyのアップデート
+ `choco upgrade chocolatey`
chocolatey本体のアップデート
### パッケージを探す
+ `choco search [パッケージ名]`
[パッケージ名]のパッケージがchocolatey上に存在するか調べる
### パッケージのインストール
+ `choco install [パッケージ名]`
[パッケージ名]で指定したパッケージのインストール
:::note
tips
パッケージ名の後ろに `-y`をつけて実行すると確認がスキップされます
:::
### パッケージのアップデート
+ `choco outdated`
最新ではないインストール済みのパッケージを表示
+ `choco upgrade [パッケージ名]`
[パッケージ名]で指定したパッケージのアップデート
+ `choco upgrade all`
全てのパッケージをアップデート
### パッケージのアンインストール
+ `choco uninstall [パッケージ名]`
[パッケージ名]で指定したパッケージのアンインストール

## GUI版でパッケージリストを作る
パッケージリストを作ることで環境の引っ越しが楽にできます
### GUI版のインストール
chocoでインストールしてみましょう
`choco install ChocolateyGUI -y`


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3851023/2f8dc66e-491f-be6b-578b-1247315b6e10.png)
開くとこんな画面が出てきます
右上のExportボタンをクリック
名前をつけて保存したら.configファイルができました
あとはchocoコマンドが使える環境で`choco install [コンフィグファイル名].config`を実行
引っ越し完了！

## 最後に
chocolateyいかがでしたでしょうか。覚えてしまうと手放せなくなってしまうくらいオススメです。
良ければAngel Dojoの開発にも役立てていただければ幸いです。
ANGEL Calendarもまだ四日目！この先の記事も毎日更新！お楽しみに！（僕はもう書かないけど！）

## 参考


https://qiita.com/kangetsu121/items/b6352b547cd32e71bc65#chocolatey%E3%81%AE%E5%B0%8E%E5%85%A5%E6%96%B9%E6%B3%95

https://docs.chocolatey.org/en-us/getting-started/
Dockerhub からの Image の ENTRYPOINT/CMD 確認方法：dockerhub → github を見る

## 背景
貰った docker-compose ファイルに、mysql の公式 image を使用する service があった(`test-mysql-db`)。

```
services:
  test-mysql-db:
    image: mysql:5.7
    command: ['--sql-mode=']
    environment:
      MYSQL_ROOT_PASSWORD: testpw
      MYSQL_DATABASE: testdb
    ports:
      - 33306:3306
    logging: *x-logging
    healthcheck:
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 15s
```

service の `command` は気になった
- 本来 command は既存の **command** を代替するものではなかった？
- なのに、command でなく、他のコマンドのオプションに見える (`command: ['--sql-mode']`)??

 → **意味をわかるために、既存のコマンドは何かが知りたい**

 ## Image 中身の確認方法：github に Dockerfile がある

Image の[公式サイト](https://hub.docker.com/_/mysql)を見ても、起動時の command が書かれていないな。

ただ「Quick reference (cont.)」のところに、image の [github](https://github.com/docker-library/mysql/)へのリンクがある。

それにちょっと漁ったら、起動時の command を含む Dockerfile が直ぐ見つかる：

https://github.com/docker-library/mysql/blob/master/8.4/Dockerfile.oracle#L123

やっぱり `mysqld` だったね。

そして、使われていた [option](https://dev.mysql.com/doc/refman/8.0/ja/sql-mode.html) の説明を、コマンドと繋いで理解に進んでいける。
【AWS WAF】誤検知が疑われる時はALBログも確認しよう！


## ■ 発生した事象
とあるお客様のAWS環境に AWS WAF を構築。
１ヶ月間 COUNTモード（遮断はせず検知のみを行うモード）にて動作させ、誤検知がないことを確認後にBLOCKモードにて本稼働することになった。
COUNTモードで動作開始させ、1ヶ月後にAWSコンソールより対象WebACLのTraffic Overview を確認し、BLOCKされているリクエストがないことを確認の上、BLOCKモードへ変更し本稼働を開始した。

本稼働後しばらくするとお客様より「アプリへの通信がBLOCKされているようだ」とのご連絡。
通信元・通信先のアプリログを確認したところ、やはり通信が届いていないとのことから調査開始した。


## ■ 調査
AWSコンソールより対象WebACLのTraffic Overview を確認するも、Blockedされている形跡はなく、全てAllowedとなっている。
ん？BLOCKはされていない？と思いながら、次にALBのメトリクスを確認すると、「ELB 4XXs」がBLOCKモード切り替え前よりも増えている。
「ELB 4XXs」とはなんぞや？「ターゲット 4XXs」ってのもある。
この機会に調べてみることに。

ドキュメントに記載がありました。
https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html

##### ・ELB 4XXs とは
> ロードバランサーから送信される HTTP 4XX クライアントエラーコードの数。この数には、ターゲットによって生成される応答コードは含まれません。

##### ・ターゲット 4XXs とは
> ターゲットによって生成された HTTP 応答コードの数。これには、ロードバランサーによって生成される応答コードは含まれません。

ELB 4XXs はクライアントからロードバランサーへの通信で何かあった場合に上昇するもの。
ターゲット 4XXs はロードバランサーからターゲット（バックエンドのインスタンス等）への通信で何かあった場合に上昇するもの。
と、認識した。
　
実際に何が起きているか、ALBログを確認してみる。
以下が、4XXエラーをピックアップしたALBログ。
（あくまでサンプルです。不要な列等は非表示としています。）
![20240904_163317036_EXCEL.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493488/b6f9e536-27c1-78f8-c797-d64169a09c9c.jpeg)
　
注目したのは『elb_status_code』と『target_status_code』。
elb_status_code に4XX系のエラーコードが入力されており、target_status_code には「-」が記載されている。
4XX系のエラーコードは大半が「460」と「408」だった。

コードの内容は以下のページに説明があった。
https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-troubleshooting.html#http-408-issues


##### ・HTTP 408: Request timeout
> アイドルタイムアウト期間の期限が切れる前に、クライアントからデータが送信されませんでした。TCP キープアライブを送信しても、このタイムアウトを防ぐことはできません。各アイドルタイムアウト期間が経過する前に、1 バイト以上のデータを送信します。必要に応じて、アイドルタイムアウト期間を長くします。

##### ・HTTP 460
> ロードバランサーはクライアントからリクエストを受信したが、クライアントはアイドルタイムアウトが経過する前に、ロードバランサーとの接続を閉じました。
クライアントのタイムアウト期間がロードバランサーのアイドルタイムアウト期間より長いかどうか確認してください。クライアントのタイムアウト期間が経過する前に、ターゲットがクライアントにレスポンスを返すことを確認するか、クライアントがサポートする場合は、クライアントのタイムアウト期間を増やしてロードバランサーのアイドルタイムアウトに合わせます。

「クライアントはアイドルタイムアウトが経過する前に、ロードバランサーとの接続を閉じました」とのこと。
どういった理由で閉じられてしまったのか？
また遮断されているのであれば、なぜWebACLのTraffic OverviewのBLOCK数がカウントアップしていないか？

これ以上の調査は難しく、AWSサポートへ問い合わせしてみた。
結論としては以下の回答を頂いた。
> RFC 7230 に準拠していないリクエストが送信される場合、本事象とは異なる要因にて、ALB または WAF にて正常にリクエストが処理されない可能性がある。
>
>参考リンク
https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-access-logs.html#classification-reasons

リクエストが7230RFCに準拠していない場合は、ALBやWAFで正常にリクエストが処理されない可能性あるとのこと。
また、今回はALB側で処理されなかったので、WAF WebACL画面のTraffic OverviewにBLOCK数がカウントアップされていないことが判明しました。
しかも、WAFをつけることでALBにて7320RFC準拠がチェックされるようで、WAFをつけていないALBは7230RFC準拠されているかのチェックはされないという事でした。

今回、アプリケーション担当者へ確認すると古いアプリのためRFCに準拠していないとのことで、アプリ側でRFC準拠するように対応するということになりました。

## ■ 身につけた知識
* 遮断情報の確認はAWSコンソールの Traffic Overview のみではなく、ALBのメトリクスやログを確認し遮断されていないかを確認する
* 7230RFCに準拠していないリクエストが送信された場合、ALBやWAFは正常にリクエストを処理しない可能性がある* WAFをALBにつけることで、ALBにて7320RFCがチェックされる（WAFをALBから外すとALBでチェックされなくなる）
OpsRamp - プライオリティごとにチケットをダッシュボードで表示する方法

本記事では、OpsRampのダッシュボードにおいてプライオリティごとにチケットを表示する方法について説明します。

# 概要
OpsRampのダッシュボードでは、さまざまなタイルを表示することができます。

# 設定方法
ダッシュボードの設定は、Dashboards > Dashboardから設定可能です。
![dashboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/f753e5f3-006b-d2c6-4b22-ac4448485c9f.png)

タイルを追加し、TicketのBuild my ownを選択します。
![dashboard-tikcet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/645c0128-73b1-b50e-bc2b-8a725cc8a4fa.png)

QUERYでticketTypeを選択し、オペレータにIN、値に任意のチケットタイプを選択します。
または、OPSQLで以下を入力します。
```
ticketType IN ("Change","Incident","Problem","ServiceRequest")
```
GROUP BYにticketTypeおよびstatusを選択します。
![dashboard-ticket1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/44ed068c-d494-5a33-7b32-247aecd1311b.png)

- サンプル
![dashboard-ticket2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/6e8a56e4-a2bf-9023-17d0-318191b3115f.png)




---------------------------------------
[<img width = 250 height = 200 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/111de30a-4d33-aa33-5c7d-83d9015093e6.png">](https://www.vistanet.jp/knowledge-base/)
【データベース】RDBの正規化を理解する〜第2正規形〜

## はじめに
前回の続きで今回は第2正規化について学んだことをまとめたいと思います！

前回の記事はこちら

https://qiita.com/rgj0830/items/673a8a78ba4c880368d9

## 第2正規化とは？
* 部分関数従属を解消し、完全関数従属だけの状態にすること。
* 異なるレベルの実体（エンティティ）を分離する作業でもある。

#### 完全関数従属
主キーを構成するすべての列に従属性がある状態。

#### 部分関数従属
主キーを構成する一部の列に対して従属する列がある状態。

## 第2正規化の方法
部分関数従属のある従属列を切り出し、別テーブルに分割する。

## 例（第2正規化前〜部分関数従属の状態〜）
#### クラステーブル

| クラスID | クラス名 | 教師ID | 教師名 | 生徒ID | 生徒名     |
|----------|----------|--------|--------|--------|------------|
| 1        | 1年A組   | T001   | 佐藤先生 | 1      | 山田太郎   |
| 1        | 1年A組   | T001   | 佐藤先生 | 2      | 鈴木花子   |
| 1        | 1年A組   | T001   | 佐藤先生 | 3      | 田中次郎   |
| 2        | 1年B組   | T002   | 高橋先生 | 4      | 佐々木一郎 |
| 2        | 1年B組   | T002   | 高橋先生 | 5      | 伊藤美咲   |
| 3        | 2年A組   | T003   | 中村先生 | 6      | 木村健太   |
| 3        | 2年A組   | T003   | 中村先生 | 7      | 渡辺陽子   |
| 3        | 2年A組   | T003   | 中村先生 | 8      | 山口幸子   |
| 3        | 2年A組   | T003   | 中村先生 | 9      | 加藤大輔   |

### 部分関数従属の状態とは？
このテーブルの主キーは「クラスID」「教師ID」「生徒ID」になります。ただし、この例だと主キーを構成する一部の列に対して従属する列がある状態、つまり部分関数従属の状態になっています。

具体的に言うと：

- クラスID → クラス名
- 教師ID → 教師名
- 生徒ID → 生徒名

上記3つの列は、対応する主キーが決まれば、その値が一意に決まる従属性があります。ただし、**クラスID**が決まっても、**生徒名**は一意に決まりません。同様に、**教師ID**が決まっても、**生徒名**は一意に決まりません。これは、同じクラスや担当教師には複数の生徒が存在する可能性があるからです。これが部分関数従属の状態になります。

### 問題点
このような状態だと以下のような問題が発生します。

1. **データの冗長性**: 同じクラス名や担任教師名が繰り返し記載されるため、データが冗長になる。
2. **更新異常**: 担任教師の名前やクラス名を変更する場合、すべての関連する行を更新する必要があり、データの不整合が発生する恐れがある。
3. **挿入異常**: 新しいクラスや教師を追加する場合、関連する生徒情報が存在しないと挿入できなくなる。
4. **削除異常**: 生徒のデータを削除するとき、クラスや教師の情報も誤って削除される可能性がある。

### 解決方法
この状態を解消するには、部分関数従属のある従属列を切り出し、別テーブルに分割を行います。具体的には以下のように分割を行います。

* 部分関数従属のある生徒ID、生徒名を生徒テーブルとして切り出す。
* 部分関数従属のある教師ID、教師名を教師テーブルとして切り出す。
* クラステーブルにはクラスの情報だけを持たせるようにする（異なる実体のエンティティの分離）。
* 生徒テーブル、教師テーブルにクラスIDを追加し、クラステーブルと紐付ける（外部キー制約）。

## 例（第2正規化後〜完全関数従属の状態〜）

#### クラステーブル

| クラスID | クラス名 |
|----------|----------|
| 1        | 1年A組   |
| 2        | 1年B組   |
| 3        | 2年A組   |

#### 教師テーブル

| 教師ID | 教師名   | クラスID |
|--------|----------|----------|
| T001   | 佐藤先生 | 1        |
| T002   | 高橋先生 | 2        |
| T003   | 中村先生 | 3        |

#### 生徒テーブル

| 生徒ID | 生徒名     | クラスID |
|--------|------------|----------|
| 1      | 山田太郎   | 1        |
| 2      | 鈴木花子   | 1        |
| 3      | 田中次郎   | 1        |
| 4      | 佐々木一郎 | 2        |
| 5      | 伊藤美咲   | 2        |
| 6      | 木村健太   | 3        |
| 7      | 渡辺陽子   | 3        |
| 8      | 山口幸子   | 3        |
| 9      | 加藤大輔   | 3        |

### 第2正規化によって改善された点

1. **データの冗長性の削減**: 同じクラス名や担任教師名が複数回記載されることがなくなり、データがシンプルになった。
2. **更新異常の防止**: 教師やクラスの名前を変更する際に、複数の行を更新する必要がなくなり、一貫性が保たれるようになった。
3. **挿入異常の解消**: 新しいクラスや教師を追加する際に、生徒情報が存在しなくても挿入できるようになった。
4. **削除異常の防止**: 生徒を削除しても、クラスや教師の情報が誤って削除されることがなくなり、データの安全性が向上した。

### まとめ
今回は第2正規化についてまとめてみました。
何となく感覚で行なっていましたが、DB設計で留意すべき点などメリット、デメリット含め、考えることでとても学びになったように思います。
また、間違った解釈等あれば教えていただけると幸いです。

次の記事はこちら

https://qiita.com/rgj0830/items/4c6db29f15b90c0186a0

### 参考書籍

https://www.shoeisha.co.jp/book/detail/9784798186627