OmniAICreator/Qiita-1.07M huggingface dataset:
AWSマネージドサービスのセキュリティグループはインバウンドを開けなくて良いって本当？！

# AWSマネージドサービスのセキュリティグループはインバウンドを開けなくて良いって本当？！

**結論から言ってしまうと、** AWS（Amazon Web Services）のマネージドサービスを利用する際、セキュリティグループの**インバウンドを開けなくて良いです！**

マネージドサービスというと、例えばClientVPNやDirectoryServiceなどと言ったサービスが該当します。
ClientVPNを例に取ると、ローカルにClientVPNアプリケーションをインストールして、ClientVPNエンドポイントに対して接続することになると思います。
![ClientVPN接続](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944513/f92f91e3-aa88-3a17-d0f2-945419a7cbe2.png)

ローカルからエンドポイントに対してアクセスしているため、「インバウンドを何かしら開けないといけないだろう」と勘違いしている人が多いように感じますが、**実はインバウンドは何も開けなくて良いのです。**

本記事では、その理屈について説明していきます。

## 目次

1. [セキュリティグループの基本理解](#セキュリティグループの基本理解)
2. [マネージドサービスがインバウンドを開けなくても接続可能な理由](#マネージドサービスがインバウンドを開けなくても接続可能な理由)
3. [セキュリティグループはどこにアタッチされているのか](#セキュリティグループはどこにアタッチされているのか)
4. [よくある勘違いから生まれるセキュリティリスク](#よくある勘違いから生まれるセキュリティリスク)
5. [まとめ](#まとめ)

## セキュリティグループの基本理解

セキュリティグループはAWSにおける仮想ファイアウォールであり、EC2インスタンスやその他のAWSリソースへのトラフィックを制御するものです。
この記事に興味を持ってくれたような方は既にここまでは理解できているのではないでしょうか。

では早速本題です！
一般的な認識として、**外部からのアクセスを許可するためにはインバウンドルールで特定のポートやIPレンジを開放する必要があると考えられがち**です。
EC2のように自分で管理するリソースに関して言えば、これは正しいです。
しかし、冒頭で挙げたClientVPNやその他の**マネージドサービスではこれは誤りです。**
マネージドサービスではインバウンドを必要とせずにクライアント接続が可能です。
その理由を以下で詳しく見ていきます。

## マネージドサービスがインバウンドを開けなくても接続可能な理由

AWSのマネージドサービスがセキュリティグループのインバウンドルールを開けずにクライアントと接続できる主な理由は、AWS側で管理しているサーバーとElastic Network Interface（ENI）が直接接続を行っているからです。

もう少し詳しく説明します。
AWSのマネージドサービスでは、ユーザーが個別にサーバーを管理する必要がない代わりに、AWSがインフラストラクチャ全体を管理し、サービス提供のために必要なネットワーク設定やセキュリティ管理を自動的に行います。

例えば、ClientVPNであれば、裏側でエンドポイントとなるサーバーが起動しています。
![ClientVPNエンドポイント](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944513/83403bd3-7c40-51e4-f860-8e0791f63816.png)

あるいはDirectory Serviceであればドメインサーバーが裏側で起動しています。
![DirectoryServiceドメインサーバー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944513/389081bc-2d83-aabf-2b7e-1bd2bddf42ff.png)

これらのサーバーはAWS側で管理されており、コンソール上からはリソースとして確認できませんが、裏側でAWSが起動しているのです。
この、裏側で起動しているサーバーとENIとの間は直接接続が行われているため、セキュリティグループのインバウンドを開けなくても接続が可能なのです。

## セキュリティグループはどこにアタッチされているのか

もう一歩理解を深めるためにセキュリティグループがどこにアタッチされるのかについて話します。
ClientVPNのエンドポイント作成時に設定するセキュリティグループは、**実際にはENIに対してアタッチ**されます。
ClientVPNのエンドポイント作成時にENIを確認すると、ClientVPNのENIが作成され、指定したセキュリティグループがアタッチされているはずです。
![ClientVPNENI](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944513/5319c49b-7c07-c09e-b496-ade10f5074ed.png)

前述したように、AWS管理の裏側で立ち上がっているサーバーとENIの間は直接接続されています。
そのため、セキュリティグループのインバウンドを開けなくても接続が可能です。
細かい話をすれば、ENIに直接アクセスするようなケースがない限り、セキュリティグループのインバウンドを開ける必要はありません。
つまり、AWSで用意されたアプリケーションをローカルにインストールしてそこからアクセスするようなケースだけであればインバウンドを開ける必要はないのです。

## よくある勘違いから生まれるセキュリティリスク

ここまで説明した通り、マネージドサービスではアタッチするセキュリティグループのインバウンドを開ける必要がないケースがあります。
しかし、「ユーザーからアクセスしているのだから何かしら開ける必要がある」と勘違いしている方が多くいらっしゃいます。

不要なインバウンドを開けてしまうことで、外部からの攻撃を受けやすくなり、セキュリティリスクが増大する可能性があります。
AWSのネットワークの仕組みを正しく理解し、必要最低限のポートやIPレンジのみを開けることが重要です。

## まとめ

AWSのマネージドサービスを利用する際、セキュリティグループのインバウンドルールを無理に開放する必要はありません。
マネージドサービスはAWSがインフラストラクチャを管理し、必要なネットワーク接続を確保しているため、ユーザー側でのインバウンド設定は不要です。

誤ったインバウンド設定はセキュリティリスクを高める可能性があるため、サービスごとの正しいネットワーク設定を理解し、最小限のセキュリティグループ設定を適用することが重要です。
これにより、安全かつ効率的にAWSのマネージドサービスを活用することができます。
AWSのCodeDeployでWindowsサーバにアプリをデプロイしてみる

## 概要
2024年Qiitaアドベントカレンダー2回目の投稿になりますので、よろしくお願いします。
CodeDeployの情報はデプロイ先がLinuxのものが多く、Windowsサーバの情報がほとんどなかったので、備忘録の意味も含めて皆様に共有できればと思ってこの記事を投稿します。
CodeBuildやCodePipeline、ECRでのCI/CDを構築したことはありましたが、CodeDeployを使うことがなく、対応した案件内ではWindowsサーバへのデプロイが求めらたこともあったので、色々と調べることになりました。

## インフラ構成図
今回想定するCI/CD構成は下記の通りになります。ただ構成手順を全て記載すると膨大な量になるので、ポイントとなる部分をかいつまんで記載させていただきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321920/85d8d07c-f461-9538-1862-832616be0046.png)

この投稿ではWindows Serverへのデプロイに必要な箇所を記載していますので、基本的なAWSでCI/CDの構築方法は他の情報を参考にしていただければと思います。

## 前提
今回は.Netのサンプル用のAPIサーバーをデプロイするようCI/CDを回します。
デプロイ先はEC2のWindows Server2022です。
インフラ構成図ではCodeCommitを使っていますが、現在は場合によって新規リポジトリは作成できないので、GitHub等の代替ホスティングサービスを使用してください。

## 構築
### ディレクトリ構成
今回の記事では下記のディレクトリ構成でCI/CDを回していくことを想定しています。
```
project/
├── src/
│   ├── SimpleServer
│   ├── Program.cs
│   └── SimpleServer.csproj
├── Script
│   ├── StartService.ps1
│   └── StopService.ps1
├── appspec.yml
└── buildspec.yml
```
src配下のコードはサンプルAPIサーバーとして下記リンク先のコードを使わせてもらっています。

https://github.com/jchristn/SimpleServer

Script配下はCodeDeployの起動時にサーバ上で実行されるファイルが格納されています。
`appspec.yml`はCodeDeployの定義ファイルで、`buildspec.yml`はCodeBuildの定義ファイルになります。

### buildspec.yml
まずCodeBuild用の定義ファイルになります。
.Netのアプリをビルドし、実行ファイルとして公開できるようにしてから、Zip化してS3バケットに配置するという流れになります。

```
version: 0.2
phases:
  install:
    runtime-versions:
      dotnet: 8.0
    commands:
      - echo Install Package
      - dotnet restore
  build:
    commands:
      - echo Build Code
      - dotnet build --configuration Release --no-restore
  post_build:
    commands:
      - echo Publish Application
      - dotnet publish --configuration Release -r win-x64 --self-contained true -f net8.0 --artifacts-path ./output

artifacts:
  files:
    - '../output/publish/**/*'
    - '../appspec.yaml'
    - '../Script/*'
  discard-paths: yes
  base-directory: ./src
```

### appspec.yaml
CodeDeployの定義署になりますが、Windowsの事例は本当に少ないので、参考にしてもらえればと思います。
分かる方はすぐにできると思いますが、調べながら対応したので、結構時間がかかりましたね〜
```
version: 0.0
os: windows
files:
  - source: /
    destination: C:¥Users¥Administrator¥Desktop¥test
hooks:
  BeforeInstall:
    - location: .¥Script¥StopService.ps1
      timeout: 300
  AfterInstall:
    - location: .¥Script¥StartService.ps1
```
上記のファイルで、S3に配置したアプリをWindowsの`test`ディレクトリに配置をすることを定義しています。
フックでは、インストール前に`StopService.ps1`ファイルを実行して、アプリを停止して、インストール後に`StartService.ps1`ファイルを実行してアプリを起動するという定義になります。

ちなみに`StopService.ps1`ファイルが、
```
Stop-Process -Name "SimpleServer" -Force
```
StartService.ps1`ファイルが、
```
Start-Process -FilePath "C:¥Users¥Administrator¥Desktop¥test¥SimpleServer.exe"
```
となります。

### 構築
CodeCommitにリポジトリを構築し上記のディレクトリでコードを配置します。
CodeBuildやCodeDeploy、CodePipelineも特に変わった設定なくシンプルに構築します。
アプリを配置するS3バケットを構築し、デプロイ先のEC2を起動しておきます。

### 実行
CodeCommitにコードをプッシュするとPipelineが実行され、最終的にEC2にアプリがデプロイされます。

## 最後に
Windows Serverに関するCodeDeployの情報が少ないことでこの記事を投稿してみましたが、なぜ少ないんでしょうかね〜デプロイ先としてWindows Serverは選択肢として少ないんでしょうかね〜と思っていますが、実際はどうですかね。
一応、Windows ServerへのCodeDeployを使った自動デプロイ方法としてみなさんの参考になればと思っています。
もしご指摘等ありましたらコメントいただければと思いますので、よろしくお願いいたします。
AWSの基礎：Route 53、ELB、Auto Scalingの役割と連携

Amazon Route 53、Elastic Load Balancing (ELB)、Auto Scalingは、AWSのインフラストラクチャサービスで、主に高可用性、スケーラビリティ、パフォーマンスを確保するために連携して使われます。それぞれが以下の役割を果たします：

### **1. Amazon Route 53 (DNSサービス)**
- **役割**: DNS（Domain Name System）を管理するサービスで、ドメイン名をIPアドレスに解決します。
- **関係**:
  - ELBのエンドポイントをDNS名として提供し、トラフィックを適切なロードバランサーにルーティングします。
  - Auto Scalingで生成された動的なリソース（例: 新しいEC2インスタンス）にも対応可能です。
  - ヘルスチェック機能で、異常なエンドポイントを検出してトラフィックを健全なエンドポイントに誘導します。

### **2. Elastic Load Balancing (ELB)**
- **役割**: トラフィックを複数のEC2インスタンスやサービスに分散することで、高可用性を確保します。
- **関係**:
  - Auto Scalingでスケールアウト（増加）またはスケールイン（削減）されたEC2インスタンスを自動で検出し、トラフィックの負荷を調整します。
  - Route 53と連携して、DNS名を通じてロードバランサーにトラフィックをルーティングします。

### **3. Auto Scaling**
- **役割**: システムの負荷に応じて、EC2インスタンスの数を自動で増減します。
- **関係**:
  - ELBと連携して、スケールアウトされたインスタンスを負荷分散プールに追加し、スケールインされたインスタンスを削除します。
  - Route 53が提供するエンドポイントを通じて、増減したインスタンスの影響を最小限に抑えます。

---

### **三者連携の具体例**
1. **トラフィックのルーティング**:
   - Route 53がユーザーリクエストをELBにルーティング。
2. **負荷分散**:
   - ELBがリクエストを現在稼働中のEC2インスタンスに分散。
3. **動的なリソース管理**:
   - トラフィックが増加すると、Auto Scalingが新しいEC2インスタンスを起動し、ELBのバックエンドに追加。
   - トラフィックが減少すると、不要なインスタンスを削除。

これらのサービスを組み合わせることで、スケーラブルで信頼性の高いアプリケーションのデプロイが可能となります。
Pythonのリスト内包表記で効率的なデータ操作をマスターしよう

了解しました！以下は、プロフェッショナルな印象を与えられるようなコーディング関連の記事の例です。テーマとして「Pythonでのリスト内包表記の使い方」を選びました。

---

# Pythonのリスト内包表記で効率的なデータ操作をマスターしよう

こんにちは！今回はPythonでの強力なツール「リスト内包表記」について解説します。リスト内包表記を使えば、コードをより簡潔かつ効率的に書くことができます。初心者にも分かりやすく、かつ実践的な例を交えながら説明していきます。

---

## リスト内包表記とは？

リスト内包表記は、リストを簡単に生成するためのPython特有の構文です。従来のforループを使ったリスト生成を1行で記述できるため、コードの見通しが良くなります。

基本構文は以下の通りです：

```python
[expression for item in iterable]
```

例えば、0から9までの整数のリストを生成する場合：

```python
numbers = [x for x in range(10)]
print(numbers)  # 出力: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
```

簡潔で読みやすいですよね？

---

## 条件付きリスト内包表記

条件を追加することで、特定の条件を満たす要素だけをリストに含めることもできます。

```python
even_numbers = [x for x in range(10) if x % 2 == 0]
print(even_numbers)  # 出力: [0, 2, 4, 6, 8]
```

ここでは、`x % 2 == 0`という条件で偶数だけをフィルタリングしています。

---

## ネストしたリスト内包表記

リスト内包表記はネストすることも可能です。例えば、二次元配列をフラットにする場合：

```python
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat_list = [item for row in matrix for item in row]
print(flat_list)  # 出力: [1, 2, 3, 4, 5, 6, 7, 8, 9]
```

読みづらくなる場合は、適切にコメントを追加して補足しましょう。

---

## 実践例：文字列操作

次に、実践的な例として、文字列のリストを操作するケースを紹介します。

```python
words = ["apple", "banana", "cherry"]
capitalized_words = [word.capitalize() for word in words]
print(capitalized_words)  # 出力: ['Apple', 'Banana', 'Cherry']
```

データの前処理やテキスト処理に便利ですね！

---

## 注意点

リスト内包表記は便利ですが、使いすぎると可読性を損なう場合があります。以下の場合には従来のforループを検討しましょう：

1. ネストが深すぎる場合
2. 複雑な処理を含む場合

読みやすさと効率性のバランスを意識することが大切です。

---

## まとめ

リスト内包表記をマスターすると、コードの簡潔さと効率が大幅に向上します。ぜひ、自分のプロジェクトで試してみてください！

Qiitaの記事では読者に価値を提供することが大切です。この記事があなたのPythonスキル向上に役立てば幸いです。コメントやフィードバックもお待ちしています！

--- 

どうでしょうか？読み手の興味を引きつけつつ、具体例で理解を深められる内容にしました！
初心者エンジニア向け：Pythonで始める簡単なウェブスクレイピング入門

### 初心者エンジニア向け：Pythonで始める簡単なウェブスクレイピング入門

ウェブスクレイピングは、データ収集や分析にとって非常に便利なスキルです。この記事では、Pythonを使ってシンプルなウェブスクレイピングを実現する方法を解説します。Pythonは初心者にも扱いやすく、強力なライブラリが豊富に揃っているため、非常に適した選択肢です。

---

#### **必要なツールと環境**
まず、Python環境を準備しましょう。おすすめは以下の通りです：
- Python 3.x（公式サイトからインストール可能）
- 必要なライブラリ：`requests` と `BeautifulSoup`

次に、ライブラリをインストールします。以下のコマンドをターミナルで実行してください：

```bash
pip install requests beautifulsoup4
```

---

#### **サンプルコード：HTMLからデータを取得する**
ここでは、あるウェブサイトのタイトルを取得する簡単な例を示します。

```python
import requests
from bs4 import BeautifulSoup

# 1. URLの指定
url = "https://example.com"

# 2. ページの取得
response = requests.get(url)

# 3. HTMLの解析
soup = BeautifulSoup(response.text, 'html.parser')

# 4. タイトルを取得
title = soup.title.string
print(f"ページのタイトルは: {title}")
```

このコードを実行すると、指定したウェブサイトのタイトルがコンソールに表示されます。

---

#### **もう一歩進んだ例：複数のデータを取得**
例えば、ブログの記事タイトルをすべて取得したい場合、以下のようにします：

```python
# 記事タイトルの取得
articles = soup.find_all('h2', class_='article-title')

for i, article in enumerate(articles, start=1):
    print(f"{i}: {article.text}")
```

`find_all` メソッドを使うことで、特定のタグやクラスにマッチする要素を全て取得できます。

---

#### **注意点：ウェブスクレイピングのルールを守る**
ウェブスクレイピングを行う際は、ターゲットサイトの利用規約や`robots.txt`を必ず確認してください。不正なスクレイピングは法的問題を引き起こす可能性があります。

---

#### **最後に**
ウェブスクレイピングは多くの分野で役立つスキルです。この記事をきっかけに、自分で興味のあるデータを取得してみてください！また、Qiitaでの共有や他の投稿者との交流を通じて、知識をさらに深めていきましょう。

「コードを書く楽しさを、もっと広げましょう！」

--- 

この記事が役立つと感じたら、ぜひ「いいね」やコメントをお寄せください！読者のフィードバックをお待ちしています。
連想配列を使ってコントローラからビューにデータを渡す

<p>Laravelを勉強し始めて間もない頃につまずきがちな"連想配列"ですが、コントローラからビューに値を受け渡す際に使われます。<br><br>連想配列って？<br>なんで連想配列で記述すると値をビューに渡すことができるの？<br><br>そんな疑問にお答えします！
</p>

# 配列と連想配列
<p>
配列と連想配列について確認します。
</p>

### 配列について

<p>配列の例は以下です。<br>
\$data = ['name', 'tokyo', 'soccer', 12];<br><br>
配列では、各要素に整数のインデックス番号(0,1,2...）が自動的に割り当てられます。<br>
・0 => 'taro'<br>
・1 => 'tokyo'<br>
・2 => 'soccer'<br>
・3 => 12<br><br>
配列の各要素は、インデックス番号を使ってアクセスできます。例えば、$data[0]とすると'taro'にアクセスできます。
</p>

### 連想配列について<br>
<p>連想配列の例は以下です。<br>
\$data = [<br>
    &emsp;&emsp;'name' => 'taro',<br>
    &emsp;&emsp;'city' => 'tokyo',<br>
    &emsp;&emsp;'sport' => 'soccer',<br>
    &emsp;&emsp;'number' => 12<br>
];<br><br>
連想配列では、各要素に任意のキー（文字列などを）割り当ててアクセスします。番号ではなく、意味のある名前でアクセスできるため、より直感的でわかりやすいです。<br>
・'name' => 'taro'<br>
・'city' => 'tokyo'<br>
・'sport' => 'soccer'<br>
・'number' => 12<br><br>
各要素は、キーを使ってアクセスします。<br>例えば、$data['city']で'tokyo'にアクセスできます。
</p>

# 連想配列でコントローラからビューにデータを受け渡す
<p>Laravelでは、ビューに渡すデータを連想配列としてまとめることが一般的であり、Laravelの公式ドキュメントでも推奨されています。そこで、記述例を以下に記載します。</p><br>
<p>
コントローラ側の記述は以下<br>
class TestController extends Controller<br>
{<br>
&emsp;public function index(Request $request)<br>
&emsp;{<br>
&emsp;&emsp;$data = [<br>
&emsp;&emsp;&emsp;'name' => 'taro',<br>
&emsp;&emsp;&emsp;'city' => 'tokyo',<br>
&emsp;&emsp;&emsp;'sport' => 'soccer',<br>
&emsp;&emsp;&emsp;'age' => 12<br>
&emsp;&emsp;];<br>
&emsp;&emsp;return view('test.index', \$data);<br>
&emsp;}<br>
}<br>
</p><br>

ビュー側の記述は以下
<p>名前：{{ \$name }}</p>
<p>出身：{{ \$city }}</p>
<p>得意なスポーツ：{{ \$sport }}</p>
<p>年齢：{{ \$age }}</p>


### Laravelの内部動作
<p>ここで一つ気になる点があります。それは、連想配列のキーにそれぞれ'name, 'city', 'sport', 'age'と指定しているだけで、ビュー側で\$name, \$city, \$sport, \$ageという変数として扱うことができています。これはなぜでしょうか？</p>
<p>実は、<strong>Laravelが内部的に配列のキー名を変数名として自動展開</strong>しているのです。Laravelを学習する上でつまずきポイントだと思うので理解しておくと良いです。私はLaravelを使った開発期間中、謎に思いながらコードを書いていました笑</p>
ニューラルネットワークをまとらぼ関数シミュリンクで再現


```
function [sigmoid_output, weighted_sum, binary_output] = sigmoid_with_sum(x1, x2, x3)
    % 重みとバイアスを事前に設定（ここでは例として設定）
    w1 = 0.5;  % x1に対する重み
    w2 = -0.3; % x2に対する重み
    w3 = 0.8;  % x3に対する重み
    bias = 0.4; % バイアス項

    % 重み付き入力の合計
    weighted_sum = w1 * x1 + w2 * x2 + w3 * x3 + bias;
    
    % シグモイド関数
    sigmoid_output = 1 / (1 + exp(-weighted_sum));  % シグモイド関数の適用

    % ビット生成出力: sigmoid_output が 0.5 より小さいなら 0、そうでなければ 1 を出力
    if sigmoid_output < 0.5
        binary_output = 0;
    else
        binary_output = 1;
    end
end

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/af9faa9f-58cf-079b-6f8b-6ad7f6632baa.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/75875c0c-a0e9-247c-2473-7a9f9a93ad43.png)
summary(サマリー)を書こう

# はじめに
職場で「summary(サマリー)をちゃんと書こう」という話が出ました。

https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/xmldoc/recommended-tags

公式ページによると多くのタグがありますが、
とりあえず、使いそうなものをピックアップしました。

* summary
* remarks
* param
* returns
* exception

# サンプル
```c#
/// <summary>
/// 文字列の先頭から指定した文字数の文字列を返します。
/// </summary>
/// <remarks>
/// lengthが0未満の場合：ArgumentException<br/>
/// strがnullの場合：null<br/>
/// lengthが0の場合：string.Empty<br/>
/// lengthが文字数以上の場合：str
/// </remarks>
/// <param name="str">文字列</param>
/// <param name="length">文字数</param>
/// <returns>取得した文字列</returns>
/// <exception cref="ArgumentException">lengthが0未満の場合</exception>
public static string Left(string str, int length)
{
    if (length < 0) throw new ArgumentException("引数'length'は0以上でなければなりません。");
    if (str == null) return null;
    if (length == 0) return string.Empty;
    if (str.Length <= length) return str;

    return str.Substring(0, length);
}
```

マウスカーソルを当てるとこんな感じになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779420/02f9f22a-0f63-b082-6d98-2f40097f7932.png)
AWSのフェイルオーバーとは？利用できるサービスを紹介

AWSのフェイルオーバーとは、システム障害時にサービスを継続するために自動的にリソースやインスタンスを切り替える仕組みです。以下は、AWSでフェイルオーバーを実現する主なサービスです。

---

### 1. **Route 53 (DNSフェイルオーバー)**  
AWSのDNSサービスであるRoute 53は、ヘルスチェックを利用してリソースの状態を監視し、障害が発生した場合にトラフィックを正常なリソースに自動的にルーティングします。  
**用途例**: サーバーがダウンした際にバックアップサーバーに切り替え。

---

### 2. **Elastic Load Balancer (ELB)**  
トラフィックを複数インスタンスに分散し、正常なインスタンスにルーティング。  
**用途例**: ウェブアプリケーションの可用性を向上。

---

### 3. **Auto Scaling**  
障害発生時に新しいインスタンスを自動起動してリソースを復元。  
**用途例**: サーバー障害の復旧。

---

### 4. **EC2 インスタンスの冗長化**
障害発生時にEC2インスタンスを別のアベイラビリティゾーン（AZ）に自動的に再起動するよう設定できます。

---

### 5. **Elastic IP**  
Elastic IPを使用して、新しいインスタンスに同じIPを割り当て、継続的にアクセス可能に。

---

### 6. **RDS (リレーショナルデータベースサービス)**

- **マルチAZ配置**: RDSにはマルチAZ配置（Multi-AZ Deployment）オプションがあり、プライマリデータベースに障害が発生した場合、自動的にセカンダリ（スタンバイ）インスタンスにフェイルオーバーします。  
- **用途例**: データベースの高可用性を維持。

---

### 7. **Aurora (リレーショナルデータベース ※高可用性データベース)**  
Auroraは自動的なフェイルオーバー機能を備えており、プライマリインスタンスが障害を起こした場合、リードレプリカが自動的にプライマリとして昇格します。

---

### 8. **AWS Global Accelerator**  
グローバルにトラフィックを最適化し、障害時には別リージョンに切り替えます。  
**用途例**: 国際的なアプリケーションの高可用性。

---

### 9. **S3クロスリージョンレプリケーション**  
データを複数のリージョンにレプリケートし、障害時でもデータを利用可能に。  
**用途例**: データ耐久性の確保。


---

### フェイルオーバーが重要な理由
- **可用性の向上**: システムが停止してもサービスを継続可能。
- **ビジネスの継続性**: 障害が顧客体験やビジネス運営に与える影響を最小限に抑えられる。
- **復旧時間の短縮**: 自動化によりダウンタイムを大幅に削減。
【ArticleHub Project ノート】05.Webpackでプロジェクトをビルド

https://github.com/KyleAndKelly/ArticleHub
### Webpackの紹介

Webpackは、静的モジュールの内容を圧縮、統合、変換するためのツールです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/83f88c16-aea9-7e46-1fe3-a4fbabd41d39.png)


### JavaScriptファイルのビルド

1. プロジェクトのルートディレクトリに`webpack.config.js`を新規作成します。
2. 出力設定オブジェクトをエクスポートし、エントリーポイントと出力ファイルのパスを指定します。
3. 再ビルドして結果を確認します。

4. 注意：エントリポイントに直接または間接的に関係のあるファイルのみがビルドされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/ed9d2057-7111-59a6-7758-0e631ee559a5.png)



### HTMLファイルのビルド

1. `html-webpack-plugin`をローカルにインストールします。
2. `webpack.config.js`でWebpackがプラグイン機能を使用できるように設定します。
3. 再ビルドして効果を確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/d46d55ec-9858-fd28-46d7-2d0ce3dbb5b7.png)



### CSSファイルのビルド

Loaderである`css-loader`を使ってCSSコードを解析します。
Loaderである`style-loader`を使って、解析後のCSSコードをDOMに挿入します。

手順：

1. CSSファイルのコードをsrc/login/index.jsに準備し、圧縮・変換を行います。
2. `css-loader`および`style-loader`をローカルにインストールします。
3. `webpack.config.js`でWebpackがLoader機能を使用できるように設定します。
4. ビルド後に効果を確認します。

5. 注意：WebpackはデフォルトでJavaScriptコードのみを認識します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/2e19b495-f529-de4c-ac7c-2d63525da187.png)



### 画像ファイルのビルド

Webpack5では、内蔵のリソースモジュール（フォント、画像など）を使ってビルドが可能です。追加のLoaderは不要です。

手順：

1. `webpack.config.js`でWebpackが画像ビルド機能を使用できるように設定します。
  
   ✓ プレースホルダー【hash】は、モジュールの内容を計算して、文字と数字の組み合わせ文字列を生成します。
   ✓ プレースホルダー【ext】は、元のファイルの拡張子（.png、.jpgなど）を使用します。
   ✓ プレースホルダー【query】は、コード中のクエリパラメーターを保持します（URLのみに有効）。

2. ビルド後の効果や差異を確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/54a8e90e-bff2-7e6d-442f-d44676abbc1f.png)



### ソースマップの設定

問題：コードが圧縮され、エラーメッセージや警告の正しい位置を確認できない。

source map（ソースマップ）は、エラーや警告が元のコードでどこにあるかを正確にトラッキングできます。

設定：`webpack.config.js`でdevtoolオプションを設定します。

inline-source-mapオプション：ソースの位置情報を一緒にビルドして、JavaScriptファイル内に格納します。

注意：source mapは開発環境のみで使用してください。生産環境では使用しない方がよいです（元のコードが容易に確認されるのを防ぐため）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/bc552668-8dc0-fda6-5c64-48360f0eaa4f.png)
【ArticleHub Project ノート】04.Contentページの開発

### 文章リストの表示

**目標**：記事リストを取得し、表示する。

**手順**：

1. クエリパラメータオブジェクトを準備する。
2. 記事リストのデータを取得する。
3. 指定されたタグ構造にデータを表示する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/94a03a98-cae9-b62a-f4e8-e07a51b327c3.png)


---

### フィルタ機能

**目標**：フィルタ条件に基づいて、マッチするデータを取得し、表示する。

**手順**：

1. チャンネルリストデータを設定する。
2. フィルタ条件の変更を監視し、クエリパラメータオブジェクトに情報を保存する。
3. フィルタボタンをクリックした際に、クエリパラメータオブジェクトをサーバーに送信する。
4. マッチするデータを取得し、ページに表示する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/fa0dfc88-6a94-c7c3-c440-016a94a61148.png)



---

### ページネーション機能

**目標**：記事リストのページング管理機能を完成させる。

**手順**：

1. 記事の総数を保存し、設定する。
2. 次のページをクリックした際に、境界値を判定し、ページ番号パラメータを切り替えて最新データをリクエストする。
3. 前のページをクリックした際に、境界値を判定し、ページ番号パラメータを切り替えて最新データをリクエストする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/ccac79fc-2283-de5b-7f9f-886079746a8d.png)
AWS CloudFormation で利用する cfg ファイルに関する学習メモ

# これなに

- AWS CloudFormation の実行を色々試したときに気になった以下の点：
    - cfg ファイルとは？
    - どうやって使う？
- これらの内容を個人的な学習メモとして記録した記事です

# cfg ファイルとは？

- 端的に言うと設定ファイル
- CloudFormation では主に任意のパラメーターの値を決め打ちで設定しておきたい時に利用

# どうやって使う？

- cfg ファイルには変数名と値をイコールで結んで設定します
- CloudFormation を実行するための yml ファイル内で cfg ファイルの中身を呼び出すには `!Ref` という記載をする
- 実行時には cat で cfg ファイルの中身を渡して実行する

### cfg ファイル内容の例

例えば `dev.cfg` という名前で作成

```cfg
EnvironmentName=su3hokkaido
ClusterName=su3hokkaido-cluster
DatabasePassword=rds-database-secret-password
Keypairname=keypair01
ApplicationDesiredCount=1
DesiredCount=1
DBInstanceClass=db.t4g.micro
DBName=su3hokkaido_db
DBMasterUsername=su3hokkaido_user
```

### yml ファイル内での呼び出し方

`!Ref` という接頭語を付けた上で変数名を呼び出す

```yml
...
  Cluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: !Ref ClusterName

  ApplicationTaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: todobackend
      Volumes:
        - Name: public
          Host:
            SourcePath: /data/public
      ContainerDefinitions:
        - Name: todobackend
          Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/su3hokkaido/todobackend:${ApplicationImageTag}
          MemoryReservation: 395
          Cpu: 245
          MountPoints:
            - SourceVolume: public
              ContainerPath: /public
          Environment:
            - Name: DJANGO_SETTINGS_MODULE
              Value: todobackend.settings_release
            - Name: MYSQL_HOST
              Value: !Sub ${ApplicationDatabase.Endpoint.Address}
            - Name: MYSQL_USER
              Value: todobackend
            - Name: MYSQL_PASSWORD
              Value: !Ref DatabasePassword # ここで dev.cfg から変数を呼び出している
            - Name: MYSQL_DATABASE
              Value: todobackend
            - Name: SECRET_KEY
              Value: some-random-secret-should-be-here
...
```

### 実行時に cat で呼び出す

`--parameter-overrides $(cat dev.cfg)` で cfg ファイルに定義した変数を呼び出している

```zsh
aws cloudformation deploy --template-file cloudformation_task_definition.yml --stack-name su3hokkaido-app --parameter-overrides $(cat dev.cfg) --capabilities CAPABILITY_NAMED_IAM --no-execute-changeset
```


# あとがき

CloudFormation は便利だけどいろんな情報があって大変…
ちゃんと自分のサンプルファイルを作っておこう
[競プロ][Python] collections.Counter活用術

Pythonのcollections.Counterは、競技プログラミングで利用できる強力なツールです。以下のようなパターンでよく使用されます。

## 要素の頻度計算
与えられた配列や文字列内で、各要素の出現回数を簡単にカウントできます。

例題：
配列内で最も頻度が高い要素を見つける。重複した要素を探す。
```python
from collections import Counter

arr = [1, 2, 2, 3, 3, 3, 4]
counter = Counter(arr)
most_common = counter.most_common(1)[0]  # [(要素, 出現回数)]のリスト
print(most_common)  # 出力: (3, 3)
```

## アナグラム判定
2つの文字列がアナグラム（文字の並べ替えで一致）かどうかを確認します。

例題：
入力された2つの文字列がアナグラムかどうかを判定。
```python
from collections import Counter

s1 = "listen"
s2 = "silent"

if Counter(s1) == Counter(s2):
    print("アナグラム")
else:
    print("アナグラムではない")
```

## 条件付きの頻度チェック
一定の条件を満たす頻度の要素を抽出するパターン。

例題：
配列内でk回以上出現する要素を抽出。

```python
from collections import Counter

arr = [1, 1, 2, 2, 2, 3, 4, 4, 5]
k = 2
counter = Counter(arr)
result = [key for key, count in counter.items() if count >= k]
print(result)  # 出力: [1, 2, 4]
```

## 多重集合の操作
複数のリストの要素間で和・積・差を計算できます。

例題：
2つのリストの共通部分や差分を求めるパターン。

```python
from collections import Counter

list1 = [1, 2, 2, 3]
list2 = [2, 3, 3, 4]

counter1 = Counter(list1)
counter2 = Counter(list2)

# 共通部分
intersection = counter1 & counter2
print(list(intersection.elements()))  # 出力: [2, 3]

# 差分
difference = counter1 - counter2
print(list(difference.elements()))  # 出力: [1, 2]
```

## 頻度のカウントで分類
出現回数に基づいて要素をグループ化するパターン。

例題：
要素を頻度ごとに分類。

```python
from collections import Counter

arr = [1, 1, 2, 2, 2, 3, 4, 4]
counter = Counter(arr)
grouped = {freq: [key for key, count in counter.items() if count == freq] for freq in set(counter.values())}
print(grouped)  # 出力: {2: [1, 4], 3: [2], 1: [3]}
```

## スライディングウィンドウでの使用
ウィンドウ内の要素頻度を動的に管理するパターン。

例題：
部分配列内の要素頻度を効率的にカウント。

```python
from collections import Counter

arr = [1, 2, 2, 3, 3, 3, 4]
k = 3

window_counter = Counter(arr[:k])
print(window_counter)  # 最初のウィンドウの頻度

for i in range(k, len(arr)):
    window_counter[arr[i - k]] -= 1  # 古い要素を削除
    if window_counter[arr[i - k]] == 0:
        del window_counter[arr[i - k]]  # 0になったら削除
    window_counter[arr[i]] += 1  # 新しい要素を追加
    print(window_counter)  # 各ウィンドウの頻度
```

## 辞書順での頻度カウント
頻度が同じ場合、要素を辞書順にソートして出力します。

例題：
頻度順、かつ同頻度の場合は辞書順に並べる。

```python
from collections import Counter

arr = ["apple", "banana", "apple", "cherry", "banana", "apple"]
counter = Counter(arr)

# 頻度順、同頻度なら辞書順
sorted_result = sorted(counter.items(), key=lambda x: (-x[1], x[0]))
print(sorted_result)  # 出力: [('apple', 3), ('banana', 2), ('cherry', 1)]
```

## まとめ
これらのパターンを理解しておくことで、競技プログラミングの問題で効率的に活用できます。特に、データの頻度分析や集合演算に役立ちます。
Software Design 

Software Design (ソフトウェアデザイン) Calendar 2024
https://qiita.com/advent-calendar/2024/softwaredesign
day 20投稿予定記事です。

最近、技術評論者の雑誌、書籍を買っていません。ごめんなさい。

Software Design (ソフトウェアデザイン) 2024年12月号 (発売日2024年11月18日) の目次
https://www.fujisan.co.jp/product/1535/
>［連載］ITエンジニア必須の最新用語解説【192】Valkey 8.0 ......杉山 貴章
［連載］万能IT技術研究所【31】結婚式や葬式が決められない!? 旧暦2033年問題――150年前に廃された天保暦に仕込まれた時限爆弾 ......万能IT技術研究所
［連載］FE/AP試験問題に挑戦【2】情報セキュリティ（技術） ......石田 宏実
［連載］ドメイン解体新書【11】セキュリティとパフォーマンスを向上するHTTPSレコード ......谷口 元紀
［連載］ハピネスチームビルディング【33】小さなシェアドリーダーシップの発揮を見える化しよう ......小島 優介　
読者プレゼントのお知らせ
■第1特集 落し穴にハマる前に！ シェルスクリプトの基本と罠 コンテナ、クラウド、Web開発、なにかと使える基礎技術
第1章：シェルスクリプトの基礎 利点・欠点・使いどころを認識しよう ......滝澤 隆史
第2章：シェルスクリプトの基本文法 実務で頻出の機能を要領よく学ぼう ......滝澤 隆史
第3章：シェルスクリプトの使いどころ CLIコマンドの活用が業務効率化のカギ ......山田 泰宏
第4章：落し穴に落ちないシェルスクリプト開発のススメ ShellCheckとShellSpecで安全なシェルスクリプトを作る ......近松 直弘
■第2特集 10周年特別 ［最新］Swiftの現場 これまでの進化の軌跡＆Swift 6レポート ......田中 涼賀
第1章：10周年を迎えるSwiftのこれまで Apple謹製言語の歩みを振り返る
第2章： Swift 6への移行 求められる既存コード変更へのヒント
SD BOOK REVIEW
［短期連載］［速習］PHPアプリ開発の現在地【2】PHPUnitのassertSameとassertEqualsの実装ってどう違うの？ ......asumikam
［連載］Cloudflare Workersへの招待【13】Cloudflare Queuesを使ってバックグラウンドで処理してみよう ......Aiji Uejima
SD 総集編のお知らせ
［連載］ソフトウェアテスト探検隊【3】シフトレフトテスティングの意義と戦略 ......Kuniwak
［連載］実践データベースリファクタリング【11】ループされたクエリの倒し方 ......曽根 壮大
［連載］レガシーシステム攻略のプロセス【最終回】フロントエンドエンジニアから見るZOZOTOWNリプレイスとまとめ・今後の展望 ......新家 弘久、森 泰樹、高橋 智也、瀬尾 直利
［連載］ぼくらの「開発者体験」改善クエスト【12】テスト体験の改善で、開発者体験を改善 ......西園 和希
［連載］Databricksで勝つデータ活用【最終回】Databricksで始めるデータメッシュアーキテクチャ ......北岡 早紀、桑野 章弘
［連載］実践LLMアプリケーション開発【15】Human-in-the-loopでAIエージェントの動きにフィードバックを加える（後編） ......西見 公宏
［連載］AWS活用ジャーニー【27】AWS WAF ......杉金 晋
［連載］インターネットの姿をとらえる【4】ISPとは何者か ......土屋 太二
［連載］基礎からわかるDetection Engineering【5】検知ルールの評価とDetection Engineering Program① ......石川 朝久
［連載］魅惑の自作シェルの世界【25】引数のシングルクォートの実装とパラメータ展開の準備 ......上田 隆一
バックナンバーのお知らせ
［連載］あなたのスキルは社会に役立つ～エンジニアだからできる社会貢献～【155】バリアフリーに関する情報を誰かの「一歩」に～みんなのトイレマッププロジェクトから見えてきたこと　......菅原 洋介（Pen）
SD NEWS ＆ PRODUCTS
Reader’s Link
次号のお知らせ

# 杉山 貴章
書籍の紹介
https://gihyo.jp/author/杉山貴章

# 石田 宏実
石田宏実の情報処理技術者試験講座
https://www.youtube.com/channel/UCkpHrln-rOvg0QOohl83iTg

情報処理技術者試験　プログラミング(PHP,JAVA,Python,JavaScriptなど)　マーケティング
https://www.udemy.com/user/shi-tian-hong-shi2/
# 谷口 元紀
Genki Taniguchi's Blog
https://www.gtworks.dev/profile

# 小島 優介　
小島 優介 @kojimadev
https://qiita.com/kojimadev

# 滝澤 隆史
滝澤 隆史
https://gihyo.jp/author/滝澤隆史

# 山田 泰宏
1日1問、半年以内に習得 シェル・ワンライナー160本ノック (Software Design plusシリーズ) 
https://www.amazon.co.jp/dp/4297122677
WHERE内のIN句を楽に記述するための正規表現

エンジニアやってると、ちょくちょくSQLを書くタイミングがあると思います。
IN句の中を手作業で加工するのはちょっと大変なので、置換用の正規表現を準備しました。


~~~SQL:サンプルSOQL1
SELECT Id, Name
  FROM Account
 WHERE Name IN (
     --この中を手作業で書いてられない
 )
~~~

検索対象の一覧をエディタで開く。置換用の正規表現を設定し、全置換する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336848/10c14a6f-ed54-5671-c8f2-fd41cee0eb02.png)

    置換前：(.*?)(\r?\n|\r)
    置換後：      , '$1'$2
    
置換後のイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336848/a0740bd5-85e7-f7dc-73c0-dab8b58488f3.png)


エディタの内容をSOQLにペースト。1行目のカンマは手作業で修正する。

~~~SQL:サンプルSOQL2
SELECT Id, Name
  FROM Account
 WHERE Name IN (
     , 'name1' -- カンマ消す
     , 'name2'
     , 'name3'
 )
~~~


主に自分用のメモですが、どなたかのお役に立てば幸いです。


参考：
[囲みナシCSVを、囲みアリに変更する方法～正規表現置換](https://sun-san-tech.com/regex/462/)
【CSRF保護】【CORSエラー】についての理解を深める

## CSRF（クロスサイトリクエストフォージェリ）

CSRFのことをシーサーフって呼んだりもします。
攻撃者が用意した偽造サイトを用いて、ユーザーが意図していないリクエストを強制的に行わせる攻撃手法です。﻿
ログイン状態のユーザーを狙って行われることが多いです。
下記の例は架空の銀行システムです。
ログイン機能があるので、基本的に各機能はログイン済みのユーザーからのリクエストしか受け付けません。
しかし、CSRF保護をしていない場合このような事が起こり得ます。

（例）
①Aさんが銀行システムにログイン
↓
②攻撃者が悪意あるリンク付きのメールをAさんに送る。
↓
③Aさんがメールのリンクをクリック
↓
④Aさんがリンクのサイトを開いた瞬間に銀行のシステムに悪意のあるリクエストを発生させる。
例えば、「Aさんから100万円を攻撃者の口座に送金する」ものとします。
 ↓
⑤銀行システムからすると、認証済みの（ログイン済みの）Aさんのブラウザから送信されたリクエストなので、Aさんからのリクエストだと誤認してリクエストを処理。
↓
⑥攻撃者はAさんから100万円騙し取ることに成功。


現実に金融系のシステムでこんなセキュリティがガバガバなことはまずありませんが、これを防ぐ為にCSRF保護を行う必要があります。

## Same Origin Policy（同一オリジンポリシー）
攻撃者が用意したサイトは、銀行システムと同一オリジンでは無いのでそもそもリクエストを飛ばせないのではないか？と思いましたが違います。
同一オリジンポリシーとは、サーバのリソースを同一オリジンでしか共有出来ないようにするものです。
つまり、ブラウザ側の不正なレスポンスを処理しない為のセキュリティ機能であって、リクエストを制限するものではありません。
同一オリジンでなくてもGETリクエストやPOSTリクエストはサーバーまで届きます。
そのレスポンスをブラウザが処理出来ないというだけであって、CSRFのようにリクエストをサーバーに処理させることが目的なのでレスポンスは受け取れなくても攻撃者からしたら関係ないことです。

## CORS（Cross-Origin Resource Sharing）
しかし、昨今のSPAではブラウザ側とAPIでドメインが異なるシチュエーションがよくあります。
例えば、ローカルの開発環境でも、フロントのReactはポート3000、APIのLaravelはport8000のようにポートが異なるケースです。
ポートが異なるのであれば異なるドメインです。
このようなシチュエーションでCross-Origin Resource Sharingが活躍します。
サーバ側でホワイトリスト形式で許可して通信が出来るようにします。

誰もが一度はCORSエラーに悩まされたことがあるかと思いますが、CORSは本来ありがたいものなんです。

## ブラウザからsessionIDの送り方
javascriptでCookieの中身を見られないならどうやってセットするのか？
axiosでwithCredentials = trueを設定することで、リクエストにCookieに保持したセッションを含めて送ってくれるようになります。

## sessionIDの守り方
サーバからセッションIDをブラウザに返す際、domain属性オプションを指定した上でブラウザに渡す。ブラウザはそれをCookieに保存します。
指定したドメインでなければ、withCredentials = trueを設定してもリクエストに含めることが出来なくなります。これで攻撃者がwithCredentials = trueを指定していてもリクエストにCookieのセッションIDを入れることが出来ないので安心です。


## 最後に
徳丸さんの以下の記事が分かりやすいので一読オススメいたします。

https://www.slideshare.net/slideshow/phpconf2021spasecurity/250357376#4
LLM 関連 Calendar 2024


LLM(Large Language Model)  Calendar 2024
https://qiita.com/advent-calendar/2024/llm

M5Stack Module LLM Advent Calendar 2024
https://qiita.com/advent-calendar/2024/m5stack_module_llm

MLOps（LLMOps、生成AIOps） Advent Calendar 2024
https://qiita.com/advent-calendar/2024/mlops

LLM・LLM活用 Advent Calendar 2024
https://qiita.com/advent-calendar/2024/large-language-model

黒CoPilotと悪役令嬢  Calendar 2024
https://qiita.com/advent-calendar/2024/blackcopilotandvillainess

ChatGPT Calendar 2024
https://qiita.com/advent-calendar/2024/chatgpt

ChatGPT 私の使い方  Calendar 2024
https://qiita.com/advent-calendar/2024/chatgptusecase


生成AI Calendar 2024 @k-keita 
https://qiita.com/advent-calendar/2024/generateai


生成AI Calendar 2024 @uchunanora 
https://qiita.com/advent-calendar/2024/kagai

生成AI駆動開発  Calendar 2024
https://qiita.com/advent-calendar/2024/tatsuki-tsuchiyama

機械学習 Calendar 2024
https://qiita.com/advent-calendar/2024/machine-learning

kaggle入門 Calendar 2024
https://qiita.com/advent-calendar/2024/kaggle_learn

Qiita 自然言語システム Calendar 2024
https://qiita.com/advent-calendar/2024/qiita_nl

AI・機械学習関連論文 Advent Calendar 2024
https://qiita.com/advent-calendar/2024/aiml

からあげ帝国 Calendar 2024
https://qiita.com/advent-calendar/2024/karaage
【Neovim】fidget.nvim💫のメッセージが長すぎるとき

fidget.nvimはLSPとかのロード状況をアニメーションで教えてくれるプラグインです。

https://github.com/j-hui/fidget.nvim

とってもCoolで便利なのですが、rust-analyzerと一緒に使ってたときに表示されるメッセージが長すぎて見切れちゃったので、対処法を書いておきます！

![Screenshot 2024-11-25 212529_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1777479/29939d29-1d03-8953-e490-ab6e49d1317d.png)
↑ 長すぎて見切れちゃってますね

## 方針
どうもメッセージにライブラリ？かなんかのパスが含まれてるせいで長すぎになっちゃってるみたいです。設定でLSPから渡されたメッセージからパスの部分を削除して表示するようにします！！

## Let's GO🦓

##### 1. 次のヘルパー関数を定義します
```lua
-- 文字列がパスかどうか判定します
local function isPath(inputString)
  return string.find(inputString, "[/\\]")
end

-- 文字列をスペースで分割します
local function splitString(inputString)
  local splittedStrings = {}
  for word in string.gmatch(inputString, "%S+") do
    table.insert(splittedStrings, word)
  end
  return splittedStrings
end

-- 文字列からパスを取り除きます
local function removePathFromString(inputString)
  local splittedStrings = splitString(inputString)

  local processedStrings = {}
  for _,word in ipairs(splittedStrings) do
    if not isPath(word) then
      table.insert(processedStrings, word)
    end
  end

  local processedString = ""
  for i,word in ipairs(processedStrings) do
    if i == #processedStrings then
      processedString = processedString..word
    else
      processedString = processedString..word.." "
    end
  end

  return processedString
end

```

##### 2. fidgetの設定に以下を追加
```lua
require("fidget").setup {
  progress = {
    display = {
--===================<ここから追加>===================
      format_message = function(msg)
        local message = ""
        if not msg.message then
          message = msg.done and "Completed" or "In progress..."
        else
          message = removePathFromString(msg.message)
        end
        if msg.percentage ~= nil then
          message = string.format("%s (%.0f%%)", message, msg.percentage)
        end
        return message
      end,
--===================<ここまで追加>===================
    }
  }
}
```

完成！！

## 確認

![Screenshot 2024-11-25 212918.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1777479/c74accca-b935-20b7-e0b2-ba56c47b2c1c.png)

パスの部分がなくなってスッキリしました。やったね！！！🎊🎊🎊🎊🎊🎊

## 参考文献

https://github.com/j-hui/fidget.nvim/blob/main/lua/fidget/progress/display.lua

http://simplesandsamples.com/

https://www.rtpro.yamaha.co.jp/RT/docs/lua/tutorial/library.html
@zureのWAFがめんどくさすぎる

このアホみたいにリクエストをブロックしてくれる仕組みはWAFといい、CDNやゲートウェイ的なところに居着いてリクエストを監視してインターネットからの悪意あるリクエストを排除してくれます。

そしてこの仕組みで我々にてっぺきのぼうぎょを提供することができます。

この素晴らしい仕組みはだいたいのCloudに存在するのですが、驚くことにそのカスタマイズ性の高さはクラウドやWAF界隈でも随一です。

もう気づいてる方もいるかもしれませんが、WAFを入れておくことによって関係者各位の安心を得ることができます。
また、情シスが憧れるほどのしっかりとしたせきゅりてぃは数百以上の判断基準（ルール）から構成されるチェック機構を備え、世界で最も優れた類のWAFとなっています。

ここまででこのWAFの優れたぼうぎょりょくがわかると思いますが、最も優れているのはお堅い業界へセキュリティやってまっせのアピールがしやすくなり、製品やシステムの売り文句とすることができたりできなかったりします。

（中略）

それほどまでに優れたぼうぎょりょくを持ったWAFですが、一つだけクソめんどくさい欠点があります。

**それは信じられないくらい誤検知が多いことです。** (*1)

WAFはその売り文句からのぼうぎょりょくと引き換えに、ちょっとしたNGワードやその筋っぽいリクエストパラメータがあるだけでリクエストをブロック(*2)します。
そのため、そのままではひっかかったリクエストがforbidden、基本的にカスタマイズなしでは使うことができず、API増加時の保守性が最悪(*3, *4)です。
リクエストボディのJSONにあるフリーワードなどは最悪で、容易にNGワードがヒットしリクエストはブロックされます。
更に文中に盛り込まれたランダムな文字列やBASE64エンコードっぽいものを見かけると疑いの眼差しを向け、アノマリースコアが上昇し高い頻度でブロックされます。
また、URLが大嫌いであるため、このリクエストも発作のようにてっぺきのぼうぎょの犠牲となります。
なぜブロックしているのかは開発者にはわかりません。

それがアホみたいな誤検知率とてっぺきのぼうぎょを備えたこのクラウドのアプリケーションファイアウォールです。(*5)

*1 @WSのWAF使ったことあるけどこんな誤検知なかった
*2 ブロックしない検出モードもあります。
*3 WAF対策のテストに盛り込み、取り入れ実施する必要があります。
*4 継続的なメンテナンスが必要です
*5 誤検知が本当に怖い　泣きそう
ネイキッドドメインをCDN化する際に悩んだこと

# はじめに
これまでの社会人人生でなんと2度ネイキッドドメインに対してCDN化をするということを経験したりしてちょっと大変だったり悩ましいシーンなどがあったためここでアウトプットして成仏させていく。

# ネイキッドドメインの悩み
### ネイキッドドメインとは
- ネイキッドドメイン（Zone Apexとも呼ぶ）
  - 例： `example.com`
- サブドメイン
  - 例： `www.example.com`

:::note info
厳密にはサブドメインのように見えてもZone Apexであることもある。
例えば`example.com`ゾーン内で`1.example.com`というレコードに対してNS委任を行い、委任された環境で`1.example.com`ゾーンを作った場合は`1.example.com`がZone Apex。
つまり権威DNSの設定情報（Zone）と同じレコードがApex（頂点）という扱いになる。
:::

### ネイキッドドメインの良さ（個人的感覚）
**分かりやすくそのサービスを象徴しているので、かっこいい！**
- 長らくネイキッドドメインのサービスを運用しているが本当にこれ以外に思いつかなかったりする

### ネイキッドドメインのCDN化が結構大変
- サイトのCDN化の方法として一般的なのが対象サイトのレコードをCDN環境のFQDNにCNAMEすること
- しかしCNAMEには制約が存在しておりCNAMEレコードは他のレコードと同居ができない（[RFC 1912](https://datatracker.ietf.org/doc/html/rfc1912)）
- Zone Apexにはその他NSレコードやSOAレコードが存在しており、モロにこの制約に引っかかってしまう
- この問題を回避するために各CDN提供社が手法を用意している、いくつか参考例を記載する

| ベンダー | 製品 | 手法 | 考慮ポイント |
| ---- | ---- | ---- | ---- |
| AWS | Route53 | Aliasレコード | ・AWSの特定サービスに対してのみネイキッドドメインだったとしてもエイリアスレコードで対応可能（[参考](https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/resource-record-sets-choosing-alias-non-alias.html)） |
| Akamai | Edge DNS | Zone Apex Mapping（ZAM） | ・AkamaiのEdge CDN環境に対してのみネイキッドドメインだったとしてもZAMで対応可能 |
| 色々 | 色々 | IP AnyCast | ・Aレコードとして払い出されたIP AnyCastを設定する<br>・[EDNS Client Subnet（ECS）](https://www.nic.ad.jp/ja/basics/terms/edns-client-subnet.html)に対応していないDNSサーバーだと挙動がおかしかったりする<br>・非対応な場合にクライアントの所在地ではなくDNS問い合わせを行ってきた端末に最も近い環境を応答してしまい遅延に繋がる可能性がある<br>・プライバシーの観点からECSを有効化していないパブリックDNSサーバーも多々存在する|

- IP AnyCastは一見便利そうだがECSの観点など考慮ポイントが多々ある、それ以外の手法は基本的に**使いたいCDNサービスを提供するベンダーの権威DNSへの移行もセットで考えなくてはいけなくなる**ため導入ハードルが一気に上がる
- DNSのサービスは可用性が高いものが多いためそこまで意識する必要がないかもしれないが各社の独自ロジックを使ってしまうと異なるサービスへのZONE転送などができなくなり冗長構成を取りづらかったりする

# まとめ
- ドメイン設計は将来を見越して計画的にやろう
Advent of code 2015 Day 12 Part 1 & Part 2 を Livebook で楽しむ

## はじめに

Advent of code 2024 の準備として、過去回の Advent of code 2015 を Livebook で楽しみます

本記事では Day 12 の Part 1 と Part 2 を解きます

問題文はこちら

https://adventofcode.com/2015/day/12

実装したノートブックはこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/aoc/2015/2015_day12_part1.livemd

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/aoc/2015/2015_day12_part2.livemd

## セットアップ

Kino AOC をインストールします

```elixir
Mix.install([
  {:kino_aoc, "~> 0.1"}
])
```

Kino AOC の使い方はこちらを参照

https://qiita.com/RyoWakabayashi/items/3d3abcf9134cee4dff05

## 入力の取得

"Advent of Code Helper" スマートセルを追加し、 Day 12 の入力を取得します

![スクリーンショット 2024-11-25 21.34.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/73a343a1-2332-70e5-3d1e-f156967cec98.png)

## 私の答え

私の答えです。
折りたたんでおきます。
▶を押して開いてください。

### Part 1

<details><summary>回答</summary>

`Jason.decode!` で JSON 文字列を Map と List の構造に変換できます

Map と List の改造構造を再帰的に探索し、整数なら合計していくモジュールを定義し亜mす

```elixir
defmodule SumIntegers do
  def sum_integers(data) when is_integer(data), do: data

  def sum_integers(data) when is_map(data) do
    data
    |> Map.values()
    |> Enum.map(&sum_integers/1)
    |> Enum.sum()
  end

  def sum_integers(data) when is_list(data) do
    data
    |> Enum.map(&sum_integers/1)
    |> Enum.sum()
  end

  def sum_integers(_data), do: 0
end
```

```elixir
puzzle_input
|> String.split("\n")
|> Enum.map(fn row -> Jason.decode!(row) end)
|> SumIntegers.sum_integers()
```

</details>

### Part 2

<details><summary>回答</summary>

階層が Map で値に "red" を含む場合、合計を 0 にします

```elixir
defmodule SumIntegers do
  def sum_integers(data) when is_integer(data), do: data

  def sum_integers(data) when is_map(data) do
    values = Map.values(data)

    if Enum.find(values, fn value -> value == "red" end) do
      0
    else
      values
      |> Enum.map(&sum_integers/1)
      |> Enum.sum()
    end
  end

  def sum_integers(data) when is_list(data) do
    data
    |> Enum.map(&sum_integers/1)
    |> Enum.sum()
  end

  def sum_integers(_data), do: 0
end
```

```elixir
puzzle_input
|> String.split("\n")
|> Enum.map(fn row -> Jason.decode!(row) end)
|> SumIntegers.sum_integers()
```

</details>

## まとめ

Map と List の階層を再帰的に探索する問題でした

パターンマッチでシンプルに実装できますね
【Raspberry Pi】ラズパイが公式USBハブ作ったよ

ラズパイ公式が[USBハブを作って売り出し](https://www.raspberrypi.com/news/raspberry-pi-usb-3-hub-on-sale-now-at-12/)ました。

いや何でだよ。

以下はRaspberry Pi公式ブログから、[Raspberry Pi USB 3 Hub on sale now at $12](https://www.raspberrypi.com/news/raspberry-pi-usb-3-hub-on-sale-now-at-12/)の紹介です。


# Raspberry Pi USB 3 Hub on sale now at $12

ZeroとA+以外のほとんどのRaspberry PiにはオンボードのUSBハブが組み込まれており、ひとつのUSBポートから分岐できる複数のダウンストリームUSB Aポートを提供しています。
しかし、ポートをいくつ並べても、それ以上の周辺機器をくっつけたくなることもあります。
そのため我々は、Raspberry Piやその他の低性能コンピュータでも使用できる、高性能4分岐USB3.0ハブである[Raspberry Pi USB 3 Hub](https://www.raspberrypi.com/products/usb-3-hub/)を発売します。

![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/30417c29-9418-25bf-57ed-6495750b2a96.jpeg)

主な機能は以下のとおりです。

・8cmの直結ケーブルにアップストリーム用USB3.0 TypeAコネクタ。
・ダウンストリーム用USB3.0 TypeAポートを4個。
・データ転送速度最大5Gbps。
・オプションの3A電源を接続できるUSB-Cソケット。

## Race you to the bottom

どうして独自のUSBハブを作ったのか。
それは、オンラインで入手できるUSBハブの品質と価格に不満を持っていたからです。
汎用性が高くデザインがよく信頼性の高い商品に大枚をはたくか、互換性が低いもしくは信頼性が低いもしくは見た目が悪い、あるいはその全てを兼ね添えた低品質な商品に安物買いの銭失いをするか、そのどちらかしかありませんでした。
さらに大金を払っても粗悪品が届く可能性すらあります。

USBハブは、悪貨が良貨を駆逐する底辺競争に踏み入っています。
Amazonをはじめとした販売サイトは、ハブという機能にぎりぎり応えられる最低限の安物に支配されてしまいました。

そこで我々は[Infineon](https://www.infineon.com/)と協力して高性能なシリコンCYUSB3304を調達し、電子部品の作業をDominicが、工業デザインをJohnが担当し、そして我々の製造能力流通能力を駆使することで、可能なかぎりの低価格で提供できるようにしました。
完成品はRaspberry Piの全モデルで完璧に動作します。
この製品に当社のロゴがついているのは、我々が誇りを持っているからです。
本製品が、市場において現在最高のUSB3.0ハブであることを信じています。

![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/b6fe0190-f61f-e8e7-4fa6-c4442c43a8d9.jpeg)


ぜひ[手に取って](https://www.raspberrypi.com/products/usb-3-hub/)みてください。
きっと気に入ると思います。


# 感想

価格はなんと12ドルです。
まともなUSB3.0ハブとしては最安値価格帯ではないでしょうか。
普通に品質のいいUSBハブが欲しかった人、ちょうどUSBハブを切らしていた人、まともなUSBハブがなくて困っていた人、どうせならRaspberryを支援したい人、などなどせっかくだから購入してみてはいかがでしょうか。

ちなみにAmazonで調べたら100円とか200円とかのUSB3.0ハブもたくさん出てきたりしますが、ああいうのはゴミなので物好き以外は決して手を出さないようにしましょう。
というかああいうの、送料だけで赤字な気もするんだが何処で儲けているんだろうか。

ところで私は……USBハブの先にくっつけるものがバッテリーくらいしかないから何でもいいんだよなあ。
1ファイルでPowerShellを管理者として実行できるバッチファイル

先日、1 ファイルで PowerShell を管理者として実行できるバッチファイルが必要になった。そこで、これまでは単独で利用していた 1、2 のコードを、3 のように組合わせて使用することで作成できた。

1. PowerShell をダブルクリックで実行できるように、バッチファイルに埋め込んで使用するとき
   - ファイルの1行目に次を記述する
   ```batch
   @powershell -NoProfile -ExecutionPolicy Unrestricted "$s=[System.Management.Automation.ScriptBlock]::create((Get-Content \"%~f0\"|Where-Object{$_.readcount -gt 1}) -join \"`n\");&$s" %*&goto:eof
   ```
   
   - 2行目以降に PowerShell を記述する
   - 拡張子 `.bat` で保存する
   <br>
1. ダブルクリックでバッチファイルを管理者として実行できるようにするとき
   - ファイルの先頭に次を記述する
   ```batch
   @echo off
   
   cd /d %~dp0
   
   whoami /priv | find "SeDebugPrivilege" > nul
   if %errorlevel% neq 0 (
       @powershell start-process %~0 -verb runas
       exit
   )
   ```
   - 次の行以降に、管理者として実行したいコマンドを記述する
   - 拡張子 `.bat` で保存する
   <br>
1. 1つのバッチファイルでPowerShellを管理者として実行できるようにするとき
   - 次のように 2、1 の順に記述する
   - `@powershell -NoProfile` で始まる行において、`$_.readcount -gt 1` の `1` を `$_.readcount -gt 11` のように、その行の行番号に変更する
   - その数字より大きい行番号の行に書かれたコードが、PowerShell のコードとして実行される
   ```batch
   @echo off
   
   cd /d %~dp0
   
   whoami /priv | find "SeDebugPrivilege" > nul
   if %errorlevel% neq 0 (
       @powershell start-process %~0 -verb runas
       exit
   )

   @powershell -NoProfile -ExecutionPolicy Unrestricted "$s=[System.Management.Automation.ScriptBlock]::create((Get-Content \"%~f0\"|Where-Object{$_.readcount -gt 11}) -join \"`n\");&$s" %*&goto:eof
   ```
   - 次の行以降に、管理者として実行したい PowerShell を記述する
   - 拡張子 `.bat` で保存する
label 軽視してないですか？

# label侮ってないですか！？
labelって結構無視されがちなタグだと思うんですけど、結構大事なんですよね。

## なんで？
inputと繋がらないから！
## どうやるの！
labelのforとinputのidを一致させる
## 具体例
以下のようにチェックボックスがある時「ラベルいる」っていう文字押すとチェック入りますよね？これが理由です。アクセシビリティ大事ですよぉ

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="xbKKPPG" data-pen-title="Title" data-user="jlxgiqfo-the-scripter" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/jlxgiqfo-the-scripter/pen/xbKKPPG">
  Title</a> by 山崎惣大 (<a href="https://codepen.io/jlxgiqfo-the-scripter">@jlxgiqfo-the-scripter</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

以上！
それでは！
【イベントレポート】ファシリテーションに関するワークショップを通じて

いつも記事を読んでいただきありがとうございます！
モブエンジニア（[@mob-engineer](https://qiita.com/mob_engineer))です！

今回は私が所属しているPMOコミュニティ内で企画・運営したワークショップに関するレポート記事を投稿したいと思います。
コミュニティメンバーに加え、**ファシリテーションに関して悩みを抱えている方**にとってもお役に立てる内容となっております。

ぜひ、お気軽に読んでいただけますと幸いです。

:::note info
本ワークショップ資料はSpeaker Desk上にアップロードしております。

https://speakerdeck.com/masakiokuda/pmokomiyuniteihuasiritesiyonniguan-suruwakusiyotupu-20241119

:::

# 目次
- イベント運営のきっかけ
- イベントの様子
    - 目線合わせ（ファシリテーションを進めるためのポイント
- ワークショップ
    - **良いファシリテーション/イマイチなファシリテーション**
    - **ファシリテーションに関する悩み**
- まとめ

## イベント運営のきっかけ
今回私がイベントを開催したきっかけとして次のような動機がありました。

- PMOコミュニティ内でのアウトプット活動を実施したかった
- 前回企画したイベントを通じて、私が考えている**ファシリテーションのポイント**を共有したかった
- **コミュニティメンバー間での交流機会**を作りたかった

そのうえで、今回企画した**ファシリテーションに関するワークショップ**がぴったりだと思い、企画・運営を行ってまいりました。

## イベントの様子
今回のイベントについて、コミュニティメンバーに閉じて開催しましたが、今回4名の方に参加いただき、ファシリテーションに関するワークショップを行っていきました。

企画・運営した立場からして、本当にありがたいと思っております。

### 目線合わせ（ファシリテーションを進めるためのポイント
目線合わせのセッションでは、ファシリテーションに関するポイントについて約20分ほどお時間をもらってお話しいたしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/18774e1c-8e36-8114-84cb-e0f4c55efaca.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/3b907541-3178-5944-fa59-c06603ef905a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/12fce458-8d91-ff3a-f67c-576d19277688.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/37ea79a9-648a-23d3-6bf1-8932356147c3.png)

## ワークショップ

ワークショップでは参加者間でテーマに沿ってコミュニケーションを行いました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/6d1bbe11-5b4b-b5f6-6bc8-3132b4c045d2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/4967d6fa-3948-3882-1a3d-68219c9ba4ad.png)

### 良いファシリテーション/イマイチなファシリテーション*

参加者からのコメント
- 良いファシリテーション
    - 打合せで決めるべき事項を決めることが出来たファシリテーション
    - 資料が作り込んであって、わかりやすかったとき
    - ファシリテーターに協力したいと思った
    - メッセージ性があるかどうか
    - 相手の相手の立場に立ったセッティング
    - 準備が出来ていること
    - 目的について参加者間で決めていること
    - やるべきことと期限が決まっていること
    - 伝えたいことが図として示されていること

- いまいちなファシリテーション
    - 一人がずっと話している
    - わかりづらい資料
    - その場を進めることに注力してしまう
    - いいファシリテーションの条件がそろっていない

### ファシリテーションに関する悩み

参加者からのコメント
- 悩み
    - ファシリテーションの当たり前を周囲の人が知らない場合がある
    - ※社内であればコントール可能だが、社外だとコントロールしにくい
    - 会議途中で途中で口をはさんでしまう人がいる。代案なく、批判を行う人がいる
    - ※自分でコントールしようとするが難しい
    - 会ったことない人の意見を尊重することが難しい
    - 参加者間の認識相違、レベルが違う
- アイデア
    - ファシリテーションに関する研修（ワークショップなど）を開催する
    - 話しすぎる人がいれば別場で話すように誘導する
    - 雑談からはじめて、相手の懐に入っていく
    - 目線合わせの資料を用意しておく※上の立場の人が下の立場に合わせていく

## まとめ
私個人、ファシリテーションに関するトークセッションを開催できてよかったと考えています。
そのうえで、**今回、参加できなかった方に対してもアウトプットする場**を提供していくことが必要なのかなぁと思いました。

引き続き、コミュニティ内で役立つイベントを企画・推進していくので楽しみにしていただければと思います！！

最後まで記事を読んでいただきありがとうございました！！
本記事が、読者の方が持っている悩み解決につながっていただければ幸いです。
【Laravel】debug log をヘルパーから出力する方法


```php
info('インフォてすと');

debug('デバッグてすと');
```

```log:laravel.php
[2024-11-25 20:21:44] testing.INFO: インフォてすと 
```

何故か表示されない :thinking:



## 原因

IDE でジャンプしてみると・・・

`info()` は、ちゃんと Hepler に繋がってた
```php
# vendor/laravel/framework/src/Illuminate/Foundation/helpers.php
function info($message, $context = [])
{
    app('log')->info($message, $context);
}
```

しかし `debug()` は、Debugbar のほうに繋がってた
```php
# vendor/barryvdh/laravel-debugbar/src/helpers.php
function debug($value)
{
    $debugbar = debugbar();
    foreach (func_get_args() as $value) {
        $debugbar->addMessage($value, 'debug');
    }
}
```

## 答え

`logger()` をチェーンさせないで使えばいいらしい
これは分かんないよ～

```php
# vendor/laravel/framework/src/Illuminate/Foundation/helpers.php
function logger($message = null, array $context = [])
{
    if (is_null($message)) {
        return app('log');
    }

    return app('log')->debug($message, $context);
}
```

```php
logger('デバッグてすと');
```
BevyEngineのQueryフィルター種類まとめ(0.14)

# フィルターの種類
参考：https://docs.rs/bevy/latest/bevy/ecs/query/trait.QueryFilter.html

## コンポーネントフィルター
<dl>
    <dt>With</dt>
        <dd>Tで指定されたコンポーネントを持っているEntityのフィルター</dd>
    <dt>Without</dt>
        <dd>Withの否定版</dd>
</dl>

## 変更検出フィルター
<dl>
    <dt>Added</dt>
        <dd>追加後の最初にのみ保持されるコンポーネントのフィルタ
    一回限り初期化などに利用します</dd>
    <dt>Changed</dt>
        <dd>コマンドで発行されたエンティティの修正(エンティティの作成、エンティティコンポーネントの追加や削除など)のフィルタです</dd>
</dl>

## タプルでフィルターの指定
<dl>
    <dd><code>Query<&ComponentA, (With<ComponentB>, Without<ComponentC>)></code></dd>
    <dd>タプルを利用すると一つのQueryでフィルターを複数定義できる</dd>
</dl>

## フィルタの論理演算子
<dl>
    <dt>Or</dt>
    <dd><code>Query<&ComponentA, Or<(With<ComponentB>, Without<ComponentC>)>></code></dd>
    <dd>`Or`の中にタプルで定義すると与えられたフィルタのいずれかが適用されるかテストするフィルタになる</dd>
</dl> 

# 自作フィルター
`QueryFilter`を`#[derive()]`につかすることで新たにフィルターを自作することができる
これにより、
複数のシステム間でフィルターを再利用することができる、
フィルターを組み合わせて、より複雑なフィルターを作成することができる。
```
#[derive(QueryFilter)]
struct MyFilter<T: Component, P: Component> {
    with_a: With<ComponentA>,
    or_filter: Or<(With<ComponentC>, Added<ComponentB>)>,
    generic_tuple: (With<T>, Without<P>),
}

fn my_system(query: Query<Entity, MyFilter<ComponentD, ComponentE>>) {
    // ...
}
```
Human Interface Guidelines「privacy」のまとめ

## これは何
`Human Interface Guidelines>Foundations>Privacy`を読んだまとめメモ:memo:

https://developer.apple.com/design/human-interface-guidelines/privacy


## 書いてあったこと
### 概要
- 透明性を保つことが大事
- プライバシーに関して情報取集するときは、取り組みや収集するデータの詳細を提供する
    - App Storeの製品ページでその情報を表示できるようにするため

### ベストプラクティス
- 本当に必要なデータのみ、アクセスをリクエストする
    - アプリが明らかに必要としているもののみ
    - ユーザーからの信頼されるため
    - :memo:情報保護の責任が無駄に大きくなるためもある
    - :memo:アンケートでも質問項目は必要なものだけにするような感じ
- データの使用方法の説明をちゃんとする
    - アプリがどのように使用するか明確に説明する文章にする
    - 目的が曖昧:ng:
    - 強制的:ng:
- 常にユーザーの選択を尊重する
    - 許可なく情報を取らない
- ユーザーがアクセスを必要とするアプリの機能を実際に使用するまで、許可を要求するのを待つのが良い
    - 起動時に必要ないのに許可を要求する:ng:
- ユーザーが意図せず許可するような誘導にならないようにする
    - 「続行」などのラベルのボタンを表示させて、システムアラートを開くものであることを明確にする
- システムアラートを表示せずに画面を離れる方法を提供しない
- リクエストを許可することでインセンティブ:moneybag:を与える:ng:
- 位置情報ボタンを使って特定の機能だけで位置情報が共有できるようにすることを検討する
    - 位置情報ボタンはカスタムしてUIに合うようにする

### 許可がいるもの
- 個人情報
    - 例：位置情報、連絡先、健康（歩数とか？）、クレカ
- メール、メッセージ、カレンダーデータ、ゲーム、オーディオ、ビデオなどのプレイ情報などのユーザー生成コンテンツ
    - :memo:対応している例：「Slackから写真にアクセスしようとしています」
- Bluetooth周辺機器、ホームオートメーション機能、Wi-Fi接続、ローカルネットワークなどの保護されたリソース
- カメラやマイクなどのデバイス機能
- データを追跡するとき

### データの保護について
- 認証をパスワードのみに頼る:ng:
- 機密情報はキーチェーンに保存
- カスタム認証スキームを考案することは避ける

## まとめ
:::note info
- 無駄にユーザーの情報をとらない
- 許可なくユーザーの情報をとらない
- 本当に必要な情報を、必要なときに要求する
- データの保護は厳重にする
:::
任意の項目の値をコピーしながらレコードを新規作成するカスタムボタンの実装

色々と試行錯誤して、ひとまず期待どおりに機能するボタンが作れましたので公開します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336848/6d945927-9a2a-f716-784d-73f6dfb23f65.png)



「説明」欄に記載したとおり、ブラウザから「ページのソースを表示」して
項目のidを取得して、URLに組み込みます。

参照（主従）項目（4,5行目）と、それ以外（2,3行目）で記述方法が変わるようです。


メンテナンス性の観点から言うと、画面フローを使っての実装も選択肢に
入ってくると思いますが、ご参考までに。




参考

[既存レコードを元に必要な項目のみコピーした状態で新規作成画面を立ち上げたい](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000LG8b4SAD)

[レコードのコピー 最適化！必要な情報だけコピーしたい。](https://www.circlace.com/blog/salesforce/recordcopy_202104)

[ボタンを使ってコピー作成したいが、参照項目の設定がわかりません](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000HDDVESA5)

[カスタムボタンの例: デフォルト項目値を含むレコード作成ページ](https://help.salesforce.com/s/articleView?id=sf.links_useful_custom_buttons_create_record_dfv.htm&type=5)

[Salesforceでコピー時に初期値を埋め込む](https://qiita.com/mvvs/items/cd42b1af9dc226063e32)