OmniAICreator/Qiita-1.07M huggingface dataset:
Unity-Dependency Injectionとは

# Unity C# で解説する Dependency Injection (依存性の注入)

## 【概要】

Dependency Injection (依存性の注入)は、クラス間の結合度を低くして、テストや拡張をしやすくするための技法です。Unity の C# 開発では、小覧細なスクリプトから大規模なゲームシステムまで常に役立ちます。

---

## 【デフォルトの実装と問題点】

例: Player が GameManager に依存している情報を使いたコード

```csharp
public class Player : MonoBehaviour
{
    private GameManager gameManager;

    void Start()
    {
        gameManager = FindObjectOfType<GameManager>(); // 依存関係が固定
    }

    void Update()
    {
        gameManager.DoSomething();
    }
}
```

### 問題:

* Player は GameManager の実装に完全に依存している
* Unit Test でのモックなどの差し替えが困難
* 再利用性が低い

---

## 【Dependency Injection を使った改善例】

### 方法 1: コンストラクタ注入 (MonoBehaviour外)

```csharp
public class PlayerLogic
{
    private IGameManager gameManager;

    public PlayerLogic(IGameManager gameManager)
    {
        this.gameManager = gameManager;
    }

    public void DoSomething()
    {
        gameManager.DoSomething();
    }
}
```

### 方法 2: メソッド/プロパティ注入

```csharp
public class Player : MonoBehaviour
{
    private IGameManager gameManager;

    public void Initialize(IGameManager manager)
    {
        this.gameManager = manager;
    }

    void Update()
    {
        gameManager?.DoSomething();
    }
}
```

---

## 【Unityでの実務的なDI実装】

### GameInstallerなクラスを作成

```csharp
public class GameInstaller : MonoBehaviour
{
    [SerializeField] private Player player;
    [SerializeField] private GameManager gameManager;

    void Awake()
    {
        player.Initialize(gameManager);
    }
}
```

---

## 【ZenjectなどのDIコンテナの利用】

Zenjectを使うと、インジェクションで自動的に依存性が注入されます。

```csharp
public class Player : MonoBehaviour
{
    [Inject]
    private IGameManager gameManager;

    void Update()
    {
        gameManager.DoSomething();
    }
}

public class GameInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.Bind<IGameManager>().To<GameManager>().AsSingle();
    }
}
```

---

## 【まとめ】

| DI手段      | 特徴                          |
| --------- | --------------------------- |
| 手動DI      | Initialize()などで手動で注入。小規模向け。 |
| Zenject 等 | \[Inject]などを使い自動注入。中大規模向け。  |
| 利点        | テスト容易、拡張性高い、再利用性が高い         |

Unityでは、最初は手動でこつこつとやって、解約してきたらZenjectなどのフレームワークに移行するのが普通です。

この概念を理解することで、コードの解耐性や拡張性が大きく向上します。
GooglePlaceAPIをRailsアプリに導入して店舗一覧を作成できたので流れをまとめてみた

<h1> モチベーション </h1>
店舗一覧画面では店舗情報を取得して表示する必要がある。

情報量が多く普段よく使うGoogleではAPIが利用可能である。

GoogleAPIをアプリと紐付けて情報取得および店舗情報の一覧を作成したい。

<h1> 目次 </h1>

| ページ内リンク |
|:-------------|
| [1. GoogleAPIの取得および設定](#1-GoogleAPIの取得および設定) |
| [2. アプリ側の設定](#2-アプリ側の設定) |
| [3. 実装](#3-実装) |
| [4. 結果](#4-結果) |
| [Reference](#Reference) |
| [余談](#余談) |

# 1. GoogleAPIの取得および設定
GoogleAPI利用するにはGoogleCloudにアカウント登録、利用したいAPIの有効化、APIキーの取得と制限が必要。[1]を参考にして有効化しました。
店舗一覧とマップ機能を利用したいので、以下のAPIを有効化しました。
Places API (詳細は[2]参照)
Maps JavaScript API

# 2. アプリ側の設定
アプリ側の設定も必要です。[3]ではAPIキーの設定を.envファイルへ書き込み、envファイルをgitに上げないようにするまでの内容が書かれています。[4]では各ファイルの役割や利用例などが書かれています。

PlacesAPIのリクエスト・レスポンスについては[5]参照。

# 3. 実装の流れ
実装内容は書いて良いかわからなかったのでとりあえず載せずに流れだけ載せます。

## 3-1. 必要なGemインストール
Gemfileに"httparty"と"dotenv-rails"を記述
ターミナルでbundle install

## 3-2. APIキーを.envへ記述
googleAPIのキーを記述。
.gitignoreに.envが未記載の場合、記述して漏洩防止。

## 3-3. サービスクラス作成
servicesフォルダ作成してサービスクラス用ファイル作成。
作成したrbファイルには以下を記述。
- initializaメソッドでAPIキー取得
- 検索メソッドを作成。引数としてlocation, 検索半径を設定。以下を実行する。
-- 検索ワードなどの任意引数を設定。
-- HTTPartyのgetメソッド実行。

## 3-4. コントローラ作成および呼び出し
indexメソッド(アクション)として以下を記述。
検索場所設定(デフォルト場所も設定)、上記サービスクラスのインスタンス生成、処理実行。
処理成功した場合、実行結果を変数へ格納。
上記以外の場合、空文字を変数へ格納。取得失敗したことをflashで表示。

## 3-5. ビューの作成
コントローラで取得した情報分だけeach文でループ。
表示したい内容を変数から出力。

## 3-6. ルーティングの設定
config/routes.rbに「getメソッドで【コントローラ名】が呼ばれた時、【コントローラ名】のindexアクションを実行する」ができるように記述。

すると一覧が表示されました！！！！！初めて動いたのでめっっっっっっちゃ感動しました！！！！！

# 4. 結果
参考資料とChatGPTのおかげで初めて画面を作成して動かすことができました！この感動を共有できる人がいないのが寂しいですが、おそらく忘れないでしょう。
詰まったところとしては、メソッド名の頭文字が大文字にしていてAPIが取得できなかったことです。ちゃんとメソッド名の頭文字は小文字でないといけないみたいです。

ここまで読んでくださりありがとうございました！


# Reference
[1]yo4shi80, Google Places API (New) を使った店舗情報と口コミデータの取得方法, (2024), https://note.com/yo4shi80/n/n37b720b6d95c
[2]@jinta_02(jinta), Google Places APIを使用して情報を取得（Rails）, (2025), https://qiita.com/jinta_02/items/d7c62be909ac4edca5d2
[3]Miyachi Labo, 【Rails】Googleマップに掲載されている店舗情報をAPIで自由に取得する,(2021), https://labo.kon-ruri.co.jp/rails-google-places-api/#index_id0
[4]@fumiya1800(f n), Rails 環境変数の設定方法（dotenv-rails）, (2023), https://qiita.com/fumiya1800/items/6795e5e1046ec6f60aed
[5]@yoshii0110(Yoshitaka KOITABASHI), Google mapのPlaces APIで指定したエリア内にある特定の場所を調べてみよう！, (2021), https://qiita.com/yoshii0110/items/7938085151f569427af6

# 余談
初めて目次と見出しとのページリンクを作成しました。
リンク作成にはいくつかの条件があり、以下の資料が参考になりました。
hタグをつけるとリンクできないことを知らず詰まりました。
@shizen-shin, 【実例解説】Qiitaでページ内リンクを使う方法（マークダウンによるアンカーリンクの書き方）, https://qiita.com/shizen-shin/items/a65f1e2b6a3c3a4a28e1
N-Prolog のモダン化

# 時代に追いつく
N-Prologは1980年代のRUN/PROLOGのコードがそのまま動くことを目標につくりました。当時のPrologコードを楽しむ程度のつもりだったのです。しかし、欲がでてきました。RUN/PROLOG互換は堅持しつつもモダンな機能をかなり追加しましたのでご紹介します。

# CLPFD
1980年代にはなかったものでその後に発達したものとして制約論理プログラミングがあります。このうち整数の範囲で動作するCLPFD機能を追加しました。下記はCLPFDで記述した9queensです。

```prolog
nqueens(Queens) :-
    length(Queens, 9),       
    Queens ins 1..9,         
    all_different(Queens),   
    safe(Queens),         
    label(Queens).
    
safe([]).
safe([Q|Rest]) :-
    safe(Rest),
    no_attack(Q, Rest, 1).
    
no_attack(_, [], _).
no_attack(Q, [Q2|Rest], Dist) :-
    Q #\= Q2 + Dist,  
    Q #\= Q2 - Dist,
    Dist1 #= Dist + 1,
    no_attack(Q, Rest, Dist1).

```

素朴なアルゴリズムでありSWI-Prologのような最新のアルゴリズムは採用していません。それでもPrologインタプリタで実行した程度の速度は出せるようにまでなりました。

![bandicam 2025-05-10 16-53-04-907.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/02497561-cfe2-4fee-ac41-220e0819bb72.jpeg)


# TCLTKライブラリ
GUIを使えればゲームを作るなど応用範囲が広がるだろうと考えてTCLTKライブラリを追加しました。N-PrologのC言語埋め込み機能を活用しています。下記はこれを利用したシェルピンスキー図形です。

![bandicam 2025-05-10 16-56-15-014.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/998d94df-a9d6-4351-afbc-91991f1b7a72.jpeg)

# OpenGL
あわせてOpenGLライブラリも追加しました。

![bandicam 2025-05-10 16-57-48-979.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/c88be318-089a-4974-b3c8-e9b62eb6035f.jpeg)


# HTTPS
ChatGPTとAPIを介して通信するにはHTTPSも必要ということでしたのでcurlを利用してHTTPSライブラリを作りました。

```prolog
% curl test
:- use_module(json).

foo(T) :- 
    create_client_curl(C, "https://httpbin.org/post"),
    set_curl_option(C, method(post)),
    send_curl(C, "hello=world"),
    recv_curl(C, R),
    string_term(R,J),
    term_json(T,J),
    write(R),nl,
    close_curl(C).


```

# JSONライブラリ
ChatGPTとやりとりするにはデータとしてJSONを使うということがわかりましたのでPrologのパーサを流用して即席にJSONライブラリを作りました。下記ｈHTTPSでやりとりしたデータであるJSONをProlog述語に変換している例です。

```prolog
N-Prolog Ver 4.08
?- [-'./tests/curl.pl'].
yes
?- foo(X).
{
 "args": {}, 
 "data": "", 
 "files": {}, 
 "form": {
 "hello": "world"
 }, 
 "headers": {
 "Accept": "*/*", 
 "Content-Length": "11", 
 "Content-Type": "application/x-www-form-urlencoded", 
 "Host": "httpbin.org", 
 "X-Amzn-Trace-Id": "Root=1–680dcaa7–6a263f1233844c2c69d17b9f"
 }, 
 "json": null, 
 "origin": "XXX.XXX.XXX.XXX", 
 "url": "https://httpbin.org/post"
}
X = [args='{}',data="",files='{}',form=hello=world,headers=
['Accept'='*/*','Content-Length'='11',
'Content-Type'='application/x-www-form-urlencoded',
'Host'='httpbin.org',=,
'X-Amzn-Trace-Id','Root=1–680dcaa7–6a263f1233844c2c69d17b9f'],
json=null,origin='xxx.xxx.xxx.xxx',=,url,'https://httpbin.org/post'] .
yes
?-

```

# テンソルフローとの接続
ニューロシンボリックに興味があった私はN-Prologとテンソルフローとの接続を試みました。Pythonを介して接続するのが楽なのでPythonとプロセス間通信をするライブラリを作りました。下記はテンソルフローと通信をしている様子です。

![bandicam 2025-05-10 17-05-39-222.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33927/046b14e1-eb22-470a-bc95-b238a10081e8.jpeg)


# 知的な遊び道具
Prologは私にとって知的な遊び道具です。これだけ機能拡張すれば遊ぶには困らないかなと思っています。いずれの機能もまだまだ開発途上です。使いつつ改良を予定しております。よかったら遊んでみてください。N-Prologはオープンソースです。下記にて公開しています。

https://github.com/sasagawa888/nprolog
関係代数からリレーショナル・データベースの特性を理解する

## はじめに
データベースと聞くと、MySQLがぱっと思い浮かぶという感じだった。
でも、バックエンド開発に関して学んでいくと、ストレージという言葉やキャッシュ、リレーショナルデータベース、NoSQLなど、データに関する様々な言葉が出てくる。
そこで、Recursionのデータベース講座を参考にし、データの種類、データの表現方法、データベースの種類などを体系的に整理しておくことにした。
最終的には、リレーショナル・データベースの特性を関係代数から理解できるようになった。

---

## データの保存先の種類

データの保存には主に以下の3つがある。

* メモリ
* ストレージ
* データベース

### メモリ

* 高速だが揮発性があり、一時的な保存に向いている

### ストレージ

* 永続的な保存が可能で大容量に向く
* 画像やCSS、動画などの静的ファイルを保存する

### データベース

* 永続的に保存できるだけでなく、
* 検索や更新、関連データの操作など複雑な処理ができる

---

## データの表現方法（データモデル）の種類

データには、表現方法として以下の4つのモデルがある。

1. 関係モデル
2. 実体関連モデル
3. 半構造化モデル
4. オブジェクトモデル

### 関係モデル

* 表（テーブル）形式のデータ構造
* スキーマ（型や構造）が固定
* SQLで操作する

### 実体関連モデル

* 現実世界の「人」「商品」などをエンティティとして図で表現
* データベース設計時に使われる

### 半構造化モデル

* JSONやXMLのような柔軟な構造
* スキーマが不要
* MongoDBなどのNoSQLで使われる

### オブジェクトモデル

* プログラム上のクラスのような構造でデータを表現
* ORM（Object Relational Mapping）によってRDBと連携する

---

## データモデルとデータベースの関係

* 関係モデルや半構造化モデルは、実際にデータを保存するデータベースとして使える
* 一方、実体関連モデルやオブジェクトモデルは、保存ではなく設計や操作のための考え方

---

## NoSQLとは？

* リレーショナル（関係）モデル以外を採用したデータベースの総称
* 代表例：MongoDB、Redis、Firebase など
* 柔軟な構造とスケーラビリティが特徴

---

## データベースの本質的な理解

今日一番の気付きが以下。

「今日の学びを紙に書いて、夜に見返す。これはデータベースでは？」

つまり、

* データベースとは、「データを保存し、あとで取り出せるように整理された仕組み」である
* 保存手段だけでなく、管理の仕組みを含んでいる

---

## リレーショナルデータベースの理論背景

* リレーショナルデータベースは「関係代数」という数学理論に基づいて作られている

### 関係代数の3つの特徴

1. 集合的（重複がない、順序がない）
2. 関数的（同じ入力には必ず同じ出力）
3. 合成可能（操作をいくつでも組み合わせられる）

この3つを理解すると、SQLの特徴や使い方の意味が腑に落ちるようになる。

---

## SQLと関係代数のつながり

* SQLは関係代数の操作を人間にわかりやすく命令文にしたもの

### 例：

* `SELECT name FROM users WHERE age > 20;`
  → `π_name(σ_age>20(users))`

### 集合的

* `SELECT`結果の行の順序は保証されない → `ORDER BY`が必要
* 重複は許される → `DISTINCT`で除去できる

### 関数的

* 同じクエリを同じテーブルに投げれば、毎回同じ結果が得られる

### 合成可能

* クエリをネストして複雑に合成できる → サブクエリ

---

## 最後に

SQLの背後にある関係代数の特徴（集合性・関数性・合成可能性）を理解すると、

* なぜ順序が保証されないのか
* なぜ `DISTINCT` があるのか
* なぜクエリを重ねられるのか
  など、SQLの設計本質が見えてきた。

調べれば調べるほど、「データ」に興味関心が出てきた。
【AWS】NATゲートウェイ・NATインスタンスの違い


NATゲートウェイとNATインスタンスは、AWSでプライベートサブネットからインターネットへアクセスするための2つの異なる方法である。両者は目的が同じであるが、管理方法やパフォーマンス、コストなどにおいて違いがある。

## 特徴の比較

| 特徴                    | **NATゲートウェイ**                                    | **NATインスタンス**                                   |
|-------------------------|-------------------------------------------------------|-----------------------------------------------------|
| **マネージメント**       | 完全にマネージド（AWSが自動的に管理）                   | ユーザーが手動で設定および管理                       |
| **スケーラビリティ**     | 自動スケーリング機能あり、需要に応じて拡張               | スケーラビリティは手動で調整する必要がある             |
| **可用性**               | 高可用性（AZごとに冗長構成される）                      | 自分でHA構成を設定する必要がある                      |
| **パフォーマンス**       | 高性能（AWSが提供するインフラに基づいて最適化されている）   | パフォーマンスはインスタンスタイプに依存               |
| **料金**                 | データ転送および時間単位で課金される（使用量に応じた従量課金） | インスタンスタイプによる課金、データ転送も発生       |
| **サポートされる帯域幅** | 高帯域幅（最大45Gbps）                                  | 帯域幅はインスタンスタイプに依存、通常は低帯域幅       |
| **設定の容易さ**         | 非常に簡単、数分でセットアップ可能                      | 手動でのインスタンスセットアップが必要                |
| **セキュリティ**         | デフォルトでセキュリティが強化されており、管理不要       | セキュリティ設定（セキュリティグループ、ネットワークACL）を手動で行う必要がある |
| **適用ケース**           | スケールが必要で、シンプルに運用したい場合に最適         | コスト重視、または高度なカスタマイズが必要な場合      |

## 1. **NATゲートウェイ**

### 特徴
- **完全にマネージド**: AWSがバックエンドで自動的に管理・スケーリングを行うため、ユーザーは基本的にインスタンスの設定に関する管理を意識することなく利用できる。
- **高可用性**: 各アベイラビリティゾーン（AZ）に対して冗長化されているため、可用性が高く、通常は特別な設定なく利用できる。
- **高性能**: AWSインフラに最適化されており、大規模なトラフィックにも耐えることができる。
- **管理が簡単**: 設定は非常に簡単で、数分で使用を開始できる。ユーザーはセキュリティやスケーラビリティに関する懸念が少なくて済む。

### 使用場面
- 高トラフィックの処理が必要な場合や、可用性・スケーラビリティを重視する場合に最適である。

## 2. **NATインスタンス**

### 特徴
- **ユーザー管理**: EC2インスタンスとして自分で管理・設定が必要で、OSやパッチ、セキュリティ設定を含めたすべての管理を行う。
- **スケーラビリティ**: ユーザー自身でスケーリングや負荷分散の設定を行う必要がある。必要に応じてインスタンスサイズを変更することができるが、自動でスケールすることはない。
- **コスト管理**: NATゲートウェイよりもコストを抑えることができる場合がある。特に、トラフィックが少ない場合や小規模なシステムではコストパフォーマンスが良いことがある。
- **柔軟性**: セキュリティグループやカスタマイズが可能で、特定のニーズに合わせて設定できる。例: ログの収集や特定のセキュリティ設定。

### 使用場面
- コストを最優先したい場合や、NATインスタンスに対するカスタマイズが必要な場合、または低トラフィックの環境で使用することが適している。

## 3. **どちらを選ぶべきか？**

- **NATゲートウェイ**は、**スケーラビリティ、可用性、簡単な管理**を求める場合に適している。特にトラフィックが多いシステムや、高可用性を求めるシステムではNATゲートウェイの方が圧倒的に便利で安定している。
  
- **NATインスタンス**は、**コストを抑えつつ、自分でカスタマイズが必要な場合**や、比較的低トラフィックなシステムで利用することが適している。

## まとめ

- **NATゲートウェイ**は、管理が簡単で高可用性とスケーラビリティに優れたサービスで、AWSが提供するマネージド型のソリューションである。
- **NATインスタンス**は、ユーザー管理が必要でカスタマイズ性が高いが、トラフィック量が少ない環境やコスト重視の場合に適している。
React起動時の「ERR_OSSL_EVP_UNSUPPORTED」エラーの解決法

React プロジェクトを Node.js v18 環境で立ち上げようとしたとき、以下のようなエラーが発生することがあります。

```
Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:69:19)
    ...
code: 'ERR_OSSL_EVP_UNSUPPORTED'
```
これは Webpack などのビルドツールが OpenSSL 3 に対応していないことが原因で、Node.js v17以降でよく見られる問題です。本記事ではその解決策を紹介します。
### 💡 原因
Node.js v17 以降、OpenSSL 3 が標準で使用されるようになりました。
一部のパッケージ（特に webpack@4 などの古いバージョン）は OpenSSL 3 に対応しておらず、ハッシュ生成などの処理が失敗します。

## ✅ 解決方法
### 方法1：環境変数 NODE_OPTIONS を使って起動（簡易）

Mac や Linux の場合：
```bash
NODE_OPTIONS=--openssl-legacy-provider npm start
```

Windows の場合（PowerShell）：
```powershell
$env:NODE_OPTIONS="--openssl-legacy-provider"
npm start
```
Windows の場合（cmd）：
```cmd
set NODE_OPTIONS=--openssl-legacy-provider
npm start
```

### 方法2：package.json のスクリプトに組み込む（恒久対応）
```json
"scripts": {
  "start": "NODE_OPTIONS=--openssl-legacy-provider react-scripts start",
  "build": "NODE_OPTIONS=--openssl-legacy-provider react-scripts build"
}
```
Windows 環境では cross-env を使うのがおすすめ
```bash
npm install --save-dev cross-env
```
```json
"scripts": {
  "start": "cross-env NODE_OPTIONS=--openssl-legacy-provider react-scripts start"
}
```

### 方法3：Node.js のバージョンを下げる（根本的）
OpenSSL 3 による問題を完全に避けたい場合は、Node.js v16 など LTS 安定版を使用するのも手です。

nvm を使ってバージョンを変更
```bash
nvm install 16
nvm use 16
```

### 📝 まとめ
| 対応方法               | 手軽さ | 推奨度 |
| ------------------ | --- | --- |
| 環境変数を一時的に設定        | ◎   | ◯   |
| `package.json` に設定 | ◯   | ◎   |
| Node.js のバージョンを変更  | △   | ◯   |

Node.js のバージョンアップにより思わぬところでエラーが出ることもありますが、今回のように環境変数で対処できるケースも多いです。
同じエラーで困っている方の助けになれば幸いです！
【備忘録】Linuxコマンドの復習～catコマンド～

# はじめに
自分が忘れてしまいがちなLinuxコマンドの復習です。
今回はcatコマンドについて整理します。

# catコマンド
### 1. ファイルの中身を確認する
```bash
➜  ~ cat test1.txt
test1の中身です
➜  ~ cat test2.txt
test2の中身です                                                                             
```

### 2. 複数のファイルを連結して表示する
```bash
➜  ~ cat test1.txt test2.txt
test1の中身です
test2の中身です
```

### 3. 新しいファイルに内容を書き出す
```bash
➜  ~ cat test1.txt > test3.txt
➜  ~ cat test3.txt
test1の中身です
```

### 4. ファイルAの内容をファイルBに追記する
```bash
➜  ~ cat test1.txt >> test2.txt
➜  ~ cat test2.txt
test2の中身です
test1の中身です
```

### 5. ターミナル上で手入力して保存する
```bash
➜  ~ cat >> test1.txt  # > の場合は上書きされる
追記しました    # ctrl + D で保存・終了する
➜  ~ cat test1.txt
test1の中身です
追記しました 
```

# echoコマンドとの違い
前回復習したechoコマンドと似たような機能がありますが、明確な違いとしては、
・echoは文字列をターミナルやファイルに出力する
・catはファイルの中身をターミナルやファイル内に出力する
というように、標準出力自体は同じですが、出力元が異なります。ただ、catは確認する用途のほうが向いている気がします。

# catコマンドの使いどころ
特にデプロイ時、.envファイルなど、ちょっとしたファイルの中身を確認したいときに有用だと理解しました。手軽に表示できますからね。そしてそこにちょっと書き込みたいときはecho。
行数の多いファイルの全体を見たい、または編集したいといった場合にはcatコマンドでは厳しい部分があるので、vimの出番、ということだと思います。

# catコマンドの応用
ファイルの内容をささっと確認したい場合の応用技を整理しておきたいと思います。

### 1. head, tailと組み合わせる
```bash
➜  ~ cat test4.txt | head -n 3  # ファイルの最初の三行目を確認する
1行目：ああ
2行目：いい
3行目：うう
```
```bash
➜  ~ cat test4.txt | tail -n 3  # 最後の3行を確認する
8行目：くく
9行目：けけ
10行目：ここ
```

### 2. grepと組み合わせる
```bash
➜  ~ cat test4.txt | grep "お"  # 「お」が含まれる行だけ表示する
5行目：おお
```
※`grep "お" test4.txt`でも同様の結果になる様ですが、まずはパイプの使い方に慣れる事を優先。

```bash
➜  ~ cat test4.txt | grep -v "^5行目"  # 5行目という文字から始まる行を除外して表示する
1行目：ああ
2行目：いい
3行目：うう
4行目：ええ
6行目：かか
7行目：きき
8行目：くく
9行目：けけ
10行目：ここ
```

# おわりに
catは手軽にファイルの中身を確認したい時に有用で、パイプとの組み合わせに慣れるとより便利に使いこなせると理解しました。まだまだ奥が深いコマンドですが、まずはhead,tail,grepとの併用に慣れていきたいと思います。
MicroPython x Web Serial APIで構築する、Raspberry Pi Pico Wのエンドユーザー向けWiFi初期設定(1)

まずは GitHub 公開リポジトリの URL を貼っておきます。  
すぐに動くものを見たい方はこちらをご確認ください。  
[GitHubリポジトリ](https://github.com/DBA-Z21A/raspico_wifi_set_repl)  
※サンプルコードも同梱されていますので、実行時はご注意ください。

---

## 開発動機

[前回](https://qiita.com/asd_m/items/7ecf9ba27909e7bfa844)も述べたとおり、Raspberry Pi Pico W をはじめとする無線LAN機能搭載の IoT 機器では、**エンドユーザーが自身の WiFi 接続情報を機器に設定する必要がある**という課題があります。

近年では WPS のような規格も存在しますが、Raspberry Pi Pico W のようなリソースの限られたデバイスでは実装が困難です。

現実的な解決策として、以下のような手法があり、Qiitaでも多くの記事が公開されています。

1. 初回起動時に Pico W をアクセスポイントとして動作させ、HTMLフォームを通じて接続情報を入力させる  
　→ [その１](https://qiita.com/h0uk1st4r/items/e4428902e95ac9581e4a)、[その２](https://qiita.com/jksoft/items/436d27ae270521de3055)

2. [Bluetooth 経由で接続情報を書き込む](https://qiita.com/0yama/items/7105725013456d0ff782)

3. [Raspberry Pi Pico W を USB ストレージとして認識させ、情報を書き込む](https://qiita.com/0yama/items/df1f1b38a250f2b94760)

これらは有効な手法ですが、それぞれに以下のような課題があります。

* 手法1には「設定中に外部との通信ができない」という制限がある  
* 手法2・3では、利用者にもある程度の IT スキルが求められる

「Raspberry Pi Pico W（を組み込んだIoT機器）を実用的に使うには、これらの課題を解決する必要がある」と考えていたところ、次の情報を目にしました。

> Raspberry Pi Pico の MicroPython 開発環境で利用する REPL（Read-Eval-Print Loop）は、単なるシリアル通信である

この情報をきっかけに、

**「Web Serial API を使えば、ブラウザと USB ケーブルだけで、外部通信を維持したまま、安全に設定ファイルの書き換えができるのでは？」**

というアイデアが浮かび、今回のツールキット（と呼ぶのは少し大げさですが）を作成しました。

---

## 従来手法に対する利点

今回のアプローチが、既存の手法と比較して優れていると考える点は以下のとおりです。

* **USB接続とブラウザだけで設定可能**  
　→ 利用者に専門知識は不要。「機器とPCをUSBで接続し、指定されたURLを開く」と伝えるだけで完了。

* **即時に接続確認が可能**  
　→ 設定直後にネットワーク接続の成否を確認できます。

* **汎用的な設定内容の受け渡しが可能**  
　→ WiFi情報に限らず、クラウド接続用のトークンなどの認証情報も同時に保存できます。

* **情報の安全な保存**  
　→ 接続情報は暗号化して保存。.mpy化や暗号処理の工夫により、盗難・解析リスクを大きく軽減できます。

これらの利点により、「Raspberry Pi Pico W + MicroPython」を活用した IoT 機器の**実用的かつ安全な運用**が現実のものになったと考えています。

---

## 使用技術

このツールキットでは、以下の技術を使用しています。

* MicroPython REPL（Raspberry Pi Pico W 側）
* Web Serial API（ブラウザ → Pico W 通信）
* Bootstrap 5（UI の整形）
* Vue.js（CDN版、クライアント側の状態管理・再利用）

なお、Vue.js に関しては補足があります。

近年の Vue 解説では .vue ファイルを用いた SFC（Single File Component）形式が主流ですが、本プロジェクトでは**CDN版 Vue.js をクライアントサイドのみに限定して使用**しています。

SSR（サーバーサイドレンダリング）との併用や、既存Webアプリへの部分的な導入など、**再利用性や柔軟性を重視した Vue の使い方**として、同じ考えを持つ方の参考になれば幸いです。

---

## 次回の予定

次回は、GitHub に公開しているソースコードをベースに、Web Serial API の基本的な使い方や動作原理について解説する予定です。

どうぞよろしくお願いします。
学校のパソコンでマイクラを無料でプレイする方法【Education Edition】

# 学校のパソコンでMinecraftを無料でプレイする方法【Education Edition】

## はじめに

この記事では、**学校のパソコンでMinecraft: Education Editionを無料で使う方法**を紹介します。  
Microsoftの教育用ライセンスが付与されたアカウント（例：学校のメールアドレス）を使えば、無料でプレイできます。

> ⚠ 注意：この方法は**教育機関に提供されているMicrosoftアカウント**を持っている人向けです。一般の個人アカウントでは使えないのでご注意ください。

## 手順

### 1. コマンドプロンプトを開く


まず、パソコンの検索バーで「`cmd`」と入力し、**コマンドプロンプト**を開きます。
![スクリーンショット 2025-05-10 160414.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873238/27a952f0-b0a0-45d4-b4c7-58b03285968e.png)


### 2. wingetコマンドでMinecraftをインストール

以下のコマンドをそのままコピー＆ペーストして実行します：
```bash
winget install 9NBLGGH4R2R6
```
これは、Microsoft Storeに登録されている「Minecraft: Education Edition」をwinget経由でインストールするコマンドです。

![スクリーンショット 2025-05-10 160026.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873238/56860ab7-ff65-4d43-bd89-e3bb24da0d0b.png)

次のような確認画面が出たら、y を入力してEnterキーを押してください。![スクリーンショット 2025-05-10 155551.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873238/e4e5ff82-c29c-4e26-a568-e83c429df1e0.png)
　　　　　　　　　　　　　　　　　　　⇩
![スクリーンショット 2025-05-10 160205.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873238/b5c81bd6-758d-4f44-8152-eb0e44db7e69.png)


### 3. 学校のアカウントでログイン

インストールが完了したら、Minecraftを起動し、**学校の自分のMicrosoftアカウント**でログインします。
![スクリーンショット 2025-05-10 160620.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873238/13be95fd-dc04-4698-b760-a0c1bc32961a.png)
ログインできれば、すぐにプレイ可能です！


## おわりに

Minecraft: Education Editionは、プログラミングやグループ活動にも活用できる便利なツールです。  
授業だけでなく、放課後に楽しみながら学ぶのにもおすすめです。

ぜひ、試してみてください！
M2チップ搭載MacでDockerが動かない時の解決法



# 
新しいMac（M2チップ搭載）でDockerの中のConda環境を動かそうとしたらCPUの違いでDockerコンテナを起動することができませんでした。
今回はその時の対処法についてまとめておきます。

---

## 起きた問題と原因をやさしく解説

### どんなエラーが出たのか？

こんなエラーに出会いました。

```
bash: /opt/conda/bin/python: cannot execute binary file
ERROR conda.cli.main_run:execute(125): `conda run /bin/bash -il python` failed.
```

「Pythonが実行できないよ！」という意味のエラーです。

### なぜこのエラーが起きるの？

この問題の理由は、新しいMac（M1やM2など）に搭載されている**Apple Silicon**というCPUにあります。
私のCPUは「ARM64」という種類ですが、
多くのDockerのイメージは別の種類のCPU（「x86\_64」）向けに作られていることが多いです。
そのためプログラムの種類が合わずに、エラーが起きてしまうのです。

つまり、この問題の原因は以下の3つにまとめられます。

* **CPU（アーキテクチャ）の違い**
* **Condaの実行方法の問題**
* **Dockerfileで動作するCPUを指定していなかったこと**

---

## 解決法

では、どうすればいいのかを順に説明します。

### ① Dockerfileに「ARM64向け」と明記する

まず、Dockerfileを以下のように作り直しましょう。

```dockerfile
# ARM64に対応したMinicondaを使うことを指定
FROM --platform=linux/arm64 continuumio/miniconda3:latest

# 作業用フォルダを指定
WORKDIR /app

# conda環境ファイルをコピーして環境を作る
COPY 1_environment/conda.yml ./conda.yml
RUN conda env create -f conda.yml && \
    conda clean -afy

# Conda環境をデフォルトで有効にする
ENV PATH /opt/conda/envs/aml-env/bin:$PATH

# プロジェクトファイルをDocker内にコピー
COPY . /app

# Conda環境を確実にアクティベートするためのスクリプトを用意
RUN echo '#!/bin/bash\n\
source /opt/conda/etc/profile.d/conda.sh\n\
conda activate aml-env\n\
exec "$@"' > /entrypoint.sh && \
    chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]
CMD ["python"]
```

---

### ② Conda環境をちゃんと有効化する工夫

先ほどのDockerfile内で作ったスクリプト（`entrypoint.sh`）がポイントです。このスクリプトはDockerコンテナを実行するたびにConda環境を正しく使えるようにします。

---

### ③ Dockerをビルドする時にアーキテクチャを指定する

Dockerをビルドするときに「これはARM64向けですよ！」ということを教えてあげる必要があります。

```bash
# ARM64向けにイメージをビルド
docker build -f 1_environment/Dockerfile --platform linux/arm64 -t aml-env:latest .

# 作ったDockerを実行
docker run -it --rm aml-env:latest
```

これで正しく動くようになります！

---

## なぜCPUの種類が問題になるのか（おまけ解説）

CPUには色々な種類があります。

* **x86\_64（IntelやAMDのCPU）**

  * 以前のMacや多くのWindowsパソコンで使われているCPUの種類です。

* **ARM64（AppleのM1やM2など）**

  * 最新のMacやスマートフォン、タブレットなどでよく使われています。

これらは基本的に別の言語（命令セット）を話しているようなもので、
違う種類のCPU向けに作られたプログラムは互換性がありません。
そのため、Dockerを使う場合はCPUに合わせて「どのCPUで動くか」をはっきり指定する必要があります。

---
webp画像をGdiplus::Bitmapに変換する方法

# ライブラリ導入
webpライブラリは vcpkgで持ってくると楽でした

````json:vcpkg.json
{
    "dependencies": [
        "libwebp"
    ]
}
````

# ソースコード

````C++
#include <fstream>
#include <string>
#include <memory>
#include <GdiPlus.h>
#include <webp/decode.h>

std::string	LoadFile(const std::wstring& filePath)
{
    std::ifstream fs(filePath, std::ios::in | std::ios::binary);
    if (!fs)
        return "";

    fs.seekg(0, std::ios::end);
    std::string buff;
    auto fileSize = fs.tellg();
    buff.resize(fileSize);
    fs.seekg(std::ios::beg);
    fs.clear();
    fs.read(const_cast<char*>(buff.data()), fileSize);
    return buff;
}

std::unique_ptr<Gdiplus::Image> CreateGdiplusImage(const std::wstring& imagePath)
{
    try {
        std::string imageData = LoadFile(imagePath);
        if (imageData.size() == 0) {
            throw std::runtime_error("LoadFile failed");
        }

        // A) Init a configuration object
        WebPDecoderConfig config = {};
        if (!WebPInitDecoderConfig(&config)) {
            throw std::runtime_error("WebPInitDecoderConfig failed");
        }

        // B) optional: retrieve the bitstream's features.
        if (WebPGetFeatures(reinterpret_cast<const uint8_t*>(imageData.c_str()), imageData.size(), &config.input) != VP8_STATUS_OK) {
            throw std::runtime_error("WebPGetFeatures failed");
        }

        auto bitmap = std::make_unique<Gdiplus::Bitmap>(config.input.width, config.input.height, PixelFormat32bppARGB);
        Gdiplus::Rect	rc(0, 0, config.input.width, config.input.height);
        Gdiplus::BitmapData	bmpData = {};
        bitmap->LockBits(&rc, Gdiplus::ImageLockModeWrite, PixelFormat32bppARGB, &bmpData);

        // C) Adjust 'config', if needed
        config.output.colorspace = MODE_BGRA;
        config.output.is_external_memory = true;
        config.output.u.RGBA.rgba = static_cast<uint8_t*>(bmpData.Scan0);
        config.output.u.RGBA.stride = bmpData.Stride;
        config.output.u.RGBA.size = static_cast<size_t>(bmpData.Stride * bmpData.Height);
        // etc.

        // Note that you can also make config.output point to an externally
        // supplied memory buffer, provided it's big enough to store the decoded
        // picture. Otherwise, config.output will just be used to allocate memory
        // and store the decoded picture.

        // D) Decode!
        if (WebPDecode(reinterpret_cast<const uint8_t*>(imageData.c_str()), imageData.size(), &config) != VP8_STATUS_OK) {
            bitmap->UnlockBits(&bmpData);
            throw std::runtime_error("WebPDecode failed");
        }
        bitmap->UnlockBits(&bmpData);
        // E) Decoded image is now in config.output (and config.output.u.RGBA)

        // 完成！
        bitmap;

        std::unique_ptr<Gdiplus::Image> bmpRaw = std::move(bitmap);
        return bmpRaw;
    }
    catch (std::exception& e) {
        // error処理  
        return nullptr;
    }
}
````

bitmap->LockBits で内部メモリのアドレスを貰って、WebPDecodeで書き込むだけの簡単な作業です

webp動画は変換できません

````C++
config.output.colorspace = MODE_BGRA;
````

colorspace に MODE_BGRA を指定しないと色がおかしくなります
【振り返り】2025/05/07 〜 2025/05/09

## ご挨拶
こんにちは。
@HayatoHanaoka です。
GW休暇明けで気が抜けがちな1週間でしたが、振り返りを行っていこうと思います。

今週は3日しか稼働がなかったため、先週と全く違う方向のアクション出すのはやめておこうと思っています。
代わりに、先週出したアクションを振り返り、より良く実践するにはどうしたら良いのかを考えていきます。

## 今週の行動
### 先週出したアクション
:::note info
よりシンプルで良い設計や実装が何かを考えるきっかけを失わないために、
ペアチェンジの際に引き継いだ内容の背景や経緯について質問をする。
:::
#### 実践できた
- ほぼ実装が終わっているストーリーにペアチェンジで入った際に、どのような実装になっているのか質問して、キャッチアップできた
- ドメインについてのモヤモヤを相手から聞き、それについて自身なりの答えを示して採用された
    - 詳細な内容としてはドメイン名をどうするか程度のものだったが、設計について考えるきっかけになっただけでもプラスである
#### 実践できなかった
- 相手が詳細まで説明してくれるタイプだと、質問をしないまま納得してしまうので、質問ができなかった
#### なぜ実践できなかったのか
- どのような設計がベストなのか思いつくだけの知見がないため、質問が浮かばない
    - 本を読む・人に聞く等をして、インプットを行う
    - 思いつきレベルでも共有して、フィードバックをもらう
- 我々で開発したモノの横展開が多かったため、考え直すような事柄が少なかった
    - 横展開であっても、考えるべきことはあったはず
        - 開発しづらさを感じる部分はないか？
        - テストが書きづらい部分はないか？
        - SOLID原則を守っているか？
        - 1つのusecaseが肥大していないか？肥大化しているなら、どこで分けるべきか？ etc...

## アクション
引き続き、以下を行います。

:::note info
よりシンプルで良い設計や実装が何かを考えるきっかけを失わないために、
ペアチェンジの際に引き継いだ内容の背景や経緯について質問をする。
:::
追加で、以下のことに対して考え、自分なりに質問を1つは出すことを行おうと思います。
```
開発しづらさを感じる部分はないか？
テストが書きづらい部分はないか？
SOLID原則を守っているか？
1つのusecaseが肥大していないか？肥大化しているなら、どこで分けるべきか？ etc...
```
何度も繰り返しSafariからオンラインカジノの通知が表示された問題とその解決方法

# 問題のきっかけ
• サイト訪問後に不審な通知が表示されつづけるようになる:
Mac（macOS 15.3.1）でSafariを使って海外サイト◯◯◯◯.netを訪問しフリーソフトと誤ってダウンロードボタンクリックしてしまいました。途中で有料ソフトと気づいてそのアプリ自体はインストールしなかったのですが、その後、何度もsafariからオンラインカジノ関連の通知がされるようになりました。
※◯◯◯◯.netは、便宜上使用された仮のURLです。

# 初期の対応
safariからの通知が表示されるたびに、最初は問題の原因がわかりませんでした。その後、システム環境設定>通知に進み、通知設定を確認したところ、◯◯◯◯.netという項目名の通知が有効になっていることを発見し、それがsafariのアイコンになっていたので、これが通知の原因であることがわかりました。

# 調べた手順
1. アプリケーションおよびSafariの拡張機能を調べる
最初に、アプリケーションに何かインストールされていないか、もしくはSafariの拡張機能に何か登録されていないかを調べました。しかし、不審なアプリや拡張機能はインストールされていませんでした。この時点では、通知の原因は拡張機能にはないことがわかりました。

2. Safariのキャッシュを空にする
次に、Safariのキャッシュを空にすることを試みました。
・Safari>履歴>全削除
・Safari>設定>プライバシー>WEBサイトデータ管理＞全削除
・Safari > 開発 > キャッシュを空にする
どれが効いたのかは今となってはわからないのですが、ここでsafariからのオンラインカジノの通知は止まりました。
また、ユーテリティのアクティブモニタを調べても特に何かが動いている様子は見られず、一旦は解決したと思ったのですが、システム環境設定>通知の項目は依然として◯◯◯◯.netが残ったままとなっていました。
safariからの通知は止まったようですが、通知項目として◯◯◯◯.netが残ったままというのも気持ちが悪いので、なんとか本体を探し当てようと思ったのですがどこにあるのか全く手掛かりがありませんでした。

3. ウィルスバスターとMalwarebytesでスキャン
通知の設定が残っていたため、ウィルスバスターでフルスキャンを実行し、さらにMalwarebytesでもスキャンをかけましたが、何も検出されませんでした。
マルウェアではないにしても通知に設定が残ったままなのは、やはり気持ち悪いので、引き続き、本体を探すこととしました。
そのためターミナル上からfindコマンドで◯◯◯◯.netを使ってみましたが、現在ではSIPという機能が働いていることもあり、sudoを使っても、not permittedというレスポンスが返ってくるだけで結果的に本体は見つけられませんでした。

4. 関連するキャッシュの削除
キャッシュや関連ファイルがどこかに残っている可能性があるため、Safariの関連ファイルを確認することにしました。通知にSafariのアイコンが使われていたため、最初に疑ったのはSafariに関連するキャッシュや設定ファイルです。

## 不可視ファイルの表示:
まず、隠しファイルを可視化するために、FinderでCommand + Shift + .を押して隠しファイルを表示しました。
chatGPTにsafariに関連するフォルダとこのようなアプリが存在しそうなフォルダの一覧を作ってもらい、フォルダの中身を目視で確認していったところ、~/Library/Caches/com.apple.Safari/RemoteNotifications/内に、web.◯◯◯◯.netというフォルダを発見しました。

中身を確認しようかと思ったのですが、下手に触って何かプログラムが実行されてもまずいので、とりあえず、そのままゴミ箱に入れ、削除を完了させました。
その後、通知設定を確認したところ、通知設定にあった◯◯◯◯.netの項目名は消えていたので一旦、これで本体も削除できたのかと思われました。

# 今後について
MacOSの再インストールをしようとも思ったのですが、同OS上でいくつかの仮想環境などの構築も行なっており、Mac自体というより仮想環境の再構築するのに非常に手間がかかるので一旦はこのまま使わざるをえないかと思っています。

今のところは、定期的にウィルスバスターのフルスキャンをかけるようにして様子をみようと思います。
AWS CDKをふんわり理解する

## はじめに

日々の業務の中で、インフラの手作業に時間を取られてしまうことがあります。
近年では、**「インフラもコードで管理する（IaC: Infrastructure as Code）」** という考え方が浸透してきており、
私の所属組織でも、**AWS Cloud Development Kit（CDK）** を導入し、運用の効率化と“トイル（Toil）”の削減に取り組み始めました！

本記事では、自分の学習メモも兼ねて、AWS CDKについて学んだことをまとめてみました。

## インフラストラクチャ・アズ・コード（IaC）とは

インフラの設定をコードで書いて管理する方法です。

### 手作業とIaCの比較

**手作業：**

1. AWSのコンソール画面にログイン
2. 手動で設定（例：EC2インスタンスを作成、S3バケットを作成）
3. 設定内容をドキュメントに記録
4. 次回も同じことを繰り返す

**IaC：**

1.必要なインフラをコードで記述
2.コードを実行
3.自動的にインフラが構築される
4.変更があれば、コードを更新して再実行

## AWS CDKとは

AWS Cloud Development Kit（CDK）は、使い慣れたプログラミング言語でクラウドリソースを定義できるオープンソースのフレームワークです。コードからCloudFormationテンプレートを生成し、AWSリソースをプロビジョニングします。

### AWS CDKのメリット

1. **開発者体験の改善**
   - TypeScript、Python、Java、.NET、Goなど多言語サポート
   - 使い慣れた言語とIDEの活用（コード補完、型チェック、ユニットテスト）
   - リソース間やスタック間の依存関係の自動解決

2. **アプリ全体をコードで定義**
   - Lambda関数コードやコンテナイメージなどのアセットを一緒にデプロイ
   - CI/CDパイプラインの自動構築
   - 複数のAWSアカウントやリージョンへのデプロイ

3. **抽象化と再利用**
   - ベストプラクティスに基づいた複雑な設定の抽象化
   - 必要に応じて低レベルな設定も可能
   - モジュール化によるチーム内での共有

## AWS CDKのコンセプト

AWS CDKのコア概念は以下の3つ

1. **Constructs**: 柔軟に構造を表現するためのコアフレームワーク
2. **AWS CDK Lib**: AWSのリソースを定義するための標準的なコンストラクトライブラリ
3. **AWS CDK Toolkit (CLI)**: CDKアプリケーションを操作するためのコマンドラインツール

### アプリケーション構造

AWS CDKアプリケーションの階層構造について

- **App**: アプリケーション全体をまとめるルートとなる概念。
- **Stack**: CloudFormationスタックに対応し、デプロイの最小単位。
- **Construct**: AWS CDK において最も重要な概念。一つ以上の AWS リソースを表現します。

### Constructの抽象化レベル

Constructには3つの抽象化レベルがあります

1. **L1 Construct**: CloudFormationテンプレートをそのままコード化したもの
2. **L2 Construct**: ベストプラクティスと安全なデフォルト値を含む抽象化されたコンストラクト
3. **L3 Construct（パターン）**: よくある構成をまとめた高レベルな抽象化

例えば、S3バケットをL2コンストラクトで定義すると、適切なデフォルト値が設定され、バケットへのアクセス許可も簡単なメソッドで記述できます。


## CDKでのベストプラクティス

### 適切な抽象化レベルの選択

- 基本的にはL2コンストラクトを使用
- 複雑な設定が必要な場合はL1コンストラクトに降格
- 共通パターンはL3コンストラクトまたは独自コンストラクトとして抽象化

### 機能不足の対処法

1. L2コンストラクトがない場合はL1コンストラクトを使用
2. L2コンストラクトの機能が足りない場合は`Construct.node.defaultChild`でL1コンストラクトを取得
3. CloudFormationに対応していない機能はカスタムリソースで対応

### コンストラクトの再利用

独自のコンストラクトライブラリを作成して組織内で共有することで、ベストプラクティスやセキュリティガードレールを標準化できます。

## まとめ

AWS CDKは、使い慣れたプログラミング言語でAWSリソースを定義できるフレームワークです。CloudFormationの宣言的なアプローチを維持しながら、プログラミング言語を活用することで、より柔軟で再利用可能なインフラコードを作成できます。

## 学習リソース

- [AWS CDK公式デベロッパーガイド](https://docs.aws.amazon.com/cdk/latest/guide/home.html)
- [AWS CDK APIリファレンス](https://docs.aws.amazon.com/cdk/api/latest/)
- [AWS CDK GitHubリポジトリ](https://github.com/aws/aws-cdk)
- [TypeScriptの基礎から始めるAWS CDK開発入門ワークショップ（日本語）](https://catalog.workshops.aws/typescript-and-cdk-for-beginner/ja-JP)
- [CDKワークショップ（日本語）](https://cdkworkshop.com/ja/)
さくらのクラウドでDifyをホスティングしてみる②

# 概要

Difyをさくらのクラウドでホスティングしてみる話の続き。

前回のお話はこちら
https://qiita.com/yokotto_tech/items/fbea026056d7221d13ab

今回は、独自ドメインで運用するための設定です。

## 🌸 Difyで独自ドメインを設定する

#### 前提と注意点

- 独自ドメインは **お名前.com** で取得しました（年間管理費が安いため）
- DNS（ネームサーバー）は**さくらインターネット**を使う構成にしました
- この構成を取る場合、お名前.com側でネームサーバーを必ず「さくら」に変更する必要がある点に注意です！！


#### 1. お名前.comでドメインを取得

こちらでドメインを取得します。
https://navi.onamae.com/top

![スクリーンショット 2025-05-10 143309.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664191/0548b2b4-f81d-45ef-a25d-a9c0d8ef85bc.png)

#### 2. さくらのクラウドでDNSゾーンを作成

さくらのクラウドの、
左側のメニュー「グローバル」カテゴリ内にある「DNS」をクリックします。
新規に作成する場合は「追加」ボタンをクリックします。

- ゾーン名：取得したドメイン名
- 説明とタグは任意でわかりやすいように記入します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664191/86a3dc2d-3e8c-4993-bfe0-b09df794370f.png)
 
「作成」をクリック


#### 3. DNSゾーンにAレコードを追加

ドメインとIPを紐づけるためAレコードを追加します。
先ほど作成したDNSゾーンの、「リソースレコード」タブを開きます。
「追加」をクリックします。

![スクリーンショット 2025-05-10 141211.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664191/e7873cf7-129d-4b5a-afcf-e343b9788e7d.png)


サーバのIPアドレスが `203.0.113.10` の場合、以下のように入力します。

| ホスト名 | タイプ | TTL  | 値             |
|----------|--------|------|----------------|
| `@`      | A      | 3600 | `203.0.113.10` |


![スクリーンショット 2025-05-10 145401.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664191/3571eb94-43c9-491c-96f4-8b44f677cfa2.png)

【参照】
https://manual.sakura.ad.jp/cloud/appliance/dns/index.html



#### 4. お名前.comでネームサーバを登録

さくらのクラウドで設定した登録ゾーンをダブルクリックすると、ゾーン詳細画面が表示され、ゾーン登録先DNSサーバの確認が可能です。

![スクリーンショット 2025-05-10 150200.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664191/6fbc137d-91c7-4aff-bd27-618880c27e40.png)

この情報を、お名前.comのネームサーバ情報に登録します。

![スクリーンショット 2025-05-10 150421.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664191/bba9225e-8e12-457b-8bcf-14dca4ac263e.png)

入力後、下にスクロールして確認ボタンを押せば登録完了です。

![スクリーンショット 2025-05-10 150431.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664191/fbd783f1-2233-4490-a79a-bac1c1e45c4f.png)



#### 5.DNS設定が反映されているか確認

独自ドメイン（例：example.net）を設定したあと、名前解決（DNS）が正しくできているかを確認するには `dig` コマンドが便利です。（反映には1時間～２４時間かかります。）



- 通常の dig

```
dig example.net
```
- Google DNSを指定してdig
dig結果になかなか反映されない場合は、GoogleのDNSを指定して確認するのがおすすめです

```
dig @8.8.8.8 example.net
```
LeetCode daily #2918. Minimum Equal Sum of Two Arrays After Replacing Zeros

# 【LeetCode #2918】 Minimum Equal Sum of Two Arrays After Replacing Zeros

## はじめに
　今日の LeetCode Daily は medium 問題でした．パッと見で「難しいな...」と思うような内容でしたが，考え方を整理してみると，意外とスッと解けます．
　本記事ではその流れを解説します．

## 問題概要
　2つの配列 nums1・nums2 が与えられます．それぞれの配列には一部 0 が含まれており，この 0 を 1 以上の値に変更することで，**2つの配列の総和を一致させる**ことができるかを判定します．

* 一致が可能であれば，そのときの**変更後の配列の合計値の最小値**を返します
* 一致できない場合は -1 を返します

### 例
> **入力：** nums1 = [3, 2, 0, 1, 0], nums2 = [6, 5, 0]
> **出力：** 12
> **説明：** nums1 = [3, 2, **2**, 1, **4**], nums2 = [6, 5, **1**] のとき一致する

> **入力：** nums1 = [2, 0, 2, 0], nums2 = [1, 4]
> **出力：** -1
> **説明：** どんな値を入れても一致しないので，-1 を返す

### カテゴリ
問題難易度：medium
タグ：Array, Greedy

## 解法
　まずはこの問題で **「一致させることが不可能になる条件」** を明確にしておきます．不可能になるパターンは，nums1・nums2 内の 0 を 1 以上の任意の値に変更しても総和が一致しないときです．このとき，1 以上の任意の値は無限と考えられるので，下限を考えます．つまり，配列内の 0 を全て 1 にしても 2 つの配列の総和が一致しないときです．これは例の#2が参考になります．

**再掲**
> **入力：** nums1 = [2, 0, 2, 0], nums2 = [1, 4]
> **出力：** -1
> **説明：** どんな値を入れても一致しないので，-1 を返す

以下に nums1・nums2 の総和，0 の数，0 -> 1 としたときの最小値を整理します．

| | 総和 | 0 の数 | 0 -> 1 としたときの最小値 |
| :-: | :-: | :-:| :-: |
| nums1 | 4 | 2 | 6 |
| nums2 | 5 | 0 | 5 |

　つまり，片方の配列内の 0 の数が 0 かつ，0 -> 1 としたときの最小値がもう一方の配列よりも小さいとき，どう頑張っても一致させることはできません．これが不可能なパターンになります．
　逆に言えば，上記の不可能条件に該当しなければ一致させることは可能です．その場合，配列内の 0 をすべて 1 に変えたときの **最小合計値の大きい方** が答えになります．

**まとめると...**
　まず，0 をすべて最小値である 1 に置き換えたときの合計（=minv1, minv2）を考えます．もし一方の配列に 0 が含まれておらず，どう足しても，もう一方の min 合計に追いつけない場合は，合計を一致させることは不可能です．それ以外の場合は，一方を必要に応じて膨らませることで一致させることができ，最小合計は max(minv1, minv2) になります．

 ```python
class Solution:
    def minSum(self, nums1: List[int], nums2: List[int]) -> int:
        sum1 = sum(nums1)
        sum2 = sum(nums2)
        zero1 = nums1.count(0)
        zero2 = nums2.count(0)
        minv1 = sum1 + zero1
        minv2 = sum2 + zero2
        
        if (zero1 == 0 and minv2 > minv1) or (zero2 == 0 and minv1 > minv2):
            return -1
        return max(minv1, minv2)

 ```
 
## まとめ
　今日は配列内の値を変更して総和を一致させる問題を解説しました．
　初めこの問題を見たときは「組み合わせたくさんありそう...」と思いましたが，落ち着いて幾つかの例を考えてみると，割と簡単に解ける問題だと分かりました．medium レベルの問題は一見難しそうに見えても，実はロジックを丁寧に整理すれば簡単に解けるケースも多そうですね...．
　今後も Daily や類題を中心に，解法の整理やアイデアを投稿していこうと思います．

 ## おまけ
 TypeScript はこちら
 ```typescript
function minSum(nums1: number[], nums2: number[]): number {
    const sum1: number = nums1.reduce((curr, val) => curr+val, 0);
    const sum2: number = nums2.reduce((curr, val) => curr+val, 0);
    const zero1: number = nums1.filter((x) => x == 0).length;
    const zero2: number = nums2.filter((x) => x == 0).length;
    const minv1: number = sum1 + zero1;
    const minv2: number = sum2 + zero2;
    if ((zero1 === 0 && minv2 > minv1) || (zero2 === 0 && minv1 > minv2)) {
        return -1;
    }
    return Math.max(minv1, minv2);
};
 ```
【PowerAutomate】100件を超える「複数の項目の取得（Get Items）」

- PowerAutomateは「新しいデザイナー」で説明します。
- 職場環境の画面キャプチャは掲載できないため記事によっては文字が多くなります。ご容赦ください。

## 困ったこと
SharePointリストに「複数の項目の取得」でフィルターを設定して抽出したが、100件を超えるデータを取得できない。
（「項目（Item）」ってリストの１行なんですよね…つい１レコードの中の１項目って考えてしまいます）

## 原因
デフォルトがMAX100件であるため。
https://learn.microsoft.com/ja-jp/graph/system-messages#supported-system-message-events

## 解決方法
「改ページ」設定を変更することにより100件を超える件数に増やすことができます。
デフォルトでは「設定」タブの「改ページ」が「オフ」になっており、このままでは取得件数は100件までです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3903408/c18fad99-dc16-4528-88be-1b8818e24bbe.png)
ただし、取得件数が多いと当然パフォーマンスが下がったり、ネットワークに負荷をかける可能性が大きくなります。

1. 「設定」タブの「改ページ」を「オン」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3903408/ca08ed58-bce4-444d-81f4-0653f7a23d9a.png)

1. 「しきい値」に希望の最大取得件数を設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3903408/aa9ab84f-b60f-44e9-b1e9-300db166c779.png)
ここでは「10000」と入力して上部のエラーメッセージは消えます。
しかし、MAX5,000件？問題の有無は検証できていません。
＊「パラメーター」の「上から順に取得」のMAX5,000に影響を受ける/受けない
＊ライセンスによって制限される可能性がある(わたしは現在Freeプランです)
＊トリガーやほかのアクションによって制限される可能性がある

PowerAutomateは、日常デスクワークの業務効率化に適したツールと考えていますし実行時間制限もあるので、大量データを扱いたいなら別の手段を考えるほうがいいと思っています。
Pythonのloggingでログファイルを年月ごとのディレクトリに出力したい

# やりたいこと
Python標準のloggingの使用して年月ごとのディレクトリにログファイルを出力します。
```
LOG_DIR
├── 2025
│   ├── 01
│   │   ├── LOG_FILE.20250101.log
│   │   ├── ...
│   │   └── LOG_FILE.20250131.log
│   └── 02
│       ├── LOG_FILE.20250201.log
│       ├── ...
│       └── LOG_FILE.20250228.log
└── LOG_FILE
```
# 実装
[TimedRotatingFileHandler](https://docs.python.org/3/library/logging.handlers.html#timedrotatingfilehandler)を継承します。
```python:サンプルコード
import re
import time
from datetime import datetime
from logging import getLogger
from logging.handlers import TimedRotatingFileHandler
from pathlib import Path


class MyTimedRoatingFileHandler(TimedRotatingFileHandler):
    def __init__(
        self,
        filename,
        when="h",
        interval=1,
        backupCount=0,
        encoding=None,
        delay=False,
        utc=False,
        atTime=None,
        errors=None,
    ):
        super().__init__(
            filename, when, interval, backupCount, encoding, delay, utc, atTime, errors
        )
        # ファイル名の日時フォーマットの「-」と「_」を取り除く
        # e.g. LOG_FILE.2025-01-01_12-30-40 -> LOG_FILE.20250101123040
        self.suffix = re.sub(r"([-_])", "", self.suffix)
        extMatch = re.sub(r"([-_])", "", self.extMatch.pattern)
        self.extMatch = re.compile(extMatch, re.ASCII)

    def rotation_filename(self, default_name):
        # default_nameから日時を取り出す
        dt_str = self.extMatch.findall(default_name)[-1]
        dt = datetime.strptime(dt_str, self.suffix)
        # 年/月ディレクトリを挿入する
        # e.g. LOG_DIR/LOG_FILE -> LOG_DIR/2025/01/LOG_FILE
        default_name_path = Path(default_name)
        default_name = (
            default_name_path.parent
            / dt.strftime("%Y")
            / dt.strftime("%m")
            / default_name_path.name
        )
        return super().rotation_filename(default_name)

    def rotate(self, source, dest):
        # 存在しないディレクトリは作成する
        Path(dest).parent.mkdir(parents=True, exist_ok=True)
        return super().rotate(source, dest)

    def _open(self):
        # 存在しないディレクトリは作成する
        Path(self.baseFilename).parent.mkdir(parents=True, exist_ok=True)
        return super()._open()


# ログを出力してみる
logger = getLogger("logger")
handler = MyTimedRoatingFileHandler("LOG_DIR/LOG_FILE", "S")  # 実運用はwhen="midnight"とします
handler.namer = lambda default_name: f"{default_name}.log"  # 拡張子を.logとします
logger.addHandler(handler)

for i in range(20):
    logger.error(f"ERROR MESSAGE{i}")
    time.sleep(0.5)
```
エンジニア採用Meetup　求職者視点でのアウトプット

先日、[「エンジニア採用Meetup：リクルーターとハイアリングマネージャーの役割分担」](https://layerx.connpass.com/event/351949/)に参加してきました！

転職活動中の求職者として、今回の学びを共有したいと思います。

# 参加目的

採用側がどのような経験や経歴を持つ人材を求めているのか、どのような採用手法を用いているのかを知れるのではないかと考え参加しました。

# Meetupに参加しての感想

最も印象的だったのは、さくらインターネットの武村さんの「社長自らがリファラル採用を推進している」という点です。
正直なところ、参加するまでリファラル採用に対して良いイメージを持っていませんでした。しかし、優秀な人材ほどリファラル経由で入社するケースが多いと知り、改めて人脈の重要性を痛感しました。

また、未経験の分野に挑戦する際には、まず「自分の存在をアピールする必要がある」という認識が間違っていないと再確認できたことも収穫でした。

# LTで学んだこと

## LayerX 大石さん：ハイアリングマネージャーの役割
リクルーターとは別に、候補者の技術力を評価する役割を担うのがハイアリングマネージャーとのことでした。今後、技術面に関する面接では、このような方々と直接話す機会が増えるのだと理解しました。

## サイバーエージェント 高橋さん：リクルーターに求められるマーケット感覚
「他社を知ること」の重要性を強調されていました。具体的な行動として「定期的にベンチマーク企業を10社選定し、調査を行う」という例を挙げられており、これは転職活動を行う私にとっても、会社を選ぶ上でも応用できる視点だと感じました。

## SmartHR 奈良さん：スクラム採用
スクラム採用とは、人事担当者だけでなく、現場の社員も採用活動に積極的に関わるチーム体制で行う採用手法とのことです。これまで面接といえば人事の方とのやり取りが中心でしたが、今後はより専門的な内容について、実際に現場で働いているエンジニアの方と話す機会も増えてくるだろうと感じました。

## さくらインターネット 武村さん：大規模採用におけるリファラルの重要性
大規模な開発案件に対応するため、大量の採用が必要となる状況において、母集団形成の手段の一つとして「社長自らがリファラルを行っている」というお話には、大変驚きました。トップダウンでリファラル採用を推進する姿勢は、その効果への期待の表れだと感じました。

# まとめ

今回のMeetupを通じて、自身の技術力を高めることはもちろん、積極的にイベントに参加し、情報発信を行うことで人脈を広げていくことの重要性を改めて認識しました。今後も積極的に行動していきます！
ロジカルシンキング（MECE）とプログラミング的思考力（またはCT）とアルゴリズム的思考力の階層構造まとめ

# はじめに
ロジカルシンキング（MECE）とプログラミング的思考力とプログラミング構造考案力のアルゴリズム的思考力の階層構造について、自分なりのまとめをメモしておきます。

# ロジカルシンキング（MECE）論理的思考力
論理的思考力一般やロジカルシンキングとカタカナ用語となった場合でも、その概念にはいくつか多様性がありますが、わたしの中でロジカルシンキングというと下記のミーシー（MECE）でした。

* **M** utually（互いに）
* **E** xclusive（重複せず）
* **C** ollectively（全体的に）
* **E** xhaustive（漏れがない）

「MECE」とは、「漏れなく、ダブりなく」。

これはビジネスの現場では絶大な威力を発揮する、説得を目的とする思考ツールとわたしは認識しています。


# プログラミング的思考力
プログラミング的思考力といった場合、英語由来のカタカナ語のコンピュテーショナルシンキングまたは計算論的思考と比較される場合もあるようですが、プログラミング的思考力の方がよくみます。
後者は提唱者がいるので、厳密には異なる概念となりますので後述します。とりあえず「プログラミング的思考力」というと下記のようなことを一般的に指すとします。（わたしのアレンジを含みます。）

* **分解・整理する** 複雑な問題を小さな問題に分けて認識する
* **再構成する** 異なる要素を組み合わせて新しい要素を再構成する
* **結果予測する** 思考の中でいくつかの状況を想定して結果を予測する
* **抽象化する** 具体的な事例から一般的な原理を導き出す帰納的な分析力
* **言語化する** 自分の考えを明確に表現し、他者に伝える演繹的な力。 

ほぼエンジニアリングまたはその他のビジネスの問題解決能力と同じとも言えますが、対象がソフトウェア開発の場合はこれらのことを「プログラミング的思考力」と表現しているように思われます。

## コンピュテーショナルシンキング(CT) 計算論的思考
コンピュテーショナルシンキング(CT) 計算論的思考の場合は、より計算機的でソフトウェア開発的な思考が定義されています。（若干定義のゆらぎはあるようです。）前記プログラミング的思考力とかぶっている点がもちろんあり、見出しの文言が異なっていても概念的に同意な場合を含みます。

* **問題を分解する**　複雑な問題を解決可能なレベルまで分解する
* **パターンを認識する**　繰り返し出現する要素を特定する
* **抽象化する**　パターン群からパターンをさらに一般化し支配的な要素を特定すること
* **アルゴリズムを作成する**　問題に対して解決に至るステップ手順を明らかにすること

Wing氏の英語論文の日本語翻訳版　「情報処理」誌（情報処理学会）
翻訳「計算論的思考」
https://www.cs.cmu.edu/afs/cs/usr/wing/www/ct-japanese.pdf

# アルゴリズム的思考力
アルゴリズム的思考力とはあまり一般的な表現ではないかもしれませんが、コンピュテーショナルシンキング(CT) 計算論的思考の４つ目の定義の中身に相当するとわたしは考えています。ソフトウェアの場合は「問題を解決する≒ソフトウェアが動くようになる」が成立する場合が多いです。現在のコンピュータのソフトウェアが動作する手順書の構造は下記の４点からなるとわたしは考えています。

* **順次**　順々にステップが進行する
* **反復**　同一のステップ群がループする、繰り返される
* **分岐**　あるステップで複数のステップに分岐する
* **割込み**　あるステップとステップの間に別のステップが出現する

割込みを含めるのはわたしのアレンジなので一般的ではないかもしれません。ただし、今日のプログラミングの現実ではこの概念を知っておかないと挫折しやすくなるポイントとわたしは考えています。

https://qiita.com/mylifewithviolin/items/c5613eda58bf552d7bf6


# おわりに
いかがでしたでしょうか？なにかの役にたてば幸いです。あくまでわたしの認識の中で、より上位の一般的な論理的思考力から、プログラミングの実装に必要な思考力までを階層的にまとめてみました。
AWS RDS データベース構築 解説

## はじめに

アプリケーション開発において、データベースは非常に重要な役割を果たします。
AWS Relational Database Service (RDS) は、クラウド上でリレーショナルデータベースを簡単にセットアップ、運用、スケールできるマネージドサービスです。
本記事では、RDSの概要から基本的な使い方までを初心者向けに解説します。

## RDS メリット

従来のオンプレミスでのデータベース運用には、サーバーの調達、OSやデータベースソフトウェアのインストール、バックアップ、監視など、多くの手間と専門知識が必要でした。RDSはこれらの運用タスクをAWSが代行してくれるため、ユーザーはアプリケーション開発に集中できます。

**RDSの主なメリット:**

* **運用管理の容易さ:** セットアップ、パッチ適用、バックアップ、復旧などの運用タスクが自動化されています。
* **スケーラビリティ:** 必要に応じてコンピューティングリソースやストレージを簡単にスケールアップ/ダウンできます。
* **高可用性:** Multi-AZ構成を利用することで、可用性を向上させ、障害発生時の自動フェイルオーバーが可能です。
* **パフォーマンス:** 用途に合わせた様々なインスタンスタイプやストレージタイプを選択できます。
* **セキュリティ:** VPCとの連携、セキュリティグループによるアクセス制御、保存時/転送時の暗号化など、セキュリティ機能が充実しています。
* **コスト効率:** 従量課金制で、必要な分だけリソースを利用できるため、コストを最適化できます。

## 対応データベースエンジンの紹介と選び方

RDSは、以下の主要なリレーショナルデータベースエンジンに対応しています。

* **Amazon Aurora (MySQL/PostgreSQL互換):** 高いパフォーマンスと可用性を備えたAWS独自のデータベースサービスです。
* **MySQL:** オープンソースで広く利用されているデータベースです。
* **PostgreSQL:** 高度な機能と拡張性を持つ、オープンソースのデータベースです。
* **MariaDB:** MySQLから派生した、オープンソースのデータベースです。
* **SQL Server:** Microsoftが提供する商用データベースです（ライセンス費用に注意が必要です）。
* **Oracle:** Oracle Corporationが提供する商用データベースです（ライセンス費用に注意が必要です）。

どのエンジンを選ぶかは、アプリケーションの要件、既存の技術スタック、コストなどを考慮して決定します。一般的には、互換性や移行の容易さから、既存の環境で利用しているエンジンを選択することが多いです。新規に始める場合は、AuroraやPostgreSQLがパフォーマンスや機能面で優れている場合があります。

## RDSインスタンスの作成

RDSインスタンスは、AWS Management Console、AWS CLI、またはSDKを使用して作成できます。ここでは、AWS Management Consoleを使った基本的な手順を説明します。

1.  **AWSアカウントにログインし、RDSサービスを開きます。**
2.  **「データベースの作成」ボタンをクリックします。**
3.  **データベースエンジンの選択:** 利用したいエンジンを選択します。
4.  **テンプレートの選択:** 用途に合わせたテンプレート（例: 本番稼働、開発/テスト）を選択します。
5.  **設定:**
    * **DBインスタンス識別子:** インスタンスの名前を設定します。
    * **マスターユーザー名/パスワード:** データベースに接続するためのユーザー名とパスワードを設定します。
    * **DBインスタンスクラス:** インスタンスのスペック（CPU、メモリ）を選択します。
    * **ストレージ:** ストレージの種類とサイズを設定します。
    * **VPC:** RDSインスタンスを配置するVPCを選択します。
    * **セキュリティグループ:** データベースへのアクセスを許可するセキュリティグループを設定します。
    * **アベイラビリティーゾーン:** インスタンスを配置するAZを選択します（高可用性のためにはMulti-AZ構成を推奨します）。
6.  **追加設定:** バックアップ、メンテナンスウィンドウ、モニタリングなどの詳細設定を行います。
7.  **「データベースの作成」をクリックします。**

インスタンスの作成には数分かかる場合があります。作成が完了すると、エンドポイントとポート番号が発行され、これを使ってデータベースに接続できます。

## 基本的な運用

### データベースへの接続

作成したRDSインスタンスには、各種データベースクライアントツール（例: MySQL Workbench, pgAdmin, SQL Server Management Studioなど）を使用して接続できます。接続には、インスタンスのエンドポイント、ポート番号、マスターユーザー名、パスワードが必要です。

### 自動バックアップの設定と確認

RDSは、指定した期間（保持期間）の間、自動的にデータベースのバックアップを取得してくれます。AWS Management Consoleからバックアップの設定や保持期間を確認できます。また、手動でスナップショットを作成することも可能です。

### CloudWatchでの基本的なモニタリング

RDSのパフォーマンスやリソース使用状況は、AWS CloudWatchで監視できます。CPU使用率、メモリ使用量、ディスクI/Oなどを定期的に確認し、必要に応じてインスタンスのスケールアップなどを検討します。

## まとめ：RDSを始めるための第一歩と今後の学習の方向性

AWS RDSの基本的な概念とインスタンスの作成、そして初期運用について解説しました。RDSを活用することで、データベースの運用管理の負担を軽減し、より開発に集中できる環境を構築できます。

今後は、より高度な運用方法（パフォーマンスチューニング、スケーリング、高可用性構成など）についても学習していくことをお勧めします。
AWSの公式ドキュメントやチュートリアルも参考に、RDSを効果的に活用していきましょう。
Amazon Managed Service for Apache Flinkメモ

　**Amazon Managed Service for Apache Flink（旧称：Amazon Kinesis Data Analytics for Apache Flink）**　は、**Apache Flink** をベースにした **リアルタイムデータストリーム処理サービス** を **フルマネージドで提供**するAWSのサービスです。

---

### ✅ 主な特徴

| 特徴                             | 説明                                                                                  |
| ------------------------------ | ----------------------------------------------------------------------------------- |
| **フルマネージド**                    | Apache Flink クラスターのプロビジョニング、スケーリング、パッチ適用、モニタリングなどを AWS が自動で管理します。                   |
| **リアルタイム処理**                   | ミリ秒単位の遅延で、ストリーミングデータの分析・処理が可能です。                                                    |
| **Apache Flink API**           | Java / Scala / Python で Flink の標準 API を使用可能。既存の Flink アプリケーションをほぼそのまま移行できます。        |
| **AWSとの連携**                    | Kinesis Data Streams, Kafka, S3, DynamoDB, OpenSearch, Redshift などのAWSサービスと統合が容易です。 |
| **状態管理 (Stateful processing)** | 大量データを状態付きで処理する Flink の特長を活かし、Exactly-once 処理なども可能です。                               |

---

### 🛠 主なユースケース

* IoT デバイスからのリアルタイムデータ処理
* アプリケーションのログ・クリックストリーム分析
* 金融取引や決済データの不正検知
* メトリクスやセンサーデータのリアルタイムダッシュボード
* SNS 投稿などのリアルタイムテキストマイニング

---

### 🔗 関連サービス

* **Amazon Kinesis**：データ収集に利用（プロデューサー）
* **Amazon S3 / DynamoDB / OpenSearch**：分析結果の保存先
* **AWS Lambda**：軽量な補助処理との連携も可能

---

### 💡 まとめ

Amazon Managed Service for Apache Flink は、**大規模かつリアルタイムなストリームデータの処理**を、**専門知識なしで簡単に行えるようにする強力なサービス**です。Apache Flink のパワフルな処理能力と AWS の運用自動化を融合しています。

---
【無料】laravelで作成したアプリをrailwayでデプロイする

# デプロイ手順
1. github Repo から対象のリポジトリ選択
1. Database > Add MySQL でデータベース選択
1. 追加したリポジトリのアプリケーションにて以下の設定
    1. Root Directory：backendのコードが存在するrootディレクトリ
    1. Public Networking を ONにする
    1. Custom Build Command
        ```
        composer install && php artisan config:clear
        ```
    1. Custom Start Command
        ```
        php artisan serve --host=0.0.0.0 --port=$PORT
        ```
    1. Valiablesから環境変数を設定
        ```
        APP_URL="Public Networking のurl"
        APP_ENV="production"
        LOG_CHANNEL="stderr"
        APP_KEY="ローカルのkeyと同様（base64:××××××××××××××××××××××××）"
        DB_CONNECTION="mysql"
        DB_HOST="MySQLのMYSQL_PUBLIC_URLの@から:の間のホスト名"
        DB_PORT="MySQLのMYSQL_PUBLIC_URL の net:の後に記載のポート番号"
        DB_DATABASE="MySQLのMYSQL_DATABASE同様"
        DB_USERNAME="root"
        DB_PASSWORD="MySQLのMYSQLPASSWORD"
        ```
    1. config/logging.phpのchannels に stderr追記
        ```
        'channels' => [
            'stack' => [
                'driver' => 'stack',
                'channels' => ['single', 'stderr'],
        ```
1. 暗号化キーの生成を行なっていなければ生成してAPP_KEYに設定
1. マイグレーション
    ```
    railway run bash -c "cd backend && php artisan migrate"
    ```
1. Public Networking のurlにアクセス