OmniAICreator/Qiita-1.07M huggingface dataset:
AWS Global Acceleratorタイプ

**AWS Global Accelerator** は、グローバルなユーザーに対して AWS 上のアプリケーションへの低レイテンシかつ高可用なアクセスを提供するサービスです。
ユーザーの近くにある **AWS グローバルエッジネットワーク**（Anycast IP）を経由して、トラフィックを最適なリージョンへルーティングします。

---

## 🔐 アクセスレターとは？

AWS Global Accelerator では、**アクセスポリシー（アクセスタイプ）を指定するために「アクセスレター（Accelerator Type）」を選択**します。

| アクセスタイプ（アクセスレター）               | 説明                                           |
| ------------------------------ | -------------------------------------------- |
| **Standard（標準）**               | 複数の AWS リージョンのリソースにトラフィックをルーティングできる          |
| **Custom Routing（カスタムルーティング）** | 特定のポートと EC2 インスタンスに直接ルーティング可能。NAT やゲームサーバー向け |

---

## ✨ Standard Accelerator（標準アクセラレータ）

### 特徴

* **Elastic Load Balancer (ALB/NLB)、EC2、Elastic IP、S3 静的ウェブサイト** などにトラフィックをルーティング
* **リージョン間のフェイルオーバー / フェイルバック**
* AWS のヘルスチェックにより障害時は自動で別リージョンにルーティング

### 利用例

* グローバルな Web サービス
* マルチリージョン DR 対応
* API Gateway や ALB を用いた SaaS プラットフォーム

---

## 🛠 Custom Routing Accelerator（カスタムルーティングアクセラレータ）

### 特徴

* トラフィックを **特定のポートと EC2 インスタンスの ENI（Elastic Network Interface）に直接ルーティング**可能
* **UDP / TCP 両対応**
* アプリ側でインスタンス選定ロジックが必要（フローの振り分け）

### 利用例

* オンラインゲームサーバー（低レイテンシが重要）
* VoIP アプリケーション
* ファイル転送サーバー（FTP/SFTP）
* NAT ゲートウェイの代替としての使用

---

## 🔄 比較まとめ

| 特徴             | Standard Accelerator     | Custom Routing Accelerator |
| -------------- | ------------------------ | -------------------------- |
| 対象サービス         | ALB, NLB, EC2, EIP など    | EC2 インスタンス（ポート単位）          |
| ルーティング方式       | AWS が自動ルーティング            | アプリ側でルーティング制御              |
| プロトコル          | TCP のみ                   | TCP / UDP                  |
| リージョン間フェイルオーバー | ✅ 対応                     | ❌ 非対応（インスタンス単位）            |
| ユースケース         | Web/REST API、SaaS、DR構成など | ゲーム、VoIP、NAT用途             |

---

## 💡 注意点

* Custom Routing は内部構成の理解とメンテナンスがやや複雑です（ルーティングルール、フローマッピングなどの管理が必要）
* Standard Accelerator はセットアップがシンプルで、ほとんどの Web システムではこちらで十分

---

## 📘 まとめ

| アクセスレター            | 向いているケース                               |
| ------------------ | -------------------------------------- |
| **Standard**       | Webアプリ、API、グローバルサービスなど                 |
| **Custom Routing** | ゲーム、リアルタイム通信、低レイテンシが重要な TCP/UDP サービスなど |
IAMユーザー名の変更（たったの1ステップ）

初めまして、こんにちは。
完全未経験からIT業界に飛び込み、クラウドエンジニアとして日々勉強しています。
知識アウトプットのため、これから小さなことでもブログで公開していきます。
お手柔らかにお願いいたします。

今回はCloudshellを使って、AWSのIAMユーザー名を変更しました。


## 目的
AWS環境のIAMユーザーの名前を
**olduser**→**newuser**に変更する。

## 現状
IAMユーザー名が**olduser**です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4084313/9936151d-c377-4dcc-81bc-1bf13c3f54aa.png)

## 方法
画面右上からCloudshellを開き、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4084313/17712755-a9ba-4116-9685-c9dec6e6a275.png)
以下のプロンプトを実行。

 ```aws iam update-user --user-name olduser --new-user-name newuser```
 以上です。

 ## 結果
 コンソールをリロードすると、変更後のユーザー名**newuser**が表示されています。
 
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4084313/b9c89f79-f35b-4b40-b7b6-a8f992832a89.png)

## 感想
たった1行のプロンプトで実現できました。
Cloudshell使いこなせるよう頑張ります。

## 参考ページ
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/update-user.html
ORM抽象クラスの理解を通じて得た学び

## はじめに 

ORMの実装を通じて、ORMの仕組みや価値が理解できたので、その過程で得られた学びを整理する。

---

### そもそもORMって何をしたいのか？

まずやりたいことは、インスタンスで、データベースのテーブルの1行（レコード）を表現すること。
そして、インスタンスの操作（プロパティの参照や更新）をそのままデータベースの操作に対応させること。
そうすることで、インスタンスを使い、SQLを書かずに直感的にデータベース操作ができるようになる。

---

### ORM抽象クラスのすごさ

ORM抽象クラスのすごさは、継承するだけでデータベース操作の準備が整うこと。

具体的には、以下の流れで自動的にマッピングが行われる。

1. クラス名からテーブル名を特定する
2. テーブル名からカラム構造（カラム名と型）を取得する
3. 取得したカラム情報をもとに、インスタンス内に属性として保持する

この時点で、「どのテーブルの」「どの型の」「どのカラムを」扱うのかが判明しており、あとはそれらの情報をもとにCRUD操作メソッドを抽象化するだけとなる。

---

### おわりに

ORM抽象クラスを実際に自分で構築したことで、フレームワークの裏側で起きていることが「魔法」ではなく、とても自然なことだと実感できた。

この学びの過程で大切だと思った感覚は、
「クラス名からテーブル名を特定することから、様々な情報を取得し、大きなデータを作っていく感覚」

パソコンを立ち上げると、BIOSが起動して、OSを起動させて、、、みたいなパソコンが立ち上がるプロセスを思い出した。

フレームワークだけに限らず、拡張性の高いソフトウェアを設計するための基本的な考え方であると感じた。
RiderでハイライトやCode Visionなどの設定を「Pencilsウィジェット」で素早く切り替える

RiderのCode VisionやInlay Hintsなど、コード上に情報を表示する機能はとても便利です。しかし、これらの機能を一時的にオフにして、生のコードに集中したい場面もあるのではないでしょうか？そのような場面で、いちいち個々の設定をオン・オフにするのは面倒です。

Riderの「Pencilsウィジェット」を使えば、素早くInlay InformationやStype Inspectionsを無効にしたり、調整することができます。

※ 本投稿はRider 2025.1.2時点の情報に基づいています。

---


Rider 2025.1.2において、Pencilsウィジェットは、デフォルトで無効・非表示になっています。ウィンドウ右下のStatusバーを右クリックして、「Pencils」を選択してください。その後、Riderの再起動を求められるので、再起動してください。

![スクリーンショット 2025-05-18 10.01.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4125/daba2786-2992-49b8-878e-b1d69e2ed0c9.png)

Pencilsウィジェットを有効にすると、Statusバーに鉛筆のアイコンが表示されます。

![スクリーンショット 2025-05-18 10.06.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4125/368704c4-d0ad-480f-9c3d-5619091e8f04.png)

鉛筆アイコンをクリックすると次のようなウィジェットが表示されます。

![スクリーンショット 2025-05-18 10.07.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4125/a60f3800-0594-4078-9b51-390d244c0c1b.png)

---


一例としてPencilsウィジェットを使って、Code Visio・Inlay Hintsの表示の有無を切り替えてみます。

次に示すのは、Inlay Informationのチェックボックスの有効・無効を切り替えたエディターのスクリーンショットです。

|Inlay Information 有効|Inlay Information 無効|
|:---:|:---:|
|![スクリーンショット 2025-05-18 10.11.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4125/d54e09d0-480c-4eb4-a586-714af7240372.png)|![スクリーンショット 2025-05-18 10.11.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4125/8918f3b0-2aa4-4e52-8307-0b52fb9ad80d.png)|

このようにチェックボックスを有効・無効にするだけで、Code Vision・Inlay Hintsの表示を素早く切り替えられます。

Inlay Informationを無効にすると、「Updateメソッドが頻繁に呼ばれているための注意」を促す、炎アイコンがガター常に表示されています。（これはこれでアリかも）


---

なお、Pencilsウィジェットの設定は、


* ソリューション限定
* 開発マシンで共有
* チームで共有

が選択できます。

---

素早く設定変えるのに、Pencilsウィジェットはとても便利ですね。


参考リンク
* 公式ドキュメント ['Pencils' widget](https://www.jetbrains.com/help/rider/Pencils_Widget.html)
* [Rider 2025.2 EAP](https://blog.jetbrains.com/dotnet/2025/05/16/rider-2025-2-eap-1/)

---

余談。Pencilsウィジェット、一度 Rider 2025.1で無くなったのがユーザーフィードバックで復活したみたいです。

https://blog.jetbrains.com/dotnet/2025/05/16/rider-2025-2-eap-1/#the-pencils-widget-is-back


https://youtrack.jetbrains.com/issue/RIDER-118076/Pencils-widget-is-missing-from-Status-Bar-and-Editor
Nodeプロセス運用管理ツール「pm2」使い方まとめ

# はじめに
pm2はNodeアプリケーションのプロセスマネージャーで、
アプリケーションの起動、監視、自動再起動、ロードバランシングなどを簡単に行うことができるツールです。
特に、本番環境での運用で力を発揮します。

# インストール
npmからグローバルにインストールします。
```css:bash
npm install -g pm2
```


# 使い方
pm2の基本的な操作方法です。超簡単です。

### アプリケーションの起動
```css:bash
pm2 start app.js

/* プロセス名をつけて起動する場合 */
pm2 start app.js --name my-app
```

### プロセス一覧の確認
```css:bash
pm2 list
```

### ログの表示
```css:bash
pm2 logs

/* プロセス名を指定して閲覧する場合 */
pm2 logs my-app
```

### プロセスの停止
```css:bash
pm2 stop app.js
/* または */
pm2 stop my-app
```

### プロセスの再起動
```css:bash
pm2 restart app.js
/* または */
pm2 restart my-app
```

### pm2自体の自動起動設定（例：Ubuntuの場合）
```css:bash
pm2 startup
```
その後表示されるコマンドを実行し、  
```css:bash
pm2 save
```
で現在のプロセスリストを保存します。
これで`save`したプロセスはサーバー再起動時に自動的に起動されます。

---

### クラスターモードでの起動（ロードバランサー）
クラスターモードとは、マルチコアCPUを活用してアプリケーションを複数プロセスで並列実行する仕組みです。
複数のプロセスは`pm2`が自動的にロードバランシングします。
```css:bash
/* max指定にすると使用できるCPUコア数分だけプロセスを起動します */
pm2 start app.js -i max
```

### メモリ制限つきでの起動
メモリ制限をつけると、プロセスのメモリ使用量が指定以上となった場合に自動で再起動するようになります。
```css:bash
pm2 start app.js --max-memory-restart 200M
```

### プロセスの詳細表示
`describe`を使用することで、プロセスの詳細情報を閲覧できます。
```css:bash
pm2 describe my-app

/*
Describing process with id 0 - name my-app
┌───────────────────┬────────────────────────────┐
│ status            │ online                     │
│ name              │ my-app                     │
│ restarts          │ 2                          │
│ memory            │ 75.2 MB                    │
│ cpu               │ 0.1%                       │
│ script path       │ /home/user/app/app.js      │
│ exec mode         │ cluster_mode               │
│ instances         │ 4                          │
│ out log           │ ~/.pm2/logs/my-app-out.log │
│ error log         │ ~/.pm2/logs/my-app-err.log │
└───────────────────┴────────────────────────────┘
*/
```
NPO法人の現状と課題

NPO法人で関与してきたのは、２団体。
TOPPERSプロジェクト
https://www.toppers.jp
と
SESSAMEプロジェクト
https://www.sessame.jp/

官公庁・学校・公的団体（NPOを含む）システムの課題、官（０）
https://qiita.com/kaizen_nagoya/items/04ee6eaf7ec13d3af4c3

NPOに限らず、公的団体で、システムの設計・仕様について、公開生、公共性、公平性が確保できていないことを指摘してきた。

情報産業における自治体の都道府県連携与件 官(23) 統計(47) https://qiita.com/kaizen_nagoya/items/01699284626c48b22e20

# NPOの事例
## TOPPERSプロジェクト
オープンソースの団体である。
ITRON仕様とAUTOSAR, OSEK\VDX OS仕様のOSを中心とする。

数年理事を務めた。

主にコンテストの企画を担当した。

## SESSAMEプロジェクト
組み込みソフトウェアの教育団体である。

WG6の会合を企画したほか、WG2の企画にも参加してきた。

現在は、その一つの成果を、愛知県立名古屋港等専門校で講義している。

職業訓練(IT)
https://qiita.com/kaizen_nagoya/items/95368b63fa21d64271ec

## 共通企画 SWEST
SWEST自体はNPOではない。上記TOPPERSプロジェクトと、SESSAMEプロ弱との二つの団体の共通する企画として実行している。
10年ちょっとの間、実行委員を務めた。

最終参加時に、Silver賞をいただいた。

ちょけねこ　たんじょうびのおくりもの　はいふさきと　かつどう
https://qiita.com/kaizen_nagoya/items/0dced798518501d8ffba

ちょけねこ たんじょうびのおくりもの 安全(96) 図(34)
https://qiita.com/kaizen_nagoya/items/fc9675686c229f7a155e

# 非NPO団体
## 公共団体などの共同事業
### JAXA/IPA WOCS　プログラム委員長
JAXAという国の組織と、IPAという経済産業省の外郭団体の共済事業である。
JAXAの代表の方と、IEEE Softwareのエディタだった方の兄弟弟子という関係にあった。
彼も私も、IEEEでの最初の発表が、その方の参加された会合だった。
TOPPERS, SESSAME二つのNPO団体をはじめ、多くの団体に協力を仰いだ。

### 組み込み中核人材プロジェクト Project manager
構成員は第三セクタ、官庁、大学（国立）、民間企業。
アドバイザなどとしてTOPPERS, SESSAMEの２つのNPO団体をはじめ、多くの団体に協力を仰いだ。
経済産業省の補助事業。
ある大学が断ったため、岐阜大学と名古屋工業大学に協力を要請した。
名古屋工業大学の教授を開発委員長としてお願いできれば、プロジェクトマネージャとしてとりまとめて欲しいとある筋から依頼があった。

### VZ倶楽部
本の表題である。法人格をもった団体が存在しているわけではない。

誰でもわかるVZエディタ。0から始める。
https://qiita.com/kaizen_nagoya/items/afe6c4cdccbfdd94baab

祝：ソースコード公開：VZエディタ移植の方法と成果。註釈 coding(123)
https://qiita.com/kaizen_nagoya/items/5551be98dcbed8f41949

祝VZエディタソースコード公開
https://qiita.com/kaizen_nagoya/items/baad23cf4a041ce845a9
githuの謝辞に、人名と所属組織名が（）書きでかいてある。最後の５人は、なぜか組織名が書かれていない。自分に都合よk卯考えれば、該当する組織に所属していることによって貢献した方と、所属する組織と関係なく協力した方に分かれるのかもしれない。

# 課題
## 人材
中心人物が引退されたり、亡くなられたりすると、活動が低下する可能性がある。
個人が起業した企業とさほど違いはないかも。
NPOであるから、不利益があるとか、不具合があるとかという事象はさほど気が付かない。
官公庁、株式会社と比べると、予算基盤の脆弱性が気になるかもしれない。
NPO法人固有の課題ではない。

## 技術
技術に関するNPOを例示している。
NPOである理由は、特定の企業の目的に沿った技術ではなく、社会に貢献することを目的とする技術発信であることを強調したかったのかもしれない。
二次元配列の入力

今日は配列メニューの２次元配列の練習問題を解いたのでメモ！

<br>

## 🔍 問題概要

問題：
1行目に列数Mが与えられ、次の5行M列の整数が入力される。

やること：
各行をスペース区切りでそのまま出力。

<br>

入力例:
```
4
1 2 3 4
0 0 0 0
8 1 3 8
1 10 100 99
15 68 48 15
```

出力例:
```
1 2 3 4
0 0 0 0
8 1 3 8
1 10 100 99
15 68 48 15
```
<br>

https://paiza.jp/works/mondai/array_primer/array_primer__2dmatrix_input_step2


## <br><br>💣 NGコード例

```js
const rl = require('readline').createInterface({input:process.stdin});
const lines = [];

rl.on('line',(input)=>{
    lines.push(input);
});


rl.on('close',()=>{
    const matrix = lines.slice(1).map(line => line.split(' '));
    matrix.forEach(a => console.log(a));
});
```
<br>

見た目はOKそう。でも出力はこうなる：
```
[ '1', '2', '3', '4' ]
[ '0', '0', '0', '0' ]
[ '8', '1', '3', '8' ]
[ '1', '10', '100', '99' ]
[ '15', '68', '48', '15' ]
```
このコードは、配列 をそのまま `console.log()` に渡している。
すると、配列を [要素, 要素, …] のように表示されてしまう。

<br><br>

## ✅ OKコード
```js
const rl = require('readline').createInterface({input:process.stdin});
const lines = [];

rl.on('line',(input)=>{
    lines.push(input);
});

rl.on('close',()=>{
    const matrix = lines.slice(1).map(line => line.split(' '));
    
    const result = [];
    
    for(let i = 0; i < matrix.length; i++){
        const row = [];
        for(let j = 0; j < matrix[i].length; j++){
            row.push(matrix[i][j]);
        }
        result.push(row.join(' '));
    }
    
    result.forEach(row => console.log(row));
    
});
```
- 2行目以降をスペースで分割して、2次元配列として取得。
- 各行を1文字ずつループして新しい配列 `row` に再構築。
- 最後に `row.join(' ')`  でスペース区切りの文字列に変換して `result` に追加。
- 配列としてではなく、スペースで連結した文字列を出力するので、期待通りの出力になる。

## <Br>✅改善案
```js
const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];

rl.on('line', input => lines.push(input));

rl.on('close', () => {

    // 2行目以降を2次元配列として格納
    const matrix = lines.slice(1).map(line => line.split(' '));


    // ✅各行をスペース区切りで出力
    matrix.forEach(row => console.log(row.join(' ')));
});
```

<br><br>

## 📘メモ＆まとめ
- `console.log([1, 2, 3])` → `[1,2,3]` になる（配列のまま表示）

- `console.log([1,2,3].join(' '))` → `'1 2 3'` になる（文字列として表示）

- 実行結果が「一見正しそう」でも、形式が違うと評価NGになることもある！

<br><br><br>[僕の失敗談(´;ω;｀)と解決法🐈](https://paizabeginner.wordpress.com/2025/05/18/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc%ef%bc%9a%e4%ba%8c%e6%ac%a1%e5%85%83%e9%85%8d%e5%88%97%e3%81%ae%e5%85%a5%e5%8a%9b/)
AWS Transfer Familyメモ

**AWS Transfer Family** は、**SFTP、FTPS、FTP プロトコルを使って、Amazon S3 または Amazon EFS に安全にファイル転送できるマネージドサービス**です。

オンプレミスのファイル転送ワークロードを AWS に移行する際によく使われます。従来の SFTP や FTP サーバーと同じように使えますが、インフラ管理が不要で、スケーラブルかつセキュアな設計が特徴です。

---

## ✅ 主な特徴

| 機能          | 説明                                                |
| ----------- | ------------------------------------------------- |
| 対応プロトコル     | SFTP、FTPS、FTP（いずれかまたは複数）                          |
| バックエンドストレージ | Amazon S3 または Amazon EFS を選択可能                    |
| 認証方法        | IAM、カスタム ID プロバイダ（Lambda）、Service Managed（ユーザー管理） |
| 高可用性        | マネージドサービスで自動的に冗長化・可用性確保                           |
| モニタリング      | CloudWatch ログ、メトリクス、SNS 通知などに対応                   |
| VPC接続       | パブリック or VPCエンドポイント経由での接続が選べる                     |

---

## 🔁 よくあるユースケース

| ユースケース                | 説明                      |
| --------------------- | ----------------------- |
| 既存の SFTP サーバーのクラウド移行  | オンプレから AWS S3 に置き換え     |
| パートナー企業とのデータ交換        | 外部とのファイル授受にセキュアな転送手段を提供 |
| バッチファイル取り込み基盤         | データレイクへのファイル取り込み用に利用    |
| 医療・金融などの厳しいセキュリティ要件対応 | 転送経路と保管先の両方で暗号化対応       |

---

## 🔐 認証方法の違い

| 認証方式            | 概要                          | 向いているケース              |
| --------------- | --------------------------- | --------------------- |
| Service Managed | AWS上でユーザー名・公開鍵を管理           | 少人数・簡易な構成             |
| Custom（Lambda）  | Lambdaで独自ユーザ管理（例：AD連携、DB連携） | 認証基盤を自前で持つ場合          |
| IAM             | IAMユーザーを使ってアクセス管理           | AWS IAMベースの認可を統一したい場合 |

---

## 🧩 構成図のイメージ

```text
 [Partner User]
       |
    SFTP/FTP
       |
[AWS Transfer Family Endpoint]
       |
       +---[S3 Bucket]   ← ファイル保存
       |
       +---[Lambda]（オプション）← 認証処理
```

---

## 📋 主な設定項目

| 項目            | 内容                             |
| ------------- | ------------------------------ |
| サーバータイプ       | SFTP / FTPS / FTP を選択          |
| エンドポイントタイプ    | パブリック / VPC 内                  |
| ドメイン          | S3 または EFS を選択                 |
| ID プロバイダ      | Service Managed / Lambda / IAM |
| CloudWatch ログ | 転送操作をログとして記録可                  |

---

## 💰 コスト（おおまか）

* **基本料金**：Transfer Server あたり時間課金（例：\$0.30/時）
* **データ転送量**：送信・受信バイト単位で課金（通常の S3 転送コストと同様）
* **ストレージ料金**：S3 または EFS に従う

---

## 📌 補足情報

* FTPS/FTP の使用には **VPCエンドポイントが必須**
* セッション中のファイル転送エラーなどは **CloudWatch Logs** で確認可能
* ファイルアップロード後の処理（例：検証や通知）に **EventBridge + Lambda** の連携が有効

---

## ✅ まとめ

| 特徴                        | 有無 |
| ------------------------- | -- |
| SFTP/FTPをマネージドで提供         | ✅  |
| S3/EFS バックエンド対応           | ✅  |
| LDAP/AD連携も可能（カスタムIDプロバイダ） | ✅  |
| オンプレ連携にも適用しやすい            | ✅  |
| コード不要で開始可能                | ✅  |
Amazon AppFlow

**Amazon AppFlow** は、**SaaS アプリケーション（Salesforce、Slack、Google Analytics など）と AWS サービス（S3、Redshift、Snowflake など）との間で、安全かつスケーラブルにデータを移動・同期するマネージドサービス** です。

---

## ✅ 概要

| 特徴            | 説明                               |
| ------------- | -------------------------------- |
| データの双方向連携     | SaaS ↔ AWS 間のデータを双方向で移動可能        |
| ノーコード / ローコード | GUI ベースで設定、コード不要                 |
| トリガー可能        | 手動、スケジュール、イベント（例:レコード追加）で実行可能    |
| セキュア          | データは暗号化され、VPC エンドポイントや KMS と統合可能 |

---

## 🔁 利用ユースケース

| ユースケース                                 | 説明                         |
| -------------------------------------- | -------------------------- |
| Salesforce から S3 へ顧客データ同期              | 定期バッチや変更トリガーでデータを S3 に書き出し |
| Google Analytics のレポートを Redshift に取り込み | BI 分析用に ETL 処理             |
| Zendesk チケットを S3 に集約                   | ログ管理・可視化・データ分析用途           |
| Marketo → Snowflake                    | マーケティングキャンペーンデータの分析基盤取り込み  |

---

## 🔌 接続できる主なサービス（2024年時点）

### SaaS アプリケーション例：

* Salesforce
* Google Analytics
* ServiceNow
* Slack
* Zendesk
* SAP
* Marketo
* Microsoft Dynamics 365

### AWS サービス例：

* Amazon S3
* Amazon Redshift
* Amazon EventBridge
* Snowflake
* Amazon Lookout for Metrics

---

## 🧱 データフローの構成要素

| コンポーネント       | 説明                     |
| ------------- | ---------------------- |
| ソース           | データの取得元（例: Salesforce） |
| デスティネーション     | データの送信先（例: S3）         |
| マッピング         | フィールド間の変換定義            |
| フィルター         | 条件を指定してレコードを抽出         |
| 変換（Transform） | 入力データの整形・加工（例: 大文字変換）  |
| 実行トリガー        | スケジュール、手動、イベント         |

---

## 🧩 他のサービスとの連携例

* **Amazon EventBridge**：AppFlow フロー実行イベントをトリガーにして Lambda を実行
* **AWS Glue DataBrew**：取り込んだデータのノーコードクレンジング
* **Amazon Athena**：S3 に保存されたデータを SQL で分析
* **Amazon QuickSight**：可視化・BI ダッシュボード作成

---

## 🎯 特徴まとめ

| 特徴               | 有無             |
| ---------------- | -------------- |
| GUI で簡単構築        | ✅              |
| リアルタイム連携（イベント駆動） | ✅              |
| データ変換 / クレンジング機能 | 一部あり（変換機能は限定的） |
| コード不要            | ✅              |
| 柔軟なフィルター / マッピング | ✅              |
| セキュリティ / 暗号化対応   | ✅（KMS, VPC対応）  |

---

## ⚠️ 注意点

| 注意点              | 内容                              |
| ---------------- | ------------------------------- |
| 大量データ処理にはコスト注意   | スケーラビリティはあるが、回数・容量課金            |
| 複雑な ETL は困難      | Glue や Lambda との併用が必要な場合あり      |
| SaaS 側の API 制限あり | 例えば Salesforce 側の API 呼び出し制限に注意 |

---

## 📘 例：Salesforce → S3 へのデータ同期

1. AppFlow で新しいフローを作成
2. ソース：Salesforce に接続（OAuth認証）
3. デスティネーション：S3 バケット指定
4. データマッピング（必要に応じて）
5. スケジュール：毎日0時に実行
6. フローを保存・有効化
Vol.0：Linuxを極めたいと思ったら、なぜかJavaが楽しくなっていた話

# Vol.0｜Linuxを極めたいと思ったら、なぜかJavaが楽しくなっていた話

---

## キャリアチェンジの動機

**私はもともとインフラエンジニアとして、サーバーやネットワークの運用保守を長年担当してきました。**  
ある時、「もっと技術力を高めたい」と思い、真剣に学び始めたのが **Linux** です。

---

## Linuxを極めたくて、カーネルの世界へ

きっかけは、**OpenStack の運用経験** でした。  
OpenStack を構成する技術（Namespace、KVM、Open vSwitchなど）に触れる中で、

> 「IaaSって、結局Linuxの仕組みの上に成り立ってるんだな」

と気づき、  
**「じゃあLinuxを極めよう」** と考えるようになりました。

さらにその中で、

> 「Linuxの仕組みを本当に理解するには、カーネルのソースコードを読めるようにならなきゃ…」

という考えに至ります。

---

## カーネルの壁：C言語が読めない…

Linuxカーネルのソースは C言語 で書かれています。  
いざ読もうと試みたものの、

> 「全然読めない……そもそもC言語の構文すら危うい」

という現実に直面。

---

## レベルを下げる決断。そしてスクリプト言語へ

そこから私はこう考えました。

> 「いきなりC言語は無理でも、もっと簡単な言語から始めればいいのでは？」

まずは学習コストの低いスクリプト言語から始めて、  
**プログラミングの基礎体力をつけよう** と決意します。

---

## インフラ自動化の世界とPython

同時期に、構成管理ツール（Ansibleなど）やクラウド環境の自動化スクリプトを学んでいる中で、  
**Python** によく出会いました。

- 「あれ？インフラ自動化って、Pythonのライブラリでいろいろできるじゃん」
- 「インフラエンジニアだって、コード読めないとダメな時代かも…」

こうして、  
**「インフラ屋こそプログラミングが必要」** という認識が強まりました。

---

## LAMP環境構築とPHPとの出会い

> 「どうせやるなら、Linux上にLAMP環境を構築してWebアプリも勉強しちゃおう」

という流れで、**PHP による Web プログラミング** に着手します。

簡単なブログやECサイトを作ってみるものの――  
ほとんどが「写経」で終わり、なかなか自信には繋がりませんでした。

---

## ある人のひと言で、Javaへシフト

悩んでいた時、ある知人からこう言われました。

> 「オブジェクト指向やらんと、本当の意味でプログラミング分かったとは言えないよ」

PHPでコードは書けるようになってきたけど、  
「設計」や「構造化された開発」には不安がある…  
そう感じていた自分には、その言葉がズシンと響きました。

---

## そして現在：JavaとStruts2で開発中

- 「じゃあ、オブジェクト指向言語を学ぼう」
- 「せっかくだからWebアプリを作るのにフレームワークも触ってみよう」

こうしてたどり着いたのが、**Java × Struts2** という選択でした。

最初は不安だらけでしたが、今では  
画面遷移・セッション管理・MVC構成など、やればやるほど楽しいと感じています。

Linuxを極めたいと思って始めた旅は、  
いつしか **「アプリ開発って楽しい！」** という実感に変わっていました。

---

## まとめ：回り道だらけ。でも、全部が今につながっている

- Linuxカーネルを理解したくてC言語を目指した  
- プログラミングの入口としてスクリプト言語を学んだ  
- インフラ自動化でPythonにも触れた  
- でも結局、Javaでアプリ作るのが楽しくなっていた  

そういう回り道の末、今では **Struts2で掲示板アプリを開発中** です。

> 遠回りに見えるけど、実は全部つながっていた――

そんな経験を、これからシリーズで記事にしていきます。

---

## Vol.1 へ続く🚀
[Vol.1： プログラミングとの再会 – 「画面ありき」で変わった学び方](https://qiita.com/juehara-crypto/items/2fcc53d765dcc25a4fa3)
【初心者】Flutterで家計簿アプリをリリースした話

モバイルアプリ開発未経験でしたが、Flutterで家計簿アプリを開発し、リリースしました。
リリースした家計簿アプリはこちら（iOS）

https://apps.apple.com/jp/app/id6742489643

### コンセプト
コンセプトは「サブカテゴリー」です。
具体的には、「食費」の中で「スーパー」と「外食」で分けたい！さらにそれぞれグラフにもしたい！と思ったのがきっかけです。

<p>
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4090834/d5d526ea-58e1-460a-8187-92d402be2032.png"width=32%>
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4090834/4a87c2fe-45d1-4138-89a7-3b619a65c2b6.png"width=32%>
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4090834/043cbaf9-02c0-45d4-b199-baab9fb80b51.png"width=32%>
</p>




# なぜアプリを開発しようと思ったのか
仕事で使う技術がレガシーで、このままではまずいと思ったためです。元々アプリ開発に興味があり、挑戦しました。

### なぜ家計簿アプリ？
「家計簿」と検索すると数多の家計簿アプリがヒットします。以前は、私もその中のアプリの一つを利用していました。
UIも見やすくて、基本的な機能も揃っている...その中で、**サブカテゴリー**を中心機能としたシンプルかつ使いやすい家計簿アプリが欲しいと思ったのがきっかけです。

### なぜFlutter？
理由のひとつは、マルチプラットフォームであることです。幅広いプラットフォームへ応用ができることは、今後ますます強みとなると思っています。
現時点ではiOSのみのリリースですが、今後androidでのリリースも予定しています。

マルチプラットフォームとしてはReact Nativeも選択肢としてはありますが、以下の2点から今回はFluuterを選択しました。
- ウィジェットによるUIのカスタマイズ性の高さ（UIにも力を入れたい）
- 豊富なマニュアルとドキュメント（初心者だったので）

# アプリ概要
- カテゴリー・サブカテゴリーの登録、訂正、削除、移行
- 収入と支出の登録、訂正、削除
- カレンダーでの収支の詳細表示
- 円グラフによる内訳表示
- 棒グラフによる推移表示
- 収支の文字列検索とリスト表示
- 定期収入・支出の登録、訂正、削除
- テーマカラーの変更
- 広告の削除（非消耗型アプリ内課金）
- 問い合わせ

# 開発概要
### 期間
2024年4月〜2025年3月

### 開発言語
- フロントエンド：Dart(Flutter)
- バックエンド（問い合わせ機能）：TypeScript(Node.js)
### 開発環境
- Visual Studio Code
- Xcode

### 利用した主なFlutterパッケージ
- riverpod
- flutter_hooks
- go_router
- sqflite

### その他
- FireBase (Functions, Remote Config, Analytics)
- Google AdMob
- RevenueCat
- GitHub

# 感想・反省点
とにかく勉強しながら開発しようとしたため、途中でいくつか機能を追加したほうが良いと判断したのでスケジュールが少し伸びてしまいました。初心者なので、もう少しシンプルなアプリを短期間に作るといったステップを踏んでも良かったと思っています。

最終的には自分自身の納得のいくアプリを作ることができました。まだ実装したい機能もあるので定期的にアップデートしていきながら、次に開発するアプリを考えていきたいと思っています。

特に大変だったのは、定期収支に関するロジックと大量データの扱いによるパフォーマンスの考慮です。一度大量の収支を繰り返し登録すると、画面がカクカクになってしまいました。StatefulWidgetを極力減らしconstにすることと、データ追加は1つのSQL文で一括追加できるように工夫することでパフォーマンスを向上できました。
最初に要件定義をしっかりすることの重要性を実感しました。

# 今後について
アップデートで追加したい機能は次の通り。
- 収入・支出の登録画面で、定型内容をワンタップで設定するボタンの実装
- バックアップ機能
- Google Play Storeでのリリース

今まで自身の技術に自信がなく、アウトプットできていませんでしたが、これからは自信がないからこそ積極的にアウトプットして技術を向上していきたいと思います！
ABC406回答メモ

# 0.はじめに
　そろそろ700も切りそうな今日この頃。
　ABは難なく解けましたが、Cから難度が跳ね上がりブレーキ。
　色々試すもうまくいかず、久々の2問のみ正解。
　他の方も解けていなかったのか、レートは-8の703と
　微減にとどまりました。
　いよいよ７００台も危なくなってきました。

# 1. A - Not Acceptable
　時分判定の問題。
　まず、AとCの大小でYesとNoの出力を試み
　同じだったらBとDで最終決戦といったロジックでACでした。　

　https://atcoder.jp/contests/abc406/submissions/65857685


# 2.B - Product Calculator
　桁数が大きくなりそうな問題。
　まぁPythonなので気にせず普通に計算してACでした。

　https://atcoder.jp/contests/abc406/submissions/65863897


# 3.C - ～
　得点350点にしても、Cにしては難しいなーと思いつつチャレンジ。
　最初に、P[i-1]<P[[i]>P[[i+1]となるiをリストOにとP[i-1]>P[[i]<P[[i+1]となるiをリストXに
　それぞれ保存し、P[i]<P[[i+1]の部分を起点に次のOとXが1個ずつ現れるか・・・
　とか言った感じで実装しようとするも、場合分けが複雑になりすぎ時間切れでした。

　コンテスト後解説をみて、そんな方法でいけるの～？と疑いましたが、真面目に読むと
　なるほど。と目からうろこでした。

　https://atcoder.jp/contests/abc406/submissions/65949452

以上
データ分析実務スキル検定（CBAS）PM級に1.5週間で合格した話

# 概要
2025年5月18日、データ分析実務スキル検定 PM級に89/97で合格しました。
5月8日から勉強を始めて1.5週間で受かったので、最短距離で資格を取りたい人におすすめなことを書きます。

# About me
- データ分析の実務をしていますが、主にTableau・DB中心でありSQLやKPI周りは慣れたものですが、機械学習やプログラミングはかじったレベルでした
- 直前に統計検定2級を取っています
- 家庭もあるので基本的に勉強は夜中の2時間〜3時間・スキマ時間でした

# 私の勉強方法
### 1.データ分析実務スキル検定の教科書を読む
SQLや統計分野など知っていることは流し読みで。3日程度かかりました。

### 2.Udemyの動画を見る
Udemyの【演習形式で学ぶ】「データ分析実務スキル検定 PM級」合格への道（データ分析スキル証明資格で高得点を目指す講座）を3日で見ました。
得意なSQLは総合問題のみ、統計学は1.5倍速で見たことないワードのタイトルのみ、R/Python/機械学習は一通り見ました。

### 3.模試と毎日の復習
教科書の末尾にある模試を2回解きました。Excelの操作は慣れが必要だったり、問題文を注意深く見ないと足元をすくわれることや、時間が足りなくなりやすい点に要注意です。
１回目は74%・時間足りず、２回目は84%・時間通りという塩梅です。
毎日の復習は２の確認問題をメモして印刷・答えをフラッシュカード式で見えるようにし、それを毎日振り返りました。

# さいごに
データ分析実務スキル検定は割とGoogleDataAnalyticsで学んだような範囲が近く、分析の全体感を概ね把握できるので入門者や、データ分析者と会話する方にオススメです。
個人的には機械学習やR言語などの実務上まだ縁がなくてあまり触手が伸びなかった範囲や、統計検定２級と実務の間の橋渡しの知識が得られた点を良かったと思います。
自作キーボードへの挑戦(Keyball44編完結編)

# 自作キーボード Keyball44 完成報告とトラブル記録

とうとう自作キーボードが完成しました！  
今回はそのご報告もかねて、Keyball44のビルド過程で起きたトラブルを振り返りつつ、完成品の様子を共有します。

---

## やらかしその①：TRRSケーブルとOLEDモジュールピンを裏表逆に装着

我ながら信じられない痛恨のミスです。  
YouTubeのKeyball44の動画を見ながら作業していたのが原因かもしれません。

ビルドガイドには **「表面に付ける」** と明記されていたにも関わらず、裏側に付けてしまいました。

- OLEDモジュールピンを外す際、ピンが曲がってしまったため買い直し
- TRRSケーブルの端子も折れてしまい、こちらも買い直し

とはいえ、どちらも**300円以内**で収まったのは不幸中の幸い。

もしこれがProMicroだったら……心が折れていたかもしれません。  
特に12ピンのコンスルのはんだ付けをした後のリカバリーは非常に困難。

**教訓**：ピン類のはんだ付け時は「表裏」をよく確認し、細心の注意を。

---

## やらかしその②：LEDの16番が光らない＆ランド剥がれ

LEDの16番目が光らなかったため、はんだを剥がそうとしたところ、**ランドごと剥がしてしまう悲劇**が発生。

テスターで確認しても反応なし。

泣く泣く [公式Discussion](https://github.com/Yowkees/keyball/discussions/793) に質問したところ、親切にご回答いただきました。

**ジャンパー線で補強することで無事リカバリーに成功。**  
白銀ラボ様、本当にありがとうございます！

---

## 苦戦したポイント（やらかし未満）

### その①：一部のキースイッチが反応しない

- 一見、はんだが付いているように見えても**側面が接触していない**場合がある
- 再度はんだを溶かして、きちんと接続されていれば直ることが多い
- それでもダメな場合は、**対応するダイオードも要確認**

私はキースイッチの再はんだだけで回復しました。

---

### その②：LEDが光らない

テストファームウェアを書き込んだ直後、**LEDが1つしか光らず、笑ってしまったほど**。

Keyball44はLEDが**直列接続**されているため、

- 例えば「LED1番しか点灯しない」場合、**LED1番か2番に問題がある可能性**
- はんだブリッジが発生していないか、ルーペで拡大して確認すると良い

---

### その③：リセットボタン無反応でFW書き込み不可

これは**一番原因特定が難しかったトラブル**。

最初はProMicroの不具合かと思いましたが、単体でUSB認識していたため、問題なさそうと判断。  
**全体のはんだ付けを見直すことに。**

結局、TRRS・リセットボタン周辺、LED・キースイッチのはんだをやり直したら、  
**あるタイミングで書き込みできるように！**

ひょっとするとLEDのはんだ不良が何かしらリセット妨害要因だったのかもしれません。  
前回投稿した通り、「はんだブリッジ箇所を修正すると書き込みできるようになる」ことも。

---

## 完成写真：LEDすべて点灯！キースイッチ全反応！

そんな苦難を乗り越え、ついにKeyball44が **完璧に動作する状態** に！
完成品の画像がこちら![unnamed.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530719/e64282ea-b27a-4627-bdcd-f2bb608c7119.jpeg)

---

## 改善点

### 改善点その①：親指キーキャップの違和感

現在、親指用にロープロファイルの黄色いキーキャップを使用していますが、  
**ちょっと合っていない感じ**がするので、良いものを探し中です。

---

### 改善点その②：カバー未装着

完成時点では**基板むき出し**状態。  
カバーを付けて保護したいと考えています。

- BoothでKeyball44用のカバーを販売している方もいたので、そこから購入するか
- 自分で**3Dプリンターで作成**するか検討中

---

以上、自作キーボードビルドの備忘録兼、誰かの参考になれば幸いです。
【Minecraft 1.21.4】CutAllSMP 木こりMOD 導入ガイド

## 事前準備: Javaのインストール

### Java確認方法
1. `Windowsキー + R` を押す
2. `cmd` と入力してEnterを押す
3. `java -version` と入力してEnter
4. バージョン情報が表示されればJavaは既にインストール済み

### Javaがない場合のインストール手順
1. [Oracle Java公式サイト](https://java.com/ja/download/)にアクセス
2. 「Javaの無料ダウンロード」をクリック
3. ダウンロードしたインストーラーを実行
4. 画面の指示に従ってインストール完了

💡 **Minecraft 1.21.4の場合、Java 21以上を推奨します**

## 必要なもの

- **Java版Minecraft 1.21.4**
- **Java 21以上**
- **CutAllSMP v2.5.3** (NeoForge版)

## ステップ1: NeoForgeのインストール

### 1-1. NeoForgeをダウンロード
1. [NeoForge公式サイト](https://neoforged.net/)にアクセス
2. 「Latest NeoForge Installer」をクリックしてダウンロード

### 1-2. NeoForgeをインストール
1. ダウンロードしたjarファイルを右クリック
2. 「プログラムから開く」→「Java(TM) Platform SE binary」を選択
   - **もしダブルクリックで開かない場合**：
     - コマンドプロンプトを開く
     - `java -jar ダウンロードしたファイル名.jar` を実行
3. インストーラーが開いたら「Install client」にチェックが入っていることを確認
4. 「OK」をクリックしてインストール完了

## ステップ2: CutAllSMPの導入

### 2-1. modsフォルダを開く
1. Minecraftランチャーで「NeoForge」プロファイルを一度起動
2. Minecraftを閉じる
3. `Windowsキー + R` を押す
4. `%appdata%` と入力してOKをクリック
5. `.minecraft` → `mods` フォルダを開く

### 2-2. MODファイルを配置
1. `mod_CutAllSMP_v2.5.3.jar` を `mods` フォルダにそのまま入れる
2. Minecraftを再起動

## 使い方

### 基本操作
- **斧を持って木を切る** → 木全体が一気に破壊される
- **Cキー**でMOD機能のON/OFF切り替え
- **Shift+左クリック**で通常通り1ブロックずつ破壊

### 対応するツール
- 木の斧、石の斧、鉄の斧、ダイヤモンドの斧、金の斧
- ネザライトの斧（1.16以降）

## 設定変更（オプション）

設定を変更したい場合は以下の手順：

1. `.minecraft` → `config` → `cutallsmp-common.toml` をメモ帳で開く
2. 主な設定項目：
   - `DestroyUnder = false` → `true`（下の木も破壊）
   - `DropGather = true`（アイテムをまとめてドロップ）
   - `leavesIds = ""` → `"leaves, leaves2"`（葉っぱも破壊）

## トラブルシューティング

### MODが反映されない場合
- Minecraftランチャーで「NeoForge」プロファイルを選択しているか確認
- modsフォルダに正しくファイルが配置されているか確認
- Minecraftを完全に再起動

### jarファイルが開かない場合
1. **Jarfix**をダウンロードして実行
2. または右クリック→「プログラムから開く」→「Java(TM) Platform SE binary」

## 注意事項

- **1.21.4はNeoForge版のみ対応**（Forge版は使用不可）
- **他のMODとの競合**に注意
- **バックアップ**を取ってから導入することを推奨

---

## まとめ

このMODを導入すれば木材集めが格段に楽になります！特に大きな建築プロジェクトを進める際に重宝するでしょう。設定も柔軟で、自分のプレイスタイルに合わせてカスタマイズできるのが魅力です。

木こりライフを楽しんでください！🪓🌲
トリボナッチ・ポリリズム

# トリボナッチ・ポリリズム
トリボナッチ数列に基づき、ポリリズムのテンポで再生。

https://youtu.be/get6nTeQQY8

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/a3a37281-f356-4a21-8abb-b79e20999bbe.png)
このように解釈し、abcにそれぞれ音を割り当て、再生する。

# フィボナッチ数列
```math
F_0 = 1
```

```math
F_n = F_{n-1} + F_{n-2}
```
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|1|1|2|3|5|8|13|21|34|55|89|144|

# トリボナッチ数列
```math
T_0 = 1
```

```math
T_n = T_{n-1} + T_{n-2} + T_{n-3}
```
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|0|0|1|1|2|4|7|13|24|44|81|149|
|1|1|1|3|5|9|17|31|57|105|193|355|

０開始と、１開始がある。

https://ja.wikipedia.org/wiki/フィボナッチ数

# プログラム
Processingとminimライブラリ

```java
import ddf.minim.*;
import ddf.minim.signals.*;

Minim minim;
AudioOutput out;

SineWave waveA;
SineWave waveB;

String[] T = new String[20];
String patternA, patternB;

int idxA = 0;
int idxB = 0;

int intervalA = 300;  // ms
int intervalB = 500;  // ms

int lastTimeA = 0;
int lastTimeB = 0;

boolean playingA = false;
boolean playingB = false;

int noteDurationA = 200;  // ms
int noteDurationB = 300;  // ms

char currentCharA = ' ';
char currentCharB = ' ';

void setup() {
  size(600, 300);
  minim = new Minim(this);
  out = minim.getLineOut();

  generateTribonacci(13);  // ★ T[12] で約1500文字 → 1分以上の演奏に対応
  patternA = T[12];        // 長めのトラック
  patternB = T[11];

  waveA = new SineWave(440, 0.0, out.sampleRate());
  waveB = new SineWave(660, 0.0, out.sampleRate());

  out.addSignal(waveA);
  out.addSignal(waveB);

  textAlign(CENTER, CENTER);
  textSize(80);
  frameRate(60);
}

void draw() {
  background(255);

  int now = millis();

  // トラックA処理
  if (idxA < patternA.length() && now - lastTimeA >= intervalA) {
    currentCharA = patternA.charAt(idxA);
    waveA.setFreq(charToFreqA(currentCharA));
    waveA.setAmp(0.5);
    lastTimeA = now;
    playingA = true;
    idxA++;
  }
  if (playingA && now - lastTimeA >= noteDurationA) {
    waveA.setAmp(0.0);
    playingA = false;
  }

  // トラックB処理
  if (idxB < patternB.length() && now - lastTimeB >= intervalB) {
    currentCharB = patternB.charAt(idxB);
    waveB.setFreq(charToFreqB(currentCharB));
    waveB.setAmp(0.5);
    lastTimeB = now;
    playingB = true;
    idxB++;
  }
  if (playingB && now - lastTimeB >= noteDurationB) {
    waveB.setAmp(0.0);
    playingB = false;
  }

  // 画面表示
  fill(0);
  text("A: " + currentCharA, width * 0.3, height / 2);
  text("B: " + currentCharB, width * 0.7, height / 2);
}

float charToFreqA(char ch) {
  if (ch == 'a') return 110;
  if (ch == 'b') return 220;
  if (ch == 'c') return 440;
  return 110;
}

float charToFreqB(char ch) {
  if (ch == 'a') return 220;
  if (ch == 'b') return 440;
  if (ch == 'c') return 880;
  return 220;
}

void generateTribonacci(int n) {
  T[0] = "a";
  T[1] = "b";
  T[2] = "c";
  for (int i = 3; i <= n; i++) {
    T[i] = T[i - 1] + T[i - 2] + T[i - 3];
  }
}
```
Route53を使用したクロスアカウントでのサブドメイン委譲

# はじめに
AWS Route 53を使用して、異なるAWSアカウント間でサブドメインの委譲を行う必要があったため、その手順をまとめました。この記事では、親ドメインを管理するアカウントから、サブドメインを管理する別のアカウントにDNS管理を委譲する方法について説明します。

# 前提
- 親ドメイン（例：`example.com`）を管理するAWSアカウント A
- サブドメイン（例：`sub.example.com`）を管理するAWSアカウント B
- 両方のアカウントでRoute 53へのアクセス権限

# サブドメイン委譲の概要

DNS委譲により、組織のDNS管理を分散化し、各チームが独立してサブドメインを管理できるようになります。

# 手順1: サブドメインアカウントでのホストゾーン作成

サブドメインを管理するアカウント（アカウント B）で作業を行います。

## 1-1. Route 53コンソールにアクセス

AWSマネジメントコンソールにログインし、Route 53サービスを開きます。

## 1-2. ホストゾーンの作成

1. 左側メニューから「ホストゾーン」を選択
2. 「ホストゾーンの作成」ボタンをクリック
3. ドメイン名: `sub.example.com` を入力
4. タイプ: パブリックホストゾーン を選択
5. 「ホストゾーンの作成」をクリック

## 1-3. ネームサーバーの確認と記録

ホストゾーンの作成が完了したら、重要な情報を記録します：

1. 作成されたホストゾーンを選択
2. NSレコードを確認し、4つのネームサーバーをメモ

```
例：
ns-1234.awsdns-56.org
ns-789.awsdns-01.net
ns-012.awsdns-34.com
ns-567.awsdns-89.co.uk
```

![ns-records.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/d69c31ae-38ea-45b4-b8fe-baa2169b621d.png)

これらのネームサーバーは、次のステップで親ドメインアカウントで設定する際に使用します。

# 手順2: 親ドメインアカウントでのNSレコード作成

親ドメインを管理するアカウント（アカウント A）で作業を行います。

## 2-1. 親ドメインのホストゾーンを開く

Route 53コンソールで`example.com`のホストゾーンを選択します。

## 2-2. NSレコードの作成

親ドメインにサブドメインのNSレコードを追加することで、サブドメインのDNS管理を委譲します：

1. 「レコードの作成」をクリック
2. レコード名: `sub`（サブドメイン名を入力）
3. レコードタイプ: `NS - ホストゾーンのネームサーバー`
4. 値: 手順1で取得した4つのネームサーバーを入力（各行に1つずつ）
5. TTL: `300`（推奨値）
6. 「レコードの作成」をクリック

![ns-record-create.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/a2fbb166-7523-41d6-b2ce-aaf27c32c2fc.png)

# 手順3: DNS伝播の確認

## 3-1. DNS伝播の待機

DNSの伝播には通常48時間かかりますが、多くの場合は数分から数時間で反映されます。

## 3-2. 委譲の確認方法

`dig`コマンドを使用して、委譲が成功したか確認できます：

```bash
dig sub.example.com NS
```

期待される出力は、手順1で取得したネームサーバーが表示されることです：

```
;; ANSWER SECTION:
sub.example.com. 300 IN NS ns-1234.awsdns-56.org.
sub.example.com. 300 IN NS ns-789.awsdns-01.net.
sub.example.com. 300 IN NS ns-012.awsdns-34.com.
sub.example.com. 300 IN NS ns-567.awsdns-89.co.uk.
```

# まとめ

AWS Route 53を使用したクロスアカウントでのサブドメイン委譲で、同一ドメイン内でのDNS管理を分散化し、各チームが独立してサブドメインを管理できるようになります。


# 参考文献

- [AWS Route 53 Documentation](https://docs.aws.amazon.com/route53/)
- [DNS delegation best practices](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-configuring.html)
EC2 AMIのクロスアカウント&クロスリージョンコピー

# はじめに
AWS EC2のAMI（Amazon Machine Image）を異なるAWSアカウント間でコピーする必要があったため、GUI操作による手順を整理しました。この記事では、あるアカウントで作成したAMIを別のアカウントで利用するための具体的な手順について説明します。

# 前提
- コピー元アカウント（AMIを持っているアカウント）にアクセス権限がある
- コピー先アカウント（AMIをコピーしたいアカウント）にアクセス権限がある
- 適切なIAM権限が設定されている

# AMIクロスアカウントコピーの概要

AWS EC2のAMIクロスアカウントコピーは、以下の3つのステップで行います：

1. コピー元アカウントでAMIを共有する
2. コピー先アカウントでAMIをコピーする
3. コピー元アカウントで共有権限を削除する

# 手順1: コピー元アカウントでのAMI共有設定

## 1-1. EC2ダッシュボードにアクセス

まず、コピー元アカウントでAWS Management Consoleにログインし、EC2サービスを選択します。

## 1-2. AMIの選択

左サイドバーから「イメージ」→「AMI」を選択し、共有したいAMIを選択します。

## 1-3. AMIの共有設定

選択したAMIを右クリックまたは「アクション」ボタンをクリックし、「AMI許可を編集」を選択します。

![ami-permissions-edit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/1e8e3096-136c-41cf-b10f-20aaa698ee08.png)

## 1-4. アカウント追加

AMI許可を編集画面では、以下の設定を行います：

1. 「アカウント許可を作成するときに、関連付けられたスナップショットに [ボリュームを作成] の許可を追加します。」にチェックを入れる
2. 「プライベート」を選択
3. 「共有アカウント」フィールドにコピー先のAWSアカウントIDを入力
4. 「変更を保存」をクリック

![ami-permissions-edit-config.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/15a455c7-9ea3-4f20-9da9-fe671222f3cc.png)

# 手順2: コピー先アカウントでのAMIコピー

## 2-1. コピー先アカウントでEC2ダッシュボードにアクセス

コピー先アカウントでAWS Management Consoleにログインし、EC2サービスを開きます。

**リージョンはコピー元アカウントでAMIを共有したリージョンと同じにしてください。**

## 2-2. 共有AMIの確認

「イメージ」→「AMI」を選択し、フィルターで「プライベートイメージ」を選択すると、共有されたAMIが表示されます。

## 2-3. AMIのコピー実行

1. 対象AMIを選択
2. 「アクション」→「AMIをコピー」を選択

![ami-copy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/626faf54-84ab-4f3b-b021-c26853458eff.png)

3. 必要に応じて名前や説明を変更
4. 利用したいリージョンをコピー先リージョンに選択
5. 「AMIをコピー」をクリック

![ami-copy-config.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/517b97ba-bc23-4acc-a560-f2bd86d5c399.png)

## 2-4. コピー進行状況の確認

コピー先リージョンのEC2ダッシュボードに切り替え、「イメージ」→「AMI」でコピー進行状況を確認できます。コピーが完了すると、AMIの状態が「利用可能」に変わります。

# 手順3: コピー元アカウントでの共有解除

## 3-1. AMIの共有解除

セキュリティの観点から、AMIのコピーが完了したら不要な共有権限を削除します：

1. コピー元アカウントに戻り、EC2ダッシュボードで「イメージ」→「AMI」を選択
2. 共有したAMIを選択
3. 「AMI許可を編集」を選択
4. コピー先アカウントのIDを削除
5. 「変更を保存」をクリック

# まとめ

AWS EC2 AMIのクロスアカウントコピーにより、異なるAWSアカウント間でAMIを簡単に共有できます。
この手順を参考にして、必要なAMIを他のアカウントで利用できるようにしてください。
セキュリティの観点から、コピー後は不要な共有権限を削除することを忘れないように。

# 参考

- [AWS EC2 AMI Documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html)
- [Cross-account AMI copy](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/CopyingAMIs.html)
【小ネタ】Amazon Qを使ってVibe Codingを試してみた

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

今回、Vibe Coding 100本ノック企画としてAmazon Q Developerを使って、
簡単な参加者確認アプリを実装してみました。

https://zenn.dev/moritalous/scraps/d0f5f857058420

## やったこと

vs Code上にAmazon Qをインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/114d2ca8-1e55-4eda-b7b3-ff2fe4d6894f.png)

:::note info
初回インストール時、認証情報を求められます。
:::

インストール後、左側メニューにAmazon Qのアイコンが生えるのでクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/40c44505-4df9-42d7-b4ad-d9ad8ab7636f.png)

クリックするとチャットページへ遷移するため、プロンプトを入力します。

```text
参加者チェックツールを実装したいと考えています。
要件として以下を考えています。

GitHub.ioを起動して実行できる

対象者の氏名を入れればチェックフォームを作成してくれる
```

一定時間経過後、コードが勝手に生えてきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/143a1458-b7cc-43c7-846e-d31fd7c43863.png)

## 画面イメージ

https://masakiokuda-eng.github.io/event_check_tool/

GitHub ActionでWebページを公開した結果は以下の通りです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/75f47286-6138-4878-ae21-47518fd93665.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/163ee7b8-19c8-4aad-8101-4420564a34c6.png)

きちんと求めているアウトプットが出ていますね。

## 所感

Vibe Codingお試し用の簡単なツールですが、意外とサクッと実装できるのですごいなぁといった印象を持ちました。今後、Vibe Codingしながら開発を行っていく時代になっていくのではないかと思いました。（ネタ関連も生やす予定です）

小ネタレベルの記事ですが、最後までお読みいただきありがとうございました。

https://github.com/MASAKIOKUDA-eng/event_check_tool
割り算の商と余りを一行で表示する[C#]

はじめまして、noirです。Qiita投稿は初めてです。

軽く自己紹介をします。私は現役の大学生で、大学の授業ではPythonとC言語の基礎を履修済みです。最近C#とUnityの勉強を始めました。備忘録のため、Qiitaに投稿をしてみようと思います。周りの方々に比べるとまだまだ拙い箇所がありますが、暖かい目で見守ってください…。

# 問題文へのリンクはこちらです

https://paiza.jp/works/mondai/d_rank_level_up_problems/d_rank_level_up_problems__arithmetic_substitution_op_2

# 解答
```
using System;

class Program
{
    public static void Main()
    {
        int remainder;
        
        int quotient　= Math.DivRem(437326, 9085, out remainder);
        
        Console.WriteLine("{0} {1}",quotient, remainder);
    }
}
```

# 解説
商...``` quotient ``` , 余り...``` remainder ```とします。

``` Math.Divrem ``` は整数の割り算を行い、商と余りの両方を得ることができるメソッドです。

  ここで、``` Console.WriteLine(quotient1, remainder1); ```と書くと、上手くできません。そこで、``` Console.WriteLine("{0} {1}", quotient1, remainder1); ```
  ``` {0} ``` が最初の引数（quotient1）、``` {1} ``` が次の引数（remainder1）に置き換わります。


以上です。ここまで読んでいただきありがとうございました。
SwiftUIでタイムピッカーを実装

# はじめに
今回はSwiftUiで独自のTimePickerを実装する
### コード
```swift
import SwiftUI

struct SelectTimeWheelView: View {
    // 初期値(時間)
    @State var selectedHour: Int
    // 初期値(分)
    @State var selectedMinute: Int
    var minimumTime: DateComponents
    var maximumTime: DateComponents

    var cancelAction: () -> Void = {}
    var completedAction: (_ hour: Int, _ minute: Int) -> Void = { _, _  in }

    var body: some View {
        VStack(spacing: 0) {
            HStack {
                Button(action: {
                    cancelAction()
                }) {
                    Image(systemName: "xmark")
                        .foregroundStyle(Color.Black)
                        .frame(width: 24, height: 24)
                        .padding(16)
                }

                Spacer()
                Button(action: {
                    completedAction(selectedHour, selectedMinute)
                }) {
                    Text("保存")
                }
            }
            .padding()
            .frame(height: 60)

            HStack {
                Picker(selection: $selectedHour) {
                    ForEach(getAvailableHours, id: \.self) { hour in
                        Text(String(format: "%02d", hour))
                            .tag(hour)
                    }
                } label: {}

                Text(":")

                Picker(selection: $selectedMinute) {
                    ForEach(getAvailableMinutes, id: \.self) { minute in
                        Text(String(format: "%02d", minute))
                            .tag(minute)
                    }
                } label: {}
            }
            .pickerStyle(.wheel)
        }
    }

    var getAvailableHours: [Int] {
        let startHour = minimumTime.hour ?? 0
        let endHour = maximumTime.hour ?? 24

        return Array(startHour...endHour)
    }

    var getAvailableMinutes: [Int] {
        let minuteRange = stride(from: 0, through: 55, by: 5).map { $0 }

        var availableMinutes: [Int]

        if selectedHour == minimumTime.hour && selectedHour == maximumTime.hour {
            availableMinutes = minuteRange
                .filter { $0 >= minimumTime.minute ?? 0 }
                .filter { $0 <= maximumTime.minute ?? 0 }
        } else if selectedHour == minimumTime.hour {
            availableMinutes = minuteRange
                .filter { $0 >= minimumTime.minute ?? 0 }
        } else if selectedHour == maximumTime.hour {
            availableMinutes = minuteRange
                .filter { $0 <= maximumTime.minute ?? 0 }
        } else {
            availableMinutes = minuteRange
        }

        print("Available Minutes: \(availableMinutes)")
        return availableMinutes
    }
}

#Preview {
    struct Preview: View {
        var body: some View {
            SelectTimeWheelView(
                selectedHour: 9,
                selectedMinute: 0,
                minimumTime: .init(hour: 9, minute: 0),
                maximumTime: .init(hour: 18, minute: 0)
            )
            .padding()
        }
    }
    return Preview()
}
```
### 最後に
幅を変更したり要素を変更すれば時間以外にも使えるのでぜひ
【個人開発学習】デジタル名刺アプリを作りました～作成過程で得た気づき３つ～

# はじめに
スマートフォンでの使用を想定したデジタル名刺アプリを作成しました。
0→1で何かを作れるようになることを目標にして3か月半、開発中に得た気づきをまとめてみました。

# 作ったもの

* IDを使用して、デジタル名刺を管理できるアプリです
* 名前、自己紹介を管理、GitHub・Qiita・Xへ容易に遷移できます
* スマートフォンでの使用を想定

![画面録画 2025-05-15 210306 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993509/79e55d5a-610b-47ab-879d-c8f2745264ce.gif)

https://github.com/asa129/business-card-app


# 作ってみて
## :clap: 過去の記事に救われた
開発中、何度も**過去の記事に救われた**と感じました。

今回の名刺アプリでも、DBはSupabase、CI/CDの構築、Jest＋ReactTestingLibraryでのテスト実装など、以前作った学習記録アプリで使用した技術を使用して開発を行いました。

以前と同じエラーや、「ここどうしたらいいんだっけ？」と思った際に、過去に書いた記事を見返してスムーズに進めることができました。

**自分が書いた記事も将来の自分に役立つドキュメントになる**と改めて思いました。

また、同じコミュニティの方の記事を読んで、**自分とは違う解決方法や理解の過程を知ることも刺激になりました。**

過去の私ありがとう、過去の同じエラーに遭遇して記事にしてくれた方ありがとうとしみじみと感じた開発期間でした。

## :timer: GitHubActionsでスケジュール実行ができるようになった
開発過程で、GitHubActionsでスケジュール実行を使ってデータを削除することに挑戦しました。
その時の奮闘はこちらにまとめています。

https://qiita.com/asa129/items/bfcb2005c0061e11f452

私は保守・改修の仕事をしています。

これまでバッチ機能を作ったことはありましたが、スケジュール実行は運用チームが担当していたため、わからないままでした。
`cronってワードは聞いたことがあるレベル、どうやってやって決まった時間に実行しているんだろう`と思うことはあったもの`思う`だけでした。

実際にスケジュール実行を自分で作ってみて、こうやってやっているんだ！自分でもできる！という感覚を得ることができました。


## :frowning2: デザインパターンに挑戦、しかしながら挫折
開発過程で、デザインパターンの活用（TemplateMethodパターンとFactoryMethodパターン）に挑戦しようとしました。

TemplateMethodパターンは理解できたものの、FactoryMethodパターンで挫折しました。

概念は理解できて、コード例も読めるし再現もできます。Copilotに何度も教えてもらって、「なるほど」となります。しかし、いざ自分のプロダクトに取り込もうとすると、`「どこで使えばいいの？」「あれ？これであっている？使えている？」`となり分からなくなってしまいました。

`自分で説明できるまで理解できたことはその後も自分の糧になる`—これまでの学習で身に染みて実感していました。でも、コミュニティのメンターさんから「どうしても理解できないものは一旦寝かせることも大事」とアドバイスをもらいました。つよつよエンジニアの方も同じことを言われるそうです。

**理解できるときがきっとくることを信じて、一旦寝かせることを決断しました。**


# おわりに
作り終わった後、何気に自分のスマートフォンで作ったプロダクトを表示させました。
スマートフォンサイズで作ったので、自分のスマートフォンで見たとき嬉しかったです。

# JISOUのメンバー募集中！
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
興味のある方は、ぜひホームページをのぞいてみてください！
▼▼▼

https://projisou.jp
Djangoでユーザー登録後に自動ログインさせる方法

## はじめに
Djangoでユーザー登録機能（SignUp）を実装した際、
「登録後に自動的にログイン状態にしたい」と思ったことはありませんか？
この記事では、CreateView を継承してユーザー登録後に自動ログインを行う方法を解説します。
UX向上や実務での実装にも応用できるので、初学者にもおすすめです。

## 実現したいこと
Djangoのユーザー登録後、自動ログイン状態にする。
ユーザーに「ログインし直す」手間をかけさせない。
CreateView ＋ login() を活用したシンプルな実装。

## 実装コード
### フォーム（例：CustomUserCreationForm）
UserCreationFormを継承したCustomUserCreationFormにユーザー新規登録用のフォームを実装する。
fieldsに新規登録時の入力項目を設定する。（ここでの入力内容は、ユーザー名、メールアドレス、パスワード、パスワード（確認用）である。）

```users/forms.py
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User

class CustomUserCreationForm(UserCreationForm):
    email = forms.EmailField(required=True, widget=forms.EmailInput(attrs={"class": "form-control"}))

    class Meta:
        model = User
        fields = ("username", "email", "password1", "password2")  # 必要に応じて変更
        widgets = {
            "username": forms.TextInput(attrs={"class": "form-control"}),
            "password1": forms.PasswordInput(attrs={"class": "form-control"}),
            "password2": forms.PasswordInput(attrs={"class": "form-control"}),
        }
```

### ビュー（form_valid() でログイン処理を追加）
上記で設定したフォームについて、SignUpViewで呼び出している。
template_nameに新規登録用フォームのあるhtmlファイルが存在するパスを記載する。
self.object = form.save()でユーザー登録し、loginでログインの処理を行っている。
ログイン成功後、get_success_urlに記載のページに遷移する。

```users/views.py
from django.contrib.auth import login
from django.urls import reverse
from django.views.generic.edit import CreateView
from django.contrib.auth.models import User
from .forms import CustomUserCreationForm

class SignUpView(CreateView):
    model = User
    form_class = CustomUserCreationForm
    template_name = 'registration/signup.html'

    def form_valid(self, form):
        self.object = form.save()  # ユーザー登録
        response = super().form_valid(form)
        login(self.request, self.object)  # 自動ログイン
        return response

    def get_success_url(self):
        # 登録後に遷移するページを指定（ここではタスク一覧画面）
        return reverse('todos:index')
```

## 自動ログインが重要な理由
ユーザー新規登録後、すぐログイン状態になるため、ユーザーが使いやすくなるためです。
新規登録→ログインの流れだと、ユーザーの手間をかけさせることになってしまいます。

## まとめ
Djangoでは CreateView を拡張し、form_valid() 内で login() を呼ぶことで簡単に自動ログインを実現できます。
get_success_url() を適切に設定することで、ユーザー導線もコントロール可能です。

## 終わりに
初投稿なので、改善点やご指摘などあればぜひコメントいただけると嬉しいです！

## 備考
Djangoバージョン：4.x系想定
テンプレートエンジン：Django標準
Bootstrap 5 使用（UI整備済み）
Postgres・自分用SQLチートシート（SELECT編）

## はじめに
業務で頻繁に利用するクエリを使用例とともに自分用にまとめました。
随時、クエリの追加をしていきたいと考えています。

テストデータのCREATE TABLE、INSERTについては最後に紹介しています

- [利用するデータ](#利用するデータ)
- [文字列を連結したい](#文字列を連結したい)
- [csv等のデータをテーブルのように扱いたいとき](#csv等のデータをテーブルのように扱いたいとき)
- [日付単位でグルーピングしたい時](#日付単位でグルーピングしたい時)
- [1対多を1行で表現したいとき](#1対多を1行で表現したいとき)
- [SELECT結果をCSV出力したい](#SELECT結果をCSV出力したい)


## 利用するデータ
クエリ
```sql
select
  *
from
  simple_table;
```

実行結果
```sql
 id | last_name | first_name | created_at 
----+-----------+------------+------------
  1 | Tanaka    | Taro       | 2025-05-01
  2 | Suzuki    | Hanako     | 2025-05-01
  3 | Yamamoto  | Jiro       | 2025-05-15
(3 rows)
```


## 文字列を連結したい

クエリ
```sql
select
  concat_ws(' ', last_name, first_name, created_at, '作成')
from
  simple_table;
```

実行結果
```sql
           concat_ws           
-------------------------------
 Tanaka Taro 2025-05-01 作成
 Suzuki Hanako 2025-05-01 作成
 Yamamoto Jiro 2025-05-15 作成
(3 rows)
```

## CSV等のデータをテーブルのように扱いたいとき

クエリ
```sql
WITH csv_data (user_id, age) AS (
  VALUES
    (1, 20),
    (2, 40)
)
SELECT
  st.id,
  st.last_name,
  st.first_name,
  cd.age
FROM
  simple_table st
  INNER JOIN csv_data cd
    ON st.id = cd.user_id;
```

実行結果
```sql
 id | last_name | first_name | age 
----+-----------+------------+-----
  1 | Tanaka    | Taro       |  20
  2 | Suzuki    | Hanako     |  40
(2 rows)
```

## 日付単位でグルーピングしたい時

クエリ
```sql
SELECT
  CAST(st.created_at AS DATE) AS date,
  Count(*)
FROM
  simple_table st
GROUP BY
  date
ORDER BY
  date;
```

実行結果
```sql
    date    | count 
------------+-------
 2025-05-01 |     2
 2025-05-15 |     1
(2 rows)
```

## 1対多を1行で表現したいとき
クエリ
```sql
SELECT
  CAST(st.created_at AS DATE) AS date,
  STRING_AGG(st.last_name::text, ',') AS last_names
FROM
  simple_table st
GROUP BY
  date
ORDER BY
  date;
```

実行結果
```sql
    date    |  last_names   
------------+---------------
 2025-05-01 | Tanaka,Suzuki
 2025-05-15 | Yamamoto
(2 rows)
```

## SELECT結果をCSV出力したい
クエリ
```sql
\COPY (select * from simple_table limit 3) TO '出力先ファイルパス.csv' WITH CSV HEADER;
```

実行結果
```sql
-- psqlに接続したカレントディレクトリにCSVファイルが保存されているはずです。
```

## ◾️データの準備
```sql
CREATE TABLE IF NOT EXISTS simple_table (
    id INTEGER PRIMARY KEY,
    last_name TEXT,
    first_name TEXT,
    created_at DATE
);


INSERT INTO simple_table (id, last_name, first_name, created_at) VALUES
    (1, 'Tanaka', 'Taro', '2025-05-01'),
    (2, 'Suzuki', 'Hanako', '2025-05-10'),
    (3, 'Yamamoto', 'Jiro', '2025-05-15');

DROP TABLE IF EXISTS simple_table;
```
Atcoder解いてみた ABC 081 C - Not so Diverse

# ARC 096 C - Half and Half 解いてみた
問題は[こちら](https://atcoder.jp/contests/arc096/tasks/arc096_a)

# 方針
- A[i]に何種類の数があって、種類ごとにいくつあるのかカウントする(具体的な値については気にしなくてOK)  
- 少ない種類の数からK種類以下になるまで置き換えて行く(実際に置きかえる作業は不要で、何個おきかえればいいかカウントしていく)  

そのために、以下の手順でコードを書く  
- まず、配列Aのヒストグラム(※1)を求める
- ※1から0の要素を削除した配列(※2)を作成する。 この配列の要素数が配列Aの数の種類
- 配列Aの数の種類 - Kが削除したい種類の数(※3)
- ※2を昇順ソート(※4)
- ※4の配列の0番目の要素から、※3 - 1の要素までの値を合計した値を求める

# コード
```C++
#include <iostream>
#include <map>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;


int main() {
    int N, K;
    int A[200000];

    cin >> N;
    cin >> K;

    for (int i = 0; i < N; i++) {
        cin >> A[i];
    }

    std::vector<int> hist;
    hist.resize(N);

    // ヒストグラム作成
    for (int i = 0; i < N; i++) {
        
        hist[A[i]-1]++; // A[i] >=1
    }

    std::vector<int> histNonZero; // ヒストグラムから0の要素を削除したもの
    for (int i = 0; i < N; i++) {
        if (hist[i] != 0) {
            histNonZero.push_back(hist[i]);
        }
    }

    int diffKind = histNonZero.size() - K; // どのくらいの種類を減らしたいか

    // ヒストグラムを昇順ソート
    sort(histNonZero.begin(), histNonZero.end());

    int val = 0;
    for (int i = 0; i < diffKind; i++) {
        val += histNonZero[i];
    }

    std::cout << val << std::endl;

    return 0;
}
```  

模範回答も同様の手順で実装していた  
ただ、[こちら](https://blog.hamayanhamayan.com/entry/2017/12/10/224259)のように、mapを使えば、どの数が何種類あるのかの情報を簡単に管理することができることに加えて、使用するメモリの容量も必要最低限にできる  
今回、無意識の内に「貪欲法(Greedy)」を使っていた。  
後先のことを考えず、その場その場での最善の選択を繰り返していく」 といったような考え方を「貪欲法」というそう。  
今回でいうと、少ない種類の数の個数が格納されている配列を、最初の要素から指定の要素番号まで数えていっているが、この部分が貪欲法に該当するそう。